@engjts/nexus 0.1.7 → 0.1.9

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.
Files changed (259) hide show
  1. package/dist/advanced/playground/generatePlaygroundHTML.d.ts.map +1 -1
  2. package/dist/advanced/playground/generatePlaygroundHTML.js +107 -0
  3. package/dist/advanced/playground/generatePlaygroundHTML.js.map +1 -1
  4. package/dist/advanced/playground/playground.d.ts +19 -0
  5. package/dist/advanced/playground/playground.d.ts.map +1 -1
  6. package/dist/advanced/playground/playground.js +70 -0
  7. package/dist/advanced/playground/playground.js.map +1 -1
  8. package/dist/advanced/playground/types.d.ts +20 -0
  9. package/dist/advanced/playground/types.d.ts.map +1 -1
  10. package/dist/core/application.d.ts +14 -0
  11. package/dist/core/application.d.ts.map +1 -1
  12. package/dist/core/application.js +173 -71
  13. package/dist/core/application.js.map +1 -1
  14. package/dist/core/context-pool.d.ts +2 -13
  15. package/dist/core/context-pool.d.ts.map +1 -1
  16. package/dist/core/context-pool.js +7 -45
  17. package/dist/core/context-pool.js.map +1 -1
  18. package/dist/core/context.d.ts +108 -5
  19. package/dist/core/context.d.ts.map +1 -1
  20. package/dist/core/context.js +449 -53
  21. package/dist/core/context.js.map +1 -1
  22. package/dist/core/index.d.ts +1 -0
  23. package/dist/core/index.d.ts.map +1 -1
  24. package/dist/core/index.js +9 -1
  25. package/dist/core/index.js.map +1 -1
  26. package/dist/core/middleware.d.ts +6 -0
  27. package/dist/core/middleware.d.ts.map +1 -1
  28. package/dist/core/middleware.js +83 -84
  29. package/dist/core/middleware.js.map +1 -1
  30. package/dist/core/performance/fast-json.d.ts +149 -0
  31. package/dist/core/performance/fast-json.d.ts.map +1 -0
  32. package/dist/core/performance/fast-json.js +473 -0
  33. package/dist/core/performance/fast-json.js.map +1 -0
  34. package/dist/core/router/file-router.d.ts +20 -7
  35. package/dist/core/router/file-router.d.ts.map +1 -1
  36. package/dist/core/router/file-router.js +41 -13
  37. package/dist/core/router/file-router.js.map +1 -1
  38. package/dist/core/router/index.d.ts +6 -0
  39. package/dist/core/router/index.d.ts.map +1 -1
  40. package/dist/core/router/index.js +33 -6
  41. package/dist/core/router/index.js.map +1 -1
  42. package/dist/core/router/radix-tree.d.ts +4 -1
  43. package/dist/core/router/radix-tree.d.ts.map +1 -1
  44. package/dist/core/router/radix-tree.js +7 -3
  45. package/dist/core/router/radix-tree.js.map +1 -1
  46. package/dist/core/serializer.d.ts +251 -0
  47. package/dist/core/serializer.d.ts.map +1 -0
  48. package/dist/core/serializer.js +290 -0
  49. package/dist/core/serializer.js.map +1 -0
  50. package/dist/core/types.d.ts +39 -1
  51. package/dist/core/types.d.ts.map +1 -1
  52. package/dist/core/types.js.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +12 -2
  56. package/dist/index.js.map +1 -1
  57. package/package.json +3 -1
  58. package/documentation/01-getting-started.md +0 -240
  59. package/documentation/02-context.md +0 -335
  60. package/documentation/03-routing.md +0 -397
  61. package/documentation/04-middleware.md +0 -483
  62. package/documentation/05-validation.md +0 -514
  63. package/documentation/06-error-handling.md +0 -465
  64. package/documentation/07-performance.md +0 -364
  65. package/documentation/08-adapters.md +0 -470
  66. package/documentation/09-api-reference.md +0 -548
  67. package/documentation/10-examples.md +0 -582
  68. package/documentation/11-deployment.md +0 -477
  69. package/documentation/12-sentry.md +0 -620
  70. package/documentation/13-sentry-data-storage.md +0 -996
  71. package/documentation/14-sentry-data-reference.md +0 -457
  72. package/documentation/15-sentry-summary.md +0 -409
  73. package/documentation/16-alerts-system.md +0 -745
  74. package/documentation/17-alert-adapters.md +0 -696
  75. package/documentation/18-alerts-implementation-summary.md +0 -385
  76. package/documentation/19-class-based-routing.md +0 -840
  77. package/documentation/20-websocket-realtime.md +0 -813
  78. package/documentation/21-cache-system.md +0 -510
  79. package/documentation/22-job-queue.md +0 -772
  80. package/documentation/23-sentry-plugin.md +0 -551
  81. package/documentation/24-testing-utilities.md +0 -1287
  82. package/documentation/25-api-versioning.md +0 -533
  83. package/documentation/26-context-store.md +0 -607
  84. package/documentation/27-dependency-injection.md +0 -329
  85. package/documentation/28-lifecycle-hooks.md +0 -521
  86. package/documentation/29-package-structure.md +0 -196
  87. package/documentation/30-plugin-system.md +0 -414
  88. package/documentation/31-jwt-authentication.md +0 -597
  89. package/documentation/32-cli.md +0 -268
  90. package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
  91. package/documentation/ALERTS-INDEX.md +0 -330
  92. package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
  93. package/documentation/README.md +0 -178
  94. package/documentation/index.html +0 -34
  95. package/modern_framework_paper.md +0 -1870
  96. package/public/css/style.css +0 -87
  97. package/public/index.html +0 -34
  98. package/public/js/app.js +0 -27
  99. package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
  100. package/src/advanced/cache/MultiTierCache.ts +0 -194
  101. package/src/advanced/cache/RedisCacheStore.ts +0 -341
  102. package/src/advanced/cache/index.ts +0 -5
  103. package/src/advanced/cache/types.ts +0 -40
  104. package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
  105. package/src/advanced/graphql/index.ts +0 -22
  106. package/src/advanced/graphql/server.ts +0 -252
  107. package/src/advanced/graphql/types.ts +0 -42
  108. package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
  109. package/src/advanced/jobs/JobQueue.ts +0 -556
  110. package/src/advanced/jobs/RedisQueueStore.ts +0 -367
  111. package/src/advanced/jobs/index.ts +0 -5
  112. package/src/advanced/jobs/types.ts +0 -70
  113. package/src/advanced/observability/APMManager.ts +0 -163
  114. package/src/advanced/observability/AlertManager.ts +0 -109
  115. package/src/advanced/observability/MetricRegistry.ts +0 -151
  116. package/src/advanced/observability/ObservabilityCenter.ts +0 -304
  117. package/src/advanced/observability/StructuredLogger.ts +0 -154
  118. package/src/advanced/observability/TracingManager.ts +0 -117
  119. package/src/advanced/observability/adapters.ts +0 -304
  120. package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
  121. package/src/advanced/observability/index.ts +0 -11
  122. package/src/advanced/observability/types.ts +0 -174
  123. package/src/advanced/playground/extractPathParams.ts +0 -6
  124. package/src/advanced/playground/generateFieldExample.ts +0 -31
  125. package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1849
  126. package/src/advanced/playground/generateSummary.ts +0 -19
  127. package/src/advanced/playground/getTagFromPath.ts +0 -9
  128. package/src/advanced/playground/index.ts +0 -8
  129. package/src/advanced/playground/playground.ts +0 -170
  130. package/src/advanced/playground/types.ts +0 -20
  131. package/src/advanced/playground/zodToExample.ts +0 -16
  132. package/src/advanced/playground/zodToParams.ts +0 -15
  133. package/src/advanced/postman/buildAuth.ts +0 -31
  134. package/src/advanced/postman/buildBody.ts +0 -15
  135. package/src/advanced/postman/buildQueryParams.ts +0 -27
  136. package/src/advanced/postman/buildRequestItem.ts +0 -36
  137. package/src/advanced/postman/buildResponses.ts +0 -11
  138. package/src/advanced/postman/buildUrl.ts +0 -33
  139. package/src/advanced/postman/capitalize.ts +0 -4
  140. package/src/advanced/postman/generateCollection.ts +0 -59
  141. package/src/advanced/postman/generateEnvironment.ts +0 -34
  142. package/src/advanced/postman/generateExampleFromZod.ts +0 -21
  143. package/src/advanced/postman/generateFieldExample.ts +0 -45
  144. package/src/advanced/postman/generateName.ts +0 -20
  145. package/src/advanced/postman/generateUUID.ts +0 -11
  146. package/src/advanced/postman/getTagFromPath.ts +0 -10
  147. package/src/advanced/postman/index.ts +0 -28
  148. package/src/advanced/postman/postman.ts +0 -156
  149. package/src/advanced/postman/slugify.ts +0 -7
  150. package/src/advanced/postman/types.ts +0 -140
  151. package/src/advanced/realtime/index.ts +0 -18
  152. package/src/advanced/realtime/websocket.ts +0 -231
  153. package/src/advanced/sentry/index.ts +0 -1236
  154. package/src/advanced/sentry/types.ts +0 -355
  155. package/src/advanced/static/generateDirectoryListing.ts +0 -47
  156. package/src/advanced/static/generateETag.ts +0 -7
  157. package/src/advanced/static/getMimeType.ts +0 -9
  158. package/src/advanced/static/index.ts +0 -32
  159. package/src/advanced/static/isSafePath.ts +0 -13
  160. package/src/advanced/static/publicDir.ts +0 -21
  161. package/src/advanced/static/serveStatic.ts +0 -225
  162. package/src/advanced/static/spa.ts +0 -24
  163. package/src/advanced/static/types.ts +0 -159
  164. package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
  165. package/src/advanced/swagger/buildOperation.ts +0 -61
  166. package/src/advanced/swagger/buildParameters.ts +0 -61
  167. package/src/advanced/swagger/buildRequestBody.ts +0 -21
  168. package/src/advanced/swagger/buildResponses.ts +0 -54
  169. package/src/advanced/swagger/capitalize.ts +0 -5
  170. package/src/advanced/swagger/convertPath.ts +0 -9
  171. package/src/advanced/swagger/createSwagger.ts +0 -12
  172. package/src/advanced/swagger/generateOperationId.ts +0 -21
  173. package/src/advanced/swagger/generateSpec.ts +0 -105
  174. package/src/advanced/swagger/generateSummary.ts +0 -24
  175. package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
  176. package/src/advanced/swagger/generateThemeCss.ts +0 -53
  177. package/src/advanced/swagger/index.ts +0 -25
  178. package/src/advanced/swagger/swagger.ts +0 -237
  179. package/src/advanced/swagger/types.ts +0 -206
  180. package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
  181. package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
  182. package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
  183. package/src/advanced/testing/factory.ts +0 -509
  184. package/src/advanced/testing/harness.ts +0 -612
  185. package/src/advanced/testing/index.ts +0 -430
  186. package/src/advanced/testing/load-test.ts +0 -618
  187. package/src/advanced/testing/mock-server.ts +0 -498
  188. package/src/advanced/testing/mock.ts +0 -670
  189. package/src/cli/bin.ts +0 -9
  190. package/src/cli/cli.ts +0 -158
  191. package/src/cli/commands/add.ts +0 -178
  192. package/src/cli/commands/build.ts +0 -73
  193. package/src/cli/commands/create.ts +0 -166
  194. package/src/cli/commands/dev.ts +0 -85
  195. package/src/cli/commands/generate.ts +0 -99
  196. package/src/cli/commands/help.ts +0 -95
  197. package/src/cli/commands/init.ts +0 -91
  198. package/src/cli/commands/version.ts +0 -38
  199. package/src/cli/index.ts +0 -6
  200. package/src/cli/templates/generators.ts +0 -359
  201. package/src/cli/templates/index.ts +0 -680
  202. package/src/cli/utils/exec.ts +0 -52
  203. package/src/cli/utils/file-system.ts +0 -78
  204. package/src/cli/utils/logger.ts +0 -111
  205. package/src/core/adapter.ts +0 -88
  206. package/src/core/application.ts +0 -1335
  207. package/src/core/context-pool.ts +0 -127
  208. package/src/core/context.ts +0 -412
  209. package/src/core/index.ts +0 -80
  210. package/src/core/middleware.ts +0 -262
  211. package/src/core/performance/buffer-pool.ts +0 -108
  212. package/src/core/performance/middleware-optimizer.ts +0 -162
  213. package/src/core/plugin/PluginManager.ts +0 -435
  214. package/src/core/plugin/builder.ts +0 -358
  215. package/src/core/plugin/index.ts +0 -50
  216. package/src/core/plugin/types.ts +0 -214
  217. package/src/core/router/file-router.ts +0 -594
  218. package/src/core/router/index.ts +0 -227
  219. package/src/core/router/radix-tree.ts +0 -226
  220. package/src/core/store/index.ts +0 -30
  221. package/src/core/store/registry.ts +0 -178
  222. package/src/core/store/request-store.ts +0 -240
  223. package/src/core/store/types.ts +0 -233
  224. package/src/core/types.ts +0 -574
  225. package/src/database/adapter.ts +0 -35
  226. package/src/database/adapters/index.ts +0 -1
  227. package/src/database/adapters/mysql.ts +0 -669
  228. package/src/database/database.ts +0 -70
  229. package/src/database/dialect.ts +0 -388
  230. package/src/database/index.ts +0 -12
  231. package/src/database/migrations.ts +0 -86
  232. package/src/database/optimizer.ts +0 -125
  233. package/src/database/query-builder.ts +0 -404
  234. package/src/database/realtime.ts +0 -53
  235. package/src/database/schema.ts +0 -71
  236. package/src/database/transactions.ts +0 -56
  237. package/src/database/types.ts +0 -87
  238. package/src/deployment/cluster.ts +0 -471
  239. package/src/deployment/config.ts +0 -454
  240. package/src/deployment/docker.ts +0 -599
  241. package/src/deployment/graceful-shutdown.ts +0 -373
  242. package/src/deployment/index.ts +0 -56
  243. package/src/index.ts +0 -264
  244. package/src/security/adapter.ts +0 -318
  245. package/src/security/auth/JWTPlugin.ts +0 -234
  246. package/src/security/auth/JWTProvider.ts +0 -316
  247. package/src/security/auth/adapter.ts +0 -12
  248. package/src/security/auth/jwt.ts +0 -234
  249. package/src/security/auth/middleware.ts +0 -188
  250. package/src/security/csrf.ts +0 -220
  251. package/src/security/headers.ts +0 -108
  252. package/src/security/index.ts +0 -60
  253. package/src/security/rate-limit/adapter.ts +0 -7
  254. package/src/security/rate-limit/memory.ts +0 -108
  255. package/src/security/rate-limit/middleware.ts +0 -181
  256. package/src/security/sanitization.ts +0 -75
  257. package/src/security/types.ts +0 -240
  258. package/src/security/utils.ts +0 -52
  259. package/tsconfig.json +0 -39
