-
Notifications
You must be signed in to change notification settings - Fork 3
Add config versioning and migration system with deflate compression #56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
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
Establishes the foundation for implementing a comprehensive config versioning system by setting up Vitest as the test framework. This infrastructure will enable us to write regression tests before making schema changes, ensuring backward compatibility and safe migrations. Key additions: - Vitest 4 configuration with 100% coverage targets for critical files - Test scripts for local development (test, test:watch) and CI - GitHub Actions workflow for automated testing on all branches - Test fixture structure with v1 configs and legacy formats - Test utilities for loading JSON and hash fixtures This infrastructure allows us to: 1. Document current behavior through tests before refactoring 2. Verify migrations don't break existing functionality 3. Maintain confidence during schema evolution 4. Enforce high code quality standards via CI
Adds 47 test cases covering current schema validation, parsing, compact format conversion, and roundtrip operations. These tests serve as regression tests before implementing the versioned schema system. Key test coverage: - exportConfigSchema validation with all field types - parseExportConfig with string/object inputs and error handling - compactExportConfigSchema validation of flat array format - toCompactExportConfig conversion to flat arrays - toExportConfig reconstruction from compact format - Roundtrip data preservation (config → compact → config) - All test fixtures (minimal, full, chromaCap, invalid cases) Notable current behaviors documented: - chromaCap null values stay as null (Valibot optional() behavior) - parseExportConfig wraps all errors in generic message - Compact format uses flat arrays for levels/hues - All chroma values set to 0 during compact conversion
…ing native APIs and safe base64 encoder/decoder. Add unit tests for them.
Introduce CURRENT_CONFIG_VERSION constant and add version field to export config schema with validation (minimum value 1, defaults to 1). Update default config, store, and conversion functions to include the version field. Add comprehensive tests covering valid versions, future versions, and invalid version handling.
Introduce a comprehensive migration system to handle future config schema changes. Implement versioned schemas with explicit v1 variants, migration builder pattern for type-safe sequential migrations, and hash decoding that supports both new deflate-based and legacy base64 compact formats with automatic fallback to defaults.
Ensure bgLightStart setting is within the valid range of defined color levels to prevent out-of-bounds errors
Implement migration framework to handle config version transitions. Make config parsing asynchronous to support async compression/decompression, update all call sites to await parsing, switch from compact hash to deflate compression, and make decodeHashConfig return null instead of default config on failure for explicit error handling.
Migrate legacy compact format to dedicated migration module and implement new compression strategy using deflate + url-safe base64 for URL hashes. Maintains backward compatibility with existing legacy hashes.
Update MigrationBuilder to automatically inject the version property into migration outputs, removing the need for migrations to manually set version fields. This reduces boilerplate and enforces consistency by having the builder track and apply versions automatically. Update tests to reflect simplified migration syntax.
Introduce version 2 of the export config schema to support the showContrastLabels boolean setting. Add migration from v1 that defaults showContrastLabels to false for backward compatibility. Include test fixtures and comprehensive tests for v2 config parsing and hash encoding/decoding.
…schema v2" This reverts commit 58f6317.
|
Visit the preview URL for this PR (updated for commit fc0dcd6): https://harmonizer-web--pr56-config-migrations-2cgfsxsx.web.app (expires Tue, 27 Jan 2026 00:45:51 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 0b46b8946d697564b3f98633c5cd230a6ede1236 |
Document test commands in README, exclude coverage directories from git tracking, and remove redundant test:core alias in favor of pnpm core test syntax
2bccb69 to
fc0dcd6
Compare
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.
Overview
This PR introduces a comprehensive configuration versioning and migration system for Harmonizer. It adds support for schema versioning, type-safe sequential migrations, and replaces the legacy compact config format with modern deflate compression for URL hashes. The system is designed to ensure backward compatibility while enabling safe evolution of the config schema.
Problem Statement
The Harmonizer application needed a robust way to handle configuration schema changes over time. Without a versioning system, any breaking changes to the config format would break existing shared URLs and saved configurations. The legacy compact format for URL hashes was also limited and not easily extensible.
Key issues addressed:
Solution Approach
Config Versioning System: Added a
versionfield to the export config schema starting at v1, withCURRENT_CONFIG_VERSIONconstant tracking the latest version (currently v2). All configs now carry explicit version information.Type-Safe Migration Builder: Implemented
MigrationBuilderpattern that enables chaining migrations with full TypeScript type inference. Each migration transforms the config from one version to the next, with the builder automatically injecting version numbers into outputs.Deflate Compression for URL Hashes: Replaced the legacy compact config format with native
CompressionStreamAPI using deflate-raw compression combined with URL-safe base64 encoding. This provides better compression and a cleaner, more extensible format.Backward Compatibility: Hash decoding attempts the new deflate format first, then falls back to legacy base64 compact format, ensuring existing shared URLs continue to work.
Async Config Parsing: Made config parsing asynchronous to support async compression/decompression operations via native browser APIs.
Comprehensive Test Infrastructure: Added Vitest configuration with 100% coverage targets for critical files, extensive test fixtures for v1/v2 configs and legacy formats, and 400+ lines of tests covering schema validation, parsing, migration, and roundtrip operations.
CI Integration: Added GitHub Actions workflow for automated testing on all branches.
Schema v2 Introduction: Added
showContrastLabelsboolean setting to demonstrate the migration system, with v1→v2 migration defaulting this field tofalse.Breaking Changes
None. The changes are fully backward compatible: