@burdenoff/fluidgrids-fe-sdk 2026.1111.6 → 2026.1111.8

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 (44) hide show
  1. package/dist/{ExecutionDetailPage-wWQocYtw.js → ExecutionDetailPage-bhdyEtzU.js} +11 -11
  2. package/dist/{FailureTriagePanel-LodnXzJr.js → FailureTriagePanel-D4knfH8i.js} +2 -2
  3. package/dist/{FluidGridsProvider-BNzMznqt.js → FluidGridsProvider-CGu1DfIa.js} +332 -144
  4. package/dist/{HistoryPage-DIioKCod.js → HistoryPage-DzNRgeBL.js} +3 -3
  5. package/dist/{InsightsPage-Bm2oCTqf.js → InsightsPage-BWly1n0F.js} +6 -6
  6. package/dist/{ManagedAiPolicyAuthority-D624rJtj.js → ManagedAiPolicyAuthority-DHRJTAea.js} +7 -7
  7. package/dist/{MissingNodesInstallModal-5iwp-P3H.js → MissingNodesInstallModal-BFv9-cc9.js} +2 -2
  8. package/dist/{NodesPage-CYijlEFV.js → NodesPage-Cp11Xnmg.js} +2 -2
  9. package/dist/{PublishCustomNodeAction-CGrwIjy-.js → PublishCustomNodeAction-Bdgdkxf_.js} +1 -1
  10. package/dist/{TemplateConfigurationModal-BRjVScYa.js → TemplateConfigurationModal-Ho9dSHbX.js} +2 -2
  11. package/dist/{TemplateDetailPanel-BP43BIne.js → TemplateDetailPanel-CzkeesaA.js} +3 -3
  12. package/dist/{TemplatesPage-Bw--Ybm9.js → TemplatesPage-BzLhlV88.js} +6 -6
  13. package/dist/{VersionDiffDialog-87FMkJQb.js → VersionDiffDialog-C6sKSLQJ.js} +1 -1
  14. package/dist/{WorkflowProposalCard-1Av72TtA.js → WorkflowProposalCard-Bu3Y8Blm.js} +2 -2
  15. package/dist/{WorkflowSearchRedirect-IDjgBWKT.js → WorkflowSearchRedirect-DgQSfDvn.js} +13 -12
  16. package/dist/{WorkflowShareDialog-EsWpP8h1.js → WorkflowShareDialog-CPUkd7CL.js} +3 -3
  17. package/dist/{WorkflowsList-C-beGZ58.js → WorkflowsList-C5NllPOu.js} +6 -6
  18. package/dist/{agent-form-IKft_4iz.js → agent-form-L-gYYgLb.js} +1 -1
  19. package/dist/{agentTools-BQY87HJw.js → agentTools-DwvW-jXU.js} +2 -2
  20. package/dist/{ai-usage-CMWDlKmM.js → ai-usage-D5p7ZeRR.js} +1 -1
  21. package/dist/{codec-client-DEBa-Wl0.js → codec-client-C_eJuWkT.js} +1 -1
  22. package/dist/executions.js +1 -1
  23. package/dist/{flow-builder-DOw2DgVO.js → flow-builder-C5R5Bopw.js} +32 -27
  24. package/dist/{graphql-types-Bi7XFTD2.js → graphql-types-XcDLtFwU.js} +72 -1
  25. package/dist/history.js +1 -1
  26. package/dist/{index-CavhNsSY.d.ts → index-Cy9jNjgY.d.ts} +442 -2
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +26 -26
  29. package/dist/{node-detail-view-D56v1bff.js → node-detail-view-BeCa5NkB.js} +8 -8
  30. package/dist/{node-endpoint-configs-Dol5ckHv.js → node-endpoint-configs-n4xr62e4.js} +1179 -405
  31. package/dist/nodes.js +1 -1
  32. package/dist/observability.d.ts +1 -1
  33. package/dist/observability.js +1 -1
  34. package/dist/{quick-config-panel-BhkLeEy4.js → quick-config-panel-A8_WcO2r.js} +2 -2
  35. package/dist/settings.js +1 -1
  36. package/dist/templates.js +1 -1
  37. package/dist/{useAgentDefinitions-CUXSBw0L.js → useAgentDefinitions-D8Q-GkM7.js} +1 -1
  38. package/dist/{useExecutions-CvGl7yhb.js → useExecutions-nrxmx5sw.js} +3 -3
  39. package/dist/{useObservability--lPyvKqs.js → useObservability-D7v6zupc.js} +2 -2
  40. package/dist/{useRunHistory-Cu_oiZBw.js → useRunHistory-D-RieQFM.js} +3 -3
  41. package/dist/{useWorkflows-CGF0B59E.js → useWorkflows-DTJbPdQM.js} +6 -8
  42. package/dist/workflow-builder.js +2 -2
  43. package/dist/workflows-list.js +1 -1
  44. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
3
- import { Ai as waitForFluidGridsClient, Bi as throwIfResultError, Ei as getFluidGridsClientSafe, Fi as emitOperationErrorEvent, Gn as TriggerWorkflowDocument, Ii as emitRunCompletedOnce, Ji as setFluidGridsConfig, Ki as resetFluidGridsConfig, Li as describeOperationError, Oi as resetFluidGridsClient, Pi as emitFluidGridsEvent, R as CreateWorkflowVersionDocument, Ti as getFluidGridsClient, Vi as createLiveTokenReader, Wi as getFluidGridsConfig, Wr as WorkflowRunDocument, Yi as validateTrustedOrigin, at as EventRegistrationsDocument, gn as RunFromNodeDocument, ir as UpdateWorkflowDefinitionDocument, j as CreateWorkflowDefinitionDocument, ji as createFluidGridsTokenRefreshLink, ki as setFluidGridsClient, kt as NodeManifestDocument, ot as ExecuteStepDocument, qi as resetFluidGridsExecutionState, st as ExecutionDetailDocument, t as fetchAllNodeEndpointConfigs, wi as createFluidGridsClient, wr as WorkflowDefinitionDocument } from "./node-endpoint-configs-Dol5ckHv.js";
3
+ import { $i as validateTrustedOrigin, Ai as getFluidGridsClientSafe, At as NodeManifestsDocument, Bi as emitRunCompletedOnce, Dr as WorkflowDefinitionDocument, En as SaveWorkflowDraftDocument, Fi as createFluidGridsTokenRefreshLink, Gi as createLiveTokenReader, Ji as getFluidGridsConfig, Jn as TriggerWorkflowDocument, Jr as WorkflowRunDocument, Mi as resetFluidGridsClient, Ni as setFluidGridsClient, Oi as createFluidGridsClient, Pi as waitForFluidGridsClient, Qi as setFluidGridsConfig, R as CreateWorkflowVersionDocument, Ri as emitFluidGridsEvent, Vi as describeOperationError, Wi as throwIfResultError, Xi as resetFluidGridsConfig, Zi as resetFluidGridsExecutionState, at as EventRegistrationsDocument, j as CreateWorkflowDefinitionDocument, jt as NodePaletteEntriesDocument, ki as getFluidGridsClient, ot as ExecuteStepDocument, st as ExecutionDetailDocument, t as fetchAllNodeEndpointConfigs, vn as RunFromNodeDocument, zi as emitOperationErrorEvent } from "./node-endpoint-configs-n4xr62e4.js";
4
4
  import { A as nodeAccent, C as nodeAdaptersOf, D as NodeCard, E as resolveOutputHandles, H as useFlowStore, I as partitionStickyNotes, L as resolveStickyColor, N as DEFAULT_STICKY_COLOR, O as NodeCardBody, P as STICKY_COLORS, R as stickySurfaceStyle, T as resolveInputHandles, V as STICKY_NOTE_TYPE, W as isNodeTrigger, _ as LogicNodeCard, b as alignPlainOutputEdges, i as WAIT_FOR_SIGNAL_NODE_TYPE, j as NodeTypeIcon, k as NodeCardHeader, l as interfaceFields, m as readSignalName, n as synchronizeOperationUpdate, p as readCodeWorkflowState, r as CODE_WORKFLOW_NODE_TYPE, t as resolveOperationName, u as interfaceHandlers, v as InputHandles, w as outputHandlesSpacerHeight, x as hasNodeManifest, y as OutputHandles } from "./node-operation-selection--oy-yEq_.js";
