arcanajs 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/package.json +1 -1
  2. package/framework/cli/index.d.ts +0 -1
  3. package/framework/cli/index.js +0 -204
  4. package/framework/cli/templates.d.ts +0 -6
  5. package/framework/cli/templates.js +0 -44
  6. package/framework/cli/webpack.config.d.ts +0 -3
  7. package/framework/cli/webpack.config.js +0 -310
  8. package/framework/lib/client/index.d.ts +0 -59
  9. package/framework/lib/client/index.js +0 -97
  10. package/framework/lib/config/index.d.ts +0 -46
  11. package/framework/lib/config/index.js +0 -115
  12. package/framework/lib/global.d.ts +0 -58
  13. package/framework/lib/index.d.ts +0 -19
  14. package/framework/lib/index.js +0 -59
  15. package/framework/lib/server/ArcanaJSMiddleware.d.ts +0 -24
  16. package/framework/lib/server/ArcanaJSMiddleware.js +0 -114
  17. package/framework/lib/server/ArcanaJSServer.d.ts +0 -23
  18. package/framework/lib/server/ArcanaJSServer.js +0 -165
  19. package/framework/lib/server/ControllerBinder.d.ts +0 -4
  20. package/framework/lib/server/ControllerBinder.js +0 -32
  21. package/framework/lib/server/CsrfMiddleware.d.ts +0 -2
  22. package/framework/lib/server/CsrfMiddleware.js +0 -34
  23. package/framework/lib/server/DynamicRouter.d.ts +0 -2
  24. package/framework/lib/server/DynamicRouter.js +0 -50
  25. package/framework/lib/server/ResponseHandlerMiddleware.d.ts +0 -27
  26. package/framework/lib/server/ResponseHandlerMiddleware.js +0 -30
  27. package/framework/lib/server/Router.d.ts +0 -94
  28. package/framework/lib/server/Router.js +0 -203
  29. package/framework/lib/server/default-index.html +0 -12
  30. package/framework/lib/server.d.ts +0 -32
  31. package/framework/lib/server.js +0 -69
  32. package/framework/lib/shared/components/Body.d.ts +0 -6
  33. package/framework/lib/shared/components/Body.js +0 -8
  34. package/framework/lib/shared/components/Head.d.ts +0 -4
  35. package/framework/lib/shared/components/Head.js +0 -125
  36. package/framework/lib/shared/components/Link.d.ts +0 -7
  37. package/framework/lib/shared/components/Link.js +0 -27
  38. package/framework/lib/shared/components/NavLink.d.ts +0 -9
  39. package/framework/lib/shared/components/NavLink.js +0 -13
  40. package/framework/lib/shared/components/Page.d.ts +0 -6
  41. package/framework/lib/shared/components/Page.js +0 -10
  42. package/framework/lib/shared/context/HeadContext.d.ts +0 -6
  43. package/framework/lib/shared/context/HeadContext.js +0 -5
  44. package/framework/lib/shared/context/PageContext.d.ts +0 -1
  45. package/framework/lib/shared/context/PageContext.js +0 -5
  46. package/framework/lib/shared/context/RouterContext.d.ts +0 -15
  47. package/framework/lib/shared/context/RouterContext.js +0 -10
  48. package/framework/lib/shared/core/ArcanaJSApp.d.ts +0 -14
  49. package/framework/lib/shared/core/ArcanaJSApp.js +0 -142
  50. package/framework/lib/shared/hooks/useHead.d.ts +0 -1
  51. package/framework/lib/shared/hooks/useHead.js +0 -7
  52. package/framework/lib/shared/hooks/useLocation.d.ts +0 -5
  53. package/framework/lib/shared/hooks/useLocation.js +0 -13
  54. package/framework/lib/shared/hooks/usePage.d.ts +0 -1
  55. package/framework/lib/shared/hooks/usePage.js +0 -7
  56. package/framework/lib/shared/hooks/useParams.d.ts +0 -1
  57. package/framework/lib/shared/hooks/useParams.js +0 -13
  58. package/framework/lib/shared/hooks/useQuery.d.ts +0 -1
  59. package/framework/lib/shared/hooks/useQuery.js +0 -9
  60. package/framework/lib/shared/hooks/useRouter.d.ts +0 -1
  61. package/framework/lib/shared/hooks/useRouter.js +0 -13
  62. package/framework/lib/shared/utils/createSingletonContext.d.ts +0 -11
  63. package/framework/lib/shared/utils/createSingletonContext.js +0 -21
  64. package/framework/lib/shared/views/ErrorPage.d.ts +0 -7
  65. package/framework/lib/shared/views/ErrorPage.js +0 -12
  66. package/framework/lib/shared/views/NotFoundPage.d.ts +0 -5
  67. package/framework/lib/shared/views/NotFoundPage.js +0 -11
  68. package/framework/lib/types.d.ts +0 -174
  69. package/framework/lib/types.js +0 -8
  70. package/framework/templates/ErrorPage.tsx +0 -136
  71. package/framework/templates/HomePage.tsx +0 -344
  72. package/framework/templates/NotFoundPage.tsx +0 -108
  73. package/framework/templates/arcanajs.config.ts +0 -44
  74. package/framework/templates/arcanajs.d.ts +0 -8
  75. package/framework/templates/arcanajs.png +0 -0
  76. package/framework/templates/arcanajs.svg +0 -12
  77. package/framework/templates/client-index.tsx +0 -7
  78. package/framework/templates/favicon.ico +0 -0
  79. package/framework/templates/globals.css +0 -198
  80. package/framework/templates/package.json +0 -15
  81. package/framework/templates/postcss.config.js +0 -6
  82. package/framework/templates/server-controller-home.ts +0 -7
  83. package/framework/templates/server-index.ts +0 -11
  84. package/framework/templates/server-routes-web.ts +0 -7
  85. package/framework/templates/tsconfig.json +0 -27
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "email": "mohammed.bencheikh.dev@gmail.com",
6
6
  "url": "https://mohammedbencheikh.com/"
