@primate/core 0.1.5 → 0.1.7
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/package.json +3 -3
- package/src/build/hook/build.js +11 -11
- package/src/build/index.js +3 -4
- package/src/build/targets/web.js +19 -47
- package/src/serve/app.js +23 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Primate core",
|
|
5
5
|
"homepage": "https://primatejs.com",
|
|
6
6
|
"bugs": "https://github.com/primatejs/primate/issues",
|
|
@@ -21,13 +21,13 @@
|
|
|
21
21
|
"@rcompat/build": "^0.4.0",
|
|
22
22
|
"@rcompat/cli": "^0.5.1",
|
|
23
23
|
"@rcompat/crypto": "^0.5.0",
|
|
24
|
-
"@rcompat/fs": "^0.5.
|
|
24
|
+
"@rcompat/fs": "^0.5.1",
|
|
25
25
|
"@rcompat/function": "^0.4.0",
|
|
26
26
|
"@rcompat/http": "^0.5.3",
|
|
27
27
|
"@rcompat/invariant": "^0.5.0",
|
|
28
28
|
"@rcompat/object": "^0.5.0",
|
|
29
29
|
"@rcompat/package": "^0.7.0",
|
|
30
|
-
"@rcompat/
|
|
30
|
+
"@rcompat/runtime": "^0.1.0",
|
|
31
31
|
"@rcompat/stdio": "^0.5.0",
|
|
32
32
|
"@rcompat/sync": "^0.3.0"
|
|
33
33
|
},
|
package/src/build/hook/build.js
CHANGED
|
@@ -38,7 +38,7 @@ const pre = async (app, mode, target) => {
|
|
|
38
38
|
await app.path.build.remove();
|
|
39
39
|
await app.path.build.create();
|
|
40
40
|
|
|
41
|
-
await Promise.all(["server", "client", "
|
|
41
|
+
await Promise.all(["server", "client", "components"]
|
|
42
42
|
.map(directory => app.runpath(directory).create()));
|
|
43
43
|
|
|
44
44
|
const router = await $router(app.path.routes);
|
|
@@ -50,14 +50,15 @@ const pre = async (app, mode, target) => {
|
|
|
50
50
|
|
|
51
51
|
const js_re = /^.*.js$/u;
|
|
52
52
|
const write_directories = async (build_directory, app) => {
|
|
53
|
+
const location = app.get("location");
|
|
53
54
|
for (const name of app.server_build) {
|
|
54
|
-
const d = app.runpath(name);
|
|
55
|
+
const d = app.runpath(location.server, name);
|
|
55
56
|
const e = await Promise.all((await collect(d, js_re, { recursive: true }))
|
|
56
57
|
.map(async path => `${path}`.replace(d, _ => "")));
|
|
57
58
|
const files_js = `
|
|
58
59
|
const ${name} = [];
|
|
59
60
|
${e.map((path, i) =>
|
|
60
|
-
`import * as ${name}${i} from "${webpath(
|
|
61
|
+
`import * as ${name}${i} from "${webpath(`../server/${name}${path}`)}";
|
|
61
62
|
${name}.push(["${webpath(path.slice(1, -".js".length))}", ${name}${i}]);`,
|
|
62
63
|
).join("\n")}
|
|
63
64
|
export default ${name};`;
|
|
@@ -88,8 +89,7 @@ export default components;`;
|
|
|
88
89
|
|
|
89
90
|
const write_bootstrap = async (build_number, app, mode) => {
|
|
90
91
|
const build_start_script = `
|
|
91
|
-
import
|
|
92
|
-
import serve from "@primate/core/serve";
|
|
92
|
+
import serve from "primate/serve";
|
|
93
93
|
import config from "./${config_filename}";
|
|
94
94
|
const files = {};
|
|
95
95
|
${app.server_build.map(name =>
|
|
@@ -97,9 +97,9 @@ ${app.server_build.map(name =>
|
|
|
97
97
|
files.${name} = ${name};`,
|
|
98
98
|
).join("\n")}
|
|
99
99
|
import components from "./${build_number}/components.js";
|
|
100
|
-
import
|
|
100
|
+
import target from "./target.js";
|
|
101
101
|
|
|
102
|
-
await serve(
|
|
102
|
+
await serve(import.meta.url, {
|
|
103
103
|
...target,
|
|
104
104
|
config,
|
|
105
105
|
files,
|
|
@@ -114,10 +114,10 @@ const post = async (app, mode, target) => {
|
|
|
114
114
|
const defaults = join(import.meta.dirname, "../defaults");
|
|
115
115
|
|
|
116
116
|
// stage routes
|
|
117
|
-
await app.stage(app.path.routes, location.routes);
|
|
117
|
+
await app.stage(app.path.routes, join(location.server, location.routes));
|
|
118
118
|
|
|
119
119
|
// stage types
|
|
120
|
-
await app.stage(app.path.types, location.types);
|
|
120
|
+
await app.stage(app.path.types, join(location.server, location.types));
|
|
121
121
|
|
|
122
122
|
// stage components, transforming defines
|
|
123
123
|
await app.stage(app.path.components, location.components, true);
|
|
@@ -128,9 +128,9 @@ const post = async (app, mode, target) => {
|
|
|
128
128
|
?.(directory, path.debase(`${directory}/`));
|
|
129
129
|
}
|
|
130
130
|
// copy framework pages
|
|
131
|
-
await app.stage(defaults, location.pages);
|
|
131
|
+
await app.stage(defaults, join(location.server, location.pages));
|
|
132
132
|
// overwrite transformed pages to build
|
|
133
|
-
await app.stage(app.path.pages, location.pages);
|
|
133
|
+
await app.stage(app.path.pages, join(location.server, location.pages));
|
|
134
134
|
|
|
135
135
|
// copy static files to build/server/static
|
|
136
136
|
await app.stage(app.path.static, join(location.server, location.static));
|
package/src/build/index.js
CHANGED
|
@@ -3,12 +3,11 @@ import config from "#config";
|
|
|
3
3
|
import config_filename from "#config-filename";
|
|
4
4
|
import empty_config_file from "#error/empty-config-file";
|
|
5
5
|
import error_in_config_file from "#error/error-in-config-file";
|
|
6
|
-
import log from "@primate/core/log";
|
|
7
6
|
import tryreturn from "@rcompat/async/tryreturn";
|
|
8
7
|
import empty from "@rcompat/object/empty";
|
|
9
8
|
import override from "@rcompat/object/override";
|
|
10
9
|
import root from "@rcompat/package/root";
|
|
11
|
-
import
|
|
10
|
+
import runtime from "@rcompat/runtime";
|
|
12
11
|
import app from "./app.js";
|
|
13
12
|
import { build, init } from "./hook/exports.js";
|
|
14
13
|
|
|
@@ -16,7 +15,7 @@ const empty_config = config => config === undefined || empty(config);
|
|
|
16
15
|
|
|
17
16
|
const get_config = async project_root => {
|
|
18
17
|
const local_config = project_root.join(config_filename);
|
|
19
|
-
const exists = await local_config.exists()
|
|
18
|
+
const exists = await local_config.exists();
|
|
20
19
|
if (exists) {
|
|
21
20
|
try {
|
|
22
21
|
const imported = await local_config.import("default");
|
|
@@ -26,7 +25,7 @@ const get_config = async project_root => {
|
|
|
26
25
|
return imported;
|
|
27
26
|
} catch (error) {
|
|
28
27
|
if (error.level === undefined) {
|
|
29
|
-
error_in_config_file(error.message, `${
|
|
28
|
+
error_in_config_file(error.message, `${runtime} ${local_config}`);
|
|
30
29
|
} else {
|
|
31
30
|
throw error;
|
|
32
31
|
}
|
package/src/build/targets/web.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import collect from "@rcompat/fs/collect";
|
|
2
|
+
import join from "@rcompat/fs/join";
|
|
2
3
|
import webpath from "@rcompat/fs/webpath";
|
|
3
4
|
|
|
4
5
|
const html = /^.*.html$/u;
|
|
@@ -15,84 +16,55 @@ export default async app => {
|
|
|
15
16
|
return {
|
|
16
17
|
src,
|
|
17
18
|
path,
|
|
18
|
-
code: `await
|
|
19
|
+
code: `await load_text(asset${i})`,
|
|
19
20
|
type,
|
|
20
21
|
};
|
|
21
22
|
});
|
|
22
|
-
const d = app.runpath(location.pages);
|
|
23
|
+
const d = app.runpath(location.server, location.pages);
|
|
23
24
|
const pages = await Promise.all((await collect(d, html, { recursive: true }))
|
|
24
25
|
.map(async file => `${file.debase(d)}`.slice(1)));
|
|
25
26
|
const pages_str = pages.map(page =>
|
|
26
|
-
`"${page}": await
|
|
27
|
+
`"${page}": await load_text(import.meta.url,
|
|
28
|
+
"${webpath(`../${location.server}/${location.pages}/${page}`)}"),`).join("\n");
|
|
27
29
|
|
|
28
30
|
const assets_scripts = `
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import stringify from "@rcompat/object/stringify";
|
|
32
|
-
import crypto from "@rcompat/crypto";
|
|
33
|
-
import { OK } from "@rcompat/http/status";
|
|
34
|
-
import { resolve } from "@rcompat/http/mime";
|
|
35
|
-
|
|
36
|
-
const encoder = new TextEncoder();
|
|
37
|
-
const hash = async (data, algorithm = "sha-384") => {
|
|
38
|
-
const bytes = await crypto.subtle.digest(algorithm, encoder.encode(data));
|
|
39
|
-
const prefix = algorithm.replace("-", _ => "");
|
|
40
|
-
return \`\${prefix}-\${btoa(String.fromCharCode(...new Uint8Array(bytes)))}\`;
|
|
41
|
-
};
|
|
31
|
+
import loader from "primate/loader";
|
|
32
|
+
import load_text from "primate/load-text";
|
|
42
33
|
|
|
43
34
|
${$imports.map(({ path }, i) =>
|
|
44
|
-
`const asset${i} = await
|
|
35
|
+
`const asset${i} = await load_text(import.meta.dirname, "${path}");`)
|
|
45
36
|
.join("\n ")}
|
|
46
37
|
const assets = [${$imports.map(($import, i) => `{
|
|
47
38
|
src: "${$import.src}",
|
|
48
39
|
code: asset${i},
|
|
49
40
|
type: "${$import.type}",
|
|
50
41
|
inline: false,
|
|
51
|
-
integrity: await hash(asset${i}),
|
|
52
42
|
}`).join(",\n ")}];
|
|
53
43
|
|
|
54
44
|
const imports = {
|
|
55
|
-
|
|
56
|
-
|
|
45
|
+
app: "${join(http.static.root, $imports.find($import =>
|
|
46
|
+
$import.src.includes("app") && $import.src.endsWith(".js")).src).webpath()}"
|
|
57
47
|
};
|
|
58
48
|
// importmap
|
|
59
49
|
assets.push({
|
|
60
50
|
inline: true,
|
|
61
|
-
code:
|
|
51
|
+
code: { imports },
|
|
62
52
|
type: "importmap",
|
|
63
|
-
integrity: await hash(stringify({ imports })),
|
|
64
53
|
});
|
|
65
54
|
|
|
66
55
|
const pages = {
|
|
67
56
|
${pages_str}
|
|
68
57
|
};
|
|
69
|
-
const buildroot = file(import.meta.url).join("..");
|
|
70
58
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
page(name) {
|
|
80
|
-
return pages[name] ?? pages["${app.get("pages.app")}"];
|
|
81
|
-
},
|
|
82
|
-
async asset(pathname) {
|
|
83
|
-
const root_asset = buildroot.join(\`client/\${pathname}\`);
|
|
84
|
-
if (await await root_asset.isFile()) {
|
|
85
|
-
return serve_asset(root_asset);
|
|
86
|
-
}
|
|
87
|
-
const static_asset = buildroot.join(\`client/static/\${pathname}\`);
|
|
88
|
-
if (await static_asset.isFile()) {
|
|
89
|
-
return serve_asset(static_asset);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
59
|
+
export default {
|
|
60
|
+
assets,
|
|
61
|
+
loader: loader({
|
|
62
|
+
pages,
|
|
63
|
+
rootfile: import.meta.url,
|
|
64
|
+
pages_app: "${app.get("pages.app")}"
|
|
65
|
+
}),
|
|
66
|
+
target: "web",
|
|
92
67
|
};
|
|
93
|
-
const target = "web";
|
|
94
|
-
|
|
95
|
-
export { assets, loader, target };
|
|
96
68
|
`;
|
|
97
69
|
await app.path.build.join("target.js").write(assets_scripts);
|
|
98
70
|
|
package/src/serve/app.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import double_extension from "#error/double-extension";
|
|
2
2
|
import crypto from "@rcompat/crypto";
|
|
3
|
+
import file from "@rcompat/fs/file";
|
|
3
4
|
import join from "@rcompat/fs/join";
|
|
4
5
|
import { html } from "@rcompat/http/mime";
|
|
5
6
|
import { OK } from "@rcompat/http/status";
|
|
6
7
|
import is from "@rcompat/invariant/is";
|
|
7
8
|
import empty from "@rcompat/object/empty";
|
|
8
9
|
import get from "@rcompat/object/get";
|
|
10
|
+
import stringify from "@rcompat/object/stringify";
|
|
9
11
|
import valmap from "@rcompat/object/valmap";
|
|
10
12
|
import module_loader from "./module_loader.js";
|
|
11
13
|
import to_sorted from "./to_sorted.js";
|
|
@@ -21,8 +23,6 @@ const to_csp = (config_csp, assets, csp) => config_csp
|
|
|
21
23
|
.map(([key, directives]) => `${key} ${directives.join(" ")}`)
|
|
22
24
|
.join(";");
|
|
23
25
|
|
|
24
|
-
const encoder = new TextEncoder();
|
|
25
|
-
|
|
26
26
|
const attribute = attributes => empty(attributes)
|
|
27
27
|
? ""
|
|
28
28
|
: " ".concat(Object.entries(attributes)
|
|
@@ -61,8 +61,26 @@ const render_head = (assets, fonts, head) =>
|
|
|
61
61
|
tags.font({ href, type: "font/woff2" }),
|
|
62
62
|
).join("\n"));
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const encoder = new TextEncoder();
|
|
65
|
+
const hash = async (data, algorithm = "sha-384") => {
|
|
66
|
+
const bytes = await crypto.subtle.digest(algorithm, encoder.encode(data));
|
|
67
|
+
const prefix = algorithm.replace("-", _ => "");
|
|
68
|
+
return`${prefix}-${btoa(String.fromCharCode(...new Uint8Array(bytes)))}`;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export default async (rootfile, build) => {
|
|
72
|
+
const root = file(rootfile).directory;
|
|
73
|
+
const { config, files, components, loader, target, mode } = build;
|
|
74
|
+
const assets = await Promise.all(build.assets.map(async asset => {
|
|
75
|
+
const code = asset.type === "importmap" ? stringify(asset.code) : asset.code;
|
|
76
|
+
return {
|
|
77
|
+
...asset,
|
|
78
|
+
code,
|
|
79
|
+
integrity: await hash(code),
|
|
80
|
+
};
|
|
81
|
+
}));
|
|
82
|
+
|
|
83
|
+
const { http } = build.config;
|
|
66
84
|
const secure = http?.ssl !== undefined;
|
|
67
85
|
const path = valmap(config.location, value => root.join(value));
|
|
68
86
|
|
|
@@ -174,11 +192,7 @@ export default async (root, { config, assets, files, components, loader, target,
|
|
|
174
192
|
this.handlers[extension] !== undefined && double_extension(extension);
|
|
175
193
|
this.handlers[extension] = handle;
|
|
176
194
|
},
|
|
177
|
-
|
|
178
|
-
const bytes = await crypto.subtle.digest(algorithm, encoder.encode(data));
|
|
179
|
-
const prefix = algorithm.replace("-", _ => "");
|
|
180
|
-
return `${prefix}-${btoa(String.fromCharCode(...new Uint8Array(bytes)))}`;
|
|
181
|
-
},
|
|
195
|
+
hash,
|
|
182
196
|
// noop
|
|
183
197
|
target(name, handler) {},
|
|
184
198
|
build_target: target,
|