mvcc-api 1.2.11 → 1.3.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.
@@ -196,7 +196,9 @@ var MVCCTransaction = class {
196
196
  break;
197
197
  }
198
198
  }
199
- if (latestInSnapshotIdx > 0) {
199
+ if (latestInSnapshotIdx === versions.length - 1) {
200
+ this.versionIndex.delete(key);
201
+ } else if (latestInSnapshotIdx > 0) {
200
202
  versions.splice(0, latestInSnapshotIdx);
201
203
  }
202
204
  }
@@ -265,6 +267,25 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
265
267
  if (this.writeBuffer.has(key)) return true;
266
268
  return this.root._diskExists(key, this.snapshotVersion);
267
269
  }
270
+ _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
271
+ if (this.writeBuffer.has(key)) {
272
+ const keyModVersion = this.keyVersions.get(key);
273
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
274
+ return true;
275
+ }
276
+ }
277
+ if (this.deleteBuffer.has(key)) {
278
+ const keyModVersion = this.keyVersions.get(key);
279
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
280
+ return false;
281
+ }
282
+ }
283
+ if (this.parent) {
284
+ return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
285
+ } else {
286
+ return this._diskExists(key, snapshotVersion);
287
+ }
288
+ }
268
289
  _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
269
290
  if (this.writeBuffer.has(key)) {
270
291
  const keyModVersion = this.keyVersions.get(key);
@@ -407,7 +428,6 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
407
428
  this.localVersion = newLocalVersion;
408
429
  this.root.activeTransactions.delete(child);
409
430
  } else {
410
- const newVersion = this.version + 1;
411
431
  if (child !== this) {
412
432
  const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
413
433
  for (const key of modifiedKeys) {
@@ -426,35 +446,70 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
426
446
  }
427
447
  }
428
448
  }
429
- }
430
- for (const [key, value] of child.writeBuffer) {
431
- this.writeBuffer.set(key, value);
432
- this.deleteBuffer.delete(key);
433
- if (child.createdKeys.has(key)) {
434
- this.createdKeys.add(key);
449
+ const newVersion = this.version + 1;
450
+ for (const [key, value] of child.writeBuffer) {
451
+ if (this.writeBuffer.has(key)) {
452
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
453
+ this.deletedCache.get(key).push({
454
+ value: this.writeBuffer.get(key),
455
+ deletedAtVersion: newVersion
456
+ });
457
+ } else if (this.strategy.exists(key)) {
458
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
459
+ this.deletedCache.get(key).push({
460
+ value: this.strategy.read(key),
461
+ deletedAtVersion: newVersion
462
+ });
463
+ }
464
+ this.writeBuffer.set(key, value);
465
+ this.deleteBuffer.delete(key);
466
+ if (child.createdKeys.has(key)) {
467
+ this.createdKeys.add(key);
468
+ }
469
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
470
+ this.versionIndex.get(key).push({ version: newVersion, exists: true });
435
471
  }
436
- }
437
- for (const key of child.deleteBuffer) {
438
- this.deleteBuffer.add(key);
439
- this.writeBuffer.delete(key);
440
- this.createdKeys.delete(key);
441
- const deletedValue = child.deletedValues.get(key);
442
- if (deletedValue !== void 0) {
443
- this.deletedValues.set(key, deletedValue);
472
+ for (const key of child.deleteBuffer) {
473
+ if (this.writeBuffer.has(key)) {
474
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
475
+ this.deletedCache.get(key).push({
476
+ value: this.writeBuffer.get(key),
477
+ deletedAtVersion: newVersion
478
+ });
479
+ } else if (this.strategy.exists(key)) {
480
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
481
+ this.deletedCache.get(key).push({
482
+ value: this.strategy.read(key),
483
+ deletedAtVersion: newVersion
484
+ });
485
+ }
486
+ this.deleteBuffer.add(key);
487
+ this.writeBuffer.delete(key);
488
+ this.createdKeys.delete(key);
489
+ const deletedValue = child.deletedValues.get(key);
490
+ if (deletedValue !== void 0) {
491
+ this.deletedValues.set(key, deletedValue);
492
+ }
493
+ if (child.originallyExisted.has(key)) {
494
+ this.originallyExisted.add(key);
495
+ }
496
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
497
+ this.versionIndex.get(key).push({ version: newVersion, exists: false });
444
498
  }
445
- if (child.originallyExisted.has(key)) {
446
- this.originallyExisted.add(key);
499
+ this.version = newVersion;
500
+ this.root.activeTransactions.delete(child);
501
+ this._cleanupDeletedCache();
502
+ } else {
503
+ const newVersion = this.version + 1;
504
+ for (const [key, value] of this.writeBuffer) {
505
+ this._diskWrite(key, value, newVersion);
447
506
  }
507
+ for (const key of this.deleteBuffer) {
508
+ this._diskDelete(key, newVersion);
509
+ }
510
+ this.version = newVersion;
511
+ this._cleanupDeletedCache();
448
512
  }
449
- for (const [key, value] of child.writeBuffer) {
450
- this._diskWrite(key, value, newVersion);
451
- }
452
- for (const key of child.deleteBuffer) {
453
- this._diskDelete(key, newVersion);
454
- }
455
- this.version = newVersion;
456
- this.root.activeTransactions.delete(child);
457
- this._cleanupDeletedCache();
458
513
  }
459
514
  return null;
460
515
  }
@@ -479,6 +534,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
479
534
  if (!strategy) throw new Error("Root Transaction missing strategy");
480
535
  const versions = this.versionIndex.get(key);
481
536
  if (!versions) {
537
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
538
+ if (this.deleteBuffer.has(key)) return null;
482
539
  return strategy.exists(key) ? strategy.read(key) : null;
483
540
  }
484
541
  let targetVerObj = null;
@@ -499,10 +556,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
499
556
  if (match) return match.value;
500
557
  }
