exisjs 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (564) hide show
  1. package/README.md +9 -3
  2. package/dist/cli/commands/build.d.ts.map +1 -1
  3. package/dist/cli/commands/build.js +2 -8
  4. package/dist/cli/commands/build.js.map +1 -1
  5. package/dist/cli/commands/dev.d.ts.map +1 -1
  6. package/dist/cli/commands/dev.js +33 -44
  7. package/dist/cli/commands/dev.js.map +1 -1
  8. package/dist/cli/commands/exports.d.ts.map +1 -1
  9. package/dist/cli/commands/exports.js +5 -32
  10. package/dist/cli/commands/exports.js.map +1 -1
  11. package/dist/cli/commands/generate.d.ts +2 -13
  12. package/dist/cli/commands/generate.d.ts.map +1 -1
  13. package/dist/cli/commands/generate.js +27 -60
  14. package/dist/cli/commands/generate.js.map +1 -1
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/init.js +4 -4
  17. package/dist/cli/commands/init.js.map +1 -1
  18. package/dist/cli/commands/start.d.ts.map +1 -1
  19. package/dist/cli/commands/start.js +2 -6
  20. package/dist/cli/commands/start.js.map +1 -1
  21. package/dist/cli/index.js +11 -23
  22. package/dist/cli/index.js.map +1 -1
  23. package/dist/cli/routes.d.ts.map +1 -1
  24. package/dist/cli/routes.js +20 -8
  25. package/dist/cli/routes.js.map +1 -1
  26. package/dist/config/config.d.ts +2 -1
  27. package/dist/config/config.d.ts.map +1 -1
  28. package/dist/config/config.js +7 -5
  29. package/dist/config/config.js.map +1 -1
  30. package/dist/config/env.d.ts.map +1 -1
  31. package/dist/config/env.js +3 -2
  32. package/dist/config/env.js.map +1 -1
  33. package/dist/config/types.d.ts +7 -2
  34. package/dist/config/types.d.ts.map +1 -1
  35. package/dist/decorators/constants.d.ts +9 -2
  36. package/dist/decorators/constants.d.ts.map +1 -1
  37. package/dist/decorators/constants.js +3 -2
  38. package/dist/decorators/constants.js.map +1 -1
  39. package/dist/decorators/core/metadata.d.ts +31 -0
  40. package/dist/decorators/core/metadata.d.ts.map +1 -1
  41. package/dist/decorators/core/metadata.js +110 -1
  42. package/dist/decorators/core/metadata.js.map +1 -1
  43. package/dist/decorators/core.d.ts +19 -4
  44. package/dist/decorators/core.d.ts.map +1 -1
  45. package/dist/decorators/core.js +29 -4
  46. package/dist/decorators/core.js.map +1 -1
  47. package/dist/decorators/middleware.d.ts +17 -17
  48. package/dist/decorators/middleware.d.ts.map +1 -1
  49. package/dist/decorators/middleware.js +111 -208
  50. package/dist/decorators/middleware.js.map +1 -1
  51. package/dist/decorators/params.d.ts +54 -12
  52. package/dist/decorators/params.d.ts.map +1 -1
  53. package/dist/decorators/params.js +40 -20
  54. package/dist/decorators/params.js.map +1 -1
  55. package/dist/decorators/routing.d.ts +0 -2
  56. package/dist/decorators/routing.d.ts.map +1 -1
  57. package/dist/decorators/routing.js +3 -4
  58. package/dist/decorators/routing.js.map +1 -1
  59. package/dist/di/container.d.ts +5 -1
  60. package/dist/di/container.d.ts.map +1 -1
  61. package/dist/di/container.js +56 -8
  62. package/dist/di/container.js.map +1 -1
  63. package/dist/di/decorators.d.ts +30 -0
  64. package/dist/di/decorators.d.ts.map +1 -0
  65. package/dist/di/decorators.js +59 -0
  66. package/dist/di/decorators.js.map +1 -0
  67. package/dist/di/index.d.ts +1 -0
  68. package/dist/di/index.d.ts.map +1 -1
  69. package/dist/di/index.js +4 -1
  70. package/dist/di/index.js.map +1 -1
  71. package/dist/docs/ARCHITECTURE.md +46 -285
  72. package/dist/docs/BENCHMARKS.md +5 -5
  73. package/dist/docs/README.md +8 -11
  74. package/dist/docs/content/boundaries.mdx +151 -0
  75. package/dist/docs/content/cli/commands.mdx +66 -104
  76. package/dist/docs/content/cli/overview.mdx +37 -47
  77. package/dist/docs/content/cli/usage.mdx +29 -15
  78. package/dist/docs/content/decorators.mdx +142 -81
  79. package/dist/docs/content/installation.mdx +20 -1
  80. package/dist/docs/content/middleware.mdx +65 -291
  81. package/dist/docs/content/modules.mdx +22 -1
  82. package/dist/docs/content/providers.mdx +33 -1
  83. package/dist/docs/content/security.mdx +44 -246
  84. package/dist/docs/content/structure.mdx +227 -100
  85. package/dist/docs/content/validation.mdx +0 -17
  86. package/dist/docs/reference/decorators.mdx +34 -216
  87. package/dist/docs/reference/di.mdx +35 -11
  88. package/dist/docs/reference/logger.mdx +100 -0
  89. package/dist/docs/reference/middleware.mdx +41 -217
  90. package/dist/docs/reference/router.mdx +9 -9
  91. package/dist/docs/reference/validator.mdx +2 -5
  92. package/dist/error/errors.d.ts.map +1 -1
  93. package/dist/error/errors.js +19 -5
  94. package/dist/error/errors.js.map +1 -1
  95. package/dist/index.d.ts +0 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +1 -4
  98. package/dist/index.js.map +1 -1
  99. package/dist/lib/start-server.js +10 -0
  100. package/dist/lib/start-server.js.map +1 -1
  101. package/dist/logger/index.d.ts +81 -0
  102. package/dist/logger/index.d.ts.map +1 -0
  103. package/dist/logger/index.js +142 -0
  104. package/dist/logger/index.js.map +1 -0
  105. package/dist/middleware/dedupe.d.ts +1 -1
  106. package/dist/middleware/dedupe.js +1 -1
  107. package/dist/middleware/middleware.d.ts +3 -5
  108. package/dist/middleware/middleware.d.ts.map +1 -1
  109. package/dist/middleware/middleware.js +2 -6
  110. package/dist/middleware/middleware.js.map +1 -1
  111. package/dist/middleware/rate-limit.d.ts +0 -2
  112. package/dist/middleware/rate-limit.d.ts.map +1 -1
  113. package/dist/middleware/rate-limit.js +2 -14
  114. package/dist/middleware/rate-limit.js.map +1 -1
  115. package/dist/module/index.d.ts +2 -0
  116. package/dist/module/index.d.ts.map +1 -1
  117. package/dist/module/index.js +3 -1
  118. package/dist/module/index.js.map +1 -1
  119. package/dist/plugin/manager.d.ts +1 -1
  120. package/dist/plugin/manager.d.ts.map +1 -1
  121. package/dist/plugin/manager.js +47 -0
  122. package/dist/plugin/manager.js.map +1 -1
  123. package/dist/router/{gateway.d.ts → boundary.d.ts} +21 -13
  124. package/dist/router/boundary.d.ts.map +1 -0
  125. package/dist/router/boundary.js +11 -0
  126. package/dist/router/boundary.js.map +1 -0
  127. package/dist/router/controller-registrar.d.ts.map +1 -1
  128. package/dist/router/controller-registrar.js +33 -6
  129. package/dist/router/controller-registrar.js.map +1 -1
  130. package/dist/router/index.d.ts +3 -6
  131. package/dist/router/index.d.ts.map +1 -1
  132. package/dist/router/index.js +3 -7
  133. package/dist/router/index.js.map +1 -1
  134. package/dist/router/route-builder.d.ts +0 -28
  135. package/dist/router/route-builder.d.ts.map +1 -1
  136. package/dist/router/route-builder.js +2 -5
  137. package/dist/router/route-builder.js.map +1 -1
  138. package/dist/router/route-scanner.d.ts +1 -2
  139. package/dist/router/route-scanner.d.ts.map +1 -1
  140. package/dist/router/route-scanner.js +225 -203
  141. package/dist/router/route-scanner.js.map +1 -1
  142. package/dist/router/router.d.ts +4 -6
  143. package/dist/router/router.d.ts.map +1 -1
  144. package/dist/router/router.js +36 -72
  145. package/dist/router/router.js.map +1 -1
  146. package/dist/router/types.d.ts +2 -6
  147. package/dist/router/types.d.ts.map +1 -1
  148. package/dist/server/{bun-adapter.d.ts → adapters/bun-adapter.d.ts} +1 -1
  149. package/dist/server/adapters/bun-adapter.d.ts.map +1 -0
  150. package/dist/server/{bun-adapter.js → adapters/bun-adapter.js} +2 -24
  151. package/dist/server/adapters/bun-adapter.js.map +1 -0
  152. package/dist/server/{uws-adapter.d.ts → adapters/uws-adapter.d.ts} +1 -1
  153. package/dist/server/adapters/uws-adapter.d.ts.map +1 -0
  154. package/dist/server/{uws-adapter.js → adapters/uws-adapter.js} +1 -28
  155. package/dist/server/adapters/uws-adapter.js.map +1 -0
  156. package/dist/server/app.d.ts +10 -31
  157. package/dist/server/app.d.ts.map +1 -1
  158. package/dist/server/app.js +20 -135
  159. package/dist/server/app.js.map +1 -1
  160. package/dist/server/bootstrapper.d.ts +4 -15
  161. package/dist/server/bootstrapper.d.ts.map +1 -1
  162. package/dist/server/bootstrapper.js +30 -229
  163. package/dist/server/bootstrapper.js.map +1 -1
  164. package/dist/server/define.d.ts +2 -2
  165. package/dist/server/define.d.ts.map +1 -1
  166. package/dist/server/define.js +3 -3
  167. package/dist/server/define.js.map +1 -1
  168. package/dist/server/engines/bun-engine.d.ts +16 -0
  169. package/dist/server/engines/bun-engine.d.ts.map +1 -0
  170. package/dist/server/engines/bun-engine.js +41 -0
  171. package/dist/server/engines/bun-engine.js.map +1 -0
  172. package/dist/server/engines/engine.d.ts +16 -0
  173. package/dist/server/engines/engine.d.ts.map +1 -0
  174. package/dist/{queue/types.js → server/engines/engine.js} +1 -1
  175. package/dist/server/engines/engine.js.map +1 -0
  176. package/dist/server/engines/node-engine.d.ts +22 -0
  177. package/dist/server/engines/node-engine.d.ts.map +1 -0
  178. package/dist/server/engines/node-engine.js +130 -0
  179. package/dist/server/engines/node-engine.js.map +1 -0
  180. package/dist/server/engines/uws-engine.d.ts +16 -0
  181. package/dist/server/engines/uws-engine.d.ts.map +1 -0
  182. package/dist/server/engines/uws-engine.js +48 -0
  183. package/dist/server/engines/uws-engine.js.map +1 -0
  184. package/dist/server/request-handler.d.ts +0 -1
  185. package/dist/server/request-handler.d.ts.map +1 -1
  186. package/dist/server/request-handler.js +74 -48
  187. package/dist/server/request-handler.js.map +1 -1
  188. package/dist/server/request.d.ts +0 -8
  189. package/dist/server/request.d.ts.map +1 -1
  190. package/dist/server/request.js +0 -16
  191. package/dist/server/request.js.map +1 -1
  192. package/dist/server/response.d.ts.map +1 -1
  193. package/dist/server/response.js +2 -1
  194. package/dist/server/response.js.map +1 -1
  195. package/dist/utils/logger.d.ts.map +1 -1
  196. package/dist/utils/logger.js +0 -1
  197. package/dist/utils/logger.js.map +1 -1
  198. package/dist/utils/time.d.ts +6 -0
  199. package/dist/utils/time.d.ts.map +1 -0
  200. package/dist/utils/time.js +15 -0
  201. package/dist/utils/time.js.map +1 -0
  202. package/dist/validator/index.d.ts +1 -7
  203. package/dist/validator/index.d.ts.map +1 -1
  204. package/dist/validator/index.js +1 -5
  205. package/dist/validator/index.js.map +1 -1
  206. package/dist/validator/tex-types.d.ts +15 -2
  207. package/dist/validator/tex-types.d.ts.map +1 -1
  208. package/dist/validator/tex-types.js +8 -0
  209. package/dist/validator/tex-types.js.map +1 -1
  210. package/dist/validator/tex.d.ts.map +1 -1
  211. package/dist/validator/tex.js +21 -2
  212. package/dist/validator/tex.js.map +1 -1
  213. package/package.json +9 -151
  214. package/dist/adapters/aws-lambda.d.ts +0 -21
  215. package/dist/adapters/aws-lambda.d.ts.map +0 -1
  216. package/dist/adapters/aws-lambda.js +0 -125
  217. package/dist/adapters/aws-lambda.js.map +0 -1
  218. package/dist/adapters/bun.d.ts +0 -9
  219. package/dist/adapters/bun.d.ts.map +0 -1
  220. package/dist/adapters/bun.js +0 -23
  221. package/dist/adapters/bun.js.map +0 -1
  222. package/dist/adapters/cloudflare.d.ts +0 -10
  223. package/dist/adapters/cloudflare.d.ts.map +0 -1
  224. package/dist/adapters/cloudflare.js +0 -22
  225. package/dist/adapters/cloudflare.js.map +0 -1
  226. package/dist/adapters/deno.d.ts +0 -7
  227. package/dist/adapters/deno.d.ts.map +0 -1
  228. package/dist/adapters/deno.js +0 -21
  229. package/dist/adapters/deno.js.map +0 -1
  230. package/dist/adapters/fastly.d.ts +0 -6
  231. package/dist/adapters/fastly.d.ts.map +0 -1
  232. package/dist/adapters/fastly.js +0 -20
  233. package/dist/adapters/fastly.js.map +0 -1
  234. package/dist/adapters/fetch.d.ts +0 -30
  235. package/dist/adapters/fetch.d.ts.map +0 -1
  236. package/dist/adapters/fetch.js +0 -119
  237. package/dist/adapters/fetch.js.map +0 -1
  238. package/dist/adapters/index.d.ts +0 -9
  239. package/dist/adapters/index.d.ts.map +0 -1
  240. package/dist/adapters/index.js +0 -28
  241. package/dist/adapters/index.js.map +0 -1
  242. package/dist/adapters/netlify.d.ts +0 -8
  243. package/dist/adapters/netlify.d.ts.map +0 -1
  244. package/dist/adapters/netlify.js +0 -20
  245. package/dist/adapters/netlify.js.map +0 -1
  246. package/dist/adapters/vercel.d.ts +0 -17
  247. package/dist/adapters/vercel.d.ts.map +0 -1
  248. package/dist/adapters/vercel.js +0 -23
  249. package/dist/adapters/vercel.js.map +0 -1
  250. package/dist/auth/index.d.ts +0 -8
  251. package/dist/auth/index.d.ts.map +0 -1
  252. package/dist/auth/index.js +0 -49
  253. package/dist/auth/index.js.map +0 -1
  254. package/dist/auth/jwt.d.ts +0 -20
  255. package/dist/auth/jwt.d.ts.map +0 -1
  256. package/dist/auth/jwt.js +0 -59
  257. package/dist/auth/jwt.js.map +0 -1
  258. package/dist/auth/oauth/core.d.ts +0 -96
  259. package/dist/auth/oauth/core.d.ts.map +0 -1
  260. package/dist/auth/oauth/core.js +0 -203
  261. package/dist/auth/oauth/core.js.map +0 -1
  262. package/dist/auth/oauth/index.d.ts +0 -45
  263. package/dist/auth/oauth/index.d.ts.map +0 -1
  264. package/dist/auth/oauth/index.js +0 -64
  265. package/dist/auth/oauth/index.js.map +0 -1
  266. package/dist/auth/oauth/middleware.d.ts +0 -63
  267. package/dist/auth/oauth/middleware.d.ts.map +0 -1
  268. package/dist/auth/oauth/middleware.js +0 -164
  269. package/dist/auth/oauth/middleware.js.map +0 -1
  270. package/dist/auth/oauth/providers/custom.d.ts +0 -41
  271. package/dist/auth/oauth/providers/custom.d.ts.map +0 -1
  272. package/dist/auth/oauth/providers/custom.js +0 -204
  273. package/dist/auth/oauth/providers/custom.js.map +0 -1
  274. package/dist/auth/oauth/providers/discord.d.ts +0 -23
  275. package/dist/auth/oauth/providers/discord.d.ts.map +0 -1
  276. package/dist/auth/oauth/providers/discord.js +0 -130
  277. package/dist/auth/oauth/providers/discord.js.map +0 -1
  278. package/dist/auth/oauth/providers/facebook.d.ts +0 -28
  279. package/dist/auth/oauth/providers/facebook.d.ts.map +0 -1
  280. package/dist/auth/oauth/providers/facebook.js +0 -124
  281. package/dist/auth/oauth/providers/facebook.js.map +0 -1
  282. package/dist/auth/oauth/providers/github.d.ts +0 -25
  283. package/dist/auth/oauth/providers/github.d.ts.map +0 -1
  284. package/dist/auth/oauth/providers/github.js +0 -132
  285. package/dist/auth/oauth/providers/github.js.map +0 -1
  286. package/dist/auth/oauth/providers/google.d.ts +0 -23
  287. package/dist/auth/oauth/providers/google.d.ts.map +0 -1
  288. package/dist/auth/oauth/providers/google.js +0 -134
  289. package/dist/auth/oauth/providers/google.js.map +0 -1
  290. package/dist/auth/oauth/providers/microsoft.d.ts +0 -28
  291. package/dist/auth/oauth/providers/microsoft.d.ts.map +0 -1
  292. package/dist/auth/oauth/providers/microsoft.js +0 -136
  293. package/dist/auth/oauth/providers/microsoft.js.map +0 -1
  294. package/dist/auth/oauth/types.d.ts +0 -158
  295. package/dist/auth/oauth/types.d.ts.map +0 -1
  296. package/dist/auth/oauth/types.js +0 -4
  297. package/dist/auth/oauth/types.js.map +0 -1
  298. package/dist/auth/password.d.ts +0 -25
  299. package/dist/auth/password.d.ts.map +0 -1
  300. package/dist/auth/password.js +0 -93
  301. package/dist/auth/password.js.map +0 -1
  302. package/dist/auth/rbac.d.ts +0 -10
  303. package/dist/auth/rbac.d.ts.map +0 -1
  304. package/dist/auth/rbac.js +0 -34
  305. package/dist/auth/rbac.js.map +0 -1
  306. package/dist/auth/session.d.ts +0 -26
  307. package/dist/auth/session.d.ts.map +0 -1
  308. package/dist/auth/session.js +0 -134
  309. package/dist/auth/session.js.map +0 -1
  310. package/dist/cache/index.d.ts +0 -4
  311. package/dist/cache/index.d.ts.map +0 -1
  312. package/dist/cache/index.js +0 -25
  313. package/dist/cache/index.js.map +0 -1
  314. package/dist/cache/store.d.ts +0 -58
  315. package/dist/cache/store.d.ts.map +0 -1
  316. package/dist/cache/store.js +0 -298
  317. package/dist/cache/store.js.map +0 -1
  318. package/dist/cron/parser.d.ts +0 -2
  319. package/dist/cron/parser.d.ts.map +0 -1
  320. package/dist/cron/parser.js +0 -52
  321. package/dist/cron/parser.js.map +0 -1
  322. package/dist/cron/scheduler.d.ts +0 -23
  323. package/dist/cron/scheduler.d.ts.map +0 -1
  324. package/dist/cron/scheduler.js +0 -114
  325. package/dist/cron/scheduler.js.map +0 -1
  326. package/dist/database/adapters/mongodb.d.ts +0 -58
  327. package/dist/database/adapters/mongodb.d.ts.map +0 -1
  328. package/dist/database/adapters/mongodb.js +0 -264
  329. package/dist/database/adapters/mongodb.js.map +0 -1
  330. package/dist/database/adapters/mysql.d.ts +0 -27
  331. package/dist/database/adapters/mysql.d.ts.map +0 -1
  332. package/dist/database/adapters/mysql.js +0 -188
  333. package/dist/database/adapters/mysql.js.map +0 -1
  334. package/dist/database/adapters/postgres.d.ts +0 -28
  335. package/dist/database/adapters/postgres.d.ts.map +0 -1
  336. package/dist/database/adapters/postgres.js +0 -174
  337. package/dist/database/adapters/postgres.js.map +0 -1
  338. package/dist/database/adapters/sqlite.d.ts +0 -27
  339. package/dist/database/adapters/sqlite.d.ts.map +0 -1
  340. package/dist/database/adapters/sqlite.js +0 -149
  341. package/dist/database/adapters/sqlite.js.map +0 -1
  342. package/dist/database/index.d.ts +0 -42
  343. package/dist/database/index.d.ts.map +0 -1
  344. package/dist/database/index.js +0 -58
  345. package/dist/database/index.js.map +0 -1
  346. package/dist/database/manager.d.ts +0 -141
  347. package/dist/database/manager.d.ts.map +0 -1
  348. package/dist/database/manager.js +0 -337
  349. package/dist/database/manager.js.map +0 -1
  350. package/dist/database/migration.d.ts +0 -57
  351. package/dist/database/migration.d.ts.map +0 -1
  352. package/dist/database/migration.js +0 -329
  353. package/dist/database/migration.js.map +0 -1
  354. package/dist/database/query-builder.d.ts +0 -95
  355. package/dist/database/query-builder.d.ts.map +0 -1
  356. package/dist/database/query-builder.js +0 -404
  357. package/dist/database/query-builder.js.map +0 -1
  358. package/dist/database/sql/index.d.ts +0 -18
  359. package/dist/database/sql/index.d.ts.map +0 -1
  360. package/dist/database/sql/index.js +0 -74
  361. package/dist/database/sql/index.js.map +0 -1
  362. package/dist/database/sql/schema.d.ts +0 -38
  363. package/dist/database/sql/schema.d.ts.map +0 -1
  364. package/dist/database/sql/schema.js +0 -80
  365. package/dist/database/sql/schema.js.map +0 -1
  366. package/dist/database/synchronizer.d.ts +0 -12
  367. package/dist/database/synchronizer.d.ts.map +0 -1
  368. package/dist/database/synchronizer.js +0 -82
  369. package/dist/database/synchronizer.js.map +0 -1
  370. package/dist/database/types.d.ts +0 -184
  371. package/dist/database/types.d.ts.map +0 -1
  372. package/dist/database/types.js +0 -4
  373. package/dist/database/types.js.map +0 -1
  374. package/dist/dataloader/dataloader.d.ts +0 -23
  375. package/dist/dataloader/dataloader.d.ts.map +0 -1
  376. package/dist/dataloader/dataloader.js +0 -98
  377. package/dist/dataloader/dataloader.js.map +0 -1
  378. package/dist/dataloader/index.d.ts +0 -3
  379. package/dist/dataloader/index.d.ts.map +0 -1
  380. package/dist/dataloader/index.js +0 -19
  381. package/dist/dataloader/index.js.map +0 -1
  382. package/dist/dataloader/registry.d.ts +0 -17
  383. package/dist/dataloader/registry.d.ts.map +0 -1
  384. package/dist/dataloader/registry.js +0 -47
  385. package/dist/dataloader/registry.js.map +0 -1
  386. package/dist/dev/dep-graph.d.ts +0 -2
  387. package/dist/dev/dep-graph.d.ts.map +0 -1
  388. package/dist/dev/dep-graph.js +0 -111
  389. package/dist/dev/dep-graph.js.map +0 -1
  390. package/dist/dev/hot-reload.d.ts +0 -30
  391. package/dist/dev/hot-reload.d.ts.map +0 -1
  392. package/dist/dev/hot-reload.js +0 -262
  393. package/dist/dev/hot-reload.js.map +0 -1
  394. package/dist/docs/content/adapters.mdx +0 -199
  395. package/dist/docs/content/cache.mdx +0 -239
  396. package/dist/docs/content/circuit-breaker.mdx +0 -130
  397. package/dist/docs/content/cron.mdx +0 -109
  398. package/dist/docs/content/database.mdx +0 -278
  399. package/dist/docs/content/gateways.mdx +0 -376
  400. package/dist/docs/content/oauth.mdx +0 -179
  401. package/dist/docs/content/queues.mdx +0 -177
  402. package/dist/docs/content/rpc.mdx +0 -146
  403. package/dist/docs/content/sse.mdx +0 -159
  404. package/dist/docs/content/websockets.mdx +0 -289
  405. package/dist/docs/integrations/README.md +0 -23
  406. package/dist/docs/integrations/jwt.mdx +0 -151
  407. package/dist/docs/integrations/mongo.mdx +0 -183
  408. package/dist/docs/integrations/observability.mdx +0 -125
  409. package/dist/docs/integrations/openai.mdx +0 -108
  410. package/dist/docs/integrations/postgres.mdx +0 -190
  411. package/dist/docs/integrations/posthog.mdx +0 -122
  412. package/dist/docs/integrations/redis.mdx +0 -141
  413. package/dist/docs/integrations/resend.mdx +0 -117
  414. package/dist/docs/integrations/s3.mdx +0 -122
  415. package/dist/docs/integrations/swagger.mdx +0 -113
  416. package/dist/docs/reference/adapters.mdx +0 -130
  417. package/dist/docs/reference/auth.mdx +0 -183
  418. package/dist/docs/reference/cache.mdx +0 -132
  419. package/dist/docs/reference/circuit-breaker.mdx +0 -71
  420. package/dist/docs/reference/queue.mdx +0 -155
  421. package/dist/docs/reference/storage.mdx +0 -116
  422. package/dist/docs/reference/swagger.mdx +0 -132
  423. package/dist/integrations/drizzle.d.ts +0 -10
  424. package/dist/integrations/drizzle.d.ts.map +0 -1
  425. package/dist/integrations/drizzle.js +0 -34
  426. package/dist/integrations/drizzle.js.map +0 -1
  427. package/dist/integrations/jwt.d.ts +0 -12
  428. package/dist/integrations/jwt.d.ts.map +0 -1
  429. package/dist/integrations/jwt.js +0 -29
  430. package/dist/integrations/jwt.js.map +0 -1
  431. package/dist/integrations/mongodb.d.ts +0 -13
  432. package/dist/integrations/mongodb.d.ts.map +0 -1
  433. package/dist/integrations/mongodb.js +0 -48
  434. package/dist/integrations/mongodb.js.map +0 -1
  435. package/dist/integrations/mongoose.d.ts +0 -13
  436. package/dist/integrations/mongoose.d.ts.map +0 -1
  437. package/dist/integrations/mongoose.js +0 -84
  438. package/dist/integrations/mongoose.js.map +0 -1
  439. package/dist/integrations/openai.d.ts +0 -12
  440. package/dist/integrations/openai.d.ts.map +0 -1
  441. package/dist/integrations/openai.js +0 -47
  442. package/dist/integrations/openai.js.map +0 -1
  443. package/dist/integrations/postgres.d.ts +0 -13
  444. package/dist/integrations/postgres.d.ts.map +0 -1
  445. package/dist/integrations/postgres.js +0 -55
  446. package/dist/integrations/postgres.js.map +0 -1
  447. package/dist/integrations/posthog.d.ts +0 -13
  448. package/dist/integrations/posthog.d.ts.map +0 -1
  449. package/dist/integrations/posthog.js +0 -49
  450. package/dist/integrations/posthog.js.map +0 -1
  451. package/dist/integrations/prisma.d.ts +0 -10
  452. package/dist/integrations/prisma.d.ts.map +0 -1
  453. package/dist/integrations/prisma.js +0 -39
  454. package/dist/integrations/prisma.js.map +0 -1
  455. package/dist/integrations/redis.d.ts +0 -12
  456. package/dist/integrations/redis.d.ts.map +0 -1
  457. package/dist/integrations/redis.js +0 -48
  458. package/dist/integrations/redis.js.map +0 -1
  459. package/dist/integrations/resend.d.ts +0 -12
  460. package/dist/integrations/resend.d.ts.map +0 -1
  461. package/dist/integrations/resend.js +0 -47
  462. package/dist/integrations/resend.js.map +0 -1
  463. package/dist/integrations/s3.d.ts +0 -15
  464. package/dist/integrations/s3.d.ts.map +0 -1
  465. package/dist/integrations/s3.js +0 -60
  466. package/dist/integrations/s3.js.map +0 -1
  467. package/dist/integrations/supabase.d.ts +0 -13
  468. package/dist/integrations/supabase.d.ts.map +0 -1
  469. package/dist/integrations/supabase.js +0 -51
  470. package/dist/integrations/supabase.js.map +0 -1
  471. package/dist/middleware/cache.d.ts +0 -21
  472. package/dist/middleware/cache.d.ts.map +0 -1
  473. package/dist/middleware/cache.js +0 -156
  474. package/dist/middleware/cache.js.map +0 -1
  475. package/dist/observability/health.d.ts +0 -23
  476. package/dist/observability/health.d.ts.map +0 -1
  477. package/dist/observability/health.js +0 -49
  478. package/dist/observability/health.js.map +0 -1
  479. package/dist/observability/index.d.ts +0 -4
  480. package/dist/observability/index.d.ts.map +0 -1
  481. package/dist/observability/index.js +0 -10
  482. package/dist/observability/index.js.map +0 -1
  483. package/dist/observability/metrics.d.ts +0 -6
  484. package/dist/observability/metrics.d.ts.map +0 -1
  485. package/dist/observability/metrics.js +0 -60
  486. package/dist/observability/metrics.js.map +0 -1
  487. package/dist/observability/otel.d.ts +0 -27
  488. package/dist/observability/otel.d.ts.map +0 -1
  489. package/dist/observability/otel.js +0 -45
  490. package/dist/observability/otel.js.map +0 -1
  491. package/dist/observability/prometheus.d.ts +0 -30
  492. package/dist/observability/prometheus.d.ts.map +0 -1
  493. package/dist/observability/prometheus.js +0 -31
  494. package/dist/observability/prometheus.js.map +0 -1
  495. package/dist/queue/client.d.ts +0 -13
  496. package/dist/queue/client.d.ts.map +0 -1
  497. package/dist/queue/client.js +0 -83
  498. package/dist/queue/client.js.map +0 -1
  499. package/dist/queue/drivers/MemoryDriver.d.ts +0 -21
  500. package/dist/queue/drivers/MemoryDriver.d.ts.map +0 -1
  501. package/dist/queue/drivers/MemoryDriver.js +0 -176
  502. package/dist/queue/drivers/MemoryDriver.js.map +0 -1
  503. package/dist/queue/drivers/RedisDriver.d.ts +0 -19
  504. package/dist/queue/drivers/RedisDriver.d.ts.map +0 -1
  505. package/dist/queue/drivers/RedisDriver.js +0 -130
  506. package/dist/queue/drivers/RedisDriver.js.map +0 -1
  507. package/dist/queue/index.d.ts +0 -18
  508. package/dist/queue/index.d.ts.map +0 -1
  509. package/dist/queue/index.js +0 -37
  510. package/dist/queue/index.js.map +0 -1
  511. package/dist/queue/manager.d.ts +0 -18
  512. package/dist/queue/manager.d.ts.map +0 -1
  513. package/dist/queue/manager.js +0 -59
  514. package/dist/queue/manager.js.map +0 -1
  515. package/dist/queue/types.d.ts +0 -55
  516. package/dist/queue/types.d.ts.map +0 -1
  517. package/dist/queue/types.js.map +0 -1
  518. package/dist/queue/worker.d.ts +0 -18
  519. package/dist/queue/worker.d.ts.map +0 -1
  520. package/dist/queue/worker.js +0 -176
  521. package/dist/queue/worker.js.map +0 -1
  522. package/dist/router/gateway.d.ts.map +0 -1
  523. package/dist/router/gateway.js +0 -11
  524. package/dist/router/gateway.js.map +0 -1
  525. package/dist/server/bun-adapter.d.ts.map +0 -1
  526. package/dist/server/bun-adapter.js.map +0 -1
  527. package/dist/server/sse.d.ts +0 -16
  528. package/dist/server/sse.d.ts.map +0 -1
  529. package/dist/server/sse.js +0 -51
  530. package/dist/server/sse.js.map +0 -1
  531. package/dist/server/uws-adapter.d.ts.map +0 -1
  532. package/dist/server/uws-adapter.js.map +0 -1
  533. package/dist/storage/index.d.ts +0 -15
  534. package/dist/storage/index.d.ts.map +0 -1
  535. package/dist/storage/index.js +0 -7
  536. package/dist/storage/index.js.map +0 -1
  537. package/dist/swagger/index.d.ts +0 -9
  538. package/dist/swagger/index.d.ts.map +0 -1
  539. package/dist/swagger/index.js +0 -165
  540. package/dist/swagger/index.js.map +0 -1
  541. package/dist/threads/pool.d.ts +0 -14
  542. package/dist/threads/pool.d.ts.map +0 -1
  543. package/dist/threads/pool.js +0 -93
  544. package/dist/threads/pool.js.map +0 -1
  545. package/dist/threads/worker-runner.d.ts +0 -2
  546. package/dist/threads/worker-runner.d.ts.map +0 -1
  547. package/dist/threads/worker-runner.js +0 -71
  548. package/dist/threads/worker-runner.js.map +0 -1
  549. package/dist/validator/validator.d.ts +0 -360
  550. package/dist/validator/validator.d.ts.map +0 -1
  551. package/dist/validator/validator.js +0 -931
  552. package/dist/validator/validator.js.map +0 -1
  553. package/dist/websocket/orchestrator.d.ts +0 -11
  554. package/dist/websocket/orchestrator.d.ts.map +0 -1
  555. package/dist/websocket/orchestrator.js +0 -238
  556. package/dist/websocket/orchestrator.js.map +0 -1
  557. package/dist/websocket/server.d.ts +0 -66
  558. package/dist/websocket/server.d.ts.map +0 -1
  559. package/dist/websocket/server.js +0 -158
  560. package/dist/websocket/server.js.map +0 -1
  561. package/dist/websocket/socket.d.ts +0 -119
  562. package/dist/websocket/socket.d.ts.map +0 -1
  563. package/dist/websocket/socket.js +0 -242
  564. package/dist/websocket/socket.js.map +0 -1
@@ -1,48 +1,30 @@
1
1
  # ExisJS Architecture Reference
2
2
 
3
- This document is the single source of truth for how ExisJS is built internally. Unlike marketing copy, everything here is written to match what the code actually does — verified against the source, not aspirational. Each subsystem is labeled with a **Status** tag; treat that label as load-bearing information, not decoration.
3
+ This document is the single source of truth for how the ExisJS core engine is built internally.
4
4
 
5
- **Status legend:**
6
-
7
- - 🟢 **Stable** — core path, exercised by real deployments and dense test coverage.
8
- - 🟡 **Beta** — works as documented, but has known rough edges or thinner test coverage.
9
- - 🟠 **Experimental** — functional but unproven under real production load; expect edge cases.
10
- - 🔴 **Known Issue** — currently broken or non-functional; see linked bug reference.
11
- - ⚪ **Scaffolded / Not Implemented** — API surface or docs exist, but the behavior described does not (yet) exist at runtime.
5
+ ExisJS core is a minimal, ultra-high-performance web framework runtime: file-system routing, dependency injection, validation (`tex`), sanitization, and an HTTP request pipeline. Everything else — databases, external auth providers, cache stores, queues, websockets — is extracted into official `@exisjs/*` packages.
12
6
 
13
7
  ---
14
8
 
15
9
  ## 1. File-System Routing 🟢
16
10
 
17
- **What it is:** Folder-based routing mapping HTTP routes to the file system (`route.ts`, `gateway.ts`, `server.ts`, optionally `schema.ts` / `service.ts` / `controller.ts` as a convention, not an enforced structure).
11
+ **What it is:** Folder-based routing mapping HTTP routes to the file system (`route.ts`, `boundary.ts`, `server.ts`, `schema.ts`, `service.ts`).
18
12
 
19
- **How it's implemented:** At boot, `RouteScanner` walks the configured `src/http` directory (or a custom `apiDir`) and registers discovered routes into the `Router`'s matching engine. Folder-naming conventions are translated during the scan:
13
+ **How it's implemented:** At boot, `RouteScanner` walks the configured `src/http` directory (or a custom `apiDir`) and registers discovered routes into the `Router`'s matching engine powered by the Rust `NativeRadixTree`. Folder-naming conventions are translated during the scan:
20
14
 
21
15
  - `[param]` → `:param` dynamic segment
22
16
  - `[...param]` → `*param` catch-all
23
17
  - `(group)` → ignored entirely in the resulting URL, but still traversed for nested routes
24
18
 
25
- In development, routes are mounted lazily/dynamically and watched by `HotReloader` (see §12). In production, `exis build` can pre-generate a manifest (see §8) that lists every route file, though the request-time route matching itself is not manifest-driven — see §8 for the important distinction between "route discovery is fast" and "route execution uses a pre-compiled path," because only the former is currently true.
26
-
27
- **Example:**
28
-
29
- ```typescript
30
- // src/http/users/[id]/route.ts
31
- import { controller, route } from 'exisjs/router'
32
- export default controller({
33
- getSingle: route.get('/', {
34
- handle: ({ params }) => ({ id: params.id }),
35
- }),
36
- })
37
- ```
19
+ In development, routes are mounted dynamically and watched by `HotReloader`. In production, `exis build` pre-generates a route manifest (`.exis/routes-manifest.js`) for instant O(1) boot.
38
20
 
39
21
  ---
40
22
 
41
23
  ## 2. Dual Paradigm: Functional & Class-Based (OOP) 🟢
42
24
 
43
- **What it is:** Two ways to define the same routing/controller concepts — `controller()`/`route.*()` factory functions, or `@Controller()`/`@Get()` class decorators — that compile down to the same internal `Route` representation and execute through the same pipeline.
25
+ **What it is:** Two ways to define routing and handlers — `controller()`/`route.*()` factory functions, or `@Controller()`/`@Get()` class decorators — that compile down to the same internal `Route` representation.
44
26
 
45
- **How it's implemented:** Class decorators (`decorators/index.ts`) attach metadata to the class prototype via `Symbol.for('exisjs:...')` keys (routes, middleware, param metadata, lifecycle metadata) rather than `reflect-metadata`, for O(1) lookup without a polyfill dependency. `ControllerRegistrar` reads this metadata at registration time and produces the exact same kind of route entries that the functional `controller()`/`route.*()` API produces directly. Both paradigms can be mixed file-by-file in the same application.
27
+ **How it's implemented:** Class decorators attach metadata to the class prototype via symbols (`Symbol.for('exisjs:...')`) without any `reflect-metadata` dependency. The router processes both paradigms through the exact same internal pipeline. Choose one paradigm per project.
46
28
 
47
29
  ---
48
30
 
