dara-core 1.21.22__py3-none-any.whl → 1.21.24__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",
@@ -9364,7 +9370,7 @@
9364
9370
 
9365
9371
  background-color: ${(props) => props.theme.colors.blue1};
9366
9372
  `;
9367
- (function(thisArg, _arguments, P, generator) {
9373
+ var __awaiter$2 = function(thisArg, _arguments, P, generator) {
9368
9374
  function adopt(value) {
9369
9375
  return value instanceof P ? value : new P(function(resolve) {
9370
9376
  resolve(value);
@@ -9390,7 +9396,35 @@
9390
9396
  }
9391
9397
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9392
9398
  });
9393
- });
9399
+ };
9400
+ function copyToClipboard(value) {
9401
+ return __awaiter$2(this, void 0, void 0, function* () {
9402
+ let success2 = true;
9403
+ if (navigator.clipboard) {
9404
+ try {
9405
+ yield navigator.clipboard.writeText(value);
9406
+ } catch (_a) {
9407
+ success2 = false;
9408
+ }
9409
+ } else {
9410
+ const tempComponent = document.createElement("textarea");
9411
+ tempComponent.value = value;
9412
+ tempComponent.style.top = "0";
9413
+ tempComponent.style.left = "0";
9414
+ tempComponent.style.position = "fixed";
9415
+ document.body.appendChild(tempComponent);
9416
+ tempComponent.focus();
9417
+ tempComponent.select();
9418
+ try {
9419
+ success2 = document.execCommand("copy");
9420
+ } catch (_b) {
9421
+ success2 = false;
9422
+ }
9423
+ document.body.removeChild(tempComponent);
9424
+ }
9425
+ return success2;
9426
+ });
9427
+ }
9394
9428
  var Status;
9395
9429
  (function(Status2) {
9396
9430
  Status2["CANCELED"] = "CANCELED";
@@ -38486,23 +38520,41 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
38486
38520
  svg:not(:last-of-type) {
38487
38521
  margin-right: 0.7rem;
38488
38522
  }
38523
+ `;
38524
+ const SingleActionWrapper = styled(ActionWrapper)`
38525
+ cursor: pointer;
38526
+
38527
+ position: absolute;
38528
+ inset: 0;
38529
+
38530
+ width: 100%;
38531
+ height: 100%;
38489
38532
  `;
38490
38533
  function ActionCell(props) {
38491
38534
  if (!props.column.actions) {
38492
38535
  throw new Error("Must pass an array of actions to the column def when using the ActionCell");
38493
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
+ }
38494
38551
  return jsxRuntimeExports.jsx(ActionWrapper, { className: "table-action-cell", children: props.column.actions.map((action) => {
38495
38552
  const Icon2 = action.getIcon ? action.getIcon(props.row.original) : action.icon;
38496
38553
  if (Icon2 === void 0) {
38497
38554
  return;
38498
38555
  }
38499
38556
  const label = action.getLabel ? action.getLabel(props.row.original) : action.label;
38500
- const onClick = (e2) => {
38501
- var _a;
38502
- e2.stopPropagation();
38503
- (_a = props.onAction) === null || _a === void 0 ? void 0 : _a.call(props, action.id, props.row.original);
38504
- };
38505
- 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);
38506
38558
  }) });
38507
38559
  }
38508
38560
  function DatetimeCell(fmt = "yyyy-MM-dd HH:mm") {
@@ -50528,9 +50580,23 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
50528
50580
  url.searchParams.set("token", sessionToken);
50529
50581
  return new WebSocketClient(socketUrl, sessionToken, liveReload);
50530
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
+ }
50531
50594
  function isPathParamStore(store2) {
50532
50595
  return store2.__typename === "_PathParamStore";
50533
50596
  }
50597
+ function isRouteMatchStore(store2) {
50598
+ return store2.__typename === "_RouteMatchStore";
50599
+ }
50534
50600
  var ComponentType = /* @__PURE__ */ ((ComponentType2) => {
50535
50601
  ComponentType2["JS"] = "js";
50536
50602
  ComponentType2["PY"] = "py";
@@ -51724,7 +51790,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
51724
51790
  (match2, idx) => idx === pathMatches.length - 1 ? match2.pathname : match2.pathnameBase
51725
51791
  );
51726
51792
  }
