dara-core 1.21.16__py3-none-any.whl → 1.21.18__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.
Files changed (88) hide show
  1. dara/core/auth/base.py +5 -5
  2. dara/core/auth/basic.py +3 -3
  3. dara/core/auth/definitions.py +13 -14
  4. dara/core/auth/routes.py +7 -5
  5. dara/core/auth/utils.py +11 -10
  6. dara/core/base_definitions.py +30 -36
  7. dara/core/cli.py +7 -8
  8. dara/core/configuration.py +51 -58
  9. dara/core/css.py +2 -2
  10. dara/core/data_utils.py +12 -17
  11. dara/core/defaults.py +3 -3
  12. dara/core/definitions.py +58 -63
  13. dara/core/http.py +4 -4
  14. dara/core/interactivity/actions.py +34 -42
  15. dara/core/interactivity/any_data_variable.py +1 -1
  16. dara/core/interactivity/any_variable.py +6 -5
  17. dara/core/interactivity/client_variable.py +1 -2
  18. dara/core/interactivity/condition.py +2 -2
  19. dara/core/interactivity/data_variable.py +2 -4
  20. dara/core/interactivity/derived_data_variable.py +7 -10
  21. dara/core/interactivity/derived_variable.py +45 -51
  22. dara/core/interactivity/filtering.py +19 -19
  23. dara/core/interactivity/loop_variable.py +2 -4
  24. dara/core/interactivity/non_data_variable.py +1 -1
  25. dara/core/interactivity/plain_variable.py +22 -18
  26. dara/core/interactivity/server_variable.py +13 -15
  27. dara/core/interactivity/state_variable.py +4 -5
  28. dara/core/interactivity/switch_variable.py +16 -16
  29. dara/core/interactivity/tabular_variable.py +3 -3
  30. dara/core/interactivity/url_variable.py +3 -3
  31. dara/core/internal/cache_store/cache_store.py +6 -6
  32. dara/core/internal/cache_store/keep_all.py +3 -3
  33. dara/core/internal/cache_store/lru.py +8 -8
  34. dara/core/internal/cache_store/ttl.py +4 -4
  35. dara/core/internal/custom_response.py +3 -3
  36. dara/core/internal/dependency_resolution.py +6 -10
  37. dara/core/internal/devtools.py +2 -3
  38. dara/core/internal/download.py +5 -6
  39. dara/core/internal/encoder_registry.py +7 -11
  40. dara/core/internal/execute_action.py +5 -5
  41. dara/core/internal/hashing.py +1 -2
  42. dara/core/internal/import_discovery.py +7 -9
  43. dara/core/internal/normalization.py +12 -15
  44. dara/core/internal/pandas_utils.py +6 -6
  45. dara/core/internal/pool/channel.py +3 -4
  46. dara/core/internal/pool/definitions.py +9 -9
  47. dara/core/internal/pool/task_pool.py +8 -8
  48. dara/core/internal/pool/utils.py +4 -3
  49. dara/core/internal/pool/worker.py +3 -3
  50. dara/core/internal/registries.py +4 -4
  51. dara/core/internal/registry.py +3 -3
  52. dara/core/internal/registry_lookup.py +4 -4
  53. dara/core/internal/routing.py +34 -37
  54. dara/core/internal/scheduler.py +8 -8
  55. dara/core/internal/settings.py +1 -2
  56. dara/core/internal/store.py +9 -9
  57. dara/core/internal/tasks.py +30 -30
  58. dara/core/internal/utils.py +9 -15
  59. dara/core/internal/websocket.py +18 -18
  60. dara/core/js_tooling/js_utils.py +19 -19
  61. dara/core/logging.py +13 -13
  62. dara/core/main.py +11 -6
  63. dara/core/metrics/cache.py +2 -4
  64. dara/core/persistence.py +19 -25
  65. dara/core/router/compat.py +1 -3
  66. dara/core/router/components.py +10 -10
  67. dara/core/router/dependency_graph.py +2 -4
  68. dara/core/router/router.py +43 -42
  69. dara/core/umd/dara.core.umd.cjs +44 -197
  70. dara/core/visual/components/dynamic_component.py +1 -3
  71. dara/core/visual/components/fallback.py +3 -3
  72. dara/core/visual/components/for_cmp.py +5 -5
  73. dara/core/visual/components/menu.py +1 -3
  74. dara/core/visual/components/router_content.py +1 -3
  75. dara/core/visual/components/sidebar_frame.py +8 -10
  76. dara/core/visual/components/theme_provider.py +3 -3
  77. dara/core/visual/components/topbar_frame.py +8 -10
  78. dara/core/visual/css/__init__.py +277 -277
  79. dara/core/visual/dynamic_component.py +18 -22
  80. dara/core/visual/progress_updater.py +1 -1
  81. dara/core/visual/template.py +10 -12
  82. dara/core/visual/themes/definitions.py +46 -46
  83. {dara_core-1.21.16.dist-info → dara_core-1.21.18.dist-info}/METADATA +13 -13
  84. dara_core-1.21.18.dist-info/RECORD +127 -0
  85. dara_core-1.21.16.dist-info/RECORD +0 -127
  86. {dara_core-1.21.16.dist-info → dara_core-1.21.18.dist-info}/LICENSE +0 -0
  87. {dara_core-1.21.16.dist-info → dara_core-1.21.18.dist-info}/WHEEL +0 -0
  88. {dara_core-1.21.16.dist-info → dara_core-1.21.18.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- from typing import Annotated, Any, Literal, Optional, Union
1
+ from typing import Annotated, Any, Literal
2
2
 
3
3
  from pydantic import BeforeValidator
4
4
 
@@ -38,7 +38,7 @@ class Navigate(ComponentInstance):
38
38
  ```
39
39
  """
40
40
 
41
- to: Union[str, RouterPath, ClientVariable]
41
+ to: str | RouterPath | ClientVariable
42
42
 
43
43
  replace: bool = False
44
44
  """
@@ -132,21 +132,21 @@ class Link(StyledComponentInstance):
132
132
  ```
133
133
  """
134
134
 
135
- to: Union[str, RouterPath, ClientVariable]
135
+ to: str | RouterPath | ClientVariable
136
136
  """
137
137
  Can be a string or RouterPath object
138
138
  """
139
139
 
140
140
  # core anchor element attributes
141
- target: Optional[str] = None
142
- download: Optional[str] = None
143
- rel: Optional[str] = None
144
- referrer_policy: Optional[str] = None
141
+ target: str | None = None
142
+ download: str | None = None
143
+ rel: str | None = None
144
+ referrer_policy: str | None = None
145
145
 
146
- active_css: Annotated[Optional[Any], BeforeValidator(transform_raw_css)] = None
147
- inactive_css: Annotated[Optional[Any], BeforeValidator(transform_raw_css)] = None
146
+ active_css: Annotated[Any | None, BeforeValidator(transform_raw_css)] = None
147
+ inactive_css: Annotated[Any | None, BeforeValidator(transform_raw_css)] = None
148
148
 
149
- def __init__(self, *children: Union[str, ComponentInstance], **kwargs):
149
+ def __init__(self, *children: str | ComponentInstance, **kwargs):
150
150
  components = list(children)
151
151
  if 'children' not in kwargs:
152
152
  kwargs['children'] = components
@@ -1,5 +1,3 @@
1
- from typing import Dict
2
-
3
1
  from pydantic import BaseModel, Field, SerializeAsAny
4
2
 
5
3
  from dara.core.definitions import ComponentInstance
@@ -12,12 +10,12 @@ class DependencyGraph(BaseModel):
12
10
  Data structure representing dependencies for derived state on a page
13
11
  """
14
12
 
15
- derived_variables: SerializeAsAny[Dict[str, DerivedVariable]] = Field(default_factory=dict)
13
+ derived_variables: SerializeAsAny[dict[str, DerivedVariable]] = Field(default_factory=dict)
16
14
  """
17
15
  Map of DerivedVariable instances
18
16
  """
19
17
 
20
- py_components: SerializeAsAny[Dict[str, PyComponentInstance]] = Field(default_factory=dict)
18
+ py_components: SerializeAsAny[dict[str, PyComponentInstance]] = Field(default_factory=dict)
21
19
  """
22
20
  Map of PyComponentInstance instances
23
21
  """
@@ -1,7 +1,8 @@
1
1
  import inspect
2
2
  import re
3
3
  from abc import abstractmethod
4
- from typing import Any, Callable, Dict, List, Literal, Optional, TypedDict, Union
4
+ from collections.abc import Callable
5
+ from typing import Any, Literal, Optional, TypedDict
5
6
  from urllib.parse import quote
6
7
  from uuid import uuid4
7
8
 
@@ -29,7 +30,7 @@ PARAM_REGEX = re.compile(r':([\w-]+)\??')
29
30
  STAR_REGEX = re.compile(r'\*$')
30
31
 
31
32
 
32
- def find_patterns(path: str) -> List[str]:
33
+ def find_patterns(path: str) -> list[str]:
33
34
  """
34
35
  Extract param names from a React-Router-style path.
35
36
 
@@ -85,10 +86,10 @@ class RouteData(BaseModel):
85
86
  Data structure representing a route in the router
86
87
  """
87
88
 
88
- content: Optional[ComponentInstance] = None
89
- on_load: Optional[Action] = None
89
+ content: ComponentInstance | None = None
90
+ on_load: Action | None = None
90
91
  definition: Optional['BaseRoute'] = None
91
- dependency_graph: Optional[DependencyGraph] = Field(default=None, exclude=True)
92
+ dependency_graph: DependencyGraph | None = Field(default=None, exclude=True)
92
93
 
93
94
 
94
95
  class BaseRoute(BaseModel):
@@ -101,13 +102,13 @@ class BaseRoute(BaseModel):
101
102
  Whether the route is case sensitive
102
103
  """
103
104
 
104
- id: Optional[str] = Field(default=None, pattern=r'^[a-zA-Z0-9-_]+$')
105
+ id: str | None = Field(default=None, pattern=r'^[a-zA-Z0-9-_]+$')
105
106
  """
106
107
  Unique identifier for the route.
107
108
  Must only contain alphanumeric characters, dashes and underscores.
108
109
  """
109
110
 
110
- name: Optional[str] = None
111
+ name: str | None = None
111
112
  """
112
113
  Name of the route, used for window.title display. If not set, defaults to
113
114
  the route path.
@@ -118,7 +119,7 @@ class BaseRoute(BaseModel):
118
119
  Metadata for the route. This is used to store arbitrary data that can be used by the application.
119
120
  """
120
121
 
121
- fallback: SerializeAsAny[Optional[ComponentInstance]] = Field(default=None)
122
+ fallback: SerializeAsAny[ComponentInstance | None] = Field(default=None)
122
123
  """
123
124
  Fallback component to render while `on_load` is running.
124
125
  If not set, Dara will wait until `on_load` completes before completing the navigation.
@@ -131,7 +132,7 @@ class BaseRoute(BaseModel):
131
132
  if it's desirable to navigate to the other route immediately.
132
133
  """
133
134
 
134
- on_load: SerializeAsAny[Optional[Action]] = Field(default=None)
135
+ on_load: SerializeAsAny[Action | None] = Field(default=None)
135
136
  """
136
137
  Action to execute when the route is loaded.
137
138
  Guaranteed to be executed before the route content is rendered.
@@ -142,7 +143,7 @@ class BaseRoute(BaseModel):
142
143
  Internal unique identifier for the route
143
144
  """
144
145
 
145
- compiled_data: Optional[RouteData] = Field(default=None, exclude=True, repr=False)
146
+ compiled_data: RouteData | None = Field(default=None, exclude=True, repr=False)
146
147
  """
147
148
  Internal compiled data for the route
148
149
  """
@@ -235,7 +236,7 @@ class BaseRoute(BaseModel):
235
236
  return self.compiled_data
236
237
 
237
238
  @property
238
- def full_path(self) -> Optional[str]:
239
+ def full_path(self) -> str | None:
239
240
  """
240
241
  Compute the full path from root to this route.
241
242
  Returns None if route is not attached to a router.
@@ -279,7 +280,7 @@ class HasChildRoutes(BaseModel):
279
280
  Mixin class for objects that can have child routes.
280
281
  """
281
282
 
282
- children: SerializeAsAny[List['BaseRoute']] = Field(default_factory=list)
283
+ children: SerializeAsAny[list['BaseRoute']] = Field(default_factory=list)
283
284
  """
284
285
  List of child routes.
285
286
  Should not be set directly. Use `set_children` or one of the `add_*` methods instead.
@@ -310,13 +311,13 @@ class HasChildRoutes(BaseModel):
310
311
  self,
311
312
  *,
312
313
  path: str,
313
- content: Union[Callable[..., ComponentInstance], ComponentInstance],
314
+ content: Callable[..., ComponentInstance] | ComponentInstance,
314
315
  case_sensitive: bool = False,
315
- name: Optional[str] = None,
316
- id: Optional[str] = None,
317
- metadata: Optional[dict] = None,
318
- on_load: Optional[Action] = None,
319
- fallback: Optional[ComponentInstance] = None,
316
+ name: str | None = None,
317
+ id: str | None = None,
318
+ metadata: dict | None = None,
319
+ on_load: Action | None = None,
320
+ fallback: ComponentInstance | None = None,
320
321
  ):
