dara-core 1.21.23__py3-none-any.whl → 1.21.25__py3-none-any.whl

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.
@@ -5561,6 +5561,9 @@
5561
5561
  teal: "#0790AE",
5562
5562
  orange: "#FF8F80",
5563
5563
  plum: "#BA3C8B",
5564
+ carrot: "#E48015",
5565
+ kale: "#277357",
5566
+ chestnut: "#974741",
5564
5567
  error: "#DA6087",
5565
5568
  errorHover: "#D14975",
5566
5569
  errorDown: "#C33462",
@@ -5609,6 +5612,9 @@
5609
5612
  teal: "#00849F",
5610
5613
  orange: "#DB6D5E",
5611
5614
  plum: "#AB2178",
5615
+ carrot: "#E48015",
5616
+ kale: "#277357",
5617
+ chestnut: "#974741",
5612
5618
  error: "#CA456F",
5613
5619
  errorHover: "#D1567E",
5614
5620
  errorDown: "#D7688B",
@@ -38514,23 +38520,41 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
38514
38520
  svg:not(:last-of-type) {
38515
38521
  margin-right: 0.7rem;
38516
38522
  }
38523
+ `;
38524
+ const SingleActionWrapper = styled(ActionWrapper)`
38525
+ cursor: pointer;
38526
+
38527
+ position: absolute;
38528
+ inset: 0;
38529
+
38530
+ width: 100%;
38531
+ height: 100%;
38517
38532
  `;
38518
38533
  function ActionCell(props) {
38519
38534
  if (!props.column.actions) {
38520
38535
  throw new Error("Must pass an array of actions to the column def when using the ActionCell");
38521
38536
  }
38537
+ const onClick = (e2, actionId) => {
38538
+ var _a;
38539
+ e2.stopPropagation();
38540
+ (_a = props.onAction) === null || _a === void 0 ? void 0 : _a.call(props, actionId, props.row.original);
38541
+ };
38542
+ if (props.column.actions.length === 1) {
38543
+ const action = props.column.actions[0];
38544
+ const Icon2 = action.getIcon ? action.getIcon(props.row.original) : action.icon;
38545
+ if (Icon2 === void 0) {
38546
+ return;
38547
+ }
38548
+ const label = action.getLabel ? action.getLabel(props.row.original) : action.label;
38549
+ return jsxRuntimeExports.jsx(SingleActionWrapper, { className: "table-action-cell", onClick: (e2) => onClick(e2, action.id), children: jsxRuntimeExports.jsx(Icon2, { asButton: true, title: label }, action.label) });
38550
+ }
38522
38551
  return jsxRuntimeExports.jsx(ActionWrapper, { className: "table-action-cell", children: props.column.actions.map((action) => {
38523
38552
  const Icon2 = action.getIcon ? action.getIcon(props.row.original) : action.icon;
38524
38553
  if (Icon2 === void 0) {
38525
38554
  return;
38526
38555
  }
38527
38556
  const label = action.getLabel ? action.getLabel(props.row.original) : action.label;
38528
- const onClick = (e2) => {
38529
- var _a;
38530
- e2.stopPropagation();
38531
- (_a = props.onAction) === null || _a === void 0 ? void 0 : _a.call(props, action.id, props.row.original);
38532
- };
38533
- return jsxRuntimeExports.jsx(Icon2, { asButton: true, onClick, title: label }, action.label);
38557
+ return jsxRuntimeExports.jsx(Icon2, { asButton: true, onClick: (e2) => onClick(e2, action.id), title: label }, action.label);
38534
38558
  }) });
38535
38559
  }
38536
38560
  function DatetimeCell(fmt = "yyyy-MM-dd HH:mm") {
@@ -50556,9 +50580,23 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
50556
50580
  url.searchParams.set("token", sessionToken);
50557
50581
  return new WebSocketClient(socketUrl, sessionToken, liveReload);
50558
50582
  }
50583
+ function createRouteMatches(uiMatches, definitionMap) {
50584
+ return uiMatches.filter((m) => definitionMap.has(m.id)).map((m) => {
50585
+ const routeDef = definitionMap.get(m.id);
50586
+ return {
50587
+ id: m.id,
50588
+ pathname: m.pathname,
50589
+ params: m.params,
50590
+ definition: routeDef
50591
+ };
50592
+ });
50593
+ }
50559
50594
  function isPathParamStore(store2) {
50560
50595
  return store2.__typename === "_PathParamStore";
50561
50596
  }
50597
+ function isRouteMatchStore(store2) {
50598
+ return store2.__typename === "_RouteMatchStore";
50599
+ }
50562
50600
  var ComponentType = /* @__PURE__ */ ((ComponentType2) => {
50563
50601
  ComponentType2["JS"] = "js";
50564
50602
  ComponentType2["PY"] = "py";
@@ -51752,7 +51790,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
51752
51790
  (match2, idx) => idx === pathMatches.length - 1 ? match2.pathname : match2.pathnameBase
51753
51791
  );
51754
51792
  }
51755
- function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
51793
+ function resolveTo$1(toArg, routePathnames, locationPathname, isPathRelative = false) {
51756
51794
  let to;
51757
51795
  if (typeof toArg === "string") {
51758
51796
  to = parsePath(toArg);
@@ -54289,7 +54327,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
54289
54327
  contextualMatches = matches2;
54290
54328
  activeRouteMatch = matches2[matches2.length - 1];
54291
54329
  }
54292
- let path = resolveTo(
54330
+ let path = resolveTo$1(
54293
54331
  to ? to : ".",
54294
54332
  getResolveToMatches(contextualMatches),
54295
54333
  stripBasename$1(location2.pathname, basename) || location2.pathname,
@@ -55931,7 +55969,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
55931
55969
  navigator2.go(to);
55932
55970
  return;
55933
55971
  }
55934
- let path = resolveTo(
55972
+ let path = resolveTo$1(
55935
55973
  to,
55936
55974
  JSON.parse(routePathnamesJson),
55937
55975
  locationPathname,
@@ -55977,7 +56015,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
55977
56015
  let { pathname: locationPathname } = useLocation();
55978
56016
  let routePathnamesJson = JSON.stringify(getResolveToMatches(matches2));
55979
56017
  return React__namespace.useMemo(
55980
- () => resolveTo(
56018
+ () => resolveTo$1(
55981
56019
  to,
55982
56020
  JSON.parse(routePathnamesJson),
55983
56021
  locationPathname,
@@ -56832,7 +56870,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
56832
56870
  let { matches: matches2 } = React__namespace.useContext(RouteContext);
56833
56871
  let { pathname: locationPathname } = useLocation();
56834
56872
  let navigate = useNavigate();
56835
- let path = resolveTo(
56873
+ let path = resolveTo$1(
56836
56874
  to,
56837
56875
  getResolveToMatches(matches2),
56838
56876
  locationPathname,
@@ -64149,16 +64187,18 @@ ${String(error)}`;
64149
64187
  routeDefinitions,
64150
64188
  routeObjects,
64151
64189
  routeDefMap,
64152
- defaultPath
64190
+ defaultPath,
64191
+ routeMatches
64153
64192
  }) {
64154
64193
  const value = React__namespace.useMemo(
64155
64194
  () => ({
64156
64195
  routeDefinitions,
64157
64196
  routeObjects,
64158
64197
  routeDefMap,
64159
- defaultPath
64198
+ defaultPath,
64199
+ routeMatches
64160
64200
  }),
64161
- [routeDefinitions, routeObjects, routeDefMap, defaultPath]
64201
+ [routeDefinitions, routeObjects, routeDefMap, defaultPath, routeMatches]
64162
64202
  );
64163
64203
  return /* @__PURE__ */ React__namespace.createElement(RouterContext.Provider, { value }, children);
64164
64204
  }
@@ -64181,179 +64221,19 @@ ${String(error)}`;
64181
64221
  function useSessionToken() {
64182
64222
  return React__namespace.useSyncExternalStore(onTokenChange, getSessionToken);
64183
64223
  }
64184
- function cleanSessionCache(sessionToken) {
64185
- for (const storage of [sessionStorage, localStorage]) {
64186
- const keys = Object.keys(storage);
64187
- keys.forEach((key) => {
64188
- if (key.startsWith("dara-session") && !key.startsWith(`dara-session-${sessionToken}`)) {
64189
- storage.removeItem(key);
64190
- }
64191
- });
64192
- }
64193
- }
64194
- function isJsComponent(component) {
64195
- return component.type === ComponentType.JS;
64196
- }
64197
- var isNull_1;
64198
- var hasRequiredIsNull;
64199
- function requireIsNull() {
64200
- if (hasRequiredIsNull) return isNull_1;
64201
- hasRequiredIsNull = 1;
64202
- function isNull2(value) {
64203
- return value === null;
64204
- }
64205
- isNull_1 = isNull2;
64206
- return isNull_1;
64207
- }
64208
- var isNullExports = requireIsNull();
64209
- const isNull = /* @__PURE__ */ getDefaultExportFromCjs(isNullExports);
64210
- var negate_1;
64211
- var hasRequiredNegate;
64212
- function requireNegate() {
64213
- if (hasRequiredNegate) return negate_1;
64214
- hasRequiredNegate = 1;
64215
- var FUNC_ERROR_TEXT = "Expected a function";
64216
- function negate(predicate) {
64217
- if (typeof predicate != "function") {
64218
- throw new TypeError(FUNC_ERROR_TEXT);
64219
- }
64220
- return function() {
64221
- var args = arguments;
64222
- switch (args.length) {
64223
- case 0:
64224
- return !predicate.call(this);
64225
- case 1:
64226
- return !predicate.call(this, args[0]);
64227
- case 2:
64228
- return !predicate.call(this, args[0], args[1]);
64229
- case 3:
64230
- return !predicate.call(this, args[0], args[1], args[2]);
64231
- }
64232
- return !predicate.apply(this, args);
64233
- };
64234
- }
64235
- negate_1 = negate;
64236
- return negate_1;
64237
- }
64238
- var _baseSet;
64239
- var hasRequired_baseSet;
64240
- function require_baseSet() {
64241
- if (hasRequired_baseSet) return _baseSet;
64242
- hasRequired_baseSet = 1;
64243
- var assignValue = require_assignValue(), castPath = require_castPath(), isIndex = require_isIndex(), isObject2 = requireIsObject(), toKey = require_toKey();
64244
- function baseSet(object2, path, value, customizer) {
64245
- if (!isObject2(object2)) {
64246
- return object2;
64247
- }
64248
- path = castPath(path, object2);
64249
- var index2 = -1, length = path.length, lastIndex = length - 1, nested = object2;
64250
- while (nested != null && ++index2 < length) {
64251
- var key = toKey(path[index2]), newValue = value;
64252
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
64253
- return object2;
64254
- }
64255
- if (index2 != lastIndex) {
64256
- var objValue = nested[key];
64257
- newValue = customizer ? customizer(objValue, key, nested) : void 0;
64258
- if (newValue === void 0) {
64259
- newValue = isObject2(objValue) ? objValue : isIndex(path[index2 + 1]) ? [] : {};
64260
- }
64261
- }
64262
- assignValue(nested, key, newValue);
64263
- nested = nested[key];
64264
- }
64265
- return object2;
64266
- }
64267
- _baseSet = baseSet;
64268
- return _baseSet;
64269
- }
64270
- var _basePickBy;
64271
- var hasRequired_basePickBy;
64272
- function require_basePickBy() {
64273
- if (hasRequired_basePickBy) return _basePickBy;
64274
- hasRequired_basePickBy = 1;
64275
- var baseGet = require_baseGet(), baseSet = require_baseSet(), castPath = require_castPath();
64276
- function basePickBy(object2, paths, predicate) {
64277
- var index2 = -1, length = paths.length, result = {};
64278
- while (++index2 < length) {
64279
- var path = paths[index2], value = baseGet(object2, path);
64280
- if (predicate(value, path)) {
64281
- baseSet(result, castPath(path, object2), value);
64282
- }
64283
- }
64284
- return result;
64285
- }
64286
- _basePickBy = basePickBy;
64287
- return _basePickBy;
64288
- }
64289
- var pickBy_1;
64290
- var hasRequiredPickBy;
64291
- function requirePickBy() {
64292
- if (hasRequiredPickBy) return pickBy_1;
64293
- hasRequiredPickBy = 1;
64294
- var arrayMap = require_arrayMap(), baseIteratee = require_baseIteratee(), basePickBy = require_basePickBy(), getAllKeysIn = require_getAllKeysIn();
64295
- function pickBy(object2, predicate) {
64296
- if (object2 == null) {
64297
- return {};
64224
+ const BaseRawCssInject = styled.div`
64225
+ ${(props) => props.$rawCss}
64226
+ `;
64227
+ function injectCss(component) {
64228
+ if (typeof component === "string") {
64229
+ if (component === "div") {
64230
+ return BaseRawCssInject;
64298
64231
  }
64299
- var props = arrayMap(getAllKeysIn(object2), function(prop) {
64300
- return [prop];
64301
- });
64302
- predicate = baseIteratee(predicate);
64303
- return basePickBy(object2, props, function(value, path) {
64304
- return predicate(value, path[0]);
64305
- });
64306
- }
64307
- pickBy_1 = pickBy;
64308
- return pickBy_1;
64309
- }
64310
- var omitBy_1;
64311
- var hasRequiredOmitBy;
64312
- function requireOmitBy() {
64313
- if (hasRequiredOmitBy) return omitBy_1;
64314
- hasRequiredOmitBy = 1;
64315
- var baseIteratee = require_baseIteratee(), negate = requireNegate(), pickBy = requirePickBy();
64316
- function omitBy2(object2, predicate) {
64317
- return pickBy(object2, negate(baseIteratee(predicate)));
64318
- }
64319
- omitBy_1 = omitBy2;
64320
- return omitBy_1;
64321
- }
64322
- var omitByExports = requireOmitBy();
64323
- const omitBy = /* @__PURE__ */ getDefaultExportFromCjs(omitByExports);
64324
- function isTheme(configTheme) {
64325
- return typeof configTheme !== "string";
64326
- }
64327
- function resolveTheme(configTheme, baseTheme) {
64328
- if (!configTheme || configTheme === "light") {
64329
- return theme;
64330
- }
64331
- if (configTheme === "dark") {
64332
- return darkTheme;
64333
- }
64334
- if (isTheme(configTheme)) {
64335
- const original = baseTheme === "dark" ? darkTheme : theme;
64336
- return {
64337
- // Here we spread both first to pick up anything missing from the default theme and anything new/extra in
64338
- // the new theme.
64339
- ...original,
64340
- ...omitBy(configTheme, isNull),
64341
- colors: {
64342
- ...original.colors,
64343
- ...omitBy(configTheme.colors, isNull)
64344
- },
64345
- font: {
64346
- ...original.font,
64347
- ...omitBy(configTheme.font, isNull)
64348
- },
64349
- shadow: {
64350
- ...original.shadow,
64351
- ...omitBy(configTheme.shadow, isNull)
64352
- }
64353
- };
64232
+ return BaseRawCssInject.withComponent(component);
64354
64233
  }
64355
- console.warn("No valid theme was found. Defaulting to light theme.");
64356
- return theme;
64234
+ return styled(component)`
64235
+ ${(props) => props.$rawCss}
64236
+ `;
64357
64237
  }
64358
64238
  function useDeferLoadable(loadable, suspendOverride) {
64359
64239
  const { suspend: ctxSuspend } = useFallbackCtx();
@@ -64392,64 +64272,6 @@ ${String(error)}`;
64392
64272
  }
64393
64273
  return availableState;
64394
64274
  }
64395
- function useInterval(callback, delay2) {
64396
- React$1.useEffect(
64397
- () => {
64398
- if (delay2) {
64399
- const id = setInterval(callback, delay2 * 1e3);
64400
- return () => clearInterval(id);
64401
- }
64402
- },
64403
- useDeepCompare([delay2, callback])
64404
- );
64405
- }
64406
- function usePrevious$1(value, initialValue) {
64407
- const ref = React$1.useRef(initialValue);
64408
- React$1.useEffect(() => {
64409
- ref.current = value;
64410
- });
64411
- return ref.current;
64412
- }
64413
- function useWindowTitle(pageTitle, enabled = true) {
64414
- const config2 = useConfig();
64415
- React$1.useEffect(() => {
64416
- if (!enabled) {
64417
- return;
64418
- }
64419
- if (!pageTitle) {
64420
- document.title = config2.title;
64421
- return;
64422
- }
64423
- document.title = `${config2.title} - ${pageTitle}`;
64424
- }, [config2, config2.title, pageTitle, enabled]);
64425
- }
64426
- const BaseRawCssInject = styled.div`
64427
- ${(props) => props.$rawCss}
64428
- `;
64429
- function injectCss(component) {
64430
- if (typeof component === "string") {
64431
- if (component === "div") {
64432
- return BaseRawCssInject;
64433
- }
64434
- return BaseRawCssInject.withComponent(component);
64435
- }
64436
- return styled(component)`
64437
- ${(props) => props.$rawCss}
64438
- `;
64439
- }
64440
- const Icon = injectCss("i");
64441
- function getIcon(icon) {
64442
- let iconClasses = icon;
64443
- if (typeof icon === "string" && !icon.includes("fa-")) {
64444
- const inferredIconName = icon.replace(/([A-Z])/g, " $1").trim().toLowerCase().split(" ").join("-");
64445
- iconClasses = `fa-solid fa-${inferredIconName}`;
64446
- console.warn(
64447
- `Invalid fontawesome class string "${icon}" provided to getIcon(). This behaviour is deprecated and will be removed in the next version, please use "dara_core.css.get_icon" method.
64448
- Inferred class string: "${iconClasses}."`
64449
- );
64450
- }
64451
- return (props) => /* @__PURE__ */ React.createElement(Icon, { ...props, className: `${String(props.className ?? "")} ${iconClasses}` });
64452
- }
64453
64275
  class EventBus {
64454
64276
  #events$ = new Subject();
64455
64277
  #parentBus = null;
@@ -69296,14 +69118,14 @@ Inferred class string: "${iconClasses}."`
69296
69118
  useEffect: useEffect$2,
69297
69119
  useRef: useRef$2
69298
69120
  } = React$1;
69299
- function usePrevious(value) {
69121
+ function usePrevious$1(value) {
69300
69122
  const ref = useRef$2();
69301
69123
  useEffect$2(() => {
69302
69124
  ref.current = value;
69303
69125
  });
69304
69126
  return ref.current;
69305
69127
  }
69306
- var Recoil_usePrevious = usePrevious;
69128
+ var Recoil_usePrevious = usePrevious$1;
69307
69129
  const {
69308
69130
  DefaultValue: DefaultValue$2
69309
69131
  } = Recoil_index;
@@ -69549,6 +69371,38 @@ Inferred class string: "${iconClasses}."`
69549
69371
  );
69550
69372
  return /* @__PURE__ */ React$1.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "ServerVariable" }, children);
69551
69373
  }
69374
+ var _baseSet;
69375
+ var hasRequired_baseSet;
69376
+ function require_baseSet() {
69377
+ if (hasRequired_baseSet) return _baseSet;
69378
+ hasRequired_baseSet = 1;
69379
+ var assignValue = require_assignValue(), castPath = require_castPath(), isIndex = require_isIndex(), isObject2 = requireIsObject(), toKey = require_toKey();
69380
+ function baseSet(object2, path, value, customizer) {
69381
+ if (!isObject2(object2)) {
69382
+ return object2;
69383
+ }
69384
+ path = castPath(path, object2);
69385
+ var index2 = -1, length = path.length, lastIndex = length - 1, nested = object2;
69386
+ while (nested != null && ++index2 < length) {
69387
+ var key = toKey(path[index2]), newValue = value;
69388
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
69389
+ return object2;
69390
+ }
69391
+ if (index2 != lastIndex) {
69392
+ var objValue = nested[key];
69393
+ newValue = customizer ? customizer(objValue, key, nested) : void 0;
69394
+ if (newValue === void 0) {
69395
+ newValue = isObject2(objValue) ? objValue : isIndex(path[index2 + 1]) ? [] : {};
69396
+ }
69397
+ }
69398
+ assignValue(nested, key, newValue);
69399
+ nested = nested[key];
69400
+ }
69401
+ return object2;
69402
+ }
69403
+ _baseSet = baseSet;
69404
+ return _baseSet;
69405
+ }
69552
69406
  var set_1;
69553
69407
  var hasRequiredSet;
69554
69408
  function requireSet() {
@@ -69563,6 +69417,17 @@ Inferred class string: "${iconClasses}."`
69563
69417
  }
69564
69418
  var setExports = requireSet();
69565
69419
  const set = /* @__PURE__ */ getDefaultExportFromCjs(setExports);
69420
+ function useInterval(callback, delay2) {
69421
+ React$1.useEffect(
69422
+ () => {
69423
+ if (delay2) {
69424
+ const id = setInterval(callback, delay2 * 1e3);
69425
+ return () => clearInterval(id);
69426
+ }
69427
+ },
69428
+ useDeepCompare([delay2, callback])
69429
+ );
69430
+ }
69566
69431
  class DeferredImpl {
69567
69432
  #resolve;
69568
69433
  #reject;
@@ -70926,376 +70791,222 @@ Inferred class string: "${iconClasses}."`
70926
70791
  escapePathComponent,
70927
70792
  unescapePathComponent
70928
70793
  });
70929
- const STORE_EXTRAS_MAP = /* @__PURE__ */ new Map();
70930
- const STORE_VARIABLE_MAP = /* @__PURE__ */ new Map();
70931
- const STORE_SEQUENCE_MAP = /* @__PURE__ */ new Map();
70932
- const STORE_LATEST_VALUE_MAP = /* @__PURE__ */ new Map();
70933
- function BackendStoreSync({ children }) {
70934
- const { client: client2 } = React__namespace.useContext(websocketCtx);
70935
- const getStoreValue = React__namespace.useCallback(async (itemKey) => {
70936
- const serializableExtras = STORE_EXTRAS_MAP.get(itemKey);
70937
- const response = await request(`/api/core/store/${itemKey}`, {}, serializableExtras?.extras ?? {});
70938
- await handleAuthErrors(response, true);
70939
- await validateResponse(response, `Failed to fetch the store value for key: ${itemKey}`);
70940
- const { value, sequence_number } = await response.json();
70941
- STORE_LATEST_VALUE_MAP.set(itemKey, value);
70942
- STORE_SEQUENCE_MAP.set(itemKey, sequence_number);
70943
- return value;
70944
- }, []);
70945
- const syncStoreValues = React__namespace.useCallback(
70946
- async ({ diff }) => {
70947
- const extrasMap = /* @__PURE__ */ new Map();
70948
- Array.from(diff.entries()).filter(
70949
- ([itemKey, value]) => !STORE_LATEST_VALUE_MAP.has(itemKey) || STORE_LATEST_VALUE_MAP.get(itemKey) !== value
70950
- ).forEach(([itemKey, value]) => {
70951
- STORE_LATEST_VALUE_MAP.set(itemKey, value);
70952
- const extras = STORE_EXTRAS_MAP.get(itemKey);
70953
- if (!extrasMap.has(extras)) {
70954
- extrasMap.set(extras, {});
70955
- }
70956
- extrasMap.get(extras)[itemKey] = value;
70957
- });
70958
- async function sendRequest(serializableExtras, storeDiff) {
70959
- const response = await request(
70960
- `/api/core/store`,
70961
- {
70962
- body: JSON.stringify({
70963
- values: storeDiff,
70964
- ws_channel: await client2.getChannel()
70965
- }),
70966
- method: "POST"
70967
- },
70968
- serializableExtras.extras
70969
- );
70970
- await handleAuthErrors(response, true);
70971
- await validateResponse(response, `Failed to sync the store values`);
70972
- }
70973
- await Promise.allSettled(
70974
- Array.from(extrasMap.entries()).map(
70975
- ([serializableExtras, storeDiff]) => sendRequest(serializableExtras, storeDiff)
70976
- )
70977
- );
70978
- },
70979
- [client2]
70980
- );
70981
- const applyPatchesToAtoms = Recoil_index_31(
70982
- ({ snapshot, set: set2 }) => async (storeUid, patches, sequenceNumber) => {
70983
- const expectedSequence = STORE_SEQUENCE_MAP.get(storeUid) || 0;
70984
- if (sequenceNumber !== expectedSequence + 1) {
70985
- console.warn(
70986
- `Sequence number mismatch for store ${storeUid}. Expected: ${expectedSequence + 1}, Got: ${sequenceNumber}. Rejecting patch.`
70987
- );
70988
- return;
70989
- }
70990
- STORE_SEQUENCE_MAP.set(storeUid, sequenceNumber);
70991
- const variableUids = STORE_VARIABLE_MAP.get(storeUid);
70992
- if (!variableUids) {
70993
- return;
70994
- }
70995
- const atomsToUpdate = [];
70996
- for (const variableUid of variableUids) {
70997
- const directAtom = atomRegistry.get(variableUid);
70998
- if (directAtom) {
70999
- atomsToUpdate.push({ atom: directAtom, variableUid });
71000
- continue;
71001
- }
71002
- const atomFamily2 = atomFamilyRegistry.get(variableUid);
71003
- if (atomFamily2) {
71004
- const familyMembers = atomFamilyMembersRegistry.get(atomFamily2);
71005
- if (familyMembers) {
71006
- for (const [, atomInstance] of familyMembers) {
71007
- atomsToUpdate.push({ atom: atomInstance, variableUid });
71008
- }
71009
- }
71010
- }
71011
- }
71012
- const currentValues = await Promise.all(
71013
- atomsToUpdate.map(async ({ atom: atom2, variableUid }) => {
71014
- try {
71015
- return {
71016
- atom: atom2,
71017
- variableUid,
71018
- currentValue: await snapshot.getPromise(atom2),
71019
- error: null
71020
- };
71021
- } catch (error) {
71022
- return {
71023
- atom: atom2,
71024
- variableUid,
71025
- currentValue: null,
71026
- error
71027
- };
71028
- }
71029
- })
71030
- );
71031
- const applyPatchToValue = (currentValue, variableUid) => {
71032
- try {
71033
- return applyPatch(currentValue, patches, false, false).newDocument;
71034
- } catch (error) {
71035
- console.warn(`Failed to apply patch to atom ${variableUid}:`, error);
71036
- return currentValue;
71037
- }
71038
- };
71039
- currentValues.forEach(({ atom: atom2, variableUid, currentValue, error }) => {
71040
- if (error) {
71041
- console.warn(`Failed to read current value for atom ${variableUid}:`, error);
71042
- return;
71043
- }
71044
- const patchedValue = applyPatchToValue(currentValue, variableUid);
71045
- set2(atom2, patchedValue);
71046
- STORE_LATEST_VALUE_MAP.set(storeUid, patchedValue);
71047
- });
71048
- },
71049
- []
71050
- );
71051
- const listenToStoreChanges = React__namespace.useCallback(
71052
- ({ updateItem }) => {
71053
- if (!client2) {
71054
- return;
70794
+ function cleanSessionCache(sessionToken) {
70795
+ for (const storage of [sessionStorage, localStorage]) {
70796
+ const keys = Object.keys(storage);
70797
+ keys.forEach((key) => {
70798
+ if (key.startsWith("dara-session") && !key.startsWith(`dara-session-${sessionToken}`)) {
70799
+ storage.removeItem(key);
71055
70800
  }
71056
- const valueSub = client2.backendStoreMessages$().subscribe((message) => {
71057
- STORE_SEQUENCE_MAP.set(message.store_uid, message.sequence_number);
71058
- updateItem(message.store_uid, message.value);
71059
- STORE_LATEST_VALUE_MAP.set(message.store_uid, message.value);
71060
- });
71061
- const patchSub = client2.backendStorePatchMessages$().subscribe((message) => {
71062
- applyPatchesToAtoms(message.store_uid, message.patches, message.sequence_number);
71063
- });
71064
- return () => {
71065
- valueSub.unsubscribe();
71066
- patchSub.unsubscribe();
71067
- };
71068
- },
71069
- [client2, applyPatchesToAtoms]
71070
- );
71071
- return /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "BackendStore", write: syncStoreValues }, children);
70801
+ });
70802
+ }
71072
70803
  }
