@w6w/embed 0.2.20 → 0.2.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{WorkflowEditor-CmhXHRxi.js → WorkflowEditor-Cgv3Pvsy.js} +194 -186
- package/dist/{WorkflowEditor-CmhXHRxi.js.map → WorkflowEditor-Cgv3Pvsy.js.map} +1 -1
- package/dist/{apps-ItBvnWX3.js → apps-CYUgEfGf.js} +2 -2
- package/dist/{apps-ItBvnWX3.js.map → apps-CYUgEfGf.js.map} +1 -1
- package/dist/editor/types.d.ts +2 -0
- package/dist/{editor-apps-DkkC7wOQ.js → editor-apps-LZmDWMqf.js} +3 -3
- package/dist/{editor-apps-DkkC7wOQ.js.map → editor-apps-LZmDWMqf.js.map} +1 -1
- package/dist/{editor-tools-BR27RGto.js → editor-tools-j3ThBY_4.js} +3 -3
- package/dist/{editor-tools-BR27RGto.js.map → editor-tools-j3ThBY_4.js.map} +1 -1
- package/dist/editor.mjs +1 -1
- package/dist/editors.mjs +7 -7
- package/dist/index.mjs +1 -1
- package/dist/lists.mjs +3 -3
- package/dist/rail.mjs +1 -1
- package/dist/repos/workflows.d.ts +1 -1
- package/dist/repos.mjs +3 -3
- package/dist/{spec-export-DGy5ijps.js → spec-export-DGigBUsP.js} +2 -2
- package/dist/{spec-export-DGy5ijps.js.map → spec-export-DGigBUsP.js.map} +1 -1
- package/dist/{workflows-BZN4Hyz1.js → workflows-BK6IM4if.js} +3 -3
- package/dist/{workflows-BZN4Hyz1.js.map → workflows-BK6IM4if.js.map} +1 -1
- package/package.json +3 -3
|
@@ -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-
|
|
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-
|
|
92
|
+
//# sourceMappingURL=apps-CYUgEfGf.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps-
|
|
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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"}
|
package/dist/editor/types.d.ts
CHANGED
|
@@ -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-
|
|
3
|
-
import { H as _ } from "./workflows-
|
|
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-
|
|
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":";;;;;;AAwDA,MAAMA,KAAqB;AAI3B,SAASC,EAAaC,GAA4C;AAChE,WAASC,KAAID,KAAA,gBAAAA,EAAI,kBAAiB,MAAMC,GAAGA,IAAIA,EAAE,eAAe;AAC9D,UAAMC,IAAY,iBAAiBD,CAAC,EAAE;AACtC,SAAKC,MAAc,UAAUA,MAAc,aAAaD,EAAE,eAAeA,EAAE;AACzE,aAAOA;AAAA,EAEX;AACA,SAAO;AACT;AAgBO,SAASE,GAAYC,GAAyB;;AACnD,QAAM,EAAE,OAAAC,GAAO,UAAAC,GAAU,SAAAC,GAAS,iBAAAC,GAAiB,gBAAAC,MAAmBL,GAKhEM,IAAaC,EAAOJ,CAAO;AACjC,EAAAG,EAAW,UAAUH;AAErB,QAAM,CAACK,GAAGC,CAAI,IAAIC,EAASP,EAAQ,CAAC,GAC9BQ,IAAcJ,EAA6C,IAAI,GAC/D,CAACK,GAAUC,CAAW,IAAIH,EAAkC,IAAI;AAMtE,EAAAI,EAAU,MAAM;AACd,IAAAL,EAAKN,EAAQ,CAAC;AAAA,EAChB,GAAG,CAACA,EAAQ,CAAC,CAAC,GAGdW;AAAA,IACE,MAAM,MAAM;AACV,MAAIH,EAAY,WAAS,aAAaA,EAAY,OAAO;AAAA,IAC3D;AAAA,IACA,CAAA;AAAA,EAAC;AAGH,QAAMI,IAAYC,GAAgBf,GAAOE,CAAO,GAC1Cc,IAAaC,GAAqBjB,GAAOE,CAAO,GAChDgB,IAAcC,GAAwBR,CAAQ,GAC9CS,IAAQC,GAAA,GACRC,IAAgBC,GAAA,GAChB,CAACC,GAAWC,CAAY,IAAIhB,EAAwB,IAAI,GAMxDiB,IAAUpB,EAAuB,IAAI,GACrCqB,IAAarB,EAA2D,IAAI,GAC5EsB,KAAajB,KAAA,gBAAAA,EAAU,OAAM;AACnC,EAAAkB,GAAgB,MAAM;;AACpB,UAAMlC,IAAK+B,EAAQ;AACnB,QAAK/B;AACL,UAAIiC,MAAe,MAAM;AACvB,cAAME,IAASpC,EAAaC,CAAE;AAC9B,QAAImC,MAAe,YAAY,IACtBnC,EAAG,sBAAA,EAAwB,MAAM,aAAM,qCAAiB,EAAE,OAAO;MAC5E,WAAWgC,EAAW,SAAS;AAC7B,cAAM,EAAE,QAAAG,GAAQ,KAAAC,EAAA,IAAQJ,EAAW;AACnC,QAAAA,EAAW,UAAU,MACjBG,MAAe,YAAYC,IAC1B,OAAO,SAAS,GAAGA,CAAG;AAAA,MAC7B;AAAA;AAAA,EACF,GAAG,CAACH,CAAU,CAAC;AAEf,QAAMI,IAAc1B,EAAOK,CAAQ;AACnC,EAAAqB,EAAY,UAAUrB;AACtB,QAAMsB,IAAOC,EAAY,CAACC,MAA2B;AAEnD,QAAIH,EAAY,YAAY,MAAM;AAChC,YAAMF,IAASpC,EAAagC,EAAQ,OAAO;AAC3C,MAAAC,EAAW,UAAU,EAAE,QAAAG,GAAQ,KAAKA,IAASA,EAAO,YAAY,OAAO,QAAA;AAAA,IACzE;AACA,IAAAlB,EAAYuB,CAAI;AAAA,EAClB,GAAG,CAAA,CAAE,GAECC,MAAaC,IAAAvB,EAAU,SAAV,gBAAAuB,EAAgB,eAAc,CAAA,GAC3CC,IAASpC,EAAQ,QACjBqC,MAAUC,IAAA1B,EAAU,SAAV,gBAAA0B,EAAgB,YAAW,IAIrCC,IAAe,CAACN,MAA+B;AACnD,IAAAhC,EAAgB,EAAE,GAAGgC,GAAM,QAAQ,GAAG;AAAA,EACxC,GAEMO,IAAW,CAACP,MAA+B;AAC/C,QAAIA,EAAK,MAAM5B,GAAG;AAChB,MAAAkC,EAAaN,CAAI;AACjB;AAAA,IACF;AACA,IAAA3B,EAAK2B,EAAK,CAAC,GACPzB,EAAY,WAAS,aAAaA,EAAY,OAAO,GACzDA,EAAY,UAAU,WAAW,MAAM;AACrC,MAAAA,EAAY,UAAU,MACtBP,EAAgB,EAAE,GAAGE,EAAW,SAAS,GAAG8B,EAAK,GAAG,QAAQ,GAAG;AAAA,IACjE,GAAG1C,EAAkB;AAAA,EACvB,GAEMkD,IAAS,MACbxC,EAAgB,EAAE,GAAGD,GAAS,GAAAK,GAAG,QAAQ,KAAK,IAAI,GAAG+B,IAASM,CAAiB,GAAG,GAC9EC,IAAS,MAAM1C,EAAgB,EAAE,GAAGD,GAAS,GAAAK,GAAG,QAAQ+B,IAASM,GAAmB,GAEpFE,IAAWZ;AAAA,IACf,CAACa,MAAwB;AACvB,YAAMC,IAAMZ,EAAW,KAAK,CAACa,MAAMA,EAAE,OAAOF,CAAW;AACvD,MAAIC,OAAUA,CAAG;AAAA,IACnB;AAAA,IACA,CAACZ,GAAYH,CAAI;AAAA,EAAA,GAKbiB,IAAa,CAACC,MAA8B;AAChD,IAAA/B,EAAM,OAAO+B,GAAS;AAAA,MACpB,WAAW,CAAChB,MAAS;AACnB,QAAIA,MAAWA,CAAI,MACF,IAAI;AAAA,MACvB;AAAA,IAAA,CACD;AAAA,EACH,GACMiB,IAAchC,EAAM,cAAaiC,IAAAjC,EAAM,cAAN,gBAAAiC,EAAiB,OAAM,OAAQ,MAGhEC,IAAe,CAACC,GAAoBC,MAAe;AACvD,IAAA/B,EAAa,IAAI,GACjBH,EAAciC,GAAYC,CAAE,EACzB,KAAK,CAACR,MAAQ;AACb,MAAIA,MAAUA,CAAG,IACZvB,EAAa,GAAG+B,CAAE,0BAA0B;AAAA,IACnD,CAAC,EACA,MAAM,MAAM/B,EAAa,iBAAiB+B,CAAE,GAAG,CAAC;AAAA,EACrD,GACMC,IAAarC,EAAM,UACvB,gBAAAsC,EAAC,OAAE,WAAU,SAAQ,eAAY,uBAAsB,UAAA;AAAA,IAAA;AAAA,IACnCtC,EAAM,iBAAiB,QAAQA,EAAM,MAAM,UAAU,OAAOA,EAAM,KAAK;AAAA,EAAA,EAAA,CAC3F,IACE,MAEEuC,IAAoC;AAAA,IACxC,QAAQzD,EAAQ;AAAA,IAChB,MAAMA,EAAQ;AAAA,IACd,MAAMA,EAAQ;AAAA,IACd,IAAIA,EAAQ;AAAA,IACZ,GAAAK;AAAA,EAAA,GAKIqD,KACJjD,KAAA,gBAAAA,EAAU,UAAS,cAAcP,IAAiB,MAAMA,EAAeO,CAAQ,IAAI;AAErF,SAAIA,IAEA,gBAAA+C,EAAC,OAAA,EAAI,KAAKhC,GACP,UAAA;AAAA,IAAA+B;AAAA,IACAjC,KACC,gBAAAqC,EAAC,KAAA,EAAE,WAAU,SAAQ,eAAY,sBAC9B,UAAArC,GACH;AAAA,IAEF,gBAAAqC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,WAAW5C,EAAY,QAAQ;AAAA,QAC/B,SAASA,EAAY;AAAA,QACrB,cAAcA,EAAY,UAAU,2CAA2C;AAAA,QAC/E,QAAQ,MAAM;AACZ,UAAAE,EAAM,MAAA,GACNK,EAAa,IAAI,GACjBb,EAAY,IAAI;AAAA,QAClB;AAAA,QACA,iBAAiB,CAAC4C,MAAOF,EAAa3C,EAAS,YAAY6C,CAAE;AAAA,QAC7D,SAAS,MAAMN,EAAWvC,CAAQ;AAAA,QAClC,WAAWyC,MAAgB;AAAA,QAC3B,gBAAgBQ;AAAA,MAAA;AAAA,IAAA;AAAA,EAClB,GACF,IAKF,gBAAAF,EAAAK,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAF,EAACG,IAAA,EAAe,OAAOhD,EAAW,QAAQ,MAAM;AAAA,IAEhD,gBAAA6C,EAACI,IAAA,EAAiB,UAAAhE,GAAoB,OAAO0D,GAAa,UAAAjB,GAAoB;AAAA,IAE7E5B,EAAU,WACT,gBAAA+C,EAAC,KAAA,EAAE,WAAU,SAAQ,eAAY,iBAAgB,UAAA,mCAAA,CAEjD;AAAA,IAGDJ;AAAA,IAED,gBAAAI,EAAC,OAAA,EAAI,KAAKnC,GACR,UAAA,gBAAAmC;AAAA,MAACK;AAAA,MAAA;AAAA,QACC,OAAO9B;AAAA,QACP,cAAcnC;AAAA,QACd,SAASa,EAAU;AAAA,QACnB,SAASwB,IAAS;AAAA,QAClB,SAASC;AAAA,QACT,QAAAI;AAAA,QACA,QAAAE;AAAA,QACA,UAAAC;AAAA,QACA,SAAS,CAACU,MAAO;AACf,gBAAMR,IAAMZ,EAAW,KAAK,CAACa,MAAMA,EAAE,OAAOO,CAAE;AAC9C,UAAIR,OAAgBA,CAAG;AAAA,QACzB;AAAA,QACA,aAAAI;AAAA,MAAA;AAAA,IAAA,EACF,CACF;AAAA,EAAA,GACF;AAEJ;ACtRA,MAAMe,yBAA+C,IAAA;AAG9C,SAASC,GAAcC,GAAmE;;AAC/F,QAAMC,IAAMC,GAAA,GACNC,KAAOnC,IAAAiC,EAAI,kBAAJ,gBAAAjC,EAAmB,KAAKiC,IAC/BG,IAAM,CAAC,GAAGJ,CAAG,EAAE,KAAA,EAAO,KAAK,GAAG,GAM9BK,IALIC,GAAS;AAAA,IACjB,UAAU,CAAC,eAAeF,CAAG;AAAA,IAC7B,SAAS,CAAC,EAAE,QAAAG,EAAA,MAAcJ,IAAOA,EAAKH,GAAK,EAAE,QAAAO,GAAQ,IAAI,QAAQ,QAAQ,CAAA,CAAkB;AAAA,IAC3F,SAASP,EAAI,SAAS,KAAK,OAAOG,KAAS;AAAA,EAAA,CAC5C,EACc;AAKf,SAAO,EAAE,MAJIK;AAAA,IACX,MAAOH,IAAO,IAAI,IAAIA,EAAK,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAU,CAAC,IAAIP;AAAA,IAC7D,CAACO,CAAI;AAAA,EAAA,EAEE;AACX;AAOO,SAASI,GAAatB,GAAoC;AAC/D,QAAM,EAAE,MAAAuB,MAASX,GAAcZ,IAAK,CAACA,CAAE,IAAI,EAAE;AAC7C,SAAOA,IAAKuB,EAAK,IAAIvB,CAAE,IAAI;AAC7B;"}
|
|
@@ -3,7 +3,7 @@ import { r as Cn, l as je, m as Ve, d as De, e as En, h as Oe, c as An } from ".
|
|
|
3
3
|
import { useContext as ve, useState as u, useMemo as Qe, useEffect as be, createContext as We, useRef as Fe } from "react";
|
|
4
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";
|
|
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-
|
|
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-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
9
|
import { s as xn, M as q, b as et, C as nt } from "./ConfirmModal-Pv2-A_3U.js";
|
|
@@ -12,7 +12,7 @@ import { WorkflowConnectionsPanel as at } from "@w6w/ui/flow";
|
|
|
12
12
|
import { ApiError as L } from "@w6w/sdk";
|
|
13
13
|
import { i as rt, p as Ke, 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-
|
|
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";
|
|
@@ -1680,4 +1680,4 @@ export {
|
|
|
1680
1680
|
Wi as e,
|
|
1681
1681
|
It as u
|
|
1682
1682
|
};
|
|
1683
|
-
//# sourceMappingURL=editor-tools-
|
|
1683
|
+
//# sourceMappingURL=editor-tools-j3ThBY_4.js.map
|