aplosjs 0.15.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 (56) hide show
  1. package/README.md +28 -0
  2. package/aplos.config.dist.js +30 -0
  3. package/bin/aplos +60 -0
  4. package/create-aplos/index.js +95 -0
  5. package/create-aplos/package.json +29 -0
  6. package/create-aplos/templates/minimal/README.md +38 -0
  7. package/create-aplos/templates/minimal/_gitignore +7 -0
  8. package/create-aplos/templates/minimal/aplos.config.js +13 -0
  9. package/create-aplos/templates/minimal/package.json +22 -0
  10. package/create-aplos/templates/minimal/public/favicon.svg +4 -0
  11. package/create-aplos/templates/minimal/src/pages/_app.tsx +6 -0
  12. package/create-aplos/templates/minimal/src/pages/about.tsx +24 -0
  13. package/create-aplos/templates/minimal/src/pages/index.tsx +40 -0
  14. package/create-aplos/templates/minimal/src/styles/global.css +53 -0
  15. package/create-aplos/templates/minimal/tsconfig.json +18 -0
  16. package/package.json +92 -0
  17. package/postcss.config.js +9 -0
  18. package/rspack.config.js +306 -0
  19. package/rspack.ssr.config.js +129 -0
  20. package/src/build/config.js +42 -0
  21. package/src/build/css-noop-loader.cjs +3 -0
  22. package/src/build/router.js +609 -0
  23. package/src/build/ssg.js +198 -0
  24. package/src/client/public/index.html +8 -0
  25. package/src/command/build.js +105 -0
  26. package/src/command/create.js +91 -0
  27. package/src/command/devServer.js +198 -0
  28. package/src/command/router.js +137 -0
  29. package/src/components/head.jsx +65 -0
  30. package/src/components/navigation.jsx +11 -0
  31. package/src/config.js +5 -0
  32. package/src/pages/_app.tsx +9 -0
  33. package/src/pages/blog/[slug].tsx +6 -0
  34. package/src/pages/crash.tsx +6 -0
  35. package/src/pages/index.tsx +10 -0
  36. package/src/pages/test.tsx +5 -0
  37. package/src/runtime/DefaultErrorPage.jsx +76 -0
  38. package/src/runtime/ErrorBoundary.jsx +40 -0
  39. package/src/runtime/MiddlewareGate.jsx +149 -0
  40. package/src/runtime/app-ssr.jsx +42 -0
  41. package/src/runtime/app.jsx +126 -0
  42. package/src/runtime/default-middleware.js +10 -0
  43. package/src/runtime/default-not-found.jsx +3 -0
  44. package/src/runtime/passthrough-layout.jsx +5 -0
  45. package/src/runtime/redirect.js +46 -0
  46. package/src/runtime/ssr-entry.jsx +104 -0
  47. package/templates/minimal/README.md +38 -0
  48. package/templates/minimal/_gitignore +7 -0
  49. package/templates/minimal/aplos.config.js +13 -0
  50. package/templates/minimal/package.json +22 -0
  51. package/templates/minimal/public/favicon.svg +4 -0
  52. package/templates/minimal/src/pages/_app.tsx +6 -0
  53. package/templates/minimal/src/pages/about.tsx +24 -0
  54. package/templates/minimal/src/pages/index.tsx +40 -0
  55. package/templates/minimal/src/styles/global.css +53 -0
  56. package/templates/minimal/tsconfig.json +18 -0
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Aplos
2
+
3
+ A fast, modern React framework with file-based routing, powered by Rspack.
4
+
5
+ ## Features
6
+
7
+ - File-based routing with dynamic and catch-all routes
8
+ - Nested layouts
9
+ - Custom rspack configuration
10
+ - React Compiler & HMR
11
+ - TypeScript & PostCSS support
12
+ - Environment variables (`.env`, `.env.local`)
13
+
14
+ ## Quick Start
15
+
16
+ ```bash
17
+ bun add aplosjs
18
+
19
+ # Start development server
20
+ npx aplos server
21
+
22
+ # Build for production
23
+ npx aplos build
24
+ ```
25
+
26
+ ## Documentation
27
+
28
+ See the full documentation in the [`documentation/`](documentation/) directory, or browse it online at [aplos.alpacode.io](https://aplos.alpacode.io).
@@ -0,0 +1,30 @@
1
+ export default {
2
+ // React configuration
3
+ reactStrictMode: true,
4
+
5
+ // Server configuration
6
+ server: {
7
+ port: 3001,
8
+ },
9
+
10
+ // Client-side runtime configuration
11
+ publicRuntimeConfig: {
12
+ api_base_url: process.env.API_BASE_URL || "https://api.example.com",
13
+ },
14
+
15
+ // Routes configuration
16
+ routes: [
17
+ {
18
+ source: '/custom',
19
+ destination: '/custom-page'
20
+ },
21
+ {
22
+ path: '/blog/:id',
23
+ component: 'BlogPost',
24
+ file: 'pages/blog/[id]',
25
+ requirements: {
26
+ id: '\\d+' // Numbers only
27
+ }
28
+ }
29
+ ]
30
+ };
package/bin/aplos ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { config } from "dotenv";
4
+ import { existsSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+
7
+ const projectDir = process.cwd();
8
+ config({ path: resolve(projectDir, ".env") });
9
+ if (existsSync(resolve(projectDir, ".env.local"))) {
10
+ config({ path: resolve(projectDir, ".env.local"), override: true });
11
+ }
12
+
13
+ import { Command } from "commander";
14
+ import devServer from "../src/command/devServer.js";
15
+ import build from "../src/command/build.js";
16
+ import router from "../src/command/router.js";
17
+ import create from "../src/command/create.js";
18
+
19
+ const program = new Command();
20
+ program.name("Aplos").description("React Framework").version("0.14.0");
21
+
22
+ program
23
+ .command("server")
24
+ .description("Split a string into substrings and display as an array")
25
+ .action(devServer);
26
+
27
+ program
28
+ .command("build")
29
+ .description("Build assets")
30
+ .option(
31
+ "--mode <mode>",
32
+ "Providing the mode configuration option tells webpack to use its built-in optimizations accordingly",
33
+ process.env.NODE_ENV || "development"
34
+ )
35
+ .option(
36
+ "--static",
37
+ "Pre-render each static route to HTML (SSG). Dynamic routes fall back to SPA.",
38
+ false
39
+ )
40
+ .action(build);
41
+
42
+ program
43
+ .command("router:debug")
44
+ .argument("[name]", "Name of the route")
45
+ .description("Debug the router")
46
+ .action(router);
47
+
48
+ program
49
+ .command("router:match")
50
+ .argument("<url>", "URL to test against routes")
51
+ .description("Test if a URL matches any route")
52
+ .action((url) => router({ url }));
53
+
54
+ program
55
+ .command("create")
56
+ .argument("<project-name>", "Name of the new project")
57
+ .description("Scaffold a new Aplos project")
58
+ .action(create);
59
+
60
+ program.parse();
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = path.dirname(__filename);
9
+
10
+ const TEMPLATE_DIR = path.resolve(__dirname, "templates/minimal");
11
+ const VALID_NAME = /^[a-z0-9][a-z0-9._-]*$/i;
12
+
13
+ const projectName = process.argv[2];
14
+
15
+ if (!projectName) {
16
+ console.error("Usage: create-aplos <project-name>");
17
+ console.error(" bun create aplos <project-name>");
18
+ console.error(" npm create aplos <project-name>");
19
+ process.exit(1);
20
+ }
21
+
22
+ if (!VALID_NAME.test(projectName) || projectName.startsWith(".")) {
23
+ console.error(
24
+ `Invalid project name: "${projectName}". Use letters, digits, dashes, dots or underscores.`
25
+ );
26
+ process.exit(1);
27
+ }
28
+
29
+ const targetDir = path.resolve(process.cwd(), projectName);
30
+
31
+ if (fs.existsSync(targetDir)) {
32
+ const entries = fs.readdirSync(targetDir);
33
+ if (entries.length > 0) {
34
+ console.error(
35
+ `Target directory "${projectName}" already exists and is not empty.`
36
+ );
37
+ process.exit(1);
38
+ }
39
+ } else {
40
+ fs.mkdirSync(targetDir, { recursive: true });
41
+ }
42
+
43
+ console.log(`Creating Aplos project in ${targetDir}...`);
44
+
45
+ copyDirectory(TEMPLATE_DIR, targetDir, projectName);
46
+ renameGitignore(targetDir);
47
+
48
+ console.log("");
49
+ console.log("Done. Next steps:");
50
+ console.log("");
51
+ console.log(` cd ${projectName}`);
52
+ console.log(" bun install");
53
+ console.log(" bun dev");
54
+ console.log("");
55
+ console.log("Happy hacking!");
56
+
57
+ function copyDirectory(src, dest, name) {
58
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
59
+ const srcPath = path.join(src, entry.name);
60
+ const destPath = path.join(dest, entry.name);
61
+
62
+ if (entry.isDirectory()) {
63
+ fs.mkdirSync(destPath, { recursive: true });
64
+ copyDirectory(srcPath, destPath, name);
65
+ } else if (entry.isFile()) {
66
+ copyFile(srcPath, destPath, name);
67
+ }
68
+ }
69
+ }
70
+
71
+ function copyFile(src, dest, name) {
72
+ if (isBinary(src)) {
73
+ fs.copyFileSync(src, dest);
74
+ return;
75
+ }
76
+
77
+ const content = fs.readFileSync(src, "utf8");
78
+ const replaced = content.replace(/\{\{NAME\}\}/g, name);
79
+ fs.writeFileSync(dest, replaced);
80
+ }
81
+
82
+ function isBinary(filePath) {
83
+ const ext = path.extname(filePath).toLowerCase();
84
+ return [".png", ".jpg", ".jpeg", ".gif", ".ico", ".webp", ".woff", ".woff2"].includes(
85
+ ext
86
+ );
87
+ }
88
+
89
+ function renameGitignore(dir) {
90
+ const stub = path.join(dir, "_gitignore");
91
+ const real = path.join(dir, ".gitignore");
92
+ if (fs.existsSync(stub) && !fs.existsSync(real)) {
93
+ fs.renameSync(stub, real);
94
+ }
95
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "create-aplos",
3
+ "version": "0.14.0",
4
+ "description": "Scaffold a new Aplos project",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-aplos": "./index.js"
8
+ },
9
+ "files": [
10
+ "index.js",
11
+ "templates"
12
+ ],
13
+ "keywords": [
14
+ "aplos",
15
+ "react",
16
+ "scaffold",
17
+ "starter",
18
+ "create"
19
+ ],
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/alpac0de/aplos.git",
23
+ "directory": "create-aplos"
24
+ },
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=18"
28
+ }
29
+ }
@@ -0,0 +1,38 @@
1
+ # {{NAME}}
2
+
3
+ Built with [Aplos](https://aplos.alpacode.io) — a fast, file-based React framework powered by Rspack.
4
+
5
+ ## Getting started
6
+
7
+ ```bash
8
+ bun install
9
+ bun dev
10
+ ```
11
+
12
+ Open [http://localhost:3000](http://localhost:3000) to view the app.
13
+
14
+ ## Available scripts
15
+
16
+ - `bun dev` — start the development server with HMR
17
+ - `bun build` — build for production
18
+ - `bun build:static` — build with static pre-rendering for opt-in pages
19
+
20
+ ## Project structure
21
+
22
+ ```
23
+ src/
24
+ pages/ # File-based routes
25
+ _app.tsx # Root layout
26
+ index.tsx # Home page (/)
27
+ about.tsx # About page (/about)
28
+ styles/
29
+ global.css
30
+ aplos.config.js
31
+ ```
32
+
33
+ Add files in `src/pages/` to create new routes automatically.
34
+
35
+ ## Learn more
36
+
37
+ - [Aplos documentation](https://aplos.alpacode.io)
38
+ - [GitHub repository](https://github.com/alpac0de/aplos)
@@ -0,0 +1,7 @@
1
+ node_modules
2
+ .aplos
3
+ public/dist
4
+ dist
5
+ .env.local
6
+ *.log
7
+ .DS_Store
@@ -0,0 +1,13 @@
1
+ export default {
2
+ reactStrictMode: true,
3
+ server: {
4
+ port: 3000,
5
+ },
6
+ head: {
7
+ defaultTitle: '{{NAME}}',
8
+ meta: [
9
+ { name: 'viewport', content: 'width=device-width, initial-scale=1' },
10
+ { name: 'description', content: 'Built with Aplos' },
11
+ ],
12
+ },
13
+ };
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "{{NAME}}",
3
+ "private": true,
4
+ "version": "0.1.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "aplos server",
8
+ "build": "aplos build",
9
+ "build:static": "aplos build --static"
10
+ },
11
+ "dependencies": {
12
+ "aplosjs": "^0.14.0",
13
+ "react": "^19.2.0",
14
+ "react-dom": "^19.2.0",
15
+ "react-router-dom": "^7.9.5"
16
+ },
17
+ "devDependencies": {
18
+ "typescript": "^5.9.3",
19
+ "@types/react": "^19.0.0",
20
+ "@types/react-dom": "^19.0.0"
21
+ }
22
+ }
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
2
+ <rect width="64" height="64" rx="12" fill="#0066cc"/>
3
+ <text x="50%" y="58%" text-anchor="middle" fill="#fff" font-family="system-ui, sans-serif" font-size="32" font-weight="700">A</text>
4
+ </svg>
@@ -0,0 +1,6 @@
1
+ import { Outlet } from 'aplos/navigation';
2
+ import '@/styles/global.css';
3
+
4
+ export default function App() {
5
+ return <Outlet />;
6
+ }
@@ -0,0 +1,24 @@
1
+ import Head from 'aplos/head';
2
+ import { Link } from 'aplos/navigation';
3
+
4
+ export default function About() {
5
+ return (
6
+ <>
7
+ <Head>
8
+ <title>About</title>
9
+ </Head>
10
+
11
+ <main className="container">
12
+ <h1>About</h1>
13
+ <p>
14
+ This is an example page. Aplos uses file-based routing — this page
15
+ lives at <code>src/pages/about.tsx</code> and is served at{' '}
16
+ <code>/about</code>.
17
+ </p>
18
+ <p>
19
+ <Link to="/">← Back home</Link>
20
+ </p>
21
+ </main>
22
+ </>
23
+ );
24
+ }
@@ -0,0 +1,40 @@
1
+ import Head from 'aplos/head';
2
+ import { Link } from 'aplos/navigation';
3
+
4
+ export default function Home() {
5
+ return (
6
+ <>
7
+ <Head>
8
+ <title>Welcome — {{NAME}}</title>
9
+ </Head>
10
+
11
+ <main className="container">
12
+ <h1>Welcome to Aplos</h1>
13
+ <p>
14
+ Your project is up and running. Edit <code>src/pages/index.tsx</code>{' '}
15
+ to start building.
16
+ </p>
17
+
18
+ <ul className="links">
19
+ <li>
20
+ <Link to="/about">About page example</Link>
21
+ </li>
22
+ <li>
23
+ <a href="https://aplos.alpacode.io" target="_blank" rel="noreferrer">
24
+ Documentation
25
+ </a>
26
+ </li>
27
+ <li>
28
+ <a
29
+ href="https://github.com/alpac0de/aplos"
30
+ target="_blank"
31
+ rel="noreferrer"
32
+ >
33
+ GitHub repository
34
+ </a>
35
+ </li>
36
+ </ul>
37
+ </main>
38
+ </>
39
+ );
40
+ }
@@ -0,0 +1,53 @@
1
+ *,
2
+ *::before,
3
+ *::after {
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ html,
8
+ body {
9
+ margin: 0;
10
+ padding: 0;
11
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
12
+ "Helvetica Neue", Arial, sans-serif;
13
+ color: #1a1a1a;
14
+ background: #fafafa;
15
+ line-height: 1.6;
16
+ }
17
+
18
+ .container {
19
+ max-width: 720px;
20
+ margin: 0 auto;
21
+ padding: 4rem 1.5rem;
22
+ }
23
+
24
+ h1 {
25
+ font-size: 2.25rem;
26
+ margin-bottom: 1rem;
27
+ }
28
+
29
+ code {
30
+ background: #eee;
31
+ padding: 0.15rem 0.4rem;
32
+ border-radius: 4px;
33
+ font-size: 0.9em;
34
+ }
35
+
36
+ .links {
37
+ list-style: none;
38
+ padding: 0;
39
+ margin-top: 2rem;
40
+ }
41
+
42
+ .links li {
43
+ margin: 0.5rem 0;
44
+ }
45
+
46
+ a {
47
+ color: #0066cc;
48
+ text-decoration: none;
49
+ }
50
+
51
+ a:hover {
52
+ text-decoration: underline;
53
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "jsx": "react-jsx",
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "baseUrl": ".",
12
+ "paths": {
13
+ "@/*": ["./src/*"],
14
+ "~/*": ["./src/*"]
15
+ }
16
+ },
17
+ "include": ["src"]
18
+ }
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "aplosjs",
3
+ "version": "0.15.0",
4
+ "description": "A fast, modern React framework",
5
+ "author": "Mbechezi Nawo",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/alpac0de/aplos.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/alpac0de/aplos/issues"
14
+ },
15
+ "homepage": "https://github.com/alpac0de/aplos#readme",
16
+ "keywords": [
17
+ "react",
18
+ "framework",
19
+ "routing",
20
+ "file-based-routing",
21
+ "rspack",
22
+ "frontend",
23
+ "spa"
24
+ ],
25
+ "bin": {
26
+ "aplos": "bin/aplos"
27
+ },
28
+ "files": [
29
+ "bin/",
30
+ "src/",
31
+ "templates/",
32
+ "create-aplos/",
33
+ "rspack.config.js",
34
+ "rspack.ssr.config.js",
35
+ "postcss.config.js",
36
+ "aplos.config.dist.js",
37
+ "README.md"
38
+ ],
39
+ "scripts": {
40
+ "dev": "bin/aplos server",
41
+ "test": "bun test",
42
+ "lint": "eslint"
43
+ },
44
+ "dependencies": {
45
+ "@babel/core": "^7.28.5",
46
+ "@babel/plugin-proposal-decorators": "^7.28.0",
47
+ "@babel/preset-env": "^7.28.5",
48
+ "@babel/preset-react": "^7.28.5",
49
+ "@babel/preset-typescript": "^7.28.5",
50
+ "@rspack/cli": "^1.7.0",
51
+ "@rspack/core": "^1.7.0",
52
+ "@rspack/dev-server": "^1.1.4",
53
+ "@rspack/plugin-html": "^0.5.8",
54
+ "@rspack/plugin-react-refresh": "^1.6.0",
55
+ "autoprefixer": "^10.4.21",
56
+ "babel-loader": "^10.0.0",
57
+ "babel-plugin-react-compiler": "19.1.0-rc.3",
58
+ "cli-table3": "^0.6.5",
59
+ "commander": "^14.0.0",
60
+ "css-loader": "^7.1.2",
61
+ "dotenv": "^17.3.1",
62
+ "glob": "^11.0.3",
63
+ "postcss": "^8.5.6",
64
+ "postcss-loader": "^8.2.0",
65
+ "postcss-nested": "^7.0.2",
66
+ "react-refresh": "^0.16.0",
67
+ "style-loader": "^4.0.0",
68
+ "typescript": "^5.9.3",
69
+ "webpack-merge": "^6.0.1"
70
+ },
71
+ "devDependencies": {
72
+ "@eslint/js": "^9.39.1",
73
+ "eslint": "^9.39.1",
74
+ "eslint-plugin-react": "^7.37.5",
75
+ "eslint-plugin-react-compiler": "^19.1.0-rc.2",
76
+ "globals": "^16.5.0",
77
+ "react": "^19.2.0",
78
+ "react-dom": "^19.2.0",
79
+ "react-router-dom": "^7.9.5"
80
+ },
81
+ "peerDependencies": {
82
+ "react": "^19.0.0",
83
+ "react-dom": "^19.0.0",
84
+ "react-router-dom": "^7.0.0"
85
+ },
86
+ "exports": {
87
+ "./config": "./src/config.js",
88
+ "./navigation": "./src/components/navigation.jsx",
89
+ "./head": "./src/components/head.jsx",
90
+ "./redirect": "./src/runtime/redirect.js"
91
+ }
92
+ }
@@ -0,0 +1,9 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: [
4
+ require('autoprefixer'),
5
+ require('postcss-nested')
6
+ ]
7
+ }
8
+
9
+ module.exports = config