dara-core 1.15.7__py3-none-any.whl → 1.16.0a1__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 (49) hide show
  1. dara/core/__init__.py +16 -27
  2. dara/core/auth/base.py +3 -2
  3. dara/core/auth/definitions.py +0 -3
  4. dara/core/auth/utils.py +1 -1
  5. dara/core/base_definitions.py +122 -65
  6. dara/core/configuration.py +5 -8
  7. dara/core/defaults.py +0 -3
  8. dara/core/definitions.py +95 -231
  9. dara/core/interactivity/__init__.py +12 -18
  10. dara/core/interactivity/actions.py +22 -19
  11. dara/core/interactivity/any_data_variable.py +2 -4
  12. dara/core/interactivity/any_variable.py +10 -2
  13. dara/core/interactivity/condition.py +7 -10
  14. dara/core/interactivity/data_variable.py +11 -12
  15. dara/core/interactivity/derived_data_variable.py +7 -7
  16. dara/core/interactivity/derived_variable.py +20 -17
  17. dara/core/interactivity/filtering.py +1 -1
  18. dara/core/interactivity/plain_variable.py +10 -6
  19. dara/core/interactivity/url_variable.py +7 -6
  20. dara/core/internal/download.py +1 -1
  21. dara/core/internal/hashing.py +1 -1
  22. dara/core/internal/normalization.py +0 -24
  23. dara/core/internal/routing.py +10 -10
  24. dara/core/internal/scheduler.py +3 -2
  25. dara/core/internal/settings.py +2 -4
  26. dara/core/internal/store.py +0 -3
  27. dara/core/internal/tasks.py +2 -2
  28. dara/core/internal/websocket.py +29 -20
  29. dara/core/js_tooling/js_utils.py +1 -1
  30. dara/core/main.py +2 -2
  31. dara/core/persistence.py +12 -4
  32. dara/core/umd/dara.core.umd.js +13 -277
  33. dara/core/visual/components/__init__.py +0 -3
  34. dara/core/visual/components/fallback.py +3 -3
  35. dara/core/visual/components/invalid_component.py +3 -3
  36. dara/core/visual/components/menu.py +3 -3
  37. dara/core/visual/components/progress_tracker.py +3 -2
  38. dara/core/visual/components/raw_string.py +3 -3
  39. dara/core/visual/components/router_content.py +3 -3
  40. dara/core/visual/components/sidebar_frame.py +3 -3
  41. dara/core/visual/components/topbar_frame.py +3 -3
  42. dara/core/visual/css/__init__.py +2 -6
  43. dara/core/visual/dynamic_component.py +3 -6
  44. {dara_core-1.15.7.dist-info → dara_core-1.16.0a1.dist-info}/METADATA +13 -12
  45. {dara_core-1.15.7.dist-info → dara_core-1.16.0a1.dist-info}/RECORD +48 -49
  46. dara/core/visual/components/for_cmp.py +0 -150
  47. {dara_core-1.15.7.dist-info → dara_core-1.16.0a1.dist-info}/LICENSE +0 -0
  48. {dara_core-1.15.7.dist-info → dara_core-1.16.0a1.dist-info}/WHEEL +0 -0
  49. {dara_core-1.15.7.dist-info → dara_core-1.16.0a1.dist-info}/entry_points.txt +0 -0
@@ -21,7 +21,7 @@ from secrets import token_hex
21
21
  from typing import List, Optional
22
22
 
23
23
  from dotenv import dotenv_values
24
- from pydantic import BaseSettings
24
+ from pydantic_settings import BaseSettings, SettingsConfigDict
25
25
 
26
26
  from dara.core.logging import dev_logger
27
27
 
@@ -45,9 +45,7 @@ class Settings(BaseSettings):
45
45
  sso_jwt_algo: str = 'ES256'
46
46
  sso_verify_audience: bool = False
47
47
  sso_extra_audience: Optional[List[str]] = None
48
-
49
- class Config:
50
- env_file = '.env'
48
+ model_config = SettingsConfigDict(env_file='.env')
51
49
 
52
50
 
53
51
  def generate_env_content():
@@ -31,9 +31,6 @@ class Store:
31
31
  and resolve at the same time when the value is correctly updated by the first one to request the specific key
32
32
  """
33
33
 
34
- class Config:
35
- use_enum_values = True
36
-
37
34
  def __init__(self):
38
35
  # This dict is the main store of values, the first level of keys is the cache type and the second level are the
39
36
  # value keys. The root key is used for any non-session/user dependant keys that are added.
@@ -29,6 +29,7 @@ from anyio import (
29
29
  from anyio.abc import TaskGroup
30
30
  from anyio.streams.memory import MemoryObjectSendStream
31
31
  from exceptiongroup import ExceptionGroup
32
+ from pydantic import ConfigDict
32
33
 
33
34
  from dara.core.base_definitions import (
34
35
  BaseTask,
@@ -58,8 +59,7 @@ class Task(BaseTask):
58
59
  Methods for reading from the subprocess and writing to it are also provided.
59
60
  """
