@w6w/embed 0.2.20 → 0.2.22

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 (29) hide show
  1. package/dist/{ModelRoutesManager-1Ac5wcas.js → ModelRoutesManager-BUw_sm-M.js} +2 -2
  2. package/dist/ModelRoutesManager-BUw_sm-M.js.map +1 -0
  3. package/dist/{WorkflowEditor-CmhXHRxi.js → WorkflowEditor-LesBKjb2.js} +194 -186
  4. package/dist/{WorkflowEditor-CmhXHRxi.js.map → WorkflowEditor-LesBKjb2.js.map} +1 -1
  5. package/dist/{apps-ItBvnWX3.js → apps-CYUgEfGf.js} +2 -2
  6. package/dist/{apps-ItBvnWX3.js.map → apps-CYUgEfGf.js.map} +1 -1
  7. package/dist/editor/types.d.ts +2 -0
  8. package/dist/{editor-apps-DkkC7wOQ.js → editor-apps-LZmDWMqf.js} +3 -3
  9. package/dist/{editor-apps-DkkC7wOQ.js.map → editor-apps-LZmDWMqf.js.map} +1 -1
  10. package/dist/{editor-tools-BR27RGto.js → editor-tools-DHyWiG21.js} +49 -40
  11. package/dist/{editor-tools-BR27RGto.js.map → editor-tools-DHyWiG21.js.map} +1 -1
  12. package/dist/editor.mjs +1 -1
  13. package/dist/editors.mjs +67 -60
  14. package/dist/editors.mjs.map +1 -1
  15. package/dist/forms.mjs +272 -269
  16. package/dist/forms.mjs.map +1 -1
  17. package/dist/index.mjs +1 -1
  18. package/dist/lists.mjs +7 -7
  19. package/dist/lists.mjs.map +1 -1
  20. package/dist/rail.mjs +1 -1
  21. package/dist/repos/workflows.d.ts +1 -1
  22. package/dist/repos.mjs +3 -3
  23. package/dist/{spec-export-DGy5ijps.js → spec-export-DGigBUsP.js} +2 -2
  24. package/dist/{spec-export-DGy5ijps.js.map → spec-export-DGigBUsP.js.map} +1 -1
  25. package/dist/{workflows-BZN4Hyz1.js → workflows-BK6IM4if.js} +3 -3
  26. package/dist/{workflows-BZN4Hyz1.js.map → workflows-BK6IM4if.js.map} +1 -1
  27. package/package.json +3 -3
  28. package/src/styles.css +30 -4
  29. package/dist/ModelRoutesManager-1Ac5wcas.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { useQuery as u, keepPreviousData as l, useQueryClient as p, useMutation as y } from "@tanstack/react-query";
2
2
  import { u as i } from "./client-context-CX61Bgw-.js";
3
- import { H as d, h as f, o as r, g as q, i as a, E, j as g, I as x, x as K } from "./workflows-BZN4Hyz1.js";
3
+ import { H as d, h as f, o as r, g as q, i as a, E, j as g, I as x, x as K } from "./workflows-BK6IM4if.js";
4
4
  const c = { project: "" };
