@pronto-tools-and-more/pronto 11.1.0 → 11.3.0

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pronto-tools-and-more/pronto",
3
- "version": "11.1.0",
3
+ "version": "11.3.0",
4
4
  "description": "",
5
5
  "main": "src/main.js",
6
6
  "type": "module",
@@ -17,16 +17,16 @@
17
17
  "@lvce-editor/ipc": "^11.7.0",
18
18
  "@lvce-editor/json-rpc": "^5.3.0",
19
19
  "@lvce-editor/verror": "^1.6.0",
20
- "@pronto-tools-and-more/file-watcher": "11.1.0",
21
- "@pronto-tools-and-more/files": "11.1.0",
22
- "@pronto-tools-and-more/network-process": "11.1.0",
23
- "@pronto-tools-and-more/sass-compiler": "11.1.0",
24
- "@pronto-tools-and-more/components-renderer": "11.1.0",
25
- "@pronto-tools-and-more/components": "11.1.0",
26
- "@pronto-tools-and-more/schema-process": "11.1.0",
27
- "@pronto-tools-and-more/diff-process": "11.1.0",
28
- "@pronto-tools-and-more/type-checker": "11.1.0",
29
- "@pronto-tools-and-more/custom-js-functions": "11.1.0",
20
+ "@pronto-tools-and-more/file-watcher": "11.3.0",
21
+ "@pronto-tools-and-more/files": "11.3.0",
22
+ "@pronto-tools-and-more/network-process": "11.3.0",
23
+ "@pronto-tools-and-more/sass-compiler": "11.3.0",
24
+ "@pronto-tools-and-more/components-renderer": "11.3.0",
25
+ "@pronto-tools-and-more/components": "11.3.0",
26
+ "@pronto-tools-and-more/schema-process": "11.3.0",
27
+ "@pronto-tools-and-more/diff-process": "11.3.0",
28
+ "@pronto-tools-and-more/type-checker": "11.3.0",
29
+ "@pronto-tools-and-more/custom-js-functions": "11.3.0",
30
30
  "execa": "^9.5.2",
31
31
  "express": "^4.21.2"
32
32
  },
@@ -1,12 +1,13 @@
1
1
  import express from "express";
2
2
  import { join } from "node:path";
3
3
  import * as FilesPath from "../FilesPath/FilesPath.js";
4
+ import * as HandleConfigLoader from "../HandleConfigLoader/HandleConfigLoader.js";
4
5
  import * as HandleCss from "../HandleCss/HandleCss.js";
6
+ import * as HandleCustomServer from "../HandleCustomServer/HandleCustomServer.js";
5
7
  import * as HandleFeaturesJson from "../HandleFeaturesJson/HandleFeaturesJson.js";
6
8
  import * as HandleIndex from "../HandleIndex/HandleIndex.js";
7
9
  import * as HandleMainJs from "../HandleMainJs/HandleMainJs.js";
8
10
  import * as HandleViews from "../HandleViews/HandleViews.js";
9
- import * as HandleCustomServer from "../HandleCustomServer/HandleCustomServer.js";
10
11
  import * as ProxyPath from "../ProxyPath/ProxyPath.js";
11
12
 
12
13
  export const create = ({
@@ -42,6 +43,10 @@ export const create = ({
42
43
  filesPath: FilesPath.filesPath,
43
44
  })
44
45
  );
46
+ app.get(
47
+ "/assets/scripts/configLoader.js",
48
+ HandleConfigLoader.handleConfigLoader
49
+ );
45
50
  app.get(
46
51
  "/modules/main.js",
47
52
  HandleMainJs.handleMainJs({
@@ -0,0 +1,11 @@
1
+ import * as crypto from "node:crypto";
2
+
3
+ export const fromStats = (stats) => {
4
+ let hash = crypto.createHash("sha1");
5
+ for (const stat of stats) {
6
+ hash.update(`${stat.ino}`);
7
+ hash.update(`${stat.size}`);
8
+ hash.update(`${stat.mtime}`);
9
+ }
10
+ return hash.digest("base64");
11
+ };
@@ -0,0 +1,27 @@
1
+ import { readdir, stat } from "fs/promises";
2
+ import { join } from "path";
3
+ import * as Etag from "../Etag/Etag.js";
4
+
5
+ export const getCssEtag = async (storefrontPath) => {
6
+ try {
7
+ const scssPath = join(storefrontPath, "assets", "scss");
8
+ const dirents = await readdir(scssPath, {
9
+ recursive: true,
10
+ });
11
+ const stats = await Promise.all(
12
+ dirents.map(async (dirent) => {
13
+ const absolutePath = join(scssPath, dirent);
14
+ const info = await stat(absolutePath);
15
+ return {
16
+ size: info.size,
17
+ mtime: info.mtime,
18
+ ino: info.ino,
19
+ };
20
+ })
21
+ );
22
+ return Etag.fromStats(stats);
23
+ } catch (error) {
24
+ console.warn(`Failed to compute css etag ${error}`);
25
+ return `css-${Math.random()}`;
26
+ }
27
+ };
@@ -0,0 +1,21 @@
1
+ import * as GetRendererIpc from "../GetRendererIpc/GetRendererIpc.js";
2
+
3
+ const state = {
4
+ /**
5
+ * @type {Promise[]}
6
+ */
7
+ preloadedIpcs: [],
8
+ };
9
+
10
+ export const getOrCreateRendererIpc = async (tsconfigPath, isBuild) => {
11
+ const cachedIpc = state.preloadedIpcs.pop();
12
+ if (cachedIpc) {
13
+ state.preloadedIpcs.push(GetRendererIpc.getRendererIpc(tsconfigPath));
14
+ return cachedIpc;
15
+ }
16
+ const oursPromise = GetRendererIpc.getRendererIpc(tsconfigPath);
17
+ if (!isBuild) {
18
+ state.preloadedIpcs.push(GetRendererIpc.getRendererIpc(tsconfigPath));
19
+ }
20
+ return oursPromise;
21
+ };
@@ -6,11 +6,6 @@ import * as JsonRpc from "../JsonRpc/JsonRpc.js";
6
6
  import * as UnhandleIpc from "../UnhandleIpc/UnhandleIpc.js";
7
7
 
8
8
  export const getRendererIpc = async (tsconfigPath) => {
9
- // TODO when in watch mode, create a queue of renderers.
10
- // swc takes ~500ms to load
11
- // while the current request is being processed, launch a new renderer process and load swc
12
- // when the actual next request comes, reuse that process, saving ~700ms setup time
13
-
14
9
  const ipc = await IpcParent.create({
15
10
  path: ComponentsRendererPath.componentsRendererPath,
16
11
  method: IpcParentType.NodeForkedProcess, // TODO worker could be faster
@@ -0,0 +1,7 @@
1
+ export const handleConfigLoader = async (req, res) => {
2
+ // the default config loader makes
3
+ // useless http requests
4
+ // so remove it
5
+ res.setHeader("content-type", "application/javascript");
6
+ res.end("");
7
+ };
@@ -3,6 +3,7 @@ import { readFile } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import * as CompileSass from "../CompileSass/CompileSass.js";
5
5
  import * as Config from "../Config/Config.js";
6
+ import * as GetCssEtag from "../GetCssEtag/GetCssEtag.js";
6
7
  import * as UpdateCss from "../UpdateCss/UpdateCss.js";
7
8
 
8
9
  export const handleCss = (storeFrontPath) => async (req, res, next) => {
@@ -13,7 +14,15 @@ export const handleCss = (storeFrontPath) => async (req, res, next) => {
13
14
  res.setHeader("content-type", "text/css");
14
15
  if (pathName === "/assets/custom.css") {
15
16
  try {
17
+ const ifNoneMatch = req.headers["if-none-match"];
18
+ const cssEtag = await GetCssEtag.getCssEtag(storeFrontPath);
19
+ if (ifNoneMatch && ifNoneMatch === cssEtag) {
20
+ res.statusCode = 304;
21
+ res.end();
22
+ return;
23
+ }
16
24
  const result = await CompileSass.compileSass(Config.rootSassFile);
25
+ res.setHeader("Etag", cssEtag);
17
26
  res.end(result.css);
18
27
  } catch (error) {
19
28
  console.warn(error);
@@ -1,6 +1,6 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import * as GetRendererIpc from "../GetRendererIpc/GetRendererIpc.js";
3
+ import * as GetOrCreateRendererIpc from "../GetOrCreateRendererIpc/GetOrCreateRendererIpc.js";
4
4
  import * as HandleViewsSplit from "../HandleViewsSplit/HandleViewsSplit.js";
5
5
 
6
6
  export const handleViewsReactComponents = async (
@@ -28,7 +28,10 @@ export const handleViewsReactComponents = async (
28
28
  throw new Error(`components path not found: ${componentsPath}`);
29
29
  }
30
30
 
31
- const renderer = await GetRendererIpc.getRendererIpc(tsconfigPath);
31
+ const renderer = await GetOrCreateRendererIpc.getOrCreateRendererIpc(
32
+ tsconfigPath,
33
+ isBuild
34
+ );
32
35
  const result = await renderer.invoke(
33
36
  "RenderViews.renderViews",
34
37
  componentsPath,
@@ -23,6 +23,7 @@ const replacementSnippetBody = (appId, baseUrl, contentUrl, platform) =>
23
23
  const occurrenceSnippetHead = "</head>";
24
24
  const replacementSnippetHead = `
25
25
  <link rel="stylesheet" href="/theme.css" />
26
+ <link rel="stylesheet" href="/assets/custom.css" />
26
27
  </head>`;
27
28
 
28
29
  export const updateIndexHtml = (
@@ -1 +1 @@
1
- export const version = '11.1.0'
1
+ export const version = '11.3.0'