501
558
  }
502
- return null;
559
+ return strategy.exists(key) ? strategy.read(key) : null;
503
560
  }
504
561
  if (!targetVerObj.exists) return null;
505
562
  if (!nextVerObj) {
563
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
506
564
  return strategy.read(key);
507
565
  }
508
566
  const cached = this.deletedCache.get(key);
@@ -517,6 +575,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
517
575
  if (!strategy) throw new Error("Root Transaction missing strategy");
518
576
  const versions = this.versionIndex.get(key);
519
577
  if (!versions) {
578
+ if (this.writeBuffer.has(key)) return true;
579
+ if (this.deleteBuffer.has(key)) return false;
520
580
  return strategy.exists(key);
521
581
  }
522
582
  let targetVerObj = null;
@@ -540,8 +600,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
540
600
  value: currentVal,
541
601
  deletedAtVersion: snapshotVersion
542
602
  });
603
+ strategy.delete(key);
543
604
  }
544
- strategy.delete(key);
545
605
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
546
606
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
547
607
  }
@@ -876,6 +936,25 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
876
936
  if (this.writeBuffer.has(key)) return true;
877
937
  return this.root._diskExists(key, this.snapshotVersion);
878
938
  }
939
+ async _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
940
+ if (this.writeBuffer.has(key)) {
941
+ const keyModVersion = this.keyVersions.get(key);
942
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
943
+ return true;
944
+ }
945
+ }
946
+ if (this.deleteBuffer.has(key)) {
947
+ const keyModVersion = this.keyVersions.get(key);
948
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
949
+ return false;
950
+ }
951
+ }
952
+ if (this.parent) {
953
+ return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
954
+ } else {
955
+ return this._diskExists(key, snapshotVersion);
956
+ }
957
+ }
879
958
  async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
880
959
  if (this.writeBuffer.has(key)) {
881
960
  const keyModVersion = this.keyVersions.get(key);
@@ -1020,7 +1099,6 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1020
1099
  this.root.activeTransactions.delete(child);
1021
1100
  return null;
1022
1101
  } else {
1023
- const newVersion = this.version + 1;
1024
1102
  if (child !== this) {
1025
1103
  const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
1026
1104
  for (const key of modifiedKeys) {
@@ -1039,35 +1117,70 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1039
1117
  }
1040
1118
  }
1041
1119
  }
