@superblocksteam/library 2.0.104 → 2.0.105-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jsx-dev-runtime/index.js +1 -1
- package/dist/{jsx-wrapper-DnM3BCRU.js → jsx-wrapper-BCVlG9Wg.js} +31 -4
- package/dist/jsx-wrapper-BCVlG9Wg.js.map +1 -0
- package/dist/lib/index.d.ts +213 -14
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +547 -177
- package/dist/lib/index.js.map +1 -1
- package/package.json +6 -5
- package/dist/jsx-wrapper-DnM3BCRU.js.map +0 -1
package/dist/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as consoleLogAttributes, t as early_console_buffer_default } from "../early-console-buffer-D4wVuyBf.js";
|
|
2
|
-
import { A as useSuperblocksProfiles, B as createManagedPropsList, C as rejectById, D as useSuperblocksContext, E as getAppMode, F as editorBridge, G as getEditStore, H as PropsCategory, I as iframeMessageHandler, L as isEmbeddedBySuperblocksFirstParty, M as generateId, N as sendNotification, O as useSuperblocksDataTags, P as colors$1, R as sendMessageImmediately, S as addNewPromise, T as SuperblocksContextProvider, U as Section, V as Prop, W as createPropertiesPanelDefinition, _ as root_store_default, a as FixWithClarkButton, b as getContextFromTraceHeaders, c as ErrorContent, d as ErrorMessage$1, f as ErrorStack, g as StyledClarkIcon, h as SecondaryButton, i as getWidgetRectAnchorName, j as useSuperblocksUser, k as useSuperblocksGroups, l as ErrorDetails, m as ErrorTitle, n as useJSXContext, o as ActionsContainer, p as ErrorSummary, r as getWidgetAnchorName, s as ErrorContainer, u as ErrorIconContainer, v as startEditorSync, w as resolveById, x as api_hmr_tracker_default, y as createIframeSpan, z as isEditMode } from "../jsx-wrapper-
|
|
2
|
+
import { A as useSuperblocksProfiles, B as createManagedPropsList, C as rejectById, D as useSuperblocksContext, E as getAppMode, F as editorBridge, G as getEditStore, H as PropsCategory, I as iframeMessageHandler, L as isEmbeddedBySuperblocksFirstParty, M as generateId, N as sendNotification, O as useSuperblocksDataTags, P as colors$1, R as sendMessageImmediately, S as addNewPromise, T as SuperblocksContextProvider, U as Section, V as Prop, W as createPropertiesPanelDefinition, _ as root_store_default, a as FixWithClarkButton, b as getContextFromTraceHeaders, c as ErrorContent, d as ErrorMessage$1, f as ErrorStack, g as StyledClarkIcon, h as SecondaryButton, i as getWidgetRectAnchorName, j as useSuperblocksUser, k as useSuperblocksGroups, l as ErrorDetails, m as ErrorTitle, n as useJSXContext, o as ActionsContainer, p as ErrorSummary, r as getWidgetAnchorName, s as ErrorContainer, u as ErrorIconContainer, v as startEditorSync, w as resolveById, x as api_hmr_tracker_default, y as createIframeSpan, z as isEditMode } from "../jsx-wrapper-BCVlG9Wg.js";
|
|
3
3
|
import { n as initTracerProviderWithOrigin } from "../utils-BGEEeYie.js";
|
|
4
4
|
import { action, autorun, computed, makeAutoObservable, makeObservable, observable, reaction, when } from "mobx";
|
|
5
5
|
import { UNSAFE_DataRouterContext, generatePath, useLocation, useNavigate, useParams, useRouteError } from "react-router";
|
|
@@ -18,6 +18,7 @@ import colors from "tailwindcss/colors";
|
|
|
18
18
|
import { Observer, observer } from "mobx-react-lite";
|
|
19
19
|
import { getIntegrationDeclarations } from "@superblocksteam/sdk-api";
|
|
20
20
|
import zodToJsonSchema from "zod-to-json-schema";
|
|
21
|
+
import useSWR, { mutate } from "swr";
|
|
21
22
|
import * as Dialog from "@radix-ui/react-dialog";
|
|
22
23
|
import posthog from "posthog-js";
|
|
23
24
|
import { Graph } from "@dagrejs/graphlib";
|
|
@@ -965,6 +966,24 @@ function useGetCurrentUserQuery() {
|
|
|
965
966
|
}, []);
|
|
966
967
|
}
|
|
967
968
|
|
|
969
|
+
//#endregion
|
|
970
|
+
//#region src/lib/internal-details/lib/registry-loader.ts
|
|
971
|
+
/**
|
|
972
|
+
* Dynamically import the SDK API registry module from the app origin.
|
|
973
|
+
*
|
|
974
|
+
* Uses a cache-busting parameter because the browser's ES module map
|
|
975
|
+
* caches modules by URL — without it, subsequent import() calls return
|
|
976
|
+
* the stale first-load module and newly created APIs are never discovered.
|
|
977
|
+
*/
|
|
978
|
+
async function loadRegistryModule() {
|
|
979
|
+
const registryUrl = new URL("/server/apis/index.ts", window.location.origin);
|
|
980
|
+
registryUrl.searchParams.set("t", String(Date.now()));
|
|
981
|
+
return (await import(
|
|
982
|
+
/* @vite-ignore */
|
|
983
|
+
registryUrl.href
|
|
984
|
+
)).default;
|
|
985
|
+
}
|
|
986
|
+
|
|
968
987
|
//#endregion
|
|
969
988
|
//#region src/lib/internal-details/lib/utils/zod-to-typescript.ts
|
|
970
989
|
/**
|
|
@@ -1073,6 +1092,7 @@ function extractSdkApiMetadata(name, api, sourceCode) {
|
|
|
1073
1092
|
outputSchema,
|
|
1074
1093
|
isStreaming: false,
|
|
1075
1094
|
entryPoint,
|
|
1095
|
+
exportName: root_store_default.getApiExportName(name),
|
|
1076
1096
|
integrations: (api.integrations ?? []).map((integration) => ({
|
|
1077
1097
|
key: integration.key,
|
|
1078
1098
|
pluginId: integration.pluginId,
|
|
@@ -1154,7 +1174,7 @@ async function discoverAndRegisterSdkApis() {
|
|
|
1154
1174
|
if (!root_store_default.sdkApiEnabled) return;
|
|
1155
1175
|
if (!root_store_default.hasUnresolvedGate()) root_store_default.initDiscoveryGate();
|
|
1156
1176
|
try {
|
|
1157
|
-
const apis =
|
|
1177
|
+
const apis = await loadRegistryModule();
|
|
1158
1178
|
const apiNames = Object.keys(apis);
|
|
1159
1179
|
if (apiNames.length === 0) {
|
|
1160
1180
|
console.debug("[sdk-api-discovery] No SDK APIs found in registry");
|
|
@@ -1181,6 +1201,24 @@ async function discoverAndRegisterSdkApis() {
|
|
|
1181
1201
|
}
|
|
1182
1202
|
});
|
|
1183
1203
|
const sources = await Promise.all(sourcePromises);
|
|
1204
|
+
const namedImportMap = await buildRegistryNamedImportMap();
|
|
1205
|
+
for (let i = 0; i < apiNames.length; i++) {
|
|
1206
|
+
const source = sources[i];
|
|
1207
|
+
const name = apiNames[i];
|
|
1208
|
+
if (!source) continue;
|
|
1209
|
+
const namedExportName = namedImportMap.get(name);
|
|
1210
|
+
if (namedExportName !== void 0) {
|
|
1211
|
+
root_store_default.setApiExportName(name, namedExportName);
|
|
1212
|
+
continue;
|
|
1213
|
+
}
|
|
1214
|
+
if (/export\s+default\b/.test(source)) continue;
|
|
1215
|
+
const namedExportPattern = /export\s+(?:const|let|var)\s+(\w+)\s*=/g;
|
|
1216
|
+
let match;
|
|
1217
|
+
const exportNames = [];
|
|
1218
|
+
while ((match = namedExportPattern.exec(source)) !== null) if (match[1]) exportNames.push(match[1]);
|
|
1219
|
+
if (exportNames.length === 1) root_store_default.setApiExportName(name, exportNames[0]);
|
|
1220
|
+
else if (exportNames.length > 1) root_store_default.setApiExportName(name, name);
|
|
1221
|
+
}
|
|
1184
1222
|
const results = await Promise.allSettled(apiNames.map(async (name, i) => {
|
|
1185
1223
|
const apiModule = apis[name];
|
|
1186
1224
|
if (!apiModule) throw new Error(`API ${name} not found in registry`);
|
|
@@ -1195,6 +1233,47 @@ async function discoverAndRegisterSdkApis() {
|
|
|
1195
1233
|
root_store_default.notifyDiscoveryComplete();
|
|
1196
1234
|
}
|
|
1197
1235
|
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Fetches `server/apis/index.ts` and builds a map of ALL named imports:
|
|
1238
|
+
* `registryKey → originalExportName`.
|
|
1239
|
+
*
|
|
1240
|
+
* Given a registry line like:
|
|
1241
|
+
* import { GetAllUsers as ListUsers, CreateOrder } from './users.js'
|
|
1242
|
+
*
|
|
1243
|
+
* The map will contain:
|
|
1244
|
+
* ListUsers → GetAllUsers (aliased)
|
|
1245
|
+
* CreateOrder → CreateOrder (non-aliased)
|
|
1246
|
+
*
|
|
1247
|
+
* Also handles mixed default+named imports:
|
|
1248
|
+
* import Default, { GetOrders as ListOrders } from './orders.js'
|
|
1249
|
+
* → ListOrders → GetOrders
|
|
1250
|
+
*
|
|
1251
|
+
* Default imports and type-only imports are excluded.
|
|
1252
|
+
*/
|
|
1253
|
+
async function buildRegistryNamedImportMap() {
|
|
1254
|
+
const map = /* @__PURE__ */ new Map();
|
|
1255
|
+
try {
|
|
1256
|
+
const resp = await fetch("/sb-raw-source/server/apis/index.ts");
|
|
1257
|
+
if (!resp.ok) return map;
|
|
1258
|
+
const text = await resp.text();
|
|
1259
|
+
const importBlockPattern = /import\s+(?:type\s+)?(?:\w+\s*,\s*)?\{([^}]+)\}\s*from\s*['"][^'"]+['"]/g;
|
|
1260
|
+
let blockMatch;
|
|
1261
|
+
while ((blockMatch = importBlockPattern.exec(text)) !== null) {
|
|
1262
|
+
const fullStatement = blockMatch[0];
|
|
1263
|
+
if (/^import\s+type\b/.test(fullStatement)) continue;
|
|
1264
|
+
const specifiers = blockMatch[1].split(",");
|
|
1265
|
+
for (const spec of specifiers) {
|
|
1266
|
+
const trimmed = spec.trim();
|
|
1267
|
+
if (!trimmed || /^type\s/.test(trimmed)) continue;
|
|
1268
|
+
const parts = trimmed.split(/\s+as\s+/);
|
|
1269
|
+
const originalName = parts[0].trim();
|
|
1270
|
+
const localName = (parts[1] ?? originalName).trim();
|
|
1271
|
+
if (/^\w+$/.test(originalName) && /^\w+$/.test(localName)) map.set(localName, originalName);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
} catch {}
|
|
1275
|
+
return map;
|
|
1276
|
+
}
|
|
1198
1277
|
if (import.meta.hot) import.meta.hot.accept("/server/apis/index.ts", () => {
|
|
1199
1278
|
if (!root_store_default.sdkApiEnabled) return;
|
|
1200
1279
|
console.debug("[sdk-api-discovery] API registry updated via HMR, re-running discovery");
|
|
@@ -1204,6 +1283,360 @@ if (import.meta.hot) import.meta.hot.accept("/server/apis/index.ts", () => {
|
|
|
1204
1283
|
discoverAndRegisterSdkApis();
|
|
1205
1284
|
});
|
|
1206
1285
|
|
|
1286
|
+
//#endregion
|
|
1287
|
+
//#region src/lib/internal-details/query-cache.ts
|
|
1288
|
+
/**
|
|
1289
|
+
* query-cache — thin SWR-backed QueryClient.
|
|
1290
|
+
*
|
|
1291
|
+
* Replaces the hand-rolled QueryCache/QueryEntry/QueryClient with SWR's
|
|
1292
|
+
* built-in cache and mutate API. The module-scope `queryClient` singleton
|
|
1293
|
+
* survives React tree teardowns (critical for the iframe sb-init lifecycle)
|
|
1294
|
+
* because SWR's default cache is a module-scope Map.
|
|
1295
|
+
*
|
|
1296
|
+
* Public surface:
|
|
1297
|
+
* - `queryClient.invalidateQueries(prefix)` — cache invalidation
|
|
1298
|
+
* - `queryClient.setQueryData(key, data)` — optimistic updates
|
|
1299
|
+
* - `queryClient.getQueryData(key)` — read cached data
|
|
1300
|
+
* - `queryClient.buildCacheKey(apiName, inputs)` — deterministic key
|
|
1301
|
+
* - `queryClient.cache.clear()` — test helper
|
|
1302
|
+
*/
|
|
1303
|
+
const KEY_SEPARATOR = "::";
|
|
1304
|
+
const dataStore = /* @__PURE__ */ new Map();
|
|
1305
|
+
/** Last successful write time per cache key (survives hook remounts; used for `isStale`). */
|
|
1306
|
+
const dataUpdatedAtByKey = /* @__PURE__ */ new Map();
|
|
1307
|
+
/**
|
|
1308
|
+
* Build a deterministic, string cache key from API name + inputs.
|
|
1309
|
+
* Sorts object entries so { b: 2, a: 1 } and { a: 1, b: 2 } produce
|
|
1310
|
+
* the same key.
|
|
1311
|
+
*/
|
|
1312
|
+
function buildCacheKey(apiName, inputs) {
|
|
1313
|
+
return `${apiName}${KEY_SEPARATOR}${JSON.stringify(Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b)))}`;
|
|
1314
|
+
}
|
|
1315
|
+
var QueryClient = class {
|
|
1316
|
+
buildCacheKey = buildCacheKey;
|
|
1317
|
+
getQueryData(key) {
|
|
1318
|
+
return dataStore.get(key);
|
|
1319
|
+
}
|
|
1320
|
+
setQueryData(key, updater) {
|
|
1321
|
+
const current = this.getQueryData(key);
|
|
1322
|
+
const next = typeof updater === "function" ? updater(current) : updater;
|
|
1323
|
+
dataStore.set(key, next);
|
|
1324
|
+
dataUpdatedAtByKey.set(key, Date.now());
|
|
1325
|
+
mutate(key, next, { revalidate: false }).catch(() => {});
|
|
1326
|
+
}
|
|
1327
|
+
async invalidateQueries(keyPrefix) {
|
|
1328
|
+
const prefix = keyPrefix.includes(KEY_SEPARATOR) ? keyPrefix : keyPrefix + KEY_SEPARATOR;
|
|
1329
|
+
for (const key of dataStore.keys()) if (key.startsWith(prefix)) {
|
|
1330
|
+
dataStore.delete(key);
|
|
1331
|
+
dataUpdatedAtByKey.delete(key);
|
|
1332
|
+
}
|
|
1333
|
+
await mutate((key) => typeof key === "string" && key.startsWith(prefix));
|
|
1334
|
+
}
|
|
1335
|
+
cache = { clear: () => {
|
|
1336
|
+
dataStore.clear();
|
|
1337
|
+
dataUpdatedAtByKey.clear();
|
|
1338
|
+
mutate(() => true, void 0, { revalidate: false }).catch(() => {});
|
|
1339
|
+
} };
|
|
1340
|
+
};
|
|
1341
|
+
const queryClient = new QueryClient();
|
|
1342
|
+
|
|
1343
|
+
//#endregion
|
|
1344
|
+
//#region src/lib/internal-details/execute-api.ts
|
|
1345
|
+
/**
|
|
1346
|
+
* execute-api — framework-agnostic API execution function.
|
|
1347
|
+
*
|
|
1348
|
+
* Extracts the core SDK/legacy routing logic from useSdkApi so it can be:
|
|
1349
|
+
* 1. Called as a plain Promise outside any React component.
|
|
1350
|
+
* 2. Used as the `queryFn` inside useApiData's QueryEntry.
|
|
1351
|
+
* 3. Exported as a public primitive for utility functions and tests.
|
|
1352
|
+
*
|
|
1353
|
+
* Edit-mode tracking messages (execution-started / completed / failed) are
|
|
1354
|
+
* sent to the parent frame when isEditMode() is true, matching the behaviour
|
|
1355
|
+
* of the original useSdkApi implementation.
|
|
1356
|
+
*/
|
|
1357
|
+
/**
|
|
1358
|
+
* Returns true for every error except user-cancelled aborts.
|
|
1359
|
+
* Only `DOMException` with `name === "AbortError"` is treated as non-retryable.
|
|
1360
|
+
*/
|
|
1361
|
+
function isRetryableError(error) {
|
|
1362
|
+
if (error instanceof DOMException && error.name === "AbortError") return false;
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
/** Default exponential backoff: 1s, 2s, 4s, …, capped at 30s. */
|
|
1366
|
+
function defaultRetryDelay(attempt) {
|
|
1367
|
+
return Math.min(1e3 * Math.pow(2, attempt), 3e4);
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Execute a Superblocks API as a plain Promise, without any React lifecycle.
|
|
1371
|
+
*
|
|
1372
|
+
* Routes to the SDK path (`executeSdkApiV3`) when the API has an entry point
|
|
1373
|
+
* or when `sdkApiEnabled` is set on rootStore. Falls back to the legacy YAML
|
|
1374
|
+
* path otherwise.
|
|
1375
|
+
*
|
|
1376
|
+
* Sends edit-mode tracking messages to the parent frame when in edit mode,
|
|
1377
|
+
* keeping the Requests Panel in sync even for out-of-React calls.
|
|
1378
|
+
*
|
|
1379
|
+
* @throws {DOMException} with name "AbortError" if cancelled via signal.
|
|
1380
|
+
* @throws The orchestrator error object on API failure.
|
|
1381
|
+
*/
|
|
1382
|
+
async function executeApi(apiName, inputs, options) {
|
|
1383
|
+
const inputRecord = inputs ?? {};
|
|
1384
|
+
let sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1385
|
+
let hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1386
|
+
if (!sdkApiEnabled && !hasEntryPoint) {
|
|
1387
|
+
await root_store_default.awaitDiscovery();
|
|
1388
|
+
sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1389
|
+
hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1390
|
+
}
|
|
1391
|
+
if (sdkApiEnabled || hasEntryPoint) {
|
|
1392
|
+
const executionId = options?.executionId ?? generateId();
|
|
1393
|
+
const startTime = Date.now();
|
|
1394
|
+
const editMode = isEditMode();
|
|
1395
|
+
if (editMode) sendMessageImmediately({
|
|
1396
|
+
type: "sdk-api-execution-started",
|
|
1397
|
+
payload: {
|
|
1398
|
+
executionId,
|
|
1399
|
+
apiName,
|
|
1400
|
+
input: inputRecord
|
|
1401
|
+
}
|
|
1402
|
+
});
|
|
1403
|
+
try {
|
|
1404
|
+
const result$1 = await root_store_default.apis.executeSdkApiV3(apiName, inputRecord, { signal: options?.signal });
|
|
1405
|
+
const durationMs = Date.now() - startTime;
|
|
1406
|
+
if (result$1 == null) {
|
|
1407
|
+
const nullError = {
|
|
1408
|
+
code: "NO_RESPONSE",
|
|
1409
|
+
message: `API "${apiName}" returned no response`
|
|
1410
|
+
};
|
|
1411
|
+
if (editMode) sendMessageImmediately({
|
|
1412
|
+
type: "sdk-api-execution-failed",
|
|
1413
|
+
payload: {
|
|
1414
|
+
executionId,
|
|
1415
|
+
apiName,
|
|
1416
|
+
error: nullError,
|
|
1417
|
+
durationMs
|
|
1418
|
+
}
|
|
1419
|
+
});
|
|
1420
|
+
throw new Error(nullError.message);
|
|
1421
|
+
}
|
|
1422
|
+
if (result$1.error?.code === "ABORTED") {
|
|
1423
|
+
if (editMode) sendMessageImmediately({
|
|
1424
|
+
type: "sdk-api-execution-failed",
|
|
1425
|
+
payload: {
|
|
1426
|
+
executionId,
|
|
1427
|
+
apiName,
|
|
1428
|
+
error: result$1.error,
|
|
1429
|
+
durationMs
|
|
1430
|
+
}
|
|
1431
|
+
});
|
|
1432
|
+
throw new DOMException(`API "${apiName}" execution was aborted`, "AbortError");
|
|
1433
|
+
}
|
|
1434
|
+
if (result$1.success) {
|
|
1435
|
+
if (editMode) sendMessageImmediately({
|
|
1436
|
+
type: "sdk-api-execution-completed",
|
|
1437
|
+
payload: {
|
|
1438
|
+
executionId,
|
|
1439
|
+
apiName,
|
|
1440
|
+
output: result$1.output,
|
|
1441
|
+
durationMs,
|
|
1442
|
+
diagnostics: result$1.diagnostics,
|
|
1443
|
+
orchestratorStartMs: result$1.executionStartMs,
|
|
1444
|
+
orchestratorDurationMs: result$1.executionDurationMs,
|
|
1445
|
+
fetchStartMs: result$1.fetchStartMs
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
return result$1.output;
|
|
1449
|
+
}
|
|
1450
|
+
const error = result$1.error ?? {
|
|
1451
|
+
code: "UNKNOWN",
|
|
1452
|
+
message: "API execution failed"
|
|
1453
|
+
};
|
|
1454
|
+
if (editMode) sendMessageImmediately({
|
|
1455
|
+
type: "sdk-api-execution-failed",
|
|
1456
|
+
payload: {
|
|
1457
|
+
executionId,
|
|
1458
|
+
apiName,
|
|
1459
|
+
error,
|
|
1460
|
+
durationMs,
|
|
1461
|
+
diagnostics: result$1.diagnostics,
|
|
1462
|
+
orchestratorStartMs: result$1.executionStartMs,
|
|
1463
|
+
orchestratorDurationMs: result$1.executionDurationMs,
|
|
1464
|
+
fetchStartMs: result$1.fetchStartMs
|
|
1465
|
+
}
|
|
1466
|
+
});
|
|
1467
|
+
throw error;
|
|
1468
|
+
} catch (err) {
|
|
1469
|
+
if (editMode && !(err instanceof DOMException && err.name === "AbortError") && !(err instanceof Error && err.message === `API "${apiName}" returned no response`) && !(typeof err === "object" && err !== null && "code" in err)) {
|
|
1470
|
+
const durationMs = Date.now() - startTime;
|
|
1471
|
+
sendMessageImmediately({
|
|
1472
|
+
type: "sdk-api-execution-failed",
|
|
1473
|
+
payload: {
|
|
1474
|
+
executionId,
|
|
1475
|
+
apiName,
|
|
1476
|
+
error: {
|
|
1477
|
+
code: "UNKNOWN",
|
|
1478
|
+
message: err instanceof Error ? err.message : "API execution failed"
|
|
1479
|
+
},
|
|
1480
|
+
durationMs
|
|
1481
|
+
}
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
throw err;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
const apiPath = getApiPath(apiName);
|
|
1488
|
+
const result = await root_store_default.apis.runApiByPath({
|
|
1489
|
+
path: apiPath,
|
|
1490
|
+
inputs: inputRecord
|
|
1491
|
+
});
|
|
1492
|
+
if (result == null) throw new Error(`API "${apiName}" returned no response`);
|
|
1493
|
+
if (result.error != null) throw result.error;
|
|
1494
|
+
return result.data;
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Creates a typed version of executeApi bound to a specific API registry.
|
|
1498
|
+
*
|
|
1499
|
+
* @example
|
|
1500
|
+
* ```typescript
|
|
1501
|
+
* import type { ApiRegistry } from "../../server/apis/index.js";
|
|
1502
|
+
* import { createTypedExecuteApi } from "@superblocksteam/library";
|
|
1503
|
+
* export const executeApi = createTypedExecuteApi<ApiRegistry>();
|
|
1504
|
+
* ```
|
|
1505
|
+
*/
|
|
1506
|
+
function createTypedExecuteApi() {
|
|
1507
|
+
return executeApi;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
//#endregion
|
|
1511
|
+
//#region src/lib/internal-details/use-api-data.ts
|
|
1512
|
+
/**
|
|
1513
|
+
* useApiData — declarative data-fetching hook backed by SWR.
|
|
1514
|
+
*
|
|
1515
|
+
* Designed for GET-style reads that auto-fetch on mount and when inputs change.
|
|
1516
|
+
* Uses SWR for caching, deduplication, revalidation, and shared state.
|
|
1517
|
+
*
|
|
1518
|
+
* Use this hook for data loading. For mutations and event-driven calls use
|
|
1519
|
+
* `useApi`. For utility functions outside React use `executeApi`.
|
|
1520
|
+
*
|
|
1521
|
+
* @example
|
|
1522
|
+
* ```tsx
|
|
1523
|
+
* const { data, loading, isError, error } = useApiData("GetUsers", { email });
|
|
1524
|
+
* if (loading) return <Skeleton />;
|
|
1525
|
+
* if (isError) return <ErrorBanner error={error} />;
|
|
1526
|
+
* return <UserList users={data.users} />;
|
|
1527
|
+
* ```
|
|
1528
|
+
*/
|
|
1529
|
+
const EXEC_ID_PREFIX = "sb-exec-id:";
|
|
1530
|
+
function getOrCreateExecId(cacheKey) {
|
|
1531
|
+
const key = EXEC_ID_PREFIX + cacheKey;
|
|
1532
|
+
try {
|
|
1533
|
+
const id$1 = sessionStorage.getItem(key);
|
|
1534
|
+
if (id$1) return id$1;
|
|
1535
|
+
} catch {}
|
|
1536
|
+
const id = generateId();
|
|
1537
|
+
try {
|
|
1538
|
+
sessionStorage.setItem(key, id);
|
|
1539
|
+
} catch {}
|
|
1540
|
+
return id;
|
|
1541
|
+
}
|
|
1542
|
+
function rotateExecId(cacheKey) {
|
|
1543
|
+
const key = EXEC_ID_PREFIX + cacheKey;
|
|
1544
|
+
const id = generateId();
|
|
1545
|
+
try {
|
|
1546
|
+
sessionStorage.setItem(key, id);
|
|
1547
|
+
} catch {}
|
|
1548
|
+
return id;
|
|
1549
|
+
}
|
|
1550
|
+
function useApiData(apiName, inputs, options = {}) {
|
|
1551
|
+
const { enabled = true, staleTime = 0, gcTime: _gcTime = 3e5, retry = 3, retryDelay = defaultRetryDelay, refetchOnWindowFocus = false, refetchOnReconnect = true, refetchInterval = false, structuralSharing = false } = options;
|
|
1552
|
+
const cacheKey = buildCacheKey(apiName, inputs);
|
|
1553
|
+
const controllerRef = useRef(null);
|
|
1554
|
+
const dataUpdatedAtRef = useRef(0);
|
|
1555
|
+
const fetcher = useCallback(async (_key) => {
|
|
1556
|
+
controllerRef.current?.abort();
|
|
1557
|
+
const controller = new AbortController();
|
|
1558
|
+
controllerRef.current = controller;
|
|
1559
|
+
const executionId = getOrCreateExecId(cacheKey);
|
|
1560
|
+
try {
|
|
1561
|
+
const result = await executeApi(apiName, inputs, {
|
|
1562
|
+
signal: controller.signal,
|
|
1563
|
+
executionId
|
|
1564
|
+
});
|
|
1565
|
+
const now = Date.now();
|
|
1566
|
+
dataUpdatedAtRef.current = now;
|
|
1567
|
+
dataUpdatedAtByKey.set(cacheKey, now);
|
|
1568
|
+
dataStore.set(cacheKey, result);
|
|
1569
|
+
return result;
|
|
1570
|
+
} finally {
|
|
1571
|
+
rotateExecId(cacheKey);
|
|
1572
|
+
}
|
|
1573
|
+
}, [cacheKey]);
|
|
1574
|
+
const swrConfig = {
|
|
1575
|
+
revalidateOnFocus: refetchOnWindowFocus,
|
|
1576
|
+
revalidateOnReconnect: refetchOnReconnect,
|
|
1577
|
+
refreshInterval: refetchInterval || 0,
|
|
1578
|
+
dedupingInterval: staleTime,
|
|
1579
|
+
compare: structuralSharing ? void 0 : (a, b) => a === b,
|
|
1580
|
+
onErrorRetry: (err, _key, _config, revalidate, { retryCount }) => {
|
|
1581
|
+
if (err instanceof DOMException && err.name === "AbortError") return;
|
|
1582
|
+
if (retry === false || retry === 0) return;
|
|
1583
|
+
if (!isRetryableError(err)) return;
|
|
1584
|
+
if (retryCount > retry) return;
|
|
1585
|
+
const delay = retryDelay(retryCount - 1);
|
|
1586
|
+
const timer = setTimeout(() => void revalidate({ retryCount }), delay);
|
|
1587
|
+
controllerRef.current?.signal.addEventListener("abort", () => clearTimeout(timer), { once: true });
|
|
1588
|
+
},
|
|
1589
|
+
shouldRetryOnError: true,
|
|
1590
|
+
revalidateOnMount: staleTime > 0 ? void 0 : true,
|
|
1591
|
+
keepPreviousData: true,
|
|
1592
|
+
fallbackData: options.placeholderData
|
|
1593
|
+
};
|
|
1594
|
+
const { data, error, isValidating, isLoading, mutate: mutate$1 } = useSWR(enabled ? cacheKey : null, fetcher, swrConfig);
|
|
1595
|
+
const effectiveError = error instanceof DOMException && error.name === "AbortError" ? void 0 : error;
|
|
1596
|
+
const hasData = data !== void 0;
|
|
1597
|
+
const hasError = effectiveError !== void 0;
|
|
1598
|
+
const isFetching = isValidating;
|
|
1599
|
+
const status = hasData ? "success" : hasError ? "error" : "pending";
|
|
1600
|
+
const lastUpdatedAt = dataUpdatedAtByKey.get(cacheKey) ?? dataUpdatedAtRef.current;
|
|
1601
|
+
const isStaleNow = hasData && staleTime > 0 && lastUpdatedAt > 0 && Date.now() - lastUpdatedAt >= staleTime;
|
|
1602
|
+
const refetch = useCallback(async () => {
|
|
1603
|
+
controllerRef.current?.abort();
|
|
1604
|
+
controllerRef.current = null;
|
|
1605
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1606
|
+
return await mutate$1();
|
|
1607
|
+
}, [mutate$1]);
|
|
1608
|
+
const cancel = useCallback(() => {
|
|
1609
|
+
controllerRef.current?.abort();
|
|
1610
|
+
controllerRef.current = null;
|
|
1611
|
+
}, []);
|
|
1612
|
+
return {
|
|
1613
|
+
data: data ?? options.placeholderData,
|
|
1614
|
+
error: effectiveError ?? void 0,
|
|
1615
|
+
status,
|
|
1616
|
+
fetchStatus: isFetching ? "fetching" : "idle",
|
|
1617
|
+
loading: isLoading && !hasData,
|
|
1618
|
+
fetching: isFetching,
|
|
1619
|
+
isError: status === "error",
|
|
1620
|
+
isSuccess: status === "success",
|
|
1621
|
+
isStale: isStaleNow,
|
|
1622
|
+
refetch,
|
|
1623
|
+
cancel
|
|
1624
|
+
};
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* Creates a typed version of useApiData bound to a specific API registry.
|
|
1628
|
+
*
|
|
1629
|
+
* @example
|
|
1630
|
+
* ```typescript
|
|
1631
|
+
* import type { ApiRegistry } from "../../server/apis/index.js";
|
|
1632
|
+
* import { useTypedApiData } from "@superblocksteam/library";
|
|
1633
|
+
* export const useApiData = useTypedApiData<ApiRegistry>();
|
|
1634
|
+
* ```
|
|
1635
|
+
*/
|
|
1636
|
+
function useTypedApiData() {
|
|
1637
|
+
return useApiData;
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1207
1640
|
//#endregion
|
|
1208
1641
|
//#region src/lib/internal-details/use-api.ts
|
|
1209
1642
|
/**
|
|
@@ -1216,6 +1649,11 @@ if (import.meta.hot) import.meta.hot.accept("/server/apis/index.ts", () => {
|
|
|
1216
1649
|
* Delegation happens at RUN TIME (when run() is invoked), not render time,
|
|
1217
1650
|
* so components that mount before bootstrap completes still use the SDK path
|
|
1218
1651
|
* once the user triggers execution.
|
|
1652
|
+
*
|
|
1653
|
+
* Three primitives are now available:
|
|
1654
|
+
* - `useApi` — imperative mutations (this file)
|
|
1655
|
+
* - `useApiData` — declarative reads with cache (use-api-data.ts)
|
|
1656
|
+
* - `executeApi` — plain Promise outside React (execute-api.ts)
|
|
1219
1657
|
*/
|
|
1220
1658
|
/**
|
|
1221
1659
|
* Get the API path for an API by name.
|
|
@@ -1314,7 +1752,10 @@ function useSdkApi(apiName) {
|
|
|
1314
1752
|
apiName,
|
|
1315
1753
|
output: result.output,
|
|
1316
1754
|
durationMs,
|
|
1317
|
-
diagnostics: result.diagnostics
|
|
1755
|
+
diagnostics: result.diagnostics,
|
|
1756
|
+
orchestratorStartMs: result.executionStartMs,
|
|
1757
|
+
orchestratorDurationMs: result.executionDurationMs,
|
|
1758
|
+
fetchStartMs: result.fetchStartMs
|
|
1318
1759
|
}
|
|
1319
1760
|
});
|
|
1320
1761
|
return result.output;
|
|
@@ -1330,7 +1771,10 @@ function useSdkApi(apiName) {
|
|
|
1330
1771
|
apiName,
|
|
1331
1772
|
error,
|
|
1332
1773
|
durationMs,
|
|
1333
|
-
diagnostics: result.diagnostics
|
|
1774
|
+
diagnostics: result.diagnostics,
|
|
1775
|
+
orchestratorStartMs: result.executionStartMs,
|
|
1776
|
+
orchestratorDurationMs: result.executionDurationMs,
|
|
1777
|
+
fetchStartMs: result.fetchStartMs
|
|
1334
1778
|
}
|
|
1335
1779
|
});
|
|
1336
1780
|
throw error;
|
|
@@ -1345,195 +1789,114 @@ function useSdkApi(apiName) {
|
|
|
1345
1789
|
};
|
|
1346
1790
|
}
|
|
1347
1791
|
/**
|
|
1348
|
-
*
|
|
1349
|
-
*
|
|
1350
|
-
*
|
|
1351
|
-
*
|
|
1352
|
-
* **Imperative** — call `run()` manually (e.g., on button click):
|
|
1353
|
-
* ```ts
|
|
1354
|
-
* const { run, loading, data } = useApi("CreateOrder");
|
|
1355
|
-
* await run({ item, qty });
|
|
1356
|
-
* ```
|
|
1357
|
-
*
|
|
1358
|
-
* **Declarative** — pass inputs to auto-fetch when they change:
|
|
1359
|
-
* ```ts
|
|
1360
|
-
* const { loading, data } = useApi("GetUsers", { email, name });
|
|
1361
|
-
* // re-fetches automatically when email or name changes
|
|
1362
|
-
* ```
|
|
1363
|
-
*
|
|
1364
|
-
* When the SDK API feature flag (`clark.sdk-api.enabled`) is on, this executes
|
|
1365
|
-
* via the orchestrator's v3/execute endpoint from within the library iframe.
|
|
1366
|
-
*
|
|
1367
|
-
* When the flag is off, this delegates to the legacy YAML-based API system
|
|
1368
|
-
* which uses `rootStore.apis.runApiByPath`.
|
|
1369
|
-
*
|
|
1370
|
-
* IMPORTANT: The path is chosen at RUN TIME (when run() is invoked), not at
|
|
1371
|
-
* render time. This ensures that if the component mounts before the bootstrap
|
|
1372
|
-
* response arrives (sdkApiEnabled still false), the API will still use the SDK
|
|
1373
|
-
* path once bootstrap completes.
|
|
1792
|
+
* Imperative state machine for useApi (no inputs / mutation mode).
|
|
1793
|
+
* Extracted so Rules of Hooks are satisfied when useApi conditionally routes
|
|
1794
|
+
* to the declarative path via useApiData.
|
|
1374
1795
|
*
|
|
1375
|
-
*
|
|
1376
|
-
*
|
|
1377
|
-
* automatically on mount and whenever the input values change (shallow compare).
|
|
1378
|
-
* @returns Object with `run`, `cancel`, `loading`, and `data`
|
|
1796
|
+
* Both useApiImperative and the useApiData call inside useApi are always
|
|
1797
|
+
* invoked on every render — React requires unconditional hook calls.
|
|
1379
1798
|
*/
|
|
1380
|
-
|
|
1381
|
-
const MOUNTS_KEY = "__sb_useApi_activeMounts";
|
|
1382
|
-
const EDIT_MODE_FETCH_DELAY_MS = 150;
|
|
1383
|
-
function getFetchDelayMs() {
|
|
1384
|
-
return isEditMode() ? EDIT_MODE_FETCH_DELAY_MS : 0;
|
|
1385
|
-
}
|
|
1386
|
-
function getInflightFetches() {
|
|
1387
|
-
const w = globalThis;
|
|
1388
|
-
if (!w[INFLIGHT_KEY]) w[INFLIGHT_KEY] = /* @__PURE__ */ new Map();
|
|
1389
|
-
return w[INFLIGHT_KEY];
|
|
1390
|
-
}
|
|
1391
|
-
function getActiveMounts() {
|
|
1392
|
-
const w = globalThis;
|
|
1393
|
-
if (!w[MOUNTS_KEY]) w[MOUNTS_KEY] = /* @__PURE__ */ new Map();
|
|
1394
|
-
return w[MOUNTS_KEY];
|
|
1395
|
-
}
|
|
1396
|
-
function incMounts(key) {
|
|
1397
|
-
const mounts = getActiveMounts();
|
|
1398
|
-
const prev = mounts.get(key) ?? 0;
|
|
1399
|
-
mounts.set(key, prev + 1);
|
|
1400
|
-
}
|
|
1401
|
-
function decMounts(key) {
|
|
1402
|
-
const mounts = getActiveMounts();
|
|
1403
|
-
const n = (mounts.get(key) ?? 1) - 1;
|
|
1404
|
-
if (n <= 0) mounts.delete(key);
|
|
1405
|
-
else mounts.set(key, n);
|
|
1406
|
-
}
|
|
1407
|
-
function scheduleInflightCleanup(cacheKey) {
|
|
1408
|
-
setTimeout(() => {
|
|
1409
|
-
if ((getActiveMounts().get(cacheKey) ?? 0) === 0) getInflightFetches().delete(cacheKey);
|
|
1410
|
-
}, Math.max(getFetchDelayMs() * 2, 1));
|
|
1411
|
-
}
|
|
1412
|
-
/** Build a cache key from API name and input fingerprint. */
|
|
1413
|
-
function inflightKey(apiName, fingerprint) {
|
|
1414
|
-
return `${apiName}::${fingerprint}`;
|
|
1415
|
-
}
|
|
1416
|
-
function useApi(apiName, inputs) {
|
|
1799
|
+
function useApiImperative(apiName) {
|
|
1417
1800
|
const { run: sdkRun, cancel: sdkCancel } = useSdkApi(apiName);
|
|
1418
1801
|
const { run: legacyRun, cancel: legacyCancel } = useApiStateful(apiName);
|
|
1419
1802
|
const [loading, setLoading] = useState(false);
|
|
1420
1803
|
const [data, setData] = useState(void 0);
|
|
1421
1804
|
const [error, setError] = useState(void 0);
|
|
1805
|
+
const [status, setStatus] = useState("idle");
|
|
1806
|
+
const [variables, setVariables] = useState(void 0);
|
|
1422
1807
|
const runIdRef = useRef(0);
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
getInflightFetches().delete(inflightKey(apiName, currentFingerprintRef.current ?? ""));
|
|
1426
|
-
const thisRun = ++runIdRef.current;
|
|
1427
|
-
setLoading(true);
|
|
1428
|
-
setError(void 0);
|
|
1429
|
-
try {
|
|
1430
|
-
let sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1431
|
-
let hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1432
|
-
if (!sdkApiEnabled && !hasEntryPoint) {
|
|
1433
|
-
await root_store_default.awaitDiscovery();
|
|
1434
|
-
sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1435
|
-
hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1436
|
-
}
|
|
1437
|
-
const result = sdkApiEnabled || hasEntryPoint ? await sdkRun(runInputs ?? {}) : await legacyRun(runInputs);
|
|
1438
|
-
if (thisRun === runIdRef.current) {
|
|
1439
|
-
setData(result);
|
|
1440
|
-
setError(void 0);
|
|
1441
|
-
}
|
|
1442
|
-
return result;
|
|
1443
|
-
} catch (err) {
|
|
1444
|
-
if (thisRun === runIdRef.current) setError(err);
|
|
1445
|
-
throw err;
|
|
1446
|
-
} finally {
|
|
1447
|
-
if (thisRun === runIdRef.current) setLoading(false);
|
|
1448
|
-
}
|
|
1449
|
-
}, [
|
|
1450
|
-
apiName,
|
|
1451
|
-
sdkRun,
|
|
1452
|
-
legacyRun
|
|
1453
|
-
]);
|
|
1454
|
-
runRef.current = run;
|
|
1455
|
-
const cancel = useCallback(async () => {
|
|
1456
|
-
++runIdRef.current;
|
|
1457
|
-
setLoading(false);
|
|
1458
|
-
setError(void 0);
|
|
1459
|
-
getInflightFetches().delete(inflightKey(apiName, currentFingerprintRef.current ?? ""));
|
|
1460
|
-
if (root_store_default.sdkApiEnabled || !!root_store_default.getApiEntryPoint(apiName)) return sdkCancel();
|
|
1461
|
-
return legacyCancel();
|
|
1462
|
-
}, [
|
|
1463
|
-
apiName,
|
|
1464
|
-
sdkCancel,
|
|
1465
|
-
legacyCancel
|
|
1466
|
-
]);
|
|
1467
|
-
const inputRecord = inputs;
|
|
1468
|
-
const inputFingerprint = inputRecord ? JSON.stringify(Object.entries(inputRecord).sort(([a], [b]) => a.localeCompare(b))) : null;
|
|
1469
|
-
const currentFingerprintRef = useRef(inputFingerprint);
|
|
1470
|
-
currentFingerprintRef.current = inputFingerprint;
|
|
1471
|
-
useEffect(() => {
|
|
1472
|
-
if (!inputRecord || inputFingerprint === null) return;
|
|
1473
|
-
const cacheKey = inflightKey(apiName, inputFingerprint);
|
|
1474
|
-
const inflightPromise = getInflightFetches().get(cacheKey);
|
|
1475
|
-
if (inflightPromise) {
|
|
1476
|
-
incMounts(cacheKey);
|
|
1477
|
-
setLoading(true);
|
|
1808
|
+
return {
|
|
1809
|
+
run: useCallback(async (runInputs) => {
|
|
1478
1810
|
const thisRun = ++runIdRef.current;
|
|
1479
|
-
|
|
1480
|
-
|
|
1811
|
+
setLoading(true);
|
|
1812
|
+
setError(void 0);
|
|
1813
|
+
setStatus("pending");
|
|
1814
|
+
setVariables(runInputs);
|
|
1815
|
+
try {
|
|
1816
|
+
let sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1817
|
+
let hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1818
|
+
if (!sdkApiEnabled && !hasEntryPoint) {
|
|
1819
|
+
await root_store_default.awaitDiscovery();
|
|
1820
|
+
sdkApiEnabled = root_store_default.sdkApiEnabled;
|
|
1821
|
+
hasEntryPoint = !!root_store_default.getApiEntryPoint(apiName);
|
|
1822
|
+
}
|
|
1823
|
+
const result = sdkApiEnabled || hasEntryPoint ? await sdkRun(runInputs ?? {}) : await legacyRun(runInputs);
|
|
1824
|
+
if (thisRun === runIdRef.current) {
|
|
1481
1825
|
setData(result);
|
|
1482
1826
|
setError(void 0);
|
|
1827
|
+
setStatus("success");
|
|
1828
|
+
}
|
|
1829
|
+
return result;
|
|
1830
|
+
} catch (thrown) {
|
|
1831
|
+
if (thisRun === runIdRef.current) {
|
|
1832
|
+
setError(thrown);
|
|
1833
|
+
setStatus("error");
|
|
1483
1834
|
}
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
}).finally(() => {
|
|
1835
|
+
throw thrown;
|
|
1836
|
+
} finally {
|
|
1487
1837
|
if (thisRun === runIdRef.current) setLoading(false);
|
|
1488
|
-
});
|
|
1489
|
-
return () => {
|
|
1490
|
-
++runIdRef.current;
|
|
1491
|
-
setLoading(false);
|
|
1492
|
-
decMounts(cacheKey);
|
|
1493
|
-
scheduleInflightCleanup(cacheKey);
|
|
1494
|
-
};
|
|
1495
|
-
}
|
|
1496
|
-
incMounts(cacheKey);
|
|
1497
|
-
let resolveFetch;
|
|
1498
|
-
let rejectFetch;
|
|
1499
|
-
const placeholder = new Promise((resolve, reject) => {
|
|
1500
|
-
resolveFetch = resolve;
|
|
1501
|
-
rejectFetch = reject;
|
|
1502
|
-
});
|
|
1503
|
-
placeholder.catch(() => {});
|
|
1504
|
-
getInflightFetches().set(cacheKey, placeholder);
|
|
1505
|
-
let timerFired = false;
|
|
1506
|
-
const timer = setTimeout(() => {
|
|
1507
|
-
timerFired = true;
|
|
1508
|
-
const fetchResult = runRef.current(inputRecord).catch((err) => {
|
|
1509
|
-
rejectFetch(err);
|
|
1510
|
-
});
|
|
1511
|
-
getInflightFetches().set(cacheKey, placeholder);
|
|
1512
|
-
fetchResult.then((result) => {
|
|
1513
|
-
resolveFetch(result);
|
|
1514
|
-
if (result !== void 0) scheduleInflightCleanup(cacheKey);
|
|
1515
|
-
else if (getInflightFetches().get(cacheKey) === placeholder) getInflightFetches().delete(cacheKey);
|
|
1516
|
-
});
|
|
1517
|
-
}, getFetchDelayMs());
|
|
1518
|
-
return () => {
|
|
1519
|
-
clearTimeout(timer);
|
|
1520
|
-
if (!timerFired) {
|
|
1521
|
-
if (getInflightFetches().get(cacheKey) === placeholder) getInflightFetches().delete(cacheKey);
|
|
1522
|
-
resolveFetch(void 0);
|
|
1523
1838
|
}
|
|
1839
|
+
}, [
|
|
1840
|
+
apiName,
|
|
1841
|
+
sdkRun,
|
|
1842
|
+
legacyRun
|
|
1843
|
+
]),
|
|
1844
|
+
cancel: useCallback(async () => {
|
|
1524
1845
|
++runIdRef.current;
|
|
1525
1846
|
setLoading(false);
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1847
|
+
setError(void 0);
|
|
1848
|
+
setStatus("idle");
|
|
1849
|
+
if (root_store_default.sdkApiEnabled || !!root_store_default.getApiEntryPoint(apiName)) return sdkCancel();
|
|
1850
|
+
return legacyCancel();
|
|
1851
|
+
}, [
|
|
1852
|
+
apiName,
|
|
1853
|
+
sdkCancel,
|
|
1854
|
+
legacyCancel
|
|
1855
|
+
]),
|
|
1856
|
+
reset: useCallback(() => {
|
|
1857
|
+
++runIdRef.current;
|
|
1858
|
+
setLoading(false);
|
|
1859
|
+
setData(void 0);
|
|
1860
|
+
setError(void 0);
|
|
1861
|
+
setStatus("idle");
|
|
1862
|
+
setVariables(void 0);
|
|
1863
|
+
}, []),
|
|
1532
1864
|
loading,
|
|
1533
1865
|
data,
|
|
1534
|
-
error
|
|
1866
|
+
error,
|
|
1867
|
+
status,
|
|
1868
|
+
variables
|
|
1535
1869
|
};
|
|
1536
1870
|
}
|
|
1871
|
+
function useApi(apiName, inputs) {
|
|
1872
|
+
const isDeclarative = inputs !== void 0;
|
|
1873
|
+
const imperativeResult = useApiImperative(apiName);
|
|
1874
|
+
const declarativeResult = useApiData(apiName, inputs ?? {}, {
|
|
1875
|
+
enabled: isDeclarative,
|
|
1876
|
+
refetchOnWindowFocus: false,
|
|
1877
|
+
refetchOnReconnect: false,
|
|
1878
|
+
retry: false
|
|
1879
|
+
});
|
|
1880
|
+
if (isDeclarative) {
|
|
1881
|
+
const imperativeUsed = imperativeResult.status !== "idle";
|
|
1882
|
+
return {
|
|
1883
|
+
run: imperativeResult.run,
|
|
1884
|
+
cancel: async () => {
|
|
1885
|
+
await imperativeResult.cancel();
|
|
1886
|
+
declarativeResult.cancel();
|
|
1887
|
+
},
|
|
1888
|
+
reset: () => {
|
|
1889
|
+
imperativeResult.reset();
|
|
1890
|
+
},
|
|
1891
|
+
loading: imperativeUsed ? imperativeResult.loading : declarativeResult.fetching || declarativeResult.loading,
|
|
1892
|
+
data: imperativeUsed ? imperativeResult.data : declarativeResult.data,
|
|
1893
|
+
error: imperativeUsed ? imperativeResult.error : declarativeResult.error,
|
|
1894
|
+
status: imperativeUsed ? imperativeResult.status : declarativeResult.status,
|
|
1895
|
+
variables: imperativeUsed ? imperativeResult.variables : inputs
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1898
|
+
return imperativeResult;
|
|
1899
|
+
}
|
|
1537
1900
|
/**
|
|
1538
1901
|
* Creates a typed version of useApi bound to a specific API registry type.
|
|
1539
1902
|
*
|
|
@@ -4861,7 +5224,10 @@ const EmbedWrapper$2 = (props) => {
|
|
|
4861
5224
|
executionId,
|
|
4862
5225
|
apiName,
|
|
4863
5226
|
output: result.output,
|
|
4864
|
-
durationMs
|
|
5227
|
+
durationMs,
|
|
5228
|
+
orchestratorStartMs: result.executionStartMs,
|
|
5229
|
+
orchestratorDurationMs: result.executionDurationMs,
|
|
5230
|
+
fetchStartMs: result.fetchStartMs
|
|
4865
5231
|
}
|
|
4866
5232
|
});
|
|
4867
5233
|
else sendMessageImmediately({
|
|
@@ -4873,7 +5239,10 @@ const EmbedWrapper$2 = (props) => {
|
|
|
4873
5239
|
code: "UNKNOWN",
|
|
4874
5240
|
message: "API execution failed"
|
|
4875
5241
|
},
|
|
4876
|
-
durationMs
|
|
5242
|
+
durationMs,
|
|
5243
|
+
orchestratorStartMs: result.executionStartMs,
|
|
5244
|
+
orchestratorDurationMs: result.executionDurationMs,
|
|
5245
|
+
fetchStartMs: result.fetchStartMs
|
|
4877
5246
|
}
|
|
4878
5247
|
});
|
|
4879
5248
|
}).catch((error$1) => {
|
|
@@ -5608,6 +5977,7 @@ async function loadBuildManifest() {
|
|
|
5608
5977
|
root_store_default.clearApiIntegrations();
|
|
5609
5978
|
for (const [name, meta] of Object.entries(sdkApis)) {
|
|
5610
5979
|
root_store_default.setApiEntryPoint(name, meta.entryPoint);
|
|
5980
|
+
if (meta.exportName) root_store_default.setApiExportName(name, meta.exportName);
|
|
5611
5981
|
if (meta.integrations) root_store_default.setApiIntegrations(name, meta.integrations);
|
|
5612
5982
|
}
|
|
5613
5983
|
} else root_store_default.apis.loadApiManifest(mod.default);
|
|
@@ -5768,7 +6138,7 @@ const SbProvider = function SbProvider$1({ name = "codemode", children, classNam
|
|
|
5768
6138
|
value: context$1 ?? void 0,
|
|
5769
6139
|
children: isEmbedded ? /* @__PURE__ */ jsx(EmbedWrapper, { children }) : /* @__PURE__ */ jsx(Auth0Wrapper, { children })
|
|
5770
6140
|
}), /* @__PURE__ */ jsx(DevTools, {})]
|
|
5771
|
-
}) }), /* @__PURE__ */ jsx(interaction_layer_default, {})]
|
|
6141
|
+
}) }), isEditMode() && /* @__PURE__ */ jsx(interaction_layer_default, {})]
|
|
5772
6142
|
});
|
|
5773
6143
|
};
|
|
5774
6144
|
var sb_provider_default = SbProvider;
|
|
@@ -6997,5 +7367,5 @@ early_console_buffer_default.getInstance().patchEarly();
|
|
|
6997
7367
|
registerHtmlElements();
|
|
6998
7368
|
|
|
6999
7369
|
//#endregion
|
|
7000
|
-
export { App, PageNotFound, Prop, Property, PropsCategory, RouteLoadError, Section, Superblocks, sb_provider_default as SuperblocksProvider, createElement, embedStore, getAppMode, logoutIntegrations, registerComponent, tailwindStylesCategory, useApi, useApiStateful, useEmbedEvent, useEmbedProperties, useEmitEmbedEvent, useSuperblocksDataTags, useSuperblocksGroups, useSuperblocksProfiles, useSuperblocksUser, useTypedApi };
|
|
7370
|
+
export { App, PageNotFound, Prop, Property, PropsCategory, RouteLoadError, Section, Superblocks, sb_provider_default as SuperblocksProvider, createElement, createTypedExecuteApi, embedStore, executeApi, getAppMode, logoutIntegrations, queryClient, registerComponent, tailwindStylesCategory, useApi, useApiData, useApiStateful, useEmbedEvent, useEmbedProperties, useEmitEmbedEvent, useSuperblocksDataTags, useSuperblocksGroups, useSuperblocksProfiles, useSuperblocksUser, useTypedApi, useTypedApiData };
|
|
7001
7371
|
//# sourceMappingURL=index.js.map
|