@primate/core 0.1.4 → 0.1.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/core",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Primate core",
5
5
  "homepage": "https://primatejs.com",
6
6
  "bugs": "https://github.com/primatejs/primate/issues",
@@ -21,9 +21,9 @@
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.4.1",
24
+ "@rcompat/fs": "^0.5.0",
25
25
  "@rcompat/function": "^0.4.0",
26
- "@rcompat/http": "^0.5.2",
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",
@@ -11,6 +11,7 @@ import manifest from "@rcompat/package/manifest";
11
11
  import root from "@rcompat/package/root";
12
12
  import copy_includes from "./copy_includes.js";
13
13
  import $router from "./router.js";
14
+ import webpath from "@rcompat/fs/webpath";
14
15
 
15
16
  const pre = async (app, mode, target) => {
16
17
  let target$ = target;
@@ -52,12 +53,12 @@ const write_directories = async (build_directory, app) => {
52
53
  for (const name of app.server_build) {
53
54
  const d = app.runpath(name);
54
55
  const e = await Promise.all((await collect(d, js_re, { recursive: true }))
55
- .map(async file => `${file}`.replace(d, _ => "")));
56
+ .map(async path => `${path}`.replace(d, _ => "")));
56
57
  const files_js = `
57
58
  const ${name} = [];
58
- ${e.map((file , i) =>
59
- `import * as ${name}${i} from "../${name}${file}";
60
- ${name}.push(["${file.slice(1, -".js".length)}", ${name}${i}]);`,
59
+ ${e.map((path, i) =>
60
+ `import * as ${name}${i} from "${webpath(`../${name}${path}`)}";
61
+ ${name}.push(["${webpath(path.slice(1, -".js".length))}", ${name}${i}]);`,
61
62
  ).join("\n")}
62
63
  export default ${name};`;
63
64
  await build_directory.join(`${name}.js`).write(files_js);
@@ -68,16 +69,16 @@ const write_components = async (build_directory, app) => {
68
69
  const location = app.get("location");
69
70
  const d2 = app.runpath(location.server, location.components);
70
71
  const e = await Promise.all((await collect(d2, js_re, { recursive: true }))
71
- .map(async file => `${file}`.replace(d2, _ => "")));
72
+ .map(async path => `${path}`.replace(d2, _ => "")));
72
73
  const components_js = `
73
74
  const components = [];
74
75
  ${e.map((component, i) =>
75
- `import * as component${i} from "../server/components${component}";
76
- components.push(["${component.slice(1, -".js".length)}", component${i}]);`,
76
+ `import * as component${i} from "${webpath(`../server/components${component}`)}";
77
+ components.push(["${webpath(component.slice(1, -".js".length))}", component${i}]);`,
77
78
  ).join("\n")}
78
79
 
79
80
  ${app.roots.map((root, i) => `
80
- import * as root${i} from "${root}";
81
+ import * as root${i} from "${webpath(`../server/${root.name}`)}";
81
82
  components.push(["${root.name}", root${i}]);
82
83
  `).join("\n")}
83
84
 
@@ -87,8 +88,7 @@ export default components;`;
87
88
 
88
89
  const write_bootstrap = async (build_number, app, mode) => {
89
90
  const build_start_script = `
90
- import file from "@rcompat/fs/file";
91
- import serve from "@primate/core/serve";
91
+ import serve from "primate/serve";
92
92
  import config from "./${config_filename}";
93
93
  const files = {};
94
94
  ${app.server_build.map(name =>
@@ -96,9 +96,9 @@ ${app.server_build.map(name =>
96
96
  files.${name} = ${name};`,
97
97
  ).join("\n")}
98
98
  import components from "./${build_number}/components.js";
99
- import * as target from "./target.js";
99
+ import target from "./target.js";
100
100
 
101
- await serve(file(import.meta.url).directory, {
101
+ await serve(import.meta.url, {
102
102
  ...target,
103
103
  config,
104
104
  files,
@@ -3,7 +3,6 @@ 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";
@@ -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");
@@ -1,4 +1,6 @@
1
1
  import collect from "@rcompat/fs/collect";
2
+ import join from "@rcompat/fs/join";
3
+ import webpath from "@rcompat/fs/webpath";
2
4
 
3
5
  const html = /^.*.html$/u;
4
6
 
@@ -14,84 +16,55 @@ export default async app => {
14
16
  return {
15
17
  src,
16
18
  path,
17
- code: `await file(asset${i}).text()`,
19
+ code: `await load_text(asset${i})`,
18
20
  type,
19
21
  };
20
22
  });
21
23
  const d = app.runpath(location.pages);
22
24
  const pages = await Promise.all((await collect(d, html, { recursive: true }))
23
- .map(async file => `${file}`.replace(`${d}/`, _ => "")));
25
+ .map(async file => `${file.debase(d)}`.slice(1)));
24
26
  const pages_str = pages.map(page =>
25
- `"${page}": await join(import.meta.url, "../${location.pages}/${page}").text(),`).join("\n");
27
+ `"${page}": await load_text(import.meta.url,
28
+ "${webpath(`../${location.pages}/${page}`)}"),`).join("\n");
26
29
 
27
30
  const assets_scripts = `
28
- import file from "@rcompat/fs/file";
29
- import join from "@rcompat/fs/join";
30
- import stringify from "@rcompat/object/stringify";
31
- import crypto from "@rcompat/crypto";
32
- import { OK } from "@rcompat/http/status";
33
- import { resolve } from "@rcompat/http/mime";
34
-
35
- const encoder = new TextEncoder();
36
- const hash = async (data, algorithm = "sha-384") => {
37
- const bytes = await crypto.subtle.digest(algorithm, encoder.encode(data));
38
- const prefix = algorithm.replace("-", _ => "");
39
- return \`\${prefix}-\${btoa(String.fromCharCode(...new Uint8Array(bytes)))}\`;
40
- };
31
+ import loader from "primate/loader";
32
+ import load_text from "primate/load-text";
41
33
 
42
34
  ${$imports.map(({ path }, i) =>
43
- `const asset${i} = await join(import.meta.dirname, "${path}").text();`)
35
+ `const asset${i} = await load_text(import.meta.dirname, "${path}");`)
44
36
  .join("\n ")}
45
37
  const assets = [${$imports.map(($import, i) => `{
46
38
  src: "${$import.src}",
47
39
  code: asset${i},
48
40
  type: "${$import.type}",
49
41
  inline: false,
50
- integrity: await hash(asset${i}),
51
42
  }`).join(",\n ")}];
52
43
 
53
44
  const imports = {
54
- app: join("${http.static.root}", "${$imports.find($import =>
55
- $import.src.includes("app") && $import.src.endsWith(".js")).src}").webpath(),
45
+ app: "${join(http.static.root, $imports.find($import =>
46
+ $import.src.includes("app") && $import.src.endsWith(".js")).src).webpath()}"
56
47
  };
57
48
  // importmap
58
49
  assets.push({
59
50
  inline: true,
60
- code: stringify({ imports }),
51
+ code: { imports },
61
52
  type: "importmap",
62
- integrity: await hash(stringify({ imports })),
63
53
  });
64
54
 
65
55
  const pages = {
66
56
  ${pages_str}
67
57
  };
68
- const buildroot = file(import.meta.url).join("..");
69
58
 
70
- const serve_asset = asset => new Response(asset.stream(), {
71
- status: OK,
72
- headers: {
73
- "Content-Type": resolve(asset.name),
74
- },
75
- });
76
-
77
- const loader = {
78
- page(name) {
79
- return pages[name] ?? pages["${app.get("pages.app")}"];
80
- },
81
- async asset(pathname) {
82
- const root_asset = buildroot.join(\`client/\${pathname}\`);
83
- if (await await root_asset.isFile) {
84
- return serve_asset(root_asset);
85
- }
86
- const static_asset = buildroot.join(\`client/static/\${pathname}\`);
87
- if (await static_asset.isFile) {
88
- return serve_asset(static_asset);
89
- }
90
- },
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",
91
67
  };
92
- const target = "web";
93
-
94
- export { assets, loader, target };
95
68
  `;
96
69
  await app.path.build.join("target.js").write(assets_scripts);
97
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
- export default async (root, { config, assets, files, components, loader, target, mode }) => {
65
- const { http } = config;
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
- async hash(data, algorithm = "sha-384") {
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,