321
322
  """
322
323
  Standard route with a unique URL segment and content to render
@@ -350,12 +351,12 @@ class HasChildRoutes(BaseModel):
350
351
  def add_layout(
351
352
  self,
352
353
  *,
353
- content: Union[Callable[..., ComponentInstance], ComponentInstance],
354
+ content: Callable[..., ComponentInstance] | ComponentInstance,
354
355
  case_sensitive: bool = False,
355
- id: Optional[str] = None,
356
- metadata: Optional[dict] = None,
357
- on_load: Optional[Action] = None,
358
- fallback: Optional[ComponentInstance] = None,
356
+ id: str | None = None,
357
+ metadata: dict | None = None,
358
+ on_load: Action | None = None,
359
+ fallback: ComponentInstance | None = None,
359
360
  ):
360
361
  """
361
362
  Layout route creates a route with a layout component to render without adding any segments to the URL
@@ -409,10 +410,10 @@ class HasChildRoutes(BaseModel):
409
410
  *,
410
411
  path: str,
411
412
  case_sensitive: bool = False,
412
- id: Optional[str] = None,
413
- metadata: Optional[dict] = None,
414
- on_load: Optional[Action] = None,
415
- fallback: Optional[ComponentInstance] = None,
413
+ id: str | None = None,
414
+ metadata: dict | None = None,
415
+ on_load: Action | None = None,
416
+ fallback: ComponentInstance | None = None,
416
417
  ):