5
5
  import { n as FluidGridsTranslationProvider, r as useTr, t as ENGLISH_FALLBACK_TRANSLATOR } from "./TranslationBridge-Da-TPgQm.js";
6
6
  import { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
@@ -3769,8 +3769,10 @@ function prepareNodeForSave(node) {
3769
3769
  return prepareNodeForSave$1(node, slimNodeDataToCurrentOperation);
3770
3770
  }
3771
3771
  /**
3772
- * The stored `definitionJson` of a saved version, read fresh, so a save keeps
3773
- * what other screens wrote there (the Settings page's `config`).
3772
+ * The stored `definitionJson` of a saved version, read fresh, so a save that
3773
+ * creates a new version from it keeps what other screens wrote there (the
3774
+ * Settings page's `config`). A save in place does not read it: the service
3775
+ * keeps those fields itself (`mergeStoredDefinition`).
3774
3776
  */
3775
3777
  async function readStoredDefinition(client, dbId) {
3776
3778
  const { data } = throwIfResultError(await client.query({
@@ -3781,6 +3783,21 @@ async function readStoredDefinition(client, dbId) {
3781
3783
  if (!data?.workflowDefinition) throw new Error("Could not read the saved workflow before saving it");
3782
3784
  return data.workflowDefinition.definitionJson;
3783
3785
  }
3786
+ /**
3787
+ * Drop a saved version's cached `definitionJson`. The draft save no longer
3788
+ * reads the definition back (BOFF-10389), so the cached copy is the one from
3789
+ * before the save; a later cache-first read must go to the service instead.
3790
+ */
3791
+ function forgetCachedDefinition(client, dbId) {
3792
+ const id = client.cache.identify({
3793
+ __typename: "WorkflowDefinition",
3794
+ id: dbId
3795
+ });
3796
+ if (id) client.cache.evict({
3797
+ id,
3798
+ fieldName: "definitionJson"
3799
+ });
3800
+ }
3784
3801
  /** The canvas part of `definitionJson`, as the builder has always written it. */
3785
3802
  function builderDefinition(snapshot, workflowKey, minted) {
3786
3803
  const { workflow } = snapshot;
@@ -3839,20 +3856,22 @@ function useSaveWorkflow() {
3839
3856
  const workflowKey = snapshot.key || mintedKey || "";
3840
3857
  const forkRequested = asNewVersion && !!workflow.dbId;
3841
3858
  const isDraft = !forkRequested && (!workflow.status || workflow.status === "DRAFT");
3859
+ const inPlace = !forkRequested && savesInPlace(workflow);
3842
3860
  const expectedRevision = revisionOf(workflow.dbId);
3843
3861
  const client = getFluidGridsClient();
3844
3862
  const { preparedWorkflow, owned } = builderDefinition(snapshot, workflowKey, !!mintedKey);
3845
- const definitionJson = workflow.dbId ? mergeDefinitionJson(await readStoredDefinition(client, workflow.dbId), owned) : owned;
3863
+ const definitionJson = workflow.dbId && !inPlace ? mergeDefinitionJson(await readStoredDefinition(client, workflow.dbId), owned) : owned;
3846
3864
  let savedVersion = workflow.version;
3847
3865
  let savedDbId = workflow.dbId;
3848
3866
  let operation = "updated";
3849
- if (workflow.dbId && savesInPlace(workflow)) {
3867
+ if (workflow.dbId && inPlace) {
3850
3868
  const { data } = throwIfResultError(await client.mutate({
3851
- mutation: UpdateWorkflowDefinitionDocument,
3869
+ mutation: SaveWorkflowDraftDocument,
3852
3870
  variables: {
3853
3871
  id: workflow.dbId,
3854
3872
  input: {
3855
3873
  definitionJson,
3874
+ mergeStoredDefinition: true,
3856
3875
  name: workflow.name,
3857
3876
  description: workflow.name || "Workflow update",
3858
3877
  alias: workflow.alias?.trim() ? workflow.alias.trim() : null,
@@ -3865,6 +3884,7 @@ function useSaveWorkflow() {
3865
3884
  savedVersion = data.updateWorkflowDefinition.version;
3866
3885
  savedDbId = data.updateWorkflowDefinition.id;
3867
3886
  rememberRevision(savedDbId, data.updateWorkflowDefinition.revision);
3887
+ forgetCachedDefinition(client, savedDbId);
3868
3888
  operation = "updated";
3869
3889
  if (!silent) toast.success("Workflow saved", {
3870
3890
  description: `Updated version ${savedVersion}`,
@@ -4063,14 +4083,23 @@ function isFlowComplete(nodes, edges) {
4063
4083
  const hasAnyLoneNode = nodesWithEmptyTarget.length > 0;
4064
4084
  return hasTriggerNode && isTriggerConnected && (!hasEndNode || isEndConnected) && !hasAnyLoneNode;
4065
4085
  }
4086
+ /**
4087
+ * Check the canvas with {@link isFlowComplete} and hand the answer to
4088
+ * `onValidate` (Save and Run). The check is synchronous and takes well under a
4089
+ * frame, so it runs at once (BOFF-10389: a fixed 300 ms wait used to delay
4090
+ * every Save and Run). `isValidating` stays true until `onValidate` settles,
4091
+ * so a second click while the save or run is starting is ignored.
4092
+ */
4066
4093
  function useFlowValidator(onValidate) {
4067
4094
  const [isValidating, setIsValidating] = useState(false);
4068
4095
  const { getNodes, getEdges } = useReactFlow();
4069
4096
  return [isValidating, useCallback(async () => {
4070
4097
  setIsValidating(true);
4071
- await new Promise((resolve) => setTimeout(resolve, 300));
4072
- onValidate?.(isFlowComplete(getNodes(), getEdges()));
4073
- setIsValidating(false);
4098
+ try {
4099
+ await onValidate?.(isFlowComplete(getNodes(), getEdges()));
4100
+ } finally {
4101
+ setIsValidating(false);
4102
+ }
4074
4103
  }, [
4075
4104
  getNodes,
4076
4105
  getEdges,
@@ -10109,38 +10138,88 @@ const OrganizationPrivateNodesDocument = {
10109
10138
  // src/graphql/global-operations.ts
10110
10139
  var global_operations_exports = /* @__PURE__ */ __exportAll({ InstallWorkflowNodeDocument: () => InstallWorkflowNodeDocument });
10111
10140
 
10112
- // src/builder/components/flow-builder/components/blocks/index.ts
10113
- const NODE_MANIFEST = NodeManifestDocument;
10114
- const NODE_CONFIGS = [];
10115
- /**
10116
- * Fetch node manifest using GraphQL
10117
- */
10118
- async function fetchNodeManifest(nodeType, nodeVersion) {
10119
- try {
10120
- const { data } = await getFluidGridsClient().query({
10121
- query: NODE_MANIFEST,
10122
- variables: {
10123
- nodeType,
10124
- version: nodeVersion
10125
- }
10126
- });
10127
- return data?.nodeManifest ?? null;
10128
- } catch (error) {
10129
- const message = error instanceof Error ? error.message : "Unknown error";
10130
- console.error(`Error fetching manifest for ${nodeType} v${nodeVersion}:`, message);
10131
- return null;
10141
+ // src/builder/components/flow-builder/components/blocks/node-manifests.ts
10142
+ /**
10143
+ * Refs per request. The server takes up to 500; smaller requests keep each
10144
+ * response to a few megabytes (store manifests reach 370 KB each) and let the
10145
+ * gateway resolve them side by side.
10146
+ */
10147
+ const NODE_MANIFEST_BATCH_SIZE = 100;
10148
+ const manifestCache = /* @__PURE__ */ new Map();
10149
+ function manifestKey(nodeType, version) {
10150
+ return `${nodeType}@${version}`;
10151
+ }
10152
+ /** The value as a node manifest, or null when it lacks the identifying fields. */
10153
+ function asNodeManifest(value) {
10154
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
10155
+ const record = value;
10156
+ if (typeof record.nodeType !== "string" || !record.nodeType || typeof record.version !== "string" || !record.version) return null;
10157
+ return {
10158
+ ...record,
10159
+ name: typeof record.name === "string" ? record.name : record.nodeType
10160
+ };
10161
+ }
10162
+ /** Keep manifests that arrived some other way (with a workflow) for the session. */
10163
+ function rememberNodeManifests(values) {
10164
+ const manifests = [];
10165
+ for (const value of values) {
10166
+ const manifest = asNodeManifest(value);
10167
+ if (!manifest) continue;
10168
+ manifestCache.set(manifestKey(manifest.nodeType, manifest.version), manifest);
10169
+ manifests.push(manifest);
10132
10170
  }
10171
+ return manifests;
10172
+ }
10173
+ /** The cached manifest of an exact node version, if this session loaded it. */
10174
+ function cachedNodeManifest(nodeType, version) {
10175
+ return manifestCache.get(manifestKey(nodeType, version));
10133
10176
  }
10134
10177
  /**
10135
- * Push a store node manifest entry into NODE_CONFIGS if not already present.
10136
- * Used for both BUILTIN-registered store nodes and user-installed store nodes
10137
- * whose manifest comes from the StoreAppInstallation record.
10178
+ * Manifests for `refs`: exact versions already in the session cache are served
10179
+ * from it; the rest are fetched with `nodeManifests`, at most
10180
+ * `NODE_MANIFEST_BATCH_SIZE` refs per request, all requests in parallel. Refs the
10181
+ * registry does not know are absent from the result. A failed request is logged
10182
+ * and its refs are treated as unknown, so one bad batch never empties the palette.
10138
10183
  */
10139
- function pushStoreNodeConfig(manifest, publishType = "STORE") {
10140
- if (NODE_CONFIGS.some((c) => c.type === manifest.nodeType)) return;
10184
+ async function loadNodeManifests(client, refs) {
10185
+ const result = [];
10186
+ const missing = [];
10187
+ const seen = /* @__PURE__ */ new Set();
10188
+ for (const ref of refs) {
10189
+ const key = manifestKey(ref.nodeType, ref.version ?? "");
10190
+ if (!ref.nodeType || seen.has(key)) continue;
10191
+ seen.add(key);
10192
+ const cached = ref.version ? cachedNodeManifest(ref.nodeType, ref.version) : void 0;
10193
+ if (cached) result.push(cached);
10194
+ else missing.push(ref.version ? ref : { nodeType: ref.nodeType });
10195
+ }
10196
+ const batches = [];
10197
+ for (let i = 0; i < missing.length; i += 100) batches.push(missing.slice(i, i + 100));
10198
+ const fetched = await Promise.all(batches.map(async (batch) => {
10199
+ try {
10200
+ const { data } = await client.query({
10201
+ query: NodeManifestsDocument,
10202
+ variables: { refs: batch },
10203
+ fetchPolicy: "no-cache"
10204
+ });
10205
+ return rememberNodeManifests(data?.nodeManifests ?? []);
10206
+ } catch (error) {
10207
+ const message = error instanceof Error ? error.message : String(error);
10208
+ console.error(`[Workflows] Could not load ${batch.length} node manifest(s):`, message);
10209
+ return [];
10210
+ }
10211
+ }));
10212
+ for (const manifests of fetched) result.push(...manifests);
10213
+ return result;
10214
+ }
10215
+
10216
+ // src/builder/components/flow-builder/components/blocks/index.ts
10217
+ const NODE_CONFIGS = [];
10218
+ /** The registry entry for one manifest. */
10219
+ function toNodeConfig(manifest, publishType) {
10141
10220
  const manifestOps = manifest.operations;
10142
10221
  const operations = Array.isArray(manifestOps) ? manifestOps : manifestOps?.operations ?? manifestOps;
10143
- NODE_CONFIGS.push({
10222
+ return {
10144
10223
  type: manifest.nodeType,
10145
10224
  detail: {
10146
10225
  icon: manifest.icon || "mynaui:keyboard-solid",
@@ -10165,21 +10244,36 @@ function pushStoreNodeConfig(manifest, publishType = "STORE") {
10165
10244
  },
10166
10245
  operations,
10167
10246
  publishType
10168
- });
10247
+ };
10248
+ }
10249
+ function hasNodeConfig(type) {
10250
+ return NODE_CONFIGS.some((config) => config.type === type);
10251
+ }
10252
+ /** Add a config unless its node type is already registered. */
10253
+ function addNodeConfig(config) {
10254
+ if (hasNodeConfig(config.type)) return false;
10255
+ NODE_CONFIGS.push(config);
10256
+ return true;
10169
10257
  }
10258
+ /** Only one installations request at a time: the canvas and the palette may both ask. */
10259
+ let installationsRequest = null;
10170
10260
  /**
10171
- * Load installed store nodes from the global store client.
10172
- * Uses the manifest stored in each StoreAppInstallation (recorded at install time)
10173
- * so store-svc is the single source of truth — no zip download or workflow-svc
10174
- * NodeEndpointConfig entry needed for store nodes.
10175
- *
10176
- * Silently no-ops if the global store client or workspaceId is not yet configured.
10261
+ * The manifests of the workspace's ACTIVE store installations, recorded at install
10262
+ * time. Store-svc is the single source of truth for them: no zip download or
10263
+ * workflow-svc registry entry is needed. Empty when the global store client or the
10264
+ * workspace is not configured yet.
10177
10265
  */
10178
- async function loadInstalledStoreNodes() {
10266
+ function fetchInstalledStoreNodeManifests() {
10267
+ if (!installationsRequest) installationsRequest = queryInstalledStoreNodeManifests().finally(() => {
10268
+ installationsRequest = null;
10269
+ });
10270
+ return installationsRequest;
10271
+ }
10272
+ async function queryInstalledStoreNodeManifests() {
10179
10273
  const globalClient = getGlobalStoreClient();
10180
- if (!globalClient) return;
10274
+ if (!globalClient) return [];
10181
10275
  const { workspaceId } = getFluidGridsConfig();
10182
- if (!workspaceId) return;
10276
+ if (!workspaceId) return [];
10183
10277
  try {
10184
10278
  const { data } = await globalClient.query({
10185
10279
  query: GetMyNodeInstallationsDocument,
@@ -10190,25 +10284,36 @@ async function loadInstalledStoreNodes() {
10190
10284
  },
10191
10285
  fetchPolicy: "network-only"
10192
10286
  });
10193
- const installations = data?.myStoreAppInstallations?.items ?? [];
10194
- let loaded = 0;
10195
- for (const installation of installations) {
10287
+ const manifests = [];
10288
+ for (const installation of data?.myStoreAppInstallations?.items ?? []) {
10196
10289
  if (installation.status !== "ACTIVE") continue;
10197
10290
  const manifest = installation.manifest;
10198
- if (!manifest?.nodeType) continue;
10199
- pushStoreNodeConfig(manifest, "STORE");
10200
- loaded++;
10291
+ if (manifest?.nodeType) manifests.push(manifest);
10201
10292
  }
10202
- if (loaded > 0) console.log(`[Workflows] Loaded ${loaded} installed store node(s) from workspace installations.`);
10293
+ return manifests;
10203
10294
  } catch (error) {
10204
10295
  const message = error instanceof Error ? error.message : "Unknown error";
10205
10296
  console.warn("[Workflows] Could not load installed store nodes:", message);
10297
+ return [];
10206
10298
  }
10207
10299
  }
10208
10300
  /**
10209
- * Fetch all nodes from GraphQL and populate NODE_CONFIGS.
10210
- * Loads BUILTIN nodes from workflow-svc, then overlays installed store nodes
10211
- * from the global store (using the manifest stored at install time).
10301
+ * Register installed store nodes. Any node type already registered (a built-in, or
10302
+ * a store node the registry vendors) is skipped; only genuinely missing ones are
10303
+ * added. `onlyTypes` limits it to those node types.
10304
+ */
10305
+ async function loadInstalledStoreNodes(onlyTypes) {
10306
+ const manifests = await fetchInstalledStoreNodeManifests();
10307
+ let loaded = 0;
10308
+ for (const manifest of manifests) {
10309
+ if (onlyTypes && !onlyTypes.has(manifest.nodeType)) continue;
10310
+ if (addNodeConfig(toNodeConfig(manifest, "STORE"))) loaded++;
10311
+ }
10312
+ if (loaded > 0) console.log(`[Workflows] Loaded ${loaded} installed store node(s) from workspace installations.`);
10313
+ }
10314
+ /**
10315
+ * Load the full palette into NODE_CONFIGS: every available registry node in the
10316
+ * registry's order (newest first), then the installed store nodes.
10212
10317
  */
10213
10318
  async function initializeNodeConfigs() {
10214
10319
  try {
@@ -10218,81 +10323,123 @@ async function initializeNodeConfigs() {
10218
10323
  await loadInstalledStoreNodes();
10219
10324
  return;
10220
10325
  }
10221
- const nodes = await fetchAllNodeEndpointConfigs(client, { status: "AVAILABLE" }, "cache-first");
10222
- if (nodes.length === 0) {
10326
+ const entries = await fetchAllNodeEndpointConfigs(client, { status: "AVAILABLE" }, "cache-first", NodePaletteEntriesDocument);
10327
+ if (entries.length === 0) {
10223
10328
  console.warn("No node endpoint configs found.");
10224
10329
  await loadInstalledStoreNodes();
10225
10330
  return;
10226
10331
  }
10227
- const manifestPromises = nodes.map(async (node) => {
10228
- if (node?.nodeType && node?.nodeVersion) try {
10229
- return await fetchNodeManifest(node.nodeType, node.nodeVersion);
10230
- } catch {
10231
- console.error(`Failed to fetch manifest for node ${node.id} (${node.nodeType} v${node.nodeVersion})`);
10232
- return null;
10233
- }
10234
- else {
10235
- console.warn(`Node ${node?.id ?? "unknown"} is missing nodeType or nodeVersion. Skipping manifest fetch.`);
10236
- return null;
10237
- }
10238
- });
10239
- (await Promise.all(manifestPromises)).forEach((manifest, index) => {
10240
- if (manifest === null) return;
10241
- const node = nodes[index];
10242
- const manifestOps = manifest.operations;
10243
- const operations = Array.isArray(manifestOps) ? manifestOps : manifestOps?.operations ?? manifestOps;
10244
- NODE_CONFIGS.push({
10245
- type: manifest.nodeType,
10246
- detail: {
10247
- icon: manifest.icon || "mynaui:keyboard-solid",
10248
- title: manifest.name,
10249
- description: manifest.description,
10250
- gradientColor: "yellow"
10251
- },
10252
- defaultData: {
10253
- operation_name: "",
10254
- operation_type: "",
10255
- nodeData: manifest,
10256
- version: manifest.version,
10257
- args: {
10258
- context: { node: {
10259
- id: manifest.nodeType,
10260
- kind: manifest.kind,
10261
- type: manifest.nodeType
10262
- } },
10263
- state: {},
10264
- credentials: []
10265
- }
10266
- },
10267
- operations,
10268
- publishType: node.publishType
10269
- });
10270
- });
10332
+ const manifests = await loadNodeManifests(client, entries.map((entry) => ({
10333
+ nodeType: entry.nodeType,
10334
+ version: entry.nodeVersion
10335
+ })));
10336
+ const byVersion = new Map(manifests.map((manifest) => [`${manifest.nodeType}@${manifest.version}`, manifest]));
10337
+ const palette = [];
10338
+ for (const entry of entries) {
10339
+ const manifest = byVersion.get(`${entry.nodeType}@${entry.nodeVersion}`);
10340
+ if (manifest) palette.push(toNodeConfig(manifest, entry.publishType ?? void 0));
10341
+ }
10342
+ const listed = new Set(palette.map((config) => config.type));
10343
+ const earlier = NODE_CONFIGS.filter((config) => !listed.has(config.type));
10344
+ NODE_CONFIGS.length = 0;
10345
+ NODE_CONFIGS.push(...palette, ...earlier);
10271
10346
  await loadInstalledStoreNodes();
10272
10347
  } catch (error) {
10273
10348
  const message = error instanceof Error ? error.message : "Unknown error";
10274
10349
  console.error("Failed to fetch nodes or manifests:", message);
10275
10350
  }
10276
10351
  }
10352
+ /** Node types the registry never has: canvas-only annotations. */
10353
+ function isRegistryNodeType(type) {
10354
+ return Boolean(type) && type !== "sticky-note" && type !== "default";
10355
+ }
10356
+ /** Node types being loaded for a canvas, so concurrent callers share one request. */
10357
+ const nodeTypeLoads = /* @__PURE__ */ new Map();
10358
+ async function loadNodeTypes(types) {
10359
+ try {
10360
+ const client = await waitForFluidGridsClient(15e3, 150);
10361
+ if (client) {
10362
+ const manifests = await loadNodeManifests(client, types.map((nodeType) => ({ nodeType })));
10363
+ for (const manifest of manifests) addNodeConfig(toNodeConfig(manifest, manifest.publishType));
10364
+ }
10365
+ const missing = new Set(types.filter((type) => !hasNodeConfig(type)));
10366
+ if (missing.size > 0) await loadInstalledStoreNodes(missing);
10367
+ } catch (error) {
10368
+ const message = error instanceof Error ? error.message : "Unknown error";
10369
+ console.error("[Workflows] Could not load node types:", message);
10370
+ }
10371
+ rebuildNodeArrays();
10372
+ }
10373
+ /**
10374
+ * Make sure the given node types are registered, without loading the rest of the
10375
+ * palette: what a canvas needs before it is drawn. Types already registered cost
10376
+ * nothing; the rest are fetched with one batched request, and a type the registry
10377
+ * does not carry is looked up among the workspace's installed store nodes. Types
10378
+ * that resolve nowhere stay unregistered (the canvas draws them with the fallback
10379
+ * card). Never rejects.
10380
+ */
10381
+ function ensureNodeTypesLoaded(types) {
10382
+ if (isInitialized) return Promise.resolve();
10383
+ const wanted = [...new Set(types)].filter((type) => isRegistryNodeType(type) && !hasNodeConfig(type));
10384
+ if (wanted.length === 0) return Promise.resolve();
10385
+ const pending = /* @__PURE__ */ new Set();
10386
+ const fresh = [];
10387
+ for (const type of wanted) {
10388
+ const inFlight = nodeTypeLoads.get(type);
10389
+ if (inFlight) pending.add(inFlight);
10390
+ else fresh.push(type);
10391
+ }
10392
+ if (fresh.length > 0) {
10393
+ const load = loadNodeTypes(fresh).finally(() => {
10394
+ for (const type of fresh) if (nodeTypeLoads.get(type) === load) nodeTypeLoads.delete(type);
10395
+ });
10396
+ for (const type of fresh) nodeTypeLoads.set(type, load);
10397
+ pending.add(load);
10398
+ }
10399
+ return Promise.all(pending).then(() => void 0);
10400
+ }
10277
10401
  /**
10278
- * Refetch all nodes by re-running initializeNodeConfigs.
10279
- * Called after installing/uninstalling a store node.
10402
+ * Register manifests that arrived with a workflow (`WorkflowDefinition.nodeManifests`)
10403
+ * and keep them in the session cache, so the canvas needs no further request.
10404
+ */
10405
+ function registerNodeManifests(values) {
10406
+ let added = false;
10407
+ for (const manifest of rememberNodeManifests(values)) if (addNodeConfig(toNodeConfig(manifest, manifest.publishType))) added = true;
10408
+ if (added) rebuildNodeArrays();
10409
+ }
10410
+ /** Register the client-side node components every canvas needs. */
10411
+ function registerBaseNodeTypes() {
10412
+ const fallback = getNodeMetadata({ type: "__default_dynamic__" });
10413
+ if (fallback?.node) NODE_TYPES["default"] = fallback.node;
10414
+ NODE_TYPES[STICKY_NOTE_TYPE] = StickyNoteNode;
10415
+ }
10416
+ /** Empty the registry, keeping only the client-side node components. */
10417
+ function resetNodeRegistry() {
10418
+ NODE_CONFIGS.length = 0;
10419
+ NODES.length = 0;
10420
+ AVAILABLE_NODES.length = 0;
10421
+ for (const key of Object.keys(NODE_TYPES)) delete NODE_TYPES[key];
10422
+ for (const key of Object.keys(NODES_METADATA)) delete NODES_METADATA[key];
10423
+ isInitialized = false;
10424
+ initPromise = null;
10425
+ nodeTypeLoads.clear();
10426
+ registerBaseNodeTypes();
10427
+ }
10428
+ /**
10429
+ * Reload the registry from scratch, as the full palette. Called after installing or
10430
+ * uninstalling a store node, and when the hosts set the workspace's clients.
10431
+ * Manifests stay in the session cache (they are fixed per version), so only new
10432
+ * ones are fetched.
10280
10433
  *
10281
- * Resets the initialization guard and all derived arrays so
10282
- * initializeNodeConfigs() runs a fresh fetch instead of returning early.
10434
+ * While nothing is loaded or loading there is nothing stale to refresh, and it does
10435
+ * nothing: the registry loads on demand (BOFF-10387). Hosts call this when they
10436
+ * mount, which used to load the whole palette before the builder had asked for
10437
+ * anything.
10283
10438
  */
10284
10439
  async function refetchStoreNodes() {
10440
+ if (NODE_CONFIGS.length === 0 && !initPromise && nodeTypeLoads.size === 0) return;
10285
10441
  try {
10286
- NODE_CONFIGS.length = 0;
10287
- NODES.length = 0;
10288
- AVAILABLE_NODES.length = 0;
10289
- for (const key of Object.keys(NODE_TYPES)) delete NODE_TYPES[key];
10290
- for (const key of Object.keys(NODES_METADATA)) delete NODES_METADATA[key];
10291
- isInitialized = false;
10292
- initPromise = null;
10293
- const fallback = getNodeMetadata({ type: "__default_dynamic__" });
10294
- if (fallback?.node) NODE_TYPES["default"] = fallback.node;
10295
- NODE_TYPES[STICKY_NOTE_TYPE] = StickyNoteNode;
10442
+ resetNodeRegistry();
10296
10443
  await initializeNodeConfigs();
10297
10444
  isInitialized = NODE_CONFIGS.length > 0;
10298
10445
  rebuildNodeArrays();
@@ -10350,7 +10497,7 @@ function registryNodeData(type) {
10350
10497
  return manifest ? manifest : void 0;
10351
10498
  }
10352
10499
  /**
10353
- * Ensure node configs are loaded. Safe to call multiple times.
10500
+ * Ensure the full palette is loaded. Safe to call multiple times.
10354
10501
  * Returns immediately if already initialized or initializing.
10355
10502
  */
10356
10503
  function ensureNodeConfigsLoaded() {
@@ -10363,33 +10510,74 @@ function ensureNodeConfigsLoaded() {
10363
10510
  return initPromise;
10364
10511
  }
10365
10512
  /**
10366
- * Check if node configs have been initialized
10513
+ * Check if the full palette has been loaded
10367
10514
  */
10368
10515
  function isNodeConfigsInitialized() {
10369
10516
  return isInitialized;
10370
10517
  }
10371
10518
  /**
10372
- * Rebuild NODES and derived arrays after NODE_CONFIGS is populated.
10373
- * This is called after lazy initialization completes.
10519
+ * How long an idle palette load may wait for the browser to go idle. A canvas
10520
+ * opens the palette's panels on demand anyway; this only bounds the wait when
10521
+ * the page never idles.
10374
10522
  */
10375
- function rebuildNodeArrays() {
10376
- NODE_CONFIGS.forEach((config) => {
10377
- const nodeMetadata = {
10378
- ...getNodeMetadata(config),
10379
- detail: { ...config.detail }
10380
- };
10381
- if (!NODES.some((n) => n.type === nodeMetadata.type)) {
10382
- NODES.push(nodeMetadata);
10383
- NODE_TYPES[nodeMetadata.type] = nodeMetadata.node;
10384
- NODES_METADATA[nodeMetadata.type] = {
10385
- ...nodeMetadata,
10386
- __details: {
10387
- type: nodeMetadata.type,
10388
- ...nodeMetadata.detail
10389
- }
10390
- };
10523
+ const NODE_PALETTE_IDLE_TIMEOUT_MS = 5e3;
10524
+ let paletteLoadScheduled = false;
10525
+ /**
10526
+ * Load the full palette once the page is idle (BOFF-10387): after a canvas is
10527
+ * drawn, so the palette is ready when the person opens it without delaying the
10528
+ * canvas. Does nothing when it is loaded, loading or already scheduled.
10529
+ */
10530
+ function scheduleNodePaletteLoad() {
10531
+ if (isInitialized || initPromise || paletteLoadScheduled) return;
10532
+ paletteLoadScheduled = true;
10533
+ const load = () => {
10534
+ paletteLoadScheduled = false;
10535
+ ensureNodeConfigsLoaded().catch((error) => {
10536
+ console.warn("[Workflows] Idle node palette load failed:", error);
10537
+ });
10538
+ };
10539
+ if (typeof window !== "undefined" && "requestIdleCallback" in window) window.requestIdleCallback(load, { timeout: NODE_PALETTE_IDLE_TIMEOUT_MS });
10540
+ else setTimeout(load, 1e3);
10541
+ }
10542
+ /** The registry entry of each config's node type, created on first sight. */
10543
+ function nodeMetadataFor(config) {
10544
+ const nodeMetadata = {
10545
+ ...getNodeMetadata(config),
10546
+ detail: { ...config.detail }
10547
+ };
10548
+ NODE_TYPES[nodeMetadata.type] = nodeMetadata.node;
10549
+ NODES_METADATA[nodeMetadata.type] = {
10550
+ ...nodeMetadata,
10551
+ __details: {
10552
+ type: nodeMetadata.type,
10553
+ ...nodeMetadata.detail
10391
10554
  }
10392
- });
10555
+ };
10556
+ return nodeMetadata;
10557
+ }
10558
+ /**
10559
+ * Rebuild NODES and derived arrays from NODE_CONFIGS, in its order.
10560
+ *
10561
+ * A node type keeps the entry (and the React component) it was first registered
10562
+ * with: replacing the component would remount every node of that type already on
10563
+ * the canvas. Called whenever the registry grows: the canvas's node types first,
10564
+ * the full palette later.
10565
+ */
10566
+ function rebuildNodeArrays() {
10567
+ const existing = new Map(NODES.map((node) => [node.type, node]));
10568
+ const ordered = [];
10569
+ const seen = /* @__PURE__ */ new Set();
10570
+ for (const config of NODE_CONFIGS) {
10571
+ if (seen.has(config.type)) continue;
10572
+ seen.add(config.type);
10573
+ ordered.push(existing.get(config.type) ?? nodeMetadataFor(config));
10574
+ }
10575
+ for (const node of NODES) if (!seen.has(node.type)) {
10576
+ seen.add(node.type);
10577
+ ordered.push(node);
10578
+ }
10579
+ NODES.length = 0;
10580
+ NODES.push(...ordered);
10393
10581
  const newAvailableNodes = NODES.filter((node) => node.available === void 0 || node.available).map((node) => {
10394
10582
  const nodeConfig = NODE_CONFIGS.find((config) => config.type === node.type);
10395
10583
  return {
@@ -10406,18 +10594,17 @@ function rebuildNodeArrays() {
10406
10594
  AVAILABLE_NODES.push(...newAvailableNodes);
10407
10595
  notifyNodeTypesListeners();
10408
10596
  }
10409
- ensureNodeConfigsLoaded().catch((err) => {
10410
- console.warn("[Workflows] Background node config initialization failed:", err);
10411
- });
10412
- const fallbackDynamic = getNodeMetadata({ type: "__default_dynamic__" });
10413
- if (fallbackDynamic?.node) NODE_TYPES["default"] = fallbackDynamic.node;
10414
- NODE_TYPES[STICKY_NOTE_TYPE] = StickyNoteNode;
10597
+ registerBaseNodeTypes();
10415
10598
  /**
10416
10599
  * Pre-register node types from the workflow definition so React Flow never sees unknown types.
10417
- * Called by FlowBuilderPage before hydrating the store.
10600
+ * Called by FlowBuilderPage before hydrating the store, and for nodes an assistant
10601
+ * adds to an open canvas. Unknown types get a fallback card at once; their real
10602
+ * registry entries load in the background and replace it (BOFF-10387).
10418
10603
  */
10419
10604
  function registerWorkflowNodeTypes(workflowNodes) {
10605
+ const unknownTypes = [];
10420
10606
  for (const node of workflowNodes) if (node.type && !NODE_TYPES[node.type]) {
10607
+ unknownTypes.push(node.type);
10421
10608
  const meta = getNodeMetadata({
10422
10609
  type: node.type,
10423
10610
  defaultData: {
@@ -10428,6 +10615,7 @@ function registerWorkflowNodeTypes(workflowNodes) {
10428
10615
  });
10429
10616
  if (meta?.node) NODE_TYPES[node.type] = meta.node;
10430
10617
  }
10618
+ ensureNodeTypesLoaded(unknownTypes);
10431
10619
  }
10432
10620
 
10433
10621
  // src/components/FluidGridsProvider.tsx
@@ -10628,4 +10816,4 @@ function useFluidGridsContext() {
10628
10816
  return context;
10629
10817
  }
10630
10818
 
10631
- export { casesFromRules as $, newConnectionProviderKey as $n, runDurationMs as $t, buildOperationSeed as A, declaredSignals as An, leaseCallSequence as At, nodeTitle as B, resolvePhaseCFlags as Bn, rememberOwnStatusChange as Bt, MyWorkflowTemplateSubmissionsDocument as C, findQuotaRefusal as Cn, saveIndicatorOf as Ct, UninstallWorkflowNodeDocument as D, loadDefinitionJson as Dn, bannerOf as Dt, UninstallOrganizationPrivateNodeDocument as E, clearCodeWorkflowDefinitionCache as En, useEditLeaseStore as Et, workflowParameterIssues as F, signalPayloadCard as Fn, tickAction as Ft, resolveUiSpec as G, useFluidGridsFlagsSettled as Gn, codeBuildIdOf as Gt, paramsFromOperation as H, useDurableFunctionNodesEnabled as Hn, AUTOSAVE_DEBOUNCE_MS as Ht, asRecord as I, FLUIDGRIDS_FLAGS as In, EDIT_SESSION_ID as It, optionListText as J, useSelfHostedWorkersEnabled as Jn, saveFailureActionOf as Jt, stripSubmitActions as K, usePaletteGates as Kn, findSaveConflict as Kt, coerceNumber as L, FLUIDGRIDS_FLAG_DEFAULTS as Ln, forgetSessionForReload as Lt, useInsertNode as M, parseRawSignalPayload as Mn, phaseAfterTakeOver as Mt, MissingParametersDialog as N, payloadFromCardValues as Nn, releasesOnClose as Nt, WithdrawWorkflowTemplateSubmissionDocument as O, useCodeWorkflowInterface as On, isLocked as Ot, useRunGuard as P, runSignalTargets as Pn, shouldReleaseForIdle as Pt, SwitchRulesEditor as Q, matchesAdapterProvider as Qn, nodeStateDurationMs as Qt, fixedParameterState as R, PHASE_C_FLAGS_OFF as Rn, rememberSessionForReload as Rt, InstallWorkflowNodeDocument as S, collectExtensions as Sn, refusalOfQuota as St, SubmitWorkflowTemplateDocument as T, useCanvasEdges as Tn, useEditLeaseLocked as Tt, selectedOperationOf as U, useDurableParityEnabled as Un, AUTOSAVE_RETRY_DELAYS_MS as Ut, optionText as V, useContinuousOptimisationEnabled as Vn, rememberRevision as Vt, useNodeConfig as W, useFluidGridsFlag as Wn, canAutosave as Wt, resolveLoadOptionsSpec as X, connectionsForAdapter as Xn, useNodeExecution as Xt, optionListValues as Y, useWorkflowTestsEnabled as Yn, workflowFingerprint as Yt, ConditionTreeBuilder as Z, isOptionalAdapter as Zn, formatElapsedMs as Zt, CreateStoreOrderDocument as _, nodesOf as _n, useSaveWorkflow as _t, NODES_METADATA as a, isParamVisible as an, createGlobalStoreClient as ar, useGuardedNavigate as at, InstallOrganizationPrivateNodeDocument as b, RUNS_QUOTA_NAME as bn, classifyCreateRefusal as bt, ensureNodeConfigsLoaded as c, emitNodeInstalled as cn, resetGlobalStoreClient as cr, departingSave as ct, refetchStoreNodes as d, emitRunStarted as dn, leavingLosesChanges as dt, formatParameterValue as en, replaceAdapterConnections as er, FieldTree as et, registerWorkflowNodeTypes as f, emitTemplateUsed as fn, savedEverythingBeforeLeaving as ft, BrowseWorkflowTemplatesDocument as g, emitWorkflowPublished as gn, useFlowValidator as gt, BrowseWorkflowNodesDocument as h, emitWorkflowLimitHit as hn, isFlowComplete as ht, AVAILABLE_NODES as i, resolveNodeOperation as in, useBuilderReadOnly as ir, missingRequiredParameters as it, createConfiguredNode as j, durableInterfaceOf as jn, phaseAfterAcquire as jt, getNodeMetadata as k, canSignalRun as kn, leaseCallQueue as kt, isNodeConfigsInitialized as l, emitRunFailed as ln, setGlobalStoreClient as lr, editStateFor as lt, global_operations_exports as m, emitWorkflowCreated as mn, watchLeavingLosesChanges as mt, FluidGridsProvider as n, structuredParameterType as nn, buildStickyNode as nr, latestNodeLog as nt, NODE_CONFIGS as o, useFluidGridsAnalytics as on, getGlobalStoreClient as or, useManualSave as ot, registryNodeData as p, emitUpgradeClicked as pn, touchesSavedFields as pt, isStringOptionList as q, usePhaseCFlags as qn, inAppLeaveTarget as qt, useFluidGridsContext as r, fieldsFromValue as rn, BuilderReadOnlyProvider as rr, boundFieldsOf as rt, NODE_TYPES as s, openRunQuotaUpgradePrompt as sn, global_client_exports as sr, autosaveAllowedFor as st, FluidGridsContext as t, parseParameterValue as tn, getNodeDetail as tr, parseMappingValue as tt, onNodeTypesUpdate as u, emitRunLimitHit as un, editingLeaseLocked as ut, GetMyNodeInstallationsDocument as v, runTriggerFromMode as vn, blankWorkflowCreateInput as vt, OrganizationPrivateNodesDocument as w, isQuotaExhaustedFailure as wn, useSaveStatusStore as wt, InstallPurchasedNodeDocument as x, WORKFLOWS_QUOTA_NAME as xn, createThenOpen as xt, GetNodeInstallableVersionsDocument as y, BILLING_PLANS_PATH as yn, builderPathOf as yt, nodeSubtitle as z, resolveFluidGridsFlagsSettled as zn, sessionBeforeReload as zt };
10819
+ export { resolveLoadOptionsSpec as $, useWorkflowTestsEnabled as $n, useNodeExecution as $t, UninstallWorkflowNodeDocument as A, clearCodeWorkflowDefinitionCache as An, bannerOf as At, coerceNumber as B, FLUIDGRIDS_FLAGS as Bn, forgetSessionForReload as Bt, InstallOrganizationPrivateNodeDocument as C, RUNS_QUOTA_NAME as Cn, classifyCreateRefusal as Ct, OrganizationPrivateNodesDocument as D, isQuotaExhaustedFailure as Dn, useSaveStatusStore as Dt, MyWorkflowTemplateSubmissionsDocument as E, findQuotaRefusal as En, saveIndicatorOf as Et, useInsertNode as F, durableInterfaceOf as Fn, phaseAfterTakeOver as Ft, paramsFromOperation as G, useContinuousOptimisationEnabled as Gn, AUTOSAVE_DEBOUNCE_MS as Gt, nodeSubtitle as H, PHASE_C_FLAGS_OFF as Hn, sessionBeforeReload as Ht, MissingParametersDialog as I, parseRawSignalPayload as In, releasesOnClose as It, resolveUiSpec as J, useFluidGridsFlag as Jn, codeBuildIdOf as Jt, selectedOperationOf as K, useDurableFunctionNodesEnabled as Kn, AUTOSAVE_RETRY_DELAYS_MS as Kt, useRunGuard as L, payloadFromCardValues as Ln, shouldReleaseForIdle as Lt, getNodeMetadata as M, useCodeWorkflowInterface as Mn, leaseCallQueue as Mt, buildOperationSeed as N, canSignalRun as Nn, leaseCallSequence as Nt, SubmitWorkflowTemplateDocument as O, useCanvasEdges as On, useEditLeaseLocked as Ot, createConfiguredNode as P, declaredSignals as Pn, phaseAfterAcquire as Pt, optionListValues as Q, useSelfHostedWorkersEnabled as Qn, workflowFingerprint as Qt, workflowParameterIssues as R, runSignalTargets as Rn, tickAction as Rt, GetNodeInstallableVersionsDocument as S, BILLING_PLANS_PATH as Sn, builderPathOf as St, InstallWorkflowNodeDocument as T, collectExtensions as Tn, refusalOfQuota as Tt, nodeTitle as U, resolveFluidGridsFlagsSettled as Un, rememberOwnStatusChange as Ut, fixedParameterState as V, FLUIDGRIDS_FLAG_DEFAULTS as Vn, rememberSessionForReload as Vt, optionText as W, resolvePhaseCFlags as Wn, rememberRevision as Wt, isStringOptionList as X, usePaletteGates as Xn, inAppLeaveTarget as Xt, stripSubmitActions as Y, useFluidGridsFlagsSettled as Yn, findSaveConflict as Yt, optionListText as Z, usePhaseCFlags as Zn, saveFailureActionOf as Zt, global_operations_exports as _, emitWorkflowCreated as _n, watchLeavingLosesChanges as _t, NODES_METADATA as a, structuredParameterType as an, getNodeDetail as ar, latestNodeLog as at, CreateStoreOrderDocument as b, nodesOf as bn, useSaveWorkflow as bt, ensureNodeConfigsLoaded as c, isParamVisible as cn, useBuilderReadOnly as cr, useGuardedNavigate as ct, onNodeTypesUpdate as d, emitNodeInstalled as dn, global_client_exports as dr, departingSave as dt, formatElapsedMs as en, connectionsForAdapter as er, ConditionTreeBuilder as et, refetchStoreNodes as f, emitRunFailed as fn, resetGlobalStoreClient as fr, editStateFor as ft, scheduleNodePaletteLoad as g, emitUpgradeClicked as gn, touchesSavedFields as gt, registryNodeData as h, emitTemplateUsed as hn, savedEverythingBeforeLeaving as ht, AVAILABLE_NODES as i, parseParameterValue as in, replaceAdapterConnections as ir, parseMappingValue as it, WithdrawWorkflowTemplateSubmissionDocument as j, loadDefinitionJson as jn, isLocked as jt, UninstallOrganizationPrivateNodeDocument as k, useNodeRegistryRevision as kn, useEditLeaseStore as kt, ensureNodeTypesLoaded as l, useFluidGridsAnalytics as ln, createGlobalStoreClient as lr, useManualSave as lt, registerWorkflowNodeTypes as m, emitRunStarted as mn, leavingLosesChanges as mt, FluidGridsProvider as n, runDurationMs as nn, matchesAdapterProvider as nr, casesFromRules as nt, NODE_CONFIGS as o, fieldsFromValue as on, buildStickyNode as or, boundFieldsOf as ot, registerNodeManifests as p, emitRunLimitHit as pn, setGlobalStoreClient as pr, editingLeaseLocked as pt, useNodeConfig as q, useDurableParityEnabled as qn, canAutosave as qt, useFluidGridsContext as r, formatParameterValue as rn, newConnectionProviderKey as rr, FieldTree as rt, NODE_TYPES as s, resolveNodeOperation as sn, BuilderReadOnlyProvider as sr, missingRequiredParameters as st, FluidGridsContext as t, nodeStateDurationMs as tn, isOptionalAdapter as tr, SwitchRulesEditor as tt, isNodeConfigsInitialized as u, openRunQuotaUpgradePrompt as un, getGlobalStoreClient as ur, autosaveAllowedFor as ut, BrowseWorkflowNodesDocument as v, emitWorkflowLimitHit as vn, isFlowComplete as vt, InstallPurchasedNodeDocument as w, WORKFLOWS_QUOTA_NAME as wn, createThenOpen as wt, GetMyNodeInstallationsDocument as x, runTriggerFromMode as xn, blankWorkflowCreateInput as xt, BrowseWorkflowTemplatesDocument as y, emitWorkflowPublished as yn, useFlowValidator as yt, asRecord as z, signalPayloadCard as zn, EDIT_SESSION_ID as zt };