71073
- function backendStoreEffect(variable, requestExtras) {
71074
- STORE_EXTRAS_MAP.set(variable.store.uid, requestExtras);
71075
- if (!STORE_VARIABLE_MAP.has(variable.store.uid)) {
71076
- STORE_VARIABLE_MAP.set(variable.store.uid, /* @__PURE__ */ new Set());
70804
+ function isJsComponent(component) {
70805
+ return component.type === ComponentType.JS;
70806
+ }
70807
+ var isNull_1;
70808
+ var hasRequiredIsNull;
70809
+ function requireIsNull() {
70810
+ if (hasRequiredIsNull) return isNull_1;
70811
+ hasRequiredIsNull = 1;
70812
+ function isNull2(value) {
70813
+ return value === null;
71077
70814
  }
71078
- STORE_VARIABLE_MAP.get(variable.store.uid).add(variable.uid);
71079
- return RecoilSync_index_2({
71080
- /** Use store uid as the unique identifier */
71081
- itemKey: variable.store.uid,
71082
- refine: Refine_index_6(),
71083
- storeKey: "BackendStore",
71084
- write({ write: write2 }, newValue) {
71085
- if (variable.store.readonly) {
71086
- return;
70815
+ isNull_1 = isNull2;
70816
+ return isNull_1;
70817
+ }
70818
+ var isNullExports = requireIsNull();
70819
+ const isNull = /* @__PURE__ */ getDefaultExportFromCjs(isNullExports);
70820
+ var negate_1;
70821
+ var hasRequiredNegate;
70822
+ function requireNegate() {
70823
+ if (hasRequiredNegate) return negate_1;
70824
+ hasRequiredNegate = 1;
70825
+ var FUNC_ERROR_TEXT = "Expected a function";
70826
+ function negate(predicate) {
70827
+ if (typeof predicate != "function") {
70828
+ throw new TypeError(FUNC_ERROR_TEXT);
70829
+ }
70830
+ return function() {
70831
+ var args = arguments;
70832
+ switch (args.length) {
70833
+ case 0:
70834
+ return !predicate.call(this);
70835
+ case 1:
70836
+ return !predicate.call(this, args[0]);
70837
+ case 2:
70838
+ return !predicate.call(this, args[0], args[1]);
70839
+ case 3:
70840
+ return !predicate.call(this, args[0], args[1], args[2]);
71087
70841
  }
71088
- if (newValue instanceof Recoil_index_1) {
71089
- return;
70842
+ return !predicate.apply(this, args);
70843
+ };
70844
+ }
70845
+ negate_1 = negate;
70846
+ return negate_1;
70847
+ }
70848
+ var _basePickBy;
70849
+ var hasRequired_basePickBy;
70850
+ function require_basePickBy() {
70851
+ if (hasRequired_basePickBy) return _basePickBy;
70852
+ hasRequired_basePickBy = 1;
70853
+ var baseGet = require_baseGet(), baseSet = require_baseSet(), castPath = require_castPath();
70854
+ function basePickBy(object2, paths, predicate) {
70855
+ var index2 = -1, length = paths.length, result = {};
70856
+ while (++index2 < length) {
70857
+ var path = paths[index2], value = baseGet(object2, path);
70858
+ if (predicate(value, path)) {
70859
+ baseSet(result, castPath(path, object2), value);
71090
70860
  }
71091
- write2(variable.store.uid, newValue);
71092
70861
  }
71093
- });
71094
- }
71095
- function getSessionKey(uid2) {
71096
- if (isEmbedded()) {
71097
- return `dara-session-${window.frameElement.dataset.daraPageId}-var-${uid2}`;
70862
+ return result;
71098
70863
  }
71099
- return `dara-session-${getSessionToken()}-var-${uid2}`;
70864
+ _basePickBy = basePickBy;
70865
+ return _basePickBy;
71100
70866
  }
71101
- function BrowserStoreSync({ children }) {
71102
- const getStoreValue = React__namespace.useCallback((itemKey) => {
71103
- const key = getSessionKey(itemKey);
71104
- return JSON.parse(localStorage.getItem(key) ?? "null");
71105
- }, []);
71106
- const syncStoreValues = React__namespace.useCallback(({ diff }) => {
71107
- for (const [itemKey, value] of diff.entries()) {
71108
- const key = getSessionKey(itemKey);
71109
- localStorage.setItem(key, JSON.stringify(value));
70867
+ var pickBy_1;
70868
+ var hasRequiredPickBy;
70869
+ function requirePickBy() {
70870
+ if (hasRequiredPickBy) return pickBy_1;
70871
+ hasRequiredPickBy = 1;
70872
+ var arrayMap = require_arrayMap(), baseIteratee = require_baseIteratee(), basePickBy = require_basePickBy(), getAllKeysIn = require_getAllKeysIn();
70873
+ function pickBy(object2, predicate) {
70874
+ if (object2 == null) {
70875
+ return {};
71110
70876
  }
71111
- }, []);
71112
- const listenToStoreChanges = React__namespace.useCallback(({ updateItem }) => {
71113
- const listener2 = (e2) => {
71114
- if (e2.storageArea === localStorage) {
71115
- if (e2.key) {
71116
- const match2 = e2.key.match(/^dara-session-(.*)-var-(.*)$/);
71117
- if (match2) {
71118
- const [, sessionToken, uid2] = match2;
71119
- if (sessionToken === getSessionToken()) {
71120
- updateItem(uid2, JSON.parse(e2.newValue ?? "null"));
71121
- }
71122
- }
71123
- }
70877
+ var props = arrayMap(getAllKeysIn(object2), function(prop) {
70878
+ return [prop];
70879
+ });
70880
+ predicate = baseIteratee(predicate);
70881
+ return basePickBy(object2, props, function(value, path) {
70882
+ return predicate(value, path[0]);
70883
+ });
70884
+ }
70885
+ pickBy_1 = pickBy;
70886
+ return pickBy_1;
70887
+ }
70888
+ var omitBy_1;
70889
+ var hasRequiredOmitBy;
70890
+ function requireOmitBy() {
70891
+ if (hasRequiredOmitBy) return omitBy_1;
70892
+ hasRequiredOmitBy = 1;
70893
+ var baseIteratee = require_baseIteratee(), negate = requireNegate(), pickBy = requirePickBy();
70894
+ function omitBy2(object2, predicate) {
70895
+ return pickBy(object2, negate(baseIteratee(predicate)));
70896
+ }
70897
+ omitBy_1 = omitBy2;
70898
+ return omitBy_1;
70899
+ }
70900
+ var omitByExports = requireOmitBy();
70901
+ const omitBy = /* @__PURE__ */ getDefaultExportFromCjs(omitByExports);
70902
+ function isTheme(configTheme) {
70903
+ return typeof configTheme !== "string";
70904
+ }
70905
+ function resolveTheme(configTheme, baseTheme) {
70906
+ if (!configTheme || configTheme === "light") {
70907
+ return theme;
70908
+ }
70909
+ if (configTheme === "dark") {
70910
+ return darkTheme;
70911
+ }
70912
+ if (isTheme(configTheme)) {
70913
+ const original = baseTheme === "dark" ? darkTheme : theme;
70914
+ return {
70915
+ // Here we spread both first to pick up anything missing from the default theme and anything new/extra in
70916
+ // the new theme.
70917
+ ...original,
70918
+ ...omitBy(configTheme, isNull),
70919
+ colors: {
70920
+ ...original.colors,
70921
+ ...omitBy(configTheme.colors, isNull)
70922
+ },
70923
+ font: {
70924
+ ...original.font,
70925
+ ...omitBy(configTheme.font, isNull)
70926
+ },
70927
+ shadow: {
70928
+ ...original.shadow,
70929
+ ...omitBy(configTheme.shadow, isNull)
71124
70930
  }
71125
70931
  };
71126
- window.addEventListener("storage", listener2);
71127
- return () => {
71128
- window.removeEventListener("storage", listener2);
71129
- };
71130
- }, []);
71131
- return /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "BrowserStore", write: syncStoreValues }, children);
70932
+ }
70933
+ console.warn("No valid theme was found. Defaulting to light theme.");
70934
+ return theme;
71132
70935
  }
71133
- function PathParamSync({ children }) {
71134
- const navigate = useNavigate();
71135
- const location2 = useLocation();
71136
- const locationRef = useLatestRef$3(location2);
71137
- const matches2 = useMatches();
71138
- const matchesRef = useLatestRef$3(matches2);
71139
- const params = useParams();
71140
- const paramsRef = React__namespace.useRef(params);
71141
- const locationSubscribers = React__namespace.useRef([]);
71142
- React__namespace.useLayoutEffect(() => {
71143
- if (isEqual$4(paramsRef.current, params)) {
70936
+ function usePrevious(value, initialValue) {
70937
+ const ref = React$1.useRef(initialValue);
70938
+ React$1.useEffect(() => {
70939
+ ref.current = value;
70940
+ });
70941
+ return ref.current;
70942
+ }
70943
+ function useWindowTitle(pageTitle, enabled = true) {
70944
+ const config2 = useConfig();
70945
+ React$1.useEffect(() => {
70946
+ if (!enabled) {
71144
70947
  return;
71145
70948
  }
71146
- paramsRef.current = params;
70949
+ if (!pageTitle) {
70950
+ document.title = config2.title;
70951
+ return;
70952
+ }
70953
+ document.title = `${config2.title} - ${pageTitle}`;
70954
+ }, [config2, config2.title, pageTitle, enabled]);
70955
+ }
70956
+ const Icon = injectCss("i");
70957
+ function getIcon(icon) {
70958
+ let iconClasses = icon;
70959
+ if (typeof icon === "string" && !icon.includes("fa-")) {
70960
+ const inferredIconName = icon.replace(/([A-Z])/g, " $1").trim().toLowerCase().split(" ").join("-");
70961
+ iconClasses = `fa-solid fa-${inferredIconName}`;
70962
+ console.warn(
70963
+ `Invalid fontawesome class string "${icon}" provided to getIcon(). This behaviour is deprecated and will be removed in the next version, please use "dara_core.css.get_icon" method.
70964
+ Inferred class string: "${iconClasses}."`
70965
+ );
70966
+ }
70967
+ return (props) => /* @__PURE__ */ React.createElement(Icon, { ...props, className: `${String(props.className ?? "")} ${iconClasses}` });
70968
+ }
70969
+ function useUrlSync() {
70970
+ const location2 = useLocation();
70971
+ const locationSubscribers = React$1.useRef([]);
70972
+ React$1.useEffect(() => {
71147
70973
  for (const subscriber of locationSubscribers.current) {
71148
- subscriber(params);
70974
+ subscriber();
71149
70975
  }
71150
- }, [paramsRef, params]);
71151
- const getStoreValue = React__namespace.useCallback(
71152
- (paramName) => {
71153
- return paramsRef.current[paramName] ?? null;
71154
- },
71155
- [paramsRef]
71156
- );
71157
- const writeStoreValue = React__namespace.useCallback(
71158
- async ({ diff }) => {
71159
- const newParams = mapValues({ ...paramsRef.current, ...Object.fromEntries(diff) }, (v) => String(v));
71160
- const loaderData = matchesRef.current.at(-1).loaderData;
71161
- const data2 = loaderData.data instanceof Promise ? await loaderData.data : loaderData.data;
71162
- const fullPathname = data2.route_definition.full_path;
71163
- navigate({
71164
- pathname: generatePath(fullPathname, newParams),
71165
- // preserve current search
71166
- search: locationRef.current.search
71167
- });
71168
- },
71169
- [matchesRef, navigate, paramsRef, locationRef]
71170
- );
71171
- const listenToStoreChanges = React__namespace.useCallback(({ updateItems }) => {
71172
- function handleUpdate(newParams) {
71173
- updateItems(new Map(Object.entries(newParams)));
70976
+ }, [location2]);
70977
+ const urlSerializer = React$1.useCallback((val) => {
70978
+ if (val === void 0 || val === null) {
70979
+ return "";
71174
70980
  }
71175
- locationSubscribers.current.push(handleUpdate);
70981
+ if (["string", "number", "boolean"].includes(typeof val)) {
70982
+ return String(val);
70983
+ }
70984
+ return JSON.stringify(val);
70985
+ }, []);
70986
+ const urlDeserializer = React$1.useCallback((val) => {
70987
+ if (val === "") {
70988
+ return void 0;
70989
+ }
70990
+ try {
70991
+ return JSON.parse(val);
70992
+ } catch {
70993
+ return val;
70994
+ }
70995
+ }, []);
70996
+ const listenChangeURL = React$1.useCallback((handler) => {
70997
+ locationSubscribers.current.push(handler);
71176
70998
  return () => {
71177
- locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handleUpdate);
70999
+ locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handler);
71178
71000
  };
71179
71001
  }, []);
71180
- return /* @__PURE__ */ React__namespace.createElement(
71181
- RecoilSync_index_1,
71182
- {
71183
- listen: listenToStoreChanges,
71184
- read: getStoreValue,
71185
- write: writeStoreValue,
71186
- storeKey: "_PathParamStore"
71187
- },
71188
- children
71189
- );
71190
- }
71191
- function localStorageEffect(variable, extrasSerializable, wsClient, taskContext) {
71192
- let firstRun = false;
71193
- return RecoilSync_index_2({
71194
- itemKey: variable.uid,
71195
- read: ({ read: read2 }) => {
71196
- const readValue = read2(variable.uid);
71197
- if (!firstRun) {
71198
- firstRun = true;
71199
- if (!readValue) {
71200
- const isDefaultDerived = isDerivedVariable(variable.default);
71201
- return isDefaultDerived ? getOrRegisterDerivedVariable(
71202
- variable.default,
71203
- wsClient,
71204
- taskContext,
71205
- extrasSerializable.extras
71206
- ) : variable.default;
71207
- }
71208
- }
71209
- return readValue;
71002
+ return {
71003
+ browserInterface: {
71004
+ listenChangeURL
71210
71005
  },
71211
- refine: Refine_index_6(),
71212
- storeKey: "BrowserStore"
71213
- });
71214
- }
71215
- function urlEffect(variable) {
71216
- return RecoilSync_index_6({
71217
- history: "push",
71218
- itemKey: variable.store.query,
71219
- refine: Refine_index_6()
71220
- });
71221
- }
71222
- function pathParamEffect(variable) {
71223
- const itemKey = variable.store.param_name;
71224
- const effect2 = RecoilSync_index_2({
71225
- itemKey,
71226
- refine: Refine_index_6(),
71227
- storeKey: "_PathParamStore"
71228
- });
71229
- return (effectParams) => {
71230
- const cleanup = effect2(effectParams);
71231
- effectParams.setSelf(effectParams.getLoadable(effectParams.node).valueOrThrow());
71232
- return () => {
71233
- cleanup?.();
71234
- };
71235
- };
71236
- }
71237
- const STORES = {
71238
- BackendStore: {
71239
- effect: backendStoreEffect
71240
- },
71241
- BrowserStore: {
71242
- effect: localStorageEffect
71243
- },
71244
- QueryParamStore: {
71245
- effect: urlEffect
71246
- },
71247
- _PathParamStore: {
71248
- effect: pathParamEffect
71249
- }
71250
- };
71251
- function getEffect(variable) {
71252
- const storeName = variable.store?.__typename;
71253
- if (!storeName || !(storeName in STORES)) {
71254
- return null;
71255
- }
71256
- return STORES[storeName]?.effect ?? null;
71257
- }
71258
- function StoreProviders({ children }) {
71259
- return /* @__PURE__ */ React__namespace.createElement(BackendStoreSync, null, /* @__PURE__ */ React__namespace.createElement(BrowserStoreSync, null, children));
71260
- }
71261
- function isConditionTrue(operator, value, other) {
71262
- if (operator === ConditionOperator.EQUAL) {
71263
- return value === other;
71264
- }
71265
- if (operator === ConditionOperator.NOT_EQUAL) {
71266
- return value !== other;
71267
- }
71268
- if (operator === ConditionOperator.GREATER_EQUAL) {
71269
- return value >= other;
71270
- }
71271
- if (operator === ConditionOperator.GREATER_THAN) {
71272
- return value > other;
71273
- }
71274
- if (operator === ConditionOperator.LESS_EQUAL) {
71275
- return value <= other;
71276
- }
71277
- if (operator === ConditionOperator.LESS_THAN) {
71278
- return value < other;
71279
- }
71280
- if (operator === ConditionOperator.TRUTHY) {
71281
- return !!value;
71282
- }
71283
- throw new Error(`Unexpected operator ${String(operator)} passed to conditional (If) component`);
71284
- }
71285
- function useConditionOrVariable(arg, opts = {}) {
71286
- if (isCondition(arg)) {
71287
- const value = useVariable(arg.variable, opts)[0];
71288
- const other = useVariable(arg.other, opts)[0];
71289
- return isConditionTrue(arg.operator, value, other);
71290
- }
71291
- return useVariable(arg, opts)[0];
71292
- }
71293
- function useSwitchVariable(variable) {
71294
- const value = useConditionOrVariable(variable.value, { suspend: false });
71295
- const [valueMap] = useVariable(variable.value_map, { suspend: false });
71296
- const [defaultValue] = useVariable(variable.default, { suspend: false });
71297
- const lookupKey = String(value);
71298
- return valueMap[lookupKey] ?? defaultValue;
71006
+ deserialize: urlDeserializer,
71007
+ location: { part: "queryParams" },
71008
+ serialize: urlSerializer
71009
+ };
71299
71010
  }
71300
71011
  const COLUMN_PREFIX_REGEX = /__(?:col|index)__\d+__/;
71301
71012
  function combineFilters(combinator, queries) {
@@ -71562,733 +71273,258 @@ Inferred class string: "${iconClasses}."`
71562
71273
  const response = result.value;
71563
71274
  return response.data;
71564
71275
  }
71565
- function warnUpdateOnDerivedState() {
71566
- console.warn("You tried to call update on variable with derived state, this is a noop and will be ignored.");
71276
+ function useRefreshSelector() {
71277
+ return Recoil_index_31(({ refresh }) => {
71278
+ return (key, extras) => {
71279
+ const family = selectorFamilyRegistry.get(key);
71280
+ if (family) {
71281
+ const selector2 = selectorFamilyMembersRegistry.get(family)?.get(extras);
71282
+ if (selector2) {
71283
+ refresh(selector2);
71284
+ }
71285
+ }
71286
+ };
71287
+ });
71567
71288
  }
71568
- function useVariable(variable, opts = { serverVariable: "disallow" }) {
71289
+ function useVariableState() {
71569
71290
  const extras = useRequestExtras();
71570
- const { client: wsClient } = React$1.useContext(websocketCtx);
71571
- const taskContext = useTaskContext();
71572
- const variablesContext = React$1.useContext(variablesCtx);
71573
- const bus = useEventBus();
71574
- if (!isVariable(variable)) {
71575
- const [state, setState] = React$1.useState(variable);
71576
- const [prevVariable, setPrevVariable] = React$1.useState(variable);
71577
- if (!isEqual$4(variable, prevVariable)) {
71578
- setState(variable);
71579
- setPrevVariable(variable);
71580
- }
71581
- return [state, setState];
71582
- }
71583
- variablesContext?.variables.current.add(variable.uid);
71584
- React$1.useEffect(() => {
71585
- return () => {
71586
- variablesContext?.variables.current.delete(variable.uid);
71291
+ const { client: client2 } = React$1.useContext(websocketCtx);
71292
+ const taskCtx = useTaskContext();
71293
+ return Recoil_index_31(({ snapshot }) => {
71294
+ return async (variable) => {
71295
+ if (!isRegistered(variable)) {
71296
+ return "__NOT_REGISTERED__";
71297
+ }
71298
+ const resolvedVariable = await resolveVariable(
71299
+ variable,
71300
+ client2,
71301
+ taskCtx,
71302
+ extras,
71303
+ (v) => snapshot.getLoadable(v).toPromise()
71304
+ );
71305
+ return resolvedVariable;
71587
71306
  };
71588
71307
  }, []);
71589
- if (isDerivedVariable(variable)) {
71590
- const selector2 = useDerivedVariable(variable, wsClient, taskContext, extras);
71591
- const selectorLoadable = Recoil_index_28(selector2);
71592
- React$1.useEffect(() => {
71593
- if (selectorLoadable.state !== "loading") {
71594
- bus.publish("DERIVED_VARIABLE_LOADED", { variable, value: selectorLoadable.contents });
71595
- }
71596
- }, [selectorLoadable]);
71597
- const deferred22 = useDeferLoadable(selectorLoadable, opts.suspend);
71598
- return [deferred22, warnUpdateOnDerivedState];
71599
- }
71600
- if (isSwitchVariable(variable)) {
71601
- return [useSwitchVariable(variable), warnUpdateOnDerivedState];
71602
- }
71603
- if (isStateVariable(variable)) {
71604
- const parentSelector = useDerivedVariable(variable.parent_variable, wsClient, taskContext, extras);
71605
- const parentLoadable = Recoil_index_28(parentSelector);
71606
- let stateValue;
71607
- switch (variable.property_name) {
71608
- case "loading":
71609
- stateValue = parentLoadable.state === "loading";
71610
- break;
71611
- case "error":
71612
- stateValue = parentLoadable.state === "hasError";
71613
- break;
71614
- case "hasValue":
71615
- stateValue = parentLoadable.state === "hasValue";
71616
- break;
71617
- default:
71618
- stateValue = false;
71308
+ }
71309
+ var _arrayAggregator;
71310
+ var hasRequired_arrayAggregator;
71311
+ function require_arrayAggregator() {
71312
+ if (hasRequired_arrayAggregator) return _arrayAggregator;
71313
+ hasRequired_arrayAggregator = 1;
71314
+ function arrayAggregator(array2, setter, iteratee, accumulator) {
71315
+ var index2 = -1, length = array2 == null ? 0 : array2.length;
71316
+ while (++index2 < length) {
71317
+ var value = array2[index2];
71318
+ setter(accumulator, value, iteratee(value), array2);
71619
71319
  }
71620
- return [stateValue, warnUpdateOnDerivedState];
71320
+ return accumulator;
71621
71321
  }
71622
- if (isServerVariable(variable)) {
71623
- if (opts.serverVariable === "disallow") {
71624
- throw new UserError("ServerVariable cannot be directly consumed by this component");
71625
- }
71626
- const atom2 = React$1.useMemo(() => getOrRegisterServerVariable(variable, extras), [variable, extras]);
71627
- const [seqNumber] = Recoil_index_22(atom2);
71628
- const fetcher = useTabularVariable(variable);
71629
- const { data: data2 } = reactQuery.useSuspenseQuery({
71630
- // use the seq number as a dependency to refetch on changes
71631
- queryKey: ["use-variable-server-variable", variable.uid, seqNumber],
71632
- queryFn: async () => {
71633
- const result = await fetcher(null, {
71634
- limit: 1,
71635
- offset: 0
71636
- });
71637
- return result.data;
71638
- },
71639
- refetchOnWindowFocus: false
71322
+ _arrayAggregator = arrayAggregator;
71323
+ return _arrayAggregator;
71324
+ }
71325
+ var _baseAggregator;
71326
+ var hasRequired_baseAggregator;
71327
+ function require_baseAggregator() {
71328
+ if (hasRequired_baseAggregator) return _baseAggregator;
71329
+ hasRequired_baseAggregator = 1;
71330
+ var baseEach = require_baseEach();
71331
+ function baseAggregator(collection, setter, iteratee, accumulator) {
71332
+ baseEach(collection, function(value, key, collection2) {
71333
+ setter(accumulator, value, iteratee(value), collection2);
71640
71334
  });
71641
- return [data2?.[0] ?? null, warnUpdateOnDerivedState];
71335
+ return accumulator;
71642
71336
  }
71643
- const recoilState = getOrRegisterPlainVariable(variable, wsClient, taskContext, extras);
71644
- if (!isDerivedVariable(variable.default)) {
71645
- const [value, setValue] = Recoil_index_22(recoilState);
71646
- React$1.useEffect(() => {
71647
- bus.publish("PLAIN_VARIABLE_LOADED", { variable, value });
71648
- }, [value]);
71649
- return [value, setValue];
71337
+ _baseAggregator = baseAggregator;
71338
+ return _baseAggregator;
71339
+ }
71340
+ var _createAggregator;
71341
+ var hasRequired_createAggregator;
71342
+ function require_createAggregator() {
71343
+ if (hasRequired_createAggregator) return _createAggregator;
71344
+ hasRequired_createAggregator = 1;
71345
+ var arrayAggregator = require_arrayAggregator(), baseAggregator = require_baseAggregator(), baseIteratee = require_baseIteratee(), isArray = requireIsArray();
71346
+ function createAggregator(setter, initializer2) {
71347
+ return function(collection, iteratee) {
71348
+ var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer2 ? initializer2() : {};
71349
+ return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
71350
+ };
71650
71351
  }
71651
- const [loadable, setLoadable] = Recoil_index_23(recoilState);
71652
- React$1.useEffect(() => {
71653
- if (loadable.state !== "loading") {
71654
- bus.publish("PLAIN_VARIABLE_LOADED", { variable, value: loadable.contents });
71655
- }
71656
- }, [loadable]);
71657
- const deferred2 = useDeferLoadable(loadable, opts.suspend);
71658
- return [deferred2, setLoadable];
71352
+ _createAggregator = createAggregator;
71353
+ return _createAggregator;
71659
71354
  }
71660
- function flexStyles(props, displayCtx2, useDisplayContext) {
71661
- let flexBasis = props.basis;
71662
- let flexShrink = props.shrink;
71663
- let flexGrow = props.grow;
71664
- if (useDisplayContext) {
71665
- if (props.width && displayCtx2.direction === "horizontal") {
71666
- flexBasis ??= props.width;
71667
- flexShrink ??= "0";
71668
- flexGrow ??= "0";
71669
- }
71670
- if (props.height && displayCtx2.direction === "vertical") {
71671
- flexBasis ??= props.height;
71672
- flexShrink ??= "0";
71673
- flexGrow ??= "0";
71355
+ var groupBy_1;
71356
+ var hasRequiredGroupBy;
71357
+ function requireGroupBy() {
71358
+ if (hasRequiredGroupBy) return groupBy_1;
71359
+ hasRequiredGroupBy = 1;
71360
+ var baseAssignValue = require_baseAssignValue(), createAggregator = require_createAggregator();
71361
+ var objectProto = Object.prototype;
71362
+ var hasOwnProperty2 = objectProto.hasOwnProperty;
71363
+ var groupBy2 = createAggregator(function(result, value, key) {
71364
+ if (hasOwnProperty2.call(result, key)) {
71365
+ result[key].push(value);
71366
+ } else {
71367
+ baseAssignValue(result, key, [value]);
71674
71368
  }
71369
+ });
71370
+ groupBy_1 = groupBy2;
71371
+ return groupBy_1;
71372
+ }
71373
+ var groupByExports = requireGroupBy();
71374
+ const groupBy = /* @__PURE__ */ getDefaultExportFromCjs(groupByExports);
71375
+ async function invokeAction(input, executionId, annotatedAction, actionCtx) {
71376
+ const resolvedKwargs = await Promise.all(
71377
+ Object.entries(annotatedAction.dynamic_kwargs).map(async ([k, value]) => {
71378
+ const resolvedValue = isVariable(value) ? await resolveVariable(
71379
+ value,
71380
+ actionCtx.wsClient,
71381
+ actionCtx.taskCtx,
71382
+ actionCtx.extras,
71383
+ (v) => actionCtx.snapshot.getLoadable(v).toPromise()
71384
+ ) : value;
71385
+ return [k, resolvedValue];
71386
+ })
71387
+ ).then((entries) => Object.fromEntries(entries));
71388
+ const ws_channel = await actionCtx.wsClient.getChannel();
71389
+ const res = await request(
71390
+ `/api/core/action/${annotatedAction.definition_uid}`,
71391
+ {
71392
+ body: JSON.stringify({
71393
+ execution_id: executionId,
71394
+ input,
71395
+ uid: annotatedAction.uid,
71396
+ values: normalizeRequest(cleanKwargs(resolvedKwargs, null), annotatedAction.dynamic_kwargs),
71397
+ ws_channel
71398
+ }),
71399
+ method: HTTP_METHOD.POST
71400
+ },
71401
+ actionCtx.extras
71402
+ );
71403
+ await handleAuthErrors(res, true);
71404
+ await validateResponse(res, `Failed to fetch the action value with uid: ${annotatedAction.uid}`);
71405
+ const resContent = await res.json();
71406
+ if ("task_id" in resContent) {
71407
+ const taskId = resContent.task_id;
71408
+ actionCtx.taskCtx.startTask(taskId);
71409
+ await actionCtx.wsClient.waitForTask(taskId);
71410
+ actionCtx.taskCtx.endTask(taskId);
71411
+ await fetchTaskResult(taskId, actionCtx.extras);
71675
71412
  }
71676
- if (props.hug || props.hug !== false && displayCtx2.hug) {
71677
- flexBasis ??= "content";
71678
- flexShrink ??= "1";
71679
- flexGrow ??= "0";
71680
- }
71681
- return { flexBasis, flexGrow, flexShrink };
71682
71413
  }
71683
- function parseRawCss(rawCss) {
71684
- const isRawObject = typeof rawCss === "object" && rawCss !== null && rawCss !== void 0;
71685
- const componentCss = !isRawObject && typeof rawCss === "string" ? rawCss : "";
71686
- const styles2 = isRawObject ? rawCss : {};
71687
- return [styles2, componentCss];
71414
+ const ACTION_HANDLER_BY_NAME = {};
71415
+ async function preloadActions(importers, actions) {
71416
+ const componentsByModule = groupBy(actions, (actionDef) => actionDef.py_module);
71417
+ await Promise.all(
71418
+ Object.entries(componentsByModule).map(async ([module2, moduleActions]) => {
71419
+ const moduleContent = await importers[module2]();
71420
+ for (const action of moduleActions) {
71421
+ if (ACTION_HANDLER_BY_NAME[action.name]) {
71422
+ continue;
71423
+ }
71424
+ const actionHandler = moduleContent[action.name];
71425
+ if (actionHandler) {
71426
+ ACTION_HANDLER_BY_NAME[action.name] = actionHandler;
71427
+ }
71428
+ }
71429
+ })
71430
+ );
71688
71431
  }
71689
- function useComponentStyles(props, useDisplayContext = true, propName = "raw_css") {
71690
- const [rawCssValue] = useVariable(props[propName]);
71691
- const [rawStyles, rawCss] = parseRawCss(rawCssValue);
71692
- const displayCtx$1 = React$1.useContext(displayCtx);
71693
- const flexProps = flexStyles(props, displayCtx$1, useDisplayContext);
71694
- const styles2 = React$1.useMemo(() => {
71695
- const stylesObj = {
71696
- backgroundColor: props.background,
71697
- border: props.border,
71698
- borderRadius: props.border_radius,
71699
- color: props.color,
71700
- fontFamily: props.font,
71701
- fontSize: props.font_size,
71702
- fontStyle: props.italic ? "italic" : "normal",
71703
- fontWeight: props.bold ? "bold" : "normal",
71704
- gap: props.gap,
71705
- height: props.height,
71706
- margin: props.margin,
71707
- maxHeight: props.max_height,
71708
- maxWidth: props.max_width,
71709
- minHeight: props.min_height,
71710
- minWidth: props.min_width,
71711
- overflow: props.overflow,
71712
- padding: props.padding,
71713
- position: props.position,
71714
- textDecoration: props.underline ? "underline" : "none",
71715
- width: props.width,
71716
- ...flexProps,
71717
- ...rawStyles,
71718
- ...props.style ?? {}
71719
- };
71720
- return Object.fromEntries(Object.entries(stylesObj).filter(([, v]) => v !== null && v !== void 0));
71721
- }, [useDeepCompare(props), rawStyles, flexProps]);
71722
- return [styles2, rawCss];
71432
+ function clearActionHandlerCache_TEST() {
71433
+ Object.keys(ACTION_HANDLER_BY_NAME).forEach((k) => delete ACTION_HANDLER_BY_NAME[k]);
71723
71434
  }
71724
- function useUrlSync() {
71725
- const location2 = useLocation();
71726
- const locationSubscribers = React$1.useRef([]);
71727
- React$1.useEffect(() => {
71728
- for (const subscriber of locationSubscribers.current) {
71729
- subscriber();
71730
- }
71731
- }, [location2]);
71732
- const urlSerializer = React$1.useCallback((val) => {
71733
- if (val === void 0 || val === null) {
71734
- return "";
71735
- }
71736
- if (["string", "number", "boolean"].includes(typeof val)) {
71737
- return String(val);
71738
- }
71739
- return JSON.stringify(val);
71740
- }, []);
71741
- const urlDeserializer = React$1.useCallback((val) => {
71742
- if (val === "") {
71743
- return void 0;
71435
+ class UnhandledActionError extends Error {
71436
+ constructor(message, actionImpl) {
71437
+ super(message);
71438
+ this.actionImpl = actionImpl;
71439
+ }
71440
+ }
71441
+ function resolveActionImpl(actionImpl, actionCtx) {
71442
+ let actionHandler;
71443
+ if (!ACTION_HANDLER_BY_NAME[actionImpl.name]) {
71444
+ if (actionCtx.onUnhandledAction) {
71445
+ actionHandler = actionCtx.onUnhandledAction;
71446
+ } else {
71447
+ throw new UnhandledActionError(`Action definition for impl "${actionImpl.name}" not found`, actionImpl);
71744
71448
  }
71745
- try {
71746
- return JSON.parse(val);
71747
- } catch {
71748
- return val;
71449
+ } else {
71450
+ actionHandler = ACTION_HANDLER_BY_NAME[actionImpl.name];
71451
+ }
71452
+ return actionHandler;
71453
+ }
71454
+ async function executeAction(input, action, actionCtx) {
71455
+ if (isActionImpl(action)) {
71456
+ const handler = resolveActionImpl(action, actionCtx);
71457
+ const result = handler(actionCtx, action);
71458
+ if (result instanceof Promise) {
71459
+ await result;
71749
71460
  }
71750
- }, []);
71751
- const listenChangeURL = React$1.useCallback((handler) => {
71752
- locationSubscribers.current.push(handler);
71753
- return () => {
71754
- locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handler);
71461
+ return;
71462
+ }
71463
+ const executionId = nanoid$1();
71464
+ const observable2 = actionCtx.wsClient.actionMessages$(executionId);
71465
+ return new Promise((resolve, reject) => {
71466
+ let activeTasks = 0;
71467
+ let streamCompleted = false;
71468
+ let isSettled = false;
71469
+ let sub;
71470
+ const checkForCompletion = () => {
71471
+ if (!isSettled && streamCompleted && activeTasks === 0) {
71472
+ isSettled = true;
71473
+ sub.unsubscribe();
71474
+ resolve();
71475
+ }
71755
71476
  };
71756
- }, []);
71757
- return {
71758
- browserInterface: {
71759
- listenChangeURL
71760
- },
71761
- deserialize: urlDeserializer,
71762
- location: { part: "queryParams" },
71763
- serialize: urlSerializer
71764
- };
71765
- }
71766
- const StyledDots$1 = injectCss(Dots);
71767
- function DefaultFallback$1(props) {
71768
- const [style, css2] = useComponentStyles(props);
71769
- return /* @__PURE__ */ React.createElement(StyledDots$1, { $rawCss: css2, style });
71477
+ const onError = (error) => {
71478
+ if (!isSettled) {
71479
+ isSettled = true;
71480
+ sub.unsubscribe();
71481
+ reject(error);
71482
+ }
71483
+ };
71484
+ sub = observable2.pipe(
71485
+ // eslint-disable-next-line @typescript-eslint/require-await
71486
+ concatMap(async (actionImpl) => {
71487
+ if (actionImpl) {
71488
+ const handler = resolveActionImpl(actionImpl, actionCtx);
71489
+ return [handler, actionImpl];
71490
+ }
71491
+ return null;
71492
+ }),
71493
+ takeWhile((res) => !!res)
71494
+ // stop when falsy is returned from concatMap
71495
+ ).subscribe({
71496
+ complete: () => {
71497
+ streamCompleted = true;
71498
+ checkForCompletion();
71499
+ },
71500
+ error: onError,
71501
+ // Reject the promise if there's an error in the stream
71502
+ next: async ([handler, actionImpl]) => {
71503
+ try {
71504
+ activeTasks += 1;
71505
+ const result = handler(actionCtx, actionImpl);
71506
+ if (result instanceof Promise) {
71507
+ await result;
71508
+ }
71509
+ } catch (error) {
71510
+ onError(error);
71511
+ } finally {
71512
+ if (activeTasks > 0) {
71513
+ activeTasks -= 1;
71514
+ }
71515
+ checkForCompletion();
71516
+ }
71517
+ }
71518
+ });
71519
+ invokeAction(input, executionId, action, actionCtx).catch(onError);
71520
+ });
71770
71521
  }
71771
- function DefaultFallbackStatic() {
71772
- return /* @__PURE__ */ React.createElement(StyledDots$1, { grey3: theme.colors.grey3, grey4: theme.colors.grey4 });
71773
- }
71774
- const Center = styled.div`
71775
- overflow: hidden;
71776
- display: flex;
71777
- flex-direction: column;
71778
- align-items: center;
71779
- justify-content: center;
71780
-
71781
- width: 100%;
71782
- height: 100%;
71783
-
71784
- background: ${(props) => props.colored ? props.theme.colors.blue1 : ""};
71785
- `;
71786
- const Wrapper$1 = styled.div`
71787
- display: flex;
71788
- flex: 1 1 0%;
71789
- flex-direction: column;
71790
- justify-content: center;
71791
-
71792
- min-height: 100%;
71793
-
71794
- background: ${(props) => `radial-gradient(circle closest-corner at 50% 40%, ${curriedTransparentize$1(
71795
- 0.9,
71796
- props.theme.colors.background
71797
- )} 0%, ${curriedTransparentize$1(
71798
- 0.8,
71799
- props.theme.colors.blue4
71800
- )} 70%),radial-gradient(circle closest-corner at 20% 150%, ${curriedTransparentize$1(
71801
- 0.8,
71802
- props.theme.colors.error
71803
- )} 0%, ${curriedTransparentize$1(0.2, props.theme.colors.blue4)} 230%)`};
71804
- `;
71805
- const Card = styled.div`
71806
- padding: 1.5rem;
71807
-
71808
- color: ${(props) => props.theme.colors.text};
71809
-
71810
- background-color: ${(props) => props.theme.colors.blue1};
71811
- border-radius: 1rem;
71812
- box-shadow: ${(props) => props.theme.shadow.medium};
71813
-
71814
- @media (width >= 640px) {
71815
- width: 100%;
71816
- max-width: 24rem;
71817
- margin-right: auto;
71818
- margin-left: auto;
71819
- }
71820
- `;
71821
- const FormWrapper = styled.div`
71822
- margin-top: 1.5rem;
71823
- `;
71824
- const Form = styled.form`
71825
- > * + * {
71826
- margin-top: 1.5rem;
71827
- }
71828
- `;
71829
- const ErrorText$1 = styled.h3`
71830
- margin: 0;
71831
-
71832
- font-size: 0.875rem;
71833
- font-weight: 500;
71834
- line-height: 1.25rem;
71835
- color: ${(props) => props.theme.colors.error};
71836
- letter-spacing: 0.025em;
71837
-
71838
- visibility: ${(props) => props.$hidden ? "hidden" : "visible"};
71839
- `;
71840
- const Label = styled.label`
71841
- font-weight: 500;
71842
- line-height: 1.5rem;
71843
- `;
71844
- const StyledInput = styled.input`
71845
- display: flex;
71846
- display: block;
71847
- align-items: center;
71848
-
71849
- width: 100%;
71850
- height: 2.5rem;
71851
- margin-top: 0.5rem;
71852
- padding: 0 1rem;
71853
-
71854
- font-size: 1rem;
71855
- line-height: 1.5rem;
71856
- color: ${(props) => props.theme.colors.text};
71857
-
71858
- background-color: ${(props) => props.theme.colors.blue1};
71859
- border: none;
71860
- border-radius: 0.25rem;
71861
- outline: none;
71862
- box-shadow:
71863
- inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
71864
- inset 0 0 0 1px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.grey2},
71865
- 0 1px 2px 0 rgb(0 0 0 / 5%);
71866
-
71867
- :active,
71868
- :focus {
71869
- box-shadow:
71870
- inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
71871
- inset 0 0 0 2px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.primary},
71872
- 0 1px 2px 0 rgb(0 0 0 / 5%);
71873
- }
71874
- `;
71875
- const StyledButton = styled(Button$1)`
71876
- width: 100%;
71877
- font-weight: 600;
71878
- line-height: 1.5rem;
71879
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
71880
-
71881
- :active,
71882
- :focus {
71883
- outline-color: ${(props) => props.theme.colors.primary};
71884
- outline-width: 2px;
71885
- outline-offset: 2px;
71886
- }
71887
- `;
71888
- function BasicAuthLogin() {
71889
- const [isVerifyingToken, setIsVerifyingToken] = React$1.useState(true);
71890
- const [isLoggingIn, setIsLoggingIn] = React$1.useState(false);
71891
- const [username, setUsername] = React$1.useState("");
71892
- const [password, setPassword] = React$1.useState("");
71893
- const [isError2, setIsError] = React$1.useState(false);
71894
- const location2 = useLocation();
71895
- const navigate = useNavigate();
71896
- const { defaultPath } = useRouterContext();
71897
- const queryParams = new URLSearchParams(location2.search);
71898
- const previousLocation = queryParams.get("referrer") ?? defaultPath;
71899
- const login = async () => {
71900
- setIsLoggingIn(true);
71901
- setIsError(false);
71902
- try {
71903
- const sessionToken = await requestSessionToken({ password, username });
71904
- if (sessionToken) {
71905
- setSessionToken(sessionToken);
71906
- navigate(decodeURIComponent(previousLocation));
71907
- }
71908
- } catch {
71909
- setIsError(true);
71910
- }
71911
- setIsLoggingIn(false);
71912
- };
71913
- React$1.useEffect(() => {
71914
- if (getSessionToken()) {
71915
- verifySessionToken().then((verified) => {
71916
- if (verified) {
71917
- navigate(decodeURIComponent(previousLocation), { replace: true });
71918
- } else {
71919
- setIsVerifyingToken(false);
71920
- }
71921
- });
71922
- } else {
71923
- setIsVerifyingToken(false);
71924
- }
71925
- }, []);
71926
- if (isVerifyingToken) {
71927
- return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
71928
- }
71929
- return /* @__PURE__ */ React.createElement(Wrapper$1, null, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(FormWrapper, null, /* @__PURE__ */ React.createElement(
71930
- Form,
71931
- {
71932
- onSubmit: (e2) => {
71933
- e2.preventDefault();
71934
- login();
71935
- }
71936
- },
71937
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "username" }, "Username"), /* @__PURE__ */ React.createElement(
71938
- StyledInput,
71939
- {
71940
- $error: isError2,
71941
- id: "username",
71942
- onChange: (e2) => setUsername(e2.target.value),
71943
- required: true,
71944
- type: "text",
71945
- value: username
71946
- }
71947
- )),
71948
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "password" }, "Password"), /* @__PURE__ */ React.createElement(
71949
- StyledInput,
71950
- {
71951
- $error: isError2,
71952
- id: "password",
71953
- onChange: (e2) => setPassword(e2.target.value),
71954
- required: true,
71955
- type: "password",
71956
- value: password
71957
- }
71958
- )),
71959
- /* @__PURE__ */ React.createElement(ErrorText$1, { $hidden: !isError2, style: { marginTop: "1rem" } }, "Incorrect Username or Password"),
71960
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
71961
- StyledButton,
71962
- {
71963
- loading: isLoggingIn,
71964
- style: { color: "white" },
71965
- styling: "primary",
71966
- type: "submit"
71967
- },
71968
- "Sign in"
71969
- ))
71970
- ))));
71971
- }
71972
- function BasicAuthLogout() {
71973
- React$1.useEffect(() => {
71974
- revokeSession().then(() => {
71975
- setSessionToken(null);
71976
- window.location.href = `${window.dara.base_url}/login`;
71977
- });
71978
- }, []);
71979
- return null;
71980
- }
71981
- function DefaultAuthLogin() {
71982
- const location2 = useLocation();
71983
- const navigate = useNavigate();
71984
- const { defaultPath } = useRouterContext();
71985
- const queryParams = new URLSearchParams(location2.search);
71986
- const previousLocation = queryParams.get("referrer") ?? defaultPath;
71987
- async function getNewToken() {
71988
- const sessionToken = await requestSessionToken({});
71989
- if (sessionToken) {
71990
- setSessionToken(sessionToken);
71991
- navigate(decodeURIComponent(previousLocation));
71992
- }
71993
- }
71994
- React$1.useEffect(() => {
71995
- if (getSessionToken()) {
71996
- verifySessionToken().then((verified) => {
71997
- if (verified) {
71998
- navigate(decodeURIComponent(previousLocation), { replace: true });
71999
- } else {
72000
- getNewToken();
72001
- }
72002
- });
72003
- } else {
72004
- getNewToken();
72005
- }
72006
- }, []);
72007
- return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
72008
- }
72009
- const CenteredDivWithGap$1 = styled(Center)`
72010
- gap: 1rem;
72011
- margin: 10px;
72012
- text-align: center;
72013
- `;
72014
- const config401 = {
72015
- description: "Your login session may have expired. Try again.",
72016
- styling: "primary",
72017
- title: "We were not able to authenticate you"
72018
- };
72019
- const errorMessages = {
72020
- "403": {
72021
- description: "You are not authorised to access this application. Please contact the application owner to enable access.",
72022
- styling: "error",
72023
- title: "We were not able to authenticate you"
72024
- },
72025
- "404": {
72026
- description: "The requested page could not be found.",
72027
- styling: "error",
72028
- title: "Page not found"
72029
- },
72030
- "401": config401,
72031
- default: config401
72032
- };
72033
- function ErrorPage(props) {
72034
- const { search } = useLocation();
72035
- const query = React$1.useMemo(() => new URLSearchParams(search), [search]);
72036
- const code = props.code ?? query.get("code");
72037
- const errorConfig = code && errorMessages[code] || errorMessages.default;
72038
- return /* @__PURE__ */ React.createElement(CenteredDivWithGap$1, null, /* @__PURE__ */ React.createElement("h1", null, errorConfig.title), /* @__PURE__ */ React.createElement("p", null, errorConfig.description), /* @__PURE__ */ React.createElement(Button$1, { href: "/login", styling: errorConfig.styling }, "Retry"));
72039
- }
72040
- function useRefreshSelector() {
72041
- return Recoil_index_31(({ refresh }) => {
72042
- return (key, extras) => {
72043
- const family = selectorFamilyRegistry.get(key);
72044
- if (family) {
72045
- const selector2 = selectorFamilyMembersRegistry.get(family)?.get(extras);
72046
- if (selector2) {
72047
- refresh(selector2);
72048
- }
72049
- }
72050
- };
72051
- });
72052
- }
72053
- function useVariableState() {
72054
- const extras = useRequestExtras();
72055
- const { client: client2 } = React$1.useContext(websocketCtx);
72056
- const taskCtx = useTaskContext();
72057
- return Recoil_index_31(({ snapshot }) => {
72058
- return async (variable) => {
72059
- if (!isRegistered(variable)) {
72060
- return "__NOT_REGISTERED__";
72061
- }
72062
- const resolvedVariable = await resolveVariable(
72063
- variable,
72064
- client2,
72065
- taskCtx,
72066
- extras,
72067
- (v) => snapshot.getLoadable(v).toPromise()
72068
- );
72069
- return resolvedVariable;
72070
- };
72071
- }, []);
72072
- }
72073
- var _arrayAggregator;
72074
- var hasRequired_arrayAggregator;
72075
- function require_arrayAggregator() {
72076
- if (hasRequired_arrayAggregator) return _arrayAggregator;
72077
- hasRequired_arrayAggregator = 1;
72078
- function arrayAggregator(array2, setter, iteratee, accumulator) {
72079
- var index2 = -1, length = array2 == null ? 0 : array2.length;
72080
- while (++index2 < length) {
72081
- var value = array2[index2];
72082
- setter(accumulator, value, iteratee(value), array2);
72083
- }
72084
- return accumulator;
72085
- }
72086
- _arrayAggregator = arrayAggregator;
72087
- return _arrayAggregator;
72088
- }
72089
- var _baseAggregator;
72090
- var hasRequired_baseAggregator;
72091
- function require_baseAggregator() {
72092
- if (hasRequired_baseAggregator) return _baseAggregator;
72093
- hasRequired_baseAggregator = 1;
72094
- var baseEach = require_baseEach();
72095
- function baseAggregator(collection, setter, iteratee, accumulator) {
72096
- baseEach(collection, function(value, key, collection2) {
72097
- setter(accumulator, value, iteratee(value), collection2);
72098
- });
72099
- return accumulator;
72100
- }
72101
- _baseAggregator = baseAggregator;
72102
- return _baseAggregator;
72103
- }
72104
- var _createAggregator;
72105
- var hasRequired_createAggregator;
72106
- function require_createAggregator() {
72107
- if (hasRequired_createAggregator) return _createAggregator;
72108
- hasRequired_createAggregator = 1;
72109
- var arrayAggregator = require_arrayAggregator(), baseAggregator = require_baseAggregator(), baseIteratee = require_baseIteratee(), isArray = requireIsArray();
72110
- function createAggregator(setter, initializer2) {
72111
- return function(collection, iteratee) {
72112
- var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer2 ? initializer2() : {};
72113
- return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
72114
- };
72115
- }
72116
- _createAggregator = createAggregator;
72117
- return _createAggregator;
72118
- }
72119
- var groupBy_1;
72120
- var hasRequiredGroupBy;
72121
- function requireGroupBy() {
72122
- if (hasRequiredGroupBy) return groupBy_1;
72123
- hasRequiredGroupBy = 1;
72124
- var baseAssignValue = require_baseAssignValue(), createAggregator = require_createAggregator();
72125
- var objectProto = Object.prototype;
72126
- var hasOwnProperty2 = objectProto.hasOwnProperty;
72127
- var groupBy2 = createAggregator(function(result, value, key) {
72128
- if (hasOwnProperty2.call(result, key)) {
72129
- result[key].push(value);
72130
- } else {
72131
- baseAssignValue(result, key, [value]);
72132
- }
72133
- });
72134
- groupBy_1 = groupBy2;
72135
- return groupBy_1;
72136
- }
72137
- var groupByExports = requireGroupBy();
72138
- const groupBy = /* @__PURE__ */ getDefaultExportFromCjs(groupByExports);
72139
- async function invokeAction(input, executionId, annotatedAction, actionCtx) {
72140
- const resolvedKwargs = await Promise.all(
72141
- Object.entries(annotatedAction.dynamic_kwargs).map(async ([k, value]) => {
72142
- const resolvedValue = isVariable(value) ? await resolveVariable(
72143
- value,
72144
- actionCtx.wsClient,
72145
- actionCtx.taskCtx,
72146
- actionCtx.extras,
72147
- (v) => actionCtx.snapshot.getLoadable(v).toPromise()
72148
- ) : value;
72149
- return [k, resolvedValue];
72150
- })
72151
- ).then((entries) => Object.fromEntries(entries));
72152
- const ws_channel = await actionCtx.wsClient.getChannel();
72153
- const res = await request(
72154
- `/api/core/action/${annotatedAction.definition_uid}`,
72155
- {
72156
- body: JSON.stringify({
72157
- execution_id: executionId,
72158
- input,
72159
- uid: annotatedAction.uid,
72160
- values: normalizeRequest(cleanKwargs(resolvedKwargs, null), annotatedAction.dynamic_kwargs),
72161
- ws_channel
72162
- }),
72163
- method: HTTP_METHOD.POST
72164
- },
72165
- actionCtx.extras
72166
- );
72167
- await handleAuthErrors(res, true);
72168
- await validateResponse(res, `Failed to fetch the action value with uid: ${annotatedAction.uid}`);
72169
- const resContent = await res.json();
72170
- if ("task_id" in resContent) {
72171
- const taskId = resContent.task_id;
72172
- actionCtx.taskCtx.startTask(taskId);
72173
- await actionCtx.wsClient.waitForTask(taskId);
72174
- actionCtx.taskCtx.endTask(taskId);
72175
- await fetchTaskResult(taskId, actionCtx.extras);
72176
- }
72177
- }
72178
- const ACTION_HANDLER_BY_NAME = {};
72179
- async function preloadActions(importers, actions) {
72180
- const componentsByModule = groupBy(actions, (actionDef) => actionDef.py_module);
72181
- await Promise.all(
72182
- Object.entries(componentsByModule).map(async ([module2, moduleActions]) => {
72183
- const moduleContent = await importers[module2]();
72184
- for (const action of moduleActions) {
72185
- if (ACTION_HANDLER_BY_NAME[action.name]) {
72186
- continue;
72187
- }
72188
- const actionHandler = moduleContent[action.name];
72189
- if (actionHandler) {
72190
- ACTION_HANDLER_BY_NAME[action.name] = actionHandler;
72191
- }
72192
- }
72193
- })
72194
- );
72195
- }
72196
- function clearActionHandlerCache_TEST() {
72197
- Object.keys(ACTION_HANDLER_BY_NAME).forEach((k) => delete ACTION_HANDLER_BY_NAME[k]);
72198
- }
72199
- class UnhandledActionError extends Error {
72200
- constructor(message, actionImpl) {
72201
- super(message);
72202
- this.actionImpl = actionImpl;
72203
- }
72204
- }
72205
- function resolveActionImpl(actionImpl, actionCtx) {
72206
- let actionHandler;
72207
- if (!ACTION_HANDLER_BY_NAME[actionImpl.name]) {
72208
- if (actionCtx.onUnhandledAction) {
72209
- actionHandler = actionCtx.onUnhandledAction;
72210
- } else {
72211
- throw new UnhandledActionError(`Action definition for impl "${actionImpl.name}" not found`, actionImpl);
72212
- }
72213
- } else {
72214
- actionHandler = ACTION_HANDLER_BY_NAME[actionImpl.name];
72215
- }
72216
- return actionHandler;
72217
- }
72218
- async function executeAction(input, action, actionCtx) {
72219
- if (isActionImpl(action)) {
72220
- const handler = resolveActionImpl(action, actionCtx);
72221
- const result = handler(actionCtx, action);
72222
- if (result instanceof Promise) {
72223
- await result;
72224
- }
72225
- return;
72226
- }
72227
- const executionId = nanoid$1();
72228
- const observable2 = actionCtx.wsClient.actionMessages$(executionId);
72229
- return new Promise((resolve, reject) => {
72230
- let activeTasks = 0;
72231
- let streamCompleted = false;
72232
- let isSettled = false;
72233
- let sub;
72234
- const checkForCompletion = () => {
72235
- if (!isSettled && streamCompleted && activeTasks === 0) {
72236
- isSettled = true;
72237
- sub.unsubscribe();
72238
- resolve();
72239
- }
72240
- };
72241
- const onError = (error) => {
72242
- if (!isSettled) {
72243
- isSettled = true;
72244
- sub.unsubscribe();
72245
- reject(error);
72246
- }
72247
- };
72248
- sub = observable2.pipe(
72249
- // eslint-disable-next-line @typescript-eslint/require-await
72250
- concatMap(async (actionImpl) => {
72251
- if (actionImpl) {
72252
- const handler = resolveActionImpl(actionImpl, actionCtx);
72253
- return [handler, actionImpl];
72254
- }
72255
- return null;
72256
- }),
72257
- takeWhile((res) => !!res)
72258
- // stop when falsy is returned from concatMap
72259
- ).subscribe({
72260
- complete: () => {
72261
- streamCompleted = true;
72262
- checkForCompletion();
72263
- },
72264
- error: onError,
72265
- // Reject the promise if there's an error in the stream
72266
- next: async ([handler, actionImpl]) => {
72267
- try {
72268
- activeTasks += 1;
72269
- const result = handler(actionCtx, actionImpl);
72270
- if (result instanceof Promise) {
72271
- await result;
72272
- }
72273
- } catch (error) {
72274
- onError(error);
72275
- } finally {
72276
- if (activeTasks > 0) {
72277
- activeTasks -= 1;
72278
- }
72279
- checkForCompletion();
72280
- }
72281
- }
72282
- });
72283
- invokeAction(input, executionId, action, actionCtx).catch(onError);
72284
- });
72285
- }
72286
- const noop = () => Promise.resolve();
72287
- function useActionIsLoading(action) {
72288
- if (!action || isActionImpl(action) || Array.isArray(action)) {
72289
- return false;
72290
- }
72291
- return useVariable(action.loading)[0];
71522
+ const noop = () => Promise.resolve();
71523
+ function useActionIsLoading(action) {
71524
+ if (!action || isActionImpl(action) || Array.isArray(action)) {
71525
+ return false;
71526
+ }
71527
+ return useVariable(action.loading)[0];
72292
71528
  }
72293
71529
  function useExecuteAction() {
72294
71530
  const { client: wsClient } = React$1.useContext(websocketCtx);
@@ -72434,16 +71670,55 @@ Inferred class string: "${iconClasses}."`
72434
71670
  }
72435
71671
  return callback;
72436
71672
  }
72437
- function isTaskResponse(response) {
72438
- return response && typeof response === "object" && "task_id" in response;
72439
- }
72440
- function getComponentRegistryKey(uid2, trigger, loopInstanceUid) {
72441
- let key = `_COMPONENT_${uid2}`;
72442
- if (trigger) {
72443
- key += "_TRIGGER";
71673
+ function isConditionTrue(operator, value, other) {
71674
+ if (operator === ConditionOperator.EQUAL) {
71675
+ return value === other;
72444
71676
  }
72445
- if (loopInstanceUid) {
72446
- key += `_${loopInstanceUid}`;
71677
+ if (operator === ConditionOperator.NOT_EQUAL) {
71678
+ return value !== other;
71679
+ }
71680
+ if (operator === ConditionOperator.GREATER_EQUAL) {
71681
+ return value >= other;
71682
+ }
71683
+ if (operator === ConditionOperator.GREATER_THAN) {
71684
+ return value > other;
71685
+ }
71686
+ if (operator === ConditionOperator.LESS_EQUAL) {
71687
+ return value <= other;
71688
+ }
71689
+ if (operator === ConditionOperator.LESS_THAN) {
71690
+ return value < other;
71691
+ }
71692
+ if (operator === ConditionOperator.TRUTHY) {
71693
+ return !!value;
71694
+ }
71695
+ throw new Error(`Unexpected operator ${String(operator)} passed to conditional (If) component`);
71696
+ }
71697
+ function useConditionOrVariable(arg, opts = {}) {
71698
+ if (isCondition(arg)) {
71699
+ const value = useVariable(arg.variable, opts)[0];
71700
+ const other = useVariable(arg.other, opts)[0];
71701
+ return isConditionTrue(arg.operator, value, other);
71702
+ }
71703
+ return useVariable(arg, opts)[0];
71704
+ }
71705
+ function useSwitchVariable(variable) {
71706
+ const value = useConditionOrVariable(variable.value, { suspend: false });
71707
+ const [valueMap] = useVariable(variable.value_map, { suspend: false });
71708
+ const [defaultValue] = useVariable(variable.default, { suspend: false });
71709
+ const lookupKey = String(value);
71710
+ return valueMap[lookupKey] ?? defaultValue;
71711
+ }
71712
+ function isTaskResponse(response) {
71713
+ return response && typeof response === "object" && "task_id" in response;
71714
+ }
71715
+ function getComponentRegistryKey(uid2, trigger, loopInstanceUid) {
71716
+ let key = `_COMPONENT_${uid2}`;
71717
+ if (trigger) {
71718
+ key += "_TRIGGER";
71719
+ }
71720
+ if (loopInstanceUid) {
71721
+ key += `_${loopInstanceUid}`;
72447
71722
  }
72448
71723
  return key;
72449
71724
  }
@@ -72686,6 +71961,18 @@ Inferred class string: "${iconClasses}."`
72686
71961
  [uid2]
72687
71962
  );
72688
71963
  }
71964
+ const Center = styled.div`
71965
+ overflow: hidden;
71966
+ display: flex;
71967
+ flex-direction: column;
71968
+ align-items: center;
71969
+ justify-content: center;
71970
+
71971
+ width: 100%;
71972
+ height: 100%;
71973
+
71974
+ background: ${(props) => props.colored ? props.theme.colors.blue1 : ""};
71975
+ `;
72689
71976
  const ErrorBoundaryContext = React$1.createContext(null);
72690
71977
  const initialState = {
72691
71978
  didCatch: false,
@@ -72856,7 +72143,17 @@ Inferred class string: "${iconClasses}."`
72856
72143
  walk(renderer, []);
72857
72144
  return markers;
72858
72145
  }
72859
- function applyMarkers(renderer, markers, loopValue, itemKey) {
72146
+ const MARKER_INDEX = "__index";
72147
+ const MARKER_IS_LAST = "__is_last";
72148
+ const MARKER_IS_FIRST = "__is_first";
72149
+ function applyMarkers({
72150
+ renderer,
72151
+ markers,
72152
+ loopValue,
72153
+ itemKey,
72154
+ index: index2,
72155
+ itemsLength
72156
+ }) {
72860
72157
  if (markers.length === 0) {
72861
72158
  return renderer;
72862
72159
  }
@@ -72864,7 +72161,17 @@ Inferred class string: "${iconClasses}."`
72864
72161
  for (const marker of markers) {
72865
72162
  switch (marker.type) {
72866
72163
  case "loop_var": {
72867
- set(clonedRenderer, marker.path, resolveNested(loopValue, marker.nested));
72164
+ let value;
72165
+ if (marker.nested.length === 1 && marker.nested[0] === MARKER_INDEX) {
72166
+ value = index2;
72167
+ } else if (marker.nested.length === 1 && marker.nested[0] === MARKER_IS_LAST) {
72168
+ value = index2 === itemsLength - 1;
72169
+ } else if (marker.nested.length === 1 && marker.nested[0] === MARKER_IS_FIRST) {
72170
+ value = index2 === 0;
72171
+ } else {
72172
+ value = resolveNested(loopValue, marker.nested);
72173
+ }
72174
+ set(clonedRenderer, marker.path, value);
72868
72175
  break;
72869
72176
  }
72870
72177
  case "action": {
@@ -73087,7 +72394,7 @@ Inferred class string: "${iconClasses}."`
73087
72394
  line-height: 1.375rem;
73088
72395
  color: ${(props) => props.theme.colors.error};
73089
72396
  `;
73090
- const ErrorText = styled.span`
72397
+ const ErrorText$1 = styled.span`
73091
72398
  font-size: 0.875rem;
73092
72399
  line-height: 1.25rem;
73093
72400
  `;
@@ -73132,7 +72439,7 @@ Inferred class string: "${iconClasses}."`
73132
72439
  const [cssValue] = useVariable(props.config?.raw_css);
73133
72440
  const [styles2, css2] = parseRawCss(cssValue);
73134
72441
  const defaultMessage = props.error instanceof UserError ? props.error.message : "Try again or contact the application owner.";
73135
- return /* @__PURE__ */ React.createElement(ErrorDisplayWrapper, { $rawCss: css2, style: styles2 }, /* @__PURE__ */ React.createElement(ContentWrapper, null, /* @__PURE__ */ React.createElement(ErrorContent, null, /* @__PURE__ */ React.createElement(ErrorTitle$1, null, /* @__PURE__ */ React.createElement(IconWrapper, null, /* @__PURE__ */ React.createElement(ErrorIcon, { "aria-hidden": true, className: "fa-solid fa-circle-xmark fa-lg" })), props?.config?.title ?? "Error"), /* @__PURE__ */ React.createElement(ErrorText, null, props?.config?.description ?? defaultMessage))), props.resetErrorBoundary && /* @__PURE__ */ React.createElement(RetryButton, { onClick: () => props.resetErrorBoundary(props.error), type: "button" }, /* @__PURE__ */ React.createElement("i", { "aria-hidden": true, className: "fa-solid fa-rotate fa-xl" })));
72442
+ return /* @__PURE__ */ React.createElement(ErrorDisplayWrapper, { $rawCss: css2, style: styles2 }, /* @__PURE__ */ React.createElement(ContentWrapper, null, /* @__PURE__ */ React.createElement(ErrorContent, null, /* @__PURE__ */ React.createElement(ErrorTitle$1, null, /* @__PURE__ */ React.createElement(IconWrapper, null, /* @__PURE__ */ React.createElement(ErrorIcon, { "aria-hidden": true, className: "fa-solid fa-circle-xmark fa-lg" })), props?.config?.title ?? "Error"), /* @__PURE__ */ React.createElement(ErrorText$1, null, props?.config?.description ?? defaultMessage))), props.resetErrorBoundary && /* @__PURE__ */ React.createElement(RetryButton, { onClick: () => props.resetErrorBoundary(props.error), type: "button" }, /* @__PURE__ */ React.createElement("i", { "aria-hidden": true, className: "fa-solid fa-rotate fa-xl" })));
73136
72443
  }
73137
72444
  function cleanProps(props) {
73138
72445
  if ("children" in props && Array.isArray(props.children)) {
@@ -73927,7 +73234,7 @@ Inferred class string: "${iconClasses}."`
73927
73234
  }, [wsClient]);
73928
73235
  return /* @__PURE__ */ React.createElement(websocketCtx.Provider, { value: { client: wsClient } }, /* @__PURE__ */ React.createElement(DynamicContext, { contextComponents: props.daraData.context_components }, /* @__PURE__ */ React.createElement(StoreProviders, null, /* @__PURE__ */ React.createElement(ServerVariableSyncProvider, null, /* @__PURE__ */ React.createElement(RootWrapper, null, /* @__PURE__ */ React.createElement(NotificationWrapper, null), /* @__PURE__ */ React.createElement(Outlet, null), /* @__PURE__ */ React.createElement(VariableStateProvider, { wsClient }), props.daraData.enable_devtools && /* @__PURE__ */ React.createElement(DevTools, null))))));
73929
73236
  }
73930
- const Wrapper = styled.div`
73237
+ const Wrapper$1 = styled.div`
73931
73238
  overflow: auto;
73932
73239
  display: flex;
73933
73240
  flex: 1 1 auto;
@@ -73938,6 +73245,1097 @@ Inferred class string: "${iconClasses}."`
73938
73245
 
73939
73246
  background-color: ${(props) => props.backgroundColor};
73940
73247
  `;
73248
+ class SingleUseCache {
73249
+ constructor(options = {}) {
73250
+ this.cache = /* @__PURE__ */ new Map();
73251
+ this.defaultTimeout = options.defaultTimeout ?? 5e3;
73252
+ }
73253
+ isEntryStale(entry, timeout) {
73254
+ const timeoutMs = timeout ?? this.defaultTimeout;
73255
+ return Date.now() - entry.timestamp > timeoutMs;
73256
+ }
73257
+ has(key, timeout) {
73258
+ const entry = this.cache.get(key);
73259
+ return entry ? !this.isEntryStale(entry, timeout) : false;
73260
+ }
73261
+ get(key, timeout) {
73262
+ const entry = this.cache.get(key);
73263
+ if (!entry || this.isEntryStale(entry, timeout)) {
73264
+ return void 0;
73265
+ }
73266
+ this.delete(key);
73267
+ return entry.data;
73268
+ }
73269
+ set(key, value) {
73270
+ this.cache.set(key, {
73271
+ data: value,
73272
+ timestamp: Date.now()
73273
+ });
73274
+ }
73275
+ delete(key) {
73276
+ return this.cache.delete(key);
73277
+ }
73278
+ clear() {
73279
+ this.cache.clear();
73280
+ }
73281
+ /**
73282
+ * Set a value if it doesn't exist in the cache, otherwise return the existing value.
73283
+ * The promise resolves the the new or existing value stored.
73284
+ *
73285
+ * @param key cache key
73286
+ * @param computeFn function to compute the value
73287
+ * @param timeout optional timeout in ms
73288
+ */
73289
+ setIfMissing(key, computeFn, timeout) {
73290
+ const entry = this.cache.get(key);
73291
+ if (entry && !this.isEntryStale(entry, timeout)) {
73292
+ return Promise.resolve(entry.data);
73293
+ }
73294
+ const promise = computeFn();
73295
+ this.set(key, promise);
73296
+ return promise;
73297
+ }
73298
+ size() {
73299
+ return this.cache.size;
73300
+ }
73301
+ keys() {
73302
+ return this.cache.keys();
73303
+ }
73304
+ entries() {
73305
+ return Array.from(this.cache.entries()).map(([key, entry]) => [key, entry.data]);
73306
+ }
73307
+ }
73308
+ const NormalizedObject = object$3({
73309
+ data: any(),
73310
+ lookup: record(string(), any())
73311
+ });
73312
+ const TemplateChunk = object$3({
73313
+ type: literal("template"),
73314
+ template: NormalizedObject
73315
+ });
73316
+ const ActionChunk = object$3({
73317
+ type: literal("actions"),
73318
+ actions: record(string(), array$3(ActionImpl))
73319
+ });
73320
+ const DerivedVariableChunk = object$3({
73321
+ type: literal("derived_variable"),
73322
+ uid: string(),
73323
+ result: object$3({ ok: boolean(), value: any() })
73324
+ });
73325
+ const PyComponentChunk = object$3({
73326
+ type: literal("py_component"),
73327
+ uid: string(),
73328
+ result: object$3({ ok: boolean(), value: any() })
73329
+ });
73330
+ const ResponseChunk = union([TemplateChunk, ActionChunk, DerivedVariableChunk, PyComponentChunk]);
73331
+ const PRELOAD_TIMEOUT = 5e3;
73332
+ const preloadCache = new SingleUseCache({
73333
+ defaultTimeout: PRELOAD_TIMEOUT
73334
+ });
73335
+ function createCacheKey(routeId, params) {
73336
+ return `${routeId}:${JSON.stringify(params)}`;
73337
+ }
73338
+ async function* ndjson(response, signal) {
73339
+ const reader = response.body.getReader();
73340
+ const newline = /\r?\n/;
73341
+ const decoder = new TextDecoder();
73342
+ let buffer = "";
73343
+ while (true) {
73344
+ if (signal?.aborted) {
73345
+ throw new DOMException("The operation was aborted", "AbortError");
73346
+ }
73347
+ const { done, value } = await reader.read();
73348
+ if (done) {
73349
+ if (buffer.length > 0) {
73350
+ yield JSON.parse(buffer);
73351
+ }
73352
+ return;
73353
+ }
73354
+ const chunk = decoder.decode(value, { stream: true });
73355
+ buffer += chunk;
73356
+ const parts = buffer.split(newline);
73357
+ buffer = parts.pop();
73358
+ for (const part of parts) {
73359
+ yield JSON.parse(part);
73360
+ }
73361
+ }
73362
+ }
73363
+ async function fetchRouteData(route, params, snapshot, signal) {
73364
+ let actions = [];
73365
+ if (Array.isArray(route.on_load)) {
73366
+ actions = route.on_load;
73367
+ } else if (route.on_load) {
73368
+ actions = [route.on_load];
73369
+ }
73370
+ const actionPayloads = actions.filter(isAnnotatedAction).map((a2) => {
73371
+ const kwargs = cleanKwargs(
73372
+ Object.fromEntries(
73373
+ Object.entries(a2.dynamic_kwargs).map(([k, v]) => {
73374
+ return [k, resolveVariableStatic(v, snapshot, params)];
73375
+ })
73376
+ ),
73377
+ null
73378
+ );
73379
+ return {
73380
+ uid: a2.uid,
73381
+ definition_uid: a2.definition_uid,
73382
+ values: normalizeRequest(kwargs, a2.dynamic_kwargs)
73383
+ };
73384
+ });
73385
+ const dvHandles = Object.values(route.dependency_graph?.derived_variables ?? {}).flatMap((dv) => {
73386
+ const handle = preloadDerivedVariable(dv, snapshot, params);
73387
+ if (!handle) {
73388
+ return [];
73389
+ }
73390
+ return {
73391
+ ...handle,
73392
+ dv,
73393
+ payload: {
73394
+ values: normalizeRequest(cleanArgs(handle.result.values, null), dv.variables),
73395
+ uid: dv.uid
73396
+ }
73397
+ };
73398
+ });
73399
+ const pyHandles = Object.values(route.dependency_graph?.py_components ?? {}).flatMap((py) => {
73400
+ const handle = preloadServerComponent(py, snapshot, params);
73401
+ if (!handle) {
73402
+ return [];
73403
+ }
73404
+ const kwargValues = cleanKwargs(
73405
+ Object.keys(py.props.dynamic_kwargs).reduce(
73406
+ (acc, k, idx) => {
73407
+ acc[k] = handle.result.values[idx];
73408
+ return acc;
73409
+ },
73410
+ {}
73411
+ )
73412
+ );
73413
+ return {
73414
+ ...handle,
73415
+ py,
73416
+ payload: {
73417
+ uid: py.uid,
73418
+ name: py.name,
73419
+ values: normalizeRequest(kwargValues, py.props.dynamic_kwargs)
73420
+ }
73421
+ };
73422
+ });
73423
+ const dvHandlesByUid = dvHandles.reduce(
73424
+ (acc, h) => ({ ...acc, [h.dv.uid]: h }),
73425
+ {}
73426
+ );
73427
+ const pyHandlesByUid = pyHandles.reduce(
73428
+ (acc, h) => ({ ...acc, [h.py.uid]: h }),
73429
+ {}
73430
+ );
73431
+ const wsClient = await window.dara.ws.getValue();
73432
+ const wsChannel = await wsClient.getChannel();
73433
+ const response = await request(`/api/core/route/${route.id}`, {
73434
+ method: HTTP_METHOD.POST,
73435
+ body: JSON.stringify({
73436
+ action_payloads: actionPayloads,
73437
+ derived_variable_payloads: dvHandles.map((h) => h.payload),
73438
+ py_component_payloads: pyHandles.map((h) => h.payload),
73439
+ ws_channel: wsChannel,
73440
+ params
73441
+ }),
73442
+ signal
73443
+ });
73444
+ await handleAuthErrors(response, true);
73445
+ if (!response.ok) {
73446
+ const error = await response.json();
73447
+ throw new LoaderError(error.detail);
73448
+ }
73449
+ const template = deferred();
73450
+ const onLoadActions = deferred();
73451
+ const resolvedDvs = /* @__PURE__ */ new Set();
73452
+ const resolvedPyComponents = /* @__PURE__ */ new Set();
73453
+ queueMicrotask(async () => {
73454
+ try {
73455
+ for await (const data2 of ndjson(response, signal)) {
73456
+ const chunk = ResponseChunk.parse(data2);
73457
+ if (chunk.type === "template") {
73458
+ const component = denormalize(chunk.template.data, chunk.template.lookup);
73459
+ template.resolve(component);
73460
+ }
73461
+ if (chunk.type === "actions") {
73462
+ onLoadActions.resolve(actions.flatMap((a2) => isAnnotatedAction(a2) ? chunk.actions[a2.uid] : a2));
73463
+ }
73464
+ if (chunk.type === "derived_variable") {
73465
+ dvHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
73466
+ resolvedDvs.add(chunk.uid);
73467
+ }
73468
+ if (chunk.type === "py_component") {
73469
+ pyHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
73470
+ resolvedPyComponents.add(chunk.uid);
73471
+ }
73472
+ }
73473
+ } catch (e2) {
73474
+ template.reject(e2);
73475
+ onLoadActions.reject(e2);
73476
+ for (const [uid2, handle] of Object.entries(dvHandlesByUid)) {
73477
+ if (!resolvedDvs.has(uid2)) {
73478
+ handle.handle.reject(e2);
73479
+ }
73480
+ }
73481
+ for (const [uid2, handle] of Object.entries(pyHandlesByUid)) {
73482
+ if (!resolvedPyComponents.has(uid2)) {
73483
+ handle.handle.reject(e2);
73484
+ }
73485
+ }
73486
+ }
73487
+ });
73488
+ const [templateValue, onLoadActionsValue] = await Promise.all([template.getValue(), onLoadActions.getValue()]);
73489
+ return {
73490
+ template: templateValue,
73491
+ on_load: onLoadActionsValue,
73492
+ route_definition: route,
73493
+ py_components: pyHandles,
73494
+ derived_variables: dvHandles
73495
+ };
73496
+ }
73497
+ function getFromPreloadCache(routeId, params) {
73498
+ return preloadCache.get(createCacheKey(routeId, params));
73499
+ }
73500
+ function usePreloadRoute() {
73501
+ const currentMatches = useMatches();
73502
+ const { routeObjects, routeDefMap } = useRouterContext();
73503
+ return Recoil_index_31(
73504
+ ({ snapshot }) => async (url) => {
73505
+ const matches2 = matchRoutes(routeObjects, url, window.dara?.base_url);
73506
+ if (!matches2) {
73507
+ return;
73508
+ }
73509
+ const release = snapshot.retain();
73510
+ try {
73511
+ await Promise.all(
73512
+ matches2.filter(
73513
+ (match2) => !currentMatches.some(
73514
+ (m) => m.id === match2.route.id && isEqual$4(m.params, match2.params)
73515
+ )
73516
+ ).map((match2) => {
73517
+ const routeDef = routeDefMap.get(match2.route.id);
73518
+ if (!routeDef) {
73519
+ return Promise.resolve();
73520
+ }
73521
+ return preloadCache.setIfMissing(createCacheKey(routeDef.id, match2.params), () => {
73522
+ return fetchRouteData(routeDef, match2.params, snapshot);
73523
+ });
73524
+ })
73525
+ );
73526
+ } finally {
73527
+ release();
73528
+ }
73529
+ },
73530
+ [routeDefMap, routeObjects, currentMatches]
73531
+ );
73532
+ }
73533
+ const STORE_EXTRAS_MAP = /* @__PURE__ */ new Map();
73534
+ const STORE_VARIABLE_MAP = /* @__PURE__ */ new Map();
73535
+ const STORE_SEQUENCE_MAP = /* @__PURE__ */ new Map();
73536
+ const STORE_LATEST_VALUE_MAP = /* @__PURE__ */ new Map();
73537
+ const ROUTE_MATCHES_KEY = "__route_matches";
73538
+ function BackendStoreSync({ children }) {
73539
+ const { client: client2 } = React__namespace.useContext(websocketCtx);
73540
+ const getStoreValue = React__namespace.useCallback(async (itemKey) => {
73541
+ const serializableExtras = STORE_EXTRAS_MAP.get(itemKey);
73542
+ const response = await request(`/api/core/store/${itemKey}`, {}, serializableExtras?.extras ?? {});
73543
+ await handleAuthErrors(response, true);
73544
+ await validateResponse(response, `Failed to fetch the store value for key: ${itemKey}`);
73545
+ const { value, sequence_number } = await response.json();
73546
+ STORE_LATEST_VALUE_MAP.set(itemKey, value);
73547
+ STORE_SEQUENCE_MAP.set(itemKey, sequence_number);
73548
+ return value;
73549
+ }, []);
73550
+ const syncStoreValues = React__namespace.useCallback(
73551
+ async ({ diff }) => {
73552
+ const extrasMap = /* @__PURE__ */ new Map();
73553
+ Array.from(diff.entries()).filter(
73554
+ ([itemKey, value]) => !STORE_LATEST_VALUE_MAP.has(itemKey) || STORE_LATEST_VALUE_MAP.get(itemKey) !== value
73555
+ ).forEach(([itemKey, value]) => {
73556
+ STORE_LATEST_VALUE_MAP.set(itemKey, value);
73557
+ const extras = STORE_EXTRAS_MAP.get(itemKey);
73558
+ if (!extrasMap.has(extras)) {
73559
+ extrasMap.set(extras, {});
73560
+ }
73561
+ extrasMap.get(extras)[itemKey] = value;
73562
+ });
73563
+ async function sendRequest(serializableExtras, storeDiff) {
73564
+ const response = await request(
73565
+ `/api/core/store`,
73566
+ {
73567
+ body: JSON.stringify({
73568
+ values: storeDiff,
73569
+ ws_channel: await client2.getChannel()
73570
+ }),
73571
+ method: "POST"
73572
+ },
73573
+ serializableExtras.extras
73574
+ );
73575
+ await handleAuthErrors(response, true);
73576
+ await validateResponse(response, `Failed to sync the store values`);
73577
+ }
73578
+ await Promise.allSettled(
73579
+ Array.from(extrasMap.entries()).map(
73580
+ ([serializableExtras, storeDiff]) => sendRequest(serializableExtras, storeDiff)
73581
+ )
73582
+ );
73583
+ },
73584
+ [client2]
73585
+ );
73586
+ const applyPatchesToAtoms = Recoil_index_31(
73587
+ ({ snapshot, set: set2 }) => async (storeUid, patches, sequenceNumber) => {
73588
+ const expectedSequence = STORE_SEQUENCE_MAP.get(storeUid) || 0;
73589
+ if (sequenceNumber !== expectedSequence + 1) {
73590
+ console.warn(
73591
+ `Sequence number mismatch for store ${storeUid}. Expected: ${expectedSequence + 1}, Got: ${sequenceNumber}. Rejecting patch.`
73592
+ );
73593
+ return;
73594
+ }
73595
+ STORE_SEQUENCE_MAP.set(storeUid, sequenceNumber);
73596
+ const variableUids = STORE_VARIABLE_MAP.get(storeUid);
73597
+ if (!variableUids) {
73598
+ return;
73599
+ }
73600
+ const atomsToUpdate = [];
73601
+ for (const variableUid of variableUids) {
73602
+ const directAtom = atomRegistry.get(variableUid);
73603
+ if (directAtom) {
73604
+ atomsToUpdate.push({ atom: directAtom, variableUid });
73605
+ continue;
73606
+ }
73607
+ const atomFamily2 = atomFamilyRegistry.get(variableUid);
73608
+ if (atomFamily2) {
73609
+ const familyMembers = atomFamilyMembersRegistry.get(atomFamily2);
73610
+ if (familyMembers) {
73611
+ for (const [, atomInstance] of familyMembers) {
73612
+ atomsToUpdate.push({ atom: atomInstance, variableUid });
73613
+ }
73614
+ }
73615
+ }
73616
+ }
73617
+ const currentValues = await Promise.all(
73618
+ atomsToUpdate.map(async ({ atom: atom2, variableUid }) => {
73619
+ try {
73620
+ return {
73621
+ atom: atom2,
73622
+ variableUid,
73623
+ currentValue: await snapshot.getPromise(atom2),
73624
+ error: null
73625
+ };
73626
+ } catch (error) {
73627
+ return {
73628
+ atom: atom2,
73629
+ variableUid,
73630
+ currentValue: null,
73631
+ error
73632
+ };
73633
+ }
73634
+ })
73635
+ );
73636
+ const applyPatchToValue = (currentValue, variableUid) => {
73637
+ try {
73638
+ return applyPatch(currentValue, patches, false, false).newDocument;
73639
+ } catch (error) {
73640
+ console.warn(`Failed to apply patch to atom ${variableUid}:`, error);
73641
+ return currentValue;
73642
+ }
73643
+ };
73644
+ currentValues.forEach(({ atom: atom2, variableUid, currentValue, error }) => {
73645
+ if (error) {
73646
+ console.warn(`Failed to read current value for atom ${variableUid}:`, error);
73647
+ return;
73648
+ }
73649
+ const patchedValue = applyPatchToValue(currentValue, variableUid);
73650
+ set2(atom2, patchedValue);
73651
+ STORE_LATEST_VALUE_MAP.set(storeUid, patchedValue);
73652
+ });
73653
+ },
73654
+ []
73655
+ );
73656
+ const listenToStoreChanges = React__namespace.useCallback(
73657
+ ({ updateItem }) => {
73658
+ if (!client2) {
73659
+ return;
73660
+ }
73661
+ const valueSub = client2.backendStoreMessages$().subscribe((message) => {
73662
+ STORE_SEQUENCE_MAP.set(message.store_uid, message.sequence_number);
73663
+ updateItem(message.store_uid, message.value);
73664
+ STORE_LATEST_VALUE_MAP.set(message.store_uid, message.value);
73665
+ });
73666
+ const patchSub = client2.backendStorePatchMessages$().subscribe((message) => {
73667
+ applyPatchesToAtoms(message.store_uid, message.patches, message.sequence_number);
73668
+ });
73669
+ return () => {
73670
+ valueSub.unsubscribe();
73671
+ patchSub.unsubscribe();
73672
+ };
73673
+ },
73674
+ [client2, applyPatchesToAtoms]
73675
+ );
73676
+ return /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "BackendStore", write: syncStoreValues }, children);
73677
+ }
73678
+ function backendStoreEffect(variable, requestExtras) {
73679
+ STORE_EXTRAS_MAP.set(variable.store.uid, requestExtras);
73680
+ if (!STORE_VARIABLE_MAP.has(variable.store.uid)) {
73681
+ STORE_VARIABLE_MAP.set(variable.store.uid, /* @__PURE__ */ new Set());
73682
+ }
73683
+ STORE_VARIABLE_MAP.get(variable.store.uid).add(variable.uid);
73684
+ return RecoilSync_index_2({
73685
+ /** Use store uid as the unique identifier */
73686
+ itemKey: variable.store.uid,
73687
+ refine: Refine_index_6(),
73688
+ storeKey: "BackendStore",
73689
+ write({ write: write2 }, newValue) {
73690
+ if (variable.store.readonly) {
73691
+ return;
73692
+ }
73693
+ if (newValue instanceof Recoil_index_1) {
73694
+ return;
73695
+ }
73696
+ write2(variable.store.uid, newValue);
73697
+ }
73698
+ });
73699
+ }
73700
+ function getSessionKey(uid2) {
73701
+ if (isEmbedded()) {
73702
+ return `dara-session-${window.frameElement.dataset.daraPageId}-var-${uid2}`;
73703
+ }
73704
+ return `dara-session-${getSessionToken()}-var-${uid2}`;
73705
+ }
73706
+ function BrowserStoreSync({ children }) {
73707
+ const getStoreValue = React__namespace.useCallback((itemKey) => {
73708
+ const key = getSessionKey(itemKey);
73709
+ return JSON.parse(localStorage.getItem(key) ?? "null");
73710
+ }, []);
73711
+ const syncStoreValues = React__namespace.useCallback(({ diff }) => {
73712
+ for (const [itemKey, value] of diff.entries()) {
73713
+ const key = getSessionKey(itemKey);
73714
+ localStorage.setItem(key, JSON.stringify(value));
73715
+ }
73716
+ }, []);
73717
+ const listenToStoreChanges = React__namespace.useCallback(({ updateItem }) => {
73718
+ const listener2 = (e2) => {
73719
+ if (e2.storageArea === localStorage) {
73720
+ if (e2.key) {
73721
+ const match2 = e2.key.match(/^dara-session-(.*)-var-(.*)$/);
73722
+ if (match2) {
73723
+ const [, sessionToken, uid2] = match2;
73724
+ if (sessionToken === getSessionToken()) {
73725
+ updateItem(uid2, JSON.parse(e2.newValue ?? "null"));
73726
+ }
73727
+ }
73728
+ }
73729
+ }
73730
+ };
73731
+ window.addEventListener("storage", listener2);
73732
+ return () => {
73733
+ window.removeEventListener("storage", listener2);
73734
+ };
73735
+ }, []);
73736
+ return /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "BrowserStore", write: syncStoreValues }, children);
73737
+ }
73738
+ function PathParamSync({ children }) {
73739
+ const navigate = useNavigate();
73740
+ const location2 = useLocation();
73741
+ const locationRef = useLatestRef$3(location2);
73742
+ const matches2 = useMatches();
73743
+ const matchesRef = useLatestRef$3(matches2);
73744
+ const params = useParams();
73745
+ const paramsRef = React__namespace.useRef(params);
73746
+ const locationSubscribers = React__namespace.useRef([]);
73747
+ React__namespace.useLayoutEffect(() => {
73748
+ if (isEqual$4(paramsRef.current, params)) {
73749
+ return;
73750
+ }
73751
+ paramsRef.current = params;
73752
+ for (const subscriber of locationSubscribers.current) {
73753
+ subscriber(params);
73754
+ }
73755
+ }, [paramsRef, params]);
73756
+ const getStoreValue = React__namespace.useCallback(
73757
+ (paramName) => {
73758
+ return paramsRef.current[paramName] ?? null;
73759
+ },
73760
+ [paramsRef]
73761
+ );
73762
+ const writeStoreValue = React__namespace.useCallback(
73763
+ async ({ diff }) => {
73764
+ const newParams = mapValues({ ...paramsRef.current, ...Object.fromEntries(diff) }, (v) => String(v));
73765
+ const loaderData = matchesRef.current.at(-1).loaderData;
73766
+ const data2 = loaderData.data instanceof Promise ? await loaderData.data : loaderData.data;
73767
+ const fullPathname = data2.route_definition.full_path;
73768
+ navigate({
73769
+ pathname: generatePath(fullPathname, newParams),
73770
+ // preserve current search
73771
+ search: locationRef.current.search
73772
+ });
73773
+ },
73774
+ [matchesRef, navigate, paramsRef, locationRef]
73775
+ );
73776
+ const listenToStoreChanges = React__namespace.useCallback(({ updateItems }) => {
73777
+ function handleUpdate(newParams) {
73778
+ updateItems(new Map(Object.entries(newParams)));
73779
+ }
73780
+ locationSubscribers.current.push(handleUpdate);
73781
+ return () => {
73782
+ locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handleUpdate);
73783
+ };
73784
+ }, []);
73785
+ return /* @__PURE__ */ React__namespace.createElement(
73786
+ RecoilSync_index_1,
73787
+ {
73788
+ listen: listenToStoreChanges,
73789
+ read: getStoreValue,
73790
+ write: writeStoreValue,
73791
+ storeKey: "_PathParamStore"
73792
+ },
73793
+ children
73794
+ );
73795
+ }
73796
+ function RouteMatchSync({ children }) {
73797
+ const routerCtx = useRouterContext();
73798
+ const matches2 = useMatches();
73799
+ const matchesRef = React__namespace.useRef(matches2);
73800
+ const matchesSubscribers = React__namespace.useRef([]);
73801
+ React__namespace.useLayoutEffect(() => {
73802
+ if (isEqual$4(matchesRef.current, matches2)) {
73803
+ return;
73804
+ }
73805
+ matchesRef.current = matches2;
73806
+ for (const subscriber of matchesSubscribers.current) {
73807
+ subscriber(matches2);
73808
+ }
73809
+ }, [matchesRef, matches2]);
73810
+ const getStoreValue = React__namespace.useCallback(() => {
73811
+ return createRouteMatches(matchesRef.current, routerCtx.routeDefMap);
73812
+ }, [matchesRef, routerCtx.routeDefMap]);
73813
+ const listenToStoreChanges = React__namespace.useCallback(
73814
+ ({ updateAllKnownItems }) => {
73815
+ function handleUpdate(newMatches) {
73816
+ const newRouteMatches = createRouteMatches(newMatches, routerCtx.routeDefMap);
73817
+ updateAllKnownItems(/* @__PURE__ */ new Map([[ROUTE_MATCHES_KEY, newRouteMatches]]));
73818
+ }
73819
+ matchesSubscribers.current.push(handleUpdate);
73820
+ return () => {
73821
+ matchesSubscribers.current = matchesSubscribers.current.filter((item) => item !== handleUpdate);
73822
+ };
73823
+ },
73824
+ [routerCtx.routeDefMap]
73825
+ );
73826
+ return (
73827
+ // NOTE: write is not defined as we don't support updating the route matches
73828
+ /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "_RouteMatchStore" }, children)
73829
+ );
73830
+ }
73831
+ function localStorageEffect(variable, extrasSerializable, wsClient, taskContext) {
73832
+ let firstRun = false;
73833
+ return RecoilSync_index_2({
73834
+ itemKey: variable.uid,
73835
+ read: ({ read: read2 }) => {
73836
+ const readValue = read2(variable.uid);
73837
+ if (!firstRun) {
73838
+ firstRun = true;
73839
+ if (!readValue) {
73840
+ const isDefaultDerived = isDerivedVariable(variable.default);
73841
+ return isDefaultDerived ? getOrRegisterDerivedVariable(
73842
+ variable.default,
73843
+ wsClient,
73844
+ taskContext,
73845
+ extrasSerializable.extras
73846
+ ) : variable.default;
73847
+ }
73848
+ }
73849
+ return readValue;
73850
+ },
73851
+ refine: Refine_index_6(),
73852
+ storeKey: "BrowserStore"
73853
+ });
73854
+ }
73855
+ function urlEffect(variable) {
73856
+ return RecoilSync_index_6({
73857
+ history: "push",
73858
+ itemKey: variable.store.query,
73859
+ refine: Refine_index_6()
73860
+ });
73861
+ }
73862
+ function pathParamEffect(variable) {
73863
+ const itemKey = variable.store.param_name;
73864
+ const effect2 = RecoilSync_index_2({
73865
+ itemKey,
73866
+ refine: Refine_index_6(),
73867
+ storeKey: "_PathParamStore"
73868
+ });
73869
+ return (effectParams) => {
73870
+ const cleanup = effect2(effectParams);
73871
+ effectParams.setSelf(effectParams.getLoadable(effectParams.node).valueOrThrow());
73872
+ return () => {
73873
+ cleanup?.();
73874
+ };
73875
+ };
73876
+ }
73877
+ function routeMatchEffect() {
73878
+ const effect2 = RecoilSync_index_2({
73879
+ itemKey: ROUTE_MATCHES_KEY,
73880
+ refine: Refine_index_6(),
73881
+ storeKey: "_RouteMatchStore"
73882
+ });
73883
+ return (effectParams) => {
73884
+ const cleanup = effect2(effectParams);
73885
+ effectParams.setSelf(effectParams.getLoadable(effectParams.node).valueOrThrow());
73886
+ return () => {
73887
+ cleanup?.();
73888
+ };
73889
+ };
73890
+ }
73891
+ const STORES = {
73892
+ BackendStore: {
73893
+ effect: backendStoreEffect
73894
+ },
73895
+ BrowserStore: {
73896
+ effect: localStorageEffect
73897
+ },
73898
+ QueryParamStore: {
73899
+ effect: urlEffect
73900
+ },
73901
+ _PathParamStore: {
73902
+ effect: pathParamEffect
73903
+ },
73904
+ _RouteMatchStore: {
73905
+ effect: routeMatchEffect
73906
+ }
73907
+ };
73908
+ function getEffect(variable) {
73909
+ const storeName = variable.store?.__typename;
73910
+ if (!storeName || !(storeName in STORES)) {
73911
+ return null;
73912
+ }
73913
+ return STORES[storeName]?.effect ?? null;
73914
+ }
73915
+ function StoreProviders({ children }) {
73916
+ return /* @__PURE__ */ React__namespace.createElement(BackendStoreSync, null, /* @__PURE__ */ React__namespace.createElement(BrowserStoreSync, null, children));
73917
+ }
73918
+ function warnUpdateOnDerivedState() {
73919
+ console.warn("You tried to call update on variable with derived state, this is a noop and will be ignored.");
73920
+ }
73921
+ function useVariable(variable, opts = { serverVariable: "disallow" }) {
73922
+ const extras = useRequestExtras();
73923
+ const { client: wsClient } = React$1.useContext(websocketCtx);
73924
+ const taskContext = useTaskContext();
73925
+ const variablesContext = React$1.useContext(variablesCtx);
73926
+ const bus = useEventBus();
73927
+ if (!isVariable(variable)) {
73928
+ const [state, setState] = React$1.useState(variable);
73929
+ const [prevVariable, setPrevVariable] = React$1.useState(variable);
73930
+ if (!isEqual$4(variable, prevVariable)) {
73931
+ setState(variable);
73932
+ setPrevVariable(variable);
73933
+ }
73934
+ return [state, setState];
73935
+ }
73936
+ variablesContext?.variables.current.add(variable.uid);
73937
+ React$1.useEffect(() => {
73938
+ return () => {
73939
+ variablesContext?.variables.current.delete(variable.uid);
73940
+ };
73941
+ }, []);
73942
+ if (isDerivedVariable(variable)) {
73943
+ const selector2 = useDerivedVariable(variable, wsClient, taskContext, extras);
73944
+ const selectorLoadable = Recoil_index_28(selector2);
73945
+ React$1.useEffect(() => {
73946
+ if (selectorLoadable.state !== "loading") {
73947
+ bus.publish("DERIVED_VARIABLE_LOADED", { variable, value: selectorLoadable.contents });
73948
+ }
73949
+ }, [selectorLoadable]);
73950
+ const deferred22 = useDeferLoadable(selectorLoadable, opts.suspend);
73951
+ return [deferred22, warnUpdateOnDerivedState];
73952
+ }
73953
+ if (isSwitchVariable(variable)) {
73954
+ return [useSwitchVariable(variable), warnUpdateOnDerivedState];
73955
+ }
73956
+ if (isStateVariable(variable)) {
73957
+ const parentSelector = useDerivedVariable(variable.parent_variable, wsClient, taskContext, extras);
73958
+ const parentLoadable = Recoil_index_28(parentSelector);
73959
+ let stateValue;
73960
+ switch (variable.property_name) {
73961
+ case "loading":
73962
+ stateValue = parentLoadable.state === "loading";
73963
+ break;
73964
+ case "error":
73965
+ stateValue = parentLoadable.state === "hasError";
73966
+ break;
73967
+ case "hasValue":
73968
+ stateValue = parentLoadable.state === "hasValue";
73969
+ break;
73970
+ default:
73971
+ stateValue = false;
73972
+ }
73973
+ return [stateValue, warnUpdateOnDerivedState];
73974
+ }
73975
+ if (isServerVariable(variable)) {
73976
+ if (opts.serverVariable === "disallow") {
73977
+ throw new UserError("ServerVariable cannot be directly consumed by this component");
73978
+ }
73979
+ const atom2 = React$1.useMemo(() => getOrRegisterServerVariable(variable, extras), [variable, extras]);
73980
+ const [seqNumber] = Recoil_index_22(atom2);
73981
+ const fetcher = useTabularVariable(variable);
73982
+ const { data: data2 } = reactQuery.useSuspenseQuery({
73983
+ // use the seq number as a dependency to refetch on changes
73984
+ queryKey: ["use-variable-server-variable", variable.uid, seqNumber],
73985
+ queryFn: async () => {
73986
+ const result = await fetcher(null, {
73987
+ limit: 1,
73988
+ offset: 0
73989
+ });
73990
+ return result.data;
73991
+ },
73992
+ refetchOnWindowFocus: false
73993
+ });
73994
+ return [data2?.[0] ?? null, warnUpdateOnDerivedState];
73995
+ }
73996
+ const recoilState = getOrRegisterPlainVariable(variable, wsClient, taskContext, extras);
73997
+ if (!isDerivedVariable(variable.default)) {
73998
+ const [value, setValue] = Recoil_index_22(recoilState);
73999
+ React$1.useEffect(() => {
74000
+ bus.publish("PLAIN_VARIABLE_LOADED", { variable, value });
74001
+ }, [value]);
74002
+ return [value, setValue];
74003
+ }
74004
+ const [loadable, setLoadable] = Recoil_index_23(recoilState);
74005
+ React$1.useEffect(() => {
74006
+ if (loadable.state !== "loading") {
74007
+ bus.publish("PLAIN_VARIABLE_LOADED", { variable, value: loadable.contents });
74008
+ }
74009
+ }, [loadable]);
74010
+ const deferred2 = useDeferLoadable(loadable, opts.suspend);
74011
+ return [deferred2, setLoadable];
74012
+ }
74013
+ function flexStyles(props, displayCtx2, useDisplayContext) {
74014
+ let flexBasis = props.basis;
74015
+ let flexShrink = props.shrink;
74016
+ let flexGrow = props.grow;
74017
+ if (useDisplayContext) {
74018
+ if (props.width && displayCtx2.direction === "horizontal") {
74019
+ flexBasis ??= props.width;
74020
+ flexShrink ??= "0";
74021
+ flexGrow ??= "0";
74022
+ }
74023
+ if (props.height && displayCtx2.direction === "vertical") {
74024
+ flexBasis ??= props.height;
74025
+ flexShrink ??= "0";
74026
+ flexGrow ??= "0";
74027
+ }
74028
+ }
74029
+ if (props.hug || props.hug !== false && displayCtx2.hug) {
74030
+ flexBasis ??= "content";
74031
+ flexShrink ??= "1";
74032
+ flexGrow ??= "0";
74033
+ }
74034
+ return { flexBasis, flexGrow, flexShrink };
74035
+ }
74036
+ function parseRawCss(rawCss) {
74037
+ const isRawObject = typeof rawCss === "object" && rawCss !== null && rawCss !== void 0;
74038
+ const componentCss = !isRawObject && typeof rawCss === "string" ? rawCss : "";
74039
+ const styles2 = isRawObject ? rawCss : {};
74040
+ return [styles2, componentCss];
74041
+ }
74042
+ function useComponentStyles(props, useDisplayContext = true, propName = "raw_css") {
74043
+ const [rawCssValue] = useVariable(props[propName]);
74044
+ const [rawStyles, rawCss] = parseRawCss(rawCssValue);
74045
+ const displayCtx$1 = React$1.useContext(displayCtx);
74046
+ const flexProps = flexStyles(props, displayCtx$1, useDisplayContext);
74047
+ const styles2 = React$1.useMemo(() => {
74048
+ const stylesObj = {
74049
+ backgroundColor: props.background,
74050
+ border: props.border,
74051
+ borderRadius: props.border_radius,
74052
+ color: props.color,
74053
+ fontFamily: props.font,
74054
+ fontSize: props.font_size,
74055
+ fontStyle: props.italic ? "italic" : "normal",
74056
+ fontWeight: props.bold ? "bold" : "normal",
74057
+ gap: props.gap,
74058
+ height: props.height,
74059
+ margin: props.margin,
74060
+ maxHeight: props.max_height,
74061
+ maxWidth: props.max_width,
74062
+ minHeight: props.min_height,
74063
+ minWidth: props.min_width,
74064
+ overflow: props.overflow,
74065
+ padding: props.padding,
74066
+ position: props.position,
74067
+ textDecoration: props.underline ? "underline" : "none",
74068
+ width: props.width,
74069
+ ...flexProps,
74070
+ ...rawStyles,
74071
+ ...props.style ?? {}
74072
+ };
74073
+ return Object.fromEntries(Object.entries(stylesObj).filter(([, v]) => v !== null && v !== void 0));
74074
+ }, [useDeepCompare(props), rawStyles, flexProps]);
74075
+ return [styles2, rawCss];
74076
+ }
74077
+ const StyledDots$1 = injectCss(Dots);
74078
+ function DefaultFallback$1(props) {
74079
+ const [style, css2] = useComponentStyles(props);
74080
+ return /* @__PURE__ */ React.createElement(StyledDots$1, { $rawCss: css2, style });
74081
+ }
74082
+ function DefaultFallbackStatic() {
74083
+ return /* @__PURE__ */ React.createElement(StyledDots$1, { grey3: theme.colors.grey3, grey4: theme.colors.grey4 });
74084
+ }
74085
+ const Wrapper = styled.div`
74086
+ display: flex;
74087
+ flex: 1 1 0%;
74088
+ flex-direction: column;
74089
+ justify-content: center;
74090
+
74091
+ min-height: 100%;
74092
+
74093
+ background: ${(props) => `radial-gradient(circle closest-corner at 50% 40%, ${curriedTransparentize$1(
74094
+ 0.9,
74095
+ props.theme.colors.background
74096
+ )} 0%, ${curriedTransparentize$1(
74097
+ 0.8,
74098
+ props.theme.colors.blue4
74099
+ )} 70%),radial-gradient(circle closest-corner at 20% 150%, ${curriedTransparentize$1(
74100
+ 0.8,
74101
+ props.theme.colors.error
74102
+ )} 0%, ${curriedTransparentize$1(0.2, props.theme.colors.blue4)} 230%)`};
74103
+ `;
74104
+ const Card = styled.div`
74105
+ padding: 1.5rem;
74106
+
74107
+ color: ${(props) => props.theme.colors.text};
74108
+
74109
+ background-color: ${(props) => props.theme.colors.blue1};
74110
+ border-radius: 1rem;
74111
+ box-shadow: ${(props) => props.theme.shadow.medium};
74112
+
74113
+ @media (width >= 640px) {
74114
+ width: 100%;
74115
+ max-width: 24rem;
74116
+ margin-right: auto;
74117
+ margin-left: auto;
74118
+ }
74119
+ `;
74120
+ const FormWrapper = styled.div`
74121
+ margin-top: 1.5rem;
74122
+ `;
74123
+ const Form = styled.form`
74124
+ > * + * {
74125
+ margin-top: 1.5rem;
74126
+ }
74127
+ `;
74128
+ const ErrorText = styled.h3`
74129
+ margin: 0;
74130
+
74131
+ font-size: 0.875rem;
74132
+ font-weight: 500;
74133
+ line-height: 1.25rem;
74134
+ color: ${(props) => props.theme.colors.error};
74135
+ letter-spacing: 0.025em;
74136
+
74137
+ visibility: ${(props) => props.$hidden ? "hidden" : "visible"};
74138
+ `;
74139
+ const Label = styled.label`
74140
+ font-weight: 500;
74141
+ line-height: 1.5rem;
74142
+ `;
74143
+ const StyledInput = styled.input`
74144
+ display: flex;
74145
+ display: block;
74146
+ align-items: center;
74147
+
74148
+ width: 100%;
74149
+ height: 2.5rem;
74150
+ margin-top: 0.5rem;
74151
+ padding: 0 1rem;
74152
+
74153
+ font-size: 1rem;
74154
+ line-height: 1.5rem;
74155
+ color: ${(props) => props.theme.colors.text};
74156
+
74157
+ background-color: ${(props) => props.theme.colors.blue1};
74158
+ border: none;
74159
+ border-radius: 0.25rem;
74160
+ outline: none;
74161
+ box-shadow:
74162
+ inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
74163
+ inset 0 0 0 1px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.grey2},
74164
+ 0 1px 2px 0 rgb(0 0 0 / 5%);
74165
+
74166
+ :active,
74167
+ :focus {
74168
+ box-shadow:
74169
+ inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
74170
+ inset 0 0 0 2px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.primary},
74171
+ 0 1px 2px 0 rgb(0 0 0 / 5%);
74172
+ }
74173
+ `;
74174
+ const StyledButton = styled(Button$1)`
74175
+ width: 100%;
74176
+ font-weight: 600;
74177
+ line-height: 1.5rem;
74178
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
74179
+
74180
+ :active,
74181
+ :focus {
74182
+ outline-color: ${(props) => props.theme.colors.primary};
74183
+ outline-width: 2px;
74184
+ outline-offset: 2px;
74185
+ }
74186
+ `;
74187
+ function BasicAuthLogin() {
74188
+ const [isVerifyingToken, setIsVerifyingToken] = React$1.useState(true);
74189
+ const [isLoggingIn, setIsLoggingIn] = React$1.useState(false);
74190
+ const [username, setUsername] = React$1.useState("");
74191
+ const [password, setPassword] = React$1.useState("");
74192
+ const [isError2, setIsError] = React$1.useState(false);
74193
+ const location2 = useLocation();
74194
+ const navigate = useNavigate();
74195
+ const { defaultPath } = useRouterContext();
74196
+ const queryParams = new URLSearchParams(location2.search);
74197
+ const previousLocation = queryParams.get("referrer") ?? defaultPath;
74198
+ const login = async () => {
74199
+ setIsLoggingIn(true);
74200
+ setIsError(false);
74201
+ try {
74202
+ const sessionToken = await requestSessionToken({ password, username });
74203
+ if (sessionToken) {
74204
+ setSessionToken(sessionToken);
74205
+ navigate(decodeURIComponent(previousLocation));
74206
+ }
74207
+ } catch {
74208
+ setIsError(true);
74209
+ }
74210
+ setIsLoggingIn(false);
74211
+ };
74212
+ React$1.useEffect(() => {
74213
+ if (getSessionToken()) {
74214
+ verifySessionToken().then((verified) => {
74215
+ if (verified) {
74216
+ navigate(decodeURIComponent(previousLocation), { replace: true });
74217
+ } else {
74218
+ setIsVerifyingToken(false);
74219
+ }
74220
+ });
74221
+ } else {
74222
+ setIsVerifyingToken(false);
74223
+ }
74224
+ }, []);
74225
+ if (isVerifyingToken) {
74226
+ return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
74227
+ }
74228
+ return /* @__PURE__ */ React.createElement(Wrapper, null, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(FormWrapper, null, /* @__PURE__ */ React.createElement(
74229
+ Form,
74230
+ {
74231
+ onSubmit: (e2) => {
74232
+ e2.preventDefault();
74233
+ login();
74234
+ }
74235
+ },
74236
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "username" }, "Username"), /* @__PURE__ */ React.createElement(
74237
+ StyledInput,
74238
+ {
74239
+ $error: isError2,
74240
+ id: "username",
74241
+ onChange: (e2) => setUsername(e2.target.value),
74242
+ required: true,
74243
+ type: "text",
74244
+ value: username
74245
+ }
74246
+ )),
74247
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "password" }, "Password"), /* @__PURE__ */ React.createElement(
74248
+ StyledInput,
74249
+ {
74250
+ $error: isError2,
74251
+ id: "password",
74252
+ onChange: (e2) => setPassword(e2.target.value),
74253
+ required: true,
74254
+ type: "password",
74255
+ value: password
74256
+ }
74257
+ )),
74258
+ /* @__PURE__ */ React.createElement(ErrorText, { $hidden: !isError2, style: { marginTop: "1rem" } }, "Incorrect Username or Password"),
74259
+ /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
74260
+ StyledButton,
74261
+ {
74262
+ loading: isLoggingIn,
74263
+ style: { color: "white" },
74264
+ styling: "primary",
74265
+ type: "submit"
74266
+ },
74267
+ "Sign in"
74268
+ ))
74269
+ ))));
74270
+ }
74271
+ function BasicAuthLogout() {
74272
+ React$1.useEffect(() => {
74273
+ revokeSession().then(() => {
74274
+ setSessionToken(null);
74275
+ window.location.href = `${window.dara.base_url}/login`;
74276
+ });
74277
+ }, []);
74278
+ return null;
74279
+ }
74280
+ function DefaultAuthLogin() {
74281
+ const location2 = useLocation();
74282
+ const navigate = useNavigate();
74283
+ const { defaultPath } = useRouterContext();
74284
+ const queryParams = new URLSearchParams(location2.search);
74285
+ const previousLocation = queryParams.get("referrer") ?? defaultPath;
74286
+ async function getNewToken() {
74287
+ const sessionToken = await requestSessionToken({});
74288
+ if (sessionToken) {
74289
+ setSessionToken(sessionToken);
74290
+ navigate(decodeURIComponent(previousLocation));
74291
+ }
74292
+ }
74293
+ React$1.useEffect(() => {
74294
+ if (getSessionToken()) {
74295
+ verifySessionToken().then((verified) => {
74296
+ if (verified) {
74297
+ navigate(decodeURIComponent(previousLocation), { replace: true });
74298
+ } else {
74299
+ getNewToken();
74300
+ }
74301
+ });
74302
+ } else {
74303
+ getNewToken();
74304
+ }
74305
+ }, []);
74306
+ return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
74307
+ }
74308
+ const CenteredDivWithGap$1 = styled(Center)`
74309
+ gap: 1rem;
74310
+ margin: 10px;
74311
+ text-align: center;
74312
+ `;
74313
+ const config401 = {
74314
+ description: "Your login session may have expired. Try again.",
74315
+ styling: "primary",
74316
+ title: "We were not able to authenticate you"
74317
+ };
74318
+ const errorMessages = {
74319
+ "403": {
74320
+ description: "You are not authorised to access this application. Please contact the application owner to enable access.",
74321
+ styling: "error",
74322
+ title: "We were not able to authenticate you"
74323
+ },
74324
+ "404": {
74325
+ description: "The requested page could not be found.",
74326
+ styling: "error",
74327
+ title: "Page not found"
74328
+ },
74329
+ "401": config401,
74330
+ default: config401
74331
+ };
74332
+ function ErrorPage(props) {
74333
+ const { search } = useLocation();
74334
+ const query = React$1.useMemo(() => new URLSearchParams(search), [search]);
74335
+ const code = props.code ?? query.get("code");
74336
+ const errorConfig = code && errorMessages[code] || errorMessages.default;
74337
+ return /* @__PURE__ */ React.createElement(CenteredDivWithGap$1, null, /* @__PURE__ */ React.createElement("h1", null, errorConfig.title), /* @__PURE__ */ React.createElement("p", null, errorConfig.description), /* @__PURE__ */ React.createElement(Button$1, { href: "/login", styling: errorConfig.styling }, "Retry"));
74338
+ }
73941
74339
  const CenteredDivWithGap = styled.div`
73942
74340
  display: flex;
73943
74341
  flex: 1;
@@ -74076,292 +74474,7 @@ body,
74076
74474
  }
74077
74475
  }
74078
74476
  }, [navigation.state]);
74079
- return /* @__PURE__ */ React.createElement(PathParamSync, null, /* @__PURE__ */ React.createElement(RecoilSync_index_3, { ...syncOptions }, /* @__PURE__ */ React.createElement(StyleRoot, null, /* @__PURE__ */ React.createElement(Outlet, null))));
74080
- }
74081
- class SingleUseCache {
74082
- constructor(options = {}) {
74083
- this.cache = /* @__PURE__ */ new Map();
74084
- this.defaultTimeout = options.defaultTimeout ?? 5e3;
74085
- }
74086
- isEntryStale(entry, timeout) {
74087
- const timeoutMs = timeout ?? this.defaultTimeout;
74088
- return Date.now() - entry.timestamp > timeoutMs;
74089
- }
74090
- has(key, timeout) {
74091
- const entry = this.cache.get(key);
74092
- return entry ? !this.isEntryStale(entry, timeout) : false;
74093
- }
74094
- get(key, timeout) {
74095
- const entry = this.cache.get(key);
74096
- if (!entry || this.isEntryStale(entry, timeout)) {
74097
- return void 0;
74098
- }
74099
- this.delete(key);
74100
- return entry.data;
74101
- }
74102
- set(key, value) {
74103
- this.cache.set(key, {
74104
- data: value,
74105
- timestamp: Date.now()
74106
- });
74107
- }
74108
- delete(key) {
74109
- return this.cache.delete(key);
74110
- }
74111
- clear() {
74112
- this.cache.clear();
74113
- }
74114
- /**
74115
- * Set a value if it doesn't exist in the cache, otherwise return the existing value.
74116
- * The promise resolves the the new or existing value stored.
74117
- *
74118
- * @param key cache key
74119
- * @param computeFn function to compute the value
74120
- * @param timeout optional timeout in ms
74121
- */
74122
- setIfMissing(key, computeFn, timeout) {
74123
- const entry = this.cache.get(key);
74124
- if (entry && !this.isEntryStale(entry, timeout)) {
74125
- return Promise.resolve(entry.data);
74126
- }
74127
- const promise = computeFn();
74128
- this.set(key, promise);
74129
- return promise;
74130
- }
74131
- size() {
74132
- return this.cache.size;
74133
- }
74134
- keys() {
74135
- return this.cache.keys();
74136
- }
74137
- entries() {
74138
- return Array.from(this.cache.entries()).map(([key, entry]) => [key, entry.data]);
74139
- }
74140
- }
74141
- const NormalizedObject = object$3({
74142
- data: any(),
74143
- lookup: record(string(), any())
74144
- });
74145
- const TemplateChunk = object$3({
74146
- type: literal("template"),
74147
- template: NormalizedObject
74148
- });
74149
- const ActionChunk = object$3({
74150
- type: literal("actions"),
74151
- actions: record(string(), array$3(ActionImpl))
74152
- });
74153
- const DerivedVariableChunk = object$3({
74154
- type: literal("derived_variable"),
74155
- uid: string(),
74156
- result: object$3({ ok: boolean(), value: any() })
74157
- });
74158
- const PyComponentChunk = object$3({
74159
- type: literal("py_component"),
74160
- uid: string(),
74161
- result: object$3({ ok: boolean(), value: any() })
74162
- });
74163
- const ResponseChunk = union([TemplateChunk, ActionChunk, DerivedVariableChunk, PyComponentChunk]);
74164
- const PRELOAD_TIMEOUT = 5e3;
74165
- const preloadCache = new SingleUseCache({
74166
- defaultTimeout: PRELOAD_TIMEOUT
74167
- });
74168
- function createCacheKey(routeId, params) {
74169
- return `${routeId}:${JSON.stringify(params)}`;
74170
- }
74171
- async function* ndjson(response, signal) {
74172
- const reader = response.body.getReader();
74173
- const newline = /\r?\n/;
74174
- const decoder = new TextDecoder();
74175
- let buffer = "";
74176
- while (true) {
74177
- if (signal?.aborted) {
74178
- throw new DOMException("The operation was aborted", "AbortError");
74179
- }
74180
- const { done, value } = await reader.read();
74181
- if (done) {
74182
- if (buffer.length > 0) {
74183
- yield JSON.parse(buffer);
74184
- }
74185
- return;
74186
- }
74187
- const chunk = decoder.decode(value, { stream: true });
74188
- buffer += chunk;
74189
- const parts = buffer.split(newline);
74190
- buffer = parts.pop();
74191
- for (const part of parts) {
74192
- yield JSON.parse(part);
74193
- }
74194
- }
74195
- }
74196
- async function fetchRouteData(route, params, snapshot, signal) {
74197
- let actions = [];
74198
- if (Array.isArray(route.on_load)) {
74199
- actions = route.on_load;
74200
- } else if (route.on_load) {
74201
- actions = [route.on_load];
74202
- }
74203
- const actionPayloads = actions.filter(isAnnotatedAction).map((a2) => {
74204
- const kwargs = cleanKwargs(
74205
- Object.fromEntries(
74206
- Object.entries(a2.dynamic_kwargs).map(([k, v]) => {
74207
- return [k, resolveVariableStatic(v, snapshot, params)];
74208
- })
74209
- ),
74210
- null
74211
- );
74212
- return {
74213
- uid: a2.uid,
74214
- definition_uid: a2.definition_uid,
74215
- values: normalizeRequest(kwargs, a2.dynamic_kwargs)
74216
- };
74217
- });
74218
- const dvHandles = Object.values(route.dependency_graph?.derived_variables ?? {}).flatMap((dv) => {
74219
- const handle = preloadDerivedVariable(dv, snapshot, params);
74220
- if (!handle) {
74221
- return [];
74222
- }
74223
- return {
74224
- ...handle,
74225
- dv,
74226
- payload: {
74227
- values: normalizeRequest(cleanArgs(handle.result.values, null), dv.variables),
74228
- uid: dv.uid
74229
- }
74230
- };
74231
- });
74232
- const pyHandles = Object.values(route.dependency_graph?.py_components ?? {}).flatMap((py) => {
74233
- const handle = preloadServerComponent(py, snapshot, params);
74234
- if (!handle) {
74235
- return [];
74236
- }
74237
- const kwargValues = cleanKwargs(
74238
- Object.keys(py.props.dynamic_kwargs).reduce(
74239
- (acc, k, idx) => {
74240
- acc[k] = handle.result.values[idx];
74241
- return acc;
74242
- },
74243
- {}
74244
- )
74245
- );
74246
- return {
74247
- ...handle,
74248
- py,
74249
- payload: {
74250
- uid: py.uid,
74251
- name: py.name,
74252
- values: normalizeRequest(kwargValues, py.props.dynamic_kwargs)
74253
- }
74254
- };
74255
- });
74256
- const dvHandlesByUid = dvHandles.reduce(
74257
- (acc, h) => ({ ...acc, [h.dv.uid]: h }),
74258
- {}
74259
- );
74260
- const pyHandlesByUid = pyHandles.reduce(
74261
- (acc, h) => ({ ...acc, [h.py.uid]: h }),
74262
- {}
74263
- );
74264
- const wsClient = await window.dara.ws.getValue();
74265
- const wsChannel = await wsClient.getChannel();
74266
- const response = await request(`/api/core/route/${route.id}`, {
74267
- method: HTTP_METHOD.POST,
74268
- body: JSON.stringify({
74269
- action_payloads: actionPayloads,
74270
- derived_variable_payloads: dvHandles.map((h) => h.payload),
74271
- py_component_payloads: pyHandles.map((h) => h.payload),
74272
- ws_channel: wsChannel,
74273
- params
74274
- }),
74275
- signal
74276
- });
74277
- await handleAuthErrors(response, true);
74278
- if (!response.ok) {
74279
- const error = await response.json();
74280
- throw new LoaderError(error.detail);
74281
- }
74282
- const template = deferred();
74283
- const onLoadActions = deferred();
74284
- const resolvedDvs = /* @__PURE__ */ new Set();
74285
- const resolvedPyComponents = /* @__PURE__ */ new Set();
74286
- queueMicrotask(async () => {
74287
- try {
74288
- for await (const data2 of ndjson(response, signal)) {
74289
- const chunk = ResponseChunk.parse(data2);
74290
- if (chunk.type === "template") {
74291
- const component = denormalize(chunk.template.data, chunk.template.lookup);
74292
- template.resolve(component);
74293
- }
74294
- if (chunk.type === "actions") {
74295
- onLoadActions.resolve(actions.flatMap((a2) => isAnnotatedAction(a2) ? chunk.actions[a2.uid] : a2));
74296
- }
74297
- if (chunk.type === "derived_variable") {
74298
- dvHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
74299
- resolvedDvs.add(chunk.uid);
74300
- }
74301
- if (chunk.type === "py_component") {
74302
- pyHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
74303
- resolvedPyComponents.add(chunk.uid);
74304
- }
74305
- }
74306
- } catch (e2) {
74307
- template.reject(e2);
74308
- onLoadActions.reject(e2);
74309
- for (const [uid2, handle] of Object.entries(dvHandlesByUid)) {
74310
- if (!resolvedDvs.has(uid2)) {
74311
- handle.handle.reject(e2);
74312
- }
74313
- }
74314
- for (const [uid2, handle] of Object.entries(pyHandlesByUid)) {
74315
- if (!resolvedPyComponents.has(uid2)) {
74316
- handle.handle.reject(e2);
74317
- }
74318
- }
74319
- }
74320
- });
74321
- const [templateValue, onLoadActionsValue] = await Promise.all([template.getValue(), onLoadActions.getValue()]);
74322
- return {
74323
- template: templateValue,
74324
- on_load: onLoadActionsValue,
74325
- route_definition: route,
74326
- py_components: pyHandles,
74327
- derived_variables: dvHandles
74328
- };
74329
- }
74330
- function getFromPreloadCache(routeId, params) {
74331
- return preloadCache.get(createCacheKey(routeId, params));
74332
- }
74333
- function usePreloadRoute() {
74334
- const currentMatches = useMatches();
74335
- const { routeObjects, routeDefMap } = useRouterContext();
74336
- return Recoil_index_31(
74337
- ({ snapshot }) => async (url) => {
74338
- const matches2 = matchRoutes(routeObjects, url, window.dara?.base_url);
74339
- if (!matches2) {
74340
- return;
74341
- }
74342
- const release = snapshot.retain();
74343
- try {
74344
- await Promise.all(
74345
- matches2.filter(
74346
- (match2) => !currentMatches.some(
74347
- (m) => m.id === match2.route.id && isEqual$4(m.params, match2.params)
74348
- )
74349
- ).map((match2) => {
74350
- const routeDef = routeDefMap.get(match2.route.id);
74351
- if (!routeDef) {
74352
- return Promise.resolve();
74353
- }
74354
- return preloadCache.setIfMissing(createCacheKey(routeDef.id, match2.params), () => {
74355
- return fetchRouteData(routeDef, match2.params, snapshot);
74356
- });
74357
- })
74358
- );
74359
- } finally {
74360
- release();
74361
- }
74362
- },
74363
- [routeDefMap, routeObjects, currentMatches]
74364
- );
74477
+ return /* @__PURE__ */ React.createElement(PathParamSync, null, /* @__PURE__ */ React.createElement(RouteMatchSync, null, /* @__PURE__ */ React.createElement(RecoilSync_index_3, { ...syncOptions }, /* @__PURE__ */ React.createElement(StyleRoot, null, /* @__PURE__ */ React.createElement(Outlet, null)))));
74365
74478
  }
74366
74479
  function shouldHoldPromise(route) {
74367
74480
  return !route.fallback;
@@ -74538,7 +74651,7 @@ body,
74538
74651
  const { login, logout, ...extraRoutes } = config2.auth_components;
74539
74652
  const routeDefMap = /* @__PURE__ */ new Map();
74540
74653
  const userRoutes = config2.router.children.map((r2) => createRoute(r2, snapshot, routeDefMap));
74541
- const defaultPath = findFirstPath(config2.router.children) || "/";
74654
+ const defaultPath = config2.router.default_path ?? (findFirstPath(config2.router.children) || "/");
74542
74655
  const router = createBrowserRouter(
74543
74656
  [
74544
74657
  {
@@ -74607,7 +74720,8 @@ body,
74607
74720
  routeDefinitions: config2.router.children,
74608
74721
  routeObjects: userRoutes,
74609
74722
  routeDefMap,
74610
- defaultPath
74723
+ defaultPath,
74724
+ routeMatches: config2.router.route_matches
74611
74725
  };
74612
74726
  }
74613
74727
  function RouterRoot({ daraData }) {
@@ -74619,7 +74733,8 @@ body,
74619
74733
  routeDefinitions: routerData.routeDefinitions,
74620
74734
  routeObjects: routerData.routeObjects,
74621
74735
  routeDefMap: routerData.routeDefMap,
74622
- defaultPath: routerData.defaultPath
74736
+ defaultPath: routerData.defaultPath,
74737
+ routeMatches: routerData.routeMatches
74623
74738
  },
74624
74739
  /* @__PURE__ */ React.createElement(RouterProvider2, { router: routerData.router })
74625
74740
  );
@@ -74644,6 +74759,46 @@ body,
74644
74759
  const root = clientExports.createRoot(container);
74645
74760
  root.render(/* @__PURE__ */ React.createElement(Root, { daraData, queryClient }));
74646
74761
  }
74762
+ const safeGeneratePath = (path, params) => {
74763
+ try {
74764
+ return generatePath(path, params);
74765
+ } catch {
74766
+ return path;
74767
+ }
74768
+ };
74769
+ function useResolvedTo(path) {
74770
+ if (typeof path === "string") {
74771
+ return path;
74772
+ }
74773
+ if (!path.params || !path.pathname) {
74774
+ return path;
74775
+ }
74776
+ const resolvedParams = Object.fromEntries(
74777
+ // eslint-disable-next-line react-hooks/rules-of-hooks
74778
+ Object.entries(path.params).map(([key, value]) => [key, useVariable(value)[0]])
74779
+ );
74780
+ const resolvedPath = safeGeneratePath(path.pathname, resolvedParams);
74781
+ return { ...path, pathname: resolvedPath };
74782
+ }
74783
+ async function resolveTo(path, ctx) {
74784
+ if (typeof path === "string") {
74785
+ return path;
74786
+ }
74787
+ if (!path.params || !path.pathname) {
74788
+ return path;
74789
+ }
74790
+ const values = await Promise.all(
74791
+ Object.values(path.params).map((value) => {
74792
+ if (!isVariable(value)) {
74793
+ return Promise.resolve(value);
74794
+ }
74795
+ return resolveVariable(value, ctx.wsClient, ctx.taskCtx, ctx.extras, (v) => ctx.snapshot.getPromise(v));
74796
+ })
74797
+ );
74798
+ const resolvedParams = Object.fromEntries(Object.keys(path.params).map((key, idx) => [key, values[idx]]));
74799
+ const resolvedPath = safeGeneratePath(path.pathname, resolvedParams);
74800
+ return { ...path, pathname: resolvedPath };
74801
+ }
74647
74802
  function getBasename() {
74648
74803
  if (window.dara.base_url !== "") {
74649
74804
  return new URL(window.dara.base_url, window.origin).pathname;
@@ -74665,7 +74820,7 @@ body,
74665
74820
  }
74666
74821
  return pathname.slice(startIndex) || "/";
74667
74822
  }
74668
- const NavigateTo = (ctx, actionImpl) => {
74823
+ const NavigateTo = async (ctx, actionImpl) => {
74669
74824
  const basename = getBasename();
74670
74825
  let isExternal = false;
74671
74826
  let to = actionImpl.url;
@@ -74697,7 +74852,8 @@ body,
74697
74852
  window.location.href = to;
74698
74853
  return;
74699
74854
  }
74700
- ctx.navigate(to, actionImpl.options);
74855
+ const resolvedTo = await resolveTo(to, ctx);
74856
+ ctx.navigate(resolvedTo, actionImpl.options);
74701
74857
  };
74702
74858
  const ResetVariables = (ctx, actionImpl) => {
74703
74859
  actionImpl.variables.filter(isVariable).forEach((variable) => {
@@ -98212,7 +98368,7 @@ body,
98212
98368
  ${(props) => props.$inactiveCss}
98213
98369
  }
98214
98370
  `;
