@oomol-lab/open-flow 0.1.0-beta.51 → 0.1.0-beta.52

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 (41) hide show
  1. package/dist/browser/{createResourceDialog-BDtXpRSt.js → createResourceDialog-BsaBMf7_.js} +2 -1
  2. package/dist/browser/flow-authoring.js +46 -3
  3. package/dist/browser/flow-change.d.ts +6 -1
  4. package/dist/browser/flow-change.js +46 -3
  5. package/dist/browser/{flowChanges-BWSXSnMX.js → flowChanges-DtraMpva.js} +3463 -1930
  6. package/dist/browser/{flowWorkspace-DBaq2Eks.js → flowWorkspace-DLgti4Lk.js} +896 -325
  7. package/dist/browser/{workbenchSelect-C9kwcUmN.js → icons-0s-Q_3lp.js} +48 -32
  8. package/dist/browser/licenses.md +204 -0
  9. package/dist/browser/preview.css +282 -179
  10. package/dist/browser/preview.js +4289 -2193
  11. package/dist/browser/theme.css +2 -0
  12. package/dist/browser/ui-hostNavigationActions.d.ts +13 -0
  13. package/dist/browser/ui-hostTooltip.d.ts +8 -0
  14. package/dist/browser/ui-logo.d.ts +5 -0
  15. package/dist/browser/ui.css +82 -8
  16. package/dist/browser/ui.d.ts +3 -0
  17. package/dist/browser/ui.js +172 -8
  18. package/dist/browser/workbench-contract.d.ts +4 -11
  19. package/dist/browser/workbench.css +346 -200
  20. package/dist/browser/workbench.d.ts +1 -1
  21. package/dist/browser/workbench.js +1029 -365
  22. package/dist/browser/workbenchSelect-BqUPacsr.js +31 -0
  23. package/dist/common/authoringExamples.d.ts +4 -3
  24. package/dist/common/control-api-conformance.js +47 -1
  25. package/dist/common/control-api.d.ts +4 -0
  26. package/dist/common/control-api.js +51 -2
  27. package/dist/common/control-requests.d.ts +4 -0
  28. package/dist/common/control-requests.js +1299 -68
  29. package/dist/common/flow-encoding.js +34 -0
  30. package/dist/common/flow-semantics.js +674 -252
  31. package/dist/common/integration-trigger.js +23 -0
  32. package/dist/common/mcp.js +47 -1
  33. package/dist/common/openapi.d.ts +53 -0
  34. package/dist/common/openapi.js +10390 -0
  35. package/dist/common/poll-trigger.js +23 -0
  36. package/dist/common/provider-triggers.js +23 -0
  37. package/dist/common/run-events.js +1 -0
  38. package/dist/common/scheduler.d.ts +1 -1
  39. package/dist/common/scheduler.js +31 -1
  40. package/dist/common/webhook-trigger.js +23 -0
  41. package/package.json +5 -1
@@ -1,7 +1,7 @@
1
- import { $t as EmptyTitle, An as connection, At as flowDependencies, Ct as resetInputValues, Dt as setTriggerConnection, En as isJsonObject, Et as setInputSources, F as deriveAddNodeOptions, Fn as record, Ft as PopoverContent, G as resourceValue, Gt as InputGroup, H as Resource, In as string, Jt as Empty, K as designerGraph, Kt as InputGroupAddon, L as feishuResourceKind, Ln as providerIconAppearance, Mn as inputValue, Mt as followWorkbenchLink, Nn as invalidResponse, Nt as Switch, Ot as updateTriggerConfig, P as addNodeIntent, Pn as jsonValue, Pt as Popover, Qt as EmptyMedia, R as supportsFeishuChatFilter, Rn as ApiError, Rt as PopoverTitle, St as repairNodeNames, Tn as triggerOutputDefinitions, Tt as setConnectorConnection, V as scopedValue, Vn as IconThemeContext, W as resourceData, X as providerIcon, Xt as EmptyDescription, Yt as EmptyContent, Zt as EmptyHeader, _ as updateTaskAdditionalInputs, _n as WorkbenchClient, _t as setComment, a as deleteSelection, at as Latest, b as updateWebhook, bt as setNodePositions, c as setInputVariable, d as updateNodeIcon, dt as actionWithConnections, en as EventSourcesPage, f as updateNodeName, ft as connectionCatalog, g as updateTask, gn as errorNotice, gt as restoreCanvasPresentation, h as updateSubflow, ht as removeComments, i as createResource, it as revisionView, jn as connectorActionMetadata, jt as IdTooltip, kt as updateTriggerSchedule, l as updateCondition, m as updateResolution, mt as commentIds, o as nameCreatedNodes, ot as deriveInspectorDiagnostics, p as updateNodeSettings, pt as canvasPresentationChange, qt as InputGroupInput, r as applyFlowChanges, rn as createI18n, s as setInputValue, st as diagnosticItems, t as addNode, tt as RunStore, u as updateNodeDescription, v as updateTaskPorts, vn as randomId, vt as setFlowViewport, wn as sampleErrorOutputs, wt as setCodeActions, xn as decodeTriggerCatalog, xt as targetPresentation, y as updateValue, yn as allConnectorConnectionsQuery, yt as setNodeContentHidden, z as combineSources, zn as controlErrorCode, zt as PopoverTrigger } from "./flowChanges-BWSXSnMX.js";
1
+ import { $t as InputGroup, At as flowDependencies, Bn as inputValue, Bt as followWorkbenchLink, Ct as resetInputValues, Dn as allConnectorConnectionsQuery, Dt as setTriggerConnection, En as randomId, Et as setInputSources, F as deriveAddNodeOptions, G as resourceValue, Gn as providerIconAppearance, H as CacheResource, Hn as jsonValue, Ht as Popover, K as designerGraph, Kn as ApiError, Kt as PopoverTitle, L as feishuResourceKind, Mn as sampleErrorOutputs, Nn as triggerOutputDefinitions, Ot as updateTriggerConfig, P as addNodeIntent, Pn as isJsonObject, R as supportsFeishuChatFilter, Rn as connection, St as repairNodeNames, Tn as WorkbenchClient, Tt as setConnectorConnection, Un as record, Ut as PopoverContent, V as scopedValue, Vn as invalidResponse, Vt as Switch, W as resourceData, Wn as string, X as providerIcon, Yn as IconThemeContext, _ as updateTaskAdditionalInputs, _t as setComment, a as deleteSelection, an as EmptyHeader, at as Latest, b as updateWebhook, bt as setNodePositions, c as setInputVariable, cn as EventSourcesPage, d as updateNodeIcon, dn as createI18n, dt as actionWithConnections, en as InputGroupAddon, f as updateNodeName, ft as connectionCatalog, g as updateTask, gt as restoreCanvasPresentation, h as updateSubflow, ht as removeComments, i as createResource, in as EmptyDescription, it as revisionView, kn as decodeTriggerCatalog, kt as updateTriggerSchedule, l as updateCondition, m as updateResolution, mt as commentIds, nn as Empty, o as nameCreatedNodes, on as EmptyMedia, ot as deriveInspectorDiagnostics, p as updateNodeSettings, pt as canvasPresentationChange, qn as controlErrorCode, qt as PopoverTrigger, r as applyFlowChanges, rn as EmptyContent, s as setInputValue, sn as EmptyTitle, st as diagnosticItems, t as addNode, tn as InputGroupInput, tt as RunStore, u as updateNodeDescription, v as updateTaskPorts, vt as setFlowViewport, wn as errorNotice, wt as setCodeActions, xt as targetPresentation, y as updateValue, yt as setNodeContentHidden, z as combineSources, zn as connectorActionMetadata, zt as IdTooltip } from "./flowChanges-DtraMpva.js";
2
2
  import { a as derive, i as compute, l as val } from "./dist-bO8nvHFH.js";
3
3
  import { a as useVal, i as useTranslate, r as useLang, t as I18nProvider } from "./main-BPABKzwN.js";
4
- import { D as FlowChangeError, E as FieldLabel, Fr as Button, L as mapConditionSources, Lr as cn, Mn as Input, N as portsByHandle, O as applyFlowChanges$1, P as resourceNameIssue, R as nodeInputMappings, S as Field, T as FieldGroup, a as DialogContent, c as DialogHeader, d as Tooltip, f as TooltipContent, i as DialogClose, l as DialogTitle, m as TooltipTrigger, n as Icon, o as DialogDescription, q as dequal$1, r as Dialog, s as DialogFooter, t as WorkbenchSelect, w as FieldError, x as Spinner } from "./workbenchSelect-C9kwcUmN.js";
4
+ import { C as FieldError, D as applyFlowChanges$1, E as FlowChangeError, I as mapConditionSources, Ir as cn, K as dequal$1, L as nodeInputMappings, N as resourceNameIssue, Pr as Button, T as FieldLabel, a as DialogDescription, b as Spinner, c as DialogTitle, d as TooltipContent, i as DialogContent, jn as Input, n as Dialog, o as DialogFooter, p as TooltipTrigger, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, w as FieldGroup, x as Field } from "./icons-0s-Q_3lp.js";
5
5
  import { a as toPlainObject } from "./dist-BDBTOgS5.js";
6
6
  import { c as isUiLanguage, d as uiLanguages, l as resolveUiLanguage, u as uiLanguageNames } from "./value-DL_poNiC.js";
7
7
  import { Suspense, lazy, useEffect, useRef, useState } from "react";
@@ -196,34 +196,11 @@ function Skeleton({ className, ...props }) {
196
196
  }
197
197
  //#endregion
198
198
  //#region src/workbench/browser/runtime/shell/resourceBrowser.tsx
199
- var CreateResourceDialog = lazy(() => import("./createResourceDialog-BDtXpRSt.js"));
200
- var languageOptions = uiLanguages.map((language) => ({
201
- label: uiLanguageNames[language],
202
- value: language
203
- }));
199
+ var CreateResourceDialog = lazy(() => import("./createResourceDialog-BsaBMf7_.js"));
204
200
  var flowIdTooltipAlignOffset = 44;
205
201
  var renamePopoverAlignOffset = -12;
206
202
  var renamePopoverVerticalShift = 8;
207
203
  var rowControlSelector = "a, button, input, select, textarea, [data-slot=\"tooltip-trigger\"]";
208
- function LanguageSelect({ language, onLanguageChange }) {
209
- const t = useTranslate();
210
- const [portalRoot, setPortalRoot] = useState(null);
211
- if (onLanguageChange == null) return null;
212
- return /* @__PURE__ */ jsxs("div", {
213
- className: "resource-language",
214
- ref: setPortalRoot,
215
- children: [/* @__PURE__ */ jsx("span", {
216
- className: "sr-only",
217
- children: t("language.label")
218
- }), /* @__PURE__ */ jsx(WorkbenchSelect, {
219
- ariaLabel: t("language.label"),
220
- onValueChange: (value) => onLanguageChange(value),
221
- options: languageOptions,
222
- portalRoot,
223
- value: language
224
- })]
225
- });
226
- }
227
204
  function compactFlowId(flowId) {
228
205
  return flowId.length <= 20 ? flowId : `${flowId.slice(0, 10)}…${flowId.slice(-6)}`;
229
206
  }
@@ -504,12 +481,19 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
504
481
  "aria-hidden": "true",
505
482
  className: cn("status-dot", publicationTone)
506
483
  }),
507
- t(publicationStatus),
508
- flow.live != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
509
- "aria-hidden": "true",
510
- className: "resource-status-separator",
511
- children: "·"
512
- }), /* @__PURE__ */ jsx("span", { children: t(flow.live.enabled ? "resource.enabled" : "resource.disabled") })] })
484
+ /* @__PURE__ */ jsx("span", { children: t(publicationStatus) }),
485
+ flow.live != null && /* @__PURE__ */ jsxs("span", {
486
+ className: "resource-enabled-status",
487
+ "aria-busy": pending == "enabled",
488
+ children: [/* @__PURE__ */ jsx("span", { children: t(flow.live.enabled ? "resource.enabled" : "resource.disabled") }), /* @__PURE__ */ jsx(Switch, {
489
+ "aria-label": t("resource.enableFlow", { name: flow.name }),
490
+ checked: flow.live.enabled,
491
+ disabled: flow.status != "active" || busy != null || pending != null,
492
+ onCheckedChange: (enabled) => void update(enabled),
493
+ size: "sm",
494
+ title: t("resource.enabledHint")
495
+ })]
496
+ })
513
497
  ]
514
498
  })
515
499
  ]
@@ -519,14 +503,6 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
519
503
  "aria-busy": pending != null,
520
504
  onClick: openFromRow,
521
505
  children: [
522
- flow.live != null && /* @__PURE__ */ jsx(Switch, {
523
- "aria-label": t("resource.enableFlow", { name: flow.name }),
524
- checked: flow.live.enabled,
525
- disabled: flow.status != "active" || busy != null || pending != null,
526
- onCheckedChange: (enabled) => void update(enabled),
527
- size: "sm",
528
- title: t("resource.enabledHint")
529
- }),
530
506
  flow.status == "active" && /* @__PURE__ */ jsx(Button, {
531
507
  onClick: () => onSelect(flow),
532
508
  size: "sm",
@@ -619,7 +595,7 @@ function FlowSkeleton() {
619
595
  })]
620
596
  });
621
597
  }
622
- function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBadges, hrefForFlow, language, onCreateFlow, onLanguageChange, onSelectFlow, store }) {
598
+ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBadges, hrefForFlow, onCreateFlow, onSelectFlow, store }) {
623
599
  const t = useTranslate();
624
600
  const busy = useVal(store.workspace.$.busy);
625
601
  const loadFailed = useVal(store.workspace.$.flowLoadFailed);
@@ -666,107 +642,105 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
666
642
  }), !loading && /* @__PURE__ */ jsx("span", { children: t("resource.flowCount", { count: total ?? flows.length }) })]
667
643
  }), /* @__PURE__ */ jsxs("div", {
668
644
  className: "resource-list-actions",
669
- children: [
670
- /* @__PURE__ */ jsx(LanguageSelect, {
671
- language,
672
- onLanguageChange
673
- }),
674
- /* @__PURE__ */ jsxs(InputGroup, {
675
- className: "w-full sm:w-56",
676
- children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Icon, {
677
- name: "search",
678
- size: 17
679
- }) }), /* @__PURE__ */ jsx(InputGroupInput, {
680
- autoComplete: "off",
681
- "aria-label": t("resource.searchByName"),
682
- name: "flow-search",
683
- onChange: (event) => setFilter(event.target.value),
684
- placeholder: t("resource.searchByName"),
685
- value: filter
686
- })]
687
- }),
688
- /* @__PURE__ */ jsxs(Button, {
689
- className: "pr-3",
690
- disabled: busy != null,
691
- onClick: () => setCreating(true),
692
- children: [/* @__PURE__ */ jsx(Icon, {
693
- "data-icon": "inline-start",
694
- name: "plus"
695
- }), t("resource.newFlow")]
696
- })
697
- ]
698
- })]
699
- }),
700
- /* @__PURE__ */ jsxs("div", {
701
- "aria-hidden": "true",
702
- className: "resource-list-columns-shell",
703
- children: [/* @__PURE__ */ jsxs("div", {
704
- className: "resource-list-columns flow-columns",
705
- children: [
706
- /* @__PURE__ */ jsx("span", { children: t("resource.name") }),
707
- /* @__PURE__ */ jsx("span", {
708
- className: "resource-flow-id-heading",
709
- children: t("resource.flowId")
710
- }),
711
- /* @__PURE__ */ jsx("span", {
712
- className: "resource-updated-heading",
713
- children: t("resource.updated")
714
- }),
715
- /* @__PURE__ */ jsx("span", { children: t("resource.status") })
716
- ]
717
- }), /* @__PURE__ */ jsx("span", {
718
- className: "resource-actions-heading",
719
- children: t("resource.actions")
720
- })]
721
- }),
722
- /* @__PURE__ */ jsx("div", {
723
- className: "resource-list",
724
- children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, {}, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
725
- className: "min-h-64",
726
- role: "alert",
727
- children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
728
- /* @__PURE__ */ jsx(EmptyMedia, {
729
- variant: "icon",
730
- children: /* @__PURE__ */ jsx(Icon, {
731
- name: "alert",
732
- size: 20
733
- })
734
- }),
735
- /* @__PURE__ */ jsx(EmptyTitle, { children: t("resource.flowsLoadFailed") }),
736
- /* @__PURE__ */ jsx(EmptyDescription, { children: t("resource.flowsLoadFailedDescription") })
737
- ] }), /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsx(Button, {
738
- onClick: () => void store.retryFlows(),
739
- variant: "outline",
740
- children: t("empty.retry")
741
- }) })]
742
- }) : visible.length == 0 ? /* @__PURE__ */ jsxs(Empty, {
743
- className: "min-h-64",
744
- children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
745
- /* @__PURE__ */ jsx(EmptyMedia, {
746
- variant: "icon",
747
- children: /* @__PURE__ */ jsx(Icon, {
748
- name: "flow",
749
- size: 20
750
- })
751
- }),
752
- /* @__PURE__ */ jsx(EmptyTitle, { children: t(normalized.length == 0 ? "resource.noFlows" : "resource.noMatchingFlows") }),
753
- /* @__PURE__ */ jsx(EmptyDescription, { children: t(normalized.length == 0 ? "resource.noFlowsDescription" : "resource.noMatchingDescription") })
754
- ] }), normalized.length == 0 && /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsxs(Button, {
645
+ children: [/* @__PURE__ */ jsxs(InputGroup, {
646
+ className: "w-full sm:w-56",
647
+ children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Icon, {
648
+ name: "search",
649
+ size: 17
650
+ }) }), /* @__PURE__ */ jsx(InputGroupInput, {
651
+ autoComplete: "off",
652
+ "aria-label": t("resource.searchByName"),
653
+ name: "flow-search",
654
+ onChange: (event) => setFilter(event.target.value),
655
+ placeholder: t("resource.searchByName"),
656
+ value: filter
657
+ })]
658
+ }), /* @__PURE__ */ jsxs(Button, {
659
+ className: "pr-3",
660
+ disabled: busy != null,
755
661
  onClick: () => setCreating(true),
756
- variant: "outline",
757
662
  children: [/* @__PURE__ */ jsx(Icon, {
758
663
  "data-icon": "inline-start",
759
664
  name: "plus"
760
665
  }), t("resource.newFlow")]
761
- }) })]
762
- }) : visible.map((flow) => /* @__PURE__ */ jsx(FlowItem, {
763
- badge: flowBadges?.[flow.flowId],
764
- busy,
765
- flow,
766
- href: hrefForFlow(flow),
767
- onSelect: onSelectFlow,
768
- store
769
- }, flow.flowId))
666
+ })]
667
+ })]
668
+ }),
669
+ /* @__PURE__ */ jsx("div", {
670
+ className: "resource-table-scroll",
671
+ children: /* @__PURE__ */ jsxs("div", {
672
+ className: "resource-table",
673
+ children: [/* @__PURE__ */ jsxs("div", {
674
+ "aria-hidden": "true",
675
+ className: "resource-list-columns-shell",
676
+ children: [/* @__PURE__ */ jsxs("div", {
677
+ className: "resource-list-columns flow-columns",
678
+ children: [
679
+ /* @__PURE__ */ jsx("span", { children: t("resource.name") }),
680
+ /* @__PURE__ */ jsx("span", {
681
+ className: "resource-flow-id-heading",
682
+ children: t("resource.flowId")
683
+ }),
684
+ /* @__PURE__ */ jsx("span", {
685
+ className: "resource-updated-heading",
686
+ children: t("resource.updated")
687
+ }),
688
+ /* @__PURE__ */ jsx("span", { children: t("resource.status") })
689
+ ]
690
+ }), /* @__PURE__ */ jsx("span", {
691
+ className: "resource-actions-heading",
692
+ children: t("resource.actions")
693
+ })]
694
+ }), /* @__PURE__ */ jsx("div", {
695
+ className: "resource-list",
696
+ children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, {}, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
697
+ className: "min-h-64",
698
+ role: "alert",
699
+ children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
700
+ /* @__PURE__ */ jsx(EmptyMedia, {
701
+ variant: "icon",
702
+ children: /* @__PURE__ */ jsx(Icon, {
703
+ name: "alert",
704
+ size: 20
705
+ })
706
+ }),
707
+ /* @__PURE__ */ jsx(EmptyTitle, { children: t("resource.flowsLoadFailed") }),
708
+ /* @__PURE__ */ jsx(EmptyDescription, { children: t("resource.flowsLoadFailedDescription") })
709
+ ] }), /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsx(Button, {
710
+ onClick: () => void store.retryFlows(),
711
+ variant: "outline",
712
+ children: t("empty.retry")
713
+ }) })]
714
+ }) : visible.length == 0 ? /* @__PURE__ */ jsxs(Empty, {
715
+ className: "min-h-64",
716
+ children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
717
+ /* @__PURE__ */ jsx(EmptyMedia, {
718
+ variant: "icon",
719
+ children: /* @__PURE__ */ jsx(Icon, {
720
+ name: "flow",
721
+ size: 20
722
+ })
723
+ }),
724
+ /* @__PURE__ */ jsx(EmptyTitle, { children: t(normalized.length == 0 ? "resource.noFlows" : "resource.noMatchingFlows") }),
725
+ /* @__PURE__ */ jsx(EmptyDescription, { children: t(normalized.length == 0 ? "resource.noFlowsDescription" : "resource.noMatchingDescription") })
726
+ ] }), normalized.length == 0 && /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsxs(Button, {
727
+ onClick: () => setCreating(true),
728
+ variant: "outline",
729
+ children: [/* @__PURE__ */ jsx(Icon, {
730
+ "data-icon": "inline-start",
731
+ name: "plus"
732
+ }), t("resource.newFlow")]
733
+ }) })]
734
+ }) : visible.map((flow) => /* @__PURE__ */ jsx(FlowItem, {
735
+ badge: flowBadges?.[flow.flowId],
736
+ busy,
737
+ flow,
738
+ href: hrefForFlow(flow),
739
+ onSelect: onSelectFlow,
740
+ store
741
+ }, flow.flowId))
742
+ })]
743
+ })
770
744
  }),
