@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,5 +1,5 @@
1
- import type Binder from "#Binder";
2
1
  import type Config from "#config/Config";
2
+ import type Flags from "#Flags";
3
3
  import type Mode from "#Mode";
4
4
  import type Module from "#Module";
5
5
  import TargetManager from "#target/Manager";
@@ -7,55 +7,41 @@ import type FileRef from "@rcompat/fs/FileRef";
7
7
  import get from "@rcompat/record/get";
8
8
  export default class App {
9
9
  #private;
10
- constructor(root: FileRef, config: Config, mode: Mode);
11
- init(target: string): Promise<App>;
10
+ constructor(root: FileRef, config: Config, flags: typeof Flags.infer);
11
+ init(): Promise<App>;
12
12
  get location(): {
13
13
  app_html: "app.html";
14
- build: "build";
15
14
  client: "client";
16
- lib: "lib";
17
- components: "components";
18
15
  config: "config";
19
16
  error_html: "error.html";
20
- modules: "modules";
21
17
  pages: "pages";
22
18
  routes: "routes";
23
- server: "server";
24
19
  static: "static";
25
20
  stores: "stores";
26
21
  locales: "locales";
27
22
  views: "views";
28
- hooks: "hooks";
29
23
  };
30
24
  get target(): TargetManager;
31
25
  get root(): FileRef;
32
26
  get path(): {
33
27
  readonly app_html: FileRef;
34
- readonly build: FileRef;
35
28
  readonly client: FileRef;
36
- readonly lib: FileRef;
37
- readonly components: FileRef;
38
29
  readonly config: FileRef;
39
30
  readonly error_html: FileRef;
40
- readonly modules: FileRef;
41
31
  readonly pages: FileRef;
42
32
  readonly routes: FileRef;
43
- readonly server: FileRef;
44
33
  readonly static: FileRef;
45
34
  readonly stores: FileRef;
46
35
  readonly locales: FileRef;
47
36
  readonly views: FileRef;
48
- readonly hooks: FileRef;
37
+ } & {
38
+ build: FileRef;
49
39
  };
50
40
  get mode(): Mode;
51
41
  get modules(): Module[];
52
- get extensions(): string[];
53
- binder(file: FileRef): Binder | undefined;
54
- basename(file: FileRef, directory: FileRef): string;
55
42
  get<T>(key: symbol): T;
56
43
  set(key: symbol, value: unknown): void;
57
44
  config<P extends string>(path: P): ReturnType<typeof get<Config, P>>;
58
45
  runpath(...directories: string[]): FileRef;
59
- bind(extension: string, binder: Binder): void;
60
46
  }
61
47
  //# sourceMappingURL=App.d.ts.map
@@ -2,49 +2,8 @@ import fail from "#fail";
2
2
  import location from "#location";
3
3
  import reducer from "#reducer";
4
4
  import TargetManager from "#target/Manager";
5
- import assert from "@rcompat/assert";
6
- import transform from "@rcompat/build/sync/transform";
7
5
  import entries from "@rcompat/record/entries";
8
6
  import get from "@rcompat/record/get";
9
- const ts_options = {
10
- loader: "ts",
11
- tsconfigRaw: {
12
- compilerOptions: {
13
- experimentalDecorators: true,
14
- },
15
- },
16
- };
17
- const compile = (code) => transform(code, ts_options).code;
18
- const toContextString = (array) => array
19
- .map(member => member.endsWith("s") ? member.slice(0, -1) : member)
20
- .join(", ");
21
- const BIND_CONTEXTS = [
22
- "config",
23
- "routes",
24
- "components",
25
- "views",
26
- "stores",
27
- "locales",
28
- "modules",
29
- ];
30
- function generate_bindings(_app) {
31
- return {
32
- ".js": (file, { context }) => {
33
- const error = `js: only ${toContextString(BIND_CONTEXTS)} are supported`;
34
- assert(BIND_CONTEXTS.includes(context), error);
35
- return file.text();
36
- },
37
- ".json": (file) => {
38
- // just copy the JSON for now
39
- return file.text();
40
- },
41
- ".ts": async (file, { context }) => {
42
- const error = `ts: only ${toContextString(BIND_CONTEXTS)} are supported`;
43
- assert(BIND_CONTEXTS.includes(context), error);
44
- return compile(await file.text());
45
- },
46
- };
47
- }
48
7
  const doubled = (set) => set.find((part, i, array) => array.filter((_, j) => i !== j).includes(part)) ?? "";