60
61
 
61
- class Config:
62
- use_enum_values = True
62
+ model_config = ConfigDict(use_enum_values=True)
63
63
 
64
64
  def __init__(
65
65
  self,
@@ -30,12 +30,19 @@ from exceptiongroup import catch
30
30
  from fastapi import Query, WebSocketException
31
31
  from fastapi.encoders import jsonable_encoder
32
32
  from jwt import DecodeError
33
- from pydantic import BaseModel, Field, parse_obj_as
33
+ from pydantic import (
34
+ ConfigDict,
35
+ Field,
36
+ SerializerFunctionWrapHandler,
37
+ TypeAdapter,
38
+ model_serializer,
39
+ )
34
40
  from starlette.websockets import WebSocket, WebSocketDisconnect
35
41
 
36
42
  from dara.core.auth.base import BaseAuthConfig
37
43
  from dara.core.auth.definitions import AuthError, TokenData
38
44
  from dara.core.auth.utils import decode_token
45
+ from dara.core.base_definitions import DaraBaseModel as BaseModel
39
46
  from dara.core.logging import dev_logger, eng_logger
40
47
 
41
48
 
@@ -47,22 +54,24 @@ class DaraClientMessage(BaseModel):
47
54
  An optional chunk_count field can be used to indicate that a message is chunked and what number of messages to expect
48
55
  """
49
56
 
50
- type: Literal['message'] = Field(default='message', const=True)
57
+ type: Literal['message'] = 'message'
51
58
  channel: str
52
59
  chunk_count: Optional[int] = None
53
60
  message: Any
54
61
 
55
62
 
56
63
  class CustomClientMessagePayload(BaseModel):
64
+ model_config = ConfigDict(serialize_by_alias=True)
65
+
57
66
  rchan: Optional[str] = Field(default=None, alias='__rchan')
58
67
  """Return channel if the message is expected to have a response for"""
59
68
 
60
69
  kind: str
61
70
  data: Any
62
71
 
63
- def dict(self, *args, **kwargs):
64
- # Force by_alias to True to use __rchan name
65
- result = super().dict(*args, **{**kwargs, 'by_alias': True})
72
+ @model_serializer(mode='wrap')
73
+ def ser_model(self, nxt: SerializerFunctionWrapHandler) -> dict:
74
+ result = nxt(self)
66
75
 
67
76
  # remove rchan if None
68
77
  if '__rchan' in result and result.get('__rchan') is None:
@@ -76,7 +85,7 @@ class CustomClientMessage(BaseModel):
76
85
  Represents a custom message sent by the frontend to the backend.
77
86
  """
78
87
 
79
- type: Literal['custom'] = Field(default='custom', const=True)
88
+ type: Literal['custom'] = 'custom'
80
89
  message: CustomClientMessagePayload
81
90
 
82
91
 
@@ -85,18 +94,17 @@ ClientMessage = Union[DaraClientMessage, CustomClientMessage]
85
94
 
86
95
  # Server message types
87
96
  class ServerMessagePayload(BaseModel):
97
+ model_config = ConfigDict(serialize_by_alias=True, extra='allow')
98
+
88
99
  rchan: Optional[str] = Field(default=None, alias='__rchan')
89
100
  """Return channel if the message is expected to have a response for"""
90
101
 
91
102
  response_for: Optional[str] = Field(default=None, alias='__response_for')
92
103
  """ID of the __rchan included in the original client message if this message is a response to a client message"""
93
104
 
94
- class Config:
95
- extra = 'allow'
96
-
97
- def dict(self, *args, **kwargs):
98
- # Force by_alias to True to use __rchan name
99
- result = super().dict(*args, **{**kwargs, 'by_alias': True})
105
+ @model_serializer(mode='wrap')
106
+ def ser_model(self, nxt: SerializerFunctionWrapHandler) -> dict:
107
+ result = nxt(self)
100
108
 
101
109
  # remove rchan if None
102
110
  if '__rchan' in result and result.get('__rchan') is None:
@@ -119,7 +127,7 @@ class DaraServerMessage(BaseModel):
119
127
  Represents a message sent by Dara internals from the backend to the frontend.
120
128
  """
121
129
 
122
- type: Literal['message'] = Field(default='message', const=True)
130
+ type: Literal['message'] = 'message'
123
131
  message: ServerMessagePayload # exact messages expected by frontend are defined in js/api/websocket.tsx
124
132
 
125
133
 
@@ -128,7 +136,7 @@ class CustomServerMessage(BaseModel):
128
136
  Represents a custom message sent by the backend to the frontend.
129
137
  """
130
138
 
131
- type: Literal['custom'] = Field(default='custom', const=True)
139
+ type: Literal['custom'] = 'custom'
132
140
  message: CustomServerMessagePayload
133
141
 
134
142
 
@@ -165,8 +173,7 @@ class WebSocketHandler:
165
173
  notify when the response is received and the response data.
166
174
  """
167
175
 
168
- class Config:
169
- arbitrary_types_allowed = True
176
+ model_config = ConfigDict(arbitrary_types_allowed=True)
170
177
 
171
178
  def __init__(self, channel_id: str):
172
179
  send_stream, receive_stream = create_memory_object_stream[ServerMessage](math.inf)
@@ -334,9 +341,9 @@ class WebsocketManager:
334
341
  :param custom: Whether the message is a custom message
335
342
  """
336
343
  if custom:
337
- return CustomServerMessage(message=CustomServerMessagePayload.parse_obj(payload))
344
+ return CustomServerMessage(message=CustomServerMessagePayload.model_validate(payload))
338
345
  else:
339
- return DaraServerMessage(message=ServerMessagePayload.parse_obj(payload))
346
+ return DaraServerMessage(message=ServerMessagePayload.model_validate(payload))
340
347
 
341
348
  def create_handler(self, channel_id: str) -> WebSocketHandler:
342
349
  """
@@ -534,7 +541,7 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
534
541
  eng_logger.error('Error updating token data', error=e)
535
542
  else:
536
543
  try:
537
- parsed_data = parse_obj_as(ClientMessage, data)
544
+ parsed_data = TypeAdapter(ClientMessage).validate_python(data)
538
545
  result = handler.process_client_message(parsed_data)
539
546
  # Process the resulting coroutine before moving on to next message
540
547
  if inspect.iscoroutine(result):
@@ -547,6 +554,8 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
547
554
  Handle messages sent to the client and pass them via the websocket
548
555
  """
549
556
  async for message in handler.receive_stream:
557
+ # TODO: This is hacky, should probably be a model_serializer
558
+ # on a proper payload type
550
559
  if (
551
560
  message.type == 'message'
552
561
  and isinstance(message.message, ServerMessagePayload)
@@ -556,7 +565,7 @@ async def ws_handler(websocket: WebSocket, token: Optional[str] = Query(default=
556
565
  data = message.message
557
566
  # Reconstruct the payload without the result field
558
567
  message.message = ServerMessagePayload(
559
- **{k: v for k, v in data.dict().items() if k != 'result'}
568
+ **{k: v for k, v in data.model_dump().items() if k != 'result'}
560
569
  )
561
570
  await websocket.send_json(jsonable_encoder(message))
562
571
 
@@ -451,7 +451,7 @@ def rebuild_js(build_cache: BuildCache, build_diff: BuildCacheDiff = BuildCacheD
451
451
  # Store the new build cache
452
452
  build_cache_path = os.path.join(build_cache.static_files_dir, BuildCache.FILENAME)
453
453
  with open(build_cache_path, 'w+', encoding='utf-8') as f:
454
- f.write(build_cache.json(indent=2))
454
+ f.write(build_cache.model_dump_json(indent=2))
455
455
 
456
456
 
457
457
  def bundle_js(build_cache: BuildCache, copy_js: bool = False):
dara/core/main.py CHANGED
@@ -264,8 +264,8 @@ def _start_application(config: Configuration):
264
264
  dev_logger.debug(
265
265
  'Building JS...',
266
266
  extra={
267
- 'New build cache': build_cache.dict(),
268
- 'Difference from last cache': build_diff.dict(),
267
+ 'New build cache': build_cache.model_dump(),
268
+ 'Difference from last cache': build_diff.model_dump(),
269
269
  },
270
270
  )
271
271
  rebuild_js(build_cache, build_diff)
dara/core/persistence.py CHANGED
@@ -6,7 +6,14 @@ from uuid import uuid4
6
6
 
7
7
  import aiorwlock
8
8
  import anyio
9
- from pydantic import BaseModel, Field, PrivateAttr, validator
9
+ from pydantic import (
10
+ BaseModel,
11
+ Field,
12
+ PrivateAttr,
13
+ SerializerFunctionWrapHandler,
14
+ field_validator,
15
+ model_serializer,
16
+ )
10
17
 
11
18
  from dara.core.auth.definitions import USER
12
19
  from dara.core.internal.utils import run_user_handler
@@ -88,7 +95,7 @@ class FileBackend(PersistenceBackend):
88
95
  path: str
89
96
  _lock: aiorwlock.RWLock = PrivateAttr(default_factory=aiorwlock.RWLock)
90
97
 
91
- @validator('path', check_fields=True)
98
+ @field_validator('path', check_fields=True)
92
99
  @classmethod
93
100
  def validate_path(cls, value):
94
101
  if not os.path.splitext(value)[1] == '.json':
@@ -151,8 +158,9 @@ class PersistenceStore(BaseModel, abc.ABC):
151
158
  Initialize the store when connecting to a variable
152
159
  """
153
160
 
154
- def dict(self, *args, **kwargs):
155
- parent_dict = super().dict(*args, **kwargs)
161
+ @model_serializer(mode='wrap')
162
+ def ser_model(self, nxt: SerializerFunctionWrapHandler) -> dict:
163
+ parent_dict = nxt(self)
156
164
  parent_dict['__typename'] = self.__class__.__name__
157
165
  return parent_dict
158
166
 
@@ -11588,7 +11588,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
11588
11588
  map: map$1$1,
11589
11589
  object: object$1$1,
11590
11590
  optional: optional$1$1,
11591
- set: set$1$2,
11591
+ set: set$1$1,
11592
11592
  tuple: tuple$1$1,
11593
11593
  writableArray: writableArray$1$1,
11594
11594
  writableDict: writableDict$1$1,
@@ -11651,7 +11651,7 @@ var __privateWrapper = (obj, member, setter, getter) => ({
11651
11651
  dict: dict$1$1,
11652
11652
  object: object$1$1,
11653
11653
  optional: optional$1$1,
11654
- set: set$1$2,
11654
+ set: set$1$1,
11655
11655
  map: map$1$1,
11656
11656
  writableArray: writableArray$1$1,
11657
11657
  writableDict: writableDict$1$1,
@@ -49604,7 +49604,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
49604
49604
  };
49605
49605
  function createListComponent(_ref2) {
49606
49606
  var _class;
49607
- var getItemOffset = _ref2.getItemOffset, getEstimatedTotalSize2 = _ref2.getEstimatedTotalSize, getItemSize = _ref2.getItemSize, getOffsetForIndexAndAlignment = _ref2.getOffsetForIndexAndAlignment, getStartIndexForOffset = _ref2.getStartIndexForOffset, getStopIndexForStartIndex = _ref2.getStopIndexForStartIndex, initInstanceProps = _ref2.initInstanceProps, shouldResetStyleCacheOnItemSizeChange = _ref2.shouldResetStyleCacheOnItemSizeChange, validateProps = _ref2.validateProps;
49607
+ var getItemOffset = _ref2.getItemOffset, getEstimatedTotalSize = _ref2.getEstimatedTotalSize, getItemSize = _ref2.getItemSize, getOffsetForIndexAndAlignment = _ref2.getOffsetForIndexAndAlignment, getStartIndexForOffset = _ref2.getStartIndexForOffset, getStopIndexForStartIndex = _ref2.getStopIndexForStartIndex, initInstanceProps = _ref2.initInstanceProps, shouldResetStyleCacheOnItemSizeChange = _ref2.shouldResetStyleCacheOnItemSizeChange, validateProps = _ref2.validateProps;
49608
49608
  return _class = /* @__PURE__ */ function(_PureComponent) {
49609
49609
  _inheritsLoose$1(List2, _PureComponent);
49610
49610
  function List2(props) {
@@ -49832,7 +49832,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
49832
49832
  }));
49833
49833
  }
49834
49834
  }
49835
- var estimatedTotalSize = getEstimatedTotalSize2(this.props, this._instanceProps);
49835
+ var estimatedTotalSize = getEstimatedTotalSize(this.props, this._instanceProps);
49836
49836
  return React.createElement(outerElementType || outerTagName || "div", {
49837
49837
  className,
49838
49838
  onScroll,
@@ -49900,161 +49900,6 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
49900
49900
  _ref2.width;
49901
49901
  _ref3.instance;
49902
49902
  };
49903
- var DEFAULT_ESTIMATED_ITEM_SIZE$1 = 50;
49904
- var getItemMetadata$1 = function getItemMetadata(props, index2, instanceProps) {
49905
- var _ref2 = props, itemSize = _ref2.itemSize;
49906
- var itemMetadataMap = instanceProps.itemMetadataMap, lastMeasuredIndex = instanceProps.lastMeasuredIndex;
49907
- if (index2 > lastMeasuredIndex) {
49908
- var offset2 = 0;
49909
- if (lastMeasuredIndex >= 0) {
49910
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
49911
- offset2 = itemMetadata.offset + itemMetadata.size;
49912
- }
49913
- for (var i2 = lastMeasuredIndex + 1; i2 <= index2; i2++) {
49914
- var size2 = itemSize(i2);
49915
- itemMetadataMap[i2] = {
49916
- offset: offset2,
49917
- size: size2
49918
- };
49919
- offset2 += size2;
49920
- }
49921
- instanceProps.lastMeasuredIndex = index2;
49922
- }
49923
- return itemMetadataMap[index2];
49924
- };
49925
- var findNearestItem$1 = function findNearestItem(props, instanceProps, offset2) {
49926
- var itemMetadataMap = instanceProps.itemMetadataMap, lastMeasuredIndex = instanceProps.lastMeasuredIndex;
49927
- var lastMeasuredItemOffset = lastMeasuredIndex > 0 ? itemMetadataMap[lastMeasuredIndex].offset : 0;
49928
- if (lastMeasuredItemOffset >= offset2) {
49929
- return findNearestItemBinarySearch$1(props, instanceProps, lastMeasuredIndex, 0, offset2);
49930
- } else {
49931
- return findNearestItemExponentialSearch$1(props, instanceProps, Math.max(0, lastMeasuredIndex), offset2);
49932
- }
49933
- };
49934
- var findNearestItemBinarySearch$1 = function findNearestItemBinarySearch(props, instanceProps, high, low, offset2) {
49935
- while (low <= high) {
49936
- var middle = low + Math.floor((high - low) / 2);
49937
- var currentOffset = getItemMetadata$1(props, middle, instanceProps).offset;
49938
- if (currentOffset === offset2) {
49939
- return middle;
49940
- } else if (currentOffset < offset2) {
49941
- low = middle + 1;
49942
- } else if (currentOffset > offset2) {
49943
- high = middle - 1;
49944
- }
49945
- }
49946
- if (low > 0) {
49947
- return low - 1;
49948
- } else {
49949
- return 0;
49950
- }
49951
- };
49952
- var findNearestItemExponentialSearch$1 = function findNearestItemExponentialSearch(props, instanceProps, index2, offset2) {
49953
- var itemCount = props.itemCount;
49954
- var interval = 1;
49955
- while (index2 < itemCount && getItemMetadata$1(props, index2, instanceProps).offset < offset2) {
49956
- index2 += interval;
49957
- interval *= 2;
49958
- }
49959
- return findNearestItemBinarySearch$1(props, instanceProps, Math.min(index2, itemCount - 1), Math.floor(index2 / 2), offset2);
49960
- };
49961
- var getEstimatedTotalSize = function getEstimatedTotalSize2(_ref2, _ref3) {
49962
- var itemCount = _ref2.itemCount;
49963
- var itemMetadataMap = _ref3.itemMetadataMap, estimatedItemSize = _ref3.estimatedItemSize, lastMeasuredIndex = _ref3.lastMeasuredIndex;
49964
- var totalSizeOfMeasuredItems = 0;
49965
- if (lastMeasuredIndex >= itemCount) {
49966
- lastMeasuredIndex = itemCount - 1;
49967
- }
49968
- if (lastMeasuredIndex >= 0) {
49969
- var itemMetadata = itemMetadataMap[lastMeasuredIndex];
49970
- totalSizeOfMeasuredItems = itemMetadata.offset + itemMetadata.size;
49971
- }
49972
- var numUnmeasuredItems = itemCount - lastMeasuredIndex - 1;
49973
- var totalSizeOfUnmeasuredItems = numUnmeasuredItems * estimatedItemSize;
49974
- return totalSizeOfMeasuredItems + totalSizeOfUnmeasuredItems;
49975
- };
49976
- var VariableSizeList = /* @__PURE__ */ createListComponent({
49977
- getItemOffset: function getItemOffset(props, index2, instanceProps) {
49978
- return getItemMetadata$1(props, index2, instanceProps).offset;
49979
- },
49980
- getItemSize: function getItemSize(props, index2, instanceProps) {
49981
- return instanceProps.itemMetadataMap[index2].size;
49982
- },
49983
- getEstimatedTotalSize,
49984
- getOffsetForIndexAndAlignment: function getOffsetForIndexAndAlignment(props, index2, align, scrollOffset, instanceProps, scrollbarSize) {
49985
- var direction = props.direction, height = props.height, layout = props.layout, width = props.width;
49986
- var isHorizontal = direction === "horizontal" || layout === "horizontal";
49987
- var size2 = isHorizontal ? width : height;
49988
- var itemMetadata = getItemMetadata$1(props, index2, instanceProps);
49989
- var estimatedTotalSize = getEstimatedTotalSize(props, instanceProps);
49990
- var maxOffset = Math.max(0, Math.min(estimatedTotalSize - size2, itemMetadata.offset));
49991
- var minOffset = Math.max(0, itemMetadata.offset - size2 + itemMetadata.size + scrollbarSize);
49992
- if (align === "smart") {
49993
- if (scrollOffset >= minOffset - size2 && scrollOffset <= maxOffset + size2) {
49994
- align = "auto";
49995
- } else {
49996
- align = "center";
49997
- }
49998
- }
49999
- switch (align) {
50000
- case "start":
50001
- return maxOffset;
50002
- case "end":
50003
- return minOffset;
50004
- case "center":
50005
- return Math.round(minOffset + (maxOffset - minOffset) / 2);
50006
- case "auto":
50007
- default:
50008
- if (scrollOffset >= minOffset && scrollOffset <= maxOffset) {
50009
- return scrollOffset;
50010
- } else if (scrollOffset < minOffset) {
50011
- return minOffset;
50012
- } else {
50013
- return maxOffset;
50014
- }
50015
- }
50016
- },
50017
- getStartIndexForOffset: function getStartIndexForOffset(props, offset2, instanceProps) {
50018
- return findNearestItem$1(props, instanceProps, offset2);
50019
- },
50020
- getStopIndexForStartIndex: function getStopIndexForStartIndex(props, startIndex, scrollOffset, instanceProps) {
50021
- var direction = props.direction, height = props.height, itemCount = props.itemCount, layout = props.layout, width = props.width;
50022
- var isHorizontal = direction === "horizontal" || layout === "horizontal";
50023
- var size2 = isHorizontal ? width : height;
50024
- var itemMetadata = getItemMetadata$1(props, startIndex, instanceProps);
50025
- var maxOffset = scrollOffset + size2;
50026
- var offset2 = itemMetadata.offset + itemMetadata.size;
50027
- var stopIndex = startIndex;
50028
- while (stopIndex < itemCount - 1 && offset2 < maxOffset) {
50029
- stopIndex++;
50030
- offset2 += getItemMetadata$1(props, stopIndex, instanceProps).size;
50031
- }
50032
- return stopIndex;
50033
- },
50034
- initInstanceProps: function initInstanceProps(props, instance) {
50035
- var _ref4 = props, estimatedItemSize = _ref4.estimatedItemSize;
50036
- var instanceProps = {
50037
- itemMetadataMap: {},
50038
- estimatedItemSize: estimatedItemSize || DEFAULT_ESTIMATED_ITEM_SIZE$1,
50039
- lastMeasuredIndex: -1
50040
- };
50041
- instance.resetAfterIndex = function(index2, shouldForceUpdate) {
50042
- if (shouldForceUpdate === void 0) {
50043
- shouldForceUpdate = true;
50044
- }
50045
- instanceProps.lastMeasuredIndex = Math.min(instanceProps.lastMeasuredIndex, index2 - 1);
50046
- instance._getItemStyleCache(-1);
50047
- if (shouldForceUpdate) {
50048
- instance.forceUpdate();
50049
- }
50050
- };
50051
- return instanceProps;
50052
- },
50053
- shouldResetStyleCacheOnItemSizeChange: false,
50054
- validateProps: function validateProps(_ref5) {
50055
- _ref5.itemSize;
50056
- }
50057
- });
50058
49903
  var FixedSizeList = /* @__PURE__ */ createListComponent({
50059
49904
  getItemOffset: function getItemOffset(_ref2, index2) {
50060
49905
  var itemSize = _ref2.itemSize;
@@ -50064,7 +49909,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
50064
49909
  var itemSize = _ref2.itemSize;
50065
49910
  return itemSize;
50066
49911
  },
50067
- getEstimatedTotalSize: function getEstimatedTotalSize2(_ref3) {
49912
+ getEstimatedTotalSize: function getEstimatedTotalSize(_ref3) {
50068
49913
  var itemCount = _ref3.itemCount, itemSize = _ref3.itemSize;
50069
49914
  return itemSize * itemCount;
50070
49915
  },
@@ -54634,7 +54479,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
54634
54479
  }
54635
54480
  var _assignValue = assignValue$3;
54636
54481
  var assignValue$2 = _assignValue, castPath$1 = _castPath, isIndex = _isIndex, isObject$2 = isObject_1, toKey = _toKey;
54637
- function baseSet$2(object2, path, value, customizer) {
54482
+ function baseSet$1(object2, path, value, customizer) {
54638
54483
  if (!isObject$2(object2)) {
54639
54484
  return object2;
54640
54485
  }
@@ -54657,14 +54502,14 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
54657
54502
  }
54658
54503
  return object2;
54659
54504
  }
54660
- var _baseSet = baseSet$2;
54661
- var baseGet = _baseGet, baseSet$1 = _baseSet, castPath = _castPath;
54505
+ var _baseSet = baseSet$1;
54506
+ var baseGet = _baseGet, baseSet = _baseSet, castPath = _castPath;
54662
54507
  function basePickBy$1(object2, paths, predicate) {
54663
54508
  var index2 = -1, length = paths.length, result = {};
54664
54509
  while (++index2 < length) {
54665
54510
  var path = paths[index2], value = baseGet(object2, path);
54666
54511
  if (predicate(value, path)) {
54667
- baseSet$1(result, castPath(path, object2), value);
54512
+ baseSet(result, castPath(path, object2), value);
54668
54513
  }
54669
54514
  }
54670
54515
  return result;
@@ -56703,7 +56548,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
56703
56548
  return success$1(out, warnings);
56704
56549
  };
56705
56550
  }
56706
- function set$1(checker) {
56551
+ function set(checker) {
56707
56552
  return (value, path = new Path$1()) => {
56708
56553
  if (!(value instanceof Set)) {
56709
56554
  return failure$1("value is not a Set", path);
@@ -56773,7 +56618,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
56773
56618
  object,
56774
56619
  optional,
56775
56620
  dict,
56776
- set: set$1,
56621
+ set,
56777
56622
  map,
56778
56623
  writableArray,
56779
56624
  writableDict,
@@ -57055,7 +56900,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
57055
56900
  map: map$1,
57056
56901
  object: object$1,
57057
56902
  optional: optional$1,
57058
- set: set$1$1,
56903
+ set: set$1,
57059
56904
  tuple: tuple$1,
57060
56905
  writableArray: writableArray$1,
57061
56906
  writableDict: writableDict$1,
@@ -57116,7 +56961,7 @@ You must set sticky: 'left' | 'right' for the '${bugWithUnderColumnsSticky.Heade
57116
56961
  dict: dict$1,
57117
56962
  object: object$1,
57118
56963
  optional: optional$1,
57119
- set: set$1$1,
56964
+ set: set$1,
57120
56965
  map: map$1,
57121
56966
  writableArray: writableArray$1,
57122
56967
  writableDict: writableDict$1,
@@ -58825,50 +58670,6 @@ Inferred class string: "${iconClasses}."`
58825
58670
  serialize: urlSerializer
58826
58671
  };
58827
58672
  }
58828
- var baseSet = _baseSet;
58829
- function set(object2, path, value) {
58830
- return object2 == null ? object2 : baseSet(object2, path, value);
58831
- }
58832
- var set_1 = set;
58833
- function isTemplateMarker(value) {
58834
- return value && typeof value === "object" && value.__typename === "TemplateMarker";
58835
- }
58836
- function hasTemplateMarkers(component) {
58837
- if (!component || typeof component !== "object") {
58838
- return false;
58839
- }
58840
- for (const value of Object.values(component)) {
58841
- if (isTemplateMarker(value)) {
58842
- return true;
58843
- }
58844
- if (value && typeof value === "object") {
58845
- return hasTemplateMarkers(value);
58846
- }
58847
- }
58848
- return false;
58849
- }
58850
- function getMarkerPaths(template) {
58851
- const paths = {};
58852
- function recurse(component, path) {
58853
- for (const [key, value] of Object.entries(component)) {
58854
- if (isTemplateMarker(value)) {
58855
- paths[path + key] = value.field_name;
58856
- } else if (value instanceof Object) {
58857
- recurse(value, `${path + key}.`);
58858
- }
58859
- }
58860
- }
58861
- recurse(template, "");
58862
- return paths;
58863
- }
58864
- function replaceMarkers(template, data, paths) {
58865
- const templateCopy = cloneDeep_1(template);
58866
- for (const [path, fieldName] of Object.entries(paths)) {
58867
- const value = data[fieldName];
58868
- set_1(templateCopy, path, value);
58869
- }
58870
- return templateCopy;
58871
- }
58872
58673
  const Wrapper$2 = styled__default.default.div`
58873
58674
  display: flex;
58874
58675
  align-items: center;
@@ -59854,15 +59655,6 @@ Inferred class string: "${iconClasses}."`
59854
59655
  const { get: getComponent } = useComponentRegistry();
59855
59656
  const importers = React.useContext(importersCtx);
59856
59657
  const fallbackCtx$1 = React.useContext(fallbackCtx);
59857
- const firstRender = React.useRef(true);
59858
- if (firstRender.current) {
59859
- if (hasTemplateMarkers(props.component)) {
59860
- throw new Error(
59861
- `Component "${props.component.name}" has unhandled template markers. Make sure it's used in a component which handles templated components`
59862
- );
59863
- }
59864
- firstRender.current = false;
59865
- }
59866
59658
  React.useEffect(() => {
59867
59659
  var _a2;
59868
59660
  if (((_a2 = props.component) == null ? void 0 : _a2.name) === "RawString") {
@@ -86441,61 +86233,6 @@ Inferred class string: "${iconClasses}."`
86441
86233
  const [style, css2] = useComponentStyles(props);
86442
86234
  return /* @__PURE__ */ React__default.default.createElement(StyledDots, { $rawCss: css2, style });
86443
86235
  }
86444
- function ForChild(props) {
86445
- const component = React.useMemo(() => {
86446
- const withoutMarkers = replaceMarkers(props.template, props.data, props.markerPaths);
86447
- withoutMarkers.props.style = props.style;
86448
- return withoutMarkers;
86449
- }, [props.template, props.data]);
86450
- return /* @__PURE__ */ React__default.default.createElement(DynamicComponent, { component });
86451
- }
86452
- function For(props) {
86453
- const data = useAnyVariable(props.data);
86454
- const markerPaths = React.useMemo(() => getMarkerPaths(props.template), [props.template]);
86455
- const ListChild = React.useCallback(
86456
- (listProps) => {
86457
- return /* @__PURE__ */ React__default.default.createElement(
86458
- ForChild,
86459
- {
86460
- data: listProps.data[listProps.index],
86461
- key: listProps.data[listProps.index][props.key_accessor],
86462
- markerPaths,
86463
- style: listProps.style,
86464
- template: props.template
86465
- }
86466
- );
86467
- },
86468
- [markerPaths, props.key_accessor]
86469
- );
86470
- const getItemSize = React.useCallback(
86471
- (index2) => {
86472
- return data[index2][props.size_accessor];
86473
- },
86474
- [data, props.size_accessor]
86475
- );
86476
- const getItemKey = React.useCallback(
86477
- (index2, listData) => {
86478
- return listData[index2][props.key_accessor];
86479
- },
86480
- [props.key_accessor]
86481
- );
86482
- if (!props.virtualize) {
86483
- return /* @__PURE__ */ React__default.default.createElement(React__default.default.Fragment, null, data.map((item, index2) => /* @__PURE__ */ React__default.default.createElement(ListChild, { data, index: index2, key: item[props.key_accessor], style: {} })));
86484
- }
86485
- return /* @__PURE__ */ React__default.default.createElement(AutoSizer, null, ({ height, width }) => /* @__PURE__ */ React__default.default.createElement(
86486
- VariableSizeList,
86487
- {
86488
- height,
86489
- itemCount: data.length,
86490
- itemData: data,
86491
- itemKey: getItemKey,
86492
- itemSize: getItemSize,
86493
- layout: props.direction,
86494
- width
86495
- },
86496
- ListChild
86497
- ));
86498
- }
86499
86236
  exports.BasicAuthLogin = BasicAuthLogin;
86500
86237
  exports.BasicAuthLogout = BasicAuthLogout;
86501
86238
  exports.Center = Center;
@@ -86508,7 +86245,6 @@ Inferred class string: "${iconClasses}."`
86508
86245
  exports.DynamicComponent = DynamicComponent;
86509
86246
  exports.EventBus = EventBus;
86510
86247
  exports.EventCapturer = EventCapturer;
86511
- exports.For = For;
86512
86248
  exports.Menu = Menu;
86513
86249
  exports.NavigateTo = NavigateTo;
86514
86250
  exports.Notifications = index$1;
@@ -23,7 +23,6 @@ from dara.core.visual.components.fallback import (
23
23
  Fallback,
24
24
  RowFallbackDef,
25
25
  )
26
- from dara.core.visual.components.for_cmp import For, ForDef
27
26
  from dara.core.visual.components.invalid_component import InvalidComponent
28
27
  from dara.core.visual.components.menu import Menu, MenuDef
29
28
  from dara.core.visual.components.progress_tracker import (
@@ -50,8 +49,6 @@ __all__ = [
50
49
  'SideBarFrameDef',
51
50
  'TopBarFrame',
52
51
  'TopBarFrameDef',
53
- 'For',
54
- 'ForDef',
55
52
  'DefaultFallbackDef',
56
53
  'RowFallbackDef',
57
54
  'Fallback',