@primate/core 0.3.3 → 0.4.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 (157) hide show
  1. package/lib/private/App.d.ts +5 -19
  2. package/lib/private/App.js +13 -75
  3. package/lib/private/Binder.d.ts +1 -3
  4. package/lib/private/Flags.d.ts +7 -0
  5. package/lib/private/Flags.js +7 -0
  6. package/lib/private/Module.d.ts +2 -2
  7. package/lib/private/backend/TAG.d.ts +1 -1
  8. package/lib/private/backend/TAG.js +1 -1
  9. package/lib/private/build/App.d.ts +34 -0
  10. package/lib/private/build/App.js +103 -0
  11. package/lib/private/build/client/index.d.ts +3 -0
  12. package/lib/private/build/client/index.js +95 -0
  13. package/lib/private/build/client/plugin/alias.d.ts +4 -0
  14. package/lib/private/build/client/plugin/alias.js +12 -0
  15. package/lib/private/build/client/plugin/entrypoint.d.ts +4 -0
  16. package/lib/private/build/client/plugin/entrypoint.js +15 -0
  17. package/lib/private/build/client/plugin/frontend.d.ts +4 -0
  18. package/lib/private/build/client/plugin/frontend.js +15 -0
  19. package/lib/private/build/client/plugin/server-stamp.d.ts +4 -0
  20. package/lib/private/build/client/plugin/server-stamp.js +14 -0
  21. package/lib/private/build/client/reload.d.ts +7 -0
  22. package/lib/private/build/client/reload.js +6 -0
  23. package/lib/private/{hook/build.d.ts → build/hook.d.ts} +2 -2
  24. package/lib/private/build/hook.js +49 -0
  25. package/lib/private/build/index.d.ts +4 -0
  26. package/lib/private/{build.js → build/index.js} +7 -5
  27. package/lib/private/build/server/index.d.ts +3 -0
  28. package/lib/private/build/server/index.js +89 -0
  29. package/lib/private/build/server/plugin/assets.d.ts +4 -0
  30. package/lib/private/build/server/plugin/assets.js +67 -0
  31. package/lib/private/build/server/plugin/config.d.ts +4 -0
  32. package/lib/private/build/server/plugin/config.js +43 -0
  33. package/lib/private/build/server/plugin/database-default.d.ts +4 -0
  34. package/lib/private/build/server/plugin/database-default.js +48 -0
  35. package/lib/private/build/server/plugin/frontend.d.ts +4 -0
  36. package/lib/private/build/server/plugin/frontend.js +21 -0
  37. package/lib/private/build/server/plugin/hot-reload.d.ts +4 -0
  38. package/lib/private/build/server/plugin/hot-reload.js +36 -0
  39. package/lib/private/build/server/plugin/native-addons.d.ts +4 -0
  40. package/lib/private/build/server/plugin/native-addons.js +55 -0
  41. package/lib/private/build/server/plugin/node-imports.d.ts +4 -0
  42. package/lib/private/build/server/plugin/node-imports.js +32 -0
  43. package/lib/private/build/server/plugin/requires.d.ts +4 -0
  44. package/lib/private/build/server/plugin/requires.js +30 -0
  45. package/lib/private/build/server/plugin/roots.d.ts +4 -0
  46. package/lib/private/build/server/plugin/roots.js +18 -0
  47. package/lib/private/build/server/plugin/route.d.ts +4 -0
  48. package/lib/private/build/server/plugin/route.js +56 -0
  49. package/lib/private/build/server/plugin/store-wrap.d.ts +4 -0
  50. package/lib/private/build/server/plugin/store-wrap.js +33 -0
  51. package/lib/private/build/server/plugin/store.d.ts +4 -0
  52. package/lib/private/build/server/plugin/store.js +47 -0
  53. package/lib/private/build/server/plugin/stores.d.ts +4 -0
  54. package/lib/private/build/server/plugin/stores.js +25 -0
  55. package/lib/private/build/server/plugin/view.d.ts +4 -0
  56. package/lib/private/build/server/plugin/view.js +64 -0
  57. package/lib/private/build/server/plugin/views.d.ts +4 -0
  58. package/lib/private/build/server/plugin/views.js +36 -0
  59. package/lib/private/build/server/plugin/virtual-pages.d.ts +4 -0
  60. package/lib/private/build/server/plugin/virtual-pages.js +41 -0
  61. package/lib/private/build/server/plugin/virtual-routes.d.ts +4 -0
  62. package/lib/private/build/server/plugin/virtual-routes.js +46 -0
  63. package/lib/private/build/server/plugin/wasm.d.ts +4 -0
  64. package/lib/private/build/server/plugin/wasm.js +36 -0
  65. package/lib/private/client/Data.d.ts +2 -0
  66. package/lib/private/client/app.js +4 -1
  67. package/lib/private/config/index.d.ts +0 -2
  68. package/lib/private/config/schema.d.ts +4 -6
  69. package/lib/private/config/schema.js +9 -19
  70. package/lib/private/database/Store.d.ts +4 -1
  71. package/lib/private/database/Store.js +8 -2
  72. package/lib/private/database/test.js +8 -8
  73. package/lib/private/frontend/Module.d.ts +5 -3
  74. package/lib/private/frontend/Module.js +50 -50
  75. package/lib/private/frontend/Publish.d.ts +1 -1
  76. package/lib/private/i18n/Module.d.ts +1 -1
  77. package/lib/private/i18n/Module.js +2 -2
  78. package/lib/private/location.d.ts +0 -6
  79. package/lib/private/location.js +0 -12
  80. package/lib/private/module/BuildHook.d.ts +1 -1
  81. package/lib/private/module/NextBuild.d.ts +1 -1
  82. package/lib/private/module/NextServe.d.ts +1 -1
  83. package/lib/private/paths.d.ts +5 -0
  84. package/lib/private/paths.js +30 -0
  85. package/lib/private/reducer.d.ts +2 -2
  86. package/lib/private/request/route.d.ts +1 -1
  87. package/lib/private/request/route.js +6 -8
  88. package/lib/private/response/ResponseFunction.d.ts +1 -1
  89. package/lib/private/response/binary.d.ts +1 -1
  90. package/lib/private/response/json.d.ts +1 -1
  91. package/lib/private/response/sse.d.ts +1 -1
  92. package/lib/private/response/text.d.ts +1 -1
  93. package/lib/private/response/view.d.ts +6 -9
  94. package/lib/private/response/view.js +12 -8
  95. package/lib/private/response.d.ts +1 -1
  96. package/lib/private/route/router.d.ts +3 -2
  97. package/lib/private/route/router.js +5 -4
  98. package/lib/private/{ServeApp.d.ts → serve/App.d.ts} +5 -22
  99. package/lib/private/{ServeApp.js → serve/App.js} +106 -35
  100. package/lib/private/{ServeInit.d.ts → serve/Init.d.ts} +16 -12
  101. package/lib/private/serve/Init.js +2 -0
  102. package/lib/private/{hook/serve.d.ts → serve/hook.d.ts} +2 -2
  103. package/lib/private/{hook/serve.js → serve/hook.js} +1 -1
  104. package/lib/private/serve/index.d.ts +5 -0
  105. package/lib/private/serve/index.js +6 -0
  106. package/lib/private/{builtin/DevModule.d.ts → serve/module/Dev.d.ts} +2 -2
  107. package/lib/private/{builtin/DevModule.js → serve/module/Dev.js} +4 -6
  108. package/lib/private/{builtin/HandleModule.d.ts → serve/module/Handle.d.ts} +2 -2
  109. package/lib/private/{builtin/HandleModule.js → serve/module/Handle.js} +2 -2
  110. package/lib/private/session/SessionModule.d.ts +3 -2
  111. package/lib/private/session/SessionModule.js +47 -24
  112. package/lib/private/session/index.d.ts +11 -8
  113. package/lib/private/session/index.js +5 -3
  114. package/lib/private/session/schema.d.ts +2 -4
  115. package/lib/private/session/schema.js +14 -16
  116. package/lib/private/target/Manager.js +5 -1
  117. package/lib/private/wasm/instantiate.js +2 -2
  118. package/lib/public/BuildApp.d.ts +1 -1
  119. package/lib/public/BuildApp.js +1 -1
  120. package/lib/public/Flags.d.ts +2 -0
  121. package/lib/public/Flags.js +2 -0
  122. package/lib/public/ServeApp.d.ts +1 -1
  123. package/lib/public/ServeApp.js +1 -1
  124. package/lib/public/build.d.ts +1 -1
  125. package/lib/public/build.js +1 -1
  126. package/lib/public/serve.d.ts +1 -1
  127. package/lib/public/serve.js +1 -1
  128. package/package.json +6 -7
  129. package/lib/private/BindingContext.d.ts +0 -3
  130. package/lib/private/BindingContext.js +0 -2
  131. package/lib/private/BuildApp.d.ts +0 -29
  132. package/lib/private/BuildApp.js +0 -125
  133. package/lib/private/Loader.d.ts +0 -17
  134. package/lib/private/Loader.js +0 -47
  135. package/lib/private/ServeInit.js +0 -2
  136. package/lib/private/build.d.ts +0 -4
  137. package/lib/private/config/config/app.d.ts +0 -3
  138. package/lib/private/config/config/app.js +0 -3
  139. package/lib/private/config/config/database/index.d.ts +0 -3
  140. package/lib/private/config/config/database/index.js +0 -3
  141. package/lib/private/config/config/session.d.ts +0 -3
  142. package/lib/private/config/config/session.js +0 -3
  143. package/lib/private/frontend/bundle-server.d.ts +0 -12
  144. package/lib/private/frontend/bundle-server.js +0 -48
  145. package/lib/private/hook/build.js +0 -260
  146. package/lib/private/serve.d.ts +0 -5
  147. package/lib/private/serve.js +0 -8
  148. package/lib/private/session/InMemoryManager.d.ts +0 -9
  149. package/lib/private/session/InMemoryManager.js +0 -23
  150. package/lib/private/session/Manager.d.ts +0 -9
  151. package/lib/private/session/Manager.js +0 -4
  152. package/lib/private/target/web.d.ts +0 -4
  153. package/lib/private/target/web.js +0 -58
  154. package/lib/public/Loader.d.ts +0 -2
  155. package/lib/public/Loader.js +0 -2
  156. package/lib/public/session/Manager.d.ts +0 -2
  157. package/lib/public/session/Manager.js +0 -2