98215
- function Link(props) {
98371
+ function LinkImpl(props) {
98216
98372
  const displayCtx$1 = React__namespace.useContext(displayCtx);
98217
98373
  const [style, css2] = useComponentStyles(props);
98218
98374
  const [activeStyle, activeCss] = useComponentStyles(props, true, "active_css");
@@ -98281,6 +98437,14 @@ body,
98281
98437
  props.children.map((child, idx) => /* @__PURE__ */ React__namespace.createElement(DynamicComponent$1, { component: child, key: idx }))
98282
98438
  ));
98283
98439
  }
98440
+ function LinkResolveImpl(props) {
98441
+ const to = useResolvedTo(props.to);
98442
+ return /* @__PURE__ */ React__namespace.createElement(LinkImpl, { ...props, to });
98443
+ }
98444
+ function Link(props) {
98445
+ const [to] = useVariable(props.to);
98446
+ return /* @__PURE__ */ React__namespace.createElement(LinkResolveImpl, { ...props, to, key: JSON.stringify(to) });
98447
+ }
98284
98448
  const StyledLink = styled(Link)`
98285
98449
  cursor: pointer;
98286
98450
 
@@ -98441,7 +98605,7 @@ body,
98441
98605
  const logoSrc = theme2.themeType === "dark" ? DaraDark : DaraLight;
98442
98606
  const daraLogo = /* @__PURE__ */ React.createElement("img", { alt: "Dara Logo", src: logoSrc });
98443
98607
  const showPoweredBy = props.powered_by_causalens ?? config2.powered_by_causalens;
98444
- return /* @__PURE__ */ React.createElement(Wrapper, { backgroundColor: theme2.colors.background }, props.side_bar_position === "right" && /* @__PURE__ */ React.createElement(Wrapper, null, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })), /* @__PURE__ */ React.createElement(SideBar, { style: { padding: props.side_bar_padding }, width: props.side_bar_width }, !props.hide_logo && props.logo_position !== "bottom" && logo, /* @__PURE__ */ React.createElement(Wrapper, { direction: "column" }, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "column" } }, props.side_bar && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.side_bar }))), !props.hide_logo && props.logo_position === "bottom" && logo, /* @__PURE__ */ React.createElement(LogoutButton$1, { href: "/logout", styling: "error" }, /* @__PURE__ */ React.createElement(LogoutArrow$1, { style: { marginRight: "0.5rem" } }), "Logout"), /* @__PURE__ */ React.createElement(BuiltWithLink, { href: "https://github.com/causalens/dara", target: "_blank", rel: "noopener noreferrer" }, "Built with ", daraLogo), showPoweredBy && /* @__PURE__ */ React.createElement(PoweredByCausalens, null)), props.side_bar_position !== "right" && /* @__PURE__ */ React.createElement(Wrapper, { style: { padding: "2rem 3rem" } }, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })));
98608
+ return /* @__PURE__ */ React.createElement(Wrapper$1, { backgroundColor: theme2.colors.background }, props.side_bar_position === "right" && /* @__PURE__ */ React.createElement(Wrapper$1, null, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })), /* @__PURE__ */ React.createElement(SideBar, { style: { padding: props.side_bar_padding }, width: props.side_bar_width }, !props.hide_logo && props.logo_position !== "bottom" && logo, /* @__PURE__ */ React.createElement(Wrapper$1, { direction: "column" }, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "column" } }, props.side_bar && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.side_bar }))), !props.hide_logo && props.logo_position === "bottom" && logo, /* @__PURE__ */ React.createElement(LogoutButton$1, { href: "/logout", styling: "error" }, /* @__PURE__ */ React.createElement(LogoutArrow$1, { style: { marginRight: "0.5rem" } }), "Logout"), /* @__PURE__ */ React.createElement(BuiltWithLink, { href: "https://github.com/causalens/dara", target: "_blank", rel: "noopener noreferrer" }, "Built with ", daraLogo), showPoweredBy && /* @__PURE__ */ React.createElement(PoweredByCausalens, null)), props.side_bar_position !== "right" && /* @__PURE__ */ React.createElement(Wrapper$1, { style: { padding: "2rem 3rem" } }, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })));
98445
98609
  }
98446
98610
  const shouldForwardProp = (prop) => !["width"].includes(prop);
98447
98611
  const TopBar = styled.div.withConfig({ shouldForwardProp })`
