mvcc-api 1.2.0 → 1.2.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/README.md CHANGED
@@ -74,9 +74,10 @@ import { AsyncMVCCTransaction } from 'mvcc-api'
74
74
  const root = new AsyncMVCCTransaction(new FileStrategy())
75
75
  const tx = root.createNested()
76
76
 
77
- tx.create('new.json', '{}') // Create new key
78
- tx.write('config.json', '{"v":2}') // Update existing key
79
- tx.delete('old.json') // Delete key
77
+ await tx.create('new.json', '{}') // Create new key
78
+ await tx.write('config.json', '{"v":2}') // Update existing key
79
+ await tx.delete('old.json') // Delete key
80
+ await tx.exists('config.json') // true
80
81
 
81
82
  const result = await tx.commit()
82
83
  // result.created = [{ key: 'new.json', data: '{}' }]
@@ -177,6 +178,7 @@ const bResult = b.commit()
177
178
  | `write(key, value)` | Update existing key | `this` |
178
179
  | `delete(key)` | Delete key | `this` |
179
180
  | `read(key)` | Read value | `T \| null` |
181
+ | `exists(key)` | Check if key exists | `boolean` |
180
182
  | `commit()` | Apply changes | `TransactionResult<K, T>` |
181
183
  | `rollback()` | Discard changes | `TransactionResult<K, T>` |
182
184
  | `createNested()` | Create child transaction | `MVCCTransaction` |
@@ -201,4 +203,5 @@ type TransactionEntry<K, T> = { key: K, data: T }
201
203
  Bug reports, feature suggestions, and PRs are always welcome! Please feel free to leave your feedback via GitHub Issues.
202
204
 
203
205
  ## License
206
+
204
207
  MIT
@@ -186,6 +186,12 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
186
186
  if (this.deleteBuffer.has(key)) return null;
187
187
  return this.root._diskRead(key, this.snapshotVersion);
188
188
  }
189
+ exists(key) {
190
+ if (this.committed) throw new Error("Transaction already committed");
191
+ if (this.deleteBuffer.has(key)) return false;
192
+ if (this.writeBuffer.has(key)) return true;
193
+ return this.root._diskExists(key, this.snapshotVersion);
194
+ }
189
195
  _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
190
196
  if (this.writeBuffer.has(key)) {
191
197
  const keyModVersion = this.keyVersions.get(key);
@@ -350,6 +356,24 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
350
356
  }
351
357
  return null;
352
358
  }
359
+ _diskExists(key, snapshotVersion) {
360
+ const strategy = this.strategy;
361
+ if (!strategy) throw new Error("Root Transaction missing strategy");
362
+ const versions = this.versionIndex.get(key);
363
+ if (!versions) {
364
+ return strategy.exists(key);
365
+ }
366
+ let targetVerObj = null;
367
+ for (const v of versions) {
368
+ if (v.version <= snapshotVersion) {
369
+ targetVerObj = v;
370
+ } else {
371
+ break;
372
+ }
373
+ }
374
+ if (!targetVerObj) return strategy.exists(key);
375
+ return targetVerObj.exists;
376
+ }
353
377
  _diskDelete(key, snapshotVersion) {
354
378
  const strategy = this.strategy;
355
379
  if (!strategy) throw new Error("Root Transaction missing strategy");
@@ -704,6 +728,12 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
704
728
  if (this.deleteBuffer.has(key)) return null;
705
729
  return this.root._diskRead(key, this.snapshotVersion);
706
730
  }
731
+ async exists(key) {
732
+ if (this.committed) throw new Error("Transaction already committed");
733
+ if (this.deleteBuffer.has(key)) return false;
734
+ if (this.writeBuffer.has(key)) return true;
735
+ return this.root._diskExists(key, this.snapshotVersion);
736
+ }
707
737
  async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
708
738
  if (this.writeBuffer.has(key)) {
709
739
  const keyModVersion = this.keyVersions.get(key);
@@ -872,6 +902,24 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
872
902
  }
873
903
  return null;
874
904
  }
905
+ async _diskExists(key, snapshotVersion) {
906
+ const strategy = this.strategy;
907
+ if (!strategy) throw new Error("Root Transaction missing strategy");
908
+ const versions = this.versionIndex.get(key);
909
+ if (!versions) {
910
+ return strategy.exists(key);
911
+ }
912
+ let targetVerObj = null;
913
+ for (const v of versions) {
914
+ if (v.version <= snapshotVersion) {
915
+ targetVerObj = v;
916
+ } else {
917
+ break;
918
+ }
919
+ }
920
+ if (!targetVerObj) return strategy.exists(key);
921
+ return targetVerObj.exists;
922
+ }
875
923
  async _diskDelete(key, snapshotVersion) {
876
924
  const strategy = this.strategy;
877
925
  if (!strategy) throw new Error("Root Transaction missing strategy");
@@ -157,6 +157,12 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
157
157
  if (this.deleteBuffer.has(key)) return null;
158
158
  return this.root._diskRead(key, this.snapshotVersion);
159
159
  }
160
+ exists(key) {
161
+ if (this.committed) throw new Error("Transaction already committed");
162
+ if (this.deleteBuffer.has(key)) return false;
163
+ if (this.writeBuffer.has(key)) return true;
164
+ return this.root._diskExists(key, this.snapshotVersion);
165
+ }
160
166
  _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
