@w6w/embed 0.2.1 → 0.2.19

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.
Files changed (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,170 +1,207 @@
1
1
  "use client";
2
- import { jsx as i, jsxs as G } from "react/jsx-runtime";
3
- import { QueryClientProvider as M, QueryClient as H, useQuery as J } from "@tanstack/react-query";
4
- import { W6WProvider as L, useW6WClient as P, useW6WSession as N, createW6WUiAdapter as V } from "@w6w/react";
2
+ import { jsx as c, jsxs as N } from "react/jsx-runtime";
3
+ import { QueryClientProvider as O, QueryClient as G, useQuery as z } from "@tanstack/react-query";
4
+ import { W6WProvider as J, useW6WClient as P, useW6WSession as H, createW6WUiAdapter as V } from "@w6w/react";
5
5
  import { W6WUIProvider as X } from "@w6w/ui";
6
- import { useState as h, useRef as k, useEffect as j, useCallback as D, useMemo as C, useContext as Y, createContext as Z } from "react";
6
+ import { useState as j, useRef as T, useEffect as w, useCallback as R, useMemo as v, useContext as Y, createContext as Z } from "react";
7
7
  import { E as _ } from "./client-context-CX61Bgw-.js";
8
- import { c as $, D as ee } from "./draft-registry-YF0tqNN0.js";
9
- import { E as re } from "./project-context-BiCjv_E3.js";
10
- import { a as Ee } from "./project-context-BiCjv_E3.js";
11
- import { u as te } from "./connections-CjjYeRqb.js";
12
- class ne extends Error {
13
- constructor(t) {
14
- super("The w6w API rejected the embed session token (401).", { cause: t }), this.name = "EmbedAuthError";
8
+ import { c as ee, D as te } from "./draft-registry-YF0tqNN0.js";
9
+ import { E as re, a as oe } from "./project-context-Tvp-La7A.js";
10
+ import { b as Ne } from "./project-context-Tvp-La7A.js";
11
+ import { j as ne } from "./connections-CzsCyIxY.js";
12
+ import { x as se } from "./credentials-Cn92LGhJ.js";
13
+ import { e as ie, c as ue } from "./data-stores-UeQvwVCa.js";
14
+ import { r as ae } from "./fields-DvS8XZFc.js";
15
+ import { l as ce } from "./models-bAayQPJ_.js";
16
+ import { path as q } from "@w6w/sdk";
17
+ import { s as le, t as de, J as fe } from "./workflows-BZN4Hyz1.js";
18
+ import { E as pe } from "./theme-context-E2ZhlXDX.js";
19
+ class me extends Error {
20
+ constructor(s) {
21
+ super("The w6w API rejected the embed session token (401).", { cause: s }), this.name = "EmbedAuthError";
15
22
  }
16
23
  }
17
- function oe(r, t, e) {
24
+ function ye(n, s, e) {
18
25
  if (e) return { status: "error", error: e };
19
- switch (r) {
26
+ switch (n) {
20
27
  case "ready":
21
28
  case "renewing":
22
29
  return { status: "ready", error: null };
23
30
  case "error":
24
- return { status: "error", error: t };
31
+ return { status: "error", error: s };
25
32
  case "loading":
26
33
  case "expired":
27
34
  return { status: "connecting", error: null };
28
35
  }
29
36
  }
30
- function F() {
31
- return new H({
37
+ async function he(n, s) {
38
+ return (await n.request({
39
+ method: "POST",
40
+ path: q`/subscriptions/${s}/listen`,
41
+ body: {}
42
+ })).body;
43
+ }
44
+ async function be(n, s, e, i) {
45
+ return (await n.request({
46
+ method: "GET",
47
+ path: q`/subscriptions/${s}/listen/${e}`,
48
+ query: { wait: String((i == null ? void 0 : i.waitSeconds) ?? 0) },
49
+ signal: i == null ? void 0 : i.signal
50
+ })).body.session;
51
+ }
52
+ async function je(n, s, e) {
53
+ await n.request({
54
+ method: "DELETE",
55
+ path: q`/subscriptions/${s}/listen/${e}`
56
+ });
57
+ }
58
+ function I() {
59
+ return new G({
32
60
  defaultOptions: { queries: { retry: !1, refetchOnWindowFocus: !1 } }
33
61
  });
34
62
  }
35
- function se({ children: r }) {
36
- return /* @__PURE__ */ i(_, { client: P(), children: r });
63
+ function we({ children: n }) {
64
+ return /* @__PURE__ */ c(_, { client: P(), children: n });
37
65
  }
38
- function ue({ theme: r, children: t }) {
39
- const e = P(), d = C(() => {
40
- const n = V(e);
41
- return typeof n.updateConnection == "function" ? n : { ...n, updateConnection: (c, o) => te(e, c, o) };
42
- }, [e]);
43
- return /* @__PURE__ */ i(X, { api: d, theme: r, children: t });
66
+ function ve({ theme: n, children: s }) {
67
+ const e = P(), i = oe(), a = v(() => {
68
+ const t = V(e);
69
+ return typeof t.updateConnection != "function" && (t.updateConnection = (r, o) => ne(e, r, o)), se(t, e), typeof t.listModelRoutes != "function" && (t.listModelRoutes = async (r) => {
70
+ const o = r || i;
71
+ return o ? (await ce(e, o)).map((f) => ({ name: f.name, model: f.modelId, status: f.status })) : [];
72
+ }), typeof t.listDataStores != "function" && (t.listDataStores = async (r) => {
73
+ const o = r || i;
74
+ return o ? ie(e, o) : [];
75
+ }), typeof t.listDataStoreEntries != "function" && (t.listDataStoreEntries = async (r, o) => {
76
+ const u = o.project || i;
77
+ return u ? ue(e, u, r, o) : { items: [] };
78
+ }), typeof t.loadNodeSamples != "function" && (t.loadNodeSamples = (r) => le(e, r)), typeof t.loadTestInputs != "function" && (t.loadTestInputs = (r) => de(e, r)), typeof t.saveTestInput != "function" && (t.saveTestInput = (r, o, u) => fe(e, r, o, u)), typeof t.resolveActionFields != "function" && (t.resolveActionFields = (r, o, u, f) => ae(e, r, o, u, f)), typeof t.startWebhookListen != "function" && (t.startWebhookListen = (r) => he(e, r), t.pollWebhookListen = (r, o, u) => be(e, r, o, u), t.stopWebhookListen = (r, o) => je(e, r, o)), t;
79
+ }, [e, i]);
80
+ return /* @__PURE__ */ c(X, { api: a, theme: n, children: /* @__PURE__ */ c(pe.Provider, { value: n, children: s }) });
44
81
  }
45
- const U = Z({ status: "connecting", error: null });
46
- function Ce() {
47
- return Y(U);
82
+ const F = Z({ status: "connecting", error: null });
83
+ function $e() {
84
+ return Y(F);
48
85
  }
49
- function ie({
50
- eager: r,
51
- authError: t,
86
+ function Ee({
87
+ eager: n,
88
+ authError: s,
52
89
  onAcquire: e,
53
- children: d
90
+ children: i
54
91
  }) {
55
- const { status: n, error: c, refresh: o } = N();
56
- j(() => {
57
- r && o();
58
- }, [r, o]), j(() => {
59
- (n === "loading" || n === "renewing") && e();
60
- }, [n, e]);
61
- const l = C(
62
- () => oe(n, c, t),
63
- [n, c, t]
92
+ const { status: a, error: t, refresh: r } = H();
93
+ w(() => {
94
+ n && r();
95
+ }, [n, r]), w(() => {
96
+ (a === "loading" || a === "renewing") && e();
97
+ }, [a, e]);
98
+ const o = v(
99
+ () => ye(a, t, s),
100
+ [a, t, s]
64
101
  );
65
- return /* @__PURE__ */ i(U.Provider, { value: l, children: d });
102
+ return /* @__PURE__ */ c(F.Provider, { value: o, children: i });
66
103
  }
67
- function ce({
68
- identityKey: r,
69
- enabled: t,
104
+ function Ce({
105
+ identityKey: n,
106
+ enabled: s,
70
107
  onState: e
71
108
  }) {
72
- const d = P(), n = J({
109
+ const i = P(), a = z({
73
110
  queryKey: ["w6w-embed", "default-project"],
74
- enabled: t,
111
+ enabled: s,
75
112
  queryFn: async () => {
76
- const p = (await d.projects.list()).find((s) => s.isDefault === !0);
77
- if (!p) throw new Error("The account has no default project.");
78
- return p.id;
113
+ const y = (await i.projects.list()).find((l) => l.isDefault === !0);
114
+ if (!y) throw new Error("The account has no default project.");
115
+ return y.id;
79
116
  }
80
- }), { isError: c, error: o, data: l } = n, w = C(
81
- () => c ? { project: null, status: "error", error: o } : l !== void 0 ? { project: l, status: "ready" } : { project: null, status: "resolving" },
82
- [c, o, l]
117
+ }), { isError: t, error: r, data: o } = a, u = v(
118
+ () => t ? { project: null, status: "error", error: r } : o !== void 0 ? { project: o, status: "ready" } : { project: null, status: "resolving" },
119
+ [t, r, o]
83
120
  );
84
- return j(() => {
85
- e(r, w);
86
- }, [r, w, e]), null;
121
+ return w(() => {
122
+ e(n, u);
123
+ }, [n, u, e]), null;
87
124
  }
88
- function we({
89
- apiOrigin: r,
90
- getSession: t,
125
+ function Ke({
126
+ apiOrigin: n,
127
+ getSession: s,
91
128
  identityKey: e,
92
- fallback: d = null,
93
- eager: n = !1,
94
- theme: c,
95
- ready: o,
96
- project: l,
97
- fetch: w,
98
- children: q
129
+ fallback: i = null,
130
+ eager: a = !1,
131
+ theme: t,
132
+ ready: r,
133
+ project: o,
134
+ fetch: u,
135
+ children: f
99
136
  }) {
100
- const [p] = h($), [s, K] = h(() => ({
137
+ const [y] = j(ee), [l, L] = j(() => ({
101
138
  identityKey: e,
102
- queryClient: F()
103
- })), Q = e !== s.identityKey, x = k({ apiOrigin: r, project: l, getSession: t });
104
- Q || (x.current = { apiOrigin: r, project: l, getSession: t });
105
- const b = x.current, A = k(b.getSession);
106
- A.current = b.getSession;
107
- const [B] = h(() => () => A.current());
108
- j(() => {
109
- if (e === s.identityKey) return;
110
- let a = !1;
111
- const u = () => {
112
- a || K({ identityKey: e, queryClient: F() });
139
+ queryClient: I()
140
+ })), M = e !== l.identityKey, k = T({ apiOrigin: n, project: o, getSession: s });
141
+ M || (k.current = { apiOrigin: n, project: o, getSession: s });
142
+ const E = k.current, A = T(E.getSession);
143
+ A.current = E.getSession;
144
+ const [U] = j(() => () => A.current());
145
+ w(() => {
146
+ if (e === l.identityKey) return;
147
+ let p = !1;
148
+ const d = () => {
149
+ p || L({ identityKey: e, queryClient: I() });
113
150
  };
114
- return s.identityKey === null ? (u(), () => {
115
- a = !0;
116
- }) : (p.flushAll().then(u, u), () => {
117
- a = !0;
151
+ return l.identityKey === null ? (d(), () => {
152
+ p = !0;
153
+ }) : (y.flushAll().then(d, d), () => {
154
+ p = !0;
118
155
  });
119
- }, [e, s.identityKey, p]);
120
- const g = s.queryClient;
121
- j(() => () => g.clear(), [g]);
122
- const [E, I] = h(null), O = D((a, u) => {
123
- I(
124
- (m) => m && m.key === a && m.state.project === u.project && m.state.status === u.status && m.state.error === u.error ? m : { key: a, state: u }
156
+ }, [e, l.identityKey, y]);
157
+ const C = l.queryClient;
158
+ w(() => () => C.clear(), [C]);
159
+ const [S, $] = j(null), K = R((p, d) => {
160
+ $(
161
+ (b) => b && b.key === p && b.state.project === d.project && b.state.status === d.status && b.state.error === d.error ? b : { key: p, state: d }
125
162
  );
126
- }, []), [v, S] = h(null), T = C(() => {
127
- const a = s.queryClient;
128
- return (u) => {
129
- S({ key: a, error: new ne(u) });
163
+ }, []), [g, D] = j(null), Q = v(() => {
164
+ const p = l.queryClient;
165
+ return (d) => {
166
+ D({ key: p, error: new me(d) });
130
167
  };
131
- }, [s.queryClient]), z = D(() => S(null), []), y = s.identityKey, f = b.project, W = typeof f == "object" && f !== null && !Array.isArray(f) && f.use === "default", R = C(() => typeof f == "string" ? { project: f, status: "ready" } : W ? E && E.key === y ? E.state : { project: null, status: "resolving" } : { project: null, status: "ready" }, [f, W, E, y]);
132
- return y === null ? d : /* @__PURE__ */ i(ee, { registry: p, children: /* @__PURE__ */ i(M, { client: g, children: /* @__PURE__ */ G(
133
- L,
168
+ }, [l.queryClient]), B = R(() => D(null), []), h = l.identityKey, m = E.project, W = typeof m == "object" && m !== null && !Array.isArray(m) && m.use === "default", x = v(() => typeof m == "string" ? { project: m, status: "ready" } : W ? S && S.key === h ? S.state : { project: null, status: "resolving" } : { project: null, status: "ready" }, [m, W, S, h]);
169
+ return h === null ? i : /* @__PURE__ */ c(te, { registry: y, children: /* @__PURE__ */ c(O, { client: C, children: /* @__PURE__ */ N(
170
+ J,
134
171
  {
135
- baseUrl: b.apiOrigin,
136
- getSession: B,
137
- identityKey: y,
138
- ready: o,
139
- project: R.project ?? void 0,
140
- fetch: w,
141
- onUnauthorized: T,
172
+ baseUrl: E.apiOrigin,
173
+ getSession: U,
174
+ identityKey: h,
175
+ ready: r,
176
+ project: x.project ?? void 0,
177
+ fetch: u,
178
+ onUnauthorized: Q,
142
179
  children: [
143
- W ? /* @__PURE__ */ i(
144
- ce,
180
+ W ? /* @__PURE__ */ c(
181
+ Ce,
145
182
  {
146
- identityKey: y,
147
- enabled: o !== !1,
148
- onState: O
183
+ identityKey: h,
184
+ enabled: r !== !1,
185
+ onState: K
149
186
  }
150
187
  ) : null,
151
- /* @__PURE__ */ i(re.Provider, { value: R, children: /* @__PURE__ */ i(
152
- ie,
188
+ /* @__PURE__ */ c(re.Provider, { value: x, children: /* @__PURE__ */ c(
189
+ Ee,
153
190
  {
154
- eager: n,
155
- authError: v && v.key === g ? v.error : null,
156
- onAcquire: z,
157
- children: /* @__PURE__ */ i(se, { children: /* @__PURE__ */ i(ue, { theme: c, children: q }) })
191
+ eager: a,
192
+ authError: g && g.key === C ? g.error : null,
193
+ onAcquire: B,
194
+ children: /* @__PURE__ */ c(we, { children: /* @__PURE__ */ c(ve, { theme: t, children: f }) })
158
195
  }
159
196
  ) })
160
197
  ]
161
198
  }
162
- ) }, y) });
199
+ ) }, h) });
163
200
  }
164
201
  export {
165
- ne as EmbedAuthError,
166
- we as W6WEmbedProvider,
167
- Ee as useEmbedProject,
168
- Ce as useEmbedStatus
202
+ me as EmbedAuthError,
203
+ Ke as W6WEmbedProvider,
204
+ Ne as useEmbedProject,
205
+ $e as useEmbedStatus
169
206
  };
170
207
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/embed-status.ts","../src/W6WEmbedProvider.tsx"],"sourcesContent":["/**\n * The embed's public session status, as a pure total function over the `@w6w/react` session\n * store's status plus whether a terminal partner-token 401 has been seen. No React here, so\n * `node:test` covers it exhaustively.\n */\nimport type { W6WSessionStatus } from \"@w6w/react\";\n\nexport type EmbedStatusValue = \"connecting\" | \"ready\" | \"error\";\n\nexport interface EmbedStatus {\n status: EmbedStatusValue;\n /** `EmbedAuthError` for a terminal 401, else the session store's own error; `null` otherwise. */\n error: unknown;\n}\n\n/**\n * The terminal partner-token 401: the host's `getSession` minted a token the API refused, and a\n * renewal did not fix it. `cause` is the SDK `ApiError`.\n */\nexport class EmbedAuthError extends Error {\n constructor(cause: unknown) {\n super(\"The w6w API rejected the embed session token (401).\", { cause });\n this.name = \"EmbedAuthError\";\n }\n}\n\n/**\n * `loading -> connecting`, `ready|renewing -> ready`, `expired -> connecting` (the provider\n * re-acquires), `error -> error`. A seen 401 wins over everything: it is `error` with the\n * `EmbedAuthError`, whatever the store currently says.\n */\nexport function deriveEmbedStatus(\n sessionStatus: W6WSessionStatus,\n sessionError: unknown,\n authError: EmbedAuthError | null,\n): EmbedStatus {\n if (authError) return { status: \"error\", error: authError };\n switch (sessionStatus) {\n case \"ready\":\n case \"renewing\":\n return { status: \"ready\", error: null };\n case \"error\":\n return { status: \"error\", error: sessionError };\n case \"loading\":\n case \"expired\":\n return { status: \"connecting\", error: null };\n }\n}\n","import { QueryClient, QueryClientProvider, useQuery } from \"@tanstack/react-query\";\n/**\n * `<W6WEmbedProvider>` — everything an embedded w6w surface needs from a host, behind one\n * element: an identity-scoped `QueryClient`, a `@w6w/react` `<W6WProvider>` (client, session\n * renewal, per-request token) and `@w6w/ui`'s `<W6WUIProvider>` fed by `createW6WUiAdapter`.\n * It composes the three public pieces exactly as `@w6w/react`'s README bridge does: it never\n * spreads or patches the adapter, never reaches into `client.console`, and keeps no session\n * store of its own (`getSession` goes straight to `<W6WProvider>`).\n *\n * **Identity cache.** The `QueryClient` is owned here, not borrowed from the host, and it is a\n * NEW instance whenever `identityKey` changes — so a query cached while signed in as account A\n * is unreachable once the host switches to B. A new client alone is NOT enough: a mounted\n * `useQuery` keeps the `QueryObserver` it was born with, and that observer is bound to the client\n * it was created against, so a child that survives the swap would keep rendering A's cache. The\n * subtree is therefore also re-mounted (`key`), which drops every observer and every piece of\n * child state from the previous identity. The client, the `key` and the tuple handed to\n * `<W6WProvider>` all change in ONE state update: there is no render in which B's tree reads A's\n * cache. The old client is cleared once it is no longer mounted.\n *\n * **Identity switch (flush first).** A draft with a pending save must be written into the account\n * that produced the edit. When `identityKey` changes this provider therefore HOLDS the applied\n * tuple — `identityKey`, `apiOrigin`, `project`, `getSession`, the client — and keeps handing the\n * OLD one to `<W6WProvider>`, awaits `registry.flushAll()` (bounded, never rejects), and only then\n * applies the new tuple in a single update. `<W6WProvider>` swaps its client synchronously on a\n * new `identityKey` and detaches the old session store, so the flush must finish first; and the\n * new `getSession` is NOT forwarded early: `<W6WProvider>` reaches it through the stable wrapper\n * below, whose target is swapped in the same update as the tuple (forwarded early, the new\n * account's token would be minted on the old client). A flush that fails or times out still lets\n * the switch proceed (Q6) and is never retried with the new identity. A token rotation under an\n * unchanged `identityKey` is not a switch: it is forwarded at once, no hold.\n *\n * **No identity.** `identityKey={null}` mounts nothing but `fallback`: no `<W6WProvider>`, no\n * `QueryClientProvider`, no children — so no `getSession` call and no request. `null -> \"A\"`\n * applies at once (nothing can be pending); `\"A\" -> null` takes the SAME flush-first path as any\n * other switch before the fallback renders.\n *\n * **Default project.** `project={{ use: \"default\" }}` resolves ONCE per applied identity, through\n * one `client.projects.list()` query inside the identity-scoped `QueryClient`, to the row with\n * `isDefault === true` — never `list[0]`, never a fallback. `<W6WProvider>` gets no project until\n * it resolves; the client rebuild that follows reuses the cached answer (the query is keyed\n * without the client and lives in a component that stays mounted, so it is not re-issued).\n *\n * **Status.** `useEmbedStatus()` is `deriveEmbedStatus` over the `@w6w/react` session store plus a\n * terminal 401 seen through the forwarded `onUnauthorized`.\n */\nimport {\n W6WProvider,\n type W6WSession,\n createW6WUiAdapter,\n useW6WClient,\n useW6WSession,\n} from \"@w6w/react\";\nimport type { ApiError, FetchLike } from \"@w6w/sdk\";\nimport { type ThemeMode, type W6WApi, W6WUIProvider } from \"@w6w/ui\";\nimport {\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DraftRegistryProvider, EmbedClientProvider, createDraftRegistry } from \"./draft/index.ts\";\nimport { EmbedAuthError, type EmbedStatus, deriveEmbedStatus } from \"./embed-status.ts\";\nimport { EmbedProjectContext, type EmbedProjectState } from \"./project-context.ts\";\nimport { updateConnection } from \"./repos/connections.ts\";\n\nexport interface W6WEmbedProviderProps {\n /** The w6w API origin, e.g. `\"https://api.w6w.io\"`. */\n apiOrigin: string;\n /**\n * Mints a session for the CURRENT host user (`{token, expiresAt, expiresIn?}`). Always the\n * latest callback; the provider caches and renews the result.\n */\n getSession: () => Promise<W6WSession>;\n /**\n * Which signed-in identity this provider speaks for (e.g. `${userId}:${accountId}`). Changing it\n * rebuilds the API client AND replaces the `QueryClient`, so nothing cached for the previous\n * identity is ever shown under the new one.\n */\n identityKey: string | null;\n /**\n * Rendered instead of the embed while `identityKey` is `null` (no signed-in user). Nothing of\n * the embed mounts then: no `getSession` call, no request. Default `null`.\n */\n fallback?: ReactNode;\n /**\n * Start acquiring a session on mount. Without it the session is acquired lazily, by the first\n * request a mounted surface makes, and `useEmbedStatus()` stays `\"connecting\"` until then.\n */\n eager?: boolean;\n /** Force the `@w6w/ui` theme to follow the host's. Omit to resolve it the library's default way. */\n theme?: ThemeMode;\n /** Gates every read hook while `false` (default `true`) — e.g. until the host has a user. */\n ready?: boolean;\n /**\n * Default project for project-scoped operations: a project id, or `{ use: \"default\" }` to use\n * the account's default project (resolved once per identity; see `useEmbedProject()`).\n */\n project?: string | { use: \"default\" };\n /** Transport override (tests, request recording). Defaults to `globalThis.fetch`. */\n fetch?: FetchLike;\n children: ReactNode;\n}\n\nfunction makeQueryClient(): QueryClient {\n // Same defaults as Studio's own client (`studio/src/main.tsx`).\n return new QueryClient({\n defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } },\n });\n}\n\n/** The part of the tuple that changes only when a switch has been APPLIED (after the flush). */\ninterface Applied {\n identityKey: string | null;\n queryClient: QueryClient;\n}\n\n/** What `<W6WProvider>` is fed while no switch is in progress; frozen at the last such render. */\ninterface Forwarded {\n apiOrigin: string;\n project: string | { use: \"default\" } | undefined;\n getSession: () => Promise<W6WSession>;\n}\n\n/** Hands the SDK client of the nearest `<W6WProvider>` to `useWorkflowDraft`. */\nfunction ClientBridge({ children }: { children: ReactNode }) {\n return <EmbedClientProvider client={useW6WClient()}>{children}</EmbedClientProvider>;\n}\n\n/** The README bridge: `useW6WClient` -> `createW6WUiAdapter` -> `<W6WUIProvider>`. */\nfunction UiBridge({ theme, children }: { theme?: ThemeMode; children: ReactNode }) {\n const client = useW6WClient();\n // `createW6WUiAdapter` has no `updateConnection`; keep one if it ever gains it, else supply the\n // embed repo's write so the ui Edit modal can save.\n const api = useMemo(() => {\n const base: W6WApi = createW6WUiAdapter(client);\n if (typeof base.updateConnection === \"function\") return base;\n return { ...base, updateConnection: (id, body) => updateConnection(client, id, body) };\n }, [client]);\n return (\n <W6WUIProvider api={api} theme={theme}>\n {children}\n </W6WUIProvider>\n );\n}\n\nconst EmbedStatusContext = createContext<EmbedStatus>({ status: \"connecting\", error: null });\n\n/** The session status of the nearest `<W6WEmbedProvider>`. See `deriveEmbedStatus`. */\nexport function useEmbedStatus(): EmbedStatus {\n return useContext(EmbedStatusContext);\n}\n\n/** Publishes `useEmbedStatus()`, and starts the session on mount when `eager`. */\nfunction StatusBridge({\n eager,\n authError,\n onAcquire,\n children,\n}: {\n eager: boolean;\n authError: EmbedAuthError | null;\n onAcquire: () => void;\n children: ReactNode;\n}) {\n const { status, error, refresh } = useW6WSession();\n // `refresh` is per session store, so a rebuilt client (project resolved) is started again.\n useEffect(() => {\n if (eager) void refresh();\n }, [eager, refresh]);\n useEffect(() => {\n if (status === \"loading\" || status === \"renewing\") onAcquire();\n }, [status, onAcquire]);\n const value = useMemo(\n () => deriveEmbedStatus(status, error, authError),\n [status, error, authError],\n );\n return <EmbedStatusContext.Provider value={value}>{children}</EmbedStatusContext.Provider>;\n}\n\n/**\n * Resolves `{use:\"default\"}`. Lives INSIDE `<W6WProvider>` (it needs the client) but at a fixed\n * slot, so it survives the client rebuild that follows resolution; the query key carries no\n * client, so nothing refetches.\n */\nfunction DefaultProjectResolver({\n identityKey,\n enabled,\n onState,\n}: {\n identityKey: string;\n enabled: boolean;\n onState: (key: string, state: EmbedProjectState) => void;\n}) {\n const client = useW6WClient();\n const q = useQuery({\n queryKey: [\"w6w-embed\", \"default-project\"],\n enabled,\n queryFn: async () => {\n const rows = await client.projects.list();\n const home = rows.find((p) => p.isDefault === true);\n if (!home) throw new Error(\"The account has no default project.\");\n return home.id;\n },\n });\n const { isError, error, data } = q;\n const state = useMemo<EmbedProjectState>(\n () =>\n isError\n ? { project: null, status: \"error\", error }\n : data !== undefined\n ? { project: data, status: \"ready\" }\n : { project: null, status: \"resolving\" },\n [isError, error, data],\n );\n useEffect(() => {\n onState(identityKey, state);\n }, [identityKey, state, onState]);\n return null;\n}\n\nexport function W6WEmbedProvider({\n apiOrigin,\n getSession,\n identityKey,\n fallback = null,\n eager = false,\n theme,\n ready,\n project,\n fetch,\n children,\n}: W6WEmbedProviderProps): ReactNode {\n const [registry] = useState(createDraftRegistry);\n const [applied, setApplied] = useState<Applied>(() => ({\n identityKey,\n queryClient: makeQueryClient(),\n }));\n\n // While `identityKey` differs from the applied one a switch is pending: everything below keeps\n // using the values frozen at the last render that was not pending. Otherwise props flow straight\n // through (project / origin changes, token rotation). Idempotent latest-value writes, the same\n // pattern `<W6WProvider>` uses for its own refs.\n const switching = identityKey !== applied.identityKey;\n const forwardedRef = useRef<Forwarded>({ apiOrigin, project, getSession });\n if (!switching) forwardedRef.current = { apiOrigin, project, getSession };\n const forwarded = forwardedRef.current;\n\n // The stable `getSession` handed to `<W6WProvider>`: reads whatever is applied RIGHT NOW. Its\n // target changes in the same render that applies the new tuple, never before the flush settles.\n const sessionRef = useRef(forwarded.getSession);\n sessionRef.current = forwarded.getSession;\n const [stableGetSession] = useState(() => () => sessionRef.current());\n\n useEffect(() => {\n if (identityKey === applied.identityKey) return;\n let cancelled = false;\n const apply = () => {\n if (cancelled) return;\n setApplied({ identityKey, queryClient: makeQueryClient() });\n };\n // Nothing is mounted under a null identity, so nothing can be pending: apply at once.\n if (applied.identityKey === null) {\n apply();\n return () => {\n cancelled = true;\n };\n }\n // `flushAll` never rejects and is bounded; the switch proceeds either way (Q6).\n registry.flushAll().then(apply, apply);\n return () => {\n cancelled = true;\n };\n }, [identityKey, applied.identityKey, registry]);\n\n // The replaced client is dropped once nothing mounted reads it.\n const queryClient = applied.queryClient;\n useEffect(() => () => queryClient.clear(), [queryClient]);\n\n // Default-project resolution, tagged with the identity it was resolved for: a result for A is\n // never read once B is applied.\n const [resolved, setResolved] = useState<{ key: string; state: EmbedProjectState } | null>(null);\n const onResolved = useCallback((key: string, state: EmbedProjectState) => {\n setResolved((prev) =>\n prev &&\n prev.key === key &&\n prev.state.project === state.project &&\n prev.state.status === state.status &&\n prev.state.error === state.error\n ? prev\n : { key, state },\n );\n }, []);\n\n // The terminal partner-token 401, tagged with its identity; cleared when the next acquisition\n // starts (StatusBridge) or the identity changes (the tag no longer matches).\n const [authFailure, setAuthFailure] = useState<{\n key: QueryClient;\n error: EmbedAuthError;\n } | null>(null);\n // The handler is bound to the per-mount client it was created for: a late 401 from a previous\n // `<W6WProvider>` is tagged with ITS client, never the one applied by the time it fires — even\n // when the identity key came back (A -> B -> A mints a new client for the same key).\n const onUnauthorized = useMemo(() => {\n const key = applied.queryClient;\n return (error: ApiError) => {\n setAuthFailure({ key, error: new EmbedAuthError(error) });\n };\n }, [applied.queryClient]);\n const clearAuthFailure = useCallback(() => setAuthFailure(null), []);\n\n const appliedKey = applied.identityKey;\n const spec = forwarded.project;\n // Only exactly `{ use: \"default\" }` asks for the account default; null, `{}`, `[]` or any other\n // object (JS hosts, casts) is \"no project\" and makes no lookup.\n const wantsDefault =\n typeof spec === \"object\" && spec !== null && !Array.isArray(spec) && spec.use === \"default\";\n const projectState: EmbedProjectState = useMemo(() => {\n if (typeof spec === \"string\") return { project: spec, status: \"ready\" };\n if (!wantsDefault) return { project: null, status: \"ready\" };\n return resolved && resolved.key === appliedKey\n ? resolved.state\n : { project: null, status: \"resolving\" };\n }, [spec, wantsDefault, resolved, appliedKey]);\n\n if (appliedKey === null) return fallback;\n\n return (\n <DraftRegistryProvider registry={registry}>\n <QueryClientProvider key={appliedKey} client={queryClient}>\n <W6WProvider\n baseUrl={forwarded.apiOrigin}\n getSession={stableGetSession}\n identityKey={appliedKey}\n ready={ready}\n project={projectState.project ?? undefined}\n fetch={fetch}\n onUnauthorized={onUnauthorized}\n >\n {wantsDefault ? (\n <DefaultProjectResolver\n identityKey={appliedKey}\n enabled={ready !== false}\n onState={onResolved}\n />\n ) : null}\n <EmbedProjectContext.Provider value={projectState}>\n <StatusBridge\n eager={eager}\n authError={authFailure && authFailure.key === queryClient ? authFailure.error : null}\n onAcquire={clearAuthFailure}\n >\n <ClientBridge>\n <UiBridge theme={theme}>{children}</UiBridge>\n </ClientBridge>\n </StatusBridge>\n </EmbedProjectContext.Provider>\n </W6WProvider>\n </QueryClientProvider>\n </DraftRegistryProvider>\n );\n}\n"],"names":["EmbedAuthError","cause","deriveEmbedStatus","sessionStatus","sessionError","authError","makeQueryClient","QueryClient","ClientBridge","children","jsx","EmbedClientProvider","useW6WClient","UiBridge","theme","client","api","useMemo","base","createW6WUiAdapter","id","body","updateConnection","W6WUIProvider","EmbedStatusContext","createContext","useEmbedStatus","useContext","StatusBridge","eager","onAcquire","status","error","refresh","useW6WSession","useEffect","value","DefaultProjectResolver","identityKey","enabled","onState","q","useQuery","home","p","isError","data","state","W6WEmbedProvider","apiOrigin","getSession","fallback","ready","project","fetch","registry","useState","createDraftRegistry","applied","setApplied","switching","forwardedRef","useRef","forwarded","sessionRef","stableGetSession","cancelled","apply","queryClient","resolved","setResolved","onResolved","useCallback","key","prev","authFailure","setAuthFailure","onUnauthorized","clearAuthFailure","appliedKey","spec","wantsDefault","projectState","DraftRegistryProvider","QueryClientProvider","jsxs","W6WProvider","EmbedProjectContext"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/embed-status.ts","../src/repos/webhook-listen.ts","../src/W6WEmbedProvider.tsx"],"sourcesContent":["/**\n * The embed's public session status, as a pure total function over the `@w6w/react` session\n * store's status plus whether a terminal partner-token 401 has been seen. No React here, so\n * `node:test` covers it exhaustively.\n */\nimport type { W6WSessionStatus } from \"@w6w/react\";\n\nexport type EmbedStatusValue = \"connecting\" | \"ready\" | \"error\";\n\nexport interface EmbedStatus {\n status: EmbedStatusValue;\n /** `EmbedAuthError` for a terminal 401, else the session store's own error; `null` otherwise. */\n error: unknown;\n}\n\n/**\n * The terminal partner-token 401: the host's `getSession` minted a token the API refused, and a\n * renewal did not fix it. `cause` is the SDK `ApiError`.\n */\nexport class EmbedAuthError extends Error {\n constructor(cause: unknown) {\n super(\"The w6w API rejected the embed session token (401).\", { cause });\n this.name = \"EmbedAuthError\";\n }\n}\n\n/**\n * `loading -> connecting`, `ready|renewing -> ready`, `expired -> connecting` (the provider\n * re-acquires), `error -> error`. A seen 401 wins over everything: it is `error` with the\n * `EmbedAuthError`, whatever the store currently says.\n */\nexport function deriveEmbedStatus(\n sessionStatus: W6WSessionStatus,\n sessionError: unknown,\n authError: EmbedAuthError | null,\n): EmbedStatus {\n if (authError) return { status: \"error\", error: authError };\n switch (sessionStatus) {\n case \"ready\":\n case \"renewing\":\n return { status: \"ready\", error: null };\n case \"error\":\n return { status: \"error\", error: sessionError };\n case \"loading\":\n case \"expired\":\n return { status: \"connecting\", error: null };\n }\n}\n","import type { W6WClient } from \"@w6w/sdk\";\nimport { path } from \"@w6w/sdk\";\n/**\n * \"Listen for test event\" on a `@w6w/webhook` subscription — `/subscriptions/:id/listen` over\n * `client.request()`. Not in the SDK's stable contract (Studio reaches it the same way, its\n * `repos/subscriptions.ts`), and `createW6WUiAdapter` carries none of it, so without these the\n * embedded editor's webhook Test tab fell back to the paste-a-payload form.\n */\n\n/**\n * Structural mirror of ui's `WebhookListenSession` (this barrel may not import `@w6w/ui`); the\n * UiBridge assignment typechecks against W6WApi structurally.\n */\nexport interface WebhookListenSession {\n id: string;\n subscriptionId: string;\n nodeId: string | null;\n expiresAt: string;\n status: \"waiting\" | \"captured\" | \"expired\";\n request?: {\n method: string;\n path: string;\n query: Record<string, string>;\n headers: Record<string, string>;\n body: unknown;\n };\n receivedAt?: string;\n}\n\nexport async function startWebhookListen(\n client: W6WClient,\n subscriptionId: string,\n): Promise<{ session: WebhookListenSession; webhookUrl: string }> {\n const res = await client.request<{ session: WebhookListenSession; webhookUrl: string }>({\n method: \"POST\",\n path: path`/subscriptions/${subscriptionId}/listen`,\n body: {},\n });\n return res.body;\n}\n\nexport async function pollWebhookListen(\n client: W6WClient,\n subscriptionId: string,\n sessionId: string,\n opts?: { waitSeconds?: number; signal?: AbortSignal },\n): Promise<WebhookListenSession> {\n const res = await client.request<{ session: WebhookListenSession }>({\n method: \"GET\",\n path: path`/subscriptions/${subscriptionId}/listen/${sessionId}`,\n query: { wait: String(opts?.waitSeconds ?? 0) },\n signal: opts?.signal,\n });\n return res.body.session;\n}\n\nexport async function stopWebhookListen(\n client: W6WClient,\n subscriptionId: string,\n sessionId: string,\n): Promise<void> {\n await client.request<unknown>({\n method: \"DELETE\",\n path: path`/subscriptions/${subscriptionId}/listen/${sessionId}`,\n });\n}\n","import { QueryClient, QueryClientProvider, useQuery } from \"@tanstack/react-query\";\n/**\n * `<W6WEmbedProvider>` — everything an embedded w6w surface needs from a host, behind one\n * element: an identity-scoped `QueryClient`, a `@w6w/react` `<W6WProvider>` (client, session\n * renewal, per-request token) and `@w6w/ui`'s `<W6WUIProvider>` fed by `createW6WUiAdapter`.\n * It composes the three public pieces exactly as `@w6w/react`'s README bridge does: it never\n * spreads or patches the adapter, never reaches into `client.console`, and keeps no session\n * store of its own (`getSession` goes straight to `<W6WProvider>`).\n *\n * **Identity cache.** The `QueryClient` is owned here, not borrowed from the host, and it is a\n * NEW instance whenever `identityKey` changes — so a query cached while signed in as account A\n * is unreachable once the host switches to B. A new client alone is NOT enough: a mounted\n * `useQuery` keeps the `QueryObserver` it was born with, and that observer is bound to the client\n * it was created against, so a child that survives the swap would keep rendering A's cache. The\n * subtree is therefore also re-mounted (`key`), which drops every observer and every piece of\n * child state from the previous identity. The client, the `key` and the tuple handed to\n * `<W6WProvider>` all change in ONE state update: there is no render in which B's tree reads A's\n * cache. The old client is cleared once it is no longer mounted.\n *\n * **Identity switch (flush first).** A draft with a pending save must be written into the account\n * that produced the edit. When `identityKey` changes this provider therefore HOLDS the applied\n * tuple — `identityKey`, `apiOrigin`, `project`, `getSession`, the client — and keeps handing the\n * OLD one to `<W6WProvider>`, awaits `registry.flushAll()` (bounded, never rejects), and only then\n * applies the new tuple in a single update. `<W6WProvider>` swaps its client synchronously on a\n * new `identityKey` and detaches the old session store, so the flush must finish first; and the\n * new `getSession` is NOT forwarded early: `<W6WProvider>` reaches it through the stable wrapper\n * below, whose target is swapped in the same update as the tuple (forwarded early, the new\n * account's token would be minted on the old client). A flush that fails or times out still lets\n * the switch proceed (Q6) and is never retried with the new identity. A token rotation under an\n * unchanged `identityKey` is not a switch: it is forwarded at once, no hold.\n *\n * **No identity.** `identityKey={null}` mounts nothing but `fallback`: no `<W6WProvider>`, no\n * `QueryClientProvider`, no children — so no `getSession` call and no request. `null -> \"A\"`\n * applies at once (nothing can be pending); `\"A\" -> null` takes the SAME flush-first path as any\n * other switch before the fallback renders.\n *\n * **Default project.** `project={{ use: \"default\" }}` resolves ONCE per applied identity, through\n * one `client.projects.list()` query inside the identity-scoped `QueryClient`, to the row with\n * `isDefault === true` — never `list[0]`, never a fallback. `<W6WProvider>` gets no project until\n * it resolves; the client rebuild that follows reuses the cached answer (the query is keyed\n * without the client and lives in a component that stays mounted, so it is not re-issued).\n *\n * **Status.** `useEmbedStatus()` is `deriveEmbedStatus` over the `@w6w/react` session store plus a\n * terminal 401 seen through the forwarded `onUnauthorized`.\n */\nimport {\n W6WProvider,\n type W6WSession,\n createW6WUiAdapter,\n useW6WClient,\n useW6WSession,\n} from \"@w6w/react\";\nimport type { ApiError, FetchLike } from \"@w6w/sdk\";\nimport { type ThemeMode, type W6WApi, W6WUIProvider } from \"@w6w/ui\";\nimport {\n type ReactNode,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { DraftRegistryProvider, EmbedClientProvider, createDraftRegistry } from \"./draft/index.ts\";\nimport { EmbedAuthError, type EmbedStatus, deriveEmbedStatus } from \"./embed-status.ts\";\nimport {\n EmbedProjectContext,\n type EmbedProjectState,\n useProvidedProject,\n} from \"./project-context.ts\";\nimport { updateConnection } from \"./repos/connections.ts\";\nimport { withCredentialMethods } from \"./repos/credentials.ts\";\nimport { listDataStoreEntries, listDataStores } from \"./repos/data-stores.ts\";\nimport { resolveActionFields } from \"./repos/fields.ts\";\nimport { listModelRoutes } from \"./repos/models.ts\";\nimport {\n pollWebhookListen,\n startWebhookListen,\n stopWebhookListen,\n} from \"./repos/webhook-listen.ts\";\nimport { listNodeSamples, listTestInputs, saveTestInput } from \"./repos/workflows.ts\";\nimport { EmbedThemeContext } from \"./theme-context.ts\";\n\nexport interface W6WEmbedProviderProps {\n /** The w6w API origin, e.g. `\"https://api.w6w.io\"`. */\n apiOrigin: string;\n /**\n * Mints a session for the CURRENT host user (`{token, expiresAt, expiresIn?}`). Always the\n * latest callback; the provider caches and renews the result.\n */\n getSession: () => Promise<W6WSession>;\n /**\n * Which signed-in identity this provider speaks for (e.g. `${userId}:${accountId}`). Changing it\n * rebuilds the API client AND replaces the `QueryClient`, so nothing cached for the previous\n * identity is ever shown under the new one.\n */\n identityKey: string | null;\n /**\n * Rendered instead of the embed while `identityKey` is `null` (no signed-in user). Nothing of\n * the embed mounts then: no `getSession` call, no request. Default `null`.\n */\n fallback?: ReactNode;\n /**\n * Start acquiring a session on mount. Without it the session is acquired lazily, by the first\n * request a mounted surface makes, and `useEmbedStatus()` stays `\"connecting\"` until then.\n */\n eager?: boolean;\n /** Force the `@w6w/ui` theme to follow the host's. Omit to resolve it the library's default way. */\n theme?: ThemeMode;\n /** Gates every read hook while `false` (default `true`) — e.g. until the host has a user. */\n ready?: boolean;\n /**\n * Default project for project-scoped operations: a project id, or `{ use: \"default\" }` to use\n * the account's default project (resolved once per identity; see `useEmbedProject()`).\n */\n project?: string | { use: \"default\" };\n /** Transport override (tests, request recording). Defaults to `globalThis.fetch`. */\n fetch?: FetchLike;\n children: ReactNode;\n}\n\nfunction makeQueryClient(): QueryClient {\n // Same defaults as Studio's own client (`studio/src/main.tsx`).\n return new QueryClient({\n defaultOptions: { queries: { retry: false, refetchOnWindowFocus: false } },\n });\n}\n\n/** The part of the tuple that changes only when a switch has been APPLIED (after the flush). */\ninterface Applied {\n identityKey: string | null;\n queryClient: QueryClient;\n}\n\n/** What `<W6WProvider>` is fed while no switch is in progress; frozen at the last such render. */\ninterface Forwarded {\n apiOrigin: string;\n project: string | { use: \"default\" } | undefined;\n getSession: () => Promise<W6WSession>;\n}\n\n/** Hands the SDK client of the nearest `<W6WProvider>` to `useWorkflowDraft`. */\nfunction ClientBridge({ children }: { children: ReactNode }) {\n return <EmbedClientProvider client={useW6WClient()}>{children}</EmbedClientProvider>;\n}\n\n/** The README bridge: `useW6WClient` -> `createW6WUiAdapter` -> `<W6WUIProvider>`. */\nfunction UiBridge({ theme, children }: { theme?: ThemeMode; children: ReactNode }) {\n const client = useW6WClient();\n const provided = useProvidedProject();\n // `createW6WUiAdapter` has no `updateConnection` or `listModelRoutes`; keep them if it ever\n // gains them, else supply the embed repo's own so the ui Edit modal can save and the\n // `@w6w/model` node's Route field offers the project's routes (not free text) in any host.\n const api = useMemo(() => {\n const adapter: W6WApi = createW6WUiAdapter(client);\n if (typeof adapter.updateConnection !== \"function\") {\n adapter.updateConnection = (id, body) => updateConnection(client, id, body);\n }\n withCredentialMethods(adapter, client);\n if (typeof adapter.listModelRoutes !== \"function\") {\n adapter.listModelRoutes = async (editorProject) => {\n const project = editorProject || provided;\n if (!project) return [];\n const routes = await listModelRoutes(client, project);\n return routes.map((r) => ({ name: r.name, model: r.modelId, status: r.status }));\n };\n }\n // Same for the `@w6w/store` node's store picker: the project's store names, not free text.\n if (typeof adapter.listDataStores !== \"function\") {\n adapter.listDataStores = async (editorProject) => {\n const project = editorProject || provided;\n if (!project) return [];\n return listDataStores(client, project);\n };\n }\n // ...and its key picker: one page of the named store's entries, searched by key prefix.\n if (typeof adapter.listDataStoreEntries !== \"function\") {\n adapter.listDataStoreEntries = async (store, opts) => {\n const project = opts.project || provided;\n if (!project) return { items: [] };\n return listDataStoreEntries(client, project, store, opts);\n };\n }\n // Persisted node samples, so the editor's picker keeps upstream keys across a reload.\n if (typeof adapter.loadNodeSamples !== \"function\") {\n adapter.loadNodeSamples = (workflowId) => listNodeSamples(client, workflowId);\n }\n // Remembered test inputs, so every test form reopens prefilled with the last values used.\n if (typeof adapter.loadTestInputs !== \"function\") {\n adapter.loadTestInputs = (workflowId) => listTestInputs(client, workflowId);\n }\n if (typeof adapter.saveTestInput !== \"function\") {\n adapter.saveTestInput = (workflowId, nodeId, input) =>\n saveTestInput(client, workflowId, nodeId, input);\n }\n if (typeof adapter.resolveActionFields !== \"function\") {\n adapter.resolveActionFields = (appId, actionKey, body, opts) =>\n resolveActionFields(client, appId, actionKey, body, opts);\n }\n // The webhook node's Test tab listens for a real request only when all three exist; without\n // them it falls back to the paste-a-payload form.\n if (typeof adapter.startWebhookListen !== \"function\") {\n adapter.startWebhookListen = (subscriptionId) => startWebhookListen(client, subscriptionId);\n adapter.pollWebhookListen = (subscriptionId, sessionId, opts) =>\n pollWebhookListen(client, subscriptionId, sessionId, opts);\n adapter.stopWebhookListen = (subscriptionId, sessionId) =>\n stopWebhookListen(client, subscriptionId, sessionId);\n }\n return adapter;\n }, [client, provided]);\n return (\n <W6WUIProvider api={api} theme={theme}>\n <EmbedThemeContext.Provider value={theme}>{children}</EmbedThemeContext.Provider>\n </W6WUIProvider>\n );\n}\n\nconst EmbedStatusContext = createContext<EmbedStatus>({ status: \"connecting\", error: null });\n\n/** The session status of the nearest `<W6WEmbedProvider>`. See `deriveEmbedStatus`. */\nexport function useEmbedStatus(): EmbedStatus {\n return useContext(EmbedStatusContext);\n}\n\n/** Publishes `useEmbedStatus()`, and starts the session on mount when `eager`. */\nfunction StatusBridge({\n eager,\n authError,\n onAcquire,\n children,\n}: {\n eager: boolean;\n authError: EmbedAuthError | null;\n onAcquire: () => void;\n children: ReactNode;\n}) {\n const { status, error, refresh } = useW6WSession();\n // `refresh` is per session store, so a rebuilt client (project resolved) is started again.\n useEffect(() => {\n if (eager) void refresh();\n }, [eager, refresh]);\n useEffect(() => {\n if (status === \"loading\" || status === \"renewing\") onAcquire();\n }, [status, onAcquire]);\n const value = useMemo(\n () => deriveEmbedStatus(status, error, authError),\n [status, error, authError],\n );\n return <EmbedStatusContext.Provider value={value}>{children}</EmbedStatusContext.Provider>;\n}\n\n/**\n * Resolves `{use:\"default\"}`. Lives INSIDE `<W6WProvider>` (it needs the client) but at a fixed\n * slot, so it survives the client rebuild that follows resolution; the query key carries no\n * client, so nothing refetches.\n */\nfunction DefaultProjectResolver({\n identityKey,\n enabled,\n onState,\n}: {\n identityKey: string;\n enabled: boolean;\n onState: (key: string, state: EmbedProjectState) => void;\n}) {\n const client = useW6WClient();\n const q = useQuery({\n queryKey: [\"w6w-embed\", \"default-project\"],\n enabled,\n queryFn: async () => {\n const rows = await client.projects.list();\n const home = rows.find((p) => p.isDefault === true);\n if (!home) throw new Error(\"The account has no default project.\");\n return home.id;\n },\n });\n const { isError, error, data } = q;\n const state = useMemo<EmbedProjectState>(\n () =>\n isError\n ? { project: null, status: \"error\", error }\n : data !== undefined\n ? { project: data, status: \"ready\" }\n : { project: null, status: \"resolving\" },\n [isError, error, data],\n );\n useEffect(() => {\n onState(identityKey, state);\n }, [identityKey, state, onState]);\n return null;\n}\n\nexport function W6WEmbedProvider({\n apiOrigin,\n getSession,\n identityKey,\n fallback = null,\n eager = false,\n theme,\n ready,\n project,\n fetch,\n children,\n}: W6WEmbedProviderProps): ReactNode {\n const [registry] = useState(createDraftRegistry);\n const [applied, setApplied] = useState<Applied>(() => ({\n identityKey,\n queryClient: makeQueryClient(),\n }));\n\n // While `identityKey` differs from the applied one a switch is pending: everything below keeps\n // using the values frozen at the last render that was not pending. Otherwise props flow straight\n // through (project / origin changes, token rotation). Idempotent latest-value writes, the same\n // pattern `<W6WProvider>` uses for its own refs.\n const switching = identityKey !== applied.identityKey;\n const forwardedRef = useRef<Forwarded>({ apiOrigin, project, getSession });\n if (!switching) forwardedRef.current = { apiOrigin, project, getSession };\n const forwarded = forwardedRef.current;\n\n // The stable `getSession` handed to `<W6WProvider>`: reads whatever is applied RIGHT NOW. Its\n // target changes in the same render that applies the new tuple, never before the flush settles.\n const sessionRef = useRef(forwarded.getSession);\n sessionRef.current = forwarded.getSession;\n const [stableGetSession] = useState(() => () => sessionRef.current());\n\n useEffect(() => {\n if (identityKey === applied.identityKey) return;\n let cancelled = false;\n const apply = () => {\n if (cancelled) return;\n setApplied({ identityKey, queryClient: makeQueryClient() });\n };\n // Nothing is mounted under a null identity, so nothing can be pending: apply at once.\n if (applied.identityKey === null) {\n apply();\n return () => {\n cancelled = true;\n };\n }\n // `flushAll` never rejects and is bounded; the switch proceeds either way (Q6).\n registry.flushAll().then(apply, apply);\n return () => {\n cancelled = true;\n };\n }, [identityKey, applied.identityKey, registry]);\n\n // The replaced client is dropped once nothing mounted reads it.\n const queryClient = applied.queryClient;\n useEffect(() => () => queryClient.clear(), [queryClient]);\n\n // Default-project resolution, tagged with the identity it was resolved for: a result for A is\n // never read once B is applied.\n const [resolved, setResolved] = useState<{ key: string; state: EmbedProjectState } | null>(null);\n const onResolved = useCallback((key: string, state: EmbedProjectState) => {\n setResolved((prev) =>\n prev &&\n prev.key === key &&\n prev.state.project === state.project &&\n prev.state.status === state.status &&\n prev.state.error === state.error\n ? prev\n : { key, state },\n );\n }, []);\n\n // The terminal partner-token 401, tagged with its identity; cleared when the next acquisition\n // starts (StatusBridge) or the identity changes (the tag no longer matches).\n const [authFailure, setAuthFailure] = useState<{\n key: QueryClient;\n error: EmbedAuthError;\n } | null>(null);\n // The handler is bound to the per-mount client it was created for: a late 401 from a previous\n // `<W6WProvider>` is tagged with ITS client, never the one applied by the time it fires — even\n // when the identity key came back (A -> B -> A mints a new client for the same key).\n const onUnauthorized = useMemo(() => {\n const key = applied.queryClient;\n return (error: ApiError) => {\n setAuthFailure({ key, error: new EmbedAuthError(error) });\n };\n }, [applied.queryClient]);\n const clearAuthFailure = useCallback(() => setAuthFailure(null), []);\n\n const appliedKey = applied.identityKey;\n const spec = forwarded.project;\n // Only exactly `{ use: \"default\" }` asks for the account default; null, `{}`, `[]` or any other\n // object (JS hosts, casts) is \"no project\" and makes no lookup.\n const wantsDefault =\n typeof spec === \"object\" && spec !== null && !Array.isArray(spec) && spec.use === \"default\";\n const projectState: EmbedProjectState = useMemo(() => {\n if (typeof spec === \"string\") return { project: spec, status: \"ready\" };\n if (!wantsDefault) return { project: null, status: \"ready\" };\n return resolved && resolved.key === appliedKey\n ? resolved.state\n : { project: null, status: \"resolving\" };\n }, [spec, wantsDefault, resolved, appliedKey]);\n\n if (appliedKey === null) return fallback;\n\n return (\n <DraftRegistryProvider registry={registry}>\n <QueryClientProvider key={appliedKey} client={queryClient}>\n <W6WProvider\n baseUrl={forwarded.apiOrigin}\n getSession={stableGetSession}\n identityKey={appliedKey}\n ready={ready}\n project={projectState.project ?? undefined}\n fetch={fetch}\n onUnauthorized={onUnauthorized}\n >\n {wantsDefault ? (\n <DefaultProjectResolver\n identityKey={appliedKey}\n enabled={ready !== false}\n onState={onResolved}\n />\n ) : null}\n <EmbedProjectContext.Provider value={projectState}>\n <StatusBridge\n eager={eager}\n authError={authFailure && authFailure.key === queryClient ? authFailure.error : null}\n onAcquire={clearAuthFailure}\n >\n <ClientBridge>\n <UiBridge theme={theme}>{children}</UiBridge>\n </ClientBridge>\n </StatusBridge>\n </EmbedProjectContext.Provider>\n </W6WProvider>\n </QueryClientProvider>\n </DraftRegistryProvider>\n );\n}\n"],"names":["EmbedAuthError","cause","deriveEmbedStatus","sessionStatus","sessionError","authError","startWebhookListen","client","subscriptionId","path","pollWebhookListen","sessionId","opts","stopWebhookListen","makeQueryClient","QueryClient","ClientBridge","children","jsx","EmbedClientProvider","useW6WClient","UiBridge","theme","provided","useProvidedProject","api","useMemo","adapter","createW6WUiAdapter","id","body","updateConnection","withCredentialMethods","editorProject","project","listModelRoutes","r","listDataStores","store","listDataStoreEntries","workflowId","listNodeSamples","listTestInputs","nodeId","input","saveTestInput","appId","actionKey","resolveActionFields","W6WUIProvider","EmbedThemeContext","EmbedStatusContext","createContext","useEmbedStatus","useContext","StatusBridge","eager","onAcquire","status","error","refresh","useW6WSession","useEffect","value","DefaultProjectResolver","identityKey","enabled","onState","q","useQuery","home","p","isError","data","state","W6WEmbedProvider","apiOrigin","getSession","fallback","ready","fetch","registry","useState","createDraftRegistry","applied","setApplied","switching","forwardedRef","useRef","forwarded","sessionRef","stableGetSession","cancelled","apply","queryClient","resolved","setResolved","onResolved","useCallback","key","prev","authFailure","setAuthFailure","onUnauthorized","clearAuthFailure","appliedKey","spec","wantsDefault","projectState","DraftRegistryProvider","QueryClientProvider","jsxs","W6WProvider","EmbedProjectContext"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export type AppConnections = {
2
+ state: "loading";
3
+ } | {
4
+ state: "error";
5
+ } | {
6
+ state: "ready";
7
+ ids: ReadonlySet<string>;
8
+ };
9
+ export interface BindingSite {
10
+ id: string;
11
+ uses?: {
12
+ app?: string;
13
+ connection?: string | null;
14
+ connectionRef?: string;
15
+ };
16
+ }
17
+ export interface BindingProblem {
18
+ siteId: string;
19
+ app: string;
20
+ connection: string;
21
+ code: "unknown_connection";
22
+ }
23
+ /** A problem iff app + connection are non-empty and the app's list is `ready` without the id.
24
+ * `loading`, `error` and `undefined` (internal app / not fetched) never report — no false red. */
25
+ export declare function findBindingProblems(sites: readonly BindingSite[], byApp: (app: string) => AppConnections | undefined, connections?: Record<string, {
26
+ app: string;
27
+ connection: string | null;
28
+ }>): BindingProblem[];
29
+ export interface DisabledBannerInput {
30
+ enabled: boolean | undefined;
31
+ problemCount: number;
32
+ dirty: boolean;
33
+ hadProblems: boolean;
34
+ }
35
+ export interface DisabledBannerState {
36
+ show: boolean;
37
+ canEnable: boolean;
38
+ problemCount: number;
39
+ }
40
+ /** Show iff disabled AND (problems now OR problems seen this mount). Enable only once every
41
+ * binding is fixed AND saved. `enabled` undefined (versions not loaded) never shows. */
42
+ export declare function disabledBannerState(input: DisabledBannerInput): DisabledBannerState;
@@ -23,18 +23,20 @@ export type RailCallable = {
23
23
  } | {
24
24
  kind: "connection";
25
25
  id: string;
26
+ action?: string;
27
+ params?: readonly SnippetInput[];
26
28
  } | null;
27
29
  /**
28
30
  * Is a "Call from code" panel meaningful for this context? Mirrors
29
31
  * `alias-rail.ts`'s `targetForCallable` fail-closed shape exactly (its own
30
32
  * comment: *"'connection' and no resource at all both fail closed to null —
31
- * house style"*) — `"connection"` and `null` both answer `false`.
33
+ * house style"*) — a bare `"connection"` (no `action`) and `null` both answer `false`.
32
34
  */
33
35
  export declare function isAvailable(ctx: RailCallable): boolean;
34
36
  /**
35
37
  * The widened-union -> `SnippetCallable` conversion `CodeTool.Panel` hands to
36
38
  * `CallFromCodeBody`. `null` for a context this tool has no snippet for
37
- * (`"connection"`, or no resource at all) — defensive, since `isAvailable`
39
+ * (a connection without an `action`, or no resource at all) — defensive, since `isAvailable`
38
40
  * already keeps the tool off the strip for those.
39
41
  *
40
42
  * The one easy-to-miss field: `WorkspaceCallable`'s `label` maps to
@@ -11,6 +11,15 @@ export interface ExecutionSummary {
11
11
  finishedAt: string | null;
12
12
  durationMs: number | null;
13
13
  workflowRunId: string | null;
14
+ /** The execution this one RE-RUNS (History's Re-run), or `null`. Absent from an older server. */
15
+ rerunOf?: string | null;
16
+ /** How a workflow run was started (manual, schedule, webhook, event, replay); `null` for a
17
+ * Function/Endpoint call. Absent from an older server. */
18
+ trigger?: string | null;
19
+ /** The trigger node a workflow run entered through. Absent from an older server. */
20
+ triggerNodeId?: string | null;
21
+ /** The start of the input as JSON text. Absent from an older server. */
22
+ inputPreview?: string | null;
14
23
  }
15
24
  export interface ExecutionStats {
16
25
  total: number;
@@ -109,15 +118,36 @@ export interface ExecutionDetailData {
109
118
  input?: unknown;
110
119
  output?: unknown;
111
120
  error?: unknown;
121
+ /** The execution this one re-runs, carried from its summary row. */
122
+ rerunOf?: string | null;
112
123
  steps?: Array<{
113
124
  id: string;
114
125
  status: "pending" | "running" | "succeeded" | "failed" | "skipped";
126
+ skipReason?: "not_on_path" | "condition" | "stopped" | "disabled";
115
127
  startedAt?: string;
116
128
  finishedAt?: string;
117
129
  input?: unknown;
118
130
  output?: unknown;
131
+ node?: StepNode;
119
132
  }>;
120
133
  }
134
+ /** What a workflow step IS (`@w6w/ui`'s `ExecutionLogNode`, restated locally — A1): the app and
135
+ * action it uses, whether it is a trigger, and the app's display names when it is a registered app.
136
+ * A built-in `@w6w/*` node carries ids only; the panel names those from its own catalog. */
137
+ export interface StepNode {
138
+ app: string;
139
+ action: string;
140
+ trigger?: boolean;
141
+ appName?: string;
142
+ actionName?: string;
143
+ }
144
+ /**
145
+ * Every node of the workflow's CURRENT definition, keyed by id, as a {@link StepNode} — with the
146
+ * display names of each registered app (`GET /apps/:id`'s `displayName` and action titles, plus
147
+ * `GET /apps/:id/triggers` for an app a trigger node uses). Best-effort throughout: a definition
148
+ * that cannot be read yields an empty map, and an app that cannot be read keeps its raw ids.
149
+ */
150
+ export declare function describeWorkflowNodes(client: W6WClient, workflowId: string): Promise<Map<string, StepNode>>;
121
151
  /**
122
152
  * Expand a list row into its full detail. Function/Endpoint invocations are
123
153
  * synchronous calls recorded one row per call (`.claude/docs/invocations.md`)
@@ -133,3 +163,18 @@ export interface ExecutionDetailData {
133
163
  * carries a human-readable callable name of its own.
134
164
  */
135
165
  export declare function getExecutionDetail(client: W6WClient, summary: ExecutionSummary): Promise<ExecutionDetailData>;
166
+ /**
167
+ * Run a past execution again with the input it had, against the callable's
168
+ * CURRENT definition (the stored draft — `allowUnpublished`, as the editor's
169
+ * own Run and Test do), and return the new execution's summary row so the
170
+ * host can open it. A workflow is replayed by the server from its stored seed
171
+ * (`POST /runs/:id/rerun`, trigger payload included); a function replays its
172
+ * `inputs`; an endpoint its `input`. `null` when the new row is not yet listed (the host then just
173
+ * shows the refreshed list).
174
+ */
175
+ export declare function rerunExecution(client: W6WClient, summary: ExecutionSummary, opts?: {
176
+ sleep?: (ms: number) => Promise<void>;
177
+ }): Promise<ExecutionSummary | null>;
178
+ /** One callable's execution by id, as its summary row (`GET /history`'s id search), or `null`
179
+ * when it is not listed — e.g. the original a re-run names, once retention removed it. */
180
+ export declare function findExecution(client: W6WClient, callableId: string, id: string): Promise<ExecutionSummary | null>;