7
7
  },
8
- "version": "2.4.0",
8
+ "version": "2.5.0",
9
9
  "description": "ArcanaJS Framework",
10
10
  "main": "framework/lib/index.js",
11
11
  "types": "framework/lib/index.d.ts",
@@ -1 +0,0 @@
1
- export {};
@@ -1,204 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const child_process_1 = require("child_process");
7
- const fs_1 = __importDefault(require("fs"));
8
- const path_1 = __importDefault(require("path"));
9
- const webpack_1 = __importDefault(require("webpack"));
10
- const templates_1 = require("./templates");
11
- const webpack_config_1 = require("./webpack.config");
12
- const args = process.argv.slice(2);
13
- const command = args[0];
14
- if (!command) {
15
- console.error("Please specify a command: init, dev, build, start");
16
- process.exit(1);
17
- }
18
- const runCompiler = (compiler) => {
19
- return new Promise((resolve, reject) => {
20
- compiler.run((err, stats) => {
21
- if (err) {
22
- console.error(err);
23
- return reject(err);
24
- }
25
- if (stats && stats.hasErrors()) {
26
- console.error(stats.toString({ colors: true }));
27
- return reject(new Error("Webpack build failed"));
28
- }
29
- console.log(stats?.toString({ colors: true }));
30
- resolve();
31
- });
32
- });
33
- };
34
- let serverProcess = null;
35
- const ws_1 = require("ws");
36
- const startDevServer = (hmrPort) => {
37
- return new Promise((resolve) => {
38
- if (serverProcess) {
39
- serverProcess.kill();
40
- }
41
- const serverPath = path_1.default.resolve(process.cwd(), "dist/server.js");
42
- serverProcess = (0, child_process_1.spawn)("node", [serverPath], {
43
- stdio: ["inherit", "pipe", "inherit"],
44
- env: { ...process.env, ARCANA_HMR_PORT: hmrPort.toString() },
45
- });
46
- serverProcess.stdout?.on("data", (data) => {
47
- process.stdout.write(data);
48
- if (data.toString().includes("Server is running")) {
49
- resolve();
50
- }
51
- });
52
- serverProcess.on("close", (code) => {
53
- if (code !== 0 && code !== null) {
54
- console.error(`Dev server exited with code ${code}`);
55
- }
56
- });
57
- });
58
- };
59
- const watchCompiler = (compiler, onBuildComplete) => {
60
- compiler.watch({}, (err, stats) => {
61
- if (err) {
62
- console.error(err);
63
- return;
64
- }
65
- console.log(stats?.toString({ colors: true }));
66
- if (stats && !stats.hasErrors() && onBuildComplete) {
67
- onBuildComplete();
68
- }
69
- });
70
- };
71
- const build = async () => {
72
- process.env.NODE_ENV = "production";
73
- console.log("Building for production...");
74
- const clientConfig = (0, webpack_config_1.createClientConfig)();
75
- const serverConfig = (0, webpack_config_1.createServerConfig)();
76
- try {
77
- await runCompiler((0, webpack_1.default)(clientConfig));
78
- await runCompiler((0, webpack_1.default)(serverConfig));
79
- console.log("Build complete.");
80
- }
81
- catch (error) {
82
- console.error("Build failed:", error);
83
- process.exit(1);
84
- }
85
- };
86
- const dev = async () => {
87
- process.env.NODE_ENV = "development";
88
- console.log("Starting development server...");
89
- // Start HMR WebSocket Server
90
- const HMR_PORT = 3001;
91
- const wss = new ws_1.WebSocketServer({ port: HMR_PORT });
92
- console.log(`HMR Server running on port ${HMR_PORT}`);
93
- const broadcastReload = () => {
94
- wss.clients.forEach((client) => {
95
- if (client.readyState === 1) {
96
- client.send(JSON.stringify({ type: "reload" }));
97
- }
98
- });
99
- };
100
- const clientConfig = (0, webpack_config_1.createClientConfig)();
101
- const serverConfig = (0, webpack_config_1.createServerConfig)();
102
- let isServerBuilding = false;
103
- let pendingReload = false;
104
- const serverCompiler = (0, webpack_1.default)(serverConfig);
105
- serverCompiler.hooks.invalid.tap("ArcanaJS", () => {
106
- isServerBuilding = true;
107
- });
108
- // Watch client
109
- watchCompiler((0, webpack_1.default)(clientConfig), () => {
110
- console.log("Client build complete.");
111
- if (isServerBuilding) {
112
- console.log("Server is building. Waiting to reload...");
113
- pendingReload = true;
114
- }
115
- else {
116
- console.log("Reloading browsers...");
117
- broadcastReload();
118
- }
119
- });
120
- // Watch server and restart on build
121
- watchCompiler(serverCompiler, async () => {
122
- console.log("Server build complete. Restarting server...");
123
- await startDevServer(HMR_PORT);
124
- isServerBuilding = false;
125
- if (pendingReload) {
126
- console.log("Pending reload found. Reloading browsers...");
127
- broadcastReload();
128
- pendingReload = false;
129
- }
130
- });
131
- };
132
- const init = () => {
133
- console.log("Initializing ArcanaJS project with Tailwind CSS...");
134
- const cwd = process.cwd();
135
- const templatesDir = path_1.default.resolve(__dirname, "../templates");
136
- // Create necessary directories
137
- templates_1.requiredDirs.forEach((dir) => {
138
- const fullPath = path_1.default.resolve(cwd, dir);
139
- if (!fs_1.default.existsSync(fullPath)) {
140
- fs_1.default.mkdirSync(fullPath, { recursive: true });
141
- console.log(`Created directory: ${dir}`);
142
- }
143
- });
144
- // Copy configuration files
145
- templates_1.configFiles.forEach(({ src, dest }) => {
146
- const srcPath = path_1.default.resolve(templatesDir, src);
147
- const destPath = path_1.default.resolve(cwd, dest);
148
- if (!fs_1.default.existsSync(destPath)) {
149
- if (fs_1.default.existsSync(srcPath)) {
150
- fs_1.default.copyFileSync(srcPath, destPath);
151
- console.log(`Created: ${dest}`);
152
- }
153
- else {
154
- console.warn(`Template not found: ${src}`);
155
- }
156
- }
157
- else {
158
- console.log(`Skipped: ${dest} (already exists)`);
159
- }
160
- });
161
- // Create default error pages
162
- templates_1.errorPages.forEach((page) => {
163
- const viewPath = path_1.default.resolve(cwd, `src/views/${page}`);
164
- const templatePath = path_1.default.resolve(templatesDir, page);
165
- if (!fs_1.default.existsSync(viewPath) && fs_1.default.existsSync(templatePath)) {
166
- fs_1.default.copyFileSync(templatePath, viewPath);
167
- console.log(`Created: src/views/${page}`);
168
- }
169
- });
170
- console.log("\n✅ ArcanaJS project initialized successfully!");
171
- console.log("\nNext steps:");
172
- console.log("1. Run 'npm install' to install dependencies");
173
- console.log("2. Run 'npm run dev' to start development");
174
- console.log("3. Visit http://localhost:3000 to see your app");
175
- console.log("4. Edit src/views/HomePage.tsx to customize your homepage");
176
- console.log("5. Customize your theme in src/client/globals.css");
177
- console.log("6. Add your Tailwind classes and enjoy!");
178
- };
179
- const start = () => {
180
- process.env.NODE_ENV = "production";
181
- const serverPath = path_1.default.resolve(process.cwd(), "dist/server.js");
182
- console.log(`Starting server at ${serverPath}...`);
183
- const child = (0, child_process_1.spawn)("node", [serverPath], { stdio: "inherit" });
184
- child.on("close", (code) => {
185
- process.exit(code || 0);
186
- });
187
- };
188
- switch (command) {
189
- case "init":
190
- init();
191
- break;
192
- case "build":
193
- build();
194
- break;
195
- case "dev":
196
- dev();
197
- break;
198
- case "start":
199
- start();
200
- break;
201
- default:
202
- console.error(`Unknown command: ${command}`);
203
- process.exit(1);
204
- }
@@ -1,6 +0,0 @@
1
- export declare const configFiles: {
2
- src: string;
3
- dest: string;
4
- }[];
5
- export declare const errorPages: string[];
6
- export declare const requiredDirs: string[];
@@ -1,44 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.requiredDirs = exports.errorPages = exports.configFiles = void 0;
4
- exports.configFiles = [
5
- { src: "package.json", dest: "package.json" },
6
- { src: "tsconfig.json", dest: "tsconfig.json" },
7
- { src: "arcanajs.config.ts", dest: "arcanajs.config.ts" },
8
- { src: "postcss.config.js", dest: "postcss.config.js" },
9
- { src: "arcanajs.d.ts", dest: "src/arcanajs.d.ts" },
10
- { src: "globals.css", dest: "src/client/globals.css" },
11
- { src: "client-index.tsx", dest: "src/client/index.tsx" },
12
- { src: "server-index.ts", dest: "src/server/index.ts" },
13
- { src: "server-routes-web.ts", dest: "src/server/routes/web.ts" },
14
- {
15
- src: "server-controller-home.ts",
16
- dest: "src/server/controllers/HomeController.ts",
17
- },
18
- {
19
- src: "HomePage.tsx",
20
- dest: "src/views/HomePage.tsx",
21
- },
22
- {
23
- src: "arcanajs.png",
24
- dest: "public/arcanajs.png",
25
- },
26
- {
27
- src: "arcanajs.svg",
28
- dest: "public/arcanajs.svg",
29
- },
30
- {
31
- src: "favicon.ico",
32
- dest: "public/favicon.ico",
33
- },
34
- ];
35
- exports.errorPages = ["NotFoundPage.tsx", "ErrorPage.tsx"];
36
- exports.requiredDirs = [
37
- "public",
38
- "src",
39
- "src/client",
40
- "src/server",
41
- "src/server/routes",
42
- "src/server/controllers",
43
- "src/views",
44
- ];
@@ -1,3 +0,0 @@
1
- import webpack from "webpack";
2
- export declare const createClientConfig: () => webpack.Configuration;
3
- export declare const createServerConfig: () => webpack.Configuration;
@@ -1,310 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createServerConfig = exports.createClientConfig = void 0;
7
- const clean_webpack_plugin_1 = require("clean-webpack-plugin");
8
- const html_webpack_plugin_1 = __importDefault(require("html-webpack-plugin"));
9
- const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
10
- const path_1 = __importDefault(require("path"));
11
- const webpack_node_externals_1 = __importDefault(require("webpack-node-externals"));
12
- const cwd = process.cwd();
13
- // Helper to resolve loaders from the framework's node_modules
14
- const resolveLoader = (loader) => require.resolve(loader);
15
- const fs_1 = __importDefault(require("fs"));
16
- // Helper to find entry file with supported extensions
17
- const findEntry = (searchPaths) => {
18
- const extensions = [".ts", ".tsx", ".js", ".jsx"];
19
- for (const basePath of searchPaths) {
20
- for (const ext of extensions) {
21
- const fullPath = path_1.default.resolve(cwd, basePath + ext);
22
- if (fs_1.default.existsSync(fullPath)) {
23
- return fullPath;
24
- }
25
- // Also check for index files in directories
26
- const indexPath = path_1.default.resolve(cwd, basePath, "index" + ext);
27
- if (fs_1.default.existsSync(indexPath)) {
28
- return indexPath;
29
- }
30
- }
31
- }
32
- // Fallback to example if not found (for internal framework dev) or throw error
33
- // For now, we'll try the example paths as a last resort before failing
34
- const exampleClient = path_1.default.resolve(cwd, "src/example/client/index.tsx");
35
- const exampleServer = path_1.default.resolve(cwd, "src/example/server/index.ts");
36
- if (searchPaths.some((p) => p.includes("client")) &&
37
- fs_1.default.existsSync(exampleClient))
38
- return exampleClient;
39
- if (searchPaths.some((p) => p.includes("server")) &&
40
- fs_1.default.existsSync(exampleServer))
41
- return exampleServer;
42
- throw new Error(`Could not find entry point. Searched in: ${searchPaths.join(", ")}`);
43
- };
44
- const getViewsLoaderPath = () => {
45
- const viewsDir = path_1.default.resolve(cwd, "src/views");
46
- const hasViews = fs_1.default.existsSync(viewsDir);
47
- const viewsLoaderPath = path_1.default.resolve(__dirname, "../../node_modules/.cache/arcanajs/views-loader.js");
48
- // Ensure cache directory exists
49
- const cacheDir = path_1.default.dirname(viewsLoaderPath);
50
- if (!fs_1.default.existsSync(cacheDir)) {
51
- fs_1.default.mkdirSync(cacheDir, { recursive: true });
52
- }
53
- // Generate the loader file
54
- const loaderContent = hasViews
55
- ? `module.exports = require.context('${viewsDir}', true, /\\.(tsx|jsx)$/);`
56
- : `module.exports = null;`;
57
- fs_1.default.writeFileSync(viewsLoaderPath, loaderContent);
58
- return viewsLoaderPath;
59
- };
60
- const createClientConfig = () => {
61
- const isProduction = process.env.NODE_ENV === "production";
62
- const viewsLoaderPath = getViewsLoaderPath();
63
- const clientEntry = findEntry([
64
- "src/client",
65
- "src/client/index",
66
- "src/index",
67
- "src/main",
68
- ]);
69
- return {
70
- mode: isProduction ? "production" : "development",
71
- target: "web",
72
- entry: {
73
- client: clientEntry,
74
- },
75
- output: {
76
- path: path_1.default.resolve(cwd, "dist/public"),
77
- filename: isProduction
78
- ? "[name].[contenthash].bundle.js"
79
- : "[name].bundle.js",
80
- publicPath: "/",
81
- assetModuleFilename: "assets/[hash][ext][query]",
82
- },
83
- resolve: {
84
- extensions: [".ts", ".tsx", ".js", ".jsx"],
85
- alias: {
86
- "arcana-views": viewsLoaderPath,
87
- },
88
- },
89
- resolveLoader: {
90
- modules: ["node_modules", path_1.default.resolve(__dirname, "../../node_modules")],
91
- },
92
- module: {
93
- rules: [
94
- {
95
- test: /\.(ts|tsx|js|jsx)$/,
96
- exclude: /node_modules/,
97
- use: {
98
- loader: resolveLoader("babel-loader"),
99
- options: {
100
- presets: [
101
- resolveLoader("@babel/preset-env"),
102
- [
103
- resolveLoader("@babel/preset-react"),
104
- { runtime: "automatic" },
105
- ],
106
- resolveLoader("@babel/preset-typescript"),
107
- ],
108
- },
109
- },
110
- },
111
- // CSS Modules rule for .module.css files
112
- {
113
- test: /\.module\.css$/,
114
- use: [
115
- isProduction
116
- ? mini_css_extract_plugin_1.default.loader
117
- : resolveLoader("style-loader"),
118
- {
119
- loader: resolveLoader("css-loader"),
120
- options: {
121
- importLoaders: 1,
122
- modules: {
123
- localIdentName: isProduction
124
- ? "[hash:base64:8]"
125
- : "[path][name]__[local]--[hash:base64:5]",
126
- exportLocalsConvention: "camelCaseOnly",
127
- },
128
- },
129
- },
130
- {
131
- loader: resolveLoader("postcss-loader"),
132
- options: {
133
- postcssOptions: {
134
- config: path_1.default.resolve(cwd, "postcss.config.js"),
135
- },
136
- },
137
- },
138
- ],
139
- },
140
- // Global CSS rule for regular .css files
141
- {
142
- test: /\.css$/,
143
- exclude: /\.module\.css$/,
144
- use: [
145
- isProduction
146
- ? mini_css_extract_plugin_1.default.loader
147
- : resolveLoader("style-loader"),
148
- {
149
- loader: resolveLoader("css-loader"),
150
- options: {
151
- importLoaders: 1,
152
- },
153
- },
154
- {
155
- loader: resolveLoader("postcss-loader"),
156
- options: {
157
- postcssOptions: {
158
- config: path_1.default.resolve(cwd, "postcss.config.js"),
159
- },
160
- },
161
- },
162
- ],
163
- },
164
- {
165
- test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/i,
166
- type: "asset/resource",
167
- },
168
- ],
169
- },
170
- plugins: [
171
- new clean_webpack_plugin_1.CleanWebpackPlugin(),
172
- new html_webpack_plugin_1.default({
173
- template: path_1.default.resolve(__dirname, "../lib/server/default-index.html"),
174
- filename: "index.html",
175
- inject: "body",
176
- minify: isProduction
177
- ? {
178
- removeComments: false,
179
- collapseWhitespace: true,
180
- removeRedundantAttributes: true,
181
- useShortDoctype: true,
182
- removeEmptyAttributes: true,
183
- removeStyleLinkTypeAttributes: true,
184
- keepClosingSlash: true,
185
- minifyJS: true,
186
- minifyCSS: true,
187
- minifyURLs: true,
188
- }
189
- : false,
190
- }),
191
- new mini_css_extract_plugin_1.default({
192
- filename: isProduction ? "[name].[contenthash].css" : "[name].css",
193
- }),
194
- ],
195
- optimization: {
196
- splitChunks: {
197
- chunks: "all",
198
- cacheGroups: {
199
- defaultVendors: {
200
- test: /[\\/]node_modules[\\/]/,
201
- priority: -10,
202
- reuseExistingChunk: true,
203
- },
204
- default: {
205
- minChunks: 2,
206
- priority: -20,
207
- reuseExistingChunk: true,
208
- },
209
- react: {
210
- test: /[\\/]node_modules[\\/](react|react-dom|scheduler)[\\/]/,
211
- name: "react-vendor",
212
- chunks: "all",
213
- priority: 10,
214
- },
215
- },
216
- },
217
- },
218
- performance: {
219
- maxEntrypointSize: 512000,
220
- maxAssetSize: 512000,
221
- hints: isProduction ? "warning" : false,
222
- },
223
- devtool: isProduction ? "source-map" : "eval-source-map",
224
- };
225
- };
226
- exports.createClientConfig = createClientConfig;
227
- const createServerConfig = () => {
228
- const isProduction = process.env.NODE_ENV === "production";
229
- const serverEntry = findEntry([
230
- "src/server",
231
- "src/server/index",
232
- "src/server/main",
233
- ]);
234
- const viewsLoaderPath = getViewsLoaderPath();
235
- return {
236
- mode: isProduction ? "production" : "development",
237
- target: "node",
238
- entry: serverEntry,
239
- output: {
240
- path: path_1.default.resolve(cwd, "dist"),
241
- filename: "server.js",
242
- },
243
- externals: [
244
- (0, webpack_node_externals_1.default)({
245
- allowlist: [/^arcanajs/],
246
- }),
247
- ],
248
- resolve: {
249
- extensions: [".ts", ".tsx", ".js", ".jsx"],
250
- alias: {
251
- "arcana-views": viewsLoaderPath,
252
- },
253
- },
254
- resolveLoader: {
255
- modules: ["node_modules", path_1.default.resolve(__dirname, "../../node_modules")],
256
- },
257
- module: {
258
- rules: [
259
- {
260
- test: /\.(ts|tsx|js|jsx)$/,
261
- exclude: /node_modules/,
262
- use: {
263
- loader: resolveLoader("babel-loader"),
264
- options: {
265
- presets: [
266
- resolveLoader("@babel/preset-env"),
267
- [
268
- resolveLoader("@babel/preset-react"),
269
- { runtime: "automatic" },
270
- ],
271
- resolveLoader("@babel/preset-typescript"),
272
- ],
273
- },
274
- },
275
- },
276
- // CSS Modules rule for .module.css files on server (for SSR)
277
- {
278
- test: /\.module\.css$/,
279
- use: {
280
- loader: resolveLoader("css-loader"),
281
- options: {
282
- modules: {
283
- localIdentName: isProduction
284
- ? "[hash:base64:8]"
285
- : "[path][name]__[local]--[hash:base64:5]",
286
- exportLocalsConvention: "camelCaseOnly",
287
- exportOnlyLocals: true, // Only export class names, not CSS
288
- },
289
- },
290
- },
291
- },
292
- // Regular CSS files - ignore on server side
293
- {
294
- test: /\.css$/,
295
- exclude: /\.module\.css$/,
296
- use: resolveLoader("null-loader"),
297
- },
298
- {
299
- test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/i,
300
- type: "asset/resource",
301
- generator: {
302
- emit: false,
303
- },
304
- },
305
- ],
306
- },
307
- devtool: isProduction ? "source-map" : "eval-source-map",
308
- };
309
- };
310
- exports.createServerConfig = createServerConfig;
@@ -1,59 +0,0 @@
1
- import React from "react";
2
- export type { LayoutComponent, ViewsRegistry } from "../types";
3
- /**
4
- * Navigation options for configuring ArcanaJS behavior
5
- */
6
- export interface NavigationOptions {
7
- /**
8
- * Callback function called after each successful navigation
9
- * Useful for analytics, logging, or custom scroll behavior
10
- */
11
- onNavigate?: (url: string) => void;
12
- }
13
- /**
14
- * Hydrate the ArcanaJS application on the client side
15
- *
16
- * This function initializes the React application on the client,
17
- * hydrating the server-rendered HTML with client-side interactivity.
18
- *
19
- * @param viewsOrContext - Either a views registry object or a webpack require.context
20
- * @param layout - Optional layout component to wrap all pages
21
- * @param options - Optional navigation configuration options
22
- *
23
- * @example
24
- * ```typescript
25
- * // Using webpack require.context (recommended)
26
- * import { hydrateArcanaJS } from 'arcanajs/client';
27
- *
28
- * const views = require.context('./views', false, /\.tsx$/);
29
- * hydrateArcanaJS(views);
30
- * ```
31
- *
32
- * @example
33
- * ```typescript
34
- * // Using manual views registry
35
- * import { hydrateArcanaJS } from 'arcanajs/client';
36
- * import HomePage from './views/HomePage';
37
- * import AboutPage from './views/AboutPage';
38
- *
39
- * hydrateArcanaJS({
40
- * HomePage,
41
- * AboutPage,
42
- * });
43
- * ```
44
- *
45
- * @example
46
- * ```typescript
47
- * // With navigation options
48
- * import { hydrateArcanaJS } from 'arcanajs/client';
49
- *
50
- * const views = require.context('./views', false, /\.tsx$/);
51
- * hydrateArcanaJS(views, undefined, {
52
- * onNavigate: (url) => {
53
- * // Track page views
54
- * gtag('event', 'page_view', { page_path: url });
55
- * }
56
- * });
57
- * ```
58
- */
59
- export declare const hydrateArcanaJS: (viewsOrContext: Record<string, React.FC<any>> | any, layout?: React.FC<any>, options?: NavigationOptions) => void;