5
5
  function b(e, t, n = d) {
6
6
  const s = i();
@@ -89,4 +89,4 @@ export {
89
89
  k,
90
90
  b as u
91
91
  };
92
- //# sourceMappingURL=apps-ItBvnWX3.js.map
92
+ //# sourceMappingURL=apps-CYUgEfGf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apps-ItBvnWX3.js","sources":["../src/repos/history.ts","../src/repos/apps.ts"],"sourcesContent":["/**\n * The `history` domain repo (T2.3.1) — thin react-query hooks over\n * `lib/history-query.ts`'s pure fetchers, mirroring `./dashboard.ts`'s\n * shape exactly: the query keys ship from the pure module, not from here or\n * from a caller; every hook is `useEmbedClient()` + one `useQuery`.\n *\n * `lib/history-query.ts` carries every judgment call (URL⇄filter mapping,\n * request params, cache keys, fetchers, detail mapping) so it stays loadable\n * by `node --test`; this file adds nothing but React wiring on top of it.\n */\nimport { keepPreviousData, useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n EMPTY_HISTORY_FILTERS,\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n findExecution,\n getExecutionDetail,\n getHistory,\n getHistoryStats,\n historyKeys,\n rerunExecution,\n} from \"../lib/history-query.ts\";\nimport { runsKey } from \"./workflows.ts\";\n\n/** A placeholder scope to key a disabled query by — never fetched, since\n * `enabled` gates on the real (possibly `null`) scope, matching\n * `repos/workflows.ts`'s `useLiveRunQuery(runId ?? \"\")` idiom. */\nconst NO_SCOPE: HistoryScope = { project: \"\" };\n\n/** The project-wide or per-callable execution list, one page at a time.\n * Disabled while `scope` is `null` (no project/callable selected yet).\n * `placeholderData: keepPreviousData` keeps the previous page's rows on\n * screen while a filter/page change is in flight, instead of flashing to\n * an empty list. */\nexport function useHistoryQuery(\n scope: HistoryScope | null,\n f: HistoryFilters,\n limit: number = HISTORY_PAGE_SIZE,\n) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.list(scope ?? NO_SCOPE, f, limit),\n queryFn: () => getHistory(apiClient, scope as HistoryScope, f, limit),\n enabled: scope !== null,\n placeholderData: keepPreviousData,\n });\n}\n\n/** The aggregate stats card above the list — same scope/filters, no paging.\n * Disabled while `scope` is `null`. */\nexport function useHistoryStatsQuery(scope: HistoryScope | null, f: HistoryFilters) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.stats(scope ?? NO_SCOPE, f),\n queryFn: () => getHistoryStats(apiClient, scope as HistoryScope, f),\n enabled: scope !== null,\n });\n}\n\n/** \"Has this callable ever been executed?\" — the cheap existence probe the\n * header's History button uses to decide its disabled state (one row,\n * every filter at its default). `hasExecuted` reads `false` while loading\n * or on error — never a false \"yes\". */\nexport function useHasExecutedQuery(callableId: string): {\n hasExecuted: boolean;\n isLoading: boolean;\n} {\n const apiClient = useEmbedClient();\n const query = useQuery({\n queryKey: historyKeys.exists(callableId),\n queryFn: () => getHistory(apiClient, { callable: callableId }, EMPTY_HISTORY_FILTERS, 1),\n });\n return {\n hasExecuted: (query.data?.executions?.length ?? 0) > 0,\n isLoading: query.isLoading,\n };\n}\n\n/** One execution's full detail, opened from a list row. Disabled while\n * `summary` is `null` (no row selected). */\nexport function useExecutionDetailQuery(summary: ExecutionSummary | null) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.detail(summary?.kind ?? \"function\", summary?.id ?? \"\"),\n queryFn: () => getExecutionDetail(apiClient, summary as ExecutionSummary),\n enabled: summary !== null,\n });\n}\n\n/** Run a listed execution again with the same input (`rerunExecution`),\n * resolving to the new execution's row (or `null` if not listed yet). Every\n * history list, stat and probe is invalidated once it settles — a failed\n * re-run is still a new execution — as is the workflow's own run list. */\nexport function useRerunExecutionMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (summary: ExecutionSummary) => rerunExecution(apiClient, summary),\n onSettled: (_res, _err, summary) => {\n qc.invalidateQueries({ queryKey: historyKeys.root });\n if (summary.kind === \"workflow\") {\n qc.invalidateQueries({ queryKey: runsKey(summary.callableId) });\n }\n },\n });\n}\n\n/** Look one execution of a callable up by id (`findExecution`) — what opens the original from a\n * re-run's \"Re-run of <id>\". A plain function over the embed client, not a query: it runs once per\n * click, and the opened detail has its own query. */\nexport function useFindExecution() {\n const apiClient = useEmbedClient();\n return (callableId: string, id: string) => findExecution(apiClient, callableId, id);\n}\n","/**\n * The per-app Actions repo — what the Target selector and the canvas's step pickers read.\n *\n * Moved from Studio's `repos/apps.ts` (B-3a); the Studio file re-exports these names. The client\n * comes from `useEmbedClient()`. `GET /apps/:id` through `client.console.apps.getActions` is the\n * same payload the W6WApi adapter serves the canvas, and the key is byte-identical to the one\n * the editor and `WorkflowsPage` compose by hand, so every reader shares one cache entry.\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { W6WClient } from \"@w6w/sdk\";\nimport type { ActionDef, AppDetail } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n\nexport const appActionsKey = (id: string) => [\"app-actions\", id] as const;\n\nexport function getAppActions(client: W6WClient, id: string): Promise<ActionDef[]> {\n return client.console.apps.getActions(id);\n}\n\n/** `enabled` defaults to `true`; a selector passes `app !== \"\"` so an empty app issues nothing. */\nexport function useAppActionsQuery(id: string, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appActionsKey(id),\n queryFn: () => getAppActions(client, id),\n enabled,\n });\n}\n\n// ── app (detail) ─────────────────────────────────────────────────────────\n\nexport const appKey = (id: string) => [\"app\", id] as const;\n\nexport function getApp(client: W6WClient, id: string): Promise<AppDetail> {\n return client.console.apps.get(id);\n}\n\n/**\n * `id` accepts `string | undefined`: a detail view's app id is `undefined` until its own\n * connection query resolves, so the caller passes `enabled` (its `!!id` guard) instead of\n * `!`-asserting.\n */\nexport function useAppQuery(id: string | undefined, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appKey(id ?? \"\"),\n queryFn: () => getApp(client, id as string),\n enabled,\n });\n}\n"],"names":["NO_SCOPE","useHistoryQuery","scope","f","limit","HISTORY_PAGE_SIZE","apiClient","useEmbedClient","useQuery","historyKeys","getHistory","keepPreviousData","useHistoryStatsQuery","getHistoryStats","useHasExecutedQuery","callableId","query","EMPTY_HISTORY_FILTERS","_b","_a","useExecutionDetailQuery","summary","getExecutionDetail","useRerunExecutionMutation","qc","useQueryClient","useMutation","rerunExecution","_res","_err","runsKey","useFindExecution","id","findExecution","appActionsKey","getAppActions","client","useAppActionsQuery","enabled","appKey","getApp","useAppQuery"],"mappings":"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"}
1
+ {"version":3,"file":"apps-CYUgEfGf.js","sources":["../src/repos/history.ts","../src/repos/apps.ts"],"sourcesContent":["/**\n * The `history` domain repo (T2.3.1) — thin react-query hooks over\n * `lib/history-query.ts`'s pure fetchers, mirroring `./dashboard.ts`'s\n * shape exactly: the query keys ship from the pure module, not from here or\n * from a caller; every hook is `useEmbedClient()` + one `useQuery`.\n *\n * `lib/history-query.ts` carries every judgment call (URL⇄filter mapping,\n * request params, cache keys, fetchers, detail mapping) so it stays loadable\n * by `node --test`; this file adds nothing but React wiring on top of it.\n */\nimport { keepPreviousData, useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\nimport {\n EMPTY_HISTORY_FILTERS,\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n findExecution,\n getExecutionDetail,\n getHistory,\n getHistoryStats,\n historyKeys,\n rerunExecution,\n} from \"../lib/history-query.ts\";\nimport { runsKey } from \"./workflows.ts\";\n\n/** A placeholder scope to key a disabled query by — never fetched, since\n * `enabled` gates on the real (possibly `null`) scope, matching\n * `repos/workflows.ts`'s `useLiveRunQuery(runId ?? \"\")` idiom. */\nconst NO_SCOPE: HistoryScope = { project: \"\" };\n\n/** The project-wide or per-callable execution list, one page at a time.\n * Disabled while `scope` is `null` (no project/callable selected yet).\n * `placeholderData: keepPreviousData` keeps the previous page's rows on\n * screen while a filter/page change is in flight, instead of flashing to\n * an empty list. */\nexport function useHistoryQuery(\n scope: HistoryScope | null,\n f: HistoryFilters,\n limit: number = HISTORY_PAGE_SIZE,\n) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.list(scope ?? NO_SCOPE, f, limit),\n queryFn: () => getHistory(apiClient, scope as HistoryScope, f, limit),\n enabled: scope !== null,\n placeholderData: keepPreviousData,\n });\n}\n\n/** The aggregate stats card above the list — same scope/filters, no paging.\n * Disabled while `scope` is `null`. */\nexport function useHistoryStatsQuery(scope: HistoryScope | null, f: HistoryFilters) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.stats(scope ?? NO_SCOPE, f),\n queryFn: () => getHistoryStats(apiClient, scope as HistoryScope, f),\n enabled: scope !== null,\n });\n}\n\n/** \"Has this callable ever been executed?\" — the cheap existence probe the\n * header's History button uses to decide its disabled state (one row,\n * every filter at its default). `hasExecuted` reads `false` while loading\n * or on error — never a false \"yes\". */\nexport function useHasExecutedQuery(callableId: string): {\n hasExecuted: boolean;\n isLoading: boolean;\n} {\n const apiClient = useEmbedClient();\n const query = useQuery({\n queryKey: historyKeys.exists(callableId),\n queryFn: () => getHistory(apiClient, { callable: callableId }, EMPTY_HISTORY_FILTERS, 1),\n });\n return {\n hasExecuted: (query.data?.executions?.length ?? 0) > 0,\n isLoading: query.isLoading,\n };\n}\n\n/** One execution's full detail, opened from a list row. Disabled while\n * `summary` is `null` (no row selected). */\nexport function useExecutionDetailQuery(summary: ExecutionSummary | null) {\n const apiClient = useEmbedClient();\n return useQuery({\n queryKey: historyKeys.detail(summary?.kind ?? \"function\", summary?.id ?? \"\"),\n queryFn: () => getExecutionDetail(apiClient, summary as ExecutionSummary),\n enabled: summary !== null,\n });\n}\n\n/** Run a listed execution again with the same input (`rerunExecution`),\n * resolving to the new execution's row (or `null` if not listed yet). Every\n * history list, stat and probe is invalidated once it settles — a failed\n * re-run is still a new execution — as is the workflow's own run list. */\nexport function useRerunExecutionMutation() {\n const apiClient = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (summary: ExecutionSummary) => rerunExecution(apiClient, summary),\n onSettled: (_res, _err, summary) => {\n qc.invalidateQueries({ queryKey: historyKeys.root });\n if (summary.kind === \"workflow\") {\n qc.invalidateQueries({ queryKey: runsKey(summary.callableId) });\n }\n },\n });\n}\n\n/** Look one execution of a callable up by id (`findExecution`) — what opens the original from a\n * re-run's \"Re-run of <id>\". A plain function over the embed client, not a query: it runs once per\n * click, and the opened detail has its own query. */\nexport function useFindExecution() {\n const apiClient = useEmbedClient();\n return (callableId: string, id: string) => findExecution(apiClient, callableId, id);\n}\n","/**\n * The per-app Actions repo — what the Target selector and the canvas's step pickers read.\n *\n * Moved from Studio's `repos/apps.ts` (B-3a); the Studio file re-exports these names. The client\n * comes from `useEmbedClient()`. `GET /apps/:id` through `client.console.apps.getActions` is the\n * same payload the W6WApi adapter serves the canvas, and the key is byte-identical to the one\n * the editor and `WorkflowsPage` compose by hand, so every reader shares one cache entry.\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { W6WClient } from \"@w6w/sdk\";\nimport type { ActionDef, AppDetail } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n\nexport const appActionsKey = (id: string) => [\"app-actions\", id] as const;\n\nexport function getAppActions(client: W6WClient, id: string): Promise<ActionDef[]> {\n return client.console.apps.getActions(id);\n}\n\n/** `enabled` defaults to `true`; a selector passes `app !== \"\"` so an empty app issues nothing. */\nexport function useAppActionsQuery(id: string, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appActionsKey(id),\n queryFn: () => getAppActions(client, id),\n enabled,\n });\n}\n\n// ── app (detail) ─────────────────────────────────────────────────────────\n\nexport const appKey = (id: string) => [\"app\", id] as const;\n\nexport function getApp(client: W6WClient, id: string): Promise<AppDetail> {\n return client.console.apps.get(id);\n}\n\n/**\n * `id` accepts `string | undefined`: a detail view's app id is `undefined` until its own\n * connection query resolves, so the caller passes `enabled` (its `!!id` guard) instead of\n * `!`-asserting.\n */\nexport function useAppQuery(id: string | undefined, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: appKey(id ?? \"\"),\n queryFn: () => getApp(client, id as string),\n enabled,\n });\n}\n"],"names":["NO_SCOPE","useHistoryQuery","scope","f","limit","HISTORY_PAGE_SIZE","apiClient","useEmbedClient","useQuery","historyKeys","getHistory","keepPreviousData","useHistoryStatsQuery","getHistoryStats","useHasExecutedQuery","callableId","query","EMPTY_HISTORY_FILTERS","_b","_a","useExecutionDetailQuery","summary","getExecutionDetail","useRerunExecutionMutation","qc","useQueryClient","useMutation","rerunExecution","_res","_err","runsKey","useFindExecution","id","findExecution","appActionsKey","getAppActions","client","useAppActionsQuery","enabled","appKey","getApp","useAppQuery"],"mappings":"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"}
@@ -21,6 +21,8 @@ export interface WorkflowEditorSlots {
21
21
  backLabel?: string | null;
22
22
  }
23
23
  export interface WorkflowEditorProps {
24
+ /** Host routes for opening called workflows/functions in another tab. */
25
+ callableHref?: (kind: "function" | "workflow", id: string) => string;
24
26
  workflowId: string;
25
27
  /**
26
28
  * The project this workflow is saved into. Omitted: the `<W6WEmbedProvider project>`. `null` or
@@ -1,6 +1,6 @@
1
1
  import { jsxs as C, jsx as f, Fragment as X } from "react/jsx-runtime";
2
- import { u as ee, a as te, b as ne, c as re, d as oe } from "./apps-ItBvnWX3.js";
3
- import { H as _ } from "./workflows-BZN4Hyz1.js";
2
+ import { u as ee, a as te, b as ne, c as re, d as oe } from "./apps-CYUgEfGf.js";
3
+ import { H as _ } from "./workflows-BK6IM4if.js";
4
4
  import { ExecutionDetail as se, ExecutionStats as ie, ExecutionFilters as le, ExecutionList as ce, useW6WApi as ue } from "@w6w/ui";
5
5
  import { useRef as E, useState as R, useEffect as B, useLayoutEffect as ae, useCallback as L, useMemo as fe } from "react";
6
6
  import { useQuery as de } from "@tanstack/react-query";
@@ -149,4 +149,4 @@ export {
149
149
  Ee as a,
150
150
  be as u
151
151
  };
152
- //# sourceMappingURL=editor-apps-DkkC7wOQ.js.map
152
+ //# sourceMappingURL=editor-apps-LZmDWMqf.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-apps-DkkC7wOQ.js","sources":["../src/chrome/HistoryView.tsx","../src/editor/editor-apps.ts"],"sourcesContent":["/**\n * `HistoryView` — the execution-history view body (T3.2.1, extracted from\n * `HistoryPage.tsx`'s T2.4.1 shape): stats + filters + paged list, OR the\n * selected execution's detail — never both. Opening a row swaps the list for\n * that execution (with a Back control to return to the list where it was\n * left); it does not stack the detail under a long list, where it lands\n * off-screen. Two hosts mount it — `HistoryPage` (the\n * project-wide and per-callable routes, filters URL-backed) and\n * `HistoryModal` (R-2's in-place modal, filters kept in local state) — so\n * this component owns every judgment call about HOW the view behaves, and\n * takes no position on WHERE its filters live: the host hands down\n * `filters` and gets every change back through `onFiltersChange`, exactly\n * the controlled-value shape `filtersToSearch`/`filtersFromSearch` already\n * assume on the URL-backed side.\n *\n * What stays here, same as it was in `HistoryPage` before the extraction:\n * - the search box's text, debounced, so a keystroke does not re-key and\n * re-issue both queries on every character (`onFiltersChange` — and so\n * the host's own write, URL or local state — fires only once typing\n * settles);\n * - which list row is selected, which is not shareable state and resets on\n * every mount;\n * - re-running an execution (a control on every row and in the detail): the\n * same input, against the callable's current definition. The view then\n * opens the NEW execution, so the outcome is what the author sees next;\n * - every filter change but paging snapping the page back to the first\n * (`offset` 0), because a narrowed result set has no meaningful \"page 3\".\n *\n * `onOpenInEditor`, when given, is called with the selected execution ONLY\n * while it is a workflow run (a function/endpoint invocation has no visual\n * editor to open) — the same gate `HistoryPage.tsx` applied inline before\n * this extraction. A host that never passes it (none of today's two do)\n * simply never sees the call.\n */\nimport {\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n useExecutionDetailQuery,\n useFindExecution,\n useHistoryQuery,\n useHistoryStatsQuery,\n useRerunExecutionMutation,\n} from \"@w6w/embed/repos\";\nimport {\n ExecutionDetail,\n type ExecutionFilterValue,\n ExecutionFilters,\n ExecutionList,\n ExecutionStats,\n} from \"@w6w/ui\";\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\n/** How long to wait after the last keystroke before `onFiltersChange` fires\n * with the new `q` (and so before either query re-issues with it). */\nconst SEARCH_DEBOUNCE_MS = 300;\n\n/** The nearest ancestor that actually scrolls (the modal body, the app's main\n * pane), or `null` when the document itself does. */\nfunction scrollParent(el: HTMLElement | null): HTMLElement | null {\n for (let p = el?.parentElement ?? null; p; p = p.parentElement) {\n const overflowY = getComputedStyle(p).overflowY;\n if ((overflowY === \"auto\" || overflowY === \"scroll\") && p.scrollHeight > p.clientHeight) {\n return p;\n }\n }\n return null;\n}\n\nexport interface HistoryViewProps {\n /** `null` ⇒ no scope known yet (the project-wide host, before its project\n * resolves) — both queries stay disabled, mirroring `repos/history.ts`'s\n * own `enabled: scope !== null`. */\n scope: HistoryScope | null;\n /** Project-wide chrome: the Kind filter, and the Callable column on every\n * row. A per-callable host (every callable already knows its own kind)\n * passes `false`. */\n showKind: boolean;\n filters: HistoryFilters;\n onFiltersChange: (next: HistoryFilters) => void;\n onOpenInEditor?: (execution: ExecutionSummary) => void;\n}\n\nexport function HistoryView(props: HistoryViewProps) {\n const { scope, showKind, filters, onFiltersChange, onOpenInEditor } = props;\n\n // The debounce below fires outside any render, so it needs the LATEST\n // filters (a status picked while a `q` write was still pending must\n // survive it) rather than the ones captured when typing started.\n const filtersRef = useRef(filters);\n filtersRef.current = filters;\n\n const [q, setQ] = useState(filters.q);\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [selected, setSelected] = useState<ExecutionSummary | null>(null);\n\n // Keep the search box in step with `filters.q` when IT moves from outside\n // (Back/Forward or a shared link on the URL-backed host). This never\n // fights a keystroke: an outside `q` only changes once typing has\n // settled, by which point `q` already equals it.\n useEffect(() => {\n setQ(filters.q);\n }, [filters.q]);\n\n // Drop a pending debounce on unmount.\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const listQuery = useHistoryQuery(scope, filters);\n const statsQuery = useHistoryStatsQuery(scope, filters);\n const detailQuery = useExecutionDetailQuery(selected);\n const rerun = useRerunExecutionMutation();\n const findExecution = useFindExecution();\n const [findError, setFindError] = useState<string | null>(null);\n\n // Swapping list ⇄ detail keeps the scroll offset of whatever scrolls around\n // this view, which would open a detail scrolled past its own top (the row\n // was clicked far down the list). So: remember the list's offset on the\n // way in, show the detail from its top, and put the list back on the way out.\n const viewRef = useRef<HTMLDivElement>(null);\n const listScroll = useRef<{ parent: HTMLElement | null; top: number } | null>(null);\n const selectedId = selected?.id ?? null;\n useLayoutEffect(() => {\n const el = viewRef.current;\n if (!el) return;\n if (selectedId !== null) {\n const parent = scrollParent(el);\n if (parent) parent.scrollTop = 0;\n else if (el.getBoundingClientRect().top < 0) el.scrollIntoView?.({ block: \"start\" });\n } else if (listScroll.current) {\n const { parent, top } = listScroll.current;\n listScroll.current = null;\n if (parent) parent.scrollTop = top;\n else window.scrollTo(0, top);\n }\n }, [selectedId]);\n\n const selectedRef = useRef(selected);\n selectedRef.current = selected;\n const open = useCallback((next: ExecutionSummary) => {\n // Leaving the LIST (not one detail for another, as a re-run from the detail does).\n if (selectedRef.current === null) {\n const parent = scrollParent(viewRef.current);\n listScroll.current = { parent, top: parent ? parent.scrollTop : window.scrollY };\n }\n setSelected(next);\n }, []);\n\n const executions = listQuery.data?.executions ?? [];\n const offset = filters.offset;\n const hasMore = listQuery.data?.hasMore ?? false;\n\n /** Every filter change but paging reports a fresh filter set and resets\n * the page to the first. */\n const applyFilters = (next: ExecutionFilterValue) => {\n onFiltersChange({ ...next, offset: 0 });\n };\n\n const onChange = (next: ExecutionFilterValue) => {\n if (next.q === q) {\n applyFilters(next);\n return;\n }\n setQ(next.q);\n if (searchTimer.current) clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => {\n searchTimer.current = null;\n onFiltersChange({ ...filtersRef.current, q: next.q, offset: 0 });\n }, SEARCH_DEBOUNCE_MS);\n };\n\n const onPrev = () =>\n onFiltersChange({ ...filters, q, offset: Math.max(0, offset - HISTORY_PAGE_SIZE) });\n const onNext = () => onFiltersChange({ ...filters, q, offset: offset + HISTORY_PAGE_SIZE });\n\n const onSelect = useCallback(\n (executionId: string) => {\n const row = executions.find((r) => r.id === executionId);\n if (row) open(row);\n },\n [executions, open],\n );\n\n /** Re-run one execution, then open the new one — or, when it is not listed\n * yet, fall back to the (refreshed) list. */\n const startRerun = (summary: ExecutionSummary) => {\n rerun.mutate(summary, {\n onSuccess: (next) => {\n if (next) open(next);\n else setSelected(null);\n },\n });\n };\n const rerunningId = rerun.isPending ? (rerun.variables?.id ?? null) : null;\n\n /** \"Re-run of <id>\": open the original, from the callable this one belongs to. */\n const openOriginal = (callableId: string, id: string) => {\n setFindError(null);\n findExecution(callableId, id)\n .then((row) => {\n if (row) open(row);\n else setFindError(`${id} is no longer available.`);\n })\n .catch(() => setFindError(`Couldn't open ${id}.`));\n };\n const rerunError = rerun.isError ? (\n <p className=\"error\" data-testid=\"history-rerun-error\">\n Couldn't re-run: {rerun.error instanceof Error ? rerun.error.message : String(rerun.error)}\n </p>\n ) : null;\n\n const filterValue: ExecutionFilterValue = {\n status: filters.status,\n kind: filters.kind,\n from: filters.from,\n to: filters.to,\n q,\n };\n\n // A workflow run is the only execution with a visual editor to jump into\n // — a function/endpoint invocation has no such surface.\n const openInEditor =\n selected?.kind === \"workflow\" && onOpenInEditor ? () => onOpenInEditor(selected) : undefined;\n\n if (selected) {\n return (\n <div ref={viewRef}>\n {rerunError}\n {findError && (\n <p className=\"error\" data-testid=\"history-find-error\">\n {findError}\n </p>\n )}\n <ExecutionDetail\n execution={detailQuery.data ?? null}\n loading={detailQuery.isLoading}\n errorMessage={detailQuery.isError ? \"This execution is no longer available.\" : undefined}\n onBack={() => {\n rerun.reset();\n setFindError(null);\n setSelected(null);\n }}\n onOpenExecution={(id) => openOriginal(selected.callableId, id)}\n onRerun={() => startRerun(selected)}\n rerunning={rerunningId !== null}\n onOpenInEditor={openInEditor}\n />\n </div>\n );\n }\n\n return (\n <>\n <ExecutionStats stats={statsQuery.data ?? null} />\n\n <ExecutionFilters showKind={showKind} value={filterValue} onChange={onChange} />\n\n {listQuery.isError && (\n <p className=\"error\" data-testid=\"history-error\">\n Couldn't load execution history.\n </p>\n )}\n\n {rerunError}\n\n <div ref={viewRef}>\n <ExecutionList\n items={executions}\n showCallable={showKind}\n loading={listQuery.isLoading}\n hasPrev={offset > 0}\n hasNext={hasMore}\n onPrev={onPrev}\n onNext={onNext}\n onSelect={onSelect}\n onRerun={(id) => {\n const row = executions.find((r) => r.id === id);\n if (row) startRerun(row);\n }}\n rerunningId={rerunningId}\n />\n </div>\n </>\n );\n}\n","/**\n * The canvas's app lookups, through the host-provided `W6WApi` (`useW6WApi()` — in an embed that\n * is `createW6WUiAdapter`'s, in Studio the facade, which delegates to the same store/repo).\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport { type AppSummary, useW6WApi } from \"@w6w/ui\";\nimport { useMemo } from \"react\";\n\n/** The per-app actions query key — the repos export itself (one declaration, no copy). */\nexport { appActionsKey } from \"../repos/apps.ts\";\n\nconst NO_APPS: ReadonlyMap<string, AppSummary> = new Map();\n\n/** A bounded set of app records by id. Empty when the host's API has no `listAppsByIds`. */\nexport function useEditorApps(ids: readonly string[]): { byId: ReadonlyMap<string, AppSummary> } {\n const api = useW6WApi();\n const list = api.listAppsByIds?.bind(api);\n const key = [...ids].sort().join(\",\");\n const q = useQuery({\n queryKey: [\"editor-apps\", key],\n queryFn: ({ signal }) => (list ? list(ids, { signal }) : Promise.resolve([] as AppSummary[])),\n enabled: ids.length > 0 && typeof list === \"function\",\n });\n const data = q.data;\n const byId = useMemo(\n () => (data ? new Map(data.map((a) => [a.id, a] as const)) : NO_APPS),\n [data],\n );\n return { byId };\n}\n\n/**\n * One app record by id, over {@link useEditorApps} (same `/apps` request, same cache entry as the\n * canvas's batch lookup). `undefined` while loading, for an empty id (which issues no request),\n * or when the host's API cannot look apps up by id.\n */\nexport function useEditorApp(id: string): AppSummary | undefined {\n const { byId } = useEditorApps(id ? [id] : []);\n return id ? byId.get(id) : undefined;\n}\n"],"names":["SEARCH_DEBOUNCE_MS","scrollParent","el","p","overflowY","HistoryView","props","scope","showKind","filters","onFiltersChange","onOpenInEditor","filtersRef","useRef","q","setQ","useState","searchTimer","selected","setSelected","useEffect","listQuery","useHistoryQuery","statsQuery","useHistoryStatsQuery","detailQuery","useExecutionDetailQuery","rerun","useRerunExecutionMutation","findExecution","useFindExecution","findError","setFindError","viewRef","listScroll","selectedId","useLayoutEffect","parent","top","selectedRef","open","useCallback","next","executions","_a","offset","hasMore","_b","applyFilters","onChange","onPrev","HISTORY_PAGE_SIZE","onNext","onSelect","executionId","row","r","startRerun","summary","rerunningId","_c","openOriginal","callableId","id","rerunError","jsxs","filterValue","openInEditor","jsx","ExecutionDetail","Fragment","ExecutionStats","ExecutionFilters","ExecutionList","NO_APPS","useEditorApps","ids","api","useW6WApi","list","key","data","useQuery","signal","useMemo","useEditorApp","byId"],"mappings":"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"}
1
+ {"version":3,"file":"editor-apps-LZmDWMqf.js","sources":["../src/chrome/HistoryView.tsx","../src/editor/editor-apps.ts"],"sourcesContent":["/**\n * `HistoryView` — the execution-history view body (T3.2.1, extracted from\n * `HistoryPage.tsx`'s T2.4.1 shape): stats + filters + paged list, OR the\n * selected execution's detail — never both. Opening a row swaps the list for\n * that execution (with a Back control to return to the list where it was\n * left); it does not stack the detail under a long list, where it lands\n * off-screen. Two hosts mount it — `HistoryPage` (the\n * project-wide and per-callable routes, filters URL-backed) and\n * `HistoryModal` (R-2's in-place modal, filters kept in local state) — so\n * this component owns every judgment call about HOW the view behaves, and\n * takes no position on WHERE its filters live: the host hands down\n * `filters` and gets every change back through `onFiltersChange`, exactly\n * the controlled-value shape `filtersToSearch`/`filtersFromSearch` already\n * assume on the URL-backed side.\n *\n * What stays here, same as it was in `HistoryPage` before the extraction:\n * - the search box's text, debounced, so a keystroke does not re-key and\n * re-issue both queries on every character (`onFiltersChange` — and so\n * the host's own write, URL or local state — fires only once typing\n * settles);\n * - which list row is selected, which is not shareable state and resets on\n * every mount;\n * - re-running an execution (a control on every row and in the detail): the\n * same input, against the callable's current definition. The view then\n * opens the NEW execution, so the outcome is what the author sees next;\n * - every filter change but paging snapping the page back to the first\n * (`offset` 0), because a narrowed result set has no meaningful \"page 3\".\n *\n * `onOpenInEditor`, when given, is called with the selected execution ONLY\n * while it is a workflow run (a function/endpoint invocation has no visual\n * editor to open) — the same gate `HistoryPage.tsx` applied inline before\n * this extraction. A host that never passes it (none of today's two do)\n * simply never sees the call.\n */\nimport {\n type ExecutionSummary,\n HISTORY_PAGE_SIZE,\n type HistoryFilters,\n type HistoryScope,\n useExecutionDetailQuery,\n useFindExecution,\n useHistoryQuery,\n useHistoryStatsQuery,\n useRerunExecutionMutation,\n} from \"@w6w/embed/repos\";\nimport {\n ExecutionDetail,\n type ExecutionFilterValue,\n ExecutionFilters,\n ExecutionList,\n ExecutionStats,\n} from \"@w6w/ui\";\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from \"react\";\n\n/** How long to wait after the last keystroke before `onFiltersChange` fires\n * with the new `q` (and so before either query re-issues with it). */\nconst SEARCH_DEBOUNCE_MS = 300;\n\n/** The nearest ancestor that actually scrolls (the modal body, the app's main\n * pane), or `null` when the document itself does. */\nfunction scrollParent(el: HTMLElement | null): HTMLElement | null {\n for (let p = el?.parentElement ?? null; p; p = p.parentElement) {\n const overflowY = getComputedStyle(p).overflowY;\n if ((overflowY === \"auto\" || overflowY === \"scroll\") && p.scrollHeight > p.clientHeight) {\n return p;\n }\n }\n return null;\n}\n\nexport interface HistoryViewProps {\n /** `null` ⇒ no scope known yet (the project-wide host, before its project\n * resolves) — both queries stay disabled, mirroring `repos/history.ts`'s\n * own `enabled: scope !== null`. */\n scope: HistoryScope | null;\n /** Project-wide chrome: the Kind filter, and the Callable column on every\n * row. A per-callable host (every callable already knows its own kind)\n * passes `false`. */\n showKind: boolean;\n filters: HistoryFilters;\n onFiltersChange: (next: HistoryFilters) => void;\n onOpenInEditor?: (execution: ExecutionSummary) => void;\n}\n\nexport function HistoryView(props: HistoryViewProps) {\n const { scope, showKind, filters, onFiltersChange, onOpenInEditor } = props;\n\n // The debounce below fires outside any render, so it needs the LATEST\n // filters (a status picked while a `q` write was still pending must\n // survive it) rather than the ones captured when typing started.\n const filtersRef = useRef(filters);\n filtersRef.current = filters;\n\n const [q, setQ] = useState(filters.q);\n const searchTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [selected, setSelected] = useState<ExecutionSummary | null>(null);\n\n // Keep the search box in step with `filters.q` when IT moves from outside\n // (Back/Forward or a shared link on the URL-backed host). This never\n // fights a keystroke: an outside `q` only changes once typing has\n // settled, by which point `q` already equals it.\n useEffect(() => {\n setQ(filters.q);\n }, [filters.q]);\n\n // Drop a pending debounce on unmount.\n useEffect(\n () => () => {\n if (searchTimer.current) clearTimeout(searchTimer.current);\n },\n [],\n );\n\n const listQuery = useHistoryQuery(scope, filters);\n const statsQuery = useHistoryStatsQuery(scope, filters);\n const detailQuery = useExecutionDetailQuery(selected);\n const rerun = useRerunExecutionMutation();\n const findExecution = useFindExecution();\n const [findError, setFindError] = useState<string | null>(null);\n\n // Swapping list ⇄ detail keeps the scroll offset of whatever scrolls around\n // this view, which would open a detail scrolled past its own top (the row\n // was clicked far down the list). So: remember the list's offset on the\n // way in, show the detail from its top, and put the list back on the way out.\n const viewRef = useRef<HTMLDivElement>(null);\n const listScroll = useRef<{ parent: HTMLElement | null; top: number } | null>(null);\n const selectedId = selected?.id ?? null;\n useLayoutEffect(() => {\n const el = viewRef.current;\n if (!el) return;\n if (selectedId !== null) {\n const parent = scrollParent(el);\n if (parent) parent.scrollTop = 0;\n else if (el.getBoundingClientRect().top < 0) el.scrollIntoView?.({ block: \"start\" });\n } else if (listScroll.current) {\n const { parent, top } = listScroll.current;\n listScroll.current = null;\n if (parent) parent.scrollTop = top;\n else window.scrollTo(0, top);\n }\n }, [selectedId]);\n\n const selectedRef = useRef(selected);\n selectedRef.current = selected;\n const open = useCallback((next: ExecutionSummary) => {\n // Leaving the LIST (not one detail for another, as a re-run from the detail does).\n if (selectedRef.current === null) {\n const parent = scrollParent(viewRef.current);\n listScroll.current = { parent, top: parent ? parent.scrollTop : window.scrollY };\n }\n setSelected(next);\n }, []);\n\n const executions = listQuery.data?.executions ?? [];\n const offset = filters.offset;\n const hasMore = listQuery.data?.hasMore ?? false;\n\n /** Every filter change but paging reports a fresh filter set and resets\n * the page to the first. */\n const applyFilters = (next: ExecutionFilterValue) => {\n onFiltersChange({ ...next, offset: 0 });\n };\n\n const onChange = (next: ExecutionFilterValue) => {\n if (next.q === q) {\n applyFilters(next);\n return;\n }\n setQ(next.q);\n if (searchTimer.current) clearTimeout(searchTimer.current);\n searchTimer.current = setTimeout(() => {\n searchTimer.current = null;\n onFiltersChange({ ...filtersRef.current, q: next.q, offset: 0 });\n }, SEARCH_DEBOUNCE_MS);\n };\n\n const onPrev = () =>\n onFiltersChange({ ...filters, q, offset: Math.max(0, offset - HISTORY_PAGE_SIZE) });\n const onNext = () => onFiltersChange({ ...filters, q, offset: offset + HISTORY_PAGE_SIZE });\n\n const onSelect = useCallback(\n (executionId: string) => {\n const row = executions.find((r) => r.id === executionId);\n if (row) open(row);\n },\n [executions, open],\n );\n\n /** Re-run one execution, then open the new one — or, when it is not listed\n * yet, fall back to the (refreshed) list. */\n const startRerun = (summary: ExecutionSummary) => {\n rerun.mutate(summary, {\n onSuccess: (next) => {\n if (next) open(next);\n else setSelected(null);\n },\n });\n };\n const rerunningId = rerun.isPending ? (rerun.variables?.id ?? null) : null;\n\n /** \"Re-run of <id>\": open the original, from the callable this one belongs to. */\n const openOriginal = (callableId: string, id: string) => {\n setFindError(null);\n findExecution(callableId, id)\n .then((row) => {\n if (row) open(row);\n else setFindError(`${id} is no longer available.`);\n })\n .catch(() => setFindError(`Couldn't open ${id}.`));\n };\n const rerunError = rerun.isError ? (\n <p className=\"error\" data-testid=\"history-rerun-error\">\n Couldn't re-run: {rerun.error instanceof Error ? rerun.error.message : String(rerun.error)}\n </p>\n ) : null;\n\n const filterValue: ExecutionFilterValue = {\n status: filters.status,\n kind: filters.kind,\n from: filters.from,\n to: filters.to,\n q,\n };\n\n // A workflow run is the only execution with a visual editor to jump into\n // — a function/endpoint invocation has no such surface.\n const openInEditor =\n selected?.kind === \"workflow\" && onOpenInEditor ? () => onOpenInEditor(selected) : undefined;\n\n if (selected) {\n return (\n <div ref={viewRef}>\n {rerunError}\n {findError && (\n <p className=\"error\" data-testid=\"history-find-error\">\n {findError}\n </p>\n )}\n <ExecutionDetail\n execution={detailQuery.data ?? null}\n loading={detailQuery.isLoading}\n errorMessage={detailQuery.isError ? \"This execution is no longer available.\" : undefined}\n onBack={() => {\n rerun.reset();\n setFindError(null);\n setSelected(null);\n }}\n onOpenExecution={(id) => openOriginal(selected.callableId, id)}\n onRerun={() => startRerun(selected)}\n rerunning={rerunningId !== null}\n onOpenInEditor={openInEditor}\n />\n </div>\n );\n }\n\n return (\n <>\n <ExecutionStats stats={statsQuery.data ?? null} />\n\n <ExecutionFilters showKind={showKind} value={filterValue} onChange={onChange} />\n\n {listQuery.isError && (\n <p className=\"error\" data-testid=\"history-error\">\n Couldn't load execution history.\n </p>\n )}\n\n {rerunError}\n\n <div ref={viewRef}>\n <ExecutionList\n items={executions}\n showCallable={showKind}\n loading={listQuery.isLoading}\n hasPrev={offset > 0}\n hasNext={hasMore}\n onPrev={onPrev}\n onNext={onNext}\n onSelect={onSelect}\n onRerun={(id) => {\n const row = executions.find((r) => r.id === id);\n if (row) startRerun(row);\n }}\n rerunningId={rerunningId}\n />\n </div>\n </>\n );\n}\n","/**\n * The canvas's app lookups, through the host-provided `W6WApi` (`useW6WApi()` — in an embed that\n * is `createW6WUiAdapter`'s, in Studio the facade, which delegates to the same store/repo).\n */\nimport { useQuery } from \"@tanstack/react-query\";\nimport { type AppSummary, useW6WApi } from \"@w6w/ui\";\nimport { useMemo } from \"react\";\n\n/** The per-app actions query key — the repos export itself (one declaration, no copy). */\nexport { appActionsKey } from \"../repos/apps.ts\";\n\nconst NO_APPS: ReadonlyMap<string, AppSummary> = new Map();\n\n/** A bounded set of app records by id. Empty when the host's API has no `listAppsByIds`. */\nexport function useEditorApps(ids: readonly string[]): { byId: ReadonlyMap<string, AppSummary> } {\n const api = useW6WApi();\n const list = api.listAppsByIds?.bind(api);\n const key = [...ids].sort().join(\",\");\n const q = useQuery({\n queryKey: [\"editor-apps\", key],\n queryFn: ({ signal }) => (list ? list(ids, { signal }) : Promise.resolve([] as AppSummary[])),\n enabled: ids.length > 0 && typeof list === \"function\",\n });\n const data = q.data;\n const byId = useMemo(\n () => (data ? new Map(data.map((a) => [a.id, a] as const)) : NO_APPS),\n [data],\n );\n return { byId };\n}\n\n/**\n * One app record by id, over {@link useEditorApps} (same `/apps` request, same cache entry as the\n * canvas's batch lookup). `undefined` while loading, for an empty id (which issues no request),\n * or when the host's API cannot look apps up by id.\n */\nexport function useEditorApp(id: string): AppSummary | undefined {\n const { byId } = useEditorApps(id ? [id] : []);\n return id ? byId.get(id) : undefined;\n}\n"],"names":["SEARCH_DEBOUNCE_MS","scrollParent","el","p","overflowY","HistoryView","props","scope","showKind","filters","onFiltersChange","onOpenInEditor","filtersRef","useRef","q","setQ","useState","searchTimer","selected","setSelected","useEffect","listQuery","useHistoryQuery","statsQuery","useHistoryStatsQuery","detailQuery","useExecutionDetailQuery","rerun","useRerunExecutionMutation","findExecution","useFindExecution","findError","setFindError","viewRef","listScroll","selectedId","useLayoutEffect","parent","top","selectedRef","open","useCallback","next","executions","_a","offset","hasMore","_b","applyFilters","onChange","onPrev","HISTORY_PAGE_SIZE","onNext","onSelect","executionId","row","r","startRerun","summary","rerunningId","_c","openOriginal","callableId","id","rerunError","jsxs","filterValue","openInEditor","jsx","ExecutionDetail","Fragment","ExecutionStats","ExecutionFilters","ExecutionList","NO_APPS","useEditorApps","ids","api","useW6WApi","list","key","data","useQuery","signal","useMemo","useEditorApp","byId"],"mappings":"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"}
@@ -1,18 +1,18 @@
1
1
  import { jsx as n, jsxs as r, Fragment as j } from "react/jsx-runtime";