771
745
  nextCursor != null && /* @__PURE__ */ jsx("div", {
772
746
  className: "resource-list-footer",
@@ -1506,93 +1480,35 @@ var PublicationStore = class {
1506
1480
  //#endregion
1507
1481
  //#region src/workbench/browser/runtime/runs/runRequestStore.ts
1508
1482
  var initialState$5 = { starting: false };
1509
- function inputPorts$1(node) {
1510
- switch (node.kind) {
1511
- case "condition": return {};
1512
- case "subflow": return portsByHandle(node.definition?.inputs ?? []);
1513
- case "task": return portsByHandle(node.definition?.inputs ?? []);
1514
- case "value": return {};
1515
- case "approval":
1516
- case "wait": return portsByHandle(node.node.inputDefinitions);
1517
- }
1518
- }
1519
- function nodeTitle(node) {
1520
- if (node.node.name != null) return node.node.name;
1521
- if (node.kind == "task" || node.kind == "subflow") return node.definition?.name ?? node.id;
1522
- return node.id;
1523
- }
1524
- function inputSpecs(draft, triggerId) {
1525
- const revision = revisionView(draft);
1526
- const graph = revision.graph({ kind: "flow" });
1527
- if (graph == null) return [];
1528
- const reachable = /* @__PURE__ */ new Set([triggerId]);
1529
- const pending = [triggerId];
1530
- while (pending.length > 0) {
1531
- const source = pending.pop();
1532
- for (const edge of graph.edges) {
1533
- if (edge.source != source || reachable.has(edge.target)) continue;
1534
- reachable.add(edge.target);
1535
- pending.push(edge.target);
1536
- }
1537
- }
1538
- return Object.entries(graph.nodes).filter(([id]) => reachable.has(id)).toSorted(([left], [right]) => left.localeCompare(right)).flatMap(([nodeId, node]) => {
1539
- const resolved = revision.resolveNode(nodeId, node);
1540
- if (resolved.kind == "trigger") {
1541
- if (resolved.trigger.kind == "manual" || resolved.trigger.kind == "cron") return [];
1542
- return [{
1543
- definitions: triggerOutputDefinitions(resolved.trigger),
1544
- samples: resolved.trigger.kind == "error" ? sampleErrorOutputs : void 0,
1545
- nodeId,
1546
- title: resolved.trigger.name
1547
- }];
1548
- }
1549
- const definitions = Object.entries(inputPorts$1(resolved)).filter(([handle, port]) => resolved.node.inputs[handle] == null && !Object.hasOwn(port, "value")).toSorted(([left], [right]) => left.localeCompare(right)).map(([handle, port]) => Object.assign({
1550
- handle,
1551
- jsonSchema: port.jsonSchema,
1552
- nullable: port.nullable
1553
- }, port.description == null ? {} : { description: port.description }));
1554
- return definitions.length == 0 ? [] : [{
1555
- definitions,
1556
- samples: void 0,
1557
- nodeId,
1558
- title: nodeTitle(resolved)
1559
- }];
1560
- });
1483
+ function inputSpec(draft, triggerId) {
1484
+ const trigger = revisionView(draft).graph({ kind: "flow" })?.nodes[triggerId];
1485
+ if (trigger == null || "inputs" in trigger || trigger.kind == "manual" || trigger.kind == "cron") return void 0;
1486
+ const definitions = triggerOutputDefinitions(trigger);
1487
+ return definitions.length === 0 ? void 0 : {
1488
+ definitions,
1489
+ samples: trigger.kind == "error" ? sampleErrorOutputs : void 0
1490
+ };
1561
1491
  }
1562
- function inputSignature(specs) {
1563
- return JSON.stringify(specs.map((group) => [group.nodeId, group.definitions.map((definition) => [
1492
+ function inputSignature(spec) {
1493
+ return JSON.stringify(spec?.definitions.map((definition) => [
1564
1494
  definition.handle,
1565
1495
  definition.jsonSchema,
1566
1496
  definition.nullable
1567
- ])]));
1497
+ ]) ?? []);
1568
1498
  }
1569
- async function inputGroups(specs, language, values) {
1499
+ async function inputEditor(spec, language, values) {
1500
+ if (spec == null) return void 0;
1570
1501
  const { FlowRunInputEditorStore } = await import("./flowRunInputEditorStore-Dsxyfwae.js").then((n) => n.t);
1571
- return specs.map((group) => {
1572
- const editor = new FlowRunInputEditorStore(group.definitions, language);
1573
- const initial = values?.[group.nodeId] ?? group.samples;
1574
- if (initial != null) editor.replaceValues(initial);
1575
- return {
1576
- editor,
1577
- nodeId: group.nodeId,
1578
- title: group.title
1579
- };
1580
- });
1581
- }
1582
- function groupValues(groups) {
1583
- return Object.fromEntries(groups.map((group) => [group.nodeId, group.editor.values()]));
1502
+ const editor = new FlowRunInputEditorStore(spec.definitions, language);
1503
+ const initial = values ?? spec.samples;
1504
+ if (initial != null) editor.replaceValues(initial);
1505
+ return editor;
1584
1506
  }
1585
1507
  function testOutputs(revision, triggerId) {
1586
1508
  const node = revisionView(revision).graph({ kind: "flow" })?.nodes[triggerId];
1587
1509
  if (node?.kind == "error") return sampleErrorOutputs;
1588
1510
  return node?.kind === "cron" ? { scheduledAt: (/* @__PURE__ */ new Date()).toISOString() } : {};
1589
1511
  }
1590
- function runValues(groups, triggerId, revision) {
1591
- return {
1592
- inputs: Object.fromEntries(groups.filter((group) => group.nodeId != triggerId).map((group) => [group.nodeId, group.editor.values()])),
1593
- outputs: groups.find((group) => group.nodeId == triggerId)?.editor.values() ?? testOutputs(revision, triggerId)
1594
- };
1595
- }
1596
1512
  var RunRequestStore = class {
1597
1513
  #prepareDraft;
1598
1514
  #client;
@@ -1657,10 +1573,10 @@ var RunRequestStore = class {
1657
1573
  }
1658
1574
  }
1659
1575
  inputStatus(flowId, draft, triggerId) {
1660
- const specs = inputSpecs(draft, triggerId);
1661
- if (specs.length == 0) return "none";
1576
+ const spec = inputSpec(draft, triggerId);
1577
+ if (spec == null) return "none";
1662
1578
  const saved = this.#savedInputs.get(this.#inputKey(flowId, triggerId));
1663
- return saved?.valid == true && saved.signature == inputSignature(specs) ? "ready" : "missing";
1579
+ return saved?.valid == true && saved.signature == inputSignature(spec) ? "ready" : "missing";
1664
1580
  }
1665
1581
  async requestLive(flow) {
1666
1582
  const current = this.#requests.begin();
@@ -1695,11 +1611,11 @@ var RunRequestStore = class {
1695
1611
  return false;
1696
1612
  }
1697
1613
  this.#rememberInputs(request);
1698
- const { inputs, outputs } = runValues(request.groups, request.triggerId, request.revision);
1614
+ const outputs = request.editor?.values() ?? testOutputs(request.revision, request.triggerId);
1699
1615
  const started = await this.#start(request.source, request.flow, request.revisionId, {
1700
1616
  nodeId: request.triggerId,
1701
1617
  outputs
1702
- }, inputs, request.publicationId);
1618
+ }, request.publicationId);
1703
1619
  if (started && this.#state.value.inputRequest === request) this.dismissInputs();
1704
1620
  return started;
1705
1621
  }
@@ -1710,18 +1626,18 @@ var RunRequestStore = class {
1710
1626
  this.#rememberInputs(request);
1711
1627
  this.#set({ starting: true });
1712
1628
  try {
1713
- const specs = inputSpecs(request.revision, triggerId);
1629
+ const spec = inputSpec(request.revision, triggerId);
1714
1630
  const saved = this.#savedInputs.get(this.#inputKey(request.flow.flowId, triggerId));
1715
- const groups = await inputGroups(specs, this.#i18n.lang$, saved?.values);
1631
+ const editor = await inputEditor(spec, this.#i18n.lang$, saved?.values);
1716
1632
  if (!current() || this.#state.value.inputRequest !== request) {
1717
- for (const group of groups) group.editor.dispose();
1633
+ editor?.dispose();
1718
1634
  return;
1719
1635
  }
1720
- const valid = compute((get) => groups.every((group) => get(group.editor.valid$)));
1636
+ const valid = compute((get) => editor == null || get(editor.valid$));
1721
1637
  this.#set({ inputRequest: {
1722
1638
  ...request,
1723
1639
  attempted: false,
1724
- groups,
1640
+ editor,
1725
1641
  triggerId,
1726
1642
  valid
1727
1643
  } });
@@ -1763,32 +1679,32 @@ var RunRequestStore = class {
1763
1679
  });
1764
1680
  return "unavailable";
1765
1681
  }
1766
- const specs = only == null ? [] : inputSpecs(revision, only.nodeId);
1767
- const signature = inputSignature(specs);
1682
+ const spec = only == null ? void 0 : inputSpec(revision, only.nodeId);
1683
+ const signature = inputSignature(spec);
1768
1684
  const saved = only == null ? void 0 : this.#savedInputs.get(this.#inputKey(flow.flowId, only.nodeId));
1769
- const groups = only == null ? [] : await inputGroups(specs, this.#i18n.lang$, saved?.values);
1685
+ const editor = await inputEditor(spec, this.#i18n.lang$, saved?.values);
1770
1686
  if (!current()) {
1771
- for (const group of groups) group.editor.dispose();
1687
+ editor?.dispose();
1772
1688
  return "unavailable";
1773
1689
  }
1774
- if (!edit && only != null && groups.length == 0) return await this.#start(source, flow, revisionId, {
1690
+ if (!edit && only != null && editor == null) return await this.#start(source, flow, revisionId, {
1775
1691
  nodeId: only.nodeId,
1776
1692
  outputs: testOutputs(revision, only.nodeId)
1777
- }, {}, publicationId) ? "started" : "unavailable";
1778
- if (!edit && only != null && saved?.valid == true && saved.signature == signature && groups.every((group) => group.editor.valid$.value)) {
1779
- const values = runValues(groups, only.nodeId, revision);
1780
- for (const group of groups) group.editor.dispose();
1693
+ }, publicationId) ? "started" : "unavailable";
1694
+ if (!edit && only != null && saved?.valid == true && saved.signature == signature && editor != null && editor.valid$.value) {
1695
+ const outputs = editor.values();
1696
+ editor?.dispose();
1781
1697
  return await this.#start(source, flow, revisionId, {
1782
1698
  nodeId: only.nodeId,
1783
- outputs: values.outputs
1784
- }, values.inputs, publicationId) ? "started" : "unavailable";
1699
+ outputs
1700
+ }, publicationId) ? "started" : "unavailable";
1785
1701
  }
1786
- const valid = compute((get) => only != null && groups.every((group) => get(group.editor.valid$)));
1702
+ const valid = compute((get) => only != null && (editor == null || get(editor.valid$)));
1787
1703
  this.#set({
1788
1704
  inputRequest: {
1789
1705
  attempted: false,
1790
1706
  flow,
1791
- groups,
1707
+ editor,
1792
1708
  revision,
1793
1709
  triggers,
1794
1710
  triggerId: only?.nodeId,
@@ -1802,7 +1718,7 @@ var RunRequestStore = class {
1802
1718
  });
1803
1719
  return "input";
1804
1720
  }
1805
- async #start(source, flow, revisionId, trigger, inputs = {}, publicationId) {
1721
+ async #start(source, flow, revisionId, trigger, publicationId) {
1806
1722
  if (source == "live" && publicationId == null) return false;
1807
1723
  const alive = this.#lifetime.capture();
1808
1724
  const current = this.#runs.prepareStart();
@@ -1821,7 +1737,6 @@ var RunRequestStore = class {
1821
1737
  revisionId
1822
1738
  } : { publicationId };
1823
1739
  const signature = JSON.stringify({
1824
- inputs,
1825
1740
  trigger,
1826
1741
  source,
1827
1742
  ...target
@@ -1833,11 +1748,11 @@ var RunRequestStore = class {
1833
1748
  this.#attempt = attempt;
1834
1749
  const run = source == "draft" ? await this.#client.createDraftRun(flow.flowId, revisionId, {
1835
1750
  idempotencyKey: attempt.key,
1836
- inputs,
1751
+ inputs: {},
1837
1752
  trigger
1838
1753
  }) : await this.#client.createLiveRun(publicationId, {
1839
1754
  idempotencyKey: attempt.key,
1840
- inputs,
1755
+ inputs: {},
1841
1756
  trigger
1842
1757
  });
