Skip to content

Commit 6943a3f

Browse files
committed
first commit
0 parents  commit 6943a3f

35 files changed

+9895
-0
lines changed

.eslintrc.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"root": true,
3+
"env": {
4+
"browser": true,
5+
"es2020": true,
6+
"node": true
7+
},
8+
"extends": [
9+
"eslint:recommended",
10+
"plugin:@typescript-eslint/recommended",
11+
"plugin:react-hooks/recommended"
12+
],
13+
"ignorePatterns": ["dist", "dist-demo", "node_modules"],
14+
"parser": "@typescript-eslint/parser",
15+
"parserOptions": {
16+
"ecmaVersion": "latest",
17+
"sourceType": "module"
18+
},
19+
"plugins": ["react-refresh"],
20+
"rules": {
21+
"react-refresh/only-export-components": [
22+
"warn",
23+
{ "allowConstantExport": true }
24+
],
25+
"@typescript-eslint/no-explicit-any": "warn",
26+
"@typescript-eslint/no-unused-vars": [
27+
"error",
28+
{ "argsIgnorePattern": "^_" }
29+
]
30+
}
31+
}

.github/workflows/ci.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
jobs:
10+
test:
11+
name: Test
12+
runs-on: ubuntu-latest
13+
14+
strategy:
15+
matrix:
16+
node-version: [18.x, 20.x]
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Node.js ${{ matrix.node-version }}
23+
uses: actions/setup-node@v4
24+
with:
25+
node-version: ${{ matrix.node-version }}
26+
cache: 'npm'
27+
28+
- name: Install dependencies
29+
run: npm ci
30+
31+
- name: Run linter
32+
run: npm run lint
33+
34+
- name: Type check
35+
run: npm run typecheck
36+
37+
- name: Run tests
38+
run: npm test
39+
40+
- name: Upload coverage
41+
if: matrix.node-version == '20.x'
42+
uses: codecov/codecov-action@v4
43+
with:
44+
fail_ci_if_error: false
45+
46+
build:
47+
name: Build
48+
runs-on: ubuntu-latest
49+
50+
steps:
51+
- name: Checkout code
52+
uses: actions/checkout@v4
53+
54+
- name: Setup Node.js
55+
uses: actions/setup-node@v4
56+
with:
57+
node-version: '20.x'
58+
cache: 'npm'
59+
60+
- name: Install dependencies
61+
run: npm ci
62+
63+
- name: Build library
64+
run: npm run build
65+
66+
- name: Check build output
67+
run: |
68+
ls -lh dist/
69+
test -f dist/index.js
70+
test -f dist/index.cjs
71+
test -f dist/index.d.ts
72+
73+
- name: Upload build artifacts
74+
uses: actions/upload-artifact@v4
75+
with:
76+
name: dist
77+
path: dist/
78+
retention-days: 7

.github/workflows/publish.yml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Publish to NPM
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
publish:
9+
name: Publish
10+
runs-on: ubuntu-latest
11+
12+
permissions:
13+
contents: read
14+
id-token: write # Required for NPM provenance
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: '20.x'
24+
registry-url: 'https://registry.npmjs.org'
25+
cache: 'npm'
26+
27+
- name: Install dependencies
28+
run: npm ci
29+
30+
- name: Run tests
31+
run: npm test
32+
33+
- name: Build library
34+
run: npm run build
35+
36+
- name: Publish to NPM
37+
run: npm publish --provenance --access public
38+
env:
39+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
40+
41+
- name: Create GitHub Release Comment
42+
uses: actions/github-script@v7
43+
with:
44+
script: |
45+
const release = context.payload.release
46+
const comment = `🎉 Published to NPM: https://www.npmjs.com/package/react-shrink
47+
48+
Install with:
49+
\`\`\`bash
50+
npm install react-shrink@${release.tag_name.replace('v', '')}
51+
\`\`\`
52+
`
53+
github.rest.issues.createComment({
54+
issue_number: release.id,
55+
owner: context.repo.owner,
56+
repo: context.repo.repo,
57+
body: comment
58+
})

