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/src/core/Alepha.ts
CHANGED
|
@@ -165,6 +165,13 @@ export class Alepha {
|
|
|
165
165
|
...state.env,
|
|
166
166
|
...process.env,
|
|
167
167
|
};
|
|
168
|
+
|
|
169
|
+
// remove empty env variables
|
|
170
|
+
for (const key in state.env) {
|
|
171
|
+
if (state.env[key] === "") {
|
|
172
|
+
delete (state.env as any)[key];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
168
175
|
}
|
|
169
176
|
|
|
170
177
|
// force production mode when building with vite
|
|
@@ -908,6 +915,27 @@ export class Alepha {
|
|
|
908
915
|
return graph;
|
|
909
916
|
}
|
|
910
917
|
|
|
918
|
+
public dump(): AlephaDump {
|
|
919
|
+
const env: Record<string, AlephaDumpEnvVariable> = {};
|
|
920
|
+
for (const [schema] of this.cacheEnv.entries()) {
|
|
921
|
+
const ref = schema as any;
|
|
922
|
+
for (const [key, value] of Object.entries(ref.properties)) {
|
|
923
|
+
const prop = value as any;
|
|
924
|
+
env[key] = {
|
|
925
|
+
description: prop.description,
|
|
926
|
+
default: prop.default,
|
|
927
|
+
required: ref.required?.includes(key) ?? undefined,
|
|
928
|
+
enum: prop.enum ? ([...prop.enum] as Array<string>) : undefined,
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
return {
|
|
934
|
+
env,
|
|
935
|
+
providers: this.graph(),
|
|
936
|
+
};
|
|
937
|
+
}
|
|
938
|
+
|
|
911
939
|
public services<T extends object>(base: Service<T>): Array<T> {
|
|
912
940
|
const list: Array<T> = [];
|
|
913
941
|
for (const [key, value] of this.registry.entries()) {
|
|
@@ -1012,6 +1040,20 @@ export interface Hook<T extends keyof Hooks = any> {
|
|
|
1012
1040
|
|
|
1013
1041
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
1014
1042
|
|
|
1043
|
+
export interface AlephaDump {
|
|
1044
|
+
env: Record<string, AlephaDumpEnvVariable>;
|
|
1045
|
+
providers: Record<string, { from: string[]; as?: string[]; module?: string }>;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
export interface AlephaDumpEnvVariable {
|
|
1049
|
+
description: string;
|
|
1050
|
+
default?: string;
|
|
1051
|
+
required?: boolean;
|
|
1052
|
+
enum?: Array<string>;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
1056
|
+
|
|
1015
1057
|
/**
|
|
1016
1058
|
* This is how we store services in the Alepha container.
|
|
1017
1059
|
*/
|
|
@@ -80,6 +80,10 @@ describe("Alepha#graph", () => {
|
|
|
80
80
|
from: ["StateManager", "CodecManager"],
|
|
81
81
|
module: "alepha.core",
|
|
82
82
|
},
|
|
83
|
+
KeylessJsonSchemaCodec: {
|
|
84
|
+
from: ["CodecManager"],
|
|
85
|
+
module: "alepha.core",
|
|
86
|
+
},
|
|
83
87
|
CodecManager: {
|
|
84
88
|
from: ["Alepha"],
|
|
85
89
|
module: "alepha.core",
|
package/src/core/index.shared.ts
CHANGED
|
@@ -28,6 +28,7 @@ export * from "./providers/AlsProvider.ts";
|
|
|
28
28
|
export * from "./providers/CodecManager.ts";
|
|
29
29
|
export * from "./providers/EventManager.ts";
|
|
30
30
|
export * from "./providers/JsonSchemaCodec.ts";
|
|
31
|
+
export * from "./providers/KeylessJsonSchemaCodec.ts";
|
|
31
32
|
export * from "./providers/SchemaCodec.ts";
|
|
32
33
|
export * from "./providers/StateManager.ts";
|
|
33
34
|
export * from "./providers/TypeProvider.ts";
|
package/src/core/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { CodecManager } from "./providers/CodecManager.ts";
|
|
|
11
11
|
import { EventManager } from "./providers/EventManager.ts";
|
|
12
12
|
import { Json } from "./providers/Json.ts";
|
|
13
13
|
import { JsonSchemaCodec } from "./providers/JsonSchemaCodec.ts";
|
|
14
|
+
import { KeylessJsonSchemaCodec } from "./providers/KeylessJsonSchemaCodec.ts";
|
|
14
15
|
import { SchemaCodec } from "./providers/SchemaCodec.ts";
|
|
15
16
|
import { SchemaValidator } from "./providers/SchemaValidator.ts";
|
|
16
17
|
import { StateManager } from "./providers/StateManager.ts";
|
|
@@ -30,6 +31,7 @@ export const AlephaCore = $module({
|
|
|
30
31
|
AlsProvider,
|
|
31
32
|
Json,
|
|
32
33
|
JsonSchemaCodec,
|
|
34
|
+
KeylessJsonSchemaCodec,
|
|
33
35
|
SchemaCodec,
|
|
34
36
|
SchemaValidator,
|
|
35
37
|
],
|
|
@@ -82,12 +82,16 @@ export class HookPrimitive<T extends keyof Hooks> extends Primitive<
|
|
|
82
82
|
public called = 0;
|
|
83
83
|
|
|
84
84
|
protected onInit() {
|
|
85
|
+
// Store reference to handler to avoid property access in hot path
|
|
86
|
+
const handler = this.options.handler;
|
|
87
|
+
|
|
85
88
|
this.alepha.events.on(this.options.on, {
|
|
86
89
|
caller: this.config.service,
|
|
87
90
|
priority: this.options.priority,
|
|
88
|
-
|
|
91
|
+
// Return handler result directly - EventManager checks if it's a promise
|
|
92
|
+
callback: (args: any) => {
|
|
89
93
|
this.called += 1;
|
|
90
|
-
|
|
94
|
+
return handler(args);
|
|
91
95
|
},
|
|
92
96
|
});
|
|
93
97
|
}
|
|
@@ -51,6 +51,10 @@ describe("$module", () => {
|
|
|
51
51
|
from: ["StateManager", "CodecManager"],
|
|
52
52
|
module: "alepha.core",
|
|
53
53
|
},
|
|
54
|
+
KeylessJsonSchemaCodec: {
|
|
55
|
+
from: ["CodecManager"],
|
|
56
|
+
module: "alepha.core",
|
|
57
|
+
},
|
|
54
58
|
CodecManager: {
|
|
55
59
|
from: ["Alepha"],
|
|
56
60
|
module: "alepha.core",
|
|
@@ -44,7 +44,10 @@ describe("CodecManager", () => {
|
|
|
44
44
|
const codecManager = alepha.codec;
|
|
45
45
|
const customCodec = new CustomCodec();
|
|
46
46
|
|
|
47
|
-
codecManager.register(
|
|
47
|
+
codecManager.register({
|
|
48
|
+
name: "custom",
|
|
49
|
+
codec: customCodec,
|
|
50
|
+
});
|
|
48
51
|
|
|
49
52
|
const retrieved = codecManager.getCodec("custom");
|
|
50
53
|
expect(retrieved).toBe(customCodec);
|
|
@@ -74,10 +77,13 @@ describe("CodecManager", () => {
|
|
|
74
77
|
|
|
75
78
|
const alepha = Alepha.create();
|
|
76
79
|
const codecManager = alepha.codec;
|
|
77
|
-
codecManager.register(
|
|
80
|
+
codecManager.register({
|
|
81
|
+
name: "mock",
|
|
82
|
+
codec: new MockCodec(),
|
|
83
|
+
});
|
|
78
84
|
|
|
79
85
|
expect(() => codecManager.getCodec("missing")).toThrow(
|
|
80
|
-
'Codec "missing" not found. Available codecs: json, mock',
|
|
86
|
+
'Codec "missing" not found. Available codecs: json, keyless, mock',
|
|
81
87
|
);
|
|
82
88
|
});
|
|
83
89
|
});
|
|
@@ -298,7 +304,7 @@ describe("CodecManager", () => {
|
|
|
298
304
|
|
|
299
305
|
const alepha = Alepha.create();
|
|
300
306
|
const codecManager = alepha.codec;
|
|
301
|
-
codecManager.register("custom", new CustomCodec());
|
|
307
|
+
codecManager.register({ name: "custom", codec: new CustomCodec() });
|
|
302
308
|
|
|
303
309
|
const schema = t.object({ value: t.text() });
|
|
304
310
|
const result = codecManager.encode(
|
|
@@ -513,7 +519,7 @@ describe("CodecManager", () => {
|
|
|
513
519
|
|
|
514
520
|
const alepha = Alepha.create();
|
|
515
521
|
const codecManager = alepha.codec;
|
|
516
|
-
codecManager.register("custom", new CustomCodec());
|
|
522
|
+
codecManager.register({ name: "custom", codec: new CustomCodec() });
|
|
517
523
|
|
|
518
524
|
const schema = t.object({ value: t.text() });
|
|
519
525
|
const result = codecManager.decode(
|
|
@@ -631,7 +637,7 @@ describe("CodecManager", () => {
|
|
|
631
637
|
codec = $inject(CodecManager);
|
|
632
638
|
|
|
633
639
|
constructor() {
|
|
634
|
-
this.codec.register("custom", new CustomCodec());
|
|
640
|
+
this.codec.register({ name: "custom", codec: new CustomCodec() });
|
|
635
641
|
}
|
|
636
642
|
}
|
|
637
643
|
|
|
@@ -2,6 +2,7 @@ import type { StaticEncode, TSchema } from "typebox";
|
|
|
2
2
|
import { AlephaError } from "../errors/AlephaError.ts";
|
|
3
3
|
import { $inject } from "../primitives/$inject.ts";
|
|
4
4
|
import { JsonSchemaCodec } from "./JsonSchemaCodec.ts";
|
|
5
|
+
import { KeylessJsonSchemaCodec } from "./KeylessJsonSchemaCodec.ts";
|
|
5
6
|
import type { SchemaCodec } from "./SchemaCodec.ts";
|
|
6
7
|
import { SchemaValidator, type ValidateOptions } from "./SchemaValidator.ts";
|
|
7
8
|
import type { Static } from "./TypeProvider.ts";
|
|
@@ -61,23 +62,34 @@ export interface DecodeOptions {
|
|
|
61
62
|
export class CodecManager {
|
|
62
63
|
protected readonly codecs: Map<string, SchemaCodec> = new Map();
|
|
63
64
|
protected readonly jsonCodec = $inject(JsonSchemaCodec);
|
|
65
|
+
protected readonly keylessCodec = $inject(KeylessJsonSchemaCodec);
|
|
64
66
|
protected readonly schemaValidator = $inject(SchemaValidator);
|
|
65
67
|
|
|
66
68
|
public default = "json";
|
|
67
69
|
|
|
68
70
|
constructor() {
|
|
69
71
|
// Register default JSON codec
|
|
70
|
-
this.register(
|
|
72
|
+
this.register({
|
|
73
|
+
name: "json",
|
|
74
|
+
codec: this.jsonCodec,
|
|
75
|
+
default: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Register keyless JSON codec (smaller, faster decoding)
|
|
79
|
+
this.register({
|
|
80
|
+
name: "keyless",
|
|
81
|
+
codec: this.keylessCodec,
|
|
82
|
+
});
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
/**
|
|
74
86
|
* Register a new codec format.
|
|
75
|
-
*
|
|
76
|
-
* @param name - The name of the codec (e.g., 'json', 'protobuf')
|
|
77
|
-
* @param codec - The codec implementation
|
|
78
87
|
*/
|
|
79
|
-
public register(
|
|
80
|
-
this.codecs.set(name, codec);
|
|
88
|
+
public register(opts: CodecRegisterOptions): void {
|
|
89
|
+
this.codecs.set(opts.name, opts.codec);
|
|
90
|
+
if (opts.default) {
|
|
91
|
+
this.default = opts.name;
|
|
92
|
+
}
|
|
81
93
|
}
|
|
82
94
|
|
|
83
95
|
/**
|
|
@@ -164,3 +176,11 @@ export class CodecManager {
|
|
|
164
176
|
return this.schemaValidator.validate(schema, value, options);
|
|
165
177
|
}
|
|
166
178
|
}
|
|
179
|
+
|
|
180
|
+
// ---------------------------------------------------------------------------------------------------------------------
|
|
181
|
+
|
|
182
|
+
export interface CodecRegisterOptions {
|
|
183
|
+
name: string;
|
|
184
|
+
codec: SchemaCodec;
|
|
185
|
+
default?: boolean;
|
|
186
|
+
}
|
|
@@ -3,6 +3,23 @@ import { AlephaError } from "../errors/AlephaError.ts";
|
|
|
3
3
|
import type { Async } from "../interfaces/Async.ts";
|
|
4
4
|
import type { LoggerInterface } from "../interfaces/LoggerInterface.ts";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Compiled event executor - optimized for hot paths.
|
|
8
|
+
* Returns void for sync-only chains, Promise<void> for chains with async hooks.
|
|
9
|
+
*/
|
|
10
|
+
export type CompiledEventExecutor<T> = (payload: T) => void | Promise<void>;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Options for compiled event executors.
|
|
14
|
+
*/
|
|
15
|
+
export interface CompileOptions {
|
|
16
|
+
/**
|
|
17
|
+
* If true, errors will be caught and logged instead of throwing.
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
catch?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
6
23
|
export class EventManager {
|
|
7
24
|
public logFn?: () => LoggerInterface | undefined;
|
|
8
25
|
|
|
@@ -59,8 +76,114 @@ export class EventManager {
|
|
|
59
76
|
};
|
|
60
77
|
}
|
|
61
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Compiles an event into an optimized executor function.
|
|
81
|
+
*
|
|
82
|
+
* Call this after all hooks are registered (e.g., after Alepha.start()).
|
|
83
|
+
* The returned function checks each hook's return value and awaits promises.
|
|
84
|
+
* Returns undefined if all hooks are sync, or a Promise if any hook returns one.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* // At startup (after hooks are registered)
|
|
89
|
+
* const onRequest = alepha.events.compile("server:onRequest", { catch: true });
|
|
90
|
+
*
|
|
91
|
+
* // In hot path - only await if promise returned
|
|
92
|
+
* const result = onRequest({ request, route });
|
|
93
|
+
* if (result) await result;
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
public compile<T extends keyof Hooks>(
|
|
97
|
+
event: T,
|
|
98
|
+
options: CompileOptions = {},
|
|
99
|
+
): CompiledEventExecutor<Hooks[T]> {
|
|
100
|
+
const hooks = this.events[event];
|
|
101
|
+
|
|
102
|
+
// No hooks - return no-op
|
|
103
|
+
if (!hooks || hooks.length === 0) {
|
|
104
|
+
return () => {};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const catchErrors = options.catch ?? false;
|
|
108
|
+
const log = this.log;
|
|
109
|
+
|
|
110
|
+
// Helper to run remaining hooks sequentially after first async hook
|
|
111
|
+
const runRemainingAsync = async (
|
|
112
|
+
startIndex: number,
|
|
113
|
+
payload: Hooks[T],
|
|
114
|
+
): Promise<void> => {
|
|
115
|
+
for (let i = startIndex; i < hooks.length; i++) {
|
|
116
|
+
const hook = hooks[i];
|
|
117
|
+
try {
|
|
118
|
+
const result = hook.callback(payload);
|
|
119
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
120
|
+
if (catchErrors) {
|
|
121
|
+
await (result as Promise<void>).catch((error) => {
|
|
122
|
+
log?.error(
|
|
123
|
+
`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`,
|
|
124
|
+
error,
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
} else {
|
|
128
|
+
await result;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if (catchErrors) {
|
|
133
|
+
log?.error(
|
|
134
|
+
`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`,
|
|
135
|
+
error,
|
|
136
|
+
);
|
|
137
|
+
} else {
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// Return executor that runs sync hooks synchronously, then switches to async
|
|
145
|
+
// when encountering the first async hook. Returns void if all sync.
|
|
146
|
+
return (payload: Hooks[T]): void | Promise<void> => {
|
|
147
|
+
for (let i = 0; i < hooks.length; i++) {
|
|
148
|
+
const hook = hooks[i];
|
|
149
|
+
try {
|
|
150
|
+
const result = hook.callback(payload);
|
|
151
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
152
|
+
// Hit an async hook - await it and continue remaining hooks async
|
|
153
|
+
if (catchErrors) {
|
|
154
|
+
return (result as Promise<void>)
|
|
155
|
+
.catch((error) => {
|
|
156
|
+
log?.error(
|
|
157
|
+
`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`,
|
|
158
|
+
error,
|
|
159
|
+
);
|
|
160
|
+
})
|
|
161
|
+
.then(() => runRemainingAsync(i + 1, payload));
|
|
162
|
+
}
|
|
163
|
+
return (result as Promise<void>).then(() =>
|
|
164
|
+
runRemainingAsync(i + 1, payload),
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
} catch (error) {
|
|
168
|
+
if (catchErrors) {
|
|
169
|
+
log?.error(
|
|
170
|
+
`${String(event)}(${hook.caller?.name ?? "unknown"}) ERROR`,
|
|
171
|
+
error,
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// All hooks were sync - return void
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
62
182
|
/**
|
|
63
183
|
* Emits the specified event with the given payload.
|
|
184
|
+
*
|
|
185
|
+
* For hot paths (like HTTP request handling), use compile() instead
|
|
186
|
+
* to get an optimized executor.
|
|
64
187
|
*/
|
|
65
188
|
public async emit<T extends keyof Hooks>(
|
|
66
189
|
func: T,
|
|
@@ -87,36 +210,65 @@ export class EventManager {
|
|
|
87
210
|
catch?: boolean;
|
|
88
211
|
} = {},
|
|
89
212
|
): Promise<void> {
|
|
213
|
+
// Fast path: no listeners for this event
|
|
214
|
+
const events = this.events[func];
|
|
215
|
+
if (!events || events.length === 0) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Fast path: single listener, no logging, no reverse
|
|
220
|
+
if (events.length === 1 && !options.log && !options.reverse) {
|
|
221
|
+
const hook = events[0];
|
|
222
|
+
try {
|
|
223
|
+
const result = hook.callback(payload);
|
|
224
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
225
|
+
await result;
|
|
226
|
+
}
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (options.catch) {
|
|
229
|
+
this.log?.error(
|
|
230
|
+
`${String(func)}(${hook.caller?.name ?? "unknown"}) ERROR`,
|
|
231
|
+
error,
|
|
232
|
+
);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
90
240
|
const ctx: any = {};
|
|
91
241
|
|
|
92
242
|
if (options.log) {
|
|
93
|
-
ctx.now =
|
|
94
|
-
this.log?.trace(`${func} ...`);
|
|
243
|
+
ctx.now = performance.now();
|
|
244
|
+
this.log?.trace(`${String(func)} ...`);
|
|
95
245
|
}
|
|
96
246
|
|
|
97
|
-
let
|
|
98
|
-
|
|
247
|
+
let eventList = events;
|
|
99
248
|
if (options.reverse) {
|
|
100
|
-
|
|
249
|
+
eventList = events.toReversed();
|
|
101
250
|
}
|
|
102
251
|
|
|
103
|
-
for (const hook of
|
|
252
|
+
for (const hook of eventList) {
|
|
104
253
|
const name = hook.caller?.name ?? "unknown";
|
|
105
254
|
if (options.log) {
|
|
106
|
-
ctx.now2 =
|
|
107
|
-
this.log?.trace(`${func}(${name}) ...`);
|
|
255
|
+
ctx.now2 = performance.now();
|
|
256
|
+
this.log?.trace(`${String(func)}(${name}) ...`);
|
|
108
257
|
}
|
|
109
258
|
|
|
110
259
|
try {
|
|
111
|
-
|
|
260
|
+
const result = hook.callback(payload);
|
|
261
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
262
|
+
await result;
|
|
263
|
+
}
|
|
112
264
|
} catch (error) {
|
|
113
265
|
if (options.catch) {
|
|
114
|
-
this.log?.error(`${func}(${name}) ERROR`, error);
|
|
266
|
+
this.log?.error(`${String(func)}(${name}) ERROR`, error);
|
|
115
267
|
continue;
|
|
116
268
|
}
|
|
117
269
|
if (options.log) {
|
|
118
270
|
throw new AlephaError(
|
|
119
|
-
`Failed during '${func}()' hook for service: ${name}`,
|
|
271
|
+
`Failed during '${String(func)}()' hook for service: ${name}`,
|
|
120
272
|
{ cause: error },
|
|
121
273
|
);
|
|
122
274
|
}
|
|
@@ -124,12 +276,16 @@ export class EventManager {
|
|
|
124
276
|
}
|
|
125
277
|
|
|
126
278
|
if (options.log) {
|
|
127
|
-
this.log?.debug(
|
|
279
|
+
this.log?.debug(
|
|
280
|
+
`${String(func)}(${name}) OK [${(performance.now() - ctx.now2).toFixed(1)}ms]`,
|
|
281
|
+
);
|
|
128
282
|
}
|
|
129
283
|
}
|
|
130
284
|
|
|
131
285
|
if (options.log) {
|
|
132
|
-
this.log?.debug(
|
|
286
|
+
this.log?.debug(
|
|
287
|
+
`${String(func)} OK [${(performance.now() - ctx.now).toFixed(1)}ms]`,
|
|
288
|
+
);
|
|
133
289
|
}
|
|
134
290
|
}
|
|
135
291
|
}
|