417
418
  """
418
419
  Prefix route creates a group of routes with a common prefix without a specific component to render
@@ -450,13 +451,13 @@ class HasChildRoutes(BaseModel):
450
451
  def add_index(
451
452
  self,
452
453
  *,
453
- content: Union[Callable[..., ComponentInstance], ComponentInstance],
454
+ content: Callable[..., ComponentInstance] | ComponentInstance,
454
455
  case_sensitive: bool = False,
455
- name: Optional[str] = None,
456
- id: Optional[str] = None,
457
- metadata: Optional[dict] = None,
458
- on_load: Optional[Action] = None,
459
- fallback: Optional[ComponentInstance] = None,
456
+ name: str | None = None,
457
+ id: str | None = None,
458
+ metadata: dict | None = None,
459
+ on_load: Action | None = None,
460
+ fallback: ComponentInstance | None = None,
460
461
  ):
461
462
  """
462
463
  Index routes render into their parent's Outlet() at their parent URL (like a default child route).
@@ -518,7 +519,7 @@ class IndexRoute(BaseRoute):
518
519
  """
519
520
 
520
521
  index: Literal[True] = True
521
- content: Union[Callable[..., ComponentInstance], ComponentInstance] = Field(exclude=True)
522
+ content: Callable[..., ComponentInstance] | ComponentInstance = Field(exclude=True)
522
523
 
523
524
  def compile(self):
524
525
  super().compile()
@@ -538,7 +539,7 @@ class PageRoute(BaseRoute, HasChildRoutes):
538
539
  """