@@ -50,300 +32,79 @@ export default controller({
50
32
 
51
33
  **What it is:** Access to the current request's `req`/`res`/app-scoped state from anywhere in the call graph without prop-drilling, plus `after()` for deferred post-response work.
52
34
 
53
- **How it's implemented:** `context.ts` wraps Node's native `AsyncLocalStorage` in an `InternalContext` store containing `{ state, afterCallbacks, req, res, app, diCache }`. `getContext()`, `setContext()`, `getRequest()`, `getResponse()`, `getApp()`, and `after()` all read from the active store, throwing a clear error if called outside an active request. `RequestHandler._executeWithContext` establishes the store per-request and flushes `afterCallbacks` on the `finish`/`close` events of the response, catching and logging (not throwing) errors in background `after()` work so they can't crash the request.
54
-
55
- **Isolation:** each request gets its own `diCache` (a fresh `Map`) for request-scoped DI resolution, and context state does not leak across concurrent requests — this is tested and confirmed correct.
35
+ **How it's implemented:** `AsyncLocalStorage` maintains an active store per request containing `{ state, afterCallbacks, req, res, app, diCache }`. `inject()`, `getContext()`, and `after()` read from this store, guaranteeing request isolation across concurrent requests.
56
36
 
57
37
  ---
58
38
 
59
39
  ## 4. Dependency Injection (`Container`) 🟢
60
40
 
61
- **What it is:** A lightweight IoC container supporting value, factory, and class providers, with singleton and per-request scoping.
62
-
63
- **How it's implemented:** `di/container.ts`'s `Container` class holds a `providers` map and a `singletonCache`. `resolve(token, requestCache?)` checks the singleton cache, then the passed-in per-request cache, then the registered provider definition, instantiating and caching as appropriate to the provider's declared `scope`. Unregistered class tokens are auto-instantiated on first resolve and cached as singletons by default.
64
-
65
- **Two access patterns exist and are both supported:**
66
-
67
- - `inject(token)` (`di/inject.ts`) — the recommended primitive, reads the active `AsyncLocalStorage` context and resolves against `app.resolve(token, store.diCache)`. Works inside any route handler or middleware.
68
- - `app.provide(token, definition)` / `app.resolve(token)` — direct container access, primarily used at boot time (`server.ts`, module registration) rather than inside request handlers.
69
-
70
- **Known limitation:** when auto-instantiation of an unregistered class throws (e.g., a constructor-time validation error), the container currently discards the original error and throws a generic "Cannot resolve provider" message. Treat the original error as recoverable debugging information that should not be lost — this is tracked as a fix, not a design decision.
71
-
72
- ---
73
-
74
- ## 5. Modules & Plugins 🟢
75
-
76
- **What it is:** Two related but distinct extension primitives.
77
-
78
- - **`defineModule`** (`module/module.ts`) — groups domain-level providers, sub-module imports, and optional manual routes into a single registrable unit, with automatic deduplication of shared imports (`app.hasPlugin(name)` check before re-registering).
79
- - **`definePlugin`** (`utils/plugin.ts`) — for distributable, configurable third-party packages. Returns a hybrid object: usable directly, or callable as a function to pass options (`MyPlugin({ apiKey })`).
80
-
81
- **How registration/encapsulation works:** `PluginManager.register()` optionally wraps the target `App` in a `Proxy` (when `plugin.encapsulate !== false`) that intercepts routing methods and scopes them to a plugin-local `Router`, which is then mounted onto the main app under `/`. This prevents a plugin's internal route/middleware registration from silently leaking into the global app surface unless explicitly intended.
82
-
83
- **Gateways as modules:** `defineGateway` (`router/gateway.ts`) can itself carry `imports`/`providers`, letting a folder-scoped `gateway.ts` file behave as a lightweight module that hydrates the DI container before any `route.ts` inside that folder executes.
84
-
85
- ---
86
-
87
- ## 6. Cascading Gateways 🟢
88
-
89
- **What it is:** Folder-level configuration (middleware, CORS, headers, guards, filters, interceptors, providers, plugins, metadata) that applies to a directory and all its subdirectories.
90
-
91
- **How it's implemented:** During route mounting, the router maintains a stack of active gateway configs as it descends the directory tree, merging arrays (middleware, guards, filters, interceptors) from parent to child rather than overriding them. A gateway can return a response directly, which halts execution before the route handler is reached — the same mechanism regular middleware uses.
92
-
93
- ---
94
-
95
- ## 7. Native Validation Engine (`v`) 🟢
96
-
97
- **What it is:** A dependency-free, Zod-like schema validator with strict parsing and structured error aggregation.
98
-
99
- **How it's implemented:** `utils/validator.ts` defines `ValidatorType` subclasses (`StringValidator`, `NumberValidator`, `ObjectValidator`, `ArrayValidator`, etc.) each implementing `.parse()`/`.validate()`. Validation failures collect into a `ValidatorError` carrying a structured `errors: { path, message }[]` array rather than throwing on the first failure. Supports `.optional()`, `.default()`, `.transform()`, `.refine()`, custom error messages, and `.sanitize()` — which composes with `utils/sanitize.ts`'s pure transformation functions (trim, escape, clamp, etc.) and runs _before_ validation rules are checked, so sanitization can bring otherwise-invalid input into a valid shape (e.g., trimming whitespace before a `.min(3)` check).
100
-
101
- Test coverage here is dense and correctness-focused (string/number/boolean/object/array/enum/literal/union/date/record validators, nested objects, multi-error collection, async parsing) — this is one of the most solidly verified subsystems in the framework.
102
-
103
- ---
104
-
105
- ## 8. Production Build Pipeline
106
-
107
- ### 8a. Compilation 🟢
108
-
109
- `exis build` uses **esbuild** to compile TypeScript to JavaScript (`cli/commands/build.ts`), dropping the slow `tsc` dependency for the actual transpilation step, then rewrites path aliases (`@/*` → relative imports) via a native regex-based resolver (`resolve-aliases.ts`) so the output runs without needing a module-alias runtime.
110
-
111
- ### 8b. Route Manifest Generation 🟢
41
+ **What it is:** An IoC container supporting value, factory, and class providers, with singleton and request scoping.
112
42
 
113
- `cli/manifest.ts` scans `route.ts` files post-compile and writes `.exis/routes-manifest.js` (a flat list of `{ routePath, module, filePath, hash }`) plus a generated `.exis/types.d.ts` for the tRPC-style client (§17). This manifest is fully wired into the boot path: in production, `route-scanner.ts` detects `.exis/routes-manifest.js`, reads it, dynamically imports the required modules, and completely bypasses the recursive filesystem scan, delivering true O(1) boot performance regardless of route count.
114
-
115
- ### 8c. Production Optimizers (AOT Routing & JIT Serialization) 🟢
116
-
117
- The framework achieves production optimizations directly within its core engine rather than relying on brittle post-processing build scripts:
118
-
119
- - **AOT Routing (O(1) Boot Time)** — During `exis build`, `manifest.ts` generates a `.exis/routes-manifest.js` file. In production, `RouteScanner` detects this manifest and uses it to load routes instantly, skipping the expensive `fs.readdir` recursive scan entirely.
120
- - **JIT Fast JSON Serialization** — During route registration at boot time, the `Router` checks if `fast-json-stringify` is installed. If a route has an ExisJS `v` response schema, the router automatically converts it to JSON Schema via `.toOpenApi()` and compiles an optimized serializer Just-In-Time, attaching it to the route's response handler (`res._serializer`). This eliminates the need to precompile serializers to disk.
121
-
122
- ---
123
-
124
- ## 9. Native Job Queues 🟢 (core queue & cron integration)
125
-
126
- **What it is:** A background job queue with pluggable drivers, retry/backoff, visibility timeouts, and a worker-thread execution model.
127
-
128
- **How enqueue/poll/ack/fail work (both drivers share this contract, `queue/types.ts` `QueueDriver`):**
129
-
130
- - **Redis driver** (`queue/drivers/RedisDriver.ts`): pending jobs live in a Redis **sorted set** (`{prefix}:{name}:pending`, score = ready-at timestamp) with payloads stored separately in a **hash** (`{prefix}:{name}:payloads`). `enqueue()` uses a Lua script for atomic `ZADD` + `HSET` (with an optional max-queue-size check baked into the same script for backpressure). `poll()` atomically pops the earliest-ready job via `ZRANGEBYSCORE` + moves it to a `processing` zset with a visibility-timeout score, using another Lua script. `sweep()` periodically requeues anything left in `processing` past its visibility timeout (crash recovery for workers that died mid-job).
131
- - **Memory driver** (`queue/drivers/MemoryDriver.ts`): the same conceptual model (pending list, processing list, sweep-based recovery) implemented with in-process arrays instead of Redis — correctly mirrors the Redis driver's semantics for single-process/dev use.
132
- - **Job execution:** `ExisWorker` (`queue/worker.ts`) polls continuously (`setImmediate`-chained, with backoff on connection errors), and for jobs with a `filePath` (rather than an inline `handler`), dispatches execution to a `ThreadPool` (`threads/pool.ts`) — a integrated `worker_threads` pool — so CPU-heavy job handlers don't block the main event loop.
133
-
134
- **Retry behavior:** on failure, `attemptsMade` increments and the job is requeued (with optional exponential/fixed backoff) if under `maxAttempts`; once attempts are exhausted, the job is moved to a dead-letter queue (`{prefix}:{name}:dead` in Redis, or a `deadLetter` list in Memory) and an `onJobFailedPermanently` hook is fired, ensuring no data is lost for permanently failed jobs.
135
-
136
- **Cron scheduling — 🟢 correctly integrated with the Redis driver:** `CronScheduler` (`cron/scheduler.ts`) uses its own native cron-expression parser (`cron/parser.ts`, supports lists/steps/ranges/wildcards) and ticks every 60 seconds, aligned to the minute boundary. To guarantee exactly-once execution across a multi-instance cluster, it acquires a `SETNX`-style Redis lock (`SET key val EX 55 NX`) per job per minute — this locking mechanism is correctly designed. Once the lock is acquired, the scheduler enqueues the triggered job payload via the exact same `ZADD` + `HSET` sequence the `RedisQueueDriver` expects, ensuring cron jobs are processed identically to manually enqueued jobs.
43
+ **How it's implemented:** `Container` holds provider definitions and a singleton cache. Inside request handlers, `inject(token)` resolves dependencies dynamically using the request's context store.
137
44
 
138
45
  ---
139
46
 
140
- ## 10. WebSockets & Pub/Sub 🟢
47
+ ## 5. Folder-Scoped Boundaries (`boundary.ts`) 🟢
141
48
 
142
- **What it is:** Native WebSocket routes (`route.ws()` / `@Ws()`) with Socket.io-style room subscriptions, sitting behind the same middleware/auth pipeline as HTTP routes.
49
+ **What it is:** Folder-level configuration and auto-detected request pipelines that apply to a directory and all its subdirectories recursively.
143
50
 
144
51
  **How it's implemented:**
145
-
146
- - `ExisWebSocketServer` (`websocket/server.ts`) tracks all active connections in a `Set` and room membership in a `Map<room, Set<socket>>`, with automatic room cleanup when a room empties and a 30-second `.unref()`'d ping/pong heartbeat that terminates dead connections.
147
- - `ExisWebSocket` (`websocket/socket.ts`) wraps the raw socket with `.subscribe()`/`.publish()`/`.emit()`/`.to()`/`.broadcast`, JSON auto-serialization, and an `emitWithAck()` request/response pattern with timeout.
148
- - **Upgrade handling on the Node backend** (`ws-orchestrator.ts`): builds a synthetic `ServerResponse` so the normal middleware pipeline (including auth) can run _before_ the actual protocol upgrade happens. If middleware sends a response (e.g., 401), the socket is destroyed instead of upgraded.
149
- - **Upgrade handling on the uWebSockets.js backend** (`ws-orchestrator.ts`'s `handleUwsUpgrade` + `uws-adapter.ts`'s `open()` callback): functionally equivalent. The request shim correctly captures all synchronously-available request data (including `sec-websocket-*` headers), safely defers the `res.upgrade()` call until after asynchronous middlewares complete (using `onAborted` to catch dropped connections), and passes the required context into the `open()` callback seamlessly.
150
-
151
- ---
152
-
153
- ## 11. Server-Sent Events (SSE) 🟢
154
-
155
- **What it is:** One-way server-to-client streaming (`route.sse()` / `@Sse()`), useful for LLM token streaming and other push-style use cases.
156
-
157
- **How it's implemented:** `ExisSSE` (`server/sse.ts`) sets the standard `text/event-stream` headers plus `X-Accel-Buffering: no` (to prevent reverse-proxy buffering from defeating streaming), tracks connection state via the response's `close` event, and exposes `.send(data, eventName?)` which formats either plain strings or JSON-serialized objects per the SSE wire format. Full middleware support is retained, so auth/rate-limiting apply the same as any other route.
158
-
159
- ---
160
-
161
- ## 12. Intelligent Hot-Reloading 🟢
162
-
163
- **What it is:** File-change-triggered reloading that patches only the affected routes rather than restarting the whole process, preserving WebSocket connections and in-memory state.
164
-
165
- **How it's implemented:** `dep-graph.ts` builds a dependency graph by regex-scanning `import`/`export`/`require` statements in route files (resolving both relative imports and `@/` aliases) so that changing a `service.ts` file can be traced back to the `route.ts` files that depend on it. `hot-reload.ts`'s `HotReloader` watches via `chokidar`, and on a relevant change: removes the stale route(s) from the router, busts the CommonJS `require.cache` entry, re-imports the file, and re-mounts it — all without touching unrelated routes or dropping active connections. `dev-error-overlay.ts` provides a readable terminal error format (parsed stack trace + syntax-highlighted code frame) when a hot-reloaded file fails to import.
52
+ 1. **Config:** Export `config = defineBoundary(...)` (functional) or `@Boundary(...)` (OOP) to define CORS, headers, exclusions, and DI providers for that directory tree.
53
+ 2. **Auto-Detected Pipeline:**
54
+ - Functions matching `(req, res, next)` are auto-detected as sequential chain steps.
55
+ - The default export `(ctx, next)` (functional) or class method `handle(ctx, next)` (OOP) is auto-detected as an onion wrapper around all inner steps and child routes.
166
56
 
167
57
  ---
168
58
 
169
- ## 13. uWebSockets.js Adapter 🟢
59
+ ## 6. Native Validation Engine (`tex`) 🟢
170
60
 
171
- **What it is:** An optional high-throughput backend that swaps Node's native HTTP server for `uWebSockets.js`, auto-detected if installed (or forced via `server: 'uws'` config).
61
+ **What it is:** A dependency-free, high-performance schema validator powered by Rust (`@exisjs/rs`) with strict typing, auto-coercion, and structured error responses.
172
62
 
173
- **How it's implemented:** `uws-adapter.ts` provides `UwsIncomingMessage`/`UwsServerResponse` shims that emulate the subset of Node's `IncomingMessage`/`ServerResponse` interface the rest of the framework depends on. Response writes use `res.cork()` to batch header/status/body into a single write. The shim correctly emulates asynchronous Node stream semantics (e.g., buffered `data`/`end` events delivered via microtasks for late listener registration), making it a robust and efficient drop-in replacement.
63
+ **How it's implemented:** `tex` provides primitives (`string`, `number`, `boolean`, `email`, `object`, `array`, `enum`) and integrates directly with `route.*()` configs and `@Body()`. Input sanitization via `exisjs/sanitize` can be chained synchronously via `.sanitize(...)` before validation occurs.
174
64
 
175
65
  ---
176
66
 
177
- ## 14. Request & Response Engine 🟢
178
-
179
- **What it is:** `ExisRequest`/`ExisResponse` wrapper classes providing a fuller feature set than raw Node `IncomingMessage`/`ServerResponse`.
180
-
181
- **Request (`server/request.ts`):**
67
+ ## 7. Production Build & Manifest Pipeline 🟢
182
68
 
183
- - Multipart parsing via `busboy`, query parsing via `fast-querystring`.
184
- - `trustProxy` logic (boolean, or numeric hop-count) correctly resolves `x-forwarded-for`/`x-forwarded-proto`/`x-forwarded-host` — this has explicit, well-covered test cases for the `false`/`true`/numeric-hop variants.
185
- - Body-size limiting with a clear rejection error when exceeded.
186
- - Per-request `Dataloader` instances (see §16) accessible via `req.dataloader(name)`.
187
-
188
- **Response (`server/response.ts`):**
189
-
190
- - Chainable `status()`/`set()`/`header()`/`cookie()` API.
191
- - Automatic ETag generation (SHA1-based, weak ETags) plus `304 Not Modified` short-circuiting when the request is fresh.
192
- - `.download()`, `.html()`, `.sendStream()`, `.redirect()` convenience methods.
193
- - A subtlety worth knowing: **if you inject the raw response object to set custom headers but still return a value from the handler, ExisJS still auto-serializes the returned value to JSON** — unlike frameworks where injecting the raw response disables auto-serialization and silently hangs the request if you forget to call `.send()`.
69
+ - **esbuild Compilation:** `exis build` bundles and transpiles TypeScript rapidly using esbuild, resolving path aliases (`@/*`).
70
+ - **Route Manifest Generation:** Scans routes and writes `.exis/routes-manifest.js` to enable O(1) boot in production without recursive filesystem scanning.
71
+ - **Fast Serialization:** Validated route responses integrate with JIT fast serializers.
194
72
 
195
73
  ---
196
74
 
197
- ## 15. Global Error Handling 🟢
198
-
199
- **What it is:** A structured `HttpError` hierarchy plus a global handler that formats operational errors consistently and masks internals in production.
200
-
201
- **How it's implemented:** `HttpError` (`utils/errors.ts`) carries `statusCode`/`code`/`details`/`isOperational`, with static factories (`badRequest`, `unauthorized`, `notFound`, etc.) and matching subclasses/aliases for both functional and exception-style usage. `createErrorHandler(isDev)` recognizes `HttpError` instances, Zod-shaped and native `ValidatorError` shapes, and JSON `SyntaxError`s, formatting each appropriately; unrecognized errors are logged and returned as a generic message in production, or the full message + stack in development. A dev-mode HTML error overlay is available when the client accepts `text/html`.
75
+ ## 8. Request & Response Engine 🟢
202
76
 
203
- **Exception filters:** `catchError(errorClass, handler)` (`middleware/exception-filter.ts`) provides a functional equivalent to `@Catch()` — a 4-argument middleware that only handles errors matching `instanceof errorClass`, falling through to the next handler otherwise. This composes cleanly with `HttpError`'s subclasses for granular per-error-type handling.
77
+ - **Request:** Native JSON body parsing and cookie parsing delegated to Rust off-heap bindings in `@exisjs/rs`, busboy for multipart form data, and robust proxy trust resolution.
78
+ - **Response:** Chainable status, header, and cookie APIs, automatic ETag generation (weak ETags), and JSON auto-serialization.
204
79
 
205
80
  ---
206
81
 
207
- ## 16. Dataloaders 🟢
208
-
209
- **What it is:** GraphQL-style per-request batching and caching to solve the N+1 query problem.
210
-
211
- **How it's implemented:** `Dataloader` (`dataloader/dataloader.ts`) collects `.load(key)` calls into a queue and dispatches a single batched call to the developer's `batchFn` on `process.nextTick`, splitting into multiple batches if `maxBatchSize` is exceeded. Supports per-instance caching (default on, keyed by identity or a custom `cacheKeyFn` for object keys — objects are `JSON.stringify`'d by default to avoid reference-equality cache misses), `.prime()` for pre-filling the cache, and per-key error rejection (a batch function can return a mix of values and `Error` instances, with each key resolved/rejected independently). Loaders are correctly isolated per request via the DI/context system — verified by tests asserting two concurrent requests using the same loader name get independent batches and caches.
212
-
213
- ---
214
-
215
- ## 17. tRPC-style Frontend Type Client 🟢
216
-
217
- **What it is:** End-to-end type safety between the ExisJS backend and a frontend, without a separate tRPC dependency.
218
-
219
- **How it's implemented:** The manifest generator (§8b) produces `.exis/types.d.ts` exporting an `AppRouter` type. The `exisjs/client` package's `createClient<AppRouter>()` uses a recursive `Proxy` to translate property access chains (`client.api.users.get(...)`) into the corresponding HTTP request, inferring the payload/response shape from the generated types. This is a type-level feature (compile-time safety) layered on a runtime `fetch` call. The framework CLI's file watcher (`exis dev`) explicitly listens to all file events (`add`, `unlink`, `change`) to instantly regenerate the types manifest, ensuring your frontend types never silently fall out of sync with your backend routes.
220
-
221
- ---
222
-
223
- ## 18. Authentication Suite (`exisjs/auth`) 🟢
224
-
225
- **What it is:** JWT, password hashing, RBAC, and session primitives built on Node's native `crypto`, with no third-party cryptography dependency.
226
-
227
- - **JWT (`auth/jwt.ts`):** HS256 via `crypto.createHmac`. Verification checks buffer length before calling `timingSafeEqual` (avoiding the common length-mismatch-throws footgun), and distinguishes `TokenExpiredError` from a generic invalid-signature `HttpError` — useful for clients that want to auto-refresh on expiry specifically.
228
- - **Passwords (`auth/password.ts`):** `crypto.scrypt`, promisified. Hashes are stored with their cost parameters embedded inline (`scrypt:N:r:p:keylen:salt:hash`), so cost factors can be increased later without invalidating existing hashes. Backwards-compatible with a legacy 2-part `salt:hash` format.
229
- - **RBAC (`auth/rbac.ts`):** `requireRole(roles)` checks array intersection between `req.user.role` (string or array) and the allowed list, throwing `401` if unauthenticated or `403` if authenticated but unauthorized.
230
- - **Sessions (`auth/session.ts`):** HMAC-signed, HttpOnly cookies (`timingSafeEqual`-verified) with a pluggable `SessionStore` (in-memory provided, Redis/DB left to the developer). Auto-saves session mutations back to the store by hooking `res.raw.end` and uses dirty-checking (`JSON.stringify(sessionData) !== initialState`) to ensure it only writes to the remote store when the session was actually mutated.
231
-
232
- ---
233
-
234
- ## 19. Universal Edge & Serverless Adapters 🟢
235
-
236
- **What it is:** A consistent `fetch`-based adapter pattern letting the same `App` run on Cloudflare Workers, Deno, Bun, Fastly Compute@Edge, Netlify Edge, Vercel, and AWS Lambda.
237
-
238
- **How it's implemented:** All platform adapters (`adapters/*.ts`) follow the identical init-once-then-handle pattern: lazily call `app.create()`/`app.onStartHook()` on first invocation, then delegate to either `app.fetch(request, env, ctx)` (Web-standard platforms) or `app.handle(req, res)` (Node-stream platforms like Vercel). This consistency across seven adapters is a genuine strength — there's no divergence in behavior between them.
239
-
240
- `adapters/fetch.ts`'s `FetchIncomingMessage`/`FetchServerResponse` polyfill is the shared foundation for all Web-standard-`Request`-based platforms: it emulates just enough of Node's stream/EventEmitter interface (including correctly flushing pre-buffered body bytes to late-registered `'data'`/`'end'` listeners, and correctly handling `.once()` since it delegates to the same `.on()` override) for the framework's existing middleware to run unmodified on Edge runtimes.
241
-
242
- **AWS Lambda specifics (`adapters/aws-lambda.ts`):** automatically detects text-based payloads (JSON, HTML, plain text) and sends them as unencoded strings to save wire overhead, falling back to base64 encoding (`isBase64Encoded: true`) only for binary data (images, octet streams).
243
-
244
- ---
245
-
246
- ## 20. Security Middleware Suite
247
-
248
- Split by actual strength, not lumped together as one "Security Suite":
249
-
250
- ### 20a. Solid, standard-pattern implementations 🟢
251
-
252
- - **Helmet-equivalent headers** (`middleware/security.ts` `helmet()`) — standard static security headers (HSTS, X-Frame-Options, X-Content-Type-Options, etc.), configurable, well-tested.
253
- - **CSRF** (`csrf({ secret })`) — Signed Double Submit Cookie pattern using HMAC SHA-256 to prevent Cookie Tossing attacks. Validated via header-vs-cookie match on state-changing methods.
254
- - **HPP** (`hpp()`) — mitigates HTTP Parameter Pollution by forcing array-like query/body parameters down to their last element.
255
- - **DB sanitize** (`dbSanitize()` / `mongoSanitize()`) — recursively strips keys starting with `$` or containing `.` from body/query/params to prevent NoSQL injection.
256
- - **Timeout** (`timeout()`) — kills stalled requests and sends a 503 if response takes too long.
257
-
258
- ### 20b. Removed Features
259
-
260
- - **`sqlSanitize()` / `dbSanitize({ sql: true })`** — Removed. This regex-based blocklist filtering was trivially bypassable and mangled legitimate content. Real protection comes from parameterized queries / ORM usage. See `REMOVED_FEATURES.md`.
261
-
262
- ---
263
-
264
- ## 21. Observability
265
-
266
- - **Health checks 🟢** (`observability/health.ts`) — runs an array of named async checks in parallel, each wrapped in a `Promise.race()` against a `.unref()`'d timeout so a hanging dependency check can't block the health endpoint itself; aggregates to `200 pass` / `503 fail`.
267
- - **Metrics 🟢** (`observability/prometheus.ts`) — "bring your own metrics" adapter pattern; the middleware itself only measures duration and delegates recording to a developer-supplied adapter (prom-client, StatsD, custom), using `req.routePath` rather than the raw URL to avoid cardinality explosions on parameterized routes.
268
- - **Tracing 🟢** (`observability/otel.ts`) — same "bring your own tracer" pattern for OpenTelemetry-shaped spans, correctly redacts sensitive headers (`authorization`, `cookie`, `x-api-key`, etc.) before they'd reach an external tracing backend, and maps 5xx responses to `SpanStatusCode.ERROR`.
269
-
270
- ---
271
-
272
- ## 22. Zero-Config Third-Party Integrations 🟢
273
-
274
- **What it is:** Lazy-loaded clients for 12 external services (Drizzle, JWT, MongoDB, Mongoose, OpenAI, PostgreSQL, PostHog, Prisma, Redis, Resend, S3, Supabase) that read connection config from conventional environment variables and dynamically `require()` the underlying SDK only when first accessed.
275
-
276
- **How it's implemented:** Each integration (`integrations/*.ts`) exports a `Proxy`-wrapped singleton (e.g. `redis`, `s3`, `mongo`) whose `get` trap lazily constructs the real client on first property access, plus a `create*Client()` factory for explicit instantiation and a `configure*()` function to set options before first use. This means the framework's core bundle never imports these heavy SDKs directly, and connection setup is deferred until the exact moment it's needed — contributing to fast boot times. The test suite comprehensively validates both the missing-env-var failure modes and the successful client constructions (via mocked module injection) across the integrations.
277
-
278
- **Important architectural caveat:** these are **process-wide module-level singletons**, not per-`App`-instance. Multiple `App` instances in one process (e.g. multi-tenant setups, or multiple test files each creating an app) will share the same underlying client unless the explicit `create*Client()` factory is used instead of the singleton proxy. Document this clearly for any usage beyond "one app, one process."
279
-
280
- **Test coverage caveat:** the "throws when required env var is missing" path is tested for all 12 integrations; the "successfully constructs a client with valid config" path is currently only asserted for JWT — the equivalent Redis/S3 tests exist but are marked `.skip()`. Low-effort to complete since the mocking infrastructure is already built.
281
-
282
- ---
283
-
284
- ## 23. CLI & Tooling 🟢
285
-
286
- `exis dev` (esbuild/tsx-powered HMR via child process + chokidar watch, smart port-conflict messaging), `exis build` (§8), `exis start` (production boot), `exis routes` (colorized routing table), `exis test` (native `node:test` wrapper with a custom Jest-style reporter — see §24), `exis generate <type>` (scaffolding for routes/plugins/middleware/tests, functional or OOP), `exis init` / `create-exis` (interactive project scaffolding), `exis console`/`repl` (interactive REPL with auto-discovered model injection), `exis exports` (prints the subpath export map). This surface is broad but consistently implemented and reasonably well covered by both unit and e2e tests (`cli.test.ts` mocks `spawn`/`exit` for fast unit tests; `cli-e2e.test.ts` runs the compiled CLI as a real child process for a smaller set of true end-to-end checks).
287
-
288
- **Cluster mode** (`server/cluster.ts`): `workers: 'safe' | 'max' | number` forks Node's native `cluster` module, with crash-loop detection (stops auto-respawning if more than `maxRespawns` crashes occur within `respawnWindow`) and graceful multi-worker shutdown on SIGINT/SIGTERM.
289
-
290
- ---
291
-
292
- ## 24. Native Test Runner Integration 🟢
293
-
294
- **What it is:** A integrated test runner built on `node:test`, with a custom Jest/Vitest-style terminal reporter, a Jest-compatible `expect()` assertion library, and `createTestContext()` for booting a full `App` (DI container, database connections) inside tests without mocking.
295
-
296
- **How it's implemented:** `testing/reporter.mts` consumes `node:test`'s async iterable of `TestEvent`s and renders grouped, colorized, file-scoped PASS/FAIL output with a Jest-style failure summary — genuinely nicer than raw TAP output. `testing/expect.ts` implements the common Jest matcher surface (`toBe`, `toEqual`, `toMatchObject`, `toHaveBeenCalledWith`, `resolves`/`rejects`, etc.) on top of `node:assert`. `createTestContext()` (`testing/index.ts`) wires `before`/`after` hooks that boot the app, and on teardown, correctly awaits and closes Mongoose, Redis, and Prisma connections if detected in use.
297
-
298
-
299
- **Suite quality note:** the framework's own test suite (used to write this document) is dense and well-constructed across routing, request/response, DI, validator, dataloader, WebSockets (including negative-path auth tests), observability, and both queue drivers. Its main gaps are exactly the two areas this document flags as risk: no test crosses the cron↔queue integration boundary, and the dedupe/cache tests use a single logical client rather than simulating concurrent different users.
300
-
301
- ---
302
-
303
- ## 25. Response Interceptors, Guards, and Pipes 🟢
304
-
305
- - **`intercept(transform)`** (`middleware/interceptor.ts`) — monkey-patches `res.json` for the request duration to apply a transformation function to the outgoing payload, supporting both sync and async transforms. Deliberately does not intercept `res.send()`, since that's meant for raw string/buffer output.
306
- - **`guard(canActivate, options?)`** (`middleware/guard.ts`) — evaluates a boolean (or async-boolean) condition and short-circuits with `403` if it returns false; the OOP equivalent (`@UseGuards`-style) resolves guard classes via the DI container if registered, or instantiates them directly otherwise.
307
- - **`pipe(location, key, transformFn)`** (`middleware/pipe.ts`) — transforms a specific `body`/`query`/`params` key before the handler runs, catching thrown errors and responding `400` automatically.
308
-
309
- ---
310
-
311
- ## 26. Caching, Deduplication, and Backpressure — read this section carefully
312
-
313
- These three middlewares are implemented correctly for their _intended_ single-client use case, and are dangerous with default settings outside it. Do not present them as safe defaults without qualification.
314
-
315
- ### 26a. Tag-based Cache Stores 🟢
316
-
317
- `FileSystemCacheStore`, `MemoryCacheStore`, `RedisCacheStore` (`cache/store.ts`) all implement the same `CacheStore` interface: entries carry an array of string `tags`, and a separate tag→`lastRevalidated` timestamp map is checked on every `get()` — if any of an entry's tags were revalidated after the entry was created, it's treated as a miss. `revalidateTag(tag)` instantly invalidates every entry carrying that tag, Next.js-style. **`MemoryCacheStore` automatically synchronizes invalidations across cluster workers** — when running in `workers > 1` mode, it uses IPC to broadcast tag invalidations to all sibling workers so the memory cache remains safely consistent across the cluster (without requiring Redis).
318
-
319
- ### 26b. `cacheMiddleware` 🟢
320
-
321
- Requires a mandatory `keyGenerator` function (e.g., `(req) => req.user?.id + ':' + req.path`) to ensure cache segregation across users/sessions on authenticated routes. Attempting to use this middleware without providing a `keyGenerator` throws a startup error, preventing accidental cross-user data leaks.
322
-
323
- ### 26c. `dedupeMiddleware` 🟢
324
-
325
- Also requires a mandatory `keyGenerator` to prevent cross-user broadcasting of in-flight requests. Two different authenticated users requesting the same path within the same in-flight window are correctly segregated if the key includes their identity.
326
-
327
- ### 26d. Backpressure Engine 🟢
328
-
329
- `backpressureMiddleware` (`middleware/backpressure.ts`) tracks `activeCount` against `maxConcurrent`, queues overflow up to `maxQueue` with a timeout, and returns `503` once the queue itself is full — correctly implemented and tested, no identity-related caveats since it doesn't cache or share response data between requests.
330
-
331
- ### 26e. Circuit Breaker 🟢
82
+ ## 9. Global Error Handling 🟢
332
83
 
333
- `CircuitBreaker` (`utils/circuit-breaker.ts`) implements a standard `CLOSED`/`OPEN`/`HALF_OPEN` state machine with a single-probe half-open test — correctly implemented and tested, including the full open→half-open→closed recovery cycle.
84
+ Structured `HttpError` hierarchy (`badRequest`, `unauthorized`, `forbidden`, `notFound`, etc.) with consistent JSON error envelopes and dev-mode formatting.
334
85
 
335
86
  ---
336
87
 
337
- ## 27. Standardized JSON Responses 🟢
88
+ ## 10. Core Middleware Suite 🟢
338
89
 
339
- `response/index.ts` exports `success(data, message?)` / `error(message, code?, details?)` helper functions producing a consistent `{ success: boolean, data?, error? }` envelope shape — a convention, not an enforced contract; handlers can return anything and it will still be auto-serialized, but using these helpers keeps API responses consistent across a codebase.
90
+ - **Security:** `helmet()`, `csrf()`, `hpp()`, `dbSanitize()`, `timeout()`.
91
+ - **Traffic & Performance:** In-memory off-heap `rateLimit()`, `idempotent()` (keyed response caching in off-heap memory), `dedupe()`, and `backpressure()`.
92
+ - **Utilities:** `cors()`, `requestId()`, `requestLogger()`, `serveStatic()`.
340
93
 
341
94
  ---
342
95
 
343
- ## Summary: what to actually rely on today
96
+ ## 11. Core Boundary Contract
344
97
 
345
- | Category | Subsystems |
346
- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
347
- | **Rely on freely** | Routing, controllers/decorators, DI, context API, validation, request/response, error handling, dataloaders, gateways/modules/plugins, hot reload, CLI, WebSockets (Node backend), uWebSockets.js backend, SSE, auth primitives (JWT/password/RBAC/session), backpressure, circuit breaker, health/metrics/tracing, cacheMiddleware, dedupeMiddleware, cron, production optimizers (AOT/JIT), edge/serverless adapters, tRPC-style client |
348
- | **Use, but read the caveat first** | Cache stores (mind multi-server horizontal scaling with `MemoryCacheStore`), zero-config integrations (mind singleton scope) |
349
- This table should be kept current as fixes land — moving a row from the middle to the top category is exactly the kind of visible progress worth calling out in a changelog.
98
+ | Subsystem | Location | Scope |
99
+ |---|---|---|
100
+ | Routing & Boundaries | `exisjs/router` | Core runtime |
101
+ | Schema & Validation | `exisjs/validator` (`tex`) | Core runtime |
102
+ | Data Sanitization | `exisjs/sanitize` | Core runtime |
103
+ | Dependency Injection | `exisjs/di` | Core runtime |
104
+ | Core Middleware | `exisjs/middleware` | Core runtime |
105
+ | CLI & Scaffolding | `exisjs/cli` | Core tooling |
106
+ | Database & ORM | `@exisjs/database` | Extracted package |
107
+ | Cache & Redis | `@exisjs/cache` | Extracted package |
108
+ | Background Queues | `@exisjs/queue` | Extracted package |
109
+ | WebSockets | `@exisjs/websocket` | Extracted package |
110
+ | Auth & OAuth | `@exisjs/auth` | Extracted package |
@@ -12,16 +12,16 @@
12
12
  - **Trials:** 3 per framework, order randomized each trial, median reported
13
13
  - **Warmup:** 2s untimed warmup run before each timed trial
14
14
  - **Cores:** single-core, no clustering, for all four frameworks
15
- - **Framework versions:** Express ^5.2.1, Fastify ^5.10.0, Hono ^4.12.32, ExisJS 0.5.0
15
+ - **Framework versions:** Express ^5.2.1, Fastify ^5.12.1, Hono ^4.13.5, ExisJS 0.6.1
16
16
 
17
17
  ### Performance Metrics
18
18
 
19
19
  | Framework | Req/Sec (median) | Latency avg (ms) | Latency p50 (ms) | Latency p99 (ms) | Errors | Server backend |
20
20
  |---|---|---|---|---|---|---|
21
- | Express | 25186.19 | 3.36 | 3.00 | 5.00 | 0 | n/a |
22
- | Fastify | 42916.37 | 2.04 | 2.00 | 3.00 | 0 | n/a |
23
- | Hono | 40938.19 | 2.08 | 2.00 | 4.00 | 0 | n/a |
24
- | Exis JS | 53619.20 | 1.17 | 1.00 | 2.00 | 0 | uws |
21
+ | Express | 16821.82 | 5.40 | 6.00 | 7.00 | 0 | n/a |
22
+ | Fastify | 27625.46 | 3.12 | 3.00 | 5.00 | 0 | n/a |
23
+ | Hono | 30645.82 | 2.79 | 3.00 | 4.00 | 0 | n/a |
24
+ | Exis JS | 38022.55 | 2.14 | 2.00 | 4.00 | 0 | uws |
25
25
 
26
26
  ### Handler Parity Note
27
27
 
@@ -4,7 +4,7 @@
4
4
  </p>
5
5
 
6
6
  <p align="center">
7
- <b>Enterprise ambition with zero-config simplicity. The ultimate batteries-included Node.js backend.</b>
7
+ <b>Ultra-high-performance TypeScript web framework with a raw Rust engine under the hood.</b>
8
8
  </p>
9
9
 
10
10
  <p align="center">
@@ -19,16 +19,13 @@
19
19
  </a>
20
20
  </p>
21
21
 
22
- Welcome to the Exis JS documentation! Exis JS is a powerful, folder-based routing framework designed for building scalable and type-safe backend APIs with ease. It features out-of-the-box RPC client generation, modular route organization, and intuitive middleware/gateway configurations.
22
+ Welcome to the ExisJS documentation! ExisJS is a minimal, opinionated core framework featuring file-system routing, dependency injection, validation (`tex`), sanitization, and an auto-detected request pipeline (`boundary.ts`).
23
23
 
24
- ## Documentation Structure
25
-
26
- This documentation is split into the following main sections:
24
+ Additional capabilities (databases, auth, queues, websockets, caching) are provided as official `@exisjs/*` packages.
27
25
 
28
- - **[Content](./content/)**: Core concepts, tutorials, and deep-dives into building applications with Exis JS. Learn about folder-based routing, setting up your `gateway.ts`, and leveraging the RPC client.
29
- - **[Integrations](./integrations/)**: Guides on how to integrate Exis JS with external services and libraries.
30
- - **[Architecture](./ARCHITECTURE.md)**: Catalog of features supported by Exis JS and their internal implementation details.
31
-
32
- *(Note: Detailed API Reference will be added at a later time)*
26
+ ## Documentation Structure
33
27
 
34
- Dive into the respective folders to get started!
28
+ - **[Content](./content/)**: Core concepts, guides, and deep-dives into building applications with ExisJS. Learn about folder-based routing, setting up your `boundary.ts`, dependency injection, and schema validation with `tex`.
29
+ - **[Reference](./reference/)**: API reference for the core framework modules (`router`, `di`, `validator`, `middleware`, `decorators`, `config`, etc.).
30
+ - **[Architecture](./ARCHITECTURE.md)**: Catalog of core features and internal architectural details.
31
+ - **[Benchmarks](./BENCHMARKS.md)**: Performance benchmarks against other Node.js frameworks.