Files
smartdata/readme.hints.md

3.5 KiB

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:

// 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