@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
@@ -0,0 +1,57 @@
1
+ import { MIME } from "@rcompat/http";
2
+ const sameorigin = (url) => url.origin === globalThis.location.origin;
3
+ const get_location = (response, base) => {
4
+ if (response.type === "opaqueredirect")
5
+ return null;
6
+ const location = response.headers.get("Location");
7
+ return location !== null ? new URL(location, base) : null;
8
+ };
9
+ async function refetch(input, init = {}, max_hops = 5) {
10
+ let url = new URL(input.toString(), globalThis.location.href);
11
+ const method = (init.method ?? "GET").toUpperCase();
12
+ let hops = 0;
13
+ if (method !== "GET") {
14
+ const response = await fetch(url.pathname + url.search, {
15
+ ...init, redirect: "follow",
16
+ });
17
+ return { requested: new URL(response.url), response };
18
+ }
19
+ while (hops < max_hops) {
20
+ const response = await fetch(url.pathname + url.search, {
21
+ ...init, redirect: "manual",
22
+ });
23
+ if (response.type === "opaqueredirect")
24
+ return { requested: url, response };
25
+ const location = get_location(response, url.toString());
26
+ if (location !== null && response.status >= 300 && response.status < 400) {
27
+ if (!sameorigin(location))
28
+ return { requested: url, response };
29
+ url = location;
30
+ hops++;
31
+ continue;
32
+ }
33
+ return { requested: url, response };
34
+ }
35
+ throw new Error("Too many redirects");
36
+ }
37
+ function is_json(response) {
38
+ const raw = response.headers.get("content-type") ?? "";
39
+ return raw.split(";")[0].trim() === MIME.APPLICATION_JSON;
40
+ }
41
+ async function submit(pathname, body, method) {
42
+ const { requested, response } = await refetch(pathname, { body, method });
43
+ if (is_json(response)) {
44
+ history.replaceState({}, "", requested.pathname + requested.search);
45
+ }
46
+ else {
47
+ globalThis.location.assign(requested.toString());
48
+ }
49
+ return response;
50
+ }
51
+ const http = {
52
+ refetch,
53
+ is_json,
54
+ submit,
55
+ };
56
+ export default http;
57
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1,23 @@
1
+ import type { FormInit, FormView } from "#client/create-form";
2
+ import createForm from "#client/create-form";
3
+ import type Data from "#client/Data";
4
+ import type Publish from "#client/Publish";
5
+ import type Render from "#client/Render";
6
+ import submit from "#client/submit";
7
+ import toValidated from "#client/to-validated";
8
+ import validateField from "#client/validate-field";
9
+ import type ValidateInit from "#client/ValidateInit";
10
+ import type ValidateUpdater from "#client/ValidateUpdater";
11
+ import type ValidationError from "#client/ValidationError";
12
+ import type ViewResponse from "#client/ViewResponse";
13
+ declare const client: {
14
+ boot: <T extends import("@rcompat/type").Dict>(u: import("./root.js").Updater<T>) => void;
15
+ navigate: (href: string, event?: Event) => Promise<void>;
16
+ submit: typeof submit;
17
+ createForm: typeof createForm;
18
+ validateField: typeof validateField;
19
+ toValidated: typeof toValidated;
20
+ };
21
+ export default client;
22
+ export type { Data, FormInit, FormView, Publish, Render, ValidateInit, ValidateUpdater, ValidationError, ViewResponse, };
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ import boot from "#client/boot";
2
+ import createForm from "#client/create-form";
3
+ import navigate from "#client/navigate";
4
+ import submit from "#client/submit";
5
+ import toValidated from "#client/to-validated";
6
+ import validateField from "#client/validate-field";
7
+ const client = {
8
+ boot,
9
+ navigate: navigate.go,
10
+ submit,
11
+ createForm,
12
+ validateField,
13
+ toValidated,
14
+ };
15
+ export default client;
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,13 @@
1
+ type Location = {
2
+ hash: string;
3
+ pathname: string;
4
+ };
5
+ declare function goto(target: Location, state?: boolean, after?: () => void): Promise<void>;
6
+ declare function go(href: string, event?: Event): Promise<void>;
7
+ declare const navigate: {
8
+ go: typeof go;
9
+ goto: typeof goto;
10
+ scroll_hash: (hash: string) => void;
11
+ };
12
+ export default navigate;
13
+ //# sourceMappingURL=navigate.d.ts.map
@@ -0,0 +1,67 @@
1
+ import http from "#client/http";
2
+ import root from "#client/root";
3
+ import storage from "#client/storage";
4
+ import { MIME } from "@rcompat/http";
5
+ const headers = {
6
+ Accept: MIME.APPLICATION_JSON,
7
+ };
8
+ const get_by_id_or_name = (name) => document.getElementById(name) ?? document.getElementsByName(name)[0];
9
+ const scroll_hash = (hash) => {
10
+ if (hash === "") {
11
+ globalThis.scrollTo(0, 0);
12
+ }
13
+ else {
14
+ get_by_id_or_name(hash.slice(1)).scrollIntoView();
15
+ }
16
+ };
17
+ async function goto(target, state = false, after) {
18
+ try {
19
+ const { scrollTop } = globalThis.document.scrollingElement;
20
+ const { location } = globalThis;
21
+ const { requested, response } = await http.refetch(target.pathname, { headers });
22
+ if (http.is_json(response)) {
23
+ if (response.ok)
24
+ root.update(await response.json());
25
+ if (state) {
26
+ storage.new({ hash: location.hash, pathname: location.pathname, scrollTop });
27
+ history.pushState({}, "", `${target.pathname}${target.hash}`);
28
+ }
29
+ after?.();
30
+ return;
31
+ }
32
+ const dest = response.type !== "opaqueredirect"
33
+ ? requested.toString() + target.hash
34
+ : new URL(target.pathname + target.hash, location.href).toString();
35
+ location.assign(dest);
36
+ }
37
+ catch (error) {
38
+ console.warn(error);
39
+ }
40
+ }
41
+ async function go(href, event) {
42
+ const url = new URL(href);
43
+ const { hash, pathname } = url;
44
+ const { location } = globalThis;
45
+ if (url.host === location.host) {
46
+ event?.preventDefault();
47
+ if (location.pathname !== pathname) {
48
+ await goto(url, true, () => {
49
+ scroll_hash(hash);
50
+ globalThis.dispatchEvent(new Event("updated"));
51
+ });
52
+ }
53
+ if (location.hash !== hash) {
54
+ const { scrollTop } = globalThis.document.scrollingElement;
55
+ storage.new({ hash: location.hash, pathname: location.pathname, scrollTop, stop: true });
56
+ history.pushState(null, "", `${location.pathname}${hash}`);
57
+ scroll_hash(hash);
58
+ }
59
+ }
60
+ }
61
+ const navigate = {
62
+ go,
63
+ goto,
64
+ scroll_hash,
65
+ };
66
+ export default navigate;
67
+ //# sourceMappingURL=navigate.js.map
@@ -0,0 +1,9 @@
1
+ import type ClientData from "#client/Data";
2
+ import type { Dict } from "@rcompat/type";
3
+ export type Updater<T extends Dict> = (json: ClientData<T>, after?: () => void) => void;
4
+ declare const root: {
5
+ set(updater: Updater<any>): void;
6
+ update(data: any, after?: () => void): void;
7
+ };
8
+ export default root;
9
+ //# sourceMappingURL=root.d.ts.map
@@ -0,0 +1,11 @@
1
+ let current;
2
+ const root = {
3
+ set(updater) {
4
+ current = updater;
5
+ },
6
+ update(data, after) {
7
+ current(data, after);
8
+ },
9
+ };
10
+ export default root;
11
+ //# sourceMappingURL=root.js.map
@@ -0,0 +1,2 @@
1
+ export default function submit(pathname: string, body: any, method: string): Promise<Response>;
2
+ //# sourceMappingURL=submit.d.ts.map
@@ -0,0 +1,41 @@
1
+ import http from "#client/http";
2
+ import root from "#client/root";
3
+ import storage from "#client/storage";
4
+ import { MIME } from "@rcompat/http";
5
+ const headers = {
6
+ Accept: MIME.APPLICATION_JSON,
7
+ };
8
+ export default async function submit(pathname, body, method) {
9
+ const { requested, response } = await http.refetch(pathname, {
10
+ body, headers, method,
11
+ });
12
+ if (response.redirected) {
13
+ const { location, document, history } = globalThis;
14
+ const scrollTop = document.scrollingElement?.scrollTop ?? 0;
15
+ if (http.is_json(response))
16
+ root.update(await response.json());
17
+ storage.new({
18
+ hash: location.hash,
19
+ pathname: location.pathname,
20
+ scrollTop,
21
+ });
22
+ const url = new URL(response.url);
23
+ history.pushState({}, "", url.pathname + url.search);
24
+ return response;
25
+ }
26
+ if (http.is_json(response)) {
27
+ if (response.ok) {
28
+ root.update(await response.json());
29
+ history.replaceState({}, "", requested.pathname + requested.search);
30
+ }
31
+ return response;
32
+ }
33
+ if (response.status === 204)
34
+ return response;
35
+ const target = response.type !== "opaqueredirect"
36
+ ? requested.toString()
37
+ : new URL(pathname, globalThis.location.href).toString();
38
+ globalThis.location.assign(target);
39
+ return response;
40
+ }
41
+ //# sourceMappingURL=submit.js.map
@@ -1,5 +1,10 @@
1
+ import type EnvSchema from "#app/EnvSchema";
1
2
  import AppFacade from "#app/Facade";
