@olane/o-storage 0.8.2 → 0.8.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 +169 -37
  2. package/package.json +7 -7
package/README.md CHANGED
@@ -8,7 +8,7 @@ A unified storage application for Olane OS that provides multiple storage backen
8
8
 
9
9
  ```bash
10
10
  # Install
11
- npm install @olane/o-storage
11
+ pnpm install @olane/o-storage
12
12
  ```
13
13
 
14
14
  ```typescript
@@ -40,7 +40,7 @@ console.log(result.result.data);
40
40
 
41
41
  ## Overview {#overview}
42
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.
43
+ `o-storage` is a **Level 3 Application** (multiple coordinated nodes) that provides a unified storage layer for Olane OS. It includes five specialized storage providers, each optimized for different use cases.
44
44
 
45
45
  ### What it does
46
46
 
@@ -53,21 +53,24 @@ console.log(result.result.data);
53
53
  ### Architecture
54
54
 
55
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
- └──────────┘ └──────────┘ └──────────┘ └──────────────┘
56
+ ┌──────────────────────────────────────────────────────────────────────┐
57
+ │ StorageTool (Application)
58
+ │ o://storage
59
+ │ • Routes requests to providers
60
+ └──────────────────────────────────────────────────────────────────────┘
61
+ ⬇ manages
62
+ ┌─────────────┬─────────────┬─────────────┬──────────────┬─────────────┐
63
+ ⬇ ⬇
64
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ ┌─────────────┐
65
+ │ Memory │ │ Disk │ │ Secure │ │ Placeholder │ OS Config │
66
+ │ o:// │ o://disk │ │ o:// │ o:// │ o:// │
67
+ memory secure │ │ placeholder │ os-config
68
+ │ Fast │ │ Persist │ │ Encrypt │ │ AI-Powered │ │ OS Settings │
69
+ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ └─────────────┘
69
70
  ```
70
71
 
72
+ Each child node uses a simple `o://` address (e.g., `new oAddress('o://disk')`) with `parent: this.address` set to `o://storage`. The system creates nested address paths during registration. See the [CLAUDE.md](../../CLAUDE.md) guide for details on address construction patterns.
73
+
71
74
  ## Storage Providers {#storage-providers}
72
75
 
73
76
  ### Memory Storage (`o://memory`) {#memory-storage}
@@ -101,7 +104,7 @@ const exists = await leader.use(new oAddress('o://memory'), {
101
104
  method: 'has',
102
105
  params: { key: 'session-token' }
103
106
  });
104
- console.log(exists.result.data.success); // true
107
+ console.log(exists.result.data); // true
105
108
 
106
109
  // Delete from memory
