@olane/o-storage 0.7.2 → 0.7.4

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.
Files changed (2) hide show
  1. package/README.md +1008 -0
  2. package/package.json +8 -8
package/README.md CHANGED
@@ -0,0 +1,1008 @@
1
+ # o-storage
2
+
3
+ A unified storage application for Olane OS that provides multiple storage backends with a consistent interface.
4
+
5
+ **TL;DR**: Store, retrieve, and manage data across memory, disk, secure encrypted storage, and AI-powered placeholder storage using a simple key-value interface with `o://` addresses.
6
+
7
+ ## Quick Start {#quick-start}
8
+
9
+ ```bash
10
+ # Install
11
+ npm install @olane/o-storage
12
+ ```
13
+
14
+ ```typescript
15
+ // Basic usage with disk storage
16
+ import { StorageTool } from '@olane/o-storage';
17
+ import { oAddress } from '@olane/o-core';
18
+
19
+ // Initialize storage application
20
+ const storage = new StorageTool({
21
+ parent: null,
22
+ leader: leaderAddress
23
+ });
24
+ await storage.start();
25
+
26
+ // Store data
27
+ await leader.use(new oAddress('o://disk'), {
28
+ method: 'put',
29
+ params: {
30
+ key: 'user-config',
31
+ value: JSON.stringify({ theme: 'dark', lang: 'en' })
32
+ }
33
+ });
34
+
35
+ // Retrieve data
36
+ const result = await leader.use(new oAddress('o://disk/user-config'));
37
+ console.log(result.result.data);
38
+ // { value: '{"theme":"dark","lang":"en"}' }
39
+ ```
40
+
41
+ ## Overview {#overview}
42
+
43
+ `o-storage` is a **Level 3 Application** (multiple coordinated nodes) that provides a unified storage layer for Olane OS. It includes four specialized storage providers, each optimized for different use cases.
44
+
45
+ ### What it does
46
+
47
+ - **Stores data** with multiple backend options (memory, disk, encrypted, AI-powered)
48
+ - **Retrieves data** using `o://` addresses or explicit method calls
49
+ - **Manages data** with put, get, delete, and has operations
50
+ - **Intelligently summarizes** large documents with placeholder storage
51
+ - **Routes requests** automatically to the appropriate storage provider
52
+
53
+ ### Architecture
54
+
55
+ ```
56
+ ┌─────────────────────────────────────────────────────────┐
57
+ │ StorageTool (Application) │
58
+ │ o://storage │
59
+ │ • Routes requests to providers │
60
+ └─────────────────────────────────────────────────────────┘
61
+ ⬇ manages
62
+ ┌──────────────┬──────────────┬──────────────┬──────────────┐
63
+ ⬇ ⬇ ⬇ ⬇ ⬇
64
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐
65
+ │ Memory │ │ Disk │ │ Secure │ │ Placeholder │
66
+ │ o://mem │ │ o://disk │ │ o://sec │ │ o://placehldr│
67
+ │ Fast │ │ Persist │ │ Encrypt │ │ AI-Powered │
68
+ └──────────┘ └──────────┘ └──────────┘ └──────────────┘
69
+ ```
70
+
71
+ ## Storage Providers {#storage-providers}
72
+
73
+ ### Memory Storage (`o://memory`) {#memory-storage}
74
+
75
+ Fast, volatile storage for temporary data.
76
+
77
+ **Best for**: Caching, session data, temporary computations
78
+
79
+ **Characteristics**:
80
+ - ⚡ Fastest performance
81
+ - 💾 Lost on restart
82
+ - 🔓 No encryption
83
+ - 🎯 Simple key-value storage
84
+
85
+ ```typescript
86
+ // Store in memory
87
+ await leader.use(new oAddress('o://memory'), {
88
+ method: 'put',
89
+ params: {
90
+ key: 'session-token',
91
+ value: 'abc123xyz'
92
+ }
93
+ });
94
+
95
+ // Retrieve from memory
96
+ const result = await leader.use(new oAddress('o://memory/session-token'));
97
+ console.log(result.result.data.value); // 'abc123xyz'
98
+
99
+ // Check if exists
100
+ const exists = await leader.use(new oAddress('o://memory'), {
101
+ method: 'has',
102
+ params: { key: 'session-token' }
103
+ });
104
+ console.log(exists.result.data.success); // true
105
+
106
+ // Delete from memory
107
+ await leader.use(new oAddress('o://memory'), {
108
+ method: 'delete',
109
+ params: { key: 'session-token' }
110
+ });
111
+ ```
112
+
113
+ ---
114
+
115
+ ### Disk Storage (`o://disk`) {#disk-storage}
116
+
117
+ Persistent storage on the local filesystem.
118
+
119
+ **Best for**: Application state, configuration files, persistent data
120
+
121
+ **Characteristics**:
122
+ - 💾 Persists across restarts
123
+ - 📁 Stored in `~/.olane/storage/` by default
124
+ - 📝 JSON format with metadata
125
+ - 🔓 No encryption
126
+
127
+ ```typescript
128
+ // Store on disk
129
+ await leader.use(new oAddress('o://disk'), {
130
+ method: 'put',
131
+ params: {
132
+ key: 'app-settings',
133
+ value: JSON.stringify({
134
+ theme: 'dark',
135
+ notifications: true,
136
+ version: '1.0.0'
137
+ })
138
+ }
139
+ });
140
+
141
+ // Retrieve from disk
142
+ const result = await leader.use(new oAddress('o://disk/app-settings'));
143
+ const settings = JSON.parse(result.result.data.value);
144
+ console.log(settings);
145
+ // { theme: 'dark', notifications: true, version: '1.0.0' }
146
+
147
+ // Custom storage directory
148
+ const diskStorage = new DiskStorageProvider({
149
+ name: 'custom-disk',
150
+ leader: leaderAddress,
151
+ storageDir: '/custom/path/to/storage'
152
+ });
153
+ ```
154
+
155
+ ---
156
+
157
+ ### Secure Storage (`o://secure`) {#secure-storage}
158
+
159
+ Encrypted persistent storage using `o://encryption` service.
160
+
161
+ **Best for**: API keys, passwords, sensitive user data, credentials
162
+
163
+ **Characteristics**:
164
+ - 🔒 Encrypted at rest
165
+ - 💾 Persists across restarts
166
+ - 📁 Stored in `~/.olane/storage/`
167
+ - 🔐 Requires `o://encryption` node
168
+
169
+ ```typescript
170
+ // Store encrypted data
171
+ await leader.use(new oAddress('o://secure'), {
172
+ method: 'put',
173
+ params: {
174
+ key: 'api-credentials',
175
+ value: JSON.stringify({
176
+ apiKey: 'sk_live_xxxxxxxxxxxxx',
177
+ apiSecret: 'secret_xxxxxxxxxxxxx'
178
+ })
179
+ }
180
+ });
181
+
182
+ // Retrieve and decrypt automatically
183
+ const result = await leader.use(new oAddress('o://secure/api-credentials'));
184
+ const credentials = JSON.parse(result.result.data.value);
185
+ console.log(credentials);
186
+ // { apiKey: 'sk_live_xxxxxxxxxxxxx', apiSecret: 'secret_xxxxxxxxxxxxx' }
187
+ ```
188
+
189
+ **Note**: Secure storage requires the `o://encryption` node to be running. The encryption/decryption happens automatically during put/get operations.
190
+
191
+ ---
192
+
193
+ ### Placeholder Storage (`o://placeholder`) {#placeholder-storage}
194
+
195
+ AI-powered storage that summarizes large documents to save context window space.
196
+
197
+ **Best for**: Large files, documents, code files that need summarization
198
+
199
+ **Characteristics**:
200
+ - 🤖 AI-powered summarization
201
+ - 💡 Intent-aware summaries
202
+ - 📝 Returns summary + original
203
+ - 🎯 Reduces context window usage
204
+
205
+ ```typescript
206
+ // Store large document with intent
207
+ const largeDocument = `
208
+ [50,000 characters of code/documentation]
209
+ `;
210
+
211
+ const result = await leader.use(new oAddress('o://placeholder'), {
212
+ method: 'put',
213
+ params: {
214
+ key: 'large-codebase',
215
+ value: largeDocument,
216
+ intent: 'Find all API endpoints and their authentication requirements'
217
+ }
218
+ });
219
+
220
+ console.log(result);
221
+ // {
222
+ // value: "[original 50,000 character document]",
223
+ // intent: "Find all API endpoints...",
224
+ // summary: "This is a Node.js Express application with 15 API endpoints...",
225
+ // instructions: "To save on context window size, I have summarized...",
226
+ // address: "o://placeholder/large-codebase"
227
+ // }
228
+
229
+ // Later, retrieve the original if needed
230
+ const original = await leader.use(
231
+ new oAddress('o://placeholder/large-codebase')
232
+ );
233
+ ```
234
+
235
+ **How it works**:
236
+
237
+ 1. **Store with intent**: Provide optional `intent` parameter describing what you need from the document
238
+ 2. **AI summarizes**: Uses `o://intelligence` to create an intent-aligned summary
239
+ 3. **Returns both**: Get original value + summary + instructions
240
+ 4. **Reference address**: Use address in agents without re-uploading large content
241
+
242
+ **Use Case Example**:
243
+
244
+ ```typescript
245
+ // Agent needs to copy a large file
246
+ const fileContent = await fs.readFile('bigfile.txt', 'utf-8');
247
+
248
+ const stored = await leader.use(new oAddress('o://placeholder'), {
249
+ method: 'put',
250
+ params: {
251
+ key: 'source-file',
252
+ value: fileContent,
253
+ intent: 'Copy this file to a new location with a different name'
254
+ }
255
+ });
256
+
257
+ // Agent can now reference the summary instead of full content
258
+ // Summary: "This is a 50KB text file containing server configuration..."
259
+ // Agent knows it's a config file without loading all 50KB into context
260
+ ```
261
+
262
+ ## API Reference {#api-reference}
263
+
264
+ ### Storage Operations {#storage-operations}
265
+
266
+ All storage providers support these four core operations:
267
+
268
+ #### `put` {#put}
269
+
270
+ Store data under a key.
271
+
272
+ **Parameters**:
273
+ - `key` (string, required): Unique identifier for the data
274
+ - `value` (string, required): Data to store (serialize objects as JSON)
275
+ - `intent` (string, optional): Only for placeholder storage - describes what you need from the data
276
+
277
+ **Returns**:
278
+ ```typescript
279
+ {
280
+ success: boolean;
281
+ error?: string; // Only present if success is false
282
+ }
283
+ ```
284
+
285
+ **Example**:
286
+ ```typescript
287
+ const result = await leader.use(new oAddress('o://disk'), {
288
+ method: 'put',
289
+ params: {
290
+ key: 'user-123',
291
+ value: JSON.stringify({ name: 'Alice', email: 'alice@example.com' })
292
+ }
293
+ });
294
+ ```
295
+
296
+ ---
297
+
298
+ #### `get` {#get}
299
+
300
+ Retrieve data by key.
301
+
302
+ **Parameters**:
303
+ - `key` (string, required): Key to retrieve
304
+
305
+ **Returns**:
306
+ ```typescript
307
+ {
308
+ value: string | null; // null if key doesn't exist
309
+ }
310
+ ```
311
+
312
+ **Example**:
313
+ ```typescript
314
+ // Method 1: Address with key
315
+ const result = await leader.use(new oAddress('o://disk/user-123'));
316
+ console.log(result.result.data.value);
317
+
318
+ // Method 2: Explicit get method
319
+ const result2 = await leader.use(new oAddress('o://disk'), {
320
+ method: 'get',
321
+ params: { key: 'user-123' }
322
+ });
323
+ console.log(result2.result.data.value);
324
+ ```
325
+
326
+ ---
327
+
328
+ #### `delete` {#delete}
329
+
330
+ Remove data by key.
331
+
332
+ **Parameters**:
333
+ - `key` (string, required): Key to delete
334
+
335
+ **Returns**:
336
+ ```typescript
337
+ {
338
+ success: boolean;
339
+ error?: string;
340
+ }
341
+ ```
342
+
343
+ **Example**:
344
+ ```typescript
345
+ await leader.use(new oAddress('o://memory'), {
346
+ method: 'delete',
347
+ params: { key: 'temporary-data' }
348
+ });
349
+ ```
350
+
351
+ ---
352
+
353
+ #### `has` {#has}
354
+
355
+ Check if a key exists.
356
+
357
+ **Parameters**:
358
+ - `key` (string, required): Key to check
359
+
360
+ **Returns**:
361
+ ```typescript
362
+ {
363
+ success: boolean;
364
+ data?: boolean; // true if key exists, false otherwise
365
+ error?: string;
366
+ }
367
+ ```
368
+
369
+ **Example**:
370
+ ```typescript
371
+ const result = await leader.use(new oAddress('o://disk'), {
372
+ method: 'has',
373
+ params: { key: 'user-123' }
374
+ });
375
+
376
+ if (result.result.data.data) {
377
+ console.log('Key exists!');
378
+ }
379
+ ```
380
+
381
+ ## Storage Provider Classes {#storage-provider-classes}
382
+
383
+ ### `StorageTool` {#storagetool}
384
+
385
+ Main application class that manages all storage providers.
386
+
387
+ ```typescript
388
+ import { StorageTool } from '@olane/o-storage';
389
+
390
+ const storage = new StorageTool({
391
+ parent: parentAddress,
392
+ leader: leaderAddress
393
+ });
394
+
395
+ await storage.start();
396
+ // Automatically initializes:
397
+ // - o://memory (MemoryStorageProvider)
398
+ // - o://disk (DiskStorageProvider)
399
+ // - o://secure (SecureStorageProvider)
400
+ // - o://placeholder (PlaceholderTool)
401
+ ```
402
+
403
+ ---
404
+
405
+ ### `MemoryStorageProvider` {#memorystorageprovider}
406
+
407
+ In-memory storage provider.
408
+
409
+ ```typescript
410
+ import { MemoryStorageProvider } from '@olane/o-storage';
411
+ import { oAddress } from '@olane/o-core';
412
+
413
+ const memory = new MemoryStorageProvider({
414
+ name: 'custom-memory',
415
+ leader: leaderAddress,
416
+ address: new oAddress('o://custom-memory')
417
+ });
418
+
419
+ await memory.start();
420
+ ```
421
+
422
+ ---
423
+
424
+ ### `DiskStorageProvider` {#diskstorageprovider}
425
+
426
+ Filesystem-based storage provider.
427
+
428
+ **Configuration**:
429
+ ```typescript
430
+ interface DiskStorageConfig {
431
+ name: string;
432
+ leader: oAddress;
433
+ address?: oAddress;
434
+ storageDir?: string; // Default: ~/.olane/storage
435
+ }
436
+ ```
437
+
438
+ **Example**:
439
+ ```typescript
440
+ import { DiskStorageProvider } from '@olane/o-storage';
441
+
442
+ const disk = new DiskStorageProvider({
443
+ name: 'my-disk',
444
+ leader: leaderAddress,
445
+ storageDir: '/path/to/custom/storage'
446
+ });
447
+
448
+ await disk.start();
449
+ ```
450
+
451
+ **File Format**:
452
+ ```json
453
+ {
454
+ "value": "your-data-here",
455
+ "timestamp": "2024-10-06T12:00:00.000Z",
456
+ "key": "user-123"
457
+ }
458
+ ```
459
+
460
+ ---
461
+
462
+ ### `SecureStorageProvider` {#securestorageprovider}
463
+
464
+ Encrypted disk storage provider (extends `DiskStorageProvider`).
465
+
466
+ **Requirements**:
467
+ - Requires `o://encryption` node to be running
468
+ - Uses same configuration as `DiskStorageProvider`
469
+
470
+ ```typescript
471
+ import { SecureStorageProvider } from '@olane/o-storage';
472
+
473
+ const secure = new SecureStorageProvider({
474
+ name: 'secure-vault',
475
+ leader: leaderAddress,
476
+ storageDir: '/secure/path'
477
+ });
478
+
479
+ await secure.start();
480
+ ```
481
+
482
+ ---
483
+
484
+ ### `PlaceholderTool` {#placeholdertool}
485
+
486
+ AI-powered storage with summarization (extends `MemoryStorageProvider`).
487
+
488
+ **Requirements**:
489
+ - Requires `o://intelligence` node to be running
490
+ - Uses `o-lane` capability loop for AI processing
491
+
492
+ ```typescript
493
+ import { PlaceholderTool } from '@olane/o-storage';
494
+
495
+ const placeholder = new PlaceholderTool({
496
+ name: 'smart-storage',
497
+ leader: leaderAddress
498
+ });
499
+
500
+ await placeholder.start();
501
+ ```
502
+
503
+ ## Common Use Cases {#common-use-cases}
504
+
505
+ ### Use Case 1: Configuration Management {#config-management}
506
+
507
+ Store and retrieve application configuration.
508
+
509
+ ```typescript
510
+ // Store configuration
511
+ const config = {
512
+ theme: 'dark',
513
+ language: 'en',
514
+ features: {
515
+ betaFeatures: true,
516
+ analytics: false
517
+ }
518
+ };
519
+
520
+ await leader.use(new oAddress('o://disk'), {
521
+ method: 'put',
522
+ params: {
523
+ key: 'app-config',
524
+ value: JSON.stringify(config)
525
+ }
526
+ });
527
+
528
+ // Retrieve configuration
529
+ const result = await leader.use(new oAddress('o://disk/app-config'));
530
+ const loadedConfig = JSON.parse(result.result.data.value);
531
+
532
+ // Update configuration
533
+ loadedConfig.theme = 'light';
534
+ await leader.use(new oAddress('o://disk'), {
535
+ method: 'put',
536
+ params: {
537
+ key: 'app-config',
538
+ value: JSON.stringify(loadedConfig)
539
+ }
540
+ });
541
+ ```
542
+
543
+ ---
544
+
545
+ ### Use Case 2: Secure Credential Storage {#secure-credentials}
546
+
547
+ Store API keys and sensitive data encrypted.
548
+
549
+ ```typescript
550
+ // Store credentials securely
551
+ await leader.use(new oAddress('o://secure'), {
552
+ method: 'put',
553
+ params: {
554
+ key: 'stripe-keys',
555
+ value: JSON.stringify({
556
+ publishableKey: 'pk_live_xxxx',
557
+ secretKey: 'sk_live_xxxx',
558
+ webhookSecret: 'whsec_xxxx'
559
+ })
560
+ }
561
+ });
562
+
563
+ // Retrieve when needed (auto-decrypted)
564
+ const result = await leader.use(new oAddress('o://secure/stripe-keys'));
565
+ const keys = JSON.parse(result.result.data.value);
566
+
567
+ // Use in your application
568
+ const stripe = new Stripe(keys.secretKey);
569
+ ```
570
+
571
+ ---
572
+
573
+ ### Use Case 3: Caching with Memory Storage {#caching}
574
+
575
+ Fast temporary storage for computed values.
576
+
577
+ ```typescript
578
+ // Check cache first
579
+ const cached = await leader.use(new oAddress('o://memory'), {
580
+ method: 'has',
581
+ params: { key: 'expensive-computation' }
582
+ });
583
+
584
+ if (cached.result.data.data) {
585
+ // Use cached value
586
+ const result = await leader.use(
587
+ new oAddress('o://memory/expensive-computation')
588
+ );
589
+ return JSON.parse(result.result.data.value);
590
+ } else {
591
+ // Compute and cache
592
+ const computed = performExpensiveComputation();
593
+ await leader.use(new oAddress('o://memory'), {
594
+ method: 'put',
595
+ params: {
596
+ key: 'expensive-computation',
597
+ value: JSON.stringify(computed)
598
+ }
599
+ });
600
+ return computed;
601
+ }
602
+ ```
603
+
604
+ ---
605
+
606
+ ### Use Case 4: Large Document Processing {#large-documents}
607
+
608
+ Process large files with AI-powered summarization.
609
+
610
+ ```typescript
611
+ // Read large codebase file
612
+ const sourceCode = await fs.readFile('src/app.ts', 'utf-8');
613
+ // Assume sourceCode is 100KB
614
+
615
+ // Store with intent
616
+ const stored = await leader.use(new oAddress('o://placeholder'), {
617
+ method: 'put',
618
+ params: {
619
+ key: 'source-app',
620
+ value: sourceCode,
621
+ intent: 'Refactor the authentication logic to use JWT tokens'
622
+ }
623
+ });
624
+
625
+ console.log(stored.summary);
626
+ // "This TypeScript application uses Express.js with session-based authentication.
627
+ // The authentication logic is in the AuthController class (lines 45-123).
628
+ // Current implementation uses cookies and express-session middleware..."
629
+
630
+ // Agent can now work with summary instead of full 100KB
631
+ // Only retrieve full content if absolutely necessary
632
+ ```
633
+
634
+ ---
635
+
636
+ ### Use Case 5: Multi-Provider Data Management {#multi-provider}
637
+
638
+ Use different providers for different data types.
639
+
640
+ ```typescript
641
+ class DataManager {
642
+ constructor(private leader: oAddress) {}
643
+
644
+ // Temporary data -> Memory
645
+ async cacheSessionData(userId: string, data: any) {
646
+ await this.leader.use(new oAddress('o://memory'), {
647
+ method: 'put',
648
+ params: {
649
+ key: `session-${userId}`,
650
+ value: JSON.stringify(data)
651
+ }
652
+ });
653
+ }
654
+
655
+ // User preferences -> Disk
656
+ async saveUserPreferences(userId: string, prefs: any) {
657
+ await this.leader.use(new oAddress('o://disk'), {
658
+ method: 'put',
659
+ params: {
660
+ key: `prefs-${userId}`,
661
+ value: JSON.stringify(prefs)
662
+ }
663
+ });
664
+ }
665
+
666
+ // Credentials -> Secure
667
+ async saveUserCredentials(userId: string, credentials: any) {
668
+ await this.leader.use(new oAddress('o://secure'), {
669
+ method: 'put',
670
+ params: {
671
+ key: `creds-${userId}`,
672
+ value: JSON.stringify(credentials)
673
+ }
674
+ });
675
+ }
676
+
677
+ // Large documents -> Placeholder
678
+ async saveDocument(docId: string, content: string, intent: string) {
679
+ return await this.leader.use(new oAddress('o://placeholder'), {
680
+ method: 'put',
681
+ params: {
682
+ key: docId,
683
+ value: content,
684
+ intent
685
+ }
686
+ });
687
+ }
688
+ }
689
+ ```
690
+
691
+ ## Integration Examples {#integration-examples}
692
+
693
+ ### With o-node {#integration-o-node}
694
+
695
+ Use storage in a custom node.
696
+
697
+ ```typescript
698
+ import { oNodeTool } from '@olane/o-node';
699
+ import { oAddress } from '@olane/o-core';
700
+
701
+ class MyCustomNode extends oNodeTool {
702
+ async _tool_save_config(request: oRequest) {
703
+ const { configData } = request.params;
704
+
705
+ // Store configuration using disk storage
706
+ await this.use(new oAddress('o://disk'), {
707
+ method: 'put',
708
+ params: {
709
+ key: 'my-node-config',
710
+ value: JSON.stringify(configData)
711
+ }
712
+ });
713
+
714
+ return { success: true };
715
+ }
716
+
717
+ async _tool_load_config(request: oRequest) {
718
+ // Retrieve configuration
719
+ const result = await this.use(new oAddress('o://disk/my-node-config'));
720
+ return JSON.parse(result.result.data.value);
721
+ }
722
+ }
723
+ ```
724
+
725
+ ---
726
+
727
+ ### With o-lane {#integration-o-lane}
728
+
729
+ Use storage in an intelligent node.
730
+
731
+ ```typescript
732
+ import { oLaneTool } from '@olane/o-lane';
733
+ import { oAddress } from '@olane/o-core';
734
+
735
+ class IntelligentDataNode extends oLaneTool {
736
+ async _tool_analyze_document(request: oRequest) {
737
+ const { documentContent, analysisGoal } = request.params;
738
+
739
+ // Store document with intent using placeholder
740
+ const stored = await this.use(new oAddress('o://placeholder'), {
741
+ method: 'put',
742
+ params: {
743
+ key: `doc-${Date.now()}`,
744
+ value: documentContent,
745
+ intent: analysisGoal
746
+ }
747
+ });
748
+
749
+ // Return summary for further processing
750
+ return {
751
+ summary: stored.summary,
752
+ address: stored.address,
753
+ instructions: stored.instructions
754
+ };
755
+ }
756
+ }
757
+ ```
758
+
759
+ ---
760
+
761
+ ### Standalone Usage {#standalone-usage}
762
+
763
+ Use storage providers independently.
764
+
765
+ ```typescript
766
+ import { MemoryStorageProvider } from '@olane/o-storage';
767
+ import { oLeaderNode } from '@olane/o-leader';
768
+ import { oAddress } from '@olane/o-core';
769
+
770
+ // Setup
771
+ const leader = new oLeaderNode({
772
+ parent: null,
773
+ leader: null
774
+ });
775
+ await leader.start();
776
+
777
+ // Create standalone memory storage
778
+ const memory = new MemoryStorageProvider({
779
+ name: 'cache',
780
+ leader: leader.address
781
+ });
782
+ await memory.start();
783
+
784
+ // Use directly
785
+ await leader.use(new oAddress('o://memory'), {
786
+ method: 'put',
787
+ params: { key: 'test', value: 'data' }
788
+ });
789
+
790
+ const result = await leader.use(new oAddress('o://memory/test'));
791
+ console.log(result.result.data.value); // 'data'
792
+ ```
793
+
794
+ ## Troubleshooting {#troubleshooting}
795
+
796
+ ### Error: "Failed to store data: EACCES: permission denied" {#error-eacces}
797
+
798
+ **Problem**: Disk storage can't write to storage directory.
799
+
800
+ **Solution**:
801
+ ```bash
802
+ # Check permissions on default storage directory
803
+ ls -la ~/.olane/
804
+
805
+ # Fix permissions
806
+ chmod 755 ~/.olane
807
+ chmod 755 ~/.olane/storage
808
+
809
+ # Or specify custom directory with write permissions
810
+ const disk = new DiskStorageProvider({
811
+ name: 'disk',
812
+ leader: leaderAddress,
813
+ storageDir: '/path/with/write/permissions'
814
+ });
815
+ ```
816
+
817
+ ---
818
+
819
+ ### Error: "Cannot find node with address o://encryption" {#error-no-encryption}
820
+
821
+ **Problem**: Secure storage requires `o://encryption` node.
822
+
823
+ **Solution**:
824
+ ```typescript
825
+ // Ensure encryption node is running before using secure storage
826
+ import { EncryptionTool } from '@olane/o-encryption';
827
+
828
+ const encryption = new EncryptionTool({
829
+ parent: leaderAddress,
830
+ leader: leaderAddress
831
+ });
832
+ await encryption.start();
833
+
834
+ // Now secure storage will work
835
+ const result = await leader.use(new oAddress('o://secure'), {
836
+ method: 'put',
837
+ params: { key: 'secret', value: 'data' }
838
+ });
839
+ ```
840
+
841
+ ---
842
+
843
+ ### Error: "Cannot find node with address o://intelligence" {#error-no-intelligence}
844
+
845
+ **Problem**: Placeholder storage requires `o://intelligence` node.
846
+
847
+ **Solution**:
848
+ ```typescript
849
+ // Ensure intelligence node is running before using placeholder storage
850
+ import { IntelligenceTool } from '@olane/o-intelligence';
851
+
852
+ const intelligence = new IntelligenceTool({
853
+ parent: leaderAddress,
854
+ leader: leaderAddress
855
+ });
856
+ await intelligence.start();
857
+
858
+ // Now placeholder storage will work
859
+ const result = await leader.use(new oAddress('o://placeholder'), {
860
+ method: 'put',
861
+ params: {
862
+ key: 'doc',
863
+ value: largeDocument,
864
+ intent: 'Summarize key points'
865
+ }
866
+ });
867
+ ```
868
+
869
+ ---
870
+
871
+ ### Issue: Memory storage data lost on restart {#memory-data-lost}
872
+
873
+ **Problem**: Data stored in memory storage disappears after restart.
874
+
875
+ **Solution**: This is expected behavior. Memory storage is volatile.
876
+
877
+ ```typescript
878
+ // For persistent data, use disk storage instead
879
+ await leader.use(new oAddress('o://disk'), {
880
+ method: 'put',
881
+ params: { key: 'persistent-data', value: data }
882
+ });
883
+
884
+ // Or implement your own persistence pattern
885
+ class PersistentCache {
886
+ async set(key: string, value: string) {
887
+ // Store in memory for speed
888
+ await leader.use(new oAddress('o://memory'), {
889
+ method: 'put',
890
+ params: { key, value }
891
+ });
892
+
893
+ // Also persist to disk
894
+ await leader.use(new oAddress('o://disk'), {
895
+ method: 'put',
896
+ params: { key: `cache-${key}`, value }
897
+ });
898
+ }
899
+
900
+ async get(key: string) {
901
+ // Try memory first
902
+ const memResult = await leader.use(new oAddress('o://memory'), {
903
+ method: 'has',
904
+ params: { key }
905
+ });
906
+
907
+ if (memResult.result.data.data) {
908
+ return await leader.use(new oAddress('o://memory/') + key);
909
+ }
910
+
911
+ // Fall back to disk
912
+ return await leader.use(new oAddress('o://disk/cache-') + key);
913
+ }
914
+ }
915
+ ```
916
+
917
+ ---
918
+
919
+ ### Issue: Placeholder storage using too many tokens {#placeholder-tokens}
920
+
921
+ **Problem**: AI summarization costs too many tokens for large documents.
922
+
923
+ **Solution**: Documents are truncated to 50,000 characters automatically.
924
+
925
+ ```typescript
926
+ // For very large documents, pre-process them
927
+ const largeDoc = await fs.readFile('huge-file.txt', 'utf-8');
928
+
929
+ if (largeDoc.length > 50000) {
930
+ // Option 1: Store relevant section only
931
+ const relevantSection = extractRelevantSection(largeDoc);
932
+ await leader.use(new oAddress('o://placeholder'), {
933
+ method: 'put',
934
+ params: {
935
+ key: 'doc-section',
936
+ value: relevantSection,
937
+ intent: 'Find API endpoints'
938
+ }
939
+ });
940
+
941
+ // Option 2: Use regular disk storage for full content
942
+ await leader.use(new oAddress('o://disk'), {
943
+ method: 'put',
944
+ params: {
945
+ key: 'full-doc',
946
+ value: largeDoc
947
+ }
948
+ });
949
+
950
+ // Store summary separately
951
+ const summary = manualSummary(largeDoc);
952
+ await leader.use(new oAddress('o://memory'), {
953
+ method: 'put',
954
+ params: {
955
+ key: 'doc-summary',
956
+ value: summary
957
+ }
958
+ });
959
+ }
960
+ ```
961
+
962
+ ## Package Information {#package-info}
963
+
964
+ **Package Name**: `@olane/o-storage`
965
+ **Version**: 0.7.2
966
+ **License**: ISC
967
+ **Repository**: [github.com/olane-labs/olane](https://github.com/olane-labs/olane)
968
+
969
+ ### Dependencies {#dependencies}
970
+
971
+ **Peer Dependencies** (required):
972
+ - `@olane/o-core` - Core types and utilities
973
+ - `@olane/o-protocol` - Protocol definitions
974
+ - `@olane/o-tool` - Tool base classes
975
+ - `@olane/o-node` - Node functionality
976
+ - `@olane/o-lane` - Intelligence capabilities
977
+ - `@olane/o-config` - Configuration management
978
+
979
+ **Optional Runtime Dependencies**:
980
+ - `@olane/o-encryption` - Required for `SecureStorageProvider`
981
+ - `@olane/o-intelligence` - Required for `PlaceholderTool`
982
+
983
+ ### Installation {#installation}
984
+
985
+ ```bash
986
+ # Install storage package
987
+ npm install @olane/o-storage
988
+
989
+ # Install peer dependencies
990
+ npm install @olane/o-core @olane/o-protocol @olane/o-tool @olane/o-node @olane/o-lane @olane/o-config
991
+
992
+ # Optional: For secure storage
993
+ npm install @olane/o-encryption
994
+
995
+ # Optional: For placeholder storage
996
+ npm install @olane/o-intelligence
997
+ ```
998
+
999
+ ## Related {#related}
1000
+
1001
+ - **Package**: [o-core](/packages/o-core) - Core addressing and request types
1002
+ - **Package**: [o-node](/packages/o-node) - Node creation and management
1003
+ - **Package**: [o-lane](/packages/o-lane) - Intelligence and capability loops
1004
+ - **Package**: [o-leader](/packages/o-leader) - Service discovery and coordination
1005
+ - **Package**: [o-intelligence](/packages/o-intelligence) - AI integration for placeholder storage
1006
+ - **Concept**: [Tools, Nodes, and Applications](/concepts/tools-nodes-applications) - Understanding architectural levels
1007
+ - **Guide**: [Building Applications](/concepts/applications) - Multi-node coordination patterns
1008
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-storage",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "url": "git+https://github.com/olane-labs/olane.git"
34
34
  },
35
35
  "author": "oLane Inc.",
36
- "license": "ISC",
36
+ "license": "(MIT OR Apache-2.0)",
37
37
  "description": "oLane storage tool",
38
38
  "devDependencies": {
39
39
  "@eslint/eslintrc": "^3.3.1",
@@ -56,12 +56,12 @@
56
56
  "typescript": "5.4.5"
57
57
  },
58
58
  "peerDependencies": {
59
- "@olane/o-config": "^0.7.1",
60
- "@olane/o-core": "^0.7.1",
61
- "@olane/o-lane": "^0.7.1",
62
- "@olane/o-node": "^0.7.1",
63
- "@olane/o-protocol": "^0.7.1",
64
- "@olane/o-tool": "^0.7.1"
59
+ "@olane/o-config": "^0.7.3",
60
+ "@olane/o-core": "^0.7.3",
61
+ "@olane/o-lane": "^0.7.3",
62
+ "@olane/o-node": "^0.7.3",
63
+ "@olane/o-protocol": "^0.7.3",
64
+ "@olane/o-tool": "^0.7.3"
65
65
  },
66
66
  "dependencies": {
67
67
  "debug": "^4.4.1",