instaui 0.1.0__py3-none-any.whl → 0.1.1__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.
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Dict, List, Optional, Set, Union
3
+ from typing import TYPE_CHECKING, Dict, List, Optional, Set
4
4
  from instaui.common.jsonable import Jsonable
5
5
  from instaui.runtime import get_slot_stacks, pop_slot
6
6
  from instaui.runtime._app import get_app_slot
@@ -8,7 +8,6 @@ from instaui.vars.slot_prop import BindingSlotPropItem
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from instaui.components.component import Component
11
- from instaui.components.vfor import VFor
12
11
 
13
12
  _DEFAULT_SLOT_NAME = ":"
14
13
 
@@ -50,7 +49,7 @@ class Slot(Jsonable):
50
49
 
51
50
  self._id: Optional[str] = None
52
51
  self._name = name
53
- self._children: List[Union[Component, VFor]] = []
52
+ self._children: List[Component] = []
54
53
  self._props_use_name: Set[str] = set()
55
54
 
56
55
  def _has_props_use(self):
@@ -3,7 +3,6 @@ from collections import deque
3
3
  from datetime import datetime
4
4
  import importlib.util
5
5
  from pathlib import Path
6
- import sys
7
6
  import typing
8
7
  from pydantic import BaseModel, Field
9
8
  import jinja2
@@ -13,29 +12,42 @@ import inspect
13
12
  def build_routes_from_files(
14
13
  folder_path: typing.Union[str, Path] = "pages",
15
14
  module_name: str = "_routes",
15
+ route_config_var_name: str = "_route_config",
16
16
  ):
17
- folder_path = _utils.get_caller_path().parent / Path(folder_path)
18
- root = _model_utils.create_root(folder_path, module_name)
17
+ global_args = _GlobalArgs(
18
+ base_folder_path=_utils.get_caller_path().parent / Path(folder_path),
19
+ module_name=module_name,
20
+ route_config_var_name=route_config_var_name,
21
+ )
22
+
23
+ root = _model_utils.create_root(global_args)
19
24
  _code_gen.generate_router_file(root)
20
25
 
21
- print(f"Build _routes from files in {folder_path}...")
22
- # _module_utils.reload_module_from_folder(folder_path, module_name)
26
+ print(f"Build _routes from files in {global_args.base_folder_path}...")
27
+
28
+
29
+ class _GlobalArgs(BaseModel):
30
+ base_folder_path: Path
31
+ module_name: str
32
+ route_config_var_name: str
23
33
 
24
34
 
25
35
  class _model_utils:
26
36
  class FileRouteInfo(BaseModel):
27
37
  file: Path
28
38
  base_folder: Path
39
+ global_args: _GlobalArgs
29
40
  children: typing.List[_model_utils.FileRouteInfo] = []
30
-
31
41
  path: str = Field(init=False, default="")
32
42
  name: str = Field(init=False, default="")
33
43
  fn_path: typing.Optional[str] = Field(init=False, default=None)
34
44
 
35
45
  params: str = Field(init=False, default="")
46
+ meta: typing.Dict = Field(init=False, default={})
36
47
 
37
48
  def model_post_init(self, __context) -> None:
38
49
  self.params = self._extract_params()
50
+ self.meta = self._extract_meta()
39
51
  self.path, self.name = self._extra_path_name()
40
52
 
41
53
  if self.file.is_file():
@@ -46,14 +58,15 @@ class _model_utils:
46
58
  def is_index_file(self):
47
59
  return self.file.is_file() and self.file.stem == "index"
48
60
 
49
- def change_index(self, index_info: _model_utils.FileRouteInfo):
61
+ def change_sync_index_info(self, index_info: _model_utils.FileRouteInfo):
50
62
  self.fn_path = index_info.fn_path
51
63
  self.path = self.path + index_info.params
64
+ self.meta = index_info.meta
52
65
 
53
66
  def _extract_params(self):
54
67
  if self.file.is_file():
55
68
  route_config = _module_utils.get_module_getter(self.file)(
56
- "_route_config"
69
+ self.global_args.route_config_var_name
57
70
  )
58
71
  if route_config:
59
72
  if "params" in route_config:
@@ -61,6 +74,18 @@ class _model_utils:
61
74
 
62
75
  return ""
63
76
 
77
+ def _extract_meta(self):
78
+ if self.file.is_file():
79
+ route_config = _module_utils.get_module_getter(self.file)(
80
+ self.global_args.route_config_var_name
81
+ )
82
+
83
+ if route_config:
84
+ if "meta" in route_config:
85
+ return route_config["meta"]
86
+
87
+ return {}
88
+
64
89
  def _extra_path_name(self):