1042
- }
1043
- for (const [key, value] of child.writeBuffer) {
1044
- this.writeBuffer.set(key, value);
1045
- this.deleteBuffer.delete(key);
1046
- if (child.createdKeys.has(key)) {
1047
- this.createdKeys.add(key);
1120
+ const newVersion = this.version + 1;
1121
+ for (const [key, value] of child.writeBuffer) {
1122
+ if (this.writeBuffer.has(key)) {
1123
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1124
+ this.deletedCache.get(key).push({
1125
+ value: this.writeBuffer.get(key),
1126
+ deletedAtVersion: newVersion
1127
+ });
1128
+ } else if (await this.strategy.exists(key)) {
1129
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1130
+ this.deletedCache.get(key).push({
1131
+ value: await this.strategy.read(key),
1132
+ deletedAtVersion: newVersion
1133
+ });
1134
+ }
1135
+ this.writeBuffer.set(key, value);
1136
+ this.deleteBuffer.delete(key);
1137
+ if (child.createdKeys.has(key)) {
1138
+ this.createdKeys.add(key);
1139
+ }
1140
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1141
+ this.versionIndex.get(key).push({ version: newVersion, exists: true });
1048
1142
  }
1049
- }
1050
- for (const key of child.deleteBuffer) {
1051
- this.deleteBuffer.add(key);
1052
- this.writeBuffer.delete(key);
1053
- this.createdKeys.delete(key);
1054
- const deletedValue = child.deletedValues.get(key);
1055
- if (deletedValue !== void 0) {
1056
- this.deletedValues.set(key, deletedValue);
1143
+ for (const key of child.deleteBuffer) {
1144
+ if (this.writeBuffer.has(key)) {
1145
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1146
+ this.deletedCache.get(key).push({
1147
+ value: this.writeBuffer.get(key),
1148
+ deletedAtVersion: newVersion
1149
+ });
1150
+ } else if (await this.strategy.exists(key)) {
1151
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1152
+ this.deletedCache.get(key).push({
1153
+ value: await this.strategy.read(key),
1154
+ deletedAtVersion: newVersion
1155
+ });
1156
+ }
1157
+ this.deleteBuffer.add(key);
1158
+ this.writeBuffer.delete(key);
1159
+ this.createdKeys.delete(key);
1160
+ const deletedValue = child.deletedValues.get(key);
1161
+ if (deletedValue !== void 0) {
1162
+ this.deletedValues.set(key, deletedValue);
1163
+ }
1164
+ if (child.originallyExisted.has(key)) {
1165
+ this.originallyExisted.add(key);
1166
+ }
1167
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1168
+ this.versionIndex.get(key).push({ version: newVersion, exists: false });
1057
1169
  }
1058
- if (child.originallyExisted.has(key)) {
1059
- this.originallyExisted.add(key);
1170
+ this.version = newVersion;
1171
+ this.root.activeTransactions.delete(child);
1172
+ this._cleanupDeletedCache();
1173
+ } else {
1174
+ const newVersion = this.version + 1;
1175
+ for (const [key, value] of this.writeBuffer) {
1176
+ await this._diskWrite(key, value, newVersion);
1060
1177
  }
1178
+ for (const key of this.deleteBuffer) {
1179
+ await this._diskDelete(key, newVersion);
1180
+ }
1181
+ this.version = newVersion;
1182
+ this._cleanupDeletedCache();
1061
1183
  }
1062
- for (const [key, value] of child.writeBuffer) {
1063
- await this._diskWrite(key, value, newVersion);
1064
- }
1065
- for (const key of child.deleteBuffer) {
1066
- await this._diskDelete(key, newVersion);
1067
- }
1068
- this.version = newVersion;
1069
- this.root.activeTransactions.delete(child);
1070
- this._cleanupDeletedCache();
1071
1184
  return null;
1072
1185
  }
1073
1186
  });
@@ -1093,6 +1206,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1093
1206
  if (!strategy) throw new Error("Root Transaction missing strategy");
1094
1207
  const versions = this.versionIndex.get(key);
1095
1208
  if (!versions) {
1209
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
1210
+ if (this.deleteBuffer.has(key)) return null;
1096
1211
  return await strategy.exists(key) ? strategy.read(key) : null;
1097
1212
  }
1098
1213
  let targetVerObj = null;
@@ -1113,10 +1228,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1113
1228
  if (match) return match.value;
1114
1229
  }
1115
1230
  }
1116
- return null;
1231
+ return await strategy.exists(key) ? strategy.read(key) : null;
1117
1232
  }
1118
1233
  if (!targetVerObj.exists) return null;
1119
1234
  if (!nextVerObj) {
1235
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
1120
1236
  return strategy.read(key);
1121
1237
  }
1122
1238
  const cached = this.deletedCache.get(key);
@@ -1131,6 +1247,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1131
1247
  if (!strategy) throw new Error("Root Transaction missing strategy");
1132
1248
  const versions = this.versionIndex.get(key);
1133
1249
  if (!versions) {
1250
+ if (this.writeBuffer.has(key)) return true;
1251
+ if (this.deleteBuffer.has(key)) return false;
1134
1252
  return strategy.exists(key);
1135
1253
  }
1136
1254
  let targetVerObj = null;
@@ -1154,8 +1272,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1154
1272
  value: currentVal,
1155
1273
  deletedAtVersion: snapshotVersion
1156
1274
  });
1275
+ await strategy.delete(key);
1157
1276
  }
1158
- await strategy.delete(key);
1159
1277
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1160
1278
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
1161
1279
  }
@@ -165,7 +165,9 @@ var MVCCTransaction = class {
165
165
  break;
166
166
  }
167
167
  }
168
- if (latestInSnapshotIdx > 0) {
168
+ if (latestInSnapshotIdx === versions.length - 1) {
169
+ this.versionIndex.delete(key);
170
+ } else if (latestInSnapshotIdx > 0) {
169
171
  versions.splice(0, latestInSnapshotIdx);
170
172
  }
171
173
  }
@@ -234,6 +236,25 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
234
236
  if (this.writeBuffer.has(key)) return true;
235
237
  return this.root._diskExists(key, this.snapshotVersion);
236
238
  }
239
+ _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
240
+ if (this.writeBuffer.has(key)) {
241
+ const keyModVersion = this.keyVersions.get(key);
242
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
243
+ return true;
244
+ }
245
+ }
246
+ if (this.deleteBuffer.has(key)) {
247
+ const keyModVersion = this.keyVersions.get(key);
248
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
249
+ return false;
250
+ }
251
+ }
252
+ if (this.parent) {
253
+ return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
254
+ } else {
255
+ return this._diskExists(key, snapshotVersion);
256
+ }
257
+ }
237
258
  _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
238
259
  if (this.writeBuffer.has(key)) {
239
260
  const keyModVersion = this.keyVersions.get(key);
@@ -376,7 +397,6 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
376
397
  this.localVersion = newLocalVersion;
377
398
  this.root.activeTransactions.delete(child);
378
399
  } else {
379
- const newVersion = this.version + 1;
380
400
  if (child !== this) {
381
401
  const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
382
402
  for (const key of modifiedKeys) {
@@ -395,35 +415,70 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
395
415
  }
396
416
  }
397
417
  }
398
- }
399
- for (const [key, value] of child.writeBuffer) {
400
- this.writeBuffer.set(key, value);
401
- this.deleteBuffer.delete(key);
402
- if (child.createdKeys.has(key)) {
403
- this.createdKeys.add(key);
418
+ const newVersion = this.version + 1;
419
+ for (const [key, value] of child.writeBuffer) {
420
+ if (this.writeBuffer.has(key)) {
421
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
422
+ this.deletedCache.get(key).push({
423
+ value: this.writeBuffer.get(key),
424
+ deletedAtVersion: newVersion
425
+ });
426
+ } else if (this.strategy.exists(key)) {
427
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
428
+ this.deletedCache.get(key).push({
429
+ value: this.strategy.read(key),
430
+ deletedAtVersion: newVersion
431
+ });
432
+ }
433
+ this.writeBuffer.set(key, value);
434
+ this.deleteBuffer.delete(key);
435
+ if (child.createdKeys.has(key)) {
436
+ this.createdKeys.add(key);
437
+ }
438
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
439
+ this.versionIndex.get(key).push({ version: newVersion, exists: true });
404
440
  }
405
- }
406
- for (const key of child.deleteBuffer) {
407
- this.deleteBuffer.add(key);
408
- this.writeBuffer.delete(key);
409
- this.createdKeys.delete(key);
410
- const deletedValue = child.deletedValues.get(key);
411
- if (deletedValue !== void 0) {
412
- this.deletedValues.set(key, deletedValue);
441
+ for (const key of child.deleteBuffer) {
442
+ if (this.writeBuffer.has(key)) {
443
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
444
+ this.deletedCache.get(key).push({
445
+ value: this.writeBuffer.get(key),
446
+ deletedAtVersion: newVersion
447
+ });
448
+ } else if (this.strategy.exists(key)) {
449
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
450
+ this.deletedCache.get(key).push({
451
+ value: this.strategy.read(key),
452
+ deletedAtVersion: newVersion
453
+ });
454
+ }
455
+ this.deleteBuffer.add(key);
456
+ this.writeBuffer.delete(key);
457
+ this.createdKeys.delete(key);
458
+ const deletedValue = child.deletedValues.get(key);
459
+ if (deletedValue !== void 0) {
460
+ this.deletedValues.set(key, deletedValue);
461
+ }
462
+ if (child.originallyExisted.has(key)) {
463
+ this.originallyExisted.add(key);
464
+ }
465
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
466
+ this.versionIndex.get(key).push({ version: newVersion, exists: false });
413
467
  }
414
- if (child.originallyExisted.has(key)) {
415
- this.originallyExisted.add(key);
468
+ this.version = newVersion;
469
+ this.root.activeTransactions.delete(child);
470
+ this._cleanupDeletedCache();
471
+ } else {
472
+ const newVersion = this.version + 1;
473
+ for (const [key, value] of this.writeBuffer) {
474
+ this._diskWrite(key, value, newVersion);
416
475
  }
476
+ for (const key of this.deleteBuffer) {
477
+ this._diskDelete(key, newVersion);
478
+ }
479
+ this.version = newVersion;
480
+ this._cleanupDeletedCache();
417
481
  }
418
- for (const [key, value] of child.writeBuffer) {
419
- this._diskWrite(key, value, newVersion);
420
- }
421
- for (const key of child.deleteBuffer) {
422
- this._diskDelete(key, newVersion);
423
- }
424
- this.version = newVersion;
425
- this.root.activeTransactions.delete(child);
426
- this._cleanupDeletedCache();
427
482
  }
428
483
  return null;
429
484
  }
@@ -448,6 +503,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
448
503
  if (!strategy) throw new Error("Root Transaction missing strategy");
449
504
  const versions = this.versionIndex.get(key);
450
505
  if (!versions) {
506
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
507
+ if (this.deleteBuffer.has(key)) return null;
451
508
  return strategy.exists(key) ? strategy.read(key) : null;
452
509
  }
453
510
  let targetVerObj = null;
@@ -468,10 +525,11 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
468
525
  if (match) return match.value;
469
526
  }