49
8
  export default class App {
50
9
  #path;
@@ -53,24 +12,30 @@ export default class App {
53
12
  #modules;
54
13
  #kv = new Map();
55
14
  #mode;
56
- #bindings;
57
15
  #target;
58
- constructor(root, config, mode) {
16
+ #target_name;
17
+ constructor(root, config, flags) {
18
+ if (Object.values(location).includes(flags.dir)) {
19
+ throw fail("cannot build to {0} - reserved directory", flags.dir);
20
+ }
59
21
  this.#root = root;
60
22
  this.#config = config;
61
23
  this.#modules = config.modules?.flat(10) ?? [];
62
- this.#path = entries(location).valmap(([, path]) => root.join(path)).get();
63
- this.#mode = mode;
24
+ this.#path = entries({
25
+ ...location,
26
+ build: flags.dir,
27
+ }).valmap(([, path]) => root.join(path)).get();
28
+ this.#mode = flags.mode;
64
29
  this.#target = new TargetManager(this);
65
- this.#bindings = Object.entries(generate_bindings(this));
30
+ this.#target_name = flags.target;
66
31
  }
67
- async init(target) {
32
+ async init() {
68
33
  const names = this.#modules.map(({ name }) => name);
69
34
  if (new Set(names).size !== this.#modules.length) {
70
35
  throw fail("module {0} loaded twice", doubled(names));
71
36
  }
72
37
  const app = await reducer(this.#modules, this, "init");
73
- this.#target.set(target);
38
+ this.#target.set(this.#target_name);
74
39
  return app;
75
40
  }
76
41
  get location() {
@@ -91,25 +56,6 @@ export default class App {
91
56
  get modules() {
92
57
  return [...this.#modules];
93
58
  }
94
- get extensions() {
95
- return this.#bindings.map(([extension]) => extension);
96
- }
97
- binder(file) {
98
- return this.#bindings
99
- .toSorted(([a], [b]) => a.length > b.length ? -1 : 1)
100
- .find(([extension]) => file.path.endsWith(extension))?.[1];
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
- }
113
59
  get(key) {
114
60
  return this.#kv.get(key);
115
61
  }
@@ -122,13 +68,5 @@ export default class App {
122
68
  runpath(...directories) {
123
69
  return this.#path.build.join(...directories);
124
70
  }
125
- // this is technically not necessary for serving, but it has to be used by
126
- // the init hook, which is shared between the build and serve app
127
- bind(extension, binder) {
128
- if (this.extensions.includes(extension)) {
129
- throw new Error(`${extension} already bound`);
130
- }
131
- this.#bindings.push([extension, binder]);
132
- }
133
71
  }
134
72
  //# sourceMappingURL=App.js.map
@@ -1,12 +1,10 @@
1
- import type BindingContext from "#BindingContext";
2
1
  import type FileRef from "@rcompat/fs/FileRef";
3
2
  import type MaybePromise from "@rcompat/type/MaybePromise";
4
3
  type Options = {
5
4
  build: {
6
5
  id: string;
7
- stage: FileRef;
8
6
  };
9
- context: BindingContext;
7
+ context: string;
10
8
  };
11
9
  type Binder = (file: FileRef, options: Options) => MaybePromise<string>;
12
10
  export type { Binder as default };
@@ -0,0 +1,7 @@
1
+ declare const _default: import("pema").ObjectType<{
2
+ mode: import("pema/union").UnionType<[import("pema").LiteralType<"production">, import("pema").LiteralType<"development">, import("pema").LiteralType<"testing">]>;
3
+ target: import("pema").DefaultType<import("pema/string").StringType, "web">;
4
+ dir: import("pema").DefaultType<import("pema/string").StringType, "build">;
5
+ }>;
6
+ export default _default;
7
+ //# sourceMappingURL=Flags.d.ts.map
@@ -0,0 +1,7 @@
1
+ import p from "pema";
2
+ export default p({
3
+ mode: p.union("production", "development", "testing"),
4
+ target: p.string.default("web"),
5
+ dir: p.string.default("build"),
6
+ });
7
+ //# sourceMappingURL=Flags.js.map
@@ -1,12 +1,12 @@
1
1
  import type App from "#App";
2
- import type BuildApp from "#BuildApp";
2
+ import type BuildApp from "#build/App";
3
3
  import type Next from "#module/Next";
4
4
  import type NextBuild from "#module/NextBuild";
5
5
  import type NextHandle from "#module/NextHandle";
6
6
  import type NextRoute from "#module/NextRoute";
7
7
  import type NextServe from "#module/NextServe";
8
8
  import type RequestFacade from "#request/RequestFacade";
9
- import type ServeApp from "#ServeApp";
9
+ import type ServeApp from "#serve/App";
10
10
  export default abstract class Module {
11
11
  abstract get name(): string;
12
12
  init<T extends App>(app: T, next: Next<T>): import("@rcompat/type/MaybePromise").default<T>;
@@ -1,3 +1,3 @@
1
- declare const _default: "0.2";
1
+ declare const _default: "0.3";
2
2
  export default _default;
3
3
  //# sourceMappingURL=TAG.d.ts.map
@@ -1,2 +1,2 @@
1
- export default "0.2";
1
+ export default "0.3";
2
2
  //# sourceMappingURL=TAG.js.map
@@ -0,0 +1,34 @@
1
+ import App from "#App";
2
+ import type Binder from "#Binder";
3
+ import type FileRef from "@rcompat/fs/FileRef";
4
+ import type Dict from "@rcompat/type/Dict";
5
+ import type { Plugin } from "esbuild";
6
+ type PluginType = "server" | "client";
7
+ export default class BuildApp extends App {
8
+ #private;
9
+ frontends: Map<string, string[]>;
10
+ conditions: Set<string>;
11
+ buildInit(): Promise<void>;
12
+ get extensions(): string[];
13
+ get id(): string;
14
+ get paths(): Dict<string[]>;
15
+ get frontendExtensions(): string[];
16
+ addRoot(name: string, source: string): void;
17
+ get roots(): Dict<string>;
18
+ plugin(type: PluginType, plugin: Plugin): void;
19
+ plugins(type: PluginType): Plugin[];
20
+ entrypoint(code: string): void;
21
+ get entrypoints(): string;
22
+ binder(file: FileRef): Binder | undefined;
23
+ bind(extension: string, binder: Binder): void;
24
+ done(fn: () => void): void;
25
+ cleanup(): void;
26
+ basename(file: FileRef, directory: FileRef): string;
27
+ depth(): number;
28
+ get i18n_active(): boolean;
29
+ set i18n_active(active: boolean);
30
+ get session_active(): boolean;
31
+ set session_active(active: boolean);
32
+ }
33
+ export {};
34
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1,103 @@
1
+ import App from "#App";
2
+ import build from "#build/hook";
3
+ import log from "#log";
4
+ import resolve_paths from "#paths";
5
+ import s_layout_depth from "#symbol/layout-depth";
6
+ export default class BuildApp extends App {
7
+ frontends = new Map();
8
+ conditions = new Set();
9
+ #postbuild = [];
10
+ #roots = {};
11
+ #id = crypto.randomUUID().slice(0, 8);
12
+ #i18n_active = false;
13
+ #session_active = false;
14
+ #paths;
15
+ #bindings = [
16
+ [".js", file => file.text()],
17
+ [".ts", file => file.text()],
18
+ ];
19
+ #plugins = [];
20
+ #entrypoint_imports = [];
21
+ async buildInit() {
22
+ log.system("starting {0} build in {1} mode", this.target.name, this.mode);
23
+ this.#paths = await resolve_paths(this.root, this.config("paths"));
24
+ await build(this);
25
+ }
26
+ get extensions() {
27
+ const builtin = [".ts", ".js", ".json"];
28
+ return [...builtin, ...this.#bindings.map(([extension]) => extension)];
29
+ }
30
+ get id() {
31
+ return this.#id;
32
+ }
33
+ get paths() {
34
+ return this.#paths;
35
+ }
36
+ get frontendExtensions() {
37
+ return [...this.frontends.values()].flat();
38
+ }
39
+ addRoot(name, source) {
40
+ this.#roots[name] = source;
41
+ }
42
+ get roots() {
43
+ return this.#roots;
44
+ }
45
+ plugin(type, plugin) {
46
+ this.#plugins.push({ type, plugin });
47
+ }
48
+ plugins(type) {
49
+ return this.#plugins
50
+ .filter(plugin => plugin.type === type)
51
+ .map(plugin => plugin.plugin);
52
+ }
53
+ entrypoint(code) {
54
+ this.#entrypoint_imports.push(code);
55
+ }
56
+ get entrypoints() {
57
+ return this.#entrypoint_imports.join("\n");
58
+ }
59
+ binder(file) {
60
+ return this.#bindings
61
+ .toSorted(([a], [b]) => a.length > b.length ? -1 : 1)
62
+ .find(([extension]) => file.path.endsWith(extension))?.[1];
63
+ }
64
+ bind(extension, binder) {
65
+ if (this.extensions.includes(extension)) {
66
+ throw new Error(`${extension} already bound`);
67
+ }
68
+ this.#bindings.push([extension, binder]);
69
+ }
70
+ done(fn) {
71
+ this.#postbuild.push(fn);
72
+ }
73
+ cleanup() {
74
+ this.#postbuild.forEach(fn => fn());
75
+ }
76
+ basename(file, directory) {
77
+ const relative = file.debase(directory);
78
+ const extensions = this.extensions
79
+ .toSorted((a, b) => a.length > b.length ? -1 : 1);
80
+ for (const extension of extensions) {
81
+ if (relative.path.endsWith(extension)) {
82
+ return relative.path.slice(1, -extension.length);
83
+ }
84
+ }
85
+ return relative.bare().path.slice(1);
86
+ }
87
+ depth() {
88
+ return this.get(s_layout_depth);
89
+ }
90
+ get i18n_active() {
91
+ return this.#i18n_active;
92
+ }
93
+ set i18n_active(active) {
94
+ this.#i18n_active = active;
95
+ }
96
+ get session_active() {
97
+ return this.#session_active;
98
+ }
99
+ set session_active(active) {
100
+ this.#session_active = active;
101
+ }
102
+ }
103
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1,3 @@
1
+ import type BuildApp from "#build/App";
2
+ export default function build_client(app: BuildApp): Promise<void>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,95 @@
1
+ import plugin_alias from "#build/client/plugin/alias";
2
+ import plugin_entrypoint from "#build/client/plugin/entrypoint";
3
+ import plugin_frontend from "#build/client/plugin/frontend";
4
+ import plugin_server_stamp from "#build/client/plugin/server-stamp";
5
+ import reload from "#build/client/reload";
6
+ import location from "#location";
7
+ import * as esbuild from "esbuild";
8
+ const write_bootstrap = async (app, mode) => {
9
+ const build_start_script = `
10
+ import serve from "primate/serve";
11
+ import views from "app:views";
12
+ import routes from "app:routes";
13
+ import pages from "app:pages";
14
+ import assets from "app:assets";
15
+ import s_config from "primate/symbol/config";
16
+ ${app.session_active ? `
17
+ import session from "app:config:session";
18
+ const session_config = session[s_config];
19
+ ` : `
20
+ const session_config = undefined;
21
+ `}
22
+ import config from "app:config";
23
+
24
+ ${app.i18n_active ? `
25
+ import i18n from "app:config:i18n";
26
+ const i18n_config = i18n[s_config];
27
+ ` : `
28
+ const i18n_config = undefined;
29
+ `}
30
+
31
+ const app = await serve(import.meta.url, {
32
+ assets,
33
+ config,
34
+ routes,
35
+ views,
36
+ pages,
37
+ mode: "${mode}",
38
+ session_config,
39
+ i18n_config,
40
+ target: "${app.target.name}",
41
+ });
42
+
43
+ export default app;
44
+ `;
45
+ await app.path.build.join("serve.js").write(build_start_script);
46
+ };
47
+ export default async function build_client(app) {
48
+ app.plugin("client", plugin_frontend(app));
49
+ app.plugin("client", plugin_alias(app));
50
+ app.plugin("client", plugin_server_stamp(app));
51
+ app.plugin("client", plugin_entrypoint(app));
52
+ const imports = await app.path.static.collect(file => /\.(?:js|ts|css)$/.test(file.path));
53
+ imports.forEach(file => {
54
+ const src = file.debase(app.path.static);
55
+ app.entrypoint(`import "./${location.static}${src}";`);
56
+ });
57
+ app.entrypoint("import \"primate/client/app\";");
58
+ const conditions = app.conditions.values();
59
+ const build_options = {
60
+ plugins: app.plugins("client"),
61
+ outdir: app.runpath(location.client).path,
62
+ entryPoints: ["app:client"],
63
+ conditions: ["style", "browser", "default", "module", ...conditions],
64
+ resolveExtensions: [".ts", ".js", ...app.frontendExtensions],
65
+ tsconfig: app.root.join("tsconfig.json").path,
66
+ bundle: true,
67
+ format: "esm",
68
+ };
69
+ const mode_options = app.mode === "development"
70
+ ? {
71
+ banner: {
72
+ js: `new EventSource("${reload.path}").addEventListener("change",
73
+ () => globalThis.location.reload());`,
74
+ },
75
+ entryNames: "app",
76
+ minify: false,
77
+ splitting: false,
78
+ }
79
+ : {
80
+ entryNames: "app-[hash]",
81
+ minify: true,
82
+ splitting: true,
83
+ };
84
+ const options = { ...build_options, ...mode_options };
85
+ if (app.mode === "development") {
86
+ const context = await esbuild.context(options);
87
+ await context.watch();
88
+ await context.serve({ host: reload.host, port: reload.port });
89
+ }
90
+ else {
91
+ await esbuild.build(options);
92
+ }
93
+ await write_bootstrap(app, app.mode);
94
+ }
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_client_alias(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=alias.d.ts.map
@@ -0,0 +1,12 @@
1
+ export default function plugin_client_alias(app) {
2
+ return {
3
+ name: "primate/client/alias",
4
+ setup(build) {
5
+ build.onResolve({ filter: /app:static/ }, args => {
6
+ const path = args.path.slice("app:static/".length);
7
+ return { path: app.root.join(path).path };
8
+ });
9
+ },
10
+ };
11
+ }
12
+ //# sourceMappingURL=alias.js.map
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_client_entrypoint(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=entrypoint.d.ts.map
@@ -0,0 +1,15 @@
1
+ export default function plugin_client_entrypoint(app) {
2
+ return {
3
+ name: "primate/client/entrypoint",
4
+ setup(build) {
5
+ build.onResolve({ filter: /^app:client$/ }, () => {
6
+ return { path: "client-entrypoint", namespace: "primate-client" };
7
+ });
8
+ build.onLoad({ filter: /.*/, namespace: "primate-client" }, async () => {
9
+ const contents = app.entrypoints;
10
+ return { contents, loader: "js", resolveDir: app.root.path };
11
+ });
12
+ },
13
+ };
14
+ }
15
+ //# sourceMappingURL=entrypoint.js.map
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_client_frontend(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=frontend.d.ts.map
@@ -0,0 +1,15 @@
1
+ export default function plugin_client_frontend(app) {
2
+ return {
3
+ name: "primate/client/frontend",
4
+ setup(build) {
5
+ build.onResolve({ filter: /app:frontends/ }, ({ path }) => {
6
+ return { namespace: "frontends", path };
7
+ });
8
+ build.onLoad({ filter: /app:frontends/ }, async () => {
9
+ const contents = [...app.frontends.keys()].map(name => `export { default as ${name} } from "@primate/${name}";`).join("\n");
10
+ return { contents, resolveDir: app.root.path };
11
+ });
12
+ },
13
+ };
14
+ }
15
+ //# sourceMappingURL=frontend.js.map
@@ -0,0 +1,4 @@
1
+ import type BuildApp from "#build/App";
2
+ import type { Plugin } from "esbuild";
3
+ export default function plugin_client_server_stamp(app: BuildApp): Plugin;
4
+ //# sourceMappingURL=server-stamp.d.ts.map
@@ -0,0 +1,14 @@
1
+ export default function plugin_client_server_stamp(app) {
2
+ return {
3
+ name: "primate/client/server-stamp",
4
+ setup(build) {
5
+ build.onResolve({ filter: /^server:stamp$/ }, () => {
6
+ return {
7
+ path: app.runpath("client", "server-stamp.js").path,
8
+ sideEffects: true,
9
+ };
10
+ });
11
+ },
12
+ };
13
+ }
14
+ //# sourceMappingURL=server-stamp.js.map
@@ -0,0 +1,7 @@
1
+ declare const _default: {
2
+ path: string;
3
+ host: string;
4
+ port: number;
5
+ };
6
+ export default _default;
7
+ //# sourceMappingURL=reload.d.ts.map
@@ -0,0 +1,6 @@
1
+ export default {
2
+ path: "/esbuild",
3
+ host: "localhost",
4
+ port: 6262,
5
+ };
6
+ //# sourceMappingURL=reload.js.map
@@ -1,4 +1,4 @@
1
- import type BuildApp from "#BuildApp";
1
+ import type BuildApp from "#build/App";
2
2
  declare const _default: (app: BuildApp) => Promise<BuildApp>;
3
3
  export default _default;
4
- //# sourceMappingURL=build.d.ts.map
4
+ //# sourceMappingURL=hook.d.ts.map
@@ -0,0 +1,49 @@
1
+ import build_client from "#build/client/index";
2
+ import build_server from "#build/server/index";
3
+ import fail from "#fail";
4
+ import location from "#location";
5
+ import log from "#log";
6
+ import reducer from "#reducer";
7
+ import $router from "#request/router";
8
+ import s_layout_depth from "#symbol/layout-depth";
9
+ import pkg from "@rcompat/fs/project/package";
10
+ const core_pkg = await pkg(import.meta.url);
11
+ const { version } = await core_pkg.json();
12
+ async function pre(app) {
13
+ const dot_primate = app.path.build.join(".primate");
14
+ if (await app.path.build.exists() && !await dot_primate.exists()) {
15
+ const message = "{0} exists but does not contain a previous build";
16
+ throw fail(message, app.path.build.path);
17
+ }
18
+ // remove build directory if exists
19
+ await app.path.build.remove();
20
+ await app.path.build.create();
21
+ // touch a .primate file to indicate this is a Primate build directory
22
+ await dot_primate.write(version);
23
+ await app.runpath(location.client).create();
24
+ const stamp = app.runpath("client", "server-stamp.js");
25
+ await stamp.write("export default 0;\n");
26
+ // this has to occur before post, so that layout depth is available for
27
+ // compiling root views
28
+ // bindings should have been registered during `init`
29
+ const router = await $router(app.path.routes, app.extensions);
30
+ app.set(s_layout_depth, router.depth("layout"));
31
+ const i18n_ts = app.path.config.join("i18n.ts");
32
+ const i18n_js = app.path.config.join("i18n.js");
33
+ app.i18n_active = await i18n_ts.exists() || await i18n_js.exists();
34
+ const session_ts = app.path.config.join("session.ts");
35
+ const session_js = app.path.config.join("session.js");
36
+ app.session_active = await session_ts.exists() || await session_js.exists();
37
+ return app;
38
+ }
39
+ ;
40
+ async function post(app) {
41
+ await build_client(app);
42
+ await build_server(app);
43
+ log.system("build written to {0}", app.path.build);
44
+ app.cleanup();
45
+ return app;
46
+ }
47
+ ;
48
+ export default async (app) => post(await reducer(app.modules, await pre(app), "build"));
49
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1,4 @@
1
+ import Flags from "#Flags";
2
+ declare const _default: (input: typeof Flags.input) => Promise<true | undefined>;
3
+ export default _default;
4
+ //# sourceMappingURL=index.d.ts.map