@@ -98502,7 +98666,7 @@ body,
98502
98666
  color: ${(props) => props.theme.colors.blue1};
98503
98667
  }
98504
98668
  `;
98505
- const RouteButtons = styled(Wrapper)`
98669
+ const RouteButtons = styled(Wrapper$1)`
98506
98670
  gap: 0.5rem;
98507
98671
  align-items: center;
98508
98672
  `;
@@ -98523,7 +98687,7 @@ body,
98523
98687
  const logo = props.logo_path && /* @__PURE__ */ React.createElement(LogoImage, { alt: "Logo", src: prependBaseUrl(props.logo_path), width: props.logo_width });
98524
98688
  const logoSrc = theme2.themeType === "dark" ? DaraDark : DaraLight;
98525
98689
  const daraLogo = /* @__PURE__ */ React.createElement("img", { alt: "Dara", src: logoSrc });
98526
- return /* @__PURE__ */ React.createElement(Wrapper, { backgroundColor: theme2.colors.background, direction: "column" }, /* @__PURE__ */ React.createElement(TopBar, { height: props.top_bar_height, style: { padding: props.top_bar_padding } }, /* @__PURE__ */ React.createElement(TopBarContent, null, !props.hide_logo && logo, props.top_bar && /* @__PURE__ */ React.createElement(RouteButtons, { direction: "row" }, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "row" } }, props.top_bar && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.top_bar }))), /* @__PURE__ */ React.createElement(LogoutButton, { href: "/logout", styling: "error" }, /* @__PURE__ */ React.createElement(LogoutArrow, { style: { marginRight: "0.5rem" } }), "Logout")), /* @__PURE__ */ React.createElement(BuiltWithSpan, null, "Built with ", daraLogo)), /* @__PURE__ */ React.createElement(Wrapper, { style: { padding: "2rem 3rem" } }, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })));
98690
+ return /* @__PURE__ */ React.createElement(Wrapper$1, { backgroundColor: theme2.colors.background, direction: "column" }, /* @__PURE__ */ React.createElement(TopBar, { height: props.top_bar_height, style: { padding: props.top_bar_padding } }, /* @__PURE__ */ React.createElement(TopBarContent, null, !props.hide_logo && logo, props.top_bar && /* @__PURE__ */ React.createElement(RouteButtons, { direction: "row" }, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "row" } }, props.top_bar && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.top_bar }))), /* @__PURE__ */ React.createElement(LogoutButton, { href: "/logout", styling: "error" }, /* @__PURE__ */ React.createElement(LogoutArrow, { style: { marginRight: "0.5rem" } }), "Logout")), /* @__PURE__ */ React.createElement(BuiltWithSpan, null, "Built with ", daraLogo)), /* @__PURE__ */ React.createElement(Wrapper$1, { style: { padding: "2rem 3rem" } }, props.content && /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.content })));
98527
98691
  }
