alepha 0.14.3 → 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.
- package/README.md +2 -5
- package/dist/api/audits/index.d.ts +620 -811
- package/dist/api/audits/index.d.ts.map +1 -1
- package/dist/api/files/index.d.ts +185 -377
- package/dist/api/files/index.d.ts.map +1 -1
- package/dist/api/files/index.js +0 -1
- package/dist/api/files/index.js.map +1 -1
- package/dist/api/jobs/index.d.ts +245 -435
- package/dist/api/jobs/index.d.ts.map +1 -1
- package/dist/api/notifications/index.d.ts +238 -429
- package/dist/api/notifications/index.d.ts.map +1 -1
- package/dist/api/parameters/index.d.ts +236 -427
- package/dist/api/parameters/index.d.ts.map +1 -1
- package/dist/api/users/index.browser.js +1 -2
- package/dist/api/users/index.browser.js.map +1 -1
- package/dist/api/users/index.d.ts +1010 -1196
- package/dist/api/users/index.d.ts.map +1 -1
- package/dist/api/users/index.js +178 -151
- package/dist/api/users/index.js.map +1 -1
- package/dist/api/verifications/index.d.ts +17 -17
- 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/batch/index.js +1 -2
- package/dist/batch/index.js.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/cli/index.d.ts +384 -285
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1113 -623
- package/dist/cli/index.js.map +1 -1
- package/dist/command/index.d.ts +299 -300
- package/dist/command/index.d.ts.map +1 -1
- package/dist/command/index.js +13 -9
- package/dist/command/index.js.map +1 -1
- package/dist/core/index.browser.js +445 -103
- package/dist/core/index.browser.js.map +1 -1
- package/dist/core/index.d.ts +733 -625
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +446 -103
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.native.js +445 -103
- 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/datetime/index.js +4 -4
- package/dist/datetime/index.js.map +1 -1
- package/dist/email/index.d.ts +97 -50
- package/dist/email/index.d.ts.map +1 -1
- package/dist/email/index.js +129 -33
- package/dist/email/index.js.map +1 -1
- package/dist/fake/index.d.ts +7981 -14
- package/dist/fake/index.d.ts.map +1 -1
- package/dist/file/index.d.ts +523 -390
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +253 -1
- package/dist/file/index.js.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 +25 -26
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +12 -2
- package/dist/logger/index.js.map +1 -1
- package/dist/mcp/index.d.ts +197 -197
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/orm/chunk-DtkW-qnP.js +38 -0
- package/dist/orm/index.browser.js.map +1 -1
- package/dist/orm/index.bun.js +2814 -0
- package/dist/orm/index.bun.js.map +1 -0
- package/dist/orm/index.d.ts +1228 -1216
- package/dist/orm/index.d.ts.map +1 -1
- package/dist/orm/index.js +2041 -1967
- package/dist/orm/index.js.map +1 -1
- package/dist/queue/core/index.d.ts +248 -248
- package/dist/queue/core/index.d.ts.map +1 -1
- package/dist/queue/redis/index.d.ts.map +1 -1
- package/dist/redis/index.bun.js +285 -0
- package/dist/redis/index.bun.js.map +1 -0
- package/dist/redis/index.d.ts +118 -136
- package/dist/redis/index.d.ts.map +1 -1
- package/dist/redis/index.js +18 -38
- package/dist/redis/index.js.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 +25 -25
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/security/index.browser.js +5 -1
- package/dist/security/index.browser.js.map +1 -1
- package/dist/security/index.d.ts +417 -254
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +386 -86
- package/dist/security/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +110 -110
- package/dist/server/auth/index.d.ts.map +1 -1
- package/dist/server/auth/index.js +20 -20
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/cache/index.d.ts +62 -47
- package/dist/server/cache/index.d.ts.map +1 -1
- package/dist/server/cache/index.js +56 -3
- package/dist/server/cache/index.js.map +1 -1
- package/dist/server/compress/index.d.ts +6 -0
- package/dist/server/compress/index.d.ts.map +1 -1
- package/dist/server/compress/index.js +36 -1
- package/dist/server/compress/index.js.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/cookies/index.js +3 -3
- package/dist/server/cookies/index.js.map +1 -1
- package/dist/server/core/index.browser.js +2 -2
- package/dist/server/core/index.browser.js.map +1 -1
- package/dist/server/core/index.d.ts +242 -150
- package/dist/server/core/index.d.ts.map +1 -1
- package/dist/server/core/index.js +294 -125
- package/dist/server/core/index.js.map +1 -1
- package/dist/server/cors/index.d.ts +11 -12
- package/dist/server/cors/index.d.ts.map +1 -1
- package/dist/server/health/index.d.ts +0 -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.map +1 -1
- package/dist/server/links/index.d.ts +123 -124
- package/dist/server/links/index.d.ts.map +1 -1
- package/dist/server/links/index.js +1 -2
- package/dist/server/links/index.js.map +1 -1
- package/dist/server/metrics/index.d.ts.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 -103
- 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/static/index.js +4 -0
- package/dist/server/static/index.js.map +1 -1
- package/dist/server/swagger/index.d.ts +48 -49
- package/dist/server/swagger/index.d.ts.map +1 -1
- package/dist/server/swagger/index.js +3 -5
- package/dist/server/swagger/index.js.map +1 -1
- package/dist/sms/index.d.ts +13 -11
- package/dist/sms/index.d.ts.map +1 -1
- package/dist/sms/index.js +7 -7
- package/dist/sms/index.js.map +1 -1
- package/dist/thread/index.d.ts +71 -72
- package/dist/thread/index.d.ts.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 +5805 -249
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +599 -513
- package/dist/vite/index.js.map +1 -1
- package/dist/websocket/index.browser.js +6 -6
- package/dist/websocket/index.browser.js.map +1 -1
- package/dist/websocket/index.d.ts +247 -247
- package/dist/websocket/index.d.ts.map +1 -1
- package/dist/websocket/index.js +6 -6
- package/dist/websocket/index.js.map +1 -1
- package/package.json +9 -14
- package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
- package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
- package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
- package/src/api/users/entities/users.ts +1 -1
- package/src/api/users/index.ts +8 -8
- package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
- package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
- package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
- package/src/api/users/services/CredentialService.ts +7 -7
- package/src/api/users/services/IdentityService.ts +4 -4
- package/src/api/users/services/RegistrationService.spec.ts +25 -27
- package/src/api/users/services/RegistrationService.ts +38 -27
- package/src/api/users/services/SessionCrudService.ts +3 -3
- package/src/api/users/services/SessionService.spec.ts +3 -3
- package/src/api/users/services/SessionService.ts +28 -9
- package/src/api/users/services/UserService.ts +7 -7
- package/src/batch/providers/BatchProvider.ts +1 -2
- package/src/cli/apps/AlephaCli.ts +0 -2
- package/src/cli/apps/AlephaPackageBuilderCli.ts +38 -19
- package/src/cli/assets/apiHelloControllerTs.ts +18 -0
- package/src/cli/assets/apiIndexTs.ts +16 -0
- package/src/cli/assets/claudeMd.ts +303 -0
- package/src/cli/assets/mainBrowserTs.ts +2 -2
- package/src/cli/assets/mainServerTs.ts +24 -0
- package/src/cli/assets/webAppRouterTs.ts +15 -0
- package/src/cli/assets/webHelloComponentTsx.ts +16 -0
- package/src/cli/assets/webIndexTs.ts +16 -0
- package/src/cli/atoms/buildOptions.ts +88 -0
- package/src/cli/commands/build.ts +70 -87
- package/src/cli/commands/db.ts +21 -22
- package/src/cli/commands/deploy.ts +17 -5
- package/src/cli/commands/dev.ts +22 -14
- package/src/cli/commands/format.ts +8 -2
- package/src/cli/commands/gen/env.ts +53 -0
- package/src/cli/commands/gen/openapi.ts +1 -1
- package/src/cli/commands/gen/resource.ts +15 -0
- package/src/cli/commands/gen.ts +7 -1
- package/src/cli/commands/init.ts +74 -30
- package/src/cli/commands/lint.ts +8 -2
- package/src/cli/commands/test.ts +8 -3
- package/src/cli/commands/typecheck.ts +5 -1
- package/src/cli/commands/verify.ts +5 -3
- package/src/cli/defineConfig.ts +49 -7
- package/src/cli/index.ts +0 -1
- package/src/cli/services/AlephaCliUtils.ts +39 -589
- package/src/cli/services/PackageManagerUtils.ts +301 -0
- package/src/cli/services/ProjectScaffolder.ts +306 -0
- package/src/command/helpers/Runner.spec.ts +2 -2
- package/src/command/helpers/Runner.ts +16 -4
- package/src/command/primitives/$command.ts +0 -6
- package/src/command/providers/CliProvider.ts +1 -3
- package/src/core/Alepha.ts +42 -0
- package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
- package/src/core/index.shared.ts +1 -0
- package/src/core/index.ts +2 -0
- package/src/core/primitives/$hook.ts +6 -2
- package/src/core/primitives/$module.spec.ts +4 -0
- package/src/core/providers/AlsProvider.ts +1 -1
- package/src/core/providers/CodecManager.spec.ts +12 -6
- package/src/core/providers/CodecManager.ts +26 -6
- package/src/core/providers/EventManager.ts +169 -13
- package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +621 -0
- package/src/core/providers/KeylessJsonSchemaCodec.ts +407 -0
- package/src/core/providers/StateManager.spec.ts +27 -16
- package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
- package/src/email/providers/LocalEmailProvider.ts +52 -15
- package/src/email/providers/NodemailerEmailProvider.ts +167 -56
- package/src/file/errors/FileError.ts +7 -0
- package/src/file/index.ts +9 -1
- package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
- package/src/logger/index.ts +15 -3
- package/src/mcp/transports/StdioMcpTransport.ts +1 -1
- package/src/orm/index.browser.ts +1 -19
- package/src/orm/index.bun.ts +77 -0
- package/src/orm/index.shared-server.ts +22 -0
- package/src/orm/index.shared.ts +15 -0
- package/src/orm/index.ts +13 -39
- package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
- package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
- package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
- package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
- package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
- package/src/orm/services/Repository.ts +8 -0
- package/src/queue/core/providers/WorkerProvider.spec.ts +48 -32
- package/src/redis/index.bun.ts +35 -0
- package/src/redis/providers/BunRedisProvider.ts +12 -43
- package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
- package/src/redis/providers/NodeRedisProvider.ts +16 -34
- package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
- package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
- package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
- package/src/security/index.browser.ts +5 -0
- package/src/security/index.ts +90 -7
- package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
- package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
- package/src/security/primitives/$role.ts +5 -5
- package/src/security/primitives/$serviceAccount.spec.ts +5 -5
- package/src/security/primitives/$serviceAccount.ts +3 -3
- package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
- package/src/server/auth/primitives/$auth.ts +10 -10
- package/src/server/auth/primitives/$authCredentials.ts +3 -3
- package/src/server/auth/primitives/$authGithub.ts +3 -3
- package/src/server/auth/primitives/$authGoogle.ts +3 -3
- package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
- package/src/server/cache/providers/ServerCacheProvider.spec.ts +183 -0
- package/src/server/cache/providers/ServerCacheProvider.ts +95 -10
- package/src/server/compress/providers/ServerCompressProvider.ts +61 -2
- package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
- package/src/server/core/helpers/ServerReply.ts +2 -2
- package/src/server/core/providers/NodeHttpServerProvider.ts +25 -6
- package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
- package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
- package/src/server/core/providers/ServerProvider.ts +155 -22
- package/src/server/core/providers/ServerRouterProvider.ts +259 -115
- package/src/server/core/providers/ServerTimingProvider.ts +2 -2
- package/src/server/links/index.ts +1 -1
- package/src/server/links/providers/LinkProvider.ts +1 -1
- package/src/server/static/providers/ServerStaticProvider.ts +10 -0
- package/src/server/swagger/index.ts +1 -1
- package/src/server/swagger/providers/ServerSwaggerProvider.ts +5 -8
- package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
- package/src/sms/providers/LocalSmsProvider.ts +8 -7
- package/src/vite/helpers/boot.ts +28 -17
- package/src/vite/helpers/importViteReact.ts +13 -0
- package/src/vite/index.ts +1 -21
- package/src/vite/plugins/viteAlephaDev.ts +16 -1
- package/src/vite/plugins/viteAlephaSsrPreload.ts +222 -0
- package/src/vite/tasks/buildClient.ts +11 -0
- package/src/vite/tasks/buildServer.ts +59 -4
- package/src/vite/tasks/devServer.ts +71 -0
- package/src/vite/tasks/generateCloudflare.ts +7 -0
- package/src/vite/tasks/index.ts +2 -1
- package/dist/server/security/index.browser.js +0 -13
- package/dist/server/security/index.browser.js.map +0 -1
- package/dist/server/security/index.d.ts +0 -173
- package/dist/server/security/index.d.ts.map +0 -1
- package/dist/server/security/index.js +0 -311
- package/dist/server/security/index.js.map +0 -1
- package/src/cli/assets/appRouterTs.ts +0 -9
- package/src/cli/assets/mainTs.ts +0 -13
- package/src/cli/assets/viteConfigTs.ts +0 -14
- package/src/cli/commands/run.ts +0 -24
- package/src/server/security/index.browser.ts +0 -10
- package/src/server/security/index.ts +0 -94
- package/src/vite/plugins/viteAlepha.ts +0 -37
- package/src/vite/plugins/viteAlephaBuild.ts +0 -281
- /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
- /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
package/dist/vite/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import m, { createRequire } from "node:module";
|
|
2
|
-
import { access, cp, mkdir, readFile,
|
|
3
|
-
import path, { basename, dirname, join, resolve } from "node:path";
|
|
4
|
-
import { AlephaError
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { access, cp, mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import path, { basename, dirname, join, relative, resolve } from "node:path";
|
|
4
|
+
import { AlephaError } from "alepha";
|
|
5
|
+
import { pathToFileURL } from "node:url";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { existsSync, mkdirSync, promises, writeFileSync } from "node:fs";
|
|
7
8
|
import { promisify } from "node:util";
|
|
8
9
|
import { brotliCompress, gzip } from "node:zlib";
|
|
9
|
-
import {
|
|
10
|
+
import { analyzer } from "vite-bundle-analyzer";
|
|
10
11
|
|
|
11
12
|
//#region ../../src/vite/helpers/boot.ts
|
|
12
13
|
/**
|
|
@@ -15,6 +16,16 @@ import { pathToFileURL } from "node:url";
|
|
|
15
16
|
* For avoiding cli -> vite, all code moved here.
|
|
16
17
|
*/
|
|
17
18
|
/**
|
|
19
|
+
* Server entry files in priority order.
|
|
20
|
+
* main.server.ts is preferred over main.ts for consistency.
|
|
21
|
+
*/
|
|
22
|
+
const SERVER_ENTRIES = [
|
|
23
|
+
"main.server.ts",
|
|
24
|
+
"main.server.tsx",
|
|
25
|
+
"main.ts",
|
|
26
|
+
"main.tsx"
|
|
27
|
+
];
|
|
28
|
+
/**
|
|
18
29
|
* Find browser/client entry file path.
|
|
19
30
|
*/
|
|
20
31
|
const getClientEntry = async (root = process.cwd()) => {
|
|
@@ -27,6 +38,8 @@ const getClientEntry = async (root = process.cwd()) => {
|
|
|
27
38
|
};
|
|
28
39
|
/**
|
|
29
40
|
* Find server entry file path.
|
|
41
|
+
*
|
|
42
|
+
* Optimized to use a single readdir() call instead of multiple access() calls.
|
|
30
43
|
*/
|
|
31
44
|
const getServerEntry = async (root = process.cwd(), explicitEntry) => {
|
|
32
45
|
if (explicitEntry) {
|
|
@@ -38,22 +51,14 @@ const getServerEntry = async (root = process.cwd(), explicitEntry) => {
|
|
|
38
51
|
throw new AlephaError(`Explicit server entry file "${explicitEntry}" not found.`);
|
|
39
52
|
}
|
|
40
53
|
}
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"src/server-entry.tsx",
|
|
46
|
-
"src/main.ts",
|
|
47
|
-
"src/main.tsx"
|
|
48
|
-
];
|
|
49
|
-
for (const entry of maybeEntry) try {
|
|
50
|
-
const path$1 = join(root, entry).replace(/\\/g, "/");
|
|
51
|
-
await access(path$1);
|
|
52
|
-
return path$1;
|
|
54
|
+
const srcDir = join(root, "src");
|
|
55
|
+
try {
|
|
56
|
+
const files = new Set(await readdir(srcDir));
|
|
57
|
+
for (const entry of SERVER_ENTRIES) if (files.has(entry)) return join(srcDir, entry).replace(/\\/g, "/");
|
|
53
58
|
} catch {}
|
|
54
59
|
const clientEntry = await getClientEntry(root);
|
|
55
60
|
if (clientEntry) return clientEntry;
|
|
56
|
-
throw new AlephaError(`Could not find a server entry file.
|
|
61
|
+
throw new AlephaError(`Could not find a server entry file. Supported entries: ${SERVER_ENTRIES.map((e) => `src/${e}`).join(", ")}`);
|
|
57
62
|
};
|
|
58
63
|
/**
|
|
59
64
|
* Extract first module script src from HTML.
|
|
@@ -159,12 +164,6 @@ function createBufferedLogger() {
|
|
|
159
164
|
};
|
|
160
165
|
}
|
|
161
166
|
|
|
162
|
-
//#endregion
|
|
163
|
-
//#region ../../src/vite/helpers/fileExists.ts
|
|
164
|
-
const fileExists = async (path$1) => {
|
|
165
|
-
return await access(join(process.cwd(), path$1)).then(() => true).catch(() => false);
|
|
166
|
-
};
|
|
167
|
-
|
|
168
167
|
//#endregion
|
|
169
168
|
//#region ../../src/vite/helpers/importVite.ts
|
|
170
169
|
const importVite = async () => {
|
|
@@ -180,88 +179,505 @@ const importVite = async () => {
|
|
|
180
179
|
};
|
|
181
180
|
|
|
182
181
|
//#endregion
|
|
183
|
-
//#region ../../src/vite/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
182
|
+
//#region ../../src/vite/tasks/runAlepha.ts
|
|
183
|
+
/**
|
|
184
|
+
* Create an Alepha runner for development.
|
|
185
|
+
*
|
|
186
|
+
* The runner manages the lifecycle of an Alepha application during
|
|
187
|
+
* Vite dev server operation, handling start/stop/restart and HMR.
|
|
188
|
+
*/
|
|
189
|
+
function createAlephaRunner(opts) {
|
|
190
|
+
return new AlephaRunner({
|
|
191
|
+
root: process.cwd().replace(/\\/g, "/"),
|
|
192
|
+
started: false,
|
|
193
|
+
log: opts.debug ? (...msg) => console.log(...msg) : () => {},
|
|
194
|
+
entry: opts.entry,
|
|
195
|
+
onReload: () => {}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
var AlephaRunner = class {
|
|
199
|
+
state;
|
|
200
|
+
constructor(state) {
|
|
201
|
+
this.state = state;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Set resolved Vite config.
|
|
205
|
+
*/
|
|
206
|
+
setConfig(config) {
|
|
207
|
+
this.state.config = config;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Check if SSR is enabled for the running app.
|
|
211
|
+
*/
|
|
212
|
+
isSsrEnabled() {
|
|
213
|
+
if (!this.state.app) return false;
|
|
214
|
+
return this.state.app.store.get("alepha.react.server.ssr") ?? false;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Check if app is started.
|
|
218
|
+
*/
|
|
219
|
+
get isStarted() {
|
|
220
|
+
return this.state.started;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get the running Alepha app instance.
|
|
224
|
+
*/
|
|
225
|
+
get app() {
|
|
226
|
+
return this.state.app;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Start the Alepha application.
|
|
230
|
+
*/
|
|
231
|
+
async start(server) {
|
|
232
|
+
const { loadEnv } = await importVite();
|
|
233
|
+
global.ssrFixStacktrace = (e) => {
|
|
234
|
+
server.ssrFixStacktrace(e);
|
|
235
|
+
let it = e;
|
|
236
|
+
do {
|
|
237
|
+
server.ssrFixStacktrace(it);
|
|
238
|
+
it = it.cause;
|
|
239
|
+
} while (it instanceof Error);
|
|
240
|
+
};
|
|
241
|
+
if (this.state.started) {
|
|
242
|
+
await this.restart(server, true);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!this.state.config) {
|
|
246
|
+
this.state.log("[DEBUG] No config - skip starting");
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
this.state.onReload?.();
|
|
250
|
+
this.state.log("[DEBUG] Starting Alepha app...");
|
|
251
|
+
this.state.started = false;
|
|
252
|
+
this.state.app = void 0;
|
|
253
|
+
const fileUrl = pathToFileURL(`${path.resolve(this.state.config.root, this.state.entry)}`).href;
|
|
254
|
+
const env = loadEnv("development", this.state.config.root, "");
|
|
255
|
+
const before = { ...process.env };
|
|
256
|
+
for (const key in env) process.env[key] = env[key];
|
|
257
|
+
let port = 5173;
|
|
258
|
+
const address = server.httpServer?.address();
|
|
259
|
+
if (typeof address === "object" && address?.port) port = address.port;
|
|
260
|
+
process.env.NODE_ENV ??= "development";
|
|
261
|
+
process.env.VITE_ALEPHA_DEV = "true";
|
|
262
|
+
process.env.SERVER_HOST ??= typeof server.config.server.host === "string" ? server.config.server.host : "localhost";
|
|
263
|
+
process.env.SERVER_PORT ??= String(port);
|
|
264
|
+
try {
|
|
193
265
|
const now = Date.now();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
await
|
|
205
|
-
this.
|
|
266
|
+
await server.ssrLoadModule(fileUrl, { fixStacktrace: true });
|
|
267
|
+
this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
|
|
268
|
+
await new Promise((r) => setTimeout(r, 10));
|
|
269
|
+
this.state.app = globalThis.__alepha;
|
|
270
|
+
if (!this.state.app) {
|
|
271
|
+
this.state.log("[DEBUG] No app found - skip starting");
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.state.app.store.set("alepha.node.server", server.httpServer);
|
|
275
|
+
console.log("");
|
|
276
|
+
await this.state.app.start();
|
|
277
|
+
this.state.started = true;
|
|
278
|
+
process.env = { ...before };
|
|
279
|
+
this.state.log("[DEBUG] Starting Done!");
|
|
280
|
+
} catch (e) {
|
|
281
|
+
if (e instanceof Error) {
|
|
282
|
+
let it = e;
|
|
283
|
+
do {
|
|
284
|
+
server.ssrFixStacktrace(it);
|
|
285
|
+
it = it.cause;
|
|
286
|
+
} while (it instanceof Error);
|
|
287
|
+
server.ssrFixStacktrace(e);
|
|
288
|
+
if (e.cause instanceof Error) server.ssrFixStacktrace(e.cause);
|
|
289
|
+
this.state.app?.log?.error("App failed to start:", e);
|
|
290
|
+
this.state.app?.log?.info("Waiting for changes to restart...");
|
|
291
|
+
}
|
|
292
|
+
this.state.log("[DEBUG] Alepha app start error");
|
|
293
|
+
this.state.started = false;
|
|
206
294
|
}
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
async function compressFile(options = {}, filePath) {
|
|
210
|
-
const { brotli = true, gzip: gzip$1 = true } = options;
|
|
211
|
-
const compressionTasks = [];
|
|
212
|
-
const fileContentPromise = promises.readFile(filePath);
|
|
213
|
-
if (gzip$1) {
|
|
214
|
-
const gzipOptions = typeof gzip$1 === "object" ? gzip$1 : { level: 9 };
|
|
215
|
-
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
216
|
-
const compressed = await gzipCompress(content, gzipOptions);
|
|
217
|
-
await promises.writeFile(`${filePath}.gz`, compressed);
|
|
218
|
-
}));
|
|
219
295
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Stop the Alepha application.
|
|
298
|
+
*/
|
|
299
|
+
async stop() {
|
|
300
|
+
if (this.state.app?.stop && this.state.started) {
|
|
301
|
+
this.state.log("[DEBUG] Stopping Alepha app...");
|
|
302
|
+
await this.state.app.stop();
|
|
303
|
+
this.state.started = false;
|
|
304
|
+
this.state.log("[DEBUG] Stopping Done!");
|
|
305
|
+
} else this.state.log("[DEBUG] Alepha app not started - skip stop");
|
|
226
306
|
}
|
|
227
|
-
|
|
307
|
+
/**
|
|
308
|
+
* Restart the Alepha application.
|
|
309
|
+
*
|
|
310
|
+
* @returns true if the restart was skipped due to locking
|
|
311
|
+
*/
|
|
312
|
+
async restart(server, invalidate) {
|
|
313
|
+
if (this.state.lock) {
|
|
314
|
+
this.state.log("[DEBUG] STILL LOCKING");
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
this.state.log("[DEBUG] LOCK RESTART");
|
|
318
|
+
this.state.lock = Promise.withResolvers();
|
|
319
|
+
const now = Date.now();
|
|
320
|
+
this.state.log("[DEBUG] RESTART");
|
|
321
|
+
await this.stop();
|
|
322
|
+
this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);
|
|
323
|
+
if (invalidate) server.moduleGraph.invalidateAll();
|
|
324
|
+
await this.start(server);
|
|
325
|
+
this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);
|
|
326
|
+
setTimeout(() => {
|
|
327
|
+
this.state.log("[DEBUG] UNLOCK RESTART");
|
|
328
|
+
this.state.lock?.resolve();
|
|
329
|
+
this.state.lock = void 0;
|
|
330
|
+
}, 500);
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Send reload event to client.
|
|
335
|
+
*/
|
|
336
|
+
sendReload(server) {
|
|
337
|
+
server.ws.send({
|
|
338
|
+
type: "custom",
|
|
339
|
+
event: "alepha:reload",
|
|
340
|
+
data: {}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Check if a URL path is a Vite internal file.
|
|
346
|
+
*/
|
|
347
|
+
function isViteInternalPath(pathname) {
|
|
348
|
+
const [path$1] = pathname.split("?");
|
|
349
|
+
if (path$1.startsWith("/@") || path$1.startsWith("/src") || path$1.includes("/node_modules/")) return true;
|
|
350
|
+
return false;
|
|
228
351
|
}
|
|
229
352
|
|
|
230
353
|
//#endregion
|
|
231
|
-
//#region ../../src/vite/
|
|
354
|
+
//#region ../../src/vite/plugins/viteAlephaDev.ts
|
|
232
355
|
/**
|
|
233
|
-
*
|
|
356
|
+
* Plug Alepha into Vite development server.
|
|
234
357
|
*
|
|
235
|
-
* This
|
|
236
|
-
*
|
|
358
|
+
* This plugin manages the Alepha application lifecycle during development,
|
|
359
|
+
* handling hot module replacement and request forwarding.
|
|
237
360
|
*/
|
|
238
|
-
async function
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
361
|
+
async function viteAlephaDev(options = {}) {
|
|
362
|
+
let entry = options.serverEntry;
|
|
363
|
+
if (!entry) {
|
|
364
|
+
entry = await boot.getServerEntry();
|
|
365
|
+
if (!entry) return {
|
|
366
|
+
name: "alepha-dev",
|
|
367
|
+
apply: "serve",
|
|
368
|
+
config() {}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
const runner = createAlephaRunner({
|
|
372
|
+
entry,
|
|
373
|
+
debug: options.debug
|
|
374
|
+
});
|
|
375
|
+
const { loadEnv } = await importVite();
|
|
376
|
+
const env = loadEnv("development", process.cwd(), "SERVER");
|
|
377
|
+
const config = {};
|
|
378
|
+
if (env.SERVER_PORT) config.server = { port: parseInt(env.SERVER_PORT, 10) };
|
|
379
|
+
return {
|
|
380
|
+
name: "alepha-dev",
|
|
381
|
+
apply: "serve",
|
|
382
|
+
config: () => config,
|
|
383
|
+
configResolved(resolvedConfig) {
|
|
384
|
+
runner.setConfig(resolvedConfig);
|
|
385
|
+
},
|
|
386
|
+
async handleHotUpdate(ctx) {
|
|
387
|
+
if (options.debug) console.log("[DEBUG] HMR", ctx.file);
|
|
388
|
+
if (ctx.file.includes("/.idea/")) return [];
|
|
389
|
+
const isServerOnly = !ctx.modules[0]?._clientModule;
|
|
390
|
+
const isBrowserOnly = !ctx.modules[0]?._ssrModule;
|
|
391
|
+
const isSsrEnabled = runner.isSsrEnabled();
|
|
392
|
+
if (isBrowserOnly) {
|
|
393
|
+
if (options.debug) console.log("[DEBUG] HMR - browser only - no reason to reload server");
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
const root = process.cwd().replace(/\\/g, "/");
|
|
397
|
+
const invalidate = !ctx.file.startsWith(root);
|
|
398
|
+
if (invalidate && options.debug) console.log("[DEBUG] HMR - outside root - invalidate all");
|
|
399
|
+
if (!isSsrEnabled && isServerOnly) {
|
|
400
|
+
await runner.restart(ctx.server, invalidate);
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
if (isSsrEnabled && ctx.modules[0]) {
|
|
404
|
+
if (await runner.restart(ctx.server, invalidate)) return [];
|
|
405
|
+
if (!runner.isStarted) {
|
|
406
|
+
if (options.debug) console.log("[DEBUG] HMR - abort due to app not started");
|
|
407
|
+
return [];
|
|
408
|
+
}
|
|
409
|
+
if (isServerOnly && runner.isStarted) {
|
|
410
|
+
runner.sendReload(ctx.server);
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
async configureServer(server) {
|
|
416
|
+
if (env.SERVER_PORT) server.config.server.port = parseInt(env.SERVER_PORT, 10);
|
|
417
|
+
const middleware = (req, res, next) => {
|
|
418
|
+
if (runner.isStarted && runner.app && req.url && !isViteInternalPath(req.url)) {
|
|
419
|
+
let ended = false;
|
|
420
|
+
const writeHead = res.writeHead.bind(res);
|
|
421
|
+
res.writeHead = (...args) => {
|
|
422
|
+
ended = true;
|
|
423
|
+
return writeHead(args[0], args[1], args[2]);
|
|
424
|
+
};
|
|
425
|
+
return runner.app.events.emit("node:request", {
|
|
426
|
+
req,
|
|
427
|
+
res
|
|
428
|
+
}).then(() => {
|
|
429
|
+
if (!ended) next();
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
next();
|
|
433
|
+
};
|
|
434
|
+
server.middlewares.use((req, res, next) => {
|
|
435
|
+
middleware(req, res, next);
|
|
436
|
+
});
|
|
437
|
+
server.config.logger.info = (msg) => {
|
|
438
|
+
console.log(msg);
|
|
439
|
+
};
|
|
440
|
+
server.config.logger.clearScreen = () => {};
|
|
441
|
+
return () => {
|
|
442
|
+
server.httpServer?.once("listening", () => {
|
|
443
|
+
runner.start(server);
|
|
444
|
+
});
|
|
445
|
+
};
|
|
446
|
+
},
|
|
447
|
+
async closeBundle() {}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
//#endregion
|
|
452
|
+
//#region ../../src/vite/plugins/viteAlephaSsrPreload.ts
|
|
453
|
+
/**
|
|
454
|
+
* Vite plugin that generates a preload manifest for SSR module preloading.
|
|
455
|
+
*
|
|
456
|
+
* Instead of injecting source paths directly into $page definitions (which would
|
|
457
|
+
* leak component paths in the browser bundle), this plugin:
|
|
458
|
+
*
|
|
459
|
+
* 1. Collects all lazy import paths from $page definitions during transform
|
|
460
|
+
* 2. Generates a manifest file mapping short keys to resolved source paths
|
|
461
|
+
* 3. Injects only the short key into $page definitions
|
|
462
|
+
*
|
|
463
|
+
* The manifest is written to `.vite/preload-manifest.json` alongside Vite's
|
|
464
|
+
* other manifests. The CLI build command moves all manifests to
|
|
465
|
+
* `dist/server/.ssr/` where SSRManifestProvider loads them at runtime.
|
|
466
|
+
*
|
|
467
|
+
* Before:
|
|
468
|
+
* ```typescript
|
|
469
|
+
* $page({
|
|
470
|
+
* path: '/users/:id',
|
|
471
|
+
* lazy: () => import('./UserDetail.tsx'),
|
|
472
|
+
* })
|
|
473
|
+
* ```
|
|
474
|
+
*
|
|
475
|
+
* After:
|
|
476
|
+
* ```typescript
|
|
477
|
+
* $page({
|
|
478
|
+
* path: '/users/:id',
|
|
479
|
+
* lazy: () => import('./UserDetail.tsx'),
|
|
480
|
+
* [Symbol.for("alepha.page.preload")]: "a1b2c3",
|
|
481
|
+
* })
|
|
482
|
+
* ```
|
|
483
|
+
*
|
|
484
|
+
* Manifest (.alepha/preload-manifest.json):
|
|
485
|
+
* ```json
|
|
486
|
+
* {
|
|
487
|
+
* "a1b2c3": "src/pages/UserDetail.tsx"
|
|
488
|
+
* }
|
|
489
|
+
* ```
|
|
490
|
+
*/
|
|
491
|
+
function viteAlephaSsrPreload() {
|
|
492
|
+
let root = "";
|
|
493
|
+
const preloadMap = /* @__PURE__ */ new Map();
|
|
494
|
+
/**
|
|
495
|
+
* Generate a short hash key for a source path.
|
|
496
|
+
* Uses first 8 chars of MD5 hash for brevity while avoiding collisions.
|
|
497
|
+
*/
|
|
498
|
+
function generateKey(sourcePath) {
|
|
499
|
+
return createHash("md5").update(sourcePath).digest("hex").slice(0, 8);
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
name: "alepha-preload",
|
|
503
|
+
configResolved(config) {
|
|
504
|
+
root = config.root;
|
|
505
|
+
},
|
|
506
|
+
transform(code, id) {
|
|
507
|
+
if (!id.match(/\.[tj]sx?$/)) return null;
|
|
508
|
+
if (id.includes("node_modules")) return null;
|
|
509
|
+
if (!code.includes("$page") || !code.includes("lazy")) return null;
|
|
510
|
+
const insertions = [];
|
|
511
|
+
const pageStartRegex = /\$page\s*\(\s*\{/g;
|
|
512
|
+
let pageMatch = pageStartRegex.exec(code);
|
|
513
|
+
while (pageMatch !== null) {
|
|
514
|
+
const objectStartIndex = pageMatch.index + pageMatch[0].length - 1;
|
|
515
|
+
let braceCount = 1;
|
|
516
|
+
let i = objectStartIndex + 1;
|
|
517
|
+
while (i < code.length && braceCount > 0) {
|
|
518
|
+
if (code[i] === "{") braceCount++;
|
|
519
|
+
else if (code[i] === "}") braceCount--;
|
|
520
|
+
i++;
|
|
521
|
+
}
|
|
522
|
+
if (braceCount !== 0) {
|
|
523
|
+
pageMatch = pageStartRegex.exec(code);
|
|
524
|
+
continue;
|
|
525
|
+
}
|
|
526
|
+
const objectEndIndex = i - 1;
|
|
527
|
+
const pageContent = code.slice(objectStartIndex, objectEndIndex + 1);
|
|
528
|
+
if (pageContent.includes("alepha.page.preload")) {
|
|
529
|
+
pageMatch = pageStartRegex.exec(code);
|
|
530
|
+
continue;
|
|
531
|
+
}
|
|
532
|
+
const lazyMatch = /lazy\s*:\s*\(\s*\)\s*=>\s*import\s*\(\s*['"]([^'"]+)['"]\s*\)/.exec(pageContent);
|
|
533
|
+
if (!lazyMatch) {
|
|
534
|
+
pageMatch = pageStartRegex.exec(code);
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
const importPath = lazyMatch[1];
|
|
538
|
+
const currentDir = dirname(id);
|
|
539
|
+
let resolvedPath;
|
|
540
|
+
if (importPath.startsWith(".")) resolvedPath = resolve(currentDir, importPath);
|
|
541
|
+
else if (importPath.startsWith("/")) resolvedPath = resolve(root, importPath.slice(1));
|
|
542
|
+
else {
|
|
543
|
+
pageMatch = pageStartRegex.exec(code);
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
let relativePath = relative(root, resolvedPath);
|
|
547
|
+
relativePath = relativePath.replace(/\\/g, "/");
|
|
548
|
+
if (!relativePath.match(/\.[tj]sx?$/)) relativePath = `${relativePath}.tsx`;
|
|
549
|
+
else if (relativePath.endsWith(".jsx")) relativePath = relativePath.replace(/\.jsx$/, ".tsx");
|
|
550
|
+
else if (relativePath.endsWith(".js")) relativePath = relativePath.replace(/\.js$/, ".ts");
|
|
551
|
+
const key = generateKey(relativePath);
|
|
552
|
+
preloadMap.set(key, relativePath);
|
|
553
|
+
const preloadProperty = `${!code.slice(0, objectEndIndex).trimEnd().endsWith(",") ? "," : ""} [Symbol.for("alepha.page.preload")]: "${key}"`;
|
|
554
|
+
insertions.push({
|
|
555
|
+
position: objectEndIndex,
|
|
556
|
+
text: preloadProperty
|
|
557
|
+
});
|
|
558
|
+
pageMatch = pageStartRegex.exec(code);
|
|
559
|
+
}
|
|
560
|
+
if (insertions.length === 0) return null;
|
|
561
|
+
let result = code;
|
|
562
|
+
for (let j = insertions.length - 1; j >= 0; j--) {
|
|
563
|
+
const { position, text } = insertions[j];
|
|
564
|
+
result = result.slice(0, position) + text + result.slice(position);
|
|
565
|
+
}
|
|
566
|
+
return {
|
|
567
|
+
code: result,
|
|
568
|
+
map: null
|
|
569
|
+
};
|
|
570
|
+
},
|
|
571
|
+
writeBundle(options) {
|
|
572
|
+
const outDir = options.dir || "";
|
|
573
|
+
if (outDir.includes("server")) return;
|
|
574
|
+
if (preloadMap.size > 0) {
|
|
575
|
+
const viteDir = join(outDir, ".vite");
|
|
576
|
+
if (!existsSync(viteDir)) mkdirSync(viteDir, { recursive: true });
|
|
577
|
+
const manifest = Object.fromEntries(preloadMap);
|
|
578
|
+
writeFileSync(join(viteDir, "preload-manifest.json"), JSON.stringify(manifest, null, 2));
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
//#endregion
|
|
585
|
+
//#region ../../src/vite/plugins/viteCompress.ts
|
|
586
|
+
const gzipCompress = promisify(gzip);
|
|
587
|
+
const brotliCompress$1 = promisify(brotliCompress);
|
|
588
|
+
function viteCompress(options = {}) {
|
|
589
|
+
const { disabled = false, filter = /\.(js|mjs|cjs|css|wasm|svg)$/ } = options;
|
|
590
|
+
return {
|
|
591
|
+
name: "compress",
|
|
592
|
+
apply: "build",
|
|
593
|
+
async writeBundle(outputOptions, bundle) {
|
|
594
|
+
if (disabled) return;
|
|
595
|
+
const now = Date.now();
|
|
596
|
+
const outputDir = outputOptions.dir || resolve(process.cwd(), "dist");
|
|
597
|
+
const files = Object.keys(bundle).filter((fileName) => {
|
|
598
|
+
if (typeof filter === "function") return filter(fileName);
|
|
599
|
+
return filter.test(fileName);
|
|
600
|
+
}).map((fileName) => ({
|
|
601
|
+
fileName,
|
|
602
|
+
filePath: join(outputDir, fileName)
|
|
603
|
+
}));
|
|
604
|
+
const compressionTasks = [];
|
|
605
|
+
for (const { filePath } of files) compressionTasks.push(compressFile(options, filePath));
|
|
606
|
+
await Promise.all(compressionTasks);
|
|
607
|
+
this.info(`Compressed ${files.length} file${files.length > 1 ? "s" : ""} in ${Date.now() - now}ms.`);
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
async function compressFile(options = {}, filePath) {
|
|
612
|
+
const { brotli = true, gzip: gzip$1 = true } = options;
|
|
613
|
+
const compressionTasks = [];
|
|
614
|
+
const fileContentPromise = promises.readFile(filePath);
|
|
615
|
+
if (gzip$1) {
|
|
616
|
+
const gzipOptions = typeof gzip$1 === "object" ? gzip$1 : { level: 9 };
|
|
617
|
+
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
618
|
+
const compressed = await gzipCompress(content, gzipOptions);
|
|
619
|
+
await promises.writeFile(`${filePath}.gz`, compressed);
|
|
620
|
+
}));
|
|
621
|
+
}
|
|
622
|
+
if (brotli) {
|
|
623
|
+
const brotliOptions = typeof brotli === "object" ? brotli : {};
|
|
624
|
+
compressionTasks.push(fileContentPromise.then(async (content) => {
|
|
625
|
+
const compressed = await brotliCompress$1(content, brotliOptions);
|
|
626
|
+
await promises.writeFile(`${filePath}.br`, compressed);
|
|
627
|
+
}));
|
|
628
|
+
}
|
|
629
|
+
await Promise.all(compressionTasks);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
//#endregion
|
|
633
|
+
//#region ../../src/vite/helpers/importViteReact.ts
|
|
634
|
+
const importViteReact = async () => {
|
|
635
|
+
try {
|
|
636
|
+
const { default: viteReact } = createRequire(import.meta.url)("@vitejs/plugin-react");
|
|
637
|
+
return viteReact;
|
|
638
|
+
} catch {}
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
//#endregion
|
|
642
|
+
//#region ../../src/vite/tasks/buildClient.ts
|
|
643
|
+
/**
|
|
644
|
+
* Build client-side bundle with Vite.
|
|
645
|
+
*
|
|
646
|
+
* This task compiles the browser/client code for production,
|
|
647
|
+
* including code splitting, minification, and optional compression.
|
|
648
|
+
*/
|
|
649
|
+
async function buildClient(opts) {
|
|
650
|
+
const { build: viteBuild, mergeConfig } = await importVite();
|
|
651
|
+
const plugins = [];
|
|
652
|
+
const viteReact = await importViteReact();
|
|
653
|
+
if (viteReact) plugins.push(viteReact());
|
|
654
|
+
plugins.push(viteAlephaSsrPreload());
|
|
655
|
+
const compress = opts.precompress ? typeof opts.precompress === "object" ? opts.precompress : {} : void 0;
|
|
656
|
+
if (opts.stats) plugins.push(analyzer({ analyzerMode: "static" }));
|
|
657
|
+
if (opts.precompress && compress) plugins.push(viteCompress(compress));
|
|
658
|
+
const logger = opts.silent ? createBufferedLogger() : void 0;
|
|
659
|
+
const viteBuildClientConfig = {
|
|
660
|
+
mode: "production",
|
|
661
|
+
logLevel: opts.silent ? "silent" : void 0,
|
|
662
|
+
define: { "process.env.NODE_ENV": "\"production\"" },
|
|
663
|
+
publicDir: "public",
|
|
664
|
+
build: {
|
|
665
|
+
chunkSizeWarningLimit: 1e3,
|
|
666
|
+
outDir: opts.dist,
|
|
667
|
+
manifest: true,
|
|
668
|
+
ssrManifest: true,
|
|
669
|
+
rollupOptions: { output: {
|
|
670
|
+
entryFileNames: "entry.[hash].js",
|
|
671
|
+
chunkFileNames: "chunk.[hash].js",
|
|
672
|
+
assetFileNames: "asset.[hash][extname]"
|
|
673
|
+
} }
|
|
674
|
+
},
|
|
675
|
+
esbuild: { legalComments: "none" },
|
|
676
|
+
customLogger: logger,
|
|
677
|
+
plugins
|
|
678
|
+
};
|
|
679
|
+
try {
|
|
680
|
+
await viteBuild(mergeConfig(viteBuildClientConfig, opts.config ?? {}));
|
|
265
681
|
} catch (error) {
|
|
266
682
|
logger?.flush();
|
|
267
683
|
throw error;
|
|
@@ -307,14 +723,27 @@ async function generateExternals(opts) {
|
|
|
307
723
|
async function buildServer(opts) {
|
|
308
724
|
const { build: viteBuild, mergeConfig } = await importVite();
|
|
309
725
|
const plugins = [];
|
|
726
|
+
const viteReact = await importViteReact();
|
|
727
|
+
if (viteReact && opts.clientDir) plugins.push(viteReact());
|
|
728
|
+
plugins.push(viteAlephaSsrPreload());
|
|
310
729
|
if (opts.stats) plugins.push(analyzer({ analyzerMode: "static" }));
|
|
311
730
|
const logger = opts.silent ? createBufferedLogger() : void 0;
|
|
731
|
+
const conditions = [
|
|
732
|
+
"node",
|
|
733
|
+
"import",
|
|
734
|
+
"module",
|
|
735
|
+
"default"
|
|
736
|
+
];
|
|
737
|
+
if (opts.conditions) conditions.unshift(...opts.conditions);
|
|
312
738
|
const viteBuildServerConfig = {
|
|
313
739
|
mode: "production",
|
|
314
740
|
logLevel: opts.silent ? "silent" : void 0,
|
|
315
741
|
define: { "process.env.NODE_ENV": "\"production\"" },
|
|
316
742
|
publicDir: false,
|
|
317
|
-
ssr: {
|
|
743
|
+
ssr: {
|
|
744
|
+
noExternal: true,
|
|
745
|
+
resolve: { conditions }
|
|
746
|
+
},
|
|
318
747
|
build: {
|
|
319
748
|
sourcemap: true,
|
|
320
749
|
ssr: opts.entry,
|
|
@@ -322,7 +751,7 @@ async function buildServer(opts) {
|
|
|
322
751
|
minify: true,
|
|
323
752
|
chunkSizeWarningLimit: 1e4,
|
|
324
753
|
rollupOptions: {
|
|
325
|
-
external: [
|
|
754
|
+
external: [/^bun(:|$)/, /^cloudflare:/],
|
|
326
755
|
output: {
|
|
327
756
|
entryFileNames: "[hash].js",
|
|
328
757
|
chunkFileNames: "[hash].js",
|
|
@@ -353,12 +782,37 @@ async function buildServer(opts) {
|
|
|
353
782
|
const entryFile = extractEntryFromBundle(opts.entry, result);
|
|
354
783
|
let template = "";
|
|
355
784
|
if (opts.clientDir) template = `__alepha.set("alepha.react.server.template", \`${(await readFile(`${opts.distDir}/${opts.clientDir}/index.html`, "utf-8")).replace(/>\s*</g, "><").trim()}\`);\n`;
|
|
785
|
+
let manifest = "";
|
|
786
|
+
if (opts.clientDir) {
|
|
787
|
+
const viteDir = `${opts.distDir}/${opts.clientDir}/.vite`;
|
|
788
|
+
const combined = {
|
|
789
|
+
ssr: await loadJsonFile(`${viteDir}/ssr-manifest.json`),
|
|
790
|
+
client: await loadJsonFile(`${viteDir}/manifest.json`),
|
|
791
|
+
preload: await loadJsonFile(`${viteDir}/preload-manifest.json`)
|
|
792
|
+
};
|
|
793
|
+
manifest = `__alepha.set("alepha.react.ssr.manifest", ${JSON.stringify(combined)});\n`;
|
|
794
|
+
await rm(viteDir, {
|
|
795
|
+
recursive: true,
|
|
796
|
+
force: true
|
|
797
|
+
});
|
|
798
|
+
}
|
|
356
799
|
await writeFile(`${opts.distDir}/index.js`, `// This file was automatically generated. DO NOT MODIFY.
|
|
357
800
|
// Changes to this file will be lost when the code is regenerated.
|
|
358
|
-
\
|
|
801
|
+
\n${template}${manifest}import './server/${entryFile}';\n`.trim());
|
|
359
802
|
return { entryFile };
|
|
360
803
|
}
|
|
361
804
|
/**
|
|
805
|
+
* Load a JSON file, returning undefined if it doesn't exist.
|
|
806
|
+
*/
|
|
807
|
+
async function loadJsonFile(path$1) {
|
|
808
|
+
try {
|
|
809
|
+
const content = await readFile(path$1, "utf-8");
|
|
810
|
+
return JSON.parse(content);
|
|
811
|
+
} catch {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
362
816
|
* Extract entry filename from Vite build result.
|
|
363
817
|
*/
|
|
364
818
|
function extractEntryFromBundle(entry, result) {
|
|
@@ -418,6 +872,39 @@ async function copyAssets(opts) {
|
|
|
418
872
|
else await fn();
|
|
419
873
|
}
|
|
420
874
|
|
|
875
|
+
//#endregion
|
|
876
|
+
//#region ../../src/vite/tasks/devServer.ts
|
|
877
|
+
/**
|
|
878
|
+
* Start Vite development server with Alepha plugins.
|
|
879
|
+
*
|
|
880
|
+
* This task starts the Vite dev server with all required plugins:
|
|
881
|
+
* - @vitejs/plugin-react (JSX/TSX compilation)
|
|
882
|
+
* - viteAlephaDev (Alepha server integration)
|
|
883
|
+
* - viteAlephaSsrPreload (SSR module preloading)
|
|
884
|
+
*/
|
|
885
|
+
async function devServer(opts = {}) {
|
|
886
|
+
const { createServer, mergeConfig } = await importVite();
|
|
887
|
+
const plugins = [];
|
|
888
|
+
const viteReact = await importViteReact();
|
|
889
|
+
if (viteReact) plugins.push(viteReact());
|
|
890
|
+
plugins.push(viteAlephaSsrPreload());
|
|
891
|
+
plugins.push(await viteAlephaDev({
|
|
892
|
+
serverEntry: opts.entry,
|
|
893
|
+
debug: opts.debug
|
|
894
|
+
}));
|
|
895
|
+
const server = await createServer(mergeConfig({
|
|
896
|
+
plugins,
|
|
897
|
+
server: {
|
|
898
|
+
port: opts.port,
|
|
899
|
+
host: opts.host
|
|
900
|
+
}
|
|
901
|
+
}, {}));
|
|
902
|
+
await server.listen();
|
|
903
|
+
console.log("");
|
|
904
|
+
server.printUrls();
|
|
905
|
+
server.bindCLIShortcuts({ print: true });
|
|
906
|
+
}
|
|
907
|
+
|
|
421
908
|
//#endregion
|
|
422
909
|
//#region ../../src/vite/tasks/generateCloudflare.ts
|
|
423
910
|
const WARNING_COMMENT$1 = "// This file was automatically generated. DO NOT MODIFY.\n// Changes to this file will be lost when the code is regenerated.\n";
|
|
@@ -438,6 +925,11 @@ async function generateCloudflare(opts = {}) {
|
|
|
438
925
|
main: "./main.cloudflare.js",
|
|
439
926
|
compatibility_flags: ["nodejs_compat"],
|
|
440
927
|
compatibility_date: "2025-11-17",
|
|
928
|
+
no_bundle: true,
|
|
929
|
+
rules: [{
|
|
930
|
+
type: "ESModule",
|
|
931
|
+
globs: ["index.js", "server/*.js"]
|
|
932
|
+
}],
|
|
441
933
|
...opts.config
|
|
442
934
|
};
|
|
443
935
|
if (hasAssets) wrangler.assets ??= {
|
|
@@ -482,6 +974,12 @@ export default {
|
|
|
482
974
|
await writeFile(join(root, distDir, "main.cloudflare.js"), `${WARNING_COMMENT$1}\n${workerCode}`.trim());
|
|
483
975
|
}
|
|
484
976
|
|
|
977
|
+
//#endregion
|
|
978
|
+
//#region ../../src/vite/helpers/fileExists.ts
|
|
979
|
+
const fileExists = async (path$1) => {
|
|
980
|
+
return await access(join(process.cwd(), path$1)).then(() => true).catch(() => false);
|
|
981
|
+
};
|
|
982
|
+
|
|
485
983
|
//#endregion
|
|
486
984
|
//#region ../../src/vite/tasks/generateDocker.ts
|
|
487
985
|
/**
|
|
@@ -704,417 +1202,5 @@ async function renderFile(page, options, dist, compress) {
|
|
|
704
1202
|
}
|
|
705
1203
|
|
|
706
1204
|
//#endregion
|
|
707
|
-
|
|
708
|
-
/**
|
|
709
|
-
* Create an Alepha runner for development.
|
|
710
|
-
*
|
|
711
|
-
* The runner manages the lifecycle of an Alepha application during
|
|
712
|
-
* Vite dev server operation, handling start/stop/restart and HMR.
|
|
713
|
-
*/
|
|
714
|
-
function createAlephaRunner(opts) {
|
|
715
|
-
return new AlephaRunner({
|
|
716
|
-
root: process.cwd().replace(/\\/g, "/"),
|
|
717
|
-
started: false,
|
|
718
|
-
log: opts.debug ? (...msg) => console.log(...msg) : () => {},
|
|
719
|
-
entry: opts.entry,
|
|
720
|
-
onReload: () => {}
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
var AlephaRunner = class {
|
|
724
|
-
state;
|
|
725
|
-
constructor(state) {
|
|
726
|
-
this.state = state;
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Set resolved Vite config.
|
|
730
|
-
*/
|
|
731
|
-
setConfig(config) {
|
|
732
|
-
this.state.config = config;
|
|
733
|
-
}
|
|
734
|
-
/**
|
|
735
|
-
* Check if SSR is enabled for the running app.
|
|
736
|
-
*/
|
|
737
|
-
isSsrEnabled() {
|
|
738
|
-
if (!this.state.app) return false;
|
|
739
|
-
return this.state.app.store.get("alepha.react.server.ssr") ?? false;
|
|
740
|
-
}
|
|
741
|
-
/**
|
|
742
|
-
* Check if app is started.
|
|
743
|
-
*/
|
|
744
|
-
get isStarted() {
|
|
745
|
-
return this.state.started;
|
|
746
|
-
}
|
|
747
|
-
/**
|
|
748
|
-
* Get the running Alepha app instance.
|
|
749
|
-
*/
|
|
750
|
-
get app() {
|
|
751
|
-
return this.state.app;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Start the Alepha application.
|
|
755
|
-
*/
|
|
756
|
-
async start(server) {
|
|
757
|
-
const { loadEnv } = await importVite();
|
|
758
|
-
global.ssrFixStacktrace = (e) => {
|
|
759
|
-
server.ssrFixStacktrace(e);
|
|
760
|
-
let it = e;
|
|
761
|
-
do {
|
|
762
|
-
server.ssrFixStacktrace(it);
|
|
763
|
-
it = it.cause;
|
|
764
|
-
} while (it instanceof Error);
|
|
765
|
-
};
|
|
766
|
-
if (this.state.started) {
|
|
767
|
-
await this.restart(server, true);
|
|
768
|
-
return;
|
|
769
|
-
}
|
|
770
|
-
if (!this.state.config) {
|
|
771
|
-
this.state.log("[DEBUG] No config - skip starting");
|
|
772
|
-
return;
|
|
773
|
-
}
|
|
774
|
-
this.state.onReload?.();
|
|
775
|
-
this.state.log("[DEBUG] Starting Alepha app...");
|
|
776
|
-
this.state.started = false;
|
|
777
|
-
this.state.app = void 0;
|
|
778
|
-
const fileUrl = pathToFileURL(`${path.resolve(this.state.config.root, this.state.entry)}`).href;
|
|
779
|
-
const env = loadEnv("development", this.state.config.root, "");
|
|
780
|
-
const before = { ...process.env };
|
|
781
|
-
for (const key in env) process.env[key] = env[key];
|
|
782
|
-
let port = 5173;
|
|
783
|
-
const address = server.httpServer?.address();
|
|
784
|
-
if (typeof address === "object" && address?.port) port = address.port;
|
|
785
|
-
process.env.NODE_ENV ??= "development";
|
|
786
|
-
process.env.VITE_ALEPHA_DEV = "true";
|
|
787
|
-
process.env.SERVER_HOST ??= typeof server.config.server.host === "string" ? server.config.server.host : "localhost";
|
|
788
|
-
process.env.SERVER_PORT ??= String(port);
|
|
789
|
-
try {
|
|
790
|
-
const now = Date.now();
|
|
791
|
-
await server.ssrLoadModule(fileUrl, { fixStacktrace: true });
|
|
792
|
-
this.state.log(`[DEBUG] Alepha app loaded in ${Date.now() - now}ms`);
|
|
793
|
-
await new Promise((r) => setTimeout(r, 10));
|
|
794
|
-
this.state.app = globalThis.__alepha;
|
|
795
|
-
if (!this.state.app) {
|
|
796
|
-
this.state.log("[DEBUG] No app found - skip starting");
|
|
797
|
-
return;
|
|
798
|
-
}
|
|
799
|
-
this.state.app.store.set("alepha.node.server", server.httpServer);
|
|
800
|
-
console.log("");
|
|
801
|
-
await this.state.app.start();
|
|
802
|
-
this.state.started = true;
|
|
803
|
-
process.env = { ...before };
|
|
804
|
-
this.state.log("[DEBUG] Starting Done!");
|
|
805
|
-
} catch (e) {
|
|
806
|
-
if (e instanceof Error) {
|
|
807
|
-
let it = e;
|
|
808
|
-
do {
|
|
809
|
-
server.ssrFixStacktrace(it);
|
|
810
|
-
it = it.cause;
|
|
811
|
-
} while (it instanceof Error);
|
|
812
|
-
server.ssrFixStacktrace(e);
|
|
813
|
-
if (e.cause instanceof Error) server.ssrFixStacktrace(e.cause);
|
|
814
|
-
this.state.app?.log?.error("App failed to start:", e);
|
|
815
|
-
this.state.app?.log?.info("Waiting for changes to restart...");
|
|
816
|
-
}
|
|
817
|
-
this.state.log("[DEBUG] Alepha app start error");
|
|
818
|
-
this.state.started = false;
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
|
-
* Stop the Alepha application.
|
|
823
|
-
*/
|
|
824
|
-
async stop() {
|
|
825
|
-
if (this.state.app?.stop && this.state.started) {
|
|
826
|
-
this.state.log("[DEBUG] Stopping Alepha app...");
|
|
827
|
-
await this.state.app.stop();
|
|
828
|
-
this.state.started = false;
|
|
829
|
-
this.state.log("[DEBUG] Stopping Done!");
|
|
830
|
-
} else this.state.log("[DEBUG] Alepha app not started - skip stop");
|
|
831
|
-
}
|
|
832
|
-
/**
|
|
833
|
-
* Restart the Alepha application.
|
|
834
|
-
*
|
|
835
|
-
* @returns true if the restart was skipped due to locking
|
|
836
|
-
*/
|
|
837
|
-
async restart(server, invalidate) {
|
|
838
|
-
if (this.state.lock) {
|
|
839
|
-
this.state.log("[DEBUG] STILL LOCKING");
|
|
840
|
-
return true;
|
|
841
|
-
}
|
|
842
|
-
this.state.log("[DEBUG] LOCK RESTART");
|
|
843
|
-
this.state.lock = Promise.withResolvers();
|
|
844
|
-
const now = Date.now();
|
|
845
|
-
this.state.log("[DEBUG] RESTART");
|
|
846
|
-
await this.stop();
|
|
847
|
-
this.state.log(`[DEBUG] RESTART (stop) in ${Date.now() - now}ms`);
|
|
848
|
-
if (invalidate) server.moduleGraph.invalidateAll();
|
|
849
|
-
await this.start(server);
|
|
850
|
-
this.state.log(`[DEBUG] RESTART OK in ${Date.now() - now}ms`);
|
|
851
|
-
setTimeout(() => {
|
|
852
|
-
this.state.log("[DEBUG] UNLOCK RESTART");
|
|
853
|
-
this.state.lock?.resolve();
|
|
854
|
-
this.state.lock = void 0;
|
|
855
|
-
}, 500);
|
|
856
|
-
return false;
|
|
857
|
-
}
|
|
858
|
-
/**
|
|
859
|
-
* Send reload event to client.
|
|
860
|
-
*/
|
|
861
|
-
sendReload(server) {
|
|
862
|
-
server.ws.send({
|
|
863
|
-
type: "custom",
|
|
864
|
-
event: "alepha:reload",
|
|
865
|
-
data: {}
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
};
|
|
869
|
-
/**
|
|
870
|
-
* Check if a URL path is a Vite internal file.
|
|
871
|
-
*/
|
|
872
|
-
function isViteInternalPath(pathname) {
|
|
873
|
-
const [path$1] = pathname.split("?");
|
|
874
|
-
if (path$1.startsWith("/@") || path$1.startsWith("/src") || path$1.includes("/node_modules/")) return true;
|
|
875
|
-
return false;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
//#endregion
|
|
879
|
-
//#region ../../src/vite/plugins/viteAlephaBuild.ts
|
|
880
|
-
/**
|
|
881
|
-
* Alepha build plugin for Vite.
|
|
882
|
-
*
|
|
883
|
-
* This plugin orchestrates the complete build process:
|
|
884
|
-
* 1. Build client (if index.html exists)
|
|
885
|
-
* 2. Build server (SSR)
|
|
886
|
-
* 3. Copy assets from packages
|
|
887
|
-
* 4. Pre-render static pages (if enabled)
|
|
888
|
-
* 5. Generate sitemap (if enabled)
|
|
889
|
-
* 6. Generate deployment config (Vercel/Cloudflare/Docker)
|
|
890
|
-
*
|
|
891
|
-
* Build mode can be controlled via ALEPHA_BUILD_MODE env var for CLI integration.
|
|
892
|
-
*/
|
|
893
|
-
async function viteAlephaBuild(options = {}) {
|
|
894
|
-
const entry = options.serverEntry ?? await boot.getServerEntry();
|
|
895
|
-
const distDir = "dist";
|
|
896
|
-
const clientDir = "public";
|
|
897
|
-
let rootConfig = {};
|
|
898
|
-
return {
|
|
899
|
-
name: "alepha:build",
|
|
900
|
-
apply: "build",
|
|
901
|
-
[OPTIONS]: options,
|
|
902
|
-
config(config, ctx) {
|
|
903
|
-
if (process.env.ALEPHA_BUILD_MODE === "cli") return;
|
|
904
|
-
if (!process.env.VITE_DOUBLE_BUILD_DONE) rootConfig = config;
|
|
905
|
-
if (ctx.isSsrBuild || !process.env.VITE_DOUBLE_BUILD_DONE) config.publicDir = false;
|
|
906
|
-
else config.publicDir = "public";
|
|
907
|
-
},
|
|
908
|
-
async buildStart() {
|
|
909
|
-
const buildMode = process.env.ALEPHA_BUILD_MODE;
|
|
910
|
-
if (buildMode === "cli") return;
|
|
911
|
-
if (process.env.VITE_DOUBLE_BUILD_DONE === "true") return;
|
|
912
|
-
process.env.VITE_DOUBLE_BUILD_DONE = "true";
|
|
913
|
-
const hasClient = options.client !== false && await fileExists("index.html");
|
|
914
|
-
const buildClientOptions = typeof options.client === "object" ? options.client : {};
|
|
915
|
-
const stats = options.stats ?? process.env.ALEPHA_BUILD_STATS === "true";
|
|
916
|
-
if (buildMode === "client") {
|
|
917
|
-
if (hasClient) await buildClient({
|
|
918
|
-
...buildClientOptions,
|
|
919
|
-
config: rootConfig,
|
|
920
|
-
dist: `${distDir}/${clientDir}`,
|
|
921
|
-
stats
|
|
922
|
-
});
|
|
923
|
-
process.exit(0);
|
|
924
|
-
}
|
|
925
|
-
if (buildMode === "server") {
|
|
926
|
-
if (entry) {
|
|
927
|
-
let clientBuilt = false;
|
|
928
|
-
try {
|
|
929
|
-
await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
930
|
-
clientBuilt = true;
|
|
931
|
-
} catch {}
|
|
932
|
-
await buildServer({
|
|
933
|
-
config: { base: rootConfig.base || "" },
|
|
934
|
-
entry,
|
|
935
|
-
distDir,
|
|
936
|
-
clientDir: clientBuilt ? clientDir : void 0,
|
|
937
|
-
stats
|
|
938
|
-
});
|
|
939
|
-
}
|
|
940
|
-
process.exit(0);
|
|
941
|
-
}
|
|
942
|
-
if (hasClient) await buildClient({
|
|
943
|
-
...buildClientOptions,
|
|
944
|
-
config: rootConfig,
|
|
945
|
-
dist: `${distDir}/${clientDir}`,
|
|
946
|
-
stats
|
|
947
|
-
});
|
|
948
|
-
let template = "";
|
|
949
|
-
if (hasClient) template = await readFile(`${distDir}/${clientDir}/index.html`, "utf-8");
|
|
950
|
-
if (entry) {
|
|
951
|
-
await buildServer({
|
|
952
|
-
config: { base: rootConfig.base || "" },
|
|
953
|
-
entry,
|
|
954
|
-
distDir,
|
|
955
|
-
clientDir: hasClient ? clientDir : void 0,
|
|
956
|
-
stats
|
|
957
|
-
});
|
|
958
|
-
if (hasClient && options.serverEntry !== false) await unlink(`${distDir}/${clientDir}/index.html`);
|
|
959
|
-
await copyAssets({
|
|
960
|
-
entry: `${distDir}/index.js`,
|
|
961
|
-
distDir
|
|
962
|
-
});
|
|
963
|
-
}
|
|
964
|
-
if (buildClientOptions.sitemap && entry) await writeFile(`${distDir}/${clientDir}/sitemap.xml`, await generateSitemap({
|
|
965
|
-
entry: `${distDir}/index.js`,
|
|
966
|
-
baseUrl: buildClientOptions.sitemap.hostname
|
|
967
|
-
}));
|
|
968
|
-
if (buildClientOptions.prerender && template) await prerenderPages({
|
|
969
|
-
dist: `${distDir}/${clientDir}`,
|
|
970
|
-
entry: `${distDir}/index.js`,
|
|
971
|
-
compress: buildClientOptions.precompress
|
|
972
|
-
});
|
|
973
|
-
if (options.vercel) await generateVercel({
|
|
974
|
-
distDir,
|
|
975
|
-
clientDir,
|
|
976
|
-
config: typeof options.vercel === "boolean" ? {} : options.vercel
|
|
977
|
-
});
|
|
978
|
-
if (options.cloudflare) await generateCloudflare({
|
|
979
|
-
distDir,
|
|
980
|
-
config: typeof options.cloudflare === "boolean" ? {} : options.cloudflare
|
|
981
|
-
});
|
|
982
|
-
if (options.docker) await generateDocker({
|
|
983
|
-
distDir,
|
|
984
|
-
...typeof options.docker === "boolean" ? {} : options.docker
|
|
985
|
-
});
|
|
986
|
-
process.exit(0);
|
|
987
|
-
}
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
//#endregion
|
|
992
|
-
//#region ../../src/vite/plugins/viteAlephaDev.ts
|
|
993
|
-
/**
|
|
994
|
-
* Plug Alepha into Vite development server.
|
|
995
|
-
*
|
|
996
|
-
* This plugin manages the Alepha application lifecycle during development,
|
|
997
|
-
* handling hot module replacement and request forwarding.
|
|
998
|
-
*/
|
|
999
|
-
async function viteAlephaDev(options = {}) {
|
|
1000
|
-
let entry = options.serverEntry;
|
|
1001
|
-
if (!entry) {
|
|
1002
|
-
entry = await boot.getServerEntry();
|
|
1003
|
-
if (!entry) return {
|
|
1004
|
-
name: "alepha-dev",
|
|
1005
|
-
apply: "serve",
|
|
1006
|
-
config() {}
|
|
1007
|
-
};
|
|
1008
|
-
}
|
|
1009
|
-
const runner = createAlephaRunner({
|
|
1010
|
-
entry,
|
|
1011
|
-
debug: options.debug
|
|
1012
|
-
});
|
|
1013
|
-
return {
|
|
1014
|
-
name: "alepha-dev",
|
|
1015
|
-
apply: "serve",
|
|
1016
|
-
configResolved(resolvedConfig) {
|
|
1017
|
-
runner.setConfig(resolvedConfig);
|
|
1018
|
-
},
|
|
1019
|
-
async handleHotUpdate(ctx) {
|
|
1020
|
-
if (options.debug) console.log("[DEBUG] HMR", ctx.file);
|
|
1021
|
-
if (ctx.file.includes("/.idea/")) return [];
|
|
1022
|
-
const isServerOnly = !ctx.modules[0]?._clientModule;
|
|
1023
|
-
const isBrowserOnly = !ctx.modules[0]?._ssrModule;
|
|
1024
|
-
const isSsrEnabled = runner.isSsrEnabled();
|
|
1025
|
-
if (isBrowserOnly) {
|
|
1026
|
-
if (options.debug) console.log("[DEBUG] HMR - browser only - no reason to reload server");
|
|
1027
|
-
return;
|
|
1028
|
-
}
|
|
1029
|
-
const root = process.cwd().replace(/\\/g, "/");
|
|
1030
|
-
const invalidate = !ctx.file.startsWith(root);
|
|
1031
|
-
if (invalidate && options.debug) console.log("[DEBUG] HMR - outside root - invalidate all");
|
|
1032
|
-
if (!isSsrEnabled && isServerOnly) {
|
|
1033
|
-
await runner.restart(ctx.server, invalidate);
|
|
1034
|
-
return [];
|
|
1035
|
-
}
|
|
1036
|
-
if (isSsrEnabled && ctx.modules[0]) {
|
|
1037
|
-
if (await runner.restart(ctx.server, invalidate)) return [];
|
|
1038
|
-
if (!runner.isStarted) {
|
|
1039
|
-
if (options.debug) console.log("[DEBUG] HMR - abort due to app not started");
|
|
1040
|
-
return [];
|
|
1041
|
-
}
|
|
1042
|
-
if (isServerOnly && runner.isStarted) {
|
|
1043
|
-
runner.sendReload(ctx.server);
|
|
1044
|
-
return [];
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
},
|
|
1048
|
-
async configureServer(server) {
|
|
1049
|
-
const middleware = (req, res, next) => {
|
|
1050
|
-
if (runner.isStarted && runner.app && req.url && !isViteInternalPath(req.url)) {
|
|
1051
|
-
let ended = false;
|
|
1052
|
-
const writeHead = res.writeHead.bind(res);
|
|
1053
|
-
res.writeHead = (...args) => {
|
|
1054
|
-
ended = true;
|
|
1055
|
-
return writeHead(args[0], args[1], args[2]);
|
|
1056
|
-
};
|
|
1057
|
-
return runner.app.events.emit("node:request", {
|
|
1058
|
-
req,
|
|
1059
|
-
res
|
|
1060
|
-
}).then(() => {
|
|
1061
|
-
if (!ended) next();
|
|
1062
|
-
});
|
|
1063
|
-
}
|
|
1064
|
-
next();
|
|
1065
|
-
};
|
|
1066
|
-
server.middlewares.use((req, res, next) => {
|
|
1067
|
-
middleware(req, res, next);
|
|
1068
|
-
});
|
|
1069
|
-
server.config.logger.info = (msg) => {
|
|
1070
|
-
console.log(msg);
|
|
1071
|
-
};
|
|
1072
|
-
server.config.logger.clearScreen = () => {};
|
|
1073
|
-
return () => {
|
|
1074
|
-
server.httpServer?.once("listening", () => {
|
|
1075
|
-
runner.start(server);
|
|
1076
|
-
});
|
|
1077
|
-
};
|
|
1078
|
-
},
|
|
1079
|
-
async closeBundle() {}
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
//#endregion
|
|
1084
|
-
//#region ../../src/vite/plugins/viteAlepha.ts
|
|
1085
|
-
function viteAlepha(options = {}) {
|
|
1086
|
-
if (process.env.NODE_ENV === "test") return [];
|
|
1087
|
-
const plugins = [];
|
|
1088
|
-
if (options.react !== false) try {
|
|
1089
|
-
const { default: viteReact } = createRequire(import.meta.url)("@vitejs/plugin-react");
|
|
1090
|
-
plugins.push(viteReact());
|
|
1091
|
-
} catch (e) {}
|
|
1092
|
-
plugins.push(viteAlephaDev(options), viteAlephaBuild(options));
|
|
1093
|
-
plugins[OPTIONS] = options;
|
|
1094
|
-
return plugins;
|
|
1095
|
-
}
|
|
1096
|
-
|
|
1097
|
-
//#endregion
|
|
1098
|
-
//#region ../../src/vite/index.ts
|
|
1099
|
-
/**
|
|
1100
|
-
* Plugin vite for Alepha framework.
|
|
1101
|
-
*
|
|
1102
|
-
* This module provides Vite plugins and configurations to integrate Alepha applications with Vite's build and development processes.
|
|
1103
|
-
*
|
|
1104
|
-
* @example
|
|
1105
|
-
* ```ts
|
|
1106
|
-
* import { defineConfig } from "vite";
|
|
1107
|
-
* import { viteAlepha } from "alepha/vite";
|
|
1108
|
-
*
|
|
1109
|
-
* export default defineConfig({
|
|
1110
|
-
* plugins: [viteAlepha()],
|
|
1111
|
-
* // other Vite configurations...
|
|
1112
|
-
* });
|
|
1113
|
-
* ```
|
|
1114
|
-
*
|
|
1115
|
-
* @module alepha.vite
|
|
1116
|
-
*/
|
|
1117
|
-
|
|
1118
|
-
//#endregion
|
|
1119
|
-
export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlepha, viteAlephaBuild, viteAlephaDev, viteCompress };
|
|
1205
|
+
export { AlephaRunner, boot, buildClient, buildServer, compressFile, copyAssets, createAlephaRunner, createBufferedLogger, devServer, generateCloudflare, generateDocker, generateExternals, generateSitemap, generateVercel, isViteInternalPath, prerenderPages, viteAlephaDev, viteAlephaSsrPreload, viteCompress };
|
|
1120
1206
|
//# sourceMappingURL=index.js.map
|