51727
- function resolveTo(toArg, routePathnames, locationPathname, isPathRelative = false) {
51793
+ function resolveTo$1(toArg, routePathnames, locationPathname, isPathRelative = false) {
51728
51794
  let to;
51729
51795
  if (typeof toArg === "string") {
51730
51796
  to = parsePath(toArg);
@@ -54261,7 +54327,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
54261
54327
  contextualMatches = matches2;
54262
54328
  activeRouteMatch = matches2[matches2.length - 1];
54263
54329
  }
54264
- let path = resolveTo(
54330
+ let path = resolveTo$1(
54265
54331
  to ? to : ".",
54266
54332
  getResolveToMatches(contextualMatches),
54267
54333
  stripBasename$1(location2.pathname, basename) || location2.pathname,
@@ -55903,7 +55969,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
55903
55969
  navigator2.go(to);
55904
55970
  return;
55905
55971
  }
55906
- let path = resolveTo(
55972
+ let path = resolveTo$1(
55907
55973
  to,
55908
55974
  JSON.parse(routePathnamesJson),
55909
55975
  locationPathname,
@@ -55949,7 +56015,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
55949
56015
  let { pathname: locationPathname } = useLocation();
55950
56016
  let routePathnamesJson = JSON.stringify(getResolveToMatches(matches2));
55951
56017
  return React__namespace.useMemo(
55952
- () => resolveTo(
56018
+ () => resolveTo$1(
55953
56019
  to,
55954
56020
  JSON.parse(routePathnamesJson),
55955
56021
  locationPathname,
@@ -56804,7 +56870,7 @@ Please change the parent <Route path="${parentPath}"> to <Route path="${parentPa
56804
56870
  let { matches: matches2 } = React__namespace.useContext(RouteContext);
56805
56871
  let { pathname: locationPathname } = useLocation();
56806
56872
  let navigate = useNavigate();
56807
- let path = resolveTo(
56873
+ let path = resolveTo$1(
56808
56874
  to,
56809
56875
  getResolveToMatches(matches2),
56810
56876
  locationPathname,
@@ -64121,16 +64187,18 @@ ${String(error)}`;
64121
64187
  routeDefinitions,
64122
64188
  routeObjects,
64123
64189
  routeDefMap,
64124
- defaultPath
64190
+ defaultPath,
64191
+ routeMatches
64125
64192
  }) {
64126
64193
  const value = React__namespace.useMemo(
64127
64194
  () => ({
64128
64195
  routeDefinitions,
64129
64196
  routeObjects,
64130
64197
  routeDefMap,
64131
- defaultPath
64198
+ defaultPath,
64199
+ routeMatches
64132
64200
  }),
64133
- [routeDefinitions, routeObjects, routeDefMap, defaultPath]
64201
+ [routeDefinitions, routeObjects, routeDefMap, defaultPath, routeMatches]
64134
64202
  );
64135
64203
  return /* @__PURE__ */ React__namespace.createElement(RouterContext.Provider, { value }, children);
64136
64204
  }
@@ -64153,179 +64221,19 @@ ${String(error)}`;
64153
64221
  function useSessionToken() {
64154
64222
  return React__namespace.useSyncExternalStore(onTokenChange, getSessionToken);
64155
64223
  }
64156
- function cleanSessionCache(sessionToken) {
64157
- for (const storage of [sessionStorage, localStorage]) {
64158
- const keys = Object.keys(storage);
64159
- keys.forEach((key) => {
64160
- if (key.startsWith("dara-session") && !key.startsWith(`dara-session-${sessionToken}`)) {
64161
- storage.removeItem(key);
64162
- }
64163
- });
64164
- }
64165
- }
64166
- function isJsComponent(component) {
64167
- return component.type === ComponentType.JS;
64168
- }
64169
- var isNull_1;
64170
- var hasRequiredIsNull;
64171
- function requireIsNull() {
64172
- if (hasRequiredIsNull) return isNull_1;
64173
- hasRequiredIsNull = 1;
64174
- function isNull2(value) {
64175
- return value === null;
64176
- }
64177
- isNull_1 = isNull2;
64178
- return isNull_1;
64179
- }
64180
- var isNullExports = requireIsNull();
64181
- const isNull = /* @__PURE__ */ getDefaultExportFromCjs(isNullExports);
64182
- var negate_1;
64183
- var hasRequiredNegate;
64184
- function requireNegate() {
64185
- if (hasRequiredNegate) return negate_1;
64186
- hasRequiredNegate = 1;
64187
- var FUNC_ERROR_TEXT = "Expected a function";
64188
- function negate(predicate) {
64189
- if (typeof predicate != "function") {
64190
- throw new TypeError(FUNC_ERROR_TEXT);
64191
- }
64192
- return function() {
64193
- var args = arguments;
64194
- switch (args.length) {
64195
- case 0:
64196
- return !predicate.call(this);
64197
- case 1:
64198
- return !predicate.call(this, args[0]);
64199
- case 2:
64200
- return !predicate.call(this, args[0], args[1]);
64201
- case 3:
64202
- return !predicate.call(this, args[0], args[1], args[2]);
64203
- }
64204
- return !predicate.apply(this, args);
64205
- };
64206
- }
64207
- negate_1 = negate;
64208
- return negate_1;
64209
- }
64210
- var _baseSet;
64211
- var hasRequired_baseSet;
64212
- function require_baseSet() {
64213
- if (hasRequired_baseSet) return _baseSet;
64214
- hasRequired_baseSet = 1;
64215
- var assignValue = require_assignValue(), castPath = require_castPath(), isIndex = require_isIndex(), isObject2 = requireIsObject(), toKey = require_toKey();
64216
- function baseSet(object2, path, value, customizer) {
64217
- if (!isObject2(object2)) {
64218
- return object2;
64219
- }
64220
- path = castPath(path, object2);
64221
- var index2 = -1, length = path.length, lastIndex = length - 1, nested = object2;
64222
- while (nested != null && ++index2 < length) {
64223
- var key = toKey(path[index2]), newValue = value;
64224
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
64225
- return object2;
64226
- }
64227
- if (index2 != lastIndex) {
64228
- var objValue = nested[key];
64229
- newValue = customizer ? customizer(objValue, key, nested) : void 0;
64230
- if (newValue === void 0) {
64231
- newValue = isObject2(objValue) ? objValue : isIndex(path[index2 + 1]) ? [] : {};
64232
- }
64233
- }
64234
- assignValue(nested, key, newValue);
64235
- nested = nested[key];
64236
- }
64237
- return object2;
64238
- }
64239
- _baseSet = baseSet;
64240
- return _baseSet;
64241
- }
64242
- var _basePickBy;
64243
- var hasRequired_basePickBy;
64244
- function require_basePickBy() {
64245
- if (hasRequired_basePickBy) return _basePickBy;
64246
- hasRequired_basePickBy = 1;
64247
- var baseGet = require_baseGet(), baseSet = require_baseSet(), castPath = require_castPath();
64248
- function basePickBy(object2, paths, predicate) {
64249
- var index2 = -1, length = paths.length, result = {};
64250
- while (++index2 < length) {
64251
- var path = paths[index2], value = baseGet(object2, path);
64252
- if (predicate(value, path)) {
64253
- baseSet(result, castPath(path, object2), value);
64254
- }
64255
- }
64256
- return result;
64257
- }
64258
- _basePickBy = basePickBy;
64259
- return _basePickBy;
64260
- }
64261
- var pickBy_1;
64262
- var hasRequiredPickBy;
64263
- function requirePickBy() {
64264
- if (hasRequiredPickBy) return pickBy_1;
64265
- hasRequiredPickBy = 1;
64266
- var arrayMap = require_arrayMap(), baseIteratee = require_baseIteratee(), basePickBy = require_basePickBy(), getAllKeysIn = require_getAllKeysIn();
64267
- function pickBy(object2, predicate) {
64268
- if (object2 == null) {
64269
- 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;
64270
64231
  }
64271
- var props = arrayMap(getAllKeysIn(object2), function(prop) {
64272
- return [prop];
64273
- });
64274
- predicate = baseIteratee(predicate);
64275
- return basePickBy(object2, props, function(value, path) {
64276
- return predicate(value, path[0]);
64277
- });
64278
- }
64279
- pickBy_1 = pickBy;
64280
- return pickBy_1;
64281
- }
64282
- var omitBy_1;
64283
- var hasRequiredOmitBy;
64284
- function requireOmitBy() {
64285
- if (hasRequiredOmitBy) return omitBy_1;
64286
- hasRequiredOmitBy = 1;
64287
- var baseIteratee = require_baseIteratee(), negate = requireNegate(), pickBy = requirePickBy();
64288
- function omitBy2(object2, predicate) {
64289
- return pickBy(object2, negate(baseIteratee(predicate)));
64290
- }
64291
- omitBy_1 = omitBy2;
64292
- return omitBy_1;
64293
- }
64294
- var omitByExports = requireOmitBy();
64295
- const omitBy = /* @__PURE__ */ getDefaultExportFromCjs(omitByExports);
64296
- function isTheme(configTheme) {
64297
- return typeof configTheme !== "string";
64298
- }
64299
- function resolveTheme(configTheme, baseTheme) {
64300
- if (!configTheme || configTheme === "light") {
64301
- return theme;
64302
- }
64303
- if (configTheme === "dark") {
64304
- return darkTheme;
64305
- }
64306
- if (isTheme(configTheme)) {
64307
- const original = baseTheme === "dark" ? darkTheme : theme;
64308
- return {
64309
- // Here we spread both first to pick up anything missing from the default theme and anything new/extra in
64310
- // the new theme.
64311
- ...original,
64312
- ...omitBy(configTheme, isNull),
64313
- colors: {
64314
- ...original.colors,
64315
- ...omitBy(configTheme.colors, isNull)
64316
- },
64317
- font: {
64318
- ...original.font,
64319
- ...omitBy(configTheme.font, isNull)
64320
- },
64321
- shadow: {
64322
- ...original.shadow,
64323
- ...omitBy(configTheme.shadow, isNull)
64324
- }
64325
- };
64232
+ return BaseRawCssInject.withComponent(component);
64326
64233
  }
64327
- console.warn("No valid theme was found. Defaulting to light theme.");
64328
- return theme;
64234
+ return styled(component)`
64235
+ ${(props) => props.$rawCss}
64236
+ `;
64329
64237
  }
64330
64238
  function useDeferLoadable(loadable, suspendOverride) {
64331
64239
  const { suspend: ctxSuspend } = useFallbackCtx();
@@ -64364,64 +64272,6 @@ ${String(error)}`;
64364
64272
  }
64365
64273
  return availableState;
64366
64274
  }
64367
- function useInterval(callback, delay2) {
64368
- React$1.useEffect(
64369
- () => {
64370
- if (delay2) {
64371
- const id = setInterval(callback, delay2 * 1e3);
64372
- return () => clearInterval(id);
64373
- }
64374
- },
64375
- useDeepCompare([delay2, callback])
64376
- );
64377
- }
64378
- function usePrevious$1(value, initialValue) {
64379
- const ref = React$1.useRef(initialValue);
64380
- React$1.useEffect(() => {
64381
- ref.current = value;
64382
- });
64383
- return ref.current;
64384
- }
64385
- function useWindowTitle(pageTitle, enabled = true) {
64386
- const config2 = useConfig();
64387
- React$1.useEffect(() => {
64388
- if (!enabled) {
64389
- return;
64390
- }
64391
- if (!pageTitle) {
64392
- document.title = config2.title;
64393
- return;
64394
- }
64395
- document.title = `${config2.title} - ${pageTitle}`;
64396
- }, [config2, config2.title, pageTitle, enabled]);
64397
- }
64398
- const BaseRawCssInject = styled.div`
64399
- ${(props) => props.$rawCss}
64400
- `;
64401
- function injectCss(component) {
64402
- if (typeof component === "string") {
64403
- if (component === "div") {
64404
- return BaseRawCssInject;
64405
- }
64406
- return BaseRawCssInject.withComponent(component);
64407
- }
64408
- return styled(component)`
64409
- ${(props) => props.$rawCss}
64410
- `;
64411
- }
64412
- const Icon = injectCss("i");
64413
- function getIcon(icon) {
64414
- let iconClasses = icon;
64415
- if (typeof icon === "string" && !icon.includes("fa-")) {
64416
- const inferredIconName = icon.replace(/([A-Z])/g, " $1").trim().toLowerCase().split(" ").join("-");
64417
- iconClasses = `fa-solid fa-${inferredIconName}`;
64418
- console.warn(
64419
- `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.
64420
- Inferred class string: "${iconClasses}."`
64421
- );
64422
- }
64423
- return (props) => /* @__PURE__ */ React.createElement(Icon, { ...props, className: `${String(props.className ?? "")} ${iconClasses}` });
64424
- }
64425
64275
  class EventBus {
64426
64276
  #events$ = new Subject();
64427
64277
  #parentBus = null;
@@ -69268,14 +69118,14 @@ Inferred class string: "${iconClasses}."`
69268
69118
  useEffect: useEffect$2,
69269
69119
  useRef: useRef$2
69270
69120
  } = React$1;
69271
- function usePrevious(value) {
69121
+ function usePrevious$1(value) {
69272
69122
  const ref = useRef$2();
69273
69123
  useEffect$2(() => {
69274
69124
  ref.current = value;
69275
69125
  });
69276
69126
  return ref.current;
69277
69127
  }
69278
- var Recoil_usePrevious = usePrevious;
69128
+ var Recoil_usePrevious = usePrevious$1;
69279
69129
  const {
69280
69130
  DefaultValue: DefaultValue$2
69281
69131
  } = Recoil_index;
@@ -69521,6 +69371,38 @@ Inferred class string: "${iconClasses}."`
69521
69371
  );
69522
69372
  return /* @__PURE__ */ React$1.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "ServerVariable" }, children);
69523
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
+ }
69524
69406
  var set_1;
69525
69407
  var hasRequiredSet;
69526
69408
  function requireSet() {
@@ -69535,6 +69417,17 @@ Inferred class string: "${iconClasses}."`
69535
69417
  }
69536
69418
  var setExports = requireSet();
69537
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
+ }
69538
69431
  class DeferredImpl {
69539
69432
  #resolve;
69540
69433
  #reject;
@@ -70898,376 +70791,222 @@ Inferred class string: "${iconClasses}."`
70898
70791
  escapePathComponent,
70899
70792
  unescapePathComponent
70900
70793
  });
70901
- const STORE_EXTRAS_MAP = /* @__PURE__ */ new Map();
70902
- const STORE_VARIABLE_MAP = /* @__PURE__ */ new Map();
70903
- const STORE_SEQUENCE_MAP = /* @__PURE__ */ new Map();
70904
- const STORE_LATEST_VALUE_MAP = /* @__PURE__ */ new Map();
70905
- function BackendStoreSync({ children }) {
70906
- const { client: client2 } = React__namespace.useContext(websocketCtx);
70907
- const getStoreValue = React__namespace.useCallback(async (itemKey) => {
70908
- const serializableExtras = STORE_EXTRAS_MAP.get(itemKey);
70909
- const response = await request(`/api/core/store/${itemKey}`, {}, serializableExtras?.extras ?? {});
70910
- await handleAuthErrors(response, true);
70911
- await validateResponse(response, `Failed to fetch the store value for key: ${itemKey}`);
70912
- const { value, sequence_number } = await response.json();
70913
- STORE_LATEST_VALUE_MAP.set(itemKey, value);
70914
- STORE_SEQUENCE_MAP.set(itemKey, sequence_number);
70915
- return value;
70916
- }, []);
70917
- const syncStoreValues = React__namespace.useCallback(
70918
- async ({ diff }) => {
70919
- const extrasMap = /* @__PURE__ */ new Map();
70920
- Array.from(diff.entries()).filter(
70921
- ([itemKey, value]) => !STORE_LATEST_VALUE_MAP.has(itemKey) || STORE_LATEST_VALUE_MAP.get(itemKey) !== value
70922
- ).forEach(([itemKey, value]) => {
70923
- STORE_LATEST_VALUE_MAP.set(itemKey, value);
70924
- const extras = STORE_EXTRAS_MAP.get(itemKey);
70925
- if (!extrasMap.has(extras)) {
70926
- extrasMap.set(extras, {});
70927
- }
70928
- extrasMap.get(extras)[itemKey] = value;
70929
- });
70930
- async function sendRequest(serializableExtras, storeDiff) {
70931
- const response = await request(
70932
- `/api/core/store`,
70933
- {
70934
- body: JSON.stringify({
70935
- values: storeDiff,
70936
- ws_channel: await client2.getChannel()
70937
- }),
70938
- method: "POST"
70939
- },
70940
- serializableExtras.extras
70941
- );
70942
- await handleAuthErrors(response, true);
70943
- await validateResponse(response, `Failed to sync the store values`);
70944
- }
70945
- await Promise.allSettled(
70946
- Array.from(extrasMap.entries()).map(
70947
- ([serializableExtras, storeDiff]) => sendRequest(serializableExtras, storeDiff)
70948
- )
70949
- );
70950
- },
70951
- [client2]
70952
- );
70953
- const applyPatchesToAtoms = Recoil_index_31(
70954
- ({ snapshot, set: set2 }) => async (storeUid, patches, sequenceNumber) => {
70955
- const expectedSequence = STORE_SEQUENCE_MAP.get(storeUid) || 0;
70956
- if (sequenceNumber !== expectedSequence + 1) {
70957
- console.warn(
70958
- `Sequence number mismatch for store ${storeUid}. Expected: ${expectedSequence + 1}, Got: ${sequenceNumber}. Rejecting patch.`
70959
- );
70960
- return;
70961
- }
70962
- STORE_SEQUENCE_MAP.set(storeUid, sequenceNumber);
70963
- const variableUids = STORE_VARIABLE_MAP.get(storeUid);
70964
- if (!variableUids) {
70965
- return;
70966
- }
70967
- const atomsToUpdate = [];
70968
- for (const variableUid of variableUids) {
70969
- const directAtom = atomRegistry.get(variableUid);
70970
- if (directAtom) {
70971
- atomsToUpdate.push({ atom: directAtom, variableUid });
70972
- continue;
70973
- }
70974
- const atomFamily2 = atomFamilyRegistry.get(variableUid);
70975
- if (atomFamily2) {
70976
- const familyMembers = atomFamilyMembersRegistry.get(atomFamily2);
70977
- if (familyMembers) {
70978
- for (const [, atomInstance] of familyMembers) {
70979
- atomsToUpdate.push({ atom: atomInstance, variableUid });
70980
- }
70981
- }
70982
- }
70983
- }
70984
- const currentValues = await Promise.all(
70985
- atomsToUpdate.map(async ({ atom: atom2, variableUid }) => {
70986
- try {
70987
- return {
70988
- atom: atom2,
70989
- variableUid,
70990
- currentValue: await snapshot.getPromise(atom2),
70991
- error: null
70992
- };
70993
- } catch (error) {
70994
- return {
70995
- atom: atom2,
70996
- variableUid,
70997
- currentValue: null,
70998
- error
70999
- };
71000
- }
71001
- })
71002
- );
71003
- const applyPatchToValue = (currentValue, variableUid) => {
71004
- try {
71005
- return applyPatch(currentValue, patches, false, false).newDocument;
71006
- } catch (error) {
71007
- console.warn(`Failed to apply patch to atom ${variableUid}:`, error);
71008
- return currentValue;
71009
- }
71010
- };
71011
- currentValues.forEach(({ atom: atom2, variableUid, currentValue, error }) => {
71012
- if (error) {
71013
- console.warn(`Failed to read current value for atom ${variableUid}:`, error);
71014
- return;
71015
- }
71016
- const patchedValue = applyPatchToValue(currentValue, variableUid);
71017
- set2(atom2, patchedValue);
71018
- STORE_LATEST_VALUE_MAP.set(storeUid, patchedValue);
71019
- });
71020
- },
71021
- []
71022
- );
71023
- const listenToStoreChanges = React__namespace.useCallback(
71024
- ({ updateItem }) => {
71025
- if (!client2) {
71026
- 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);
71027
70800
  }
71028
- const valueSub = client2.backendStoreMessages$().subscribe((message) => {
71029
- STORE_SEQUENCE_MAP.set(message.store_uid, message.sequence_number);
71030
- updateItem(message.store_uid, message.value);
71031
- STORE_LATEST_VALUE_MAP.set(message.store_uid, message.value);
71032
- });
71033
- const patchSub = client2.backendStorePatchMessages$().subscribe((message) => {
71034
- applyPatchesToAtoms(message.store_uid, message.patches, message.sequence_number);
71035
- });
71036
- return () => {
71037
- valueSub.unsubscribe();
71038
- patchSub.unsubscribe();
71039
- };
71040
- },
71041
- [client2, applyPatchesToAtoms]
71042
- );
71043
- return /* @__PURE__ */ React__namespace.createElement(RecoilSync_index_1, { listen: listenToStoreChanges, read: getStoreValue, storeKey: "BackendStore", write: syncStoreValues }, children);
70801
+ });
70802
+ }
71044
70803
  }
71045
- function backendStoreEffect(variable, requestExtras) {
71046
- STORE_EXTRAS_MAP.set(variable.store.uid, requestExtras);
71047
- if (!STORE_VARIABLE_MAP.has(variable.store.uid)) {
71048
- 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;
71049
70814
  }
71050
- STORE_VARIABLE_MAP.get(variable.store.uid).add(variable.uid);
71051
- return RecoilSync_index_2({
71052
- /** Use store uid as the unique identifier */
71053
- itemKey: variable.store.uid,
71054
- refine: Refine_index_6(),
71055
- storeKey: "BackendStore",
71056
- write({ write: write2 }, newValue) {
71057
- if (variable.store.readonly) {
71058
- 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]);
71059
70841
  }
71060
- if (newValue instanceof Recoil_index_1) {
71061
- 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);
71062
70860
  }
71063
- write2(variable.store.uid, newValue);
71064
70861
  }
71065
- });
71066
- }
71067
- function getSessionKey(uid2) {
71068
- if (isEmbedded()) {
71069
- return `dara-session-${window.frameElement.dataset.daraPageId}-var-${uid2}`;
70862
+ return result;
71070
70863
  }
71071
- return `dara-session-${getSessionToken()}-var-${uid2}`;
70864
+ _basePickBy = basePickBy;
70865
+ return _basePickBy;
71072
70866
  }
71073
- function BrowserStoreSync({ children }) {
71074
- const getStoreValue = React__namespace.useCallback((itemKey) => {
71075
- const key = getSessionKey(itemKey);
71076
- return JSON.parse(localStorage.getItem(key) ?? "null");
71077
- }, []);
71078
- const syncStoreValues = React__namespace.useCallback(({ diff }) => {
71079
- for (const [itemKey, value] of diff.entries()) {
71080
- const key = getSessionKey(itemKey);
71081
- 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 {};
71082
70876
  }
71083
- }, []);
71084
- const listenToStoreChanges = React__namespace.useCallback(({ updateItem }) => {
71085
- const listener2 = (e2) => {
71086
- if (e2.storageArea === localStorage) {
71087
- if (e2.key) {
71088
- const match2 = e2.key.match(/^dara-session-(.*)-var-(.*)$/);
71089
- if (match2) {
71090
- const [, sessionToken, uid2] = match2;
71091
- if (sessionToken === getSessionToken()) {
71092
- updateItem(uid2, JSON.parse(e2.newValue ?? "null"));
71093
- }
71094
- }
71095
- }
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)
71096
70930
  }
71097
70931
  };
71098
- window.addEventListener("storage", listener2);
71099
- return () => {
71100
- window.removeEventListener("storage", listener2);
71101
- };
71102
- }, []);
71103
- 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;
71104
70935
  }
71105
- function PathParamSync({ children }) {
71106
- const navigate = useNavigate();
71107
- const location2 = useLocation();
71108
- const locationRef = useLatestRef$3(location2);
71109
- const matches2 = useMatches();
71110
- const matchesRef = useLatestRef$3(matches2);
71111
- const params = useParams();
71112
- const paramsRef = React__namespace.useRef(params);
71113
- const locationSubscribers = React__namespace.useRef([]);
71114
- React__namespace.useLayoutEffect(() => {
71115
- 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) {
71116
70947
  return;
71117
70948
  }
71118
- 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(() => {
71119
70973
  for (const subscriber of locationSubscribers.current) {
71120
- subscriber(params);
70974
+ subscriber();
71121
70975
  }
71122
- }, [paramsRef, params]);
71123
- const getStoreValue = React__namespace.useCallback(
71124
- (paramName) => {
71125
- return paramsRef.current[paramName] ?? null;
71126
- },
71127
- [paramsRef]
71128
- );
71129
- const writeStoreValue = React__namespace.useCallback(
71130
- async ({ diff }) => {
71131
- const newParams = mapValues({ ...paramsRef.current, ...Object.fromEntries(diff) }, (v) => String(v));
71132
- const loaderData = matchesRef.current.at(-1).loaderData;
71133
- const data2 = loaderData.data instanceof Promise ? await loaderData.data : loaderData.data;
71134
- const fullPathname = data2.route_definition.full_path;
71135
- navigate({
71136
- pathname: generatePath(fullPathname, newParams),
71137
- // preserve current search
71138
- search: locationRef.current.search
71139
- });
71140
- },
71141
- [matchesRef, navigate, paramsRef, locationRef]
71142
- );
71143
- const listenToStoreChanges = React__namespace.useCallback(({ updateItems }) => {
71144
- function handleUpdate(newParams) {
71145
- updateItems(new Map(Object.entries(newParams)));
70976
+ }, [location2]);
70977
+ const urlSerializer = React$1.useCallback((val) => {
70978
+ if (val === void 0 || val === null) {
70979
+ return "";
71146
70980
  }
71147
- 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);
71148
70998
  return () => {
71149
- locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handleUpdate);
70999
+ locationSubscribers.current = locationSubscribers.current.filter((item) => item !== handler);
71150
71000
  };
71151
71001
  }, []);
71152
- return /* @__PURE__ */ React__namespace.createElement(
71153
- RecoilSync_index_1,
71154
- {
71155
- listen: listenToStoreChanges,
71156
- read: getStoreValue,
71157
- write: writeStoreValue,
71158
- storeKey: "_PathParamStore"
71159
- },
71160
- children
71161
- );
71162
- }
71163
- function localStorageEffect(variable, extrasSerializable, wsClient, taskContext) {
71164
- let firstRun = false;
71165
- return RecoilSync_index_2({
71166
- itemKey: variable.uid,
71167
- read: ({ read: read2 }) => {
71168
- const readValue = read2(variable.uid);
71169
- if (!firstRun) {
71170
- firstRun = true;
71171
- if (!readValue) {
71172
- const isDefaultDerived = isDerivedVariable(variable.default);
71173
- return isDefaultDerived ? getOrRegisterDerivedVariable(
71174
- variable.default,
71175
- wsClient,
71176
- taskContext,
71177
- extrasSerializable.extras
71178
- ) : variable.default;
71179
- }
71180
- }
71181
- return readValue;
71002
+ return {
71003
+ browserInterface: {
71004
+ listenChangeURL
71182
71005
  },
71183
- refine: Refine_index_6(),
71184
- storeKey: "BrowserStore"
71185
- });
71186
- }
71187
- function urlEffect(variable) {
71188
- return RecoilSync_index_6({
71189
- history: "push",
71190
- itemKey: variable.store.query,
71191
- refine: Refine_index_6()
71192
- });
71193
- }
71194
- function pathParamEffect(variable) {
71195
- const itemKey = variable.store.param_name;
71196
- const effect2 = RecoilSync_index_2({
71197
- itemKey,
71198
- refine: Refine_index_6(),
71199
- storeKey: "_PathParamStore"
71200
- });
71201
- return (effectParams) => {
71202
- const cleanup = effect2(effectParams);
71203
- effectParams.setSelf(effectParams.getLoadable(effectParams.node).valueOrThrow());
71204
- return () => {
71205
- cleanup?.();
71206
- };
71207
- };
71208
- }
71209
- const STORES = {
71210
- BackendStore: {
71211
- effect: backendStoreEffect
71212
- },
71213
- BrowserStore: {
71214
- effect: localStorageEffect
71215
- },
71216
- QueryParamStore: {
71217
- effect: urlEffect
71218
- },
71219
- _PathParamStore: {
71220
- effect: pathParamEffect
71221
- }
71222
- };
71223
- function getEffect(variable) {
71224
- const storeName = variable.store?.__typename;
71225
- if (!storeName || !(storeName in STORES)) {
71226
- return null;
71227
- }
71228
- return STORES[storeName]?.effect ?? null;
71229
- }
71230
- function StoreProviders({ children }) {
71231
- return /* @__PURE__ */ React__namespace.createElement(BackendStoreSync, null, /* @__PURE__ */ React__namespace.createElement(BrowserStoreSync, null, children));
71232
- }
71233
- function isConditionTrue(operator, value, other) {
71234
- if (operator === ConditionOperator.EQUAL) {
71235
- return value === other;
71236
- }
71237
- if (operator === ConditionOperator.NOT_EQUAL) {
71238
- return value !== other;
71239
- }
71240
- if (operator === ConditionOperator.GREATER_EQUAL) {
71241
- return value >= other;
71242
- }
71243
- if (operator === ConditionOperator.GREATER_THAN) {
71244
- return value > other;
71245
- }
71246
- if (operator === ConditionOperator.LESS_EQUAL) {
71247
- return value <= other;
71248
- }
71249
- if (operator === ConditionOperator.LESS_THAN) {
71250
- return value < other;
71251
- }
71252
- if (operator === ConditionOperator.TRUTHY) {
71253
- return !!value;
71254
- }
71255
- throw new Error(`Unexpected operator ${String(operator)} passed to conditional (If) component`);
71256
- }
71257
- function useConditionOrVariable(arg, opts = {}) {
71258
- if (isCondition(arg)) {
71259
- const value = useVariable(arg.variable, opts)[0];
71260
- const other = useVariable(arg.other, opts)[0];
71261
- return isConditionTrue(arg.operator, value, other);
71262
- }
71263
- return useVariable(arg, opts)[0];
71264
- }
71265
- function useSwitchVariable(variable) {
71266
- const value = useConditionOrVariable(variable.value, { suspend: false });
71267
- const [valueMap] = useVariable(variable.value_map, { suspend: false });
71268
- const [defaultValue] = useVariable(variable.default, { suspend: false });
71269
- const lookupKey = String(value);
71270
- return valueMap[lookupKey] ?? defaultValue;
71006
+ deserialize: urlDeserializer,
71007
+ location: { part: "queryParams" },
71008
+ serialize: urlSerializer
71009
+ };
71271
71010
  }
71272
71011
  const COLUMN_PREFIX_REGEX = /__(?:col|index)__\d+__/;
71273
71012
  function combineFilters(combinator, queries) {
@@ -71534,733 +71273,258 @@ Inferred class string: "${iconClasses}."`
71534
71273
  const response = result.value;
71535
71274
  return response.data;
71536
71275
  }
71537
- function warnUpdateOnDerivedState() {
71538
- 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
+ });
71539
71288
  }
71540
- function useVariable(variable, opts = { serverVariable: "disallow" }) {
71289
+ function useVariableState() {
71541
71290
  const extras = useRequestExtras();
71542
- const { client: wsClient } = React$1.useContext(websocketCtx);
71543
- const taskContext = useTaskContext();
71544
- const variablesContext = React$1.useContext(variablesCtx);
71545
- const bus = useEventBus();
71546
- if (!isVariable(variable)) {
71547
- const [state, setState] = React$1.useState(variable);
71548
- const [prevVariable, setPrevVariable] = React$1.useState(variable);
71549
- if (!isEqual$4(variable, prevVariable)) {
71550
- setState(variable);
71551
- setPrevVariable(variable);
71552
- }
71553
- return [state, setState];
71554
- }
71555
- variablesContext?.variables.current.add(variable.uid);
71556
- React$1.useEffect(() => {
71557
- return () => {
71558
- 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;
71559
71306
  };
71560
71307
  }, []);
71561
- if (isDerivedVariable(variable)) {
71562
- const selector2 = useDerivedVariable(variable, wsClient, taskContext, extras);
71563
- const selectorLoadable = Recoil_index_28(selector2);
71564
- React$1.useEffect(() => {
71565
- if (selectorLoadable.state !== "loading") {
71566
- bus.publish("DERIVED_VARIABLE_LOADED", { variable, value: selectorLoadable.contents });
71567
- }
71568
- }, [selectorLoadable]);
71569
- const deferred22 = useDeferLoadable(selectorLoadable, opts.suspend);
71570
- return [deferred22, warnUpdateOnDerivedState];
71571
- }
71572
- if (isSwitchVariable(variable)) {
71573
- return [useSwitchVariable(variable), warnUpdateOnDerivedState];
71574
- }
71575
- if (isStateVariable(variable)) {
71576
- const parentSelector = useDerivedVariable(variable.parent_variable, wsClient, taskContext, extras);
71577
- const parentLoadable = Recoil_index_28(parentSelector);
71578
- let stateValue;
71579
- switch (variable.property_name) {
71580
- case "loading":
71581
- stateValue = parentLoadable.state === "loading";
71582
- break;
71583
- case "error":
71584
- stateValue = parentLoadable.state === "hasError";
71585
- break;
71586
- case "hasValue":
71587
- stateValue = parentLoadable.state === "hasValue";
71588
- break;
71589
- default:
71590
- 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);
71591
71319
  }
71592
- return [stateValue, warnUpdateOnDerivedState];
71320
+ return accumulator;
71593
71321
  }
71594
- if (isServerVariable(variable)) {
71595
- if (opts.serverVariable === "disallow") {
71596
- throw new UserError("ServerVariable cannot be directly consumed by this component");
71597
- }
71598
- const atom2 = React$1.useMemo(() => getOrRegisterServerVariable(variable, extras), [variable, extras]);
71599
- const [seqNumber] = Recoil_index_22(atom2);
71600
- const fetcher = useTabularVariable(variable);
71601
- const { data: data2 } = reactQuery.useSuspenseQuery({
71602
- // use the seq number as a dependency to refetch on changes
71603
- queryKey: ["use-variable-server-variable", variable.uid, seqNumber],
71604
- queryFn: async () => {
71605
- const result = await fetcher(null, {
71606
- limit: 1,
71607
- offset: 0
71608
- });
71609
- return result.data;
71610
- },
71611
- 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);
71612
71334
  });
71613
- return [data2?.[0] ?? null, warnUpdateOnDerivedState];
71335
+ return accumulator;
71614
71336
  }
71615
- const recoilState = getOrRegisterPlainVariable(variable, wsClient, taskContext, extras);
71616
- if (!isDerivedVariable(variable.default)) {
71617
- const [value, setValue] = Recoil_index_22(recoilState);
71618
- React$1.useEffect(() => {
71619
- bus.publish("PLAIN_VARIABLE_LOADED", { variable, value });
71620
- }, [value]);
71621
- 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
+ };
71622
71351
  }
71623
- const [loadable, setLoadable] = Recoil_index_23(recoilState);
71624
- React$1.useEffect(() => {
71625
- if (loadable.state !== "loading") {
71626
- bus.publish("PLAIN_VARIABLE_LOADED", { variable, value: loadable.contents });
71627
- }
71628
- }, [loadable]);
71629
- const deferred2 = useDeferLoadable(loadable, opts.suspend);
71630
- return [deferred2, setLoadable];
71352
+ _createAggregator = createAggregator;
71353
+ return _createAggregator;
71631
71354
  }
71632
- function flexStyles(props, displayCtx2, useDisplayContext) {
71633
- let flexBasis = props.basis;
71634
- let flexShrink = props.shrink;
71635
- let flexGrow = props.grow;
71636
- if (useDisplayContext) {
71637
- if (props.width && displayCtx2.direction === "horizontal") {
71638
- flexBasis ??= props.width;
71639
- flexShrink ??= "0";
71640
- flexGrow ??= "0";
71641
- }
71642
- if (props.height && displayCtx2.direction === "vertical") {
71643
- flexBasis ??= props.height;
71644
- flexShrink ??= "0";
71645
- 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]);
71646
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);
71647
71412
  }
71648
- if (props.hug || props.hug !== false && displayCtx2.hug) {
71649
- flexBasis ??= "content";
71650
- flexShrink ??= "1";
71651
- flexGrow ??= "0";
71652
- }
71653
- return { flexBasis, flexGrow, flexShrink };
71654
71413
  }
71655
- function parseRawCss(rawCss) {
71656
- const isRawObject = typeof rawCss === "object" && rawCss !== null && rawCss !== void 0;
71657
- const componentCss = !isRawObject && typeof rawCss === "string" ? rawCss : "";
71658
- const styles2 = isRawObject ? rawCss : {};
71659
- 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
+ );
71660
71431
  }
71661
- function useComponentStyles(props, useDisplayContext = true, propName = "raw_css") {
71662
- const [rawCssValue] = useVariable(props[propName]);
71663
- const [rawStyles, rawCss] = parseRawCss(rawCssValue);
71664
- const displayCtx$1 = React$1.useContext(displayCtx);
71665
- const flexProps = flexStyles(props, displayCtx$1, useDisplayContext);
71666
- const styles2 = React$1.useMemo(() => {
71667
- const stylesObj = {
71668
- backgroundColor: props.background,
71669
- border: props.border,
71670
- borderRadius: props.border_radius,
71671
- color: props.color,
71672
- fontFamily: props.font,
71673
- fontSize: props.font_size,
71674
- fontStyle: props.italic ? "italic" : "normal",
71675
- fontWeight: props.bold ? "bold" : "normal",
71676
- gap: props.gap,
71677
- height: props.height,
71678
- margin: props.margin,
71679
- maxHeight: props.max_height,
71680
- maxWidth: props.max_width,
71681
- minHeight: props.min_height,
71682
- minWidth: props.min_width,
71683
- overflow: props.overflow,
71684
- padding: props.padding,
71685
- position: props.position,
71686
- textDecoration: props.underline ? "underline" : "none",
71687
- width: props.width,
71688
- ...flexProps,
71689
- ...rawStyles,
71690
- ...props.style ?? {}
71691
- };
71692
- return Object.fromEntries(Object.entries(stylesObj).filter(([, v]) => v !== null && v !== void 0));
71693
- }, [useDeepCompare(props), rawStyles, flexProps]);
71694
- return [styles2, rawCss];
71432
+ function clearActionHandlerCache_TEST() {
71433
+ Object.keys(ACTION_HANDLER_BY_NAME).forEach((k) => delete ACTION_HANDLER_BY_NAME[k]);
71695
71434
  }
71696
- function useUrlSync() {
71697
- const location2 = useLocation();
71698
- const locationSubscribers = React$1.useRef([]);
71699
- React$1.useEffect(() => {
71700
- for (const subscriber of locationSubscribers.current) {
71701
- subscriber();
71702
- }
71703
- }, [location2]);
71704
- const urlSerializer = React$1.useCallback((val) => {
71705
- if (val === void 0 || val === null) {
71706
- return "";
71707
- }
71708
- if (["string", "number", "boolean"].includes(typeof val)) {
71709
- return String(val);
71710
- }
71711
- return JSON.stringify(val);
71712
- }, []);
71713
- const urlDeserializer = React$1.useCallback((val) => {
71714
- if (val === "") {
71715
- 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);
71716
71448
  }
71717
- try {
71718
- return JSON.parse(val);
71719
- } catch {
71720
- 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;
71721
71460
  }
71722
- }, []);
71723
- const listenChangeURL = React$1.useCallback((handler) => {
71724
- locationSubscribers.current.push(handler);
71725
- return () => {
71726
- 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
+ }
71727
71476
  };
71728
- }, []);
71729
- return {
71730
- browserInterface: {
71731
- listenChangeURL
71732
- },
71733
- deserialize: urlDeserializer,
71734
- location: { part: "queryParams" },
71735
- serialize: urlSerializer
71736
- };
71737
- }
71738
- const StyledDots$1 = injectCss(Dots);
71739
- function DefaultFallback$1(props) {
71740
- const [style, css2] = useComponentStyles(props);
71741
- 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
+ });
71742
71521
  }
