Compare commits

...

3 Commits

Author SHA1 Message Date
DarkSky
41fa209047 Merge branch 'canary' into darksky/lit-style-minify 2026-02-24 09:16:27 +08:00
DarkSky
f8146526af fix: test stability 2026-02-24 01:38:31 +08:00
DarkSky
a3603cc0c8 feat: minify lit styles 2026-02-24 01:38:31 +08:00
7 changed files with 351 additions and 87 deletions

View File

@@ -194,13 +194,27 @@ const PAGE_SIZE = 6;
export const BackupSettingPanel = () => {
const t = useI18n();
const backupService = useService(BackupService);
const [retryCount, setRetryCount] = useState(0);
useEffect(() => {
setRetryCount(0);
backupService.revalidate();
}, [backupService]);
const isLoading = useLiveData(backupService.isLoading$);
const backupWorkspaces = useLiveData(backupService.pageBackupWorkspaces$);
const backupCount = backupWorkspaces?.items.length ?? 0;
useEffect(() => {
// Workspace deletion may complete slightly after panel mount.
// Retry a few times to avoid showing stale empty state.
if (isLoading || backupCount > 0 || retryCount >= 4) return;
const timer = setTimeout(() => {
setRetryCount(current => current + 1);
backupService.revalidate();
}, 1000);
return () => clearTimeout(timer);
}, [backupCount, backupService, isLoading, retryCount]);
const [pageNum, setPageNum] = useState(0);

View File

@@ -137,15 +137,26 @@ test('delete workspace and then restore it from backup', async ({ page }) => {
);
//#endregion
await page.waitForTimeout(1000);
await expect
.poll(
async () =>
(
await page.evaluate(async () => {
return await window.__apis?.workspace.getBackupWorkspaces();
})
)?.items.length,
{ timeout: 20000 }
)
.toBeGreaterThan(0);
//#region 4. restore the workspace from backup
await page.getByTestId('slider-bar-workspace-setting-button').click();
await expect(page.getByTestId('setting-modal')).toBeVisible();
await page.getByTestId('backup-panel-trigger').click();
await expect(page.getByTestId('backup-workspace-item')).toHaveCount(1);
await page.getByTestId('backup-workspace-item').click();
const backupWorkspaceItems = page.getByTestId('backup-workspace-item');
await expect(backupWorkspaceItems.first()).toBeVisible();
await backupWorkspaceItems.first().click();
await page.getByRole('menuitem', { name: 'Enable local workspace' }).click();
const toast = page.locator(
'[data-sonner-toast]:has-text("Workspace enabled successfully")'

View File

@@ -36,6 +36,7 @@
"lodash-es": "^4.17.23",
"mime-types": "^3.0.0",
"mini-css-extract-plugin": "^2.9.2",
"minify-html-literals": "^1.3.5",
"node-loader": "^2.1.0",
"postcss": "^8.4.49",
"postcss-loader": "^8.1.1",

View File

@@ -22,6 +22,9 @@ import {
const require = createRequire(import.meta.url);
const IN_CI = !!process.env.CI;
const LIT_CSS_MINIFY_LOADER = Path.dir(import.meta.url).join(
'../webpack/lit-css-minify-loader.cjs'
).value;
const availableChannels = ['canary', 'beta', 'stable', 'internal'];
function getBuildConfigFromEnv(pkg: Package) {
@@ -145,55 +148,69 @@ export function createHTMLTargetConfig(
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: false,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
useDefineForClassFields: false,
decoratorVersion: '2022-03',
use: compact([
!buildConfig.debug && {
loader: LIT_CSS_MINIFY_LOADER,
},
{
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: false,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
useDefineForClassFields: false,
decoratorVersion: '2022-03',
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
]),
},
{
test: /\.tsx$/,
exclude: /node_modules/,
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: true,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
react: { runtime: 'automatic' },
useDefineForClassFields: false,
decoratorVersion: '2022-03',
use: compact([
!buildConfig.debug && {
loader: LIT_CSS_MINIFY_LOADER,
},
{
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: true,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
react: { runtime: 'automatic' },
useDefineForClassFields: false,
decoratorVersion: '2022-03',
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
]),
},
{
test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/,

View File

@@ -24,6 +24,9 @@ const require = createRequire(import.meta.url);
const cssnano = require('cssnano');
const IN_CI = !!process.env.CI;
const LIT_CSS_MINIFY_LOADER = Path.dir(import.meta.url).join(
'lit-css-minify-loader.cjs'
).value;
const availableChannels = ['canary', 'beta', 'stable', 'internal'];
function getBuildConfigFromEnv(pkg: Package) {
@@ -147,55 +150,69 @@ export function createHTMLTargetConfig(
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: false,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
useDefineForClassFields: false,
decoratorVersion: '2022-03',
use: compact([
!buildConfig.debug && {
loader: LIT_CSS_MINIFY_LOADER,
},
{
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: false,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
useDefineForClassFields: false,
decoratorVersion: '2022-03',
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
]),
},
{
test: /\.tsx$/,
exclude: /node_modules/,
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: true,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
react: { runtime: 'automatic' },
useDefineForClassFields: false,
decoratorVersion: '2022-03',
use: compact([
!buildConfig.debug && {
loader: LIT_CSS_MINIFY_LOADER,
},
{
loader: 'swc-loader',
options: {
// https://swc.rs/docs/configuring-swc/
jsc: {
preserveAllComments: true,
parser: {
syntax: 'typescript',
dynamicImport: true,
topLevelAwait: false,
tsx: true,
decorators: true,
},
target: 'es2022',
externalHelpers: false,
transform: {
react: { runtime: 'automatic' },
useDefineForClassFields: false,
decoratorVersion: '2022-03',
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
},
sourceMaps: true,
inlineSourcesContent: true,
},
]),
},
{
test: /\.(png|jpg|gif|svg|webp|mp4|zip)$/,

View File

@@ -0,0 +1,31 @@
const { minifyHTMLLiterals } = require('minify-html-literals');
/**
* Minify CSS in tagged template literals (e.g. lit `css```) while leaving
* HTML templates untouched to avoid parser regressions on dynamic templates.
*
* @type {import('webpack').LoaderDefinitionFunction}
*/
module.exports = function litCssMinifyLoader(source, sourceMap) {
if (typeof source !== 'string' || !source.includes('`')) {
return source;
}
try {
const result = minifyHTMLLiterals(source, {
fileName: this.resourcePath,
shouldMinify: () => false,
shouldMinifyCSS: template =>
!!template.tag && template.tag.toLowerCase().includes('css'),
});
if (!result) {
return source;
}
this.callback(null, result.code, result.map ?? sourceMap);
return;
} catch {
return source;
}
};

177
yarn.lock
View File

@@ -141,6 +141,7 @@ __metadata:
lodash-es: "npm:^4.17.23"
mime-types: "npm:^3.0.0"
mini-css-extract-plugin: "npm:^2.9.2"
minify-html-literals: "npm:^1.3.5"
node-loader: "npm:^2.1.0"
postcss: "npm:^8.4.49"
postcss-loader: "npm:^8.1.1"
@@ -17297,6 +17298,16 @@ __metadata:
languageName: node
linkType: hard
"@types/clean-css@npm:*":
version: 4.2.11
resolution: "@types/clean-css@npm:4.2.11"
dependencies:
"@types/node": "npm:*"
source-map: "npm:^0.6.0"
checksum: 10/385337a881c7870664d8987f12b9c814d835104dcf5f1737b74ab759ca68424ce93636cbff73ea9c41290c3dc2a92a4cc6246869bd9982255cfa28dcc2ccec93
languageName: node
linkType: hard
"@types/connect-history-api-fallback@npm:^1.5.4":
version: 1.5.4
resolution: "@types/connect-history-api-fallback@npm:1.5.4"
@@ -17818,6 +17829,17 @@ __metadata:
languageName: node
linkType: hard
"@types/html-minifier@npm:^3.5.3":
version: 3.5.3
resolution: "@types/html-minifier@npm:3.5.3"
dependencies:
"@types/clean-css": "npm:*"
"@types/relateurl": "npm:*"
"@types/uglify-js": "npm:*"
checksum: 10/bad3bece7ec0c29d81266a5884ade79a6d6fb5c10b9a7b79e17dae13290052776a1a5a571125fd5f47e396cd45304eafaec41b68bf42d0dd765356cf77a6e088
languageName: node
linkType: hard
"@types/http-assert@npm:*":
version: 1.5.6
resolution: "@types/http-assert@npm:1.5.6"
@@ -18277,6 +18299,13 @@ __metadata:
languageName: node
linkType: hard
"@types/relateurl@npm:*":
version: 0.2.33
resolution: "@types/relateurl@npm:0.2.33"
checksum: 10/a4b7876cc24da3eddc1202d9f57fb6cdd551ff3d884124365dd15012dde20c2b4c19eee9bcd3b17e7c43e8edbe82a33753a6c266e41e3761283d44e6234d47da
languageName: node
linkType: hard
"@types/resolve@npm:^1.20.2":
version: 1.20.6
resolution: "@types/resolve@npm:1.20.6"
@@ -18437,6 +18466,15 @@ __metadata:
languageName: node
linkType: hard
"@types/uglify-js@npm:*":
version: 3.17.5
resolution: "@types/uglify-js@npm:3.17.5"
dependencies:
source-map: "npm:^0.6.1"
checksum: 10/87368861a3f2df071905d698c9f7a4b825e2f69dd29530283594ccddd155d4a8ff7795021af28a97d938c9557a6ea23bc3d77e076a6cf3e02f6401849e067f61
languageName: node
linkType: hard
"@types/unist@npm:*, @types/unist@npm:^3.0.0":
version: 3.0.3
resolution: "@types/unist@npm:3.0.3"
@@ -20753,6 +20791,16 @@ __metadata:
languageName: node
linkType: hard
"camel-case@npm:^3.0.0":
version: 3.0.0
resolution: "camel-case@npm:3.0.0"
dependencies:
no-case: "npm:^2.2.0"
upper-case: "npm:^1.1.1"
checksum: 10/4190ed6ab8acf4f3f6e1a78ad4d0f3f15ce717b6bfa1b5686d58e4bcd29960f6e312dd746b5fa259c6d452f1413caef25aee2e10c9b9a580ac83e516533a961a
languageName: node
linkType: hard
"camel-case@npm:^4.1.2":
version: 4.1.2
resolution: "camel-case@npm:4.1.2"
@@ -21223,6 +21271,15 @@ __metadata:
languageName: node
linkType: hard
"clean-css@npm:^4.2.1":
version: 4.2.4
resolution: "clean-css@npm:4.2.4"
dependencies:
source-map: "npm:~0.6.0"
checksum: 10/4f64dbebfa29feb79be25d6f91239239179adc805c6d7442e2c728970ca23a75b5f238118477b4b78553b89e50f14a64fe35145ecc86b6badf971883c4ad2ffe
languageName: node
linkType: hard
"clean-css@npm:^5.2.2":
version: 5.3.3
resolution: "clean-css@npm:5.3.3"
@@ -21604,7 +21661,7 @@ __metadata:
languageName: node
linkType: hard
"commander@npm:^2.20.0, commander@npm:^2.20.3":
"commander@npm:^2.19.0, commander@npm:^2.20.0, commander@npm:^2.20.3":
version: 2.20.3
resolution: "commander@npm:2.20.3"
checksum: 10/90c5b6898610cd075984c58c4f88418a4fb44af08c1b1415e9854c03171bec31b336b7f3e4cefe33de994b3f12b03c5e2d638da4316df83593b9e82554e7e95b
@@ -26506,6 +26563,23 @@ __metadata:
languageName: node
linkType: hard
"html-minifier@npm:^4.0.0":
version: 4.0.0
resolution: "html-minifier@npm:4.0.0"
dependencies:
camel-case: "npm:^3.0.0"
clean-css: "npm:^4.2.1"
commander: "npm:^2.19.0"
he: "npm:^1.2.0"
param-case: "npm:^2.1.1"
relateurl: "npm:^0.2.7"
uglify-js: "npm:^3.5.1"
bin:
html-minifier: ./cli.js
checksum: 10/a1a49ee78a41eb3232f7aa51be25092d7634548e8996577b2bdab22dc9ac736594d35aab7fdf81fb5a0da11f7bc688f500c297b24fd312d48c0ce8739ed4f06f
languageName: node
linkType: hard
"html-parse-stringify2@github:locize/html-parse-stringify2":
version: 2.0.1
resolution: "html-parse-stringify2@https://github.com/locize/html-parse-stringify2.git#commit=d463109433b2c49c74a081044f54b2a6a1ccad7c"
@@ -29154,6 +29228,13 @@ __metadata:
languageName: node
linkType: hard
"lower-case@npm:^1.1.1":
version: 1.1.4
resolution: "lower-case@npm:1.1.4"
checksum: 10/0c4aebc459ba330bcc38d20cad26ee33111155ed09c09e7d7ec395997277feee3a4d8db541ed5ca555f20ddc5c65a3b23648d18fcd2a950376da6d0c2e01416e
languageName: node
linkType: hard
"lower-case@npm:^2.0.2":
version: 2.0.2
resolution: "lower-case@npm:2.0.2"
@@ -29262,6 +29343,15 @@ __metadata:
languageName: node
linkType: hard
"magic-string@npm:^0.25.0":
version: 0.25.9
resolution: "magic-string@npm:0.25.9"
dependencies:
sourcemap-codec: "npm:^1.4.8"
checksum: 10/87a14b944bd169821cbd54b169a7ab6b0348fd44b5497266dc555dd70280744e9e88047da9dcb95675bdc23b1ce33f13398b0f70b3be7b858225ccb1d185ff51
languageName: node
linkType: hard
"magic-string@npm:^0.30.0, magic-string@npm:^0.30.17, magic-string@npm:^0.30.21":
version: 0.30.21
resolution: "magic-string@npm:0.30.21"
@@ -30264,6 +30354,19 @@ __metadata:
languageName: node
linkType: hard
"minify-html-literals@npm:^1.3.5":
version: 1.3.5
resolution: "minify-html-literals@npm:1.3.5"
dependencies:
"@types/html-minifier": "npm:^3.5.3"
clean-css: "npm:^4.2.1"
html-minifier: "npm:^4.0.0"
magic-string: "npm:^0.25.0"
parse-literals: "npm:^1.2.1"
checksum: 10/9f5b50055e0df5763463f37136418af5a143169ffa1bafdc73571ab36563e5c49e4bf5068f7cc2cecd80b07d974e467e3879e750139e14c400b99843e9c23737
languageName: node
linkType: hard
"minimalistic-assert@npm:^1.0.0":
version: 1.0.1
resolution: "minimalistic-assert@npm:1.0.1"
@@ -30967,6 +31070,15 @@ __metadata:
languageName: node
linkType: hard
"no-case@npm:^2.2.0":
version: 2.3.2
resolution: "no-case@npm:2.3.2"
dependencies:
lower-case: "npm:^1.1.1"
checksum: 10/a92fc7c10f40477bb69c3ca00e2a12fd08f838204bcef66233cbe8a36c0ec7938ba0cdf3f0534b38702376cbfa26270130607c0b8460ea87f44d474919c39c91
languageName: node
linkType: hard
"no-case@npm:^3.0.4":
version: 3.0.4
resolution: "no-case@npm:3.0.4"
@@ -31899,6 +32011,15 @@ __metadata:
languageName: node
linkType: hard
"param-case@npm:^2.1.1":
version: 2.1.1
resolution: "param-case@npm:2.1.1"
dependencies:
no-case: "npm:^2.2.0"
checksum: 10/3a63dcb8d8dc7995a612de061afdc7bb6fe7bd0e6db994db8d4cae999ed879859fd24389090e1a0d93f4c9207ebf8c048c870f468a3f4767161753e03cb9ab58
languageName: node
linkType: hard
"param-case@npm:^3.0.4":
version: 3.0.4
resolution: "param-case@npm:3.0.4"
@@ -31983,6 +32104,15 @@ __metadata:
languageName: node
linkType: hard
"parse-literals@npm:^1.2.1":
version: 1.2.1
resolution: "parse-literals@npm:1.2.1"
dependencies:
typescript: "npm:^2.9.2 || ^3.0.0 || ^4.0.0"
checksum: 10/8f1ad2ed47887b555a909a402d47dfa94d57adc5f3f70b10543618eebfd77912295e54989971a580d4704994e498263ec2a2ceb0ed53fdd1a3b57449254f094e
languageName: node
linkType: hard
"parse-ms@npm:^4.0.0":
version: 4.0.0
resolution: "parse-ms@npm:4.0.0"
@@ -35844,7 +35974,7 @@ __metadata:
languageName: node
linkType: hard
"source-map@npm:^0.6.0, source-map@npm:~0.6.0, source-map@npm:~0.6.1":
"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1":
version: 0.6.1
resolution: "source-map@npm:0.6.1"
checksum: 10/59ef7462f1c29d502b3057e822cdbdae0b0e565302c4dd1a95e11e793d8d9d62006cdc10e0fd99163ca33ff2071360cf50ee13f90440806e7ed57d81cba2f7ff
@@ -35858,6 +35988,13 @@ __metadata:
languageName: node
linkType: hard
"sourcemap-codec@npm:^1.4.8":
version: 1.4.8
resolution: "sourcemap-codec@npm:1.4.8"
checksum: 10/6fc57a151e982b5c9468362690c6d062f3a0d4d8520beb68a82f319c79e7a4d7027eeb1e396de0ecc2cd19491e1d602b2d06fd444feac9b63dd43fea4c55a857
languageName: node
linkType: hard
"space-separated-tokens@npm:^2.0.0":
version: 2.0.2
resolution: "space-separated-tokens@npm:2.0.2"
@@ -37541,6 +37678,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@npm:^2.9.2 || ^3.0.0 || ^4.0.0":
version: 4.9.5
resolution: "typescript@npm:4.9.5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10/458f7220ab11e0fc191514cc41be1707645ec9a8c2d609448a448e18c522cef9646f58728f6811185a4c35613dacdf6c98cf8965c88b3541d0288c47291e4300
languageName: node
linkType: hard
"typescript@npm:~5.4.5":
version: 5.4.5
resolution: "typescript@npm:5.4.5"
@@ -37561,6 +37708,16 @@ __metadata:
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A^2.9.2 || ^3.0.0 || ^4.0.0#optional!builtin<compat/typescript>":
version: 4.9.5
resolution: "typescript@patch:typescript@npm%3A4.9.5#optional!builtin<compat/typescript>::version=4.9.5&hash=289587"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10/5659316360b5cc2d6f5931b346401fa534107b68b60179cf14970e27978f0936c1d5c46f4b5b8175f8cba0430f522b3ce355b4b724c0ea36ce6c0347fab25afd
languageName: node
linkType: hard
"typescript@patch:typescript@npm%3A~5.4.5#optional!builtin<compat/typescript>":
version: 5.4.5
resolution: "typescript@patch:typescript@npm%3A5.4.5#optional!builtin<compat/typescript>::version=5.4.5&hash=5adc0c"
@@ -37594,6 +37751,15 @@ __metadata:
languageName: node
linkType: hard
"uglify-js@npm:^3.5.1":
version: 3.19.3
resolution: "uglify-js@npm:3.19.3"
bin:
uglifyjs: bin/uglifyjs
checksum: 10/6b9639c1985d24580b01bb0ab68e78de310d38eeba7db45bec7850ab4093d8ee464d80ccfaceda9c68d1c366efbee28573b52f95e69ac792354c145acd380b11
languageName: node
linkType: hard
"uid2@npm:1.0.0":
version: 1.0.0
resolution: "uid2@npm:1.0.0"
@@ -37983,6 +38149,13 @@ __metadata:
languageName: node
linkType: hard
"upper-case@npm:^1.1.1":
version: 1.1.3
resolution: "upper-case@npm:1.1.3"
checksum: 10/fc4101fdcd783ee963d49d279186688d4ba2fab90e78dbd001ad141522a66ccfe310932f25e70d5211b559ab205be8c24bf9c5520c7ab7dcd0912274c6d976a3
languageName: node
linkType: hard
"upper-case@npm:^2.0.2":
version: 2.0.2
resolution: "upper-case@npm:2.0.2"