reactpy 2.0.0b4__py3-none-any.whl → 2.0.0b6__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.
- reactpy/__init__.py +3 -2
- reactpy/_console/rewrite_props.py +2 -2
- reactpy/_html.py +11 -9
- reactpy/_option.py +2 -1
- reactpy/config.py +2 -2
- reactpy/core/_life_cycle_hook.py +12 -10
- reactpy/core/_thread_local.py +2 -1
- reactpy/core/component.py +4 -38
- reactpy/core/events.py +61 -36
- reactpy/core/hooks.py +25 -35
- reactpy/core/layout.py +193 -201
- reactpy/core/serve.py +17 -22
- reactpy/core/vdom.py +9 -12
- reactpy/executors/asgi/__init__.py +9 -4
- reactpy/executors/asgi/middleware.py +1 -2
- reactpy/executors/asgi/pyscript.py +3 -7
- reactpy/executors/asgi/standalone.py +4 -6
- reactpy/executors/asgi/types.py +2 -2
- reactpy/pyscript/components.py +3 -3
- reactpy/pyscript/utils.py +49 -46
- reactpy/reactjs/__init__.py +353 -0
- reactpy/reactjs/module.py +203 -0
- reactpy/reactjs/types.py +7 -0
- reactpy/reactjs/utils.py +183 -0
- reactpy/static/index-h31022cd.js +5 -0
- reactpy/static/index-h31022cd.js.map +11 -0
- reactpy/static/index-sbddj6ms.js +5 -0
- reactpy/static/index-sbddj6ms.js.map +10 -0
- reactpy/static/index-y71bxs88.js +5 -0
- reactpy/static/index-y71bxs88.js.map +10 -0
- reactpy/static/index.js +2 -2
- reactpy/static/index.js.map +6 -10
- reactpy/static/react-dom.js +4 -0
- reactpy/static/react-dom.js.map +11 -0
- reactpy/static/react-jsx-runtime.js +4 -0
- reactpy/static/react-jsx-runtime.js.map +9 -0
- reactpy/static/react.js +4 -0
- reactpy/static/react.js.map +10 -0
- reactpy/testing/backend.py +6 -5
- reactpy/testing/common.py +3 -5
- reactpy/testing/display.py +2 -1
- reactpy/testing/logs.py +1 -1
- reactpy/transforms.py +2 -2
- reactpy/types.py +117 -58
- reactpy/utils.py +8 -8
- reactpy/web/__init__.py +0 -6
- reactpy/web/module.py +37 -470
- reactpy/web/utils.py +2 -158
- reactpy/widgets.py +2 -2
- {reactpy-2.0.0b4.dist-info → reactpy-2.0.0b6.dist-info}/METADATA +4 -7
- {reactpy-2.0.0b4.dist-info → reactpy-2.0.0b6.dist-info}/RECORD +54 -39
- reactpy/web/templates/react.js +0 -61
- {reactpy-2.0.0b4.dist-info → reactpy-2.0.0b6.dist-info}/WHEEL +0 -0
- {reactpy-2.0.0b4.dist-info → reactpy-2.0.0b6.dist-info}/entry_points.txt +0 -0
- {reactpy-2.0.0b4.dist-info → reactpy-2.0.0b6.dist-info}/licenses/LICENSE +0 -0
reactpy/web/module.py
CHANGED
|
@@ -1,281 +1,44 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import filecmp
|
|
4
|
-
import logging
|
|
5
|
-
import shutil
|
|
6
|
-
from dataclasses import dataclass
|
|
7
3
|
from pathlib import Path
|
|
8
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, overload
|
|
9
5
|
|
|
10
6
|
from reactpy._warnings import warn
|
|
11
|
-
from reactpy.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
module_name_suffix,
|
|
16
|
-
resolve_module_exports_from_file,
|
|
17
|
-
resolve_module_exports_from_url,
|
|
7
|
+
from reactpy.reactjs.types import (
|
|
8
|
+
NAME_SOURCE,
|
|
9
|
+
URL_SOURCE,
|
|
10
|
+
SourceType,
|
|
18
11
|
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
NAME_SOURCE
|
|
25
|
-
""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
""
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
_STRING_WEB_MODULE_CACHE: dict[str, WebModule] = {}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@overload
|
|
37
|
-
def reactjs_component_from_url(
|
|
38
|
-
url: str,
|
|
39
|
-
import_names: str,
|
|
40
|
-
fallback: Any | None = ...,
|
|
41
|
-
resolve_imports: bool | None = ...,
|
|
42
|
-
resolve_imports_depth: int = ...,
|
|
43
|
-
unmount_before_update: bool = ...,
|
|
44
|
-
allow_children: bool = ...,
|
|
45
|
-
) -> VdomConstructor: ...
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
@overload
|
|
49
|
-
def reactjs_component_from_url(
|
|
50
|
-
url: str,
|
|
51
|
-
import_names: list[str] | tuple[str, ...],
|
|
52
|
-
fallback: Any | None = ...,
|
|
53
|
-
resolve_imports: bool | None = ...,
|
|
54
|
-
resolve_imports_depth: int = ...,
|
|
55
|
-
unmount_before_update: bool = ...,
|
|
56
|
-
allow_children: bool = ...,
|
|
57
|
-
) -> list[VdomConstructor]: ...
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def reactjs_component_from_url(
|
|
61
|
-
url: str,
|
|
62
|
-
import_names: str | list[str] | tuple[str, ...],
|
|
63
|
-
fallback: Any | None = None,
|
|
64
|
-
resolve_imports: bool | None = None,
|
|
65
|
-
resolve_imports_depth: int = 5,
|
|
66
|
-
unmount_before_update: bool = False,
|
|
67
|
-
allow_children: bool = True,
|
|
68
|
-
) -> VdomConstructor | list[VdomConstructor]:
|
|
69
|
-
"""Import a component from a URL.
|
|
70
|
-
|
|
71
|
-
Parameters:
|
|
72
|
-
url:
|
|
73
|
-
The URL to import the component from.
|
|
74
|
-
import_names:
|
|
75
|
-
One or more component names to import. If given as a string, a single component
|
|
76
|
-
will be returned. If a list is given, then a list of components will be
|
|
77
|
-
returned.
|
|
78
|
-
fallback:
|
|
79
|
-
What to temporarily display while the module is being loaded.
|
|
80
|
-
resolve_imports:
|
|
81
|
-
Whether to try and find all the named imports of this module.
|
|
82
|
-
resolve_imports_depth:
|
|
83
|
-
How deeply to search for those imports.
|
|
84
|
-
unmount_before_update:
|
|
85
|
-
Cause the component to be unmounted before each update. This option should
|
|
86
|
-
only be used if the imported package fails to re-render when props change.
|
|
87
|
-
Using this option has negative performance consequences since all DOM
|
|
88
|
-
elements must be changed on each render. See :issue:`461` for more info.
|
|
89
|
-
allow_children:
|
|
90
|
-
Whether or not these components can have children.
|
|
91
|
-
"""
|
|
92
|
-
key = f"{url}{resolve_imports}{resolve_imports_depth}{unmount_before_update}"
|
|
93
|
-
if key in _URL_WEB_MODULE_CACHE:
|
|
94
|
-
module = _URL_WEB_MODULE_CACHE[key]
|
|
95
|
-
else:
|
|
96
|
-
module = _module_from_url(
|
|
97
|
-
url,
|
|
98
|
-
fallback=fallback,
|
|
99
|
-
resolve_imports=resolve_imports,
|
|
100
|
-
resolve_imports_depth=resolve_imports_depth,
|
|
101
|
-
unmount_before_update=unmount_before_update,
|
|
102
|
-
)
|
|
103
|
-
_URL_WEB_MODULE_CACHE[key] = module
|
|
104
|
-
return _vdom_from_web_module(module, import_names, fallback, allow_children)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@overload
|
|
108
|
-
def reactjs_component_from_file(
|
|
109
|
-
name: str,
|
|
110
|
-
file: str | Path,
|
|
111
|
-
import_names: str,
|
|
112
|
-
fallback: Any | None = ...,
|
|
113
|
-
resolve_imports: bool | None = ...,
|
|
114
|
-
resolve_imports_depth: int = ...,
|
|
115
|
-
unmount_before_update: bool = ...,
|
|
116
|
-
symlink: bool = ...,
|
|
117
|
-
allow_children: bool = ...,
|
|
118
|
-
) -> VdomConstructor: ...
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@overload
|
|
122
|
-
def reactjs_component_from_file(
|
|
123
|
-
name: str,
|
|
124
|
-
file: str | Path,
|
|
125
|
-
import_names: list[str] | tuple[str, ...],
|
|
126
|
-
fallback: Any | None = ...,
|
|
127
|
-
resolve_imports: bool | None = ...,
|
|
128
|
-
resolve_imports_depth: int = ...,
|
|
129
|
-
unmount_before_update: bool = ...,
|
|
130
|
-
symlink: bool = ...,
|
|
131
|
-
allow_children: bool = ...,
|
|
132
|
-
) -> list[VdomConstructor]: ...
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def reactjs_component_from_file(
|
|
136
|
-
name: str,
|
|
137
|
-
file: str | Path,
|
|
138
|
-
import_names: str | list[str] | tuple[str, ...],
|
|
139
|
-
fallback: Any | None = None,
|
|
140
|
-
resolve_imports: bool | None = None,
|
|
141
|
-
resolve_imports_depth: int = 5,
|
|
142
|
-
unmount_before_update: bool = False,
|
|
143
|
-
symlink: bool = False,
|
|
144
|
-
allow_children: bool = True,
|
|
145
|
-
) -> VdomConstructor | list[VdomConstructor]:
|
|
146
|
-
"""Import a component from a file.
|
|
147
|
-
|
|
148
|
-
Parameters:
|
|
149
|
-
name:
|
|
150
|
-
The name of the package
|
|
151
|
-
file:
|
|
152
|
-
The file from which the content of the web module will be created.
|
|
153
|
-
import_names:
|
|
154
|
-
One or more component names to import. If given as a string, a single component
|
|
155
|
-
will be returned. If a list is given, then a list of components will be
|
|
156
|
-
returned.
|
|
157
|
-
fallback:
|
|
158
|
-
What to temporarily display while the module is being loaded.
|
|
159
|
-
resolve_imports:
|
|
160
|
-
Whether to try and find all the named imports of this module.
|
|
161
|
-
resolve_imports_depth:
|
|
162
|
-
How deeply to search for those imports.
|
|
163
|
-
unmount_before_update:
|
|
164
|
-
Cause the component to be unmounted before each update. This option should
|
|
165
|
-
only be used if the imported package fails to re-render when props change.
|
|
166
|
-
Using this option has negative performance consequences since all DOM
|
|
167
|
-
elements must be changed on each render. See :issue:`461` for more info.
|
|
168
|
-
symlink:
|
|
169
|
-
Whether the web module should be saved as a symlink to the given ``file``.
|
|
170
|
-
allow_children:
|
|
171
|
-
Whether or not these components can have children.
|
|
172
|
-
"""
|
|
173
|
-
key = f"{name}{resolve_imports}{resolve_imports_depth}{unmount_before_update}"
|
|
174
|
-
if key in _FILE_WEB_MODULE_CACHE:
|
|
175
|
-
module = _FILE_WEB_MODULE_CACHE[key]
|
|
176
|
-
else:
|
|
177
|
-
module = _module_from_file(
|
|
178
|
-
name,
|
|
179
|
-
file,
|
|
180
|
-
fallback=fallback,
|
|
181
|
-
resolve_imports=resolve_imports,
|
|
182
|
-
resolve_imports_depth=resolve_imports_depth,
|
|
183
|
-
unmount_before_update=unmount_before_update,
|
|
184
|
-
symlink=symlink,
|
|
185
|
-
)
|
|
186
|
-
_FILE_WEB_MODULE_CACHE[key] = module
|
|
187
|
-
return _vdom_from_web_module(module, import_names, fallback, allow_children)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
@overload
|
|
191
|
-
def reactjs_component_from_string(
|
|
192
|
-
name: str,
|
|
193
|
-
content: str,
|
|
194
|
-
import_names: str,
|
|
195
|
-
fallback: Any | None = ...,
|
|
196
|
-
resolve_imports: bool | None = ...,
|
|
197
|
-
resolve_imports_depth: int = ...,
|
|
198
|
-
unmount_before_update: bool = ...,
|
|
199
|
-
allow_children: bool = ...,
|
|
200
|
-
) -> VdomConstructor: ...
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
@overload
|
|
204
|
-
def reactjs_component_from_string(
|
|
205
|
-
name: str,
|
|
206
|
-
content: str,
|
|
207
|
-
import_names: list[str] | tuple[str, ...],
|
|
208
|
-
fallback: Any | None = ...,
|
|
209
|
-
resolve_imports: bool | None = ...,
|
|
210
|
-
resolve_imports_depth: int = ...,
|
|
211
|
-
unmount_before_update: bool = ...,
|
|
212
|
-
allow_children: bool = ...,
|
|
213
|
-
) -> list[VdomConstructor]: ...
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
def reactjs_component_from_string(
|
|
217
|
-
name: str,
|
|
218
|
-
content: str,
|
|
219
|
-
import_names: str | list[str] | tuple[str, ...],
|
|
220
|
-
fallback: Any | None = None,
|
|
221
|
-
resolve_imports: bool | None = None,
|
|
222
|
-
resolve_imports_depth: int = 5,
|
|
223
|
-
unmount_before_update: bool = False,
|
|
224
|
-
allow_children: bool = True,
|
|
225
|
-
) -> VdomConstructor | list[VdomConstructor]:
|
|
226
|
-
"""Import a component from a string.
|
|
227
|
-
|
|
228
|
-
Parameters:
|
|
229
|
-
name:
|
|
230
|
-
The name of the package
|
|
231
|
-
content:
|
|
232
|
-
The contents of the web module
|
|
233
|
-
import_names:
|
|
234
|
-
One or more component names to import. If given as a string, a single component
|
|
235
|
-
will be returned. If a list is given, then a list of components will be
|
|
236
|
-
returned.
|
|
237
|
-
fallback:
|
|
238
|
-
What to temporarily display while the module is being loaded.
|
|
239
|
-
resolve_imports:
|
|
240
|
-
Whether to try and find all the named imports of this module.
|
|
241
|
-
resolve_imports_depth:
|
|
242
|
-
How deeply to search for those imports.
|
|
243
|
-
unmount_before_update:
|
|
244
|
-
Cause the component to be unmounted before each update. This option should
|
|
245
|
-
only be used if the imported package fails to re-render when props change.
|
|
246
|
-
Using this option has negative performance consequences since all DOM
|
|
247
|
-
elements must be changed on each render. See :issue:`461` for more info.
|
|
248
|
-
allow_children:
|
|
249
|
-
Whether or not these components can have children.
|
|
250
|
-
"""
|
|
251
|
-
key = f"{name}{resolve_imports}{resolve_imports_depth}{unmount_before_update}"
|
|
252
|
-
if key in _STRING_WEB_MODULE_CACHE:
|
|
253
|
-
module = _STRING_WEB_MODULE_CACHE[key]
|
|
254
|
-
else:
|
|
255
|
-
module = _module_from_string(
|
|
256
|
-
name,
|
|
257
|
-
content,
|
|
258
|
-
fallback=fallback,
|
|
259
|
-
resolve_imports=resolve_imports,
|
|
260
|
-
resolve_imports_depth=resolve_imports_depth,
|
|
261
|
-
unmount_before_update=unmount_before_update,
|
|
262
|
-
)
|
|
263
|
-
_STRING_WEB_MODULE_CACHE[key] = module
|
|
264
|
-
return _vdom_from_web_module(module, import_names, fallback, allow_children)
|
|
12
|
+
from reactpy.types import JavaScriptModule as WebModule
|
|
13
|
+
from reactpy.types import VdomConstructor
|
|
14
|
+
|
|
15
|
+
# Re-export for backward compatibility
|
|
16
|
+
__all__ = [
|
|
17
|
+
"NAME_SOURCE",
|
|
18
|
+
"URL_SOURCE",
|
|
19
|
+
"SourceType",
|
|
20
|
+
"WebModule",
|
|
21
|
+
"export",
|
|
22
|
+
"module_from_file",
|
|
23
|
+
"module_from_string",
|
|
24
|
+
"module_from_url",
|
|
25
|
+
]
|
|
265
26
|
|
|
266
27
|
|
|
267
28
|
def module_from_url(
|
|
268
29
|
url: str,
|
|
269
30
|
fallback: Any | None = None,
|
|
270
|
-
resolve_exports: bool
|
|
31
|
+
resolve_exports: bool = False,
|
|
271
32
|
resolve_exports_depth: int = 5,
|
|
272
33
|
unmount_before_update: bool = False,
|
|
273
34
|
) -> WebModule: # pragma: no cover
|
|
274
35
|
warn(
|
|
275
|
-
"module_from_url is deprecated, use
|
|
36
|
+
"module_from_url is deprecated, use component_from_url instead",
|
|
276
37
|
DeprecationWarning,
|
|
277
38
|
)
|
|
278
|
-
|
|
39
|
+
from reactpy.reactjs.module import url_to_module
|
|
40
|
+
|
|
41
|
+
return url_to_module(
|
|
279
42
|
url,
|
|
280
43
|
fallback=fallback,
|
|
281
44
|
resolve_imports=resolve_exports,
|
|
@@ -288,16 +51,18 @@ def module_from_file(
|
|
|
288
51
|
name: str,
|
|
289
52
|
file: str | Path,
|
|
290
53
|
fallback: Any | None = None,
|
|
291
|
-
resolve_exports: bool
|
|
54
|
+
resolve_exports: bool = False,
|
|
292
55
|
resolve_exports_depth: int = 5,
|
|
293
56
|
unmount_before_update: bool = False,
|
|
294
57
|
symlink: bool = False,
|
|
295
58
|
) -> WebModule: # pragma: no cover
|
|
296
59
|
warn(
|
|
297
|
-
"module_from_file is deprecated, use
|
|
60
|
+
"module_from_file is deprecated, use component_from_file instead",
|
|
298
61
|
DeprecationWarning,
|
|
299
62
|
)
|
|
300
|
-
|
|
63
|
+
from reactpy.reactjs.module import file_to_module
|
|
64
|
+
|
|
65
|
+
return file_to_module(
|
|
301
66
|
name,
|
|
302
67
|
file,
|
|
303
68
|
fallback=fallback,
|
|
@@ -312,15 +77,17 @@ def module_from_string(
|
|
|
312
77
|
name: str,
|
|
313
78
|
content: str,
|
|
314
79
|
fallback: Any | None = None,
|
|
315
|
-
resolve_exports: bool
|
|
80
|
+
resolve_exports: bool = False,
|
|
316
81
|
resolve_exports_depth: int = 5,
|
|
317
82
|
unmount_before_update: bool = False,
|
|
318
83
|
) -> WebModule: # pragma: no cover
|
|
319
84
|
warn(
|
|
320
|
-
"module_from_string is deprecated, use
|
|
85
|
+
"module_from_string is deprecated, use component_from_string instead",
|
|
321
86
|
DeprecationWarning,
|
|
322
87
|
)
|
|
323
|
-
|
|
88
|
+
from reactpy.reactjs.module import string_to_module
|
|
89
|
+
|
|
90
|
+
return string_to_module(
|
|
324
91
|
name,
|
|
325
92
|
content,
|
|
326
93
|
fallback=fallback,
|
|
@@ -330,142 +97,6 @@ def module_from_string(
|
|
|
330
97
|
)
|
|
331
98
|
|
|
332
99
|
|
|
333
|
-
def _module_from_url(
|
|
334
|
-
url: str,
|
|
335
|
-
fallback: Any | None = None,
|
|
336
|
-
resolve_imports: bool | None = None,
|
|
337
|
-
resolve_imports_depth: int = 5,
|
|
338
|
-
unmount_before_update: bool = False,
|
|
339
|
-
) -> WebModule:
|
|
340
|
-
return WebModule(
|
|
341
|
-
source=url,
|
|
342
|
-
source_type=URL_SOURCE,
|
|
343
|
-
default_fallback=fallback,
|
|
344
|
-
file=None,
|
|
345
|
-
export_names=(
|
|
346
|
-
resolve_module_exports_from_url(url, resolve_imports_depth)
|
|
347
|
-
if (
|
|
348
|
-
resolve_imports
|
|
349
|
-
if resolve_imports is not None
|
|
350
|
-
else REACTPY_DEBUG.current
|
|
351
|
-
)
|
|
352
|
-
else None
|
|
353
|
-
),
|
|
354
|
-
unmount_before_update=unmount_before_update,
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
def _module_from_file(
|
|
359
|
-
name: str,
|
|
360
|
-
file: str | Path,
|
|
361
|
-
fallback: Any | None = None,
|
|
362
|
-
resolve_imports: bool | None = None,
|
|
363
|
-
resolve_imports_depth: int = 5,
|
|
364
|
-
unmount_before_update: bool = False,
|
|
365
|
-
symlink: bool = False,
|
|
366
|
-
) -> WebModule:
|
|
367
|
-
name += module_name_suffix(name)
|
|
368
|
-
|
|
369
|
-
source_file = Path(file).resolve()
|
|
370
|
-
target_file = _web_module_path(name)
|
|
371
|
-
if not source_file.exists():
|
|
372
|
-
msg = f"Source file does not exist: {source_file}"
|
|
373
|
-
raise FileNotFoundError(msg)
|
|
374
|
-
|
|
375
|
-
if not target_file.exists():
|
|
376
|
-
_copy_file(target_file, source_file, symlink)
|
|
377
|
-
elif not _equal_files(source_file, target_file):
|
|
378
|
-
logger.info(
|
|
379
|
-
f"Existing web module {name!r} will "
|
|
380
|
-
f"be replaced with {target_file.resolve()}"
|
|
381
|
-
)
|
|
382
|
-
target_file.unlink()
|
|
383
|
-
_copy_file(target_file, source_file, symlink)
|
|
384
|
-
|
|
385
|
-
return WebModule(
|
|
386
|
-
source=name,
|
|
387
|
-
source_type=NAME_SOURCE,
|
|
388
|
-
default_fallback=fallback,
|
|
389
|
-
file=target_file,
|
|
390
|
-
export_names=(
|
|
391
|
-
resolve_module_exports_from_file(source_file, resolve_imports_depth)
|
|
392
|
-
if (
|
|
393
|
-
resolve_imports
|
|
394
|
-
if resolve_imports is not None
|
|
395
|
-
else REACTPY_DEBUG.current
|
|
396
|
-
)
|
|
397
|
-
else None
|
|
398
|
-
),
|
|
399
|
-
unmount_before_update=unmount_before_update,
|
|
400
|
-
)
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
def _equal_files(f1: Path, f2: Path) -> bool:
|
|
404
|
-
f1 = f1.resolve()
|
|
405
|
-
f2 = f2.resolve()
|
|
406
|
-
return (
|
|
407
|
-
(f1.is_symlink() or f2.is_symlink()) and (f1.resolve() == f2.resolve())
|
|
408
|
-
) or filecmp.cmp(str(f1), str(f2), shallow=False)
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
def _copy_file(target: Path, source: Path, symlink: bool) -> None:
|
|
412
|
-
target.parent.mkdir(parents=True, exist_ok=True)
|
|
413
|
-
if symlink:
|
|
414
|
-
target.symlink_to(source)
|
|
415
|
-
else:
|
|
416
|
-
shutil.copy(source, target)
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
def _module_from_string(
|
|
420
|
-
name: str,
|
|
421
|
-
content: str,
|
|
422
|
-
fallback: Any | None = None,
|
|
423
|
-
resolve_imports: bool | None = None,
|
|
424
|
-
resolve_imports_depth: int = 5,
|
|
425
|
-
unmount_before_update: bool = False,
|
|
426
|
-
) -> WebModule:
|
|
427
|
-
name += module_name_suffix(name)
|
|
428
|
-
|
|
429
|
-
target_file = _web_module_path(name)
|
|
430
|
-
|
|
431
|
-
if target_file.exists() and target_file.read_text(encoding="utf-8") != content:
|
|
432
|
-
logger.info(
|
|
433
|
-
f"Existing web module {name!r} will "
|
|
434
|
-
f"be replaced with {target_file.resolve()}"
|
|
435
|
-
)
|
|
436
|
-
target_file.unlink()
|
|
437
|
-
|
|
438
|
-
target_file.parent.mkdir(parents=True, exist_ok=True)
|
|
439
|
-
target_file.write_text(content)
|
|
440
|
-
|
|
441
|
-
return WebModule(
|
|
442
|
-
source=name,
|
|
443
|
-
source_type=NAME_SOURCE,
|
|
444
|
-
default_fallback=fallback,
|
|
445
|
-
file=target_file,
|
|
446
|
-
export_names=(
|
|
447
|
-
resolve_module_exports_from_file(target_file, resolve_imports_depth)
|
|
448
|
-
if (
|
|
449
|
-
resolve_imports
|
|
450
|
-
if resolve_imports is not None
|
|
451
|
-
else REACTPY_DEBUG.current
|
|
452
|
-
)
|
|
453
|
-
else None
|
|
454
|
-
),
|
|
455
|
-
unmount_before_update=unmount_before_update,
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
@dataclass(frozen=True)
|
|
460
|
-
class WebModule:
|
|
461
|
-
source: str
|
|
462
|
-
source_type: SourceType
|
|
463
|
-
default_fallback: Any | None
|
|
464
|
-
export_names: set[str] | None
|
|
465
|
-
file: Path | None
|
|
466
|
-
unmount_before_update: bool
|
|
467
|
-
|
|
468
|
-
|
|
469
100
|
@overload
|
|
470
101
|
def export(
|
|
471
102
|
web_module: WebModule,
|
|
@@ -491,73 +122,9 @@ def export(
|
|
|
491
122
|
allow_children: bool = True,
|
|
492
123
|
) -> VdomConstructor | list[VdomConstructor]: # pragma: no cover
|
|
493
124
|
warn(
|
|
494
|
-
"export is deprecated, use
|
|
125
|
+
"export is deprecated, use component_from_* functions instead",
|
|
495
126
|
DeprecationWarning,
|
|
496
127
|
)
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
def _vdom_from_web_module(
|
|
501
|
-
web_module: WebModule,
|
|
502
|
-
export_names: str | list[str] | tuple[str, ...],
|
|
503
|
-
fallback: Any | None = None,
|
|
504
|
-
allow_children: bool = True,
|
|
505
|
-
) -> VdomConstructor | list[VdomConstructor]:
|
|
506
|
-
"""Return one or more VDOM constructors from a :class:`WebModule`
|
|
507
|
-
|
|
508
|
-
Parameters:
|
|
509
|
-
export_names:
|
|
510
|
-
One or more names to export. If given as a string, a single component
|
|
511
|
-
will be returned. If a list is given, then a list of components will be
|
|
512
|
-
returned.
|
|
513
|
-
fallback:
|
|
514
|
-
What to temporarily display while the module is being loaded.
|
|
515
|
-
allow_children:
|
|
516
|
-
Whether or not these components can have children.
|
|
517
|
-
"""
|
|
518
|
-
if isinstance(export_names, str):
|
|
519
|
-
if (
|
|
520
|
-
web_module.export_names is not None
|
|
521
|
-
and export_names.split(".")[0] not in web_module.export_names
|
|
522
|
-
):
|
|
523
|
-
msg = f"{web_module.source!r} does not export {export_names!r}"
|
|
524
|
-
raise ValueError(msg)
|
|
525
|
-
return _make_export(web_module, export_names, fallback, allow_children)
|
|
526
|
-
else:
|
|
527
|
-
if web_module.export_names is not None:
|
|
528
|
-
missing = sorted(
|
|
529
|
-
{e.split(".")[0] for e in export_names}.difference(
|
|
530
|
-
web_module.export_names
|
|
531
|
-
)
|
|
532
|
-
)
|
|
533
|
-
if missing:
|
|
534
|
-
msg = f"{web_module.source!r} does not export {missing!r}"
|
|
535
|
-
raise ValueError(msg)
|
|
536
|
-
return [
|
|
537
|
-
_make_export(web_module, name, fallback, allow_children)
|
|
538
|
-
for name in export_names
|
|
539
|
-
]
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
def _make_export(
|
|
543
|
-
web_module: WebModule,
|
|
544
|
-
name: str,
|
|
545
|
-
fallback: Any | None,
|
|
546
|
-
allow_children: bool,
|
|
547
|
-
) -> VdomConstructor:
|
|
548
|
-
return Vdom(
|
|
549
|
-
name,
|
|
550
|
-
allow_children=allow_children,
|
|
551
|
-
import_source=ImportSourceDict(
|
|
552
|
-
source=web_module.source,
|
|
553
|
-
sourceType=web_module.source_type,
|
|
554
|
-
fallback=(fallback or web_module.default_fallback),
|
|
555
|
-
unmountBeforeUpdate=web_module.unmount_before_update,
|
|
556
|
-
),
|
|
557
|
-
)
|
|
558
|
-
|
|
128
|
+
from reactpy.reactjs.module import module_to_vdom
|
|
559
129
|
|
|
560
|
-
|
|
561
|
-
directory = REACTPY_WEB_MODULES_DIR.current
|
|
562
|
-
path = directory.joinpath(*name.split("/"))
|
|
563
|
-
return path.with_suffix(path.suffix)
|
|
130
|
+
return module_to_vdom(web_module, export_names, fallback, allow_children)
|