@primate/core 0.2.3 → 0.3.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 (64) hide show
  1. package/lib/private/App.d.ts +7 -0
  2. package/lib/private/App.js +18 -12
  3. package/lib/private/Binder.d.ts +1 -1
  4. package/lib/private/BindingContext.d.ts +1 -1
  5. package/lib/private/BuildApp.d.ts +7 -1
  6. package/lib/private/BuildApp.js +35 -31
  7. package/lib/private/Loader.d.ts +1 -1
  8. package/lib/private/Loader.js +4 -3
  9. package/lib/private/ServeApp.d.ts +3 -2
  10. package/lib/private/ServeApp.js +27 -15
  11. package/lib/private/ServeInit.d.ts +1 -1
  12. package/lib/private/backend/TAG.d.ts +3 -0
  13. package/lib/private/backend/TAG.js +2 -0
  14. package/lib/private/builtin/DevModule.js +1 -3
  15. package/lib/private/client/Data.d.ts +1 -1
  16. package/lib/private/client/app.d.ts +2 -0
  17. package/lib/private/client/{App.js → app.js} +4 -2
  18. package/lib/private/client/spa/index.js +4 -0
  19. package/lib/private/database/Query.d.ts +3 -3
  20. package/lib/private/database/QueryBuilder.d.ts +2 -2
  21. package/lib/private/database/{DataRecord.d.ts → Schema.d.ts} +3 -3
  22. package/lib/private/database/Schema.js +3 -0
  23. package/lib/private/database/Store.d.ts +11 -11
  24. package/lib/private/frontend/Module.d.ts +2 -2
  25. package/lib/private/frontend/Module.js +47 -39
  26. package/lib/private/frontend/Render.d.ts +1 -1
  27. package/lib/private/frontend/ServerData.d.ts +2 -2
  28. package/lib/private/frontend/ServerView.d.ts +5 -0
  29. package/lib/private/frontend/ServerView.js +2 -0
  30. package/lib/private/frontend/View.d.ts +8 -0
  31. package/lib/private/frontend/View.js +2 -0
  32. package/lib/private/frontend/bundle-server.js +3 -3
  33. package/lib/private/hook/build.js +83 -69
  34. package/lib/private/i18n/Module.js +16 -3
  35. package/lib/private/location.d.ts +3 -0
  36. package/lib/private/location.js +6 -0
  37. package/lib/private/request/RequestBody.d.ts +8 -7
  38. package/lib/private/request/RequestBody.js +30 -14
  39. package/lib/private/response/ResponseFunction.d.ts +2 -2
  40. package/lib/private/response/redirect.js +5 -1
  41. package/lib/private/response/view.d.ts +3 -3
  42. package/lib/private/response/view.js +14 -12
  43. package/lib/private/route/wrap.d.ts +1 -5
  44. package/lib/private/route/wrap.js +4 -9
  45. package/lib/private/target/Manager.js +1 -1
  46. package/lib/private/target/web.js +0 -10
  47. package/lib/private/wasm/encode-request.js +25 -28
  48. package/lib/public/backend/TAG.d.ts +2 -0
  49. package/lib/public/backend/TAG.js +2 -0
  50. package/lib/public/client/app.d.ts +2 -0
  51. package/lib/public/client/app.js +2 -0
  52. package/lib/public/fail.d.ts +2 -0
  53. package/lib/public/fail.js +2 -0
  54. package/package.json +4 -4
  55. package/lib/private/client/App.d.ts +0 -4
  56. package/lib/private/database/DataRecord.js +0 -3
  57. package/lib/private/frontend/Component.d.ts +0 -8
  58. package/lib/private/frontend/Component.js +0 -2
  59. package/lib/private/frontend/ServerComponent.d.ts +0 -5
  60. package/lib/private/frontend/ServerComponent.js +0 -2
  61. package/lib/public/client/App.d.ts +0 -2
  62. package/lib/public/client/App.js +0 -2
  63. package/lib/public/route/wrap.d.ts +0 -2
  64. package/lib/public/route/wrap.js +0 -2