71743
- function DefaultFallbackStatic() {
71744
- return /* @__PURE__ */ React.createElement(StyledDots$1, { grey3: theme.colors.grey3, grey4: theme.colors.grey4 });
71745
- }
71746
- const Center = styled.div`
71747
- overflow: hidden;
71748
- display: flex;
71749
- flex-direction: column;
71750
- align-items: center;
71751
- justify-content: center;
71752
-
71753
- width: 100%;
71754
- height: 100%;
71755
-
71756
- background: ${(props) => props.colored ? props.theme.colors.blue1 : ""};
71757
- `;
71758
- const Wrapper$1 = styled.div`
71759
- display: flex;
71760
- flex: 1 1 0%;
71761
- flex-direction: column;
71762
- justify-content: center;
71763
-
71764
- min-height: 100%;
71765
-
71766
- background: ${(props) => `radial-gradient(circle closest-corner at 50% 40%, ${curriedTransparentize$1(
71767
- 0.9,
71768
- props.theme.colors.background
71769
- )} 0%, ${curriedTransparentize$1(
71770
- 0.8,
71771
- props.theme.colors.blue4
71772
- )} 70%),radial-gradient(circle closest-corner at 20% 150%, ${curriedTransparentize$1(
71773
- 0.8,
71774
- props.theme.colors.error
71775
- )} 0%, ${curriedTransparentize$1(0.2, props.theme.colors.blue4)} 230%)`};
71776
- `;
71777
- const Card = styled.div`
71778
- padding: 1.5rem;
71779
-
71780
- color: ${(props) => props.theme.colors.text};
71781
-
71782
- background-color: ${(props) => props.theme.colors.blue1};
71783
- border-radius: 1rem;
71784
- box-shadow: ${(props) => props.theme.shadow.medium};
71785
-
71786
- @media (width >= 640px) {
71787
- width: 100%;
71788
- max-width: 24rem;
71789
- margin-right: auto;
71790
- margin-left: auto;
71791
- }
71792
- `;
71793
- const FormWrapper = styled.div`
71794
- margin-top: 1.5rem;
71795
- `;
71796
- const Form = styled.form`
71797
- > * + * {
71798
- margin-top: 1.5rem;
71799
- }
71800
- `;
71801
- const ErrorText$1 = styled.h3`
71802
- margin: 0;
71803
-
71804
- font-size: 0.875rem;
71805
- font-weight: 500;
71806
- line-height: 1.25rem;
71807
- color: ${(props) => props.theme.colors.error};
71808
- letter-spacing: 0.025em;
71809
-
71810
- visibility: ${(props) => props.$hidden ? "hidden" : "visible"};
71811
- `;
71812
- const Label = styled.label`
71813
- font-weight: 500;
71814
- line-height: 1.5rem;
71815
- `;
71816
- const StyledInput = styled.input`
71817
- display: flex;
71818
- display: block;
71819
- align-items: center;
71820
-
71821
- width: 100%;
71822
- height: 2.5rem;
71823
- margin-top: 0.5rem;
71824
- padding: 0 1rem;
71825
-
71826
- font-size: 1rem;
71827
- line-height: 1.5rem;
71828
- color: ${(props) => props.theme.colors.text};
71829
-
71830
- background-color: ${(props) => props.theme.colors.blue1};
71831
- border: none;
71832
- border-radius: 0.25rem;
71833
- outline: none;
71834
- box-shadow:
71835
- inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
71836
- inset 0 0 0 1px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.grey2},
71837
- 0 1px 2px 0 rgb(0 0 0 / 5%);
71838
-
71839
- :active,
71840
- :focus {
71841
- box-shadow:
71842
- inset 0 0 0 0 ${(props) => props.theme.colors.blue1},
71843
- inset 0 0 0 2px ${(props) => props.$error ? props.theme.colors.error : props.theme.colors.primary},
71844
- 0 1px 2px 0 rgb(0 0 0 / 5%);
71845
- }
71846
- `;
71847
- const StyledButton = styled(Button$1)`
71848
- width: 100%;
71849
- font-weight: 600;
71850
- line-height: 1.5rem;
71851
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
71852
-
71853
- :active,
71854
- :focus {
71855
- outline-color: ${(props) => props.theme.colors.primary};
71856
- outline-width: 2px;
71857
- outline-offset: 2px;
71858
- }
71859
- `;
71860
- function BasicAuthLogin() {
71861
- const [isVerifyingToken, setIsVerifyingToken] = React$1.useState(true);
71862
- const [isLoggingIn, setIsLoggingIn] = React$1.useState(false);
71863
- const [username, setUsername] = React$1.useState("");
71864
- const [password, setPassword] = React$1.useState("");
71865
- const [isError2, setIsError] = React$1.useState(false);
71866
- const location2 = useLocation();
71867
- const navigate = useNavigate();
71868
- const { defaultPath } = useRouterContext();
71869
- const queryParams = new URLSearchParams(location2.search);
71870
- const previousLocation = queryParams.get("referrer") ?? defaultPath;
71871
- const login = async () => {
71872
- setIsLoggingIn(true);
71873
- setIsError(false);
71874
- try {
71875
- const sessionToken = await requestSessionToken({ password, username });
71876
- if (sessionToken) {
71877
- setSessionToken(sessionToken);
71878
- navigate(decodeURIComponent(previousLocation));
71879
- }
71880
- } catch {
71881
- setIsError(true);
71882
- }
71883
- setIsLoggingIn(false);
71884
- };
71885
- React$1.useEffect(() => {
71886
- if (getSessionToken()) {
71887
- verifySessionToken().then((verified) => {
71888
- if (verified) {
71889
- navigate(decodeURIComponent(previousLocation), { replace: true });
71890
- } else {
71891
- setIsVerifyingToken(false);
71892
- }
71893
- });
71894
- } else {
71895
- setIsVerifyingToken(false);
71896
- }
71897
- }, []);
71898
- if (isVerifyingToken) {
71899
- return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
71900
- }
71901
- return /* @__PURE__ */ React.createElement(Wrapper$1, null, /* @__PURE__ */ React.createElement(Card, null, /* @__PURE__ */ React.createElement(FormWrapper, null, /* @__PURE__ */ React.createElement(
71902
- Form,
71903
- {
71904
- onSubmit: (e2) => {
71905
- e2.preventDefault();
71906
- login();
71907
- }
71908
- },
71909
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "username" }, "Username"), /* @__PURE__ */ React.createElement(
71910
- StyledInput,
71911
- {
71912
- $error: isError2,
71913
- id: "username",
71914
- onChange: (e2) => setUsername(e2.target.value),
71915
- required: true,
71916
- type: "text",
71917
- value: username
71918
- }
71919
- )),
71920
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(Label, { htmlFor: "password" }, "Password"), /* @__PURE__ */ React.createElement(
71921
- StyledInput,
71922
- {
71923
- $error: isError2,
71924
- id: "password",
71925
- onChange: (e2) => setPassword(e2.target.value),
71926
- required: true,
71927
- type: "password",
71928
- value: password
71929
- }
71930
- )),
71931
- /* @__PURE__ */ React.createElement(ErrorText$1, { $hidden: !isError2, style: { marginTop: "1rem" } }, "Incorrect Username or Password"),
71932
- /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement(
71933
- StyledButton,
71934
- {
71935
- loading: isLoggingIn,
71936
- style: { color: "white" },
71937
- styling: "primary",
71938
- type: "submit"
71939
- },
71940
- "Sign in"
71941
- ))
71942
- ))));
71943
- }
71944
- function BasicAuthLogout() {
71945
- React$1.useEffect(() => {
71946
- revokeSession().then(() => {
71947
- setSessionToken(null);
71948
- window.location.href = `${window.dara.base_url}/login`;
71949
- });
71950
- }, []);
71951
- return null;
71952
- }
71953
- function DefaultAuthLogin() {
71954
- const location2 = useLocation();
71955
- const navigate = useNavigate();
71956
- const { defaultPath } = useRouterContext();
71957
- const queryParams = new URLSearchParams(location2.search);
71958
- const previousLocation = queryParams.get("referrer") ?? defaultPath;
71959
- async function getNewToken() {
71960
- const sessionToken = await requestSessionToken({});
71961
- if (sessionToken) {
71962
- setSessionToken(sessionToken);
71963
- navigate(decodeURIComponent(previousLocation));
71964
- }
71965
- }
71966
- React$1.useEffect(() => {
71967
- if (getSessionToken()) {
71968
- verifySessionToken().then((verified) => {
71969
- if (verified) {
71970
- navigate(decodeURIComponent(previousLocation), { replace: true });
71971
- } else {
71972
- getNewToken();
71973
- }
71974
- });
71975
- } else {
71976
- getNewToken();
71977
- }
71978
- }, []);
71979
- return /* @__PURE__ */ React.createElement(Center, null, /* @__PURE__ */ React.createElement(DefaultFallback$1, null));
71980
- }
71981
- const CenteredDivWithGap$1 = styled(Center)`
71982
- gap: 1rem;
71983
- margin: 10px;
71984
- text-align: center;
71985
- `;
71986
- const config401 = {
71987
- description: "Your login session may have expired. Try again.",
71988
- styling: "primary",
71989
- title: "We were not able to authenticate you"
71990
- };
71991
- const errorMessages = {
71992
- "403": {
71993
- description: "You are not authorised to access this application. Please contact the application owner to enable access.",
71994
- styling: "error",
71995
- title: "We were not able to authenticate you"
71996
- },
71997
- "404": {
71998
- description: "The requested page could not be found.",
71999
- styling: "error",
72000
- title: "Page not found"
72001
- },
72002
- "401": config401,
72003
- default: config401
72004
- };
72005
- function ErrorPage(props) {
72006
- const { search } = useLocation();
72007
- const query = React$1.useMemo(() => new URLSearchParams(search), [search]);
72008
- const code = props.code ?? query.get("code");
72009
- const errorConfig = code && errorMessages[code] || errorMessages.default;
72010
- 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"));
72011
- }
72012
- function useRefreshSelector() {
72013
- return Recoil_index_31(({ refresh }) => {
72014
- return (key, extras) => {
72015
- const family = selectorFamilyRegistry.get(key);
72016
- if (family) {
72017
- const selector2 = selectorFamilyMembersRegistry.get(family)?.get(extras);
72018
- if (selector2) {
72019
- refresh(selector2);
72020
- }
72021
- }
72022
- };
72023
- });
72024
- }
72025
- function useVariableState() {
72026
- const extras = useRequestExtras();
72027
- const { client: client2 } = React$1.useContext(websocketCtx);
72028
- const taskCtx = useTaskContext();
72029
- return Recoil_index_31(({ snapshot }) => {
72030
- return async (variable) => {
72031
- if (!isRegistered(variable)) {
72032
- return "__NOT_REGISTERED__";
72033
- }
72034
- const resolvedVariable = await resolveVariable(
72035
- variable,
72036
- client2,
72037
- taskCtx,
72038
- extras,
72039
- (v) => snapshot.getLoadable(v).toPromise()
72040
- );
72041
- return resolvedVariable;
72042
- };
72043
- }, []);
72044
- }
72045
- var _arrayAggregator;
72046
- var hasRequired_arrayAggregator;
72047
- function require_arrayAggregator() {
72048
- if (hasRequired_arrayAggregator) return _arrayAggregator;
72049
- hasRequired_arrayAggregator = 1;
72050
- function arrayAggregator(array2, setter, iteratee, accumulator) {
72051
- var index2 = -1, length = array2 == null ? 0 : array2.length;
72052
- while (++index2 < length) {
72053
- var value = array2[index2];
72054
- setter(accumulator, value, iteratee(value), array2);
72055
- }
72056
- return accumulator;
72057
- }
72058
- _arrayAggregator = arrayAggregator;
72059
- return _arrayAggregator;
72060
- }
72061
- var _baseAggregator;
72062
- var hasRequired_baseAggregator;
72063
- function require_baseAggregator() {
72064
- if (hasRequired_baseAggregator) return _baseAggregator;
72065
- hasRequired_baseAggregator = 1;
72066
- var baseEach = require_baseEach();
72067
- function baseAggregator(collection, setter, iteratee, accumulator) {
72068
- baseEach(collection, function(value, key, collection2) {
72069
- setter(accumulator, value, iteratee(value), collection2);
72070
- });
72071
- return accumulator;
72072
- }
72073
- _baseAggregator = baseAggregator;
72074
- return _baseAggregator;
72075
- }
72076
- var _createAggregator;
72077
- var hasRequired_createAggregator;
72078
- function require_createAggregator() {
72079
- if (hasRequired_createAggregator) return _createAggregator;
72080
- hasRequired_createAggregator = 1;
72081
- var arrayAggregator = require_arrayAggregator(), baseAggregator = require_baseAggregator(), baseIteratee = require_baseIteratee(), isArray = requireIsArray();
72082
- function createAggregator(setter, initializer2) {
72083
- return function(collection, iteratee) {
72084
- var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer2 ? initializer2() : {};
72085
- return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
72086
- };
72087
- }
72088
- _createAggregator = createAggregator;
72089
- return _createAggregator;
72090
- }
72091
- var groupBy_1;
72092
- var hasRequiredGroupBy;
72093
- function requireGroupBy() {
72094
- if (hasRequiredGroupBy) return groupBy_1;
72095
- hasRequiredGroupBy = 1;
72096
- var baseAssignValue = require_baseAssignValue(), createAggregator = require_createAggregator();
72097
- var objectProto = Object.prototype;
72098
- var hasOwnProperty2 = objectProto.hasOwnProperty;
72099
- var groupBy2 = createAggregator(function(result, value, key) {
72100
- if (hasOwnProperty2.call(result, key)) {
72101
- result[key].push(value);
72102
- } else {
72103
- baseAssignValue(result, key, [value]);
72104
- }
72105
- });
72106
- groupBy_1 = groupBy2;
72107
- return groupBy_1;
72108
- }
72109
- var groupByExports = requireGroupBy();
72110
- const groupBy = /* @__PURE__ */ getDefaultExportFromCjs(groupByExports);
72111
- async function invokeAction(input, executionId, annotatedAction, actionCtx) {
72112
- const resolvedKwargs = await Promise.all(
72113
- Object.entries(annotatedAction.dynamic_kwargs).map(async ([k, value]) => {
72114
- const resolvedValue = isVariable(value) ? await resolveVariable(
72115
- value,
72116
- actionCtx.wsClient,
72117
- actionCtx.taskCtx,
72118
- actionCtx.extras,
72119
- (v) => actionCtx.snapshot.getLoadable(v).toPromise()
72120
- ) : value;
72121
- return [k, resolvedValue];
72122
- })
72123
- ).then((entries) => Object.fromEntries(entries));
72124
- const ws_channel = await actionCtx.wsClient.getChannel();
72125
- const res = await request(
72126
- `/api/core/action/${annotatedAction.definition_uid}`,
72127
- {
72128
- body: JSON.stringify({
72129
- execution_id: executionId,
72130
- input,
72131
- uid: annotatedAction.uid,
72132
- values: normalizeRequest(cleanKwargs(resolvedKwargs, null), annotatedAction.dynamic_kwargs),
72133
- ws_channel
72134
- }),
72135
- method: HTTP_METHOD.POST
72136
- },
72137
- actionCtx.extras
72138
- );
72139
- await handleAuthErrors(res, true);
72140
- await validateResponse(res, `Failed to fetch the action value with uid: ${annotatedAction.uid}`);
72141
- const resContent = await res.json();
72142
- if ("task_id" in resContent) {
72143
- const taskId = resContent.task_id;
72144
- actionCtx.taskCtx.startTask(taskId);
72145
- await actionCtx.wsClient.waitForTask(taskId);
72146
- actionCtx.taskCtx.endTask(taskId);
72147
- await fetchTaskResult(taskId, actionCtx.extras);
72148
- }
72149
- }
72150
- const ACTION_HANDLER_BY_NAME = {};
72151
- async function preloadActions(importers, actions) {
72152
- const componentsByModule = groupBy(actions, (actionDef) => actionDef.py_module);
72153
- await Promise.all(
72154
- Object.entries(componentsByModule).map(async ([module2, moduleActions]) => {
72155
- const moduleContent = await importers[module2]();
72156
- for (const action of moduleActions) {
72157
- if (ACTION_HANDLER_BY_NAME[action.name]) {
72158
- continue;
72159
- }
72160
- const actionHandler = moduleContent[action.name];
72161
- if (actionHandler) {
72162
- ACTION_HANDLER_BY_NAME[action.name] = actionHandler;
72163
- }
72164
- }
72165
- })
72166
- );
72167
- }
72168
- function clearActionHandlerCache_TEST() {
72169
- Object.keys(ACTION_HANDLER_BY_NAME).forEach((k) => delete ACTION_HANDLER_BY_NAME[k]);
72170
- }
72171
- class UnhandledActionError extends Error {
72172
- constructor(message, actionImpl) {
72173
- super(message);
72174
- this.actionImpl = actionImpl;
72175
- }
72176
- }
72177
- function resolveActionImpl(actionImpl, actionCtx) {
72178
- let actionHandler;
72179
- if (!ACTION_HANDLER_BY_NAME[actionImpl.name]) {
72180
- if (actionCtx.onUnhandledAction) {
72181
- actionHandler = actionCtx.onUnhandledAction;
72182
- } else {
72183
- throw new UnhandledActionError(`Action definition for impl "${actionImpl.name}" not found`, actionImpl);
72184
- }
72185
- } else {
72186
- actionHandler = ACTION_HANDLER_BY_NAME[actionImpl.name];
72187
- }
72188
- return actionHandler;
72189
- }
72190
- async function executeAction(input, action, actionCtx) {
72191
- if (isActionImpl(action)) {
72192
- const handler = resolveActionImpl(action, actionCtx);
72193
- const result = handler(actionCtx, action);
72194
- if (result instanceof Promise) {
72195
- await result;
72196
- }
72197
- return;
72198
- }
72199
- const executionId = nanoid$1();
72200
- const observable2 = actionCtx.wsClient.actionMessages$(executionId);
72201
- return new Promise((resolve, reject) => {
72202
- let activeTasks = 0;
72203
- let streamCompleted = false;
72204
- let isSettled = false;
72205
- let sub;
72206
- const checkForCompletion = () => {
72207
- if (!isSettled && streamCompleted && activeTasks === 0) {
72208
- isSettled = true;
72209
- sub.unsubscribe();
72210
- resolve();
72211
- }
72212
- };
72213
- const onError = (error) => {
72214
- if (!isSettled) {
72215
- isSettled = true;
72216
- sub.unsubscribe();
72217
- reject(error);
72218
- }
72219
- };
72220
- sub = observable2.pipe(
72221
- // eslint-disable-next-line @typescript-eslint/require-await
72222
- concatMap(async (actionImpl) => {
72223
- if (actionImpl) {
72224
- const handler = resolveActionImpl(actionImpl, actionCtx);
72225
- return [handler, actionImpl];
72226
- }
72227
- return null;
72228
- }),
72229
- takeWhile((res) => !!res)
72230
- // stop when falsy is returned from concatMap
72231
- ).subscribe({
72232
- complete: () => {
72233
- streamCompleted = true;
72234
- checkForCompletion();
72235
- },
72236
- error: onError,
72237
- // Reject the promise if there's an error in the stream
72238
- next: async ([handler, actionImpl]) => {
72239
- try {
72240
- activeTasks += 1;
72241
- const result = handler(actionCtx, actionImpl);
72242
- if (result instanceof Promise) {
72243
- await result;
72244
- }
72245
- } catch (error) {
72246
- onError(error);
72247
- } finally {
72248
- if (activeTasks > 0) {
72249
- activeTasks -= 1;
72250
- }
72251
- checkForCompletion();
72252
- }
72253
- }
72254
- });
72255
- invokeAction(input, executionId, action, actionCtx).catch(onError);
72256
- });
72257
- }
72258
- const noop = () => Promise.resolve();
72259
- function useActionIsLoading(action) {
72260
- if (!action || isActionImpl(action) || Array.isArray(action)) {
72261
- return false;
72262
- }
72263
- 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];
72264
71528
  }
