Convert SigPlot to Typescript#20
Draft
mrecachinas wants to merge 23 commits intospectriclabs:mainfrom
Draft
Conversation
Replace dated build tooling with modern equivalents: - esbuild replaces Browserify + Babel + Closure Compiler (~200× faster builds) Outputs: UMD, minified, ESM, and plugins bundles - ESLint 9 (flat config) replaces JSHint with auto-fixable rules - Prettier replaces jsbeautifier for code formatting - GitHub Actions CI updated: Node 20, modern action versions, lint+build jobs - package.json: add 'module' and 'exports' fields for dual CJS/ESM publish - Grunt tooling preserved under 'grunt:*' scripts for backward compatibility Legacy files (.jshintrc, .jsbeautifyrc, Gruntfile.js, karma.conf.js) kept for now — will be removed after full migration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Vite config for instant HMR dev server (replaces budo) - Vitest config with jsdom environment for unit tests - Vitest browser mode configured (Playwright/Chromium) for canvas tests - Setup file that makes sigplot globally available for tests - Smoke test suite (11 tests) validating build output and core APIs - npm scripts: 'dev', 'test', 'test:watch', 'test:browser' Existing QUnit tests remain runnable via 'npm run grunt:test'. New tests use Vitest API — existing tests can be migrated incrementally. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Migrate all 18 source files in js/ from the CommonJS IIFE pattern:
(function() { var x = require(...); module.exports = X; }());
to standard ES module syntax:
import x from './x.js'; export default X;
- Remove IIFE wrappers from all files
- Convert require() to import (with .js extension for relative paths)
- Convert module.exports to export default
- Update ESLint config sourceType to 'module'
- esbuild handles the ES module bundling natively
No behavioral changes — same bundle output, same API surface.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove 35+ packages and 7 config files: - Gruntfile.js, karma.conf.js, .jshintrc, .jsbeautifyrc, .travis.yml, .nvmrc - All grunt-* plugins (12 packages) - Karma + launchers + adapters (5 packages) - Babel toolchain (3 packages) - QUnit, Jasmine, and related test deps - JSDoc template deps (catharsis, marked, minami, taffydb) - budo dev server, travis CLI Net result: 33 devDependencies → 14, dependencies: 8 → 7 Build toolchain is now: esbuild + ESLint + Prettier + Vitest + Vite Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Convert math, graphics, and colormap tests from QUnit to Vitest: - tests.m.test.js: sec2tod time formatting tests - tests.mx.test.js: format_f, real_to_pixel, distance, box tests - tests.colormap.test.js: ColorMap construction with various color formats Migration pattern: QUnit.test → it(), assert.equal → expect().toBe(), assert.close → expect(Math.abs()).toBeLessThanOrEqual() Total: 4 test files, 17 tests, all passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
These tests have been migrated to Vitest (.test.js files). The HTML test runners are no longer needed (Vitest replaces Karma). Remaining QUnit files (tests.js, tests.sigplot.js, tests.interactive-*.js) are kept for reference — they require real browser canvas and will be migrated when Vitest browser mode is fully set up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Convert tests.sigplot.js from QUnit to Vitest API: - 17 tests pass in jsdom (Plot construction, overlay, layers, zoom, etc.) - 8 tests skipped: need real browser (layout-dependent or XHR-based) - Enhanced vitest.setup.js with canvas 2D context stub for jsdom - Removed migrated QUnit files (tests.sigplot.js, tests.js) Remaining unmigrated: 12 interactive test files (manual visual verification tests using interactiveTest() — these prompt humans to verify rendering). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove .jshintignore (JSHint no longer used) - Remove .npmignore (empty; package.json 'files' field handles publishing) - Trim .gitignore from 100+ lines of boilerplate to ~25 relevant entries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- engines: node >= 18 - Dependabot: weekly npm + GitHub Actions updates - Groups: dev deps (minor/patch), prod deps (minor/patch), actions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove underscore dependency — all 11 usages replaced with builtins:
- _.clone(obj) → Object.assign({}, obj)
- _.has(obj, key) → Object.prototype.hasOwnProperty.call(obj, key)
- _.indexOf(arr, val) → arr.indexOf(val)
- _.isFunction(fn) → typeof fn === 'function'
- _.size(obj) → Object.keys(obj).length
- _.each(arr, fn) → arr.forEach(fn)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace spin (2013, unmaintained) with a CSS-only spinner: 28px border-based circle with @Keyframes rotation, injected once - Replace lru (uses Node 'events' module) with inline js/lru.js: 25-line Map-based LRU cache with get/set/eviction - Remove events polyfill (no longer needed without lru) - Fix leftover _.mapObject call in hide_spinner Dependencies dropped: spin, lru, events (3 packages removed) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove polyfills targeting IE/ancient browsers (now targeting ES2018+): - ArrayBuffer.prototype.slice (iOS/old Firefox) - ArrayBuffer.isView - requestAnimFrame/cancelAnimFrame shims → native requestAnimationFrame - Float64Array polyfill (iOS) - String.prototype.endsWith (ES6) - TypedArray.prototype.slice (6 types) - Array.isArray - console shim - Firefox 4 subarray bug workaround - addWheelListener (mousewheel/DOMMouseScroll) → native 'wheel' event - Proxy polyfill - mozDash/webkitLineDash fallbacks in dashOn/dashOff → setLineDash only - window.event/attachEvent fallbacks Kept: ArrayBuffer.transfer polyfill (not yet universal), dashOn/dashOff, getKeyCode, setKeypressHandler, update, debounce, uuidv4. common.js: 393 lines → 100 lines Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Configure @vitest/coverage-v8 with text, lcov, and html reporters - Add npm script: test:coverage New test files: - lru.test.js: 8 tests — eviction, recency refresh, overwrite, edge cases (100% coverage) - common.test.js: 11 tests — dashOn/Off, getKeyCode, update, debounce, uuidv4 - m.math.test.js: 20 tests — vmov, vmovmax, vmxmn, vsmul, vfill, vabs, cvmag, cvmag2, PointArray, throttle Total: 8 test files, 71 passing, 8 skipped Coverage: lru.js 100%, common.js 82% (+29), m.js 62% (+7) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
New test files: - m.extended.test.js (84 tests): log10, vlog10, vlogscale, cvmag2logscale, cvpha, cvphad, trunc, sign, bound, mult_prefix, trim_name, epoch conversion round-trips, pad - ColorMap.extended.test.js (21 tests): construction, setRange, getColorIndex, getColorByIndex, getNColors, interpolation, edge cases - sigplot.plugin.test.js (23 tests): Plugin lifecycle, init/dispose, addListener/removeListener, menu/refresh hooks, properties Coverage improvements: m.js: 62% → 80% stmts, 42% → 64% branch, 61% → 85% funcs ColorMap.js: 75% → 81% stmts sigplot.plugin.js: 42% → 84% stmts, 42% → 100% funcs Total: 11 files, 199 passing, 8 skipped Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mock clientWidth/clientHeight on the container element to return dimensions based on style.width/height (accounting for display:none). This lets the 5 previously-skipped tests pass in jsdom without a real browser layout engine. Remaining 3 skipped: XHR-based tests (overlay_href needs file loading) Tests: 204 passing, 3 skipped (was 199 passing, 8 skipped) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Vitest browser mode requires server-side preprocessing of setup files, but sigfile's UMD wrapper references 'window' at top level, causing failures in Node context. Until sigfile ships proper ESM exports, jsdom with canvas context stubs is the correct approach. The canvas stubs are sufficient for testing data structures, API surface, math operations, and plot construction logic — which is what matters for unit tests. Visual rendering is covered by the interactive test suite. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Install typescript, @typescript-eslint/parser, @typescript-eslint/eslint-plugin, @types/tinycolor2 - Create tsconfig.json with strict mode, allowJs for incremental migration - Update ESLint config with TypeScript parser and plugin - Update esbuild entrypoints for .ts files - Add typecheck and types npm scripts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Convert all 20 source files from JavaScript to TypeScript: - Create js/types.ts with shared interfaces (BlueHeader, MxContext, GxContext, PlotSettings, LayerOptions, and supporting types) - Create js/sigfile.d.ts declaration stub for sigfile dependency - Migrate core: sigplot.ts (9300 lines), mx.ts (5900 lines), m.ts (1300 lines) - Migrate layers: layer1d.ts, layer2d.ts, layer1dSDS.ts, layer2dSDS.ts - Migrate plugins: plugin.ts, accordion.ts, annotations.ts, boxes.ts, playback.ts, slider.ts, plugins.ts (barrel) - Migrate utilities: common.ts, ColorMap.ts, CanvasInput.ts, lru.ts, license.ts - Migrate dommenu: mx.dommenu.ts - Use namespace import for sigfile (import * as sigfile) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Enable noImplicitAny, then full strict: true in tsconfig.json - Remove @ts-nocheck from all 10 files (677 type errors fixed): sigplot.ts, mx.ts, layer1d.ts, layer2d.ts, layer1dSDS.ts, layer2dSDS.ts, CanvasInput.ts, accordion.ts, annotations.ts, boxes.ts - Replace 32 any types with concrete types in types.ts - Tighten types in m.ts and sigplot.plugin.ts Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes found by parallel review with Gemini 3 Pro, GPT 5.3, and Opus 4.6: Pass 1 (3 critical, 2 medium): - Fix layer2d: use dview.length not .byteLength (was 4-8x wrong) - Fix CanvasInput: check data==='none' not _boxShadow state for shadow init - Fix all layers: revert hcb.buf._type back to hcb.buf_type - Fix add_highlight: restore array-replaces-all behavior - Fix MxContext.xi type: boolean → boolean | string Pass 2 (1 critical, 3 high, 3 medium): - Fix Layer1D: use position=0 not undefined (null coerces to 0 in arithmetic) - Fix Layer2D: remove spurious position/ymin/ymax from constructor - Fix slider: restore .bind() listener references for proper removal - Fix slider: restore && (intersection) for 'both' mode hit-testing - Fix slider: restore evt.slider_drag guard and preventDefault calls - Fix m.ts: getDview returns TypedArray|undefined to preserve null guards - Fix hide_spinner: guard HCB_UCB against undefined - Fix esbuild: unwrap default export in IIFE for global sigplot access Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 25 regression tests covering all 12 bugs found in code review - Distribute tests into per-module files: slider.test.ts, m.extended.test.ts, tests.sigplot.test.ts, canvasinput.test.ts - Migrate all 12 test files from .test.js to .test.ts - Generate .d.ts declaration files in dist/types/ - Update package.json with types field and exports map Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Update Vite alias to point to sigplot.ts - Add Vite middleware to serve dist/sigplot.js for examples - Set willReadFrequently on main canvas context for performance - Add trailing slashes to example links for index.html resolution - Run prettier on all TS files - Disable no-undef and no-redeclare in ESLint for .ts files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This branches off #18 FYI