@@ -13,6 +13,7 @@ export default class App {
13
13
  app_html: "app.html";
14
14
  build: "build";
15
15
  client: "client";
16
+ lib: "lib";
16
17
  components: "components";
17
18
  config: "config";
18
19
  error_html: "error.html";
@@ -23,6 +24,8 @@ export default class App {
23
24
  static: "static";
24
25
  stores: "stores";
25
26
  locales: "locales";
27
+ views: "views";
28
+ hooks: "hooks";
26
29
  };
27
30
  get target(): TargetManager;
28
31
  get root(): FileRef;
@@ -30,6 +33,7 @@ export default class App {
30
33
  readonly app_html: FileRef;
31
34
  readonly build: FileRef;
32
35
  readonly client: FileRef;
36
+ readonly lib: FileRef;
33
37
  readonly components: FileRef;
34
38
  readonly config: FileRef;
35
39
  readonly error_html: FileRef;
@@ -40,11 +44,14 @@ export default class App {
40
44
  readonly static: FileRef;
41
45
  readonly stores: FileRef;
42
46
  readonly locales: FileRef;
47
+ readonly views: FileRef;
48
+ readonly hooks: FileRef;
43
49
  };
44
50
  get mode(): Mode;
45
51
  get modules(): Module[];
46
52
  get extensions(): string[];
47
53
  binder(file: FileRef): Binder | undefined;
54
+ basename(file: FileRef, directory: FileRef): string;
48
55
  get<T>(key: symbol): T;
49
56
  set(key: symbol, value: unknown): void;
50
57
  config<P extends string>(path: P): ReturnType<typeof get<Config, P>>;
@@ -1,7 +1,6 @@
1
1
  import fail from "#fail";
2
2
  import location from "#location";
3
3
  import reducer from "#reducer";
4
- import wrap from "#route/wrap";
5
4
  import TargetManager from "#target/Manager";
6
5
  import assert from "@rcompat/assert";
7
6
  import transform from "@rcompat/build/sync/transform";
@@ -23,30 +22,26 @@ const BIND_CONTEXTS = [
23
22
  "config",
24
23
  "routes",
25
24
  "components",
25
+ "views",
26
26
  "stores",
27
27
  "locales",
28
28
  "modules",
29
29
  ];
30
30
  function generate_bindings(_app) {
31
31
  return {
32
- ".js": async (file, { build, context }) => {
32
+ ".js": (file, { context }) => {
33
33
  const error = `js: only ${toContextString(BIND_CONTEXTS)} are supported`;
34
34
  assert(BIND_CONTEXTS.includes(context), error);
35
- const code = context === "routes"
36
- ? wrap(await file.text(), file, build)
37
- : await file.text();
38
- await file.append(".js").write(code);
35
+ return file.text();
39
36
  },
40
- ".json": () => {
37
+ ".json": (file) => {
41
38
  // just copy the JSON for now
39
+ return file.text();
42
40
  },
43
- ".ts": async (file, { build, context }) => {
41
+ ".ts": async (file, { context }) => {
44
42
  const error = `ts: only ${toContextString(BIND_CONTEXTS)} are supported`;
45
43
  assert(BIND_CONTEXTS.includes(context), error);
46
- const code = context === "routes"
47
- ? wrap(compile(await file.text()), file, build)
48
- : compile(await file.text());
49
- await file.append(".js").write(code);
44
+ return compile(await file.text());
50
45
  },
51
46
  };
52
47
  }
@@ -104,6 +99,17 @@ export default class App {
104
99
  .toSorted(([a], [b]) => a.length > b.length ? -1 : 1)
105
100
  .find(([extension]) => file.path.endsWith(extension))?.[1];
106
101
  }
102
+ basename(file, directory) {
103
+ const relative = file.debase(directory);
104
+ const extensions = this.extensions
105
+ .toSorted((a, b) => a.length > b.length ? -1 : 1);
106
+ for (const extension of extensions) {
107
+ if (relative.path.endsWith(extension)) {
108
+ return relative.path.slice(1, -extension.length);
109
+ }
110
+ }
111
+ return relative.bare().path.slice(1);
112
+ }
107
113
  get(key) {
108
114
  return this.#kv.get(key);
109
115
  }
@@ -8,6 +8,6 @@ type Options = {
8
8
  };
9
9
  context: BindingContext;
10
10
  };
11
- type Binder = (file: FileRef, options: Options) => MaybePromise<void>;
11
+ type Binder = (file: FileRef, options: Options) => MaybePromise<string>;
12
12
  export type { Binder as default };
13
13
  //# sourceMappingURL=Binder.d.ts.map
@@ -1,3 +1,3 @@
1
- type BindingContext = "components" | "config" | "locales" | "modules" | "routes" | "stores";
1
+ type BindingContext = "components" | "views" | "config" | "locales" | "modules" | "routes" | "stores" | "hooks";
2
2
  export type { BindingContext as default };
3
3
  //# sourceMappingURL=BindingContext.d.ts.map
@@ -3,6 +3,8 @@ import type BindingContext from "#BindingContext";
3
3
  import Build from "@rcompat/build";
4
4
  import type FileRef from "@rcompat/fs/FileRef";
5
5
  import type MaybePromise from "@rcompat/type/MaybePromise";
6
+ type Loader = (source: string, file: FileRef) => MaybePromise<string>;
7
+ type Resolver = (basename: string, file: FileRef) => string;
6
8
  export default class BuildApp extends App {
7
9
  #private;
8
10
  frontends: Map<string, string>;
@@ -15,9 +17,13 @@ export default class BuildApp extends App {
15
17
  done(fn: () => void): void;
16
18
  cleanup(): void;
17
19
  export(code: string): void;
18
- stage(directory: FileRef, context: BindingContext, importer: (file: FileRef) => MaybePromise<string>): Promise<void>;
20
+ compile(directory: FileRef, context: BindingContext, options?: {
21
+ loader?: Loader;
22
+ resolver?: Resolver;
23
+ }): Promise<void>;
19
24
  depth(): number;
20
25
  get i18n_active(): boolean;
21
26
  set i18n_active(active: boolean);
22
27
  }
28
+ export {};
23
29
  //# sourceMappingURL=BuildApp.d.ts.map
@@ -29,11 +29,15 @@ export default class BuildApp extends App {
29
29
  contents: "",
30
30
  resolveDir: this.root.path,
31
31
  },
32
+ conditions: ["style", "browser", "default", "module"],
32
33
  resolveExtensions: [".ts", ".js", ...extensions],
33
34
  tsconfigRaw: {
34
35
  compilerOptions: {
35
36
  baseUrl: "${configDir}",
36
37
  paths: {
38
+ "#view/*": [
39
+ "views/*", ...extensions.map(e => `views/*${e}`),
40
+ ],
37
41
  "#component/*": [
38
42
  "components/*", ...extensions.map(e => `components/*${e}`),
39
43
  ],
@@ -72,41 +76,41 @@ export default class BuildApp extends App {
72
76
  export(code) {
73
77
  this.build.export(code);
74
78
  }
75
- async stage(directory, context, importer) {
76
- if (!await directory.exists()) {
79
+ async compile(directory, context, options = {}) {
80
+ if (!await directory.exists())
77
81
  return;
82
+ const files = await directory.collect(({ path }) => this.extensions.some(e => path.endsWith(e)) && !path.endsWith(".d.ts"));
83
+ for (const file of files) {
84
+ await this.#compileFile(file, context, directory, options);
78
85
  }
79
- if (!await this.runpath("stage").exists()) {
80
- await this.runpath("stage").create();
81
- }
82
- const base = this.runpath("stage", context);
83
- if (!await base.exists()) {
84
- await base.create();
86
+ }
87
+ async #compileFile(file, context, directory, options) {
88
+ const binder = this.binder(file);
89
+ if (binder === undefined) {
90
+ log.info("no binder found for {0}", file.path);
91
+ return;
85
92
  }
86
- const build_directory = this.runpath(directory.name);
87
- await build_directory.create();
88
- for (const file of await directory.collect(({ path }) => /^.*$/.test(path))) {
89
- const debased = file.debase(directory);
90
- const target = base.join(debased);
91
- if (!await target.directory.exists()) {
92
- await target.directory.create({ recursive: true });
93
- }
94
- const binder = this.binder(file);
95
- if (binder === undefined) {
96
- log.info("no binder found for {0}", file.path);
97
- continue;
98
- }
99
- // copy to build/stage/${directory}
100
- await file.copy(target);
101
- await binder(target, {
102
- build: { id: this.id, stage: this.runpath("stage") },
103
- context,
104
- });
105
- // actual
106
- const runtime_file = build_directory.join(debased.bare(".js"));
107
- await runtime_file.directory.create();
108
- runtime_file.write(await importer(debased));
93
+ // call the binder to compile
94
+ const compiled = await binder(file, {
95
+ build: { id: this.id, stage: this.runpath("stage") },
96
+ context,
97
+ });
98
+ if (!compiled) {
99
+ log.info("binder returned empty output for {0}", file.path);
100
+ return;
109
101
  }
102
+ // apply loader if provided
103
+ const transformed = options.loader
104
+ ? await options.loader(compiled, file)
105
+ : compiled;
106
+ const basename = this.basename(file, directory);
107
+ const resolved = options.resolver
108
+ ? options.resolver(basename, file)
109
+ : basename;
110
+ const target = this.runpath(context, `${resolved}.js`);
111
+ // write to final location
112
+ await target.directory.create({ recursive: true });
113
+ await target.write(transformed);
110
114
  }
111
115
  depth() {
112
116
  return this.get(s_layout_depth);
@@ -10,7 +10,7 @@ export default class Loader {
10
10
  constructor(init: Init);
11
11
  get static_root(): string;
12
12
  page(name?: string): string;
13
- asset(file: FileRef): Response;
13
+ asset(file: FileRef): Promise<Response>;
14
14
  serve(pathname: string): Promise<Response | undefined>;
15
15
  }
16
16
  export {};
@@ -21,10 +21,11 @@ export default class Loader {
21
21
  }
22
22
  return this.#pages[name];
23
23
  }
24
- asset(file) {
24
+ async asset(file) {
25
25
  return new Response(file.stream(), {
26
26
  headers: {
27
27
  "Content-Type": resolve(file.name),
28
+ "Content-Length": String(await file.byteLength()),
28
29
  },
29
30
  status: Status.OK,
30
31
  });
@@ -32,13 +33,13 @@ export default class Loader {
32
33
  async serve(pathname) {
33
34
  const client_file = this.#root.join(`client/${pathname}`);
34
35
  if (await client_file.isFile()) {
35
- return this.asset(client_file);
36
+ return await this.asset(client_file);
36
37
  }
37
38
  if (pathname.startsWith(this.static_root)) {
38
39
  const assetname = pathname.slice(this.static_root.length);
39
40
  const static_file = this.#root.join(`static/${assetname}`);
40
41
  if (await static_file.isFile()) {
41
- return this.asset(static_file);
42
+ return await this.asset(static_file);
42
43
  }
43
44
  }
44
45
  }
@@ -1,6 +1,6 @@
1
1
  import App from "#App";
2
2
  import type Asset from "#asset/Asset";
3
- import type ServerComponent from "#frontend/ServerComponent";
3
+ import type ServerView from "#frontend/ServerView";
4
4
  import type ViewOptions from "#frontend/ViewOptions";
5
5
  import type ViewResponse from "#frontend/ViewResponse";
6
6
  import type I18NConfig from "#i18n/Config";
@@ -41,12 +41,13 @@ export default class ServeApp extends App {
41
41
  };
42
42
  get stores(): Dict;
43
43
  get i18n(): I18NConfig | undefined;
44
- component<T = ServerComponent>(name: string): T;
44
+ loadView<T = ServerView>(name: string): T;
45
45
  headers(csp?: {}): {
46
46
  "Content-Security-Policy"?: string | undefined;
47
47
  };
48
48
  render(content: Omit<FullViewOptions, keyof ResponseInit>): string;
49
49
  page(page?: string): string;
50
+ body_length(body: BodyInit | null): number;
50
51
  respond(body: BodyInit | null, init?: ResponseInit): Response;
51
52
  view(options: FullViewOptions): Response;
52
53
  media(content_type: string, response?: ResponseInit): ResponseInit;
@@ -20,6 +20,7 @@ import TEXT_HTML from "@rcompat/http/mime/text/html";
20
20
  import serve from "@rcompat/http/serve";
21
21
  import Status from "@rcompat/http/Status";
22
22
  import entries from "@rcompat/record/entries";
23
+ import utf8ByteLength from "@rcompat/string/utf8-bytelength";
23
24
  import pema from "pema";
24
25
  import record from "pema/record";
25
26
  import string from "pema/string";
@@ -44,17 +45,17 @@ const render_head = (assets, head) => {
44
45
  const fonts = assets.filter(asset => asset.src?.endsWith(".woff2"));
45
46
  const rest = assets.filter(asset => !asset.src?.endsWith(".woff2")
46
47
  && asset.type !== "js");
47
- return rest.toSorted(({ type }) => -1 * Number(type === "importmap"))
48
+ return fonts.map(font => tags.font({ href: font.src, type: "font/woff2" })).join("\n").concat("\n", rest
48
49
  .map(({ code, inline, integrity, src, type }) => type === "style"
49
50
  ? tags.style({ code, href: src, inline })
50
- : tags.script({ code, inline, integrity, src, type })).join("\n").concat("\n", head ?? "").concat("\n", fonts.map(font => tags.font({ href: font.src, type: "font/woff2" })).join("\n"));
51
+ : tags.script({ code, inline, integrity, src, type })).join("\n")).concat("\n", head ?? "");
51
52
  };
52
53
  const s_http = Symbol("s_http");
53
54
  ;
54
55
  export default class ServeApp extends App {
55
56
  #init;
56
57
  #server;
57
- #components;
58
+ #views;
58
59
  #csp = {};
59
60
  #assets = [];
60
61
  #stores;
@@ -65,7 +66,7 @@ export default class ServeApp extends App {
65
66
  constructor(rootfile, init) {
66
67
  super(new FileRef(rootfile).directory, init.config, init.mode);
67
68
  this.#init = init;
68
- this.#components = Object.fromEntries(init.components ?? []);
69
+ this.#views = Object.fromEntries(init.views ?? []);
69
70
  this.#stores = Object.fromEntries((init.stores?.map(([k, s]) => [k, s.default])) ?? []);
70
71
  const http = this.#init.config.http;
71
72
  this.#i18n_config = init.i18n_config;
@@ -130,13 +131,14 @@ export default class ServeApp extends App {
130
131
  get i18n() {
131
132
  return this.#i18n_config;
132
133
  }
133
- component(name) {
134
- const base = name.slice(0, name.lastIndexOf((".")));
135
- const component = this.#components[base];
136
- if (component === undefined) {
137
- throw fail("missing component {0}", `${location.components}/${name}`);
134
+ loadView(name) {
135
+ const f = new FileRef(name);
136
+ const base = f.path.slice(0, -f.fullExtension.length);
137
+ const view = this.#views[base];
138
+ if (view === undefined) {
139
+ throw fail("missing view component {0}", `${location.views}/${name}`);
138
140
  }
139
- return (component.default ?? component);
141
+ return (view.default ?? view);
140
142
  }
141
143
  ;
142
144
  headers(csp = {}) {
@@ -165,14 +167,20 @@ export default class ServeApp extends App {
165
167
  page(page) {
166
168
  return this.loader().page(page);
167
169
  }
170
+ body_length(body) {
171
+ return typeof body === "string" ? utf8ByteLength(body) : 0;
172
+ }
168
173
  respond(body, init) {
169
174
  const { headers, status } = pema({
170
175
  headers: record(string, string),
171
176
  status: uint.values(Status).default(Status.OK),
172
177
  }).parse(init);
178
+ const body_length = this.body_length(body);
173
179
  return new Response(body, {
174
180
  headers: {
175
- "Content-Type": TEXT_HTML, ...this.headers(), ...headers,
181
+ "Content-Type": TEXT_HTML,
182
+ ...this.headers(),
183
+ ...body_length ? { ...headers, "Content-Length": String(body_length) } : headers,
176
184
  }, status: status,
177
185
  });
178
186
  }
@@ -218,9 +226,7 @@ export default class ServeApp extends App {
218
226
  ;
219
227
  async start() {
220
228
  this.#assets = await Promise.all(this.#init.assets.map(async (asset) => {
221
- const code = asset.type === "importmap"
222
- ? JSON.stringify(asset.code, null, 2)
223
- : asset.code;
229
+ const code = asset.code;
224
230
  return {
225
231
  ...asset,
226
232
  code,
@@ -239,7 +245,13 @@ export default class ServeApp extends App {
239
245
  }
240
246
  catch (error) {
241
247
  log.error(error);
242
- return new Response(null, { status: Status.INTERNAL_SERVER_ERROR });
248
+ return new Response(null, {
249
+ headers: {
250
+ "Content-Length": String(0),
251
+ "Cache-Control": "no-cache",
252
+ },
253
+ status: Status.INTERNAL_SERVER_ERROR,
254
+ });
243
255
  }
244
256
  }, this.get(s_http));
245
257
  log.system("started {0}", this.url);
@@ -15,7 +15,7 @@ type BuildFiles = {
15
15
  };
16
16
  type ServeInit = {
17
17
  assets: Asset[];
18
- components?: [string, Import][];
18
+ views?: [string, Import][];
19
19
  stores?: [string, Import][];
20
20
  config: Config;
21
21
  files: BuildFiles;
@@ -0,0 +1,3 @@
1
+ declare const _default: "0.2";
2
+ export default _default;
3
+ //# sourceMappingURL=TAG.d.ts.map
@@ -0,0 +1,2 @@
1
+ export default "0.2";
2
+ //# sourceMappingURL=TAG.js.map
@@ -15,9 +15,7 @@ export default class DevModule extends Module {
15
15
  #reload_url;
16
16
  constructor(app) {
17
17
  super();
18
- const assets = app.assets
19
- .filter(asset => asset.type !== "importmap")
20
- .map(asset => asset.src);
18
+ const assets = app.assets.map(asset => asset.src);
21
19
  const http = app.config("http");
22
20
  this.#paths = ([reload_path]).concat(assets);
23
21
  this.#reload_url = `http://${http.host}:${reload_defaults.port}`;
@@ -1,6 +1,6 @@
1
1
  import type Dict from "@rcompat/type/Dict";
2
2
  type ClientData<T extends Dict = Dict> = {
3
- component: string;
3
+ view: string;
4
4
  request: Dict;
5
5
  spa: boolean;
6
6
  ssr: boolean;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app.d.ts.map
@@ -1,6 +1,6 @@
1
1
  // @ts-expect-error esbuild vfs
2
2
  import * as frontends from "#frontends";
3
- export default class ClientApp {
3
+ class ClientApp {
4
4
  start() {
5
5
  const hydration = document.getElementById("hydration")?.textContent;
6
6
  if (hydration !== undefined) {
@@ -9,4 +9,6 @@ export default class ClientApp {
9
9
  }
10
10
  }
11
11
  }
12
- //# sourceMappingURL=App.js.map
12
+ const app = new ClientApp();
13
+ app.start();
14
+ //# sourceMappingURL=app.js.map
@@ -138,6 +138,10 @@ const go = async (href, updater, event) => {
138
138
  // external redirect
139
139
  };
140
140
  export default (updater) => {
141
+ if (document.contentType === "application/json") {
142
+ location.reload();
143
+ return;
144
+ }
141
145
  globalThis.addEventListener("pageshow", event => {
142
146
  if (event.persisted) {
143
147
  globalThis.location.reload();
@@ -1,14 +1,14 @@
1
+ import type Schema from "#database/Schema";
1
2
  import type StoreSchema from "pema/StoreSchema";
2
- import type DataRecord from "#database/DataRecord";
3
3
  type X<T> = {
4
4
  [K in keyof T]: T[K];
5
5
  } & {};
6
6
  type Filter<T, P extends keyof T> = X<Pick<T, Extract<P, keyof T>>>;
7
- export default class Query<T extends StoreSchema, P extends keyof DataRecord<T> = keyof DataRecord<T>> {
7
+ export default class Query<T extends StoreSchema, P extends keyof Schema<T> = keyof Schema<T>> {
8
8
  #private;
9
9
  constructor(schema: T);
10
10
  select<K extends P>(...projection: K[]): Query<T, K>;
11
- run(): Promise<Filter<DataRecord<T>, P>>;
11
+ run(): Promise<Filter<Schema<T>, P>>;
12
12
  }
13
13
  export {};
14
14
  //# sourceMappingURL=Query.d.ts.map
@@ -1,11 +1,11 @@
1
- import type DataRecord from "#database/DataRecord";
1
+ import type Schema from "#database/Schema";
2
2
  import type InferStoreOut from "pema/InferStoreOut";
3
3
  import type StoreSchema from "pema/StoreSchema";
4
4
  type X<T> = {
5
5
  [K in keyof T]: T[K];
6
6
  } & {};
7
7
  type Filter<T, P extends keyof T> = X<Pick<T, Extract<P, keyof T>>>;
8
- export default abstract class QueryBuilder<T extends StoreSchema, P extends keyof DataRecord<T> = keyof DataRecord<T>> {
8
+ export default abstract class QueryBuilder<T extends StoreSchema, P extends keyof Schema<T> = keyof Schema<T>> {
9
9
  abstract where(criteria: any): QueryBuilder<T>;
10
10
  abstract select<K extends P>(...fields: K[]): QueryBuilder<T, K>;
11
11
  abstract run(): Promise<Filter<InferStoreOut<T>, P>>;
@@ -3,6 +3,6 @@ import type StoreSchema from "pema/StoreSchema";
3
3
  type X<T> = {
4
4
  [K in keyof T]: T[K];
5
5
  } & {};
6
- type DataRecord<T extends StoreSchema> = X<InferStoreOut<T>>;
7
- export type { DataRecord as default };
8
- //# sourceMappingURL=DataRecord.d.ts.map
6
+ type Schema<T extends StoreSchema> = X<InferStoreOut<T>>;
7
+ export type { Schema as default };
8
+ //# sourceMappingURL=Schema.d.ts.map
@@ -0,0 +1,3 @@
1
+ ;
2
+ export {};
3
+ //# sourceMappingURL=Schema.js.map
@@ -1,6 +1,6 @@
1
1
  import type Changes from "#database/Changes";
2
2
  import type Database from "#database/Database";
3
- import type DataRecord from "#database/DataRecord";
3
+ import type Schema from "#database/Schema";
4
4
  import wrap from "#database/symbol/wrap";
5
5
  import type Types from "#database/Types";
6
6
  import type Dict from "@rcompat/type/Dict";
@@ -48,7 +48,7 @@ type Config = {
48
48
  export default class DatabaseStore<S extends StoreSchema> implements Serializable {
49
49
  #private;
50
50
  [wrap]: (name: string, database: Database) => this;
51
- readonly R: DataRecord<S>;
51
+ readonly Schema: Schema<S>;
52
52
  constructor(schema: S, config?: Config);
53
53
  static new<S extends StoreSchema>(schema: S, config?: Config): DatabaseStore<S>;
54
54
  get schema(): {
@@ -82,14 +82,14 @@ export default class DatabaseStore<S extends StoreSchema> implements Serializabl
82
82
  * @throws If no record with the given id exists.
83
83
  * @returns The record for the given id.
84
84
  */
85
- get(id: Id): Promise<DataRecord<S>>;
85
+ get(id: Id): Promise<Schema<S>>;
86
86
  /**
87
87
  * Try to get a record by id.
88
88
  *
89
89
  * @param id Record id.
90
90
  * @returns The record if found, otherwise `undefined`.
91
91
  */
92
- try(id: Id): Promise<DataRecord<S> | undefined>;
92
+ try(id: Id): Promise<Schema<S> | undefined>;
93
93
  /**
94
94
  * Insert a single record.
95
95
  *
@@ -100,7 +100,7 @@ export default class DatabaseStore<S extends StoreSchema> implements Serializabl
100
100
  * @throws If a record with the same id already exists or validation fails.
101
101
  * @returns The inserted record with id.
102
102
  */
103
- insert(record: Insertable<S>): Promise<DataRecord<S>>;
103
+ insert(record: Insertable<S>): Promise<Schema<S>>;
104
104
  /**
105
105
  * Update a single record.
106
106
  *
@@ -148,17 +148,17 @@ export default class DatabaseStore<S extends StoreSchema> implements Serializabl
148
148
  * @param options Query options.
149
149
  * @returns Matching records, possibly projected/limited/sorted.
150
150
  */
151
- find(criteria: Criteria<S>): Promise<Filter<DataRecord<S>>[]>;
151
+ find(criteria: Criteria<S>): Promise<Filter<Schema<S>>[]>;
152
152
  find(criteria: Criteria<S>, options: {
153
153
  limit?: number;
154
154
  select?: undefined;
155
- sort?: Sort<DataRecord<S>>;
156
- }): Promise<Filter<DataRecord<S>>[]>;
157
- find<F extends Select<DataRecord<S>>>(criteria: Criteria<S>, options?: {
155
+ sort?: Sort<Schema<S>>;
156
+ }): Promise<Filter<Schema<S>>[]>;
157
+ find<F extends Select<Schema<S>>>(criteria: Criteria<S>, options?: {
158
158
  limit?: number;
159
159
  select?: F;
160
- sort?: Sort<DataRecord<S>>;
161
- }): Promise<Filter<DataRecord<S>, F>[]>;
160
+ sort?: Sort<Schema<S>>;
161
+ }): Promise<Filter<Schema<S>, F>[]>;
162
162
  toJSON(): {
163
163
  type: "object";
164
164
  properties: Dict<import("pema/StoreType").Serialized>;
@@ -1,7 +1,7 @@
1
1
  import type App from "#App";
2
2
  import type BuildApp from "#BuildApp";
3
3
  import type Render from "#frontend/Render";
4
- import type ServerComponent from "#frontend/ServerComponent";
4
+ import type ServerView from "#frontend/ServerView";
5
5
  import type ViewResponse from "#frontend/ViewResponse";
6
6
  import Module from "#Module";
7
7
  import type Next from "#module/Next";
@@ -10,7 +10,7 @@ import type NextServe from "#module/NextServe";
10
10
  import type ServeApp from "#ServeApp";
11
11
  import FileRef from "@rcompat/fs/FileRef";
12
12
  import type MaybePromise from "@rcompat/type/MaybePromise";
13
- export default abstract class FrontendModule<S = ServerComponent> extends Module {
13
+ export default abstract class FrontendModule<S = ServerView> extends Module {
14
14
  #private;
15
15
  abstract client: boolean;
16
16
  abstract layouts: boolean;