1843
1758
  if (!alive() || !current()) return false;
@@ -1856,17 +1771,17 @@ var RunRequestStore = class {
1856
1771
  #disposeInputRequest(request = this.#state.value.inputRequest) {
1857
1772
  if (request == null) return;
1858
1773
  request.valid.dispose();
1859
- for (const group of request.groups) group.editor.dispose();
1774
+ request.editor?.dispose();
1860
1775
  }
1861
1776
  #inputKey(flowId, triggerId) {
1862
1777
  return `${flowId}\u0000${triggerId}`;
1863
1778
  }
1864
1779
  #rememberInputs(request) {
1865
- if (request?.triggerId == null || request.groups.length == 0) return;
1780
+ if (request?.triggerId == null || request.editor == null) return;
1866
1781
  this.#savedInputs.set(this.#inputKey(request.flow.flowId, request.triggerId), {
1867
- signature: inputSignature(inputSpecs(request.revision, request.triggerId)),
1782
+ signature: inputSignature(inputSpec(request.revision, request.triggerId)),
1868
1783
  valid: request.valid.value,
1869
- values: groupValues(request.groups)
1784
+ values: request.editor.values()
1870
1785
  });
1871
1786
  }
1872
1787
  #set(patch) {
@@ -1961,48 +1876,591 @@ function createStore(dbName, storeName) {
1961
1876
  };
1962
1877
  return (txMode, callback) => getDB().then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName)));
1963
1878
  }