470
527
  }
471
- return null;
528
+ return strategy.exists(key) ? strategy.read(key) : null;
472
529
  }
473
530
  if (!targetVerObj.exists) return null;
474
531
  if (!nextVerObj) {
532
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
475
533
  return strategy.read(key);
476
534
  }
477
535
  const cached = this.deletedCache.get(key);
@@ -486,6 +544,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
486
544
  if (!strategy) throw new Error("Root Transaction missing strategy");
487
545
  const versions = this.versionIndex.get(key);
488
546
  if (!versions) {
547
+ if (this.writeBuffer.has(key)) return true;
548
+ if (this.deleteBuffer.has(key)) return false;
489
549
  return strategy.exists(key);
490
550
  }
491
551
  let targetVerObj = null;
@@ -509,8 +569,8 @@ var SyncMVCCTransaction = class _SyncMVCCTransaction extends MVCCTransaction {
509
569
  value: currentVal,
510
570
  deletedAtVersion: snapshotVersion
511
571
  });
572
+ strategy.delete(key);
512
573
  }
513
- strategy.delete(key);
514
574
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
515
575
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
516
576
  }
@@ -845,6 +905,25 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
845
905
  if (this.writeBuffer.has(key)) return true;
846
906
  return this.root._diskExists(key, this.snapshotVersion);
847
907
  }
