-
-
Notifications
You must be signed in to change notification settings - Fork 0
Description
🧩 Description
The current implementation of NoteBuilder uses a mutable fluent interface — each method (paragraph(), text(), bold(), etc.) returns this, mutating the builder in-place. This pattern can lead to:
• Hidden side effects between chains
• Inadvertent reuse of mutated builders
• Bugs caused by shared reference across multiple operations
To improve safety and predictability, we will refactor NoteBuilder to be immutable: every method call returns a new builder instance with updated internal state.
⸻
🎯 Goals
• Make NoteBuilder fully immutable
• Eliminate usage of this in return values
• Ensure every call (paragraph(), text(), bold(), etc.) returns a fresh builder with copied and updated state
• Maintain existing chainability and ergonomics
• Prevent accidental builder reuse across chains
⸻
✅ Example Before (mutable)
const builder = new NoteBuilder();
builder.paragraph().text("Hello").bold(" world");
const draft = builder.build(); // 🧨 Same builder reused
⸻
✅ Example After (immutable)
const draft = new NoteBuilder()
.paragraph()
.text("Hello")
.bold(" world")
.build(); // ✅ Each step produces a new builder
⸻
🛠️ Tasks
• Replace all return this statements with return new NoteBuilder({...updatedState})
• Use a shared internal state interface (e.g. NoteBuilderState) to manage propagation
• Update all internal helpers to operate on immutable copies
• Refactor .paragraph(), .text(), .bold(), .italic(), .bulletList(), .item(), .finish(), etc.
• Update all tests to avoid relying on shared builder reference
• Add regression tests for chained but diverging builder paths
⸻
💡 Design Considerations
• Prefer shallow copies for performance and simplicity
• Allow branching logic (e.g. copy a builder mid-chain for reuse):
const base = new NoteBuilder().paragraph().text("Shared ");
const a = base.bold("A");
const b = base.italic("B");
⸻
🏷️ Labels
refactor, immutability, api-safety, note-builder, breaking-change