2
2
  import { r as Cn, l as je, m as Ve, d as De, e as En, h as Oe, c as An } from "./import-bindings-EUtxZ9Ti.js";
3
3
  import { useContext as ve, useState as u, useMemo as Qe, useEffect as be, createContext as We, useRef as Fe } from "react";
4
- import { ExpressionOptionsProvider as He, Icon as K, RetryPolicyFields as Pn, StepBuilderModal as In, IconButton as we, useEnterSubmit as Tn, CodeBlock as pe, DeleteButton as Dn, EditButton as On, ConfirmModal as Re, JsonEditor as Rn, useExpressionOptions as Mn, ExpressionInput as Ln, ResultViewer as jn } from "@w6w/ui";
4
+ import { ExpressionOptionsProvider as He, Icon as q, RetryPolicyFields as Pn, StepBuilderModal as In, IconButton as we, useEnterSubmit as Tn, CodeBlock as pe, DeleteButton as Dn, EditButton as On, ConfirmModal as Re, JsonEditor as Rn, useExpressionOptions as Mn, ExpressionInput as Ln, ResultViewer as jn } from "@w6w/ui";
5
5
  import { d as Vn, p as Qn, i as Wn, t as Fn, e as Me, a as Hn, h as $n, s as Bn } from "./document-sources-DNmBojx6.js";
