create-jen-app 1.2.3 → 1.2.4

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 (355) hide show
  1. package/dist/colors.js +0 -17
  2. package/dist/create.js +5 -17
  3. package/dist/generator.js +14 -31
  4. package/dist/index.js +6 -1
  5. package/package.json +1 -1
  6. package/templates/ssr-isr/README.md +77 -0
  7. package/templates/ssr-isr/build.js +118 -0
  8. package/templates/ssr-isr/jen.config.ts +109 -0
  9. package/templates/ssr-isr/jenjs.d.ts +22 -0
  10. package/templates/ssr-isr/lib/api/(hello).js +9 -0
  11. package/templates/ssr-isr/lib/auth/cookie-utils.js +79 -0
  12. package/templates/ssr-isr/lib/auth/index.js +2 -0
  13. package/templates/ssr-isr/lib/auth/jwt.js +57 -0
  14. package/templates/ssr-isr/lib/auth/session.js +92 -0
  15. package/templates/ssr-isr/lib/build/asset-hashing.d.ts +10 -0
  16. package/templates/ssr-isr/lib/build/asset-hashing.js +25 -0
  17. package/templates/ssr-isr/lib/build/asset-manifest.d.ts +11 -0
  18. package/templates/ssr-isr/lib/build/asset-manifest.js +21 -0
  19. package/templates/{static → ssr-isr}/lib/build/build.d.ts +1 -1
  20. package/templates/ssr-isr/lib/build/build.js +141 -0
  21. package/templates/{static → ssr-isr}/lib/build/island-hydration.d.ts +8 -5
  22. package/templates/ssr-isr/lib/build/island-hydration.js +44 -0
  23. package/templates/ssr-isr/lib/build/minifier.d.ts +20 -0
  24. package/templates/ssr-isr/lib/build/minifier.js +46 -0
  25. package/templates/ssr-isr/lib/build/page-renderer.d.ts +17 -0
  26. package/templates/ssr-isr/lib/build/page-renderer.js +28 -0
  27. package/templates/ssr-isr/lib/build/production-build.d.ts +10 -0
  28. package/templates/ssr-isr/lib/build/production-build.js +13 -0
  29. package/templates/ssr-isr/lib/build/ssg-pipeline.d.ts +15 -0
  30. package/templates/ssr-isr/lib/build/ssg-pipeline.js +113 -0
  31. package/templates/ssr-isr/lib/build-tools/build-site.js +36 -0
  32. package/templates/ssr-isr/lib/cache/index.js +10 -0
  33. package/templates/ssr-isr/lib/cache/memory.js +40 -0
  34. package/templates/ssr-isr/lib/cache/redis.js +61 -0
  35. package/templates/ssr-isr/lib/cli/banner.js +28 -0
  36. package/templates/ssr-isr/lib/cli/templates/ssg/jen.config.js +32 -0
  37. package/templates/ssr-isr/lib/cli/templates/ssg/site/index.js +9 -0
  38. package/templates/ssr-isr/lib/cli/templates/ssr/jen.config.js +32 -0
  39. package/templates/ssr-isr/lib/cli/templates/ssr/site/index.js +9 -0
  40. package/templates/ssr-isr/lib/compilers/esbuild-plugins.js +111 -0
  41. package/templates/ssr-isr/lib/compilers/svelte.js +44 -0
  42. package/templates/ssr-isr/lib/compilers/vue.js +90 -0
  43. package/templates/ssr-isr/lib/core/http.js +71 -0
  44. package/templates/ssr-isr/lib/core/middleware-hooks.js +97 -0
  45. package/templates/ssr-isr/lib/core/paths.js +39 -0
  46. package/templates/ssr-isr/lib/core/routes/match.js +47 -0
  47. package/templates/ssr-isr/lib/core/routes/scan.js +190 -0
  48. package/templates/ssr-isr/lib/core/types.js +1 -0
  49. package/templates/ssr-isr/lib/css/compiler.js +74 -0
  50. package/templates/ssr-isr/lib/db/connector.js +42 -0
  51. package/templates/ssr-isr/lib/db/drivers/jdb.js +44 -0
  52. package/templates/ssr-isr/lib/db/drivers/sql.js +182 -0
  53. package/templates/ssr-isr/lib/db/index.js +48 -0
  54. package/templates/ssr-isr/lib/db/types.js +1 -0
  55. package/templates/ssr-isr/lib/graphql/index.js +52 -0
  56. package/templates/ssr-isr/lib/graphql/resolvers.js +25 -0
  57. package/templates/ssr-isr/lib/graphql/schema.js +35 -0
  58. package/templates/ssr-isr/lib/i18n/en.json +4 -0
  59. package/templates/ssr-isr/lib/i18n/es.json +4 -0
  60. package/templates/ssr-isr/lib/i18n/index.js +15 -0
  61. package/templates/ssr-isr/lib/import/jen-import.js +161 -0
  62. package/templates/ssr-isr/lib/index.js +116 -0
  63. package/templates/ssr-isr/lib/jdb/engine.js +275 -0
  64. package/templates/ssr-isr/lib/jdb/index.js +34 -0
  65. package/templates/ssr-isr/lib/jdb/types.js +1 -0
  66. package/templates/ssr-isr/lib/jdb/utils.js +176 -0
  67. package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.js +0 -17
  68. package/templates/ssr-isr/lib/middleware/builtins/cors.js +54 -0
  69. package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.js +0 -17
  70. package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.js +0 -17
  71. package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.js +0 -17
  72. package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.js +0 -17
  73. package/templates/ssr-isr/lib/middleware/context.js +124 -0
  74. package/templates/{static → ssr-isr}/lib/middleware/decorators.js +0 -17
  75. package/templates/{static → ssr-isr}/lib/middleware/errors/handler.js +0 -17
  76. package/templates/ssr-isr/lib/middleware/errors/http-error.js +10 -0
  77. package/templates/ssr-isr/lib/middleware/kernel.js +85 -0
  78. package/templates/ssr-isr/lib/middleware/pipeline.js +148 -0
  79. package/templates/ssr-isr/lib/middleware/registry.js +85 -0
  80. package/templates/ssr-isr/lib/middleware/response.js +107 -0
  81. package/templates/ssr-isr/lib/middleware/types.d.ts +1 -0
  82. package/templates/ssr-isr/lib/middleware/types.js +1 -0
  83. package/templates/ssr-isr/lib/middleware/utils/matcher.js +13 -0
  84. package/templates/{static → ssr-isr}/lib/native/bundle.js +0 -17
  85. package/templates/{static → ssr-isr}/lib/native/dev-server.js +0 -17
  86. package/templates/{static → ssr-isr}/lib/native/index.js +0 -17
  87. package/templates/{static → ssr-isr}/lib/native/optimizer.js +0 -17
  88. package/templates/ssr-isr/lib/native/style-compiler.js +19 -0
  89. package/templates/ssr-isr/lib/plugin/loader.js +36 -0
  90. package/templates/ssr-isr/lib/runtime/client-runtime.js +25 -0
  91. package/templates/ssr-isr/lib/runtime/hmr.js +59 -0
  92. package/templates/ssr-isr/lib/runtime/hydrate.js +55 -0
  93. package/templates/ssr-isr/lib/runtime/island-hydration-client.js +146 -0
  94. package/templates/ssr-isr/lib/runtime/islands.js +110 -0
  95. package/templates/ssr-isr/lib/runtime/render.js +244 -0
  96. package/templates/ssr-isr/lib/server/api-routes.js +237 -0
  97. package/templates/ssr-isr/lib/server/api.js +108 -0
  98. package/templates/ssr-isr/lib/server/app.js +438 -0
  99. package/templates/ssr-isr/lib/server/runtimeServe.js +169 -0
  100. package/templates/ssr-isr/lib/server/ssr.js +202 -0
  101. package/templates/ssr-isr/lib/shared/log.js +64 -0
  102. package/templates/ssr-isr/package.json +23 -0
  103. package/templates/ssr-isr/server.js +128 -0
  104. package/templates/ssr-isr/site/pages/(index).tsx +11 -0
  105. package/templates/ssr-isr/site/styles/global.scss +37 -0
  106. package/templates/ssr-isr/tsconfig.json +39 -0
  107. package/templates/static/build.js +30 -18
  108. package/templates/static/jen.config.ts +0 -18
  109. package/templates/static/jenjs.d.ts +0 -18
  110. package/templates/static/lib/api/(hello).js +0 -17
  111. package/templates/static/lib/api/examples/files/[...slug].js +22 -0
  112. package/templates/static/lib/api/examples/hello.js +11 -0
  113. package/templates/static/lib/api/examples/posts/[id].js +37 -0
  114. package/templates/static/lib/api/examples/posts.js +37 -0
  115. package/templates/static/lib/api/examples/search.js +23 -0
  116. package/templates/static/lib/api/index.js +41 -0
  117. package/templates/static/lib/api/loader.js +234 -0
  118. package/templates/static/lib/api/router.js +259 -0
  119. package/templates/static/lib/assets/types.js +1 -0
  120. package/templates/static/lib/auth/cookie-utils.js +3 -16
  121. package/templates/static/lib/auth/index.js +0 -17
  122. package/templates/static/lib/auth/jwt.js +0 -17
  123. package/templates/static/lib/auth/session.js +0 -17
  124. package/templates/static/lib/build/asset-hashing.js +44 -36
  125. package/templates/static/lib/build/asset-manifest.js +16 -33
  126. package/templates/static/lib/build/build.js +270 -125
  127. package/templates/static/lib/build/bundle-analyzer-ui.js +417 -0
  128. package/templates/static/lib/build/bundle-analyzer.js +945 -0
  129. package/templates/static/lib/build/code-splitter.js +194 -0
  130. package/templates/static/lib/build/feature-analyzer.js +190 -0
  131. package/templates/static/lib/build/feature-gate.js +257 -0
  132. package/templates/static/lib/build/island-hydration.js +17 -35
  133. package/templates/static/lib/build/lazy-loader.js +322 -0
  134. package/templates/static/lib/build/minifier.js +40 -59
  135. package/templates/static/lib/build/page-renderer.js +23 -40
  136. package/templates/static/lib/build/production-build.js +9 -26
  137. package/templates/static/lib/build/rust-hashing.js +71 -0
  138. package/templates/static/lib/build/script-optimizer.js +285 -0
  139. package/templates/static/lib/build/ssg-pipeline.js +100 -106
  140. package/templates/static/lib/build/vercel-output.js +298 -0
  141. package/templates/static/lib/build-tools/build-site.js +0 -17
  142. package/templates/static/lib/cache/index.js +0 -17
  143. package/templates/static/lib/cache/memory.js +0 -17
  144. package/templates/static/lib/cache/redis.js +0 -17
  145. package/templates/static/lib/cli/banner.js +0 -17
  146. package/templates/static/lib/cli/templates/ssg/jen.config.js +0 -17
  147. package/templates/static/lib/cli/templates/ssr/jen.config.js +0 -17
  148. package/templates/static/lib/client/Image.js +42 -0
  149. package/templates/static/lib/client/Link.js +190 -0
  150. package/templates/static/lib/client/PWA.js +46 -0
  151. package/templates/static/lib/client/Seo.js +97 -0
  152. package/templates/static/lib/client/index.js +9 -0
  153. package/templates/static/lib/client/useNavigation.js +25 -0
  154. package/templates/static/lib/client/useRouter.js +64 -0
  155. package/templates/static/lib/client-routing/Link.js +17 -0
  156. package/templates/static/lib/client-routing/index.js +19 -0
  157. package/templates/static/lib/client-routing/router.js +151 -0
  158. package/templates/static/lib/client-routing/signal.js +147 -0
  159. package/templates/static/lib/compilers/esbuild-plugins.js +0 -17
  160. package/templates/static/lib/compilers/svelte.js +0 -17
  161. package/templates/static/lib/compilers/vue.js +0 -17
  162. package/templates/static/lib/core/config.js +0 -17
  163. package/templates/static/lib/core/feature-guard.js +136 -0
  164. package/templates/static/lib/core/features.js +99 -0
  165. package/templates/static/lib/core/http.js +0 -17
  166. package/templates/static/lib/core/layouts/index.js +10 -0
  167. package/templates/static/lib/core/layouts/render.js +158 -0
  168. package/templates/static/lib/core/layouts/scan.js +112 -0
  169. package/templates/static/lib/core/layouts/types.js +1 -0
  170. package/templates/static/lib/core/lifecycle.js +129 -0
  171. package/templates/static/lib/core/loader-schema.js +81 -0
  172. package/templates/static/lib/core/middleware-hooks.js +0 -17
  173. package/templates/static/lib/core/paths.js +0 -17
  174. package/templates/static/lib/core/routes/advanced.js +114 -0
  175. package/templates/static/lib/core/routes/handlers.js +181 -0
  176. package/templates/static/lib/core/routes/match.js +89 -17
  177. package/templates/static/lib/core/routes/orchestrator.js +171 -0
  178. package/templates/static/lib/core/routes/rendering-config.js +131 -0
  179. package/templates/static/lib/core/routes/scan.js +0 -17
  180. package/templates/static/lib/core/types.js +0 -17
  181. package/templates/static/lib/css/compiler.js +1 -18
  182. package/templates/static/lib/data-fetching/cache.js +223 -0
  183. package/templates/static/lib/data-fetching/client.js +202 -0
  184. package/templates/static/lib/data-fetching/feature-guard.js +29 -0
  185. package/templates/static/lib/data-fetching/graphql.js +265 -0
  186. package/templates/static/lib/data-fetching/index.js +57 -0
  187. package/templates/static/lib/data-fetching/rest.js +256 -0
  188. package/templates/static/lib/data-fetching/server.js +182 -0
  189. package/templates/static/lib/data-fetching/types.js +5 -0
  190. package/templates/static/lib/db/connector.js +0 -17
  191. package/templates/static/lib/db/drivers/jdb.js +0 -17
  192. package/templates/static/lib/db/drivers/sql.js +0 -17
  193. package/templates/static/lib/db/index.js +0 -17
  194. package/templates/static/lib/db/types.js +0 -17
  195. package/templates/static/lib/devtools/component-tree.js +106 -0
  196. package/templates/static/lib/devtools/devtools.js +638 -0
  197. package/templates/static/lib/devtools/event-bus.js +29 -0
  198. package/templates/static/lib/devtools/event-logger.js +67 -0
  199. package/templates/static/lib/devtools/index.js +9 -0
  200. package/templates/static/lib/devtools/integration.js +149 -0
  201. package/templates/static/lib/devtools/performance.js +84 -0
  202. package/templates/static/lib/devtools/persistence.js +57 -0
  203. package/templates/static/lib/devtools/plugins.js +97 -0
  204. package/templates/static/lib/devtools/search.js +89 -0
  205. package/templates/static/lib/devtools/ui.js +769 -0
  206. package/templates/static/lib/features/api/handler.js +10 -0
  207. package/templates/static/lib/features/api/index.js +5 -0
  208. package/templates/static/lib/features/api/types.js +4 -0
  209. package/templates/static/lib/features/middleware/compiled.js +7 -0
  210. package/templates/static/lib/features/middleware/index.js +5 -0
  211. package/templates/static/lib/features/middleware/types.js +4 -0
  212. package/templates/static/lib/fonts/index.js +46 -0
  213. package/templates/static/lib/fonts/inject.js +125 -0
  214. package/templates/static/lib/fonts/loader.js +196 -0
  215. package/templates/static/lib/fonts/types.js +1 -0
  216. package/templates/static/lib/graphql/index.js +1 -18
  217. package/templates/static/lib/graphql/resolvers.js +20 -13
  218. package/templates/static/lib/graphql/schema.js +0 -17
  219. package/templates/static/lib/i18n/index.js +7 -19
  220. package/templates/static/lib/import/jen-import.js +1 -18
  221. package/templates/static/lib/index.js +79 -125
  222. package/templates/static/lib/jdb/engine.js +0 -17
  223. package/templates/static/lib/jdb/index.js +1 -18
  224. package/templates/static/lib/jdb/types.js +0 -17
  225. package/templates/static/lib/jdb/utils.js +0 -17
  226. package/templates/static/lib/middleware/builtins/cors.js +3 -16
  227. package/templates/static/lib/middleware/context.js +0 -17
  228. package/templates/static/lib/middleware/kernel.js +117 -25
  229. package/templates/static/lib/middleware/pipeline.js +0 -17
  230. package/templates/static/lib/middleware/registry.js +0 -17
  231. package/templates/static/lib/middleware/response.js +0 -17
  232. package/templates/static/lib/plugin/examples/analytics-plugin.js +183 -0
  233. package/templates/static/lib/plugin/examples/cdn-upload-plugin.js +94 -0
  234. package/templates/static/lib/plugin/loader.js +0 -17
  235. package/templates/static/lib/plugin/plugin-manager.js +177 -0
  236. package/templates/static/lib/plugin/types.js +28 -0
  237. package/templates/static/lib/runtime/client-runtime.js +0 -17
  238. package/templates/static/lib/runtime/hmr.js +0 -17
  239. package/templates/static/lib/runtime/hydrate.js +0 -17
  240. package/templates/static/lib/runtime/island-hydration-client.js +0 -17
  241. package/templates/static/lib/runtime/islands.js +0 -17
  242. package/templates/static/lib/runtime/render.js +208 -50
  243. package/templates/static/lib/security/security-config.js +60 -0
  244. package/templates/static/lib/security/security-middleware.js +229 -0
  245. package/templates/static/lib/server/api-routes.js +153 -43
  246. package/templates/static/lib/server/api.js +0 -17
  247. package/templates/static/lib/server/app.js +539 -223
  248. package/templates/static/lib/server/isr.js +365 -0
  249. package/templates/static/lib/server/runtimeServe.js +31 -24
  250. package/templates/static/lib/server/ssr.js +98 -22
  251. package/templates/static/lib/server-actions/handler.js +180 -0
  252. package/templates/static/lib/server-actions/index.js +19 -0
  253. package/templates/static/lib/server-actions/middleware.js +146 -0
  254. package/templates/static/lib/server-actions/scan.js +152 -0
  255. package/templates/static/lib/server-actions/types.js +1 -0
  256. package/templates/static/lib/server-actions/validators.js +156 -0
  257. package/templates/static/lib/shared/log.js +19 -20
  258. package/templates/static/lib/telemetry/api/rate-limiter.js +32 -0
  259. package/templates/static/lib/telemetry/api/validator.js +67 -0
  260. package/templates/static/lib/telemetry/client.js +121 -0
  261. package/templates/static/lib/telemetry/tests/rate-limiter.test.js +46 -0
  262. package/templates/static/lib/telemetry/tests/validator.test.js +62 -0
  263. package/templates/static/lib/vendor/glob/glob.js +4766 -0
  264. package/templates/static/lib/vendor/preact/LICENSE +21 -0
  265. package/templates/static/lib/vendor/preact/preact.module.js +797 -0
  266. package/templates/static/lib/vendor/sass/sass.node.mjs +212 -0
  267. package/templates/static/package.json +4 -0
  268. package/templates/static/server.js +22 -22
  269. package/templates/static/site/(home).tsx +0 -18
  270. package/templates/static/tsconfig.json +5 -1
  271. package/templates/static/.esbuild/jen.config.js +0 -19
  272. package/templates/static/lib/build/asset-hashing.d.ts +0 -10
  273. package/templates/static/lib/build/asset-manifest.d.ts +0 -11
  274. package/templates/static/lib/build/minifier.d.ts +0 -20
  275. package/templates/static/lib/build/page-renderer.d.ts +0 -17
  276. package/templates/static/lib/build/production-build.d.ts +0 -10
  277. package/templates/static/lib/build/ssg-pipeline.d.ts +0 -15
  278. package/templates/static/lib/middleware/errors/http-error.js +0 -27
  279. package/templates/static/lib/middleware/types.js +0 -18
  280. package/templates/static/lib/middleware/utils/matcher.js +0 -30
  281. package/templates/static/lib/native/style-compiler.js +0 -36
  282. /package/templates/{static → ssr-isr}/lib/api/(hello).d.ts +0 -0
  283. /package/templates/{static → ssr-isr}/lib/auth/cookie-utils.d.ts +0 -0
  284. /package/templates/{static → ssr-isr}/lib/auth/index.d.ts +0 -0
  285. /package/templates/{static → ssr-isr}/lib/auth/jwt.d.ts +0 -0
  286. /package/templates/{static → ssr-isr}/lib/auth/session.d.ts +0 -0
  287. /package/templates/{static → ssr-isr}/lib/build-tools/build-site.d.ts +0 -0
  288. /package/templates/{static → ssr-isr}/lib/cache/index.d.ts +0 -0
  289. /package/templates/{static → ssr-isr}/lib/cache/memory.d.ts +0 -0
  290. /package/templates/{static → ssr-isr}/lib/cache/redis.d.ts +0 -0
  291. /package/templates/{static → ssr-isr}/lib/cli/banner.d.ts +0 -0
  292. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/jen.config.d.ts +0 -0
  293. /package/templates/{static → ssr-isr}/lib/cli/templates/ssg/site/index.d.ts +0 -0
  294. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/jen.config.d.ts +0 -0
  295. /package/templates/{static → ssr-isr}/lib/cli/templates/ssr/site/index.d.ts +0 -0
  296. /package/templates/{static → ssr-isr}/lib/compilers/esbuild-plugins.d.ts +0 -0
  297. /package/templates/{static → ssr-isr}/lib/compilers/svelte.d.ts +0 -0
  298. /package/templates/{static → ssr-isr}/lib/compilers/vue.d.ts +0 -0
  299. /package/templates/{static → ssr-isr}/lib/core/config.d.ts +0 -0
  300. /package/templates/{static/lib/middleware/types.d.ts → ssr-isr/lib/core/config.js} +0 -0
  301. /package/templates/{static → ssr-isr}/lib/core/http.d.ts +0 -0
  302. /package/templates/{static → ssr-isr}/lib/core/middleware-hooks.d.ts +0 -0
  303. /package/templates/{static → ssr-isr}/lib/core/paths.d.ts +0 -0
  304. /package/templates/{static → ssr-isr}/lib/core/routes/match.d.ts +0 -0
  305. /package/templates/{static → ssr-isr}/lib/core/routes/scan.d.ts +0 -0
  306. /package/templates/{static → ssr-isr}/lib/core/types.d.ts +0 -0
  307. /package/templates/{static → ssr-isr}/lib/css/compiler.d.ts +0 -0
  308. /package/templates/{static → ssr-isr}/lib/db/connector.d.ts +0 -0
  309. /package/templates/{static → ssr-isr}/lib/db/drivers/jdb.d.ts +0 -0
  310. /package/templates/{static → ssr-isr}/lib/db/drivers/sql.d.ts +0 -0
  311. /package/templates/{static → ssr-isr}/lib/db/index.d.ts +0 -0
  312. /package/templates/{static → ssr-isr}/lib/db/types.d.ts +0 -0
  313. /package/templates/{static → ssr-isr}/lib/graphql/index.d.ts +0 -0
  314. /package/templates/{static → ssr-isr}/lib/graphql/resolvers.d.ts +0 -0
  315. /package/templates/{static → ssr-isr}/lib/graphql/schema.d.ts +0 -0
  316. /package/templates/{static → ssr-isr}/lib/i18n/index.d.ts +0 -0
  317. /package/templates/{static → ssr-isr}/lib/import/jen-import.d.ts +0 -0
  318. /package/templates/{static → ssr-isr}/lib/index.d.ts +0 -0
  319. /package/templates/{static → ssr-isr}/lib/jdb/engine.d.ts +0 -0
  320. /package/templates/{static → ssr-isr}/lib/jdb/index.d.ts +0 -0
  321. /package/templates/{static → ssr-isr}/lib/jdb/types.d.ts +0 -0
  322. /package/templates/{static → ssr-isr}/lib/jdb/utils.d.ts +0 -0
  323. /package/templates/{static → ssr-isr}/lib/middleware/builtins/body-parser.d.ts +0 -0
  324. /package/templates/{static → ssr-isr}/lib/middleware/builtins/cors.d.ts +0 -0
  325. /package/templates/{static → ssr-isr}/lib/middleware/builtins/logger.d.ts +0 -0
  326. /package/templates/{static → ssr-isr}/lib/middleware/builtins/rate-limit.d.ts +0 -0
  327. /package/templates/{static → ssr-isr}/lib/middleware/builtins/request-id.d.ts +0 -0
  328. /package/templates/{static → ssr-isr}/lib/middleware/builtins/security-headers.d.ts +0 -0
  329. /package/templates/{static → ssr-isr}/lib/middleware/context.d.ts +0 -0
  330. /package/templates/{static → ssr-isr}/lib/middleware/decorators.d.ts +0 -0
  331. /package/templates/{static → ssr-isr}/lib/middleware/errors/handler.d.ts +0 -0
  332. /package/templates/{static → ssr-isr}/lib/middleware/errors/http-error.d.ts +0 -0
  333. /package/templates/{static → ssr-isr}/lib/middleware/kernel.d.ts +0 -0
  334. /package/templates/{static → ssr-isr}/lib/middleware/pipeline.d.ts +0 -0
  335. /package/templates/{static → ssr-isr}/lib/middleware/registry.d.ts +0 -0
  336. /package/templates/{static → ssr-isr}/lib/middleware/response.d.ts +0 -0
  337. /package/templates/{static → ssr-isr}/lib/middleware/utils/matcher.d.ts +0 -0
  338. /package/templates/{static → ssr-isr}/lib/native/bundle.d.ts +0 -0
  339. /package/templates/{static → ssr-isr}/lib/native/dev-server.d.ts +0 -0
  340. /package/templates/{static → ssr-isr}/lib/native/index.d.ts +0 -0
  341. /package/templates/{static → ssr-isr}/lib/native/optimizer.d.ts +0 -0
  342. /package/templates/{static → ssr-isr}/lib/native/style-compiler.d.ts +0 -0
  343. /package/templates/{static → ssr-isr}/lib/plugin/loader.d.ts +0 -0
  344. /package/templates/{static → ssr-isr}/lib/runtime/client-runtime.d.ts +0 -0
  345. /package/templates/{static → ssr-isr}/lib/runtime/hmr.d.ts +0 -0
  346. /package/templates/{static → ssr-isr}/lib/runtime/hydrate.d.ts +0 -0
  347. /package/templates/{static → ssr-isr}/lib/runtime/island-hydration-client.d.ts +0 -0
  348. /package/templates/{static → ssr-isr}/lib/runtime/islands.d.ts +0 -0
  349. /package/templates/{static → ssr-isr}/lib/runtime/render.d.ts +0 -0
  350. /package/templates/{static → ssr-isr}/lib/server/api-routes.d.ts +0 -0
  351. /package/templates/{static → ssr-isr}/lib/server/api.d.ts +0 -0
  352. /package/templates/{static → ssr-isr}/lib/server/app.d.ts +0 -0
  353. /package/templates/{static → ssr-isr}/lib/server/runtimeServe.d.ts +0 -0
  354. /package/templates/{static → ssr-isr}/lib/server/ssr.d.ts +0 -0
  355. /package/templates/{static → ssr-isr}/lib/shared/log.d.ts +0 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * GraphQL integration utilities for Jen.js applications.
3
+ *
4
+ * Jen.js does not include GraphQL as a built-in dependency. This module provides
5
+ * a placeholder for GraphQL query execution and can be extended with custom implementations
6
+ * that use your chosen GraphQL library.
7
+ *
8
+ * To integrate GraphQL:
9
+ * 1. Install: npm install graphql
10
+ * 2. Import the graphql library: import { graphql } from 'graphql';
11
+ * 3. Implement query execution using your schema
12
+ * 4. Use in API routes or loaders
13
+ *
14
+ * @example
15
+ * // In an API route:
16
+ * import { runQuery } from '@src/graphql';
17
+ *
18
+ * export default {
19
+ * handler: async (ctx) => {
20
+ * const result = await runQuery(ctx.body.query, ctx.body.variables);
21
+ * ctx.response.json(result);
22
+ * }
23
+ * };
24
+ */
25
+ /**
26
+ * Execute a GraphQL query.
27
+ * This is a placeholder function that must be implemented with your GraphQL library.
28
+ *
29
+ * @param query The GraphQL query string.
30
+ * @param variables Optional variables object for parameterized queries.
31
+ * @returns The query result object with data and errors (if any).
32
+ * @throws Error indicating GraphQL library must be installed.
33
+ *
34
+ * @example
35
+ * // Once graphql is installed:
36
+ * import { graphql } from 'graphql';
37
+ * import { schema } from './schema';
38
+ *
39
+ * export async function runQuery(query: string, variables?: any) {
40
+ * const result = await graphql({
41
+ * schema,
42
+ * source: query,
43
+ * variableValues: variables
44
+ * });
45
+ * return result;
46
+ * }
47
+ */
48
+ export async function runQuery(query, variables) {
49
+ throw new Error(
50
+ "GraphQL implementation requires external library. Install: npm install graphql",
51
+ );
52
+ }
@@ -0,0 +1,25 @@
1
+ /** In-memory user store for example resolvers. Replace with database queries. */
2
+ const users = [];
3
+ /**
4
+ * Example resolvers for user queries and mutations.
5
+ * These are simple demonstrations using an in-memory store.
6
+ * In a real application, resolvers should query your database (JDB, etc.).
7
+ */
8
+ export const resolvers = {
9
+ /**
10
+ * Query all users.
11
+ * @returns Array of all users.
12
+ */
13
+ users: () => users,
14
+ /**
15
+ * Create a new user.
16
+ * @param name User's full name.
17
+ * @param email User's email address.
18
+ * @returns The created user object with an ID.
19
+ */
20
+ createUser: ({ name, email }) => {
21
+ const user = { id: (users.length + 1).toString(), name, email };
22
+ users.push(user);
23
+ return user;
24
+ },
25
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * GraphQL schema placeholder module.
3
+ *
4
+ * Jen.js does not include GraphQL as a built-in dependency to keep the framework lightweight.
5
+ * GraphQL support is opt-in: users can integrate GraphQL by installing the graphql package
6
+ * and defining their own schemas in this module or elsewhere in their application.
7
+ *
8
+ * To use GraphQL with Jen.js:
9
+ * 1. Install the graphql package: npm install graphql
10
+ * 2. Define your schema using the graphql library
11
+ * 3. Create API routes that execute queries against the schema
12
+ *
13
+ * @example
14
+ * // Install: npm install graphql
15
+ * // src/graphql/schema.ts
16
+ *
17
+ * import { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLField } from 'graphql';
18
+ *
19
+ * export const schema = new GraphQLSchema({
20
+ * query: new GraphQLObjectType({
21
+ * name: 'Query',
22
+ * fields: {
23
+ * hello: {
24
+ * type: GraphQLString,
25
+ * resolve: () => 'Hello, World!'
26
+ * }
27
+ * }
28
+ * })
29
+ * });
30
+ */
31
+ /**
32
+ * Placeholder export for the GraphQL schema.
33
+ * Replace with your actual schema once graphql is installed.
34
+ */
35
+ export const schema = null;
@@ -0,0 +1,4 @@
1
+ {
2
+ "hello": "Hello",
3
+ "welcome": "Welcome"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "hello": "Hola",
3
+ "welcome": "Bienvenido"
4
+ }
@@ -0,0 +1,15 @@
1
+ import en from "./en.json";
2
+ import es from "./es.json";
3
+ const translations = { en, es };
4
+ export class I18n {
5
+ locale;
6
+ constructor(defaultLocale = "en") {
7
+ this.locale = defaultLocale;
8
+ }
9
+ setLocale(locale) {
10
+ this.locale = locale;
11
+ }
12
+ t(key) {
13
+ return translations[this.locale][key] || key;
14
+ }
15
+ }
@@ -0,0 +1,161 @@
1
+ import { buildSync } from "esbuild";
2
+ import { pathToFileURL } from "node:url";
3
+ import { join, resolve, extname } from "node:path";
4
+ import { mkdirSync, existsSync } from "node:fs";
5
+ import { createHash } from "node:crypto";
6
+ import { log } from "../shared/log.js";
7
+ import {
8
+ vueEsbuildPlugin,
9
+ svelteEsbuildPlugin,
10
+ } from "../compilers/esbuild-plugins.js";
11
+ /** In-memory cache mapping file paths to imported modules. Enables fast repeated imports. */
12
+ const importCache = new Map();
13
+ /**
14
+ * Resolve the cache directory path for a compiled module.
15
+ * Uses a flattened naming scheme to work reliably on Windows and other systems.
16
+ * Compiled modules are cached in node_modules/.jen/import-cache and are typically .gitignored.
17
+ *
18
+ * @param filePath The absolute path to the original source file.
19
+ * @returns The absolute path to the cached compiled .mjs file.
20
+ */
21
+ function getCachePath(filePath) {
22
+ const cacheDir = join(process.cwd(), "node_modules", ".jen", "import-cache");
23
+ if (!existsSync(cacheDir)) {
24
+ mkdirSync(cacheDir, { recursive: true });
25
+ }
26
+ const flatName = filePath.replace(/[\\/:]/g, "_").replace(/^_+/, "");
27
+ return join(cacheDir, flatName + ".mjs");
28
+ }
29
+ /**
30
+ * Generate an ETag hash for a file to detect changes.
31
+ * Uses SHA1 for speed and sufficient collision resistance for this use case.
32
+ *
33
+ * @param content The file content to hash.
34
+ * @returns A 40-character hex string representing the hash.
35
+ */
36
+ function generateEtag(content) {
37
+ return createHash("sha1").update(content).digest("hex");
38
+ }
39
+ /**
40
+ * Universal module importer for Vue, Svelte, and regular JS/TS files.
41
+ * Handles transpilation and caching to enable dynamic imports of framework components
42
+ * and utility modules with automatic compilation.
43
+ *
44
+ * Supported file types: .vue, .svelte, .ts, .tsx, .js, .jsx.
45
+ * Transpilation is performed using esbuild with Vue and Svelte plugins.
46
+ * Compiled modules are cached in node_modules/.jen/import-cache for fast subsequent loads.
47
+ *
48
+ * @param specifier File path relative to baseDir (typically process.cwd() or a component directory).
49
+ * @param opts Import options.
50
+ * @param opts.baseDir Base directory for relative path resolution. Defaults to process.cwd().
51
+ * @param opts.cache Whether to use in-memory cache. Defaults to true.
52
+ * @param opts.forceRecompile If true, bypass cache and recompile the module.
53
+ * @returns The imported module object (exports).
54
+ * @throws Error if the file type is unsupported, the file cannot be read, or transpilation fails.
55
+ *
56
+ * @example
57
+ * const Button = await jenImport("./components/Button.vue");
58
+ * const Card = await jenImport("./ui/Card.svelte");
59
+ * const Utils = await jenImport("./utils.ts", { cache: true });
60
+ * const Fresh = await jenImport("./component.tsx", { forceRecompile: true });
61
+ */
62
+ export async function jenImport(specifier, opts) {
63
+ const baseDir = opts?.baseDir ?? process.cwd();
64
+ const useCache = opts?.cache !== false;
65
+ const forceRecompile = opts?.forceRecompile ?? false;
66
+ try {
67
+ // Resolve the file path relative to baseDir
68
+ const filePath = resolve(baseDir, specifier);
69
+ const ext = extname(filePath);
70
+ // Check cache first if enabled and not forcing recompile
71
+ if (useCache && !forceRecompile && importCache.has(filePath)) {
72
+ log.info(`[jen.import] Cache hit: ${specifier}`);
73
+ return importCache.get(filePath).module;
74
+ }
75
+ const isVue = ext === ".vue";
76
+ const isSvelte = ext === ".svelte";
77
+ const isTs = ext === ".ts" || ext === ".tsx";
78
+ // Validate file type
79
+ if (!isVue && !isSvelte && !isTs && ext !== ".js" && ext !== ".jsx") {
80
+ throw new Error(
81
+ `Unsupported file type: ${ext}. Supported: .vue, .svelte, .ts, .tsx, .js, .jsx`,
82
+ );
83
+ }
84
+ log.info(`[jen.import] Loading: ${specifier} (${ext})`);
85
+ const outfile = getCachePath(filePath);
86
+ // Transpile the module using esbuild with appropriate plugins
87
+ // Platform is set to "browser" for client-side components
88
+ // Bundle is false to preserve imports and enable tree-shaking
89
+ const result = buildSync({
90
+ entryPoints: [filePath],
91
+ outfile,
92
+ format: "esm",
93
+ platform: "browser",
94
+ target: "es2022",
95
+ bundle: false, // Don't bundle to preserve imports
96
+ write: true,
97
+ plugins: [vueEsbuildPlugin(), svelteEsbuildPlugin()],
98
+ external: [
99
+ "preact",
100
+ "preact/hooks",
101
+ "preact/jsx-runtime",
102
+ "preact-render-to-string",
103
+ "vue",
104
+ "svelte",
105
+ ],
106
+ logLevel: "error",
107
+ define: {
108
+ "process.env.NODE_ENV": JSON.stringify("development"),
109
+ },
110
+ });
111
+ // Dynamic import with cache-busting query parameter
112
+ // Prevents Node.js from caching the old module on repeated imports
113
+ const moduleUrl = pathToFileURL(outfile).href + "?t=" + Date.now();
114
+ const mod = await import(moduleUrl);
115
+ // Cache the imported module if caching is enabled
116
+ if (useCache) {
117
+ importCache.set(filePath, {
118
+ module: mod,
119
+ etag: generateEtag(outfile),
120
+ });
121
+ }
122
+ log.info(`[jen.import] Successfully loaded: ${specifier}`);
123
+ return mod;
124
+ } catch (err) {
125
+ const message = err.message || String(err);
126
+ log.error(`[jen.import] Failed to import "${specifier}": ${message}`);
127
+ throw new Error(`jen.import() failed for "${specifier}": ${message}`);
128
+ }
129
+ }
130
+ /**
131
+ * Invalidate the import cache for a specific file.
132
+ * Forces the next import to recompile the module from source.
133
+ * Useful during development when code changes frequently and cache may be stale.
134
+ *
135
+ * @param specifier File path (relative to process.cwd()) to invalidate.
136
+ */
137
+ export function invalidateImportCache(specifier) {
138
+ const filePath = resolve(process.cwd(), specifier);
139
+ importCache.delete(filePath);
140
+ log.info(`[jen.import] Cache invalidated: ${specifier}`);
141
+ }
142
+ /**
143
+ * Clear all import caches completely.
144
+ * Forces all subsequent imports to recompile from source.
145
+ * Should be called sparingly; typically used when restarting the development server.
146
+ */
147
+ export function clearImportCache() {
148
+ importCache.clear();
149
+ log.info(`[jen.import] All caches cleared`);
150
+ }
151
+ /**
152
+ * Global jen namespace providing access to jen.import() for dynamic module loading.
153
+ * Can be used as an alternative to calling jenImport() directly.
154
+ *
155
+ * @example
156
+ * import { jen } from '@src/import/jen-import';
157
+ * const Component = await jen.import('./Component.vue');
158
+ */
159
+ export const jen = {
160
+ import: jenImport,
161
+ };
@@ -0,0 +1,116 @@
1
+ // ============================================================================
2
+ // Barrel Export: Automatically exports everything from all nested modules
3
+ // ============================================================================
4
+ // API
5
+ export * from "./api/(hello).js";
6
+ // Auth
7
+ export * from "./auth/index.js";
8
+ // Build
9
+ export { buildSite as legacyBuildSite } from "./build-tools/build-site.js";
10
+ export * from "./build/build.js";
11
+ export { ProductionBuilder } from "./build/production-build.js";
12
+ export { SSGPipeline } from "./build/ssg-pipeline.js";
13
+ export * from "./build/island-hydration.js";
14
+ export { AssetManifest } from "./build/asset-manifest.js";
15
+ export { AssetHasher } from "./build/asset-hashing.js";
16
+ export { PageRenderer } from "./build/page-renderer.js";
17
+ export { Minifier } from "./build/minifier.js";
18
+ export {
19
+ createIslandRegistry,
20
+ markIsland,
21
+ extractIslandsFromHtml,
22
+ injectIslandScript,
23
+ } from "./build/island-hydration.js";
24
+ // Cache
25
+ export * from "./cache/index.js";
26
+ export * from "./cache/memory.js";
27
+ export * from "./cache/redis.js";
28
+ // CLI
29
+ export * from "./cli/templates/ssg/jen.config.js";
30
+ export * from "./cli/templates/ssr/jen.config.js";
31
+ export * from "./cli/banner.js";
32
+ // Compilers
33
+ export { createVueCompiler } from "./compilers/vue.js";
34
+ export { createSvelteCompiler } from "./compilers/svelte.js";
35
+ export {
36
+ vueEsbuildPlugin,
37
+ svelteEsbuildPlugin,
38
+ invalidateVueCache,
39
+ invalidateSvelteCache,
40
+ clearAllCompilerCaches,
41
+ } from "./compilers/esbuild-plugins.js";
42
+ // Core
43
+ export * from "./core/config.js";
44
+ export * from "./core/http.js";
45
+ export * from "./core/paths.js";
46
+ export * from "./core/types.js";
47
+ export * from "./core/routes/match.js";
48
+ export * from "./core/routes/scan.js";
49
+ export * from "./core/middleware-hooks.js";
50
+ // CSS
51
+ export * from "./css/compiler.js";
52
+ // Database
53
+ export * from "./db/index.js";
54
+ export * from "./db/types.js";
55
+ export * from "./db/connector.js";
56
+ export * from "./db/drivers/sql.js";
57
+ export * from "./db/drivers/jdb.js";
58
+ // GraphQL
59
+ export * from "./graphql/index.js";
60
+ export * from "./graphql/schema.js";
61
+ export * from "./graphql/resolvers.js";
62
+ // i18n
63
+ export * from "./i18n/index.js";
64
+ // Import utilities
65
+ export {
66
+ jenImport,
67
+ clearImportCache,
68
+ invalidateImportCache,
69
+ jen,
70
+ } from "./import/jen-import.js";
71
+ // JDB
72
+ export * from "./jdb/index.js";
73
+ export * from "./jdb/engine.js";
74
+ export * from "./jdb/types.js";
75
+ export * from "./jdb/utils.js";
76
+ // Middleware
77
+ export * from "./middleware/types.js";
78
+ export * from "./middleware/context.js";
79
+ export * from "./middleware/response.js";
80
+ export * from "./middleware/pipeline.js";
81
+ export * from "./middleware/kernel.js";
82
+ export * from "./middleware/registry.js";
83
+ export * from "./middleware/decorators.js";
84
+ export * from "./middleware/builtins/logger.js";
85
+ export * from "./middleware/builtins/request-id.js";
86
+ export * from "./middleware/builtins/security-headers.js";
87
+ export * from "./middleware/builtins/cors.js";
88
+ export * from "./middleware/builtins/body-parser.js";
89
+ export * from "./middleware/builtins/rate-limit.js";
90
+ export * from "./middleware/errors/http-error.js";
91
+ export * from "./middleware/errors/handler.js";
92
+ export * from "./middleware/utils/matcher.js";
93
+ // Native
94
+ export * from "./native/index.js";
95
+ export * from "./native/bundle.js";
96
+ export * from "./native/dev-server.js";
97
+ export * from "./native/optimizer.js";
98
+ export * from "./native/style-compiler.js";
99
+ // Plugin
100
+ export * from "./plugin/loader.js";
101
+ // Runtime
102
+ export * from "./runtime/render.js";
103
+ export * from "./runtime/client-runtime.js";
104
+ export * from "./runtime/hydrate.js";
105
+ export * from "./runtime/hmr.js";
106
+ export * from "./runtime/islands.js";
107
+ export * from "./runtime/island-hydration-client.js";
108
+ // Server
109
+ export * from "./server/app.js";
110
+ // Use new api-routes.ts for HTTP method handlers (replaces old api.js behavior)
111
+ export { tryHandleApiRoute as tryHandleApiRoute_v2 } from "./server/api-routes.js";
112
+ // Keep old api.js exports for backward compatibility
113
+ export { tryHandleApiRoute } from "./server/api.js";
114
+ export * from "./server/runtimeServe.js";
115
+ // Shared utilities
116
+ export * from "./shared/log.js";
@@ -0,0 +1,275 @@
1
+ import path from "path";
2
+ import {
3
+ ensureDir,
4
+ readJSON,
5
+ writeJSON,
6
+ generateId,
7
+ matchFilter,
8
+ applyUpdate,
9
+ } from "./utils";
10
+ /**
11
+ * In-memory representation of a single collection.
12
+ * Manages document storage, serialization, and basic file I/O.
13
+ * Supports lazy loading of data from disk and deferred save operations to batch writes.
14
+ *
15
+ * @template T Document type, must extend the Document base type.
16
+ */
17
+ class JDBCollection {
18
+ name;
19
+ dir;
20
+ inMemory;
21
+ /** Absolute path to the .jdb file for this collection. */
22
+ file;
23
+ /** In-memory array of documents. */
24
+ data = [];
25
+ /** Flag indicating whether the data has been loaded from disk. */
26
+ loaded = false;
27
+ /** Flag indicating a save operation is currently in progress. */
28
+ saving = false;
29
+ /** Flag indicating a save was requested while another save was in progress. Triggers another save after current one completes. */
30
+ queueSave = false;
31
+ /**
32
+ * Create a new collection instance.
33
+ * Does not load data until an operation requires it (lazy loading).
34
+ *
35
+ * @param name Name of the collection.
36
+ * @param dir Directory where collection files are stored.
37
+ * @param inMemory If true, data is never persisted to disk.
38
+ */
39
+ constructor(name, dir, inMemory) {
40
+ this.name = name;
41
+ this.dir = dir;
42
+ this.inMemory = inMemory;
43
+ this.file = path.join(dir, `${name}.jdb`);
44
+ }
45
+ /**
46
+ * Load collection data from disk on first access.
47
+ * Uses lazy loading to defer file I/O until actually needed.
48
+ * In-memory collections skip disk reads entirely.
49
+ * Idempotent: subsequent calls return immediately if already loaded.
50
+ */
51
+ async load() {
52
+ if (this.loaded) return;
53
+ if (!this.inMemory) {
54
+ await ensureDir(this.dir);
55
+ const content = await readJSON(this.file);
56
+ this.data = content || [];
57
+ }
58
+ this.loaded = true;
59
+ }
60
+ /**
61
+ * Persist collection data to disk.
62
+ * Uses a queue mechanism to batch multiple rapid modifications into a single write.
63
+ * If a save is already in progress, queues the next save to run after current one completes.
64
+ * In-memory collections skip disk writes entirely.
65
+ */
66
+ async save() {
67
+ if (this.inMemory) return;
68
+ if (this.saving) {
69
+ this.queueSave = true;
70
+ return;
71
+ }
72
+ this.saving = true;
73
+ try {
74
+ await writeJSON(this.file, this.data);
75
+ } finally {
76
+ this.saving = false;
77
+ if (this.queueSave) {
78
+ this.queueSave = false;
79
+ this.save();
80
+ }
81
+ }
82
+ }
83
+ /**
84
+ * Insert a single document into the collection.
85
+ * Automatically assigns a UUID for _id (if not provided) and timestamps for _created and _updated.
86
+ * Queues a save operation to persist the document.
87
+ *
88
+ * @param doc The document to insert, without system fields.
89
+ * @returns The inserted document with _id, _created, and _updated populated.
90
+ */
91
+ async insert(doc) {
92
+ await this.load();
93
+ const now = Date.now();
94
+ const newDoc = {
95
+ _id: doc._id || generateId(),
96
+ _created: now,
97
+ _updated: now,
98
+ ...doc,
99
+ };
100
+ this.data.push(newDoc);
101
+ this.save();
102
+ return newDoc;
103
+ }
104
+ /**
105
+ * Insert multiple documents into the collection atomically.
106
+ * All documents are assigned the same _created timestamp.
107
+ * Queues a single save operation to persist all documents.
108
+ *
109
+ * @param docs Array of documents to insert.
110
+ * @returns Array of inserted documents with all system fields populated.
111
+ */
112
+ async insertMany(docs) {
113
+ await this.load();
114
+ const now = Date.now();
115
+ const newDocs = docs.map((doc) => ({
116
+ _id: doc._id || generateId(),
117
+ _created: now,
118
+ _updated: now,
119
+ ...doc,
120
+ }));
121
+ this.data.push(...newDocs);
122
+ this.save();
123
+ return newDocs;
124
+ }
125
+ /**
126
+ * Find the first document matching the filter.
127
+ *
128
+ * @param filter Query filter to apply.
129
+ * @returns The first matching document, or null if no match found.
130
+ */
131
+ async findOne(filter) {
132
+ await this.load();
133
+ return this.data.find((doc) => matchFilter(doc, filter)) || null;
134
+ }
135
+ /**
136
+ * Find all documents matching the filter with optional sorting and pagination.
137
+ * Applies sort, skip, and limit in that order for correct pagination behavior.
138
+ *
139
+ * @param filter Query filter to apply.
140
+ * @param options Optional QueryOptions for sorting, skipping, and limiting results.
141
+ * @returns Array of matching documents (empty array if no matches).
142
+ */
143
+ async find(filter, options) {
144
+ await this.load();
145
+ let result = this.data.filter((doc) => matchFilter(doc, filter));
146
+ if (options?.sort) {
147
+ const sortKeys = Object.keys(options.sort);
148
+ result.sort((a, b) => {
149
+ for (const key of sortKeys) {
150
+ const dir = options.sort[key];
151
+ if (a[key] < b[key]) return -1 * dir;
152
+ if (a[key] > b[key]) return 1 * dir;
153
+ }
154
+ return 0;
155
+ });
156
+ }
157
+ if (options?.skip) {
158
+ result = result.slice(options.skip);
159
+ }
160
+ if (options?.limit) {
161
+ result = result.slice(0, options.limit);
162
+ }
163
+ return result;
164
+ }
165
+ /**
166
+ * Update document(s) matching the filter.
167
+ * Applies update operators atomically and updates the _updated timestamp.
168
+ * By default, updates only the first matching document. Set multi=true to update all.
169
+ *
170
+ * @param filter Query filter to select documents to update.
171
+ * @param update Update operators and values to apply.
172
+ * @param multi If false (default), updates only first match. If true, updates all matches.
173
+ * @returns Count of documents updated.
174
+ */
175
+ async update(filter, update, multi = false) {
176
+ await this.load();
177
+ let count = 0;
178
+ for (const doc of this.data) {
179
+ if (matchFilter(doc, filter)) {
180
+ applyUpdate(doc, update);
181
+ count++;
182
+ if (!multi) break;
183
+ }
184
+ }
185
+ if (count > 0) this.save();
186
+ return count;
187
+ }
188
+ /**
189
+ * Delete document(s) matching the filter.
190
+ * By default, deletes only the first matching document. Set multi=true to delete all.
191
+ *
192
+ * @param filter Query filter to select documents to delete.
193
+ * @param multi If false (default), deletes only first match. If true, deletes all matches.
194
+ * @returns Count of documents deleted.
195
+ */
196
+ async delete(filter, multi = false) {
197
+ await this.load();
198
+ const originalLen = this.data.length;
199
+ if (!multi) {
200
+ const index = this.data.findIndex((doc) => matchFilter(doc, filter));
201
+ if (index !== -1) {
202
+ this.data.splice(index, 1);
203
+ this.save();
204
+ return 1;
205
+ }
206
+ return 0;
207
+ } else {
208
+ this.data = this.data.filter((doc) => !matchFilter(doc, filter));
209
+ const deleted = originalLen - this.data.length;
210
+ if (deleted > 0) this.save();
211
+ return deleted;
212
+ }
213
+ }
214
+ /**
215
+ * Count documents matching the filter.
216
+ *
217
+ * @param filter Query filter to apply.
218
+ * @returns Number of documents matching the filter.
219
+ */
220
+ async count(filter) {
221
+ await this.load();
222
+ return this.data.filter((doc) => matchFilter(doc, filter)).length;
223
+ }
224
+ }
225
+ /**
226
+ * File-based database engine implementation.
227
+ * Stores collections as JSON files in the configured directory.
228
+ * Provides lazy collection initialization and in-memory option for testing.
229
+ */
230
+ export class JDBEngine {
231
+ config;
232
+ /** Cached collection instances. Created on demand and reused for subsequent accesses. */
233
+ collections = new Map();
234
+ /**
235
+ * Create a new database engine instance.
236
+ *
237
+ * @param config Configuration specifying storage root directory and memory mode.
238
+ */
239
+ constructor(config) {
240
+ this.config = config;
241
+ }
242
+ /**
243
+ * Establish database connection by ensuring the storage root directory exists.
244
+ * Creates the directory recursively if it doesn't exist.
245
+ */
246
+ async connect() {
247
+ await ensureDir(this.config.root);
248
+ }
249
+ /**
250
+ * Close database connection and clean up resources.
251
+ * Currently a no-op for file-based storage, but provided for compatibility with IDatabaseEngine interface.
252
+ * Future versions may flush pending writes or close file handles here.
253
+ */
254
+ async disconnect() {
255
+ // No-op for file based, maybe ensure all saves are flushed
256
+ }
257
+ /**
258
+ * Get or create a collection by name.
259
+ * Collections are cached after first access, so subsequent calls return the same instance.
260
+ * Uses lazy initialization: data is not loaded from disk until the collection is accessed.
261
+ *
262
+ * @template T Document type for the collection.
263
+ * @param name Unique name for the collection. Used to generate the .jdb filename.
264
+ * @returns Collection instance for CRUD operations.
265
+ */
266
+ collection(name) {
267
+ if (!this.collections.has(name)) {
268
+ this.collections.set(
269
+ name,
270
+ new JDBCollection(name, this.config.root, !!this.config.inMemory),
271
+ );
272
+ }
273
+ return this.collections.get(name);
274
+ }
275
+ }