UNPKG

sequaljs

Version:

JavaScript/TypeScript library for parsing and manipulating ProForma peptide sequence notation

417 lines (329 loc) 10.3 kB
# ProForma Implementation Comparison ## Three Implementations Overview ### 1. **Go Implementation** (sequal-go) **Location**: `/mnt/d/GoLandProjects/sequal` **Status**: ✅ **ProForma 2.1 Complete** **Language**: Go **Version**: 2.1.0 **Features**: - All 6 ProForma 2.1 features implemented - 37+ new tests for 2.1 features - Zero regressions - Comprehensive integration tests - Updated documentation **Key Strengths**: - Strong typing with Go structs - Pointer types for optional fields - Efficient map-based modification storage - Getter methods for encapsulation --- ### 2. **TypeScript Implementation** (sequaljs) **Location**: `/mnt/d/WebstormProjects/sequaljs` **Status**: ⏳ **ProForma 2.0 Complete, 2.1 Planned** **Language**: TypeScript **Version**: 1.0.7 **Current Features**: - Complete ProForma 2.0 support - 37+ test cases covering 2.0 spec - Well-architected modification system - Production-ready **Upgrade Status**: - Upgrade plan documented in `PROFORMA_2.1_UPGRADE_PLAN.md` - Reference implementation available (Go) - Estimated 12-24 hours for complete upgrade **Key Strengths**: - Clean TypeScript types - Map-based modification indexing - Extensive JSDoc documentation - Jest test framework - Browser-compatible --- ### 3. **Python Implementation** (assumed) **Status**: Unknown (not analyzed in this session) **Language**: Python --- ## Architecture Comparison ### Data Structure Mapping | Concept | Go | TypeScript | |---------|-----|-----------| | **Sequence** | `type Sequence struct` | `class Sequence<T>` | | **Modification** | `type Modification struct` | `class Modification extends BaseBlock` | | **Global Mod** | `type GlobalModification struct` | `class GlobalModification extends Modification` | | **Amino Acid** | `type AminoAcid struct` | `class AminoAcid extends BaseBlock` | | **Mod Value** | `type ModificationValue struct` | `class ModificationValue` | | **Pipe Value** | `type PipeValue struct` | `class PipeValue` | ### Parser Approach | Aspect | Go | TypeScript | |--------|-----|-----------| | **Entry Point** | `FromProforma(str)` | `Sequence.fromProforma(str)` | | **Parser Class** | `ProFormaParser` struct | `ProFormaParser` static class | | **Bracket Tracking** | Counter-based | Counter-based | | **Regex Usage** | Heavy use of `regexp` | Heavy use of RegExp | | **Error Handling** | `(Sequence, error)` return | Throws exceptions | ### Modification Storage | Language | Approach | |----------|----------| | **Go** | `map[int][]*Modification` | | **TypeScript** | `Map<number, Modification[]>` | **Special Positions**: - `-1`: N-terminal - `-2`: C-terminal - `-3`: Labile - `-4`: Unknown position --- ## ProForma 2.1 Feature Status ### Feature Matrix | Feature | Go | TypeScript | Priority | |---------|-----|-----------|----------| | **Charged Formulas** (11.1) | ✅ Implemented | ⏳ Planned | High | | **Placement Controls** (11.2) | ✅ Implemented | ⏳ Planned | High | | **Named Entities** (11.3) | ✅ Implemented | ⏳ Planned | High | | **Custom Monosaccharides** (11.4) | ✅ Implemented | ⏳ Planned | Medium | | **Terminal Global Mods** (11.5) | ✅ Implemented | ⏳ Planned | Medium | | **Ion Notation** (11.6) | ✅ Implemented | ⏳ Planned | High | --- ## Code Style Differences ### Field Naming Conventions **Go**: ```go type Modification struct { positionConstraint []string limitPerPosition *int colocalizeKnown bool isIonType bool } ``` **TypeScript**: ```typescript class Modification { positionConstraint?: string[]; limitPerPosition?: number; colocalizeKnown: boolean = false; isIonType: boolean = false; } ``` ### Optional Fields **Go**: Uses pointers (`*int`, `*string`) for optionality ```go limitPerPosition *int ``` **TypeScript**: Uses optional types (`?`) and union with undefined ```typescript limitPerPosition?: number ``` ### Getter Methods **Go**: Explicit getter methods ```go func (m *Modification) GetPositionConstraint() []string { return m.positionConstraint } ``` **TypeScript**: Explicit getter methods (similar to Go) ```typescript getPositionConstraint(): string[] | undefined { return this.positionConstraint; } ``` --- ## Testing Frameworks ### Go - **Framework**: Standard `testing` package - **Pattern**: Table-driven tests - **Run**: `go test ./sequal` - **Files**: `*_test.go` **Example**: ```go func TestPlacementControls_PositionConstraint(t *testing.T) { tests := []struct { name string proformaString string expectedPos []string shouldParse bool }{ { name: "Single position constraint", proformaString: "<[Oxidation|Position:M]@M>PEPTIDE", expectedPos: []string{"M"}, shouldParse: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Test implementation }) } } ``` ### TypeScript - **Framework**: Jest - **Pattern**: Describe/test blocks - **Run**: `npm test` - **Files**: `*.test.ts` **Example**: ```typescript describe('Placement Controls', () => { test('should parse position constraint', () => { const seq = Sequence.fromProforma('<[Oxidation|Position:M]@M>PEPTIDE'); const globalMod = seq.getGlobalMods()[0]; expect(globalMod.getPositionConstraint()).toEqual(['M']); }); }); ``` --- ## Key Implementation Differences ### 1. **Type System** **Go**: - Static typing with structs - Explicit type declarations - Interface-based polymorphism - Nil for missing values **TypeScript**: - Static typing with classes - Type inference - Class-based inheritance - undefined/null for missing values ### 2. **Error Handling** **Go**: ```go seq, err := FromProforma("PEPTIDE") if err != nil { return err } ``` **TypeScript**: ```typescript try { const seq = Sequence.fromProforma("PEPTIDE"); } catch (error) { console.error(error); } ``` ### 3. **Collections** **Go**: - Built-in `map[K]V` - Slices `[]T` - No generics in older versions **TypeScript**: - `Map<K, V>` and `Set<T>` - Arrays `T[]` - Generic support ### 4. **Immutability** **Go**: - Explicit copying required - Pointers for mutation - Value vs reference semantics **TypeScript**: - Objects mutable by default - Spread operator for shallow copy - `readonly` keyword for immutability --- ## Migration Path: Go → TypeScript ### Step-by-Step Translation 1. **Struct → Class** ```go type Modification struct { ... } ``` becomes ```typescript class Modification { ... } ``` 2. **Pointer Fields → Optional** ```go limitPerPosition *int ``` becomes ```typescript limitPerPosition?: number ``` 3. **Constructor Parameters → Object** ```go func NewModification(val string, pos *int, ...) *Modification ``` becomes ```typescript constructor(params: ModificationParams) ``` 4. **Error Returns → Exceptions** ```go return nil, fmt.Errorf("error") ``` becomes ```typescript throw new Error("error"); ``` 5. **Getter Methods → Methods** ```go func (m *Modification) GetValue() string ``` becomes ```typescript getValue(): string ``` --- ## Performance Characteristics ### Go - **Pros**: Compiled, fast, efficient memory usage - **Cons**: Larger binary size, slower development ### TypeScript - **Pros**: Fast development, browser-compatible, npm ecosystem - **Cons**: Runtime overhead, requires transpilation ### Use Cases | Use Case | Recommended | |----------|-------------| | **Backend API** | Go | | **Web Application** | TypeScript | | **CLI Tool** | Go | | **Browser Library** | TypeScript | | **Data Processing** | Go | | **Frontend Integration** | TypeScript | --- ## Upgrade Complexity Estimate ### TypeScript → ProForma 2.1 **Complexity by Phase**: | Phase | Difficulty | Time | Reason | |-------|-----------|------|---------| | Charged Formulas | Medium | 2h | PipeValue modification | | Named Entities | Low | 3h | Similar to existing patterns | | Custom Monosaccharides | Low | 2h | Built on named entities | | Terminal Global | Medium | 2h | Parser logic changes | | Placement Controls | High | 4h | Complex tag parsing | | Ion Notation | Low | 2h | Simple boolean flag | | Integration Tests | Medium | 3h | Comprehensive coverage | | Documentation | Low | 2h | README updates | **Total**: 20 hours estimated --- ## Recommended Upgrade Order ### For TypeScript Implementation 1.**Review Go implementation** (Reference) 2.**Create upgrade plan** (This document) 3.**Phase 1: Charged Formulas** (Foundation) 4.**Phase 6: Ion Notation** (Easy win) 5.**Phase 5: Placement Controls** (Core feature) 6.**Phase 2: Named Entities** (Moderate) 7.**Phase 3: Custom Monosaccharides** (Builds on #2) 8.**Phase 4: Terminal Global** (Edge case) 9.**Integration Tests** (Comprehensive) 10.**Documentation Updates** (Final) --- ## Success Metrics ### Go Implementation (Achieved) - ✅ All 6 features implemented - ✅ 37+ new tests - ✅ Zero regressions - ✅ 100% test pass rate - ✅ Documentation updated ### TypeScript Target (Goals) - ⏳ All 6 features implemented - ⏳ 40+ new tests (including integration) - ⏳ Zero regressions - ⏳ 100% test pass rate - ⏳ README updated - ⏳ Version 2.1.0 published --- ## Conclusion The Go implementation provides a solid reference for the TypeScript upgrade. The architecture is similar enough that patterns can be directly translated, but different enough that language-specific idioms should be respected. **Key Takeaway**: The TypeScript implementation is well-positioned for the 2.1 upgrade with: - Clean existing architecture - Comprehensive test coverage - Similar design patterns to Go - Clear upgrade path documented