Skip to content

Commit

Permalink
chore: add a better package minifier
Browse files Browse the repository at this point in the history
  • Loading branch information
orefalo committed Jun 21, 2024
1 parent 69e6dd0 commit a2d4b66
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 111 deletions.
8 changes: 7 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
"singleQuote": true,
"trailingComma": "none",
"printWidth": 120,
"plugins": ["prettier-plugin-svelte"]
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
"options": { "parser": "svelte" }
}
]
}
1 change: 0 additions & 1 deletion SizeAndPositionManager.d.ts.new

This file was deleted.

4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[ ] Add a <PartialLoader/> to fetch the model on demand
[ ] Add class and style attributes
[x] Add class and style attributes - implemeted via {...attributes}
[x] store the model inside the component
[x] Rename the row snippet to something else -> slot
[ ] add disabled
[ ] move the css style logic out of the component row({ item, style, index })
[ ] considering, items={data} itemCount={data.length} itemSize={50}; model is data, items is the view should be transformed into model={data} modelCount={data.length} itemSize={50}, {@render item(...)}
[x] implement minimization for the npm package
[x] implement minimization for the npm package
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"url": "https://github.com/orefalo/svelte-virtuallists.git"
},
"license": "MIT",
"author": {
"name": "Olivier Refalo",
"url": "https://github.com/orefalo"
},
"type": "module",
"exports": {
"./package.json": "./package.json",
Expand Down Expand Up @@ -67,7 +71,6 @@
"copyfiles": "^2.4.1",
"cross-env": "^7.0.3",
"cz-customizable": "^7.0.0",
"dts-minify": "^0.3.3",
"eslint": "^9.5.0",
"eslint-config-prettier": "^9.1.0",
"eslint-gitignore": "^0.1.0",
Expand Down
198 changes: 101 additions & 97 deletions scripts/dtsminify/main.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,106 @@
"use strict";
'use strict';


var newLineCharCode = "\n".charCodeAt(0);
var newLineCharCode = '\n'.charCodeAt(0);
// todo: type the `ts` import (maybe with a local type that defines the expected compiler API structure)
/** Creates a minifier that should be stored and then used to minify one or more files. */
export function createMinifier(ts) {
var scanner = ts.createScanner(ts.ScriptTarget.Latest,
/* skipTrivia */ false, ts.LanguageVariant.Standard);
return {
minify: minify,
};
function minify(fileText, options) {
var _a;
var keepJsDocs = (_a = options === null || options === void 0 ? void 0 : options.keepJsDocs) !== null && _a !== void 0 ? _a : false;
var result = "";
var lastWrittenToken;
var lastHadSeparatingNewLine = false;
scanner.setText(fileText);
while (scanner.scan() !== ts.SyntaxKind.EndOfFileToken) {
var currentToken = scanner.getToken();
switch (currentToken) {
case ts.SyntaxKind.NewLineTrivia:
lastHadSeparatingNewLine = true;
break;
case ts.SyntaxKind.WhitespaceTrivia:
break;
case ts.SyntaxKind.SingleLineCommentTrivia:
if (isTripleSlashDirective()) {
writeSingleLineComment();
lastHadSeparatingNewLine = false;
}
break;
case ts.SyntaxKind.MultiLineCommentTrivia:
if (keepJsDocs && isJsDoc()) {
writeJsDoc();
lastHadSeparatingNewLine = false;
}
break;
default:
// use a newline where ASI is probable
if (currentToken === ts.SyntaxKind.Identifier &&
lastHadSeparatingNewLine &&
lastWrittenToken !== ts.SyntaxKind.SemicolonToken &&
lastWrittenToken !== ts.SyntaxKind.CloseBraceToken &&
lastWrittenToken !== ts.SyntaxKind.OpenBraceToken &&
lastWrittenToken !== ts.SyntaxKind.OpenParenToken &&
lastWrittenToken !== ts.SyntaxKind.CommaToken &&
lastWrittenToken !== ts.SyntaxKind.ColonToken) {
result += "\n";
}
writeText(scanner.getTokenText());
lastHadSeparatingNewLine = false;
}
}
return result;
function isTripleSlashDirective() {
var tokenText = scanner.getTokenText();
// todo: better check
return tokenText.startsWith("///") && tokenText.includes("<");
}
function writeSingleLineComment() {
writeText(scanner.getTokenText());
// write out the next newline as-is (ex. write \n or \r\n)
var nextToken = scanner.scan();
if (nextToken === ts.SyntaxKind.NewLineTrivia) {
writeText(scanner.getTokenText());
}
else if (nextToken !== ts.SyntaxKind.EndOfFileToken) {
throw new Error("Unexpected scenario where the token after a comment was a ".concat(nextToken, "."));
}
}
function isJsDoc() {
var tokenText = scanner.getTokenText();
return tokenText.startsWith("/**");
}
function writeJsDoc() {
writeText(scanner.getTokenText().replace(/^\s+\*/mg, " *"));
}
function writeText(text) {
var token = scanner.getToken();
// ensure two tokens that would merge into a single token are separated by a space
if (lastWrittenToken != null &&
isAlphaNumericToken(token) &&
isAlphaNumericToken(lastWrittenToken) &&
!wasLastWrittenNewLine()) {
result += " ";
}
result += text;
lastWrittenToken = token;
}
function wasLastWrittenNewLine() {
return result.charCodeAt(result.length - 1) === newLineCharCode;
}
}
function isAlphaNumericToken(token) {
if (token >= ts.SyntaxKind.FirstKeyword && token <= ts.SyntaxKind.LastKeyword) {
return true;
}
return token === ts.SyntaxKind.Identifier;
}
var scanner = ts.createScanner(ts.ScriptTarget.Latest, /* skipTrivia */ false, ts.LanguageVariant.Standard);
return {
minify: minify
};
function minify(fileText, options) {
var _a;
var keepJsDocs =
(_a = options === null || options === void 0 ? void 0 : options.keepJsDocs) !== null && _a !== void 0
? _a
: false;
var result = '';
var lastWrittenToken;
var lastHadSeparatingNewLine = false;
scanner.setText(fileText);
while (scanner.scan() !== ts.SyntaxKind.EndOfFileToken) {
var currentToken = scanner.getToken();
switch (currentToken) {
case ts.SyntaxKind.NewLineTrivia:
lastHadSeparatingNewLine = true;
break;
case ts.SyntaxKind.WhitespaceTrivia:
break;
case ts.SyntaxKind.SingleLineCommentTrivia:
if (isTripleSlashDirective()) {
writeSingleLineComment();
lastHadSeparatingNewLine = false;
}
break;
case ts.SyntaxKind.MultiLineCommentTrivia:
if (keepJsDocs && isJsDoc()) {
writeJsDoc();
lastHadSeparatingNewLine = false;
}
break;
default:
// use a newline where ASI is probable
if (
currentToken === ts.SyntaxKind.Identifier &&
lastHadSeparatingNewLine &&
lastWrittenToken !== ts.SyntaxKind.SemicolonToken &&
lastWrittenToken !== ts.SyntaxKind.CloseBraceToken &&
lastWrittenToken !== ts.SyntaxKind.OpenBraceToken &&
lastWrittenToken !== ts.SyntaxKind.OpenParenToken &&
lastWrittenToken !== ts.SyntaxKind.CommaToken &&
lastWrittenToken !== ts.SyntaxKind.ColonToken
) {
result += '\n';
}
writeText(scanner.getTokenText());
lastHadSeparatingNewLine = false;
}
}
return result;
function isTripleSlashDirective() {
var tokenText = scanner.getTokenText();
// todo: better check
return tokenText.startsWith('///') && tokenText.includes('<');
}
function writeSingleLineComment() {
writeText(scanner.getTokenText());
// write out the next newline as-is (ex. write \n or \r\n)
var nextToken = scanner.scan();
if (nextToken === ts.SyntaxKind.NewLineTrivia) {
writeText(scanner.getTokenText());
} else if (nextToken !== ts.SyntaxKind.EndOfFileToken) {
throw new Error('Unexpected scenario where the token after a comment was a '.concat(nextToken, '.'));
}
}
function isJsDoc() {
var tokenText = scanner.getTokenText();
return tokenText.startsWith('/**');
}
function writeJsDoc() {
writeText(scanner.getTokenText().replace(/^\s+\*/gm, ' *'));
}
function writeText(text) {
var token = scanner.getToken();
// ensure two tokens that would merge into a single token are separated by a space
if (
lastWrittenToken &&
isAlphaNumericToken(token) &&
isAlphaNumericToken(lastWrittenToken) &&
!wasLastWrittenNewLine()
) {
result += ' ';
}
result += text;
lastWrittenToken = token;
}
function wasLastWrittenNewLine() {
return result.charCodeAt(result.length - 1) === newLineCharCode;
}
}
function isAlphaNumericToken(token) {
if (token >= ts.SyntaxKind.FirstKeyword && token <= ts.SyntaxKind.LastKeyword) {
return true;
}
return token === ts.SyntaxKind.Identifier;
}
}
3 changes: 1 addition & 2 deletions scripts/minify-package.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ const simpleErrorCB = (err) => {
};

async function processPackage(path) {

console.log("Minimizing package...")
console.log('Minimizing package...');

try {
const files = fs.readdirSync(path);
Expand Down
10 changes: 7 additions & 3 deletions src/lib/VirtualList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
itemCount,
// provided or calculated size of item n
itemSize,
// usefull when using the progressive loader
// usefull when using a partial loader
estimatedItemSize,
getKey,
Expand All @@ -69,7 +69,10 @@
// events
onVisibleRangeUpdate,
onAfterScroll
onAfterScroll,
...attributes
}: {
height: number | string;
width: number | string;
Expand All @@ -92,6 +95,7 @@
// events
onVisibleRangeUpdate?: (range: VirtualRangeEvent) => void;
onAfterScroll?: (event: AfterScrollEvent) => void;
} = $props();
const SCROLL_PROP = {
Expand Down Expand Up @@ -379,7 +383,7 @@
}
</script>

<div bind:this={container} class="virtual-list-wrapper" style={wrapperStyle}>
<div bind:this={container} class="virtual-list-wrapper" style={wrapperStyle} {...attributes}>
{#if header}
{@render header()}
{/if}
Expand Down
1 change: 0 additions & 1 deletion src/routes/examples/events/code.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
// that's the model, which we don't use for this example
const myItems: Array<number> = new Array(10000).fill(1).map((v, i) => i);
let virtualList: VirtualList;
// on the UI
Expand Down
2 changes: 1 addition & 1 deletion src/routes/examples/styles/code.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<div class="list">
<VirtualList width="100%" height={600} items={data} itemCount={data.length} itemSize={50}>
{#snippet slot({ item, style, index }:{item:any, style:string, index:number})}
{#snippet slot({ item, style, index }: { item: any; style: string; index: number })}
<div class="row" {style}>
Letter: {item}, Row: #{index}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/examples/variableheight/code.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

<div class="list">
<VirtualList bind:this={virtualList} items={myItems} height={500} width="auto" {itemCount} itemSize={rowHeights}>
{#snippet slot({ item, style, index }:SlotAttributes<MyItemsData>)}
{#snippet slot({ item, style, index }: SlotAttributes<MyItemsData>)}
<div class="row" {style}>
{item.text}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/examples/vertical/code.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

<div class="list">
<VirtualList items={myItems} height={500} width="auto" itemCount={myItems.length} {itemSize}>
{#snippet slot({ item, style, index }:SlotAttributes<MyItemsData>)}
{#snippet slot({ item, style, index }: SlotAttributes<MyItemsData>)}
<div class="row" {style}>
{item.text}
</div>
Expand Down

0 comments on commit a2d4b66

Please sign in to comment.