jac-client 0.2.3__py3-none-any.whl → 0.2.8__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.
- jac_client/examples/all-in-one/app.jac +494 -347
- jac_client/examples/all-in-one/assets/workers/worker.py +5 -0
- jac_client/examples/all-in-one/button.jac +1 -1
- jac_client/examples/all-in-one/components/CategoryFilter.jac +35 -0
- jac_client/examples/all-in-one/components/Header.jac +13 -0
- jac_client/examples/all-in-one/components/ProfitOverview.jac +50 -0
- jac_client/examples/all-in-one/components/Summary.jac +53 -0
- jac_client/examples/all-in-one/components/TransactionForm.jac +158 -0
- jac_client/examples/all-in-one/components/TransactionItem.jac +55 -0
- jac_client/examples/all-in-one/components/TransactionList.jac +37 -0
- jac_client/examples/all-in-one/components/button.jac +1 -1
- jac_client/examples/all-in-one/components/navigation.jac +132 -0
- jac_client/examples/all-in-one/constants/categories.jac +37 -0
- jac_client/examples/all-in-one/constants/clients.jac +13 -0
- jac_client/examples/all-in-one/context/BudgetContext.jac +28 -0
- jac_client/examples/all-in-one/hooks/useBudget.jac +116 -0
- jac_client/examples/all-in-one/hooks/useLocalStorage.jac +36 -0
- jac_client/examples/all-in-one/pages/BudgetPlanner.cl.jac +70 -0
- jac_client/examples/all-in-one/pages/BudgetPlanner.jac +126 -0
- jac_client/examples/all-in-one/pages/FeaturesTest.cl.jac +552 -0
- jac_client/examples/all-in-one/pages/FeaturesTest.jac +126 -0
- jac_client/examples/all-in-one/pages/LandingPage.jac +101 -0
- jac_client/examples/all-in-one/pages/loginPage.jac +132 -0
- jac_client/examples/all-in-one/pages/nestedDemo.jac +61 -0
- jac_client/examples/all-in-one/pages/notFound.jac +24 -0
- jac_client/examples/all-in-one/pages/signupPage.jac +133 -0
- jac_client/examples/all-in-one/utils/formatters.jac +52 -0
- jac_client/examples/asset-serving/css-with-image/{app.jac → src/app.jac} +4 -4
- jac_client/examples/asset-serving/image-asset/{app.jac → src/app.jac} +4 -4
- jac_client/examples/asset-serving/import-alias/{app.jac → src/app.jac} +5 -5
- jac_client/examples/basic/{app.jac → src/app.jac} +4 -4
- jac_client/examples/basic-auth/src/app.jac +371 -0
- jac_client/examples/basic-auth-with-router/{app.jac → src/app.jac} +28 -28
- jac_client/examples/basic-full-stack/{app.jac → src/app.jac} +166 -127
- jac_client/examples/css-styling/js-styling/{app.jac → src/app.jac} +7 -7
- jac_client/examples/css-styling/material-ui/{app.jac → src/app.jac} +6 -6
- jac_client/examples/css-styling/pure-css/{app.jac → src/app.jac} +7 -7
- jac_client/examples/css-styling/sass-example/{app.jac → src/app.jac} +7 -7
- jac_client/examples/css-styling/styled-components/{app.jac → src/app.jac} +6 -6
- jac_client/examples/css-styling/tailwind-example/{app.jac → src/app.jac} +7 -7
- jac_client/examples/full-stack-with-auth/{app.jac → src/app.jac} +47 -47
- jac_client/examples/little-x/{app.jac → src/app.jac} +27 -32
- jac_client/examples/little-x/src/submit-button.jac +16 -0
- jac_client/examples/nested-folders/nested-advance/{ButtonRoot.jac → src/ButtonRoot.jac} +1 -1
- jac_client/examples/nested-folders/nested-advance/{app.jac → src/app.jac} +1 -1
- jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/ButtonSecondL.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/Card.jac +1 -1
- jac_client/examples/nested-folders/nested-advance/{level1 → src/level1}/level2/ButtonThirdL.jac +1 -1
- jac_client/examples/nested-folders/nested-basic/{app.jac → src/app.jac} +2 -2
- jac_client/examples/nested-folders/nested-basic/{button.jac → src/button.jac} +1 -1
- jac_client/examples/nested-folders/nested-basic/{components → src/components}/button.jac +1 -1
- jac_client/examples/ts-support/src/app.jac +35 -0
- jac_client/examples/with-router/{app.jac → src/app.jac} +15 -15
- jac_client/plugin/cli.jac +504 -0
- jac_client/plugin/client.jac +45 -0
- jac_client/plugin/client_runtime.cl.jac +42 -0
- jac_client/plugin/impl/client.impl.jac +193 -0
- jac_client/plugin/impl/client_runtime.impl.jac +195 -0
- jac_client/plugin/impl/vite_client_bundle.impl.jac +72 -0
- jac_client/plugin/plugin_config.jac +195 -0
- jac_client/plugin/src/__init__.jac +20 -0
- jac_client/plugin/src/asset_processor.jac +33 -0
- jac_client/plugin/src/babel_processor.jac +18 -0
- jac_client/plugin/src/compiler.jac +67 -0
- jac_client/plugin/src/config_loader.jac +32 -0
- jac_client/plugin/src/impl/asset_processor.impl.jac +127 -0
- jac_client/plugin/src/impl/babel_processor.impl.jac +89 -0
- jac_client/plugin/src/impl/compiler.impl.jac +288 -0
- jac_client/plugin/src/impl/config_loader.impl.jac +119 -0
- jac_client/plugin/src/impl/import_processor.impl.jac +33 -0
- jac_client/plugin/src/impl/jac_to_js.impl.jac +41 -0
- jac_client/plugin/src/impl/package_installer.impl.jac +105 -0
- jac_client/plugin/src/impl/vite_bundler.impl.jac +626 -0
- jac_client/plugin/src/import_processor.jac +19 -0
- jac_client/plugin/src/jac_to_js.jac +35 -0
- jac_client/plugin/src/package_installer.jac +26 -0
- jac_client/plugin/src/vite_bundler.jac +44 -0
- jac_client/plugin/vite_client_bundle.jac +31 -0
- jac_client/tests/conftest.py +283 -0
- jac_client/tests/fixtures/basic-app/app.jac +2 -2
- jac_client/tests/fixtures/cl_file/app.cl.jac +2 -2
- jac_client/tests/fixtures/client_app_with_antd/app.jac +1 -1
- jac_client/tests/fixtures/js_import/app.jac +5 -5
- jac_client/tests/fixtures/spawn_test/app.jac +15 -18
- jac_client/tests/fixtures/with-ts/app.jac +35 -0
- jac_client/tests/test_cli.py +811 -0
- jac_client/tests/test_it.py +592 -97
- {jac_client-0.2.3.dist-info → jac_client-0.2.8.dist-info}/METADATA +41 -34
- jac_client-0.2.8.dist-info/RECORD +97 -0
- {jac_client-0.2.3.dist-info → jac_client-0.2.8.dist-info}/WHEEL +2 -1
- jac_client-0.2.8.dist-info/entry_points.txt +4 -0
- jac_client-0.2.8.dist-info/top_level.txt +1 -0
- jac_client/docs/README.md +0 -689
- jac_client/docs/advanced-state.md +0 -1265
- jac_client/docs/asset-serving/intro.md +0 -209
- jac_client/docs/assets/pipe_line-v2.svg +0 -32
- jac_client/docs/assets/pipe_line.png +0 -0
- jac_client/docs/file-system/app.jac.md +0 -121
- jac_client/docs/file-system/backend-frontend.md +0 -217
- jac_client/docs/file-system/intro.md +0 -72
- jac_client/docs/file-system/nested-imports.md +0 -348
- jac_client/docs/guide-example/intro.md +0 -115
- jac_client/docs/guide-example/step-01-setup.md +0 -270
- jac_client/docs/guide-example/step-02-components.md +0 -416
- jac_client/docs/guide-example/step-03-styling.md +0 -478
- jac_client/docs/guide-example/step-04-todo-ui.md +0 -477
- jac_client/docs/guide-example/step-05-local-state.md +0 -530
- jac_client/docs/guide-example/step-06-events.md +0 -749
- jac_client/docs/guide-example/step-07-effects.md +0 -468
- jac_client/docs/guide-example/step-08-walkers.md +0 -534
- jac_client/docs/guide-example/step-09-authentication.md +0 -586
- jac_client/docs/guide-example/step-10-routing.md +0 -539
- jac_client/docs/guide-example/step-11-final.md +0 -963
- jac_client/docs/imports.md +0 -1141
- jac_client/docs/lifecycle-hooks.md +0 -773
- jac_client/docs/routing.md +0 -659
- jac_client/docs/styling/intro.md +0 -249
- jac_client/docs/styling/js-styling.md +0 -367
- jac_client/docs/styling/material-ui.md +0 -341
- jac_client/docs/styling/pure-css.md +0 -299
- jac_client/docs/styling/sass.md +0 -403
- jac_client/docs/styling/styled-components.md +0 -395
- jac_client/docs/styling/tailwind.md +0 -298
- jac_client/examples/all-in-one/.babelrc +0 -9
- jac_client/examples/all-in-one/README.md +0 -16
- jac_client/examples/all-in-one/assets/burger.png +0 -0
- jac_client/examples/all-in-one/package.json +0 -29
- jac_client/examples/all-in-one/styles.css +0 -26
- jac_client/examples/all-in-one/vite.config.js +0 -28
- jac_client/examples/asset-serving/css-with-image/.babelrc +0 -9
- jac_client/examples/asset-serving/css-with-image/README.md +0 -91
- jac_client/examples/asset-serving/css-with-image/assets/burger.png +0 -0
- jac_client/examples/asset-serving/css-with-image/package.json +0 -28
- jac_client/examples/asset-serving/css-with-image/styles.css +0 -26
- jac_client/examples/asset-serving/css-with-image/vite.config.js +0 -28
- jac_client/examples/asset-serving/image-asset/.babelrc +0 -9
- jac_client/examples/asset-serving/image-asset/README.md +0 -119
- jac_client/examples/asset-serving/image-asset/assets/burger.png +0 -0
- jac_client/examples/asset-serving/image-asset/package.json +0 -28
- jac_client/examples/asset-serving/image-asset/styles.css +0 -26
- jac_client/examples/asset-serving/image-asset/vite.config.js +0 -28
- jac_client/examples/asset-serving/import-alias/.babelrc +0 -9
- jac_client/examples/asset-serving/import-alias/README.md +0 -83
- jac_client/examples/asset-serving/import-alias/assets/burger.png +0 -0
- jac_client/examples/asset-serving/import-alias/package.json +0 -28
- jac_client/examples/asset-serving/import-alias/vite.config.js +0 -28
- jac_client/examples/basic/.babelrc +0 -9
- jac_client/examples/basic/README.md +0 -16
- jac_client/examples/basic/package.json +0 -27
- jac_client/examples/basic/vite.config.js +0 -27
- jac_client/examples/basic-auth/.babelrc +0 -9
- jac_client/examples/basic-auth/README.md +0 -16
- jac_client/examples/basic-auth/app.jac +0 -308
- jac_client/examples/basic-auth/package.json +0 -27
- jac_client/examples/basic-auth/vite.config.js +0 -27
- jac_client/examples/basic-auth-with-router/.babelrc +0 -9
- jac_client/examples/basic-auth-with-router/README.md +0 -60
- jac_client/examples/basic-auth-with-router/package.json +0 -28
- jac_client/examples/basic-auth-with-router/vite.config.js +0 -27
- jac_client/examples/basic-full-stack/.babelrc +0 -9
- jac_client/examples/basic-full-stack/README.md +0 -18
- jac_client/examples/basic-full-stack/package.json +0 -28
- jac_client/examples/basic-full-stack/vite.config.js +0 -27
- jac_client/examples/css-styling/js-styling/.babelrc +0 -9
- jac_client/examples/css-styling/js-styling/README.md +0 -183
- jac_client/examples/css-styling/js-styling/package.json +0 -28
- jac_client/examples/css-styling/js-styling/styles.js +0 -100
- jac_client/examples/css-styling/js-styling/vite.config.js +0 -27
- jac_client/examples/css-styling/material-ui/.babelrc +0 -9
- jac_client/examples/css-styling/material-ui/README.md +0 -16
- jac_client/examples/css-styling/material-ui/package.json +0 -32
- jac_client/examples/css-styling/material-ui/vite.config.js +0 -27
- jac_client/examples/css-styling/pure-css/.babelrc +0 -9
- jac_client/examples/css-styling/pure-css/README.md +0 -16
- jac_client/examples/css-styling/pure-css/package.json +0 -28
- jac_client/examples/css-styling/pure-css/styles.css +0 -111
- jac_client/examples/css-styling/pure-css/vite.config.js +0 -27
- jac_client/examples/css-styling/sass-example/.babelrc +0 -9
- jac_client/examples/css-styling/sass-example/README.md +0 -16
- jac_client/examples/css-styling/sass-example/package.json +0 -29
- jac_client/examples/css-styling/sass-example/styles.scss +0 -153
- jac_client/examples/css-styling/sass-example/vite.config.js +0 -27
- jac_client/examples/css-styling/styled-components/.babelrc +0 -9
- jac_client/examples/css-styling/styled-components/README.md +0 -16
- jac_client/examples/css-styling/styled-components/package.json +0 -29
- jac_client/examples/css-styling/styled-components/styled.js +0 -90
- jac_client/examples/css-styling/styled-components/vite.config.js +0 -27
- jac_client/examples/css-styling/tailwind-example/.babelrc +0 -9
- jac_client/examples/css-styling/tailwind-example/README.md +0 -16
- jac_client/examples/css-styling/tailwind-example/global.css +0 -1
- jac_client/examples/css-styling/tailwind-example/package.json +0 -30
- jac_client/examples/css-styling/tailwind-example/vite.config.js +0 -29
- jac_client/examples/full-stack-with-auth/.babelrc +0 -9
- jac_client/examples/full-stack-with-auth/README.md +0 -16
- jac_client/examples/full-stack-with-auth/package.json +0 -28
- jac_client/examples/full-stack-with-auth/vite.config.js +0 -29
- jac_client/examples/little-x/package.json +0 -23
- jac_client/examples/little-x/submit-button.jac +0 -8
- jac_client/examples/nested-folders/nested-advance/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-advance/README.md +0 -77
- jac_client/examples/nested-folders/nested-advance/package.json +0 -29
- jac_client/examples/nested-folders/nested-advance/vite.config.js +0 -28
- jac_client/examples/nested-folders/nested-basic/.babelrc +0 -9
- jac_client/examples/nested-folders/nested-basic/README.md +0 -183
- jac_client/examples/nested-folders/nested-basic/app.js +0 -7
- jac_client/examples/nested-folders/nested-basic/package.json +0 -28
- jac_client/examples/nested-folders/nested-basic/vite.config.js +0 -27
- jac_client/examples/with-router/.babelrc +0 -9
- jac_client/examples/with-router/README.md +0 -17
- jac_client/examples/with-router/package.json +0 -28
- jac_client/examples/with-router/vite.config.js +0 -27
- jac_client/plugin/cli.py +0 -244
- jac_client/plugin/client.py +0 -152
- jac_client/plugin/client_runtime.jac +0 -234
- jac_client/plugin/vite_client_bundle.py +0 -503
- jac_client/tests/fixtures/js_import/utils.js +0 -21
- jac_client/tests/fixtures/package-lock.json +0 -329
- jac_client/tests/fixtures/package.json +0 -11
- jac_client/tests/test_asset_examples.py +0 -322
- jac_client/tests/test_cl.py +0 -530
- jac_client/tests/test_create_jac_app.py +0 -131
- jac_client/tests/test_nested_file.py +0 -374
- jac_client-0.2.3.dist-info/RECORD +0 -171
- jac_client-0.2.3.dist-info/entry_points.txt +0 -4
|
@@ -1,503 +0,0 @@
|
|
|
1
|
-
"""Vite-enhanced client bundle generation for Jac web front-ends."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import contextlib
|
|
6
|
-
import hashlib
|
|
7
|
-
import shutil
|
|
8
|
-
import subprocess
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
from types import ModuleType
|
|
11
|
-
from typing import TYPE_CHECKING, Any
|
|
12
|
-
|
|
13
|
-
from jaclang.runtimelib.client_bundle import (
|
|
14
|
-
ClientBundle,
|
|
15
|
-
ClientBundleBuilder,
|
|
16
|
-
ClientBundleError,
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
if TYPE_CHECKING:
|
|
20
|
-
from jaclang.compiler.codeinfo import ClientManifest
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class ViteClientBundleBuilder(ClientBundleBuilder):
|
|
24
|
-
"""Enhanced ClientBundleBuilder that uses Vite for optimized bundling."""
|
|
25
|
-
|
|
26
|
-
def __init__(
|
|
27
|
-
self,
|
|
28
|
-
runtime_path: Path | None = None,
|
|
29
|
-
vite_output_dir: Path | None = None,
|
|
30
|
-
vite_package_json: Path | None = None,
|
|
31
|
-
vite_minify: bool = False,
|
|
32
|
-
) -> None:
|
|
33
|
-
"""Initialize the Vite-enhanced bundle builder.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
runtime_path: Path to client runtime file
|
|
37
|
-
vite_output_dir: Output directory for Vite builds (defaults to temp/dist)
|
|
38
|
-
vite_package_json: Path to package.json for Vite (required)
|
|
39
|
-
vite_minify: Whether to enable minification in Vite build
|
|
40
|
-
"""
|
|
41
|
-
super().__init__(runtime_path)
|
|
42
|
-
self.vite_output_dir = vite_output_dir
|
|
43
|
-
self.vite_package_json = vite_package_json
|
|
44
|
-
self.vite_minify = vite_minify
|
|
45
|
-
|
|
46
|
-
def _process_vite_imports(
|
|
47
|
-
self, manifest: ClientManifest | None, module_path: Path
|
|
48
|
-
) -> list[Path | None]:
|
|
49
|
-
"""Process client imports for Vite bundling.
|
|
50
|
-
|
|
51
|
-
Only mark modules as bundled when we actually inline their code (.jac files we compile
|
|
52
|
-
and local .js files we embed). Bare package specifiers (e.g., "antd") are left as real
|
|
53
|
-
ES imports so Vite can resolve and bundle them.
|
|
54
|
-
"""
|
|
55
|
-
imported_js_modules: list[Path | None] = []
|
|
56
|
-
if manifest and manifest.imports:
|
|
57
|
-
for _, import_path in manifest.imports.items():
|
|
58
|
-
import_path_obj = Path(import_path)
|
|
59
|
-
|
|
60
|
-
if import_path_obj.suffix == ".js":
|
|
61
|
-
# Inline local JS files and mark as bundled
|
|
62
|
-
try:
|
|
63
|
-
imported_js_modules.append(import_path_obj)
|
|
64
|
-
except FileNotFoundError:
|
|
65
|
-
imported_js_modules.append(None)
|
|
66
|
-
|
|
67
|
-
elif import_path_obj.suffix == ".jac":
|
|
68
|
-
# Compile .jac imports and include transitive .jac imports
|
|
69
|
-
try:
|
|
70
|
-
imported_js_modules.append(import_path_obj)
|
|
71
|
-
except ClientBundleError:
|
|
72
|
-
imported_js_modules.append(None)
|
|
73
|
-
|
|
74
|
-
else:
|
|
75
|
-
# Non .jac/.js entries (likely bare specifiers) should be handled by Vite.
|
|
76
|
-
# Do not inline or mark as bundled so their import lines are preserved.
|
|
77
|
-
pass
|
|
78
|
-
|
|
79
|
-
return imported_js_modules
|
|
80
|
-
|
|
81
|
-
def _compile_dependencies_recursively(
|
|
82
|
-
self,
|
|
83
|
-
module_path: Path,
|
|
84
|
-
visited: set[Path] | None = None,
|
|
85
|
-
collected_exports: set[str] | None = None,
|
|
86
|
-
collected_globals: dict[str, Any] | None = None,
|
|
87
|
-
source_root: Path | None = None,
|
|
88
|
-
) -> None:
|
|
89
|
-
"""Recursively compile/copy .jac/.js imports to temp, skipping bundling.
|
|
90
|
-
|
|
91
|
-
Only prepares dependency JS artifacts for Vite by writing compiled JS (.jac)
|
|
92
|
-
or copying local JS (.js) into the temp directory. Bare specifiers are left
|
|
93
|
-
untouched for Vite to resolve.
|
|
94
|
-
|
|
95
|
-
Args:
|
|
96
|
-
module_path: Path to the module being compiled
|
|
97
|
-
visited: Set of already visited paths to avoid cycles
|
|
98
|
-
collected_exports: Set to accumulate exported symbols
|
|
99
|
-
collected_globals: Dict to accumulate global values
|
|
100
|
-
source_root: Root directory of the source files (for preserving folder structure)
|
|
101
|
-
"""
|
|
102
|
-
if visited is None:
|
|
103
|
-
visited = set()
|
|
104
|
-
if collected_exports is None:
|
|
105
|
-
collected_exports = set()
|
|
106
|
-
if collected_globals is None:
|
|
107
|
-
collected_globals = {}
|
|
108
|
-
|
|
109
|
-
module_path = module_path.resolve()
|
|
110
|
-
if module_path in visited:
|
|
111
|
-
return
|
|
112
|
-
visited.add(module_path)
|
|
113
|
-
|
|
114
|
-
# Set source_root on first call (root module's parent directory)
|
|
115
|
-
if source_root is None:
|
|
116
|
-
source_root = module_path.parent.resolve()
|
|
117
|
-
|
|
118
|
-
manifest = None
|
|
119
|
-
|
|
120
|
-
# Compile current module to JS and append registration
|
|
121
|
-
module_js, mod = self._compile_to_js(module_path)
|
|
122
|
-
manifest = mod.gen.client_manifest if mod else None
|
|
123
|
-
|
|
124
|
-
# Extract exports from manifest
|
|
125
|
-
exports_list = self._extract_client_exports(manifest)
|
|
126
|
-
collected_exports.update(exports_list)
|
|
127
|
-
|
|
128
|
-
# Build globals map using manifest.globals_values only for non-root
|
|
129
|
-
non_root_globals: dict[str, Any] = {}
|
|
130
|
-
if manifest:
|
|
131
|
-
for name in manifest.globals:
|
|
132
|
-
non_root_globals[name] = manifest.globals_values.get(name)
|
|
133
|
-
collected_globals.update(non_root_globals)
|
|
134
|
-
export_block = (
|
|
135
|
-
f"export {{ {', '.join(exports_list)} }};\n" if exports_list else ""
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
# inport jacJsx from client_runtime_utils.jac
|
|
139
|
-
jac_jsx_path = 'import {__jacJsx, __jacSpawn} from "@jac-client/utils";'
|
|
140
|
-
|
|
141
|
-
combined_js = f"{jac_jsx_path}\n{module_js}\n{export_block}"
|
|
142
|
-
if self.vite_package_json is not None:
|
|
143
|
-
# Preserve folder structure: calculate relative path from source_root
|
|
144
|
-
try:
|
|
145
|
-
relative_path = module_path.relative_to(source_root)
|
|
146
|
-
# Change extension from .jac to .js
|
|
147
|
-
output_path = (
|
|
148
|
-
self.vite_package_json.parent
|
|
149
|
-
/ "src"
|
|
150
|
-
/ relative_path.with_suffix(".js")
|
|
151
|
-
)
|
|
152
|
-
except ValueError:
|
|
153
|
-
# If file is outside source_root, fall back to just filename
|
|
154
|
-
output_path = (
|
|
155
|
-
self.vite_package_json.parent / "src" / f"{module_path.stem}.js"
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
# Ensure parent directories exist
|
|
159
|
-
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
160
|
-
output_path.write_text(combined_js, encoding="utf-8")
|
|
161
|
-
|
|
162
|
-
if not manifest or not manifest.imports:
|
|
163
|
-
return
|
|
164
|
-
|
|
165
|
-
for _name, import_path in manifest.imports.items():
|
|
166
|
-
path_obj = Path(import_path).resolve()
|
|
167
|
-
# Avoid re-processing
|
|
168
|
-
if path_obj in visited:
|
|
169
|
-
continue
|
|
170
|
-
if path_obj.suffix == ".jac":
|
|
171
|
-
# Recurse into transitive deps
|
|
172
|
-
self._compile_dependencies_recursively(
|
|
173
|
-
path_obj,
|
|
174
|
-
visited,
|
|
175
|
-
collected_exports=collected_exports,
|
|
176
|
-
collected_globals=collected_globals,
|
|
177
|
-
source_root=source_root,
|
|
178
|
-
)
|
|
179
|
-
elif path_obj.suffix == ".js":
|
|
180
|
-
try:
|
|
181
|
-
js_code = path_obj.read_text(encoding="utf-8")
|
|
182
|
-
if self.vite_package_json is not None:
|
|
183
|
-
# Preserve folder structure for .js files too
|
|
184
|
-
try:
|
|
185
|
-
relative_path = path_obj.relative_to(source_root)
|
|
186
|
-
output_path = (
|
|
187
|
-
self.vite_package_json.parent / "src" / relative_path
|
|
188
|
-
)
|
|
189
|
-
except ValueError:
|
|
190
|
-
# If file is outside source_root, fall back to just filename
|
|
191
|
-
output_path = (
|
|
192
|
-
self.vite_package_json.parent / "src" / path_obj.name
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
# Ensure parent directories exist
|
|
196
|
-
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
197
|
-
output_path.write_text(js_code, encoding="utf-8")
|
|
198
|
-
except FileNotFoundError:
|
|
199
|
-
pass
|
|
200
|
-
else:
|
|
201
|
-
# Bare specifiers or other assets handled by Vite
|
|
202
|
-
if self.vite_package_json is not None and path_obj.is_file():
|
|
203
|
-
# Preserve folder structure for other assets too
|
|
204
|
-
try:
|
|
205
|
-
relative_path = path_obj.relative_to(source_root)
|
|
206
|
-
output_path = (
|
|
207
|
-
self.vite_package_json.parent / "src" / relative_path
|
|
208
|
-
)
|
|
209
|
-
except ValueError:
|
|
210
|
-
# If file is outside source_root, fall back to just filename
|
|
211
|
-
output_path = (
|
|
212
|
-
self.vite_package_json.parent / "src" / path_obj.name
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
# Ensure parent directories exist
|
|
216
|
-
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
217
|
-
output_path.write_text(
|
|
218
|
-
path_obj.read_text(encoding="utf-8"), encoding="utf-8"
|
|
219
|
-
)
|
|
220
|
-
continue
|
|
221
|
-
|
|
222
|
-
def _compile_bundle(
|
|
223
|
-
self,
|
|
224
|
-
module: ModuleType,
|
|
225
|
-
module_path: Path,
|
|
226
|
-
) -> ClientBundle:
|
|
227
|
-
"""Override to use Vite bundling instead of simple concatenation."""
|
|
228
|
-
|
|
229
|
-
# Check if package.json exists before proceeding
|
|
230
|
-
if not self.vite_package_json or not self.vite_package_json.exists():
|
|
231
|
-
raise ClientBundleError(
|
|
232
|
-
"Vite package.json not found. Set vite_package_json when using ViteClientBundleBuilder"
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
# client_runtime for jac client utils
|
|
236
|
-
runtime_utils_path = self.runtime_path.parent / "client_runtime.jac"
|
|
237
|
-
runtimeutils_js, mod = self._compile_to_js(runtime_utils_path)
|
|
238
|
-
runtimeutils_manifest = mod.gen.client_manifest if mod else None
|
|
239
|
-
runtimeutils_exports_list = self._extract_client_exports(runtimeutils_manifest)
|
|
240
|
-
|
|
241
|
-
# Add React Router exports that are variable declarations (not functions)
|
|
242
|
-
# These need to be manually added since they're 'let' declarations, not 'def' functions
|
|
243
|
-
router_exports = [
|
|
244
|
-
"Router",
|
|
245
|
-
"Routes",
|
|
246
|
-
"Route",
|
|
247
|
-
"Link",
|
|
248
|
-
"Navigate",
|
|
249
|
-
"useNavigate",
|
|
250
|
-
"useLocation",
|
|
251
|
-
"useParams",
|
|
252
|
-
]
|
|
253
|
-
|
|
254
|
-
# Combine manifest exports with router exports
|
|
255
|
-
all_exports = sorted(set(runtimeutils_exports_list + router_exports))
|
|
256
|
-
|
|
257
|
-
export_block = (
|
|
258
|
-
f"export {{ {', '.join(all_exports)} }};\n" if all_exports else ""
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
combined_runtime_utils_js = f"{runtimeutils_js}\n{export_block}"
|
|
262
|
-
(self.vite_package_json.parent / "src" / "client_runtime.js").write_text(
|
|
263
|
-
combined_runtime_utils_js, encoding="utf-8"
|
|
264
|
-
)
|
|
265
|
-
|
|
266
|
-
# Get manifest from JacProgram first to check for imports
|
|
267
|
-
# Collect exports/globals across root and recursive deps
|
|
268
|
-
module_js, mod = self._compile_to_js(module_path)
|
|
269
|
-
module_manifest = mod.gen.client_manifest if mod else None
|
|
270
|
-
collected_exports: set[str] = set(self._extract_client_exports(module_manifest))
|
|
271
|
-
|
|
272
|
-
client_globals_map = self._extract_client_globals(module_manifest, module)
|
|
273
|
-
collected_globals: dict[str, Any] = dict(client_globals_map)
|
|
274
|
-
# Recursively prepare dependencies and accumulate symbols
|
|
275
|
-
self._compile_dependencies_recursively(
|
|
276
|
-
module_path,
|
|
277
|
-
collected_exports=collected_exports,
|
|
278
|
-
collected_globals=collected_globals,
|
|
279
|
-
)
|
|
280
|
-
|
|
281
|
-
# Copy assets from root assets/ folder to src/assets/ for @jac-client/assets alias
|
|
282
|
-
project_dir = self.vite_package_json.parent
|
|
283
|
-
root_assets_dir = project_dir / "assets"
|
|
284
|
-
src_assets_dir = project_dir / "src" / "assets"
|
|
285
|
-
if root_assets_dir.exists() and root_assets_dir.is_dir():
|
|
286
|
-
self._copy_asset_files(root_assets_dir, src_assets_dir)
|
|
287
|
-
|
|
288
|
-
client_exports = sorted(collected_exports)
|
|
289
|
-
client_globals_map = collected_globals
|
|
290
|
-
|
|
291
|
-
entry_file = self.vite_package_json.parent / "src" / "main.js"
|
|
292
|
-
|
|
293
|
-
entry_content = """import React from "react";
|
|
294
|
-
import { createRoot } from "react-dom/client";
|
|
295
|
-
import { app as App } from "./app.js";
|
|
296
|
-
|
|
297
|
-
const root = createRoot(document.getElementById("root"));
|
|
298
|
-
root.render(<App />);
|
|
299
|
-
"""
|
|
300
|
-
entry_file.write_text(entry_content, encoding="utf-8")
|
|
301
|
-
|
|
302
|
-
bundle_code, bundle_hash = self._bundle_with_vite(
|
|
303
|
-
module.__name__, client_exports
|
|
304
|
-
)
|
|
305
|
-
|
|
306
|
-
return ClientBundle(
|
|
307
|
-
module_name=module.__name__,
|
|
308
|
-
code=bundle_code,
|
|
309
|
-
client_functions=client_exports,
|
|
310
|
-
client_globals=list(client_globals_map.keys()),
|
|
311
|
-
hash=bundle_hash,
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
def _bundle_with_vite(
|
|
315
|
-
self, module_name: str, client_functions: list[str]
|
|
316
|
-
) -> tuple[str, str]:
|
|
317
|
-
"""Bundle JavaScript code using Vite for optimization.
|
|
318
|
-
|
|
319
|
-
Args:
|
|
320
|
-
module_name: Name of the module being bundled
|
|
321
|
-
client_functions: List of client function names
|
|
322
|
-
|
|
323
|
-
Returns:
|
|
324
|
-
Tuple of (bundle_code, bundle_hash)
|
|
325
|
-
|
|
326
|
-
Raises:
|
|
327
|
-
ClientBundleError: If Vite bundling fails
|
|
328
|
-
"""
|
|
329
|
-
if not self.vite_package_json or not self.vite_package_json.exists():
|
|
330
|
-
raise ClientBundleError(
|
|
331
|
-
"Vite package.json not found. Set vite_package_json when using ViteClientBundleBuilder"
|
|
332
|
-
)
|
|
333
|
-
|
|
334
|
-
# Create temp directory for Vite build
|
|
335
|
-
project_dir = self.vite_package_json.parent
|
|
336
|
-
src_dir = project_dir / "src"
|
|
337
|
-
src_dir.mkdir(exist_ok=True)
|
|
338
|
-
|
|
339
|
-
output_dir = self.vite_output_dir or src_dir / "dist" / "assets"
|
|
340
|
-
output_dir.mkdir(parents=True, exist_ok=True)
|
|
341
|
-
|
|
342
|
-
try:
|
|
343
|
-
# Run Vite build from project directory
|
|
344
|
-
# need to install packages you told in package.json inside here
|
|
345
|
-
# first compile the code
|
|
346
|
-
command = ["npm", "run", "compile"]
|
|
347
|
-
subprocess.run(
|
|
348
|
-
command, cwd=project_dir, check=True, capture_output=True, text=True
|
|
349
|
-
)
|
|
350
|
-
# Copy CSS and other asset files from src/ to build/ after Babel compilation
|
|
351
|
-
# Babel only transpiles JS, so we need to manually copy assets
|
|
352
|
-
self._copy_asset_files(project_dir / "src", project_dir / "build")
|
|
353
|
-
# then build the code
|
|
354
|
-
command = ["npm", "run", "build"]
|
|
355
|
-
subprocess.run(
|
|
356
|
-
command, cwd=project_dir, check=True, capture_output=True, text=True
|
|
357
|
-
)
|
|
358
|
-
except subprocess.CalledProcessError as e:
|
|
359
|
-
raise ClientBundleError(f"Vite build failed: {e.stderr}") from e
|
|
360
|
-
except FileNotFoundError:
|
|
361
|
-
raise ClientBundleError(
|
|
362
|
-
"npx or vite command not found. Ensure Node.js and npm are installed."
|
|
363
|
-
) from None
|
|
364
|
-
# Find the generated bundle file
|
|
365
|
-
bundle_file = self._find_vite_bundle(output_dir)
|
|
366
|
-
if not bundle_file:
|
|
367
|
-
raise ClientBundleError("Vite build completed but no bundle file found")
|
|
368
|
-
|
|
369
|
-
# Read the bundled code
|
|
370
|
-
bundle_code = bundle_file.read_text(encoding="utf-8")
|
|
371
|
-
bundle_hash = hashlib.sha256(bundle_code.encode("utf-8")).hexdigest()
|
|
372
|
-
|
|
373
|
-
return bundle_code, bundle_hash
|
|
374
|
-
|
|
375
|
-
def _generate_vite_config(self, entry_file: Path, output_dir: Path) -> str:
|
|
376
|
-
"""Generate Vite configuration for bundling."""
|
|
377
|
-
entry_name = entry_file.as_posix()
|
|
378
|
-
output_dir_name = output_dir.as_posix()
|
|
379
|
-
minify_setting = "true" if self.vite_minify else "false"
|
|
380
|
-
|
|
381
|
-
return f"""
|
|
382
|
-
import {{ defineConfig }} from 'vite';
|
|
383
|
-
import {{ resolve }} from 'path';
|
|
384
|
-
|
|
385
|
-
export default defineConfig({{
|
|
386
|
-
build: {{
|
|
387
|
-
outDir: '{output_dir_name}',
|
|
388
|
-
emptyOutDir: true,
|
|
389
|
-
rollupOptions: {{
|
|
390
|
-
input: {{
|
|
391
|
-
main: resolve(__dirname, '{entry_name}'),
|
|
392
|
-
}},
|
|
393
|
-
output: {{
|
|
394
|
-
entryFileNames: 'client.[hash].js',
|
|
395
|
-
format: 'iife',
|
|
396
|
-
name: 'JacClient',
|
|
397
|
-
}},
|
|
398
|
-
}},
|
|
399
|
-
minify: {minify_setting}, // Configurable minification
|
|
400
|
-
}},
|
|
401
|
-
resolve: {{
|
|
402
|
-
}}
|
|
403
|
-
}});
|
|
404
|
-
"""
|
|
405
|
-
|
|
406
|
-
def _copy_asset_files(self, src_dir: Path, build_dir: Path) -> None:
|
|
407
|
-
"""Copy CSS and other asset files from src/ to build/ directory recursively.
|
|
408
|
-
|
|
409
|
-
Babel only transpiles JavaScript files, so CSS and other assets need to be
|
|
410
|
-
manually copied to the build directory for Vite to resolve them.
|
|
411
|
-
This method recursively copies assets from subdirectories (e.g., src/assets/)
|
|
412
|
-
while preserving the directory structure.
|
|
413
|
-
"""
|
|
414
|
-
if not src_dir.exists():
|
|
415
|
-
return
|
|
416
|
-
|
|
417
|
-
# Ensure build directory exists
|
|
418
|
-
build_dir.mkdir(parents=True, exist_ok=True)
|
|
419
|
-
|
|
420
|
-
# Asset file extensions to copy
|
|
421
|
-
asset_extensions = {
|
|
422
|
-
".css",
|
|
423
|
-
".scss",
|
|
424
|
-
".sass",
|
|
425
|
-
".less",
|
|
426
|
-
".svg",
|
|
427
|
-
".png",
|
|
428
|
-
".jpg",
|
|
429
|
-
".jpeg",
|
|
430
|
-
".gif",
|
|
431
|
-
".webp",
|
|
432
|
-
".ico",
|
|
433
|
-
".woff",
|
|
434
|
-
".woff2",
|
|
435
|
-
".ttf",
|
|
436
|
-
".eot",
|
|
437
|
-
".otf",
|
|
438
|
-
".mp4",
|
|
439
|
-
".webm",
|
|
440
|
-
".mp3",
|
|
441
|
-
".wav",
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
def copy_recursive(
|
|
445
|
-
source: Path, destination: Path, base: Path | None = None
|
|
446
|
-
) -> None:
|
|
447
|
-
"""Recursively copy asset files from source to destination.
|
|
448
|
-
|
|
449
|
-
Args:
|
|
450
|
-
source: Source directory to copy from
|
|
451
|
-
destination: Destination directory to copy to
|
|
452
|
-
base: Base directory for calculating relative paths (defaults to source)
|
|
453
|
-
"""
|
|
454
|
-
if not source.exists():
|
|
455
|
-
return
|
|
456
|
-
|
|
457
|
-
if base is None:
|
|
458
|
-
base = source
|
|
459
|
-
|
|
460
|
-
for item in source.iterdir():
|
|
461
|
-
if item.is_file() and item.suffix.lower() in asset_extensions:
|
|
462
|
-
# Preserve relative path structure from base
|
|
463
|
-
relative_path = item.relative_to(base)
|
|
464
|
-
dest_file = destination / relative_path
|
|
465
|
-
dest_file.parent.mkdir(parents=True, exist_ok=True)
|
|
466
|
-
with contextlib.suppress(OSError, shutil.Error):
|
|
467
|
-
shutil.copy2(item, dest_file)
|
|
468
|
-
elif item.is_dir():
|
|
469
|
-
# Recursively process subdirectories
|
|
470
|
-
copy_recursive(item, destination, base)
|
|
471
|
-
|
|
472
|
-
# Copy files from src_dir root and recursively from subdirectories
|
|
473
|
-
copy_recursive(src_dir, build_dir)
|
|
474
|
-
|
|
475
|
-
def _find_vite_bundle(self, output_dir: Path) -> Path | None:
|
|
476
|
-
"""Find the generated Vite bundle file."""
|
|
477
|
-
for file in output_dir.glob("client.*.js"):
|
|
478
|
-
return file
|
|
479
|
-
return None
|
|
480
|
-
|
|
481
|
-
def _find_vite_css(self, output_dir: Path) -> Path | None:
|
|
482
|
-
"""Find the generated Vite CSS file."""
|
|
483
|
-
# Vite typically outputs CSS as main.css or with a hash
|
|
484
|
-
# Try main.css first (most common), then any .css file
|
|
485
|
-
css_file = output_dir / "main.css"
|
|
486
|
-
if css_file.exists():
|
|
487
|
-
return css_file
|
|
488
|
-
# Fallback: find any CSS file
|
|
489
|
-
for file in output_dir.glob("*.css"):
|
|
490
|
-
return file
|
|
491
|
-
return None
|
|
492
|
-
|
|
493
|
-
def cleanup_temp_dir(self) -> None:
|
|
494
|
-
"""Clean up the src directory and its contents."""
|
|
495
|
-
if not self.vite_package_json or not self.vite_package_json.exists():
|
|
496
|
-
return
|
|
497
|
-
|
|
498
|
-
project_dir = self.vite_package_json.parent
|
|
499
|
-
temp_dir = project_dir / "src"
|
|
500
|
-
|
|
501
|
-
if temp_dir.exists():
|
|
502
|
-
with contextlib.suppress(OSError, shutil.Error):
|
|
503
|
-
shutil.rmtree(temp_dir)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// JavaScript utility functions for testing JS imports in Jac
|
|
2
|
-
|
|
3
|
-
export function formatMessage(name) {
|
|
4
|
-
return `Hello, ${name}!`;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function calculateSum(a, b) {
|
|
8
|
-
return a + b;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const JS_CONSTANT = "Imported from JavaScript";
|
|
12
|
-
|
|
13
|
-
export class MessageFormatter {
|
|
14
|
-
constructor(prefix) {
|
|
15
|
-
this.prefix = prefix;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
format(text) {
|
|
19
|
-
return `${this.prefix}: ${text}`;
|
|
20
|
-
}
|
|
21
|
-
}
|