@@ -1,21 +1,17 @@
1
1
  import fail from "#fail";
2
- import bundle from "#frontend/bundle-server";
3
2
  import inline from "#inline";
4
3
  import location from "#location";
5
4
  import Module from "#Module";
6
- import assert from "@rcompat/assert";
7
5
  import map from "@rcompat/async/map";
8
6
  import hash from "@rcompat/crypto/hash";
9
7
  import FileRef from "@rcompat/fs/FileRef";
10
8
  import APPLICATION_JSON from "@rcompat/http/mime/application/json";
11
9
  import Status from "@rcompat/http/Status";
12
- import pema from "pema";
13
- import array from "pema/array";
14
- import boolean from "pema/boolean";
15
- import string from "pema/string";
16
- const contexts = ["views", "components"];
17
- async function normalize(path) {
18
- return `p_${await hash(path)}`;
10
+ import p from "pema";
11
+ async function normalize(path, frontend) {
12
+ const file = new FileRef(path);
13
+ const basename = path.slice(0, -file.fullExtension.length);
14
+ return `p_${await hash(`${basename}.${frontend}`)}`;
19
15
  }
20
16
  export default class FrontendModule extends Module {
21
17
  #options;
@@ -23,10 +19,12 @@ export default class FrontendModule extends Module {
23
19
  root;
24
20
  compile = {};
25
21
  css;
26
- static schema = pema({
27
- fileExtensions: array(string).optional(),
28
- spa: boolean.default(true),
29
- ssr: boolean.default(true),
22
+ conditions = [];
23
+ #mode = "development";
24
+ static schema = p({
25
+ fileExtensions: p.array(p.string).optional(),
26
+ spa: p.boolean.default(true),
27
+ ssr: p.boolean.default(true),
30
28
  });
31
29
  static options = FrontendModule.schema.infer;
32
30
  static input = FrontendModule.schema.input;
@@ -44,12 +42,14 @@ export default class FrontendModule extends Module {
44
42
  return `root_${this.name}`;
45
43
  }
46
44
  get ssr() {
47
- return this.#options.ssr;
45
+ return this.#options.ssr && (this.#mode !== "development" || !this.client);
48
46
  }
49
47
  get spa() {
50
48
  return this.#options.spa;
51
49
  }
52
50
  #load(name, props, app) {
51
+ if (!this.ssr)
52
+ return { view: null, name, props };
53
53
  const view = app.loadView(name);
54
54
  return { view, name, props };
55
55
  }
@@ -75,7 +75,7 @@ export default class FrontendModule extends Module {
75
75
  };
76
76
  }
77
77
  normalize(name) {
78
- return normalize(name);
78
+ return normalize(name, this.name);
79
79
  }
80
80
  respond = (view, props = {}, options = {}) => async (app, { as_layout, layouts = [] } = {}, request) => {
81
81
  if (as_layout) {
@@ -95,15 +95,16 @@ export default class FrontendModule extends Module {
95
95
  };
96
96
  const $props = this.layouts
97
97
  ? {
98
- views: await map(views, ({ name }) => normalize(name)),
98
+ views: await map(views, ({ name }) => this.normalize(name)),
99
99
  props: views.map(c => c.props),
100
100
  request: $request,
101
101
  }
102
102
  : { props, request: $request };
103
103
  const client = {
104
- view: this.layouts ? "root" : await normalize(view),
104
+ view: this.layouts ? "root" : await this.normalize(view),
105
105
  spa: this.spa,
106
106
  ssr: this.ssr,
107
+ mode: app.mode,
107
108
  ...$props,
108
109
  };
109
110
  if (this.spa && request.headers.get("Accept") === APPLICATION_JSON) {
@@ -118,10 +119,14 @@ export default class FrontendModule extends Module {
118
119
  status: options.status ?? Status.OK,
119
120
  });
120
121
  }
122
+ if (!this.ssr) {
123
+ const { head } = await this.#render({ view: null, props: {} }, client, app);
124
+ return app.view({ body: "<div id=\"app\"></div>", head, ...options });
125
+ }
121
126
  try {
122
127
  const server = this.layouts
123
128
  ? {
124
- view: app.loadView(`${this.rootname}.js`),
129
+ view: app.loadView(this.rootname),
125
130
  props: {
126
131
  views: views.map(c => c.view),
127
132
  props: views.map(c => c.props),
@@ -147,14 +152,17 @@ export default class FrontendModule extends Module {
147
152
  }
148
153
  publish(app) {
149
154
  if (this.compile.client) {
150
- const { compile, css, fileExtensions, name, root } = this;
155
+ const { compile, css, fileExtensions, name, root, conditions } = this;
156
+ const _normalize = this.normalize.bind(this);
151
157
  if (this.client) {
152
- fileExtensions.forEach(fe => app.frontends.set(name, fe));
158
+ app.frontends.set(name, [...fileExtensions]);
159
+ conditions.forEach(condition => app.conditions.add(condition));
153
160
  }
154
- app.build.plugin({
161
+ app.plugin("client", {
155
162
  name,
156
163
  setup(build) {
157
164
  const resolveDir = app.root.path;
165
+ const css_cache = new Map();
158
166
  if (root !== undefined) {
159
167
  const filter = new RegExp(`^${name}:root`);
160
168
  build.onResolve({ filter }, ({ path }) => {
@@ -166,14 +174,12 @@ export default class FrontendModule extends Module {
166
174
  });
167
175
  }
168
176
  if (css !== undefined) {
169
- build.onResolve({ filter: css.filter }, ({ path }) => {
170
- return { namespace: `${name}css`, path };
177
+ build.onResolve({ filter: new RegExp(`^${name}:css:`) }, args => {
178
+ return { path: args.path, namespace: `${name}-css` };
171
179
  });
172
- build.onLoad({ filter: css.filter }, ({ path }) => {
173
- const contents = app.build.load(FileRef.webpath(path));
174
- return contents
175
- ? { contents, loader: "css", resolveDir: resolveDir }
176
- : null;
180
+ build.onLoad({ filter: /.*/, namespace: `${name}-css` }, args => {
181
+ const contents = css_cache.get(args.path);
182
+ return contents ? { contents, loader: "css" } : null;
177
183
  });
178
184
  }
179
185
  const views_filter = new RegExp(`^${name}:views`);
@@ -187,7 +193,7 @@ export default class FrontendModule extends Module {
187
193
  let contents = "";
188
194
  for (const view of views) {
189
195
  const { path } = view.debase(views_base, "/");
190
- contents += `export { default as ${await normalize(path)} }
196
+ contents += `export { default as ${await _normalize(path)} }
191
197
  from "#view/${path}";\n`;
192
198
  }
193
199
  return { contents, resolveDir: app.root.path };
@@ -195,16 +201,16 @@ export default class FrontendModule extends Module {
195
201
  const filter = new RegExp(`(${fileExtensions.map(e => e.replace(".", "\\.")).join("|")})$`);
196
202
  build.onLoad({ filter }, async (args) => {
197
203
  const file = new FileRef(args.path);
198
- // Compile file to JavaScript and potentially CSS
204
+ // compile file to JavaScript and potentially CSS
199
205
  const compiled = await compile.client(await file.text(), file, false);
200
206
  let contents = compiled.js;
201
207
  if (css
202
208
  && compiled.css !== null
203
209
  && compiled.css !== undefined
204
210
  && compiled.css !== "") {
205
- const path = FileRef.webpath(`${args.path}css`);
206
- app.build.save(path, compiled.css);
207
- contents += `\nimport "${path}";`;
211
+ const css_path = `${name}:css:${args.path}`;
212
+ css_cache.set(css_path, compiled.css);
213
+ contents += `\nimport "${css_path}";`;
208
214
  }
209
215
  return { contents };
210
216
  });
@@ -213,34 +219,28 @@ export default class FrontendModule extends Module {
213
219
  }
214
220
  }
215
221
  init(app, next) {
222
+ this.#mode = app.mode;
223
+ return next(app);
224
+ }
225
+ prebuild(app) {
216
226
  this.fileExtensions.forEach(e => {
217
227
  app.bind(e, async (file, { context }) => {
218
- assert(contexts.includes(context), `${this.name}: only components supported`);
228
+ if (context === "views" && !this.ssr)
229
+ return "";
230
+ // production: just compile to JS, don't bundle yet
219
231
  if (this.compile.server) {
220
- const code = await this.compile.server(await file.text(), file);
221
- const bundled = await bundle({
222
- code,
223
- source: file,
224
- root: app.root,
225
- extensions: this.fileExtensions,
226
- compile: async (s, f) => this.compile.server(s, f),
227
- bundle: app.config("bundle"),
228
- });
229
- return bundled;
232
+ return await this.compile.server(await file.text(), file);
230
233
  }
231
234
  return await file.text();
232
235
  });
233
236
  });
234
- return next(app);
235
237
  }
236
238
  async build(app, next) {
239
+ this.prebuild(app);
237
240
  // compile root server
238
241
  if (this.root !== undefined && this.compile.server !== undefined) {
239
- const filename = `${this.rootname}.js`;
240
- const root = await this.compile.server(this.root.create(app.depth(), app.i18n_active));
241
- const path = app.runpath(location.server, filename);
242
- await path.write(root);
243
- app.addRoot(path);
242
+ const source = await this.compile.server(this.root.create(app.depth(), app.i18n_active));
243
+ app.addRoot(this.rootname, source);
244
244
  }
245
245
  this.publish(app);
246
246
  return next(app);
@@ -1,4 +1,4 @@
1
- import type BuildApp from "#BuildApp";
1
+ import type BuildApp from "#build/App";
2
2
  import type { Plugin } from "esbuild";
3
3
  type Publish = (app: BuildApp, extension: string) => Plugin;
4
4
  export { Publish as default };
@@ -4,7 +4,7 @@ import type NextHandle from "#module/NextHandle";
4
4
  import type NextRoute from "#module/NextRoute";
5
5
  import type NextServe from "#module/NextServe";
6
6
  import type RequestFacade from "#request/RequestFacade";
7
- import type ServeApp from "#ServeApp";
7
+ import type ServeApp from "#serve/App";
8
8
  export default class I18NModule extends Module {
9
9
  #private;
10
10
  name: string;
@@ -70,7 +70,7 @@ export default class I18NModule extends Module {
70
70
  headers: {
71
71
  "Content-Length": String(0),
72
72
  },
73
- status: Status.NO_CONTENT
73
+ status: Status.NO_CONTENT,
74
74
  });
75
75
  // only accept configured locales
76
76
  if (!this.#configured(requested))
@@ -78,7 +78,7 @@ export default class I18NModule extends Module {
78
78
  headers: {
79
79
  "Content-Length": String(0),
80
80
  },
81
- status: Status.NO_CONTENT
81
+ status: Status.NO_CONTENT,
82
82
  });
83
83
  const header = cookie(COOKIE_NAME, requested, {
84
84
  secure: this.#secure,
@@ -1,20 +1,14 @@
1
1
  declare const _default: {
2
2
  readonly app_html: "app.html";
3
- readonly build: "build";
4
3
  readonly client: "client";
5
- readonly lib: "lib";
6
- readonly components: "components";
7
4
  readonly config: "config";
8
5
  readonly error_html: "error.html";
9
- readonly modules: "modules";
10
6
  readonly pages: "pages";
11
7
  readonly routes: "routes";
12
- readonly server: "server";
13
8
  readonly static: "static";
14
9
  readonly stores: "stores";
15
10
  readonly locales: "locales";
16
11
  readonly views: "views";
17
- readonly hooks: "hooks";
18
12
  };
19
13
  export default _default;
20
14
  //# sourceMappingURL=location.d.ts.map
@@ -1,26 +1,16 @@
1
1
  export default {
2
2
  // default rendering template
3
3
  app_html: "app.html",
4
- // build environment
5
- build: "build",
6
4
  // client build
7
5
  client: "client",
8
- // component library
9
- lib: "lib",
10
- // renderable components
11
- components: "components",
12
6
  // config
13
7
  config: "config",
14
8
  // error rendering template
15
9
  error_html: "error.html",
16
- // custom modules
17
- modules: "modules",
18
10
  // HTML pages
19
11
  pages: "pages",
20
12
  // hierarchical routes
21
13
  routes: "routes",
22
- // server build
23
- server: "server",
24
14
  // static assets
25
15
  static: "static",
26
16
  // stores
@@ -29,7 +19,5 @@ export default {
29
19
  locales: "locales",
30
20
  // views
31
21
  views: "views",
32
- // hooks
33
- hooks: "hooks",
34
22
  };
35
23
  //# sourceMappingURL=location.js.map
@@ -1,4 +1,4 @@
1
- import type BuildApp from "#BuildApp";
1
+ import type BuildApp from "#build/App";
2
2
  import type Hook from "#module/Hook";
3
3
  type BuildHook = Hook<BuildApp>;
4
4
  export type { BuildHook as default };
@@ -1,4 +1,4 @@
1
- import type BuildApp from "#BuildApp";
1
+ import type BuildApp from "#build/App";
2
2
  import type Next from "#module/Next";
3
3
  type NextBuild = Next<BuildApp>;
4
4
  export type { NextBuild as default };
@@ -1,5 +1,5 @@
1
1
  import type Next from "#module/Next";
2
- import type ServeApp from "#ServeApp";
2
+ import type ServeApp from "#serve/App";
3
3
  type NextServe = Next<ServeApp>;
4
4
  export type { NextServe as default };
5
5
  //# sourceMappingURL=NextServe.d.ts.map
@@ -0,0 +1,5 @@
1
+ import type FileRef from "@rcompat/fs/FileRef";
2
+ import type Dict from "@rcompat/type/Dict";
3
+ declare function resolve(root: FileRef, config_paths?: Dict<string[]>): Promise<any>;
4
+ export default resolve;
5
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1,30 @@
1
+ import fail from "#fail";
2
+ import log from "#log";
3
+ async function resolve(root, config_paths) {
4
+ const tsconfig_path = root.join("tsconfig.json");
5
+ if (await tsconfig_path.exists()) {
6
+ try {
7
+ let text = await tsconfig_path.text();
8
+ // strip JSONC features
9
+ text = text
10
+ .replace(/\/\*[\s\S]*?\*\//g, "")
11
+ .replace(/\/\/.*/g, "")
12
+ .replace(/,(\s*[}\]])/g, "$1");
13
+ const config = JSON.parse(text);
14
+ const ts_paths = config.compilerOptions?.paths ?? {};
15
+ if (config_paths !== undefined && Object.keys(ts_paths).length > 0) {
16
+ return fail("tsconfig.json exists with paths, remove config paths");
17
+ }
18
+ // merge with defaults (user paths override)
19
+ return { ...ts_paths };
20
+ }
21
+ catch {
22
+ log.warn("Failed to parse tsconfig.json, falling back to config");
23
+ }
24
+ }
25
+ if (config_paths !== undefined)
26
+ return config_paths;
27
+ return {};
28
+ }
29
+ export default resolve;
30
+ //# sourceMappingURL=paths.js.map
@@ -1,9 +1,9 @@
1
1
  import type App from "#App";
2
- import type BuildApp from "#BuildApp";
2
+ import type BuildApp from "#build/App";
3
3
  import type Module from "#Module";
4
4
  import type RequestFacade from "#request/RequestFacade";
5
5
  import type ResponseLike from "#response/ResponseLike";
6
- import type ServeApp from "#ServeApp";
6
+ import type ServeApp from "#serve/App";
7
7
  type HookInput = {
8
8
  build: BuildApp;
9
9
  handle: RequestFacade;
@@ -1,4 +1,4 @@
1
1
  import type RequestFacade from "#request/RequestFacade";
2
- import type ServeApp from "#ServeApp";
2
+ import type ServeApp from "#serve/App";
3
3
  export default function (app: ServeApp, partial_request: RequestFacade): Promise<Response>;
4
4
  //# sourceMappingURL=route.d.ts.map
@@ -1,16 +1,14 @@
1
1
  import log from "#log";
2
- import errorResponse from "#response/error";
3
- import jsonResponse from "#response/json";
2
+ import response_error from "#response/error";
3
+ import response_json from "#response/json";
4
4
  import respond from "#response/respond";
5
5
  import guard from "#route/guard";
6
6
  import Status from "@rcompat/http/Status";
7
7
  import ParseError from "pema/ParseError";
8
8
  async function reducer(hooks, request) {
9
9
  const [first, ...rest] = hooks;
10
- if (rest.length === 0) {
10
+ if (rest.length === 0)
11
11
  return await first(request, _ => new Response());
12
- }
13
- ;
14
12
  return await first(request, _ => reducer(rest, _));
15
13
  }
16
14
  ;
@@ -30,7 +28,7 @@ export default async function (app, partial_request) {
30
28
  try {
31
29
  const route = await app.route(partial_request);
32
30
  if (route === undefined) {
33
- return errorResponse()(app, {}, partial_request);
31
+ return response_error()(app, {}, partial_request);
34
32
  }
35
33
  const { errors, guards, handler, layouts } = route;
36
34
  errorRoute = errors[0];
@@ -45,7 +43,7 @@ export default async function (app, partial_request) {
45
43
  catch (error) {
46
44
  const request = partial_request;
47
45
  if (error instanceof ParseError) {
48
- return jsonResponse(error.toJSON(), { status: Status.BAD_REQUEST })(app);
46
+ return response_json(error.toJSON(), { status: Status.BAD_REQUEST })(app);
49
47
  }
50
48
  log.error(error);
51
49
  // the +error.js page itself could fail
@@ -53,7 +51,7 @@ export default async function (app, partial_request) {
53
51
  return respond(await errorRoute(request))(app, {}, request);
54
52
  }
55
53
  catch {
56
- return errorResponse()(app, {}, request);
54
+ return response_error()(app, {}, request);
57
55
  }
58
56
  }
59
57
  }
@@ -1,6 +1,6 @@
1
1
  import type View from "#frontend/View";
2
2
  import type RequestFacade from "#request/RequestFacade";
3
- import type ServeApp from "#ServeApp";
3
+ import type ServeApp from "#serve/App";
4
4
  import type Dict from "@rcompat/type/Dict";
5
5
  import type MaybePromise from "@rcompat/type/MaybePromise";
6
6
  type ResponseFunction = (app: ServeApp, transfer: Dict, request: RequestFacade) => MaybePromise<View | null | Response | undefined>;
@@ -1,4 +1,4 @@
1
- import type ServeApp from "#ServeApp";
1
+ import type ServeApp from "#serve/App";
2
2
  import type StreamSource from "@rcompat/fs/StreamSource";
3
3
  /**
4
4
  * Stream a binary response.
@@ -4,6 +4,6 @@
4
4
  * @param options response options
5
5
  * @return Response rendering function
6
6
  */
7
- declare const _default: (body: unknown, init?: ResponseInit) => (app: import("../ServeApp.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
7
+ declare const _default: (body: unknown, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
8
8
  export default _default;
9
9
  //# sourceMappingURL=json.d.ts.map
@@ -10,6 +10,6 @@ type Body = {
10
10
  * @param options response options
11
11
  * @return Response rendering function
12
12
  */
13
- declare const _default: (body: Body, init?: ResponseInit) => (app: import("../ServeApp.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
13
+ declare const _default: (body: Body, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
14
14
  export default _default;
15
15
  //# sourceMappingURL=sse.d.ts.map
@@ -4,6 +4,6 @@
4
4
  * @param options response options
5
5
  * @return Response rendering function
6
6
  */
7
- declare const _default: (body: string, init?: ResponseInit) => (app: import("../ServeApp.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
7
+ declare const _default: (body: string, init?: ResponseInit) => (app: import("../serve/App.js").default) => import("@rcompat/type/MaybePromise").default<Response>;
8
8
  export default _default;
9
9
  //# sourceMappingURL=text.d.ts.map
@@ -1,11 +1,8 @@
1
- import type ViewResponse from "#frontend/ViewResponse";
2
- /**
3
- * Render a view component using a frontend for the given filename extension
4
- * @param view path to view
5
- * @param props props for view
6
- * @param options rendering options
7
- * @return Response rendering function
8
- */
9
- declare const view: ViewResponse;
1
+ import type ViewOptions from "#frontend/ViewOptions";
2
+ import type Dict from "@rcompat/type/Dict";
3
+ import type ResponseFunction from "./ResponseFunction.js";
4
+ declare function view<Props>(component: (props: Props) => any, props: Props, options?: ViewOptions): ResponseFunction;
5
+ declare function view(component: () => any, props?: Dict, options?: ViewOptions): ResponseFunction;
6
+ declare function view(name: string, props?: Dict, options?: ViewOptions): ResponseFunction;
10
7
  export default view;
11
8
  //# sourceMappingURL=view.d.ts.map
@@ -9,7 +9,6 @@ const backmap = {
9
9
  htmx: "htmx",
10
10
  marko: "marko",
11
11
  md: "markdown",
12
- poly: "poly",
13
12
  solid: "solid",
14
13
  svelte: "svelte",
15
14
  voby: "voby",
@@ -24,7 +23,7 @@ function no_frontend(view) {
24
23
  const error = "No frontend for {0}";
25
24
  const fix = hasPkg ? ", did you configure {1}?" : "";
26
25
  const pkgname = hasPkg ? `@primate/${backmap[extension]}` : "";
27
- throw fail(`${error}${fix}`, view, pkgname);
26
+ return fail(`${error}${fix}`, view, pkgname);
28
27
  }
29
28
  /**
30
29
  * Render a view component using a frontend for the given filename extension
@@ -33,11 +32,16 @@ function no_frontend(view) {
33
32
  * @param options rendering options
34
33
  * @return Response rendering function
35
34
  */
36
- const view = (function viewResponse(name, props, options) {
37
- return (app, transfer, request) => extensions
38
- .map(extension => app.frontends[new FileRef(name)[extension]])
39
- .find(extension => extension !== undefined)?.(name, props, options)(app, transfer, request)
40
- ?? no_frontend(name);
41
- });
35
+ function view(name, props, options) {
36
+ const _name = name;
37
+ return async (app, transfer, request) => {
38
+ const found_view = extensions
39
+ .map(extension => app.frontends[new FileRef(_name)[extension]])
40
+ .find(extension => extension !== undefined)?.(_name, props, options)(app, transfer, request);
41
+ if (found_view !== undefined)
42
+ return found_view;
43
+ throw no_frontend(_name);
44
+ };
45
+ }
42
46
  export default view;
43
47
  //# sourceMappingURL=view.js.map
@@ -1,4 +1,4 @@
1
- import type ServeApp from "#ServeApp";
1
+ import type ServeApp from "#serve/App";
2
2
  import type MaybePromise from "@rcompat/type/MaybePromise";
3
3
  declare const _default: <T>(mime: string, mapper: (input: T) => BodyInit) => (body: T, init?: ResponseInit) => (app: ServeApp) => MaybePromise<Response>;
4
4
  export default _default;
@@ -1,6 +1,7 @@
1
1
  import type Verb from "#request/Verb";
2
2
  import type RouteHandler from "#route/Handler";
3
3
  import type RouteOptions from "#route/Options";
4
+ export declare const routes: string[];
4
5
  declare class Router {
5
6
  #private;
6
7
  push(route: string): void;
@@ -8,11 +9,11 @@ declare class Router {
8
9
  get active(): string | undefined;
9
10
  add(verb: Verb, handler: RouteHandler, options?: RouteOptions): void;
10
11
  get(path: string): {
11
- options?: {
12
+ head?: {
12
13
  handler: RouteHandler;
13
14
  options: RouteOptions;
14
15
  } | undefined;
15
- head?: {
16
+ options?: {
16
17
  handler: RouteHandler;
17
18
  options: RouteOptions;
18
19
  } | undefined;
@@ -1,17 +1,18 @@
1
1
  import assert from "@rcompat/assert";
2
2
  import is from "@rcompat/assert/is";
3
3
  import maybe from "@rcompat/assert/maybe";
4
+ const stack = [];
5
+ export const routes = stack;
4
6
  class Router {
5
7
  #routes = {};
6
- #stack = [];
7
8
  push(route) {
8
- this.#stack.push(route);
9
+ stack.push(route);
9
10
  }
10
11
  pop() {
11
- this.#stack.pop();
12
+ stack.pop();
12
13
  }
13
14
  get active() {
14
- return this.#stack.at(-1);
15
+ return stack.at(-1);
15
16
  }
16
17
  add(verb, handler, options = {}) {
17
18
  assert(this.active !== undefined);