@wovin/storage-fs 0.0.25 → 0.1.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/README.md +91 -91
- package/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@ Persists wovin threads (applogs/blocks) to the local filesystem.
|
|
|
6
6
|
|
|
7
7
|
## Features
|
|
8
8
|
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
9
|
+
- **Applog storage** - Store and retrieve applogs by CID
|
|
10
|
+
- **Thread management** - Track which applogs belong to which threads (many-to-many)
|
|
11
|
+
- **Block storage** - Store raw bytes (for binary content referenced by applogs)
|
|
12
|
+
- **Deduplication** - Applogs stored once, referenced by multiple threads
|
|
12
13
|
- **ACID transactions** - Atomic writes via LMDB transactions
|
|
13
|
-
- **Built on LMDB** - Leverages Lightning Memory-Mapped Database for reliability
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -20,150 +20,150 @@ pnpm add @wovin/storage-fs
|
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
23
|
-
### Basic
|
|
23
|
+
### Basic Example
|
|
24
24
|
|
|
25
25
|
```typescript
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
26
|
+
import { StorageFs } from '@wovin/storage-fs'
|
|
27
|
+
import type { Applog } from '@wovin/core/applog'
|
|
28
28
|
|
|
29
|
-
// Initialize
|
|
30
|
-
const
|
|
29
|
+
// Initialize storage
|
|
30
|
+
const storage = await StorageFs.init('./data/wovin-storage')
|
|
31
31
|
|
|
32
|
-
// Create
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// Create applogs (CID must be pre-computed)
|
|
33
|
+
const applogs: Applog[] = [
|
|
34
|
+
{ cid: 'bafyrei...', en: 'entity-1', at: 'text', vl: 'Hello', ts: '2024-01-01T00:00:00Z', ag: 'alice', pv: null },
|
|
35
|
+
{ cid: 'bafyrei...', en: 'entity-1', at: 'text', vl: 'World', ts: '2024-01-01T00:00:01Z', ag: 'alice', pv: null },
|
|
36
|
+
]
|
|
36
37
|
|
|
37
|
-
// Store
|
|
38
|
-
const
|
|
39
|
-
console.log(
|
|
38
|
+
// Store applogs in a thread
|
|
39
|
+
const stored = await storage.storeApplogs('my-thread', applogs)
|
|
40
|
+
console.log(`Stored ${stored} new applogs`)
|
|
40
41
|
|
|
41
|
-
//
|
|
42
|
-
|
|
42
|
+
// Retrieve applogs from thread
|
|
43
|
+
const retrieved = storage.getApplogs('my-thread')
|
|
43
44
|
|
|
44
|
-
//
|
|
45
|
-
const
|
|
45
|
+
// Get specific applog by CID
|
|
46
|
+
const applog = storage.getApplogByCid('bafyrei...')
|
|
46
47
|
|
|
47
|
-
//
|
|
48
|
-
|
|
48
|
+
// Check membership
|
|
49
|
+
storage.isApplogInThread('my-thread', 'bafyrei...') // true
|
|
49
50
|
|
|
50
51
|
// Clean up
|
|
51
|
-
|
|
52
|
+
storage.close()
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
### Thread
|
|
55
|
+
### Multi-Thread Example
|
|
56
|
+
|
|
57
|
+
Applogs are deduplicated - the same applog can exist in multiple threads:
|
|
55
58
|
|
|
56
59
|
```typescript
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
import { ThreadInMemory } from '@wovin/core/thread'
|
|
60
|
+
// Store in first thread
|
|
61
|
+
await storage.storeApplogs('thread-a', [applog1, applog2])
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
// Store same applogs in second thread (no duplication)
|
|
64
|
+
await storage.storeApplogs('thread-b', [applog1, applog2])
|
|
62
65
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{ ag: 'alice', en: 'thread-123', at: 'text', vl: 'World' },
|
|
67
|
-
]
|
|
66
|
+
// Applog exists in both threads
|
|
67
|
+
storage.isApplogInThread('thread-a', applog1.cid) // true
|
|
68
|
+
storage.isApplogInThread('thread-b', applog1.cid) // true
|
|
68
69
|
|
|
69
|
-
//
|
|
70
|
-
|
|
70
|
+
// Delete thread-b (applogs remain, still in thread-a)
|
|
71
|
+
await storage.deleteThread('thread-b')
|
|
72
|
+
storage.hasApplog(applog1.cid) // still true
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Block Storage
|
|
71
76
|
|
|
72
|
-
|
|
73
|
-
const snapshotRoot = blocks[0]
|
|
74
|
-
const snapshotCar = await makeCarBlob(snapshotRoot.cid, blocks)
|
|
77
|
+
For binary content referenced by applogs:
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
|
|
79
|
+
```typescript
|
|
80
|
+
// Store a block
|
|
81
|
+
await storage.storeBlock('bafyrei...', new Uint8Array([1, 2, 3, 4]))
|
|
78
82
|
|
|
79
|
-
//
|
|
80
|
-
const
|
|
81
|
-
// Use CarReader to decode applogs...
|
|
83
|
+
// Retrieve block
|
|
84
|
+
const bytes = storage.getBlock('bafyrei...')
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
// Check existence
|
|
87
|
+
storage.hasBlock('bafyrei...')
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
## API
|
|
87
91
|
|
|
88
|
-
###
|
|
92
|
+
### Initialization
|
|
89
93
|
|
|
90
|
-
|
|
94
|
+
#### `StorageFs.init(path: string): Promise<StorageFs>`
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
- `path` - Filesystem path where LMDB data will be stored
|
|
96
|
+
Initialize storage at the specified path.
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
### Applog Methods
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
#### `storeApplogs(threadId: string, applogs: Applog[]): Promise<number>`
|
|
98
101
|
|
|
99
|
-
Store
|
|
102
|
+
Store applogs in a thread. Returns count of newly stored applogs (excludes duplicates).
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
- `car` - CAR file as Blob
|
|
104
|
+
#### `getApplogs(threadId: string): Applog[]`
|
|
103
105
|
|
|
104
|
-
|
|
106
|
+
Get all applogs in a thread.
|
|
105
107
|
|
|
106
|
-
|
|
108
|
+
#### `getApplogByCid(cid: CID | string): Applog | null`
|
|
107
109
|
|
|
108
|
-
|
|
110
|
+
Get a specific applog by CID.
|
|
109
111
|
|
|
110
|
-
|
|
111
|
-
- `cid` - The CID to retrieve
|
|
112
|
+
#### `hasApplog(cid: CID | string): boolean`
|
|
112
113
|
|
|
113
|
-
|
|
114
|
+
Check if an applog exists.
|
|
114
115
|
|
|
115
|
-
###
|
|
116
|
+
### Block Methods
|
|
116
117
|
|
|
117
|
-
|
|
118
|
+
#### `storeBlock(cid: CID | string, bytes: Uint8Array): Promise<void>`
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
- `cid` - The CID to retrieve
|
|
120
|
+
Store raw bytes by CID.
|
|
121
121
|
|
|
122
|
-
|
|
122
|
+
#### `getBlock(cid: CID | string): Uint8Array | null`
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
Get block bytes by CID.
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
#### `hasBlock(cid: CID | string): boolean`
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
- `cid` - The CID to check
|
|
128
|
+
Check if a block exists.
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
### Thread Methods
|
|
132
131
|
|
|
133
|
-
|
|
132
|
+
#### `listThreads(): string[]`
|
|
134
133
|
|
|
135
|
-
|
|
134
|
+
List all thread IDs.
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
#### `deleteThread(threadId: string): Promise<void>`
|
|
138
137
|
|
|
139
|
-
|
|
138
|
+
Delete a thread (removes membership, keeps applogs).
|
|
140
139
|
|
|
141
|
-
|
|
142
|
-
- **ACID** - Atomic, consistent, isolated, durable transactions
|
|
143
|
-
- **Single file** - Stores entire database in one file
|
|
144
|
-
- **Cross-process** - Shared memory allows multiple processes to access simultaneously
|
|
145
|
-
- **Compression** - Optional compression for small values
|
|
140
|
+
#### `getThreadApplogCount(threadId: string): number`
|
|
146
141
|
|
|
147
|
-
|
|
142
|
+
Get count of applogs in a thread.
|
|
148
143
|
|
|
149
|
-
|
|
150
|
-
- ✅ Desktop/Electron apps
|
|
151
|
-
- ✅ Node.js servers with persistent storage
|
|
152
|
-
- ✅ Testing and integration tests
|
|
153
|
-
- ✅ Offline-first applications
|
|
144
|
+
#### `isApplogInThread(threadId: string, cid: CID | string): boolean`
|
|
154
145
|
|
|
155
|
-
|
|
146
|
+
Check if an applog is in a thread.
|
|
156
147
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
148
|
+
### Utilities
|
|
149
|
+
|
|
150
|
+
#### `close(): void`
|
|
151
|
+
|
|
152
|
+
Close the storage and release resources.
|
|
153
|
+
|
|
154
|
+
## LMDB Structure
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
storage-fs/data.mdb
|
|
158
|
+
├── applogs # cidString → Applog JSON
|
|
159
|
+
├── thread_index # threadId → [cidString...] (dupSort)
|
|
160
|
+
└── blocks # cidString → Uint8Array
|
|
161
|
+
```
|
|
160
162
|
|
|
161
163
|
## Related Packages
|
|
162
164
|
|
|
163
165
|
- [`@wovin/core`](../core) - Core wovin types and utilities
|
|
164
|
-
- [`@wovin/
|
|
165
|
-
- [`@wovin/connect-s3`](../connect-s3) - Cloud storage via AWS S3
|
|
166
|
-
- [`@wovin/connect-web3storage`](../connect-web3storage) - Cloud storage via Web3.storage
|
|
166
|
+
- [`@wovin/daemon-utils`](../daemon-utils) - Daemon utilities
|
|
167
167
|
|
|
168
168
|
## License
|
|
169
169
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { StorageConnector, RetrievalConnector } from '@wovin/core/pubsub';
|
|
1
|
+
import type { Applog, CidString } from '@wovin/core/applog';
|
|
3
2
|
import { CID } from 'multiformats/cid';
|
|
4
|
-
export declare class
|
|
5
|
-
private
|
|
6
|
-
|
|
3
|
+
export declare class StorageFs {
|
|
4
|
+
private root;
|
|
5
|
+
private applogs;
|
|
6
|
+
private threadIndex;
|
|
7
|
+
private blocks;
|
|
8
|
+
static init(path: string): Promise<StorageFs>;
|
|
7
9
|
private constructor();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
storeApplogs(threadId: string, applogs: Applog[]): Promise<number>;
|
|
11
|
+
getApplogs(threadId: string): Applog[];
|
|
12
|
+
getApplogByCid(cid: CID | CidString): Applog | null;
|
|
13
|
+
hasApplog(cid: CID | CidString): boolean;
|
|
14
|
+
storeBlock(cid: CID | CidString, bytes: Uint8Array): Promise<void>;
|
|
15
|
+
getBlock(cid: CID | CidString): Uint8Array | null;
|
|
16
|
+
hasBlock(cid: CID | CidString): boolean;
|
|
17
|
+
listThreads(): string[];
|
|
18
|
+
deleteThread(threadId: string): Promise<void>;
|
|
19
|
+
getThreadApplogCount(threadId: string): number;
|
|
20
|
+
isApplogInThread(threadId: string, cid: CID | CidString): boolean;
|
|
12
21
|
close(): void;
|
|
13
22
|
}
|
|
23
|
+
export { StorageFs as LmdbConnector };
|
|
14
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAE3D,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAItC,qBAAa,SAAS;IACrB,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAA8B;WAE/B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAsBnD,OAAO;IAcD,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IA8BxE,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IActC,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;IAOnD,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO;IAOlC,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxE,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI;IAMjD,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO;IAOvC,WAAW,IAAI,MAAM,EAAE;IASjB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBnD,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAI9C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,SAAS,GAAG,OAAO;IAKjE,KAAK,IAAI,IAAI;CAGb;AAGD,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,CAAA"}
|
package/dist/index.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{open as
|
|
1
|
+
import{open as p}from"lmdb";import{Logger as e}from"besonders-logger";var{DEBUG:i,VERBOSE:u,ERROR:S}=e.setup(e.INFO),a=class g{root;applogs;threadIndex;blocks;static async init(t){let s=p({path:t,compression:!0}),r=s.openDB({name:"applogs"}),n=s.openDB({name:"thread_index",dupSort:!0}),o=s.openDB({name:"blocks"});return new g(s,r,n,o)}constructor(t,s,r,n){this.root=t,this.applogs=s,this.threadIndex=r,this.blocks=n}async storeApplogs(t,s){let r=0;return await this.root.transaction(()=>{for(let n of s){let o=n.cid;if(this.applogs.doesExist(o)){this.threadIndex.doesExist(t,o)||this.threadIndex.put(t,o);continue}this.applogs.put(o,JSON.stringify(n)),this.threadIndex.put(t,o),r++}}),i(`[StorageFs] Stored ${r} applogs in thread "${t}"`),r}getApplogs(t){let s=[],r=this.threadIndex.getValues(t);for(let n of r){let o=this.applogs.get(n);o&&s.push(JSON.parse(o))}return s}getApplogByCid(t){let s=typeof t=="string"?t:t.toString(),r=this.applogs.get(s);return r?JSON.parse(r):null}hasApplog(t){let s=typeof t=="string"?t:t.toString();return this.applogs.doesExist(s)}async storeBlock(t,s){let r=typeof t=="string"?t:t.toString();await this.blocks.put(r,s)}getBlock(t){let s=typeof t=="string"?t:t.toString();return this.blocks.get(s)??null}hasBlock(t){let s=typeof t=="string"?t:t.toString();return this.blocks.doesExist(s)}listThreads(){let t=new Set;for(let{key:s}of this.threadIndex.getRange({}))t.add(s);return Array.from(t)}async deleteThread(t){await this.root.transaction(()=>{let s=Array.from(this.threadIndex.getValues(t));for(let r of s)this.threadIndex.remove(t,r)}),i(`[StorageFs] Deleted thread "${t}"`)}getThreadApplogCount(t){return this.threadIndex.getValuesCount(t)}isApplogInThread(t,s){let r=typeof s=="string"?s:s.toString();return this.threadIndex.doesExist(t,r)}close(){this.root.close()}};export{a as LmdbConnector,a as StorageFs};
|
|
2
2
|
//# sourceMappingURL=index.min.js.map
|
package/dist/index.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { open, Database } from 'lmdb'\nimport
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { open, RootDatabase, Database } from 'lmdb'\nimport type { Applog, CidString } from '@wovin/core/applog'\nimport { Logger } from 'besonders-logger'\nimport { CID } from 'multiformats/cid'\n\nconst { DEBUG, VERBOSE, ERROR } = Logger.setup(Logger.INFO)\n\nexport class StorageFs {\n\tprivate root: RootDatabase\n\tprivate applogs: Database<string, string> // cidString → Applog JSON\n\tprivate threadIndex: Database<string, string> // threadId → cidString (dupSort)\n\tprivate blocks: Database<Uint8Array, string> // cidString → bytes\n\n\tstatic async init(path: string): Promise<StorageFs> {\n\t\tconst root = open({\n\t\t\tpath,\n\t\t\tcompression: true,\n\t\t})\n\n\t\tconst applogs = root.openDB<string, string>({\n\t\t\tname: 'applogs',\n\t\t})\n\n\t\tconst threadIndex = root.openDB<string, string>({\n\t\t\tname: 'thread_index',\n\t\t\tdupSort: true,\n\t\t})\n\n\t\tconst blocks = root.openDB<Uint8Array, string>({\n\t\t\tname: 'blocks',\n\t\t})\n\n\t\treturn new StorageFs(root, applogs, threadIndex, blocks)\n\t}\n\n\tprivate constructor(\n\t\troot: RootDatabase,\n\t\tapplogs: Database<string, string>,\n\t\tthreadIndex: Database<string, string>,\n\t\tblocks: Database<Uint8Array, string>,\n\t) {\n\t\tthis.root = root\n\t\tthis.applogs = applogs\n\t\tthis.threadIndex = threadIndex\n\t\tthis.blocks = blocks\n\t}\n\n\t// === Applogs ===\n\n\tasync storeApplogs(threadId: string, applogs: Applog[]): Promise<number> {\n\t\tlet stored = 0\n\n\t\tawait this.root.transaction(() => {\n\t\t\tfor (const applog of applogs) {\n\t\t\t\tconst cidStr = applog.cid\n\n\t\t\t\t// Check if already stored (dedup by CID)\n\t\t\t\tif (this.applogs.doesExist(cidStr)) {\n\t\t\t\t\t// Applog exists, but still add to thread index if not already there\n\t\t\t\t\tif (!this.threadIndex.doesExist(threadId, cidStr)) {\n\t\t\t\t\t\tthis.threadIndex.put(threadId, cidStr)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Store applog\n\t\t\t\tthis.applogs.put(cidStr, JSON.stringify(applog))\n\n\t\t\t\t// Add to thread index\n\t\t\t\tthis.threadIndex.put(threadId, cidStr)\n\n\t\t\t\tstored++\n\t\t\t}\n\t\t})\n\n\t\tDEBUG(`[StorageFs] Stored ${stored} applogs in thread \"${threadId}\"`)\n\t\treturn stored\n\t}\n\n\tgetApplogs(threadId: string): Applog[] {\n\t\tconst applogs: Applog[] = []\n\t\tconst cidStrings = this.threadIndex.getValues(threadId)\n\n\t\tfor (const cidStr of cidStrings) {\n\t\t\tconst json = this.applogs.get(cidStr)\n\t\t\tif (json) {\n\t\t\t\tapplogs.push(JSON.parse(json))\n\t\t\t}\n\t\t}\n\n\t\treturn applogs\n\t}\n\n\tgetApplogByCid(cid: CID | CidString): Applog | null {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\tconst json = this.applogs.get(cidStr)\n\t\tif (!json) return null\n\t\treturn JSON.parse(json)\n\t}\n\n\thasApplog(cid: CID | CidString): boolean {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\treturn this.applogs.doesExist(cidStr)\n\t}\n\n\t// === Blocks ===\n\n\tasync storeBlock(cid: CID | CidString, bytes: Uint8Array): Promise<void> {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\tawait this.blocks.put(cidStr, bytes)\n\t}\n\n\tgetBlock(cid: CID | CidString): Uint8Array | null {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\tconst bytes = this.blocks.get(cidStr)\n\t\treturn bytes ?? null\n\t}\n\n\thasBlock(cid: CID | CidString): boolean {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\treturn this.blocks.doesExist(cidStr)\n\t}\n\n\t// === Threads ===\n\n\tlistThreads(): string[] {\n\t\tconst threads = new Set<string>()\n\t\t// Iterate over all keys in thread_index\n\t\tfor (const { key } of this.threadIndex.getRange({})) {\n\t\t\tthreads.add(key)\n\t\t}\n\t\treturn Array.from(threads)\n\t}\n\n\tasync deleteThread(threadId: string): Promise<void> {\n\t\tawait this.root.transaction(() => {\n\t\t\t// Get all CIDs in this thread\n\t\t\tconst cidStrings = Array.from(this.threadIndex.getValues(threadId))\n\n\t\t\t// Remove all entries for this thread from index\n\t\t\tfor (const cidStr of cidStrings) {\n\t\t\t\tthis.threadIndex.remove(threadId, cidStr)\n\t\t\t}\n\n\t\t\t// Note: We don't delete the applogs themselves - they may be in other threads\n\t\t\t// Orphan cleanup could be a separate maintenance operation\n\t\t})\n\n\t\tDEBUG(`[StorageFs] Deleted thread \"${threadId}\"`)\n\t}\n\n\t// === Utilities ===\n\n\tgetThreadApplogCount(threadId: string): number {\n\t\treturn this.threadIndex.getValuesCount(threadId)\n\t}\n\n\tisApplogInThread(threadId: string, cid: CID | CidString): boolean {\n\t\tconst cidStr = typeof cid === 'string' ? cid : cid.toString()\n\t\treturn this.threadIndex.doesExist(threadId, cidStr)\n\t}\n\n\tclose(): void {\n\t\tthis.root.close()\n\t}\n}\n\n// Re-export for backwards compatibility during transition\nexport { StorageFs as LmdbConnector }\n"],"mappings":"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","names":["open","Logger","DEBUG","VERBOSE","ERROR","StorageFs","_StorageFs","path","root","applogs","threadIndex","blocks","threadId","stored","applog","cidStr","cidStrings","json","cid","bytes","threads","key"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wovin/storage-fs",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.min.js",
|
|
6
6
|
"module": "./dist/index.min.js",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ipld/car": "^5.2.6",
|
|
26
|
-
"@wovin/core": "0.0
|
|
26
|
+
"@wovin/core": "0.1.0",
|
|
27
27
|
"besonders-logger": "1.0.1",
|
|
28
28
|
"lmdb": "^3.0.0",
|
|
29
29
|
"multiformats": "^13.0.1"
|
|
@@ -32,9 +32,15 @@
|
|
|
32
32
|
"concurrently": "^8.2.2",
|
|
33
33
|
"esbuild-plugin-polyfill-node": "^0.3.0",
|
|
34
34
|
"tsup": "^8.0.2",
|
|
35
|
+
"tsx": "^4.19.2",
|
|
35
36
|
"typescript": "^5.8.3",
|
|
36
37
|
"tsupconfig": "^0.0.0"
|
|
37
38
|
},
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://gitlab.com/wovin/wovin.git",
|
|
42
|
+
"directory": "packages/@wovin/storage-fs"
|
|
43
|
+
},
|
|
38
44
|
"scripts": {
|
|
39
45
|
"build": "rm -rf dist/ && concurrently \"pnpm build:code\" \"pnpm build:types\"",
|
|
40
46
|
"build:code": "tsup --minify --external esbuild",
|
|
@@ -42,6 +48,7 @@
|
|
|
42
48
|
"dev": "concurrently \"pnpm dev:code\" \"pnpm dev:types\"",
|
|
43
49
|
"dev:code": "tsup --watch",
|
|
44
50
|
"dev:types": "tsc --emitDeclarationOnly --declaration --watch",
|
|
51
|
+
"test": "tsx test.ts",
|
|
45
52
|
"lint": "eslint .",
|
|
46
53
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
47
54
|
"pub": "npm publish --tag latest --access=public"
|