hyperspan 1.0.0-alpha.1 → 1.0.0-alpha.3
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/package.json +3 -2
- package/src/server.ts +64 -55
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyperspan",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.3",
|
|
4
4
|
"description": "Hyperspan CLI - for @hyperspan/framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"public": true,
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/bun": "^1.3.2",
|
|
41
41
|
"@types/degit": "^2.8.6",
|
|
42
|
-
"@types/node": "^24.10.0"
|
|
42
|
+
"@types/node": "^24.10.0",
|
|
43
|
+
"bun-plugin-tailwind": "^0.1.2"
|
|
43
44
|
}
|
|
44
45
|
}
|
package/src/server.ts
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
import { Glob } from
|
|
2
|
-
import { createServer, getRunnableRoute, IS_PROD, parsePath } from '@hyperspan/framework';
|
|
1
|
+
import { Glob } from 'bun';
|
|
2
|
+
import { createServer, getRunnableRoute, IS_PROD, isValidRoutePath, parsePath } from '@hyperspan/framework';
|
|
3
3
|
import { CSS_PUBLIC_PATH, CSS_ROUTE_MAP } from '@hyperspan/framework/client/css';
|
|
4
|
-
import { join } from
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import tailwind from "bun-plugin-tailwind"
|
|
5
6
|
|
|
6
7
|
import type { Hyperspan as HS } from '@hyperspan/framework';
|
|
7
8
|
type startConfig = {
|
|
8
9
|
development?: boolean;
|
|
9
|
-
}
|
|
10
|
+
};
|
|
10
11
|
|
|
11
12
|
const CWD = process.cwd();
|
|
12
13
|
|
|
13
14
|
export async function loadConfig(): Promise<HS.Config> {
|
|
14
|
-
const configFile = join(CWD,
|
|
15
|
-
const configModule = await import(configFile)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const configFile = join(CWD, 'hyperspan.config.ts');
|
|
16
|
+
const configModule = await import(configFile)
|
|
17
|
+
.then((module) => module.default)
|
|
18
|
+
.catch((error) => {
|
|
19
|
+
console.error(`[Hyperspan] Unable to load config file: ${error}`);
|
|
20
|
+
console.error(
|
|
21
|
+
`[Hyperspan] Please create a hyperspan.config.ts file in the root of your project.`
|
|
22
|
+
);
|
|
23
|
+
console.log(`[Hyperspan] Example:
|
|
19
24
|
import { createConfig } from '@hyperspan/framework';
|
|
20
25
|
|
|
21
26
|
export default createConfig({
|
|
@@ -23,8 +28,8 @@ export default createConfig({
|
|
|
23
28
|
publicDir: './public',
|
|
24
29
|
});
|
|
25
30
|
`);
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
28
33
|
return configModule;
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -38,10 +43,10 @@ export async function startServer(startConfig: startConfig = {}): Promise<HS.Ser
|
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
export async function addRoutes(server: HS.Server, startConfig: startConfig) {
|
|
41
|
-
const routesGlob = new Glob(
|
|
46
|
+
const routesGlob = new Glob('**/*.ts');
|
|
42
47
|
const routeFiles: string[] = [];
|
|
43
|
-
const appDir = server._config.appDir ||
|
|
44
|
-
const routesDir = join(CWD, appDir,
|
|
48
|
+
const appDir = server._config.appDir || './app';
|
|
49
|
+
const routesDir = join(CWD, appDir, 'routes');
|
|
45
50
|
const buildDir = join(CWD, '.build');
|
|
46
51
|
const cssPublicDir = join(CWD, server._config.publicDir, CSS_PUBLIC_PATH);
|
|
47
52
|
|
|
@@ -57,53 +62,57 @@ export async function addRoutes(server: HS.Server, startConfig: startConfig) {
|
|
|
57
62
|
routeFiles.push(filePath);
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
const routeMap: { route: string
|
|
61
|
-
const routes: HS.Route[] = await Promise.all(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
// Wasteful perhaps to compile the JS also and then just discard it, but it's an easy way to do CSS compilation by route
|
|
70
|
-
const buildResult = await Bun.build({
|
|
71
|
-
entrypoints: [filePath],
|
|
72
|
-
outdir: buildDir,
|
|
73
|
-
naming: `app/routes/${path.endsWith('/') ? path + 'index' : path}-[hash].[ext]`,
|
|
74
|
-
minify: IS_PROD,
|
|
75
|
-
format: 'esm',
|
|
76
|
-
target: 'node',
|
|
77
|
-
env: 'APP_PUBLIC_*',
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Move CSS files to the public directory
|
|
81
|
-
for (const output of buildResult.outputs) {
|
|
82
|
-
if (output.path.endsWith('.css')) {
|
|
83
|
-
const cssFileName = output.path.split('/').pop()!;
|
|
84
|
-
await Bun.write(join(cssPublicDir, cssFileName), Bun.file(output.path));
|
|
85
|
-
cssFiles.push(cssFileName);
|
|
65
|
+
const routeMap: { route: string; file: string }[] = [];
|
|
66
|
+
const routes: HS.Route[] = (await Promise.all(
|
|
67
|
+
routeFiles
|
|
68
|
+
.map(async (filePath) => {
|
|
69
|
+
const relativePath = filePath.split('app/routes/').pop();
|
|
70
|
+
const { path } = parsePath(relativePath ?? '/');
|
|
71
|
+
|
|
72
|
+
if (!isValidRoutePath(path)) {
|
|
73
|
+
return null;
|
|
86
74
|
}
|
|
87
|
-
}
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
|
|
76
|
+
let cssFiles: string[] = [];
|
|
77
|
+
|
|
78
|
+
// Build the route just for the CSS files (expensive, but easiest way to do CSS compilation by route)
|
|
79
|
+
// @TODO: Optimize this at some later date... This is O(n) for each route and doesn't scale well for large projects.
|
|
80
|
+
// @TODO: This will also currently re-compile the same CSS file(s) that are included in multiple routes, which is dumb.
|
|
81
|
+
const buildResult = await Bun.build({
|
|
82
|
+
plugins: [tailwind],
|
|
83
|
+
entrypoints: [filePath],
|
|
84
|
+
outdir: buildDir,
|
|
85
|
+
naming: `app/routes/${path.endsWith('/') ? path + 'index' : path}-[hash].[ext]`,
|
|
86
|
+
minify: IS_PROD,
|
|
87
|
+
format: 'esm',
|
|
88
|
+
target: 'node',
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Move CSS files to the public directory
|
|
92
|
+
for (const output of buildResult.outputs) {
|
|
93
|
+
if (output.path.endsWith('.css')) {
|
|
94
|
+
const cssFileName = output.path.split('/').pop()!;
|
|
95
|
+
await Bun.write(join(cssPublicDir, cssFileName), Bun.file(output.path));
|
|
96
|
+
cssFiles.push(cssFileName);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
91
99
|
|
|
92
|
-
|
|
93
|
-
|
|
100
|
+
const routeModule = await import(filePath);
|
|
101
|
+
const route = getRunnableRoute(routeModule);
|
|
94
102
|
|
|
95
|
-
|
|
96
|
-
route._config.
|
|
97
|
-
CSS_ROUTE_MAP.set(path, cssFiles);
|
|
98
|
-
}
|
|
103
|
+
// Set route path based on the file path
|
|
104
|
+
route._config.path = path;
|
|
99
105
|
|
|
100
|
-
|
|
106
|
+
if (cssFiles.length > 0) {
|
|
107
|
+
route._config.cssImports = cssFiles;
|
|
108
|
+
CSS_ROUTE_MAP.set(path, cssFiles);
|
|
109
|
+
}
|
|
101
110
|
|
|
102
|
-
|
|
103
|
-
}
|
|
111
|
+
routeMap.push({ route: path, file: filePath.replace(CWD, '') });
|
|
104
112
|
|
|
105
|
-
|
|
106
|
-
|
|
113
|
+
return route;
|
|
114
|
+
})
|
|
115
|
+
)).filter((route) => route !== null);
|
|
107
116
|
|
|
108
117
|
if (startConfig.development) {
|
|
109
118
|
console.log('[Hyperspan] Loaded routes:');
|
|
@@ -111,4 +120,4 @@ export async function addRoutes(server: HS.Server, startConfig: startConfig) {
|
|
|
111
120
|
}
|
|
112
121
|
|
|
113
122
|
server._routes.push(...routes);
|
|
114
|
-
}
|
|
123
|
+
}
|