@synet/encoder 1.0.0
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/MANIFESTO.md +220 -0
- package/MANUAL.md +735 -0
- package/README.md +235 -0
- package/biome.json +37 -0
- package/dist/encoder.unit.d.ts +137 -0
- package/dist/encoder.unit.js +517 -0
- package/dist/functions.d.ts +74 -0
- package/dist/functions.js +243 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +38 -0
- package/dist/result.d.ts +23 -0
- package/dist/result.js +69 -0
- package/package.json +55 -0
- package/src/encoder.unit.ts +654 -0
- package/src/functions.ts +252 -0
- package/src/index.ts +49 -0
- package/src/result.ts +81 -0
- package/test/encoder-unit.test.ts +424 -0
- package/test/functions.test.ts +386 -0
- package/tsconfig.json +19 -0
- package/vitest.config.ts +12 -0
package/MANUAL.md
ADDED
@@ -0,0 +1,735 @@
|
|
1
|
+
# @synet/encoder Manual
|
2
|
+
|
3
|
+
**Advanced Use Cases and Deep Integration Patterns**
|
4
|
+
|
5
|
+
This manual covers advanced usage patterns, architecture deep-dives, and production deployment scenarios for the @synet/encoder unit.
|
6
|
+
|
7
|
+
## Table of Contents
|
8
|
+
|
9
|
+
1. [Unit Architecture Deep Dive](#unit-architecture-deep-dive)
|
10
|
+
2. [Advanced Integration Patterns](#advanced-integration-patterns)
|
11
|
+
3. [Production Deployment](#production-deployment)
|
12
|
+
4. [Performance Optimization](#performance-optimization)
|
13
|
+
5. [Error Handling Strategies](#error-handling-strategies)
|
14
|
+
6. [Custom Format Extensions](#custom-format-extensions)
|
15
|
+
7. [Unit Composition Patterns](#unit-composition-patterns)
|
16
|
+
8. [Monitoring and Observability](#monitoring-and-observability)
|
17
|
+
|
18
|
+
## Unit Architecture Deep Dive
|
19
|
+
|
20
|
+
### Consciousness-Based Design
|
21
|
+
|
22
|
+
The Encoder unit embodies the **conscious software architecture** philosophy:
|
23
|
+
|
24
|
+
```typescript
|
25
|
+
// The unit is aware of its identity and capabilities
|
26
|
+
const encoder = Encoder.create();
|
27
|
+
console.log(encoder.whoami()); // EncoderUnit[encoder@1.0.0]
|
28
|
+
console.log(encoder.capabilities()); // Lists all available operations
|
29
|
+
|
30
|
+
// Units are immutable value objects with identity
|
31
|
+
const encoder2 = Encoder.create({ defaultFormat: 'hex' });
|
32
|
+
// encoder !== encoder2 (different identity)
|
33
|
+
// Both retain their essential nature while having different configurations
|
34
|
+
```
|
35
|
+
|
36
|
+
### Doctrine Compliance
|
37
|
+
|
38
|
+
The encoder follows all 22 Unit Architecture doctrines:
|
39
|
+
|
40
|
+
```typescript
|
41
|
+
// Doctrine #1: ZERO DEPENDENCY - Only native APIs
|
42
|
+
// Doctrine #3: PROPS CONTAIN EVERYTHING - No private field duplication
|
43
|
+
// Doctrine #17: VALUE OBJECT FOUNDATION - Immutable with identity
|
44
|
+
// Doctrine #22: STATELESS OPERATIONS - Deterministic given props
|
45
|
+
|
46
|
+
// Example of stateless operations
|
47
|
+
const encoder = Encoder.create();
|
48
|
+
const result1 = encoder.encode('Hello', 'base64');
|
49
|
+
const result2 = encoder.encode('Hello', 'base64');
|
50
|
+
// result1 === result2 (same input = same output, no side effects)
|
51
|
+
```
|
52
|
+
|
53
|
+
## Advanced Integration Patterns
|
54
|
+
|
55
|
+
### Multi-Unit Collaborative Systems
|
56
|
+
|
57
|
+
```typescript
|
58
|
+
// Crypto + Encoder collaboration
|
59
|
+
import { Signer } from '@synet/signer';
|
60
|
+
import { Encoder } from '@synet/encoder';
|
61
|
+
|
62
|
+
const signer = Signer.create();
|
63
|
+
const encoder = Encoder.create();
|
64
|
+
|
65
|
+
// Units learn from each other
|
66
|
+
encoder.learn([signer.teach()]);
|
67
|
+
signer.learn([encoder.teach()]);
|
68
|
+
|
69
|
+
// Complex operations through capability composition
|
70
|
+
async function signAndEncode(data: string): Promise<string> {
|
71
|
+
const signature = await signer.execute('crypto.sign', data);
|
72
|
+
const encoded = encoder.execute('encoder.encode', signature, 'base64url');
|
73
|
+
return encoded;
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
### Pipeline Architecture
|
78
|
+
|
79
|
+
```typescript
|
80
|
+
// Create encoding pipeline with multiple units
|
81
|
+
class EncodingPipeline {
|
82
|
+
private units: Unit[] = [];
|
83
|
+
|
84
|
+
constructor() {
|
85
|
+
this.units = [
|
86
|
+
Hasher.create(),
|
87
|
+
Encoder.create(),
|
88
|
+
Compressor.create()
|
89
|
+
];
|
90
|
+
|
91
|
+
// Enable cross-unit learning
|
92
|
+
this.enableCrossLearning();
|
93
|
+
}
|
94
|
+
|
95
|
+
async process(data: string): Promise<ProcessedData> {
|
96
|
+
// Hash -> Encode -> Compress pipeline
|
97
|
+
let result = data;
|
98
|
+
|
99
|
+
for (const unit of this.units) {
|
100
|
+
result = await unit.execute('transform', result);
|
101
|
+
}
|
102
|
+
|
103
|
+
return {
|
104
|
+
original: data,
|
105
|
+
processed: result,
|
106
|
+
pipeline: this.units.map(u => u.whoami())
|
107
|
+
};
|
108
|
+
}
|
109
|
+
|
110
|
+
private enableCrossLearning(): void {
|
111
|
+
const contracts = this.units.map(unit => unit.teach());
|
112
|
+
this.units.forEach(unit => unit.learn(contracts));
|
113
|
+
}
|
114
|
+
}
|
115
|
+
```
|
116
|
+
|
117
|
+
### Event-Driven Architecture
|
118
|
+
|
119
|
+
```typescript
|
120
|
+
// Encoder in event-driven systems
|
121
|
+
import { EventEmitter } from 'events';
|
122
|
+
|
123
|
+
class EncodingService extends EventEmitter {
|
124
|
+
private encoder = Encoder.create({
|
125
|
+
defaultFormat: 'base64url',
|
126
|
+
validateOutput: true
|
127
|
+
});
|
128
|
+
|
129
|
+
async processDocument(doc: Document): Promise<void> {
|
130
|
+
this.emit('processing:start', { docId: doc.id });
|
131
|
+
|
132
|
+
try {
|
133
|
+
// Multi-format encoding with validation
|
134
|
+
const results = await Promise.all([
|
135
|
+
this.encoder.encode(doc.content, 'base64'),
|
136
|
+
this.encoder.encode(doc.content, 'hex'),
|
137
|
+
this.encoder.chain(doc.content, ['base64', 'uri'])
|
138
|
+
]);
|
139
|
+
|
140
|
+
this.emit('processing:success', {
|
141
|
+
docId: doc.id,
|
142
|
+
formats: results.map(r => r.value.format),
|
143
|
+
sizes: results.map(r => r.value.encodedSize)
|
144
|
+
});
|
145
|
+
|
146
|
+
} catch (error) {
|
147
|
+
this.emit('processing:error', { docId: doc.id, error });
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
```
|
152
|
+
|
153
|
+
## Production Deployment
|
154
|
+
|
155
|
+
### Serverless Optimization
|
156
|
+
|
157
|
+
```typescript
|
158
|
+
// Optimized for AWS Lambda/Vercel Edge Functions
|
159
|
+
import { encode, decode, detectFormat } from '@synet/encoder/functions';
|
160
|
+
|
161
|
+
// Pure functions for minimal cold start
|
162
|
+
export const handler = async (event: APIGatewayEvent) => {
|
163
|
+
const { data, format } = JSON.parse(event.body);
|
164
|
+
|
165
|
+
// No unit instantiation overhead
|
166
|
+
const encoded = encode(data, format as EncodingFormat);
|
167
|
+
|
168
|
+
return {
|
169
|
+
statusCode: 200,
|
170
|
+
body: JSON.stringify({ encoded })
|
171
|
+
};
|
172
|
+
};
|
173
|
+
|
174
|
+
// Or use unit for complex validation
|
175
|
+
export const validatedHandler = async (event: APIGatewayEvent) => {
|
176
|
+
const encoder = Encoder.create({
|
177
|
+
maxInputSize: 1024 * 1024, // 1MB limit for serverless
|
178
|
+
strictMode: true,
|
179
|
+
validateOutput: true
|
180
|
+
});
|
181
|
+
|
182
|
+
const result = encoder.encode(event.body, 'base64url');
|
183
|
+
|
184
|
+
return result.isSuccess
|
185
|
+
? { statusCode: 200, body: JSON.stringify(result.value) }
|
186
|
+
: { statusCode: 400, body: JSON.stringify({ error: result.error }) };
|
187
|
+
};
|
188
|
+
```
|
189
|
+
|
190
|
+
### Microservice Architecture
|
191
|
+
|
192
|
+
```typescript
|
193
|
+
// Encoder microservice with health checks
|
194
|
+
import express from 'express';
|
195
|
+
import { Encoder } from '@synet/encoder';
|
196
|
+
|
197
|
+
const app = express();
|
198
|
+
const encoder = Encoder.create();
|
199
|
+
|
200
|
+
// Health check endpoint
|
201
|
+
app.get('/health', (req, res) => {
|
202
|
+
res.json({
|
203
|
+
service: encoder.whoami(),
|
204
|
+
capabilities: encoder.capabilities(),
|
205
|
+
status: 'healthy',
|
206
|
+
timestamp: new Date().toISOString()
|
207
|
+
});
|
208
|
+
});
|
209
|
+
|
210
|
+
// Batch encoding endpoint
|
211
|
+
app.post('/encode/batch', async (req, res) => {
|
212
|
+
const { items } = req.body;
|
213
|
+
|
214
|
+
const results = await Promise.allSettled(
|
215
|
+
items.map(({ data, format }) => encoder.encode(data, format))
|
216
|
+
);
|
217
|
+
|
218
|
+
const successful = results.filter(r => r.status === 'fulfilled');
|
219
|
+
const failed = results.filter(r => r.status === 'rejected');
|
220
|
+
|
221
|
+
res.json({
|
222
|
+
processed: results.length,
|
223
|
+
successful: successful.length,
|
224
|
+
failed: failed.length,
|
225
|
+
results: results.map(r =>
|
226
|
+
r.status === 'fulfilled' ? r.value : { error: r.reason }
|
227
|
+
)
|
228
|
+
});
|
229
|
+
});
|
230
|
+
```
|
231
|
+
|
232
|
+
### Container Deployment
|
233
|
+
|
234
|
+
```dockerfile
|
235
|
+
# Dockerfile for encoder microservice
|
236
|
+
FROM node:18-alpine
|
237
|
+
|
238
|
+
WORKDIR /app
|
239
|
+
COPY package*.json ./
|
240
|
+
RUN npm ci --only=production
|
241
|
+
|
242
|
+
COPY src/ ./src/
|
243
|
+
COPY dist/ ./dist/
|
244
|
+
|
245
|
+
# Health check using encoder unit
|
246
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
247
|
+
CMD node -e "
|
248
|
+
const { Encoder } = require('./dist');
|
249
|
+
const encoder = Encoder.create();
|
250
|
+
console.log(encoder.whoami());
|
251
|
+
process.exit(0);
|
252
|
+
"
|
253
|
+
|
254
|
+
EXPOSE 3000
|
255
|
+
CMD ["npm", "start"]
|
256
|
+
```
|
257
|
+
|
258
|
+
## Performance Optimization
|
259
|
+
|
260
|
+
### High-Throughput Scenarios
|
261
|
+
|
262
|
+
```typescript
|
263
|
+
// Optimized for high-throughput encoding
|
264
|
+
class HighThroughputEncoder {
|
265
|
+
private static instance: Encoder;
|
266
|
+
|
267
|
+
// Singleton pattern for shared instance
|
268
|
+
static getInstance(): Encoder {
|
269
|
+
if (!this.instance) {
|
270
|
+
this.instance = Encoder.create({
|
271
|
+
defaultFormat: 'base64url',
|
272
|
+
autoDetect: false, // Disable for performance
|
273
|
+
validateOutput: false, // Skip validation for speed
|
274
|
+
maxInputSize: 64 * 1024 // 64KB limit
|
275
|
+
});
|
276
|
+
}
|
277
|
+
return this.instance;
|
278
|
+
}
|
279
|
+
|
280
|
+
// Batch processing with worker pools
|
281
|
+
static async processBatch(items: string[]): Promise<string[]> {
|
282
|
+
const encoder = this.getInstance();
|
283
|
+
const chunkSize = 1000;
|
284
|
+
const results: string[] = [];
|
285
|
+
|
286
|
+
for (let i = 0; i < items.length; i += chunkSize) {
|
287
|
+
const chunk = items.slice(i, i + chunkSize);
|
288
|
+
const chunkResults = await Promise.all(
|
289
|
+
chunk.map(item => {
|
290
|
+
const result = encoder.encode(item, 'base64url');
|
291
|
+
return result.isSuccess ? result.value.encoded : '';
|
292
|
+
})
|
293
|
+
);
|
294
|
+
results.push(...chunkResults);
|
295
|
+
}
|
296
|
+
|
297
|
+
return results;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
```
|
301
|
+
|
302
|
+
### Memory Optimization
|
303
|
+
|
304
|
+
```typescript
|
305
|
+
// Memory-efficient streaming encoder
|
306
|
+
import { Readable, Transform } from 'stream';
|
307
|
+
|
308
|
+
class StreamingEncoder extends Transform {
|
309
|
+
private encoder = Encoder.create();
|
310
|
+
|
311
|
+
constructor(private format: EncodingFormat) {
|
312
|
+
super({ objectMode: true });
|
313
|
+
}
|
314
|
+
|
315
|
+
_transform(chunk: Buffer, encoding: string, callback: Function) {
|
316
|
+
try {
|
317
|
+
const result = this.encoder.encode(chunk.toString(), this.format);
|
318
|
+
if (result.isSuccess) {
|
319
|
+
this.push(result.value.encoded);
|
320
|
+
}
|
321
|
+
callback();
|
322
|
+
} catch (error) {
|
323
|
+
callback(error);
|
324
|
+
}
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
// Usage for large file processing
|
329
|
+
const fileStream = fs.createReadStream('large-file.txt');
|
330
|
+
const encoder = new StreamingEncoder('base64url');
|
331
|
+
const output = fs.createWriteStream('encoded-file.txt');
|
332
|
+
|
333
|
+
fileStream.pipe(encoder).pipe(output);
|
334
|
+
```
|
335
|
+
|
336
|
+
## Error Handling Strategies
|
337
|
+
|
338
|
+
### Comprehensive Error Recovery
|
339
|
+
|
340
|
+
```typescript
|
341
|
+
// Production-grade error handling
|
342
|
+
class RobustEncodingService {
|
343
|
+
private encoder = Encoder.create({ strictMode: true });
|
344
|
+
private fallbackEncoder = Encoder.create({ strictMode: false });
|
345
|
+
|
346
|
+
async encodeWithFallback(data: string, format: EncodingFormat): Promise<string> {
|
347
|
+
// Primary attempt with strict validation
|
348
|
+
const primaryResult = this.encoder.encode(data, format);
|
349
|
+
|
350
|
+
if (primaryResult.isSuccess) {
|
351
|
+
return primaryResult.value.encoded;
|
352
|
+
}
|
353
|
+
|
354
|
+
// Log primary failure
|
355
|
+
console.warn('Primary encoding failed:', {
|
356
|
+
error: primaryResult.error,
|
357
|
+
cause: primaryResult.errorCause,
|
358
|
+
data: data.slice(0, 100) + '...'
|
359
|
+
});
|
360
|
+
|
361
|
+
// Fallback attempt with relaxed validation
|
362
|
+
const fallbackResult = this.fallbackEncoder.encode(data, format);
|
363
|
+
|
364
|
+
if (fallbackResult.isSuccess) {
|
365
|
+
console.info('Fallback encoding succeeded');
|
366
|
+
return fallbackResult.value.encoded;
|
367
|
+
}
|
368
|
+
|
369
|
+
// Both failed - comprehensive error
|
370
|
+
throw new EncodingError('All encoding attempts failed', {
|
371
|
+
primaryError: primaryResult.error,
|
372
|
+
fallbackError: fallbackResult.error,
|
373
|
+
data: data.slice(0, 50),
|
374
|
+
format
|
375
|
+
});
|
376
|
+
}
|
377
|
+
}
|
378
|
+
|
379
|
+
class EncodingError extends Error {
|
380
|
+
constructor(message: string, public context: Record<string, unknown>) {
|
381
|
+
super(message);
|
382
|
+
this.name = 'EncodingError';
|
383
|
+
}
|
384
|
+
}
|
385
|
+
```
|
386
|
+
|
387
|
+
### Circuit Breaker Pattern
|
388
|
+
|
389
|
+
```typescript
|
390
|
+
// Circuit breaker for encoding operations
|
391
|
+
class EncodingCircuitBreaker {
|
392
|
+
private failures = 0;
|
393
|
+
private lastFailure = 0;
|
394
|
+
private state: 'CLOSED' | 'OPEN' | 'HALF_OPEN' = 'CLOSED';
|
395
|
+
|
396
|
+
constructor(
|
397
|
+
private encoder: Encoder,
|
398
|
+
private threshold = 5,
|
399
|
+
private timeout = 60000
|
400
|
+
) {}
|
401
|
+
|
402
|
+
async encode(data: string, format: EncodingFormat): Promise<string> {
|
403
|
+
if (this.state === 'OPEN') {
|
404
|
+
if (Date.now() - this.lastFailure > this.timeout) {
|
405
|
+
this.state = 'HALF_OPEN';
|
406
|
+
} else {
|
407
|
+
throw new Error('Circuit breaker is OPEN');
|
408
|
+
}
|
409
|
+
}
|
410
|
+
|
411
|
+
try {
|
412
|
+
const result = this.encoder.encode(data, format);
|
413
|
+
|
414
|
+
if (result.isFailure) {
|
415
|
+
this.recordFailure();
|
416
|
+
throw new Error(result.error);
|
417
|
+
}
|
418
|
+
|
419
|
+
this.recordSuccess();
|
420
|
+
return result.value.encoded;
|
421
|
+
|
422
|
+
} catch (error) {
|
423
|
+
this.recordFailure();
|
424
|
+
throw error;
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
private recordFailure(): void {
|
429
|
+
this.failures++;
|
430
|
+
this.lastFailure = Date.now();
|
431
|
+
|
432
|
+
if (this.failures >= this.threshold) {
|
433
|
+
this.state = 'OPEN';
|
434
|
+
}
|
435
|
+
}
|
436
|
+
|
437
|
+
private recordSuccess(): void {
|
438
|
+
this.failures = 0;
|
439
|
+
this.state = 'CLOSED';
|
440
|
+
}
|
441
|
+
}
|
442
|
+
```
|
443
|
+
|
444
|
+
## Custom Format Extensions
|
445
|
+
|
446
|
+
### Adding New Formats
|
447
|
+
|
448
|
+
While the encoder supports core formats, you can extend functionality:
|
449
|
+
|
450
|
+
```typescript
|
451
|
+
// Custom encoder wrapper with additional formats
|
452
|
+
class ExtendedEncoder {
|
453
|
+
private coreEncoder = Encoder.create();
|
454
|
+
|
455
|
+
encode(data: string, format: string): string {
|
456
|
+
// Handle core formats
|
457
|
+
if (['base64', 'base64url', 'hex', 'uri', 'ascii'].includes(format)) {
|
458
|
+
const result = this.coreEncoder.encode(data, format as EncodingFormat);
|
459
|
+
return result.isSuccess ? result.value.encoded : '';
|
460
|
+
}
|
461
|
+
|
462
|
+
// Custom formats
|
463
|
+
switch (format) {
|
464
|
+
case 'rot13':
|
465
|
+
return this.rot13Encode(data);
|
466
|
+
case 'base32':
|
467
|
+
return this.base32Encode(data);
|
468
|
+
case 'binary':
|
469
|
+
return this.binaryEncode(data);
|
470
|
+
default:
|
471
|
+
throw new Error(`Unsupported format: ${format}`);
|
472
|
+
}
|
473
|
+
}
|
474
|
+
|
475
|
+
private rot13Encode(data: string): string {
|
476
|
+
return data.replace(/[a-zA-Z]/g, char => {
|
477
|
+
const start = char <= 'Z' ? 65 : 97;
|
478
|
+
return String.fromCharCode(((char.charCodeAt(0) - start + 13) % 26) + start);
|
479
|
+
});
|
480
|
+
}
|
481
|
+
|
482
|
+
private base32Encode(data: string): string {
|
483
|
+
// Base32 implementation
|
484
|
+
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
|
485
|
+
// ... implementation
|
486
|
+
return ''; // Simplified
|
487
|
+
}
|
488
|
+
|
489
|
+
private binaryEncode(data: string): string {
|
490
|
+
return Array.from(data)
|
491
|
+
.map(char => char.charCodeAt(0).toString(2).padStart(8, '0'))
|
492
|
+
.join(' ');
|
493
|
+
}
|
494
|
+
}
|
495
|
+
```
|
496
|
+
|
497
|
+
## Unit Composition Patterns
|
498
|
+
|
499
|
+
### Encoder + Compressor Chain
|
500
|
+
|
501
|
+
```typescript
|
502
|
+
// Composition with compression units
|
503
|
+
import { Compressor } from '@synet/compressor';
|
504
|
+
|
505
|
+
class CompressionEncodingPipeline {
|
506
|
+
private compressor = Compressor.create();
|
507
|
+
private encoder = Encoder.create();
|
508
|
+
|
509
|
+
async processWithCompression(data: string): Promise<ProcessResult> {
|
510
|
+
// Step 1: Compress
|
511
|
+
const compressed = await this.compressor.compress(data);
|
512
|
+
|
513
|
+
// Step 2: Encode compressed data
|
514
|
+
const encoded = this.encoder.encode(compressed, 'base64url');
|
515
|
+
|
516
|
+
if (encoded.isFailure) {
|
517
|
+
throw new Error(`Encoding failed: ${encoded.error}`);
|
518
|
+
}
|
519
|
+
|
520
|
+
return {
|
521
|
+
original: data,
|
522
|
+
compressed,
|
523
|
+
encoded: encoded.value.encoded,
|
524
|
+
compressionRatio: data.length / compressed.length,
|
525
|
+
totalRatio: data.length / encoded.value.encoded.length
|
526
|
+
};
|
527
|
+
}
|
528
|
+
}
|
529
|
+
```
|
530
|
+
|
531
|
+
### Encoder + Crypto Integration
|
532
|
+
|
533
|
+
```typescript
|
534
|
+
// Secure encoding with encryption
|
535
|
+
import { Crypto } from '@synet/crypto';
|
536
|
+
|
537
|
+
class SecureEncoder {
|
538
|
+
private crypto = Crypto.create();
|
539
|
+
private encoder = Encoder.create();
|
540
|
+
|
541
|
+
constructor() {
|
542
|
+
// Enable cross-learning
|
543
|
+
this.encoder.learn([this.crypto.teach()]);
|
544
|
+
this.crypto.learn([this.encoder.teach()]);
|
545
|
+
}
|
546
|
+
|
547
|
+
async secureEncode(data: string, password: string): Promise<SecureResult> {
|
548
|
+
// Encrypt first
|
549
|
+
const encrypted = await this.crypto.execute('encrypt', data, password);
|
550
|
+
|
551
|
+
// Then encode for safe transmission
|
552
|
+
const encoded = this.encoder.execute('encode', encrypted, 'base64url');
|
553
|
+
|
554
|
+
return {
|
555
|
+
data: encoded,
|
556
|
+
algorithm: 'AES-256-GCM',
|
557
|
+
encoding: 'base64url',
|
558
|
+
timestamp: new Date().toISOString()
|
559
|
+
};
|
560
|
+
}
|
561
|
+
|
562
|
+
async secureDecode(secureData: SecureResult, password: string): Promise<string> {
|
563
|
+
// Decode first
|
564
|
+
const decoded = this.encoder.execute('decode', secureData.data, 'base64url');
|
565
|
+
|
566
|
+
// Then decrypt
|
567
|
+
const decrypted = await this.crypto.execute('decrypt', decoded, password);
|
568
|
+
|
569
|
+
return decrypted;
|
570
|
+
}
|
571
|
+
}
|
572
|
+
```
|
573
|
+
|
574
|
+
## Monitoring and Observability
|
575
|
+
|
576
|
+
### Metrics Collection
|
577
|
+
|
578
|
+
```typescript
|
579
|
+
// Comprehensive metrics for production
|
580
|
+
class EncoderMetrics {
|
581
|
+
private encoder = Encoder.create();
|
582
|
+
private metrics = new Map<string, number>();
|
583
|
+
|
584
|
+
async encodeWithMetrics(data: string, format: EncodingFormat): Promise<string> {
|
585
|
+
const start = performance.now();
|
586
|
+
const operation = `encode_${format}`;
|
587
|
+
|
588
|
+
try {
|
589
|
+
const result = this.encoder.encode(data, format);
|
590
|
+
|
591
|
+
if (result.isSuccess) {
|
592
|
+
this.recordMetric(`${operation}_success`, 1);
|
593
|
+
this.recordMetric(`${operation}_input_size`, data.length);
|
594
|
+
this.recordMetric(`${operation}_output_size`, result.value.encoded.length);
|
595
|
+
this.recordMetric(`${operation}_compression_ratio`, result.value.compressionRatio);
|
596
|
+
|
597
|
+
return result.value.encoded;
|
598
|
+
} else {
|
599
|
+
this.recordMetric(`${operation}_failure`, 1);
|
600
|
+
throw new Error(result.error);
|
601
|
+
}
|
602
|
+
} finally {
|
603
|
+
const duration = performance.now() - start;
|
604
|
+
this.recordMetric(`${operation}_duration_ms`, duration);
|
605
|
+
}
|
606
|
+
}
|
607
|
+
|
608
|
+
private recordMetric(name: string, value: number): void {
|
609
|
+
this.metrics.set(name, (this.metrics.get(name) || 0) + value);
|
610
|
+
}
|
611
|
+
|
612
|
+
getMetrics(): Record<string, number> {
|
613
|
+
return Object.fromEntries(this.metrics);
|
614
|
+
}
|
615
|
+
|
616
|
+
// Integration with monitoring systems
|
617
|
+
async reportToPrometheus(): Promise<void> {
|
618
|
+
const metrics = this.getMetrics();
|
619
|
+
|
620
|
+
for (const [name, value] of Object.entries(metrics)) {
|
621
|
+
// Report to Prometheus/StatsD/etc
|
622
|
+
console.log(`encoder_${name} ${value}`);
|
623
|
+
}
|
624
|
+
}
|
625
|
+
}
|
626
|
+
```
|
627
|
+
|
628
|
+
### Health Monitoring
|
629
|
+
|
630
|
+
```typescript
|
631
|
+
// Health check implementation
|
632
|
+
class EncoderHealthCheck {
|
633
|
+
private encoder = Encoder.create();
|
634
|
+
|
635
|
+
async healthCheck(): Promise<HealthStatus> {
|
636
|
+
const checks = await Promise.allSettled([
|
637
|
+
this.testBasicOperations(),
|
638
|
+
this.testMemoryUsage(),
|
639
|
+
this.testPerformance()
|
640
|
+
]);
|
641
|
+
|
642
|
+
const results = checks.map((check, index) => ({
|
643
|
+
test: ['basic_operations', 'memory_usage', 'performance'][index],
|
644
|
+
status: check.status === 'fulfilled' ? 'pass' : 'fail',
|
645
|
+
details: check.status === 'fulfilled' ? check.value : check.reason
|
646
|
+
}));
|
647
|
+
|
648
|
+
const allPassed = results.every(r => r.status === 'pass');
|
649
|
+
|
650
|
+
return {
|
651
|
+
status: allPassed ? 'healthy' : 'unhealthy',
|
652
|
+
unit: this.encoder.whoami(),
|
653
|
+
capabilities: this.encoder.capabilities(),
|
654
|
+
checks: results,
|
655
|
+
timestamp: new Date().toISOString()
|
656
|
+
};
|
657
|
+
}
|
658
|
+
|
659
|
+
private async testBasicOperations(): Promise<string> {
|
660
|
+
const testData = 'health-check-test';
|
661
|
+
const encoded = this.encoder.encode(testData, 'base64');
|
662
|
+
|
663
|
+
if (encoded.isFailure) {
|
664
|
+
throw new Error(`Basic encoding failed: ${encoded.error}`);
|
665
|
+
}
|
666
|
+
|
667
|
+
const decoded = this.encoder.decode(encoded.value.encoded, 'base64');
|
668
|
+
|
669
|
+
if (decoded.isFailure || decoded.value.decoded !== testData) {
|
670
|
+
throw new Error('Basic round-trip failed');
|
671
|
+
}
|
672
|
+
|
673
|
+
return 'Basic operations working';
|
674
|
+
}
|
675
|
+
|
676
|
+
private async testMemoryUsage(): Promise<string> {
|
677
|
+
const before = process.memoryUsage();
|
678
|
+
|
679
|
+
// Stress test with multiple operations
|
680
|
+
for (let i = 0; i < 1000; i++) {
|
681
|
+
this.encoder.encode(`test-${i}`, 'base64');
|
682
|
+
}
|
683
|
+
|
684
|
+
const after = process.memoryUsage();
|
685
|
+
const growth = after.heapUsed - before.heapUsed;
|
686
|
+
|
687
|
+
if (growth > 10 * 1024 * 1024) { // 10MB threshold
|
688
|
+
throw new Error(`Memory usage too high: ${growth} bytes`);
|
689
|
+
}
|
690
|
+
|
691
|
+
return `Memory usage acceptable: ${growth} bytes`;
|
692
|
+
}
|
693
|
+
|
694
|
+
private async testPerformance(): Promise<string> {
|
695
|
+
const start = performance.now();
|
696
|
+
|
697
|
+
for (let i = 0; i < 100; i++) {
|
698
|
+
this.encoder.encode('performance-test-data', 'base64url');
|
699
|
+
}
|
700
|
+
|
701
|
+
const duration = performance.now() - start;
|
702
|
+
|
703
|
+
if (duration > 1000) { // 1 second threshold
|
704
|
+
throw new Error(`Performance too slow: ${duration}ms`);
|
705
|
+
}
|
706
|
+
|
707
|
+
return `Performance acceptable: ${duration}ms for 100 operations`;
|
708
|
+
}
|
709
|
+
}
|
710
|
+
|
711
|
+
interface HealthStatus {
|
712
|
+
status: 'healthy' | 'unhealthy';
|
713
|
+
unit: string;
|
714
|
+
capabilities: string[];
|
715
|
+
checks: Array<{
|
716
|
+
test: string;
|
717
|
+
status: 'pass' | 'fail';
|
718
|
+
details: string;
|
719
|
+
}>;
|
720
|
+
timestamp: string;
|
721
|
+
}
|
722
|
+
```
|
723
|
+
|
724
|
+
---
|
725
|
+
|
726
|
+
## Summary
|
727
|
+
|
728
|
+
This manual demonstrates how the @synet/encoder unit scales from simple encoding operations to complex production systems. The Unit Architecture's consciousness-based design enables:
|
729
|
+
|
730
|
+
- **Composability** - Units learn from each other
|
731
|
+
- **Observability** - Built-in identity and capability reporting
|
732
|
+
- **Reliability** - Immutable design with comprehensive error handling
|
733
|
+
- **Scalability** - Stateless operations suitable for any deployment model
|
734
|
+
|
735
|
+
The encoder serves as a foundation for larger encoding/decoding ecosystems while maintaining its essential identity and purpose.
|