@primate/core 0.3.4 → 0.4.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.
- package/lib/private/App.d.ts +5 -19
- package/lib/private/App.js +13 -75
- package/lib/private/Binder.d.ts +1 -3
- package/lib/private/Flags.d.ts +7 -0
- package/lib/private/Flags.js +7 -0
- package/lib/private/Module.d.ts +2 -2
- package/lib/private/backend/TAG.d.ts +1 -1
- package/lib/private/backend/TAG.js +1 -1
- package/lib/private/build/App.d.ts +34 -0
- package/lib/private/build/App.js +103 -0
- package/lib/private/build/client/index.d.ts +3 -0
- package/lib/private/build/client/index.js +95 -0
- package/lib/private/build/client/plugin/alias.d.ts +4 -0
- package/lib/private/build/client/plugin/alias.js +12 -0
- package/lib/private/build/client/plugin/entrypoint.d.ts +4 -0
- package/lib/private/build/client/plugin/entrypoint.js +15 -0
- package/lib/private/build/client/plugin/frontend.d.ts +4 -0
- package/lib/private/build/client/plugin/frontend.js +15 -0
- package/lib/private/build/client/plugin/server-stamp.d.ts +4 -0
- package/lib/private/build/client/plugin/server-stamp.js +14 -0
- package/lib/private/build/client/reload.d.ts +7 -0
- package/lib/private/build/client/reload.js +6 -0
- package/lib/private/{hook/build.d.ts → build/hook.d.ts} +2 -2
- package/lib/private/build/hook.js +49 -0
- package/lib/private/build/index.d.ts +4 -0
- package/lib/private/{build.js → build/index.js} +7 -5
- package/lib/private/build/server/index.d.ts +3 -0
- package/lib/private/build/server/index.js +90 -0
- package/lib/private/build/server/plugin/assets.d.ts +4 -0
- package/lib/private/build/server/plugin/assets.js +67 -0
- package/lib/private/build/server/plugin/config.d.ts +4 -0
- package/lib/private/build/server/plugin/config.js +43 -0
- package/lib/private/build/server/plugin/database-default.d.ts +4 -0
- package/lib/private/build/server/plugin/database-default.js +48 -0
- package/lib/private/build/server/plugin/frontend.d.ts +4 -0
- package/lib/private/build/server/plugin/frontend.js +21 -0
- package/lib/private/build/server/plugin/hot-reload.d.ts +4 -0
- package/lib/private/build/server/plugin/hot-reload.js +36 -0
- package/lib/private/build/server/plugin/native-addons.d.ts +4 -0
- package/lib/private/build/server/plugin/native-addons.js +55 -0
- package/lib/private/build/server/plugin/node-imports.d.ts +4 -0
- package/lib/private/build/server/plugin/node-imports.js +32 -0
- package/lib/private/build/server/plugin/requires.d.ts +4 -0
- package/lib/private/build/server/plugin/requires.js +30 -0
- package/lib/private/build/server/plugin/roots.d.ts +4 -0
- package/lib/private/build/server/plugin/roots.js +18 -0
- package/lib/private/build/server/plugin/route.d.ts +4 -0
- package/lib/private/build/server/plugin/route.js +56 -0
- package/lib/private/build/server/plugin/store-wrap.d.ts +4 -0
- package/lib/private/build/server/plugin/store-wrap.js +33 -0
- package/lib/private/build/server/plugin/store.d.ts +4 -0
- package/lib/private/build/server/plugin/store.js +47 -0
- package/lib/private/build/server/plugin/stores.d.ts +4 -0
- package/lib/private/build/server/plugin/stores.js +25 -0
- package/lib/private/build/server/plugin/view.d.ts +4 -0
- package/lib/private/build/server/plugin/view.js +64 -0
- package/lib/private/build/server/plugin/views.d.ts +4 -0
- package/lib/private/build/server/plugin/views.js +36 -0
- package/lib/private/build/server/plugin/virtual-pages.d.ts +4 -0
- package/lib/private/build/server/plugin/virtual-pages.js +41 -0
- package/lib/private/build/server/plugin/virtual-routes.d.ts +4 -0
- package/lib/private/build/server/plugin/virtual-routes.js +46 -0
- package/lib/private/build/server/plugin/wasm.d.ts +4 -0
- package/lib/private/build/server/plugin/wasm.js +36 -0
- package/lib/private/client/Data.d.ts +2 -0
- package/lib/private/client/app.js +4 -1
- package/lib/private/config/index.d.ts +0 -2
- package/lib/private/config/schema.d.ts +4 -6
- package/lib/private/config/schema.js +9 -19
- package/lib/private/database/Store.d.ts +4 -1
- package/lib/private/database/Store.js +8 -2
- package/lib/private/database/test.js +8 -8
- package/lib/private/frontend/Module.d.ts +4 -3
- package/lib/private/frontend/Module.js +47 -50
- package/lib/private/frontend/Publish.d.ts +1 -1
- package/lib/private/i18n/Module.d.ts +1 -1
- package/lib/private/i18n/Module.js +2 -2
- package/lib/private/location.d.ts +0 -6
- package/lib/private/location.js +0 -12
- package/lib/private/module/BuildHook.d.ts +1 -1
- package/lib/private/module/NextBuild.d.ts +1 -1
- package/lib/private/module/NextServe.d.ts +1 -1
- package/lib/private/paths.d.ts +5 -0
- package/lib/private/paths.js +30 -0
- package/lib/private/reducer.d.ts +2 -2
- package/lib/private/request/route.d.ts +1 -1
- package/lib/private/request/route.js +6 -8
- package/lib/private/response/ResponseFunction.d.ts +1 -1
- package/lib/private/response/binary.d.ts +1 -1
- package/lib/private/response/json.d.ts +1 -1
- package/lib/private/response/sse.d.ts +1 -1
- package/lib/private/response/text.d.ts +1 -1
- package/lib/private/response/view.d.ts +6 -9
- package/lib/private/response/view.js +12 -8
- package/lib/private/response.d.ts +1 -1
- package/lib/private/route/router.d.ts +3 -2
- package/lib/private/route/router.js +5 -4
- package/lib/private/{ServeApp.d.ts → serve/App.d.ts} +5 -22
- package/lib/private/{ServeApp.js → serve/App.js} +106 -35
- package/lib/private/{ServeInit.d.ts → serve/Init.d.ts} +16 -12
- package/lib/private/serve/Init.js +2 -0
- package/lib/private/{hook/serve.d.ts → serve/hook.d.ts} +2 -2
- package/lib/private/{hook/serve.js → serve/hook.js} +1 -1
- package/lib/private/serve/index.d.ts +5 -0
- package/lib/private/serve/index.js +6 -0
- package/lib/private/{builtin/DevModule.d.ts → serve/module/Dev.d.ts} +2 -2
- package/lib/private/{builtin/DevModule.js → serve/module/Dev.js} +4 -6
- package/lib/private/{builtin/HandleModule.d.ts → serve/module/Handle.d.ts} +2 -2
- package/lib/private/{builtin/HandleModule.js → serve/module/Handle.js} +2 -2
- package/lib/private/session/SessionModule.d.ts +3 -2
- package/lib/private/session/SessionModule.js +47 -24
- package/lib/private/session/index.d.ts +11 -8
- package/lib/private/session/index.js +5 -3
- package/lib/private/session/schema.d.ts +2 -4
- package/lib/private/session/schema.js +14 -16
- package/lib/private/target/Manager.js +5 -1
- package/lib/private/wasm/instantiate.js +2 -2
- package/lib/public/BuildApp.d.ts +1 -1
- package/lib/public/BuildApp.js +1 -1
- package/lib/public/Flags.d.ts +2 -0
- package/lib/public/Flags.js +2 -0
- package/lib/public/ServeApp.d.ts +1 -1
- package/lib/public/ServeApp.js +1 -1
- package/lib/public/build.d.ts +1 -1
- package/lib/public/build.js +1 -1
- package/lib/public/serve.d.ts +1 -1
- package/lib/public/serve.js +1 -1
- package/package.json +7 -7
- package/lib/private/BindingContext.d.ts +0 -3
- package/lib/private/BindingContext.js +0 -2
- package/lib/private/BuildApp.d.ts +0 -31
- package/lib/private/BuildApp.js +0 -130
- package/lib/private/Loader.d.ts +0 -17
- package/lib/private/Loader.js +0 -47
- package/lib/private/ServeInit.js +0 -2
- package/lib/private/build.d.ts +0 -4
- package/lib/private/config/config/app.d.ts +0 -3
- package/lib/private/config/config/app.js +0 -3
- package/lib/private/config/config/database/index.d.ts +0 -3
- package/lib/private/config/config/database/index.js +0 -3
- package/lib/private/config/config/session.d.ts +0 -3
- package/lib/private/config/config/session.js +0 -3
- package/lib/private/frontend/bundle-server.d.ts +0 -13
- package/lib/private/frontend/bundle-server.js +0 -48
- package/lib/private/hook/build.js +0 -260
- package/lib/private/serve.d.ts +0 -5
- package/lib/private/serve.js +0 -8
- package/lib/private/session/InMemoryManager.d.ts +0 -9
- package/lib/private/session/InMemoryManager.js +0 -23
- package/lib/private/session/Manager.d.ts +0 -9
- package/lib/private/session/Manager.js +0 -4
- package/lib/private/target/web.d.ts +0 -4
- package/lib/private/target/web.js +0 -58
- package/lib/public/Loader.d.ts +0 -2
- package/lib/public/Loader.js +0 -2
- package/lib/public/session/Manager.d.ts +0 -2
- package/lib/public/session/Manager.js +0 -2
package/lib/private/App.d.ts
CHANGED
|
@@ -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,
|
|
11
|
-
init(
|
|
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
|
-
|
|
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
|
package/lib/private/App.js
CHANGED
|
@@ -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
|
-
|
|
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(
|
|
63
|
-
|
|
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.#
|
|
30
|
+
this.#target_name = flags.target;
|
|
66
31
|
}
|
|
67
|
-
async init(
|
|
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(
|
|
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
|
package/lib/private/Binder.d.ts
CHANGED
|
@@ -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:
|
|
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
|
package/lib/private/Module.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type App from "#App";
|
|
2
|
-
import type BuildApp from "#
|
|
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 "#
|
|
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,2 +1,2 @@
|
|
|
1
|
-
export default "0.
|
|
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,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,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,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,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,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,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
|