107
110
  await leader.use(new oAddress('o://memory'), {
@@ -217,7 +220,7 @@ const result = await leader.use(new oAddress('o://placeholder'), {
217
220
  }
218
221
  });
219
222
 
220
- console.log(result);
223
+ console.log(result.result.data);
221
224
  // {
222
225
  // value: "[original 50,000 character document]",
223
226
  // intent: "Find all API endpoints...",
@@ -357,12 +360,10 @@ Check if a key exists.
357
360
  **Parameters**:
358
361
  - `key` (string, required): Key to check
359
362
 
360
- **Returns**:
363
+ **Returns**:
361
364
  ```typescript
362
365
  {
363
- success: boolean;
364
- data?: boolean; // true if key exists, false otherwise
365
- error?: string;
366
+ exists: boolean; // true if key exists, false otherwise
366
367
  }
367
368
  ```
368
369
 
@@ -373,7 +374,7 @@ const result = await leader.use(new oAddress('o://disk'), {
373
374
  params: { key: 'user-123' }
374
375
  });
375
376
 
376
- if (result.result.data.data) {
377
+ if (result.result.data.exists) {
377
378
  console.log('Key exists!');
378
379
  }
379
380
  ```
@@ -398,6 +399,7 @@ await storage.start();
398
399
  // - o://disk (DiskStorageProvider)
399
400
  // - o://secure (SecureStorageProvider)
400
401
  // - o://placeholder (PlaceholderTool)
402
+ // - o://os-config (OSConfigStorageTool)
401
403
  ```
402
404
 
403
405
  ---
@@ -500,6 +502,81 @@ const placeholder = new PlaceholderTool({
500
502
  await placeholder.start();
501
503
  ```
502
504
 
505
+ ### `OSConfigStorageTool` (`o://os-config`) {#osconfigstoragetool}
506
+
507
+ OS instance configuration storage that delegates to a configurable storage backend.
508
+
509
+ **Best for**: OS instance configuration, lane management, metadata tracking
510
+
511
+ **Characteristics**:
512
+ - Delegates to `o://disk` or `o://memory` (configurable)
513
+ - Manages OS instance configurations with key prefix `os-config:`
514
+ - Supports lane CID management for OS startup configuration
515
+ - Supports metadata storage per OS instance
516
+
517
+ **Configuration**:
518
+ ```typescript
519
+ interface OSConfigStorageConfig {
520
+ storageBackend?: 'disk' | 'memory' | string; // Default: 'disk'
521
+ }
522
+ ```
523
+
524
+ Can also be configured via the `OS_CONFIG_STORAGE` environment variable.
525
+
526
+ **Methods:**
527
+
528
+ | Method | Parameters | Description |
529
+ |--------|-----------|-------------|
530
+ | `save_config` | `osName` (string), `config` (object) | Save OS instance configuration |
531
+ | `load_config` | `osName` (string) | Load OS instance configuration |
532
+ | `list_configs` | (none) | List all OS instance configurations |
533
+ | `delete_config` | `osName` (string) | Delete OS instance configuration |
534
+ | `add_lane_to_config` | `osName` (string), `cid` (string) | Add a lane CID to OS startup config |
535
+ | `remove_lane_from_config` | `osName` (string), `cid` (string) | Remove a lane CID from OS startup config |
536
+ | `get_lanes` | `osName` (string) | Get all lane CIDs for an OS instance |
537
+ | `update_metadata` | `osName` (string), `metadata` (object) | Update metadata for an OS instance |
538
+ | `get_metadata` | `osName` (string) | Get metadata for an OS instance |
539
+
540
+ **Example:**
541
+ ```typescript
542
+ // Save OS configuration
543
+ await leader.use(new oAddress('o://os-config'), {
544
+ method: 'save_config',
545
+ params: {
546
+ osName: 'my-os-instance',
547
+ config: {
548
+ oNetworkConfig: { lanes: [] },
549
+ metadata: { createdAt: Date.now() }
550
+ }
551
+ }
552
+ });
553
+
554
+ // Add a lane to the OS instance
555
+ await leader.use(new oAddress('o://os-config'), {
556
+ method: 'add_lane_to_config',
557
+ params: {
558
+ osName: 'my-os-instance',
559
+ cid: 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi'
560
+ }
561
+ });
562
+
563
+ // Get lanes for an OS instance
564
+ const result = await leader.use(new oAddress('o://os-config'), {
565
+ method: 'get_lanes',
566
+ params: { osName: 'my-os-instance' }
567
+ });
568
+ console.log(result.result.data.lanes);
569
+
570
+ // Load configuration
571
+ const config = await leader.use(new oAddress('o://os-config'), {
572
+ method: 'load_config',
573
+ params: { osName: 'my-os-instance' }
574
+ });
575
+ console.log(config.result.data);
576
+ ```
577
+
578
+ ---
579
+
503
580
  ## Common Use Cases {#common-use-cases}
504
581
 
505
582
  ### Use Case 1: Configuration Management {#config-management}
@@ -581,7 +658,7 @@ const cached = await leader.use(new oAddress('o://memory'), {
581
658
  params: { key: 'expensive-computation' }
582
659
  });
583
660
 
584
- if (cached.result.data.data) {
661
+ if (cached.result.data.exists) {
585
662
  // Use cached value
586
663
  const result = await leader.use(
587
664
  new oAddress('o://memory/expensive-computation')
@@ -613,7 +690,7 @@ const sourceCode = await fs.readFile('src/app.ts', 'utf-8');
613
690
  // Assume sourceCode is 100KB
614
691
 
615
692
  // Store with intent
616
- const stored = await leader.use(new oAddress('o://placeholder'), {
693
+ const response = await leader.use(new oAddress('o://placeholder'), {
617
694
  method: 'put',
618
695
  params: {
619
696
  key: 'source-app',
@@ -622,6 +699,7 @@ const stored = await leader.use(new oAddress('o://placeholder'), {
622
699
  }
623
700
  });
624
701
 
702
+ const stored = response.result.data;
625
703
  console.log(stored.summary);
626
704
  // "This TypeScript application uses Express.js with session-based authentication.
627
705
  // The authentication logic is in the AuthController class (lines 45-123).
@@ -701,22 +779,32 @@ import { oAddress } from '@olane/o-core';
701
779
  class MyCustomNode extends oNodeTool {
702
780
  async _tool_save_config(request: oRequest) {
703
781
  const { configData } = request.params;
704
-
782
+
705
783
  // Store configuration using disk storage
706
- await this.use(new oAddress('o://disk'), {
784
+ const response = await this.use(new oAddress('o://disk'), {
707
785
  method: 'put',
708
786
  params: {
709
787
  key: 'my-node-config',
710
788
  value: JSON.stringify(configData)
711
789
  }
712
790
  });
713
-
714
- return { success: true };
791
+
792
+ if (!response.result.success) {
793
+ throw new Error(`Failed to save config: ${response.result.error}`);
794
+ }
795
+
796
+ // Return raw data - base class wraps it
797
+ return { saved: true };
715
798
  }
716
799
 
717
800
  async _tool_load_config(request: oRequest) {
718
- // Retrieve configuration
801
+ // Retrieve configuration (response.result.data contains the storage value)
719
802
  const result = await this.use(new oAddress('o://disk/my-node-config'));
803
+
804
+ if (!result.result.success) {
805
+ throw new Error(`Failed to load config: ${result.result.error}`);
806
+ }
807
+
720
808
  return JSON.parse(result.result.data.value);
721
809
  }
722
810
  }
@@ -735,9 +823,9 @@ import { oAddress } from '@olane/o-core';
735
823
  class IntelligentDataNode extends oLaneTool {
736
824
  async _tool_analyze_document(request: oRequest) {
737
825
  const { documentContent, analysisGoal } = request.params;
738
-
826
+
739
827
  // Store document with intent using placeholder
740
- const stored = await this.use(new oAddress('o://placeholder'), {
828
+ const response = await this.use(new oAddress('o://placeholder'), {
741
829
  method: 'put',
742
830
  params: {
743
831
  key: `doc-${Date.now()}`,
@@ -745,7 +833,13 @@ class IntelligentDataNode extends oLaneTool {
745
833
  intent: analysisGoal
746
834
  }
747
835
  });
748
-
836
+
837
+ if (!response.result.success) {
838
+ throw new Error(`Failed to store document: ${response.result.error}`);
839
+ }
840
+
841
+ const stored = response.result.data;
842
+
749
843
  // Return summary for further processing
750
844
  return {
751
845
  summary: stored.summary,
@@ -791,6 +885,44 @@ const result = await leader.use(new oAddress('o://memory/test'));
791
885
  console.log(result.result.data.value); // 'data'
792
886
  ```
793
887
 
888
+ ## Response Structure {#response-structure}
889
+
890
+ When calling storage methods via `node.use()`, responses follow the standard Olane response pattern:
891
+
892
+ ```typescript
893
+ const response = await leader.use(new oAddress('o://disk'), {
894
+ method: 'put',
895
+ params: { key: 'my-key', value: 'my-value' }
896
+ });
897
+
898
+ // Always access data via response.result
899
+ if (response.result.success) {
900
+ const data = response.result.data;
901
+ console.log(data); // { success: true } for put operations
902
+ } else {
903
+ console.error(response.result.error);
904
+ }
905
+
906
+ // For get operations:
907
+ const getResponse = await leader.use(new oAddress('o://disk/my-key'));
908
+ if (getResponse.result.success) {
909
+ console.log(getResponse.result.data.value); // 'my-value'
910
+ }
911
+
912
+ // Full response shape:
913
+ // {
914
+ // jsonrpc: "2.0",
915
+ // id: "request-id",
916
+ // result: {
917
+ // success: boolean,
918
+ // data: any, // Present on success
919
+ // error?: string // Present on failure
920
+ // }
921
+ // }
922
+ ```
923
+
924
+ > **Important**: Always check `response.result.success` before accessing `response.result.data`. Do not access `response.success` or `response.data` directly -- these properties do not exist at the top level of the response object.
925
+
794
926
  ## Troubleshooting {#troubleshooting}
795
927
 
796
928
  ### Error: "Failed to store data: EACCES: permission denied" {#error-eacces}
@@ -904,7 +1036,7 @@ class PersistentCache {
904
1036
  params: { key }
905
1037
  });
906
1038
 
907
- if (memResult.result.data.data) {
1039
+ if (memResult.result.data.exists) {
908
1040
  return await leader.use(new oAddress('o://memory/') + key);
909
1041
  }
910
1042
 
@@ -984,16 +1116,16 @@ if (largeDoc.length > 50000) {
984
1116
 
985
1117
  ```bash
986
1118
  # Install storage package
987
- npm install @olane/o-storage
1119
+ pnpm add @olane/o-storage
988
1120
 
989
1121
  # Install peer dependencies
990
- npm install @olane/o-core @olane/o-protocol @olane/o-tool @olane/o-node @olane/o-lane @olane/o-config
1122
+ pnpm add @olane/o-core @olane/o-protocol @olane/o-tool @olane/o-node @olane/o-lane @olane/o-config
991
1123
 
992
1124
  # Optional: For secure storage
993
- npm install @olane/o-encryption
1125
+ pnpm add @olane/o-encryption
994
1126
 
995
1127
  # Optional: For placeholder storage
996
- npm install @olane/o-intelligence
1128
+ pnpm add @olane/o-intelligence
997
1129
  ```
998
1130
 
999
1131
  ## Related {#related}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@olane/o-storage",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "type": "module",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -54,13 +54,13 @@
54
54
  "typescript": "5.4.5"
55
55
  },
56
56
  "dependencies": {
57
- "@olane/o-config": "0.8.2",
58
- "@olane/o-core": "0.8.2",
59
- "@olane/o-node": "0.8.2",
60
- "@olane/o-protocol": "0.8.2",
61
- "@olane/o-tool": "0.8.2",
57
+ "@olane/o-config": "0.8.4",
58
+ "@olane/o-core": "0.8.4",
59
+ "@olane/o-node": "0.8.4",
60
+ "@olane/o-protocol": "0.8.4",
61
+ "@olane/o-tool": "0.8.4",
62
62
  "debug": "^4.4.1",
63
63
  "dotenv": "^16.5.0"
64
64
  },
65
- "gitHead": "9e35c874d849d051bcffe483fd2a8c2b3ecf68cc"
65
+ "gitHead": "b53623b1ad4365133911722f80d5597a72b65bf2"
66
66
  }