ionbeam 1.0.0-alpha.1
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.
- package/README.md +81 -0
- package/bin/ionbeam.js +47 -0
- package/dist/build/index.d.ts +18 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +181 -0
- package/dist/build/index.js.map +1 -0
- package/dist/cli/build.d.ts +2 -0
- package/dist/cli/build.d.ts.map +1 -0
- package/dist/cli/build.js +17 -0
- package/dist/cli/build.js.map +1 -0
- package/dist/cli/dev.d.ts +2 -0
- package/dist/cli/dev.d.ts.map +1 -0
- package/dist/cli/dev.js +58 -0
- package/dist/cli/dev.js.map +1 -0
- package/dist/cli/start.d.ts +2 -0
- package/dist/cli/start.d.ts.map +1 -0
- package/dist/cli/start.js +20 -0
- package/dist/cli/start.js.map +1 -0
- package/dist/components/Page/index.d.ts +7 -0
- package/dist/components/Page/index.d.ts.map +1 -0
- package/dist/components/Page/index.js +7 -0
- package/dist/components/Page/index.js.map +1 -0
- package/dist/components/Page/page.css +35 -0
- package/dist/components-bundle.js +10 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/ioncore.css +1 -0
- package/dist/server/index.d.ts +26 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +42 -0
- package/dist/server/index.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/assets-context.d.ts +8 -0
- package/dist/utils/assets-context.d.ts.map +1 -0
- package/dist/utils/assets-context.js +8 -0
- package/dist/utils/assets-context.js.map +1 -0
- package/dist/utils/manifest.d.ts +3 -0
- package/dist/utils/manifest.d.ts.map +1 -0
- package/dist/utils/manifest.js +24 -0
- package/dist/utils/manifest.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# IonBeam
|
|
2
|
+
|
|
3
|
+
A pure React SSR framework with automatic asset hashing, CSS modules, and zero configuration.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Server-Side Rendering** - Built-in SSR with React 19
|
|
8
|
+
- 🎨 **CSS Modules** - Scoped styles with automatic class name hashing
|
|
9
|
+
- 📦 **Asset Hashing** - Automatic content-based hashing for cache busting
|
|
10
|
+
- 🔧 **Zero Config** - Works out of the box with sensible defaults
|
|
11
|
+
- ⚡ **Fast Development** - Hot reload with file watching
|
|
12
|
+
- 📝 **TypeScript First** - Full TypeScript support
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install ionbeam react react-dom
|
|
18
|
+
# or
|
|
19
|
+
pnpm add ionbeam react react-dom
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
1. Create your server (`src/server.tsx`):
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { createServer, IonCoreRequest } from 'ioncore';
|
|
28
|
+
import { Request, Response } from 'express';
|
|
29
|
+
import { HomePage } from './pages/HomePage/index.js';
|
|
30
|
+
|
|
31
|
+
const app = createServer();
|
|
32
|
+
|
|
33
|
+
// Define routes with full Express flexibility
|
|
34
|
+
app.get('/', async (req: Request, res: Response) => {
|
|
35
|
+
await req.ioncore?.render(<HomePage />);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
app.listen(3000, () => {
|
|
39
|
+
console.log('Server running on http://localhost:3000');
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
2. Create a page using the built-in `Page` component (`src/pages/HomePage/index.tsx`):
|
|
44
|
+
|
|
45
|
+
```tsx
|
|
46
|
+
import { JSX } from "react";
|
|
47
|
+
import { Page } from "ioncore";
|
|
48
|
+
|
|
49
|
+
export const HomePage = (): JSX.Element => {
|
|
50
|
+
return (
|
|
51
|
+
<Page title="Home">
|
|
52
|
+
<h1>Welcome to IonBeam!</h1>
|
|
53
|
+
<p>A flexible React SSR framework</p>
|
|
54
|
+
</Page>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
3. Add scripts to your `package.json`:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"scripts": {
|
|
64
|
+
"dev": "ioncore dev",
|
|
65
|
+
"build": "ioncore build",
|
|
66
|
+
"start": "ioncore start"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
4. Run your app:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run dev
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## CLI Commands
|
|
78
|
+
|
|
79
|
+
- `ioncore dev` - Start development server with watch mode
|
|
80
|
+
- `ioncore build` - Build for production
|
|
81
|
+
- `ioncore start` - Start production server
|
package/bin/ionbeam.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { readFileSync } from 'node:fs';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = dirname(__filename);
|
|
10
|
+
|
|
11
|
+
// Read package.json for version
|
|
12
|
+
const packageJson = JSON.parse(
|
|
13
|
+
readFileSync(join(__dirname, '../package.json'), 'utf-8')
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const program = new Command();
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.name('ionbeam')
|
|
20
|
+
.description('IonBeam - Pure React SSR Framework')
|
|
21
|
+
.version(packageJson.version);
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.command('build')
|
|
25
|
+
.description('Build the application for production')
|
|
26
|
+
.action(async () => {
|
|
27
|
+
const { build } = await import('../dist/cli/build.js');
|
|
28
|
+
await build();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
program
|
|
32
|
+
.command('dev')
|
|
33
|
+
.description('Start development server with watch mode')
|
|
34
|
+
.action(async () => {
|
|
35
|
+
const { dev } = await import('../dist/cli/dev.js');
|
|
36
|
+
await dev();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
program
|
|
40
|
+
.command('start')
|
|
41
|
+
.description('Start production server')
|
|
42
|
+
.action(async () => {
|
|
43
|
+
const { start } = await import('../dist/cli/start.js');
|
|
44
|
+
await start();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
program.parse();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface BuildOptions {
|
|
2
|
+
rootDir: string;
|
|
3
|
+
outDir: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class Builder {
|
|
6
|
+
private cssFileName;
|
|
7
|
+
private clientFileName;
|
|
8
|
+
private options;
|
|
9
|
+
constructor(options: BuildOptions);
|
|
10
|
+
buildServer(): Promise<void>;
|
|
11
|
+
buildClient(): Promise<void>;
|
|
12
|
+
generateManifest(): Promise<void>;
|
|
13
|
+
copyStaticFiles(): Promise<void>;
|
|
14
|
+
clean(): Promise<void>;
|
|
15
|
+
build(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"AASA,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,OAAO,CAAe;gBAEX,OAAO,EAAE,YAAY;IAI3B,WAAW;IAsElB,WAAW;IA2DX,gBAAgB;IAsBhB,eAAe;IAuBf,KAAK;IAKL,KAAK;CAOZ"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { rollup } from 'rollup';
|
|
2
|
+
import typescript from '@rollup/plugin-typescript';
|
|
3
|
+
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|
4
|
+
import postcss from 'rollup-plugin-postcss';
|
|
5
|
+
import fs from 'node:fs/promises';
|
|
6
|
+
import { glob } from 'glob';
|
|
7
|
+
import crypto from 'node:crypto';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
export class Builder {
|
|
10
|
+
cssFileName = null;
|
|
11
|
+
clientFileName = null;
|
|
12
|
+
options;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options;
|
|
15
|
+
}
|
|
16
|
+
async buildServer() {
|
|
17
|
+
const { rootDir, outDir } = this.options;
|
|
18
|
+
try {
|
|
19
|
+
const bundle = await rollup({
|
|
20
|
+
input: path.join(rootDir, 'src/server.tsx'),
|
|
21
|
+
external: (id) => {
|
|
22
|
+
// External all node_modules
|
|
23
|
+
return !id.startsWith('.') && !id.startsWith('/');
|
|
24
|
+
},
|
|
25
|
+
plugins: [
|
|
26
|
+
// @ts-expect-error --- IGNORE ---
|
|
27
|
+
postcss({
|
|
28
|
+
modules: {
|
|
29
|
+
generateScopedName: '[local]-[hash:6]',
|
|
30
|
+
localsConvention: 'camelCaseOnly',
|
|
31
|
+
},
|
|
32
|
+
extract: true,
|
|
33
|
+
inject: false,
|
|
34
|
+
}),
|
|
35
|
+
// Custom plugin to hash and track CSS file
|
|
36
|
+
{
|
|
37
|
+
name: 'css-hash',
|
|
38
|
+
generateBundle: (_options, bundle) => {
|
|
39
|
+
// Find the CSS file in the bundle
|
|
40
|
+
for (const [fileName, asset] of Object.entries(bundle)) {
|
|
41
|
+
if (fileName.endsWith('.css') && asset.type === 'asset') {
|
|
42
|
+
// Generate hash from CSS content
|
|
43
|
+
const hash = crypto
|
|
44
|
+
.createHash('sha256')
|
|
45
|
+
.update(asset.source)
|
|
46
|
+
.digest('hex')
|
|
47
|
+
.substring(0, 8);
|
|
48
|
+
// Create new filename with hash
|
|
49
|
+
const newFileName = `static/server-${hash}.css`;
|
|
50
|
+
this.cssFileName = `server-${hash}.css`;
|
|
51
|
+
// Update the asset's fileName
|
|
52
|
+
asset.fileName = newFileName;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
nodeResolve({
|
|
58
|
+
extensions: ['.ts', '.tsx'],
|
|
59
|
+
}),
|
|
60
|
+
// @ts-expect-error --- IGNORE ---
|
|
61
|
+
typescript({
|
|
62
|
+
tsconfig: path.join(rootDir, 'tsconfig.json'),
|
|
63
|
+
declaration: false,
|
|
64
|
+
sourceMap: true,
|
|
65
|
+
}),
|
|
66
|
+
],
|
|
67
|
+
});
|
|
68
|
+
await bundle.write({
|
|
69
|
+
dir: outDir,
|
|
70
|
+
entryFileNames: 'server.js',
|
|
71
|
+
format: 'esm',
|
|
72
|
+
sourcemap: true,
|
|
73
|
+
});
|
|
74
|
+
await bundle.close();
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error('Server build failed:', error);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async buildClient() {
|
|
82
|
+
const { rootDir, outDir } = this.options;
|
|
83
|
+
try {
|
|
84
|
+
const clientFiles = await glob('src/**/client.ts', { cwd: rootDir, absolute: true });
|
|
85
|
+
if (clientFiles.length === 0) {
|
|
86
|
+
console.log('No client files found, skipping client bundle');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const bundle = await rollup({
|
|
90
|
+
input: clientFiles,
|
|
91
|
+
plugins: [
|
|
92
|
+
postcss.default({
|
|
93
|
+
modules: {
|
|
94
|
+
generateScopedName: '[local]-[hash:8]',
|
|
95
|
+
localsConvention: 'camelCaseOnly',
|
|
96
|
+
},
|
|
97
|
+
inject: true,
|
|
98
|
+
}),
|
|
99
|
+
nodeResolve({
|
|
100
|
+
extensions: ['.ts', '.tsx'],
|
|
101
|
+
browser: true,
|
|
102
|
+
}),
|
|
103
|
+
typescript.default({
|
|
104
|
+
tsconfig: path.join(rootDir, 'tsconfig.json'),
|
|
105
|
+
declaration: false,
|
|
106
|
+
declarationMap: false,
|
|
107
|
+
sourceMap: true,
|
|
108
|
+
outDir: path.join(outDir, 'static'),
|
|
109
|
+
compilerOptions: {
|
|
110
|
+
lib: ['ES2022', 'DOM'],
|
|
111
|
+
},
|
|
112
|
+
}),
|
|
113
|
+
],
|
|
114
|
+
});
|
|
115
|
+
const { output } = await bundle.write({
|
|
116
|
+
dir: path.join(outDir, 'static'),
|
|
117
|
+
entryFileNames: 'client-[hash:8].js',
|
|
118
|
+
format: 'iife',
|
|
119
|
+
sourcemap: true,
|
|
120
|
+
});
|
|
121
|
+
// Store client JS filename
|
|
122
|
+
for (const chunk of output) {
|
|
123
|
+
if (chunk.type === 'chunk' && chunk.isEntry) {
|
|
124
|
+
this.clientFileName = chunk.fileName;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
await bundle.close();
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('Client build failed:', error);
|
|
131
|
+
throw error;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async generateManifest() {
|
|
135
|
+
const { outDir } = this.options;
|
|
136
|
+
const manifest = {};
|
|
137
|
+
// Add client JS to manifest
|
|
138
|
+
if (this.clientFileName) {
|
|
139
|
+
manifest['client.js'] = this.clientFileName;
|
|
140
|
+
}
|
|
141
|
+
// Add CSS filename from server build to manifest
|
|
142
|
+
if (this.cssFileName) {
|
|
143
|
+
manifest['server.css'] = this.cssFileName;
|
|
144
|
+
}
|
|
145
|
+
await fs.mkdir(path.join(outDir, 'static'), { recursive: true });
|
|
146
|
+
await fs.writeFile(path.join(outDir, 'static/manifest.json'), JSON.stringify(manifest, null, 2));
|
|
147
|
+
}
|
|
148
|
+
async copyStaticFiles() {
|
|
149
|
+
const { rootDir, outDir } = this.options;
|
|
150
|
+
const staticDir = path.join(rootDir, 'src/static');
|
|
151
|
+
const targetDir = path.join(outDir, 'static');
|
|
152
|
+
try {
|
|
153
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
154
|
+
const files = await glob('**/*', { cwd: staticDir, nodir: true });
|
|
155
|
+
for (const file of files) {
|
|
156
|
+
const srcFile = path.join(staticDir, file);
|
|
157
|
+
const destFile = path.join(targetDir, file);
|
|
158
|
+
await fs.mkdir(path.dirname(destFile), { recursive: true });
|
|
159
|
+
await fs.copyFile(srcFile, destFile);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
// Static directory might not exist, that's okay
|
|
164
|
+
if (error.code !== 'ENOENT') {
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async clean() {
|
|
170
|
+
const { outDir } = this.options;
|
|
171
|
+
await fs.rm(outDir, { recursive: true, force: true });
|
|
172
|
+
}
|
|
173
|
+
async build() {
|
|
174
|
+
await this.clean();
|
|
175
|
+
await this.buildServer();
|
|
176
|
+
await this.buildClient();
|
|
177
|
+
await this.copyStaticFiles();
|
|
178
|
+
await this.generateManifest();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/build/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAGA,wBAAsB,KAAK,kBAe1B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Builder } from '../build/index.js';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function build() {
|
|
4
|
+
const rootDir = process.cwd();
|
|
5
|
+
const outDir = path.join(rootDir, 'dist');
|
|
6
|
+
console.log('Building application...');
|
|
7
|
+
const builder = new Builder({ rootDir, outDir });
|
|
8
|
+
try {
|
|
9
|
+
await builder.build();
|
|
10
|
+
console.log('✓ Build completed successfully!');
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
console.error('✗ Build failed:', error);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAmBA,wBAAsB,GAAG,kBA+CxB"}
|
package/dist/cli/dev.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Builder } from '../build/index.js';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { watch } from 'chokidar';
|
|
4
|
+
import { spawn } from 'node:child_process';
|
|
5
|
+
let serverProcess = null;
|
|
6
|
+
function startServer() {
|
|
7
|
+
if (serverProcess) {
|
|
8
|
+
serverProcess.kill();
|
|
9
|
+
}
|
|
10
|
+
const serverPath = path.join(process.cwd(), 'dist/server.js');
|
|
11
|
+
serverProcess = spawn('node', [serverPath], {
|
|
12
|
+
stdio: 'inherit',
|
|
13
|
+
env: { ...process.env, NODE_ENV: 'development' },
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function dev() {
|
|
17
|
+
const rootDir = process.cwd();
|
|
18
|
+
const outDir = path.join(rootDir, 'dist');
|
|
19
|
+
console.log('Starting development server...');
|
|
20
|
+
const builder = new Builder({ rootDir, outDir });
|
|
21
|
+
// Initial build
|
|
22
|
+
try {
|
|
23
|
+
await builder.build();
|
|
24
|
+
console.log('✓ Initial build completed!');
|
|
25
|
+
startServer();
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error('✗ Build failed:', error);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
// Watch for changes
|
|
32
|
+
const watcher = watch('src/**/*.{ts,tsx,css}', {
|
|
33
|
+
cwd: rootDir,
|
|
34
|
+
ignoreInitial: true,
|
|
35
|
+
});
|
|
36
|
+
watcher.on('change', async (filePath) => {
|
|
37
|
+
console.log(`\nFile changed: ${filePath}`);
|
|
38
|
+
console.log('Rebuilding...');
|
|
39
|
+
try {
|
|
40
|
+
await builder.build();
|
|
41
|
+
console.log('✓ Rebuild completed!');
|
|
42
|
+
startServer();
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error('✗ Rebuild failed:', error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
// Handle process termination
|
|
49
|
+
process.on('SIGINT', () => {
|
|
50
|
+
if (serverProcess) {
|
|
51
|
+
serverProcess.kill();
|
|
52
|
+
}
|
|
53
|
+
watcher.close();
|
|
54
|
+
process.exit(0);
|
|
55
|
+
});
|
|
56
|
+
console.log('\n👀 Watching for changes...\n');
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,IAAI,aAAa,GAAoC,IAAI,CAAC;AAE1D,SAAS,WAAW;IAClB,IAAI,aAAa,EAAE,CAAC;QAClB,aAAa,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAC9D,aAAa,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE;QAC1C,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,aAAa,EAAE;KACjD,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAEjD,gBAAgB;IAChB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,WAAW,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oBAAoB;IACpB,MAAM,OAAO,GAAG,KAAK,CAAC,uBAAuB,EAAE;QAC7C,GAAG,EAAE,OAAO;QACZ,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QACtC,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,WAAW,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAGA,wBAAsB,KAAK,kBAoB1B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
export async function start() {
|
|
4
|
+
const serverPath = path.join(process.cwd(), 'dist/server.js');
|
|
5
|
+
console.log('Starting production server...');
|
|
6
|
+
const serverProcess = spawn('node', [serverPath], {
|
|
7
|
+
stdio: 'inherit',
|
|
8
|
+
env: { ...process.env, NODE_ENV: 'production' },
|
|
9
|
+
});
|
|
10
|
+
serverProcess.on('error', (error) => {
|
|
11
|
+
console.error('Failed to start server:', error);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
});
|
|
14
|
+
// Handle process termination
|
|
15
|
+
process.on('SIGINT', () => {
|
|
16
|
+
serverProcess.kill();
|
|
17
|
+
process.exit(0);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/cli/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,gBAAgB,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAE7C,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE;QAChD,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE;KAChD,CAAC,CAAC;IAEH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAClC,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;QAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,aAAa,CAAC,IAAI,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Page/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,eAAO,MAAM,IAAI,GAAI,qBAAqB,SAAS,KAAG,GAAG,CAAC,OAkBzD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAssets } from "../../utils/assets-context.js";
|
|
3
|
+
export const Page = ({ children, title }) => {
|
|
4
|
+
const { styleSheet, clientScript } = useAssets();
|
|
5
|
+
return (_jsxs("html", { lang: "en", children: [_jsxs("head", { children: [_jsx("meta", { charSet: "UTF-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), _jsx("title", { children: title }), styleSheet && _jsx("link", { rel: "stylesheet", href: `/${styleSheet}` }), clientScript && _jsx("script", { src: `/${clientScript}`, defer: true })] }), _jsx("body", { children: children })] }));
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/Page/index.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAO1D,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAa,EAAe,EAAE;IAClE,MAAM,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,SAAS,EAAE,CAAC;IAEjD,OAAO,CACL,gBAAM,IAAI,EAAC,IAAI,aACb,2BACE,eAAM,OAAO,EAAC,OAAO,GAAG,EACxB,eAAM,IAAI,EAAC,UAAU,EAAC,OAAO,EAAC,uCAAuC,GAAG,EACxE,0BAAQ,KAAK,GAAS,EACrB,UAAU,IAAI,eAAM,GAAG,EAAC,YAAY,EAAC,IAAI,EAAE,IAAI,UAAU,EAAE,GAAI,EAC/D,YAAY,IAAI,iBAAQ,GAAG,EAAE,IAAI,YAAY,EAAE,EAAE,KAAK,SAAG,IACrD,EAEP,yBACG,QAAQ,GACJ,IACF,CACR,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--bg-primary: #1C1C1C;
|
|
3
|
+
--text-primary: #F5E8D8;
|
|
4
|
+
|
|
5
|
+
--spacing-md: 1rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
*,
|
|
9
|
+
*::before,
|
|
10
|
+
*::after {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
html {
|
|
17
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
18
|
+
font-size: 16px;
|
|
19
|
+
scroll-behavior: smooth;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
body {
|
|
23
|
+
min-height: 100dvh;
|
|
24
|
+
line-height: 1.5;
|
|
25
|
+
color: var(--text-primary);
|
|
26
|
+
background-color: var(--bg-primary);
|
|
27
|
+
-webkit-font-smoothing: antialiased;
|
|
28
|
+
-moz-osx-font-smoothing: grayscale;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.container {
|
|
32
|
+
max-width: 1200px;
|
|
33
|
+
margin: 0 auto;
|
|
34
|
+
padding: 0 var(--spacing-md);
|
|
35
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
const Page = ({ children, title = "IonCore", description, request }) => {
|
|
4
|
+
const clientScript = request.ioncore.clientScript;
|
|
5
|
+
const styleSheet = request.ioncore.styleSheet;
|
|
6
|
+
const ionCoreCSS = request.ioncore.assets.get('ioncore.css');
|
|
7
|
+
return (jsxs("html", { lang: "en", children: [jsxs("head", { children: [jsx("meta", { charSet: "UTF-8" }), jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), description && jsx("meta", { name: "description", content: description }), jsx("title", { children: title }), ionCoreCSS && jsx("link", { rel: "stylesheet", href: `/${ionCoreCSS}` }), styleSheet && jsx("link", { rel: "stylesheet", href: `/${styleSheet}` }), clientScript && jsx("script", { src: `/${clientScript}`, defer: true })] }), jsx("body", { children: children })] }));
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { Page };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createServer, ionBeamMiddleware } from './server/index.js';
|
|
2
|
+
export type { ServerOptions, IonBeam } from './server/index.js';
|
|
3
|
+
export { Page } from './components/Page/index.js';
|
|
4
|
+
export type { PageProps } from './components/Page/index.js';
|
|
5
|
+
export type { IonBeamRequest } from './types.js';
|
|
6
|
+
export { getAsset, getManifest } from './utils/manifest.js';
|
|
7
|
+
export { Builder } from './build/index.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Server exports
|
|
2
|
+
export { createServer, ionBeamMiddleware } from './server/index.js';
|
|
3
|
+
export { Page } from './components/Page/index.js';
|
|
4
|
+
// Utility exports
|
|
5
|
+
export { getAsset, getManifest } from './utils/manifest.js';
|
|
6
|
+
// Build exports (for advanced users)
|
|
7
|
+
export { Builder } from './build/index.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAMlD,kBAAkB;AAClB,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE5D,qCAAqC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/ioncore.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--bg-primary:#1c1c1c;--text-primary:#f5e8d8;--spacing-md:1rem}*,:after,:before{box-sizing:border-box;margin:0;padding:0}html{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-size:16px;scroll-behavior:smooth}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:var(--bg-primary);color:var(--text-primary);line-height:1.5;min-height:100dvh}.container{margin:0 auto;max-width:1200px;padding:0 var(--spacing-md)}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { JSX } from 'react/jsx-runtime';
|
|
2
|
+
import { Express, Request, Response, NextFunction } from 'express';
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Express {
|
|
5
|
+
interface Request {
|
|
6
|
+
ionbeam: IonBeam;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export interface IonBeam {
|
|
11
|
+
render: (component: JSX.Element) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export interface ServerOptions {
|
|
14
|
+
staticDir?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Middleware that adds IonBeam context to request object
|
|
18
|
+
* This allows route handlers to access assets and rendering utilities
|
|
19
|
+
*/
|
|
20
|
+
export declare function ionBeamMiddleware(options?: ServerOptions): (req: Request, res: Response, next: NextFunction) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Create an Express server with IonBeam defaults
|
|
23
|
+
* Returns a configured Express app that you can customize
|
|
24
|
+
*/
|
|
25
|
+
export declare function createServer(options?: ServerOptions): Express;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAO5E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO,CAAC;QAChB,UAAU,OAAO;YACf,OAAO,EAAE,OAAO,CAAC;SAClB;KACF;CACF;AAED,MAAM,WAAW,OAAO;IACtB,MAAM,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,aAAkB,IACnD,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAqBxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAajE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import express from 'express';
|
|
3
|
+
import { prerenderToNodeStream } from 'react-dom/static';
|
|
4
|
+
import { getAsset } from '../utils/manifest.js';
|
|
5
|
+
import { AssetsProvider } from '../utils/assets-context.js';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Middleware that adds IonBeam context to request object
|
|
9
|
+
* This allows route handlers to access assets and rendering utilities
|
|
10
|
+
*/
|
|
11
|
+
export function ionBeamMiddleware(options = {}) {
|
|
12
|
+
return (req, res, next) => {
|
|
13
|
+
const clientScript = getAsset('client.js');
|
|
14
|
+
const styleSheet = getAsset('server.css');
|
|
15
|
+
console.log('IonBeam Middleware: Attaching IonBeam context to request');
|
|
16
|
+
console.log(` - Client Script: ${clientScript}`);
|
|
17
|
+
console.log(` - Style Sheet: ${styleSheet}`);
|
|
18
|
+
req.ionbeam = {
|
|
19
|
+
render: async (element) => {
|
|
20
|
+
const { prelude } = await prerenderToNodeStream(_jsx(AssetsProvider, { value: { clientScript, styleSheet }, children: element }));
|
|
21
|
+
prelude.pipe(res);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
next();
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create an Express server with IonBeam defaults
|
|
29
|
+
* Returns a configured Express app that you can customize
|
|
30
|
+
*/
|
|
31
|
+
export function createServer(options = {}) {
|
|
32
|
+
const app = express();
|
|
33
|
+
const staticDir = options.staticDir || path.join(process.cwd(), 'dist', 'static');
|
|
34
|
+
// Default middleware
|
|
35
|
+
app.use(express.static(staticDir));
|
|
36
|
+
app.use(express.urlencoded({ extended: true }));
|
|
37
|
+
app.use(express.json());
|
|
38
|
+
// Add IonBeam context to all requests
|
|
39
|
+
app.use(ionBeamMiddleware(options));
|
|
40
|
+
return app;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.tsx"],"names":[],"mappings":";AACA,OAAO,OAAqD,MAAM,SAAS,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,IAAI,MAAM,WAAW,CAAC;AAmB7B;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAyB,EAAE;IAC3D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACzD,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QAE1C,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,mBAAmB,UAAU,EAAE,CAAC,CAAC;QAE7C,GAAG,CAAC,OAAO,GAAG;YACZ,MAAM,EAAE,KAAK,EAAE,OAAwB,EAAE,EAAE;gBACzC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,qBAAqB,CAC7C,KAAC,cAAc,IAAC,KAAK,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,YAChD,OAAO,GACO,CAClB,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;SACF,CAAC;QAEF,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,UAAyB,EAAE;IACtD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAElF,qBAAqB;IACrB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAExB,sCAAsC;IACtC,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;IAEpC,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,OAAO,EAAE,OAAO,CAAC;CAClB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface AssetsContextValue {
|
|
2
|
+
styleSheet: string | null;
|
|
3
|
+
clientScript: string | null;
|
|
4
|
+
}
|
|
5
|
+
export declare const AssetsContext: import("react").Context<AssetsContextValue>;
|
|
6
|
+
export declare const AssetsProvider: import("react").Provider<AssetsContextValue>;
|
|
7
|
+
export declare const useAssets: () => AssetsContextValue;
|
|
8
|
+
//# sourceMappingURL=assets-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets-context.d.ts","sourceRoot":"","sources":["../../src/utils/assets-context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,eAAO,MAAM,aAAa,6CAGxB,CAAC;AAEH,eAAO,MAAM,cAAc,8CAAyB,CAAC;AAErD,eAAO,MAAM,SAAS,QAAO,kBAA+C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
export const AssetsContext = createContext({
|
|
3
|
+
styleSheet: null,
|
|
4
|
+
clientScript: null,
|
|
5
|
+
});
|
|
6
|
+
export const AssetsProvider = AssetsContext.Provider;
|
|
7
|
+
export const useAssets = () => useContext(AssetsContext);
|
|
8
|
+
//# sourceMappingURL=assets-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assets-context.js","sourceRoot":"","sources":["../../src/utils/assets-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAOlD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB;IAC7D,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI;CACnB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;AAErD,MAAM,CAAC,MAAM,SAAS,GAAG,GAAuB,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,QAAO,MAAM,CAAC,MAAM,EAAE,MAAM,CAenD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,WAAW,MAAM,KAAG,MAAM,GAAG,IAGrD,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
let manifestCache = null;
|
|
4
|
+
export const getManifest = () => {
|
|
5
|
+
if (manifestCache !== null) {
|
|
6
|
+
return manifestCache;
|
|
7
|
+
}
|
|
8
|
+
try {
|
|
9
|
+
const manifestPath = join(process.cwd(), 'dist', 'static', 'manifest.json');
|
|
10
|
+
const manifestContent = readFileSync(manifestPath, 'utf-8');
|
|
11
|
+
const manifest = JSON.parse(manifestContent);
|
|
12
|
+
manifestCache = manifest;
|
|
13
|
+
return manifest;
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
console.warn('Could not read manifest.json, client scripts may not be available');
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
export const getAsset = (assetName) => {
|
|
21
|
+
const manifest = getManifest();
|
|
22
|
+
return manifest[assetName] ?? null;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,IAAI,aAAa,GAAkC,IAAI,CAAC;AAExD,MAAM,CAAC,MAAM,WAAW,GAAG,GAA2B,EAAE;IACtD,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC5E,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC7C,aAAa,GAAG,QAAQ,CAAC;QACzB,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,mEAAmE,CAAC,CAAC;QAClF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,SAAiB,EAAiB,EAAE;IAC3D,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC;AACrC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ionbeam",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"description": "A pure React SSR framework with automatic asset hashing and CSS modules",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"ionbeam": "./bin/ionbeam.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./server": {
|
|
17
|
+
"types": "./dist/server/index.d.ts",
|
|
18
|
+
"import": "./dist/server/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./utils": {
|
|
21
|
+
"types": "./dist/utils/manifest.d.ts",
|
|
22
|
+
"import": "./dist/utils/manifest.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"bin"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"prepublishOnly": "npm run build"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"react",
|
|
35
|
+
"ssr",
|
|
36
|
+
"framework",
|
|
37
|
+
"server-side-rendering",
|
|
38
|
+
"css-modules"
|
|
39
|
+
],
|
|
40
|
+
"author": {
|
|
41
|
+
"name": "Martin Podloucký",
|
|
42
|
+
"email": "podlouckymartin@gmail.com"
|
|
43
|
+
},
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"react": "^19.0.0",
|
|
47
|
+
"react-dom": "^19.0.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
51
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
52
|
+
"chokidar": "^4.0.3",
|
|
53
|
+
"commander": "^12.1.0",
|
|
54
|
+
"express": "^5.2.1",
|
|
55
|
+
"glob": "^13.0.0",
|
|
56
|
+
"postcss": "^8.5.6",
|
|
57
|
+
"postcss-modules": "^6.0.1",
|
|
58
|
+
"rollup": "^4.54.0",
|
|
59
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
60
|
+
"tslib": "^2.8.1",
|
|
61
|
+
"typescript": "^5.9.3"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/express": "^5.0.6",
|
|
65
|
+
"@types/node": "^20.4.2",
|
|
66
|
+
"@types/react": "^19.2.7",
|
|
67
|
+
"@types/react-dom": "^19.2.3"
|
|
68
|
+
}
|
|
69
|
+
}
|