6
- import { u as Jn, g as qn, d as Kn, a as Un, f as $e, h as Be, b as Je, e as qe } from "./spec-export-DGy5ijps.js";
6
+ import { u as Jn, g as Kn, d as qn, a as Un, f as $e, h as Be, b as Je, e as Ke } from "./spec-export-DGigBUsP.js";
7
7
  import { i as _n, f as zn, e as Gn, b as Yn, u as Zn } from "./vault-BSEWhMYC.js";
8
8
  import { k as Xn } from "./spec-import-SWOonsNr.js";
9
- import { s as xn, M as q, b as et, C as nt } from "./ConfirmModal-Pv2-A_3U.js";
9
+ import { s as xn, M as K, b as et, C as nt } from "./ConfirmModal-Pv2-A_3U.js";
10
10
  import { u as tt, i as it, f as st } from "./slug-BVdgiP_L.js";
11
11
  import { WorkflowConnectionsPanel as at } from "@w6w/ui/flow";
12
12
  import { ApiError as L } from "@w6w/sdk";
13
- import { i as rt, p as Ke, c as Ue, d as ot } from "./settings-rail--GdRMusb.js";
13
+ import { i as rt, p as qe, c as Ue, d as ot } from "./settings-rail--GdRMusb.js";
14
14
  import { w as _e, v as ze, y as Ge, x as Ye, b as Ze, d as lt, f as dt, h as ct, u as ut, t as ht, s as ft, r as mt, q as gt } from "./endpoints-DSRo1Lc5.js";