908
+ async _existsSnapshot(key, snapshotVersion, snapshotLocalVersion) {
909
+ if (this.writeBuffer.has(key)) {
910
+ const keyModVersion = this.keyVersions.get(key);
911
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
912
+ return true;
913
+ }
914
+ }
915
+ if (this.deleteBuffer.has(key)) {
916
+ const keyModVersion = this.keyVersions.get(key);
917
+ if (snapshotLocalVersion === void 0 || keyModVersion === void 0 || keyModVersion <= snapshotLocalVersion) {
918
+ return false;
919
+ }
920
+ }
921
+ if (this.parent) {
922
+ return this.parent._existsSnapshot(key, snapshotVersion, this.snapshotLocalVersion);
923
+ } else {
924
+ return this._diskExists(key, snapshotVersion);
925
+ }
926
+ }
848
927
  async _readSnapshot(key, snapshotVersion, snapshotLocalVersion) {
849
928
  if (this.writeBuffer.has(key)) {
850
929
  const keyModVersion = this.keyVersions.get(key);
@@ -989,7 +1068,6 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
989
1068
  this.root.activeTransactions.delete(child);
990
1069
  return null;
991
1070
  } else {
992
- const newVersion = this.version + 1;
993
1071
  if (child !== this) {
994
1072
  const modifiedKeys = /* @__PURE__ */ new Set([...child.writeBuffer.keys(), ...child.deleteBuffer]);
995
1073
  for (const key of modifiedKeys) {
@@ -1008,35 +1086,70 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1008
1086
  }
1009
1087
  }
1010
1088
  }
1011
- }
1012
- for (const [key, value] of child.writeBuffer) {
1013
- this.writeBuffer.set(key, value);
1014
- this.deleteBuffer.delete(key);
1015
- if (child.createdKeys.has(key)) {
1016
- this.createdKeys.add(key);
1089
+ const newVersion = this.version + 1;
1090
+ for (const [key, value] of child.writeBuffer) {
1091
+ if (this.writeBuffer.has(key)) {
1092
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1093
+ this.deletedCache.get(key).push({
1094
+ value: this.writeBuffer.get(key),
1095
+ deletedAtVersion: newVersion
1096
+ });
1097
+ } else if (await this.strategy.exists(key)) {
1098
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1099
+ this.deletedCache.get(key).push({
1100
+ value: await this.strategy.read(key),
1101
+ deletedAtVersion: newVersion
1102
+ });
1103
+ }
1104
+ this.writeBuffer.set(key, value);
1105
+ this.deleteBuffer.delete(key);
1106
+ if (child.createdKeys.has(key)) {
1107
+ this.createdKeys.add(key);
1108
+ }
1109
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1110
+ this.versionIndex.get(key).push({ version: newVersion, exists: true });
1017
1111
  }
1018
- }
1019
- for (const key of child.deleteBuffer) {
1020
- this.deleteBuffer.add(key);
1021
- this.writeBuffer.delete(key);
1022
- this.createdKeys.delete(key);
1023
- const deletedValue = child.deletedValues.get(key);
1024
- if (deletedValue !== void 0) {
1025
- this.deletedValues.set(key, deletedValue);
1112
+ for (const key of child.deleteBuffer) {
1113
+ if (this.writeBuffer.has(key)) {
1114
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1115
+ this.deletedCache.get(key).push({
1116
+ value: this.writeBuffer.get(key),
1117
+ deletedAtVersion: newVersion
1118
+ });
1119
+ } else if (await this.strategy.exists(key)) {
1120
+ if (!this.deletedCache.has(key)) this.deletedCache.set(key, []);
1121
+ this.deletedCache.get(key).push({
1122
+ value: await this.strategy.read(key),
1123
+ deletedAtVersion: newVersion
1124
+ });
1125
+ }
1126
+ this.deleteBuffer.add(key);
1127
+ this.writeBuffer.delete(key);
1128
+ this.createdKeys.delete(key);
1129
+ const deletedValue = child.deletedValues.get(key);
1130
+ if (deletedValue !== void 0) {
1131
+ this.deletedValues.set(key, deletedValue);
1132
+ }
1133
+ if (child.originallyExisted.has(key)) {
1134
+ this.originallyExisted.add(key);
1135
+ }
1136
+ if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1137
+ this.versionIndex.get(key).push({ version: newVersion, exists: false });
1026
1138
  }
1027
- if (child.originallyExisted.has(key)) {
1028
- this.originallyExisted.add(key);
1139
+ this.version = newVersion;
1140
+ this.root.activeTransactions.delete(child);
1141
+ this._cleanupDeletedCache();
1142
+ } else {
1143
+ const newVersion = this.version + 1;
1144
+ for (const [key, value] of this.writeBuffer) {
1145
+ await this._diskWrite(key, value, newVersion);
1029
1146
  }
1147
+ for (const key of this.deleteBuffer) {
1148
+ await this._diskDelete(key, newVersion);
1149
+ }
1150
+ this.version = newVersion;
1151
+ this._cleanupDeletedCache();
1030
1152
  }
1031
- for (const [key, value] of child.writeBuffer) {
1032
- await this._diskWrite(key, value, newVersion);
1033
- }
1034
- for (const key of child.deleteBuffer) {
1035
- await this._diskDelete(key, newVersion);
1036
- }
1037
- this.version = newVersion;
1038
- this.root.activeTransactions.delete(child);
1039
- this._cleanupDeletedCache();
1040
1153
  return null;
1041
1154
  }
1042
1155
  });
