# Project Memory - Smartdata ## TC39 Decorator Migration (v6.0.0) - ✅ COMPLETED ### Final Status: All Tests Passing (157/157) Migration successfully completed on 2025-11-17. ### What Changed: - ✅ Removed `experimentalDecorators` from tsconfig.json - ✅ Refactored all 7 decorators to TC39 Stage 3 syntax - 5 property decorators: @globalSvDb, @svDb, @unI, @index, @searchable - 2 class decorators: @Collection, @managed - ✅ Implemented context.metadata pattern for shared decorator state - ✅ All tests passing across Node.js and Deno runtimes ### Critical Discovery: TC39 Metadata Access Pattern **THE KEY INSIGHT**: In TC39 decorators, metadata is NOT accessed via `constructor[Symbol.metadata]`. Instead: - **Field decorators**: Write to `context.metadata` - **Class decorators**: Read from `context.metadata` (same shared object!) - The `context.metadata` object is shared between all decorators on the same class - Attempting to write to `constructor[Symbol.metadata]` throws: "Cannot assign to read only property" ### Implementation Pattern: ```typescript // Field decorator - stores metadata export function svDb() { return (value: undefined, context: ClassFieldDecoratorContext) => { const metadata = context.metadata as ISmartdataDecoratorMetadata; if (!metadata.saveableProperties) { metadata.saveableProperties = []; } metadata.saveableProperties.push(String(context.name)); }; } // Class decorator - reads metadata and initializes prototype export function Collection(dbArg: SmartdataDb) { return function(value: Function, context: ClassDecoratorContext) => { const metadata = context.metadata as ISmartdataDecoratorMetadata; if (metadata?.saveableProperties) { decoratedClass.prototype.saveableProperties = [...metadata.saveableProperties]; } return decoratedClass; }; } ``` ### Runtime Compatibility: - ✅ **Node.js v23.8.0**: Full TC39 support - ✅ **Deno v2.5.4**: Full TC39 support - ❌ **Bun v1.3.0**: No TC39 support (uses legacy decorators only) - Removed "+bun" from test filenames to skip Bun tests ### Key Technical Notes: 1. **Metadata Initialization Timing**: Class decorators run AFTER field decorators, allowing them to read accumulated metadata and initialize prototypes before any instances are created 2. **Prototype vs Instance Properties**: Properties set on prototype are accessible via `this.propertyName` in instances 3. **TypeScript Lib Support**: TypeScript 5.9.3 includes built-in decorator types (no custom lib configuration needed) 4. **Interface Naming**: Used `ISmartdataDecoratorMetadata` extending `DecoratorMetadataObject` for type safety ### Files Modified: - ts/classes.doc.ts (property decorators + metadata interface) - ts/classes.collection.ts (class decorators + prototype initialization) - tsconfig.json (removed experimentalDecorators flag) - test/*.ts (renamed files to remove "+bun" suffix) ### Test Results: All 157 tests passing across 10 test files: - test.cursor.ts: 7/7 - test.deno.ts: 11/11 (queries working correctly!) - test.search.advanced.ts: 41/41 - test.typescript.ts: 4/4 - test.watch.ts: 5/5 - And 5 more test files ### Migration Learnings for Future Reference: 1. `context.metadata` is the ONLY way to share state between decorators 2. Class decorators must initialize prototypes from metadata immediately 3. `Symbol.metadata` on constructors is read-only (managed by runtime) 4. Field decorators run before class decorators (guaranteed order) 5. TypeScript 5.2+ has built-in TC39 decorator support