15
- import { a1 as Xe, a0 as pt, _ as vt, P as bt, U as yt, a3 as kt, Z as wt, V as Nt, X as St, K as Ct, I as Et } from "./workflows-BZN4Hyz1.js";
15
+ import { a1 as Xe, a0 as pt, _ as vt, P as bt, U as yt, a3 as kt, Z as wt, V as Nt, X as St, K as Ct, I as Et } from "./workflows-BK6IM4if.js";
16
16
  import { I as xe } from "./ImportSpecModal-Cpzp8ndt.js";
17
17
  import { useQueryClient as At } from "@tanstack/react-query";
18
18
  import { foldStateLog as Pt } from "@w6w/expr";
@@ -185,17 +185,17 @@ function Rt({ ctx: e }) {
185
185
  "aria-label": `Show the ${c} snippet`,
186
186
  onClick: () => i(o),
187
187
  children: [
188
- /* @__PURE__ */ n(K, { name: h, size: 20 }),
188
+ /* @__PURE__ */ n(q, { name: h, size: 20 }),
189
189
  /* @__PURE__ */ n("span", { children: c })
190
190
  ]
191
191
  },
192
192
  o
193
193
  )) }),
194
- t !== null && /* @__PURE__ */ n(q, { title: "Call from code", wide: !0, onClose: () => i(null), children: /* @__PURE__ */ n("div", { style: { height: 450 }, children: /* @__PURE__ */ n(et, { resource: s, triggers: a, initialTab: t }) }) })
194
+ t !== null && /* @__PURE__ */ n(K, { title: "Call from code", wide: !0, onClose: () => i(null), children: /* @__PURE__ */ n("div", { style: { height: 450 }, children: /* @__PURE__ */ n(et, { resource: s, triggers: a, initialTab: t }) }) })
195
195
  ] });
