Skip to content

Commit a2433b1

Browse files
steveruizokclaude
andauthored
Modernize build tooling and dev infrastructure for 2026 (#96)
* Add CLAUDE.md and modernization todo list Introduced CLAUDE.md to provide guidance for Claude Code and added todo.md outlining infrastructure and tooling improvements for the repository. These additions document project architecture and planned modernization tasks without affecting core algorithm code. * Upgrade TypeScript from 4.4.2 to 5.7.0 with strict mode - Update typescript to ^5.7.0 in all packages - Update @types/node from ^15.0.1 to ^20.11.0 - Enable strict: true in tsconfig.base.json - Remove deprecated importsNotUsedAsValues option - Update target to ES2020 and lib to ES2021 - Fix type errors in controls.tsx for strict mode compatibility Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Replace Lerna with lazyrepo for task orchestration - Remove lerna dependency and lerna.json configuration - Add lazyrepo (0.0.0-alpha.27) for task orchestration and caching - Create lazy.config.js with build, test, lint, and start tasks - Update start script to use lazy run - Update publish script to use npm publish directly - Add .lazy to .gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Upgrade ESLint from 7.32.0 to 9.19.0 with flat config - Update eslint to ^9.19.0 - Replace @typescript-eslint/parser and plugin with typescript-eslint ^8.23.0 - Migrate from .eslintrc.js to eslint.config.mjs (flat config) - Add eslint-config-prettier to avoid formatting conflicts - Fix unused import and expression issues in test file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Migrate from Jest to Vitest for testing - Replace Jest with Vitest ^3.0.0 for native ESM and TypeScript support - Remove Jest, ts-jest, babel-jest, and all Babel dependencies - Update @testing-library/jest-dom to ^6.6.0 (Vitest compatible) - Add jsdom ^26.0.0 for DOM testing environment - Create vitest.config.ts with jsdom environment and globals - Update setupTests.ts to import from @testing-library/jest-dom/vitest - Remove Jest types from tsconfig.base.json - Update test snapshots to Vitest format Tests now run in ~1.8s vs previous ~3s with Jest/ts-jest Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Migrate library build from esbuild to Rolldown - Replace custom esbuild scripts with Rolldown ^1.0.0-beta.1 - Create rolldown.config.mjs with dual CJS/ESM output - Enable minification and source maps for both builds - Add custom plugin to report bundle sizes - Remove packages/perfect-freehand/scripts/build.js and dev.js - Update lazy.config.js cache inputs Build time: ~11ms, output: 3.73kb ESM (1.74kb gzipped) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Migrate dev app from esbuild to Vite - Replace custom esbuild dev server with Vite ^6.0.0 - Create packages/dev/vite.config.ts with React plugin - Configure path aliases for bare imports (components, hooks, state) - Set dev server port to 5420 (same as original) - Remove esbuild.config.mjs and related dependencies - Update index.html to use Vite-style script imports Dev server starts in ~100ms with instant HMR Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Modernize CI/CD pipeline with v4 actions and Node matrix - Update actions/checkout and actions/setup-node to v4 - Replace Jest GitHub Action with direct Vitest execution - Add Node.js version matrix testing (18.x, 20.x, 22.x) - Add dependency caching via setup-node cache option - Add branch filtering for main branch only - Create publish.yml workflow for automated npm releases on GitHub release Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Extract Prettier config and add format scripts - Move Prettier config from package.json to .prettierrc - Add .prettierignore for dist, node_modules, lock files, etc. - Add prettier ^3.4.0 as devDependency - Add format and format:check scripts to package.json - Add formatting check step to CI pipeline Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Upgrade TypeDoc from 0.21.9 to 0.28.0 - Update typedoc to ^0.28.0 in root and library package.json - Create packages/perfect-freehand/typedoc.json with modern config - Configure TypeDoc with navigation, sorting, and visibility options - Add docs generation step to CI (runs on Node 20.x only) - Simplify docs script to use config file Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add missing configuration files - Add .editorconfig for consistent editor settings (2-space indent, UTF-8) - Add .nvmrc pinning Node.js to version 20 (LTS) - Add engines field to package.json (>=18.0.0) - Add .github/dependabot.yml for automated dependency updates - Weekly schedule with grouped dependencies - Monitors both npm and GitHub Actions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * build: upgrade Husky to 9.x with lint-staged and commitlint - Update husky from ^7.0.0 to ^9.1.0 - Change postinstall to prepare script (Husky 9 syntax) - Add lint-staged ^15.4.0 for faster pre-commit checks - Add @commitlint/cli and @commitlint/config-conventional ^19.7.0 - Update pre-commit hook to run lint-staged instead of full test - Add pre-push hook to run tests before push - Add commit-msg hook for conventional commit linting - Create commitlint.config.js extending conventional config Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: update dev app dependencies to latest versions - Update zustand from ^4.0.0-rc.1 to ^5.0.0 - Update @testing-library/react from ^12.0.0 to ^16.0.0 - Update @radix-ui/react-checkbox from ^0.1.0 to ^1.1.0 - Update @radix-ui/react-icons from ^1.0.3 to ^1.3.0 - Update @radix-ui/react-label from ^0.1.0 to ^2.1.0 - Update @radix-ui/react-slider from ^0.1.0 to ^1.2.0 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: clean up package.json files and remove unused dependencies - Remove unused dependencies: cac, fake-indexeddb, tslib, @modulz/radix-icons - Add packageManager field (yarn@4.12.0) for Corepack support - Disable importHelpers since tslib was removed - Remove unused fake-indexeddb import from setupTests.ts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * ci: add security audit job to CI pipeline - Add separate audit job running yarn npm audit on Node 20.x - Job runs in parallel with build matrix for efficiency - No vulnerabilities found in current dependencies Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add Yarn 4 configuration with node-modules linker - Add .yarnrc.yml configuring node-modules linker - Add .yarn/install-state.gz to .gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update README for Dart port and fix API naming Highlight the Dart port of the library and correct the API name from getOutlinePoints to getStrokeOutlinePoints. Simplified the community ports section. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add tsbuildinfo to gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): enable Corepack before setup-node for Yarn 4 The setup-node action with cache: 'yarn' runs yarn internally before any other steps, which fails when packageManager field specifies Yarn 4. Enable Corepack first and use manual caching instead. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: exclude test files from library tsconfig Test files use Vitest globals which TypeScript doesn't know about. Vitest handles type-checking for test files separately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: add dev script to package.json Introduces a 'dev' script that runs 'lazy run start' for development purposes. * style: fix formatting and lint issues - Format 16 files with Prettier - Fix unused variable in rolldown config - Add global console directive for ESLint flat config Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): require Node.js 20+ for rolldown compatibility Rolldown uses `styleText` from `node:util` which was added in Node.js 20.1.0. Update CI matrix and engines field accordingly. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokePoints): extract default pressure constants Extract magic pressure values (0.25 and 0.5) to named constants DEFAULT_FIRST_PRESSURE and DEFAULT_PRESSURE in constants.ts. Documents why first point uses lower pressure (prevents fat starts). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokePoints): extract unit offset constant Extract magic vector [1, 1] to UNIT_OFFSET constant in constants.ts. Used as placeholder for initial vector and for creating a second point when only one input point is provided. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokePoints): add explicit pressure validation helper Add isValidPressure() type guard function that explicitly checks for undefined, NaN, and negative pressure values. Makes the intent clearer compared to the implicit `>= 0` check which returns false for undefined. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * perf(getStrokePoints): use mutable vector operation in hot loop Use subInto with a scratch buffer for the vector difference calculation in the main loop to reduce array allocations. The intermediate result from sub() was being discarded after uni() normalized it. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: use Vec2 type and optimize vector operations * refactor(getStrokeOutlinePoints): rename cryptic variables Improve readability by renaming single-letter and abbreviated variables: - ts, te → taperStartStrength, taperEndStrength - pl, pr → prevLeftPoint, prevRightPoint - tl, tr → tempLeftPoint, tempRightPoint Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokeOutlinePoints): extract cap generation helpers Extract cap drawing logic into dedicated helper functions for clarity: - drawDot(): generates circular dot for single-point strokes - drawRoundStartCap(): generates rounded start cap - drawFlatStartCap(): generates squared-off start cap - drawRoundEndCap(): generates rounded end cap (1.5 turns) - drawFlatEndCap(): generates squared-off end cap Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokeOutlinePoints): extract taper distance calculation Replace nested ternary expressions for taper calculation with a dedicated computeTaperDistance() helper function. Improves readability and documents the three possible taper option values (false, true, number). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(getStrokeOutlinePoints): extract initial pressure and add isLastPoint - Add computeInitialPressure() helper to encapsulate the pressure averaging logic that prevents fat starts - Add isLastPoint variable in loop to replace repeated i === points.length - 1 checks, improving readability Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add Vitest benchmark support and stroke benchmarks Introduces 'bench' scripts to root and perfect-freehand package.json files and configures Vitest to include benchmark files. Adds a comprehensive stroke.bench.ts for benchmarking stroke-related functions with various datasets and options. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent e8f132b commit a2433b1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+16263
-37336
lines changed