72265
71529
  function useExecuteAction() {
72266
71530
  const { client: wsClient } = React$1.useContext(websocketCtx);
@@ -72406,16 +71670,55 @@ Inferred class string: "${iconClasses}."`
72406
71670
  }
72407
71671
  return callback;
72408
71672
  }
72409
- function isTaskResponse(response) {
72410
- return response && typeof response === "object" && "task_id" in response;
72411
- }
72412
- function getComponentRegistryKey(uid2, trigger, loopInstanceUid) {
72413
- let key = `_COMPONENT_${uid2}`;
72414
- if (trigger) {
72415
- key += "_TRIGGER";
71673
+ function isConditionTrue(operator, value, other) {
71674
+ if (operator === ConditionOperator.EQUAL) {
71675
+ return value === other;
72416
71676
  }
72417
- if (loopInstanceUid) {
72418
- 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}`;
72419
71722
  }
72420
71723
  return key;
72421
71724
  }
@@ -72658,6 +71961,18 @@ Inferred class string: "${iconClasses}."`
72658
71961
  [uid2]
72659
71962
  );
72660
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
+ `;
72661
71976
  const ErrorBoundaryContext = React$1.createContext(null);
72662
71977
  const initialState = {
72663
71978
  didCatch: false,
@@ -72828,7 +72143,17 @@ Inferred class string: "${iconClasses}."`
72828
72143
  walk(renderer, []);
72829
72144
  return markers;
72830
72145
  }
72831
- 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
+ }) {
72832
72157
  if (markers.length === 0) {
72833
72158
  return renderer;
72834
72159
  }
@@ -72836,7 +72161,17 @@ Inferred class string: "${iconClasses}."`
72836
72161
  for (const marker of markers) {
72837
72162
  switch (marker.type) {
72838
72163
  case "loop_var": {
72839
- 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);
72840
72175
  break;
72841
72176
  }
72842
72177
  case "action": {
@@ -73059,7 +72394,7 @@ Inferred class string: "${iconClasses}."`
73059
72394
  line-height: 1.375rem;
73060
72395
  color: ${(props) => props.theme.colors.error};
73061
72396
  `;
73062
- const ErrorText = styled.span`
72397
+ const ErrorText$1 = styled.span`
73063
72398
  font-size: 0.875rem;
73064
72399
  line-height: 1.25rem;
73065
72400
  `;
@@ -73104,7 +72439,7 @@ Inferred class string: "${iconClasses}."`
73104
72439
  const [cssValue] = useVariable(props.config?.raw_css);
73105
72440
  const [styles2, css2] = parseRawCss(cssValue);
73106
72441
  const defaultMessage = props.error instanceof UserError ? props.error.message : "Try again or contact the application owner.";
73107
- 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" })));
73108
72443
  }
73109
72444
  function cleanProps(props) {
73110
72445
  if ("children" in props && Array.isArray(props.children)) {
@@ -73899,7 +73234,7 @@ Inferred class string: "${iconClasses}."`
73899
73234
  }, [wsClient]);
73900
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))))));
73901
73236
  }
73902
- const Wrapper = styled.div`
73237
+ const Wrapper$1 = styled.div`
73903
73238
  overflow: auto;
73904
73239
  display: flex;
73905
73240
  flex: 1 1 auto;
@@ -73910,6 +73245,1097 @@ Inferred class string: "${iconClasses}."`
73910
73245
 
73911
73246
  background-color: ${(props) => props.backgroundColor};
73912
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
+ }
73913
74339
  const CenteredDivWithGap = styled.div`
73914
74340
  display: flex;
73915
74341
  flex: 1;
@@ -74048,292 +74474,7 @@ body,
74048
74474
  }
74049
74475
  }
74050
74476
  }, [navigation.state]);
74051
- return /* @__PURE__ */ React.createElement(PathParamSync, null, /* @__PURE__ */ React.createElement(RecoilSync_index_3, { ...syncOptions }, /* @__PURE__ */ React.createElement(StyleRoot, null, /* @__PURE__ */ React.createElement(Outlet, null))));
74052
- }
74053
- class SingleUseCache {
74054
- constructor(options = {}) {
74055
- this.cache = /* @__PURE__ */ new Map();
74056
- this.defaultTimeout = options.defaultTimeout ?? 5e3;
74057
- }
74058
- isEntryStale(entry, timeout) {
74059
- const timeoutMs = timeout ?? this.defaultTimeout;
74060
- return Date.now() - entry.timestamp > timeoutMs;
74061
- }
74062
- has(key, timeout) {
74063
- const entry = this.cache.get(key);
74064
- return entry ? !this.isEntryStale(entry, timeout) : false;
74065
- }
74066
- get(key, timeout) {
74067
- const entry = this.cache.get(key);
74068
- if (!entry || this.isEntryStale(entry, timeout)) {
74069
- return void 0;
74070
- }
74071
- this.delete(key);
74072
- return entry.data;
74073
- }
74074
- set(key, value) {
74075
- this.cache.set(key, {
74076
- data: value,
74077
- timestamp: Date.now()
74078
- });
74079
- }
74080
- delete(key) {
74081
- return this.cache.delete(key);
74082
- }
74083
- clear() {
74084
- this.cache.clear();
74085
- }
74086
- /**
74087
- * Set a value if it doesn't exist in the cache, otherwise return the existing value.
74088
- * The promise resolves the the new or existing value stored.
74089
- *
74090
- * @param key cache key
74091
- * @param computeFn function to compute the value
74092
- * @param timeout optional timeout in ms
74093
- */
74094
- setIfMissing(key, computeFn, timeout) {
74095
- const entry = this.cache.get(key);
74096
- if (entry && !this.isEntryStale(entry, timeout)) {
74097
- return Promise.resolve(entry.data);
74098
- }
74099
- const promise = computeFn();
74100
- this.set(key, promise);
74101
- return promise;
74102
- }
74103
- size() {
74104
- return this.cache.size;
74105
- }
74106
- keys() {
74107
- return this.cache.keys();
74108
- }
74109
- entries() {
74110
- return Array.from(this.cache.entries()).map(([key, entry]) => [key, entry.data]);
74111
- }
74112
- }
74113
- const NormalizedObject = object$3({
74114
- data: any(),
74115
- lookup: record(string(), any())
74116
- });
74117
- const TemplateChunk = object$3({
74118
- type: literal("template"),
74119
- template: NormalizedObject
74120
- });
74121
- const ActionChunk = object$3({
74122
- type: literal("actions"),
74123
- actions: record(string(), array$3(ActionImpl))
74124
- });
74125
- const DerivedVariableChunk = object$3({
74126
- type: literal("derived_variable"),
74127
- uid: string(),
74128
- result: object$3({ ok: boolean(), value: any() })
74129
- });
74130
- const PyComponentChunk = object$3({
74131
- type: literal("py_component"),
74132
- uid: string(),
74133
- result: object$3({ ok: boolean(), value: any() })
74134
- });
74135
- const ResponseChunk = union([TemplateChunk, ActionChunk, DerivedVariableChunk, PyComponentChunk]);
74136
- const PRELOAD_TIMEOUT = 5e3;
74137
- const preloadCache = new SingleUseCache({
74138
- defaultTimeout: PRELOAD_TIMEOUT
74139
- });
74140
- function createCacheKey(routeId, params) {
74141
- return `${routeId}:${JSON.stringify(params)}`;
74142
- }
74143
- async function* ndjson(response, signal) {
74144
- const reader = response.body.getReader();
74145
- const newline = /\r?\n/;
74146
- const decoder = new TextDecoder();
74147
- let buffer = "";
74148
- while (true) {
74149
- if (signal?.aborted) {
74150
- throw new DOMException("The operation was aborted", "AbortError");
74151
- }
74152
- const { done, value } = await reader.read();
74153
- if (done) {
74154
- if (buffer.length > 0) {
74155
- yield JSON.parse(buffer);
74156
- }
74157
- return;
74158
- }
74159
- const chunk = decoder.decode(value, { stream: true });
74160
- buffer += chunk;
74161
- const parts = buffer.split(newline);
74162
- buffer = parts.pop();
74163
- for (const part of parts) {
74164
- yield JSON.parse(part);
74165
- }
74166
- }
74167
- }
74168
- async function fetchRouteData(route, params, snapshot, signal) {
74169
- let actions = [];
74170
- if (Array.isArray(route.on_load)) {
74171
- actions = route.on_load;
74172
- } else if (route.on_load) {
74173
- actions = [route.on_load];
74174
- }
74175
- const actionPayloads = actions.filter(isAnnotatedAction).map((a2) => {
74176
- const kwargs = cleanKwargs(
74177
- Object.fromEntries(
74178
- Object.entries(a2.dynamic_kwargs).map(([k, v]) => {
74179
- return [k, resolveVariableStatic(v, snapshot, params)];
74180
- })
74181
- ),
74182
- null
74183
- );
74184
- return {
74185
- uid: a2.uid,
74186
- definition_uid: a2.definition_uid,
74187
- values: normalizeRequest(kwargs, a2.dynamic_kwargs)
74188
- };
74189
- });
74190
- const dvHandles = Object.values(route.dependency_graph?.derived_variables ?? {}).flatMap((dv) => {
74191
- const handle = preloadDerivedVariable(dv, snapshot, params);
74192
- if (!handle) {
74193
- return [];
74194
- }
74195
- return {
74196
- ...handle,
74197
- dv,
74198
- payload: {
74199
- values: normalizeRequest(cleanArgs(handle.result.values, null), dv.variables),
74200
- uid: dv.uid
74201
- }
74202
- };
74203
- });
74204
- const pyHandles = Object.values(route.dependency_graph?.py_components ?? {}).flatMap((py) => {
74205
- const handle = preloadServerComponent(py, snapshot, params);
74206
- if (!handle) {
74207
- return [];
74208
- }
74209
- const kwargValues = cleanKwargs(
74210
- Object.keys(py.props.dynamic_kwargs).reduce(
74211
- (acc, k, idx) => {
74212
- acc[k] = handle.result.values[idx];
74213
- return acc;
74214
- },
74215
- {}
74216
- )
74217
- );
74218
- return {
74219
- ...handle,
74220
- py,
74221
- payload: {
74222
- uid: py.uid,
74223
- name: py.name,
74224
- values: normalizeRequest(kwargValues, py.props.dynamic_kwargs)
74225
- }
74226
- };
74227
- });
74228
- const dvHandlesByUid = dvHandles.reduce(
74229
- (acc, h) => ({ ...acc, [h.dv.uid]: h }),
74230
- {}
74231
- );
74232
- const pyHandlesByUid = pyHandles.reduce(
74233
- (acc, h) => ({ ...acc, [h.py.uid]: h }),
74234
- {}
74235
- );
74236
- const wsClient = await window.dara.ws.getValue();
74237
- const wsChannel = await wsClient.getChannel();
74238
- const response = await request(`/api/core/route/${route.id}`, {
74239
- method: HTTP_METHOD.POST,
74240
- body: JSON.stringify({
74241
- action_payloads: actionPayloads,
74242
- derived_variable_payloads: dvHandles.map((h) => h.payload),
74243
- py_component_payloads: pyHandles.map((h) => h.payload),
74244
- ws_channel: wsChannel,
74245
- params
74246
- }),
74247
- signal
74248
- });
74249
- await handleAuthErrors(response, true);
74250
- if (!response.ok) {
74251
- const error = await response.json();
74252
- throw new LoaderError(error.detail);
74253
- }
74254
- const template = deferred();
74255
- const onLoadActions = deferred();
74256
- const resolvedDvs = /* @__PURE__ */ new Set();
74257
- const resolvedPyComponents = /* @__PURE__ */ new Set();
74258
- queueMicrotask(async () => {
74259
- try {
74260
- for await (const data2 of ndjson(response, signal)) {
74261
- const chunk = ResponseChunk.parse(data2);
74262
- if (chunk.type === "template") {
74263
- const component = denormalize(chunk.template.data, chunk.template.lookup);
74264
- template.resolve(component);
74265
- }
74266
- if (chunk.type === "actions") {
74267
- onLoadActions.resolve(actions.flatMap((a2) => isAnnotatedAction(a2) ? chunk.actions[a2.uid] : a2));
74268
- }
74269
- if (chunk.type === "derived_variable") {
74270
- dvHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
74271
- resolvedDvs.add(chunk.uid);
74272
- }
74273
- if (chunk.type === "py_component") {
74274
- pyHandlesByUid[chunk.uid]?.handle.resolve(chunk.result);
74275
- resolvedPyComponents.add(chunk.uid);
74276
- }
74277
- }
74278
- } catch (e2) {
74279
- template.reject(e2);
74280
- onLoadActions.reject(e2);
74281
- for (const [uid2, handle] of Object.entries(dvHandlesByUid)) {
74282
- if (!resolvedDvs.has(uid2)) {
74283
- handle.handle.reject(e2);
74284
- }
74285
- }
74286
- for (const [uid2, handle] of Object.entries(pyHandlesByUid)) {
74287
- if (!resolvedPyComponents.has(uid2)) {
74288
- handle.handle.reject(e2);
74289
- }
74290
- }
74291
- }
74292
- });
74293
- const [templateValue, onLoadActionsValue] = await Promise.all([template.getValue(), onLoadActions.getValue()]);
74294
- return {
74295
- template: templateValue,
74296
- on_load: onLoadActionsValue,
74297
- route_definition: route,
74298
- py_components: pyHandles,
74299
- derived_variables: dvHandles
74300
- };
74301
- }
74302
- function getFromPreloadCache(routeId, params) {
74303
- return preloadCache.get(createCacheKey(routeId, params));
74304
- }
74305
- function usePreloadRoute() {
74306
- const currentMatches = useMatches();
74307
- const { routeObjects, routeDefMap } = useRouterContext();
74308
- return Recoil_index_31(
74309
- ({ snapshot }) => async (url) => {
74310
- const matches2 = matchRoutes(routeObjects, url, window.dara?.base_url);
74311
- if (!matches2) {
74312
- return;
74313
- }
74314
- const release = snapshot.retain();
74315
- try {
74316
- await Promise.all(
74317
- matches2.filter(
74318
- (match2) => !currentMatches.some(
74319
- (m) => m.id === match2.route.id && isEqual$4(m.params, match2.params)
74320
- )
74321
- ).map((match2) => {
74322
- const routeDef = routeDefMap.get(match2.route.id);
74323
- if (!routeDef) {
74324
- return Promise.resolve();
74325
- }
74326
- return preloadCache.setIfMissing(createCacheKey(routeDef.id, match2.params), () => {
74327
- return fetchRouteData(routeDef, match2.params, snapshot);
74328
- });
74329
- })
74330
- );
74331
- } finally {
74332
- release();
74333
- }
74334
- },
74335
- [routeDefMap, routeObjects, currentMatches]
74336
- );
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)))));
74337
74478
  }
74338
74479
  function shouldHoldPromise(route) {
74339
74480
  return !route.fallback;
@@ -74579,7 +74720,8 @@ body,
74579
74720
  routeDefinitions: config2.router.children,
74580
74721
  routeObjects: userRoutes,
74581
74722
  routeDefMap,
74582
- defaultPath
74723
+ defaultPath,
74724
+ routeMatches: config2.router.route_matches
74583
74725
  };
74584
74726
  }
74585
74727
  function RouterRoot({ daraData }) {
@@ -74591,7 +74733,8 @@ body,
74591
74733
  routeDefinitions: routerData.routeDefinitions,
74592
74734
  routeObjects: routerData.routeObjects,
74593
74735
  routeDefMap: routerData.routeDefMap,
74594
- defaultPath: routerData.defaultPath
74736
+ defaultPath: routerData.defaultPath,
74737
+ routeMatches: routerData.routeMatches
74595
74738
  },
74596
74739
  /* @__PURE__ */ React.createElement(RouterProvider2, { router: routerData.router })
74597
74740
  );
@@ -74616,6 +74759,46 @@ body,
74616
74759
  const root = clientExports.createRoot(container);
74617
74760
  root.render(/* @__PURE__ */ React.createElement(Root, { daraData, queryClient }));
74618
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
+ }
74619
74802
  function getBasename() {
74620
74803
  if (window.dara.base_url !== "") {
74621
74804
  return new URL(window.dara.base_url, window.origin).pathname;
@@ -74637,7 +74820,7 @@ body,
74637
74820
  }
74638
74821
  return pathname.slice(startIndex) || "/";
74639
74822
  }
74640
- const NavigateTo = (ctx, actionImpl) => {
74823
+ const NavigateTo = async (ctx, actionImpl) => {
74641
74824
  const basename = getBasename();
74642
74825
  let isExternal = false;
74643
74826
  let to = actionImpl.url;
@@ -74669,7 +74852,8 @@ body,
74669
74852
  window.location.href = to;
74670
74853
  return;
74671
74854
  }
74672
- ctx.navigate(to, actionImpl.options);
74855
+ const resolvedTo = await resolveTo(to, ctx);
74856
+ ctx.navigate(resolvedTo, actionImpl.options);
74673
74857
  };
74674
74858
  const ResetVariables = (ctx, actionImpl) => {
74675
74859
  actionImpl.variables.filter(isVariable).forEach((variable) => {
@@ -98078,6 +98262,39 @@ body,
98078
98262
  title: actionImpl.title
98079
98263
  });
98080
98264
  };
98265
+ const CopyToClipboard = async (ctx, actionImpl) => {
98266
+ let value;
98267
+ if (!isVariable(actionImpl.value)) {
98268
+ value = actionImpl.value;
98269
+ } else {
98270
+ if (!isSingleVariable(actionImpl.value)) {
98271
+ throw new UserError("CopyToClipboard only supports simple Variables");
98272
+ }
98273
+ value = await resolveVariable(
98274
+ actionImpl.value,
98275
+ ctx.wsClient,
98276
+ ctx.taskCtx,
98277
+ ctx.extras,
98278
+ (v) => ctx.snapshot.getPromise(v)
98279
+ );
98280
+ }
98281
+ const success2 = await copyToClipboard(value);
98282
+ if (!success2) {
98283
+ ctx.notificationCtx.pushNotification({
98284
+ key: "_copyToClipboard",
98285
+ message: actionImpl.error_message ?? "",
98286
+ status: Status.ERROR,
98287
+ title: "Error copying to clipboard"
98288
+ });
98289
+ } else {
98290
+ ctx.notificationCtx.pushNotification({
98291
+ key: "_copyToClipboard",
98292
+ message: actionImpl.success_message ?? "",
98293
+ status: Status.SUCCESS,
98294
+ title: "Copied to clipboard"
98295
+ });
98296
+ }
98297
+ };
98081
98298
  const MenuItem = styled(NavLink)`
98082
98299
  cursor: pointer;
98083
98300
 
@@ -98151,7 +98368,7 @@ body,
98151
98368
  ${(props) => props.$inactiveCss}
98152
98369
  }
98153
98370
  `;
98154
- function Link(props) {
98371
+ function LinkImpl(props) {
98155
98372
  const displayCtx$1 = React__namespace.useContext(displayCtx);
98156
98373
  const [style, css2] = useComponentStyles(props);
98157
98374
  const [activeStyle, activeCss] = useComponentStyles(props, true, "active_css");
@@ -98220,6 +98437,14 @@ body,
98220
98437
  props.children.map((child, idx) => /* @__PURE__ */ React__namespace.createElement(DynamicComponent$1, { component: child, key: idx }))
98221
98438
  ));
98222
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
+ }
98223
98448
  const StyledLink = styled(Link)`
98224
98449
  cursor: pointer;
98225
98450
 
@@ -98380,7 +98605,7 @@ body,
98380
98605
  const logoSrc = theme2.themeType === "dark" ? DaraDark : DaraLight;
98381
98606
  const daraLogo = /* @__PURE__ */ React.createElement("img", { alt: "Dara Logo", src: logoSrc });
98382
98607
  const showPoweredBy = props.powered_by_causalens ?? config2.powered_by_causalens;
98383
- 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 })));
98384
98609
  }