1964
- var defaultGetStoreFunc;
1965
- function defaultGetStore() {
1966
- if (!defaultGetStoreFunc) defaultGetStoreFunc = createStore("keyval-store", "keyval");
1967
- return defaultGetStoreFunc;
1968
- }
1969
- /**
1970
- * Get a value by its key.
1971
- *
1972
- * @param key
1973
- * @param customStore Method to get a custom store. Use with caution (see the docs).
1974
- */
1975
- function get(key, customStore = defaultGetStore()) {
1976
- return customStore("readonly", (store) => promisifyRequest(store.get(key)));
1879
+ //#endregion
1880
+ //#region ../../node_modules/.bun/@oomol-lab+resource-cache@0.1.4/node_modules/@oomol-lab/resource-cache/dist/src-bwD0r9NQ.mjs
1881
+ function abortError() {
1882
+ return new DOMException("Cache operation aborted", "AbortError");
1977
1883
  }
1978
- /**
1979
- * Set a value with a key.
1980
- *
1981
- * @param key
1982
- * @param value
1983
- * @param customStore Method to get a custom store. Use with caution (see the docs).
1984
- */
1985
- function set(key, value, customStore = defaultGetStore()) {
1986
- return customStore("readwrite", (store) => {
1987
- store.put(value, key);
1988
- return promisifyRequest(store.transaction);
1884
+ function wait(promise, lifetime, caller) {
1885
+ const signals = caller ? [lifetime, caller] : [lifetime];
1886
+ return new Promise((resolve, reject) => {
1887
+ const cleanup = () => {
1888
+ for (const signal of signals) signal.removeEventListener("abort", abort);
1889
+ };
1890
+ const abort = () => {
1891
+ cleanup();
1892
+ reject(abortError());
1893
+ };
1894
+ for (const signal of signals) signal.addEventListener("abort", abort, { once: true });
1895
+ promise.then((value) => {
1896
+ cleanup();
1897
+ resolve(value);
1898
+ }, (error) => {
1899
+ cleanup();
1900
+ reject(error);
1901
+ });
1989
1902
  });
1990
1903
  }
1904
+ /** @internal */
1905
+ function validateOptions(options) {
1906
+ if (typeof options.namespace !== "string" || !options.namespace.trim()) throw new TypeError("namespace must be nonempty");
1907
+ if (!Number.isSafeInteger(options.schemaVersion) || options.schemaVersion <= 0) throw new TypeError("schemaVersion must be a positive safe integer");
1908
+ if (!Number.isFinite(options.maxAge) || options.maxAge < 0) throw new TypeError("maxAge must be finite and nonnegative");
1909
+ for (const name of [
1910
+ "key",
1911
+ "decode",
1912
+ "load"
1913
+ ]) if (typeof options[name] !== "function") throw new TypeError(`${name} must be a function`);
1914
+ }
1915
+ /** @internal */
1916
+ function createCache(options, backend, session) {
1917
+ const states = /* @__PURE__ */ new Map();
1918
+ let disposed = false;
1919
+ let scopeBlocked = false;
1920
+ let disposal;
1921
+ let io = Promise.resolve();
1922
+ function storage(action) {
1923
+ const result = io.then(action);
1924
+ io = result.catch(() => {});
1925
+ return result;
1926
+ }
1927
+ function checkOpen() {
1928
+ if (disposed) throw new Error("Cache is disposed");
1929
+ }
1930
+ function identity(query) {
1931
+ checkOpen();
1932
+ const key = options.key(query);
1933
+ if (typeof key !== "string") throw new TypeError("key must return a string");
1934
+ return key;
1935
+ }
1936
+ function stateFor(key) {
1937
+ let state = states.get(key);
1938
+ if (!state) {
1939
+ state = {
1940
+ controller: new AbortController(),
1941
+ blocked: scopeBlocked
1942
+ };
1943
+ states.set(key, state);
1944
+ }
1945
+ return state;
1946
+ }
1947
+ function checkState(state) {
1948
+ if (state.controller.signal.aborted) throw abortError();
1949
+ }
1950
+ function fresh(entry) {
1951
+ const now = Date.now();
1952
+ return !entry.invalidated && entry.validatedAt <= now && now - entry.validatedAt < options.maxAge;
1953
+ }
1954
+ function restore(value, previous) {
1955
+ return {
1956
+ ...value.meta,
1957
+ data: value.body ? options.decode(value.body.data) : previous.data
1958
+ };
1959
+ }
1960
+ async function read(key, state) {
1961
+ if (state.entry && fresh(state.entry)) return state.entry;
1962
+ const entry = await storage(async () => {
1963
+ checkState(state);
1964
+ if (state.blocked) return state.entry;
1965
+ try {
1966
+ const value = await backend.read(key, state.entry?.version);
1967
+ return value ? restore(value, state.entry) : state.entry;
1968
+ } catch {
1969
+ return state.entry;
1970
+ }
1971
+ });
1972
+ checkState(state);
1973
+ state.entry = entry;
1974
+ return entry;
1975
+ }
1976
+ function schedule(key, query, state, force) {
1977
+ const job = {
1978
+ started: false,
1979
+ force
1980
+ };
1981
+ job.promise = (async () => {
1982
+ const previous = await read(key, state);
1983
+ checkState(state);
1984
+ if (!job.force && previous && fresh(previous)) return previous.data;
1985
+ job.started = true;
1986
+ const result = await options.load(query, {
1987
+ etag: previous?.etag ?? null,
1988
+ signal: state.controller.signal
1989
+ });
1990
+ checkState(state);
1991
+ let entry;
1992
+ if (result.modified) entry = {
1993
+ data: result.data,
1994
+ etag: result.etag,
1995
+ version: crypto.getRandomValues(/* @__PURE__ */ new Uint32Array(4)).join("-"),
1996
+ validatedAt: Date.now(),
1997
+ invalidated: false
1998
+ };
1999
+ else {
2000
+ if (!previous) throw new Error("Load protocol error: unmodified response without cached data");
2001
+ entry = {
2002
+ ...previous,
2003
+ etag: result.etag === void 0 ? previous.etag : result.etag,
2004
+ validatedAt: Date.now(),
2005
+ invalidated: false
2006
+ };
2007
+ }
2008
+ await storage(async () => {
2009
+ checkState(state);
2010
+ try {
2011
+ if (await backend.write(key, entry, result.modified)) state.blocked = false;
2012
+ } catch {
2013
+ state.blocked = true;
2014
+ }
2015
+ checkState(state);
2016
+ state.entry = entry;
2017
+ });
2018
+ checkState(state);
2019
+ return entry.data;
2020
+ })();
2021
+ state.job = job;
2022
+ const release = () => {
2023
+ state.job = void 0;
2024
+ };
2025
+ job.promise.then(release, release);
2026
+ return job;
2027
+ }
2028
+ function refresh(key, query, state, force) {
2029
+ const active = state.job;
2030
+ if (!active) return schedule(key, query, state, force).promise;
2031
+ if (!force) return active.promise;
2032
+ if (!active.started) {
2033
+ active.force = true;
2034
+ return active.promise;
2035
+ }
2036
+ if (!state.queued) {
2037
+ const start = () => {
2038
+ checkState(state);
2039
+ state.queued = void 0;
2040
+ return schedule(key, query, state, true).promise;
2041
+ };
2042
+ state.queued = active.promise.then(start, start);
2043
+ }
2044
+ return state.queued;
2045
+ }
2046
+ function reset(key, keep) {
2047
+ const old = states.get(key);
2048
+ const state = {
2049
+ controller: new AbortController(),
2050
+ blocked: true
2051
+ };
2052
+ if (keep && old?.entry) state.entry = {
2053
+ ...old.entry,
2054
+ invalidated: true
2055
+ };
2056
+ states.set(key, state);
2057
+ return {
2058
+ state,
2059
+ cancel: () => old?.controller.abort()
2060
+ };
2061
+ }
2062
+ function resetAll() {
2063
+ const old = [...states.values()];
2064
+ states.clear();
2065
+ const barrier = {};
2066
+ scopeBlocked = barrier;
2067
+ return {
2068
+ barrier,
2069
+ cancel() {
2070
+ for (const state of old) state.controller.abort();
2071
+ }
2072
+ };
2073
+ }
2074
+ return {
2075
+ async get(query, getOptions = {}) {
2076
+ const key = identity(query);
2077
+ if (getOptions.signal?.aborted) throw abortError();
2078
+ const state = stateFor(key);
2079
+ if (!getOptions.revalidate && state.entry && fresh(state.entry)) return state.entry.data;
2080
+ return wait(refresh(key, query, state, getOptions.revalidate === true), state.controller.signal, getOptions.signal);
2081
+ },
2082
+ async peek(query) {
2083
+ const key = identity(query);
2084
+ const state = stateFor(key);
2085
+ const entry = await wait(read(key, state), state.controller.signal);
2086
+ return entry ? {
2087
+ data: entry.data,
2088
+ etag: entry.etag,
2089
+ validatedAt: entry.validatedAt,
2090
+ fresh: fresh(entry)
2091
+ } : void 0;
2092
+ },
2093
+ async invalidate(query) {
2094
+ const key = identity(query);
2095
+ const canRestore = !(states.get(key)?.blocked ?? scopeBlocked);
2096
+ const { state, cancel } = reset(key, true);
2097
+ const cleanup = storage(async () => {
2098
+ const value = await backend.invalidate(key);
2099
+ if (canRestore) state.blocked = false;
2100
+ if (canRestore && !state.controller.signal.aborted && !state.entry && value) try {
2101
+ state.entry = restore(value);
2102
+ } catch {}
2103
+ });
2104
+ cancel();
2105
+ await cleanup;
2106
+ },
2107
+ async remove(query) {
2108
+ const key = identity(query);
2109
+ const { state, cancel } = reset(key, false);
2110
+ const cleanup = storage(async () => {
2111
+ await backend.remove(key);
2112
+ state.blocked = false;
2113
+ });
2114
+ cancel();
2115
+ await cleanup;
2116
+ },
2117
+ async clear() {
2118
+ checkOpen();
2119
+ const { barrier, cancel } = resetAll();
2120
+ const cleanup = storage(async () => {
2121
+ await backend.clear(false);
2122
+ if (scopeBlocked === barrier) scopeBlocked = false;
2123
+ for (const state of states.values()) if (state.blocked === barrier) state.blocked = false;
2124
+ });
2125
+ cancel();
2126
+ await cleanup;
2127
+ },
2128
+ dispose() {
2129
+ if (!disposal) {
2130
+ disposed = true;
2131
+ const { cancel } = resetAll();
2132
+ disposal = storage(async () => {
2133
+ if (session) await backend.clear(true);
2134
+ });
2135
+ disposal = disposal.catch((error) => {
2136
+ disposal = void 0;
2137
+ throw error;
2138
+ });
2139
+ cancel();
2140
+ }
2141
+ return disposal;
2142
+ }
2143
+ };
2144
+ }
2145
+ function object(value) {
2146
+ return typeof value === "object" && value !== null;
2147
+ }
2148
+ function metadata(value) {
2149
+ if (!object(value) || typeof value.version !== "string" || !value.version || !(value.etag === null || typeof value.etag === "string") || typeof value.invalidated !== "boolean") return void 0;
2150
+ const validTime = typeof value.validatedAt === "number" && Number.isFinite(value.validatedAt) && value.validatedAt >= 0;
2151
+ return {
2152
+ version: value.version,
2153
+ etag: value.etag,
2154
+ validatedAt: validTime ? value.validatedAt : 0,
2155
+ invalidated: !validTime || value.invalidated === true
2156
+ };
2157
+ }
2158
+ function stored(meta, body) {
2159
+ if (!object(body) || body.version !== meta.version || !Object.hasOwn(body, "data")) return void 0;
2160
+ return {
2161
+ meta,
2162
+ body: { data: body.data }
2163
+ };
2164
+ }
2165
+ var storagePrefix = "@oomol-lab/resource-cache:";
2166
+ /** Delimit identity fields without ambiguous string concatenation. @internal */
2167
+ function scope(namespace) {
2168
+ return storagePrefix + JSON.stringify(namespace);
2169
+ }
2170
+ /** @internal */
2171
+ function sessionScope(namespace, sessionId) {
2172
+ return storagePrefix + JSON.stringify([namespace, sessionId]);
2173
+ }
2174
+ /** @internal */
2175
+ function persistentStorage(namespace, schemaVersion) {
2176
+ const useStore = createStore("@oomol-lab/resource-cache", "records");
2177
+ const prefix = `${scope(namespace)}:${schemaVersion}:`;
2178
+ const identity = (key, part) => prefix + JSON.stringify([key, part]);
2179
+ function transaction(mode, work) {
2180
+ return useStore(mode, (store) => new Promise((resolve, reject) => {
2181
+ const tx = store.transaction;
2182
+ let value;
2183
+ let failure;
2184
+ tx.oncomplete = () => resolve(value);
2185
+ tx.onabort = () => reject(failure ?? tx.error);
2186
+ const guard = (fn) => {
2187
+ try {
2188
+ fn();
2189
+ } catch (error) {
2190
+ failure = error;
2191
+ tx.abort();
2192
+ }
2193
+ };
2194
+ const read = (request, fn) => {
2195
+ request.onsuccess = () => guard(() => fn(request.result));
2196
+ };
2197
+ guard(() => work(store, read, (result) => {
2198
+ value = result;
2199
+ }));
2200
+ }));
2201
+ }
2202
+ return {
2203
+ read(key, version) {
2204
+ return transaction("readonly", (store, read, result) => {
2205
+ read(store.get(identity(key, "meta")), (raw) => {
2206
+ const meta = metadata(raw);
2207
+ if (!meta) return;
2208
+ if (meta.version === version) {
2209
+ result({ meta });
2210
+ return;
2211
+ }
2212
+ read(store.get(identity(key, "body")), (body) => result(stored(meta, body)));
2213
+ });
2214
+ });
2215
+ },
2216
+ write(key, entry, modified) {
2217
+ return transaction("readwrite", (store, read, result) => {
2218
+ const { data, ...meta } = entry;
2219
+ if (modified) {
2220
+ store.put(meta, identity(key, "meta"));
2221
+ store.put({
2222
+ version: meta.version,
2223
+ data
2224
+ }, identity(key, "body"));
2225
+ result(true);
2226
+ } else read(store.get(identity(key, "meta")), (raw) => {
2227
+ const matches = metadata(raw)?.version === meta.version;
2228
+ if (matches) store.put(meta, identity(key, "meta"));
2229
+ result(matches);
2230
+ });
2231
+ });
2232
+ },
2233
+ invalidate(key) {
2234
+ return transaction("readwrite", (store, read, result) => {
2235
+ read(store.get(identity(key, "meta")), (raw) => {
2236
+ const meta = metadata(raw);
2237
+ if (!meta) return;
2238
+ meta.invalidated = true;
2239
+ store.put(meta, identity(key, "meta"));
2240
+ read(store.get(identity(key, "body")), (body) => result(stored(meta, body)));
2241
+ });
2242
+ });
2243
+ },
2244
+ remove(key) {
2245
+ return transaction("readwrite", (store) => {
2246
+ store.delete(identity(key, "meta"));
2247
+ store.delete(identity(key, "body"));
2248
+ });
2249
+ },
2250
+ clear() {
2251
+ return transaction("readwrite", (store, read) => {
2252
+ read(store.getAllKeys(), (keys) => {
2253
+ for (const key of keys) if (typeof key === "string" && key.startsWith(prefix)) store.delete(key);
2254
+ });
2255
+ });
2256
+ }
2257
+ };
2258
+ }
2259
+ /** @internal */
2260
+ function sessionStorageBackend(namespace, schemaVersion, sessionId) {
2261
+ const base = `${sessionScope(namespace, sessionId)}:`;
2262
+ const prefix = `${base}${schemaVersion}:`;
2263
+ const identity = (key) => prefix + JSON.stringify(key);
2264
+ const record = (key) => {
2265
+ const text = globalThis.sessionStorage.getItem(identity(key));
2266
+ if (text === null) return void 0;
2267
+ const raw = JSON.parse(text);
2268
+ const meta = metadata(raw);
2269
+ return meta ? stored(meta, raw) : void 0;
2270
+ };
2271
+ return {
2272
+ async read(key, version) {
2273
+ const value = record(key);
2274
+ if (value && value.meta.version === version) return { meta: value.meta };
2275
+ return value;
2276
+ },
2277
+ async write(key, entry, modified) {
2278
+ if (modified) {
2279
+ globalThis.sessionStorage.setItem(identity(key), JSON.stringify(entry));
2280
+ return true;
2281
+ } else {
2282
+ const value = record(key);
2283
+ if (value?.meta.version === entry.version) {
2284
+ const { data: _data, ...meta } = entry;
2285
+ globalThis.sessionStorage.setItem(identity(key), JSON.stringify({
2286
+ ...meta,
2287
+ data: value.body.data
2288
+ }));
2289
+ return true;
2290
+ }
2291
+ return false;
2292
+ }
2293
+ },
2294
+ async invalidate(key) {
2295
+ const value = record(key);
2296
+ if (value) {
2297
+ value.meta.invalidated = true;
2298
+ globalThis.sessionStorage.setItem(identity(key), JSON.stringify({
2299
+ ...value.meta,
2300
+ ...value.body
2301
+ }));
2302
+ }
2303
+ return value;
2304
+ },
2305
+ async remove(key) {
2306
+ globalThis.sessionStorage.removeItem(identity(key));
2307
+ },
2308
+ async clear(allVersions) {
2309
+ const storage = globalThis.sessionStorage;
2310
+ const matches = [];
2311
+ for (let i = 0; i < storage.length; i++) {
2312
+ const key = storage.key(i);
2313
+ if (key.startsWith(allVersions ? base : prefix)) matches.push(key);
2314
+ }
2315
+ for (const key of matches) storage.removeItem(key);
2316
+ }
2317
+ };
2318
+ }
2319
+ /** Create an IndexedDB cache. Storage failures preserve successful network results. */
2320
+ function createPersistentCache(options) {
2321
+ validateOptions(options);
2322
+ return createCache({ ...options }, persistentStorage(options.namespace, options.schemaVersion), false);
2323
+ }
2324
+ /** Create a login-scoped sessionStorage cache. Data must survive JSON serialization and decoding. */
2325
+ function createSessionCache(options) {
2326
+ validateOptions(options);
2327
+ if (typeof options.sessionId !== "string" || !options.sessionId.trim()) throw new TypeError("sessionId must be nonempty");
2328
+ return createCache({ ...options }, sessionStorageBackend(options.namespace, options.schemaVersion, options.sessionId), true);
2329
+ }
1991
2330
  //#endregion
1992
- //#region src/workbench/browser/runtime/stores/catalogStorage.ts
1993
- var responses = createStore("open-flow-cache", "responses");
1994
- var indexedStorage = {
1995
- get: (key) => get(key, responses),
1996
- set: (key, value) => set(key, value, responses)
2331
+ //#region ../../node_modules/.bun/@oomol-lab+resource-cache@0.1.4/node_modules/@oomol-lab/resource-cache/dist/oomol.mjs
2332
+ /** Namespaces reserved for the OOMOL response factories. */
2333
+ var oomolNamespaces = {
2334
+ providers: "oomol:providers",
2335
+ actions: "oomol:actions",
2336
+ appCatalog: "oomol:app-catalog",
2337
+ connections: "oomol:connections"
1997
2338
  };
1998
- function catalogPersistence(options, kind, query) {
1999
- if (options == null) return void 0;
2000
- const storage = options.storage ?? indexedStorage;
2339
+ /** Join identity fields without nesting JSON in the storage key. */
2340
+ function readableKey(...parts) {
2341
+ return parts.map((part) => encodeURIComponent(String(part)).replaceAll("%3A", ":")).join("/");
2342
+ }
2343
+ var singletonRegistrySymbol = Symbol.for("oomol-lab.resource-cache.oomol-singletons");
2344
+ var singletonCaches = Reflect.get(globalThis, singletonRegistrySymbol) ?? (() => {
2345
+ const registry = /* @__PURE__ */ new Map();
2346
+ Reflect.set(globalThis, singletonRegistrySymbol, registry);
2347
+ return registry;
2348
+ })();
2349
+ function createOomolCache(resource, options, query) {
2350
+ const environment = validateOomolOptions(options);
2351
+ const { load } = options;
2352
+ const key = readableKey(query.locale);
2353
+ return createPersistentCache({
2354
+ namespace: readableKey(resource, environment),
2355
+ schemaVersion: options.schemaVersion,
2356
+ maxAge: options.maxAge,
2357
+ key: () => key,
2358
+ decode: options.decode,
2359
+ load: (_query, validation) => load({ ...query }, validation)
2360
+ });
2361
+ }
2362
+ function createConnectionsCacheInternal(options, validated) {
2363
+ const { environment, ownerId } = validated;
2364
+ const { load } = options;
2365
+ const key = readableKey(ownerId);
2366
+ return createSessionCache({
2367
+ namespace: readableKey(oomolNamespaces.connections, environment),
2368
+ schemaVersion: options.schemaVersion,
2369
+ maxAge: options.maxAge,
2370
+ sessionId: options.sessionId,
2371
+ key: () => key,
2372
+ decode: options.decode,
2373
+ load: (_query, validation) => load({ ownerId }, validation)
2374
+ });
2375
+ }
2376
+ function validateOomolOptions(options) {
2377
+ const environment = normalizeEnvironment(options.environment);
2378
+ if (typeof options.locale !== "string" || !options.locale.trim()) throw new TypeError("locale must be nonempty");
2379
+ if (typeof options.load !== "function") throw new TypeError("load must be a function");
2380
+ return environment;
2381
+ }
2382
+ function normalizeEnvironment(value) {
2383
+ const environment = value === void 0 ? "production" : value;
2384
+ if (typeof environment !== "string" || !environment.trim()) throw new TypeError("environment must be nonempty");
2385
+ return environment;
2386
+ }
2387
+ function normalizeOwnerId(value) {
2388
+ if (typeof value !== "string" || !value.trim()) throw new TypeError("ownerId must be nonempty");
2389
+ return value;
2390
+ }
2391
+ function validateConnectionsOptions(options) {
2392
+ const environment = normalizeEnvironment(options.environment);
2393
+ if (typeof options.sessionId !== "string" || !options.sessionId.trim()) throw new TypeError("sessionId must be nonempty");
2394
+ const ownerId = normalizeOwnerId(options.ownerId);
2395
+ if (typeof options.load !== "function") throw new TypeError("load must be a function");
2001
2396
  return {
2002
- key: `${kind}:v1:${query}`,
2003
- storage
2397
+ environment,
2398
+ ownerId
2004
2399
  };
2005
2400
  }
2401
+ /** Create an IndexedDB cache for the account-independent GET /v1/providers response, keyed by environment and locale. */
2402
+ function createProvidersCacheInternal(options) {
2403
+ return createOomolCache(oomolNamespaces.providers, options, { locale: options.locale });
2404
+ }
2405
+ /** Create an IndexedDB cache for account-independent GET /v1/actions?service=…, keyed by environment, locale and service. */
2406
+ function createActionsCacheInternal(options) {
2407
+ const environment = validateOomolOptions(options);
2408
+ const { locale, load } = options;
2409
+ return createPersistentCache({
2410
+ namespace: readableKey(oomolNamespaces.actions, environment),
2411
+ schemaVersion: options.schemaVersion,
2412
+ maxAge: options.maxAge,
2413
+ key: (service) => {
2414
+ if (typeof service !== "string" || !service.trim()) throw new TypeError("service must be nonempty");
2415
+ return readableKey(locale, service);
2416
+ },
2417
+ decode: options.decode,
2418
+ load: (service, validation) => load({
2419
+ locale,
2420
+ service
2421
+ }, validation)
2422
+ });
2423
+ }
2424
+ function singletonKey(resource, options, query, sessionId) {
2425
+ const environment = normalizeEnvironment(options.environment);
2426
+ return sessionId === void 0 ? readableKey(resource, environment, options.schemaVersion, ...query) : readableKey(resource, environment, options.schemaVersion, sessionId, ...query);
2427
+ }
2428
+ function getSingleton(key, create) {
2429
+ const existing = singletonCaches.get(key);
2430
+ if (existing) return existing;
2431
+ const cache = create();
2432
+ let disposal;
2433
+ const singleton = {
2434
+ ...cache,
2435
+ dispose() {
2436
+ if (!disposal) disposal = cache.dispose().then(() => {
2437
+ singletonCaches.delete(key);
2438
+ }, (error) => {
2439
+ disposal = void 0;
2440
+ throw error;
2441
+ });
2442
+ return disposal;
2443
+ }
2444
+ };
2445
+ singletonCaches.set(key, singleton);
2446
+ return singleton;
2447
+ }
2448
+ /** Return the shared Providers cache for one environment, locale and schema version. */
2449
+ function getProvidersCache(options) {
2450
+ const query = { locale: options.locale };
2451
+ return getSingleton(singletonKey(oomolNamespaces.providers, options, [query.locale]), () => createProvidersCacheInternal(options));
2452
+ }
2453
+ /** Return the shared Actions cache for one environment, locale and schema version. */
2454
+ function getActionsCache(options) {
2455
+ const query = { locale: options.locale };
2456
+ return getSingleton(singletonKey(oomolNamespaces.actions, options, [query.locale]), () => createActionsCacheInternal(options));
2457
+ }
2458
+ /** Return the shared sessionStorage cache for one login session and owner scope. */
2459
+ function getConnectionsCache(options) {
2460
+ const validated = validateConnectionsOptions(options);
2461
+ const query = { ownerId: validated.ownerId };
2462
+ return getSingleton(singletonKey(oomolNamespaces.connections, options, [query.ownerId], options.sessionId), () => createConnectionsCacheInternal(options, validated));
2463
+ }
2006
2464
  //#endregion
2007
2465
  //#region src/connector/common/actionSchema.ts
2008
2466
  function connectorActionPorts(inputSchema, outputSchema) {
@@ -2176,46 +2634,178 @@ function action(source, providers) {
2176
2634
  }
2177
2635
  //#endregion
2178
2636
  //#region src/workbench/browser/runtime/stores/catalogStores.ts
2179
- function actionsResponse(value) {
2637
+ var catalogMaxAge = {
2638
+ providers: 3e5,
2639
+ actions: 3e4,
2640
+ connections: 3e4
2641
+ };
2642
+ var identity = (...parts) => JSON.stringify(parts);
2643
+ function proxyCatalogPath(kind, flowId, locale, service) {
2644
+ return `/v1/connector/proxy/${kind}?${new URLSearchParams({
2645
+ ...flowId == null ? {} : { flowId },
2646
+ ...service == null ? {} : { service },
2647
+ locale
2648
+ })}`;
2649
+ }
2650
+ function mapCache(cache, toValue, toSnapshot, query) {
2651
+ return {
2652
+ get: async (value, options) => toValue(await cache.get(query(value), options)),
2653
+ peek: async (value) => {
2654
+ const snapshot = await cache.peek(query(value));
2655
+ return snapshot == null ? void 0 : {
2656
+ ...snapshot,
2657
+ data: toSnapshot(snapshot.data)
2658
+ };
2659
+ },
2660
+ invalidate: (value) => cache.invalidate(query(value)),
2661
+ remove: (value) => cache.remove(query(value)),
2662
+ clear: () => cache.clear(),
2663
+ dispose: () => cache.dispose()
2664
+ };
2665
+ }
2666
+ function providerCacheValue(value) {
2667
+ return proxyResponse(value);
2668
+ }
2669
+ function actionCacheValue(value) {
2670
+ return proxyResponse(value);
2671
+ }
2672
+ function connectionsCacheValue(value) {
2180
2673
  const source = record(value);
2181
- if (source.version != 1 || !Array.isArray(source.actions)) return invalidResponse();
2182
- return source.actions.map(connectorActionMetadata);
2674
+ if (source.success === true && Array.isArray(source.data)) return source;
2675
+ if (source.version == 1 && Array.isArray(source.connections)) return {
2676
+ success: true,
2677
+ message: "",
2678
+ data: source.connections,
2679
+ meta: { summary: {
2680
+ providerCount: 0,
2681
+ connectableProviderCount: 0,
2682
+ connectedProviderCount: 0,
2683
+ activeConnectedProviderCount: 0,
2684
+ connectedAppCount: source.connections.length,
2685
+ activeConnectedAppCount: source.connections.length,
2686
+ filteredAppCount: source.connections.length
2687
+ } }
2688
+ };
2689
+ return invalidResponse();
2183
2690
  }
2184
- var identity = (...parts) => JSON.stringify(parts);
2185
- /** Each entry owns one complete upstream response, never a merged entity catalog. */
2691
+ function connectionsAsProxy(value) {
2692
+ return value.data.map(connection);
2693
+ }
2694
+ /** Shared cache construction for one Workbench session. */
2695
+ var CacheFactory = class {
2696
+ #caches = /* @__PURE__ */ new Set();
2697
+ #entries = /* @__PURE__ */ new Map();
2698
+ #disposed = false;
2699
+ constructor(scope) {
2700
+ this.scope = scope;
2701
+ }
2702
+ cache(key, create, owned = true) {
2703
+ let entry = this.#entries.get(key);
2704
+ if (entry == null) {
2705
+ entry = create().then((cache) => {
2706
+ if (owned) {
2707
+ if (this.#disposed) cache.dispose();
2708
+ else this.#caches.add(cache);
2709
+ }
2710
+ return cache;
2711
+ });
2712
+ this.#entries.set(key, entry);
2713
+ }
2714
+ return entry;
2715
+ }
2716
+ async dispose() {
2717
+ this.#disposed = true;
2718
+ await Promise.all([...this.#caches].map((cache) => cache.dispose()));
2719
+ this.#caches.clear();
2720
+ this.#entries.clear();
2721
+ }
2722
+ get environment() {
2723
+ return this.scope.environment ?? "production";
2724
+ }
2725
+ get sessionId() {
2726
+ return this.scope.sessionId;
2727
+ }
2728
+ get connectorOwnerId() {
2729
+ return this.scope.connectorOwnerId;
2730
+ }
2731
+ };
2732
+ /** Each entry owns one complete upstream response; views are derived below. */
2186
2733
  var ProxyStore = class {
2187
- constructor(client, kind, options) {
2734
+ #factory;
2735
+ constructor(client, kind, scope) {
2188
2736
  this.client = client;
2189
2737
  this.kind = kind;
2190
- this.options = options;
2191
2738
  this.entries = /* @__PURE__ */ new Map();
2739
+ this.#factory = new CacheFactory(scope);
2192
2740
  }
2193
- get(flowId, locale, service, force = false) {
2194
- const params = new URLSearchParams({
2195
- ...flowId == null ? {} : { flowId },
2196
- ...service == null ? {} : { service },
2197
- ...locale == null ? {} : { locale }
2198
- });
2199
- const path = `/v1/connector/proxy/${this.kind}${params.size ? `?${params}` : ""}`;
2741
+ get(flowId, locale = "en", service, force = false) {
2742
+ const path = proxyCatalogPath(this.kind, flowId, locale, service);
2200
2743
  let entry = this.entries.get(path);
2201
2744
  if (entry == null) {
2202
- const decode = (value) => proxyResponse(value, this.kind == "providers" ? provider : void 0);
2203
- const cacheParams = new URLSearchParams(params);
2204
- cacheParams.delete("flowId");
2205
- const persistence = catalogPersistence(this.options, this.kind, cacheParams.toString());
2206
- entry = new Resource((etag, signal) => this.client.readProxyCatalog({
2207
- path,
2208
- decode
2209
- }, etag, signal), this.kind == "providers" ? 3e5 : 3e4, persistence == null ? void 0 : {
2210
- ...persistence,
2211
- decode
2212
- });
2745
+ entry = new CacheResource(() => this.#cache(flowId, locale, service, path), void 0, false, catalogMaxAge[this.kind]);
2213
2746
  this.entries.set(path, entry);
2214
2747
  }
2215
2748
  return entry.get(force);
2216
2749
  }
2750
+ async #cache(flowId, locale, service, path) {
2751
+ const ownerId = this.#factory.connectorOwnerId;
2752
+ const key = JSON.stringify([
2753
+ this.kind,
2754
+ flowId ?? null,
2755
+ locale,
2756
+ service ?? null,
2757
+ ownerId ?? null
2758
+ ]);
2759
+ return this.#factory.cache(key, async () => {
2760
+ if (ownerId != null) {
2761
+ if (this.kind == "providers") return mapCache(getProvidersCache({
2762
+ environment: this.#factory.environment,
2763
+ locale,
2764
+ schemaVersion: 1,
2765
+ maxAge: catalogMaxAge.providers,
2766
+ decode: providerCacheValue,
2767
+ load: async (_query, validation) => {
2768
+ return await this.client.readProxyCatalog({
2769
+ path,
2770
+ decode: providerCacheValue
2771
+ }, validation.etag, validation.signal);
2772
+ }
2773
+ }), (value) => value, (value) => value, () => void 0);
2774
+ return mapCache(getActionsCache({
2775
+ environment: this.#factory.environment,
2776
+ locale,
2777
+ schemaVersion: 1,
2778
+ maxAge: catalogMaxAge.actions,
2779
+ decode: actionCacheValue,
2780
+ load: async ({ service: requestedService }, validation) => {
2781
+ return await this.client.readProxyCatalog({
2782
+ path: proxyCatalogPath("actions", flowId, locale, requestedService),
2783
+ decode: actionCacheValue
2784
+ }, validation.etag, validation.signal);
2785
+ }
2786
+ }), (value) => value, (value) => value, () => service ?? "");
2787
+ }
2788
+ return createSessionCache({
2789
+ namespace: JSON.stringify([
2790
+ "open-flow:connector-proxy",
2791
+ this.#factory.environment,
2792
+ this.kind,
2793
+ flowId ?? null
2794
+ ]),
2795
+ schemaVersion: 1,
2796
+ sessionId: this.#factory.sessionId,
2797
+ maxAge: this.kind == "providers" ? catalogMaxAge.providers : catalogMaxAge.actions,
2798
+ key: () => JSON.stringify([locale, service ?? null]),
2799
+ decode: proxyResponse,
2800
+ load: async (_query, validation) => this.client.readProxyCatalog({
2801
+ path,
2802
+ decode: proxyResponse
2803
+ }, validation.etag, validation.signal)
2804
+ });
2805
+ }, ownerId == null);
2806
+ }
2217
2807
  retryFailed() {
2218
- for (const entry of this.entries.values()) if (entry.state.value.error != null) entry.refresh();
2808
+ for (const entry of this.entries.values()) if (entry.state.value.error != null) entry.refresh(true);
2219
2809
  }
2220
2810
  refreshFlow(flowId) {
2221
2811
  for (const [path, entry] of this.entries) if (new URL(path, "https://open-flow.invalid").searchParams.get("flowId") == flowId) entry.refresh(true);
@@ -2223,6 +2813,7 @@ var ProxyStore = class {
2223
2813
  dispose() {
2224
2814
  for (const entry of this.entries.values()) entry.dispose();
2225
2815
  this.entries.clear();
2816
+ this.#factory.dispose();
2226
2817
  }
2227
2818
  };
2228
2819
  var Views = class {
@@ -2273,8 +2864,8 @@ var Views = class {
2273
2864
  };
2274
2865
  var ProviderStore = class {
2275
2866
  #views = new Views();
2276
- constructor(client, options) {
2277
- this.raw = new ProxyStore(client, "providers", options);
2867
+ constructor(client, scope) {
2868
+ this.raw = new ProxyStore(client, "providers", scope);
2278
2869
  }
2279
2870
  get(flowId, locale = "en", force = false) {
2280
2871
  return this.#views.get(identity(flowId, locale), [this.raw.get(flowId, locale, void 0, force)], (response) => response.data.map((item) => provider(item, response.meta?.iconSprite)));
@@ -2291,33 +2882,17 @@ var ProviderStore = class {
2291
2882
  }
2292
2883
  };
2293
2884
  var ConnectionStore = class {
2294
- #storage = {
2295
- get: async (key) => {
2296
- const raw = (this.options?.storage ?? window.sessionStorage).getItem(key);
2297
- return raw == null ? void 0 : JSON.parse(raw);
2298
- },
2299
- set: async (key, value) => {
2300
- (this.options?.storage ?? window.sessionStorage).setItem(key, JSON.stringify(value));
2301
- }
2302
- };
2303
2885
  #entries = /* @__PURE__ */ new Map();
2304
2886
  #views = /* @__PURE__ */ new Map();
2305
- constructor(client, options) {
2887
+ #factory;
2888
+ constructor(client, scope) {
2306
2889
  this.client = client;
2307
- this.options = options;
2890
+ this.#factory = new CacheFactory(scope);
2308
2891
  }
2309
2892
  get(serviceId, flowId, force = false) {
2310
2893
  let entry = this.#entries.get(flowId);
2311
2894
  if (entry == null) {
2312
- const query = allConnectorConnectionsQuery(flowId);
2313
- entry = new Resource((etag, signal) => this.client.readCatalog(query, etag, signal), 3e4, this.options == null ? void 0 : {
2314
- key: `open-flow:connections:v1:${query.path}`,
2315
- storage: this.#storage,
2316
- decode: (value) => {
2317
- if (!Array.isArray(value)) return invalidResponse();
2318
- return value.map(connection);
2319
- }
2320
- });
2895
+ entry = new CacheResource(() => this.#cache(flowId), void 0, false, catalogMaxAge.connections);
2321
2896
  this.#entries.set(flowId, entry);
2322
2897
  }
2323
2898
  const source = entry.get(force);
@@ -2333,8 +2908,54 @@ var ConnectionStore = class {
2333
2908
  }
2334
2909
  return view;
2335
2910
  }
2911
+ async #cache(flowId) {
2912
+ const query = allConnectorConnectionsQuery(flowId);
2913
+ const ownerId = this.#factory.connectorOwnerId;
2914
+ const key = JSON.stringify([
2915
+ "connections",
2916
+ flowId ?? null,
2917
+ ownerId ?? null
2918
+ ]);
2919
+ return this.#factory.cache(key, async () => {
2920
+ if (ownerId != null) return mapCache(getConnectionsCache({
2921
+ environment: this.#factory.environment,
2922
+ sessionId: this.#factory.sessionId,
2923
+ ownerId,
2924
+ schemaVersion: 1,
2925
+ maxAge: catalogMaxAge.connections,
2926
+ decode: connectionsCacheValue,
2927
+ load: async (_query, validation) => {
2928
+ const result = await this.client.readCatalog(query, validation.etag, validation.signal);
2929
+ return result.modified ? {
2930
+ modified: true,
2931
+ data: connectionsCacheValue({
2932
+ version: 1,
2933
+ connections: result.data
2934
+ }),
2935
+ etag: result.etag
2936
+ } : result;
2937
+ }
2938
+ }), connectionsAsProxy, connectionsAsProxy, () => void 0);
2939
+ return createSessionCache({
2940
+ namespace: JSON.stringify([
2941
+ "open-flow:connections",
2942
+ this.#factory.environment,
2943
+ flowId ?? null
2944
+ ]),
2945
+ schemaVersion: 1,
2946
+ sessionId: this.#factory.sessionId,
2947
+ maxAge: catalogMaxAge.connections,
2948
+ key: () => "all",
2949
+ decode: (value) => {
2950
+ if (!Array.isArray(value)) return invalidResponse();
2951
+ return value.map(connection);
2952
+ },
2953
+ load: async (_query, validation) => this.client.readCatalog(query, validation.etag, validation.signal)
2954
+ });
2955
+ }, ownerId == null);
2956
+ }
2336
2957
  retryFailed() {
2337
- for (const entry of this.#entries.values()) if (entry.state.value.error != null) entry.refresh();
2958
+ for (const entry of this.#entries.values()) if (entry.state.value.error != null) entry.refresh(true);
2338
2959
  }
2339
2960
  refreshFlow(flowId) {
2340
2961
  this.#entries.get(flowId)?.refresh(true);
@@ -2344,6 +2965,7 @@ var ConnectionStore = class {
2344
2965
  this.#views.clear();
2345
2966
  for (const entry of this.#entries.values()) entry.dispose();
2346
2967
  this.#entries.clear();
2968
+ this.#factory.dispose();
2347
2969
  }
2348
2970
  };
2349
2971
  var ActionStore = class {
@@ -2352,10 +2974,10 @@ var ActionStore = class {
2352
2974
  #details = /* @__PURE__ */ new Map();
2353
2975
  #searches = /* @__PURE__ */ new Set();
2354
2976
  #searchSessions = /* @__PURE__ */ new WeakMap();
2355
- constructor(client, providers, options) {
2977
+ constructor(client, providers, scope) {
2356
2978
  this.client = client;
2357
2979
  this.providers = providers;
2358
- this.#raw = new ProxyStore(client, "actions", options);
2980
+ this.#raw = new ProxyStore(client, "actions", scope);
2359
2981
  }
2360
2982
  get(serviceId, flowId, locale = "en", force = false) {
2361
2983
  return this.#views.get(identity(flowId, serviceId, locale), [this.#raw.get(flowId, locale, serviceId, force), this.providers.raw.get(flowId, locale)], (actions, providers) => actions.data.flatMap((item) => {
@@ -2399,7 +3021,6 @@ var ActionStore = class {
2399
3021
  q: query.trim(),
2400
3022
  locale
2401
3023
  });
2402
- const key = params.toString();
2403
3024
  let entries = this.#searchSessions.get(signal);
2404
3025
  if (entries == null) {
2405
3026
  entries = /* @__PURE__ */ new Map();
@@ -2414,21 +3035,38 @@ var ActionStore = class {
2414
3035
  this.#searchSessions.delete(signal);
2415
3036
  }, { once: true });
2416
3037
  }
3038
+ const key = params.toString();
2417
3039
  const cached = entries.get(key);
2418
3040
  if (cached != null) {
2419
- cached.refresh();
3041
+ cached.refresh(true);
2420
3042
  return cached;
2421
3043
  }
2422
- const resource = new Resource((_etag, requestSignal) => this.client.readCatalog({
2423
- path: `/v1/connector/action-metadata?${params}`,
2424
- decode: actionsResponse
2425
- }, null, requestSignal), 3e4);
2426
- if (signal.aborted) resource.dispose();
3044
+ const cache = createSessionCache({
3045
+ namespace: JSON.stringify(["open-flow:action-search", crypto.randomUUID()]),
3046
+ schemaVersion: 1,
3047
+ sessionId: "search",
3048
+ maxAge: 0,
3049
+ key: () => "result",
3050
+ decode: (value) => {
3051
+ if (!Array.isArray(value)) return invalidResponse();
3052
+ return value.map(connectorActionMetadata);
3053
+ },
3054
+ load: async (_query, validation) => this.client.readCatalog({
3055
+ path: `/v1/connector/action-metadata?${params}`,
3056
+ decode: (value) => {
3057
+ const source = record(value);
3058
+ if (source.version != 1 || !Array.isArray(source.actions)) return invalidResponse();
3059
+ return source.actions.map(connectorActionMetadata);
3060
+ }
3061
+ }, validation.etag, validation.signal)
3062
+ });
3063
+ const result = new CacheResource(async () => cache, void 0, true, 0);
3064
+ if (signal.aborted) result.dispose();
2427
3065
  else {
2428
- entries.set(key, resource);
2429
- this.#searches.add(resource);
3066
+ entries.set(key, result);
3067
+ this.#searches.add(result);
2430
3068
  }
2431
- return resource;
3069
+ return result;
2432
3070
  }
2433
3071
  retryFailed() {
2434
3072
  this.#raw.retryFailed();
@@ -2446,10 +3084,10 @@ var ActionStore = class {
2446
3084
  }
2447
3085
  };
2448
3086
  var CatalogStores = class {
2449
- constructor(client, options, connections) {
2450
- this.providers = new ProviderStore(client, options);
2451
- this.actions = new ActionStore(client, this.providers, options);
2452
- this.connections = new ConnectionStore(client, connections);
3087
+ constructor(client, scope = { sessionId: crypto.randomUUID() }) {
3088
+ this.providers = new ProviderStore(client, scope);
3089
+ this.actions = new ActionStore(client, this.providers, scope);
3090
+ this.connections = new ConnectionStore(client, scope);
2453
3091
  }
2454
3092
  dispose() {
2455
3093
  this.actions.dispose();
@@ -2829,8 +3467,9 @@ var ConnectorStore = class {
2829
3467
  };
2830
3468
  this.provideAddNodeOptionChoices = (optionId, signal) => {
2831
3469
  const service = optionId.slice(19);
2832
- const source = this.data.actions.get(service, void 0, this.#language);
2833
- const providers = this.data.providers.get(void 0, this.#language);
3470
+ const flowId = this.#workspace.$.flowId.value;
3471
+ const source = this.data.actions.get(service, flowId, this.#language);
3472
+ const providers = this.data.providers.get(flowId, this.#language);
2834
3473
  return scopedValue(signal, (get) => {
2835
3474
  const state = get(source);
2836
3475
  const provider = get(providers).data?.find((item) => item.serviceId == service);
@@ -2961,12 +3600,22 @@ var ConnectorStore = class {
2961
3600
  this.#actionIds.set([]);
2962
3601
  this.#services.set([]);
2963
3602
  }
3603
+ retryAction(actionId) {
3604
+ const flowId = this.#workspace.$.flowId.value;
3605
+ if (flowId == null || this.#disposed) return;
3606
+ const actionState = this.data.actions.detail(actionId, flowId, this.#language, true);
3607
+ if (this.data.providers.get(flowId, this.#language).value.error != null) this.data.providers.get(flowId, this.#language, true);
3608
+ if (actionState.value.data?.authenticated !== false) this.data.connections.refreshFlow(flowId);
3609
+ }
2964
3610
  async resolveAction(actionId) {
2965
3611
  const flowId = this.#workspace.$.flowId.value;
2966
3612
  if (flowId == null || this.#disposed) throw new Error("Connector Action cannot be resolved without an active Flow.");
3613
+ const actionState = this.data.actions.detail(actionId, flowId, this.#language);
3614
+ await Promise.resolve();
3615
+ const action = await resourceValue(actionState, void 0, true);
3616
+ const connectionState = action.authenticated ? this.data.connections.get(action.serviceId, flowId) : void 0;
2967
3617
  await Promise.resolve();
2968
- const action = await resourceValue(this.data.actions.detail(actionId, flowId, this.#language), void 0, true);
2969
- const connections = action.authenticated ? await resourceValue(this.data.connections.get(action.serviceId, flowId), void 0, true) : [];
3618
+ const connections = connectionState == null ? [] : await resourceValue(connectionState, void 0, true);
2970
3619
  this.#remember(this.#actionIds, [actionId]);
2971
3620
  if (action.authenticated) this.#remember(this.#services, [action.serviceId]);
2972
3621
  return {
@@ -3143,9 +3792,9 @@ var ConnectorStore = class {
3143
3792
  var TriggerCatalogStore = class {
3144
3793
  #language;
3145
3794
  #entries;
3146
- constructor(client, language, host) {
3795
+ constructor(client, language, environment = "production") {
3147
3796
  this.client = client;
3148
- this.host = host;
3797
+ this.environment = environment;
3149
3798
  this.#entries = /* @__PURE__ */ new Map();
3150
3799
  this.retry = () => {
3151
3800
  this.get(true);
@@ -3161,14 +3810,18 @@ var TriggerCatalogStore = class {
3161
3810
  if (data.locale != locale) throw new Error("Unexpected Trigger catalog language.");
3162
3811
  return data;
3163
3812
  };
3164
- const persistence = catalogPersistence(this.host.catalogCache, "triggers", locale);
3165
- entry = new Resource((etag, signal) => this.client.readCatalog({
3166
- path: `/v1/trigger-keys/catalog?locale=${encodeURIComponent(locale)}`,
3167
- decode
3168
- }, etag, signal), 3e5, persistence == null ? void 0 : {
3169
- ...persistence,
3170
- decode
3813
+ const cache = createPersistentCache({
3814
+ namespace: JSON.stringify(["open-flow:trigger-catalog", this.environment]),
3815
+ schemaVersion: 1,
3816
+ maxAge: 3e5,
3817
+ key: () => locale,
3818
+ decode,
3819
+ load: async (_query, validation) => this.client.readCatalog({
3820
+ path: `/v1/trigger-keys/catalog?locale=${encodeURIComponent(locale)}`,
3821
+ decode
3822
+ }, validation.etag, validation.signal)
3171
3823
  });
3824
+ entry = new CacheResource(async () => cache, void 0, true, 3e5);
3172
3825
  this.#entries.set(locale, entry);
3173
3826
  }
3174
3827
  return entry;
@@ -3247,7 +3900,7 @@ var TriggerStore = class {
3247
3900
  this.#disposed = false;
3248
3901
  this.browseAddNodeOptions = (signal) => this.#options("", signal);
3249
3902
  this.provideAddNodeOptions = (searchTerm, signal) => this.#options(searchTerm, signal);
3250
- this.catalog = new TriggerCatalogStore(client, resolveUiLanguage([i18n.lang]), host);
3903
+ this.catalog = new TriggerCatalogStore(client, resolveUiLanguage([i18n.lang]), host.cacheEnvironment);
3251
3904
  this.#client = client;
3252
3905
  this.#host = host;
3253
3906
  this.#i18n = i18n;
@@ -3262,7 +3915,7 @@ var TriggerStore = class {
3262
3915
  if (trigger.kind != "poll" && trigger.kind != "integration") return { authorizationPending: false };
3263
3916
  const connections = current == null ? void 0 : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).data;
3264
3917
  const catalog = connections == null ? void 0 : connectionCatalog(connections);
3265
- const connectionError = current == null ? void 0 : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).error;
3918
+ const connectionError = current == null ? void 0 : state.connectionError?.provider == current.provider ? new Error(state.connectionError.message) : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).error;
3266
3919
  return {
3267
3920
  activeConnections: catalog?.active,
3268
3921
  authorizationPending: state.authorizationProvider == current?.provider,
@@ -3628,6 +4281,7 @@ function inverseFlowChanges(content, operations) {
3628
4281
  value: operation.before
3629
4282
  });
3630
4283
  break;
4284
+ case "task.openapi.set":
3631
4285
  case "task.agent.set":
3632
4286
  restore.push({
3633
4287
  ...operation,
@@ -5268,6 +5922,9 @@ var WorkspaceStore = class {
5268
5922
  position
5269
5923
  }));
5270
5924
  }
5925
+ loadOpenApiDocument(url, signal) {
5926
+ return this.#client.loadOpenApiDocument(url, signal);
5927
+ }
5271
5928
  async saveTaskSettings(nodeId, settings) {
5272
5929
  const revision = this.$.revision.value;
5273
5930
  const target = this.#model.value.target;
@@ -5817,7 +6474,7 @@ var WorkbenchStore = class {
5817
6474
  #openingCreatedFlow;
5818
6475
  #stopAccessReaction;
5819
6476
  #accessLoading;
5820
- constructor(client, preferences, identity = randomId, i18n = createI18n(), host = blockedExternalPages, variables = true) {
6477
+ constructor(client, preferences, identity = randomId, i18n = createI18n(), host = blockedExternalPages, variables = true, cacheSessionId = crypto.randomUUID()) {
5821
6478
  this.#externalRuns = new Latest();
5822
6479
  this.#notice = val();
5823
6480
  this.#variableNames = val([]);
@@ -5851,7 +6508,11 @@ var WorkbenchStore = class {
5851
6508
  this.workspace = new WorkspaceStore(client, setNotice, createAuthoringId, i18n, (event) => {
5852
6509
  if (event.kind == "run.created") this.#followExternalRun(client, event);
5853
6510
  else this.runs.changed(event.runId);
5854
- }, new CatalogStores(client, host.catalogCache, host.connectionCache), (flowId) => void this.#openCreatedFlow(flowId), (flowId) => {
6511
+ }, new CatalogStores(client, {
6512
+ sessionId: cacheSessionId,
6513
+ environment: host.cacheEnvironment,
6514
+ connectorOwnerId: host.connectorOwnerId
6515
+ }), (flowId) => void this.#openCreatedFlow(flowId), (flowId) => {
5855
6516
  this.connectorAccess.changed(flowId);
5856
6517
  this.workspace.catalogs.refreshFlow(flowId);
5857
6518
  });
@@ -6229,7 +6890,7 @@ var WorkbenchStore = class {
6229
6890
  };
6230
6891
  //#endregion
6231
6892
  //#region src/workbench/browser/runtime/openFlowWorkbench.tsx
6232
- var FlowWorkspace = lazy(() => import("./flowWorkspace-DBaq2Eks.js"));
6893
+ var FlowWorkspace = lazy(() => import("./flowWorkspace-DLgti4Lk.js"));
6233
6894
  function OpenFlowSessionGate({ action, description, error, onSubmit, onTokenChange, pending = false, title, token, tokenLabel }) {
6234
6895
  const hasToken = token != null && tokenLabel != null && onTokenChange != null;
6235
6896
  const tokenValue = token ?? "";
@@ -6364,17 +7025,17 @@ function Workbench({ catalogWidth, createFlow, createFlowDisabled, createFlowFie
6364
7025
  })
6365
7026
  });
6366
7027
  }
6367
- function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, preferences, theme, variables = true }) {
7028
+ function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, preferences, sessionKey, theme, variables = true }) {
6368
7029
  const navigate = useRef(onNavigate);
6369
7030
  navigate.current = onNavigate;
6370
7031
  const [{ i18n, navigation, store }] = useState(() => {
6371
7032
  const workbenchI18n = createI18n(language);
6372
7033
  const workbenchStore = new WorkbenchStore(new WorkbenchClient((input, init) => host.request(input, init), (flowId, listener) => host.subscribeFlow(flowId, listener), (listener) => host.subscribeFlowCatalog(listener)), preferences, randomId, workbenchI18n, {
6373
7034
  openExternalPage: (resolveUrl) => host.openExternalPage(resolveUrl),
6374
- catalogCache: host.catalogCache,
6375
- connectionCache: host.connectionCache,
7035
+ cacheEnvironment: host.cacheEnvironment,
7036
+ connectorOwnerId: host.connectorOwnerId,
6376
7037
  resolveActor: actorResolver(host, globalThis.location?.origin)
6377
- }, variables);
7038
+ }, variables, sessionKey);
6378
7039
  return {
6379
7040
  i18n: workbenchI18n,
6380
7041
  navigation: new NavigationStore(workbenchStore, location, (nextLocation, options) => navigate.current(nextLocation, options)),
@@ -6445,7 +7106,10 @@ function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField
6445
7106
  });
6446
7107
  }
6447
7108
  function OpenFlowWorkbench({ sessionKey, ...props }) {
6448
- return /* @__PURE__ */ jsx(Session, { ...props }, sessionKey);
7109
+ return /* @__PURE__ */ jsx(Session, {
7110
+ sessionKey,
7111
+ ...props
7112
+ }, `${sessionKey}:${props.host.connectorOwnerId ?? ""}`);
6449
7113
  }
6450
7114
  //#endregion
6451
7115
  export { EventSourcesPage, OpenFlowSessionGate, OpenFlowWorkbench, isUiLanguage as isWorkbenchLanguage, resolveUiLanguage as resolveWorkbenchLanguage, uiLanguageNames as workbenchLanguageNames, uiLanguages as workbenchLanguages };