@workflow/web 5.0.0-beta.27 → 5.0.0-beta.28
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/build/client/assets/{entry.client-DOJDY_4b.js → entry.client-DQZ2hM2V.js} +24 -24
- package/build/client/assets/{highlighted-body-B3W2YXNL-B-EF8R0t.js → highlighted-body-B3W2YXNL-CQ-a-eYE.js} +1 -1
- package/build/client/assets/{home-DQkixJk4.js → home-DuZRFOMe.js} +1697 -233
- package/build/client/assets/{index-C7C6cDW5.js → index-HqNj_XIX.js} +10 -10
- package/build/client/assets/{manifest-ce6dd06d.js → manifest-bb838d97.js} +1 -1
- package/build/client/assets/{mermaid-3ZIDBTTL-aixonSAh.js → mermaid-3ZIDBTTL-QcES6x1o.js} +374 -71
- package/build/client/assets/root-BT69a3LD.css +1 -0
- package/build/client/assets/{root-CsCdj08f.js → root-BiHTsCtP.js} +1 -1
- package/build/client/assets/{run-detail-CCsVqid_.js → run-detail-DSpZ5dnN.js} +50 -99
- package/build/client/assets/server-build-BkKXPNcO.css +1 -0
- package/build/client/assets/{workflow-graph-viewer-BlPvo_5I.js → workflow-graph-viewer-CyKfZJOQ.js} +222 -197
- package/build/client/assets/{zstd-browser-decoder-RyHgsNO3.js → zstd-browser-decoder-BigjGoI1.js} +2 -2
- package/build/server/assets/{app-kYNGZFkW.js → app-Cl6-bhGd.js} +43 -43
- package/build/server/assets/{highlighted-body-B3W2YXNL-D1QWoqJB.js → highlighted-body-B3W2YXNL-Daljn6fi.js} +4 -4
- package/build/server/assets/{index-fWQcXKhC.js → index-B_N7SdQh.js} +5 -5
- package/build/server/assets/{index-BafExO0s.js → index-BfLBLRRi.js} +10 -10
- package/build/server/assets/{mermaid-3ZIDBTTL-BOh-zwwU.js → mermaid-3ZIDBTTL-xnUhfFrD.js} +4 -4
- package/build/server/assets/{server-build-B21fZEey.js → server-build-D5Nuwxaw.js} +39144 -37202
- package/build/server/assets/{token-DmIqmbeU.js → token-DDgfwjzz.js} +2 -2
- package/build/server/assets/{token-util-D4JYdrFc.js → token-util-CthtfGuG.js} +2 -2
- package/build/server/assets/{zstd-browser-decoder-DgO7NCG6.js → zstd-browser-decoder-zp5ZpR7T.js} +5 -5
- package/build/server/index.js +1 -1
- package/package.json +10 -8
- package/build/client/assets/root-BlaSucTH.css +0 -1
- package/build/client/assets/server-build-DPrKlhgf.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as reactExports, j as jsxRuntimeExports, A as Link, f as reactDomExports, C as useSearchParams, B as useNavigate, D as useLocation, w as withComponentProps } from "./index-BXZSIDEp.js";
|
|
2
|
-
import { R as ResolveHookModal, S as Send,
|
|
3
|
-
import { c as createLucideIcon, h as useToast, e as cn,
|
|
1
|
+
import { r as reactExports, j as jsxRuntimeExports, A as Link, R as ReactExports, f as reactDomExports, C as useSearchParams, B as useNavigate, D as useLocation, w as withComponentProps } from "./index-BXZSIDEp.js";
|
|
2
|
+
import { R as ResolveHookModal, S as Send, r as requireShim, u as unwrapOrThrow, W as WorkflowWebAPIError, C as Check, a as Copy, f as fetchHookToken, b as Skeleton, c as RelativeTime, A as Alert, d as CircleAlert, e as AlertTitle, g as getErrorTitle, h as AlertDescription, i as getErrorMessage, j as CopyableText, D as DropdownMenu, k as DropdownMenuTrigger, E as Ellipsis, l as DropdownMenuContent, m as DropdownMenuItem, n as resumeHook, o as createCollection, p as hideOthers, q as ReactRemoveScroll, s as useDirection, t as ChevronUp, X, v as useControllableState$1, P as Primitive$1, w as composeEventHandlers$1, x as Presence, y as useSize, z as createContextScope$1, B as cancelRun, F as reenqueueRun, G as parseWorkflowName, H as StatusBadge, Z as Zap, I as CircleX, J as RunActionsDropdownItems, K as unwrapServerActionResult, L as WorkflowGraphViewer, T as Tabs, M as TabsList, N as TabsTrigger, O as TabsContent, Q as ErrorBoundary } from "./workflow-graph-viewer-CyKfZJOQ.js";
|
|
3
|
+
import { c as createLucideIcon, h as useToast, e as cn, i as fetchRuns, j as fetchHooks, k as getPaginationDisplay, T as Tooltip, a as TooltipTrigger, L as LoaderCircle, b as TooltipContent, D as DEFAULT_PAGE_SIZE, B as Button, C as ChevronRight, l as fetchEvents, m as useCallbackRef, n as useComposedRefs, P as Primitive, A as Anchor, o as composeEventHandlers, p as useLayoutEffect2, q as Portal$2, s as useId, v as createPopperScope, w as DismissableLayer, x as createContextScope, y as createSlot, z as Content$1, E as useControllableState, F as Root2$1, V as VISUALLY_HIDDEN_STYLES, G as Arrow, H as ChevronDown, I as useComposedRefs$1, u as useServerConfig, t as toast, J as fetchRun, M as cva, N as Presence$1, O as createContext2, U as fetchWorkflowsManifest } from "./mermaid-3ZIDBTTL-QcES6x1o.js";
|
|
4
4
|
import "./index-ConSkUmc.js";
|
|
5
5
|
/**
|
|
6
6
|
* @license lucide-react v0.575.0 - ISC
|
|
@@ -285,102 +285,1313 @@ const TableCaption = reactExports.forwardRef(({ className, ...props }, ref) => /
|
|
|
285
285
|
}
|
|
286
286
|
));
|
|
287
287
|
TableCaption.displayName = "TableCaption";
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
288
|
+
var shimExports = requireShim();
|
|
289
|
+
const FOCUS_EVENT = 0;
|
|
290
|
+
const RECONNECT_EVENT = 1;
|
|
291
|
+
const MUTATE_EVENT = 2;
|
|
292
|
+
const ERROR_REVALIDATE_EVENT = 3;
|
|
293
|
+
var has = Object.prototype.hasOwnProperty;
|
|
294
|
+
function dequal(foo, bar) {
|
|
295
|
+
var ctor, len;
|
|
296
|
+
if (foo === bar) return true;
|
|
297
|
+
if (foo && bar && (ctor = foo.constructor) === bar.constructor) {
|
|
298
|
+
if (ctor === Date) return foo.getTime() === bar.getTime();
|
|
299
|
+
if (ctor === RegExp) return foo.toString() === bar.toString();
|
|
300
|
+
if (ctor === Array) {
|
|
301
|
+
if ((len = foo.length) === bar.length) {
|
|
302
|
+
while (len-- && dequal(foo[len], bar[len])) ;
|
|
303
|
+
}
|
|
304
|
+
return len === -1;
|
|
305
|
+
}
|
|
306
|
+
if (!ctor || typeof foo === "object") {
|
|
307
|
+
len = 0;
|
|
308
|
+
for (ctor in foo) {
|
|
309
|
+
if (has.call(foo, ctor) && ++len && !has.call(bar, ctor)) return false;
|
|
310
|
+
if (!(ctor in bar) || !dequal(foo[ctor], bar[ctor])) return false;
|
|
311
|
+
}
|
|
312
|
+
return Object.keys(bar).length === len;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return foo !== foo && bar !== bar;
|
|
316
|
+
}
|
|
317
|
+
const SWRGlobalState = /* @__PURE__ */ new WeakMap();
|
|
318
|
+
const noop$1 = () => {
|
|
319
|
+
};
|
|
320
|
+
const UNDEFINED$1 = (
|
|
321
|
+
/*#__NOINLINE__*/
|
|
322
|
+
noop$1()
|
|
323
|
+
);
|
|
324
|
+
const OBJECT$1 = Object;
|
|
325
|
+
const isUndefined$1 = (v) => v === UNDEFINED$1;
|
|
326
|
+
const isFunction$1 = (v) => typeof v == "function";
|
|
327
|
+
const mergeObjects = (a, b) => ({
|
|
328
|
+
...a,
|
|
329
|
+
...b
|
|
330
|
+
});
|
|
331
|
+
const isPromiseLike = (x) => isFunction$1(x.then);
|
|
332
|
+
const EMPTY_CACHE = {};
|
|
333
|
+
const INITIAL_CACHE = {};
|
|
334
|
+
const STR_UNDEFINED = "undefined";
|
|
335
|
+
const isWindowDefined = typeof window != STR_UNDEFINED;
|
|
336
|
+
const isDocumentDefined = typeof document != STR_UNDEFINED;
|
|
337
|
+
const isLegacyDeno = isWindowDefined && "Deno" in window;
|
|
338
|
+
const hasRequestAnimationFrame = () => isWindowDefined && typeof window["requestAnimationFrame"] != STR_UNDEFINED;
|
|
339
|
+
const createCacheHelper = (cache2, key) => {
|
|
340
|
+
const state = SWRGlobalState.get(cache2);
|
|
341
|
+
return [
|
|
342
|
+
// Getter
|
|
343
|
+
() => !isUndefined$1(key) && cache2.get(key) || EMPTY_CACHE,
|
|
344
|
+
// Setter
|
|
345
|
+
(info) => {
|
|
346
|
+
if (!isUndefined$1(key)) {
|
|
347
|
+
const prev = cache2.get(key);
|
|
348
|
+
if (!(key in INITIAL_CACHE)) {
|
|
349
|
+
INITIAL_CACHE[key] = prev;
|
|
350
|
+
}
|
|
351
|
+
state[5](key, mergeObjects(prev, info), prev || EMPTY_CACHE);
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
// Subscriber
|
|
355
|
+
state[6],
|
|
356
|
+
// Get server cache snapshot
|
|
357
|
+
() => {
|
|
358
|
+
if (!isUndefined$1(key)) {
|
|
359
|
+
if (key in INITIAL_CACHE) return INITIAL_CACHE[key];
|
|
360
|
+
}
|
|
361
|
+
return !isUndefined$1(key) && cache2.get(key) || EMPTY_CACHE;
|
|
344
362
|
}
|
|
363
|
+
];
|
|
364
|
+
};
|
|
365
|
+
let online = true;
|
|
366
|
+
const isOnline = () => online;
|
|
367
|
+
const [onWindowEvent, offWindowEvent] = isWindowDefined && window.addEventListener ? [
|
|
368
|
+
window.addEventListener.bind(window),
|
|
369
|
+
window.removeEventListener.bind(window)
|
|
370
|
+
] : [
|
|
371
|
+
noop$1,
|
|
372
|
+
noop$1
|
|
373
|
+
];
|
|
374
|
+
const isVisible = () => {
|
|
375
|
+
const visibilityState = isDocumentDefined && document.visibilityState;
|
|
376
|
+
return isUndefined$1(visibilityState) || visibilityState !== "hidden";
|
|
377
|
+
};
|
|
378
|
+
const initFocus = (callback) => {
|
|
379
|
+
if (isDocumentDefined) {
|
|
380
|
+
document.addEventListener("visibilitychange", callback);
|
|
381
|
+
}
|
|
382
|
+
onWindowEvent("focus", callback);
|
|
383
|
+
return () => {
|
|
384
|
+
if (isDocumentDefined) {
|
|
385
|
+
document.removeEventListener("visibilitychange", callback);
|
|
386
|
+
}
|
|
387
|
+
offWindowEvent("focus", callback);
|
|
345
388
|
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
389
|
+
};
|
|
390
|
+
const initReconnect = (callback) => {
|
|
391
|
+
const onOnline = () => {
|
|
392
|
+
online = true;
|
|
393
|
+
callback();
|
|
394
|
+
};
|
|
395
|
+
const onOffline = () => {
|
|
396
|
+
online = false;
|
|
397
|
+
};
|
|
398
|
+
onWindowEvent("online", onOnline);
|
|
399
|
+
onWindowEvent("offline", onOffline);
|
|
400
|
+
return () => {
|
|
401
|
+
offWindowEvent("online", onOnline);
|
|
402
|
+
offWindowEvent("offline", onOffline);
|
|
403
|
+
};
|
|
404
|
+
};
|
|
405
|
+
const preset = {
|
|
406
|
+
isOnline,
|
|
407
|
+
isVisible
|
|
408
|
+
};
|
|
409
|
+
const defaultConfigOptions = {
|
|
410
|
+
initFocus,
|
|
411
|
+
initReconnect
|
|
412
|
+
};
|
|
413
|
+
const IS_REACT_LEGACY = !ReactExports.useId;
|
|
414
|
+
const IS_SERVER = !isWindowDefined || isLegacyDeno;
|
|
415
|
+
const rAF = (f) => hasRequestAnimationFrame() ? window["requestAnimationFrame"](f) : setTimeout(f, 1);
|
|
416
|
+
const useIsomorphicLayoutEffect = IS_SERVER ? reactExports.useEffect : reactExports.useLayoutEffect;
|
|
417
|
+
const navigatorConnection = typeof navigator !== "undefined" && navigator.connection;
|
|
418
|
+
const slowConnection = !IS_SERVER && navigatorConnection && ([
|
|
419
|
+
"slow-2g",
|
|
420
|
+
"2g"
|
|
421
|
+
].includes(navigatorConnection.effectiveType) || navigatorConnection.saveData);
|
|
422
|
+
const table$1 = /* @__PURE__ */ new WeakMap();
|
|
423
|
+
const getTypeName$1 = (value) => OBJECT$1.prototype.toString.call(value);
|
|
424
|
+
const isObjectTypeName$1 = (typeName, type) => typeName === `[object ${type}]`;
|
|
425
|
+
let counter$1 = 0;
|
|
426
|
+
const stableHash$1 = (arg) => {
|
|
427
|
+
const type = typeof arg;
|
|
428
|
+
const typeName = getTypeName$1(arg);
|
|
429
|
+
const isDate = isObjectTypeName$1(typeName, "Date");
|
|
430
|
+
const isRegex = isObjectTypeName$1(typeName, "RegExp");
|
|
431
|
+
const isPlainObject = isObjectTypeName$1(typeName, "Object");
|
|
432
|
+
let result;
|
|
433
|
+
let index;
|
|
434
|
+
if (OBJECT$1(arg) === arg && !isDate && !isRegex) {
|
|
435
|
+
result = table$1.get(arg);
|
|
436
|
+
if (result) return result;
|
|
437
|
+
result = ++counter$1 + "~";
|
|
438
|
+
table$1.set(arg, result);
|
|
439
|
+
if (Array.isArray(arg)) {
|
|
440
|
+
result = "@";
|
|
441
|
+
for (index = 0; index < arg.length; index++) {
|
|
442
|
+
result += stableHash$1(arg[index]) + ",";
|
|
443
|
+
}
|
|
444
|
+
table$1.set(arg, result);
|
|
445
|
+
}
|
|
446
|
+
if (isPlainObject) {
|
|
447
|
+
result = "#";
|
|
448
|
+
const keys = OBJECT$1.keys(arg).sort();
|
|
449
|
+
while (!isUndefined$1(index = keys.pop())) {
|
|
450
|
+
if (!isUndefined$1(arg[index])) {
|
|
451
|
+
result += index + ":" + stableHash$1(arg[index]) + ",";
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
table$1.set(arg, result);
|
|
455
|
+
}
|
|
456
|
+
} else {
|
|
457
|
+
result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
|
|
458
|
+
}
|
|
459
|
+
return result;
|
|
460
|
+
};
|
|
461
|
+
const serialize$1 = (key) => {
|
|
462
|
+
if (isFunction$1(key)) {
|
|
463
|
+
try {
|
|
464
|
+
key = key();
|
|
465
|
+
} catch (err) {
|
|
466
|
+
key = "";
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
const args = key;
|
|
470
|
+
key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash$1(key) : "";
|
|
471
|
+
return [
|
|
472
|
+
key,
|
|
473
|
+
args
|
|
474
|
+
];
|
|
475
|
+
};
|
|
476
|
+
let __timestamp = 0;
|
|
477
|
+
const getTimestamp = () => ++__timestamp;
|
|
478
|
+
async function internalMutate(...args) {
|
|
479
|
+
const [cache2, _key, _data, _opts] = args;
|
|
480
|
+
const options = mergeObjects({
|
|
481
|
+
populateCache: true,
|
|
482
|
+
throwOnError: true
|
|
483
|
+
}, typeof _opts === "boolean" ? {
|
|
484
|
+
revalidate: _opts
|
|
485
|
+
} : _opts || {});
|
|
486
|
+
let populateCache = options.populateCache;
|
|
487
|
+
const rollbackOnErrorOption = options.rollbackOnError;
|
|
488
|
+
let optimisticData = options.optimisticData;
|
|
489
|
+
const rollbackOnError = (error) => {
|
|
490
|
+
return typeof rollbackOnErrorOption === "function" ? rollbackOnErrorOption(error) : rollbackOnErrorOption !== false;
|
|
491
|
+
};
|
|
492
|
+
const throwOnError = options.throwOnError;
|
|
493
|
+
if (isFunction$1(_key)) {
|
|
494
|
+
const keyFilter = _key;
|
|
495
|
+
const matchedKeys = [];
|
|
496
|
+
const it = cache2.keys();
|
|
497
|
+
for (const key of it) {
|
|
498
|
+
if (
|
|
499
|
+
// Skip the special useSWRInfinite and useSWRSubscription keys.
|
|
500
|
+
!/^\$(inf|sub)\$/.test(key) && keyFilter(cache2.get(key)._k)
|
|
501
|
+
) {
|
|
502
|
+
matchedKeys.push(key);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return Promise.all(matchedKeys.map(mutateByKey));
|
|
506
|
+
}
|
|
507
|
+
return mutateByKey(_key);
|
|
508
|
+
async function mutateByKey(_k) {
|
|
509
|
+
const [key] = serialize$1(_k);
|
|
510
|
+
if (!key) return;
|
|
511
|
+
const [get, set] = createCacheHelper(cache2, key);
|
|
512
|
+
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
|
|
513
|
+
const startRevalidate = () => {
|
|
514
|
+
const revalidators = EVENT_REVALIDATORS[key];
|
|
515
|
+
const revalidate = isFunction$1(options.revalidate) ? options.revalidate(get().data, _k) : options.revalidate !== false;
|
|
516
|
+
if (revalidate) {
|
|
517
|
+
delete FETCH[key];
|
|
518
|
+
delete PRELOAD[key];
|
|
519
|
+
if (revalidators && revalidators[0]) {
|
|
520
|
+
return revalidators[0](MUTATE_EVENT).then(() => get().data);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return get().data;
|
|
524
|
+
};
|
|
525
|
+
if (args.length < 3) {
|
|
526
|
+
return startRevalidate();
|
|
527
|
+
}
|
|
528
|
+
let data = _data;
|
|
529
|
+
let error;
|
|
530
|
+
let isError = false;
|
|
531
|
+
const beforeMutationTs = getTimestamp();
|
|
532
|
+
MUTATION[key] = [
|
|
533
|
+
beforeMutationTs,
|
|
534
|
+
0
|
|
535
|
+
];
|
|
536
|
+
const hasOptimisticData = !isUndefined$1(optimisticData);
|
|
537
|
+
const state = get();
|
|
538
|
+
const displayedData = state.data;
|
|
539
|
+
const currentData = state._c;
|
|
540
|
+
const committedData = isUndefined$1(currentData) ? displayedData : currentData;
|
|
541
|
+
if (hasOptimisticData) {
|
|
542
|
+
optimisticData = isFunction$1(optimisticData) ? optimisticData(committedData, displayedData) : optimisticData;
|
|
543
|
+
set({
|
|
544
|
+
data: optimisticData,
|
|
545
|
+
_c: committedData
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
if (isFunction$1(data)) {
|
|
549
|
+
try {
|
|
550
|
+
data = data(committedData);
|
|
551
|
+
} catch (err) {
|
|
552
|
+
error = err;
|
|
553
|
+
isError = true;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
if (data && isPromiseLike(data)) {
|
|
557
|
+
data = await data.catch((err) => {
|
|
558
|
+
error = err;
|
|
559
|
+
isError = true;
|
|
560
|
+
});
|
|
561
|
+
if (beforeMutationTs !== MUTATION[key][0]) {
|
|
562
|
+
if (isError) throw error;
|
|
563
|
+
return data;
|
|
564
|
+
} else if (isError && hasOptimisticData && rollbackOnError(error)) {
|
|
565
|
+
populateCache = true;
|
|
566
|
+
set({
|
|
567
|
+
data: committedData,
|
|
568
|
+
_c: UNDEFINED$1
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
if (populateCache) {
|
|
573
|
+
if (!isError) {
|
|
574
|
+
if (isFunction$1(populateCache)) {
|
|
575
|
+
const populateCachedData = populateCache(data, committedData);
|
|
576
|
+
set({
|
|
577
|
+
data: populateCachedData,
|
|
578
|
+
error: UNDEFINED$1,
|
|
579
|
+
_c: UNDEFINED$1
|
|
580
|
+
});
|
|
581
|
+
} else {
|
|
582
|
+
set({
|
|
583
|
+
data,
|
|
584
|
+
error: UNDEFINED$1,
|
|
585
|
+
_c: UNDEFINED$1
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
MUTATION[key][1] = getTimestamp();
|
|
591
|
+
Promise.resolve(startRevalidate()).then(() => {
|
|
592
|
+
set({
|
|
593
|
+
_c: UNDEFINED$1
|
|
594
|
+
});
|
|
595
|
+
});
|
|
596
|
+
if (isError) {
|
|
597
|
+
if (throwOnError) throw error;
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
return data;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const revalidateAllKeys = (revalidators, type) => {
|
|
604
|
+
for (const key in revalidators) {
|
|
605
|
+
if (revalidators[key][0]) revalidators[key][0](type);
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
const initCache = (provider, options) => {
|
|
609
|
+
if (!SWRGlobalState.has(provider)) {
|
|
610
|
+
const opts = mergeObjects(defaultConfigOptions, options);
|
|
611
|
+
const EVENT_REVALIDATORS = /* @__PURE__ */ Object.create(null);
|
|
612
|
+
const mutate2 = internalMutate.bind(UNDEFINED$1, provider);
|
|
613
|
+
let unmount = noop$1;
|
|
614
|
+
const subscriptions = /* @__PURE__ */ Object.create(null);
|
|
615
|
+
const subscribe = (key, callback) => {
|
|
616
|
+
const subs = subscriptions[key] || [];
|
|
617
|
+
subscriptions[key] = subs;
|
|
618
|
+
subs.push(callback);
|
|
619
|
+
return () => subs.splice(subs.indexOf(callback), 1);
|
|
620
|
+
};
|
|
621
|
+
const setter = (key, value, prev) => {
|
|
622
|
+
provider.set(key, value);
|
|
623
|
+
const subs = subscriptions[key];
|
|
624
|
+
if (subs) {
|
|
625
|
+
for (const fn of subs) {
|
|
626
|
+
fn(value, prev);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
const initProvider = () => {
|
|
631
|
+
if (!SWRGlobalState.has(provider)) {
|
|
632
|
+
SWRGlobalState.set(provider, [
|
|
633
|
+
EVENT_REVALIDATORS,
|
|
634
|
+
/* @__PURE__ */ Object.create(null),
|
|
635
|
+
/* @__PURE__ */ Object.create(null),
|
|
636
|
+
/* @__PURE__ */ Object.create(null),
|
|
637
|
+
mutate2,
|
|
638
|
+
setter,
|
|
639
|
+
subscribe
|
|
640
|
+
]);
|
|
641
|
+
if (!IS_SERVER) {
|
|
642
|
+
const releaseFocus = opts.initFocus(setTimeout.bind(UNDEFINED$1, revalidateAllKeys.bind(UNDEFINED$1, EVENT_REVALIDATORS, FOCUS_EVENT)));
|
|
643
|
+
const releaseReconnect = opts.initReconnect(setTimeout.bind(UNDEFINED$1, revalidateAllKeys.bind(UNDEFINED$1, EVENT_REVALIDATORS, RECONNECT_EVENT)));
|
|
644
|
+
unmount = () => {
|
|
645
|
+
releaseFocus && releaseFocus();
|
|
646
|
+
releaseReconnect && releaseReconnect();
|
|
647
|
+
SWRGlobalState.delete(provider);
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
initProvider();
|
|
653
|
+
return [
|
|
654
|
+
provider,
|
|
655
|
+
mutate2,
|
|
656
|
+
initProvider,
|
|
657
|
+
unmount
|
|
658
|
+
];
|
|
659
|
+
}
|
|
660
|
+
return [
|
|
661
|
+
provider,
|
|
662
|
+
SWRGlobalState.get(provider)[4]
|
|
663
|
+
];
|
|
664
|
+
};
|
|
665
|
+
const onErrorRetry = (_, __, config, revalidate, opts) => {
|
|
666
|
+
const maxRetryCount = config.errorRetryCount;
|
|
667
|
+
const currentRetryCount = opts.retryCount;
|
|
668
|
+
const timeout = ~~((Math.random() + 0.5) * (1 << (currentRetryCount < 8 ? currentRetryCount : 8))) * config.errorRetryInterval;
|
|
669
|
+
if (!isUndefined$1(maxRetryCount) && currentRetryCount > maxRetryCount) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
setTimeout(revalidate, timeout, opts);
|
|
673
|
+
};
|
|
674
|
+
const compare = dequal;
|
|
675
|
+
const [cache, mutate] = initCache(/* @__PURE__ */ new Map());
|
|
676
|
+
const defaultConfig = mergeObjects(
|
|
677
|
+
{
|
|
678
|
+
// events
|
|
679
|
+
onLoadingSlow: noop$1,
|
|
680
|
+
onSuccess: noop$1,
|
|
681
|
+
onError: noop$1,
|
|
682
|
+
onErrorRetry,
|
|
683
|
+
onDiscarded: noop$1,
|
|
684
|
+
// switches
|
|
685
|
+
revalidateOnFocus: true,
|
|
686
|
+
revalidateOnReconnect: true,
|
|
687
|
+
revalidateIfStale: true,
|
|
688
|
+
shouldRetryOnError: true,
|
|
689
|
+
// timeouts
|
|
690
|
+
errorRetryInterval: slowConnection ? 1e4 : 5e3,
|
|
691
|
+
focusThrottleInterval: 5 * 1e3,
|
|
692
|
+
dedupingInterval: 2 * 1e3,
|
|
693
|
+
loadingTimeout: slowConnection ? 5e3 : 3e3,
|
|
694
|
+
// providers
|
|
695
|
+
compare,
|
|
696
|
+
isPaused: () => false,
|
|
697
|
+
cache,
|
|
698
|
+
mutate,
|
|
699
|
+
fallback: {}
|
|
700
|
+
},
|
|
701
|
+
// use web preset by default
|
|
702
|
+
preset
|
|
703
|
+
);
|
|
704
|
+
const mergeConfigs = (a, b) => {
|
|
705
|
+
const v = mergeObjects(a, b);
|
|
706
|
+
if (b) {
|
|
707
|
+
const { use: u1, fallback: f1 } = a;
|
|
708
|
+
const { use: u2, fallback: f2 } = b;
|
|
709
|
+
if (u1 && u2) {
|
|
710
|
+
v.use = u1.concat(u2);
|
|
711
|
+
}
|
|
712
|
+
if (f1 && f2) {
|
|
713
|
+
v.fallback = mergeObjects(f1, f2);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
return v;
|
|
717
|
+
};
|
|
718
|
+
const SWRConfigContext = reactExports.createContext({});
|
|
719
|
+
const INFINITE_PREFIX = "$inf$";
|
|
720
|
+
const enableDevtools = isWindowDefined && window.__SWR_DEVTOOLS_USE__;
|
|
721
|
+
const use$1 = enableDevtools ? window.__SWR_DEVTOOLS_USE__ : [];
|
|
722
|
+
const setupDevTools = () => {
|
|
723
|
+
if (enableDevtools) {
|
|
724
|
+
window.__SWR_DEVTOOLS_REACT__ = ReactExports;
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
const normalize = (args) => {
|
|
728
|
+
return isFunction$1(args[1]) ? [
|
|
729
|
+
args[0],
|
|
730
|
+
args[1],
|
|
731
|
+
args[2] || {}
|
|
732
|
+
] : [
|
|
733
|
+
args[0],
|
|
734
|
+
null,
|
|
735
|
+
(args[1] === null ? args[2] : args[1]) || {}
|
|
736
|
+
];
|
|
737
|
+
};
|
|
738
|
+
const useSWRConfig = () => {
|
|
739
|
+
const parentConfig = reactExports.useContext(SWRConfigContext);
|
|
740
|
+
const mergedConfig = reactExports.useMemo(() => mergeObjects(defaultConfig, parentConfig), [
|
|
741
|
+
parentConfig
|
|
742
|
+
]);
|
|
743
|
+
return mergedConfig;
|
|
744
|
+
};
|
|
745
|
+
const middleware = (useSWRNext) => (key_, fetcher_, config) => {
|
|
746
|
+
const fetcher = fetcher_ && ((...args) => {
|
|
747
|
+
const [key] = serialize$1(key_);
|
|
748
|
+
const [, , , PRELOAD] = SWRGlobalState.get(cache);
|
|
749
|
+
if (key.startsWith(INFINITE_PREFIX)) {
|
|
750
|
+
return fetcher_(...args);
|
|
751
|
+
}
|
|
752
|
+
const req = PRELOAD[key];
|
|
753
|
+
if (isUndefined$1(req)) return fetcher_(...args);
|
|
754
|
+
delete PRELOAD[key];
|
|
755
|
+
return req;
|
|
756
|
+
});
|
|
757
|
+
return useSWRNext(key_, fetcher, config);
|
|
758
|
+
};
|
|
759
|
+
const BUILT_IN_MIDDLEWARE = use$1.concat(middleware);
|
|
760
|
+
const withArgs = (hook) => {
|
|
761
|
+
return function useSWRArgs(...args) {
|
|
762
|
+
const fallbackConfig = useSWRConfig();
|
|
763
|
+
const [key, fn, _config] = normalize(args);
|
|
764
|
+
const config = mergeConfigs(fallbackConfig, _config);
|
|
765
|
+
let next = hook;
|
|
766
|
+
const { use: use2 } = config;
|
|
767
|
+
const middleware2 = (use2 || []).concat(BUILT_IN_MIDDLEWARE);
|
|
768
|
+
for (let i = middleware2.length; i--; ) {
|
|
769
|
+
next = middleware2[i](next);
|
|
770
|
+
}
|
|
771
|
+
return next(key, fn || config.fetcher || null, config);
|
|
772
|
+
};
|
|
773
|
+
};
|
|
774
|
+
const subscribeCallback = (key, callbacks, callback) => {
|
|
775
|
+
const keyedRevalidators = callbacks[key] || (callbacks[key] = []);
|
|
776
|
+
keyedRevalidators.push(callback);
|
|
777
|
+
return () => {
|
|
778
|
+
const index = keyedRevalidators.indexOf(callback);
|
|
779
|
+
if (index >= 0) {
|
|
780
|
+
keyedRevalidators[index] = keyedRevalidators[keyedRevalidators.length - 1];
|
|
781
|
+
keyedRevalidators.pop();
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
};
|
|
785
|
+
const withMiddleware = (useSWR2, middleware2) => {
|
|
786
|
+
return (...args) => {
|
|
787
|
+
const [key, fn, config] = normalize(args);
|
|
788
|
+
const uses = (config.use || []).concat(middleware2);
|
|
789
|
+
return useSWR2(key, fn, {
|
|
790
|
+
...config,
|
|
791
|
+
use: uses
|
|
792
|
+
});
|
|
793
|
+
};
|
|
794
|
+
};
|
|
795
|
+
setupDevTools();
|
|
796
|
+
const use = ReactExports.use || // This extra generic is to avoid TypeScript mixing up the generic and JSX sytax
|
|
797
|
+
// and emitting an error.
|
|
798
|
+
// We assume that this is only for the `use(thenable)` case, not `use(context)`.
|
|
799
|
+
// https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45
|
|
800
|
+
((thenable) => {
|
|
801
|
+
switch (thenable.status) {
|
|
802
|
+
case "pending":
|
|
803
|
+
throw thenable;
|
|
804
|
+
case "fulfilled":
|
|
805
|
+
return thenable.value;
|
|
806
|
+
case "rejected":
|
|
807
|
+
throw thenable.reason;
|
|
808
|
+
default:
|
|
809
|
+
thenable.status = "pending";
|
|
810
|
+
thenable.then((v) => {
|
|
811
|
+
thenable.status = "fulfilled";
|
|
812
|
+
thenable.value = v;
|
|
813
|
+
}, (e) => {
|
|
814
|
+
thenable.status = "rejected";
|
|
815
|
+
thenable.reason = e;
|
|
816
|
+
});
|
|
817
|
+
throw thenable;
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
const WITH_DEDUPE = {
|
|
821
|
+
dedupe: true
|
|
822
|
+
};
|
|
823
|
+
const resolvedUndef = Promise.resolve(UNDEFINED$1);
|
|
824
|
+
const useSWRHandler = (_key, fetcher, config) => {
|
|
825
|
+
const { cache: cache2, compare: compare2, suspense, fallbackData, revalidateOnMount, revalidateIfStale, refreshInterval, refreshWhenHidden, refreshWhenOffline, keepPreviousData } = config;
|
|
826
|
+
const [EVENT_REVALIDATORS, MUTATION, FETCH, PRELOAD] = SWRGlobalState.get(cache2);
|
|
827
|
+
const [key, fnArg] = serialize$1(_key);
|
|
828
|
+
const initialMountedRef = reactExports.useRef(false);
|
|
829
|
+
const unmountedRef = reactExports.useRef(false);
|
|
830
|
+
const keyRef = reactExports.useRef(key);
|
|
831
|
+
const fetcherRef = reactExports.useRef(fetcher);
|
|
832
|
+
const configRef = reactExports.useRef(config);
|
|
833
|
+
const getConfig = () => configRef.current;
|
|
834
|
+
const isActive = () => getConfig().isVisible() && getConfig().isOnline();
|
|
835
|
+
const [getCache, setCache, subscribeCache, getInitialCache] = createCacheHelper(cache2, key);
|
|
836
|
+
const stateDependencies = reactExports.useRef({}).current;
|
|
837
|
+
const fallback = isUndefined$1(fallbackData) ? isUndefined$1(config.fallback) ? UNDEFINED$1 : config.fallback[key] : fallbackData;
|
|
838
|
+
const isEqual = (prev, current) => {
|
|
839
|
+
for (const _ in stateDependencies) {
|
|
840
|
+
const t = _;
|
|
841
|
+
if (t === "data") {
|
|
842
|
+
if (!compare2(prev[t], current[t])) {
|
|
843
|
+
if (!isUndefined$1(prev[t])) {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
if (!compare2(returnedData, current[t])) {
|
|
847
|
+
return false;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
} else {
|
|
851
|
+
if (current[t] !== prev[t]) {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
return true;
|
|
857
|
+
};
|
|
858
|
+
const getSnapshot = reactExports.useMemo(() => {
|
|
859
|
+
const shouldStartRequest = (() => {
|
|
860
|
+
if (!key) return false;
|
|
861
|
+
if (!fetcher) return false;
|
|
862
|
+
if (!isUndefined$1(revalidateOnMount)) return revalidateOnMount;
|
|
863
|
+
if (getConfig().isPaused()) return false;
|
|
864
|
+
if (suspense) return false;
|
|
865
|
+
return revalidateIfStale !== false;
|
|
866
|
+
})();
|
|
867
|
+
const getSelectedCache = (state) => {
|
|
868
|
+
const snapshot = mergeObjects(state);
|
|
869
|
+
delete snapshot._k;
|
|
870
|
+
if (!shouldStartRequest) {
|
|
871
|
+
return snapshot;
|
|
872
|
+
}
|
|
873
|
+
return {
|
|
874
|
+
isValidating: true,
|
|
875
|
+
isLoading: true,
|
|
876
|
+
...snapshot
|
|
877
|
+
};
|
|
878
|
+
};
|
|
879
|
+
const cachedData2 = getCache();
|
|
880
|
+
const initialData = getInitialCache();
|
|
881
|
+
const clientSnapshot = getSelectedCache(cachedData2);
|
|
882
|
+
const serverSnapshot = cachedData2 === initialData ? clientSnapshot : getSelectedCache(initialData);
|
|
883
|
+
let memorizedSnapshot = clientSnapshot;
|
|
884
|
+
return [
|
|
885
|
+
() => {
|
|
886
|
+
const newSnapshot = getSelectedCache(getCache());
|
|
887
|
+
const compareResult = isEqual(newSnapshot, memorizedSnapshot);
|
|
888
|
+
if (compareResult) {
|
|
889
|
+
memorizedSnapshot.data = newSnapshot.data;
|
|
890
|
+
memorizedSnapshot.isLoading = newSnapshot.isLoading;
|
|
891
|
+
memorizedSnapshot.isValidating = newSnapshot.isValidating;
|
|
892
|
+
memorizedSnapshot.error = newSnapshot.error;
|
|
893
|
+
return memorizedSnapshot;
|
|
894
|
+
} else {
|
|
895
|
+
memorizedSnapshot = newSnapshot;
|
|
896
|
+
return newSnapshot;
|
|
897
|
+
}
|
|
898
|
+
},
|
|
899
|
+
() => serverSnapshot
|
|
900
|
+
];
|
|
901
|
+
}, [
|
|
902
|
+
cache2,
|
|
903
|
+
key
|
|
904
|
+
]);
|
|
905
|
+
const cached = shimExports.useSyncExternalStore(reactExports.useCallback(
|
|
906
|
+
(callback) => subscribeCache(key, (current, prev) => {
|
|
907
|
+
if (!isEqual(prev, current)) callback();
|
|
908
|
+
}),
|
|
909
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
910
|
+
[
|
|
911
|
+
cache2,
|
|
912
|
+
key
|
|
913
|
+
]
|
|
914
|
+
), getSnapshot[0], getSnapshot[1]);
|
|
915
|
+
const isInitialMount = !initialMountedRef.current;
|
|
916
|
+
const hasRevalidator = EVENT_REVALIDATORS[key] && EVENT_REVALIDATORS[key].length > 0;
|
|
917
|
+
const cachedData = cached.data;
|
|
918
|
+
const data = isUndefined$1(cachedData) ? fallback && isPromiseLike(fallback) ? use(fallback) : fallback : cachedData;
|
|
919
|
+
const error = cached.error;
|
|
920
|
+
const laggyDataRef = reactExports.useRef(data);
|
|
921
|
+
const returnedData = keepPreviousData ? isUndefined$1(cachedData) ? isUndefined$1(laggyDataRef.current) ? data : laggyDataRef.current : cachedData : data;
|
|
922
|
+
const shouldDoInitialRevalidation = (() => {
|
|
923
|
+
if (hasRevalidator && !isUndefined$1(error)) return false;
|
|
924
|
+
if (isInitialMount && !isUndefined$1(revalidateOnMount)) return revalidateOnMount;
|
|
925
|
+
if (getConfig().isPaused()) return false;
|
|
926
|
+
if (suspense) return isUndefined$1(data) ? false : revalidateIfStale;
|
|
927
|
+
return isUndefined$1(data) || revalidateIfStale;
|
|
928
|
+
})();
|
|
929
|
+
const defaultValidatingState = !!(key && fetcher && isInitialMount && shouldDoInitialRevalidation);
|
|
930
|
+
const isValidating = isUndefined$1(cached.isValidating) ? defaultValidatingState : cached.isValidating;
|
|
931
|
+
const isLoading = isUndefined$1(cached.isLoading) ? defaultValidatingState : cached.isLoading;
|
|
932
|
+
const revalidate = reactExports.useCallback(
|
|
933
|
+
async (revalidateOpts) => {
|
|
934
|
+
const currentFetcher = fetcherRef.current;
|
|
935
|
+
if (!key || !currentFetcher || unmountedRef.current || getConfig().isPaused()) {
|
|
936
|
+
return false;
|
|
937
|
+
}
|
|
938
|
+
let newData;
|
|
939
|
+
let startAt;
|
|
940
|
+
let loading = true;
|
|
941
|
+
const opts = revalidateOpts || {};
|
|
942
|
+
const shouldStartNewRequest = !FETCH[key] || !opts.dedupe;
|
|
943
|
+
const callbackSafeguard = () => {
|
|
944
|
+
if (IS_REACT_LEGACY) {
|
|
945
|
+
return !unmountedRef.current && key === keyRef.current && initialMountedRef.current;
|
|
946
|
+
}
|
|
947
|
+
return key === keyRef.current;
|
|
948
|
+
};
|
|
949
|
+
const finalState = {
|
|
950
|
+
isValidating: false,
|
|
951
|
+
isLoading: false
|
|
952
|
+
};
|
|
953
|
+
const finishRequestAndUpdateState = () => {
|
|
954
|
+
setCache(finalState);
|
|
955
|
+
};
|
|
956
|
+
const cleanupState = () => {
|
|
957
|
+
const requestInfo = FETCH[key];
|
|
958
|
+
if (requestInfo && requestInfo[1] === startAt) {
|
|
959
|
+
delete FETCH[key];
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
const initialState = {
|
|
963
|
+
isValidating: true
|
|
964
|
+
};
|
|
965
|
+
if (isUndefined$1(getCache().data)) {
|
|
966
|
+
initialState.isLoading = true;
|
|
967
|
+
}
|
|
968
|
+
try {
|
|
969
|
+
if (shouldStartNewRequest) {
|
|
970
|
+
setCache(initialState);
|
|
971
|
+
if (config.loadingTimeout && isUndefined$1(getCache().data)) {
|
|
972
|
+
setTimeout(() => {
|
|
973
|
+
if (loading && callbackSafeguard()) {
|
|
974
|
+
getConfig().onLoadingSlow(key, config);
|
|
975
|
+
}
|
|
976
|
+
}, config.loadingTimeout);
|
|
977
|
+
}
|
|
978
|
+
FETCH[key] = [
|
|
979
|
+
currentFetcher(fnArg),
|
|
980
|
+
getTimestamp()
|
|
981
|
+
];
|
|
982
|
+
}
|
|
983
|
+
;
|
|
984
|
+
[newData, startAt] = FETCH[key];
|
|
985
|
+
newData = await newData;
|
|
986
|
+
if (shouldStartNewRequest) {
|
|
987
|
+
setTimeout(cleanupState, config.dedupingInterval);
|
|
988
|
+
}
|
|
989
|
+
if (!FETCH[key] || FETCH[key][1] !== startAt) {
|
|
990
|
+
if (shouldStartNewRequest) {
|
|
991
|
+
if (callbackSafeguard()) {
|
|
992
|
+
getConfig().onDiscarded(key);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
return false;
|
|
996
|
+
}
|
|
997
|
+
finalState.error = UNDEFINED$1;
|
|
998
|
+
const mutationInfo = MUTATION[key];
|
|
999
|
+
if (!isUndefined$1(mutationInfo) && // case 1
|
|
1000
|
+
(startAt <= mutationInfo[0] || // case 2
|
|
1001
|
+
startAt <= mutationInfo[1] || // case 3
|
|
1002
|
+
mutationInfo[1] === 0)) {
|
|
1003
|
+
finishRequestAndUpdateState();
|
|
1004
|
+
if (shouldStartNewRequest) {
|
|
1005
|
+
if (callbackSafeguard()) {
|
|
1006
|
+
getConfig().onDiscarded(key);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
return false;
|
|
1010
|
+
}
|
|
1011
|
+
const cacheData = getCache().data;
|
|
1012
|
+
finalState.data = compare2(cacheData, newData) ? cacheData : newData;
|
|
1013
|
+
if (shouldStartNewRequest) {
|
|
1014
|
+
if (callbackSafeguard()) {
|
|
1015
|
+
getConfig().onSuccess(newData, key, config);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
} catch (err) {
|
|
1019
|
+
cleanupState();
|
|
1020
|
+
const currentConfig = getConfig();
|
|
1021
|
+
const { shouldRetryOnError } = currentConfig;
|
|
1022
|
+
if (!currentConfig.isPaused()) {
|
|
1023
|
+
finalState.error = err;
|
|
1024
|
+
if (shouldStartNewRequest && callbackSafeguard()) {
|
|
1025
|
+
currentConfig.onError(err, key, currentConfig);
|
|
1026
|
+
if (shouldRetryOnError === true || isFunction$1(shouldRetryOnError) && shouldRetryOnError(err)) {
|
|
1027
|
+
if (!getConfig().revalidateOnFocus || !getConfig().revalidateOnReconnect || isActive()) {
|
|
1028
|
+
currentConfig.onErrorRetry(err, key, currentConfig, (_opts) => {
|
|
1029
|
+
const revalidators = EVENT_REVALIDATORS[key];
|
|
1030
|
+
if (revalidators && revalidators[0]) {
|
|
1031
|
+
revalidators[0](ERROR_REVALIDATE_EVENT, _opts);
|
|
1032
|
+
}
|
|
1033
|
+
}, {
|
|
1034
|
+
retryCount: (opts.retryCount || 0) + 1,
|
|
1035
|
+
dedupe: true
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
loading = false;
|
|
1043
|
+
finishRequestAndUpdateState();
|
|
1044
|
+
return true;
|
|
1045
|
+
},
|
|
1046
|
+
// `setState` is immutable, and `eventsCallback`, `fnArg`, and
|
|
1047
|
+
// `keyValidating` are depending on `key`, so we can exclude them from
|
|
1048
|
+
// the deps array.
|
|
1049
|
+
//
|
|
1050
|
+
// FIXME:
|
|
1051
|
+
// `fn` and `config` might be changed during the lifecycle,
|
|
1052
|
+
// but they might be changed every render like this.
|
|
1053
|
+
// `useSWR('key', () => fetch('/api/'), { suspense: true })`
|
|
1054
|
+
// So we omit the values from the deps array
|
|
1055
|
+
// even though it might cause unexpected behaviors.
|
|
1056
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1057
|
+
[
|
|
1058
|
+
key,
|
|
1059
|
+
cache2
|
|
1060
|
+
]
|
|
1061
|
+
);
|
|
1062
|
+
const boundMutate = reactExports.useCallback(
|
|
1063
|
+
// Use callback to make sure `keyRef.current` returns latest result every time
|
|
1064
|
+
(...args) => {
|
|
1065
|
+
return internalMutate(cache2, keyRef.current, ...args);
|
|
1066
|
+
},
|
|
1067
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1068
|
+
[]
|
|
1069
|
+
);
|
|
1070
|
+
useIsomorphicLayoutEffect(() => {
|
|
1071
|
+
fetcherRef.current = fetcher;
|
|
1072
|
+
configRef.current = config;
|
|
1073
|
+
if (!isUndefined$1(cachedData)) {
|
|
1074
|
+
laggyDataRef.current = cachedData;
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
useIsomorphicLayoutEffect(() => {
|
|
1078
|
+
if (!key) return;
|
|
1079
|
+
const softRevalidate = revalidate.bind(UNDEFINED$1, WITH_DEDUPE);
|
|
1080
|
+
let nextFocusRevalidatedAt = 0;
|
|
1081
|
+
if (getConfig().revalidateOnFocus) {
|
|
1082
|
+
const initNow = Date.now();
|
|
1083
|
+
nextFocusRevalidatedAt = initNow + getConfig().focusThrottleInterval;
|
|
1084
|
+
}
|
|
1085
|
+
const onRevalidate = (type, opts = {}) => {
|
|
1086
|
+
if (type == FOCUS_EVENT) {
|
|
1087
|
+
const now = Date.now();
|
|
1088
|
+
if (getConfig().revalidateOnFocus && now > nextFocusRevalidatedAt && isActive()) {
|
|
1089
|
+
nextFocusRevalidatedAt = now + getConfig().focusThrottleInterval;
|
|
1090
|
+
softRevalidate();
|
|
1091
|
+
}
|
|
1092
|
+
} else if (type == RECONNECT_EVENT) {
|
|
1093
|
+
if (getConfig().revalidateOnReconnect && isActive()) {
|
|
1094
|
+
softRevalidate();
|
|
1095
|
+
}
|
|
1096
|
+
} else if (type == MUTATE_EVENT) {
|
|
1097
|
+
return revalidate();
|
|
1098
|
+
} else if (type == ERROR_REVALIDATE_EVENT) {
|
|
1099
|
+
return revalidate(opts);
|
|
1100
|
+
}
|
|
1101
|
+
return;
|
|
1102
|
+
};
|
|
1103
|
+
const unsubEvents = subscribeCallback(key, EVENT_REVALIDATORS, onRevalidate);
|
|
1104
|
+
unmountedRef.current = false;
|
|
1105
|
+
keyRef.current = key;
|
|
1106
|
+
initialMountedRef.current = true;
|
|
1107
|
+
setCache({
|
|
1108
|
+
_k: fnArg
|
|
1109
|
+
});
|
|
1110
|
+
if (shouldDoInitialRevalidation) {
|
|
1111
|
+
if (!FETCH[key]) {
|
|
1112
|
+
if (isUndefined$1(data) || IS_SERVER) {
|
|
1113
|
+
softRevalidate();
|
|
1114
|
+
} else {
|
|
1115
|
+
rAF(softRevalidate);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
return () => {
|
|
1120
|
+
unmountedRef.current = true;
|
|
1121
|
+
unsubEvents();
|
|
1122
|
+
};
|
|
1123
|
+
}, [
|
|
1124
|
+
key
|
|
1125
|
+
]);
|
|
1126
|
+
useIsomorphicLayoutEffect(() => {
|
|
1127
|
+
let timer;
|
|
1128
|
+
function next() {
|
|
1129
|
+
const interval = isFunction$1(refreshInterval) ? refreshInterval(getCache().data) : refreshInterval;
|
|
1130
|
+
if (interval && timer !== -1) {
|
|
1131
|
+
timer = setTimeout(execute, interval);
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
function execute() {
|
|
1135
|
+
if (!getCache().error && (refreshWhenHidden || getConfig().isVisible()) && (refreshWhenOffline || getConfig().isOnline())) {
|
|
1136
|
+
revalidate(WITH_DEDUPE).then(next);
|
|
1137
|
+
} else {
|
|
1138
|
+
next();
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
next();
|
|
1142
|
+
return () => {
|
|
1143
|
+
if (timer) {
|
|
1144
|
+
clearTimeout(timer);
|
|
1145
|
+
timer = -1;
|
|
1146
|
+
}
|
|
1147
|
+
};
|
|
1148
|
+
}, [
|
|
1149
|
+
refreshInterval,
|
|
1150
|
+
refreshWhenHidden,
|
|
1151
|
+
refreshWhenOffline,
|
|
1152
|
+
key
|
|
1153
|
+
]);
|
|
1154
|
+
reactExports.useDebugValue(returnedData);
|
|
1155
|
+
if (suspense) {
|
|
1156
|
+
const hasKeyButNoData = key && isUndefined$1(data);
|
|
1157
|
+
if (!IS_REACT_LEGACY && IS_SERVER && hasKeyButNoData) {
|
|
1158
|
+
throw new Error("Fallback data is required when using Suspense in SSR.");
|
|
1159
|
+
}
|
|
1160
|
+
if (hasKeyButNoData) {
|
|
1161
|
+
fetcherRef.current = fetcher;
|
|
1162
|
+
configRef.current = config;
|
|
1163
|
+
unmountedRef.current = false;
|
|
1164
|
+
}
|
|
1165
|
+
const req = PRELOAD[key];
|
|
1166
|
+
const mutateReq = !isUndefined$1(req) && hasKeyButNoData ? boundMutate(req) : resolvedUndef;
|
|
1167
|
+
use(mutateReq);
|
|
1168
|
+
if (!isUndefined$1(error) && hasKeyButNoData) {
|
|
1169
|
+
throw error;
|
|
1170
|
+
}
|
|
1171
|
+
const revalidation = hasKeyButNoData ? revalidate(WITH_DEDUPE) : resolvedUndef;
|
|
1172
|
+
if (!isUndefined$1(returnedData) && hasKeyButNoData) {
|
|
1173
|
+
revalidation.status = "fulfilled";
|
|
1174
|
+
revalidation.value = true;
|
|
1175
|
+
}
|
|
1176
|
+
use(revalidation);
|
|
1177
|
+
}
|
|
1178
|
+
const swrResponse = {
|
|
1179
|
+
mutate: boundMutate,
|
|
1180
|
+
get data() {
|
|
1181
|
+
stateDependencies.data = true;
|
|
1182
|
+
return returnedData;
|
|
1183
|
+
},
|
|
1184
|
+
get error() {
|
|
1185
|
+
stateDependencies.error = true;
|
|
1186
|
+
return error;
|
|
1187
|
+
},
|
|
1188
|
+
get isValidating() {
|
|
1189
|
+
stateDependencies.isValidating = true;
|
|
1190
|
+
return isValidating;
|
|
1191
|
+
},
|
|
1192
|
+
get isLoading() {
|
|
1193
|
+
stateDependencies.isLoading = true;
|
|
1194
|
+
return isLoading;
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
return swrResponse;
|
|
1198
|
+
};
|
|
1199
|
+
const useSWR = withArgs(useSWRHandler);
|
|
1200
|
+
const noop = () => {
|
|
1201
|
+
};
|
|
1202
|
+
const UNDEFINED = (
|
|
1203
|
+
/*#__NOINLINE__*/
|
|
1204
|
+
noop()
|
|
1205
|
+
);
|
|
1206
|
+
const OBJECT = Object;
|
|
1207
|
+
const isUndefined = (v) => v === UNDEFINED;
|
|
1208
|
+
const isFunction = (v) => typeof v == "function";
|
|
1209
|
+
const table = /* @__PURE__ */ new WeakMap();
|
|
1210
|
+
const getTypeName = (value) => OBJECT.prototype.toString.call(value);
|
|
1211
|
+
const isObjectTypeName = (typeName, type) => typeName === `[object ${type}]`;
|
|
1212
|
+
let counter = 0;
|
|
1213
|
+
const stableHash = (arg) => {
|
|
1214
|
+
const type = typeof arg;
|
|
1215
|
+
const typeName = getTypeName(arg);
|
|
1216
|
+
const isDate = isObjectTypeName(typeName, "Date");
|
|
1217
|
+
const isRegex = isObjectTypeName(typeName, "RegExp");
|
|
1218
|
+
const isPlainObject = isObjectTypeName(typeName, "Object");
|
|
1219
|
+
let result;
|
|
1220
|
+
let index;
|
|
1221
|
+
if (OBJECT(arg) === arg && !isDate && !isRegex) {
|
|
1222
|
+
result = table.get(arg);
|
|
1223
|
+
if (result) return result;
|
|
1224
|
+
result = ++counter + "~";
|
|
1225
|
+
table.set(arg, result);
|
|
1226
|
+
if (Array.isArray(arg)) {
|
|
1227
|
+
result = "@";
|
|
1228
|
+
for (index = 0; index < arg.length; index++) {
|
|
1229
|
+
result += stableHash(arg[index]) + ",";
|
|
1230
|
+
}
|
|
1231
|
+
table.set(arg, result);
|
|
1232
|
+
}
|
|
1233
|
+
if (isPlainObject) {
|
|
1234
|
+
result = "#";
|
|
1235
|
+
const keys = OBJECT.keys(arg).sort();
|
|
1236
|
+
while (!isUndefined(index = keys.pop())) {
|
|
1237
|
+
if (!isUndefined(arg[index])) {
|
|
1238
|
+
result += index + ":" + stableHash(arg[index]) + ",";
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
table.set(arg, result);
|
|
1242
|
+
}
|
|
1243
|
+
} else {
|
|
1244
|
+
result = isDate ? arg.toJSON() : type == "symbol" ? arg.toString() : type == "string" ? JSON.stringify(arg) : "" + arg;
|
|
1245
|
+
}
|
|
1246
|
+
return result;
|
|
1247
|
+
};
|
|
1248
|
+
const serialize = (key) => {
|
|
1249
|
+
if (isFunction(key)) {
|
|
1250
|
+
try {
|
|
1251
|
+
key = key();
|
|
1252
|
+
} catch (err) {
|
|
1253
|
+
key = "";
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
const args = key;
|
|
1257
|
+
key = typeof key == "string" ? key : (Array.isArray(key) ? key.length : key) ? stableHash(key) : "";
|
|
1258
|
+
return [
|
|
1259
|
+
key,
|
|
1260
|
+
args
|
|
1261
|
+
];
|
|
1262
|
+
};
|
|
1263
|
+
const getFirstPageKey = (getKey) => {
|
|
1264
|
+
return serialize(getKey ? getKey(0, null) : null)[0];
|
|
1265
|
+
};
|
|
1266
|
+
const EMPTY_PROMISE = Promise.resolve();
|
|
1267
|
+
const infinite = (useSWRNext) => (getKey, fn, config) => {
|
|
1268
|
+
const didMountRef = reactExports.useRef(false);
|
|
1269
|
+
const { cache: cache$1, initialSize = 1, revalidateAll = false, persistSize = false, revalidateFirstPage = true, revalidateOnMount = false, parallel = false } = config;
|
|
1270
|
+
const [, , , PRELOAD] = SWRGlobalState.get(cache);
|
|
1271
|
+
let infiniteKey;
|
|
1272
|
+
try {
|
|
1273
|
+
infiniteKey = getFirstPageKey(getKey);
|
|
1274
|
+
if (infiniteKey) infiniteKey = INFINITE_PREFIX + infiniteKey;
|
|
1275
|
+
} catch (err) {
|
|
1276
|
+
}
|
|
1277
|
+
const [get, set, subscribeCache] = createCacheHelper(cache$1, infiniteKey);
|
|
1278
|
+
const getSnapshot = reactExports.useCallback(() => {
|
|
1279
|
+
const size = isUndefined$1(get()._l) ? initialSize : get()._l;
|
|
1280
|
+
return size;
|
|
1281
|
+
}, [
|
|
1282
|
+
cache$1,
|
|
1283
|
+
infiniteKey,
|
|
1284
|
+
initialSize
|
|
1285
|
+
]);
|
|
1286
|
+
shimExports.useSyncExternalStore(reactExports.useCallback(
|
|
1287
|
+
(callback) => {
|
|
1288
|
+
if (infiniteKey) return subscribeCache(infiniteKey, () => {
|
|
1289
|
+
callback();
|
|
1290
|
+
});
|
|
1291
|
+
return () => {
|
|
1292
|
+
};
|
|
1293
|
+
},
|
|
1294
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1295
|
+
[
|
|
1296
|
+
cache$1,
|
|
1297
|
+
infiniteKey
|
|
1298
|
+
]
|
|
1299
|
+
), getSnapshot, getSnapshot);
|
|
1300
|
+
const resolvePageSize = reactExports.useCallback(() => {
|
|
1301
|
+
const cachedPageSize = get()._l;
|
|
1302
|
+
return isUndefined$1(cachedPageSize) ? initialSize : cachedPageSize;
|
|
1303
|
+
}, [
|
|
1304
|
+
infiniteKey,
|
|
1305
|
+
initialSize
|
|
1306
|
+
]);
|
|
1307
|
+
const lastPageSizeRef = reactExports.useRef(resolvePageSize());
|
|
1308
|
+
useIsomorphicLayoutEffect(() => {
|
|
1309
|
+
if (!didMountRef.current) {
|
|
1310
|
+
didMountRef.current = true;
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
if (infiniteKey) {
|
|
1314
|
+
set({
|
|
1315
|
+
_l: persistSize ? lastPageSizeRef.current : resolvePageSize()
|
|
1316
|
+
});
|
|
1317
|
+
}
|
|
1318
|
+
}, [
|
|
1319
|
+
infiniteKey,
|
|
1320
|
+
cache$1
|
|
1321
|
+
]);
|
|
1322
|
+
const shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current;
|
|
1323
|
+
const swr = useSWRNext(infiniteKey, async (key) => {
|
|
1324
|
+
const forceRevalidateAll = get()._i;
|
|
1325
|
+
const shouldRevalidatePage = get()._r;
|
|
1326
|
+
set({
|
|
1327
|
+
_r: UNDEFINED$1
|
|
1328
|
+
});
|
|
1329
|
+
const data = [];
|
|
1330
|
+
const pageSize = resolvePageSize();
|
|
1331
|
+
const [getCache] = createCacheHelper(cache$1, key);
|
|
1332
|
+
const cacheData = getCache().data;
|
|
1333
|
+
const revalidators = [];
|
|
1334
|
+
let previousPageData = null;
|
|
1335
|
+
for (let i = 0; i < pageSize; ++i) {
|
|
1336
|
+
const [pageKey, pageArg] = serialize$1(getKey(i, parallel ? null : previousPageData));
|
|
1337
|
+
if (!pageKey) {
|
|
1338
|
+
break;
|
|
1339
|
+
}
|
|
1340
|
+
const [getSWRCache, setSWRCache] = createCacheHelper(cache$1, pageKey);
|
|
1341
|
+
let pageData = getSWRCache().data;
|
|
1342
|
+
const shouldFetchPage = revalidateAll || forceRevalidateAll || isUndefined$1(pageData) || revalidateFirstPage && !i && !isUndefined$1(cacheData) || shouldRevalidateOnMount || cacheData && !isUndefined$1(cacheData[i]) && !config.compare(cacheData[i], pageData);
|
|
1343
|
+
if (fn && (typeof shouldRevalidatePage === "function" ? shouldRevalidatePage(pageData, pageArg) : shouldFetchPage)) {
|
|
1344
|
+
const revalidate = async () => {
|
|
1345
|
+
const hasPreloadedRequest = pageKey in PRELOAD;
|
|
1346
|
+
if (!hasPreloadedRequest) {
|
|
1347
|
+
pageData = await fn(pageArg);
|
|
1348
|
+
} else {
|
|
1349
|
+
const req = PRELOAD[pageKey];
|
|
1350
|
+
delete PRELOAD[pageKey];
|
|
1351
|
+
pageData = await req;
|
|
1352
|
+
}
|
|
1353
|
+
setSWRCache({
|
|
1354
|
+
data: pageData,
|
|
1355
|
+
_k: pageArg
|
|
1356
|
+
});
|
|
1357
|
+
data[i] = pageData;
|
|
1358
|
+
};
|
|
1359
|
+
if (parallel) {
|
|
1360
|
+
revalidators.push(revalidate);
|
|
1361
|
+
} else {
|
|
1362
|
+
await revalidate();
|
|
1363
|
+
}
|
|
1364
|
+
} else {
|
|
1365
|
+
data[i] = pageData;
|
|
1366
|
+
}
|
|
1367
|
+
if (!parallel) {
|
|
1368
|
+
previousPageData = pageData;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
if (parallel) {
|
|
1372
|
+
await Promise.all(revalidators.map((r) => r()));
|
|
1373
|
+
}
|
|
1374
|
+
set({
|
|
1375
|
+
_i: UNDEFINED$1
|
|
1376
|
+
});
|
|
1377
|
+
return data;
|
|
1378
|
+
}, config);
|
|
1379
|
+
const mutate2 = reactExports.useCallback(
|
|
1380
|
+
// eslint-disable-next-line func-names
|
|
1381
|
+
function(data, opts) {
|
|
1382
|
+
const options = typeof opts === "boolean" ? {
|
|
1383
|
+
revalidate: opts
|
|
1384
|
+
} : opts || {};
|
|
1385
|
+
const shouldRevalidate = options.revalidate !== false;
|
|
1386
|
+
if (!infiniteKey) return EMPTY_PROMISE;
|
|
1387
|
+
if (shouldRevalidate) {
|
|
1388
|
+
if (!isUndefined$1(data)) {
|
|
1389
|
+
set({
|
|
1390
|
+
_i: false,
|
|
1391
|
+
_r: options.revalidate
|
|
1392
|
+
});
|
|
1393
|
+
} else {
|
|
1394
|
+
set({
|
|
1395
|
+
_i: true,
|
|
1396
|
+
_r: options.revalidate
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
return arguments.length ? swr.mutate(data, {
|
|
1401
|
+
...options,
|
|
1402
|
+
revalidate: shouldRevalidate
|
|
1403
|
+
}) : swr.mutate();
|
|
1404
|
+
},
|
|
1405
|
+
// swr.mutate is always the same reference
|
|
1406
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1407
|
+
[
|
|
1408
|
+
infiniteKey,
|
|
1409
|
+
cache$1
|
|
1410
|
+
]
|
|
1411
|
+
);
|
|
1412
|
+
const setSize = reactExports.useCallback(
|
|
1413
|
+
(arg) => {
|
|
1414
|
+
if (!infiniteKey) return EMPTY_PROMISE;
|
|
1415
|
+
const [, changeSize] = createCacheHelper(cache$1, infiniteKey);
|
|
1416
|
+
let size;
|
|
1417
|
+
if (isFunction$1(arg)) {
|
|
1418
|
+
size = arg(resolvePageSize());
|
|
1419
|
+
} else if (typeof arg == "number") {
|
|
1420
|
+
size = arg;
|
|
1421
|
+
}
|
|
1422
|
+
if (typeof size != "number") return EMPTY_PROMISE;
|
|
1423
|
+
changeSize({
|
|
1424
|
+
_l: size
|
|
1425
|
+
});
|
|
1426
|
+
lastPageSizeRef.current = size;
|
|
1427
|
+
const data = [];
|
|
1428
|
+
const [getInfiniteCache] = createCacheHelper(cache$1, infiniteKey);
|
|
1429
|
+
let previousPageData = null;
|
|
1430
|
+
for (let i = 0; i < size; ++i) {
|
|
1431
|
+
const [pageKey] = serialize$1(getKey(i, previousPageData));
|
|
1432
|
+
const [getCache] = createCacheHelper(cache$1, pageKey);
|
|
1433
|
+
const pageData = pageKey ? getCache().data : UNDEFINED$1;
|
|
1434
|
+
if (isUndefined$1(pageData)) {
|
|
1435
|
+
return mutate2(getInfiniteCache().data);
|
|
1436
|
+
}
|
|
1437
|
+
data.push(pageData);
|
|
1438
|
+
previousPageData = pageData;
|
|
1439
|
+
}
|
|
1440
|
+
return mutate2(data);
|
|
1441
|
+
},
|
|
1442
|
+
// exclude getKey from the dependencies, which isn't allowed to change during the lifecycle
|
|
1443
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1444
|
+
[
|
|
1445
|
+
infiniteKey,
|
|
1446
|
+
cache$1,
|
|
1447
|
+
mutate2,
|
|
1448
|
+
resolvePageSize
|
|
1449
|
+
]
|
|
1450
|
+
);
|
|
1451
|
+
return {
|
|
1452
|
+
size: resolvePageSize(),
|
|
1453
|
+
setSize,
|
|
1454
|
+
mutate: mutate2,
|
|
1455
|
+
get data() {
|
|
1456
|
+
return swr.data;
|
|
1457
|
+
},
|
|
1458
|
+
get error() {
|
|
1459
|
+
return swr.error;
|
|
1460
|
+
},
|
|
1461
|
+
get isValidating() {
|
|
1462
|
+
return swr.isValidating;
|
|
1463
|
+
},
|
|
1464
|
+
get isLoading() {
|
|
1465
|
+
return swr.isLoading;
|
|
374
1466
|
}
|
|
375
1467
|
};
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
Array.from({ length: rows }, (_, i) => renderRow(i))
|
|
379
|
-
] }) });
|
|
380
|
-
}
|
|
1468
|
+
};
|
|
1469
|
+
const useSWRInfinite = withMiddleware(useSWR, infinite);
|
|
381
1470
|
function pluralize(singular, plural, count2) {
|
|
382
1471
|
return count2 === 1 ? singular : plural;
|
|
383
1472
|
}
|
|
1473
|
+
function useInfiniteList(cacheKey, fetchFn, getItemKey) {
|
|
1474
|
+
var _a;
|
|
1475
|
+
const getKey = reactExports.useCallback(
|
|
1476
|
+
(_index, prev) => {
|
|
1477
|
+
if (prev && (!prev.hasMore || !prev.cursor)) return null;
|
|
1478
|
+
return [cacheKey, (prev == null ? void 0 : prev.cursor) ?? null];
|
|
1479
|
+
},
|
|
1480
|
+
[cacheKey]
|
|
1481
|
+
);
|
|
1482
|
+
const {
|
|
1483
|
+
data: pages,
|
|
1484
|
+
error,
|
|
1485
|
+
isLoading,
|
|
1486
|
+
isValidating,
|
|
1487
|
+
size,
|
|
1488
|
+
setSize,
|
|
1489
|
+
mutate: mutate2
|
|
1490
|
+
} = useSWRInfinite(
|
|
1491
|
+
getKey,
|
|
1492
|
+
([, cursor]) => fetchFn(cursor ?? void 0),
|
|
1493
|
+
{
|
|
1494
|
+
revalidateFirstPage: false,
|
|
1495
|
+
revalidateIfStale: false,
|
|
1496
|
+
revalidateOnFocus: false,
|
|
1497
|
+
keepPreviousData: true
|
|
1498
|
+
}
|
|
1499
|
+
);
|
|
1500
|
+
const items = reactExports.useMemo(() => {
|
|
1501
|
+
if (!pages) return [];
|
|
1502
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1503
|
+
const result = [];
|
|
1504
|
+
for (const page of pages) {
|
|
1505
|
+
for (const item of page.data) {
|
|
1506
|
+
const key = getItemKey(item);
|
|
1507
|
+
if (seen.has(key)) continue;
|
|
1508
|
+
seen.add(key);
|
|
1509
|
+
result.push(item);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
return result;
|
|
1513
|
+
}, [pages, getItemKey]);
|
|
1514
|
+
const lastPage = pages == null ? void 0 : pages[pages.length - 1];
|
|
1515
|
+
const hasMore = Boolean((lastPage == null ? void 0 : lastPage.hasMore) && (lastPage == null ? void 0 : lastPage.cursor));
|
|
1516
|
+
const isLoadingMore = size > 0 && Boolean(pages) && pages.length < size;
|
|
1517
|
+
const loadMore = reactExports.useCallback(() => {
|
|
1518
|
+
if (isValidating || !hasMore) return;
|
|
1519
|
+
void setSize((s) => s + 1);
|
|
1520
|
+
}, [isValidating, hasMore, setSize]);
|
|
1521
|
+
const reload = reactExports.useCallback(() => {
|
|
1522
|
+
void setSize(1);
|
|
1523
|
+
void mutate2();
|
|
1524
|
+
}, [setSize, mutate2]);
|
|
1525
|
+
const normalizedError = error ? error instanceof Error ? error : new WorkflowWebAPIError(String(error), { layer: "client" }) : null;
|
|
1526
|
+
return {
|
|
1527
|
+
items,
|
|
1528
|
+
error: normalizedError,
|
|
1529
|
+
isLoading,
|
|
1530
|
+
isLoadingMore,
|
|
1531
|
+
hasMore,
|
|
1532
|
+
loadMore,
|
|
1533
|
+
reload,
|
|
1534
|
+
refresh: reload,
|
|
1535
|
+
pageInfo: (_a = pages == null ? void 0 : pages[0]) == null ? void 0 : _a.pageInfo
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
function useWorkflowRunsInfinite(env, params) {
|
|
1539
|
+
const {
|
|
1540
|
+
workflowName,
|
|
1541
|
+
status,
|
|
1542
|
+
limit = 25,
|
|
1543
|
+
sortOrder = "desc",
|
|
1544
|
+
startTime,
|
|
1545
|
+
endTime
|
|
1546
|
+
} = params;
|
|
1547
|
+
const cacheKey = `workflow-runs:${workflowName ?? ""}:${status ?? ""}:${sortOrder}:${limit}:${startTime ?? ""}:${endTime ?? ""}`;
|
|
1548
|
+
const fetchFn = reactExports.useCallback(
|
|
1549
|
+
(cursor) => unwrapOrThrow(
|
|
1550
|
+
fetchRuns(env, {
|
|
1551
|
+
cursor,
|
|
1552
|
+
sortOrder,
|
|
1553
|
+
limit,
|
|
1554
|
+
workflowName,
|
|
1555
|
+
status,
|
|
1556
|
+
startTime,
|
|
1557
|
+
endTime
|
|
1558
|
+
})
|
|
1559
|
+
),
|
|
1560
|
+
[env, workflowName, limit, sortOrder, status, startTime, endTime]
|
|
1561
|
+
);
|
|
1562
|
+
const getItemKey = reactExports.useCallback((run) => run.runId, []);
|
|
1563
|
+
return useInfiniteList(cacheKey, fetchFn, getItemKey);
|
|
1564
|
+
}
|
|
1565
|
+
function useLoadMoreOnScroll(loadMore, {
|
|
1566
|
+
hasMore,
|
|
1567
|
+
isLoadingMore,
|
|
1568
|
+
root = null,
|
|
1569
|
+
rootMargin = "400px"
|
|
1570
|
+
}) {
|
|
1571
|
+
const sentinelRef = reactExports.useRef(null);
|
|
1572
|
+
const loadMoreRef = reactExports.useRef(loadMore);
|
|
1573
|
+
reactExports.useEffect(() => {
|
|
1574
|
+
loadMoreRef.current = loadMore;
|
|
1575
|
+
}, [loadMore]);
|
|
1576
|
+
reactExports.useEffect(() => {
|
|
1577
|
+
const sentinel = sentinelRef.current;
|
|
1578
|
+
if (!sentinel || !hasMore || isLoadingMore) return;
|
|
1579
|
+
const observer = new IntersectionObserver(
|
|
1580
|
+
(entries) => {
|
|
1581
|
+
for (const entry of entries) {
|
|
1582
|
+
if (entry.isIntersecting) {
|
|
1583
|
+
loadMoreRef.current();
|
|
1584
|
+
break;
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
},
|
|
1588
|
+
{ root, rootMargin, threshold: 0 }
|
|
1589
|
+
);
|
|
1590
|
+
observer.observe(sentinel);
|
|
1591
|
+
return () => observer.disconnect();
|
|
1592
|
+
}, [hasMore, isLoadingMore, root, rootMargin]);
|
|
1593
|
+
return sentinelRef;
|
|
1594
|
+
}
|
|
384
1595
|
function usePaginatedList(fetchFn) {
|
|
385
1596
|
var _a;
|
|
386
1597
|
const [cursor, setCursor] = reactExports.useState(void 0);
|
|
@@ -413,7 +1624,8 @@ function usePaginatedList(fetchFn) {
|
|
|
413
1624
|
newMap.set(pageIndex, {
|
|
414
1625
|
data: cached.data,
|
|
415
1626
|
isLoading: false,
|
|
416
|
-
error: null
|
|
1627
|
+
error: null,
|
|
1628
|
+
pageInfo: cached.pageInfo
|
|
417
1629
|
});
|
|
418
1630
|
return newMap;
|
|
419
1631
|
});
|
|
@@ -427,14 +1639,16 @@ function usePaginatedList(fetchFn) {
|
|
|
427
1639
|
pageCache.current.set(cacheKey, {
|
|
428
1640
|
data: result.data,
|
|
429
1641
|
cursor: result.cursor,
|
|
430
|
-
hasMore: result.hasMore
|
|
1642
|
+
hasMore: result.hasMore,
|
|
1643
|
+
pageInfo: result.pageInfo
|
|
431
1644
|
});
|
|
432
1645
|
setAllPageResults((prev) => {
|
|
433
1646
|
const newMap = new Map(prev);
|
|
434
1647
|
newMap.set(pageIndex, {
|
|
435
1648
|
data: result.data,
|
|
436
1649
|
isLoading: false,
|
|
437
|
-
error: null
|
|
1650
|
+
error: null,
|
|
1651
|
+
pageInfo: result.pageInfo
|
|
438
1652
|
});
|
|
439
1653
|
return newMap;
|
|
440
1654
|
});
|
|
@@ -530,19 +1744,10 @@ function usePaginatedList(fetchFn) {
|
|
|
530
1744
|
hasPreviousPage: currentPage > 0,
|
|
531
1745
|
reload,
|
|
532
1746
|
refresh,
|
|
533
|
-
pageInfo
|
|
1747
|
+
pageInfo,
|
|
1748
|
+
analyticsPageInfo: currentPageResult.pageInfo
|
|
534
1749
|
};
|
|
535
1750
|
}
|
|
536
|
-
function useWorkflowRuns(env, params) {
|
|
537
|
-
const { workflowName, status, limit = 10, sortOrder = "desc" } = params;
|
|
538
|
-
const fetchFn = reactExports.useCallback(
|
|
539
|
-
(cursor) => unwrapOrThrow(
|
|
540
|
-
fetchRuns(env, { cursor, sortOrder, limit, workflowName, status })
|
|
541
|
-
),
|
|
542
|
-
[env, workflowName, limit, sortOrder, status]
|
|
543
|
-
);
|
|
544
|
-
return usePaginatedList(fetchFn);
|
|
545
|
-
}
|
|
546
1751
|
function useWorkflowHooks(env, params) {
|
|
547
1752
|
const { runId, limit = 10, sortOrder = "desc" } = params;
|
|
548
1753
|
const fetchFn = reactExports.useCallback(
|
|
@@ -551,6 +1756,137 @@ function useWorkflowHooks(env, params) {
|
|
|
551
1756
|
);
|
|
552
1757
|
return usePaginatedList(fetchFn);
|
|
553
1758
|
}
|
|
1759
|
+
function HookTokenCell({ env, runId, hookId }) {
|
|
1760
|
+
const [status, setStatus] = reactExports.useState("idle");
|
|
1761
|
+
const [error, setError] = reactExports.useState(null);
|
|
1762
|
+
const handleCopy = async (e) => {
|
|
1763
|
+
e.stopPropagation();
|
|
1764
|
+
if (status === "loading") return;
|
|
1765
|
+
setStatus("loading");
|
|
1766
|
+
setError(null);
|
|
1767
|
+
try {
|
|
1768
|
+
const token = await fetchHookToken(env, runId, hookId);
|
|
1769
|
+
await navigator.clipboard.writeText(token);
|
|
1770
|
+
setStatus("copied");
|
|
1771
|
+
setTimeout(() => setStatus("idle"), 2e3);
|
|
1772
|
+
} catch (err) {
|
|
1773
|
+
console.error("Failed to copy hook token:", err);
|
|
1774
|
+
setError("Failed to copy token");
|
|
1775
|
+
setStatus("idle");
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
const tooltip = error ? error : status === "copied" ? "Copied!" : status === "loading" ? "Fetching token…" : "Copy token";
|
|
1779
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "relative group/copy inline-block", children: [
|
|
1780
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground", children: "••••••••••••" }),
|
|
1781
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
1782
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
1783
|
+
"button",
|
|
1784
|
+
{
|
|
1785
|
+
type: "button",
|
|
1786
|
+
onClick: handleCopy,
|
|
1787
|
+
disabled: status === "loading",
|
|
1788
|
+
className: "absolute right-0 top-1/2 -translate-y-1/2 opacity-0 group-hover/copy:opacity-100 transition-opacity bg-background/80 backdrop-blur-sm p-1 rounded",
|
|
1789
|
+
"aria-label": "Copy token",
|
|
1790
|
+
children: status === "loading" ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-3 w-3 text-muted-foreground animate-spin" }) : status === "copied" ? /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "h-3 w-3 text-muted-foreground hover:text-foreground" })
|
|
1791
|
+
}
|
|
1792
|
+
) }),
|
|
1793
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: tooltip }) })
|
|
1794
|
+
] })
|
|
1795
|
+
] });
|
|
1796
|
+
}
|
|
1797
|
+
function TableSkeleton({
|
|
1798
|
+
rows = DEFAULT_PAGE_SIZE,
|
|
1799
|
+
variant = "runs"
|
|
1800
|
+
}) {
|
|
1801
|
+
const renderRow = (i) => {
|
|
1802
|
+
switch (variant) {
|
|
1803
|
+
case "runs":
|
|
1804
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1805
|
+
"div",
|
|
1806
|
+
{
|
|
1807
|
+
className: "grid grid-cols-[1fr_1.5fr_0.8fr_1fr_1fr_40px] items-center gap-4 py-3 px-4",
|
|
1808
|
+
children: [
|
|
1809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1810
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
1812
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-14" }),
|
|
1813
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-2 w-8" })
|
|
1814
|
+
] }),
|
|
1815
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1816
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-6 w-6 rounded" })
|
|
1818
|
+
]
|
|
1819
|
+
},
|
|
1820
|
+
`skeleton-row-${i}`
|
|
1821
|
+
);
|
|
1822
|
+
case "hooks":
|
|
1823
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1824
|
+
"div",
|
|
1825
|
+
{
|
|
1826
|
+
className: "grid grid-cols-[1.2fr_1.2fr_0.8fr_1fr_0.5fr_40px] items-center gap-4 py-3 px-4",
|
|
1827
|
+
children: [
|
|
1828
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1829
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1830
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-3 w-3/4" }),
|
|
1832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-8" }),
|
|
1833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-6 w-6 rounded" })
|
|
1834
|
+
]
|
|
1835
|
+
},
|
|
1836
|
+
`skeleton-row-${i}`
|
|
1837
|
+
);
|
|
1838
|
+
case "workflows":
|
|
1839
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
1840
|
+
"div",
|
|
1841
|
+
{
|
|
1842
|
+
className: "grid grid-cols-[1fr_1.5fr_0.5fr] items-center gap-4 py-3 px-4",
|
|
1843
|
+
children: [
|
|
1844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
1845
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-4/5" }),
|
|
1846
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-5 w-16 rounded-full mx-auto" })
|
|
1847
|
+
]
|
|
1848
|
+
},
|
|
1849
|
+
`skeleton-row-${i}`
|
|
1850
|
+
);
|
|
1851
|
+
default:
|
|
1852
|
+
return null;
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
const renderHeader = () => {
|
|
1856
|
+
switch (variant) {
|
|
1857
|
+
case "runs":
|
|
1858
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1fr_1.5fr_0.8fr_1fr_1fr_40px] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1859
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1860
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1861
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12" }),
|
|
1862
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1863
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1864
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-6" })
|
|
1865
|
+
] });
|
|
1866
|
+
case "hooks":
|
|
1867
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1.2fr_1.2fr_0.8fr_1fr_0.5fr_40px] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1868
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-16" }),
|
|
1869
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12" }),
|
|
1871
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-14" }),
|
|
1872
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1873
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-6" })
|
|
1874
|
+
] });
|
|
1875
|
+
case "workflows":
|
|
1876
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-[1fr_1.5fr_0.5fr] items-center gap-4 py-3 px-4 border-b", children: [
|
|
1877
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-20" }),
|
|
1878
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-10" }),
|
|
1879
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Skeleton, { className: "h-4 w-12 mx-auto" })
|
|
1880
|
+
] });
|
|
1881
|
+
default:
|
|
1882
|
+
return null;
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-0", children: [
|
|
1886
|
+
renderHeader(),
|
|
1887
|
+
Array.from({ length: rows }, (_, i) => renderRow(i))
|
|
1888
|
+
] }) });
|
|
1889
|
+
}
|
|
554
1890
|
function HooksTable({
|
|
555
1891
|
runId,
|
|
556
1892
|
onHookClick,
|
|
@@ -575,7 +1911,8 @@ function HooksTable({
|
|
|
575
1911
|
});
|
|
576
1912
|
const hookActions = useHookActions({
|
|
577
1913
|
onResolve: async (hook, payload) => {
|
|
578
|
-
await
|
|
1914
|
+
const token = await fetchHookToken(env, hook.runId, hook.hookId);
|
|
1915
|
+
await resumeHook(env, token, payload);
|
|
579
1916
|
},
|
|
580
1917
|
callbacks: {
|
|
581
1918
|
onSuccess: refresh
|
|
@@ -710,7 +2047,7 @@ function HooksTable({
|
|
|
710
2047
|
] }),
|
|
711
2048
|
error ? /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", children: [
|
|
712
2049
|
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
713
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Error loading hooks" }),
|
|
2050
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: getErrorTitle(error, "Error loading hooks") }),
|
|
714
2051
|
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
715
2052
|
] }) : !loading && (!hooks || hooks.length === 0) ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
716
2053
|
"No active hooks found. ",
|
|
@@ -735,7 +2072,14 @@ function HooksTable({
|
|
|
735
2072
|
children: [
|
|
736
2073
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: hook.hookId, overlay: true, children: hook.hookId }) }),
|
|
737
2074
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: hook.runId, overlay: true, children: hook.runId }) }),
|
|
738
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
2076
|
+
HookTokenCell,
|
|
2077
|
+
{
|
|
2078
|
+
env,
|
|
2079
|
+
runId: hook.runId,
|
|
2080
|
+
hookId: hook.hookId
|
|
2081
|
+
}
|
|
2082
|
+
) }),
|
|
739
2083
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: hook.createdAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: hook.createdAt }) : "-" }),
|
|
740
2084
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: renderInvocationCount(hook) }),
|
|
741
2085
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(DropdownMenu, { children: [
|
|
@@ -2283,6 +3627,27 @@ const SelectSeparator = reactExports.forwardRef(({ className, ...props }, ref) =
|
|
|
2283
3627
|
}
|
|
2284
3628
|
));
|
|
2285
3629
|
SelectSeparator.displayName = Separator.displayName;
|
|
3630
|
+
const windows = /* @__PURE__ */ new Map();
|
|
3631
|
+
function createWindow(periodMs) {
|
|
3632
|
+
const end = Date.now();
|
|
3633
|
+
return {
|
|
3634
|
+
startTime: new Date(end - periodMs).toISOString(),
|
|
3635
|
+
endTime: new Date(end).toISOString()
|
|
3636
|
+
};
|
|
3637
|
+
}
|
|
3638
|
+
function getListingWindow(periodId, periodMs) {
|
|
3639
|
+
let window2 = windows.get(periodId);
|
|
3640
|
+
if (!window2) {
|
|
3641
|
+
window2 = createWindow(periodMs);
|
|
3642
|
+
windows.set(periodId, window2);
|
|
3643
|
+
}
|
|
3644
|
+
return window2;
|
|
3645
|
+
}
|
|
3646
|
+
function advanceListingWindow(periodId, periodMs) {
|
|
3647
|
+
const window2 = createWindow(periodMs);
|
|
3648
|
+
windows.set(periodId, window2);
|
|
3649
|
+
return window2;
|
|
3650
|
+
}
|
|
2286
3651
|
function useTableSelection({
|
|
2287
3652
|
getItemId
|
|
2288
3653
|
}) {
|
|
@@ -2705,6 +4070,20 @@ const statusMap = {
|
|
|
2705
4070
|
failed: { label: "Failed", color: "bg-red-600 dark:bg-red-400" },
|
|
2706
4071
|
cancelled: { label: "Cancelled", color: "bg-gray-600 dark:bg-gray-400" }
|
|
2707
4072
|
};
|
|
4073
|
+
const HOUR_MS = 60 * 60 * 1e3;
|
|
4074
|
+
const DAY_MS = 24 * HOUR_MS;
|
|
4075
|
+
const PERIOD_PRESETS = [
|
|
4076
|
+
{ id: "1h", label: "Last hour", ms: HOUR_MS },
|
|
4077
|
+
{ id: "6h", label: "Last 6 hours", ms: 6 * HOUR_MS },
|
|
4078
|
+
{ id: "24h", label: "Last 24 hours", ms: DAY_MS },
|
|
4079
|
+
{ id: "3d", label: "Last 3 days", ms: 3 * DAY_MS },
|
|
4080
|
+
{ id: "7d", label: "Last 7 days", ms: 7 * DAY_MS },
|
|
4081
|
+
{ id: "30d", label: "Last 30 days", ms: 30 * DAY_MS }
|
|
4082
|
+
];
|
|
4083
|
+
const DEFAULT_PERIOD = "24h";
|
|
4084
|
+
function isPeriodId(value) {
|
|
4085
|
+
return PERIOD_PRESETS.some((preset2) => preset2.id === value);
|
|
4086
|
+
}
|
|
2708
4087
|
function useWorkflowFilter() {
|
|
2709
4088
|
const navigate = useNavigate();
|
|
2710
4089
|
const { pathname } = useLocation();
|
|
@@ -2740,15 +4119,36 @@ function useStatusFilter() {
|
|
|
2740
4119
|
[navigate, pathname, searchParams]
|
|
2741
4120
|
);
|
|
2742
4121
|
}
|
|
4122
|
+
function usePeriodFilter() {
|
|
4123
|
+
const navigate = useNavigate();
|
|
4124
|
+
const { pathname } = useLocation();
|
|
4125
|
+
const [searchParams] = useSearchParams();
|
|
4126
|
+
return reactExports.useCallback(
|
|
4127
|
+
(value) => {
|
|
4128
|
+
const params = new URLSearchParams(searchParams.toString());
|
|
4129
|
+
if (value === DEFAULT_PERIOD) {
|
|
4130
|
+
params.delete("period");
|
|
4131
|
+
} else {
|
|
4132
|
+
params.set("period", value);
|
|
4133
|
+
}
|
|
4134
|
+
navigate(`${pathname}?${params.toString()}`);
|
|
4135
|
+
},
|
|
4136
|
+
[navigate, pathname, searchParams]
|
|
4137
|
+
);
|
|
4138
|
+
}
|
|
2743
4139
|
function FilterControls({
|
|
2744
4140
|
workflowNameFilter,
|
|
2745
4141
|
status,
|
|
2746
4142
|
seenWorkflowNames,
|
|
2747
4143
|
sortOrder,
|
|
2748
4144
|
loading,
|
|
2749
|
-
|
|
4145
|
+
period,
|
|
4146
|
+
showPeriodPicker,
|
|
4147
|
+
planWindowMs,
|
|
4148
|
+
planUpgradeAvailable,
|
|
2750
4149
|
onWorkflowChange,
|
|
2751
4150
|
onStatusChange,
|
|
4151
|
+
onPeriodChange,
|
|
2752
4152
|
onSortToggle,
|
|
2753
4153
|
onRefresh,
|
|
2754
4154
|
lastRefreshTime
|
|
@@ -2766,6 +4166,35 @@ function FilterControls({
|
|
|
2766
4166
|
)
|
|
2767
4167
|
] }),
|
|
2768
4168
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4", children: [
|
|
4169
|
+
showPeriodPicker && /* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
4170
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4171
|
+
Select,
|
|
4172
|
+
{
|
|
4173
|
+
value: period,
|
|
4174
|
+
onValueChange: onPeriodChange,
|
|
4175
|
+
disabled: loading,
|
|
4176
|
+
children: [
|
|
4177
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-[150px] h-9", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Time window" }) }),
|
|
4178
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectContent, { children: PERIOD_PRESETS.map((preset2) => {
|
|
4179
|
+
const beyondPlan = planWindowMs !== void 0 && preset2.ms > planWindowMs;
|
|
4180
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4181
|
+
SelectItem,
|
|
4182
|
+
{
|
|
4183
|
+
value: preset2.id,
|
|
4184
|
+
disabled: beyondPlan,
|
|
4185
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
4186
|
+
preset2.label,
|
|
4187
|
+
beyondPlan && planUpgradeAvailable && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-muted-foreground", children: "Observability Plus" })
|
|
4188
|
+
] })
|
|
4189
|
+
},
|
|
4190
|
+
preset2.id
|
|
4191
|
+
);
|
|
4192
|
+
}) })
|
|
4193
|
+
]
|
|
4194
|
+
}
|
|
4195
|
+
) }) }),
|
|
4196
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: planUpgradeAvailable ? "Time window for the runs list. Longer windows require Observability Plus." : "Time window for the runs list" })
|
|
4197
|
+
] }),
|
|
2769
4198
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
2770
4199
|
Select,
|
|
2771
4200
|
{
|
|
@@ -2790,7 +4219,7 @@ function FilterControls({
|
|
|
2790
4219
|
{
|
|
2791
4220
|
value: status || "all",
|
|
2792
4221
|
onValueChange: onStatusChange,
|
|
2793
|
-
disabled: loading
|
|
4222
|
+
disabled: loading,
|
|
2794
4223
|
children: [
|
|
2795
4224
|
/* @__PURE__ */ jsxRuntimeExports.jsx(SelectTrigger, { className: "w-[140px] h-9", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SelectValue, { placeholder: "Filter by status" }) }),
|
|
2796
4225
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(SelectContent, { children: [
|
|
@@ -2810,7 +4239,7 @@ function FilterControls({
|
|
|
2810
4239
|
]
|
|
2811
4240
|
}
|
|
2812
4241
|
) }) }),
|
|
2813
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children:
|
|
4242
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipContent, { children: "Filter runs by status" })
|
|
2814
4243
|
] }),
|
|
2815
4244
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Tooltip, { children: [
|
|
2816
4245
|
/* @__PURE__ */ jsxRuntimeExports.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -2848,7 +4277,7 @@ function FilterControls({
|
|
|
2848
4277
|
] });
|
|
2849
4278
|
}
|
|
2850
4279
|
function RunsTable({ onRunClick }) {
|
|
2851
|
-
var _a, _b, _c
|
|
4280
|
+
var _a, _b, _c;
|
|
2852
4281
|
const [searchParams] = useSearchParams();
|
|
2853
4282
|
const handleWorkflowFilter = useWorkflowFilter();
|
|
2854
4283
|
const handleStatusFilter = useStatusFilter();
|
|
@@ -2857,6 +4286,10 @@ function RunsTable({ onRunClick }) {
|
|
|
2857
4286
|
const validStatuses = Object.keys(statusMap);
|
|
2858
4287
|
const status = rawStatus === "all" || rawStatus && validStatuses.includes(rawStatus) ? rawStatus : void 0;
|
|
2859
4288
|
const workflowNameFilter = searchParams.get("workflow");
|
|
4289
|
+
const rawPeriod = searchParams.get("period");
|
|
4290
|
+
const period = isPeriodId(rawPeriod) ? rawPeriod : DEFAULT_PERIOD;
|
|
4291
|
+
const periodPreset = PERIOD_PRESETS.find((preset2) => preset2.id === period) ?? PERIOD_PRESETS[2];
|
|
4292
|
+
const handlePeriodFilter = usePeriodFilter();
|
|
2860
4293
|
const [sortOrder, setSortOrder] = reactExports.useState("desc");
|
|
2861
4294
|
const [lastRefreshTime, setLastRefreshTime] = reactExports.useState(
|
|
2862
4295
|
() => /* @__PURE__ */ new Date()
|
|
@@ -2866,35 +4299,62 @@ function RunsTable({ onRunClick }) {
|
|
|
2866
4299
|
const isLocal = serverConfig.backendId === "local" || serverConfig.backendId === "@workflow/world-local";
|
|
2867
4300
|
const localDataDirPath = (_a = serverConfig.displayInfo) == null ? void 0 : _a["local.dataDirPath"];
|
|
2868
4301
|
const localShortName = (_b = serverConfig.displayInfo) == null ? void 0 : _b["local.shortName"];
|
|
2869
|
-
const statusFilterRequiresWorkflowNameFilter = ((_c = serverConfig.backendId) == null ? void 0 : _c.includes("vercel")) || false;
|
|
2870
4302
|
const [seenWorkflowNames, setSeenWorkflowNames] = reactExports.useState(
|
|
2871
4303
|
/* @__PURE__ */ new Set()
|
|
2872
4304
|
);
|
|
4305
|
+
const isVercelBackend = ((_c = serverConfig.backendId) == null ? void 0 : _c.includes("vercel")) ?? false;
|
|
4306
|
+
const [listingWindow, setListingWindow] = reactExports.useState(
|
|
4307
|
+
() => isVercelBackend ? getListingWindow(period, periodPreset.ms) : void 0
|
|
4308
|
+
);
|
|
4309
|
+
reactExports.useEffect(() => {
|
|
4310
|
+
setListingWindow(
|
|
4311
|
+
isVercelBackend ? getListingWindow(period, periodPreset.ms) : void 0
|
|
4312
|
+
);
|
|
4313
|
+
}, [isVercelBackend, period, periodPreset.ms]);
|
|
4314
|
+
const refreshListingWindow = reactExports.useCallback(() => {
|
|
4315
|
+
if (isVercelBackend) {
|
|
4316
|
+
setListingWindow(advanceListingWindow(period, periodPreset.ms));
|
|
4317
|
+
}
|
|
4318
|
+
}, [isVercelBackend, period, periodPreset.ms]);
|
|
2873
4319
|
const {
|
|
2874
|
-
|
|
4320
|
+
items: runs,
|
|
2875
4321
|
error,
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
4322
|
+
isLoading,
|
|
4323
|
+
isLoadingMore,
|
|
4324
|
+
hasMore,
|
|
4325
|
+
loadMore,
|
|
2880
4326
|
reload,
|
|
2881
4327
|
refresh,
|
|
2882
|
-
pageInfo
|
|
2883
|
-
} =
|
|
4328
|
+
pageInfo: analyticsPageInfo
|
|
4329
|
+
} = useWorkflowRunsInfinite(env, {
|
|
2884
4330
|
sortOrder,
|
|
2885
4331
|
workflowName: workflowNameFilter === "all" ? void 0 : workflowNameFilter,
|
|
2886
|
-
status: status === "all" ? void 0 : status
|
|
4332
|
+
status: status === "all" ? void 0 : status,
|
|
4333
|
+
startTime: listingWindow == null ? void 0 : listingWindow.startTime,
|
|
4334
|
+
endTime: listingWindow == null ? void 0 : listingWindow.endTime
|
|
4335
|
+
});
|
|
4336
|
+
const [planInfo, setPlanInfo] = reactExports.useState(void 0);
|
|
4337
|
+
reactExports.useEffect(() => {
|
|
4338
|
+
if (analyticsPageInfo) {
|
|
4339
|
+
setPlanInfo(analyticsPageInfo);
|
|
4340
|
+
}
|
|
4341
|
+
}, [analyticsPageInfo]);
|
|
4342
|
+
const planWindowMs = planInfo !== void 0 ? planInfo.currentLookbackDays * DAY_MS : void 0;
|
|
4343
|
+
const [scrollRoot, setScrollRoot] = reactExports.useState(null);
|
|
4344
|
+
const sentinelRef = useLoadMoreOnScroll(loadMore, {
|
|
4345
|
+
hasMore,
|
|
4346
|
+
isLoadingMore,
|
|
4347
|
+
root: scrollRoot
|
|
2887
4348
|
});
|
|
2888
4349
|
const selection = useTableSelection({
|
|
2889
4350
|
getItemId: (run) => run.runId
|
|
2890
4351
|
});
|
|
2891
|
-
const runs = data.data ?? [];
|
|
2892
4352
|
const [isBulkCancelling, setIsBulkCancelling] = reactExports.useState(false);
|
|
2893
4353
|
const [isBulkReenqueuing, setIsBulkReenqueuing] = reactExports.useState(false);
|
|
2894
|
-
const isLocalAndHasMissingData = isLocal && (!localDataDirPath || !
|
|
4354
|
+
const isLocalAndHasMissingData = isLocal && (!localDataDirPath || !runs.length);
|
|
2895
4355
|
reactExports.useEffect(() => {
|
|
2896
|
-
if (
|
|
2897
|
-
const newNames = new Set(
|
|
4356
|
+
if (runs.length > 0) {
|
|
4357
|
+
const newNames = new Set(runs.map((run) => run.workflowName));
|
|
2898
4358
|
setSeenWorkflowNames((prev) => {
|
|
2899
4359
|
const updated = new Set(prev);
|
|
2900
4360
|
for (const name of newNames) {
|
|
@@ -2903,8 +4363,8 @@ function RunsTable({ onRunClick }) {
|
|
|
2903
4363
|
return updated;
|
|
2904
4364
|
});
|
|
2905
4365
|
}
|
|
2906
|
-
}, [
|
|
2907
|
-
const loading =
|
|
4366
|
+
}, [runs]);
|
|
4367
|
+
const loading = isLoading;
|
|
2908
4368
|
reactExports.useEffect(() => {
|
|
2909
4369
|
if (!loading && !hasLoadedOnce) {
|
|
2910
4370
|
setHasLoadedOnce(true);
|
|
@@ -2916,12 +4376,14 @@ function RunsTable({ onRunClick }) {
|
|
|
2916
4376
|
const onReload = reactExports.useCallback(() => {
|
|
2917
4377
|
setLastRefreshTime(() => /* @__PURE__ */ new Date());
|
|
2918
4378
|
setHasLoadedOnce(false);
|
|
4379
|
+
refreshListingWindow();
|
|
2919
4380
|
reload();
|
|
2920
|
-
}, [reload]);
|
|
4381
|
+
}, [reload, refreshListingWindow]);
|
|
2921
4382
|
const onRefresh = reactExports.useCallback(() => {
|
|
2922
4383
|
setLastRefreshTime(() => /* @__PURE__ */ new Date());
|
|
4384
|
+
refreshListingWindow();
|
|
2923
4385
|
refresh();
|
|
2924
|
-
}, [refresh]);
|
|
4386
|
+
}, [refresh, refreshListingWindow]);
|
|
2925
4387
|
const selectedRuns = reactExports.useMemo(() => {
|
|
2926
4388
|
return runs.filter((run) => selection.selectedIds.has(run.runId));
|
|
2927
4389
|
}, [runs, selection.selectedIds]);
|
|
@@ -3028,120 +4490,122 @@ function RunsTable({ onRunClick }) {
|
|
|
3028
4490
|
seenWorkflowNames,
|
|
3029
4491
|
sortOrder,
|
|
3030
4492
|
loading,
|
|
3031
|
-
|
|
4493
|
+
period,
|
|
4494
|
+
showPeriodPicker: isVercelBackend,
|
|
4495
|
+
planWindowMs,
|
|
4496
|
+
planUpgradeAvailable: (planInfo == null ? void 0 : planInfo.upgradeAvailable) ?? false,
|
|
3032
4497
|
onWorkflowChange: handleWorkflowFilter,
|
|
3033
4498
|
onStatusChange: handleStatusFilter,
|
|
4499
|
+
onPeriodChange: handlePeriodFilter,
|
|
3034
4500
|
onSortToggle: toggleSortOrder,
|
|
3035
4501
|
onRefresh: onReload,
|
|
3036
4502
|
lastRefreshTime
|
|
3037
4503
|
}
|
|
3038
4504
|
),
|
|
3039
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
disabled: !runs.length
|
|
3049
|
-
}
|
|
3050
|
-
) }),
|
|
3051
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Workflow" }),
|
|
3052
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Run ID" }),
|
|
3053
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Status" }),
|
|
3054
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Started" }),
|
|
3055
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Completed" }),
|
|
3056
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10" })
|
|
3057
|
-
] }) }),
|
|
3058
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableBody, { children: error ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
3059
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
3060
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: "Error loading runs" }),
|
|
3061
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
3062
|
-
] }) }) }) }) : loading && !hasLoadedOnce ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }) }) : !data.data || data.data.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center text-muted-foreground flex flex-col items-center justify-center gap-3 h-full", children: [
|
|
3063
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm", children: [
|
|
3064
|
-
"No workflow runs found",
|
|
3065
|
-
isLocalAndHasMissingData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
3066
|
-
" in ",
|
|
3067
|
-
localDirText
|
|
3068
|
-
] }) : "",
|
|
3069
|
-
"."
|
|
3070
|
-
] }),
|
|
3071
|
-
isLocalAndHasMissingData && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm flex items-center gap-2", children: "This view will update once you run a workflow." })
|
|
3072
|
-
] }) }) }) : runs.map((run) => {
|
|
3073
|
-
var _a2;
|
|
3074
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3075
|
-
TableRow,
|
|
3076
|
-
{
|
|
3077
|
-
className: "cursor-pointer group relative",
|
|
3078
|
-
onClick: () => onRunClick(run.runId),
|
|
3079
|
-
"data-selected": selection.isSelected(run),
|
|
3080
|
-
children: [
|
|
3081
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4505
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden mt-4 bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4506
|
+
CardContent,
|
|
4507
|
+
{
|
|
4508
|
+
ref: setScrollRoot,
|
|
4509
|
+
className: "p-0 max-h-[calc(100vh-280px)] overflow-auto",
|
|
4510
|
+
children: [
|
|
4511
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Table, { children: [
|
|
4512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(TableRow, { children: [
|
|
4513
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3082
4514
|
Checkbox,
|
|
3083
4515
|
{
|
|
3084
|
-
checked: selection.
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.workflowName, overlay: true, children: ((_a2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _a2.shortName) || "?" }) }),
|
|
3090
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.runId, overlay: true, children: run.runId }) }),
|
|
3091
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3092
|
-
StatusBadge,
|
|
3093
|
-
{
|
|
3094
|
-
status: run.status,
|
|
3095
|
-
context: run,
|
|
3096
|
-
durationMs: run.startedAt ? (run.completedAt ? new Date(run.completedAt).getTime() : Date.now()) - new Date(run.startedAt).getTime() : void 0
|
|
4516
|
+
checked: selection.isAllSelected(runs),
|
|
4517
|
+
indeterminate: selection.isSomeSelected(runs),
|
|
4518
|
+
onCheckedChange: () => selection.toggleSelectAll(runs),
|
|
4519
|
+
"aria-label": "Select all runs",
|
|
4520
|
+
disabled: !runs.length
|
|
3097
4521
|
}
|
|
3098
4522
|
) }),
|
|
3099
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3100
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3101
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
}
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
4523
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Workflow" }),
|
|
4524
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Run ID" }),
|
|
4525
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Status" }),
|
|
4526
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Started" }),
|
|
4527
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10", children: "Completed" }),
|
|
4528
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableHead, { className: "sticky top-0 bg-background z-10 border-b shadow-sm h-10 w-10" })
|
|
4529
|
+
] }) }),
|
|
4530
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(TableBody, { children: [
|
|
4531
|
+
error ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
4532
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "h-4 w-4" }),
|
|
4533
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTitle, { children: getErrorTitle(error, "Error loading runs") }),
|
|
4534
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertDescription, { children: getErrorMessage(error) })
|
|
4535
|
+
] }) }) }) }) : loading && !hasLoadedOnce ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }) }) : runs.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "h-[400px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-center text-muted-foreground flex flex-col items-center justify-center gap-3 h-full", children: [
|
|
4536
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm", children: [
|
|
4537
|
+
"No workflow runs found",
|
|
4538
|
+
isLocalAndHasMissingData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4539
|
+
" in ",
|
|
4540
|
+
localDirText
|
|
4541
|
+
] }) : "",
|
|
4542
|
+
"."
|
|
4543
|
+
] }),
|
|
4544
|
+
isLocalAndHasMissingData && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm flex items-center gap-2", children: "This view will update once you run a workflow." })
|
|
4545
|
+
] }) }) }) : runs.map((run) => {
|
|
4546
|
+
var _a2;
|
|
4547
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
4548
|
+
TableRow,
|
|
4549
|
+
{
|
|
4550
|
+
className: "cursor-pointer group relative",
|
|
4551
|
+
onClick: () => onRunClick(run.runId),
|
|
4552
|
+
"data-selected": selection.isSelected(run),
|
|
4553
|
+
children: [
|
|
4554
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4555
|
+
Checkbox,
|
|
4556
|
+
{
|
|
4557
|
+
checked: selection.isSelected(run),
|
|
4558
|
+
onCheckedChange: () => selection.toggleSelection(run),
|
|
4559
|
+
"aria-label": `Select run ${run.runId}`
|
|
4560
|
+
}
|
|
4561
|
+
) }),
|
|
4562
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.workflowName, overlay: true, children: ((_a2 = parseWorkflowName(run.workflowName)) == null ? void 0 : _a2.shortName) || "?" }) }),
|
|
4563
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "font-mono text-xs py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyableText, { text: run.runId, overlay: true, children: run.runId }) }),
|
|
4564
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4565
|
+
StatusBadge,
|
|
4566
|
+
{
|
|
4567
|
+
status: run.status,
|
|
4568
|
+
context: run,
|
|
4569
|
+
durationMs: run.startedAt ? (run.completedAt ? new Date(run.completedAt).getTime() : Date.now()) - new Date(run.startedAt).getTime() : void 0
|
|
4570
|
+
}
|
|
4571
|
+
) }),
|
|
4572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: run.startedAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: run.startedAt }) : "-" }),
|
|
4573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2 text-muted-foreground text-xs", children: run.completedAt ? /* @__PURE__ */ jsxRuntimeExports.jsx(RelativeTime, { date: run.completedAt }) : "-" }),
|
|
4574
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { className: "py-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
4575
|
+
LazyDropdownMenu,
|
|
4576
|
+
{
|
|
4577
|
+
env,
|
|
4578
|
+
runId: run.runId,
|
|
4579
|
+
runStatus: run.status,
|
|
4580
|
+
onSuccess: onReload
|
|
4581
|
+
}
|
|
4582
|
+
) })
|
|
4583
|
+
]
|
|
4584
|
+
},
|
|
4585
|
+
run.runId
|
|
4586
|
+
);
|
|
4587
|
+
}),
|
|
4588
|
+
isLoadingMore && /* @__PURE__ */ jsxRuntimeExports.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(TableCell, { colSpan: 7, className: "py-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center gap-2 text-sm text-muted-foreground", children: [
|
|
4589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "h-4 w-4 animate-spin" }),
|
|
4590
|
+
"Loading more runs…"
|
|
4591
|
+
] }) }) })
|
|
4592
|
+
] })
|
|
4593
|
+
] }),
|
|
4594
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: sentinelRef, "aria-hidden": true, className: "h-px" })
|
|
4595
|
+
]
|
|
4596
|
+
}
|
|
4597
|
+
) }),
|
|
4598
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mt-4 text-sm text-muted-foreground", children: [
|
|
4599
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: runs.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
4600
|
+
"Showing ",
|
|
4601
|
+
runs.length,
|
|
4602
|
+
" run",
|
|
4603
|
+
runs.length === 1 ? "" : "s",
|
|
4604
|
+
!hasMore && !loading ? " · end of list" : ""
|
|
4605
|
+
] }) }),
|
|
4606
|
+
isVercelBackend && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
4607
|
+
periodPreset.label,
|
|
4608
|
+
(planInfo == null ? void 0 : planInfo.upgradeAvailable) ? ` · plan window ${planInfo.currentLookbackDays} day${planInfo.currentLookbackDays === 1 ? "" : "s"}` : ""
|
|
3145
4609
|
] })
|
|
3146
4610
|
] }),
|
|
3147
4611
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|