@primate/core 0.7.5 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/lib/private/App.d.ts +128 -65
  2. package/lib/private/Bag.d.ts +11 -0
  3. package/lib/private/Bag.js +31 -0
  4. package/lib/private/Flags.d.ts +5 -5
  5. package/lib/private/Flags.js +2 -1
  6. package/lib/private/app/Facade.client.d.ts +20 -0
  7. package/lib/private/app/Facade.client.js +30 -0
  8. package/lib/private/app/{Facade.d.ts → Facade.server.d.ts} +141 -72
  9. package/lib/private/app/{Facade.js → Facade.server.js} +12 -4
  10. package/lib/private/build/App.d.ts +0 -2
  11. package/lib/private/build/App.js +0 -7
  12. package/lib/private/build/client/index.js +29 -27
  13. package/lib/private/build/client/plugin/frontend.js +1 -1
  14. package/lib/private/build/client/plugin/routes.js +1 -1
  15. package/lib/private/build/hook.js +0 -3
  16. package/lib/private/build/server/index.js +5 -18
  17. package/lib/private/build/server/plugin/native-addons.d.ts +1 -1
  18. package/lib/private/build/server/plugin/native-addons.js +1 -1
  19. package/lib/private/build/shared/intercept.d.ts +1 -1
  20. package/lib/private/build/shared/intercept.js +4 -2
  21. package/lib/private/client/create-form.d.ts +13 -9
  22. package/lib/private/client/create-form.js +21 -4
  23. package/lib/private/config/index.d.ts +6 -2
  24. package/lib/private/config/schema.d.ts +28 -21
  25. package/lib/private/config/schema.js +5 -3
  26. package/lib/private/cookie.d.ts +5 -5
  27. package/lib/private/db/errors.d.ts +82 -82
  28. package/lib/private/db/migrate/store.d.ts +2 -2
  29. package/lib/private/db/primary.d.ts +1 -1
  30. package/lib/private/db/sql.d.ts +1 -1
  31. package/lib/private/errors.d.ts +80 -68
  32. package/lib/private/errors.js +23 -1
  33. package/lib/private/frontend.d.ts +7 -7
  34. package/lib/private/frontend.js +7 -10
  35. package/lib/private/i18n/API.d.ts +14 -18
  36. package/lib/private/i18n/config.client.d.ts +7 -0
  37. package/lib/private/i18n/config.client.js +130 -0
  38. package/lib/private/i18n/config.server.d.ts +7 -0
  39. package/lib/private/i18n/{index/server.js → config.server.js} +31 -23
  40. package/lib/private/i18n/constant/COOKIE_NAME.d.ts +1 -1
  41. package/lib/private/i18n/constant/DEFAULT_LOCALE.d.ts +1 -1
  42. package/lib/private/i18n/constant/DEFAULT_PERSIST_MODE.d.ts +1 -1
  43. package/lib/private/i18n/constant/PERSIST_HEADER.d.ts +1 -1
  44. package/lib/private/i18n/constant/PERSIST_METHOD.d.ts +1 -1
  45. package/lib/private/i18n/constant/PERSIST_STORAGE_KEY.d.ts +1 -1
  46. package/lib/private/i18n/index.d.ts +42 -0
  47. package/lib/private/i18n/index.js +6 -0
  48. package/lib/private/i18n/missing.d.ts +5 -0
  49. package/lib/private/i18n/missing.js +38 -0
  50. package/lib/private/i18n/module.js +36 -52
  51. package/lib/private/i18n/schema.d.ts +4 -4
  52. package/lib/private/loader.d.ts +5 -0
  53. package/lib/private/loader.js +28 -0
  54. package/lib/private/logger.d.ts +1 -1
  55. package/lib/private/request/RequestBag.d.ts +12 -13
  56. package/lib/private/request/RequestBag.js +5 -4
  57. package/lib/private/request/RequestView.d.ts +5 -5
  58. package/lib/private/request/RequestView.js +0 -1
  59. package/lib/private/response/view.d.ts +1 -0
  60. package/lib/private/response/view.js +0 -7
  61. package/lib/private/route/Handler.d.ts +1 -1
  62. package/lib/private/route/NarrowedRequest.d.ts +6 -1
  63. package/lib/private/route/Options.d.ts +2 -1
  64. package/lib/private/route/hook.d.ts +1 -2
  65. package/lib/private/route/router.d.ts +9 -9
  66. package/lib/private/route/router.js +9 -0
  67. package/lib/private/route.client.d.ts +20 -4
  68. package/lib/private/route.client.js +7 -3
  69. package/lib/private/route.d.ts +3 -0
  70. package/lib/private/route.js +2 -0
  71. package/lib/private/serve/App.d.ts +2 -13
  72. package/lib/private/serve/App.js +63 -46
  73. package/lib/private/serve/Init.d.ts +0 -3
  74. package/lib/private/server/TAG.d.ts +1 -1
  75. package/lib/private/session/{index.client.d.ts → config.client.d.ts} +1 -1
  76. package/lib/private/session/{index.client.js → config.client.js} +1 -1
  77. package/lib/private/session/config.server.d.ts +15 -0
  78. package/lib/private/session/config.server.js +44 -0
  79. package/lib/private/session/index.d.ts +2 -14
  80. package/lib/private/session/index.js +2 -43
  81. package/lib/private/session/module.js +1 -1
  82. package/lib/private/session/schema.d.ts +5 -5
  83. package/lib/private/store/PrimaryKey.d.ts +1 -1
  84. package/lib/private/store.client.d.ts +2 -0
  85. package/lib/private/store.d.ts +2 -0
  86. package/lib/private/target/Manager.d.ts +2 -0
  87. package/lib/private/target/Manager.js +29 -5
  88. package/lib/private/target/Target.d.ts +2 -0
  89. package/lib/public/i18n.d.ts +3 -0
  90. package/lib/public/{i18n/config.js → i18n.js} +1 -1
  91. package/lib/public/loader.d.ts +2 -0
  92. package/lib/public/loader.js +2 -0
  93. package/lib/public/response.d.ts +1 -1
  94. package/lib/public/{session/config.d.ts → session.d.ts} +1 -1
  95. package/lib/public/{session/config.js → session.js} +1 -1
  96. package/package.json +27 -18
  97. package/lib/private/app/Facade.browser.d.ts +0 -11
  98. package/lib/private/app/Facade.browser.js +0 -19
  99. package/lib/private/build/server/plugin/store.d.ts +0 -4
  100. package/lib/private/build/server/plugin/store.js +0 -25
  101. package/lib/private/build/server/plugin/stores.d.ts +0 -4
  102. package/lib/private/build/server/plugin/stores.js +0 -28
  103. package/lib/private/i18n/index/client.d.ts +0 -9
  104. package/lib/private/i18n/index/client.js +0 -152
  105. package/lib/private/i18n/index/server.d.ts +0 -9
  106. package/lib/private/i18n/symbol/internal.d.ts +0 -3
  107. package/lib/private/i18n/symbol/internal.js +0 -3
  108. package/lib/public/i18n/API.d.ts +0 -2
  109. package/lib/public/i18n/API.js +0 -2
  110. package/lib/public/i18n/Catalogs.d.ts +0 -2
  111. package/lib/public/i18n/Catalogs.js +0 -2
  112. package/lib/public/i18n/ContextData.d.ts +0 -2
  113. package/lib/public/i18n/ContextData.js +0 -2
  114. package/lib/public/i18n/config.d.ts +0 -2
  115. package/lib/public/i18n/locale.d.ts +0 -2
  116. package/lib/public/i18n/locale.js +0 -2
  117. package/lib/public/i18n/sInternal.d.ts +0 -2
  118. package/lib/public/i18n/sInternal.js +0 -2
  119. package/lib/public/route/hook.d.ts +0 -2
  120. package/lib/public/route/hook.js +0 -2
  121. package/lib/public/session/config.client.d.ts +0 -2
  122. package/lib/public/session/config.client.js +0 -2
  123. /package/lib/private/i18n/{index/types.d.ts → types.d.ts} +0 -0
  124. /package/lib/private/i18n/{index/types.js → types.js} +0 -0