.editorconfig

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# EditorConfig helps maintain consistent coding styles across editors
2+
# https://editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
indent_style = space
8+
indent_size = 2
9+
end_of_line = lf
10+
charset = utf-8
11+
trim_trailing_whitespace = true
12+
insert_final_newline = true
13+
14+
[*.md]
15+
trim_trailing_whitespace = false
16+
17+
[*.{yml,yaml}]
18+
indent_size = 2
19+
20+
[Makefile]
21+
indent_style = tab

.eslintrc.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

.github/dependabot.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Dependabot configuration for automated dependency updates
2+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates
3+
4+
version: 2
5+
updates:
6+
# npm dependencies
7+
- package-ecosystem: 'npm'
8+
directory: '/'
9+
schedule:
10+
interval: 'weekly'
11+
day: 'monday'
12+
open-pull-requests-limit: 10
13+
groups:
14+
# Group minor/patch updates for dev dependencies
15+
dev-dependencies:
16+
dependency-type: 'development'
17+
update-types:
18+
- 'minor'
19+
- 'patch'
20+
# Group TypeScript-related packages
21+
typescript:
22+
patterns:
23+
- 'typescript'
24+
- '@types/*'
25+
- 'typescript-eslint'
26+
# Group testing packages
27+
testing:
28+
patterns:
29+
- 'vitest'
30+
- '@testing-library/*'
31+
- 'jsdom'
32+
# Group ESLint packages
33+
eslint:
34+
patterns:
35+
- 'eslint'
36+
- 'eslint-*'
37+
- '@eslint/*'
38+
labels:
39+
- 'dependencies'
40+
commit-message:
41+
prefix: 'chore(deps)'
42+
43+
# GitHub Actions
44+
- package-ecosystem: 'github-actions'
45+
directory: '/'
46+
schedule:
47+
interval: 'weekly'
48+
day: 'monday'
49+
labels:
50+
- 'dependencies'
51+
- 'github-actions'
52+
commit-message:
53+
prefix: 'chore(ci)'