98528
98692
  const RowDots = styled(Dots)`
98529
98693
  height: 2.5rem;
@@ -98536,6 +98700,19 @@ body,
98536
98700
  function DefaultFallback(props) {
98537
98701
  return /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.component });
98538
98702
  }
98703
+ function Match(props) {
98704
+ const [value] = useVariable(props.value, { suspend: false });
98705
+ const component = React$1.useMemo(() => {
98706
+ if (value in props.when) {
98707
+ return props.when[value];
98708
+ }
98709
+ return props.default;
98710
+ }, [value, props.when, props.default]);
98711
+ if (!component) {
98712
+ return null;
98713
+ }
98714
+ return /* @__PURE__ */ React.createElement(DynamicComponent$1, { component });
98715
+ }
98539
98716
  const createItemData = (items, renderer, markers, getItemKey) => ({
98540
98717
  items,
98541
98718
  renderer,
@@ -98546,12 +98723,14 @@ body,
98546
98723
  const transformedRenderer = React__namespace.useMemo(() => {
98547
98724
  let component;
98548
98725
  try {
98549
- component = applyMarkers(
98550
- props.data.renderer,
98551
- props.data.markers,
98552
- props.data.items[props.index],
98553
- props.data.getItemKey(props.index, props.data)
98554
- );
98726
+ component = applyMarkers({
98727
+ renderer: props.data.renderer,
98728
+ markers: props.data.markers,
98729
+ loopValue: props.data.items[props.index],
98730
+ itemKey: props.data.getItemKey(props.index, props.data),
98731
+ index: props.index,
98732
+ itemsLength: props.data.items.length
98733
+ });
98555
98734
  } catch (e2) {
98556
98735
  console.error("Failed to apply markers", e2);
98557
98736
  component = copy(props.data.renderer);
@@ -98655,6 +98834,7 @@ body,
98655
98834
  exports.Link = Link;
98656
98835
  exports.LoaderError = LoaderError;
98657
98836
  exports.LockSecuredCache = SingleUseCache;
98837
+ exports.Match = Match;
98658
98838
  exports.Menu = Menu;
98659
98839
  exports.MenuLink = MenuLink;
98660
98840
  exports.Navigate = Navigate;
@@ -98684,7 +98864,7 @@ body,
98684
98864
  exports.VariableCtx = variablesCtx;
98685
98865
  exports.WebSocketClient = WebSocketClient;
98686
98866
  exports.WebSocketCtx = websocketCtx;
98687
- exports.Wrapper = Wrapper;
98867
+ exports.Wrapper = Wrapper$1;
98688
98868
  exports.atomFamilyMembersRegistry = atomFamilyMembersRegistry;
98689
98869
  exports.atomFamilyRegistry = atomFamilyRegistry;
98690
98870
  exports.atomRegistry = atomRegistry;
@@ -98695,6 +98875,7 @@ body,
98695
98875
  exports.clearRegistries_TEST = clearRegistries_TEST;
98696
98876
  exports.combineFilters = combineFilters;
98697
98877
  exports.createRouteLoader = createRouteLoader;
98878
+ exports.createRouteMatches = createRouteMatches;
98698
98879
  exports.createRouter = createRouter;
98699
98880
  exports.default = run;
98700
98881
  exports.deferred = deferred;
@@ -98737,6 +98918,7 @@ body,
98737
98918
  exports.isResolvedDerivedVariable = isResolvedDerivedVariable;
98738
98919
  exports.isResolvedServerVariable = isResolvedServerVariable;
98739
98920
  exports.isResolvedSwitchVariable = isResolvedSwitchVariable;
98921
+ exports.isRouteMatchStore = isRouteMatchStore;
98740
98922
  exports.isServerVariable = isServerVariable;
98741
98923
  exports.isSingleVariable = isSingleVariable;
98742
98924
  exports.isStateVariable = isStateVariable;
@@ -98777,7 +98959,7 @@ body,
98777
98959
  exports.useFetchTabularServerVariable = useFetchTabularServerVariable;
98778
98960
  exports.useInterval = useInterval;
98779
98961
  exports.usePreloadRoute = usePreloadRoute;
98780
- exports.usePrevious = usePrevious$1;
98962
+ exports.usePrevious = usePrevious;
98781
98963
  exports.useRefreshSelector = useRefreshSelector;
98782
98964
  exports.useRefreshServerComponent = useRefreshServerComponent;
98783
98965
  exports.useRequestExtras = useRequestExtras;