.github/workflows/size.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
name: Bundle Size Check
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
7+
jobs:
8+
size:
9+
name: Check Bundle Size
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v4
18+
with:
19+
node-version: '20.x'
20+
cache: 'npm'
21+
22+
- name: Install dependencies
23+
run: npm ci
24+
25+
- name: Build library
26+
run: npm run build
27+
28+
- name: Check bundle size
29+
run: |
30+
echo "## Bundle Size Report" >> $GITHUB_STEP_SUMMARY
31+
echo "" >> $GITHUB_STEP_SUMMARY
32+
echo "| File | Size | Gzipped |" >> $GITHUB_STEP_SUMMARY
33+
echo "|------|------|---------|" >> $GITHUB_STEP_SUMMARY
34+
35+
for file in dist/*.js dist/*.cjs; do
36+
if [ -f "$file" ]; then
37+
name=$(basename "$file")
38+
size=$(wc -c < "$file" | awk '{printf "%.2f KB", $1/1024}')
39+
gzip_size=$(gzip -c "$file" | wc -c | awk '{printf "%.2f KB", $1/1024}')
40+
echo "| $name | $size | $gzip_size |" >> $GITHUB_STEP_SUMMARY
41+
fi
42+
done
43+
44+
echo "" >> $GITHUB_STEP_SUMMARY
45+
echo "### Size Limits" >> $GITHUB_STEP_SUMMARY
46+
echo "- ✅ ESM bundle should be < 50KB (gzipped < 15KB)" >> $GITHUB_STEP_SUMMARY
47+
echo "- ✅ CJS bundle should be < 50KB (gzipped < 15KB)" >> $GITHUB_STEP_SUMMARY
48+
49+
# Check if any file is too large (50KB uncompressed)
50+
for file in dist/index.js dist/index.cjs; do
51+
if [ -f "$file" ]; then
52+
size=$(wc -c < "$file")
53+
if [ $size -gt 51200 ]; then
54+
name=$(basename "$file")
55+
echo "::error::$name is too large: $(($size / 1024)) KB (max 50 KB)"
56+
exit 1
57+
fi
58+
fi
59+
done
60+
61+
- name: Comment PR
62+
uses: actions/github-script@v7
63+
if: github.event_name == 'pull_request'
64+
with:
65+
script: |
66+
const fs = require('fs');
67+
const files = ['dist/index.js', 'dist/index.cjs'];
68+
69+
let comment = '## 📦 Bundle Size Report\n\n';
70+
comment += '| File | Size | Gzipped |\n';
71+
comment += '|------|------|---------|\\n';
72+
73+
for (const file of files) {
74+
if (fs.existsSync(file)) {
75+
const stats = fs.statSync(file);
76+
const sizeKB = (stats.size / 1024).toFixed(2);
77+
const { execSync } = require('child_process');
78+
const gzipSize = execSync(`gzip -c ${file} | wc -c`).toString().trim();
79+
const gzipKB = (parseInt(gzipSize) / 1024).toFixed(2);
80+
const name = file.split('/').pop();
81+
comment += `| ${name} | ${sizeKB} KB | ${gzipKB} KB |\\n`;
82+
}
83+
}
84+
85+
comment += '\n✅ All bundles are within size limits!';
86+
87+
github.rest.issues.createComment({
88+
issue_number: context.issue.number,
89+
owner: context.repo.owner,
90+
repo: context.repo.repo,
91+
body: comment
92+
});

.gitignore

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
# Dependencies
11+
node_modules
12+
.pnp
13+
.pnp.js
14+
15+
# Build outputs
16+
dist
17+
dist-demo
18+
dist-ssr
19+
*.local
20+
21+
# Editor directories and files
22+
.vscode/*
23+
!.vscode/extensions.json
24+
.idea
25+
.DS_Store
26+
*.suo
27+
*.ntvs*
28+
*.njsproj
29+
*.sln
30+
*.sw?
31+
32+
# Testing
33+
coverage
34+
.nyc_output
35+
36+
# Environment variables
37+
.env
38+
.env.local
39+
.env.production.local
40+
.env.development.local
41+
.env.test.local
42+
43+
# OS files
44+
Thumbs.db
45+
46+
# TypeScript
47+
*.tsbuildinfo

.husky/pre-commit

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env sh
2+
. "$(dirname -- "$0")/_/husky.sh"
3+
4+
npx lint-staged

.prettierrc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"trailingComma": "es5",
6+
"printWidth": 100,
7+
"arrowParens": "always"
8+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Badla Moussaab
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)