.github/workflows/main.yml

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,85 @@
11
name: CI
2-
on: push
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
39
jobs:
10+
audit:
11+
name: Security Audit
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Enable Corepack
18+
run: corepack enable
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: 20.x
24+
25+
- name: Get yarn cache directory
26+
id: yarn-cache
27+
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
28+
29+
- name: Cache yarn
30+
uses: actions/cache@v4
31+
with:
32+
path: ${{ steps.yarn-cache.outputs.dir }}
33+
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
34+
restore-keys: ${{ runner.os }}-yarn-
35+
36+
- name: Install dependencies
37+
run: yarn install --immutable
38+
39+
- name: Run security audit
40+
run: yarn npm audit
41+
442
build:
543
runs-on: ubuntu-latest
44+
45+
strategy:
46+
matrix:
47+
node-version: [20.x, 22.x]
48+
649
steps:
7-
- uses: actions/checkout@v2
8-
# install modules
9-
- name: Install modules
10-
run: yarn
11-
# build
50+
- uses: actions/checkout@v4
51+
52+
- name: Enable Corepack
53+
run: corepack enable
54+
55+
- name: Setup Node.js ${{ matrix.node-version }}
56+
uses: actions/setup-node@v4
57+
with:
58+
node-version: ${{ matrix.node-version }}
59+
60+
- name: Get yarn cache directory
61+
id: yarn-cache
62+
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
63+
64+
- name: Cache yarn
65+
uses: actions/cache@v4
66+
with:
67+
path: ${{ steps.yarn-cache.outputs.dir }}
68+
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
69+
restore-keys: ${{ runner.os }}-yarn-
70+
71+
- name: Install dependencies
72+
run: yarn install --immutable
73+
74+
- name: Check formatting
75+
run: yarn format:check
76+
1277
- name: Build
1378
run: yarn build:packages
14-
# run unit tests
15-
- name: Jest Annotations & Coverage
16-
uses: mattallty/jest-github-action@v1.0.3
17-
env:
18-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19-
with:
20-
test-command: 'yarn test'
79+
80+
- name: Test
81+
run: yarn test
82+
83+
- name: Generate docs
84+
if: matrix.node-version == '20.x'
85+
run: cd packages/perfect-freehand && yarn docs

.github/workflows/publish.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
name: Publish to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Enable Corepack
15+
run: corepack enable
16+
17+
- name: Setup Node.js
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: 20.x
21+
registry-url: 'https://registry.npmjs.org'
22+
23+
- name: Get yarn cache directory
24+
id: yarn-cache
25+
run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
26+
27+
- name: Cache yarn
28+
uses: actions/cache@v4
29+
with:
30+
path: ${{ steps.yarn-cache.outputs.dir }}
31+
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
32+
restore-keys: ${{ runner.os }}-yarn-
33+
34+
- name: Install dependencies
35+
run: yarn install --immutable
36+
37+
- name: Build
38+
run: yarn build:packages
39+
40+
- name: Test
41+
run: yarn test
42+
43+
- name: Publish to npm
44+
run: npm publish ./packages/perfect-freehand --access public
45+
env:
46+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,12 @@ coverage
1010
*.log
1111

1212
.vercel
13+
14+
# lazyrepo
15+
.lazy
16+
17+
# TypeScript build cache
18+
*.tsbuildinfo
19+
20+
# Yarn
21+
.yarn/install-state.gz

.husky/commit-msg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx --no -- commitlint --edit ${1}

.husky/pre-commit

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

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
yarn test

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20

0 commit comments

Comments
 (0)