@@ -1,227 +0,0 @@
1
- /**
2
- * Router implementation with schema validation
3
- */
4
-
5
- import { RadixTree } from './radix-tree';
6
- import {
7
- HTTPMethod,
8
- Handler,
9
- Middleware,
10
- RouteConfig,
11
- RouteMatch,
12
- SchemaConfig,
13
- RouteMeta,
14
- Context
15
- } from '../types';
16
-
17
- /**
18
- * Route with validation schema and metadata
19
- */
20
- export interface RouteEntry {
21
- handler: Handler;
22
- middlewares: Middleware[];
23
- schema?: SchemaConfig;
24
- meta?: RouteMeta;
25
- }
26
-
27
- /**
28
- * Router class
29
- */
30
- export class Router {
31
- private trees: Map<HTTPMethod, RadixTree> = new Map();
32
- private routes: Array<{ method: HTTPMethod; path: string; config: RouteEntry }> = [];
33
- private prefix: string = '';
34
-
35
- constructor(prefix: string = '') {
36
- this.prefix = prefix;
37
- // Initialize trees for each HTTP method
38
- const methods: HTTPMethod[] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
39
- for (const method of methods) {
40
- this.trees.set(method, new RadixTree());
41
- }
42
- }
43
-
44
- /**
45
- * Register a route
46
- */
47
- addRoute(config: RouteConfig): void {
48
- const { method, path, handler, middlewares = [], schema, meta } = config;
49
- const fullPath = this.prefix ? `${this.prefix}${path}` : path;
50
-
51
- const tree = this.trees.get(method);
52
- if (!tree) {
53
- throw new Error(`Unsupported HTTP method: ${method}`);
54
- }
55
-
56
- // Wrap handler with schema validation if provided
57
- const wrappedHandler = schema ? this.wrapWithValidation(handler, schema) : handler;
58
-
59
- tree.insert(fullPath, wrappedHandler, middlewares);
60
-
61
- // Store for introspection (including schema and meta for documentation)
62
- this.routes.push({
63
- method,
64
- path: fullPath,
65
- config: { handler: wrappedHandler, middlewares, schema, meta }
66
- });
67
- }
68
-
69
- /**
70
- * Find a matching route
71
- */
72
- match(method: string, path: string): RouteMatch | null {
73
- const tree = this.trees.get(method as HTTPMethod);
74
- if (!tree) {
75
- return null;
76
- }
77
-
78
- const result = tree.search(path);
79
- if (!result) {
80
- return null;
81
- }
82
-
83
- return {
84
- handler: result.handler,
85
- params: result.params,
86
- middlewares: result.middlewares,
87
- schema: undefined // Schema already applied in wrapped handler
88
- };
89
- }
90
-
91
- /**
92
- * Get all registered routes with full metadata
93
- */
94
- getRoutes(): Array<{ method: string; path: string; schema?: SchemaConfig; meta?: RouteMeta }> {
95
- return this.routes.map(r => ({
96
- method: r.method,
97
- path: r.path,
98
- schema: r.config.schema,
99
- meta: r.config.meta
100
- }));
101
- }
102
-
103
- /**
104
- * Get raw route configs for merging into Application
105
- */
106
- getRawRoutes(): Array<{ method: HTTPMethod; path: string; config: RouteEntry }> {
107
- return this.routes;
108
- }
109
-
110
- /**
111
- * Get internal radix trees for merging
112
- */
113
- getTrees(): Map<HTTPMethod, RadixTree> {
114
- return this.trees;
115
- }
116
-
117
- /**
118
- * Mount another router with a prefix (group routes)
119
- *
120
- * @example
121
- * ```typescript
122
- * const userRoutes = new Router();
123
- * userRoutes.get('/', getAllUsers);
124
- * userRoutes.get('/:id', getUserById);
125
- *
126
- * const router = new Router();
127
- * router.group('/api/users', userRoutes);
128
- * ```
129
- */
130
- group(prefix: string, router: Router): void {
131
- const routes = router.getRawRoutes();
132
- for (const route of routes) {
133
- const fullPath = `${prefix}${route.path}`;
134
- this.addRoute({
135
- method: route.method,
136
- path: fullPath,
137
- handler: route.config.handler,
138
- middlewares: route.config.middlewares,
139
- schema: route.config.schema,
140
- meta: route.config.meta
141
- });
142
- }
143
- }
144
-
145
- /**
146
- * Convenience methods for HTTP verbs
147
- */
148
- get(path: string, handler: Handler, options?: Partial<RouteConfig>): void {
149
- this.addRoute({ method: 'GET', path, handler, ...options });
150
- }
151
-
152
- post(path: string, handler: Handler, options?: Partial<RouteConfig>): void {
153
- this.addRoute({ method: 'POST', path, handler, ...options });
154
- }
155
-
156
- put(path: string, handler: Handler, options?: Partial<RouteConfig>): void {
157
- this.addRoute({ method: 'PUT', path, handler, ...options });
158
- }
159
-
160
- delete(path: string, handler: Handler, options?: Partial<RouteConfig>): void {
161
- this.addRoute({ method: 'DELETE', path, handler, ...options });
162
- }
163
-
164
- patch(path: string, handler: Handler, options?: Partial<RouteConfig>): void {
165
- this.addRoute({ method: 'PATCH', path, handler, ...options });
166
- }
167
-
168
- /**
169
- * Wrap handler with schema validation
170
- */
171
- private wrapWithValidation(handler: Handler, schema: SchemaConfig): Handler {
172
- return async (ctx: Context) => {
173
- try {
174
- // Validate params
175
- if (schema.params) {
176
- ctx.params = await schema.params.parseAsync(ctx.params);
177
- }
178
-
179
- // Validate query
180
- if (schema.query) {
181
- ctx.query = await schema.query.parseAsync(ctx.query);
182
- }
183
-
184
- // Validate body
185
- if (schema.body) {
186
- ctx.body = await schema.body.parseAsync(ctx.body);
187
- }
188
-
189
- // Validate headers
190
- if (schema.headers) {
191
- ctx.headers = await schema.headers.parseAsync(ctx.headers);
192
- }
193
-
194
- // Call original handler with validated data
195
- return handler(ctx, {});
196
- } catch (error: any) {
197
- // Zod validation error
198
- if (error.name === 'ZodError') {
199
- // Use custom error handler if provided
200
- if (schema.onValidationError) {
201
- const customResponse = schema.onValidationError(error.errors, ctx);
202
- // If it's already a Response object, return it
203
- if (customResponse?.statusCode) {
204
- return customResponse;
205
- }
206
- // Otherwise wrap it as JSON response
207
- return ctx.json(customResponse, 400);
208
- }
209
-
210
- // Default error response - extract first error message
211
- const firstError = error.errors[0];
212
- const message = firstError?.message || 'Validation failed';
213
-
214
- return ctx.json({
215
- success: false,
216
- message
217
- }, 400);
218
- }
219
- throw error;
220
- }
221
- };
222
- }
223
- }
224
-
225
- // Re-export file router
226
- export { FileRouter, createFileRouter, useFileRoutes } from './file-router';
227
- export type { FileRouterOptions, FileRouteClass, RouteModule } from './file-router';
@@ -1,226 +0,0 @@
1
- /**
2
- * Radix Tree implementation for efficient routing
3
- * Provides O(log n) route lookup performance
4
- */
5
-
6
- import { Handler, Middleware } from '../types';
7
-
8
- /**
9
- * Node in the radix tree
10
- */
11
- export class RadixNode {
12
- // The path segment this node represents
13
- segment: string;
14
-
15
- // Full path for this node (used for debugging)
16
- fullPath: string;
17
-
18
- // Handler if this is a terminal node
19
- handler: Handler | null = null;
20
-
21
- // Middleware for this route
22
- middlewares: Middleware[] = [];
23
-
24
- // Child nodes
25
- children: RadixNode[] = [];
26
-
27
- // Pattern type: 'static', 'param', or 'wildcard'
28
- type: 'static' | 'param' | 'wildcard' = 'static';
29
-
30
- // Parameter name for param nodes
31
- paramName?: string;
32
-
33
- constructor(segment: string, fullPath: string) {
34
- this.segment = segment;
35
- this.fullPath = fullPath;
36
-
37
- // Detect node type
38
- if (segment.startsWith(':')) {
39
- this.type = 'param';
40
- this.paramName = segment.slice(1);
41
- } else if (segment === '*' || segment.startsWith('*')) {
42
- this.type = 'wildcard';
43
- this.paramName = segment.length > 1 ? segment.slice(1) : 'wildcard';
44
- }
45
- }
46
-
47
- /**
48
- * Add a child node
49
- */
50
- addChild(node: RadixNode): void {
51
- // Insert maintaining order: static > param > wildcard
52
- const priority = this.getTypePriority(node.type);
53
- let inserted = false;
54
-
55
- for (let i = 0; i < this.children.length; i++) {
56
- const childPriority = this.getTypePriority(this.children[i].type);
57
- if (priority < childPriority) {
58
- this.children.splice(i, 0, node);
59
- inserted = true;
60
- break;
61
- }
62
- }
63
-
64
- if (!inserted) {
65
- this.children.push(node);
66
- }
67
- }
68
-
69
- /**
70
- * Find a child by segment
71
- */
72
- findChild(segment: string): RadixNode | null {
73
- for (const child of this.children) {
74
- if (child.segment === segment) {
75
- return child;
76
- }
77
- }
78
- return null;
79
- }
80
-
81
- /**
82
- * Get type priority for ordering (lower = higher priority)
83
- */
84
- private getTypePriority(type: 'static' | 'param' | 'wildcard'): number {
85
- switch (type) {
86
- case 'static': return 0;
87
- case 'param': return 1;
88
- case 'wildcard': return 2;
89
- }
90
- }
91
- }
92
-
93
- /**
94
- * Radix tree for route storage and matching
95
- */
96
- export class RadixTree {
97
- private root: RadixNode;
98
-
99
- constructor() {
100
- this.root = new RadixNode('', '/');
101
- }
102
-
103
- /**
104
- * Insert a route into the tree
105
- */
106
- insert(path: string, handler: Handler, middlewares: Middleware[] = []): void {
107
- const segments = this.splitPath(path);
108
- let current = this.root;
109
-
110
- for (let i = 0; i < segments.length; i++) {
111
- const segment = segments[i];
112
- let child = current.findChild(segment);
113
-
114
- if (!child) {
115
- const fullPath = '/' + segments.slice(0, i + 1).join('/');
116
- child = new RadixNode(segment, fullPath);
117
- current.addChild(child);
118
- }
119
-
120
- current = child;
121
- }
122
-
123
- // Set handler and middleware at terminal node
124
- current.handler = handler;
125
- current.middlewares = middlewares;
126
- }
127
-
128
- /**
129
- * Search for a route match
130
- */
131
- search(path: string): { handler: Handler; params: Record<string, string>; middlewares: Middleware[] } | null {
132
- const segments = this.splitPath(path);
133
- const params: Record<string, string> = {};
134
-
135
- const result = this.searchNode(this.root, segments, 0, params);
136
-
137
- if (result) {
138
- return {
139
- handler: result.handler!,
140
- params,
141
- middlewares: result.middlewares
142
- };
143
- }
144
-
145
- return null;
146
- }
147
-
148
- /**
149
- * Recursively search nodes
150
- */
151
- private searchNode(
152
- node: RadixNode,
153
- segments: string[],
154
- index: number,
155
- params: Record<string, string>
156
- ): RadixNode | null {
157
- // Reached end of path
158
- if (index === segments.length) {
159
- return node.handler ? node : null;
160
- }
161
-
162
- const segment = segments[index];
163
-
164
- // Try children in priority order
165
- for (const child of node.children) {
166
- if (child.type === 'static') {
167
- // Exact match required
168
- if (child.segment === segment) {
169
- const result = this.searchNode(child, segments, index + 1, params);
170
- if (result) return result;
171
- }
172
- } else if (child.type === 'param') {
173
- // Parameter match - capture value
174
- const oldValue = params[child.paramName!];
175
- params[child.paramName!] = segment;
176
-
177
- const result = this.searchNode(child, segments, index + 1, params);
178
- if (result) return result;
179
-
180
- // Backtrack
181
- if (oldValue === undefined) {
182
- delete params[child.paramName!];
183
- } else {
184
- params[child.paramName!] = oldValue;
185
- }
186
- } else if (child.type === 'wildcard') {
187
- // Wildcard match - capture remaining path
188
- params[child.paramName!] = segments.slice(index).join('/');
189
- return child;
190
- }
191
- }
192
-
193
- return null;
194
- }
195
-
196
- /**
197
- * Split path into segments
198
- */
199
- private splitPath(path: string): string[] {
200
- // Remove leading/trailing slashes and split
201
- const normalized = path.replace(/^\/+|\/+$/g, '');
202
- return normalized ? normalized.split('/') : [];
203
- }
204
-
205
- /**
206
- * Get all routes (for debugging/introspection)
207
- */
208
- getAllRoutes(): Array<{ path: string; hasHandler: boolean }> {
209
- const routes: Array<{ path: string; hasHandler: boolean }> = [];
210
- this.collectRoutes(this.root, routes);
211
- return routes;
212
- }
213
-
214
- /**
215
- * Recursively collect all routes
216
- */
217
- private collectRoutes(node: RadixNode, routes: Array<{ path: string; hasHandler: boolean }>): void {
218
- if (node.handler) {
219
- routes.push({ path: node.fullPath, hasHandler: true });
220
- }
221
-
222
- for (const child of node.children) {
223
- this.collectRoutes(child, routes);
224
- }
225
- }
226
- }
@@ -1,30 +0,0 @@
1
- /**
2
- * ContextStore System
3
- * State management inspired by Flutter's Provider pattern
4
- *
5
- * Two types of stores:
6
- * - ContextStore: Global singleton, persists across all requests
7
- * - RequestStore: Per-request scoped, disposed after response
8
- */
9
-
10
- // Core store classes
11
- export { ContextStore } from './types';
12
- export { RequestStore } from './request-store';
13
-
14
- // Types
15
- export type {
16
- StoreListener,
17
- DisposeCallback,
18
- StoreConstructor,
19
- StateOf,
20
- StoreOptions
21
- } from './types';
22
-
23
- export type {
24
- RequestStoreConstructor,
25
- RequestStateOf
26
- } from './request-store';
27
-
28
- // Registries
29
- export { StoreRegistry, createStoreRegistry } from './registry';
30
- export { RequestStoreRegistry } from './request-store';
@@ -1,178 +0,0 @@
1
- /**
2
- * StoreRegistry - Global store container
3
- * Manages all ContextStore instances at application level
4
- */
5
-
6
- import { ContextStore, StoreConstructor, StoreRegistryOptions } from './types';
7
-
8
- /**
9
- * StoreRegistry manages all stores in the application
10
- * Ensures singleton instances and handles lifecycle
11
- */
12
- export class StoreRegistry {
13
- private stores: Map<StoreConstructor<any>, ContextStore<any>> = new Map();
14
- private options: StoreRegistryOptions;
15
-
16
- constructor(options: StoreRegistryOptions = {}) {
17
- this.options = options;
18
- }
19
-
20
- /**
21
- * Register a store class
22
- * Creates instance immediately
23
- *
24
- * @param StoreClass - Store constructor class
25
- * @returns The created store instance
26
- */
27
- register<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): T {
28
- if (this.stores.has(StoreClass)) {
29
- if (this.options.debug) {
30
- console.log(`[StoreRegistry] Store ${StoreClass.name} already registered`);
31
- }
32
- return this.stores.get(StoreClass) as T;
33
- }
34
-
35
- const instance = new StoreClass({ debug: this.options.debug });
36
- this.stores.set(StoreClass, instance);
37
-
38
- if (this.options.debug) {
39
- console.log(`[StoreRegistry] Registered store: ${StoreClass.name}`);
40
- }
41
-
42
- // Call onInit if defined
43
- const initResult = instance.onInit();
44
- if (initResult instanceof Promise) {
45
- initResult.catch(err => {
46
- console.error(`[StoreRegistry] Error in ${StoreClass.name}.onInit():`, err);
47
- });
48
- }
49
-
50
- return instance;
51
- }
52
-
53
- /**
54
- * Register multiple stores at once
55
- *
56
- * @param storeClasses - Array of store constructor classes
57
- */
58
- registerAll(storeClasses: StoreConstructor<any>[]): void {
59
- storeClasses.forEach(StoreClass => this.register(StoreClass));
60
- }
61
-
62
- /**
63
- * Get a store instance by its class
64
- * Throws if store is not registered
65
- *
66
- * @param StoreClass - Store constructor class
67
- * @returns Store instance
68
- */
69
- get<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): T {
70
- const store = this.stores.get(StoreClass);
71
-
72
- if (!store) {
73
- throw new Error(
74
- `[StoreRegistry] Store ${StoreClass.name} is not registered. ` +
75
- `Make sure to call app.stores([${StoreClass.name}]) before accessing it.`
76
- );
77
- }
78
-
79
- return store as T;
80
- }
81
-
82
- /**
83
- * Check if a store is registered
84
- *
85
- * @param StoreClass - Store constructor class
86
- */
87
- has<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): boolean {
88
- return this.stores.has(StoreClass);
89
- }
90
-
91
- /**
92
- * Get a store instance, or register it if not exists
93
- * Useful for lazy initialization
94
- *
95
- * @param StoreClass - Store constructor class
96
- * @returns Store instance
97
- */
98
- getOrRegister<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): T {
99
- if (!this.stores.has(StoreClass)) {
100
- return this.register(StoreClass);
101
- }
102
- return this.stores.get(StoreClass) as T;
103
- }
104
-
105
- /**
106
- * Remove a store from registry and dispose it
107
- *
108
- * @param StoreClass - Store constructor class
109
- */
110
- unregister<T extends ContextStore<any>>(StoreClass: StoreConstructor<T>): void {
111
- const store = this.stores.get(StoreClass);
112
-
113
- if (store) {
114
- store.dispose();
115
- this.stores.delete(StoreClass);
116
-
117
- if (this.options.debug) {
118
- console.log(`[StoreRegistry] Unregistered store: ${StoreClass.name}`);
119
- }
120
- }
121
- }
122
-
123
- /**
124
- * Get all registered store classes
125
- */
126
- getRegisteredStores(): StoreConstructor<any>[] {
127
- return Array.from(this.stores.keys());
128
- }
129
-
130
- /**
131
- * Get store count
132
- */
133
- get size(): number {
134
- return this.stores.size;
135
- }
136
-
137
- /**
138
- * Dispose all stores and clear registry
139
- */
140
- dispose(): void {
141
- if (this.options.debug) {
142
- console.log(`[StoreRegistry] Disposing all stores (${this.stores.size})`);
143
- }
144
-
145
- this.stores.forEach((store, StoreClass) => {
146
- try {
147
- store.dispose();
148
- } catch (error) {
149
- console.error(`[StoreRegistry] Error disposing ${StoreClass.name}:`, error);
150
- }
151
- });
152
-
153
- this.stores.clear();
154
- }
155
-
156
- /**
157
- * Get debug info about all stores
158
- */
159
- getDebugInfo(): Record<string, { listenerCount: number; isInitialized: boolean }> {
160
- const info: Record<string, { listenerCount: number; isInitialized: boolean }> = {};
161
-
162
- this.stores.forEach((store, StoreClass) => {
163
- info[StoreClass.name] = {
164
- listenerCount: store.listenerCount,
165
- isInitialized: store.isInitialized
166
- };
167
- });
168
-
169
- return info;
170
- }
171
- }
172
-
173
- /**
174
- * Create a new store registry
175
- */
176
- export function createStoreRegistry(options?: StoreRegistryOptions): StoreRegistry {
177
- return new StoreRegistry(options);
178
- }