litestar-vite 0.11.1__py3-none-any.whl → 0.12.0__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.

Potentially problematic release.


This version of litestar-vite might be problematic. Click here for more details.

litestar_vite/commands.py CHANGED
@@ -14,7 +14,7 @@ DEFAULT_RESOURCES: set[str] = {"styles.css.j2", "main.ts.j2"}
14
14
  DEFAULT_DEV_DEPENDENCIES: dict[str, str] = {
15
15
  "typescript": "^5.7.2",
16
16
  "vite": "^6.0.3",
17
- "litestar-vite-plugin": "^0.11.1",
17
+ "litestar-vite-plugin": "^0.12.0",
18
18
  "@types/node": "^22.10.1",
19
19
  }
20
20
  DEFAULT_DEPENDENCIES: dict[str, str] = {"axios": "^1.7.2"}
@@ -2,18 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- from litestar.exceptions import ImproperlyConfiguredException
6
- from litestar.middleware import DefineMiddleware
7
- from litestar.middleware.session import SessionMiddleware
5
+ from anyio.from_thread import BlockingPortalProvider
8
6
  from litestar.plugins import InitPluginProtocol
9
- from litestar.security.session_auth.middleware import MiddlewareWrapper
10
- from litestar.utils.predicates import is_class_and_subclass
11
-
12
- from litestar_vite.inertia.exception_handler import exception_to_http_response
13
- from litestar_vite.inertia.middleware import InertiaMiddleware
14
- from litestar_vite.inertia.request import InertiaRequest
15
- from litestar_vite.inertia.response import InertiaResponse
16
- from litestar_vite.inertia.routes import generate_js_routes
17
7
 
18
8
  if TYPE_CHECKING:
19
9
  from litestar import Litestar
@@ -24,6 +14,8 @@ if TYPE_CHECKING:
24
14
 
25
15
  def set_js_routes(app: Litestar) -> None:
26
16
  """Generate the route structure of the application on startup."""
17
+ from litestar_vite.inertia.routes import generate_js_routes
18
+
27
19
  js_routes = generate_js_routes(app)
28
20
  app.state.js_routes = js_routes
29
21
 
@@ -31,7 +23,7 @@ def set_js_routes(app: Litestar) -> None:
31
23
  class InertiaPlugin(InitPluginProtocol):
32
24
  """Inertia plugin."""
33
25
 
34
- __slots__ = ("config",)
26
+ __slots__ = ("config", "portal")
35
27
 
36
28
  def __init__(self, config: InertiaConfig) -> None:
37
29
  """Initialize ``Inertia``.
@@ -41,12 +33,29 @@ class InertiaPlugin(InitPluginProtocol):
41
33
  """
42
34
  self.config = config
43
35
 
36
+ self.portal = BlockingPortalProvider()
37
+
38
+ def get_portal(self) -> BlockingPortalProvider:
39
+ return self.portal
40
+
44
41
  def on_app_init(self, app_config: AppConfig) -> AppConfig:
45
42
  """Configure application for use with Vite.
46
43
 
47
44
  Args:
48
45
  app_config: The :class:`AppConfig <litestar.config.app.AppConfig>` instance.
49
46
  """
47
+
48
+ from litestar.exceptions import ImproperlyConfiguredException
49
+ from litestar.middleware import DefineMiddleware
50
+ from litestar.middleware.session import SessionMiddleware
51
+ from litestar.security.session_auth.middleware import MiddlewareWrapper
52
+ from litestar.utils.predicates import is_class_and_subclass
53
+
54
+ from litestar_vite.inertia.exception_handler import exception_to_http_response
55
+ from litestar_vite.inertia.middleware import InertiaMiddleware
56
+ from litestar_vite.inertia.request import InertiaRequest
57
+ from litestar_vite.inertia.response import DeferredProp, InertiaBack, InertiaResponse, StaticProp
58
+
50
59
  for mw in app_config.middleware:
51
60
  if isinstance(mw, DefineMiddleware) and is_class_and_subclass(
52
61
  mw.middleware,
@@ -61,4 +70,15 @@ class InertiaPlugin(InitPluginProtocol):
61
70
  app_config.response_class = InertiaResponse
62
71
  app_config.middleware.append(InertiaMiddleware)
63
72
  app_config.on_startup.append(set_js_routes)
73
+ app_config.signature_types.extend([InertiaRequest, InertiaResponse, InertiaBack, StaticProp, DeferredProp])
74
+ app_config.type_encoders = {
75
+ StaticProp: lambda val: val.render(),
76
+ DeferredProp: lambda val: val.render(),
77
+ **(app_config.type_encoders or {}),
78
+ }
79
+ app_config.type_decoders = [
80
+ (lambda x: x is StaticProp, lambda t, v: t(v)),
81
+ (lambda x: x is DeferredProp, lambda t, v: t(v)),
82
+ *(app_config.type_decoders or []),
83
+ ]
64
84
  return app_config
@@ -1,14 +1,31 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import inspect
3
4
  import itertools
4
5
  from collections import defaultdict
6
+ from collections.abc import Mapping
7
+ from contextlib import contextmanager
5
8
  from functools import lru_cache
6
9
  from mimetypes import guess_type
7
10
  from pathlib import PurePath
8
11
  from textwrap import dedent
9
- from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Mapping, TypeVar, cast
12
+ from typing import (
13
+ TYPE_CHECKING,
14
+ Any,
15
+ Callable,
16
+ Coroutine,
17
+ Dict,
18
+ Generator,
19
+ Generic,
20
+ Iterable,
21
+ List,
22
+ TypeVar,
23
+ cast,
24
+ overload,
25
+ )
10
26
  from urllib.parse import quote, urlparse, urlunparse
11
27
 
28
+ from anyio.from_thread import BlockingPortal, start_blocking_portal
12
29
  from litestar import Litestar, MediaType, Request, Response
13
30
  from litestar.datastructures.cookie import Cookie
14
31
  from litestar.exceptions import ImproperlyConfiguredException
@@ -21,6 +38,7 @@ from litestar.utils.empty import value_or_default
21
38
  from litestar.utils.helpers import get_enum_string_value
22
39
  from litestar.utils.scope.state import ScopeState
23
40
  from markupsafe import Markup
41
+ from typing_extensions import ParamSpec, TypeGuard
24
42
 
25
43
  from litestar_vite.inertia._utils import get_headers
26
44
  from litestar_vite.inertia.types import InertiaHeaderType, PageProps
@@ -33,53 +51,224 @@ if TYPE_CHECKING:
33
51
  from litestar.connection.base import AuthT, StateT, UserT
34
52
  from litestar.types import ResponseCookies, ResponseHeaders, TypeEncodersMap
35
53
 
54
+ from litestar_vite.inertia.plugin import InertiaPlugin
36
55
  from litestar_vite.inertia.routes import Routes
37
56
 
38
- from .plugin import InertiaPlugin
39
-
40
57
  T = TypeVar("T")
58
+ T_ParamSpec = ParamSpec("T_ParamSpec")
59
+ PropKeyT = TypeVar("PropKeyT", bound=str)
60
+ StaticT = TypeVar("StaticT", bound=object)
41
61
 
42
62
 
43
- def share(
44
- connection: ASGIConnection[Any, Any, Any, Any],
63
+ @overload
64
+ def lazy(key: str, value_or_callable: None) -> StaticProp[str, None]: ...
65
+
66
+
67
+ @overload
68
+ def lazy(key: str, value_or_callable: T) -> StaticProp[str, T]: ...
69
+
70
+
71
+ @overload
72
+ def lazy(
45
73
  key: str,
46
- value: Any,
47
- ) -> None:
48
- try:
49
- connection.session.setdefault("_shared", {}).update({key: value})
50
- except (AttributeError, ImproperlyConfiguredException):
51
- msg = "Unable to set `share` session state. A valid session was not found for this request."
52
- connection.logger.warning(msg)
74
+ value_or_callable: Callable[..., None] = ...,
75
+ ) -> DeferredProp[str, None]: ...
53
76
 
54
77
 
55
- def error(
56
- connection: ASGIConnection[Any, Any, Any, Any],
78
+ @overload
79
+ def lazy(
57
80
  key: str,
58
- message: str,
59
- ) -> None:
60
- try:
61
- connection.session.setdefault("_errors", {}).update({key: message})
62
- except (AttributeError, ImproperlyConfiguredException):
63
- msg = "Unable to set `error` session state. A valid session was not found for this request."
64
- connection.logger.warning(msg)
81
+ value_or_callable: Callable[T_ParamSpec, T | Coroutine[Any, Any, T]] = ..., # pyright: ignore[reportInvalidTypeVarUse]
82
+ ) -> DeferredProp[str, T]: ...
83
+
84
+
85
+ def lazy( # type: ignore[misc]
86
+ key: str,
87
+ value_or_callable: T | Callable[T_ParamSpec, T | Coroutine[Any, Any, T]], # pyright: ignore[reportInvalidTypeVarUse]
88
+ ) -> StaticProp[str, None] | StaticProp[str, T] | DeferredProp[str, T] | DeferredProp[str, None]:
89
+ """Wrap an async function to return a DeferredProp."""
90
+ if value_or_callable is None:
91
+ return StaticProp[str, None](key=key, value=None)
92
+
93
+ if not callable(value_or_callable):
94
+ return StaticProp[str, T](key=key, value=value_or_callable)
95
+
96
+ return DeferredProp[str, T](key=key, value=value_or_callable) # pyright: ignore[reportArgumentType]
97
+
98
+
99
+ class StaticProp(Generic[PropKeyT, StaticT]):
100
+ """A wrapper for static property evaluation."""
101
+
102
+ def __init__(self, key: PropKeyT, value: StaticT) -> None:
103
+ self._key = key
104
+ self._result = value
105
+
106
+ @property
107
+ def key(self) -> PropKeyT:
108
+ return self._key
109
+
110
+ def render(self, portal: BlockingPortal | None = None) -> StaticT:
111
+ return self._result
112
+
113
+
114
+ class DeferredProp(Generic[PropKeyT, T]):
115
+ """A wrapper for deferred property evaluation."""
116
+
117
+ def __init__(self, key: PropKeyT, value: Callable[T_ParamSpec, T | Coroutine[Any, Any, T]] | None = None) -> None:
118
+ self._key = key
119
+ self._value = value
120
+ self._evaluated = False
121
+ self._result: T | None = None
122
+
123
+ @property
124
+ def key(self) -> PropKeyT:
125
+ return self._key
126
+
127
+ @staticmethod
128
+ def _is_awaitable(
129
+ v: Callable[T_ParamSpec, T | Coroutine[Any, Any, T]],
130
+ ) -> TypeGuard[Coroutine[Any, Any, T]]:
131
+ return inspect.iscoroutinefunction(v)
132
+
133
+ @staticmethod
134
+ @contextmanager
135
+ def _with_portal(portal: BlockingPortal | None = None) -> Generator[BlockingPortal, None, None]:
136
+ if portal is None:
137
+ with start_blocking_portal() as new_portal:
138
+ yield new_portal
139
+ else:
140
+ yield portal
141
+
142
+ def render(self, portal: BlockingPortal | None = None) -> T | None:
143
+ if self._evaluated:
144
+ return self._result
145
+ if self._value is None or not callable(self._value):
146
+ self._result = self._value
147
+ elif not self._is_awaitable(self._value):
148
+ self._result = self._value() # type: ignore[call-arg,assignment,unused-ignore]
149
+ else:
150
+ with self._with_portal(portal) as bp:
151
+ self._result = bp.call(self._value) # type: ignore[call-overload]
152
+ self._evaluated = True
153
+ return self._result # pyright: ignore[reportUnknownVariableType,reportUnknownMemberType]
154
+
155
+
156
+ def is_lazy_prop(value: Any) -> TypeGuard[DeferredProp[Any, Any]]:
157
+ """Check if value is a deferred property.
158
+
159
+ Args:
160
+ value: Any value to check
161
+
162
+ Returns:
163
+ bool: True if value is a deferred property
164
+ """
165
+ return isinstance(value, (DeferredProp, StaticProp))
166
+
167
+
168
+ def should_render(value: Any, partial_data: set[str] | None = None) -> bool:
169
+ """Check if value should be rendered.
170
+
171
+ Args:
172
+ value: Any value to check
173
+ partial_data: Optional set of keys for partial rendering
174
+
175
+ Returns:
176
+ bool: True if value should be rendered
177
+ """
178
+ partial_data = partial_data or set()
179
+ if is_lazy_prop(value):
180
+ return value.key in partial_data
181
+ return True
182
+
183
+
184
+ def is_or_contains_lazy_prop(value: Any) -> bool:
185
+ """Check if value is or contains a deferred property.
186
+
187
+ Args:
188
+ value: Any value to check
189
+
190
+ Returns:
191
+ bool: True if value is or contains a deferred property
192
+ """
193
+ if is_lazy_prop(value):
194
+ return True
195
+ if isinstance(value, str):
196
+ return False
197
+ if isinstance(value, Mapping):
198
+ return any(is_or_contains_lazy_prop(v) for v in cast("Mapping[str, Any]", value).values())
199
+ if isinstance(value, Iterable):
200
+ return any(is_or_contains_lazy_prop(v) for v in cast("Iterable[Any]", value))
201
+ return False
202
+
203
+
204
+ def lazy_render(value: T, partial_data: set[str] | None = None, portal: BlockingPortal | None = None) -> T:
205
+ """Filter deferred properties from the value based on partial data.
206
+
207
+ Args:
208
+ value: The value to filter
209
+ partial_data: Keys for partial rendering
210
+ portal: Optional portal to use for async rendering
211
+ Returns:
212
+ The filtered value
213
+ """
214
+ partial_data = partial_data or set()
215
+ if isinstance(value, str):
216
+ return cast("T", value)
217
+ if isinstance(value, Mapping):
218
+ return cast(
219
+ "T",
220
+ {
221
+ k: lazy_render(v, partial_data)
222
+ for k, v in cast("Mapping[str, Any]", value).items()
223
+ if should_render(v, partial_data)
224
+ },
225
+ )
226
+
227
+ if isinstance(value, (list, tuple)):
228
+ filtered = [
229
+ lazy_render(v, partial_data) for v in cast("Iterable[Any]", value) if should_render(v, partial_data)
230
+ ]
231
+ return cast("T", type(value)(filtered)) # pyright: ignore[reportUnknownArgumentType]
232
+
233
+ if is_lazy_prop(value) and should_render(value, partial_data):
234
+ return cast("T", value.render())
235
+
236
+ return cast("T", value)
65
237
 
66
238
 
67
239
  def get_shared_props(
68
240
  request: ASGIConnection[Any, Any, Any, Any],
69
241
  partial_data: set[str] | None = None,
70
- ) -> Dict[str, Any]: # noqa: UP006
71
- """Return shared session props for a request
242
+ ) -> dict[str, Any]:
243
+ """Return shared session props for a request.
244
+
245
+ Args:
246
+ request: The ASGI connection.
247
+ partial_data: Optional set of keys for partial rendering.
72
248
 
249
+ Returns:
250
+ Dict[str, Any]: The shared props.
73
251
 
74
- Be sure to call this before `self.create_template_context` if you would like to include the `flash` message details.
252
+ Note:
253
+ Be sure to call this before `self.create_template_context` if you would like to include the `flash` message details.
75
254
  """
76
255
  props: dict[str, Any] = {}
77
256
  flash: dict[str, list[str]] = defaultdict(list)
78
257
  errors: dict[str, Any] = {}
79
258
  error_bag = request.headers.get("X-Inertia-Error-Bag", None)
259
+
80
260
  try:
81
261
  errors = request.session.pop("_errors", {})
82
- props.update(cast("Dict[str,Any]", request.session.pop("_shared", {})))
262
+ shared_props = cast("Dict[str,Any]", request.session.pop("_shared", {}))
263
+
264
+ # Handle deferred props
265
+ for key, value in shared_props.items():
266
+ if is_lazy_prop(value) and should_render(value, partial_data):
267
+ props[key] = value.render()
268
+ continue
269
+ if should_render(value, partial_data):
270
+ props[key] = value
271
+
83
272
  for message in cast("List[Dict[str,Any]]", request.session.pop("_messages", [])):
84
273
  flash[message["category"]].append(message["message"])
85
274
 
@@ -92,12 +281,51 @@ def get_shared_props(
92
281
  except (AttributeError, ImproperlyConfiguredException):
93
282
  msg = "Unable to generate all shared props. A valid session was not found for this request."
94
283
  request.logger.warning(msg)
284
+
95
285
  props["flash"] = flash
96
286
  props["errors"] = {error_bag: errors} if error_bag is not None else errors
97
287
  props["csrf_token"] = value_or_default(ScopeState.from_scope(request.scope).csrf_token, "")
98
288
  return props
99
289
 
100
290
 
291
+ def share(
292
+ connection: ASGIConnection[Any, Any, Any, Any],
293
+ key: str,
294
+ value: Any,
295
+ ) -> None:
296
+ """Share a value in the session.
297
+
298
+ Args:
299
+ connection: The ASGI connection.
300
+ key: The key to store the value under.
301
+ value: The value to store.
302
+ """
303
+ try:
304
+ connection.session.setdefault("_shared", {}).update({key: value})
305
+ except (AttributeError, ImproperlyConfiguredException):
306
+ msg = "Unable to set `share` session state. A valid session was not found for this request."
307
+ connection.logger.warning(msg)
308
+
309
+
310
+ def error(
311
+ connection: ASGIConnection[Any, Any, Any, Any],
312
+ key: str,
313
+ message: str,
314
+ ) -> None:
315
+ """Set an error message in the session.
316
+
317
+ Args:
318
+ connection: The ASGI connection.
319
+ key: The key to store the error under.
320
+ message: The error message.
321
+ """
322
+ try:
323
+ connection.session.setdefault("_errors", {}).update({key: message})
324
+ except (AttributeError, ImproperlyConfiguredException):
325
+ msg = "Unable to set `error` session state. A valid session was not found for this request."
326
+ connection.logger.warning(msg)
327
+
328
+
101
329
  def js_routes_script(js_routes: Routes) -> Markup:
102
330
  @lru_cache
103
331
  def _markup_safe_json_dumps(js_routes: str) -> Markup:
@@ -197,7 +425,7 @@ class InertiaResponse(Response[T]):
197
425
  "csrf_input": f'<input type="hidden" name="_csrf_token" value="{csrf_token}" />',
198
426
  }
199
427
 
200
- def to_asgi_response(
428
+ def to_asgi_response( # noqa: C901, PLR0912
201
429
  self,
202
430
  app: Litestar | None,
203
431
  request: Request[UserT, AuthT, StateT],
@@ -250,7 +478,13 @@ class InertiaResponse(Response[T]):
250
478
  {"Vary": "Accept", **get_headers(InertiaHeaderType(enabled=True))},
251
479
  )
252
480
  shared_props = get_shared_props(request, partial_data=partial_keys if is_partial_render else None)
253
- shared_props["content"] = self.content
481
+ if is_or_contains_lazy_prop(self.content):
482
+ filtered_content = lazy_render(self.content, partial_keys if is_partial_render else None)
483
+ if filtered_content is not None:
484
+ shared_props["content"] = filtered_content
485
+ elif should_render(self.content, partial_keys):
486
+ shared_props["content"] = self.content
487
+
254
488
  page_props = PageProps[T](
255
489
  component=request.inertia.route_component, # type: ignore[attr-defined] # pyright: ignore[reportUnknownArgumentType,reportUnknownMemberType,reportAttributeAccessIssue]
256
490
  props=shared_props, # pyright: ignore[reportArgumentType]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: litestar-vite
3
- Version: 0.11.1
3
+ Version: 0.12.0
4
4
  Summary: Vite plugin for Litestar
5
5
  Project-URL: Changelog, https://cofin.github.io/litestar-vite/latest/changelog
6
6
  Project-URL: Discord, https://discord.gg/X3FJqy8d2j
@@ -10,6 +10,7 @@ Project-URL: Issue, https://github.com/cofin/litestar-vite/issues/
10
10
  Project-URL: Source, https://github.com/cofin/litestar-vite
11
11
  Author-email: Cody Fincher <cody.fincher@gmail.com>
12
12
  License: MIT
13
+ License-File: LICENSE
13
14
  Keywords: litestar,vite
14
15
  Classifier: Environment :: Web Environment
15
16
  Classifier: Intended Audience :: Developers
@@ -1,7 +1,7 @@
1
1
  litestar_vite/__init__.py,sha256=OioNGhH88mdivQlFz9JlbJV8R6wyjSYE3c8C-RIM4Ls,277
2
2
  litestar_vite/__metadata__.py,sha256=_Wo-vNQuj5co9J4FwJAB2rRafbFo8ztTHrXmEPrYrV8,514
3
3
  litestar_vite/cli.py,sha256=CBSRohDLU9cDeKMAfSbFiw1x8OE_b15ZlUaxji9Rdw8,10749
4
- litestar_vite/commands.py,sha256=E-PaU7Hk9BDj63d8u7-FSwR8oH9hfSB41BGOpmVuv3o,5228
4
+ litestar_vite/commands.py,sha256=JTRBvpR_3ddFb2o4-AJSELegw-ZGDsJ_yMaT5FVdp4w,5228
5
5
  litestar_vite/config.py,sha256=cZWIwTwNnBYScCty8OxxPaOL8cELx57dm7JQeV8og3Y,4565
6
6
  litestar_vite/loader.py,sha256=nrXL2txXoBZEsdLZnysgBYZSreMXQ7ckLuNcu7MqnSM,10277
7
7
  litestar_vite/plugin.py,sha256=2ypzvlW5TaOeXTWPa2yHXzkPUf4okRBDl9YHo2qg-cM,8043
@@ -11,9 +11,9 @@ litestar_vite/inertia/_utils.py,sha256=ijO9Lgka7ZPIAHkby9szbTGoSg0nDShC2bqWT9cDx
11
11
  litestar_vite/inertia/config.py,sha256=0Je9SLg0acv0eRvudk3aJLj5k1DjPxULoVOwAfpjnUc,1232
12
12
  litestar_vite/inertia/exception_handler.py,sha256=0FiW8jVib0xT453BzMPOeJa7bRwnxkOUdJ91kiFHPIo,5308
13
13
  litestar_vite/inertia/middleware.py,sha256=23HfQ8D2wNGXUXt_isuGfZ8AFKrr1d_498qGFLynocs,1650
14
- litestar_vite/inertia/plugin.py,sha256=OgXmmvjl7KWlt4KEkYhS3mU2EY4iYN9JtJ20S3Qlht8,2349
14
+ litestar_vite/inertia/plugin.py,sha256=f2oFwlEDt9WZ8zt-AqiCIRPlkHIyzLtPYYo8WJZX-tI,3186
15
15
  litestar_vite/inertia/request.py,sha256=Ogt_ikauWrsgKafaip7IL1YhbybwjdBAQ0PQS7cImoQ,3848
16
- litestar_vite/inertia/response.py,sha256=drOn8wdxEhoffPJLBpLGqEX1UJVgSOL-qbsTR3bJG2M,16222
16
+ litestar_vite/inertia/response.py,sha256=CY-qziEPc9FZ4oXxtgO0Iipg1Hz4x-fiUeLK04Br8kM,23425
17
17
  litestar_vite/inertia/routes.py,sha256=QksJm2RUfL-WbuhOieYnPXXWO5GYnPtmsYEm6Ef8Yeo,1782
18
18
  litestar_vite/inertia/types.py,sha256=tLp0pm1N__hcWC875khf6wH1nuFlKS9-VjDqgsRkXnw,702
19
19
  litestar_vite/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -23,7 +23,7 @@ litestar_vite/templates/package.json.j2,sha256=0JWgdTuaSZ25EmCltF_zbqDdpxfvCLeYu
23
23
  litestar_vite/templates/styles.css.j2,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  litestar_vite/templates/tsconfig.json.j2,sha256=q1REIuVyXUHCy4Zi2kgTkmrhdT98vyY89k-WTrImOj8,843
25
25
  litestar_vite/templates/vite.config.ts.j2,sha256=bF5kOPFafYMkhhV0VkIwetN-_zoVMGVM1jEMX_wKoNc,1037
26
- litestar_vite-0.11.1.dist-info/METADATA,sha256=_qb3u3hyEBieCsfpMOPNBSjCPRfX8JH9tt0UyJOxh5Y,6222
27
- litestar_vite-0.11.1.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
28
- litestar_vite-0.11.1.dist-info/licenses/LICENSE,sha256=HeTiEfEgvroUXZe_xAmYHxtTBgw--mbXyZLsWDYabHc,1069
29
- litestar_vite-0.11.1.dist-info/RECORD,,
26
+ litestar_vite-0.12.0.dist-info/METADATA,sha256=0Nv7ZBioTYS6JTE0KzPht82kwBhcBGH7W1cBRB8vgCM,6244
27
+ litestar_vite-0.12.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
28
+ litestar_vite-0.12.0.dist-info/licenses/LICENSE,sha256=HeTiEfEgvroUXZe_xAmYHxtTBgw--mbXyZLsWDYabHc,1069
29
+ litestar_vite-0.12.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any