@@ -1062,6 +1175,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1062
1175
  if (!strategy) throw new Error("Root Transaction missing strategy");
1063
1176
  const versions = this.versionIndex.get(key);
1064
1177
  if (!versions) {
1178
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
1179
+ if (this.deleteBuffer.has(key)) return null;
1065
1180
  return await strategy.exists(key) ? strategy.read(key) : null;
1066
1181
  }
1067
1182
  let targetVerObj = null;
@@ -1082,10 +1197,11 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1082
1197
  if (match) return match.value;
1083
1198
  }
1084
1199
  }
1085
- return null;
1200
+ return await strategy.exists(key) ? strategy.read(key) : null;
1086
1201
  }
1087
1202
  if (!targetVerObj.exists) return null;
1088
1203
  if (!nextVerObj) {
1204
+ if (this.writeBuffer.has(key)) return this.writeBuffer.get(key);
1089
1205
  return strategy.read(key);
1090
1206
  }
1091
1207
  const cached = this.deletedCache.get(key);
@@ -1100,6 +1216,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1100
1216
  if (!strategy) throw new Error("Root Transaction missing strategy");
1101
1217
  const versions = this.versionIndex.get(key);
1102
1218
  if (!versions) {
1219
+ if (this.writeBuffer.has(key)) return true;
1220
+ if (this.deleteBuffer.has(key)) return false;
1103
1221
  return strategy.exists(key);
1104
1222
  }
1105
1223
  let targetVerObj = null;
@@ -1123,8 +1241,8 @@ var AsyncMVCCTransaction = class _AsyncMVCCTransaction extends MVCCTransaction {
1123
1241
  value: currentVal,
1124
1242
  deletedAtVersion: snapshotVersion
1125
1243
  });
1244
+ await strategy.delete(key);
1126
1245
  }
1127
- await strategy.delete(key);
1128
1246
  if (!this.versionIndex.has(key)) this.versionIndex.set(key, []);
1129
1247
  this.versionIndex.get(key).push({ version: snapshotVersion, exists: false });
1130
1248
  }
@@ -10,6 +10,7 @@ export declare class AsyncMVCCTransaction<S extends AsyncMVCCStrategy<K, T>, K,
10
10
  createNested(): this;
11
11
  read(key: K): Promise<T | null>;
12
12
  exists(key: K): Promise<boolean>;
13
+ _existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Promise<boolean>;
13
14
  _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Promise<T | null>;
14
15
  commit(label?: string): Promise<TransactionResult<K, T>>;
15
16
  _merge(child: AsyncMVCCTransaction<S, K, T>): Promise<TransactionMergeFailure<K, T> | null>;
@@ -120,6 +120,14 @@ export declare abstract class MVCCTransaction<S extends MVCCStrategy<K, T>, K, T
120
120
  * @param snapshotLocalVersion The local version within the parent's buffer to read at.
121
121
  */
122
122
  abstract _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Deferred<T | null>;
123
+ /**
124
+ * Checks if a key exists at a specific snapshot version.
125
+ * Used by child transactions to check existence from parent respecting the child's snapshot.
126
+ * @param key The key to check.
127
+ * @param snapshotVersion The global version to check at.
128
+ * @param snapshotLocalVersion The local version within the parent's buffer to check at.
129
+ */
130
+ abstract _existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): Deferred<boolean>;
123
131
  /**
124
132
  * Cleans up both deletedCache and versionIndex based on minActiveVersion.
125
133
  * Root transactions call this after commit to reclaim memory.
@@ -8,6 +8,7 @@ export declare class SyncMVCCTransaction<S extends SyncMVCCStrategy<K, T>, K, T>
8
8
  createNested(): this;
9
9
  read(key: K): T | null;
10
10
  exists(key: K): boolean;
11
+ _existsSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): boolean;
11
12
  _readSnapshot(key: K, snapshotVersion: number, snapshotLocalVersion?: number): T | null;
12
13
  commit(label?: string): TransactionResult<K, T>;
13
14
  _merge(child: SyncMVCCTransaction<S, K, T>): TransactionMergeFailure<K, T> | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mvcc-api",
3
- "version": "1.2.11",
3
+ "version": "1.3.0",
4
4
  "description": "Multiversion Concurrency Control (MVCC) API for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "izure <admin@izure.org>",