2
3
  import schema from "#config/schema";
3
- declare const _default: (input?: typeof schema.input) => AppFacade;
4
- export default _default;
4
+ import type { ObjectType } from "pema";
5
+ export default function config<P extends EnvSchema = EnvSchema>(input?: typeof schema.input & {
6
+ env?: {
7
+ schema?: ObjectType<P>;
8
+ };
9
+ }): AppFacade<P>;
5
10
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import AppFacade from "#app/Facade";
2
2
  import schema from "#config/schema";
3
- export default (input = {}) => new AppFacade(schema.parse(input));
4
- ;
3
+ export default function config(input = {}) {
4
+ return new AppFacade(schema.parse(input));
5
+ }
5
6
  //# sourceMappingURL=index.js.map
@@ -1,29 +1,85 @@
1
- import Module from "#Module";
2
- declare const _default: import("pema").ObjectType<{
3
- http: import("pema").ObjectType<{
4
- csp: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").ArrayType<import("pema").StringType>>>;
5
- headers: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType>>;
6
- host: import("pema").DefaultType<import("pema").StringType, "localhost">;
7
- port: import("pema").DefaultType<import("pema").UintType<"u32">, 6161>;
8
- ssl: import("pema").ObjectType<{
9
- cert: import("pema").OptionalType<import("pema").UnionType<[import("pema").ConstructorType<typeof import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
10
- key: import("pema").OptionalType<import("pema").UnionType<[import("pema").ConstructorType<typeof import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
11
- }>;
12
- static: import("pema").ObjectType<{
13
- root: import("pema").DefaultType<import("pema").StringType, "/">;
14
- }>;
15
- }>;
16
- livereload: import("pema").ObjectType<{
17
- exclude: import("pema").OptionalType<import("pema").ArrayType<import("pema").StringType>>;
18
- host: import("pema").OptionalType<import("pema").StringType>;
19
- port: import("pema").OptionalType<import("pema").UintType<"u32">>;
20
- }>;
21
- modules: import("pema").OptionalType<import("pema").ArrayType<import("pema").ConstructorType<typeof Module>>>;
22
- request: import("pema").ObjectType<{
23
- body: import("pema").ObjectType<{
24
- parse: import("pema").DefaultType<import("pema").BooleanType, true>;
25
- }>;
26
- }>;
1
+ import type DB from "#db/DB";
2
+ import type Module from "#Module";
3
+ import type { Dict } from "@rcompat/type";
4
+ import type { ObjectType, Parsed } from "pema";
5
+ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
6
+ readonly http: {
7
+ readonly csp: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").ArrayType<import("pema").StringType>>>;
8
+ readonly headers: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType>>;
9
+ readonly host: import("pema").DefaultType<import("pema").StringType, "localhost">;
10
+ readonly port: import("pema").DefaultType<import("pema").UintType<"u32">, 6161>;
11
+ readonly ssl: {
12
+ readonly cert: import("pema").OptionalType<import("pema").UnionType<[import("pema").IsType<import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
13
+ readonly key: import("pema").OptionalType<import("pema").UnionType<[import("pema").IsType<import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
14
+ };
15
+ readonly static: {
16
+ readonly root: import("pema").DefaultType<import("pema").StringType, "/">;
17
+ };
18
+ };
19
+ readonly livereload: {
20
+ readonly exclude: import("pema").OptionalType<import("pema").ArrayType<import("pema").StringType>>;
21
+ readonly host: import("pema").OptionalType<import("pema").StringType>;
22
+ readonly port: import("pema").OptionalType<import("pema").UintType<"u32">>;
23
+ };
24
+ readonly db: {
25
+ readonly migrations: import("pema").OptionalType<ObjectType<{
26
+ table: import("pema").StringType;
27
+ db: import("pema").PureType<DB, "PureType">;
28
+ }, {
29
+ table: string;
30
+ db: DB;
31
+ }>>;
32
+ };
33
+ readonly env: {
34
+ readonly schema: import("pema").OptionalType<import("pema").PureType<ObjectType<Dict<Parsed<unknown>>, {
35
+ [x: string]: unknown;
36
+ }>, "PureType">>;
37
+ };
38
+ readonly modules: import("pema").DefaultType<import("pema").ArrayType<ObjectType<{
39
+ name: import("pema").StringType;
40
+ setup: import("pema").FunctionType;
41
+ }, Module>>, Module[]>;
42
+ readonly request: {
43
+ readonly body: {
44
+ readonly parse: import("pema").DefaultType<import("pema").BooleanType, true>;
45
+ };
46
+ };
47
+ }>, {
48
+ http: {
49
+ csp: Record<string, string[]> | undefined;
50
+ headers: Record<string, string> | undefined;
51
+ host: string;
52
+ port: number;
53
+ ssl: {
54
+ cert: string | import("@rcompat/fs").FileRef | undefined;
55
+ key: string | import("@rcompat/fs").FileRef | undefined;
56
+ };
57
+ static: {
58
+ root: string;
59
+ };
60
+ };
61
+ livereload: {
62
+ exclude: string[] | undefined;
63
+ host: string | undefined;
64
+ port: number | undefined;
65
+ };
66
+ db: {
67
+ migrations: {
68
+ table: string;
69
+ db: DB;
70
+ } | undefined;
71
+ };
72
+ env: {
73
+ schema: ObjectType<Dict<Parsed<unknown>>, {
74
+ [x: string]: unknown;
75
+ }> | undefined;
76
+ };
77
+ modules: Module[];
78
+ request: {
79
+ body: {
80
+ parse: boolean;
81
+ };
82
+ };
27
83
  }>;
28
84
  export default _default;
29
85
  //# sourceMappingURL=schema.d.ts.map
@@ -1,4 +1,3 @@
1
- import Module from "#Module";
2
1
  import fs from "@rcompat/fs";
3
2
  import p from "pema";
4
3
  export default p({
@@ -8,8 +7,8 @@ export default p({
8
7
  host: p.string.default("localhost"),
9
8
  port: p.uint.port().default(6161),
10
9
  ssl: {
11
- cert: p.union(fs.FileRef, p.string).optional(),
12
- key: p.union(fs.FileRef, p.string).optional(),
10
+ cert: p.union(p.is(fs.isRef), p.string).optional(),
11
+ key: p.union(p.is(fs.isRef), p.string).optional(),
13
12
  },
14
13
  static: {
15
14
  root: p.string.default("/"),
@@ -20,7 +19,21 @@ export default p({
20
19
  host: p.string.optional(),
21
20
  port: p.uint.port().optional(),
22
21
  },
23
- modules: p.array(p.constructor(Module)).optional(),
22
+ db: {
23
+ migrations: p.object({
24
+ table: p.string,
25
+ db: p.pure(),
26
+ }).optional(),
27
+ },
28
+ env: {
29
+ schema: p.pure().optional(),
30
+ },
31
+ modules: p.array(p.object({
32
+ name: p.string,
33
+ setup: p.function,
34
+ }).shape())
35
+ .uniqueBy(member => member.name)
36
+ .default([]),
24
37
  request: {
25
38
  body: {
26
39
  parse: p.boolean.default(true),
@@ -1,9 +1,15 @@
1
- declare const Schema: import("pema").ObjectType<{
2
- httpOnly: import("pema").DefaultType<import("pema").BooleanType, true>;
3
- path: import("pema").DefaultType<import("pema").StringType, "/">;
4
- sameSite: import("pema").UnionType<[import("pema").LiteralType<"Lax">, import("pema").LiteralType<"None">, import("pema").LiteralType<"Strict">]>;
5
- secure: import("pema").BooleanType;
6
- maxAge: import("pema").OptionalType<import("pema").NumberType<"f64">>;
1
+ declare const Schema: import("pema").ObjectType<import("pema").NormalizeSchemaObject<{
2
+ readonly httpOnly: import("pema").DefaultType<import("pema").BooleanType, true>;
3
+ readonly path: import("pema").DefaultType<import("pema").StringType, "/">;
4
+ readonly sameSite: import("pema").UnionType<[import("pema").LiteralType<"Lax">, import("pema").LiteralType<"None">, import("pema").LiteralType<"Strict">]>;
5
+ readonly secure: import("pema").BooleanType;
6
+ readonly maxAge: import("pema").OptionalType<import("pema").NumberType<"f64">>;
7
+ }>, {
8
+ httpOnly: boolean;
9
+ path: string;
10
+ sameSite: "Lax" | "None" | "Strict";
11
+ secure: boolean;
12
+ maxAge: number | undefined;
7
13
  }>;
8
14
  type Options = typeof Schema.input;
9
15
  export default function cookie(name: string, value: string, options: Options): string;
@@ -1,13 +1,28 @@
1
1
  import type As from "#db/As";
2
+ import type PK from "#db/PK";
2
3
  import type Sort from "#db/Sort";
4
+ import type Types from "#db/Types";
3
5
  import type With from "#db/With";
4
6
  import type { Dict, MaybePromise } from "@rcompat/type";
5
- import type { StoreSchema } from "pema";
7
+ import type { DataType } from "pema";
8
+ export interface SchemaDiff {
9
+ add: Types;
10
+ drop: string[];
11
+ rename: [string, string][];
12
+ }
13
+ type MaybeTable = Dict<(keyof DataType)[]> | null;
14
+ type PKConfig = {
15
+ name: PK;
16
+ generate: boolean;
17
+ };
18
+ export type Schema = {
19
+ create(name: string, pk: PKConfig, types: Types): MaybePromise<void>;
20
+ delete(name: string): MaybePromise<void>;
21
+ introspect(name: string, pk?: PK): MaybePromise<MaybeTable>;
22
+ alter(name: string, diff: SchemaDiff): MaybePromise<void>;
23
+ };
6
24
  export default interface DB {
7
- schema: {
8
- create(as: As, schema: StoreSchema): MaybePromise<void>;
9
- delete(name: string): MaybePromise<void>;
10
- };
25
+ schema: Schema;
11
26
  close(): MaybePromise<void>;
12
27
  create<O extends Dict>(as: As, record: Dict): MaybePromise<O>;
13
28
  read(as: As, args: {
@@ -30,4 +45,5 @@ export default interface DB {
30
45
  where: Dict;
31
46
  }): MaybePromise<number>;
32
47
  }
48
+ export {};
33
49
  //# sourceMappingURL=DB.d.ts.map
@@ -1,2 +1,3 @@
1
+ ;
1
2
  export {};
2
3
  //# sourceMappingURL=DB.js.map
@@ -1,15 +1,13 @@
1
1
  import type As from "#db/As";
2
2
  import type DB from "#db/DB";
3
+ import type { Schema } from "#db/DB";
3
4
  import type DataDict from "#db/DataDict";
4
5
  import type Sort from "#db/Sort";
5
6
  import type With from "#db/With";
6
7
  import type { Dict, MaybePromise } from "@rcompat/type";
7
8
  export default class MemoryDB implements DB {
8
9
  #private;
9
- get schema(): {
10
- create: (as: As) => void;
11
- delete: (table: string) => void;
12
- };
10
+ get schema(): Schema;
13
11
  close(): void;
14
12
  create<O extends Dict>(as: As, record: Dict): MaybePromise<O>;
15
13
  read(as: As, args: {
@@ -1,8 +1,7 @@
1
- import E from "#db/error";
1
+ import E from "#db/errors";
2
2
  import assert from "@rcompat/assert";
3
3
  import entries from "@rcompat/dict/entries";
4
4
  import is from "@rcompat/is";
5
- const PK_TYPES = ["string", "bigint", "number"];
6
5
  function escape_re(s) {
7
6
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8
7
  }
@@ -123,23 +122,44 @@ function toSorted(d1, d2, sort) {
123
122
  }
124
123
  export default class MemoryDB {
125
124
  #tables = {};
126
- #new(as) {
127
- if (this.#tables[as.table] !== undefined)
128
- return;
129
- this.#tables[as.table] = [];
130
- }
131
- #drop(table) {
132
- if (this.#tables[table] !== undefined)
133
- delete this.#tables[table];
134
- }
125
+ #types = {};
135
126
  #use(name) {
136
127
  this.#tables[name] ??= [];
137
128
  return this.#tables[name];
138
129
  }
139
130
  get schema() {
140
131
  return {
141
- create: this.#new.bind(this),
142
- delete: this.#drop.bind(this),
132
+ create: async (table, _pk, types) => {
133
+ if (this.#tables[table] !== undefined)
134
+ return;
135
+ this.#tables[table] = [];
136
+ this.#types[table] = types;
137
+ },
138
+ delete: table => {
139
+ if (this.#tables[table] !== undefined)
140
+ delete this.#tables[table];
141
+ },
142
+ introspect: table => {
143
+ if (this.#tables[table] === undefined)
144
+ return null;
145
+ const types = this.#types[table] ?? {};
146
+ return Object.fromEntries(Object.entries(types).map(([field, type]) => [field, [type]]));
147
+ },
148
+ alter: (table, diff) => {
149
+ if (this.#types[table] === undefined)
150
+ throw E.table_not_found(table);
151
+ const types = { ...this.#types[table] };
152
+ const { add, drop, rename } = diff;
153
+ for (const [field, type] of Object.entries(add))
154
+ types[field] = type;
155
+ for (const field of drop)
156
+ delete types[field];
157
+ for (const [from, to] of rename) {
158
+ types[to] = types[from];
159
+ delete types[from];
160
+ }
161
+ this.#types[table] = types;
162
+ },
143
163
  };
144
164
  }
145
165
  // noop
@@ -149,7 +169,7 @@ export default class MemoryDB {
149
169
  const size = table.length;
150
170
  const pk = assert.defined(as.pk);
151
171
  const type = as.types[pk];
152
- if (type === "string") {
172
+ if (type === "uuid" || type === "uuid_v4" || type === "uuid_v7") {
153
173
  return crypto.randomUUID();
154
174
  }
155
175
  else if (["u64", "u128", "i64", "i128"].includes(type)) {
@@ -160,7 +180,7 @@ export default class MemoryDB {
160
180
  }
161
181
  }
162
182
  create(as, record) {
163
- assert.nonempty(record, "empty record");
183
+ assert.nonempty(record);
164
184
  const table = this.#use(as.table);
165
185
  const pk = as.pk;
166
186
  let to_insert = record;
@@ -170,10 +190,8 @@ export default class MemoryDB {
170
190
  to_insert = { ...record, [pk]: this.#next_id(as) };
171
191
  }
172
192
  if (pk !== null) {
173
- const pkv = to_insert[pk];
174
- if (!PK_TYPES.includes(typeof pkv))
175
- throw E.pk_invalid(pkv);
176
- if (table.find(stored => stored[pk] === pkv))
193
+ const pv = to_insert[pk];
194
+ if (table.find(s => s[pk] === pv) !== undefined)
177
195
  throw E.pk_duplicate(pk);
178
196
  }
179
197
  table.push({ ...to_insert });
@@ -239,7 +257,7 @@ export default class MemoryDB {
239
257
  }
240
258
  // filter by target_pk equality + optional where
241
259
  let candidates = target.filter(t => t[target_pk] === fk_value && match(t, r_where));
242
- if (r_sort && Object.keys(r_sort).length > 0) {
260
+ if (r_sort !== undefined && Object.keys(r_sort).length > 0) {
243
261
  candidates = candidates.toSorted((a, b) => toSorted(a, b, r_sort));
244
262
  }
245
263
  if (r_limit !== undefined)
@@ -262,7 +280,7 @@ export default class MemoryDB {
262
280
  if (!match(row, r_where))
263
281
  continue;
264
282
  const bucket = grouped.get(key);
265
- if (bucket)
283
+ if (bucket !== undefined)
266
284
  bucket.push(row);
267
285
  else
268
286
  grouped.set(key, [row]);
@@ -271,7 +289,7 @@ export default class MemoryDB {
271
289
  const parent_full = base_full[i];
272
290
  const key = parent_full[parent_pk];
273
291
  let rows = grouped.get(key) ?? [];
274
- if (r_sort && Object.keys(r_sort).length > 0) {
292
+ if (r_sort !== undefined && Object.keys(r_sort).length > 0) {
275
293
  rows = rows.toSorted((a, b) => toSorted(a, b, r_sort));
276
294
  }
277
295
  if (kind === "one") {
@@ -3,6 +3,10 @@ import type ReadArgs from "#db/ReadArgs";
3
3
  import type ReadRelationsArgs from "#db/ReadRelationsArgs";
4
4
  import type With from "#db/With";
5
5
  import type { Dict } from "@rcompat/type";
6
+ import type { DataKey } from "pema";
7
+ declare const UUID_TYPES: DataKey[];
8
+ declare function generate_uuid(type: typeof UUID_TYPES[number]): string;
9
+ declare function is_uuid_type(type: DataKey): type is typeof UUID_TYPES[number];
6
10
  declare const BASE: {
7
11
  withed(args: ReadArgs & {
8
12
  with?: With;
@@ -10,9 +14,12 @@ declare const BASE: {
10
14
  fields(base: string[] | undefined, ...add: (string | null)[]): string[] | undefined;
11
15
  project(row: Dict, fields?: string[]): Dict;
12
16
  expand(as: As, fields: string[] | undefined, relations: With): string[] | undefined;
17
+ generate_uuid: typeof generate_uuid;
18
+ is_uuid_type: typeof is_uuid_type;
13
19
  BIGINT_STRING_TYPES: string[];
14
20
  UNSIGNED_BIGINT_TYPES: string[];
15
21
  INT_TYPES: string[];
22
+ UUID_TYPES: (keyof import("pema").DataType)[];
16
23
  };
17
24
  export default BASE;
18
25
  //# sourceMappingURL=common.d.ts.map