@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,4 +1,5 @@
1
1
  import Flags from "#Flags";
2
- declare const _default: (input: typeof Flags.input) => Promise<true | undefined>;
2
+ import type { FileRef } from "@rcompat/fs";
3
+ declare const _default: (root: FileRef, input: typeof Flags.input) => Promise<true | undefined>;
3
4
  export default _default;
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1,39 +1,38 @@
1
+ import { s_config } from "#app/Facade";
1
2
  import BuildApp from "#build/App";
2
3
  import bye from "#bye";
3
4
  import default_config from "#config/index";
4
- import fail from "#fail";
5
+ import E from "#errors";
5
6
  import Flags from "#Flags";
6
7
  import log from "#log";
7
8
  import dict from "@rcompat/dict";
8
- import fs from "@rcompat/fs";
9
- import { s_config } from "#app/Facade";
10
9
  const no_config = (config) => config === undefined || dict.empty(config);
11
- const find_config = async (root) => {
10
+ async function find_config(root) {
12
11
  const ts_config = root.join("config/app.ts");
13
12
  if (await ts_config.exists())
14
13
  return ts_config;
15
14
  const js_config = root.join("config/app.js");
16
15
  if (await js_config.exists())
17
16
  return js_config;
18
- };
19
- const get_config = async (root) => {
20
- const config = await find_config(root);
21
- if (config !== undefined) {
22
- try {
23
- const imported = (await config.import("default"))[s_config];
24
- if (no_config(imported))
25
- throw fail("empty config file at {0}", config);
26
- return imported;
27
- }
28
- catch (error) {
29
- throw fail("error in config file {0}", error);
30
- }
17
+ }
18
+ ;
19
+ async function get_config(root) {
20
+ const config_file = await find_config(root);
21
+ if (config_file === undefined)
22
+ return default_config()[s_config];
23
+ try {
24
+ const imported = (await config_file.import("default"))[s_config];
25
+ if (no_config(imported))
26
+ throw E.config_file_empty(config_file);
27
+ return imported;
31
28
  }
32
- return default_config();
33
- };
34
- export default async (input) => {
29
+ catch (error) {
30
+ throw E.config_file_error(config_file, error);
31
+ }
32
+ }
33
+ ;
34
+ export default async (root, input) => {
35
35
  try {
36
- const root = await fs.project.root();
37
36
  const flags = Flags.parse(input);
38
37
  const config = await get_config(root);
39
38
  const app = await new BuildApp(root, config, flags).init();
@@ -1,6 +1,5 @@
1
1
  import plugin_assets from "#build/server/plugin/assets";
2
2
  import plugin_config from "#build/server/plugin/config";
3
- import plugin_db_default from "#build/server/plugin/db-default";
4
3
  import plugin_frontend from "#build/server/plugin/frontend";
5
4
  import plugin_live_reload from "#build/server/plugin/live-reload";
6
5
  import plugin_native_addons from "#build/server/plugin/native-addons";
@@ -8,14 +7,13 @@ import plugin_node_imports from "#build/server/plugin/node-imports";
8
7
  import plugin_requires from "#build/server/plugin/requires";
9
8
  import plugin_roots from "#build/server/plugin/roots";
10
9
  import plugin_route from "#build/server/plugin/route";
11
- import plugin_store from "#build/server/plugin/store";
12
- import plugin_store_wrap from "#build/server/plugin/store-wrap";
13
10
  import plugin_stores from "#build/server/plugin/stores";
14
11
  import plugin_view from "#build/server/plugin/view";
15
12
  import plugin_views from "#build/server/plugin/views";
16
13
  import plugin_virtual_pages from "#build/server/plugin/virtual-pages";
17
14
  import plugin_virtual_routes from "#build/server/plugin/virtual-routes";
18
15
  import plugin_wasm from "#build/server/plugin/wasm";
16
+ import plugin_app_request from "#build/shared/plugin/app-request";
19
17
  import runtime from "@rcompat/runtime";
20
18
  import * as esbuild from "esbuild";
21
19
  const externals = {
@@ -32,9 +30,6 @@ export default async function build_server(app) {
32
30
  app.plugin("server", plugin_node_imports(app));
33
31
  app.plugin("server", plugin_frontend(app));
34
32
  app.plugin("server", plugin_view(app));
35
- app.plugin("server", plugin_store(app));
36
- app.plugin("server", plugin_store_wrap(app));
37
- app.plugin("server", plugin_db_default(app));
38
33
  if (app.mode === "development")
39
34
  app.plugin("server", plugin_live_reload(app));
40
35
  app.plugin("server", plugin_virtual_pages(app));
@@ -48,6 +43,9 @@ export default async function build_server(app) {
48
43
  app.plugin("server", plugin_requires(app));
49
44
  app.plugin("server", plugin_config(app));
50
45
  app.plugin("server", plugin_wasm(app));
46
+ app.plugin("server", plugin_app_request(app));
47
+ const runtime_name = runtime.name;
48
+ const tsconfig = app.root.join("tsconfig.json");
51
49
  const options = {
52
50
  entryPoints: [app.path.build.join("serve.js").path],
53
51
  outfile: app.path.build.join("server.js").path,
@@ -55,7 +53,7 @@ export default async function build_server(app) {
55
53
  platform: "node",
56
54
  format: "esm",
57
55
  packages: app.mode === "development" ? "external" : undefined,
58
- external: [...externals[runtime]],
56
+ external: [...externals[runtime_name]],
59
57
  loader: {
60
58
  ".json": "json",
61
59
  },
@@ -68,9 +66,9 @@ export default async function build_server(app) {
68
66
  nodePaths: [app.root.join("node_modules").path],
69
67
  resolveExtensions: app.extensions,
70
68
  absWorkingDir: app.root.path,
71
- tsconfig: app.root.join("tsconfig.json").path,
69
+ ...await tsconfig.exists() ? { tsconfig: tsconfig.path } : {},
72
70
  conditions: [
73
- ...conditions[runtime],
71
+ ...conditions[runtime_name],
74
72
  "module", "import", "runtime", "default",
75
73
  ...app.conditions
76
74
  ],
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_server_request(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=app-request.d.ts.map
@@ -0,0 +1,19 @@
1
+ export default function plugin_server_request(app) {
2
+ return {
3
+ name: "primate/server/app/request",
4
+ setup(build) {
5
+ build.onResolve({ filter: /^app:request$/ }, ({ importer }) => {
6
+ const frontend = [...app.frontends.entries()]
7
+ .find(([, exts]) => exts.some(ext => importer.endsWith(ext)));
8
+ return frontend !== undefined
9
+ ? { namespace: "request", path: frontend[0] }
10
+ : undefined;
11
+ });
12
+ build.onLoad({ filter: /.*/, namespace: "request" }, async ({ path }) => {
13
+ const contents = `export { default } from "@primate/${path}/request";`;
14
+ return { contents, resolveDir: app.root.path };
15
+ });
16
+ },
17
+ };
18
+ }
19
+ //# sourceMappingURL=app-request.js.map
@@ -1,5 +1,5 @@
1
1
  import location from "#location";
2
- import MIME from "@rcompat/http/mime";
2
+ import { MIME } from "@rcompat/http";
3
3
  function bytes2base64(bytes) {
4
4
  const chunk_size = 0x8000;
5
5
  let result = "";
@@ -1,4 +1,5 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
+ import is from "@rcompat/is";
2
3
  export default function plugin_server_live_reload(app) {
3
4
  let build_n = 0;
4
5
  let serve_app;
@@ -7,27 +8,26 @@ export default function plugin_server_live_reload(app) {
7
8
  setup(build) {
8
9
  build.onEnd(async (result) => {
9
10
  // don't do anything on errors
10
- if (result.errors.length)
11
+ if (result.errors.length > 0)
11
12
  return;
12
13
  // we expect a single bundled file
13
- const outFile = result.outputFiles?.[0];
14
- if (!outFile)
14
+ const out_file = result.outputFiles?.[0];
15
+ if (is.undefined(out_file))
15
16
  return;
16
17
  const filename = `server.${build_n}.js`;
17
18
  const s = app.path.build.join(filename);
18
- await s.write(outFile.text);
19
+ await s.write(out_file.text);
19
20
  try {
20
21
  // stop old app
21
- if (serve_app !== undefined)
22
+ if (is.defined(serve_app))
22
23
  serve_app.stop();
23
24
  serve_app = (await s.import()).default;
24
25
  const stamp = app.runpath("client", "server-stamp.js");
25
26
  await stamp.write(`export default ${build_n};\n`);
26
27
  build_n++;
27
28
  }
28
- catch (err) {
29
- fail("[primate/server/live-reload] failed to import {0}", filename);
30
- console.error(err);
29
+ catch (error) {
30
+ throw E.build_live_reload_failed(filename, error);
31
31
  }
32
32
  });
33
33
  },
@@ -1,4 +1,4 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
2
  import log from "#log";
3
3
  import fs from "@rcompat/fs";
4
4
  import { createRequire } from "node:module";
@@ -30,12 +30,9 @@ export default function plugin_server_store(app) {
30
30
  const platform = process.platform;
31
31
  const arch = process.arch;
32
32
  let node_file = node_files.find(f => f.path.includes(`${platform}-${arch}`));
33
- if (!node_file) {
34
- node_file = node_files.find(f => f.path.includes(platform));
35
- }
36
- if (!node_file) {
37
- throw fail("could not find matching binary addon");
38
- }
33
+ node_file ??= node_files.find(f => f.path.includes(platform));
34
+ if (node_file === undefined)
35
+ throw E.build_missing_binary_addon();
39
36
  const addon_name = node_files[0].name;
40
37
  const dest = app.path.build.join("native", addon_name);
41
38
  await dest.directory.create();
@@ -1,4 +1,4 @@
1
- import fail from "#fail";
1
+ import E from "#errors";
2
2
  import wrap from "#route/wrap";
3
3
  import fs from "@rcompat/fs";
4
4
  const contents = "export default {};";
@@ -26,7 +26,7 @@ export default function plugin_server_route(app) {
26
26
  }
27
27
  }
28
28
  if (!file || !extension) {
29
- throw fail(`cannot find route source for "${relative}" under ${path_routes.path}`);
29
+ throw E.build_missing_route(relative, path_routes);
30
30
  }
31
31
  // normalise "routes/foo.ext" -> "foo" for router
32
32
  const relative_from_routes = file.path.split("routes").pop();
@@ -3,39 +3,17 @@ export default function plugin_server_store(app) {
3
3
  return {
4
4
  name: "primate/server/store",
5
5
  setup(build) {
6
- build.onResolve({ filter: /^app:store\// }, args => {
7
- const name = args.path.slice("app:store/".length).replace(/\.(js|ts)$/, "");
8
- return { path: name, namespace: "primate-store-wrapper" };
9
- });
10
- build.onLoad({ filter: /.*/, namespace: "primate-store-wrapper" }, args => {
11
- const name = args.path;
12
- return {
13
- contents: `
14
- import db from "app:db";
15
- import wrap from "primate/orm/wrap";
16
- import schema from "store:${name}";
17
- export default wrap("${name}", schema, db);
18
- `,
19
- loader: "js",
20
- resolveDir: app.path.stores.path,
21
- };
22
- });
23
- build.onResolve({ filter: /^store:/ }, async (args) => {
24
- const name = args.path.slice("store:".length);
25
- for (const ext of app.extensions) {
26
- const file = fs.ref(`${app.path.stores.path}/${name}${ext}`);
27
- if (await file.exists()) {
28
- // special namespace to bypass auto-wrap
29
- return { path: file.path, namespace: "primate-store-raw" };
30
- }
31
- }
32
- return null;
33
- });
34
- build.onLoad({ filter: /.*/, namespace: "primate-store-raw" }, async (args) => {
6
+ build.onLoad({ filter: /.*/ }, async (args) => {
7
+ if (args.namespace !== "file")
8
+ return null;
9
+ if (!/\.([tj]s)$/.test(args.path))
10
+ return null;
35
11
  const file = fs.ref(args.path);
36
- const source = await file.text();
12
+ const stores_root = app.path.stores.path;
13
+ if (!file.path.startsWith(stores_root + "/"))
14
+ return null;
37
15
  return {
38
- contents: source,
16
+ contents: await file.text(),
39
17
  loader: args.path.endsWith(".ts") ? "ts" : "js",
40
18
  resolveDir: file.directory.path,
41
19
  watchFiles: [file.path],
@@ -8,14 +8,18 @@ export default function plugin_server_stores(app) {
8
8
  return { path: "stores-virtual", namespace: "primate-stores" };
9
9
  });
10
10
  build.onLoad({ filter: /.*/, namespace: "primate-stores" }, async () => {
11
- const stores = await Promise.all((await base.files({ recursive: true, filter: /\.[jt]s$/ }))
12
- .map(async (path) => `${path}`.replace(base.toString(), _ => "")));
11
+ const files = await base.files({ recursive: true, filter: /\.[jt]s$/ });
13
12
  const contents = `
14
- const stores = {};
15
- ${stores.map(path => path.slice(1, -".js".length)).map((bare, i) => `import * as store${i} from "${fs.webpath(`app:store/${bare}`)}";
16
- stores["${fs.webpath(bare)}"] = store${i}.default;`).join("\n")}
17
- export default stores;
18
- `;
13
+ const stores = {};
14
+ ${files.map((file, i) => {
15
+ const bare = fs.webpath(`${file}`
16
+ .replace(base.toString(), "")
17
+ .replace(/\.[jt]s$/, "").slice(1));
18
+ return `import * as store${i} from "${file}";
19
+ stores["${bare}"] = store${i}.default;`;
20
+ }).join("\n")}
21
+ export default stores;
22
+ `;
19
23
  return { contents, loader: "js", resolveDir: app.root.path };
20
24
  });
21
25
  },
@@ -50,7 +50,7 @@ export default function plugin_server_view(app) {
50
50
  build.onLoad({ filter: /.*/, namespace: "primate-view-original" }, async (args) => {
51
51
  const file = fs.ref(args.path);
52
52
  const binder = app.binder(file);
53
- if (!binder)
53
+ if (binder === undefined)
54
54
  return null;
55
55
  const contents = await binder(file, {
56
56
  build: { id: app.id },
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_shared_app_request(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=app-request.d.ts.map
@@ -0,0 +1,19 @@
1
+ export default function plugin_shared_app_request(app) {
2
+ return {
3
+ name: "primate/shared/app/request",
4
+ setup(build) {
5
+ build.onResolve({ filter: /^app:/ }, ({ path, importer }) => {
6
+ const framework = path.slice(4);
7
+ const exts = app.frontends.get(framework);
8
+ return exts?.some(ext => importer.endsWith(ext))
9
+ ? { namespace: "app-frontend", path: framework }
10
+ : undefined;
11
+ });
12
+ build.onLoad({ filter: /.*/, namespace: "app-frontend" }, async ({ path }) => {
13
+ const contents = `export * from "@primate/${path}/app";`;
14
+ return { contents, resolveDir: app.root.path };
15
+ });
16
+ },
17
+ };
18
+ }
19
+ //# sourceMappingURL=app-request.js.map
@@ -1,8 +1,9 @@
1
- import type { Dict } from "@rcompat/type";
2
1
  import type Mode from "#Mode";
2
+ import type RequestView from "#request/RequestView";
3
+ import type { Dict } from "@rcompat/type";
3
4
  type ClientData<T extends Dict = Dict> = {
4
5
  view: string;
5
- request: Dict;
6
+ request: RequestView;
6
7
  spa: boolean;
7
8
  ssr: boolean;
8
9
  mode: Mode;
@@ -2,7 +2,7 @@ import type { Dict, MaybePromise } from "@rcompat/type";
2
2
  type Render<V = unknown> = (view: V, props: Dict) => MaybePromise<{
3
3
  body: string;
4
4
  head?: string;
5
- headers?: Record<string, string>;
5
+ headers?: Dict<string>;
6
6
  }>;
7
7
  export type { Render as default };
8
8
  //# sourceMappingURL=Render.d.ts.map
@@ -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
  type View = (name: string, props?: Dict, options?: ViewOptions) => ResponseFunction;
@@ -13,6 +13,5 @@ class ClientApp {
13
13
  }
14
14
  }
15
15
  }
16
- const app = new ClientApp();
17
- app.start();
16
+ new ClientApp().start();
18
17
  //# sourceMappingURL=app.js.map
@@ -0,0 +1,5 @@
1
+ import type { Updater } from "#client/root";
2
+ import type { Dict } from "@rcompat/type";
3
+ declare const _default: <T extends Dict>(u: Updater<T>) => void;
4
+ export default _default;
5
+ //# sourceMappingURL=boot.d.ts.map
@@ -0,0 +1,64 @@
1
+ import navigate from "#client/navigate";
2
+ import root from "#client/root";
3
+ import storage from "#client/storage";
4
+ import submit from "#client/submit";
5
+ import { MIME } from "@rcompat/http";
6
+ export default (u) => {
7
+ root.set(u);
8
+ const { location, history } = globalThis;
9
+ if (document.contentType === "application/json") {
10
+ location.reload();
11
+ return;
12
+ }
13
+ globalThis.addEventListener("pageshow", event => {
14
+ if (event.persisted)
15
+ location.reload();
16
+ });
17
+ globalThis.addEventListener("load", _ => {
18
+ history.scrollRestoration = "manual";
19
+ if (location.hash !== "")
20
+ navigate.scroll_hash(location.hash);
21
+ });
22
+ globalThis.addEventListener("beforeunload", _ => {
23
+ history.scrollRestoration = "auto";
24
+ });
25
+ globalThis.addEventListener("popstate", () => {
26
+ const state = storage.peek() ?? { scrollTop: 0 };
27
+ const { pathname } = location;
28
+ let { scrollTop } = state;
29
+ if (state.stop) {
30
+ storage.back();
31
+ state.hash
32
+ ? navigate.scroll_hash(state.hash)
33
+ : globalThis.scrollTo(0, state.scrollTop);
34
+ return;
35
+ }
36
+ const back = state.pathname === pathname;
37
+ back ? storage.back() : (scrollTop = storage.forward().scrollTop);
38
+ navigate.goto(globalThis.location, false, () => globalThis.scrollTo(0, scrollTop ?? 0));
39
+ });
40
+ globalThis.addEventListener("click", event => {
41
+ const target = event.target.closest("a");
42
+ if (target?.tagName === "A" && target.href !== "") {
43
+ navigate.go(target.href, event);
44
+ }
45
+ });
46
+ globalThis.addEventListener("submit", async (event) => {
47
+ event.preventDefault();
48
+ const target = event.target;
49
+ const { enctype } = target;
50
+ const action = target.action ?? location.pathname;
51
+ const url = new URL(action);
52
+ const data = new FormData(target);
53
+ const form = enctype === MIME.MULTIPART_FORM_DATA
54
+ ? data
55
+ : new URLSearchParams(data);
56
+ try {
57
+ await submit(url.pathname, form, target.method);
58
+ }
59
+ catch (error) {
60
+ console.warn(error);
61
+ }
62
+ });
63
+ };
64
+ //# sourceMappingURL=boot.js.map
@@ -8,6 +8,7 @@ type FormErrors = {
8
8
  type FormSnapshot = {
9
9
  id: FormId;
10
10
  submitting: boolean;
11
+ submitted: boolean;
11
12
  errors: FormErrors;
12
13
  };
13
14
  export type FormView = FormSnapshot & {
@@ -1,4 +1,5 @@
1
1
  import extract_issues from "#client/extract-issues";
2
+ import submit from "#client/submit";
2
3
  function decode_pointer_segment(segment) {
3
4
  // decode JSON Pointer: ~1 -> /, ~0 -> ~
4
5
  return segment.replace(/~1/g, "/").replace(/~0/g, "~");
@@ -25,6 +26,7 @@ export default function createForm(init) {
25
26
  let snapshot = {
26
27
  id,
27
28
  submitting: false,
29
+ submitted: false,
28
30
  errors: { form: [], fields: {} },
29
31
  };
30
32
  const subscribers = new Set();
@@ -37,41 +39,42 @@ export default function createForm(init) {
37
39
  publish();
38
40
  }
39
41
  function setErrors(issues) {
40
- const byField = {};
41
- const formErrors = [];
42
+ const by_field = {};
43
+ const form_errors = [];
42
44
  for (const issue of issues) {
43
45
  const path = issue.path;
44
46
  // no path or empty string -> form-level error
45
- if (!path) {
46
- formErrors.push(issue.message);
47
+ if (path === undefined) {
48
+ form_errors.push(issue.message);
47
49
  continue;
48
50
  }
49
51
  const key = pointer_to_fieldname(path);
50
52
  // if normalizes to empty (e.g. "/"), treat as form-level
51
- if (!key) {
52
- formErrors.push(issue.message);
53
+ if (key.length === 0) {
54
+ form_errors.push(issue.message);
53
55
  continue;
54
56
  }
55
- (byField[key] ??= []).push(issue.message);
57
+ (by_field[key] ??= []).push(issue.message);
56
58
  }
57
59
  snapshot = {
58
60
  ...snapshot,
61
+ submitted: false,
59
62
  errors: {
60
- form: formErrors,
61
- fields: byField,
63
+ form: form_errors,
64
+ fields: by_field,
62
65
  },
63
66
  };
64
67
  publish();
65
68
  }
66
- async function submit(event) {
67
- if (event) {
69
+ async function submit_form(event) {
70
+ if (event !== undefined) {
68
71
  event.preventDefault();
69
72
  event.stopPropagation();
70
73
  }
71
74
  const form_element = event?.currentTarget ??
72
75
  document.getElementById(id);
73
76
  // no form element
74
- if (!form_element)
77
+ if (form_element === null)
75
78
  return;
76
79
  const method = init.method
77
80
  ?? form_element.method.toUpperCase()
@@ -80,15 +83,11 @@ export default function createForm(init) {
80
83
  const form_data = new FormData(form_element);
81
84
  setSubmitting(true);
82
85
  try {
83
- const response = await fetch(url, {
84
- method,
85
- body: form_data,
86
- headers: init.headers,
87
- });
86
+ const response = await submit(url, form_data, method);
88
87
  if (response.ok) {
89
88
  // on success: clear errors, let the app decide what to do next
90
89
  // (redirect/reload)
91
- snapshot = { ...snapshot, errors: { form: [], fields: {} } };
90
+ snapshot = { ...snapshot, submitted: true, errors: { form: [], fields: {} } };
92
91
  publish();
93
92
  return;
94
93
  }
@@ -98,7 +97,7 @@ export default function createForm(init) {
98
97
  }
99
98
  catch (error) {
100
99
  // network error
101
- setErrors([{ message: error.message, path: "" }]);
100
+ setErrors([{ type: "network_error", message: error.message, path: "" }]);
102
101
  }
103
102
  finally {
104
103
  setSubmitting(false);
@@ -115,7 +114,7 @@ export default function createForm(init) {
115
114
  return {
116
115
  subscribe,
117
116
  read,
118
- submit,
117
+ submit: submit_form,
119
118
  get id() {
120
119
  return snapshot.id;
121
120
  },
@@ -2,6 +2,7 @@ export default function extractIssues(payload, defaultPath = "") {
2
2
  // scalar: { message, messages }
3
3
  if ("messages" in payload) {
4
4
  return payload.messages.map(m => ({
5
+ type: payload.type,
5
6
  message: m,
6
7
  // for forms, defaultPath is "", but Issue.path expects a JSONPointer
7
8
  // so we cast here; form-level errors are handled separately anyway
@@ -12,7 +13,7 @@ export default function extractIssues(payload, defaultPath = "") {
12
13
  const issues = [];
13
14
  for (const [path, bundle] of Object.entries(payload)) {
14
15
  for (const message of bundle.messages) {
15
- issues.push({ message, path: path });
16
+ issues.push({ type: bundle.type, message, path: path });
16
17
  }
17
18
  }
18
19
  return issues;
@@ -0,0 +1,13 @@
1
+ declare function refetch(input: string | URL, init?: RequestInit, max_hops?: number): Promise<{
2
+ requested: URL;
3
+ response: Response;
4
+ }>;
5
+ declare function is_json(response: Response): boolean;
6
+ declare function submit(pathname: string, body: any, method: string): Promise<Response>;
7
+ declare const http: {
8
+ refetch: typeof refetch;
9
+ is_json: typeof is_json;
10
+ submit: typeof submit;
11
+ };
12
+ export default http;
13
+ //# sourceMappingURL=http.d.ts.map