alepha 0.15.0 → 0.15.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 +43 -98
- package/dist/api/audits/index.d.ts +240 -240
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/audits/index.js +2 -2
- package/dist/api/audits/index.js.map +1 -1
- package/dist/api/files/index.d.ts +185 -185
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +2 -2
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +245 -245
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.browser.js +4 -4
- package/dist/api/notifications/index.browser.js.map +1 -1
- package/dist/api/notifications/index.d.ts +74 -74
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/notifications/index.js +4 -4
- package/dist/api/notifications/index.js.map +1 -1
- package/dist/api/parameters/index.d.ts +221 -221
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.d.ts +1632 -1631
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +26 -34
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +132 -132
- package/dist/api/verifications/index.d.ts.map +1 -1
- package/dist/batch/index.d.ts +122 -122
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/bucket/index.d.ts +163 -163
- package/dist/bucket/index.d.ts.map +1 -1
- package/dist/cache/core/index.d.ts +46 -46
- package/dist/cache/core/index.d.ts.map +1 -1
- package/dist/cache/redis/index.d.ts.map +1 -1
- package/dist/cache/redis/index.js +2 -2
- package/dist/cache/redis/index.js.map +1 -1
- package/dist/cli/index.d.ts +5933 -201
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +609 -169
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +296 -296
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +19 -19
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +268 -79
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +768 -694
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +268 -79
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +268 -79
- package/dist/core/index.native.js.map +1 -1
- package/dist/datetime/index.d.ts +44 -44
- package/dist/datetime/index.d.ts.map +1 -1
- package/dist/email/index.d.ts +25 -25
- package/dist/email/index.d.ts.map +1 -1
- package/dist/fake/index.d.ts +5409 -5409
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/fake/index.js +22 -22
- package/dist/fake/index.js.map +1 -1
- package/dist/file/index.d.ts +435 -435
- package/dist/file/index.d.ts.map +1 -1
- package/dist/lock/core/index.d.ts +208 -208
- package/dist/lock/core/index.d.ts.map +1 -1
- package/dist/lock/redis/index.d.ts.map +1 -1
- package/dist/logger/index.d.ts +24 -24
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +1 -5
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +216 -198
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +28 -4
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/index.browser.js +9 -9
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +83 -76
- package/dist/orm/index.bun.js.map +1 -1
- package/dist/orm/index.d.ts +961 -960
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +88 -81
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +244 -244
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.d.ts +105 -105
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/retry/index.d.ts +69 -69
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/router/index.d.ts +6 -6
- package/dist/router/index.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +108 -26
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +393 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/security/index.d.ts +532 -209
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +1422 -11
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +1296 -271
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +1249 -18
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +56 -56
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/compress/index.d.ts +3 -3
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/cookies/index.d.ts +6 -6
- package/dist/server/cookies/index.d.ts.map +1 -1
- package/dist/server/core/index.d.ts +196 -186
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +43 -27
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -11
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts.map +1 -1
- package/dist/server/helmet/index.d.ts +2 -2
- package/dist/server/helmet/index.d.ts.map +1 -1
- package/dist/server/links/index.browser.js +9 -1
- package/dist/server/links/index.browser.js.map +1 -1
- package/dist/server/links/index.d.ts +83 -83
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +13 -5
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts +514 -1
- package/dist/server/metrics/index.d.ts.map +1 -1
- package/dist/server/metrics/index.js +4462 -4
- package/dist/server/metrics/index.js.map +1 -1
- package/dist/server/multipart/index.d.ts +6 -6
- package/dist/server/multipart/index.d.ts.map +1 -1
- package/dist/server/proxy/index.d.ts +102 -102
- package/dist/server/proxy/index.d.ts.map +1 -1
- package/dist/server/rate-limit/index.d.ts +16 -16
- package/dist/server/rate-limit/index.d.ts.map +1 -1
- package/dist/server/static/index.d.ts +44 -44
- package/dist/server/static/index.d.ts.map +1 -1
- package/dist/server/swagger/index.d.ts +47 -47
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/sms/index.d.ts +11 -11
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +3 -3
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +71 -71
- package/dist/thread/index.d.ts.map +1 -1
- package/dist/thread/index.js +2 -2
- package/dist/thread/index.js.map +1 -1
- package/dist/topic/core/index.d.ts +318 -318
- package/dist/topic/core/index.d.ts.map +1 -1
- package/dist/topic/redis/index.d.ts +6 -6
- package/dist/topic/redis/index.d.ts.map +1 -1
- package/dist/vite/index.d.ts +2324 -1719
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +123 -475
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +3 -3
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +275 -275
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +3 -3
- package/dist/websocket/index.js.map +1 -1
- package/package.json +9 -9
- package/src/api/users/services/SessionService.ts +0 -10
- package/src/cli/apps/AlephaCli.ts +2 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +9 -1
- package/src/cli/assets/apiHelloControllerTs.ts +2 -1
- package/src/cli/assets/biomeJson.ts +2 -1
- package/src/cli/assets/claudeMd.ts +9 -4
- package/src/cli/assets/dummySpecTs.ts +2 -1
- package/src/cli/assets/editorconfig.ts +2 -1
- package/src/cli/assets/mainBrowserTs.ts +2 -1
- package/src/cli/assets/mainCss.ts +24 -0
- package/src/cli/assets/tsconfigJson.ts +2 -1
- package/src/cli/assets/webAppRouterTs.ts +2 -1
- package/src/cli/assets/webHelloComponentTsx.ts +6 -2
- package/src/cli/atoms/appEntryOptions.ts +13 -0
- package/src/cli/atoms/buildOptions.ts +1 -1
- package/src/cli/atoms/changelogOptions.ts +1 -1
- package/src/cli/commands/build.ts +63 -47
- package/src/cli/commands/dev.ts +16 -33
- package/src/cli/commands/gen/env.ts +1 -1
- package/src/cli/commands/init.ts +17 -8
- package/src/cli/commands/lint.ts +1 -1
- package/src/cli/defineConfig.ts +9 -0
- package/src/cli/index.ts +2 -1
- package/src/cli/providers/AppEntryProvider.ts +131 -0
- package/src/cli/providers/ViteBuildProvider.ts +82 -0
- package/src/cli/providers/ViteDevServerProvider.ts +350 -0
- package/src/cli/providers/ViteTemplateProvider.ts +27 -0
- package/src/cli/services/AlephaCliUtils.ts +33 -2
- package/src/cli/services/PackageManagerUtils.ts +13 -6
- package/src/cli/services/ProjectScaffolder.ts +72 -49
- package/src/core/Alepha.ts +2 -8
- package/src/core/primitives/$module.ts +12 -0
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +257 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +396 -14
- package/src/core/providers/SchemaValidator.spec.ts +236 -0
- package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
- package/src/mcp/errors/McpError.ts +30 -0
- package/src/mcp/index.ts +3 -0
- package/src/mcp/transports/SseMcpTransport.ts +16 -6
- package/src/orm/providers/DrizzleKitProvider.ts +3 -5
- package/src/orm/services/Repository.ts +11 -0
- package/src/server/core/index.ts +1 -1
- package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
- package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
- package/src/server/core/providers/NodeHttpServerProvider.ts +71 -22
- package/src/server/core/providers/ServerLoggerProvider.ts +2 -2
- package/src/server/core/providers/ServerProvider.ts +9 -12
- package/src/server/links/atoms/apiLinksAtom.ts +7 -0
- package/src/server/links/index.browser.ts +2 -0
- package/src/server/links/index.ts +2 -0
- package/src/vite/index.ts +3 -2
- package/src/vite/tasks/buildClient.ts +0 -1
- package/src/vite/tasks/buildServer.ts +68 -21
- package/src/vite/tasks/copyAssets.ts +5 -4
- package/src/vite/tasks/generateSitemap.ts +64 -23
- package/src/vite/tasks/index.ts +0 -2
- package/src/vite/tasks/prerenderPages.ts +49 -24
- package/src/cli/assets/indexHtml.ts +0 -15
- package/src/cli/commands/format.ts +0 -23
- package/src/vite/helpers/boot.ts +0 -117
- package/src/vite/plugins/viteAlephaDev.ts +0 -177
- package/src/vite/tasks/devServer.ts +0 -71
- package/src/vite/tasks/runAlepha.ts +0 -270
- /package/dist/orm/{chunk-DtkW-qnP.js → chunk-DH6iiROE.js} +0 -0
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
-
import type { Plugin, ResolvedConfig, UserConfig } from "vite";
|
|
3
|
-
import { boot } from "../helpers/boot.ts";
|
|
4
|
-
import { importVite } from "../helpers/importVite.ts";
|
|
5
|
-
import { createAlephaRunner, isViteInternalPath } from "../tasks/runAlepha.ts";
|
|
6
|
-
|
|
7
|
-
export interface ViteAlephaDevOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Path to the entry file for the server build.
|
|
10
|
-
* If empty, plugin will be disabled.
|
|
11
|
-
*/
|
|
12
|
-
serverEntry?: string | false;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* If true, enables debug logging.
|
|
16
|
-
*
|
|
17
|
-
* @default false
|
|
18
|
-
*/
|
|
19
|
-
debug?: boolean;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Plug Alepha into Vite development server.
|
|
24
|
-
*
|
|
25
|
-
* This plugin manages the Alepha application lifecycle during development,
|
|
26
|
-
* handling hot module replacement and request forwarding.
|
|
27
|
-
*/
|
|
28
|
-
export async function viteAlephaDev(
|
|
29
|
-
options: ViteAlephaDevOptions = {},
|
|
30
|
-
): Promise<Plugin> {
|
|
31
|
-
let entry = options.serverEntry;
|
|
32
|
-
if (!entry) {
|
|
33
|
-
entry = await boot.getServerEntry();
|
|
34
|
-
if (!entry) {
|
|
35
|
-
return {
|
|
36
|
-
name: "alepha-dev",
|
|
37
|
-
apply: "serve",
|
|
38
|
-
config() {},
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const runner = createAlephaRunner({
|
|
44
|
-
entry,
|
|
45
|
-
debug: options.debug,
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
const { loadEnv } = await importVite();
|
|
49
|
-
const env = loadEnv("development", process.cwd(), "SERVER");
|
|
50
|
-
|
|
51
|
-
const config: UserConfig = {};
|
|
52
|
-
if (env.SERVER_PORT) {
|
|
53
|
-
config.server = {
|
|
54
|
-
port: parseInt(env.SERVER_PORT, 10),
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
name: "alepha-dev",
|
|
60
|
-
apply: "serve",
|
|
61
|
-
config: () => config,
|
|
62
|
-
configResolved(resolvedConfig: ResolvedConfig) {
|
|
63
|
-
runner.setConfig(resolvedConfig);
|
|
64
|
-
},
|
|
65
|
-
async handleHotUpdate(ctx) {
|
|
66
|
-
if (options.debug) {
|
|
67
|
-
console.log("[DEBUG] HMR", ctx.file);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (ctx.file.includes("/.idea/")) {
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const isServerOnly = !ctx.modules[0]?._clientModule;
|
|
75
|
-
const isBrowserOnly = !ctx.modules[0]?._ssrModule;
|
|
76
|
-
const isSsrEnabled = runner.isSsrEnabled();
|
|
77
|
-
|
|
78
|
-
if (isBrowserOnly) {
|
|
79
|
-
if (options.debug) {
|
|
80
|
-
console.log(
|
|
81
|
-
"[DEBUG] HMR - browser only - no reason to reload server",
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const root = process.cwd().replace(/\\/g, "/");
|
|
88
|
-
const invalidate = !ctx.file.startsWith(root);
|
|
89
|
-
if (invalidate && options.debug) {
|
|
90
|
-
console.log("[DEBUG] HMR - outside root - invalidate all");
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (!isSsrEnabled && isServerOnly) {
|
|
94
|
-
await runner.restart(ctx.server, invalidate);
|
|
95
|
-
return [];
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (isSsrEnabled && ctx.modules[0]) {
|
|
99
|
-
const skip = await runner.restart(ctx.server, invalidate);
|
|
100
|
-
if (skip) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (!runner.isStarted) {
|
|
105
|
-
if (options.debug) {
|
|
106
|
-
console.log("[DEBUG] HMR - abort due to app not started");
|
|
107
|
-
}
|
|
108
|
-
return [];
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (isServerOnly && runner.isStarted) {
|
|
112
|
-
runner.sendReload(ctx.server);
|
|
113
|
-
return [];
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
async configureServer(server) {
|
|
118
|
-
if (env.SERVER_PORT) {
|
|
119
|
-
server.config.server.port = parseInt(env.SERVER_PORT, 10);
|
|
120
|
-
}
|
|
121
|
-
const middleware = (
|
|
122
|
-
req: IncomingMessage,
|
|
123
|
-
res: ServerResponse,
|
|
124
|
-
next: any,
|
|
125
|
-
) => {
|
|
126
|
-
if (
|
|
127
|
-
runner.isStarted &&
|
|
128
|
-
runner.app &&
|
|
129
|
-
req.url &&
|
|
130
|
-
!isViteInternalPath(req.url)
|
|
131
|
-
) {
|
|
132
|
-
// Patch res.end to detect if alepha handled the request
|
|
133
|
-
// If not, we call next() to let vite handle it (e.g. for static files)
|
|
134
|
-
let ended = false;
|
|
135
|
-
|
|
136
|
-
const writeHead = res.writeHead.bind(res);
|
|
137
|
-
res.writeHead = (...args: any[]) => {
|
|
138
|
-
ended = true;
|
|
139
|
-
return writeHead(args[0], args[1], args[2]);
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
return runner.app.events
|
|
143
|
-
.emit("node:request" as any, { req, res })
|
|
144
|
-
.then(() => {
|
|
145
|
-
if (!ended) {
|
|
146
|
-
next();
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
next();
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
// Forward vite request to alepha server
|
|
154
|
-
server.middlewares.use((req, res, next) => {
|
|
155
|
-
// TODO: wait if restarting ?
|
|
156
|
-
middleware(req, res, next);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
server.config.logger.info = (msg: string) => {
|
|
160
|
-
console.log(msg);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
server.config.logger.clearScreen = () => {};
|
|
164
|
-
|
|
165
|
-
// Return a function - it runs AFTER internal middlewares are set up
|
|
166
|
-
// and after buildStart has been called
|
|
167
|
-
return () => {
|
|
168
|
-
server.httpServer?.once("listening", () => {
|
|
169
|
-
runner.start(server);
|
|
170
|
-
});
|
|
171
|
-
};
|
|
172
|
-
},
|
|
173
|
-
async closeBundle() {
|
|
174
|
-
// Cleanup handled by runner
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import type { InlineConfig } from "vite";
|
|
2
|
-
import { importVite } from "../helpers/importVite.ts";
|
|
3
|
-
import { importViteReact } from "../helpers/importViteReact.ts";
|
|
4
|
-
import { viteAlephaDev } from "../plugins/viteAlephaDev.ts";
|
|
5
|
-
import { viteAlephaSsrPreload } from "../plugins/viteAlephaSsrPreload.ts";
|
|
6
|
-
|
|
7
|
-
export interface DevServerOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Path to the server entry file.
|
|
10
|
-
* If not provided, will auto-detect.
|
|
11
|
-
*/
|
|
12
|
-
entry?: string;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Port to run the dev server on.
|
|
16
|
-
*/
|
|
17
|
-
port?: number;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Host to bind the dev server to.
|
|
21
|
-
*/
|
|
22
|
-
host?: string | boolean;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Enable debug logging.
|
|
26
|
-
*/
|
|
27
|
-
debug?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Start Vite development server with Alepha plugins.
|
|
32
|
-
*
|
|
33
|
-
* This task starts the Vite dev server with all required plugins:
|
|
34
|
-
* - @vitejs/plugin-react (JSX/TSX compilation)
|
|
35
|
-
* - viteAlephaDev (Alepha server integration)
|
|
36
|
-
* - viteAlephaSsrPreload (SSR module preloading)
|
|
37
|
-
*/
|
|
38
|
-
export async function devServer(opts: DevServerOptions = {}): Promise<void> {
|
|
39
|
-
const { createServer, mergeConfig } = await importVite();
|
|
40
|
-
const plugins: any[] = [];
|
|
41
|
-
|
|
42
|
-
// Add React plugin for JSX/TSX compilation
|
|
43
|
-
const viteReact = await importViteReact();
|
|
44
|
-
if (viteReact) plugins.push(viteReact());
|
|
45
|
-
|
|
46
|
-
// Add SSR preload plugin
|
|
47
|
-
plugins.push(viteAlephaSsrPreload());
|
|
48
|
-
|
|
49
|
-
// Add Alepha dev plugin
|
|
50
|
-
plugins.push(
|
|
51
|
-
await viteAlephaDev({
|
|
52
|
-
serverEntry: opts.entry,
|
|
53
|
-
debug: opts.debug,
|
|
54
|
-
}),
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const config: InlineConfig = {
|
|
58
|
-
plugins,
|
|
59
|
-
server: {
|
|
60
|
-
port: opts.port,
|
|
61
|
-
host: opts.host,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const server = await createServer(mergeConfig(config, {}));
|
|
66
|
-
await server.listen();
|
|
67
|
-
|
|
68
|
-
console.log(""); // blank line
|
|
69
|
-
server.printUrls();
|
|
70
|
-
server.bindCLIShortcuts({ print: true });
|
|
71
|
-
}
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { pathToFileURL } from "node:url";
|
|
3
|
-
import type { Alepha, State } from "alepha";
|
|
4
|
-
import type { ResolvedConfig, ViteDevServer } from "vite";
|
|
5
|
-
import { importVite } from "../helpers/importVite.ts";
|
|
6
|
-
|
|
7
|
-
export interface AlephaRunnerOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Path to the server entry file.
|
|
10
|
-
*/
|
|
11
|
-
entry: string;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Enable debug logging.
|
|
15
|
-
*/
|
|
16
|
-
debug?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface AlephaRunnerState {
|
|
20
|
-
root: string;
|
|
21
|
-
started: boolean;
|
|
22
|
-
app?: Alepha;
|
|
23
|
-
config?: ResolvedConfig;
|
|
24
|
-
lock?: PromiseWithResolvers<void>;
|
|
25
|
-
log: (...msg: string[]) => void;
|
|
26
|
-
entry: string;
|
|
27
|
-
onReload?: () => void;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Create an Alepha runner for development.
|
|
32
|
-
*
|
|
33
|
-
* The runner manages the lifecycle of an Alepha application during
|
|
34
|
-
* Vite dev server operation, handling start/stop/restart and HMR.
|
|
35
|
-
*/
|
|
36
|
-
export function createAlephaRunner(opts: AlephaRunnerOptions): AlephaRunner {
|
|
37
|
-
const state: AlephaRunnerState = {
|
|
38
|
-
root: process.cwd().replace(/\\/g, "/"),
|
|
39
|
-
started: false,
|
|
40
|
-
log: opts.debug ? (...msg: string[]) => console.log(...msg) : () => {},
|
|
41
|
-
entry: opts.entry,
|
|
42
|
-
onReload: () => {},
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
return new AlephaRunner(state);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export class AlephaRunner {
|
|
49
|
-
protected state: AlephaRunnerState;
|
|
50
|
-
|
|
51
|
-
constructor(state: AlephaRunnerState) {
|
|
52
|
-
this.state = state;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Set resolved Vite config.
|
|
57
|
-
*/
|
|
58
|
-
setConfig(config: ResolvedConfig): void {
|
|
59
|
-
this.state.config = config;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Check if SSR is enabled for the running app.
|
|
64
|
-
*/
|
|
65
|
-
isSsrEnabled(): boolean {
|
|
66
|
-
if (!this.state.app) return false;
|
|
67
|
-
return (
|
|
68
|
-
(this.state.app.store.get("alepha.react.server.ssr" as keyof State) as
|
|
69
|
-
| boolean
|
|
70
|
-
| undefined) ?? false
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Check if app is started.
|
|
76
|
-
*/
|
|
77
|
-
get isStarted(): boolean {
|
|
78
|
-
return this.state.started;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Get the running Alepha app instance.
|
|
83
|
-
*/
|
|
84
|
-
get app(): Alepha | undefined {
|
|
85
|
-
return this.state.app;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Start the Alepha application.
|
|
90
|
-
*/
|
|
91
|
-
async start(server: ViteDevServer): Promise<void> {
|
|
92
|
-
const { loadEnv } = await importVite();
|
|
93
|
-
|
|
94
|
-
// unfortunately, vite SSR loader does not fix stack traces automatically
|
|
95
|
-
// for now, we make a global helper and alepha/logger will use it before logging errors
|
|
96
|
-
// that's not ideal but works for now
|
|
97
|
-
(global as any).ssrFixStacktrace = (e: Error) => {
|
|
98
|
-
server.ssrFixStacktrace(e);
|
|
99
|
-
let it: any = e;
|
|
100
|
-
do {
|
|
101
|
-
server.ssrFixStacktrace(it);
|
|
102
|
-
it = it.cause;
|
|
103
|
-
} while (it instanceof Error);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
if (this.state.started) {
|
|
107
|
-
await this.restart(server, true);
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (!this.state.config) {
|
|
112
|
-
this.state.log("[DEBUG] No config - skip starting");
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
this.state.onReload?.();
|
|
117
|
-
|
|
118
|
-
this.state.log("[DEBUG] Starting Alepha app...");
|
|
119
|
-
|
|
120
|
-
this.state.started = false;
|
|
121
|
-
this.state.app = undefined;
|
|
122
|
-
|
|
123
|
-
const serverEntryPath = path.resolve(
|
|
124
|
-
this.state.config.root,
|
|
125
|
-
this.state.entry,
|
|
126
|
-
);
|
|
127
|
-
const fileUrl = pathToFileURL(`${serverEntryPath}`).href;
|
|
128
|
-
const env = loadEnv("development", this.state.config.root, "");
|
|
129
|
-
const before = { ...process.env };
|
|
130
|
-
|
|
131
|
-
for (const key in env) {
|
|
132
|
-
process.env[key] = env[key];
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
let port = 5173;
|
|
136
|
-
const address = server.httpServer?.address();
|
|
137
|
-
if (typeof address === "object" && address?.port) {
|
|
138
|
-
port = address.port;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
process.env.NODE_ENV ??= "development";
|
|
142
|
-
process.env.VITE_ALEPHA_DEV = "true";
|
|
143
|
-
process.env.SERVER_HOST ??=
|
|
144
|
-
typeof server.config.server.host === "string"
|
|
145
|
-
? server.config.server.host
|
|
146
|
-
: "localhost";
|
|
147
|
-
process.env.SERVER_PORT ??= String(port);
|
|
148
|
-
|
|
149
|
-
try {
|
|
150
|
-
const now = Date.now();
|
|
151
|
-
await server.ssrLoadModule(fileUrl, {
|
|
152
|
-
fixStacktrace: true,
|
|
153
|
-
});
|
|
154
|
-
this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
|
|
155
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
156
|
-
|
|
157
|
-
this.state.app = (globalThis as any).__alepha;
|
|
158
|
-
if (!this.state.app) {
|
|
159
|
-
this.state.log("[DEBUG] No app found - skip starting");
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
this.state.app.store.set("alepha.node.server" as any, server.httpServer);
|
|
164
|
-
|
|
165
|
-
console.log("");
|
|
166
|
-
await this.state.app.start();
|
|
167
|
-
this.state.started = true;
|
|
168
|
-
|
|
169
|
-
process.env = { ...before };
|
|
170
|
-
|
|
171
|
-
this.state.log("[DEBUG] Starting Done!");
|
|
172
|
-
} catch (e) {
|
|
173
|
-
if (e instanceof Error) {
|
|
174
|
-
let it: any = e;
|
|
175
|
-
do {
|
|
176
|
-
server.ssrFixStacktrace(it);
|
|
177
|
-
it = it.cause;
|
|
178
|
-
} while (it instanceof Error);
|
|
179
|
-
|
|
180
|
-
server.ssrFixStacktrace(e);
|
|
181
|
-
if (e.cause instanceof Error) {
|
|
182
|
-
server.ssrFixStacktrace(e.cause);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
this.state.app?.log?.error("App failed to start:", e);
|
|
186
|
-
this.state.app?.log?.info("Waiting for changes to restart...");
|
|
187
|
-
}
|
|
188
|
-
this.state.log("[DEBUG] Alepha app start error");
|
|
189
|
-
this.state.started = false;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Stop the Alepha application.
|
|
195
|
-
*/
|
|
196
|
-
async stop(): Promise<void> {
|
|
197
|
-
if (this.state.app?.stop && this.state.started) {
|
|
198
|
-
this.state.log("[DEBUG] Stopping Alepha app...");
|
|
199
|
-
await this.state.app.stop();
|
|
200
|
-
this.state.started = false;
|
|
201
|
-
this.state.log("[DEBUG] Stopping Done!");
|
|
202
|
-
} else {
|
|
203
|
-
this.state.log("[DEBUG] Alepha app not started - skip stop");
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Restart the Alepha application.
|
|
209
|
-
*
|
|
210
|
-
* @returns true if the restart was skipped due to locking
|
|
211
|
-
*/
|
|
212
|
-
async restart(server: ViteDevServer, invalidate?: boolean): Promise<boolean> {
|
|
213
|
-
if (this.state.lock) {
|
|
214
|
-
this.state.log("[DEBUG] STILL LOCKING");
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
this.state.log("[DEBUG] LOCK RESTART");
|
|
219
|
-
this.state.lock = Promise.withResolvers();
|
|
220
|
-
|
|
221
|
-
const now = Date.now();
|
|
222
|
-
this.state.log("[DEBUG] RESTART");
|
|
223
|
-
await this.stop();
|
|
224
|
-
this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);
|
|
225
|
-
|
|
226
|
-
if (invalidate) {
|
|
227
|
-
server.moduleGraph.invalidateAll();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
await this.start(server);
|
|
231
|
-
this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);
|
|
232
|
-
|
|
233
|
-
setTimeout(() => {
|
|
234
|
-
this.state.log("[DEBUG] UNLOCK RESTART");
|
|
235
|
-
this.state.lock?.resolve();
|
|
236
|
-
this.state.lock = undefined;
|
|
237
|
-
}, 500);
|
|
238
|
-
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Send reload event to client.
|
|
244
|
-
*/
|
|
245
|
-
sendReload(server: ViteDevServer): void {
|
|
246
|
-
server.ws.send({
|
|
247
|
-
type: "custom",
|
|
248
|
-
event: "alepha:reload",
|
|
249
|
-
data: {},
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Check if a URL path is a Vite internal file.
|
|
256
|
-
*/
|
|
257
|
-
export function isViteInternalPath(pathname: string): boolean {
|
|
258
|
-
const [path] = pathname.split("?");
|
|
259
|
-
|
|
260
|
-
// Vite internal files
|
|
261
|
-
if (
|
|
262
|
-
path.startsWith("/@") ||
|
|
263
|
-
path.startsWith("/src") ||
|
|
264
|
-
path.includes("/node_modules/")
|
|
265
|
-
) {
|
|
266
|
-
return true;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return false;
|
|
270
|
-
}
|
|
File without changes
|