@w6w/react 0.4.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 w6w-io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,172 @@
1
+ # @w6w/react
2
+
3
+ React bindings for [`@w6w/sdk`](../node) — a `<W6wProvider>` that holds one memoized
4
+ `W6wClient` with per-request token freshness, a small hook set over the SDK's public
5
+ surface (`me`, `documents`, `vars`, `connections`, `workflows`, `run`), and
6
+ `createW6wUiAdapter`, a structural bridge from a `W6wClient` to
7
+ [`@w6w/ui`](https://github.com/w6w-io/w6w-ui)'s `W6wApi` contract.
8
+
9
+ License: MIT · Version: 0.3.0
10
+
11
+ This lane implements no endpoint — it composes `@w6w/sdk`, which is already
12
+ conformant against [`endpoints.json`](../endpoints.json). There is nothing here to
13
+ re-verify against the wire contract; verify `@w6w/sdk` instead.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @w6w/react react
19
+ ```
20
+
21
+ `react-dom` is not a dependency of this package — `<W6wProvider>`'s only JSX is a
22
+ context wrapper (`<Ctx.Provider>`), never a DOM element of its own. Your app already
23
+ depends on `react-dom` to mount itself; nothing extra is needed here.
24
+
25
+ ## Quick start
26
+
27
+ Wrap your app root once:
28
+
29
+ ```tsx
30
+ import { W6wProvider } from "@w6w/react";
31
+
32
+ function App() {
33
+ return (
34
+ <W6wProvider baseUrl="https://api.example.com" token={() => getCurrentJwt()}>
35
+ <YourApp />
36
+ </W6wProvider>
37
+ );
38
+ }
39
+ ```
40
+
41
+ `token` accepts a literal string, or a supplier function called fresh on every
42
+ request — pass a supplier when your token rotates (e.g. a short-lived JWT read from
43
+ an auth SDK) and the client will pick up the new value on the very next call, with no
44
+ teardown/rebuild of the underlying `W6wClient`. See `src/W6wProvider.tsx`'s module
45
+ header for the exact mechanism (the C-4 shim).
46
+
47
+ Then, anywhere under the provider:
48
+
49
+ ```tsx
50
+ import { useDocuments, useW6wClient } from "@w6w/react";
51
+
52
+ function DocList() {
53
+ const { data, loading, error, refetch } = useDocuments();
54
+ if (loading) return <p>Loading…</p>;
55
+ if (error) return <p>Failed: {String(error)}</p>;
56
+ return (
57
+ <ul>
58
+ {data?.map((doc) => <li key={doc.id}>{doc.key}</li>)}
59
+ </ul>
60
+ );
61
+ }
62
+ ```
63
+
64
+ ## Using this package with `@w6w/ui`
65
+
66
+ `@w6w/ui`'s components (e.g. `AppPicker`, `ActionTestForm`, the flow editor) take a
67
+ `W6wApi` object through their own `<W6wUIProvider api={...}>`. Build one from your
68
+ `@w6w/react` client with `createW6wUiAdapter`:
69
+
70
+ ```tsx
71
+ import { createW6wUiAdapter, useW6wClient, W6wProvider } from "@w6w/react";
72
+ import { W6wUIProvider, AppPicker } from "@w6w/ui";
73
+
74
+ function UiBridge({ children }: { children: React.ReactNode }) {
75
+ const client = useW6wClient();
76
+ const api = useMemo(() => createW6wUiAdapter(client), [client]);
77
+ return <W6wUIProvider api={api}>{children}</W6wUIProvider>;
78
+ }
79
+
80
+ function App() {
81
+ return (
82
+ <W6wProvider baseUrl="https://api.example.com" token={jwtSupplier}>
83
+ <UiBridge>
84
+ <AppPicker onPick={(appId) => console.log(appId)} />
85
+ </UiBridge>
86
+ </W6wProvider>
87
+ );
88
+ }
89
+ ```
90
+
91
+ **`@w6w/ui` is not on npm today.** The `@w6w` scope holds only `@w6w/sdk` and
92
+ `@w6w/cli` at the time of writing (`npm view @w6w/ui` → 404); the source itself IS a
93
+ public GitHub repository (`w6w-io/w6w-ui`). `createW6wUiAdapter`'s `W6wApi` return
94
+ type targets that contract *structurally* — this package names `@w6w/ui` nowhere in
95
+ its own manifest and needs no change whenever `@w6w/ui` becomes reachable another
96
+ way (this monorepo, a `git+https://` dependency on the public repo, or a private
97
+ registry). This is an honest statement of today's install story, not a promise that
98
+ `npm i @w6w/ui` resolves.
99
+
100
+ `createW6wUiAdapter` is built entirely on `@w6w/sdk/console` — the SAME namespace
101
+ `packages/studio`'s own facade uses for these routes (`packages/ui/src/createW6wApi.ts`
102
+ is the *other* hand-rolled client for them; this package is not a third one).
103
+ **`client.console.*` is documented "Studio-internal… unstable" and is deliberately
104
+ excluded from `endpoints.json`'s conformance runner** (`node/src/client.ts:114-116`).
105
+ That means a `console.*` signature change ships with no lockstep protection for this
106
+ bridge beyond `@w6w/sdk`'s own version — pin your `@w6w/sdk` version alongside
107
+ `@w6w/react`'s, and re-test the bridge on an upgrade rather than assuming it.
108
+
109
+ ## Hooks catalog
110
+
111
+ Every read hook returns `{data, error, loading, refetch}`; every mutation hook
112
+ returns `{call, data, error, loading}`. None depends on react-query or any other
113
+ data-fetching library.
114
+
115
+ | Hook | Wraps |
116
+ |---|---|
117
+ | `useMe()` | `client.me()` |
118
+ | `useDocuments(options?)` | `client.documents.list()` |
119
+ | `useDocument(id, options?)` | `client.documents.get()` |
120
+ | `useDocumentByKey(key, options?)` | `client.documents.getByKey()` |
121
+ | `useCreateDocument()` | `client.documents.create()` |
122
+ | `useUpdateDocument()` | `client.documents.update()` |
123
+ | `useDeleteDocument()` | `client.documents.delete()` |
124
+ | `useVars()` | `client.vars.list()` |
125
+ | `useVar(id)` | `client.vars.get()` |
126
+ | `useCreateVar()` | `client.vars.create()` |
127
+ | `useUpdateVar()` | `client.vars.update()` |
128
+ | `useDeleteVar()` | `client.vars.delete()` |
129
+ | `useConnections()` | `client.connections.list()` |
130
+ | `useWorkflows(options?)` | `client.workflows.list()` |
131
+ | `useRunWorkflow()` | `client.workflows.run()`, defaults `wait: true` |
132
+ | `useRun()` | `client.run()` (the generic URN dispatch) |
133
+
134
+ `useRunWorkflow()`'s `call` defaults `wait: true` when the caller's options omit
135
+ `wait`: `workflows.run` without `wait` (`node/src/workflows.ts`) leaves the caller
136
+ with only a `runId` and no public polling operation to follow it with —
137
+ `console.workflows.getRun` exists, but it is the same studio-internal, unstable
138
+ surface described above, so this hook does not reach for it. Pass `wait: false`
139
+ explicitly if you genuinely want the queued-and-walk-away behaviour.
140
+
141
+ `useW6wClient()` returns the underlying `W6wClient` for anything not covered by a
142
+ hook (e.g. `client.console.*` directly, at your own risk per the caveat above).
143
+
144
+ ## Known limitations
145
+
146
+ - **`getAppActions`'s declared `ActionDef.params` type is a strict field subset of
147
+ `@w6w/ui`'s richer `ActionParam`.** `@w6w/sdk/console`'s `ActionParam` carries 6
148
+ fields (`key, label, type, required, default, hint`); `@w6w/ui`'s carries 14 more,
149
+ presentation-only fields (`placeholder, advanced, row, item, showIf, options,
150
+ config, children, section, title, subtitle, layout, collapsed`). This typechecks
151
+ fine — every extra field is optional — and there is no runtime data loss (the JSON
152
+ payload is unfiltered); a caller typing a variable through this adapter's declared
153
+ return type just gets no autocomplete for those extra fields.
154
+ - **`ActionTestForm.tsx:149,176`'s error handling cannot be satisfied from this
155
+ package.** `@w6w/ui`'s `ActionTestForm` does a NOMINAL `instanceof ApiError` check
156
+ against its OWN `ApiError` class (`packages/ui/src/createW6wApi.ts`), not a
157
+ duck-typed one. No error object this adapter throws can ever satisfy that check
158
+ without importing `@w6w/ui`'s class directly, which this package's MIT/C-1
159
+ boundary forbids. Concretely: on a failed `invokeAction` used together with
160
+ `@w6w/ui`'s `ActionTestForm`, the 401/403 permission-hint messaging falls back to a
161
+ generic message, and the `ApiCallsPanel` egress log renders empty instead of
162
+ showing the outbound calls the action made — even though this adapter's thrown
163
+ error genuinely carries that data on `.body`/`.raw`. This adapter still aliases
164
+ `@w6w/sdk`'s `ApiError.raw` onto `.body` (`err.body === err.raw`) and sets
165
+ `err.name = "ApiError"`, so it is already correct for any DUCK-TYPING consumer, and
166
+ needs no further change the moment `@w6w/ui` switches its own check to one. The fix
167
+ belongs to `@w6w/ui`, not this package, and is filed there:
168
+ `.ai/projects/backlog/26-08-13-01-ui-error-nominal-check.md`.
169
+ - **No `AbortSignal`/cancellation support in the hook set.** `@w6w/sdk`'s transport
170
+ (`node/src/http.ts`) has nothing to hook an abort into. A read hook only IGNORES a
171
+ result that resolves after its component unmounts (a mounted-ref guard); it cannot
172
+ cancel the in-flight request itself.
package/dist/mod.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `@w6w/react` — the package barrel.
3
+ *
4
+ * A thin React binding over `@w6w/sdk`: `<W6wProvider>` (the C-4
5
+ * token-supplier shim), a small hook set, and `createW6wUiAdapter` (the
6
+ * `@w6w/ui` `W6wApi` structural bridge, C-1/C-2). See `README.md` for the
7
+ * install + wrap-your-root example, the hooks catalog, and this lane's
8
+ * documented limitations.
9
+ *
10
+ * Every public export lives here — a symbol this file does not re-export is
11
+ * not part of the published surface.
12
+ *
13
+ * @module
14
+ */
15
+ export { VERSION } from "./src/version.ts";
16
+ export { type TokenSource, useW6wClient, W6wProvider, type W6wProviderProps, } from "./src/W6wProvider.tsx";
17
+ export { type MutationResult, type ReadResult, useConnections, useCreateDocument, useCreateVar, useDeleteDocument, useDeleteVar, useDocument, useDocumentByKey, useDocuments, useMe, useRun, useRunWorkflow, useUpdateDocument, useUpdateVar, useVar, useVars, useWorkflows, } from "./src/hooks.ts";
18
+ export { createW6wUiAdapter, type W6wApi } from "./src/adapter.ts";
19
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EACL,KAAK,WAAW,EAChB,YAAY,EACZ,WAAW,EACX,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,MAAM,EACN,OAAO,EACP,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/mod.js ADDED
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `@w6w/react` — the package barrel.
3
+ *
4
+ * A thin React binding over `@w6w/sdk`: `<W6wProvider>` (the C-4
5
+ * token-supplier shim), a small hook set, and `createW6wUiAdapter` (the
6
+ * `@w6w/ui` `W6wApi` structural bridge, C-1/C-2). See `README.md` for the
7
+ * install + wrap-your-root example, the hooks catalog, and this lane's
8
+ * documented limitations.
9
+ *
10
+ * Every public export lives here — a symbol this file does not re-export is
11
+ * not part of the published surface.
12
+ *
13
+ * @module
14
+ */
15
+ export { VERSION } from "./src/version.js";
16
+ export { useW6wClient, W6wProvider, } from "./src/W6wProvider.js";
17
+ export { useConnections, useCreateDocument, useCreateVar, useDeleteDocument, useDeleteVar, useDocument, useDocumentByKey, useDocuments, useMe, useRun, useRunWorkflow, useUpdateDocument, useUpdateVar, useVar, useVars, useWorkflows, } from "./src/hooks.js";
18
+ export { createW6wUiAdapter } from "./src/adapter.js";
19
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAEL,YAAY,EACZ,WAAW,GAEZ,MAAM,sBAAuB,CAAC;AAE/B,OAAO,EAGL,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,YAAY,EACZ,KAAK,EACL,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,MAAM,EACN,OAAO,EACP,YAAY,GACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAe,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * `<W6wProvider>` — one `W6wClient` per `baseUrl`, with per-request token
3
+ * freshness (C-4).
4
+ *
5
+ * `@w6w/sdk`'s `W6wClientOptions.token` (`node/src/config.ts:41-63`) is
6
+ * resolved ONCE, at construction, into `readonly` instance state
7
+ * (`node/src/client.ts:59`) — there is no supplier form. A naive
8
+ * `new W6wClient({ token })` therefore captures whatever `token` was at mount
9
+ * time and never sees a later rotation.
10
+ *
11
+ * The fix lives at the `fetch`-injection seam, not the `token` seam.
12
+ * `node/src/http.ts`'s `request()` builds `headers = new Headers(options.headers)`
13
+ * and then unconditionally `headers.set("authorization", ...)` BEFORE calling
14
+ * the injected `fetchImpl(url, {method, headers, body})` — `Headers.set`
15
+ * REPLACES, so a custom `fetch` passed to `new W6wClient({ fetch })` can read
16
+ * the CURRENT token and overwrite `authorization` on the `Headers` object it
17
+ * receives, immediately before delegating to the real transport. This
18
+ * provider therefore constructs its `W6wClient` ONCE, with a non-blank
19
+ * placeholder token (any non-blank string satisfies `requireToken`,
20
+ * `config.ts:229-237` — it is never actually sent, since the injected `fetch`
21
+ * always overwrites it first) and an injected `fetch` that resolves the
22
+ * current `token` prop (calling it, if it is a supplier) on every call.
23
+ *
24
+ * **Do not key the outer `useMemo` on `token`.** `packages/studio/src/api/apiClient.tsx`
25
+ * rebuilds its client whenever the token STRING changes — the right policy for
26
+ * studio's own state-variable token, and the wrong one here: a supplier
27
+ * function has a stable identity across renders, so keying on the supplier
28
+ * would never rebuild AND never read a fresh value, while keying on the
29
+ * token's resolved value would tear the client down and rebuild it on every
30
+ * rotation — exactly what C-4 says not to do ("without tearing down"). The
31
+ * memo below depends on `[baseUrl, project]` only; `token` and `fetch` are
32
+ * read through "latest" refs, updated every render but never a dependency, so
33
+ * a rotating token is read fresh per request without ever rebuilding the
34
+ * client.
35
+ *
36
+ * @module
37
+ */
38
+ import { type FetchLike, W6wClient } from "@w6w/sdk";
39
+ import { type ReactNode } from "react";
40
+ /** A static bearer token, or a supplier read fresh on every request. */
41
+ export type TokenSource = string | (() => string | null | undefined);
42
+ export interface W6wProviderProps {
43
+ /** The w6w server's origin, e.g. `"https://api.example.com"`. */
44
+ baseUrl: string;
45
+ /** A literal bearer token, or a supplier called fresh on every request. */
46
+ token: TokenSource;
47
+ /**
48
+ * The real transport this provider's injected `fetch` delegates to, after
49
+ * overwriting the `authorization` header. Defaults to `globalThis.fetch`.
50
+ * Mainly for tests — a caller wanting to record or stub outbound requests.
51
+ */
52
+ fetch?: FetchLike;
53
+ /** Default project id for the project-scoped operations (`documents.*`, `workflows.list`). */
54
+ project?: string;
55
+ children: ReactNode;
56
+ }
57
+ /**
58
+ * Provides one memoized `W6wClient` to every component under it. See this
59
+ * module's header for the C-4 token-freshness mechanism.
60
+ */
61
+ export declare function W6wProvider(props: W6wProviderProps): ReactNode;
62
+ /**
63
+ * Access the memoized `W6wClient`. Throws a helpful error if used outside a
64
+ * `<W6wProvider>` (mirrors `packages/ui/src/provider.tsx:249-258`'s
65
+ * `useW6wApi` shape — read-only reference, transcribed here, never imported).
66
+ */
67
+ export declare function useW6wClient(): W6wClient;
68
+ //# sourceMappingURL=W6wProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"W6wProvider.d.ts","sourceRoot":"","sources":["../../src/W6wProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAE,KAAK,SAAS,EAA8C,MAAM,OAAO,CAAC;AAEnF,wEAAwE;AACxE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAUrE,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,KAAK,EAAE,WAAW,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,CA8B9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,SAAS,CASxC"}
@@ -0,0 +1,92 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * `<W6wProvider>` — one `W6wClient` per `baseUrl`, with per-request token
4
+ * freshness (C-4).
5
+ *
6
+ * `@w6w/sdk`'s `W6wClientOptions.token` (`node/src/config.ts:41-63`) is
7
+ * resolved ONCE, at construction, into `readonly` instance state
8
+ * (`node/src/client.ts:59`) — there is no supplier form. A naive
9
+ * `new W6wClient({ token })` therefore captures whatever `token` was at mount
10
+ * time and never sees a later rotation.
11
+ *
12
+ * The fix lives at the `fetch`-injection seam, not the `token` seam.
13
+ * `node/src/http.ts`'s `request()` builds `headers = new Headers(options.headers)`
14
+ * and then unconditionally `headers.set("authorization", ...)` BEFORE calling
15
+ * the injected `fetchImpl(url, {method, headers, body})` — `Headers.set`
16
+ * REPLACES, so a custom `fetch` passed to `new W6wClient({ fetch })` can read
17
+ * the CURRENT token and overwrite `authorization` on the `Headers` object it
18
+ * receives, immediately before delegating to the real transport. This
19
+ * provider therefore constructs its `W6wClient` ONCE, with a non-blank
20
+ * placeholder token (any non-blank string satisfies `requireToken`,
21
+ * `config.ts:229-237` — it is never actually sent, since the injected `fetch`
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
+ *
25
+ * **Do not key the outer `useMemo` on `token`.** `packages/studio/src/api/apiClient.tsx`
26
+ * rebuilds its client whenever the token STRING changes — the right policy for
27
+ * studio's own state-variable token, and the wrong one here: a supplier
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.
36
+ *
37
+ * @module
38
+ */
39
+ import { W6wClient } from "@w6w/sdk";
40
+ import { createContext, useContext, useMemo, useRef } from "react";
41
+ /**
42
+ * Satisfies `requireToken` at construction so the client never throws a
43
+ * `ConfigError` for "no token" — this value is never actually sent on the
44
+ * wire, since the injected `fetch` below always overwrites it first. See
45
+ * this module's header.
46
+ */
47
+ const PLACEHOLDER_TOKEN = "w6w-react-unused-placeholder-token";
48
+ const Ctx = createContext(null);
49
+ /**
50
+ * Provides one memoized `W6wClient` to every component under it. See this
51
+ * module's header for the C-4 token-freshness mechanism.
52
+ */
53
+ export function W6wProvider(props) {
54
+ const { baseUrl, token, fetch: fetchOverride, project, children } = props;
55
+ // "Latest ref" pattern: kept in sync on every render, but never a `useMemo`
56
+ // dependency below — the injected `fetch` always reads the CURRENT prop
57
+ // value through these, so a token rotation or a new `fetch` prop identity
58
+ // never forces a client rebuild. Refs are stable across renders and are not
59
+ // "reactive" values, so `useExhaustiveDependencies` correctly does not
60
+ // require them in the memo's dependency array.
61
+ const tokenRef = useRef(token);
62
+ tokenRef.current = token;
63
+ const fetchRef = useRef(fetchOverride);
64
+ fetchRef.current = fetchOverride;
65
+ const client = useMemo(() => {
66
+ const injectedFetch = (input, init) => {
67
+ const current = typeof tokenRef.current === "function" ? tokenRef.current() : tokenRef.current;
68
+ const headers = new Headers(init?.headers);
69
+ if (current) {
70
+ headers.set("authorization", `Bearer ${current}`);
71
+ }
72
+ const transport = fetchRef.current ?? ((i, ii) => globalThis.fetch(i, ii));
73
+ return transport(input, { ...init, headers });
74
+ };
75
+ return new W6wClient({ baseUrl, token: PLACEHOLDER_TOKEN, project, fetch: injectedFetch });
76
+ }, [baseUrl, project]);
77
+ return _jsx(Ctx.Provider, { value: client, children: children });
78
+ }
79
+ /**
80
+ * Access the memoized `W6wClient`. Throws a helpful error if used outside a
81
+ * `<W6wProvider>` (mirrors `packages/ui/src/provider.tsx:249-258`'s
82
+ * `useW6wApi` shape — read-only reference, transcribed here, never imported).
83
+ */
84
+ export function useW6wClient() {
85
+ const client = useContext(Ctx);
86
+ if (!client) {
87
+ throw new Error("useW6wClient must be used inside <W6wProvider>. " +
88
+ 'Wrap your app root with <W6wProvider baseUrl="..." token="...">...</W6wProvider>.');
89
+ }
90
+ return client;
91
+ }
92
+ //# sourceMappingURL=W6wProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"W6wProvider.js","sourceRoot":"","sources":["../../src/W6wProvider.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,EAAkB,SAAS,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,EAAkB,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAKnF;;;;;GAKG;AACH,MAAM,iBAAiB,GAAG,oCAAoC,CAAC;AAkB/D,MAAM,GAAG,GAAG,aAAa,CAAmB,IAAI,CAAC,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;IAE1E,4EAA4E;IAC5E,wEAAwE;IACxE,0EAA0E;IAC1E,4EAA4E;IAC5E,uEAAuE;IACvE,+CAA+C;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,GAAG,aAAa,CAAC;IAEjC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;QAC1B,MAAM,aAAa,GAAc,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC/C,MAAM,OAAO,GACX,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YACjF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,MAAM,SAAS,GACb,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC,CAAS,EAAE,EAAgB,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACjF,OAAO,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC;QACF,OAAO,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;IAC7F,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvB,OAAO,KAAC,GAAG,CAAC,QAAQ,IAAC,KAAK,EAAE,MAAM,YAAG,QAAQ,GAAgB,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,kDAAkD;YAChD,mFAAmF,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * `createW6wUiAdapter` — a structurally-typed bridge from a `W6wClient` to
3
+ * `@w6w/ui`'s `W6wApi` contract (C-1, C-2).
4
+ *
5
+ * `W6wApi` below is a HAND-DUPLICATE of `packages/ui/src/provider.tsx:87-231` —
6
+ * transcribed by hand, never imported. `@w6w/ui` is `SEE LICENSE IN LICENSE`
7
+ * and unpublished; this lane is MIT, so no dependency edge to it may exist
8
+ * anywhere, not even a type-only one (C-1). The VALUE types the interface
9
+ * needs (`AppSummary`, `ActionDef`, `AuthDef`, `ApiCallRecord`, `SavedTest`,
10
+ * `TestRunSummary`, `StepTest`, `InvokeOptions`, `ConnectionSummary`) are NOT
11
+ * hand-duplicated — they are already exported from `@w6w/sdk`/`@w6w/sdk/console`
12
+ * and structurally compatible (`building-blocks.md` §3's "Type duplication"
13
+ * analysis). Two documented, harmless narrowings from that analysis:
14
+ * - `getAppActions`'s `ActionDef.params` (`ActionParam`, `@w6w/sdk/console`)
15
+ * carries 6 fields vs `@w6w/ui`'s 14 richer, presentation-only ones —
16
+ * typechecks fine, no runtime loss, no autocomplete for the extra optional
17
+ * fields. See README "Known limitations".
18
+ * - `listTestRuns` is REQUIRED here; `@w6w/ui`'s declaration marks it optional
19
+ * (`?`) only so a consumer that hasn't wired history yet still typechecks.
20
+ * Every consumer of THIS adapter gets a real implementation, so there is no
21
+ * reason to decline it — a required member still satisfies an interface
22
+ * that declares it optional.
23
+ *
24
+ * Every member here is a thin call into `client.console.*`, with two
25
+ * exceptions the SDK's own module headers document:
26
+ * - `listConnections` — see the comment at its call site below.
27
+ * - `recordTestRun` / `recordStepTestRun` — the SDK returns the real created
28
+ * row; `W6wApi` is pinned `Promise<void>`. Discarded with
29
+ * `.then(() => undefined)`, mirroring
30
+ * `packages/studio/src/repos/saved-tests.ts:97-109` and
31
+ * `step-tests.ts:46-59` (read-only reference, transcribed, never imported).
32
+ *
33
+ * `listApps` is a direct, one-line pass-through to `client.console.apps.list()`
34
+ * — that method already pages internally (`node/src/console/apps.ts:469-496`),
35
+ * so writing a second pagination loop here would be exactly the "third client
36
+ * for these routes" C-2 exists to prevent.
37
+ *
38
+ * @module
39
+ */
40
+ import { type ConnectionSummary, type W6wClient } from "@w6w/sdk";
41
+ import type { ActionDef, ApiCallRecord, AppSummary, AuthDef, InvokeOptions, SavedTest, StepTest, TestRunSummary } from "@w6w/sdk/console";
42
+ /**
43
+ * The `@w6w/ui` `W6wApi` contract, hand-duplicated — see this module's
44
+ * header. Every member's signature mirrors `provider.tsx:87-231`'s member of
45
+ * the same name.
46
+ */
47
+ export interface W6wApi {
48
+ /** List registered apps to pick from in the connection modal. */
49
+ listApps(): Promise<AppSummary[]>;
50
+ /** Load auth methods declared by an app's manifest, with availability flags. */
51
+ getAppAuth(appId: string): Promise<AuthDef[]>;
52
+ /** Create a non-OAuth connection with a user-supplied credential. */
53
+ createConnection(appId: string, body: {
54
+ authKey: string;
55
+ credential: Record<string, unknown>;
56
+ displayName?: string;
57
+ profile?: Record<string, unknown>;
58
+ }): Promise<ConnectionSummary>;
59
+ /**
60
+ * Start an OAuth 2.0 flow. Server builds the provider's authorize URL and
61
+ * returns it; the caller opens it in a popup and awaits the server's
62
+ * callback message — that popup/message flow is `@w6w/ui`'s concern
63
+ * (`oauth-popup.ts`), unchanged by this bridge.
64
+ */
65
+ startAppOAuthFlow(appId: string, authKey: string, body: {
66
+ displayName?: string;
67
+ }): Promise<{
68
+ authorizationUrl: string;
69
+ }>;
70
+ /** List the actions an app exposes, to pick from in the step builder. */
71
+ getAppActions(appId: string): Promise<ActionDef[]>;
72
+ /** List the connections that already exist for a given app. */
73
+ listConnectionsForApp(appId: string): Promise<ConnectionSummary[]>;
74
+ /** List every connection across apps — drives the "Connected apps" tab. */
75
+ listConnections(): Promise<ConnectionSummary[]>;
76
+ /**
77
+ * Invoke a single action — used to test-run one step from the visual
78
+ * editor. `opts.connectionId` runs with a stored connection's credential;
79
+ * `opts.project` scopes document/var expressions; `opts.state` seeds
80
+ * `steps.<id>.output` / `trigger.event` so upstream references resolve
81
+ * instead of the empty string. `apiCalls` carries the outbound HTTP calls
82
+ * the action made (redacted); a failed invoke rejects with an error whose
83
+ * `.body` holds the same field (see `withApiErrorBody` below).
84
+ */
85
+ invokeAction(appId: string, actionKey: string, params: Record<string, unknown>, opts?: InvokeOptions): Promise<{
86
+ value: unknown;
87
+ logs?: string[];
88
+ apiCalls?: ApiCallRecord[];
89
+ }>;
90
+ /** List the saved action-test inputs stored against a connection. */
91
+ listSavedTests(connectionId: string): Promise<SavedTest[]>;
92
+ /** Save a new set of action-test inputs against a connection. */
93
+ createSavedTest(connectionId: string, body: {
94
+ actionKey: string;
95
+ name: string;
96
+ values: Record<string, unknown>;
97
+ }): Promise<SavedTest>;
98
+ /** Rename a saved test or replace its stored input values. */
99
+ updateSavedTest(connectionId: string, id: string, patch: {
100
+ name?: string;
101
+ values?: Record<string, unknown>;
102
+ }): Promise<SavedTest>;
103
+ /** Delete a saved test by id. */
104
+ deleteSavedTest(connectionId: string, id: string): Promise<void>;
105
+ /**
106
+ * Record the outcome of an action-test run against a connection. Appends a
107
+ * run-log row server-side; when `savedTestId` is present the saved test's
108
+ * `lastRun*` fields are updated too.
109
+ */
110
+ recordTestRun(connId: string, body: {
111
+ savedTestId?: string | null;
112
+ actionKey: string;
113
+ ok: boolean;
114
+ summary?: string;
115
+ result?: unknown;
116
+ }): Promise<void>;
117
+ /** List a connection's recent tester-run history from the unified run ledger. */
118
+ listTestRuns(connectionId: string): Promise<TestRunSummary[]>;
119
+ /**
120
+ * Save a reusable per-step test fixture against a workflow step. Captures
121
+ * the resolved incoming state (`input`) and the step's params (`with`).
122
+ */
123
+ saveStepTest(workflowId: string, stepId: string, body: {
124
+ name?: string;
125
+ input: Record<string, unknown>;
126
+ with: Record<string, unknown>;
127
+ }): Promise<StepTest>;
128
+ /**
129
+ * Record the outcome of a step-test run. When `stepTestId` is present, the
130
+ * fixture's `lastRun*` fields are updated too.
131
+ */
132
+ recordStepTestRun(workflowId: string, stepId: string, body: {
133
+ stepTestId?: string | null;
134
+ status: string;
135
+ input?: unknown;
136
+ output?: unknown;
137
+ error?: unknown;
138
+ }): Promise<void>;
139
+ /** List the saved test fixtures for a workflow step. */
140
+ listStepTests(workflowId: string, stepId: string): Promise<StepTest[]>;
141
+ }
142
+ /** Build a `W6wApi` implementation over an existing `W6wClient`. See this module's header. */
143
+ export declare function createW6wUiAdapter(client: W6wClient): W6wApi;
144
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * `createW6wUiAdapter` — a structurally-typed bridge from a `W6wClient` to
3
+ * `@w6w/ui`'s `W6wApi` contract (C-1, C-2).
4
+ *
5
+ * `W6wApi` below is a HAND-DUPLICATE of `packages/ui/src/provider.tsx:87-231` —
6
+ * transcribed by hand, never imported. `@w6w/ui` is `SEE LICENSE IN LICENSE`
7
+ * and unpublished; this lane is MIT, so no dependency edge to it may exist
8
+ * anywhere, not even a type-only one (C-1). The VALUE types the interface
9
+ * needs (`AppSummary`, `ActionDef`, `AuthDef`, `ApiCallRecord`, `SavedTest`,
10
+ * `TestRunSummary`, `StepTest`, `InvokeOptions`, `ConnectionSummary`) are NOT
11
+ * hand-duplicated — they are already exported from `@w6w/sdk`/`@w6w/sdk/console`
12
+ * and structurally compatible (`building-blocks.md` §3's "Type duplication"
13
+ * analysis). Two documented, harmless narrowings from that analysis:
14
+ * - `getAppActions`'s `ActionDef.params` (`ActionParam`, `@w6w/sdk/console`)
15
+ * carries 6 fields vs `@w6w/ui`'s 14 richer, presentation-only ones —
16
+ * typechecks fine, no runtime loss, no autocomplete for the extra optional
17
+ * fields. See README "Known limitations".
18
+ * - `listTestRuns` is REQUIRED here; `@w6w/ui`'s declaration marks it optional
19
+ * (`?`) only so a consumer that hasn't wired history yet still typechecks.
20
+ * Every consumer of THIS adapter gets a real implementation, so there is no
21
+ * reason to decline it — a required member still satisfies an interface
22
+ * that declares it optional.
23
+ *
24
+ * Every member here is a thin call into `client.console.*`, with two
25
+ * exceptions the SDK's own module headers document:
26
+ * - `listConnections` — see the comment at its call site below.
27
+ * - `recordTestRun` / `recordStepTestRun` — the SDK returns the real created
28
+ * row; `W6wApi` is pinned `Promise<void>`. Discarded with
29
+ * `.then(() => undefined)`, mirroring
30
+ * `packages/studio/src/repos/saved-tests.ts:97-109` and
31
+ * `step-tests.ts:46-59` (read-only reference, transcribed, never imported).
32
+ *
33
+ * `listApps` is a direct, one-line pass-through to `client.console.apps.list()`
34
+ * — that method already pages internally (`node/src/console/apps.ts:469-496`),
35
+ * so writing a second pagination loop here would be exactly the "third client
36
+ * for these routes" C-2 exists to prevent.
37
+ *
38
+ * @module
39
+ */
40
+ import { ApiError } from "@w6w/sdk";
41
+ /**
42
+ * Alias `@w6w/sdk`'s `ApiError.raw` onto `.body` (`err.body === err.raw`, not
43
+ * a copy) before an error reaches the caller — the field name every
44
+ * duck-typing consumer of `@w6w/ui`'s own `ApiError` shape expects
45
+ * (`packages/ui/src/createW6wApi.ts:29-44`). `ApiError.name` is already
46
+ * `"ApiError"` on `@w6w/sdk`'s own class (`node/src/errors.ts`); nothing to
47
+ * add there.
48
+ *
49
+ * Does **not**, and cannot, fix `ActionTestForm.tsx:149,176`'s NOMINAL
50
+ * `instanceof ApiError` check against `@w6w/ui`'s own class — no object built
51
+ * here can ever satisfy a check against a different class without importing
52
+ * `@w6w/ui`, which C-1 forbids. Filed as a `packages/ui` follow-up
53
+ * (`.ai/projects/backlog/26-08-13-01-ui-error-nominal-check.md`); see README
54
+ * "Known limitations".
55
+ *
56
+ * ONE shared helper, not reimplemented per member — every adapter call below
57
+ * routes through this.
58
+ */
59
+ async function withApiErrorBody(fn) {
60
+ try {
61
+ return await fn();
62
+ }
63
+ catch (err) {
64
+ if (err instanceof ApiError) {
65
+ err.body = err.raw;
66
+ }
67
+ throw err;
68
+ }
69
+ }
70
+ /** Build a `W6wApi` implementation over an existing `W6wClient`. See this module's header. */
71
+ export function createW6wUiAdapter(client) {
72
+ return {
73
+ listApps: () => withApiErrorBody(() => client.console.apps.list()),
74
+ getAppAuth: (appId) => withApiErrorBody(() => client.console.apps.getAuth(appId)),
75
+ createConnection: (appId, body) => withApiErrorBody(() => client.console.connections.create(appId, body)),
76
+ startAppOAuthFlow: (appId, authKey, body) => withApiErrorBody(() => client.console.apps.startOAuthFlow(appId, authKey, body)),
77
+ getAppActions: (appId) => withApiErrorBody(() => client.console.apps.getActions(appId)),
78
+ listConnectionsForApp: (appId) => withApiErrorBody(() => client.console.connections.listForApp(appId)),
79
+ // Deliberately the BASE `client.connections.list()`, never
80
+ // `console.connections` — there is no `console.connections.list()` at all
81
+ // (only `listForApp`, which is scoped to one app). Do not "fix" this into
82
+ // console-namespace consistency; that would silently narrow "every
83
+ // connection across every app" down to one app's connections.
84
+ listConnections: () => withApiErrorBody(() => client.connections.list()),
85
+ invokeAction: (appId, actionKey, params, opts) => withApiErrorBody(() => client.console.apps.invoke(appId, actionKey, params, opts)),
86
+ listSavedTests: (connectionId) => withApiErrorBody(() => client.console.savedTests.list(connectionId)),
87
+ createSavedTest: (connectionId, body) => withApiErrorBody(() => client.console.savedTests.create(connectionId, body)),
88
+ updateSavedTest: (connectionId, id, patch) => withApiErrorBody(() => client.console.savedTests.update(connectionId, id, patch)),
89
+ deleteSavedTest: (connectionId, id) => withApiErrorBody(() => client.console.savedTests.delete(connectionId, id)),
90
+ // The SDK returns the real created `SavedTestRun`; `W6wApi.recordTestRun`
91
+ // is pinned `Promise<void>` — discard, don't drop the call.
92
+ recordTestRun: (connId, body) => withApiErrorBody(() => client.console.savedTests.recordTestRun(connId, body).then(() => undefined)),
93
+ listTestRuns: (connectionId) => withApiErrorBody(() => client.console.savedTests.listTestRuns(connectionId)),
94
+ saveStepTest: (workflowId, stepId, body) => withApiErrorBody(() => client.console.stepTests.save(workflowId, stepId, body)),
95
+ // Same discard as `recordTestRun` above.
96
+ recordStepTestRun: (workflowId, stepId, body) => withApiErrorBody(() => client.console.stepTests.recordRun(workflowId, stepId, body).then(() => undefined)),
97
+ listStepTests: (workflowId, stepId) => withApiErrorBody(() => client.console.stepTests.list(workflowId, stepId)),
98
+ };
99
+ }
100
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The hook set — one small primitive underneath (`useAsync` / a private
3
+ * mutation primitive), every read/mutation hook a thin wrapper over
4
+ * `useW6wClient()`. No react-query or any other data-fetching dependency
5
+ * anywhere (`package.json` carries none — see README).
6
+ *
7
+ * Built only over the PUBLIC, non-`console` surface (`me`, `documents`,
8
+ * `vars`, `connections`, `workflows`, `run`) — `console.*` is studio-internal
9
+ * and unstable (see README), so no hook here reaches for it.
10
+ *
11
+ * Cancellation: `@w6w/sdk`'s transport has no `AbortSignal` to hook into
12
+ * (`node/src/http.ts`), so a read hook can only IGNORE a result that resolves
13
+ * after unmount (the `mountedRef` guard below), never truly abort the
14
+ * in-flight request. See README.
15
+ *
16
+ * @module
17
+ */
18
+ import type { ConnectionSummary, Doc, DocumentCreateInput, DocumentOptions, DocumentPatch, Me, RunEnvelope, RunInput, Var, VarCreateInput, VarPatch, WorkflowListOptions, WorkflowRunOptions, WorkflowRunResult, WorkflowSummary } from "@w6w/sdk";
19
+ /** What every read hook returns. */
20
+ export interface ReadResult<T> {
21
+ /** The last successfully fetched value, or `undefined` before the first resolves. */
22
+ data: T | undefined;
23
+ /** The error the last fetch rejected with, or `undefined`. */
24
+ error: unknown;
25
+ /** `true` while a fetch is in flight (including one triggered by `refetch`). */
26
+ loading: boolean;
27
+ /** Re-run the fetch imperatively. */
28
+ refetch: () => void;
29
+ }
30
+ /** What every mutation hook returns. */
31
+ export interface MutationResult<Args extends unknown[], T> {
32
+ /** Perform the mutation. Resolves with the result; rejects rather than swallowing an error. */
33
+ call: (...args: Args) => Promise<T>;
34
+ /** The last successful result, or `undefined`. */
35
+ data: T | undefined;
36
+ /** The error the last call rejected with, or `undefined`. */
37
+ error: unknown;
38
+ /** `true` while a call is in flight. */
39
+ loading: boolean;
40
+ }
41
+ export declare function useMe(): ReadResult<Me>;
42
+ export declare function useDocuments(options?: DocumentOptions): ReadResult<Doc[]>;
43
+ export declare function useDocument(id: string, options?: DocumentOptions): ReadResult<Doc>;
44
+ export declare function useDocumentByKey(key: string, options?: DocumentOptions): ReadResult<Doc>;
45
+ export declare function useVars(): ReadResult<Var[]>;
46
+ export declare function useVar(id: string): ReadResult<Var>;
47
+ export declare function useConnections(): ReadResult<ConnectionSummary[]>;
48
+ export declare function useWorkflows(options?: WorkflowListOptions): ReadResult<WorkflowSummary[]>;
49
+ export declare function useCreateDocument(): MutationResult<[DocumentCreateInput, DocumentOptions?], Doc>;
50
+ export declare function useUpdateDocument(): MutationResult<[
51
+ string,
52
+ DocumentPatch,
53
+ DocumentOptions?
54
+ ], Doc>;
55
+ export declare function useDeleteDocument(): MutationResult<[string, DocumentOptions?], void>;
56
+ export declare function useCreateVar(): MutationResult<[VarCreateInput], Var>;
57
+ export declare function useUpdateVar(): MutationResult<[string, VarPatch], Var>;
58
+ export declare function useDeleteVar(): MutationResult<[string], void>;
59
+ /**
60
+ * `wait` defaults to `true` when the caller's options omit it. `workflows.run`
61
+ * without `wait` (`node/src/workflows.ts`) leaves the caller with only a
62
+ * `runId` and no public polling operation to follow it with —
63
+ * `console.workflows.getRun` exists, but it is studio-internal and unstable
64
+ * (see README), so this hook does not reach for it. A caller that genuinely
65
+ * wants the queued-and-walk-away behaviour can still pass `wait: false`
66
+ * explicitly; the default only fills in what the caller left unstated.
67
+ */
68
+ export declare function useRunWorkflow(): MutationResult<[string, WorkflowRunOptions?], WorkflowRunResult>;
69
+ export declare function useRun(): MutationResult<[RunInput], RunEnvelope>;
70
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EACV,iBAAiB,EACjB,GAAG,EACH,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,EAAE,EACF,WAAW,EACX,QAAQ,EACR,GAAG,EACH,cAAc,EACd,QAAQ,EACR,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EAChB,MAAM,UAAU,CAAC;AAIlB,oCAAoC;AACpC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,qFAAqF;IACrF,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC;IACpB,8DAA8D;IAC9D,KAAK,EAAE,OAAO,CAAC;IACf,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,cAAc,CAAC,IAAI,SAAS,OAAO,EAAE,EAAE,CAAC;IACvD,+FAA+F;IAC/F,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IACpC,kDAAkD;IAClD,IAAI,EAAE,CAAC,GAAG,SAAS,CAAC;IACpB,6DAA6D;IAC7D,KAAK,EAAE,OAAO,CAAC;IACf,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;CAClB;AAmFD,wBAAgB,KAAK,IAAI,UAAU,CAAC,EAAE,CAAC,CAItC;AAED,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,CAQzE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,CAQlF;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC,GAAG,CAAC,CAQxF;AAED,wBAAgB,OAAO,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC,CAI3C;AAED,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAIlD;AAED,wBAAgB,cAAc,IAAI,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAIhE;AAED,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,UAAU,CAAC,eAAe,EAAE,CAAC,CAQzF;AAID,wBAAgB,iBAAiB,IAAI,cAAc,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC,EAAE,GAAG,CAAC,CAKhG;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CACjD;IAAC,MAAM;IAAE,aAAa;IAAE,eAAe,CAAC;CAAC,EACzC,GAAG,CACJ,CAKA;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAKpF;AAED,wBAAgB,YAAY,IAAI,cAAc,CAAC,CAAC,cAAc,CAAC,EAAE,GAAG,CAAC,CAGpE;AAED,wBAAgB,YAAY,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAGtE;AAED,wBAAgB,YAAY,IAAI,cAAc,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAG7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAAC,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAKjG;AAED,wBAAgB,MAAM,IAAI,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,CAGhE"}
@@ -0,0 +1,154 @@
1
+ import { useCallback, useEffect, useRef, useState } from "react";
2
+ import { useW6wClient } from "./W6wProvider.js";
3
+ /**
4
+ * Shared plumbing behind every read hook: fetch once on mount, expose
5
+ * `refetch` for an imperative re-fetch, and drop a result that resolves after
6
+ * unmount. `fetcher` must be a `useCallback`-stabilized function — each hook
7
+ * below owns that decision by listing exactly the values its own fetch
8
+ * depends on, so this primitive's own dependency array (`[fetcher]`) stays
9
+ * exhaustive and needs no lint override.
10
+ */
11
+ function useAsync(fetcher) {
12
+ const [state, setState] = useState({
13
+ data: undefined,
14
+ error: undefined,
15
+ loading: true,
16
+ });
17
+ const mountedRef = useRef(true);
18
+ useEffect(() => {
19
+ mountedRef.current = true;
20
+ return () => {
21
+ mountedRef.current = false;
22
+ };
23
+ }, []);
24
+ const refetch = useCallback(() => {
25
+ setState((s) => ({ ...s, loading: true }));
26
+ fetcher().then((data) => {
27
+ if (mountedRef.current)
28
+ setState({ data, error: undefined, loading: false });
29
+ }, (error) => {
30
+ if (mountedRef.current)
31
+ setState({ data: undefined, error, loading: false });
32
+ });
33
+ }, [fetcher]);
34
+ useEffect(() => {
35
+ refetch();
36
+ }, [refetch]);
37
+ return { data: state.data, error: state.error, loading: state.loading, refetch };
38
+ }
39
+ /**
40
+ * Shared plumbing behind every mutation hook: imperative only, no auto-fetch.
41
+ * `mutator` is read through a "latest" ref (updated every render, never a
42
+ * `useCallback` dependency) so `call`'s own identity stays stable across
43
+ * renders without ever invoking a stale closure.
44
+ */
45
+ function useMutationResource(mutator) {
46
+ const [state, setState] = useState({
47
+ data: undefined,
48
+ error: undefined,
49
+ loading: false,
50
+ });
51
+ const mutatorRef = useRef(mutator);
52
+ mutatorRef.current = mutator;
53
+ const call = useCallback(async (...args) => {
54
+ setState({ data: undefined, error: undefined, loading: true });
55
+ try {
56
+ const data = await mutatorRef.current(...args);
57
+ setState({ data, error: undefined, loading: false });
58
+ return data;
59
+ }
60
+ catch (error) {
61
+ setState({ data: undefined, error, loading: false });
62
+ throw error;
63
+ }
64
+ }, []);
65
+ return { call, data: state.data, error: state.error, loading: state.loading };
66
+ }
67
+ // ── reads ────────────────────────────────────────────────────────────────
68
+ export function useMe() {
69
+ const client = useW6wClient();
70
+ const fetcher = useCallback(() => client.me(), [client]);
71
+ return useAsync(fetcher);
72
+ }
73
+ export function useDocuments(options) {
74
+ const client = useW6wClient();
75
+ const project = options?.project;
76
+ const fetcher = useCallback(() => client.documents.list(project === undefined ? undefined : { project }), [client, project]);
77
+ return useAsync(fetcher);
78
+ }
79
+ export function useDocument(id, options) {
80
+ const client = useW6wClient();
81
+ const project = options?.project;
82
+ const fetcher = useCallback(() => client.documents.get(id, project === undefined ? undefined : { project }), [client, id, project]);
83
+ return useAsync(fetcher);
84
+ }
85
+ export function useDocumentByKey(key, options) {
86
+ const client = useW6wClient();
87
+ const project = options?.project;
88
+ const fetcher = useCallback(() => client.documents.getByKey(key, project === undefined ? undefined : { project }), [client, key, project]);
89
+ return useAsync(fetcher);
90
+ }
91
+ export function useVars() {
92
+ const client = useW6wClient();
93
+ const fetcher = useCallback(() => client.vars.list(), [client]);
94
+ return useAsync(fetcher);
95
+ }
96
+ export function useVar(id) {
97
+ const client = useW6wClient();
98
+ const fetcher = useCallback(() => client.vars.get(id), [client, id]);
99
+ return useAsync(fetcher);
100
+ }
101
+ export function useConnections() {
102
+ const client = useW6wClient();
103
+ const fetcher = useCallback(() => client.connections.list(), [client]);
104
+ return useAsync(fetcher);
105
+ }
106
+ export function useWorkflows(options) {
107
+ const client = useW6wClient();
108
+ const project = options?.project;
109
+ const fetcher = useCallback(() => client.workflows.list(project === undefined ? undefined : { project }), [client, project]);
110
+ return useAsync(fetcher);
111
+ }
112
+ // ── mutations ────────────────────────────────────────────────────────────
113
+ export function useCreateDocument() {
114
+ const client = useW6wClient();
115
+ return useMutationResource((input, options) => client.documents.create(input, options));
116
+ }
117
+ export function useUpdateDocument() {
118
+ const client = useW6wClient();
119
+ return useMutationResource((id, patch, options) => client.documents.update(id, patch, options));
120
+ }
121
+ export function useDeleteDocument() {
122
+ const client = useW6wClient();
123
+ return useMutationResource((id, options) => client.documents.delete(id, options));
124
+ }
125
+ export function useCreateVar() {
126
+ const client = useW6wClient();
127
+ return useMutationResource((input) => client.vars.create(input));
128
+ }
129
+ export function useUpdateVar() {
130
+ const client = useW6wClient();
131
+ return useMutationResource((id, patch) => client.vars.update(id, patch));
132
+ }
133
+ export function useDeleteVar() {
134
+ const client = useW6wClient();
135
+ return useMutationResource((id) => client.vars.delete(id));
136
+ }
137
+ /**
138
+ * `wait` defaults to `true` when the caller's options omit it. `workflows.run`
139
+ * without `wait` (`node/src/workflows.ts`) leaves the caller with only a
140
+ * `runId` and no public polling operation to follow it with —
141
+ * `console.workflows.getRun` exists, but it is studio-internal and unstable
142
+ * (see README), so this hook does not reach for it. A caller that genuinely
143
+ * wants the queued-and-walk-away behaviour can still pass `wait: false`
144
+ * explicitly; the default only fills in what the caller left unstated.
145
+ */
146
+ export function useRunWorkflow() {
147
+ const client = useW6wClient();
148
+ return useMutationResource((id, options) => client.workflows.run(id, { ...options, wait: options?.wait ?? true }));
149
+ }
150
+ export function useRun() {
151
+ const client = useW6wClient();
152
+ return useMutationResource((input) => client.run(input));
153
+ }
154
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The published version of this package.
3
+ *
4
+ * It is the same string as `package.json`'s `version` and the monorepo's
5
+ * `packages/wrappers/VERSION` — the single source of truth all three w6w
6
+ * wrappers publish under (see `docs/parity.md`); this lane joins the same
7
+ * lockstep. `src/__tests__/version.test.ts` fails if any of those disagree,
8
+ * so this constant cannot drift silently. (Only `package.json` and the shared
9
+ * `VERSION` file, not `deno.json` — this lane has none.)
10
+ *
11
+ * The explicit `: string` annotation is required, not decorative: it is not
12
+ * about JSR here (this lane never publishes there, see README) — the
13
+ * monorepo's `release.yml` `verify` step reads this exact file with a
14
+ * `from_regex` pattern (`VERSION:\s*string\s*=\s*"([^"]+)"`) to cross-check
15
+ * every wrapper's version in lockstep, and that pattern depends on the literal
16
+ * `: string` shape being present.
17
+ */
18
+ export declare const VERSION: string;
19
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,OAAO,EAAE,MAAgB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The published version of this package.
3
+ *
4
+ * It is the same string as `package.json`'s `version` and the monorepo's
5
+ * `packages/wrappers/VERSION` — the single source of truth all three w6w
6
+ * wrappers publish under (see `docs/parity.md`); this lane joins the same
7
+ * lockstep. `src/__tests__/version.test.ts` fails if any of those disagree,
8
+ * so this constant cannot drift silently. (Only `package.json` and the shared
9
+ * `VERSION` file, not `deno.json` — this lane has none.)
10
+ *
11
+ * The explicit `: string` annotation is required, not decorative: it is not
12
+ * about JSR here (this lane never publishes there, see README) — the
13
+ * monorepo's `release.yml` `verify` step reads this exact file with a
14
+ * `from_regex` pattern (`VERSION:\s*string\s*=\s*"([^"]+)"`) to cross-check
15
+ * every wrapper's version in lockstep, and that pattern depends on the literal
16
+ * `: string` shape being present.
17
+ */
18
+ export const VERSION = "0.4.0";
19
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAW,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@w6w/react",
3
+ "version": "0.4.0",
4
+ "description": "React bindings for @w6w/sdk — a <W6wProvider>, a small hook set, and a structural adapter for @w6w/ui's W6wApi contract.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/w6w-io/w6w-wrappers.git",
9
+ "directory": "react"
10
+ },
11
+ "homepage": "https://github.com/w6w-io/w6w-wrappers/tree/main/react#readme",
12
+ "bugs": "https://github.com/w6w-io/w6w-wrappers/issues",
13
+ "keywords": ["w6w", "workflow", "react", "sdk", "hooks"],
14
+ "type": "module",
15
+ "types": "./dist/mod.d.ts",
16
+ "main": "./dist/mod.js",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/mod.d.ts",
20
+ "import": "./dist/mod.js"
21
+ }
22
+ },
23
+ "files": ["dist"],
24
+ "sideEffects": false,
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "scripts": {
29
+ "build": "tsc -p tsconfig.json",
30
+ "typecheck": "tsc -p tsconfig.json --noEmit",
31
+ "test": "node --import ./src/test-jsx-loader.mjs --test src/__tests__/*.test.ts",
32
+ "lint": "biome check .",
33
+ "format": "biome format --write ."
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=18"
37
+ },
38
+ "dependencies": {
39
+ "@w6w/sdk": "^0.4.0"
40
+ },
41
+ "devDependencies": {
42
+ "@biomejs/biome": "^1.9.4",
43
+ "@types/react": "^18.3.17",
44
+ "jsdom": "^30.0.1",
45
+ "react": "^18.3.1",
46
+ "react-dom": "^18.3.1",
47
+ "typescript": "^5.7.2"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }