Skip to content

Commit afbf290

Browse files
committed
Add linting, tests, sourcemaps and release workflow
- ESLint 9 flat config with browser/CJS globals - Vitest + happy-dom test suite (14 tests) - Sourcemap generation for minified build - npm publish workflow on GitHub Release - CHANGELOG.md with initial v1.0.0 entry
1 parent 85d7f5f commit afbf290

10 files changed

Lines changed: 2986 additions & 51 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ jobs:
2020
cache: npm
2121
- run: npm ci
2222
- run: npm run build
23+
- run: npm run lint
24+
- run: npm test

.github/workflows/release.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: read
9+
id-token: write
10+
11+
jobs:
12+
publish:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 20
19+
cache: npm
20+
registry-url: https://registry.npmjs.org
21+
- run: npm ci
22+
- run: npm run build
23+
- run: npm run lint
24+
- run: npm test
25+
- run: npm publish --provenance --access public
26+
env:
27+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
## [1.0.0] - 2025-01-01
6+
7+
### Added
8+
- UMD, ESM and minified builds with TypeScript definitions
9+
- Track computed CSS properties as CSS custom properties via `data-keeptrack`
10+
- Scrollbar width and height tracking (`--scrollbar-width`, `--scrollbar-height`)
11+
- Target parent or ancestor for variable placement (`data-keeptrack-target-parent`)
12+
- Sticky element detection with `data-keeptrack-stuck` attribute and `--stuck` variable
13+
- Scroll-padding-top management for anchor navigation (`data-keeptrack-scroll-padding`)
14+
- Programmatic `observe()` / `unobserve()` API
15+
- `recalculate()` for manual refresh
16+
- `onChange` callback
17+
- ResizeObserver and MutationObserver integration
18+
- Optional rAF polling for non-layout property changes
19+
- Debounced resize handling
20+
- CI workflow with Node 18/20

agents.md

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@ KeepTrack-CSS is a zero-dependency browser library that reads computed CSS prope
77
## Project structure
88

99
```
10-
src/keepTrack.js — Source of truth (UMD format)
11-
build.js — Build script (generates dist/)
12-
dist/ — Generated output (not in git)
13-
keepTrack.js — UMD copy
14-
keepTrack.esm.js — ESM build
15-
keepTrack.min.js — Minified UMD
16-
keepTrack.d.ts — TypeScript definitions
17-
docs/ — Demo/test page (GitHub Pages)
10+
src/keepTrack.js — Source of truth (UMD format)
11+
build.js — Build script (generates dist/)
12+
dist/ — Generated output (not in git)
13+
keepTrack.js — UMD copy
14+
keepTrack.esm.js — ESM build
15+
keepTrack.min.js — Minified UMD
16+
keepTrack.min.js.map — Sourcemap for minified build
17+
keepTrack.d.ts — TypeScript definitions
18+
tests/ — Vitest test suite (happy-dom)
19+
docs/ — Demo/test page (GitHub Pages)
20+
eslint.config.mjs — ESLint 9 flat config
21+
vitest.config.mjs — Vitest config
22+
CHANGELOG.md — Release changelog
1823
```
1924

2025
## Key conventions
@@ -28,11 +33,38 @@ docs/ — Demo/test page (GitHub Pages)
2833
## Build
2934

3035
```bash
31-
npm run build # generates dist/ (UMD, ESM, min, d.ts)
36+
npm run build # generates dist/ (UMD, ESM, min, min.js.map, d.ts)
3237
```
3338

3439
The `prepare` script also runs `node build.js`, so `npm install` from a git clone will build automatically.
3540

41+
## Lint
42+
43+
```bash
44+
npm run lint # ESLint 9 flat config
45+
```
46+
47+
Config lives in `eslint.config.mjs`. Browser globals are set for `src/`, CommonJS globals for `build.js`. `dist/`, `node_modules/`, and `docs/` are ignored.
48+
49+
## Test
50+
51+
```bash
52+
npm test # vitest run (happy-dom environment)
53+
```
54+
55+
Tests are in `tests/keepTrack.test.js`. The UMD source is loaded via `new Function()` with a local `module.exports` so it runs in the happy-dom environment. Tests verify API shape, CSS variable placement, cleanup, observe/unobserve, scrollbar tracking, and callbacks.
56+
57+
**Limitations:** happy-dom's `getComputedStyle` returns empty strings and `getBoundingClientRect` returns zeroes. Tests check that variables are *set*, not their pixel values. Sticky detection is not meaningfully testable.
58+
59+
## Release
60+
61+
Releases are published to npm automatically via `.github/workflows/release.yml` when a GitHub Release is created (published).
62+
63+
**Setup:**
64+
1. Create an npm access token (Granular Access Token, publish-only, scoped to `keeptrack-css`).
65+
2. Add it as a repository secret named `NPM_TOKEN` in GitHub Settings > Secrets and variables > Actions.
66+
3. Create a GitHub Release — the workflow runs build, lint, test and then `npm publish --provenance --access public`.
67+
3668
## Public API
3769

3870
The library exports a single factory function:

build.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@ async function build() {
2121
const minified = await minify(source, {
2222
compress: { passes: 2 },
2323
mangle: true,
24-
output: { comments: false }
24+
output: { comments: false },
25+
sourceMap: {
26+
filename: 'keepTrack.min.js',
27+
url: 'keepTrack.min.js.map'
28+
}
2529
});
2630
fs.writeFileSync(path.join(DIST, 'keepTrack.min.js'), minified.code);
31+
fs.writeFileSync(path.join(DIST, 'keepTrack.min.js.map'), minified.map);
2732
console.log(`dist/keepTrack.min.js: ${minified.code.length} bytes`);
33+
console.log(`dist/keepTrack.min.js.map: ${minified.map.length} bytes`);
2834

2935
// ESM build
3036
const esm = `// KeepTrack ESM build - auto-generated from src/keepTrack.js

eslint.config.mjs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import js from '@eslint/js';
2+
3+
export default [
4+
js.configs.recommended,
5+
{
6+
ignores: ['dist/**', 'node_modules/**', 'docs/**']
7+
},
8+
{
9+
files: ['src/**/*.js'],
10+
languageOptions: {
11+
ecmaVersion: 2020,
12+
sourceType: 'script',
13+
globals: {
14+
window: 'readonly',
15+
document: 'readonly',
16+
ResizeObserver: 'readonly',
17+
MutationObserver: 'readonly',
18+
requestAnimationFrame: 'readonly',
19+
cancelAnimationFrame: 'readonly',
20+
setTimeout: 'readonly',
21+
clearTimeout: 'readonly',
22+
HTMLElement: 'readonly',
23+
define: 'readonly',
24+
module: 'readonly',
25+
exports: 'readonly',
26+
global: 'readonly',
27+
globalThis: 'readonly'
28+
}
29+
},
30+
rules: {
31+
'no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }]
32+
}
33+
},
34+
{
35+
files: ['build.js'],
36+
languageOptions: {
37+
ecmaVersion: 2020,
38+
sourceType: 'commonjs',
39+
globals: {
40+
require: 'readonly',
41+
__dirname: 'readonly',
42+
process: 'readonly',
43+
console: 'readonly',
44+
module: 'readonly',
45+
exports: 'readonly'
46+
}
47+
},
48+
rules: {
49+
'no-unused-vars': ['error', { args: 'none' }]
50+
}
51+
},
52+
{
53+
files: ['tests/**/*.js'],
54+
languageOptions: {
55+
ecmaVersion: 2020,
56+
sourceType: 'module',
57+
globals: {
58+
window: 'readonly',
59+
document: 'readonly',
60+
__dirname: 'readonly'
61+
}
62+
}
63+
}
64+
];

0 commit comments

Comments
 (0)