@michijs/dev-server 0.7.7 → 0.7.9

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.
@@ -6,7 +6,25 @@ import { fileURLToPath } from "url";
6
6
  import { basename, dirname, resolve } from "path";
7
7
  import { getLocalURL } from "../utils/getLocalURL.js";
8
8
  import { assetsSizes } from "../constants.js";
9
- import puppeteer from "puppeteer";
9
+ import { chromium } from "playwright-core";
10
+ import { exec } from "child_process";
11
+ import { getColor } from "colorthief";
12
+ async function installPlaywright() {
13
+ console.log("Installing Playwright...");
14
+ return new Promise((resolve, reject) => {
15
+ const runners = ["bunx", "npx"];
16
+ exec(runners
17
+ .map((x) => `${x} playwright install chromium --with-deps`)
18
+ .join(" || "), (error, stdout, stderr) => {
19
+ if (error) {
20
+ console.error(`Error during Playwright installation: ${error.message}`);
21
+ return reject(error);
22
+ }
23
+ console.log(stdout);
24
+ resolve();
25
+ });
26
+ });
27
+ }
10
28
  const generatedPath = getPath(`${config.public.path}/${config.public.assets.path}/generated`);
11
29
  const screenshotsPath = getPath(`${generatedPath}/screenshots`);
12
30
  const svgPath = resolve(getPath(dirname(fileURLToPath(import.meta.url))), "../..");
@@ -21,10 +39,8 @@ const generateFavicon = async (src, dest) => {
21
39
  };
22
40
  config.watch = false;
23
41
  config.openBrowser = false;
24
- const browser = await puppeteer.launch({
25
- dumpio: true,
42
+ const browser = await chromium.launch({
26
43
  headless: true,
27
- product: "chrome",
28
44
  });
29
45
  const port = await new Promise(async (resolve) => {
30
46
  const { start } = await import("./start.js");
@@ -33,13 +49,20 @@ const port = await new Promise(async (resolve) => {
33
49
  async function takeScreenshots({ viewports, options, pageCallback, path, }) {
34
50
  return await Promise.all(viewports.map(async (viewport) => {
35
51
  // Create a new page
36
- const page = await browser.newPage();
37
- await page.goto(`${getLocalURL(port)}${path}`);
38
- await page.setViewport(viewport);
52
+ const page = await browser.newPage({
53
+ reducedMotion: "reduce",
54
+ colorScheme: "dark",
55
+ viewport,
56
+ });
39
57
  const suffix = await pageCallback?.(page);
58
+ const optionsResult = options?.(viewport, suffix ? `/${suffix}` : suffix) ?? {};
59
+ await page.goto(`${getLocalURL(port)}${path}`, {
60
+ waitUntil: "load",
61
+ });
62
+ await page.waitForTimeout(3000);
40
63
  const screenshot = await page.screenshot({
41
64
  fullPage: true,
42
- ...options?.(viewport, suffix ? `/${suffix}` : suffix),
65
+ ...optionsResult,
43
66
  });
44
67
  await page.close();
45
68
  return screenshot;
@@ -97,25 +120,32 @@ export async function generateScreenshots() {
97
120
  }))));
98
121
  }
99
122
  export async function generateAssets(callback, src) {
123
+ await installPlaywright();
100
124
  const { default: sharp } = await import("sharp");
101
125
  rmSync(generatedPath, { recursive: true, force: true });
102
126
  if (!existsSync(generatedPath))
103
127
  mkdirSync(screenshotsPath, { recursive: true });
104
128
  const image = sharp(src);
105
129
  const fileNameWithoutExtension = basename(src).split(".")[0];
130
+ const tempFileName = getPath(`${generatedPath}/${fileNameWithoutExtension}-temp.png`);
131
+ await image.png().toFile(tempFileName);
132
+ const dominantColor = await getColor(tempFileName, 1);
133
+ rmSync(tempFileName, { force: true });
134
+ const color = {
135
+ r: dominantColor[0],
136
+ g: dominantColor[1],
137
+ b: dominantColor[2],
138
+ };
139
+ const flattenImage = image.clone().flatten({ background: color });
106
140
  await Promise.all([
107
- ...assetsSizes.webp.map((x) => {
108
- return image
109
- .resize(x, x)
110
- .webp()
111
- .toFile(getPath(`${generatedPath}/${fileNameWithoutExtension}-${x}.webp`));
112
- }),
113
- ...assetsSizes.png.map((x) => {
114
- return image
115
- .resize(x, x)
116
- .png()
117
- .toFile(getPath(`${generatedPath}/${fileNameWithoutExtension}-${x}.png`));
118
- }),
141
+ ...assetsSizes.webp.flatMap((x) => [image, flattenImage].map((y) => y
142
+ .resize(x, x)
143
+ .webp()
144
+ .toFile(getPath(`${generatedPath}/${fileNameWithoutExtension}-${x}${y === flattenImage ? "-masked" : ""}.webp`)))),
145
+ ...assetsSizes.png.flatMap((x) => [image, flattenImage].map((y) => y
146
+ .resize(x, x)
147
+ .png()
148
+ .toFile(getPath(`${generatedPath}/${fileNameWithoutExtension}-${x}${y === flattenImage ? "-masked" : ""}.png`)))),
119
149
  generateFavicon(src, getPath(`${config.public.path}/favicon.ico`)),
120
150
  generateFeatureImage(src),
121
151
  generateScreenshots(),
@@ -2,7 +2,7 @@ import fs from "fs";
2
2
  import { buildSync as esbuild } from "esbuild";
3
3
  import { dirname } from "path";
4
4
  import { fileURLToPath } from "url";
5
- import { assetsSizes } from "../constants.js";
5
+ import { defaultProductionConfig } from "../constants.js";
6
6
  let config = {};
7
7
  if (fs.existsSync("michi.config.ts")) {
8
8
  esbuild({
@@ -23,7 +23,7 @@ if (fs.existsSync("michi.config.ts")) {
23
23
  // @ts-ignore
24
24
  const michiConfig = await import("./michi.config.cjs");
25
25
  config = michiConfig.default.default({
26
- assetsSizes,
26
+ ...defaultProductionConfig,
27
27
  environment: process.env.NODE_ENV,
28
28
  });
29
29
  config.public?.manifest?.options?.file_handlers?.forEach((fileHandler) => {
package/bin/constants.js CHANGED
@@ -12,5 +12,29 @@ export const assetsSizes = {
12
12
  };
13
13
  export const defaultProductionConfig = {
14
14
  assetsSizes,
15
+ icons: [
16
+ ...assetsSizes.webp.map((x) => ({
17
+ src: `/assets/generated/icon-${x}.webp`,
18
+ sizes: `${x}x${x}`,
19
+ type: "image/webp",
20
+ })),
21
+ ...assetsSizes.png.map((x) => ({
22
+ src: `/assets/generated/icon-${x}.png`,
23
+ sizes: `${x}x${x}`,
24
+ type: "image/png",
25
+ })),
26
+ ...assetsSizes.webp.map((x) => ({
27
+ src: `/assets/generated/icon-${x}-maskable.webp`,
28
+ sizes: `${x}x${x}`,
29
+ type: "image/webp",
30
+ purpose: "maskable",
31
+ })),
32
+ ...assetsSizes.png.map((x) => ({
33
+ src: `/assets/generated/icon-${x}-maskable.png`,
34
+ sizes: `${x}x${x}`,
35
+ type: "image/png",
36
+ purpose: "maskable",
37
+ })),
38
+ ],
15
39
  environment: "PRODUCTION",
16
40
  };
package/bin/types.d.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import type { BuildOptions } from "esbuild";
2
2
  import type { ImageResource, WebAppManifest } from "web-app-manifest";
3
3
  import type { assetsSizes } from "./constants.js";
4
- import type { Page } from "puppeteer";
4
+ import type { Page } from "playwright-core";
5
+ export interface Viewport {
6
+ width: number;
7
+ height: number;
8
+ }
5
9
  export interface AssetDescriptorWeb {
6
10
  namespace: "web";
7
11
  site: string;
@@ -129,10 +133,15 @@ export interface PublicOptions {
129
133
  options?: ServerWebAppManifest;
130
134
  };
131
135
  }
136
+ interface ProtocolHandler {
137
+ protocol: string;
138
+ url: string;
139
+ }
132
140
  export interface ServerWebAppManifest extends WebAppManifest {
133
141
  scope_extensions?: {
134
142
  origin: string;
135
143
  }[];
144
+ protocol_handlers?: ProtocolHandler[];
136
145
  file_handlers?: FileHandler[];
137
146
  }
138
147
  export interface FileHandler {
@@ -185,7 +194,9 @@ export interface MichiProcessType {
185
194
  };
186
195
  }
187
196
  export interface ServerConfigFactoryProps<T extends string> {
197
+ icons: ImageResource[];
188
198
  assetsSizes: typeof assetsSizes;
189
199
  environment: T;
190
200
  }
191
201
  export type ServerConfigFactory<T extends string = DefaultEnvironment> = (props: ServerConfigFactoryProps<T>) => ServerConfig;
202
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@michijs/dev-server",
3
3
  "license": "MIT",
4
- "version": "0.7.7",
4
+ "version": "0.7.9",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/michijs/dev-server.git"
@@ -30,9 +30,9 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@michijs/tsconfig": "0.0.4",
33
- "typescript": "^5.5.3",
34
- "@types/node": "22.1.0",
35
- "@types/yargs": "17.0.32"
33
+ "@types/node": "22.4.1",
34
+ "@types/yargs": "17.0.33",
35
+ "typescript": "5.5.3"
36
36
  },
37
37
  "keywords": [
38
38
  "react",
@@ -53,12 +53,13 @@
53
53
  "node": ">=14.16"
54
54
  },
55
55
  "dependencies": {
56
+ "colorthief": "2.4.0",
56
57
  "@types/web-app-manifest": "1.0.8",
57
- "esbuild": "0.23.0",
58
+ "esbuild": "0.23.1",
58
59
  "node-watch": "0.7.4",
59
60
  "open": "10.1.0",
60
- "puppeteer": "22.15.0",
61
- "sharp": "0.33.4",
61
+ "playwright-core": "1.46.1",
62
+ "sharp": "0.33.5",
62
63
  "yargs": "17.7.2"
63
64
  }
64
65
  }