@rbalchii/anchor-engine 4.7.0 → 4.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +608 -608
- package/README.md +513 -317
- package/anchor.bat +5 -5
- package/docs/AGENT_CONTROLLED_ENGINE.md +581 -0
- package/docs/API.md +314 -314
- package/docs/DEPLOYMENT.md +448 -448
- package/docs/INDEX.md +226 -226
- package/docs/MD_FILES_INVENTORY.md +166 -0
- package/docs/STAR_Whitepaper_Executive.md +216 -216
- package/docs/TROUBLESHOOTING.md +535 -535
- package/docs/arxiv/BIBLIOGRAPHY.bib +145 -145
- package/docs/arxiv/RELATED_WORK.tex +38 -38
- package/docs/arxiv/compile.bat +48 -48
- package/docs/arxiv/joss_response.md +32 -32
- package/docs/arxiv/prepare-submission.bat +46 -46
- package/docs/arxiv/review.md +127 -127
- package/docs/arxiv/star-whitepaper.tex +656 -656
- package/docs/code-patterns.md +289 -289
- package/docs/daily/TODAY_SUMMARY.md +245 -0
- package/docs/guides/BUILDING.md +64 -0
- package/docs/guides/INSTALL_NPM.md +160 -0
- package/docs/guides/NPM_PUBLISH_SUMMARY.md +231 -0
- package/docs/paper.md +124 -0
- package/docs/project/PROJECT_STATE_ASSESSMENT.md +312 -0
- package/docs/reviews/code-review-v4.8.1-decision-record.md +165 -0
- package/docs/testing/TESTING.md +213 -0
- package/docs/testing/TESTING_FRAMEWORK_COMPLETE.md +271 -0
- package/docs/testing/search-test-report.md +76 -0
- package/docs/whitepaper.md +445 -445
- package/engine/dist/commands/distill.js +21 -21
- package/engine/dist/config/index.d.ts +7 -0
- package/engine/dist/config/index.d.ts.map +1 -1
- package/engine/dist/config/index.js +22 -0
- package/engine/dist/config/index.js.map +1 -1
- package/engine/dist/config/paths.d.ts +1 -1
- package/engine/dist/config/paths.js +3 -3
- package/engine/dist/config/paths.js.map +1 -1
- package/engine/dist/core/db.js +131 -131
- package/engine/dist/mcp/server.d.ts +44 -0
- package/engine/dist/mcp/server.d.ts.map +1 -0
- package/engine/dist/mcp/server.js +427 -0
- package/engine/dist/mcp/server.js.map +1 -0
- package/engine/dist/native/index.d.ts +20 -21
- package/engine/dist/native/index.d.ts.map +1 -1
- package/engine/dist/profiling/atomization-profiling.js +3 -3
- package/engine/dist/profiling/bottleneck-identification.js +35 -35
- package/engine/dist/profiling/content-sanitization-profiling.js +86 -86
- package/engine/dist/routes/monitoring.js +8 -8
- package/engine/dist/routes/v1/admin.js +8 -8
- package/engine/dist/routes/v1/atoms.js +15 -15
- package/engine/dist/routes/v1/ingest.d.ts.map +1 -1
- package/engine/dist/routes/v1/ingest.js +39 -0
- package/engine/dist/routes/v1/ingest.js.map +1 -1
- package/engine/dist/routes/v1/system.d.ts.map +1 -1
- package/engine/dist/routes/v1/system.js +305 -6
- package/engine/dist/routes/v1/system.js.map +1 -1
- package/engine/dist/routes/v1/tags.js +2 -2
- package/engine/dist/services/backup/backup-restore.js +23 -23
- package/engine/dist/services/backup/backup.js +14 -14
- package/engine/dist/services/distillation/radial-distiller.d.ts +1 -0
- package/engine/dist/services/distillation/radial-distiller.d.ts.map +1 -1
- package/engine/dist/services/distillation/radial-distiller.js +23 -16
- package/engine/dist/services/distillation/radial-distiller.js.map +1 -1
- package/engine/dist/services/ingest/github-ingest-service.js +18 -18
- package/engine/dist/services/ingest/ingest-atomic.js +79 -79
- package/engine/dist/services/ingest/ingest.d.ts.map +1 -1
- package/engine/dist/services/ingest/ingest.js +28 -25
- package/engine/dist/services/ingest/ingest.js.map +1 -1
- package/engine/dist/services/ingest/watchdog.d.ts.map +1 -1
- package/engine/dist/services/ingest/watchdog.js +14 -24
- package/engine/dist/services/ingest/watchdog.js.map +1 -1
- package/engine/dist/services/llm/reader.js +9 -9
- package/engine/dist/services/mirror/mirror.js +5 -5
- package/engine/dist/services/mirror/mirror.js.map +1 -1
- package/engine/dist/services/research/researcher.js +8 -8
- package/engine/dist/services/scribe/scribe.js +27 -27
- package/engine/dist/services/search/context-inflator.js +34 -34
- package/engine/dist/services/search/explore.js +20 -20
- package/engine/dist/services/search/physics-tag-walker.js +208 -208
- package/engine/dist/services/search/query-parser.js +5 -5
- package/engine/dist/services/search/search-utils.js +3 -3
- package/engine/dist/services/search/search.js +36 -36
- package/engine/dist/services/search/sovereign-system-prompt.js +22 -22
- package/engine/dist/services/semantic/semantic-ingestion-service.js +47 -47
- package/engine/dist/services/semantic/semantic-search.js +21 -21
- package/engine/dist/services/synonyms/auto-synonym-generator.js +35 -35
- package/engine/dist/services/system-status.d.ts +34 -0
- package/engine/dist/services/system-status.d.ts.map +1 -1
- package/engine/dist/services/system-status.js +57 -1
- package/engine/dist/services/system-status.js.map +1 -1
- package/engine/dist/services/tags/discovery.js +5 -5
- package/engine/dist/services/tags/infector.js +6 -6
- package/engine/dist/services/tags/tag-auditor.js +51 -51
- package/engine/dist/services/taxonomy/taxonomy-manager.js +6 -6
- package/engine/dist/utils/tag-cleanup.js +5 -5
- package/engine/dist/utils/tag-modulation.js +1 -1
- package/engine/dist/utils/tag-modulation.js.map +1 -1
- package/engine/package.json +104 -105
- package/mcp-server/README.md +404 -0
- package/mcp-server/dist/index.d.ts +16 -0
- package/mcp-server/dist/index.d.ts.map +1 -0
- package/mcp-server/dist/index.js +709 -0
- package/mcp-server/dist/index.js.map +1 -0
- package/mcp-server/package.json +34 -0
- package/package.json +10 -2
- package/docs/archive/GIT_BACKUP_VERIFICATION.md +0 -297
- package/docs/archive/adoption-guide.md +0 -264
- package/docs/archive/adoption-preparation.md +0 -179
- package/docs/archive/agent-harness-integration.md +0 -227
- package/docs/archive/api-reference.md +0 -106
- package/docs/archive/api_flows_diagram.md +0 -118
- package/docs/archive/architecture.md +0 -410
- package/docs/archive/architecture_diagram.md +0 -174
- package/docs/archive/broader-adoption-preparation.md +0 -175
- package/docs/archive/browser-paradigm-architecture.md +0 -163
- package/docs/archive/chat-integration.md +0 -124
- package/docs/archive/community-adoption-materials.md +0 -103
- package/docs/archive/community-adoption.md +0 -147
- package/docs/archive/comparison-with-siloed-solutions.md +0 -192
- package/docs/archive/comprehensive-docs.md +0 -156
- package/docs/archive/data_flow_diagram.md +0 -251
- package/docs/archive/enhancement-implementation-summary.md +0 -146
- package/docs/archive/evolution-summary.md +0 -141
- package/docs/archive/ingestion_pipeline_diagram.md +0 -198
- package/docs/archive/native-module-profiling-results.md +0 -135
- package/docs/archive/positioning-document.md +0 -158
- package/docs/archive/positioning.md +0 -175
- package/docs/archive/query-builder-documentation.md +0 -218
- package/docs/archive/quick-reference.md +0 -40
- package/docs/archive/quickstart.md +0 -63
- package/docs/archive/relationship-narrative-discovery.md +0 -141
- package/docs/archive/search-logic-improvement-plan.md +0 -336
- package/docs/archive/search_architecture_diagram.md +0 -212
- package/docs/archive/semantic-architecture-guide.md +0 -97
- package/docs/archive/sequence-diagrams.md +0 -128
- package/docs/archive/system_components_diagram.md +0 -296
- package/docs/archive/test-framework-integration.md +0 -109
- package/docs/archive/testing-framework-documentation.md +0 -397
- package/docs/archive/testing-framework-summary.md +0 -121
- package/docs/archive/testing-framework.md +0 -377
- package/docs/archive/ui-architecture.md +0 -75
package/docs/code-patterns.md
CHANGED
|
@@ -1,289 +1,289 @@
|
|
|
1
|
-
# Anchor Engine Code Patterns Guide
|
|
2
|
-
|
|
3
|
-
A tour of the programming patterns used throughout the codebase.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
The Anchor Engine uses a **hybrid approach** - mixing functional and imperative patterns where each makes sense:
|
|
8
|
-
|
|
9
|
-
- **~31,000 lines** of TypeScript
|
|
10
|
-
- **125 files** across 12 modules
|
|
11
|
-
- **Functional** for data transformations
|
|
12
|
-
- **Imperative** for performance-critical loops
|
|
13
|
-
- **Async/await** for I/O operations
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## 1. Functional Patterns
|
|
18
|
-
|
|
19
|
-
### Pure Functions
|
|
20
|
-
Functions that don't mutate state and return predictable outputs.
|
|
21
|
-
|
|
22
|
-
**Example: `calculateLightweightScore` (search.ts)**
|
|
23
|
-
```typescript
|
|
24
|
-
function calculateLightweightScore(
|
|
25
|
-
result: SearchResult,
|
|
26
|
-
queryTerms: string[],
|
|
27
|
-
query: string
|
|
28
|
-
): number {
|
|
29
|
-
// Immutable operations only
|
|
30
|
-
const contentWords = new Set(content.split(/\s+/).filter(w => w.length > 2));
|
|
31
|
-
|
|
32
|
-
// No side effects - just calculations
|
|
33
|
-
return Math.min(1.0, baseScore * 0.3 + termScore * 0.5 + ...);
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
**Used for:**
|
|
38
|
-
- Scoring algorithms
|
|
39
|
-
- Data transformations
|
|
40
|
-
- Configuration merging
|
|
41
|
-
|
|
42
|
-
### Higher-Order Functions
|
|
43
|
-
Functions that take or return other functions.
|
|
44
|
-
|
|
45
|
-
**Example: `processWithAdaptiveConcurrency` (adaptive-concurrency.ts)**
|
|
46
|
-
```typescript
|
|
47
|
-
export async function processWithAdaptiveConcurrency<T, R>(
|
|
48
|
-
items: T[],
|
|
49
|
-
processor: (item: T, index: number) => Promise<R>, // ← Function argument
|
|
50
|
-
config?: ConcurrencyConfig
|
|
51
|
-
): Promise<R[]> {
|
|
52
|
-
// Abstracts the concurrency logic
|
|
53
|
-
const results = await processor(item, index);
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Used for:**
|
|
58
|
-
- Abstracting processing patterns
|
|
59
|
-
- Middleware chains
|
|
60
|
-
- Batch operations
|
|
61
|
-
|
|
62
|
-
### Array Methods (Map/Filter/Reduce)
|
|
63
|
-
Declarative data transformations.
|
|
64
|
-
|
|
65
|
-
**Example: Result processing (search.ts)**
|
|
66
|
-
```typescript
|
|
67
|
-
const scoredAtoms = rawAtoms.map(atom => ({
|
|
68
|
-
...atom,
|
|
69
|
-
score: calculateLightweightScore(atom, terms, sanitizedQuery)
|
|
70
|
-
}))
|
|
71
|
-
.sort((a, b) => (b.score || 0) - (a.score || 0))
|
|
72
|
-
.slice(0, maxResultsPerTerm * terms.length);
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Used for:**
|
|
76
|
-
- Data pipelines
|
|
77
|
-
- Result formatting
|
|
78
|
-
- Scoring and ranking
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## 2. Imperative Patterns
|
|
83
|
-
|
|
84
|
-
### For Loops with Index
|
|
85
|
-
When you need precise control over iteration.
|
|
86
|
-
|
|
87
|
-
**Example: Range merging deduplication (search.ts)**
|
|
88
|
-
```typescript
|
|
89
|
-
for (let i = 1; i < compoundAnchors.length; i++) {
|
|
90
|
-
const next = compoundAnchors[i];
|
|
91
|
-
const currentEnd = (current.end_byte || 0);
|
|
92
|
-
const nextStart = (next.start_byte || 0);
|
|
93
|
-
|
|
94
|
-
// Complex overlap logic requires mutable state
|
|
95
|
-
if (nextStart <= currentEnd + 50) {
|
|
96
|
-
// Merge or skip based on conditions
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Used for:**
|
|
103
|
-
- Complex deduplication
|
|
104
|
-
- Sliding window algorithms
|
|
105
|
-
- Performance-critical paths
|
|
106
|
-
|
|
107
|
-
### While Loops
|
|
108
|
-
For unknown iteration counts.
|
|
109
|
-
|
|
110
|
-
**Example: BFS traversal (explore.ts)**
|
|
111
|
-
```typescript
|
|
112
|
-
for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {
|
|
113
|
-
const nextFrontier: string[] = [];
|
|
114
|
-
|
|
115
|
-
for (const chunk of chunks) {
|
|
116
|
-
// Process current frontier
|
|
117
|
-
// Build nextFrontier for next iteration
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
frontier = nextFrontier; // ← State mutation
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Used for:**
|
|
125
|
-
- Graph traversals
|
|
126
|
-
- Queue processing
|
|
127
|
-
- Streaming data
|
|
128
|
-
|
|
129
|
-
### Mutable State
|
|
130
|
-
When performance matters more than purity.
|
|
131
|
-
|
|
132
|
-
**Example: Batch processing (context-inflator.ts)**
|
|
133
|
-
```typescript
|
|
134
|
-
const results: R[] = [];
|
|
135
|
-
|
|
136
|
-
for (let i = 0; i < items.length; i += batchSize) {
|
|
137
|
-
const batch = items.slice(i, i + batchSize);
|
|
138
|
-
const batchResults = await Promise.all(
|
|
139
|
-
batch.map((item, batchIndex) => processor(item, i + batchIndex))
|
|
140
|
-
);
|
|
141
|
-
results.push(...batchResults); // ← Mutating results array
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
**Used for:**
|
|
146
|
-
- Accumulating results
|
|
147
|
-
- Caching
|
|
148
|
-
- Performance optimization
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
## 3. Async/Await Patterns
|
|
153
|
-
|
|
154
|
-
### Sequential Processing
|
|
155
|
-
One at a time - memory safe.
|
|
156
|
-
|
|
157
|
-
```typescript
|
|
158
|
-
for (const item of items) {
|
|
159
|
-
const result = await processor(item);
|
|
160
|
-
results.push(result);
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Used for:** Low-memory environments (mobile)
|
|
165
|
-
|
|
166
|
-
### Parallel Processing with Promise.all
|
|
167
|
-
Batch concurrency for speed.
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
const batchPromises = batch.map((item, batchIndex) =>
|
|
171
|
-
processor(item, i + batchIndex)
|
|
172
|
-
);
|
|
173
|
-
const batchResults = await Promise.all(batchPromises);
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**Used for:** High-memory systems (desktops)
|
|
177
|
-
|
|
178
|
-
### Error Handling with Try/Catch
|
|
179
|
-
Graceful degradation.
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
try {
|
|
183
|
-
const result = await db.run(query, params);
|
|
184
|
-
return result.rows;
|
|
185
|
-
} catch (e) {
|
|
186
|
-
console.error('[Search] Query failed:', e);
|
|
187
|
-
return []; // ← Graceful fallback
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**Used for:** Database queries, file I/O, external APIs
|
|
192
|
-
|
|
193
|
-
---
|
|
194
|
-
|
|
195
|
-
## 4. Object-Oriented Patterns
|
|
196
|
-
|
|
197
|
-
### Static Methods
|
|
198
|
-
Utility functions grouped by domain.
|
|
199
|
-
|
|
200
|
-
**Example: ContextInflator (context-inflator.ts)**
|
|
201
|
-
```typescript
|
|
202
|
-
export class ContextInflator {
|
|
203
|
-
static async inflate(results: SearchResult[], ...): Promise<SearchResult[]> {
|
|
204
|
-
// Implementation
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
static async inflateFromAtomPositions(...): Promise<SearchResult[]> {
|
|
208
|
-
// Implementation
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**Used for:** Namespacing utility functions
|
|
214
|
-
|
|
215
|
-
### Interfaces for Type Safety
|
|
216
|
-
```typescript
|
|
217
|
-
export interface ConcurrencyConfig {
|
|
218
|
-
forceSequential?: boolean;
|
|
219
|
-
sequentialThresholdMB?: number;
|
|
220
|
-
// ...
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**Used for:** Configuration objects, API contracts
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## 5. Design Patterns
|
|
229
|
-
|
|
230
|
-
### Strategy Pattern
|
|
231
|
-
Different algorithms based on conditions.
|
|
232
|
-
|
|
233
|
-
**Example: Adaptive concurrency**
|
|
234
|
-
```typescript
|
|
235
|
-
if (concurrency === 1) {
|
|
236
|
-
// Sequential strategy
|
|
237
|
-
for (let i = 0; i < items.length; i++) { ... }
|
|
238
|
-
} else {
|
|
239
|
-
// Parallel strategy
|
|
240
|
-
for (let i = 0; i < items.length; i += batchSize) { ... }
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
### Memoization/Caching
|
|
245
|
-
```typescript
|
|
246
|
-
let cachedSettings: any = null;
|
|
247
|
-
let settingsLastRead = 0;
|
|
248
|
-
|
|
249
|
-
function loadUserSettings(): any {
|
|
250
|
-
if (cachedSettings && (now - settingsLastRead) < SETTINGS_CACHE_MS) {
|
|
251
|
-
return cachedSettings; // ← Return cached
|
|
252
|
-
}
|
|
253
|
-
// ... load fresh
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Guard Clauses
|
|
258
|
-
Early returns for edge cases.
|
|
259
|
-
```typescript
|
|
260
|
-
if (!result.content) return result.score || 0;
|
|
261
|
-
if (terms.length === 0) return [];
|
|
262
|
-
if (!databaseReady) throw new Error('Not ready');
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
---
|
|
266
|
-
|
|
267
|
-
## Pattern Selection Guide
|
|
268
|
-
|
|
269
|
-
| Pattern | Use When | Example |
|
|
270
|
-
|---------|----------|---------|
|
|
271
|
-
| **Pure Function** | Data transformation, scoring | `calculateLightweightScore` |
|
|
272
|
-
| **Higher-Order** | Abstract processing logic | `processWithAdaptiveConcurrency` |
|
|
273
|
-
| **For Loop** | Complex iteration logic | Range merging dedup |
|
|
274
|
-
| **Array Methods** | Simple transformations | Result formatting |
|
|
275
|
-
| **Sequential** | Memory-constrained | Mobile search |
|
|
276
|
-
| **Parallel** | Speed needed, memory available | Desktop search |
|
|
277
|
-
| **Mutable State** | Performance critical | Batch accumulation |
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
## Key Takeaways
|
|
282
|
-
|
|
283
|
-
1. **Functional for data** - Transformations, scoring, formatting
|
|
284
|
-
2. **Imperative for control** - Complex loops, performance, memory management
|
|
285
|
-
3. **Async for I/O** - Database, files, network
|
|
286
|
-
4. **Pure when possible** - Easier to test and reason about
|
|
287
|
-
5. **Mutable when necessary** - But isolate the mutation
|
|
288
|
-
|
|
289
|
-
The codebase prioritizes **pragmatism over purity** - using whatever pattern solves the problem best while keeping the code readable and maintainable.
|
|
1
|
+
# Anchor Engine Code Patterns Guide
|
|
2
|
+
|
|
3
|
+
A tour of the programming patterns used throughout the codebase.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Anchor Engine uses a **hybrid approach** - mixing functional and imperative patterns where each makes sense:
|
|
8
|
+
|
|
9
|
+
- **~31,000 lines** of TypeScript
|
|
10
|
+
- **125 files** across 12 modules
|
|
11
|
+
- **Functional** for data transformations
|
|
12
|
+
- **Imperative** for performance-critical loops
|
|
13
|
+
- **Async/await** for I/O operations
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Functional Patterns
|
|
18
|
+
|
|
19
|
+
### Pure Functions
|
|
20
|
+
Functions that don't mutate state and return predictable outputs.
|
|
21
|
+
|
|
22
|
+
**Example: `calculateLightweightScore` (search.ts)**
|
|
23
|
+
```typescript
|
|
24
|
+
function calculateLightweightScore(
|
|
25
|
+
result: SearchResult,
|
|
26
|
+
queryTerms: string[],
|
|
27
|
+
query: string
|
|
28
|
+
): number {
|
|
29
|
+
// Immutable operations only
|
|
30
|
+
const contentWords = new Set(content.split(/\s+/).filter(w => w.length > 2));
|
|
31
|
+
|
|
32
|
+
// No side effects - just calculations
|
|
33
|
+
return Math.min(1.0, baseScore * 0.3 + termScore * 0.5 + ...);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Used for:**
|
|
38
|
+
- Scoring algorithms
|
|
39
|
+
- Data transformations
|
|
40
|
+
- Configuration merging
|
|
41
|
+
|
|
42
|
+
### Higher-Order Functions
|
|
43
|
+
Functions that take or return other functions.
|
|
44
|
+
|
|
45
|
+
**Example: `processWithAdaptiveConcurrency` (adaptive-concurrency.ts)**
|
|
46
|
+
```typescript
|
|
47
|
+
export async function processWithAdaptiveConcurrency<T, R>(
|
|
48
|
+
items: T[],
|
|
49
|
+
processor: (item: T, index: number) => Promise<R>, // ← Function argument
|
|
50
|
+
config?: ConcurrencyConfig
|
|
51
|
+
): Promise<R[]> {
|
|
52
|
+
// Abstracts the concurrency logic
|
|
53
|
+
const results = await processor(item, index);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Used for:**
|
|
58
|
+
- Abstracting processing patterns
|
|
59
|
+
- Middleware chains
|
|
60
|
+
- Batch operations
|
|
61
|
+
|
|
62
|
+
### Array Methods (Map/Filter/Reduce)
|
|
63
|
+
Declarative data transformations.
|
|
64
|
+
|
|
65
|
+
**Example: Result processing (search.ts)**
|
|
66
|
+
```typescript
|
|
67
|
+
const scoredAtoms = rawAtoms.map(atom => ({
|
|
68
|
+
...atom,
|
|
69
|
+
score: calculateLightweightScore(atom, terms, sanitizedQuery)
|
|
70
|
+
}))
|
|
71
|
+
.sort((a, b) => (b.score || 0) - (a.score || 0))
|
|
72
|
+
.slice(0, maxResultsPerTerm * terms.length);
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Used for:**
|
|
76
|
+
- Data pipelines
|
|
77
|
+
- Result formatting
|
|
78
|
+
- Scoring and ranking
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 2. Imperative Patterns
|
|
83
|
+
|
|
84
|
+
### For Loops with Index
|
|
85
|
+
When you need precise control over iteration.
|
|
86
|
+
|
|
87
|
+
**Example: Range merging deduplication (search.ts)**
|
|
88
|
+
```typescript
|
|
89
|
+
for (let i = 1; i < compoundAnchors.length; i++) {
|
|
90
|
+
const next = compoundAnchors[i];
|
|
91
|
+
const currentEnd = (current.end_byte || 0);
|
|
92
|
+
const nextStart = (next.start_byte || 0);
|
|
93
|
+
|
|
94
|
+
// Complex overlap logic requires mutable state
|
|
95
|
+
if (nextStart <= currentEnd + 50) {
|
|
96
|
+
// Merge or skip based on conditions
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Used for:**
|
|
103
|
+
- Complex deduplication
|
|
104
|
+
- Sliding window algorithms
|
|
105
|
+
- Performance-critical paths
|
|
106
|
+
|
|
107
|
+
### While Loops
|
|
108
|
+
For unknown iteration counts.
|
|
109
|
+
|
|
110
|
+
**Example: BFS traversal (explore.ts)**
|
|
111
|
+
```typescript
|
|
112
|
+
for (let depth = 0; depth < maxDepth && frontier.length > 0; depth++) {
|
|
113
|
+
const nextFrontier: string[] = [];
|
|
114
|
+
|
|
115
|
+
for (const chunk of chunks) {
|
|
116
|
+
// Process current frontier
|
|
117
|
+
// Build nextFrontier for next iteration
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
frontier = nextFrontier; // ← State mutation
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Used for:**
|
|
125
|
+
- Graph traversals
|
|
126
|
+
- Queue processing
|
|
127
|
+
- Streaming data
|
|
128
|
+
|
|
129
|
+
### Mutable State
|
|
130
|
+
When performance matters more than purity.
|
|
131
|
+
|
|
132
|
+
**Example: Batch processing (context-inflator.ts)**
|
|
133
|
+
```typescript
|
|
134
|
+
const results: R[] = [];
|
|
135
|
+
|
|
136
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
137
|
+
const batch = items.slice(i, i + batchSize);
|
|
138
|
+
const batchResults = await Promise.all(
|
|
139
|
+
batch.map((item, batchIndex) => processor(item, i + batchIndex))
|
|
140
|
+
);
|
|
141
|
+
results.push(...batchResults); // ← Mutating results array
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Used for:**
|
|
146
|
+
- Accumulating results
|
|
147
|
+
- Caching
|
|
148
|
+
- Performance optimization
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 3. Async/Await Patterns
|
|
153
|
+
|
|
154
|
+
### Sequential Processing
|
|
155
|
+
One at a time - memory safe.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
for (const item of items) {
|
|
159
|
+
const result = await processor(item);
|
|
160
|
+
results.push(result);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Used for:** Low-memory environments (mobile)
|
|
165
|
+
|
|
166
|
+
### Parallel Processing with Promise.all
|
|
167
|
+
Batch concurrency for speed.
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
const batchPromises = batch.map((item, batchIndex) =>
|
|
171
|
+
processor(item, i + batchIndex)
|
|
172
|
+
);
|
|
173
|
+
const batchResults = await Promise.all(batchPromises);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Used for:** High-memory systems (desktops)
|
|
177
|
+
|
|
178
|
+
### Error Handling with Try/Catch
|
|
179
|
+
Graceful degradation.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
try {
|
|
183
|
+
const result = await db.run(query, params);
|
|
184
|
+
return result.rows;
|
|
185
|
+
} catch (e) {
|
|
186
|
+
console.error('[Search] Query failed:', e);
|
|
187
|
+
return []; // ← Graceful fallback
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Used for:** Database queries, file I/O, external APIs
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 4. Object-Oriented Patterns
|
|
196
|
+
|
|
197
|
+
### Static Methods
|
|
198
|
+
Utility functions grouped by domain.
|
|
199
|
+
|
|
200
|
+
**Example: ContextInflator (context-inflator.ts)**
|
|
201
|
+
```typescript
|
|
202
|
+
export class ContextInflator {
|
|
203
|
+
static async inflate(results: SearchResult[], ...): Promise<SearchResult[]> {
|
|
204
|
+
// Implementation
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static async inflateFromAtomPositions(...): Promise<SearchResult[]> {
|
|
208
|
+
// Implementation
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Used for:** Namespacing utility functions
|
|
214
|
+
|
|
215
|
+
### Interfaces for Type Safety
|
|
216
|
+
```typescript
|
|
217
|
+
export interface ConcurrencyConfig {
|
|
218
|
+
forceSequential?: boolean;
|
|
219
|
+
sequentialThresholdMB?: number;
|
|
220
|
+
// ...
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Used for:** Configuration objects, API contracts
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## 5. Design Patterns
|
|
229
|
+
|
|
230
|
+
### Strategy Pattern
|
|
231
|
+
Different algorithms based on conditions.
|
|
232
|
+
|
|
233
|
+
**Example: Adaptive concurrency**
|
|
234
|
+
```typescript
|
|
235
|
+
if (concurrency === 1) {
|
|
236
|
+
// Sequential strategy
|
|
237
|
+
for (let i = 0; i < items.length; i++) { ... }
|
|
238
|
+
} else {
|
|
239
|
+
// Parallel strategy
|
|
240
|
+
for (let i = 0; i < items.length; i += batchSize) { ... }
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Memoization/Caching
|
|
245
|
+
```typescript
|
|
246
|
+
let cachedSettings: any = null;
|
|
247
|
+
let settingsLastRead = 0;
|
|
248
|
+
|
|
249
|
+
function loadUserSettings(): any {
|
|
250
|
+
if (cachedSettings && (now - settingsLastRead) < SETTINGS_CACHE_MS) {
|
|
251
|
+
return cachedSettings; // ← Return cached
|
|
252
|
+
}
|
|
253
|
+
// ... load fresh
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Guard Clauses
|
|
258
|
+
Early returns for edge cases.
|
|
259
|
+
```typescript
|
|
260
|
+
if (!result.content) return result.score || 0;
|
|
261
|
+
if (terms.length === 0) return [];
|
|
262
|
+
if (!databaseReady) throw new Error('Not ready');
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Pattern Selection Guide
|
|
268
|
+
|
|
269
|
+
| Pattern | Use When | Example |
|
|
270
|
+
|---------|----------|---------|
|
|
271
|
+
| **Pure Function** | Data transformation, scoring | `calculateLightweightScore` |
|
|
272
|
+
| **Higher-Order** | Abstract processing logic | `processWithAdaptiveConcurrency` |
|
|
273
|
+
| **For Loop** | Complex iteration logic | Range merging dedup |
|
|
274
|
+
| **Array Methods** | Simple transformations | Result formatting |
|
|
275
|
+
| **Sequential** | Memory-constrained | Mobile search |
|
|
276
|
+
| **Parallel** | Speed needed, memory available | Desktop search |
|
|
277
|
+
| **Mutable State** | Performance critical | Batch accumulation |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Key Takeaways
|
|
282
|
+
|
|
283
|
+
1. **Functional for data** - Transformations, scoring, formatting
|
|
284
|
+
2. **Imperative for control** - Complex loops, performance, memory management
|
|
285
|
+
3. **Async for I/O** - Database, files, network
|
|
286
|
+
4. **Pure when possible** - Easier to test and reason about
|
|
287
|
+
5. **Mutable when necessary** - But isolate the mutation
|
|
288
|
+
|
|
289
|
+
The codebase prioritizes **pragmatism over purity** - using whatever pattern solves the problem best while keeping the code readable and maintainable.
|