When splitting one operation into misc and tasks operations:
- Both operations now get unique ID suffixes (_misc and _tasks)
- Skip logic verifies both conditions before skipping:
1. tasks config has migrated field (isConfirmBeforeDelete)
2. misc config has NO migrated fields remaining
This prevents:
- Potential operation ID conflicts in the sync log
- Data loss in partial migration scenarios
Adds test cases for partial migration and correct skip scenarios.
The previous commit changed module resolution to bundler mode which
fixed Angular tests but broke Node.js ESM imports in super-sync-server.
Switch to tsup bundler that outputs both ESM (.mjs) and CJS (.js) formats,
with proper exports field to support both environments:
- CJS for super-sync-server (Node.js commonjs)
- ESM for Angular/webpack bundler imports
- Change shared-schema tsconfig to use bundler moduleResolution
- Remove .js extensions from imports (incompatible with bundler mode)
- Fix tsconfig.spec.json to include both package path mappings
The shared-schema package was using NodeNext module resolution which
requires .js extensions in imports. Since the main Angular project
uses bundler resolution and imports directly from source files,
this caused webpack to fail finding the modules during tests.
Bug fix:
- Fix vector clock cache staleness in multi-tab scenarios by clearing
cache when acquiring operation write lock. Each browser tab has its
own in-memory cache, so Tab B's cache could be stale if Tab A wrote
while Tab B was waiting for the lock.
Shared code extraction (client/server consistency):
- Extract vector clock comparison to @sp/shared-schema
- Client wraps shared impl with null handling
- Server imports directly from shared
- Extract entity types to @sp/shared-schema
- Single source of truth for ENTITY_TYPES array
- Removes duplicated "must match" comments
Files:
- packages/shared-schema/src/vector-clock.ts (new)
- packages/shared-schema/src/entity-types.ts (new)
- src/app/op-log/store/operation-log-store.service.ts (cache clear)
- src/app/op-log/capture/operation-log.effects.ts (call cache clear)
1. Fix race condition in replaceToken (auth.ts)
- Wrap UPDATE and SELECT in transaction for atomicity
2. Fix mutex memory leak in operation-log-hydrator
- Add explicit error logging before rethrowing in repair promise
3. Improve global mutable state handling (is-related-model-data-valid.ts)
- Reset lastValidityError at start of each validation
- Add documentation warning about the pattern
4. Fix version tracking bug in shared-schema migration
- Update version inside try block so migratedToVersion reflects
where we actually stopped, even if operation was dropped
5. Remove unused import validateMigrationRegistry (sync.service.ts)
6. Add array payload rejection test (validate-operation-payload.spec.ts)
7. Add lock service contention tests (lock.service.spec.ts)
- Tests for corrupted lock formats (no timestamp, NaN, empty string)
Also includes shared-schema ESM configuration:
- Add "type": "module" to package.json for ESM output
- Change module/moduleResolution to NodeNext in tsconfig.json
- Add .js extensions to all relative imports (required by Node.js ESM)
Create @sp/shared-schema package with pure TypeScript migration functions
that work in both Angular frontend and Node.js backend environments.
Package contents:
- schema-version.ts: Version constants (CURRENT=1, MAX_SKIP=3)
- migration.types.ts: OperationLike, SchemaMigration interfaces
- migrate.ts: Pure functions (migrateState, migrateOperation, etc.)
- migrations/index.ts: Empty migrations array (ready for first migration)
- 22 unit tests covering all migration scenarios
Backend changes:
- Add snapshot_schema_version column to user_sync_state table
- Migrate snapshots during generateSnapshot if outdated
- Migrate operations during replayOpsToState if outdated
- Drop operations that return null from migration (removed features)
Frontend changes:
- Refactor SchemaMigrationService to use @sp/shared-schema
- Re-export constants for backwards compatibility
- All 20 existing tests pass
This enables coordinated schema migrations across client and server,
ensuring old snapshots and operations can be upgraded when the state
structure changes.
Rollout strategy: Deploy backend first, then frontend.