98385
98610
  const shouldForwardProp = (prop) => !["width"].includes(prop);
98386
98611
  const TopBar = styled.div.withConfig({ shouldForwardProp })`
@@ -98441,7 +98666,7 @@ body,
98441
98666
  color: ${(props) => props.theme.colors.blue1};
98442
98667
  }
98443
98668
  `;
98444
- const RouteButtons = styled(Wrapper)`
98669
+ const RouteButtons = styled(Wrapper$1)`
98445
98670
  gap: 0.5rem;
98446
98671
  align-items: center;
98447
98672
  `;
@@ -98462,7 +98687,7 @@ body,
98462
98687
  const logo = props.logo_path && /* @__PURE__ */ React.createElement(LogoImage, { alt: "Logo", src: prependBaseUrl(props.logo_path), width: props.logo_width });
98463
98688
  const logoSrc = theme2.themeType === "dark" ? DaraDark : DaraLight;
98464
98689
  const daraLogo = /* @__PURE__ */ React.createElement("img", { alt: "Dara", src: logoSrc });
98465
- 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 })));
98466
98691
  }
98467
98692
  const RowDots = styled(Dots)`
98468
98693
  height: 2.5rem;
@@ -98475,6 +98700,19 @@ body,
98475
98700
  function DefaultFallback(props) {
98476
98701
  return /* @__PURE__ */ React.createElement(DynamicComponent$1, { component: props.component });
98477
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
+ }
98478
98716
  const createItemData = (items, renderer, markers, getItemKey) => ({
98479
98717
  items,
98480
98718
  renderer,
@@ -98485,12 +98723,14 @@ body,
98485
98723
  const transformedRenderer = React__namespace.useMemo(() => {
98486
98724
  let component;
98487
98725
  try {
98488
- component = applyMarkers(
98489
- props.data.renderer,
98490
- props.data.markers,
98491
- props.data.items[props.index],
98492
- props.data.getItemKey(props.index, props.data)
98493
- );
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
+ });
98494
98734
  } catch (e2) {
98495
98735
  console.error("Failed to apply markers", e2);
98496
98736
  component = copy(props.data.renderer);
@@ -98576,6 +98816,7 @@ body,
98576
98816
  exports.ComponentType = ComponentType;
98577
98817
  exports.ConditionOperator = ConditionOperator;
98578
98818
  exports.ConfigContextProvider = ConfigContextProvider;
98819
+ exports.CopyToClipboard = CopyToClipboard;
98579
98820
  exports.CustomFallback = DefaultFallback;
98580
98821
  exports.DARA_JWT_TOKEN = DARA_JWT_TOKEN;
98581
98822
  exports.DEFAULT_BUS = DEFAULT_BUS;
@@ -98593,6 +98834,7 @@ body,
98593
98834
  exports.Link = Link;
98594
98835
  exports.LoaderError = LoaderError;
98595
98836
  exports.LockSecuredCache = SingleUseCache;
98837
+ exports.Match = Match;
98596
98838
  exports.Menu = Menu;
98597
98839
  exports.MenuLink = MenuLink;
98598
98840
  exports.Navigate = Navigate;
@@ -98622,7 +98864,7 @@ body,
98622
98864
  exports.VariableCtx = variablesCtx;
98623
98865
  exports.WebSocketClient = WebSocketClient;
98624
98866
  exports.WebSocketCtx = websocketCtx;
98625
- exports.Wrapper = Wrapper;
98867
+ exports.Wrapper = Wrapper$1;
98626
98868
  exports.atomFamilyMembersRegistry = atomFamilyMembersRegistry;
98627
98869
  exports.atomFamilyRegistry = atomFamilyRegistry;
98628
98870
  exports.atomRegistry = atomRegistry;
@@ -98633,6 +98875,7 @@ body,
98633
98875
  exports.clearRegistries_TEST = clearRegistries_TEST;
98634
98876
  exports.combineFilters = combineFilters;
98635
98877
  exports.createRouteLoader = createRouteLoader;
98878
+ exports.createRouteMatches = createRouteMatches;
98636
98879
  exports.createRouter = createRouter;
98637
98880
  exports.default = run;
98638
98881
  exports.deferred = deferred;
@@ -98675,6 +98918,7 @@ body,
98675
98918
  exports.isResolvedDerivedVariable = isResolvedDerivedVariable;
98676
98919
  exports.isResolvedServerVariable = isResolvedServerVariable;
98677
98920
  exports.isResolvedSwitchVariable = isResolvedSwitchVariable;
98921
+ exports.isRouteMatchStore = isRouteMatchStore;
98678
98922
  exports.isServerVariable = isServerVariable;
98679
98923
  exports.isSingleVariable = isSingleVariable;
98680
98924
  exports.isStateVariable = isStateVariable;
@@ -98715,7 +98959,7 @@ body,
98715
98959
  exports.useFetchTabularServerVariable = useFetchTabularServerVariable;
98716
98960
  exports.useInterval = useInterval;
98717
98961
  exports.usePreloadRoute = usePreloadRoute;
98718
- exports.usePrevious = usePrevious$1;
98962
+ exports.usePrevious = usePrevious;
98719
98963
  exports.useRefreshSelector = useRefreshSelector;
98720
98964
  exports.useRefreshServerComponent = useRefreshServerComponent;
98721
98965
  exports.useRequestExtras = useRequestExtras;