196
196
  }
197
197
  function Mt() {
198
- return /* @__PURE__ */ n(K, { name: "code" });
198
+ return /* @__PURE__ */ n(q, { name: "code" });
199
199
  }
200
200
  const Lt = {
201
201
  id: "code",
@@ -207,7 +207,7 @@ const Lt = {
207
207
  id: "connections",
208
208
  title: "Connections",
209
209
  rendersHeading: !0,
210
- Icon: () => /* @__PURE__ */ n(K, { name: "plug" }),
210
+ Icon: () => /* @__PURE__ */ n(q, { name: "plug" }),
211
211
  isAvailable: (e) => (e == null ? void 0 : e.kind) === "workflow" && !!e.connectionResources,
212
212
  hasIndicator: (e) => {
213
213
  var t;
@@ -363,7 +363,7 @@ function Ft({ ctx: e }) {
363
363
  {
364
364
  kind: e.kind,
365
365
  id: e.id,
366
- policy: t ? Ke(t) : {},
366
+ policy: t ? qe(t) : {},
367
367
  ready: !!i,
368
368
  saving: !1,
369
369
  onPersist: (s) => i == null ? void 0 : i(s)
@@ -377,7 +377,7 @@ function Ht({ id: e, kind: t }) {
377
377
  {
378
378
  kind: t,
379
379
  id: e,
380
- policy: o ? Ke(o.definition) : {},
380
+ policy: o ? qe(o.definition) : {},
381
381
  ready: !!o,
382
382
  saving: c,
383
383
  onPersist: (h, d) => {
@@ -397,7 +397,7 @@ function $t({ ctx: e }) {
397
397
  return (e == null ? void 0 : e.kind) !== "workflow" && (e == null ? void 0 : e.kind) !== "function" && (e == null ? void 0 : e.kind) !== "endpoint" ? null : e.kind === "workflow" || typeof e.onPolicyChange == "function" ? /* @__PURE__ */ n(Ft, { ctx: e }) : /* @__PURE__ */ n(Ht, { id: e.id, kind: e.kind });
398
398
  }
399
399
  function Bt() {
400
- return /* @__PURE__ */ n(K, { name: "warning" });
400
+ return /* @__PURE__ */ n(q, { name: "warning" });
401
401
  }
402
402
  const Jt = {
403
403
  id: "error-handling",
@@ -405,17 +405,17 @@ const Jt = {
405
405
  Icon: Bt,
406
406
  isAvailable: (e) => rt(e),
407
407
  Panel: $t
408
- }, qt = {
408
+ }, Kt = {
409
409
  id: "history",
410
410
  title: "Execution history",
411
- Icon: () => /* @__PURE__ */ n(K, { name: "history" }),
411
+ Icon: () => /* @__PURE__ */ n(q, { name: "history" }),
412
412
  isAvailable: (e) => (e == null ? void 0 : e.kind) === "workflow" && !!e.onOpenHistory,
413
413
  onActivate: (e) => {
414
414
  var t;
415
415
  (e == null ? void 0 : e.kind) === "workflow" && ((t = e.onOpenHistory) == null || t.call(e));
416
416
  }
417
417
  };
418
- function Kt(e, t) {
418
+ function qt(e, t) {
419
419
  if (!t.includes(",")) return { tags: e, typed: t };
420
420
  let i = e;
421
421
  for (const s of t.split(",")) {
@@ -430,7 +430,7 @@ function Ut(e, t) {
430
430
  function _t({ tags: e, onChange: t }) {
431
431
  const [i, s] = u("");
432
432
  function a(l) {
433
- const o = Kt(e, l);
433
+ const o = qt(e, l);
434
434
  s(o.typed), o.tags !== e && t(o.tags);
435
435
  }
436
436
  return /* @__PURE__ */ r("div", { className: "tag-list", "data-testid": "tag-editor", children: [
@@ -478,7 +478,7 @@ function rn(e) {
478
478
  }
479
479
  }
480
480
  const V = Tn(M, { enabled: y });
481
- return /* @__PURE__ */ r(q, { title: "Edit settings", onClose: e.onClose, children: [
481
+ return /* @__PURE__ */ r(K, { title: "Edit settings", onClose: e.onClose, children: [
482
482
  /* @__PURE__ */ r("div", { className: "modal-body", children: [
483
483
  /* @__PURE__ */ r("label", { className: "field", children: [
484
484
  /* @__PURE__ */ n("span", { children: "Name" }),
@@ -550,9 +550,9 @@ const zt = {
550
550
  }
551
551
  };
552
552
  function on(e) {
553
- const { kind: t, id: i, versionNumber: s } = e, a = zt[t], l = qn(t, i, s, !0), o = Kn(t), c = Un(t), [h, d] = u(!1), [v, b] = u(null);
553
+ const { kind: t, id: i, versionNumber: s } = e, a = zt[t], l = Kn(t, i, s, !0), o = qn(t), c = Un(t), [h, d] = u(!1), [v, b] = u(null);
554
554
  return /* @__PURE__ */ r(j, { children: [
555
- /* @__PURE__ */ r(q, { title: `Version ${s}`, onClose: e.onClose, wide: !0, children: [
555
+ /* @__PURE__ */ r(K, { title: `Version ${s}`, onClose: e.onClose, wide: !0, children: [
556
556
  /* @__PURE__ */ r("div", { className: "modal-body", children: [
557
557
  l.isLoading ? /* @__PURE__ */ n("p", { className: "muted small", children: "Loading…" }) : l.isError ? /* @__PURE__ */ n("div", { className: "error", "data-testid": a.error, children: l.error instanceof Error ? l.error.message : String(l.error) }) : l.data ? /* @__PURE__ */ n("div", { "data-testid": a.json, children: /* @__PURE__ */ n(
558
558
  pe,
@@ -721,7 +721,7 @@ function cn(e) {
721
721
  }
722
722
  function un(e) {
723
723
  const { kind: t, children: i, onImport: s, onClose: a } = e;
724
- return /* @__PURE__ */ r(q, { title: "Definition", onClose: a, children: [
724
+ return /* @__PURE__ */ r(K, { title: "Definition", onClose: a, children: [
725
725
  /* @__PURE__ */ r("div", { className: "modal-body", children: [
726
726
  i,
727
727
  /* @__PURE__ */ r("p", { className: "muted small", children: [
@@ -762,7 +762,7 @@ function hn(e) {
762
762
  title: "Version history",
763
763
  onClick: e.onShow,
764
764
  children: [
765
- /* @__PURE__ */ n(K, { name: "clock", size: 14 }),
765
+ /* @__PURE__ */ n(q, { name: "clock", size: 14 }),
766
766
  /* @__PURE__ */ n("span", { children: "Version history" })
767
767
  ]
768
768
  }
@@ -801,7 +801,7 @@ function hn(e) {
801
801
  }
802
802
  function fn(e) {
803
803
  const { loading: t, versions: i } = e;
804
- return /* @__PURE__ */ r(q, { title: "All versions", onClose: e.onClose, wide: !0, children: [
804
+ return /* @__PURE__ */ r(K, { title: "All versions", onClose: e.onClose, wide: !0, children: [
805
805
  /* @__PURE__ */ r("div", { className: "modal-body", children: [
806
806
  t && /* @__PURE__ */ n("p", { className: "muted small", children: "Loading…" }),
807
807
  (i == null ? void 0 : i.length) === 0 && /* @__PURE__ */ n("p", { className: "muted small", children: "No versions yet." }),
@@ -913,7 +913,7 @@ function Zt({
913
913
  setHistoryOpen: c,
914
914
  versionListOpen: h,
915
915
  setVersionListOpen: d
916
- } = s, v = Xe(t ?? void 0), b = (e == null ? void 0 : e.kind) === "workflow", m = (e == null ? void 0 : e.id) ?? "", C = pt(m, b), k = vt(t ?? void 0), D = bt(), O = yt(), E = Fe(!1), [R, y] = u(!1), [M, V] = u(!1), [N, p] = u(!1), [P, $] = u(!1), [U, Q] = u(!1), [W, re] = u(null), [_, oe] = u(null), F = $e(je("workflow"), m, N), z = Be("workflow", m, o && b), ne = Je("workflow"), le = qe("workflow"), [ke, G] = u(null), [te, de] = u(null), [ie, ce] = u(
916
+ } = s, v = Xe(t ?? void 0), b = (e == null ? void 0 : e.kind) === "workflow", m = (e == null ? void 0 : e.id) ?? "", C = pt(m, b), k = vt(t ?? void 0), D = bt(), O = yt(), E = Fe(!1), [R, y] = u(!1), [M, V] = u(!1), [N, p] = u(!1), [P, $] = u(!1), [U, Q] = u(!1), [W, re] = u(null), [_, oe] = u(null), F = $e(je("workflow"), m, N), z = Be("workflow", m, o && b), ne = Je("workflow"), le = Ke("workflow"), [ke, G] = u(null), [te, de] = u(null), [ie, ce] = u(
917
917
  null
918
918
  );
919
919
  if (!e || e.kind !== "workflow")
@@ -1060,7 +1060,7 @@ function Zt({
1060
1060
  ]
1061
1061
  }
1062
1062
  ),
1063
- N && /* @__PURE__ */ r(q, { title: "Export spec document", onClose: () => p(!1), wide: !0, children: [
1063
+ N && /* @__PURE__ */ r(K, { title: "Export spec document", onClose: () => p(!1), wide: !0, children: [
1064
1064
  /* @__PURE__ */ n("div", { className: "modal-body", children: F.isLoading ? /* @__PURE__ */ n("p", { className: "muted small", children: "Loading…" }) : F.isError ? /* @__PURE__ */ n("div", { className: "error", "data-testid": "rail-spec-error", children: F.error instanceof Error ? F.error.message : String(F.error) }) : F.data ? /* @__PURE__ */ n("div", { "data-testid": "rail-spec-json", children: /* @__PURE__ */ n(
1065
1065
  pe,
1066
1066
  {
@@ -1155,7 +1155,7 @@ function xt({
1155
1155
  setHistoryOpen: c,
1156
1156
  versionListOpen: h,
1157
1157
  setVersionListOpen: d
1158
- } = s, v = e == null ? void 0 : e.kind, b = ut(v === "endpoint"), m = Ze(v === "function"), [C, k] = u(!1), [D, O] = u(""), [E, R] = u(null), [y, M] = u(null), [V, N] = u(!1), [p, P] = u(!1), [$, U] = u(!1), [Q, W] = u(!1), [re, _] = u(!1), [oe, F] = u(null), [z, ne] = u(null), le = _e((e == null ? void 0 : e.id) ?? "", (e == null ? void 0 : e.kind) === "function"), ke = ze((e == null ? void 0 : e.id) ?? "", (e == null ? void 0 : e.kind) === "endpoint"), G = Ge(), te = Ye(), de = ht(), ie = ft(), ce = mt(), I = gt(), ue = e ? je(e.kind) : null, H = $e(ue, (e == null ? void 0 : e.id) ?? "", p), Y = e && De(e.kind) ? e.kind : null, Z = Be(Y, (e == null ? void 0 : e.id) ?? "", o), he = Je(Y ?? "function"), se = qe(Y ?? "function"), [fe, f] = u(null), [A, me] = u(null), [ae, X] = u(
1158
+ } = s, v = e == null ? void 0 : e.kind, b = ut(v === "endpoint"), m = Ze(v === "function"), [C, k] = u(!1), [D, O] = u(""), [E, R] = u(null), [y, M] = u(null), [V, N] = u(!1), [p, P] = u(!1), [$, U] = u(!1), [Q, W] = u(!1), [re, _] = u(!1), [oe, F] = u(null), [z, ne] = u(null), le = _e((e == null ? void 0 : e.id) ?? "", (e == null ? void 0 : e.kind) === "function"), ke = ze((e == null ? void 0 : e.id) ?? "", (e == null ? void 0 : e.kind) === "endpoint"), G = Ge(), te = Ye(), de = ht(), ie = ft(), ce = mt(), I = gt(), ue = e ? je(e.kind) : null, H = $e(ue, (e == null ? void 0 : e.id) ?? "", p), Y = e && De(e.kind) ? e.kind : null, Z = Be(Y, (e == null ? void 0 : e.id) ?? "", o), he = Je(Y ?? "function"), se = Ke(Y ?? "function"), [fe, f] = u(null), [A, me] = u(null), [ae, X] = u(
1159
1159
  null
1160
1160
  );
1161
1161
  if (!e || e.kind !== "function" && e.kind !== "endpoint")
@@ -1296,7 +1296,7 @@ function xt({
1296
1296
  ] })
1297
1297
  }
1298
1298
  ),
1299
- p && /* @__PURE__ */ r(q, { title: "Export spec document", onClose: () => P(!1), wide: !0, children: [
1299
+ p && /* @__PURE__ */ r(K, { title: "Export spec document", onClose: () => P(!1), wide: !0, children: [
1300
1300
  /* @__PURE__ */ n("div", { className: "modal-body", children: H.isLoading ? /* @__PURE__ */ n("p", { className: "muted small", children: "Loading…" }) : H.isError ? /* @__PURE__ */ n("div", { className: "error", "data-testid": "rail-spec-error", children: H.error instanceof Error ? H.error.message : String(H.error) }) : H.data ? /* @__PURE__ */ n("div", { "data-testid": "rail-spec-json", children: /* @__PURE__ */ n(
1301
1301
  pe,
1302
1302
  {
@@ -1308,7 +1308,7 @@ function xt({
1308
1308
  ) }) : null }),
1309
1309
  /* @__PURE__ */ n("div", { className: "modal-actions", children: /* @__PURE__ */ n("button", { type: "button", className: "btn ghost", onClick: () => P(!1), children: "Close" }) })
1310
1310
  ] }),
1311
- C && /* @__PURE__ */ r(q, { title: "Edit definition", onClose: () => k(!1), wide: !0, children: [
1311
+ C && /* @__PURE__ */ r(K, { title: "Edit definition", onClose: () => k(!1), wide: !0, children: [
1312
1312
  /* @__PURE__ */ r("div", { className: "modal-body", children: [
1313
1313
  /* @__PURE__ */ n(
1314
1314
  Rn,
@@ -1393,7 +1393,7 @@ function xt({
1393
1393
  ] });
1394
1394
  }
1395
1395
  function ei() {
1396
- return /* @__PURE__ */ n(K, { name: "settings" });
1396
+ return /* @__PURE__ */ n(q, { name: "settings" });
1397
1397
  }
1398
1398
  const ni = {
1399
1399
  id: "settings",
@@ -1428,6 +1428,12 @@ function ii({
1428
1428
  /* @__PURE__ */ n("span", { className: "muted small", children: e.length === 0 ? "No variables declared." : `${e.length} variable${e.length === 1 ? "" : "s"} declared.` }),
1429
1429
  /* @__PURE__ */ n("button", { type: "button", className: "btn ghost", onClick: s, children: "+ Add variable" })
1430
1430
  ] }),
1431
+ e.length > 0 && /* @__PURE__ */ r("div", { className: "workflow-variable-head", "aria-hidden": "true", children: [
1432
+ /* @__PURE__ */ n("span", { children: "Key" }),
1433
+ /* @__PURE__ */ n("span", { children: "Type" }),
1434
+ /* @__PURE__ */ n("span", {}),
1435
+ /* @__PURE__ */ n("span", {})
1436
+ ] }),
1431
1437
  e.length > 0 && /* @__PURE__ */ n("ul", { className: "list", "data-testid": "workflow-variables-list", children: e.map((c, h) => /* @__PURE__ */ r(
1432
1438
  "li",
1433
1439
  {
@@ -1473,6 +1479,18 @@ function ii({
1473
1479
  ),
1474
1480
  /* @__PURE__ */ n("span", { className: "muted small", children: "required" })
1475
1481
  ] }),
1482
+ /* @__PURE__ */ n(
1483
+ we,
1484
+ {
1485
+ danger: !0,
1486
+ icon: "close",
1487
+ label: `Remove variable ${c.key || h + 1}`,
1488
+ onClick: () => l(h)
1489
+ }
1490
+ )
1491
+ ] }),
1492
+ /* @__PURE__ */ r("div", { className: "workflow-variable-default", children: [
1493
+ /* @__PURE__ */ n("span", { className: "muted small", children: "Default" }),
1476
1494
  /* @__PURE__ */ n(
1477
1495
  He,
1478
1496
  {
@@ -1488,15 +1506,6 @@ function ii({
1488
1506
  `${e.length}:${h}`
1489
1507
  )
1490
1508
  }
1491
- ),
1492
- /* @__PURE__ */ n(
1493
- we,
1494
- {
1495
- danger: !0,
1496
- icon: "close",
1497
- label: `Remove variable ${c.key || h + 1}`,
1498
- onClick: () => l(h)
1499
- }
1500
1509
  )
1501
1510
  ] }),
1502
1511
  o.includes(h) && /* @__PURE__ */ n("span", { className: "muted small", "data-testid": "variable-duplicate", children: "Duplicate key — a later row with the same name wins." })
@@ -1547,7 +1556,7 @@ function li(e) {
1547
1556
  return (e == null ? void 0 : e.kind) === "workflow" ? e.onOpenStartingState : void 0;
1548
1557
  }
1549
1558
  function di() {
1550
- return /* @__PURE__ */ n(K, { name: "database" });
1559
+ return /* @__PURE__ */ n(q, { name: "database" });
1551
1560
  }
1552
1561
  function ci({ ctx: e }) {
1553
1562
  var k, D, O, E, R;
@@ -1666,7 +1675,7 @@ const fi = {
1666
1675
  Jt,
1667
1676
  fi,
1668
1677
  jt,
1669
- qt
1678
+ Kt
1670
1679
  ];
1671
1680
  export {
1672
1681
  Qt as C,
@@ -1680,4 +1689,4 @@ export {
1680
1689
  Wi as e,
1681
1690
  It as u
1682
1691
  };
1683
- //# sourceMappingURL=editor-tools-BR27RGto.js.map
1692
+ //# sourceMappingURL=editor-tools-DHyWiG21.js.map