@primate/core 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. package/lib/private/App.d.ts +263 -26
  2. package/lib/private/App.js +42 -14
  3. package/lib/private/Flags.d.ts +8 -4
  4. package/lib/private/Module.d.ts +4 -16
  5. package/lib/private/Module.js +1 -17
  6. package/lib/private/app/EnvSchema.d.ts +5 -0
  7. package/lib/private/app/EnvSchema.js +2 -0
  8. package/lib/private/app/Facade.browser.d.ts +11 -0
  9. package/lib/private/app/Facade.browser.js +19 -0
  10. package/lib/private/app/Facade.d.ts +272 -27
  11. package/lib/private/app/Facade.js +23 -0
  12. package/lib/private/build/client/index.js +8 -3
  13. package/lib/private/build/client/plugin/app-request.d.ts +4 -0
  14. package/lib/private/build/client/plugin/app-request.js +19 -0
  15. package/lib/private/build/client/plugin/view.d.ts +4 -0
  16. package/lib/private/build/client/plugin/view.js +13 -0
  17. package/lib/private/build/hook.d.ts +1 -2
  18. package/lib/private/build/hook.js +21 -16
  19. package/lib/private/build/index.d.ts +2 -1
  20. package/lib/private/build/index.js +20 -21
  21. package/lib/private/build/server/index.js +7 -9
  22. package/lib/private/build/server/plugin/app-request.d.ts +4 -0
  23. package/lib/private/build/server/plugin/app-request.js +19 -0
  24. package/lib/private/build/server/plugin/assets.js +1 -1
  25. package/lib/private/build/server/plugin/live-reload.js +9 -9
  26. package/lib/private/build/server/plugin/native-addons.js +4 -7
  27. package/lib/private/build/server/plugin/route.js +2 -2
  28. package/lib/private/build/server/plugin/store.js +9 -31
  29. package/lib/private/build/server/plugin/stores.js +11 -7
  30. package/lib/private/build/server/plugin/view.js +1 -1
  31. package/lib/private/build/shared/plugin/app-request.d.ts +4 -0
  32. package/lib/private/build/shared/plugin/app-request.js +19 -0
  33. package/lib/private/client/Data.d.ts +3 -2
  34. package/lib/private/{frontend → client}/Render.d.ts +1 -1
  35. package/lib/private/{frontend → client}/ViewResponse.d.ts +1 -1
  36. package/lib/private/client/app.js +1 -2
  37. package/lib/private/client/boot.d.ts +5 -0
  38. package/lib/private/client/boot.js +64 -0
  39. package/lib/private/client/create-form.d.ts +1 -0
  40. package/lib/private/client/create-form.js +19 -20
  41. package/lib/private/client/extract-issues.js +2 -1
  42. package/lib/private/client/http.d.ts +13 -0
  43. package/lib/private/client/http.js +57 -0
  44. package/lib/private/client/index.d.ts +23 -0
  45. package/lib/private/client/index.js +16 -0
  46. package/lib/private/client/navigate.d.ts +13 -0
  47. package/lib/private/client/navigate.js +67 -0
  48. package/lib/private/client/root.d.ts +9 -0
  49. package/lib/private/client/root.js +11 -0
  50. package/lib/private/client/submit.d.ts +2 -0
  51. package/lib/private/client/submit.js +41 -0
  52. package/lib/private/config/index.d.ts +7 -2
  53. package/lib/private/config/index.js +3 -2
  54. package/lib/private/config/schema.d.ts +82 -26
  55. package/lib/private/config/schema.js +17 -4
  56. package/lib/private/cookie.d.ts +12 -6
  57. package/lib/private/db/DB.d.ts +21 -5
  58. package/lib/private/db/DB.js +1 -0
  59. package/lib/private/db/MemoryDB.d.ts +2 -4
  60. package/lib/private/db/MemoryDB.js +40 -22
  61. package/lib/private/db/common.d.ts +7 -0
  62. package/lib/private/db/common.js +31 -0
  63. package/lib/private/db/errors.d.ts +104 -0
  64. package/lib/private/db/errors.js +237 -0
  65. package/lib/private/db/migrate/apply.d.ts +2 -0
  66. package/lib/private/db/migrate/apply.js +32 -0
  67. package/lib/private/db/migrate/bundle.d.ts +3 -0
  68. package/lib/private/db/migrate/bundle.js +22 -0
  69. package/lib/private/db/migrate/create.d.ts +2 -0
  70. package/lib/private/db/migrate/create.js +154 -0
  71. package/lib/private/db/migrate/index.d.ts +10 -0
  72. package/lib/private/db/migrate/index.js +6 -0
  73. package/lib/private/db/migrate/status.d.ts +2 -0
  74. package/lib/private/db/migrate/status.js +38 -0
  75. package/lib/private/db/migrate/store.d.ts +5 -0
  76. package/lib/private/db/migrate/store.js +33 -0
  77. package/lib/private/db/sql.js +3 -3
  78. package/lib/private/db/test.js +461 -95
  79. package/lib/private/errors.d.ts +88 -0
  80. package/lib/private/errors.js +211 -0
  81. package/lib/private/frontend.d.ts +72 -0
  82. package/lib/private/frontend.js +245 -0
  83. package/lib/private/i18n/Formatter.js +2 -2
  84. package/lib/private/i18n/errors.d.ts +16 -0
  85. package/lib/private/i18n/errors.js +27 -0
  86. package/lib/private/i18n/module.d.ts +3 -0
  87. package/lib/private/i18n/module.js +115 -0
  88. package/lib/private/i18n/schema.d.ts +10 -5
  89. package/lib/private/i18n/validate.js +5 -7
  90. package/lib/private/index.d.ts +14 -0
  91. package/lib/private/index.js +2 -0
  92. package/lib/private/log.js +6 -5
  93. package/lib/private/module/Setup.d.ts +21 -0
  94. package/lib/private/module/Setup.js +2 -0
  95. package/lib/private/module/create.d.ts +16 -0
  96. package/lib/private/module/create.js +28 -0
  97. package/lib/private/orm/ExtractSchema.d.ts +9 -0
  98. package/lib/private/orm/ExtractSchema.js +2 -0
  99. package/lib/private/orm/ForeignKey.d.ts +5 -2
  100. package/lib/private/orm/ForeignKey.js +3 -0
  101. package/lib/private/orm/PrimaryKey.d.ts +5 -3
  102. package/lib/private/orm/PrimaryKey.js +9 -6
  103. package/lib/private/orm/StoreInput.d.ts +10 -0
  104. package/lib/private/orm/StoreInput.js +2 -0
  105. package/lib/private/orm/key.d.ts +6 -6
  106. package/lib/private/orm/key.js +7 -3
  107. package/lib/private/orm/parse.d.ts +5 -4
  108. package/lib/private/orm/parse.js +2 -2
  109. package/lib/private/orm/relation.d.ts +2 -2
  110. package/lib/private/orm/{Store.d.ts → store.d.ts} +33 -17
  111. package/lib/private/orm/{Store.js → store.js} +91 -67
  112. package/lib/private/paths.js +3 -3
  113. package/lib/private/request/RequestBag.d.ts +4 -0
  114. package/lib/private/request/RequestBag.js +5 -2
  115. package/lib/private/request/RequestBody.d.ts +6 -9
  116. package/lib/private/request/RequestBody.js +49 -54
  117. package/lib/private/request/RequestFacade.d.ts +3 -8
  118. package/lib/private/request/RequestPublic.d.ts +9 -0
  119. package/lib/private/request/RequestPublic.js +2 -0
  120. package/lib/private/request/RequestView.d.ts +11 -0
  121. package/lib/private/request/RequestView.js +3 -0
  122. package/lib/private/request/handle.d.ts +4 -0
  123. package/lib/private/request/handle.js +18 -0
  124. package/lib/private/request/parse.js +1 -0
  125. package/lib/private/request/route.js +8 -9
  126. package/lib/private/request/router.js +21 -49
  127. package/lib/private/request/storage.d.ts +4 -0
  128. package/lib/private/request/storage.js +5 -0
  129. package/lib/private/response/ResponseFunction.d.ts +1 -1
  130. package/lib/private/response/binary.js +1 -1
  131. package/lib/private/response/error.d.ts +1 -1
  132. package/lib/private/response/error.js +1 -1
  133. package/lib/private/response/json.d.ts +1 -1
  134. package/lib/private/response/json.js +1 -1
  135. package/lib/private/response/redirect.d.ts +5 -5
  136. package/lib/private/response/redirect.js +8 -9
  137. package/lib/private/response/respond.js +9 -7
  138. package/lib/private/response/sse.d.ts +1 -1
  139. package/lib/private/response/sse.js +1 -1
  140. package/lib/private/response/text.d.ts +1 -1
  141. package/lib/private/response/text.js +1 -1
  142. package/lib/private/response/view.d.ts +1 -1
  143. package/lib/private/response/view.js +6 -13
  144. package/lib/private/response/ws.d.ts +1 -1
  145. package/lib/private/route/router.d.ts +3 -3
  146. package/lib/private/route/router.js +7 -10
  147. package/lib/private/serve/App.d.ts +6 -7
  148. package/lib/private/serve/App.js +52 -43
  149. package/lib/private/serve/Init.d.ts +2 -2
  150. package/lib/private/serve/dev-module.d.ts +2 -0
  151. package/lib/private/serve/dev-module.js +34 -0
  152. package/lib/private/serve/hook.d.ts +1 -2
  153. package/lib/private/serve/hook.js +2 -3
  154. package/lib/private/serve/index.d.ts +1 -1
  155. package/lib/private/serve/index.js +32 -2
  156. package/lib/private/server/TAG.d.ts +3 -0
  157. package/lib/private/server/TAG.js +2 -0
  158. package/lib/private/server/index.d.ts +5 -0
  159. package/lib/private/server/index.js +6 -0
  160. package/lib/private/session/SessionHandle.js +2 -1
  161. package/lib/private/session/index.d.ts +1 -1
  162. package/lib/private/session/module.d.ts +3 -0
  163. package/lib/private/session/module.js +114 -0
  164. package/lib/private/session/schema.d.ts +17 -9
  165. package/lib/private/session/schema.js +9 -5
  166. package/lib/private/target/Manager.js +6 -12
  167. package/lib/public/client.d.ts +2 -13
  168. package/lib/public/client.js +1 -9
  169. package/lib/public/db/errors.d.ts +2 -0
  170. package/lib/public/db/errors.js +2 -0
  171. package/lib/public/db/migrate.d.ts +2 -0
  172. package/lib/public/db/migrate.js +2 -0
  173. package/lib/public/db.d.ts +3 -3
  174. package/lib/public/frontend.d.ts +3 -0
  175. package/lib/public/frontend.js +2 -0
  176. package/lib/public/index.d.ts +2 -0
  177. package/lib/public/index.js +2 -0
  178. package/lib/public/orm/store.d.ts +2 -0
  179. package/lib/public/orm/store.js +2 -0
  180. package/lib/public/request/server.d.ts +5 -0
  181. package/lib/public/request/server.js +7 -0
  182. package/lib/public/response.d.ts +4 -4
  183. package/lib/public/server.d.ts +3 -0
  184. package/lib/public/server.js +2 -0
  185. package/package.json +30 -25
  186. package/lib/private/AppError.d.ts +0 -4
  187. package/lib/private/AppError.js +0 -8
  188. package/lib/private/backend/Module.d.ts +0 -18
  189. package/lib/private/backend/Module.js +0 -19
  190. package/lib/private/backend/TAG.d.ts +0 -3
  191. package/lib/private/backend/TAG.js +0 -2
  192. package/lib/private/build/server/plugin/db-default.d.ts +0 -4
  193. package/lib/private/build/server/plugin/db-default.js +0 -45
  194. package/lib/private/build/server/plugin/store-wrap.d.ts +0 -4
  195. package/lib/private/build/server/plugin/store-wrap.js +0 -33
  196. package/lib/private/client/spa/index.d.ts +0 -6
  197. package/lib/private/client/spa/index.js +0 -200
  198. package/lib/private/db/error.d.ts +0 -81
  199. package/lib/private/db/error.js +0 -199
  200. package/lib/private/db/symbol/wrap.d.ts +0 -3
  201. package/lib/private/db/symbol/wrap.js +0 -2
  202. package/lib/private/fail.d.ts +0 -3
  203. package/lib/private/fail.js +0 -5
  204. package/lib/private/frontend/Module.d.ts +0 -62
  205. package/lib/private/frontend/Module.js +0 -255
  206. package/lib/private/i18n/Module.d.ts +0 -16
  207. package/lib/private/i18n/Module.js +0 -133
  208. package/lib/private/module/BuildHook.d.ts +0 -5
  209. package/lib/private/module/BuildHook.js +0 -2
  210. package/lib/private/module/NextBuild.d.ts +0 -5
  211. package/lib/private/module/NextBuild.js +0 -2
  212. package/lib/private/module/NextServe.d.ts +0 -5
  213. package/lib/private/module/NextServe.js +0 -2
  214. package/lib/private/orm/Set.d.ts +0 -11
  215. package/lib/private/orm/Set.js +0 -2
  216. package/lib/private/orm/foreign.d.ts +0 -4
  217. package/lib/private/orm/foreign.js +0 -5
  218. package/lib/private/orm/primary.d.ts +0 -5
  219. package/lib/private/orm/primary.js +0 -5
  220. package/lib/private/orm/types.d.ts +0 -18
  221. package/lib/private/orm/types.js +0 -2
  222. package/lib/private/orm/wrap.d.ts +0 -5
  223. package/lib/private/orm/wrap.js +0 -5
  224. package/lib/private/reducer.d.ts +0 -24
  225. package/lib/private/reducer.js +0 -10
  226. package/lib/private/serve/module/Dev.d.ts +0 -11
  227. package/lib/private/serve/module/Dev.js +0 -32
  228. package/lib/private/serve/module/Handle.d.ts +0 -10
  229. package/lib/private/serve/module/Handle.js +0 -15
  230. package/lib/private/session/SessionModule.d.ts +0 -14
  231. package/lib/private/session/SessionModule.js +0 -122
  232. package/lib/public/App.d.ts +0 -2
  233. package/lib/public/App.js +0 -2
  234. package/lib/public/AppError.d.ts +0 -2
  235. package/lib/public/AppError.js +0 -2
  236. package/lib/public/BuildApp.d.ts +0 -2
  237. package/lib/public/BuildApp.js +0 -2
  238. package/lib/public/BuildHook.d.ts +0 -2
  239. package/lib/public/BuildHook.js +0 -2
  240. package/lib/public/Mode.d.ts +0 -2
  241. package/lib/public/Mode.js +0 -2
  242. package/lib/public/Module.d.ts +0 -2
  243. package/lib/public/Module.js +0 -2
  244. package/lib/public/Next.d.ts +0 -2
  245. package/lib/public/Next.js +0 -2
  246. package/lib/public/NextBuild.d.ts +0 -2
  247. package/lib/public/NextBuild.js +0 -2
  248. package/lib/public/NextHandle.d.ts +0 -2
  249. package/lib/public/NextHandle.js +0 -2
  250. package/lib/public/NextRoute.d.ts +0 -3
  251. package/lib/public/NextRoute.js +0 -2
  252. package/lib/public/NextServe.d.ts +0 -2
  253. package/lib/public/NextServe.js +0 -2
  254. package/lib/public/ServeApp.d.ts +0 -2
  255. package/lib/public/ServeApp.js +0 -2
  256. package/lib/public/Target.d.ts +0 -2
  257. package/lib/public/Target.js +0 -2
  258. package/lib/public/backend/Module.d.ts +0 -2
  259. package/lib/public/backend/Module.js +0 -2
  260. package/lib/public/backend/TAG.d.ts +0 -2
  261. package/lib/public/backend/TAG.js +0 -2
  262. package/lib/public/client/Data.d.ts +0 -2
  263. package/lib/public/client/Data.js +0 -2
  264. package/lib/public/client/spa.d.ts +0 -2
  265. package/lib/public/client/spa.js +0 -2
  266. package/lib/public/db/error.d.ts +0 -2
  267. package/lib/public/db/error.js +0 -2
  268. package/lib/public/fail.d.ts +0 -2
  269. package/lib/public/fail.js +0 -2
  270. package/lib/public/frontend/Module.d.ts +0 -2
  271. package/lib/public/frontend/Module.js +0 -2
  272. package/lib/public/frontend/Publish.d.ts +0 -2
  273. package/lib/public/frontend/Publish.js +0 -2
  274. package/lib/public/frontend/Render.d.ts +0 -2
  275. package/lib/public/frontend/Render.js +0 -2
  276. package/lib/public/frontend/ViewResponse.d.ts +0 -2
  277. package/lib/public/frontend/ViewResponse.js +0 -2
  278. package/lib/public/orm/Store.d.ts +0 -2
  279. package/lib/public/orm/Store.js +0 -2
  280. package/lib/public/orm/wrap.d.ts +0 -2
  281. package/lib/public/orm/wrap.js +0 -2
  282. package/lib/public/request.d.ts +0 -4
  283. package/lib/public/request.js +0 -2
  284. /package/lib/private/{frontend → client}/Publish.d.ts +0 -0
  285. /package/lib/private/{frontend → client}/Publish.js +0 -0
  286. /package/lib/private/{frontend → client}/Render.js +0 -0
  287. /package/lib/private/{frontend → client}/ServerData.d.ts +0 -0
  288. /package/lib/private/{frontend → client}/ServerData.js +0 -0
  289. /package/lib/private/{frontend → client}/ServerView.d.ts +0 -0
  290. /package/lib/private/{frontend → client}/ServerView.js +0 -0
  291. /package/lib/private/{frontend → client}/View.d.ts +0 -0
  292. /package/lib/private/{frontend → client}/View.js +0 -0
  293. /package/lib/private/{frontend → client}/ViewOptions.d.ts +0 -0
  294. /package/lib/private/{frontend → client}/ViewOptions.js +0 -0
  295. /package/lib/private/{frontend → client}/ViewResponse.js +0 -0
  296. /package/lib/private/client/{spa/storage.d.ts → storage.d.ts} +0 -0
  297. /package/lib/private/client/{spa/storage.js → storage.js} +0 -0
@@ -1,56 +1,28 @@
1
- import AppError from "#AppError";
2
- import fail from "#fail";
1
+ import E from "#errors";
3
2
  import FileRouter from "@rcompat/fs/FileRouter";
4
- const error_entries = Object.entries({
5
- DoubleRoute: "double route {0}, disambiguate routes",
6
- OptionalRoute: "optional route {0} may not be a directory",
7
- RestRoute: "rest route {0} may not be a directory",
8
- });
9
- const allowed = {
10
- re: /^[a-zA-Z0-9\-_+[\].]+$/,
11
- replacements: ["a-Z", "0-9", "-", "_", "+", "[", "]", "."],
12
- text: "letters ({1}), digits ({2}), {3}, {4}, {5}, {6}, {7}",
13
- };
3
+ const re = /^[a-zA-Z0-9\-_+[\].]+$/;
14
4
  const specials = ["error", "hook", "layout"];
15
- const _ = allowed.re.source.slice(1, -1);
16
5
  const p = /^(?:[^[\]]+|\[(?:\.{3})?[a-zA-Z0-9_]+\]|\[\[(?:\.{3})?[a-zA-Z0-9_]+\]\])$/;
17
6
  export default async (directory, extensions) => {
18
- try {
19
- const router = await FileRouter.load({
20
- directory: directory.toString(),
21
- extensions,
22
- specials: {
23
- error: { recursive: false },
24
- hook: { recursive: true },
25
- layout: { recursive: true },
26
- },
27
- });
28
- router.all().map(route => {
29
- const { path, segment } = route;
30
- if (!allowed.re.test(segment)) {
31
- const message = `route {0} may only contain ${allowed.text}`;
32
- throw fail(message, path, ...allowed.replacements);
33
- }
34
- if (segment.startsWith("+") && !specials.includes(segment.slice(1))) {
35
- throw fail("route {0} is not a valid special file", path);
36
- }
37
- if (!p.test(segment)) {
38
- throw fail("route {0} has an invalid parameter", path);
39
- }
40
- });
41
- return router;
42
- }
43
- catch (error) {
44
- if (error instanceof AppError) {
45
- throw error;
7
+ const router = await FileRouter.load({
8
+ directory: directory.toString(),
9
+ extensions,
10
+ specials: {
11
+ error: { recursive: false },
12
+ hook: { recursive: true },
13
+ layout: { recursive: true },
14
+ },
15
+ });
16
+ router.all().map(route => {
17
+ const { path, segment } = route;
18
+ if (!re.test(segment))
19
+ throw E.route_invalid_characters(path, re);
20
+ if (segment.startsWith("+") && !specials.includes(segment.slice(1))) {
21
+ throw E.route_invalid_special_file(path);
46
22
  }
47
- error_entries.forEach(([key, value]) => {
48
- if (key in FileRouter.Error) {
49
- throw new AppError(value, error.route);
50
- }
51
- });
52
- // rethrow original error
53
- throw error;
54
- }
23
+ if (!p.test(segment))
24
+ throw E.route_invalid_parameter(path, segment);
25
+ });
26
+ return router;
55
27
  };
56
28
  //# sourceMappingURL=router.js.map
@@ -0,0 +1,4 @@
1
+ import type RequestFacade from "#request/RequestFacade";
2
+ declare const _default: () => import("node:async_hooks").AsyncLocalStorage<RequestFacade>;
3
+ export default _default;
4
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1,5 @@
1
+ import io from "@rcompat/io";
2
+ import cache from "@rcompat/kv/cache";
3
+ const s = Symbol("primate.request");
4
+ export default () => cache.get(s, () => new io.async.Context());
5
+ //# sourceMappingURL=storage.js.map
@@ -1,4 +1,4 @@
1
- import type View from "#frontend/View";
1
+ import type View from "#client/View";
2
2
  import type RequestFacade from "#request/RequestFacade";
3
3
  import type ServeApp from "#serve/App";
4
4
  import type { Dict, MaybePromise } from "@rcompat/type";
@@ -1,5 +1,5 @@
1
1
  import Streamable from "@rcompat/fs/Streamable";
2
- import MIME from "@rcompat/http/mime";
2
+ import { MIME } from "@rcompat/http";
3
3
  import is from "@rcompat/is";
4
4
  const encodeRFC5987 = (s) => encodeURIComponent(s).replace(/['()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  import type ResponseFunction from "#response/ResponseFunction";
2
- import type ValidStatus from "@rcompat/http/ValidStatus";
2
+ import type { ValidStatus } from "@rcompat/http";
3
3
  type Options = {
4
4
  body?: string;
5
5
  page?: string;
@@ -1,5 +1,5 @@
1
1
  import location from "#location";
2
- import Status from "@rcompat/http/Status";
2
+ import { Status } from "@rcompat/http";
3
3
  /**
4
4
  * Render an error page.
5
5
  *
@@ -4,6 +4,6 @@
4
4
  * @param options response options
5
5
  * @return Response rendering function
6
6
  */
7
- declare const _default: (body: unknown, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type").MaybePromise<Response>;
7
+ declare const _default: (body: unknown, init?: ResponseInit) => (app: import("../index.js").ServeApp) => import("@rcompat/type").MaybePromise<Response>;
8
8
  export default _default;
9
9
  //# sourceMappingURL=json.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import response from "#response";
2
- import MIME from "@rcompat/http/mime";
2
+ import { MIME } from "@rcompat/http";
3
3
  /**
4
4
  * Issue a JSON response
5
5
  * @param body body object
@@ -1,11 +1,11 @@
1
1
  import type ResponseFunction from "#response/ResponseFunction";
2
2
  type Redirection = 300 | 301 | 302 | 303 | 304 | 307 | 308;
3
3
  /**
4
- * Redirect request
5
- * @param location location to redirect to
6
- * @param status redirection 3xx code
7
- * @return Response rendering function
8
- */
4
+ * Redirect request
5
+ * @param location location to redirect to
6
+ * @param status redirection 3xx code
7
+ * @return Response rendering function
8
+ */
9
9
  declare const _default: (location: string, status?: Redirection) => ResponseFunction;
10
10
  export default _default;
11
11
  //# sourceMappingURL=redirect.d.ts.map
@@ -1,4 +1,4 @@
1
- import Status from "@rcompat/http/Status";
1
+ import { Status } from "@rcompat/http";
2
2
  function hasCRLF(s) {
3
3
  return /[\r\n]/.test(s);
4
4
  }
@@ -22,9 +22,8 @@ function encodePathname(s) {
22
22
  .map((each, i) => i === 0 ? "" : encodeURIComponent(each)).join("/");
23
23
  }
24
24
  function toSearch(query) {
25
- if (!query) {
25
+ if (!query)
26
26
  return "";
27
- }
28
27
  const search = Object.entries(query)
29
28
  .filter(([, v]) => v !== null && v !== undefined)
30
29
  .reduce((params, [k, v]) => {
@@ -36,7 +35,7 @@ function toSearch(query) {
36
35
  }
37
36
  function toNormalized(relative, base) {
38
37
  // base -> URL resolution
39
- if (base) {
38
+ if (base !== undefined) {
40
39
  const url = new URL(relative, new URL(String(base)));
41
40
  return url.pathname + url.search;
42
41
  }
@@ -48,11 +47,11 @@ function toNormalized(relative, base) {
48
47
  return i === -1 ? relative : relative.slice(0, i);
49
48
  }
50
49
  /**
51
- * Redirect request
52
- * @param location location to redirect to
53
- * @param status redirection 3xx code
54
- * @return Response rendering function
55
- */
50
+ * Redirect request
51
+ * @param location location to redirect to
52
+ * @param status redirection 3xx code
53
+ * @return Response rendering function
54
+ */
56
55
  export default (location, status) =>
57
56
  // no body
58
57
  app => app.respond(null, {
@@ -1,14 +1,11 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
2
  import binary from "#response/binary";
3
3
  import json from "#response/json";
4
4
  import redirect from "#response/redirect";
5
5
  import text from "#response/text";
6
6
  import Streamable from "@rcompat/fs/Streamable";
7
- import Status from "@rcompat/http/Status";
7
+ import { Status } from "@rcompat/http";
8
8
  import is from "@rcompat/is";
9
- function invalid_body(body) {
10
- throw fail("invalid body {0} returned from route", body);
11
- }
12
9
  function match(m) {
13
10
  return m;
14
11
  }
@@ -22,7 +19,12 @@ const guesses = match([
22
19
  [is.array, json],
23
20
  [is.string, text],
24
21
  ]);
25
- const guess = (value) => guesses.find(([_if]) => _if(value))?.[1](value)
26
- ?? invalid_body(`${value}`);
22
+ function guess(value) {
23
+ const found = guesses.find(([_if]) => _if(value))?.[1](value);
24
+ if (found === undefined)
25
+ throw E.response_invalid_body(`${value}`);
26
+ return found;
27
+ }
28
+ ;
27
29
  export default (result) => typeof result === "function" ? result : guess(result);
28
30
  //# sourceMappingURL=respond.js.map
@@ -10,6 +10,6 @@ type Body = {
10
10
  * @param options response options
11
11
  * @return Response rendering function
12
12
  */
13
- declare const _default: (body: Body, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type").MaybePromise<Response>;
13
+ declare const _default: (body: Body, init?: ResponseInit) => (app: import("../index.js").ServeApp) => import("@rcompat/type").MaybePromise<Response>;
14
14
  export default _default;
15
15
  //# sourceMappingURL=sse.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import response from "#response";
2
- import MIME from "@rcompat/http/mime";
2
+ import { MIME } from "@rcompat/http";
3
3
  const encode = (input) => new TextEncoder().encode(input);
4
4
  const handle = (body) => new ReadableStream({
5
5
  cancel() {
@@ -4,6 +4,6 @@
4
4
  * @param options response options
5
5
  * @return Response rendering function
6
6
  */
7
- declare const _default: (body: string, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type").MaybePromise<Response>;
7
+ declare const _default: (body: string, init?: ResponseInit) => (app: import("../index.js").ServeApp) => import("@rcompat/type").MaybePromise<Response>;
8
8
  export default _default;
9
9
  //# sourceMappingURL=text.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import response from "#response";
2
2
  import fn from "@rcompat/fn";
3
- import MIME from "@rcompat/http/mime";
3
+ import { MIME } from "@rcompat/http";
4
4
  /**
5
5
  * Return a plaintext response
6
6
  * @param body plaintext body
@@ -1,4 +1,4 @@
1
- import type ViewOptions from "#frontend/ViewOptions";
1
+ import type ViewOptions from "#client/ViewOptions";
2
2
  import type ResponseFunction from "#response/ResponseFunction";
3
3
  import type { Dict } from "@rcompat/type";
4
4
  declare function view<Props>(component: (props: Props) => any, props: Props, options?: ViewOptions): ResponseFunction;
@@ -1,4 +1,4 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
2
  import fs from "@rcompat/fs";
3
3
  const extensions = ["extension", "fullExtension"];
4
4
  const backmap = {
@@ -17,14 +17,6 @@ const backmap = {
17
17
  tsx: "react",
18
18
  jsx: "react",
19
19
  };
20
- function no_frontend(view) {
21
- const extension = fs.ref(view).fullExtension.slice(1);
22
- const hasPkg = extension in backmap;
23
- const error = "No frontend for {0}";
24
- const fix = hasPkg ? ", did you configure {1}?" : "";
25
- const pkgname = hasPkg ? `@primate/${backmap[extension]}` : "";
26
- return fail(`${error}${fix}`, view, pkgname);
27
- }
28
20
  /**
29
21
  * Render a view component using a frontend for the given filename extension
30
22
  * @param view path to view
@@ -33,14 +25,15 @@ function no_frontend(view) {
33
25
  * @return Response rendering function
34
26
  */
35
27
  function view(name, props, options) {
36
- const _name = name;
28
+ const view_name = name;
37
29
  return async (app, transfer, request) => {
38
30
  const found_view = extensions
39
- .map(extension => app.frontends[fs.ref(_name)[extension]])
40
- .find(extension => extension !== undefined)?.(_name, props, options)(app, transfer, request);
31
+ .map(extension => app.frontends[fs.ref(view_name)[extension]])
32
+ .find(extension => extension !== undefined)?.(view_name, props, options)(app, transfer, request);
41
33
  if (found_view !== undefined)
42
34
  return found_view;
43
- throw no_frontend(_name);
35
+ const extension = fs.ref(view_name).fullExtension.slice(1);
36
+ throw E.frontend_missing(view_name, backmap[extension]);
44
37
  };
45
38
  }
46
39
  export default view;
@@ -1,5 +1,5 @@
1
1
  import type ResponseFunction from "#response/ResponseFunction";
2
- import type Actions from "@rcompat/http/Actions";
2
+ import type { Actions } from "@rcompat/http";
3
3
  declare const _default: (actions: Actions) => ResponseFunction;
4
4
  export default _default;
5
5
  //# sourceMappingURL=ws.d.ts.map
@@ -25,15 +25,15 @@ declare class Router {
25
25
  handler: RouteHandler;
26
26
  options: RouteOptions;
27
27
  } | undefined;
28
- delete?: {
28
+ post?: {
29
29
  handler: RouteHandler;
30
30
  options: RouteOptions;
31
31
  } | undefined;
32
- post?: {
32
+ put?: {
33
33
  handler: RouteHandler;
34
34
  options: RouteOptions;
35
35
  } | undefined;
36
- put?: {
36
+ delete?: {
37
37
  handler: RouteHandler;
38
38
  options: RouteOptions;
39
39
  } | undefined;
@@ -1,4 +1,4 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
2
  import assert from "@rcompat/assert";
3
3
  const stack = [];
4
4
  export const routes = stack;
@@ -18,9 +18,8 @@ class Router {
18
18
  assert.maybe.dict(options);
19
19
  assert.maybe.boolean(options?.parseBody);
20
20
  const active = assert.defined(this.active);
21
- if (is_hook_file(active)) {
22
- throw fail("route.{0} may not be used inside {1}; use hook(...) instead", verb, active);
23
- }
21
+ if (is_hook_file(active))
22
+ throw E.hook_route_functions_not_allowed(active);
24
23
  const _routes = this.#routes;
25
24
  if (!(active in _routes))
26
25
  _routes[active] = {};
@@ -29,18 +28,16 @@ class Router {
29
28
  addHook(fn) {
30
29
  assert.function(fn);
31
30
  const active = assert.defined(this.active);
32
- if (!is_hook_file(active)) {
33
- throw fail("hook(...) may only be used inside +hook files, got {0}", active);
34
- }
31
+ if (!is_hook_file(active))
32
+ throw E.hook_not_allowed(active);
35
33
  (this.#hooks[active] ??= []).push(fn);
36
34
  }
37
35
  getHooks(path) {
38
36
  return [...(this.#hooks[path] ?? [])];
39
37
  }
40
38
  verifyHook(path) {
41
- if ((this.#hooks[path] ?? []).length === 0) {
42
- throw fail("hook file {0} did not register any hooks (call hook(...))", path);
43
- }
39
+ if ((this.#hooks[path] ?? []).length === 0)
40
+ throw E.hook_unused(path);
44
41
  }
45
42
  get(path) {
46
43
  return { ...this.#routes[path] };
@@ -1,14 +1,14 @@
1
1
  import App from "#App";
2
2
  import type Asset from "#asset/Asset";
3
- import type ServerView from "#frontend/ServerView";
4
- import type ViewOptions from "#frontend/ViewOptions";
5
- import type ViewResponse from "#frontend/ViewResponse";
3
+ import type ServerView from "#client/ServerView";
4
+ import type ViewOptions from "#client/ViewOptions";
5
+ import type ViewResponse from "#client/ViewResponse";
6
6
  import type I18NConfig from "#i18n/Config";
7
7
  import type RequestFacade from "#request/RequestFacade";
8
8
  import type RouteHandler from "#route/Handler";
9
9
  import type ServeInit from "#serve/Init";
10
10
  import FileRouter from "@rcompat/fs/FileRouter";
11
- import type Actions from "@rcompat/http/Actions";
11
+ import type { Actions } from "@rcompat/http";
12
12
  import type { Dict } from "@rcompat/type";
13
13
  interface FullViewOptions extends ViewOptions {
14
14
  body: string;
@@ -24,11 +24,10 @@ export default class ServeApp extends App {
24
24
  constructor(rootfile: string, init: ServeInit);
25
25
  get secure(): boolean;
26
26
  get assets(): Asset[];
27
- get modules(): import("../Module.js").default[];
28
27
  get url(): string;
29
28
  get router(): FileRouter;
30
29
  get frontends(): {
31
- [x: string]: ViewResponse | undefined;
30
+ [k: string]: ViewResponse;
32
31
  };
33
32
  get stores(): Dict;
34
33
  get i18n(): I18NConfig | undefined;
@@ -43,7 +42,7 @@ export default class ServeApp extends App {
43
42
  media(content_type: string, response?: ResponseInit): ResponseInit;
44
43
  publish({ code, inline, src, type }: PublishOptions): Promise<void>;
45
44
  create_csp(): void;
46
- register(extension: string, viewFunction: ViewResponse): void;
45
+ frontend(extension: string, view_response: ViewResponse): void;
47
46
  page(name?: string): string;
48
47
  serve_assets(pathname: string): Promise<Response | undefined>;
49
48
  start(): Promise<void>;
@@ -1,25 +1,26 @@
1
1
  import App from "#App";
2
2
  import { s_config } from "#app/Facade";
3
- import fail from "#fail";
3
+ import E from "#errors";
4
4
  import hash from "#hash";
5
- import I18NModule from "#i18n/Module";
5
+ import i18n_module from "#i18n/module";
6
6
  import location from "#location";
7
7
  import log from "#log";
8
- import reducer from "#reducer";
8
+ import create from "#module/create";
9
+ import handle from "#request/handle";
9
10
  import parse from "#request/parse";
10
11
  import RequestBag from "#request/RequestBag";
11
12
  import RequestBody from "#request/RequestBody";
13
+ import route from "#request/route";
14
+ import request_storage from "#request/storage";
12
15
  import router from "#route/router";
13
- import DevModule from "#serve/module/Dev";
14
- import HandleModule from "#serve/module/Handle";
15
- import SessionModule from "#session/SessionModule";
16
+ import dev_module from "#serve/dev-module";
17
+ import session_module from "#session/module";
16
18
  import tags from "#tags";
17
19
  import assert from "@rcompat/assert";
18
20
  import fs from "@rcompat/fs";
19
21
  import FileRouter from "@rcompat/fs/FileRouter";
20
- import MIME from "@rcompat/http/mime";
22
+ import { MIME, Status } from "@rcompat/http";
21
23
  import serve from "@rcompat/http/serve";
22
- import Status from "@rcompat/http/Status";
23
24
  import is from "@rcompat/is";
24
25
  import utf8 from "@rcompat/string/utf8";
25
26
  import p from "pema";
@@ -59,9 +60,8 @@ export default class ServeApp extends App {
59
60
  #serve_assets;
60
61
  #pages;
61
62
  #stores;
62
- #frontends = {};
63
+ #frontends = new Map();
63
64
  #router;
64
- #builtins;
65
65
  #i18n_config;
66
66
  constructor(rootfile, init) {
67
67
  const dir = fs.ref(rootfile).directory;
@@ -76,7 +76,7 @@ export default class ServeApp extends App {
76
76
  this.#serve_assets = init.assets;
77
77
  this.#pages = init.pages;
78
78
  const http = this.#init.facade[s_config].http;
79
- this.#i18n_config = init.i18n_config;
79
+ this.#i18n_config = init.i18n;
80
80
  this.set(s_http, {
81
81
  host: http.host,
82
82
  port: http.port,
@@ -93,14 +93,35 @@ export default class ServeApp extends App {
93
93
  hook: { recursive: true },
94
94
  },
95
95
  }, init.routes.map(s => s[0]));
96
- this.#builtins = {
97
- dev: init.mode === "development" ? new DevModule(this) : undefined,
98
- handle: new HandleModule(this),
99
- session: init.session_config
100
- ? new SessionModule(this.secure, init.session_config)
101
- : undefined,
102
- i18n: init.i18n_config ? new I18NModule(init.i18n_config) : undefined,
103
- };
96
+ if (init.mode === "development")
97
+ this.register(dev_module());
98
+ const assets = this.serve_assets.bind(this);
99
+ const bound_route = (request) => route(this, request);
100
+ if (init.session !== undefined) {
101
+ this.register(session_module(init.session));
102
+ }
103
+ if (init.i18n !== undefined)
104
+ this.register(i18n_module(init.i18n));
105
+ this.register(create({
106
+ name: "builtin/handle",
107
+ setup({ onHandle }) {
108
+ onHandle(async (request) => {
109
+ const asset = await assets(request.url.pathname);
110
+ if (asset !== undefined)
111
+ return asset;
112
+ return new Promise((resolve, reject) => {
113
+ request_storage().run(request, async () => {
114
+ try {
115
+ resolve(await bound_route(request));
116
+ }
117
+ catch (e) {
118
+ reject(e);
119
+ }
120
+ });
121
+ });
122
+ });
123
+ },
124
+ }));
104
125
  }
105
126
  ;
106
127
  get secure() {
@@ -110,10 +131,6 @@ export default class ServeApp extends App {
110
131
  get assets() {
111
132
  return this.#assets;
112
133
  }
113
- get modules() {
114
- const { session, i18n } = this.#builtins;
115
- return [session, i18n, ...super.modules].filter(m => m !== undefined);
116
- }
117
134
  get url() {
118
135
  const { host, port } = this.config("http");
119
136
  return `http${this.secure ? "s" : ""}://${host}:${port}`;
@@ -123,7 +140,7 @@ export default class ServeApp extends App {
123
140
  return this.#router;
124
141
  }
125
142
  get frontends() {
126
- return { ...this.#frontends };
143
+ return Object.fromEntries(this.#frontends);
127
144
  }
128
145
  get stores() {
129
146
  return this.#stores;
@@ -134,14 +151,13 @@ export default class ServeApp extends App {
134
151
  loadView(name) {
135
152
  const f = fs.ref(name).path;
136
153
  const frontends = Object.keys(this.frontends);
137
- const extension = frontends.find(frontend => f.endsWith(frontend));
154
+ const extension = frontends.find(client => f.endsWith(client));
138
155
  const base = extension === undefined ? name : f.slice(0, -extension.length);
139
156
  const view = this.#views[base];
140
157
  if (view === undefined)
141
- throw fail("no view {0}", name);
142
- if (view.default === undefined) {
143
- throw fail("view {0} must export a default component", name);
144
- }
158
+ throw E.view_missing(name);
159
+ if (view.default === undefined)
160
+ throw E.view_missing_default_export(name);
145
161
  return view.default;
146
162
  }
147
163
  ;
@@ -223,11 +239,11 @@ export default class ServeApp extends App {
223
239
  }), { "script-src": [], "style-src": [] });
224
240
  }
225
241
  ;
226
- register(extension, viewFunction) {
227
- if (this.#frontends[extension] !== undefined) {
228
- throw fail("double file extension {0}", extension);
242
+ frontend(extension, view_response) {
243
+ if (this.#frontends.has(extension)) {
244
+ throw E.view_duplicate_extension(extension);
229
245
  }
230
- this.#frontends[extension] = viewFunction;
246
+ this.#frontends.set(extension, view_response);
231
247
  }
232
248
  ;
233
249
  page(name) {
@@ -313,15 +329,9 @@ export default class ServeApp extends App {
313
329
  };
314
330
  }));
315
331
  }
316
- const modules = [
317
- this.#builtins.dev,
318
- ...this.modules,
319
- this.#builtins.handle,
320
- ].filter(m => m !== undefined);
321
- const handle = (request) => reducer(modules, request, "handle");
322
332
  this.#server = await serve(async (request) => {
323
333
  try {
324
- return await handle(parse(request));
334
+ return await handle(this, parse(request));
325
335
  }
326
336
  catch (error) {
327
337
  log.error(error);
@@ -374,9 +384,8 @@ export default class ServeApp extends App {
374
384
  .flatMap(v => router.getHooks(v));
375
385
  const verbs = router.get(route.path);
376
386
  const route_path = verbs[verb];
377
- if (route_path === undefined) {
378
- throw fail("route {0} has no {1} verb", route.path, verb);
379
- }
387
+ if (route_path === undefined)
388
+ throw E.route_missing_verb(route.path, verb);
380
389
  const handler = route_path.handler;
381
390
  const parse_body = route_path.options.parseBody;
382
391
  const body = parse_body ?? this.config("request.body.parse")
@@ -26,8 +26,8 @@ type ServeInit = {
26
26
  mode: Mode;
27
27
  target: string;
28
28
  pages: Dict<string>;
29
- session_config?: SessionConfig;
30
- i18n_config?: I18NConfig;
29
+ session?: SessionConfig;
30
+ i18n?: I18NConfig;
31
31
  };
32
32
  export type { ServeInit as default };
33
33
  //# sourceMappingURL=Init.d.ts.map
@@ -0,0 +1,2 @@
1
+ export default function dev(): import("#module/create").Created;
2
+ //# sourceMappingURL=dev-module.d.ts.map