65
90
  name_parts = list(
66
91
  self.file.relative_to(self.base_folder).with_suffix("").parts
@@ -86,12 +111,12 @@ class _model_utils:
86
111
  if not self.fn_path:
87
112
  return ""
88
113
 
89
- return f"from .{self.fn_path} import main as {self.main_fn_name()}"
114
+ return f"from .{self.fn_path.replace(' ','_')} import main as {self.main_fn_name()}"
90
115
 
91
116
  def main_fn_name(self):
92
117
  if not self.fn_path:
93
118
  return ""
94
- return self.name.replace(".", "_")
119
+ return self.name.replace(".", "_").replace(" ", "_")
95
120
 
96
121
  class FileRouteRoot(BaseModel):
97
122
  folder: str
@@ -99,15 +124,17 @@ class _model_utils:
99
124
  infos: list[_model_utils.FileRouteInfo] = []
100
125
 
101
126
  @staticmethod
102
- def create_root(folder: Path, module_name: str) -> FileRouteRoot:
103
- base_folder = Path(folder)
104
- infos = _model_utils._create_route_info(base_folder)
127
+ def create_root(global_args: _GlobalArgs) -> FileRouteRoot:
128
+ base_folder = Path(global_args.base_folder_path)
129
+ infos = _model_utils._create_route_info(base_folder, global_args)
105
130
  return _model_utils.FileRouteRoot(
106
- folder=str(base_folder), module_name=module_name, infos=infos
131
+ folder=str(base_folder), module_name=global_args.module_name, infos=infos
107
132
  )
108
133
 
109
134
  @staticmethod
110
- def _create_route_info(base_folder: Path) -> typing.List[FileRouteInfo]:
135
+ def _create_route_info(
136
+ base_folder: Path, global_args: _GlobalArgs
137
+ ) -> typing.List[FileRouteInfo]:
111
138
  result: typing.List[_model_utils.FileRouteInfo] = []
112
139
 
113
140
  stack: deque[
@@ -124,7 +151,7 @@ class _model_utils:
124
151
 
125
152
  if is_dir:
126
153
  folder_info = _model_utils.FileRouteInfo(
127
- file=item, base_folder=base_folder
154
+ file=item, base_folder=base_folder, global_args=global_args
128
155
  )
129
156
  infos = ((folder_info, path) for path in item.iterdir())
130
157
  stack.extendleft(infos)
@@ -138,13 +165,15 @@ class _model_utils:
138
165
  if item.suffix != ".py":
139
166
  continue
140
167
 
141
- file_info = _model_utils.FileRouteInfo(file=item, base_folder=base_folder)
168
+ file_info = _model_utils.FileRouteInfo(
169
+ file=item, base_folder=base_folder, global_args=global_args
170
+ )
142
171
 
143
172
  if parent_info is None:
144
173
  result.append(file_info)
145
174
  else:
146
175
  if file_info.is_index_file():
147
- parent_info.change_index(file_info)
176
+ parent_info.change_sync_index_info(file_info)
148
177
 
149
178
  else:
150
179
  parent_info.children.append(file_info)
@@ -200,30 +229,6 @@ class _code_gen:
200
229
 
201
230
 
202
231
  class _module_utils:
203
- @staticmethod
204
- def reload_module_from_folder(folder: Path, module_name: str):
205
- module_file_path = folder / f"{module_name}.py"
206
-
207
- if not module_file_path.exists():
208
- raise FileNotFoundError(f"No such file: '{module_file_path}'")
209
-
210
- package_name = module_file_path.parent.name
211
- spec = importlib.util.spec_from_file_location(
212
- module_name, str(module_file_path)
213
- )
214
- if spec is None:
215
- raise ImportError(f"Failed to load module: '{module_name}'")
216
-
217
- module = importlib.util.module_from_spec(spec)
218
- module.__package__ = package_name
219
-
220
- if module_name in sys.modules:
221
- sys.modules[module_name] = module
222
- importlib.reload(module)
223
- return
224
-
225
- spec.loader.exec_module(module) # type: ignore
226
-
227
232
  @staticmethod
228
233
  def get_module_getter(path: Path):
229
234
  if not isinstance(path, Path):
@@ -17,31 +17,7 @@ class RouteItem(BaseModel):
17
17
  component_fn: typing.Optional[typing.Callable] = Field(exclude=True)
18
18
  scope: typing.Optional[Scope] = None
19
19
  vue_route_item: VueRouteItem = Field(serialization_alias="vueItem")
20
-
21
- # def model_post_init(self, __context: typing.Any) -> None:
22
- # if self.component_fn is None and (not self.vue_route_item.path):
23
- # raise ValueError("Either component_fn or vue_route_item.path must be set")
24
-
25
- # if self.component_fn is None:
26
- # return None
27
-
28
- # if self.vue_route_item.path is None:
29
- # self.vue_route_item.path = f"/{'' if self.component_fn.__name__=='index' else self.component_fn.__name__}"
30
-
31
- # app = get_app_slot()
32
-
33
- # with new_scope(append_to_app=False) as scope:
34
- # with Div() as div:
35
- # self.component_fn()
36
-
37
- # app.items.pop()
38
-
39
- # self.scope = scope
40
- # self.vue_route_item.component = div._slot_manager.default._children
41
-
42
- # @field_serializer("scope")
43
- # def serialize_scope(self, value: Scope):
44
- # return dumps2dict(value)
20
+ meta: typing.Optional[typing.Dict] = None
45
21
 
46
22
  @model_serializer
47
23
  def model_ser(self):
@@ -80,6 +56,7 @@ class RouteItem(BaseModel):
80
56
  name: typing.Optional[str] = None,
81
57
  params: typing.Optional[typing.Dict[str, str]] = None,
82
58
  children: typing.Optional[typing.List[RouteItem]] = None,
59
+ meta: typing.Optional[typing.Dict] = None,
83
60
  ):
84
61
  """Create a new RouteItem
85
62
 
@@ -103,6 +80,7 @@ class RouteItem(BaseModel):
103
80
 
104
81
  return cls(
105
82
  component_fn=component_fn,
83
+ meta=meta,
106
84
  vue_route_item=VueRouteItem(
107
85
  path=path,
108
86
  name=name,
@@ -21,6 +21,7 @@
21
21
  router.RouteItem.create(
22
22
  path="{{route.path}}",
23
23
  name="{{route.name}}",
24
+ meta = {{route.meta}},
24
25
  {{ render_fn_arg(route.main_fn_name()) |trim}}
25
26
  {{ render_children_arg(route.children) |trim}}
26
27
  ),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: instaui
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: insta-ui is a Python-based UI library for rapidly building user interfaces.
5
5
  License: MIT
6
6
  Author: CrystalWindSnake
@@ -28,7 +28,7 @@ instaui/components/html/span.py,sha256=kPqXHckL0YRWzV84ze4mAcKZPbmvalqDFtiwez_Lb
28
28
  instaui/components/html/ul.py,sha256=YbP2kH0Utlwr194uvVlCNQk1Xfl-5O24nVsDHSM0dqg,545
29
29
  instaui/components/match.py,sha256=B3wV1h-SkvYnX8RiMObdM2tfJb8nW2gjFxXQvNeZWWM,2774
30
30
  instaui/components/row.py,sha256=dvLbVmXFgigBZo1OKK6fFyJdrYHPms5-EZ11PVPD23I,388
31
- instaui/components/slot.py,sha256=M_hmeje3EGv2r_GmcjW1y6qdpiEysaGjjTi6K-YtDM4,2353
31
+ instaui/components/slot.py,sha256=RT0eU7wH7ffFDkl5ucfrNXB1nbsKDq688Hp920TZaoo,2287
32
32
  instaui/components/transition_group.py,sha256=H9zx9NTlCoQnBArWfmxmh7CMKb5hZn8vKrFe4OFxPrE,201
33
33
  instaui/components/value_element.py,sha256=Y10W4Hus-k-Og2ft2noBdVqF_Hq3x54vFdVvi1Tlf_I,1236
34
34
  instaui/components/vfor.py,sha256=hPkTk8sBVXRodmIu-9aXugrxK-AlexkiG3mP1KmYbXQ,4015
@@ -76,15 +76,15 @@ instaui/settings/__settings.py,sha256=DWzRvs9bBqjoNA2MvGAyz3GRrSV8H6lMLF1H3iJyoy
76
76
  instaui/skip.py,sha256=uqhqusgeChVoivKFMoZd-XePYrlSoLvUzRZDBcUgFmA,149
77
77
  instaui/spa_router/__init__.py,sha256=DGSf0YD6wZFj22kmPSyJWUmm_Lx3_YFg32iOa096T7Y,519
78
78
  instaui/spa_router/_components.py,sha256=vPo4JuRtbD_5ll0LkGwU1p8l_pxNfCSdFLDzMXsoEpw,896
79
- instaui/spa_router/_file_base_utils.py,sha256=ddhkLVHuhxWsgLhOa62oxaQ-1swZzoTE630Ux6INsLs,8506
79
+ instaui/spa_router/_file_base_utils.py,sha256=jcT9QoNu_ILhoI3JYhEA2JvINOg3PgWFa0d0IgysAa8,8697
80
80
  instaui/spa_router/_functions.py,sha256=j0ga2dq1q5JdPiUtOUS9KaRyvjm0Kmgf_HXYVVLcqvo,3226
81
81
  instaui/spa_router/_install.py,sha256=X9p7wtuGxo6B5F47UTY4ndOSRzENXkoK1XdkNo3F_YA,291
82
- instaui/spa_router/_route_model.py,sha256=4O8jasS-uIZncmvNCF4KDKQjDOWdZAWn_b_JRYn88R0,4834
82
+ instaui/spa_router/_route_model.py,sha256=Vua-xnk2AgHwTz4jBiPSL_3QOLKzX3cFCUDlJHE_mxY,4056
83
83
  instaui/spa_router/_router_box.py,sha256=Ez0vWWEYH_FHuFDvcAVhhfrlMRnDpT0_7tjmMZRMWZg,1163
84
84
  instaui/spa_router/_router_output.py,sha256=Nc6N8yO_9IrUbaYbPZMkOX_9VlwBKzyXMahaPp5GFGg,528
85
85
  instaui/spa_router/_router_param_var.py,sha256=KCy54xBZxGMqLO3Zlbzr6XV8ts-M6jCOKunL2gz5IUc,1455
86
86
  instaui/spa_router/_types.py,sha256=KuGuv5C6qivwllfdmV5qrvM0S_GWJ6u8OOTkCNmJImU,81
87
- instaui/spa_router/templates/page_routes,sha256=vX9OWoonvo6BP1pDWZeOPOsfzx1hIAADI46zomDgtGw,1323
87
+ instaui/spa_router/templates/page_routes,sha256=8VjM_8f6pjFb01QbU9z5HNqpcNRdCiX3X0OqNHLq8fo,1355
88
88
  instaui/static/insta-ui.css,sha256=B0xrNK9qVoRwRXhnTT8OascdHFeUk7vtfr7VhoA23_Y,297
89
89
  instaui/static/insta-ui.esm-browser.prod.js,sha256=gz3EFnwRRXx3F1t4Fp4fikkr0kjAWZ1xICdBuOnslGw,104366
90
90
  instaui/static/insta-ui.iife.js,sha256=JhloLLlMG3D7s6LTpcV9K7f42khfd8ZjzUl1uMR2DEY,71856
@@ -146,7 +146,7 @@ instaui/watch/vue_watch.py,sha256=n6yVt2ruKCjx-ZnIb29ytN9ugDas1JpUBOJeQ_FSYAA,15
146
146
  instaui/watch/web_watch.py,sha256=Gl0AZ9ji_A7tAoqsvyHmBOAYaX1CHxowVONlZKy8nd8,3763
147
147
  instaui/zero/__init__.py,sha256=N0LuRUAcaurxHSspcEDuwZg62W2S3qL4VtrMKxOivBE,49
148
148
  instaui/zero/scope.py,sha256=i4RqD1doMvyrAwQY3NpdPbMaIGbZE2crV3VZyj1k0VA,204
149
- instaui-0.1.0.dist-info/LICENSE,sha256=_JjnAWrikJ6qkwT7PazeFNRlcIu8q_RH3mYcHTxEF5c,1094
150
- instaui-0.1.0.dist-info/METADATA,sha256=tV2oibtubxE0YIEyzkpscRXo8VpbFTVI7LrlwEeYOWU,3474
151
- instaui-0.1.0.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
152
- instaui-0.1.0.dist-info/RECORD,,
149
+ instaui-0.1.1.dist-info/LICENSE,sha256=_JjnAWrikJ6qkwT7PazeFNRlcIu8q_RH3mYcHTxEF5c,1094
150
+ instaui-0.1.1.dist-info/METADATA,sha256=6M12PNmMvDs2Gv4vzBoluCXls_EejCvohpPfkYbx8Pw,3474
151
+ instaui-0.1.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
152
+ instaui-0.1.1.dist-info/RECORD,,