@@ -26,8 +26,6 @@ export default class BuildApp extends App {
26
26
  cleanup(): void;
27
27
  basename(file: FileRef, directory: FileRef): string;
28
28
  depth(): number;
29
- get i18n_active(): boolean;
30
- set i18n_active(active: boolean);
31
29
  get session_active(): boolean;
32
30
  set session_active(active: boolean);
33
31
  serve(): Promise<ServeApp>;
@@ -8,7 +8,6 @@ export default class BuildApp extends App {
8
8
  #postbuild = [];
9
9
  #roots = {};
10
10
  #id = crypto.randomUUID().slice(0, 8);
11
- #i18n_active = false;
12
11
  #session_active = false;
13
12
  #paths;
14
13
  #bindings = [
@@ -91,12 +90,6 @@ export default class BuildApp extends App {
91
90
  depth() {
92
91
  return this.get(s_layout_depth);
93
92
  }
94
- get i18n_active() {
95
- return this.#i18n_active;
96
- }
97
- set i18n_active(active) {
98
- this.#i18n_active = active;
99
- }
100
93
  get session_active() {
101
94
  return this.#session_active;
102
95
  }
@@ -7,6 +7,7 @@ import plugin_routes from "#build/client/plugin/routes";
7
7
  import plugin_server_stamp from "#build/client/plugin/server-stamp";
8
8
  import plugin_view from "#build/client/plugin/view";
9
9
  import plugin_app_request from "#build/shared/plugin/app-request";
10
+ import E from "#errors";
10
11
  import location from "#location";
11
12
  import { CodeError } from "@rcompat/error";
12
13
  import * as esbuild from "esbuild";
@@ -26,13 +27,6 @@ const write_bootstrap = async (app) => {
26
27
  `}
27
28
  import facade from "$:app";
28
29
 
29
- ${app.i18n_active ? `
30
- import i18n from "app:config:i18n";
31
- const i18n_config = i18n[s_config];
32
- ` : `
33
- const i18n_config = undefined;
34
- `}
35
-
36
30
  const app = await serve(import.meta.url, {
37
31
  assets,
38
32
  facade,
@@ -40,7 +34,6 @@ const write_bootstrap = async (app) => {
40
34
  views,
41
35
  pages,
42
36
  session: session_config,
43
- i18n: i18n_config,
44
37
  mode: "${app.mode}",
45
38
  target: "${app.target.name}",
46
39
  log: "${app.log.level}"
@@ -50,6 +43,17 @@ const write_bootstrap = async (app) => {
50
43
  `;
51
44
  await app.path.build.join("serve.js").write(build_start_script);
52
45
  };
46
+ function user_entrypoints(app) {
47
+ const configured = app.config("entrypoints") ?? {};
48
+ const reserved = ["app", "head", "body"];
49
+ const conflicts = Object.keys(configured).filter(name => reserved.includes(name));
50
+ if (conflicts.length)
51
+ throw E.build_reserved_entrypoints(conflicts);
52
+ return Object.fromEntries(Object.entries(configured).map(([name, file]) => [
53
+ name,
54
+ app.path.client.join(file).path,
55
+ ]));
56
+ }
53
57
  export default async function build_client(app) {
54
58
  app.plugin("client", plugin_frontend(app));
55
59
  app.plugin("client", plugin_alias(app));
@@ -60,42 +64,41 @@ export default async function build_client(app) {
60
64
  app.plugin("client", plugin_routes(app));
61
65
  app.plugin("client", plugin_server_stamp(app));
62
66
  app.plugin("client", plugin_entrypoint(app));
63
- const imports = await app.path.static.files({
64
- recursive: true,
65
- filter: file => /\.(?:js|ts|css)$/.test(file.path),
66
- });
67
- imports.forEach(file => {
68
- const src = file.debase(app.path.static);
69
- app.entrypoint(`import "./${location.static}${src}";`);
70
- });
71
67
  app.entrypoint("import \"primate/client/app\";");
72
68
  const tsconfig = app.root.join("tsconfig.json");
73
69
  const conditions = app.conditions.values();
74
70
  const build_options = {
75
71
  plugins: app.plugins("client"),
76
72
  outdir: app.runpath(location.client).path,
77
- entryPoints: ["app:client"],
73
+ entryPoints: {
74
+ app: "app:client",
75
+ ...user_entrypoints(app),
76
+ },
78
77
  conditions: ["style", "browser", "default", "module", ...conditions],
79
78
  resolveExtensions: [".ts", ".js", ...app.frontendExtensions],
80
79
  ...await tsconfig.exists() ? { tsconfig: tsconfig.path } : {},
81
80
  bundle: true,
82
81
  format: "esm",
83
82
  logLevel: "silent",
83
+ loader: app.config("loaders"),
84
84
  };
85
- const NO_HR = app.config("livereload.exclude") ?? [];
85
+ if (app.mode === "development") {
86
+ const NO_HR = app.config("livereload.exclude") ?? [];
87
+ app.entrypoint(`
88
+ const NO_HR = ${JSON.stringify(NO_HR)};
89
+ new EventSource("/esbuild").addEventListener("change", () => {
90
+ if (!NO_HR.includes(location.pathname)) location.reload();
91
+ });
92
+ `);
93
+ }
86
94
  const mode_options = app.mode === "development"
87
95
  ? {
88
- banner: {
89
- js: `const NO_HR=${JSON.stringify(NO_HR)};
90
- new EventSource("/esbuild").addEventListener("change",
91
- () => !NO_HR.includes(location.pathname) && location.reload());`,
92
- },
93
- entryNames: "app",
96
+ entryNames: "[name]",
94
97
  minify: false,
95
98
  splitting: false,
96
99
  }
97
100
  : {
98
- entryNames: "app-[hash]",
101
+ entryNames: "[name]-[hash]",
99
102
  minify: true,
100
103
  splitting: true,
101
104
  };
@@ -113,9 +116,8 @@ export default async function build_client(app) {
113
116
  }
114
117
  catch (cause) {
115
118
  const original = cause?.errors?.[0]?.detail;
116
- if (CodeError.is(original)) {
119
+ if (CodeError.is(original))
117
120
  throw original;
118
- }
119
121
  throw cause;
120
122
  }
121
123
  await write_bootstrap(app);
@@ -6,7 +6,7 @@ export default function plugin_client_frontend(app) {
6
6
  return { namespace: "frontends", path };
7
7
  });
8
8
  build.onLoad({ filter: /app:frontends/ }, async () => {
9
- const contents = [...app.frontends.keys()].map(name => `export { default as ${name} } from "@primate/${name}";`).join("\n");
9
+ const contents = [...app.frontends.keys()].map(name => `export { app as ${name} } from "@primate/${name}";`).join("\n");
10
10
  return { contents, resolveDir: app.root.path };
11
11
  });
12
12
  },
@@ -7,7 +7,7 @@ export default function plugin_client_routes(app) {
7
7
  build.onResolve({ filter: /.*/ }, async (args) => {
8
8
  if (args.pluginData === "primate-client-route-inner")
9
9
  return null;
10
- if (intercept(args, app.path.views))
10
+ if (intercept(args, app.root))
11
11
  return null;
12
12
  const result = await build.resolve(args.path, {
13
13
  resolveDir: args.resolveDir,
@@ -24,9 +24,6 @@ async function pre(app) {
24
24
  await stamp.write("export default 0;\n");
25
25
  const router = await $router(app.path.routes, app.extensions);
26
26
  app.set(s_layout_depth, router.depth("layout"));
27
- const i18n_ts = app.path.config.join("i18n.ts");
28
- const i18n_js = app.path.config.join("i18n.js");
29
- app.i18n_active = await i18n_ts.exists() || await i18n_js.exists();
30
27
  const session_ts = app.path.config.join("session.ts");
31
28
  const session_js = app.path.config.join("session.js");
32
29
  app.session_active = await session_ts.exists() || await session_js.exists();
@@ -7,26 +7,14 @@ import plugin_node_imports from "#build/server/plugin/node-imports";
7
7
  import plugin_requires from "#build/server/plugin/requires";
8
8
  import plugin_roots from "#build/server/plugin/roots";
9
9
  import plugin_route from "#build/server/plugin/route";
10
- import plugin_stores from "#build/server/plugin/stores";
10
+ import plugin_route_client from "#build/server/plugin/route-client";
11
11
  import plugin_view from "#build/server/plugin/view";
12
12
  import plugin_views from "#build/server/plugin/views";
13
13
  import plugin_virtual_pages from "#build/server/plugin/virtual-pages";
14
14
  import plugin_virtual_routes from "#build/server/plugin/virtual-routes";
15
15
  import plugin_wasm from "#build/server/plugin/wasm";
16
16
  import plugin_app_request from "#build/shared/plugin/app-request";
17
- import plugin_route_client from "#build/server/plugin/route-client";
18
- import runtime from "@rcompat/runtime";
19
17
  import * as esbuild from "esbuild";
20
- const externals = {
21
- node: ["node:*"],
22
- bun: ["node:*", "bun:*"],
23
- deno: ["node:*"],
24
- };
25
- const conditions = {
26
- node: ["node"],
27
- bun: ["bun", "node"],
28
- deno: ["deno", "node"],
29
- };
30
18
  export default async function build_server(app) {
31
19
  app.plugin("server", plugin_node_imports(app));
32
20
  app.plugin("server", plugin_frontend(app));
@@ -40,13 +28,11 @@ export default async function build_server(app) {
40
28
  app.plugin("server", plugin_roots(app));
41
29
  app.plugin("server", plugin_views(app));
42
30
  app.plugin("server", plugin_assets(app));
43
- app.plugin("server", plugin_stores(app));
44
31
  app.plugin("server", plugin_native_addons(app));
45
32
  app.plugin("server", plugin_requires(app));
46
33
  app.plugin("server", plugin_config(app));
47
34
  app.plugin("server", plugin_wasm(app));
48
35
  app.plugin("server", plugin_app_request(app));
49
- const runtime_name = runtime.name;
50
36
  const tsconfig_json = app.root.join("tsconfig.json");
51
37
  const options = {
52
38
  entryPoints: [app.path.build.join("serve.js").path],
@@ -56,19 +42,20 @@ export default async function build_server(app) {
56
42
  platform: "node",
57
43
  format: "esm",
58
44
  packages: app.mode === "development" ? "external" : undefined,
59
- external: [...externals[runtime_name]],
45
+ external: [...app.target.externals],
60
46
  loader: {
61
47
  ".json": "json",
62
48
  },
63
49
  banner: {
64
- js: `import { createRequire as __createRequire } from "node:module";const require = __createRequire(import.meta.url);`,
50
+ js: `import { createRequire as __createRequire } from "node:module";
51
+ const require = __createRequire(import.meta.url);`,
65
52
  },
66
53
  nodePaths: [app.root.join("node_modules").path],
67
54
  resolveExtensions: app.extensions,
68
55
  absWorkingDir: app.root.path,
69
56
  ...await tsconfig_json.exists() ? { tsconfig: tsconfig_json.path } : {},
70
57
  conditions: [
71
- ...conditions[runtime_name], // node | deno | bun
58
+ ...app.target.conditions, // node | deno | bun
72
59
  ...app.conditions, // set by modules
73
60
  ...app.config("conditions"), // set by user,
74
61
  "module", "import", "runtime", "default", // defaults
@@ -1,4 +1,4 @@
1
1
  import type BuildApp from "#build/App";
2
2
  import type { Plugin } from "esbuild";
3
- export default function plugin_server_store(app: BuildApp): Plugin;
3
+ export default function plugin_native_addons(app: BuildApp): Plugin;
4
4
  //# sourceMappingURL=native-addons.d.ts.map
@@ -2,7 +2,7 @@ import E from "#errors";
2
2
  import fs from "@rcompat/fs";
3
3
  import runtime from "@rcompat/runtime";
4
4
  const requirer = runtime.toRequire(import.meta.url);
5
- export default function plugin_server_store(app) {
5
+ export default function plugin_native_addons(app) {
6
6
  return {
7
7
  name: "primate/server/native-addons",
8
8
  setup(build) {
@@ -1,4 +1,4 @@
1
1
  import type { FileRef } from "@rcompat/fs";
2
2
  import type { OnResolveArgs } from "esbuild";
3
- export default function intercept(args: OnResolveArgs, views: FileRef): boolean;
3
+ export default function intercept(args: OnResolveArgs, root: FileRef): boolean;
4
4
  //# sourceMappingURL=intercept.d.ts.map
@@ -17,8 +17,10 @@ function is_npm_package(path, resolve_dir) {
17
17
  return false;
18
18
  }
19
19
  }
20
- export default function intercept(args, views) {
21
- if (!args.resolveDir.startsWith(views.path))
20
+ export default function intercept(args, root) {
21
+ if (!args.resolveDir.startsWith(root.path))
22
+ return true;
23
+ if (args.resolveDir.includes("node_modules"))
22
24
  return true;
23
25
  if (is_bare(args.path))
24
26
  return true;
@@ -5,21 +5,23 @@ type FormErrors = {
5
5
  form: FieldErrors;
6
6
  fields: Dict<FieldErrors>;
7
7
  };
8
- type FormSnapshot = {
8
+ type FormSnapshot<Result = unknown> = {
9
9
  id: FormId;
10
10
  submitting: boolean;
11
11
  submitted: boolean;
12
+ result: Result | null;
12
13
  errors: FormErrors;
13
14
  };
14
- export type FormView = FormSnapshot & {
15
+ export type FormView<Result = unknown> = FormSnapshot<Result> & {
15
16
  submit: (event?: Event) => Promise<void>;
16
17
  };
17
- type FormSubscriber = (snapshot: FormSnapshot) => void;
18
+ type FormSubscriber<Result = unknown> = (snapshot: FormSnapshot<Result>) => void;
18
19
  export type MethodMeta = {
19
20
  contentType?: string;
20
21
  };
21
- export type ClientMethod<Values extends Dict = Dict> = MethodMeta & ((args: {
22
+ export type ClientMethod<Values extends Dict = Dict, Path extends Dict = Dict, Result = unknown> = MethodMeta & ((args: {
22
23
  body: Values;
24
+ path: Path;
23
25
  }) => Promise<Response>);
24
26
  export type FormInit = {
25
27
  id?: string;
@@ -28,15 +30,17 @@ export type FormInit = {
28
30
  headers?: Dict<string>;
29
31
  action?: (args: {
30
32
  body: unknown;
33
+ path?: Dict<string>;
31
34
  }) => Promise<Response>;
32
35
  contentType?: string;
36
+ path?: Dict<string>;
33
37
  };
34
- type FormController = {
35
- subscribe(fn: FormSubscriber): () => void;
36
- read(): FormSnapshot;
38
+ type FormController<Result = unknown> = {
39
+ subscribe(fn: FormSubscriber<Result>): () => void;
40
+ read(): FormSnapshot<Result>;
37
41
  submit(event?: Event): Promise<void>;
38
42
  get id(): FormId;
39
43
  };
40
- export default function createForm(init: FormInit): FormController;
41
- export {};
44
+ declare function createForm<Result = unknown>(init: FormInit): FormController<Result>;
45
+ export default createForm;
42
46
  //# sourceMappingURL=create-form.d.ts.map
@@ -37,12 +37,13 @@ function form_data_body(form_data) {
37
37
  }
38
38
  return new URLSearchParams(form_data);
39
39
  }
40
- export default function createForm(init) {
40
+ function createForm(init) {
41
41
  const id = init.id ?? `form-${crypto.randomUUID()}`;
42
42
  let snapshot = {
43
43
  id,
44
44
  submitting: false,
45
45
  submitted: false,
46
+ result: null,
46
47
  errors: { form: [], fields: {} },
47
48
  };
48
49
  const subscribers = new Set();
@@ -100,12 +101,23 @@ export default function createForm(init) {
100
101
  setSubmitting(true);
101
102
  try {
102
103
  const response = await (is.defined(init.action)
103
- ? init.action({ body: content_type_body(init.contentType, form_data) })
104
+ ? init.action({
105
+ body: content_type_body(init.contentType, form_data),
106
+ path: init.path,
107
+ })
104
108
  : submit(url, form_data_body(form_data), method));
105
109
  if (response.ok) {
106
110
  // on success: clear errors, let the app decide what to do next
107
111
  // (redirect/reload)
108
- snapshot = { ...snapshot, submitted: true, errors: { form: [], fields: {} } };
112
+ const result = response.status === 204
113
+ ? null
114
+ : await response.json();
115
+ snapshot = {
116
+ ...snapshot,
117
+ submitted: true,
118
+ result,
119
+ errors: { form: [], fields: {} },
120
+ };
109
121
  publish();
110
122
  return;
111
123
  }
@@ -115,7 +127,11 @@ export default function createForm(init) {
115
127
  }
116
128
  catch (error) {
117
129
  // network error
118
- setErrors([{ type: "network_error", message: error.message, path: "" }]);
130
+ setErrors([{
131
+ type: "network_error",
132
+ message: error.message,
133
+ path: "",
134
+ }]);
119
135
  }
120
136
  finally {
121
137
  setSubmitting(false);
@@ -138,4 +154,5 @@ export default function createForm(init) {
138
154
  },
139
155
  };
140
156
  }
157
+ export default createForm;
141
158
  //# sourceMappingURL=create-form.js.map
@@ -1,10 +1,14 @@
1
1
  import type EnvSchema from "#app/EnvSchema";
2
2
  import AppFacade from "#app/Facade";
3
3
  import schema from "#config/schema";
4
+ import type I18NConfig from "#i18n/Config";
4
5
  import type { ObjectType } from "pema";
5
- export default function config<P extends EnvSchema = EnvSchema>(input?: typeof schema.input & {
6
+ type ConfigInput<P extends EnvSchema, I extends I18NConfig | undefined> = typeof schema.input & {
6
7
  env?: {
7
8
  schema?: ObjectType<P>;
8
9
  };
9
- }): AppFacade<P>;
10
+ i18n?: I;
11
+ };
12
+ export default function config<P extends EnvSchema = EnvSchema, const I extends I18NConfig | undefined = undefined>(input?: ConfigInput<P, I>): AppFacade<P, I>;
13
+ export {};
10
14
  //# sourceMappingURL=index.d.ts.map
@@ -1,46 +1,50 @@
1
1
  import type DB from "#db/DB";
2
+ import type I18NConfig from "#i18n/Config";
2
3
  import type Module from "#Module";
3
4
  import type { Dict } from "@rcompat/type";
4
5
  import type { ObjectType, Parsed } from "pema";
5
6
  declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
6
- readonly conditions: import("pema").DefaultType<import("pema").ArrayType<import("pema").StringType>, string[]>;
7
+ readonly conditions: import("pema").DefaultType<import("pema").ArrayType<import("pema").StringType, undefined>, string[]>;
7
8
  readonly http: {
8
- readonly csp: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").ArrayType<import("pema").StringType>>>;
9
- readonly headers: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType>>;
10
- readonly host: import("pema").DefaultType<import("pema").StringType, "localhost">;
11
- readonly port: import("pema").DefaultType<import("pema").UintType<"u32">, 6161>;
12
- readonly ssl: {
13
- readonly cert: import("pema").OptionalType<import("pema").UnionType<[import("pema").IsType<import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
14
- readonly key: import("pema").OptionalType<import("pema").UnionType<[import("pema").IsType<import("@rcompat/fs").FileRef>, import("pema").StringType]>>;
9
+ csp: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").ArrayType<import("pema").StringType, undefined>, undefined>>;
10
+ headers: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType, undefined>>;
11
+ host: import("pema").DefaultType<import("pema").StringType, "localhost">;
12
+ port: import("pema").DefaultType<import("pema").UintType<"u32", undefined>, 6161>;
13
+ ssl: {
14
+ cert: import("pema").OptionalType<import("pema").StringType>;
15
+ key: import("pema").OptionalType<import("pema").StringType>;
15
16
  };
16
- readonly static: {
17
- readonly root: import("pema").DefaultType<import("pema").StringType, "/">;
17
+ static: {
18
+ root: import("pema").DefaultType<import("pema").StringType, "/">;
18
19
  };
19
20
  };
20
21
  readonly livereload: {
21
- readonly exclude: import("pema").OptionalType<import("pema").ArrayType<import("pema").StringType>>;
22
- readonly host: import("pema").OptionalType<import("pema").StringType>;
23
- readonly port: import("pema").OptionalType<import("pema").UintType<"u32">>;
22
+ exclude: import("pema").OptionalType<import("pema").ArrayType<import("pema").StringType, undefined>>;
23
+ host: import("pema").OptionalType<import("pema").StringType>;
24
+ port: import("pema").OptionalType<import("pema").UintType<"u32", undefined>>;
24
25
  };
25
26
  readonly db: {
26
- readonly migrations: import("pema").OptionalType<ObjectType<{
27
+ migrations: import("pema").OptionalType<ObjectType<{
27
28
  table: import("pema").StringType;
28
29
  db: import("pema").PureType<DB<unknown>, "PureType">;
29
- }, {
30
+ }, undefined, {
30
31
  table: string;
31
32
  db: DB<unknown>;
32
33
  }>>;
33
34
  };
34
35
  readonly env: {
35
- readonly schema: import("pema").OptionalType<import("pema").PureType<ObjectType<Dict<Parsed<unknown>>, {
36
+ schema: import("pema").OptionalType<import("pema").PureType<ObjectType<Dict<Parsed<unknown>>, undefined, {
36
37
  [x: string]: unknown;
37
38
  }>, "PureType">>;
38
39
  };
40
+ readonly i18n: import("pema").OptionalType<import("pema").PureType<I18NConfig, "PureType">>;
41
+ readonly loaders: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").LiteralType<"file", undefined>, undefined>>;
42
+ readonly entrypoints: import("pema").OptionalType<import("pema").RecordType<import("pema").StringType, import("pema").StringType, undefined>>;
39
43
  readonly modules: import("pema").DefaultType<import("pema").ArrayType<ObjectType<{
40
44
  name: import("pema").StringType;
41
45
  setup: import("pema").FunctionType;
42
- }, Module>>, Module[]>;
43
- }>, {
46
+ }, undefined, Module>, undefined>, Module[]>;
47
+ }>, undefined, {
44
48
  conditions: string[];
45
49
  http: {
46
50
  csp: Record<string, string[]> | undefined;
@@ -48,8 +52,8 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
48
52
  host: string;
49
53
  port: number;
50
54
  ssl: {
51
- cert: string | import("@rcompat/fs").FileRef | undefined;
52
- key: string | import("@rcompat/fs").FileRef | undefined;
55
+ cert: string | undefined;
56
+ key: string | undefined;
53
57
  };
54
58
  static: {
55
59
  root: string;
@@ -67,10 +71,13 @@ declare const _default: ObjectType<import("pema").NormalizeSchemaObject<{
67
71
  } | undefined;
68
72
  };
69
73
  env: {
70
- schema: ObjectType<Dict<Parsed<unknown>>, {
74
+ schema: ObjectType<Dict<Parsed<unknown>>, undefined, {
71
75
  [x: string]: unknown;
72
76
  }> | undefined;
73
77
  };
78
+ i18n: I18NConfig | undefined;
79
+ loaders: Record<string, "file"> | undefined;
80
+ entrypoints: Record<string, string> | undefined;
74
81
  modules: Module[];
75
82
  }>;
76
83
  export default _default;
@@ -1,4 +1,3 @@
1
- import fs from "@rcompat/fs";
2
1
  import p from "pema";
3
2
  export default p({
4
3
  conditions: p.array(p.string).unique().default([]),
@@ -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(p.is(fs.isRef), p.string).optional(),
12
- key: p.union(p.is(fs.isRef), p.string).optional(),
10
+ cert: p.string.optional(),
11
+ key: p.string.optional(),
13
12
  },
14
13
  static: {
15
14
  root: p.string.default("/"),
@@ -29,6 +28,9 @@ export default p({
29
28
  env: {
30
29
  schema: p.pure().optional(),
31
30
  },
31
+ i18n: p.pure().optional(),
32
+ loaders: p.dict(p.literal("file")).optional(),
33
+ entrypoints: p.dict(p.string).optional(),
32
34
  modules: p.array(p.object({
33
35
  name: p.string,
34
36
  setup: p.function,
@@ -1,10 +1,10 @@
1
1
  declare const Schema: import("pema").ObjectType<import("pema").NormalizeSchemaObject<{
2
- readonly httpOnly: import("pema").DefaultType<import("pema").BooleanType, true>;
2
+ readonly httpOnly: import("pema").DefaultType<import("pema").BooleanType<undefined>, true>;
3
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
- }>, {
4
+ readonly sameSite: import("pema").UnionType<[import("pema").LiteralType<"Lax", undefined>, import("pema").LiteralType<"None", undefined>, import("pema").LiteralType<"Strict", undefined>], undefined>;
5
+ readonly secure: import("pema").BooleanType<undefined>;
6
+ readonly maxAge: import("pema").OptionalType<import("pema").NumberType<"f64", undefined>>;
7
+ }>, undefined, {
8
8
  httpOnly: boolean;
9
9
  path: string;
10
10
  sameSite: "Lax" | "None" | "Strict";