161
167
  if (this.writeBuffer.has(key)) {
162
168
  const keyModVersion = this.keyVersions.get(key);
@@ -321,6 +327,24 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
321
327
  }
322
328
  return null;
323
329
  }
330
+ _diskExists(key, snapshotVersion) {
331
+ const strategy = this.strategy;
332
+ if (!strategy) throw new Error("Root Transaction missing strategy");
333
+ const versions = this.versionIndex.get(key);
334
+ if (!versions) {
335
+ return strategy.exists(key);
336
+ }
337
+ let targetVerObj = null;
338
+ for (const v of versions) {
339
+ if (v.version <= snapshotVersion) {
340
+ targetVerObj = v;
341
+ } else {
342
+ break;
343
+ }
344
+ }
345
+ if (!targetVerObj) return strategy.exists(key);
346
+ return targetVerObj.exists;
347
+ }
324
348
  _diskDelete(key, snapshotVersion) {
325
349
  const strategy = this.strategy;
326
350
  if (!strategy) throw new Error("Root Transaction missing strategy");
@@ -675,6 +699,12 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
675
699
  if (this.deleteBuffer.has(key)) return null;
676
700
  return this.root._diskRead(key, this.snapshotVersion);
677
701
  }
702
+ async exists(key) {
703
+ if (this.committed) throw new Error("Transaction already committed");
704
+ if (this.deleteBuffer.has(key)) return false;
705
+ if (this.writeBuffer.has(key)) return true;
706
+ return this.root._diskExists(key, this.snapshotVersion);
707
+ }
678
708
  async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
679
709
  if (this.writeBuffer.has(key)) {
680
710
  const keyModVersion = this.keyVersions.get(key);
@@ -843,6 +873,24 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
843
873
  }
844
874
  return null;
845
875
  }
876
+ async _diskExists(key, snapshotVersion) {
877
+ const strategy = this.strategy;
878
+ if (!strategy) throw new Error("Root Transaction missing strategy");
879
+ const versions = this.versionIndex.get(key);
880
+ if (!versions) {
881
+ return strategy.exists(key);
882
+ }
883
+ let targetVerObj = null;
884
+ for (const v of versions) {
885
+ if (v.version <= snapshotVersion) {
886
+ targetVerObj = v;
887
+ } else {
888
+ break;
889
+ }
890
+ }
891
+ if (!targetVerObj) return strategy.exists(key);
892
+ return targetVerObj.exists;
893
+ }
846
894
  async _diskDelete(key, snapshotVersion) {
847
895
  const strategy = this.strategy;
848
896
  if (!strategy) throw new Error("Root Transaction missing strategy");
@@ -9,11 +9,13 @@ export declare class AsyncMVCCTransaction<S extends AsyncMVCCStrategy<K, T>, K,
9
9
  delete(key: K): Promise<this>;
10
10
  createNested(): this;
11
11
  read(key: K): Promise<T | null>;
12
+ exists(key: K): Promise<boolean>;
12
13
  _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Promise<T | null>;
13
14
  commit(): Promise<TransactionResult<K, T>>;
14
15
  _merge(child: MVCCTransaction<S, K, T>): Promise<string | null>;
15
16
  _diskWrite(key: K, value: T, version: number): Promise<void>;
16
17
  _diskRead(key: K, snapshotVersion: number): Promise<T | null>;
18
+ _diskExists(key: K, snapshotVersion: number): Promise<boolean>;
17
19
  _diskDelete(key: K, snapshotVersion: number): Promise<void>;
18
20
  _cleanupDeletedCache(): void;
19
21
  }
@@ -71,6 +71,12 @@ export declare abstract class MVCCTransaction<S extends MVCCStrategy<K, T>, K, T
71
71
  * @returns The value, or null if not found.
72
72
  */
73
73
  abstract read(key: K): Deferred<T | null>;
74
+ /**
75
+ * Checks if a key exists in the transaction's snapshot.
76
+ * @param key The key to check.
77
+ * @returns True if the key exists, false otherwise.
78
+ */
79
+ abstract exists(key: K): Deferred<boolean>;
74
80
  /**
75
81
  * Commits the transaction.
76
82
  * If root, persists to storage.
@@ -7,11 +7,13 @@ export declare class SyncMVCCTransaction<S extends SyncMVCCStrategy<K, T>, K, T>
7
7
  delete(key: K): this;
8
8
  createNested(): this;
9
9
  read(key: K): T | null;
10
+ exists(key: K): boolean;
10
11
  _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): T | null;
11
12
  commit(): TransactionResult<K, T>;
12
13
  _merge(child: MVCCTransaction<S, K, T>): string | null;
13
14
  _diskWrite(key: K, value: T, version: number): void;
14
15
  _diskRead(key: K, snapshotVersion: number): T | null;
16
+ _diskExists(key: K, snapshotVersion: number): boolean;
15
17
  _diskDelete(key: K, snapshotVersion: number): void;
16
18
  _cleanupDeletedCache(): void;
17
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mvcc-api",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Multiversion Concurrency Control (MVCC) API for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",