539
540
 
540
541
  path: str
541
- content: Union[Callable[..., ComponentInstance], ComponentInstance] = Field(exclude=True)
542
+ content: Callable[..., ComponentInstance] | ComponentInstance = Field(exclude=True)
542
543
 
543
544
  def __init__(self, *children: BaseRoute, **kwargs):
544
545
  routes = list(children)
@@ -588,7 +589,7 @@ class LayoutRoute(BaseRoute, HasChildRoutes):
588
589
  - Project and EditProject will be rendered into the ProjectLayout outlet while ProjectsHome will not.
589
590
  """
590
591
 
591
- content: Union[Callable[..., ComponentInstance], ComponentInstance] = Field(exclude=True)
592
+ content: Callable[..., ComponentInstance] | ComponentInstance = Field(exclude=True)
592
593
 
593
594
  def __init__(self, *children: BaseRoute, **kwargs):
594
595
  routes = list(children)
@@ -723,11 +724,11 @@ class Router(HasChildRoutes):
723
724
  for child in self.children:
724
725
  child.compile()
725
726
 
726
- def to_route_map(self) -> Dict[str, RouteData]:
727
+ def to_route_map(self) -> dict[str, RouteData]:
727
728
  """
728
729
  Convert the route tree into a dictionary of route data keyed by unique route identifiers.
729
730
  """
730
- routes: Dict[str, RouteData] = {}
731
+ routes: dict[str, RouteData] = {}
731
732
 
732
733
  def _walk(route: BaseRoute):
733
734
  identifier = route.get_identifier()
@@ -749,7 +750,7 @@ class Router(HasChildRoutes):
749
750
  id: str
750
751
  metadata: dict
751
752
 
752
- def get_navigable_routes(self) -> List[NavigableRoute]:
753
+ def get_navigable_routes(self) -> list[NavigableRoute]:
753
754
  """
754
755
  Get a flattened list of all navigable routes (PageRoute and IndexRoute only).
755
756
 
@@ -810,10 +811,10 @@ class Router(HasChildRoutes):
810
811
  print('Router')
811
812
  self._print_routes(self.children, prefix='')
812
813
 
813
- def _print_routes(self, routes: List['BaseRoute'], prefix: str = ''):
814
+ def _print_routes(self, routes: list['BaseRoute'], prefix: str = ''):
814
815
  """Helper method to recursively print route tree structure"""
815
816
 
816
- def _format_content(content: Union[Callable[..., ComponentInstance], ComponentInstance]):
817
+ def _format_content(content: Callable[..., ComponentInstance] | ComponentInstance):
817
818
  if isinstance(content, ComponentInstance):
818
819
  return content.__class__.__name__
819
820
  return content.__name__
@@ -870,7 +871,7 @@ class Router(HasChildRoutes):
870
871
 
871
872
 
872
873
  def _execute_route_func(
873
- content: Union[Callable[..., ComponentInstance], ComponentInstance], path: Optional[str]
874
+ content: Callable[..., ComponentInstance] | ComponentInstance, path: str | None
874
875
  ) -> ComponentInstance:
875
876
  """
876
877
  Executes a route function or returns a ComponentInstance directly.
@@ -39409,7 +39409,6 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
39409
39409
  white-space: nowrap;
39410
39410
  `;
39411
39411
  const directionCtx = React$1.createContext({ direction: "row" });
39412
- const importersCtx = React$1.createContext({});
39413
39412
  var _arrayEach;
39414
39413
  var hasRequired_arrayEach;
39415
39414
  function require_arrayEach() {
@@ -47568,7 +47567,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
47568
47567
  }
47569
47568
  return baseOrderBy(collection, iteratees, orders);
47570
47569
  }
47571
- var partition2 = createAggregator(function(result2, value, key) {
47570
+ var partition = createAggregator(function(result2, value, key) {
47572
47571
  result2[key ? 0 : 1].push(value);
47573
47572
  }, function() {
47574
47573
  return [[], []];
@@ -48952,7 +48951,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
48952
48951
  lodash2.overSome = overSome;
48953
48952
  lodash2.partial = partial2;
48954
48953
  lodash2.partialRight = partialRight;
48955
- lodash2.partition = partition2;
48954
+ lodash2.partition = partition;
48956
48955
  lodash2.pick = pick2;
48957
48956
  lodash2.pickBy = pickBy;
48958
48957
  lodash2.property = property;
@@ -50870,52 +50869,6 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
50870
50869
  }
50871
50870
  const variablesCtx = React__namespace.createContext(null);
50872
50871
  const websocketCtx = React$1.createContext({ client: void 0 });
50873
- const registriesCtx = React$1.createContext(null);
50874
- function RegistriesCtxProvider(props) {
50875
- const [actionRegistry] = React$1.useState(props.actionRegistry);
50876
- const [componentRegistry, setComponentRegistry] = React$1.useState(props.componentRegistry);
50877
- const extras = useRequestExtras();
50878
- const refetchComponentMutation = reactQuery.useMutation({
50879
- mutationKey: ["component-definition"],
50880
- mutationFn: async ({ name }) => {
50881
- const response = await request(
50882
- `/api/core/components/${name}/definition`,
50883
- { method: HTTP_METHOD.GET },
50884
- extras
50885
- );
50886
- await handleAuthErrors(response, true);
50887
- await validateResponse(
50888
- response,
50889
- `Failed to fetch the component definition for ${name}, was it registered in the app?`
50890
- );
50891
- return response.json();
50892
- },
50893
- retry: 3
50894
- });
50895
- const getComponent = React$1.useCallback(
50896
- async (instance) => {
50897
- if (componentRegistry[instance.name]) {
50898
- return componentRegistry[instance.name];
50899
- }
50900
- const component = await refetchComponentMutation.mutateAsync({ name: instance.name });
50901
- setComponentRegistry((prev) => ({ ...prev, [instance.name]: component }));
50902
- return component;
50903
- },
50904
- [componentRegistry, refetchComponentMutation]
50905
- );
50906
- const contextValue = React$1.useMemo(
50907
- () => ({ actionRegistry, componentRegistry, getComponent }),
50908
- [actionRegistry, componentRegistry, getComponent]
50909
- );
50910
- return /* @__PURE__ */ React.createElement(registriesCtx.Provider, { value: contextValue }, props.children);
50911
- }
50912
- function useRegistriesCtx() {
50913
- const context = React$1.useContext(registriesCtx);
50914
- if (!context) {
50915
- throw new Error("useRegistriesCtx must be used within a RegistriesCtxProvider");
50916
- }
50917
- return context;
50918
- }
50919
50872
  const displayCtx = React$1.createContext({ component: null, direction: "horizontal" });
50920
50873
  const fallbackCtx = React__namespace.createContext(null);
50921
50874
  function useFallbackCtx() {
@@ -72705,22 +72658,6 @@ Inferred class string: "${iconClasses}."`
72705
72658
  [uid2]
72706
72659
  );
72707
72660
  }
72708
- var partition_1;
72709
- var hasRequiredPartition;
72710
- function requirePartition() {
72711
- if (hasRequiredPartition) return partition_1;
72712
- hasRequiredPartition = 1;
72713
- var createAggregator = require_createAggregator();
72714
- var partition2 = createAggregator(function(result, value, key) {
72715
- result[key ? 0 : 1].push(value);
72716
- }, function() {
72717
- return [[], []];
72718
- });
72719
- partition_1 = partition2;
72720
- return partition_1;
72721
- }
72722
- var partitionExports = requirePartition();
72723
- const partition = /* @__PURE__ */ getDefaultExportFromCjs(partitionExports);
72724
72661
  const ErrorBoundaryContext = React$1.createContext(null);
72725
72662
  const initialState = {
72726
72663
  didCatch: false,
@@ -73213,31 +73150,25 @@ Inferred class string: "${iconClasses}."`
73213
73150
  MODULE_CACHE.clear();
73214
73151
  COMPONENT_METADATA_CACHE.clear();
73215
73152
  }
73216
- async function preloadComponents(importers, components) {
73217
- const [jsComponents, pyComponents] = partition(components, isJsComponent);
73218
- for (const component of pyComponents) {
73219
- if (COMPONENT_METADATA_CACHE.has(component.name)) {
73220
- continue;
73221
- }
73222
- COMPONENT_METADATA_CACHE.set(component.name, component);
73223
- }
73153
+ async function preloadComponents(importers, jsComponents) {
73224
73154
  const componentsByModule = groupBy(jsComponents, (component) => component.py_module);
73225
73155
  for (const [pyModule, componentsInModule] of Object.entries(componentsByModule)) {
73226
- if (MODULE_CACHE.has(pyModule)) {
73227
- continue;
73228
- }
73229
- const importer = importers[pyModule];
73230
- if (!importer) {
73231
- throw new Error(`Missing importer for module ${pyModule}`);
73232
- }
73233
73156
  let moduleContent = null;
73234
- try {
73235
- moduleContent = await importer();
73236
- if (moduleContent) {
73237
- MODULE_CACHE.set(pyModule, moduleContent);
73157
+ if (MODULE_CACHE.has(pyModule)) {
73158
+ moduleContent = MODULE_CACHE.get(pyModule);
73159
+ } else {
73160
+ const importer = importers[pyModule];
73161
+ if (!importer) {
73162
+ throw new Error(`Missing importer for module ${pyModule}`);
73163
+ }
73164
+ try {
73165
+ moduleContent = await importer();
73166
+ if (moduleContent) {
73167
+ MODULE_CACHE.set(pyModule, moduleContent);
73168
+ }
73169
+ } catch (e2) {
73170
+ throw new Error(`Failed to load module ${pyModule}: ${String(e2)}`);
73238
73171
  }
73239
- } catch (e2) {
73240
- throw new Error(`Failed to load module ${pyModule}: ${String(e2)}`);
73241
73172
  }
73242
73173
  for (const component of componentsInModule) {
73243
73174
  if (COMPONENT_METADATA_CACHE.has(component.name)) {
@@ -73247,7 +73178,7 @@ Inferred class string: "${iconClasses}."`
73247
73178
  }
73248
73179
  }
73249
73180
  }
73250
- function resolveComponentSync(component) {
73181
+ function resolveComponent(component) {
73251
73182
  if (!component) {
73252
73183
  return null;
73253
73184
  }
@@ -73256,9 +73187,19 @@ Inferred class string: "${iconClasses}."`
73256
73187
  }
73257
73188
  const metadata = COMPONENT_METADATA_CACHE.get(component.name);
73258
73189
  if (!metadata) {
73259
- return null;
73260
- }
73261
- if (metadata.type === "py") {
73190
+ if (!isPyComponent(component)) {
73191
+ return /* @__PURE__ */ React.createElement(
73192
+ ErrorDisplay$1,
73193
+ {
73194
+ config: {
73195
+ title: `Component ${component.name} could not be resolved`,
73196
+ description: `This likely means the component was not registered with the app.
73197
+ You can try re-building JavaScript for the app by running Dara with the --rebuild flag and/or explicitly registering the component with "config.add_component(MyComponent)".
73198
+ In most cases the import discovery system should auto-register components used throughout the app so please report the issue if you think it is a bug in the system.`
73199
+ }
73200
+ }
73201
+ );
73202
+ }
73262
73203
  return (
73263
73204
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
73264
73205
  /* @__PURE__ */ React.createElement(
@@ -73276,7 +73217,15 @@ Inferred class string: "${iconClasses}."`
73276
73217
  }
73277
73218
  const moduleContent = MODULE_CACHE.get(metadata.py_module);
73278
73219
  if (!moduleContent) {
73279
- return null;
73220
+ return /* @__PURE__ */ React.createElement(
73221
+ ErrorDisplay$1,
73222
+ {
73223
+ config: {
73224
+ title: `Component ${metadata.name} could not be resolved`,
73225
+ description: `The JavaScript module for ${metadata.py_module} was not found`
73226
+ }
73227
+ }
73228
+ );
73280
73229
  }
73281
73230
  const ResolvedComponent = moduleContent[metadata.js_component ?? metadata.name];
73282
73231
  if (!ResolvedComponent) {
@@ -73293,57 +73242,6 @@ Inferred class string: "${iconClasses}."`
73293
73242
  const props = cleanProps(component.props);
73294
73243
  return /* @__PURE__ */ React.createElement(ResolvedComponent, { uid: component.uid, ...props });
73295
73244
  }
73296
- class ComponentLoadError extends Error {
73297
- constructor(message, title) {
73298
- super(message);
73299
- this.title = title;
73300
- }
73301
- }
73302
- async function resolveComponentAsync(component, getComponent, importers) {
73303
- if (!component) {
73304
- return;
73305
- }
73306
- let entry;
73307
- try {
73308
- entry = await getComponent(component);
73309
- } catch (e2) {
73310
- throw new ComponentLoadError(e2 instanceof Error ? e2.message : String(e2), "Failed to load component");
73311
- }
73312
- if (!isJsComponent(entry)) {
73313
- COMPONENT_METADATA_CACHE.set(component.name, entry);
73314
- return;
73315
- }
73316
- COMPONENT_METADATA_CACHE.set(component.name, entry);
73317
- if (MODULE_CACHE.has(entry.py_module)) {
73318
- return;
73319
- }
73320
- const importer = importers[entry.py_module];
73321
- if (!importer) {
73322
- const errorDescription = entry.py_module === "LOCAL" ? `This is a local component so make sure you are in production mode and dara.config.json is present.
73323
- You can try re-building JavaScript by running Dara with the --rebuild flag.` : `This means that the JavaScript module for the component was not included by the discovery system.
73324
- You can try re-building JavaScript by running Dara with the --rebuild flag
73325
- and/or explicitly registering the component with "config.add_component(MyComponentClass)".`;
73326
- throw new ComponentLoadError(errorDescription, `Component ${entry.name} could not be resolved`);
73327
- }
73328
- let moduleContent = null;
73329
- try {
73330
- moduleContent = await importer();
73331
- if (moduleContent) {
73332
- MODULE_CACHE.set(entry.py_module, moduleContent);
73333
- }
73334
- } catch (e2) {
73335
- console.error(`Failed to load module ${entry.py_module}:`, e2);
73336
- }
73337
- if (!moduleContent) {
73338
- throw new ComponentLoadError(
73339
- `Failed to import the JavaScript module for the component.
73340
- This likely means that the module was not installed properly.
73341
- You can try re-building JavaScript by running Dara with the --rebuild flag
73342
- and/or explicitly registering the component with "config.add_component(MyComponentClass)".`,
73343
- `Component ${entry.name} could not be resolved`
73344
- );
73345
- }
73346
- }
73347
73245
  function getFallbackComponent(fallback, track_progress, variablesRef) {
73348
73246
  let fallbackComponent = /* @__PURE__ */ React.createElement(DefaultFallback$1, null);
73349
73247
  if (fallback) {
@@ -73355,12 +73253,7 @@ Inferred class string: "${iconClasses}."`
73355
73253
  return fallbackComponent;
73356
73254
  }
73357
73255
  function DynamicComponent(props) {
73358
- const importers = React$1.useContext(importersCtx);
73359
73256
  const fallbackCtx$1 = React$1.useContext(fallbackCtx);
73360
- const { getComponent } = useRegistriesCtx();
73361
- const [component, setComponent] = React$1.useState(() => resolveComponentSync(props.component));
73362
- const [isLoading, setIsLoading] = React$1.useState(() => component === null);
73363
- const [loadingStarted, setLoadingStarted] = React$1.useState(false);
73364
73257
  React$1.useLayoutEffect(() => {
73365
73258
  if (!props.component) {
73366
73259
  return;
@@ -73373,40 +73266,7 @@ Inferred class string: "${iconClasses}."`
73373
73266
  );
73374
73267
  }
73375
73268
  }, [props.component]);
73376
- const isInitialMount = React$1.useRef(true);
73377
- React$1.useEffect(() => {
73378
- if (isInitialMount.current) {
73379
- isInitialMount.current = false;
73380
- return;
73381
- }
73382
- const SyncResolved = resolveComponentSync(props.component);
73383
- if (SyncResolved) {
73384
- setComponent(SyncResolved);
73385
- setIsLoading(false);
73386
- setLoadingStarted(false);
73387
- } else {
73388
- setIsLoading(true);
73389
- setLoadingStarted(false);
73390
- }
73391
- }, [props.component]);
73392
- const getComponentStable = useLatestRef$3(getComponent);
73393
- React$1.useEffect(() => {
73394
- if (!isLoading || loadingStarted) {
73395
- return;
73396
- }
73397
- setLoadingStarted(true);
73398
- resolveComponentAsync(props.component, getComponentStable.current, importers).then(() => {
73399
- const resolvedComponent = resolveComponentSync(props.component);
73400
- setIsLoading(false);
73401
- setComponent(resolvedComponent);
73402
- }).catch((error) => {
73403
- console.error("Failed to resolve component:", error);
73404
- setIsLoading(false);
73405
- if (error instanceof ComponentLoadError) {
73406
- setComponent(/* @__PURE__ */ React.createElement(ErrorDisplay$1, { config: { title: error.title, description: error.message } }));
73407
- }
73408
- });
73409
- }, [props.component, getComponentStable, importers, isLoading, loadingStarted]);
73269
+ const component = React$1.useMemo(() => resolveComponent(props.component), [props.component]);
73410
73270
  const refreshSelector = useRefreshSelector();
73411
73271
  function onResetErrorBoundary(error) {
73412
73272
  if (isSelectorError(error)) {
@@ -73428,9 +73288,6 @@ Inferred class string: "${iconClasses}."`
73428
73288
  if (!props.component) {
73429
73289
  return null;
73430
73290
  }
73431
- if (isLoading) {
73432
- return fallback;
73433
- }
73434
73291
  const suspend = props.component?.props?.fallback?.props?.suspend_render ?? fallbackCtx$1?.suspend ?? 200;
73435
73292
  return /* @__PURE__ */ React.createElement(
73436
73293
  ErrorBoundary,
@@ -74040,14 +73897,7 @@ Inferred class string: "${iconClasses}."`
74040
73897
  }
74041
73898
  });
74042
73899
  }, [wsClient]);
74043
- return /* @__PURE__ */ React.createElement(websocketCtx.Provider, { value: { client: wsClient } }, /* @__PURE__ */ React.createElement(
74044
- RegistriesCtxProvider,
74045
- {
74046
- componentRegistry: props.daraData.components,
74047
- actionRegistry: props.daraData.actions
74048
- },
74049
- /* @__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)))))
74050
- ));
73900
+ 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))))));
74051
73901
  }
74052
73902
  const Wrapper = styled.div`
74053
73903
  overflow: auto;
@@ -74747,7 +74597,7 @@ body,
74747
74597
  );
74748
74598
  }
74749
74599
  function Root(props) {
74750
- return /* @__PURE__ */ React.createElement(ConfigContextProvider, { initialConfig: props.daraData }, /* @__PURE__ */ React.createElement(reactQuery.QueryClientProvider, { client: props.queryClient }, /* @__PURE__ */ React.createElement(ErrorBoundary$1, null, /* @__PURE__ */ React.createElement(importersCtx.Provider, { value: props.importers }, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "row" } }, /* @__PURE__ */ React.createElement(Recoil_index_5, null, /* @__PURE__ */ React.createElement(GlobalTaskProvider, null, /* @__PURE__ */ React.createElement(RouterRoot, { daraData: props.daraData }))))))));
74600
+ return /* @__PURE__ */ React.createElement(ConfigContextProvider, { initialConfig: props.daraData }, /* @__PURE__ */ React.createElement(reactQuery.QueryClientProvider, { client: props.queryClient }, /* @__PURE__ */ React.createElement(ErrorBoundary$1, null, /* @__PURE__ */ React.createElement(directionCtx.Provider, { value: { direction: "row" } }, /* @__PURE__ */ React.createElement(Recoil_index_5, null, /* @__PURE__ */ React.createElement(GlobalTaskProvider, null, /* @__PURE__ */ React.createElement(RouterRoot, { daraData: props.daraData })))))));
74751
74601
  }
74752
74602
  async function run(importers) {
74753
74603
  const queryClient = new reactQuery.QueryClient();
@@ -74764,7 +74614,7 @@ body,
74764
74614
  ]);
74765
74615
  const container = document.getElementById("dara_root");
74766
74616
  const root = clientExports.createRoot(container);
74767
- root.render(/* @__PURE__ */ React.createElement(Root, { daraData, queryClient, importers }));
74617
+ root.render(/* @__PURE__ */ React.createElement(Root, { daraData, queryClient }));
74768
74618
  }
74769
74619
  function getBasename() {
74770
74620
  if (window.dara.base_url !== "") {
@@ -98736,7 +98586,6 @@ body,
98736
98586
  exports.FallbackCtx = fallbackCtx;
98737
98587
  exports.For = For;
98738
98588
  exports.GlobalTaskProvider = GlobalTaskProvider;
98739
- exports.ImportersCtx = importersCtx;
98740
98589
  exports.Link = Link;
98741
98590
  exports.LoaderError = LoaderError;
98742
98591
  exports.LockSecuredCache = SingleUseCache;
@@ -98751,7 +98600,6 @@ body,
98751
98600
  exports.PoweredByCausalens = PoweredByCausalens;
98752
98601
  exports.ProgressTracker = ProgressTracker;
98753
98602
  exports.ReactRouter = index;
98754
- exports.RegistriesCtxProvider = RegistriesCtxProvider;
98755
98603
  exports.RequestExtrasCtx = requestExtrasCtx;
98756
98604
  exports.RequestExtrasProvider = RequestExtrasProvider;
98757
98605
  exports.ResetVariables = ResetVariables;
@@ -98865,7 +98713,6 @@ body,
98865
98713
  exports.usePrevious = usePrevious$1;
98866
98714
  exports.useRefreshSelector = useRefreshSelector;
98867
98715
  exports.useRefreshServerComponent = useRefreshServerComponent;
98868
- exports.useRegistriesCtx = useRegistriesCtx;
98869
98716
  exports.useRequestExtras = useRequestExtras;
98870
98717
  exports.useRouterContext = useRouterContext;
98871
98718
  exports.useSession = useSession;