serializable-bptree 9.0.0 → 9.0.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.
@@ -5014,32 +5014,73 @@ var BPTreePureSync = class {
5014
5014
  createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5015
5015
  const id = strategy.id(leaf);
5016
5016
  const node = { id, keys, values, leaf, parent, next, prev };
5017
- strategy.write(id, node);
5017
+ return node;
5018
+ },
5019
+ updateNode() {
5020
+ },
5021
+ deleteNode() {
5022
+ },
5023
+ readHead() {
5024
+ return strategy.readHead();
5025
+ },
5026
+ writeHead() {
5027
+ }
5028
+ };
5029
+ }
5030
+ _createBufferedOps() {
5031
+ const strategy = this.strategy;
5032
+ const writeBuffer = /* @__PURE__ */ new Map();
5033
+ const deleteBuffer = /* @__PURE__ */ new Set();
5034
+ let headBuffer = null;
5035
+ const ops = {
5036
+ getNode(id) {
5037
+ const buffered = writeBuffer.get(id);
5038
+ if (buffered) return buffered;
5039
+ return strategy.read(id);
5040
+ },
5041
+ createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5042
+ const id = strategy.id(leaf);
5043
+ const node = { id, keys, values, leaf, parent, next, prev };
5044
+ writeBuffer.set(id, node);
5018
5045
  return node;
5019
5046
  },
5020
5047
  updateNode(node) {
5021
- strategy.write(node.id, node);
5048
+ writeBuffer.set(node.id, node);
5022
5049
  },
5023
5050
  deleteNode(node) {
5024
- strategy.delete(node.id);
5051
+ deleteBuffer.add(node.id);
5052
+ writeBuffer.delete(node.id);
5025
5053
  },
5026
5054
  readHead() {
5055
+ if (headBuffer) return headBuffer;
5027
5056
  return strategy.readHead();
5028
5057
  },
5029
5058
  writeHead(head) {
5030
- strategy.writeHead(head);
5059
+ headBuffer = head;
5031
5060
  }
5032
5061
  };
5062
+ function flush() {
5063
+ for (const id of deleteBuffer) {
5064
+ strategy.delete(id);
5065
+ }
5066
+ for (const [id, node] of writeBuffer) {
5067
+ strategy.write(id, node);
5068
+ }
5069
+ if (headBuffer) {
5070
+ strategy.writeHead(headBuffer);
5071
+ }
5072
+ }
5073
+ return { ops, flush };
5033
5074
  }
5034
5075
  init() {
5035
- this._ops = this._createOps();
5076
+ const { ops, flush } = this._createBufferedOps();
5036
5077
  this._ctx = {
5037
5078
  rootId: "",
5038
5079
  order: this.strategy.order,
5039
5080
  headData: () => this.strategy.head.data
5040
5081
  };
5041
5082
  initOp(
5042
- this._ops,
5083
+ ops,
5043
5084
  this._ctx,
5044
5085
  this.strategy.order,
5045
5086
  this.strategy.head,
@@ -5047,6 +5088,8 @@ var BPTreePureSync = class {
5047
5088
  this.strategy.head = head;
5048
5089
  }
5049
5090
  );
5091
+ flush();
5092
+ this._ops = this._createOps();
5050
5093
  }
5051
5094
  /**
5052
5095
  * Returns the ID of the root node.
@@ -5120,16 +5163,24 @@ var BPTreePureSync = class {
5120
5163
  }
5121
5164
  // ─── Mutation ────────────────────────────────────────────────────
5122
5165
  insert(key, value) {
5123
- insertOp(this._ops, this._ctx, key, value, this.comparator);
5166
+ const { ops, flush } = this._createBufferedOps();
5167
+ insertOp(ops, this._ctx, key, value, this.comparator);
5168
+ flush();
5124
5169
  }
5125
5170
  delete(key, value) {
5126
- deleteOp(this._ops, this._ctx, key, this.comparator, value);
5171
+ const { ops, flush } = this._createBufferedOps();
5172
+ deleteOp(ops, this._ctx, key, this.comparator, value);
5173
+ flush();
5127
5174
  }
5128
5175
  batchInsert(entries) {
5129
- batchInsertOp(this._ops, this._ctx, entries, this.comparator);
5176
+ const { ops, flush } = this._createBufferedOps();
5177
+ batchInsertOp(ops, this._ctx, entries, this.comparator);
5178
+ flush();
5130
5179
  }
5131
5180
  bulkLoad(entries) {
5132
- bulkLoadOp(this._ops, this._ctx, entries, this.comparator);
5181
+ const { ops, flush } = this._createBufferedOps();
5182
+ bulkLoadOp(ops, this._ctx, entries, this.comparator);
5183
+ flush();
5133
5184
  }
5134
5185
  // ─── Head Data ───────────────────────────────────────────────────
5135
5186
  getHeadData() {
@@ -5140,15 +5191,17 @@ var BPTreePureSync = class {
5140
5191
  return head.data;
5141
5192
  }
5142
5193
  setHeadData(data) {
5143
- const head = this._ops.readHead();
5194
+ const { ops, flush } = this._createBufferedOps();
5195
+ const head = ops.readHead();
5144
5196
  if (head === null) {
5145
5197
  throw new Error("Head not found");
5146
5198
  }
5147
- this._ops.writeHead({
5199
+ ops.writeHead({
5148
5200
  root: head.root,
5149
5201
  order: head.order,
5150
5202
  data
5151
5203
  });
5204
+ flush();
5152
5205
  }
5153
5206
  // ─── Static utilities ────────────────────────────────────────────
5154
5207
  static ChooseDriver = BPTreeTransaction.ChooseDriver;
@@ -5159,6 +5212,7 @@ var BPTreePureAsync = class {
5159
5212
  strategy;
5160
5213
  comparator;
5161
5214
  option;
5215
+ lock = new Ryoiki2();
5162
5216
  _cachedRegexp = /* @__PURE__ */ new Map();
5163
5217
  _ctx;
5164
5218
  _ops;
@@ -5184,39 +5238,93 @@ var BPTreePureAsync = class {
5184
5238
  async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5185
5239
  const id = await strategy.id(leaf);
5186
5240
  const node = { id, keys, values, leaf, parent, next, prev };
5187
- await strategy.write(id, node);
5241
+ return node;
5242
+ },
5243
+ async updateNode() {
5244
+ },
5245
+ async deleteNode() {
5246
+ },
5247
+ async readHead() {
5248
+ return await strategy.readHead();
5249
+ },
5250
+ async writeHead() {
5251
+ }
5252
+ };
5253
+ }
5254
+ _createBufferedOps() {
5255
+ const strategy = this.strategy;
5256
+ const writeBuffer = /* @__PURE__ */ new Map();
5257
+ const deleteBuffer = /* @__PURE__ */ new Set();
5258
+ let headBuffer = null;
5259
+ const ops = {
5260
+ async getNode(id) {
5261
+ const buffered = writeBuffer.get(id);
5262
+ if (buffered) return buffered;
5263
+ return await strategy.read(id);
5264
+ },
5265
+ async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5266
+ const id = await strategy.id(leaf);
5267
+ const node = { id, keys, values, leaf, parent, next, prev };
5268
+ writeBuffer.set(id, node);
5188
5269
  return node;
5189
5270
  },
5190
5271
  async updateNode(node) {
5191
- await strategy.write(node.id, node);
5272
+ writeBuffer.set(node.id, node);
5192
5273
  },
5193
5274
  async deleteNode(node) {
5194
- await strategy.delete(node.id);
5275
+ deleteBuffer.add(node.id);
5276
+ writeBuffer.delete(node.id);
5195
5277
  },
5196
5278
  async readHead() {
5279
+ if (headBuffer) return headBuffer;
5197
5280
  return await strategy.readHead();
5198
5281
  },
5199
5282
  async writeHead(head) {
5200
- await strategy.writeHead(head);
5283
+ headBuffer = head;
5201
5284
  }
5202
5285
  };
5286
+ async function flush() {
5287
+ for (const id of deleteBuffer) {
5288
+ await strategy.delete(id);
5289
+ }
5290
+ for (const [id, node] of writeBuffer) {
5291
+ await strategy.write(id, node);
5292
+ }
5293
+ if (headBuffer) {
5294
+ await strategy.writeHead(headBuffer);
5295
+ }
5296
+ }
5297
+ return { ops, flush };
5298
+ }
5299
+ async writeLock(fn) {
5300
+ let lockId;
5301
+ return this.lock.writeLock(async (_lockId) => {
5302
+ lockId = _lockId;
5303
+ return fn();
5304
+ }).finally(() => {
5305
+ this.lock.writeUnlock(lockId);
5306
+ });
5203
5307
  }
5204
5308
  async init() {
5205
- this._ops = this._createOps();
5206
- this._ctx = {
5207
- rootId: "",
5208
- order: this.strategy.order,
5209
- headData: () => this.strategy.head.data
5210
- };
5211
- await initOpAsync(
5212
- this._ops,
5213
- this._ctx,
5214
- this.strategy.order,
5215
- this.strategy.head,
5216
- (head) => {
5217
- this.strategy.head = head;
5218
- }
5219
- );
5309
+ return this.writeLock(async () => {
5310
+ const { ops, flush } = this._createBufferedOps();
5311
+ this._ctx = {
5312
+ rootId: "",
5313
+ order: this.strategy.order,
5314
+ headData: () => this.strategy.head.data
5315
+ };
5316
+ await initOpAsync(
5317
+ ops,
5318
+ this._ctx,
5319
+ this.strategy.order,
5320
+ this.strategy.head,
5321
+ (head) => {
5322
+ this.strategy.head = head;
5323
+ }
5324
+ );
5325
+ await flush();
5326
+ this._ops = this._createOps();
5327
+ });
5220
5328
  }
5221
5329
  getRootId() {
5222
5330
  return this._ctx.rootId;
@@ -5240,28 +5348,40 @@ var BPTreePureAsync = class {
5240
5348
  return existsOpAsync(this._ops, this._ctx.rootId, key, value, this.comparator);
5241
5349
  }
5242
5350
  async *keysStream(condition, options) {
5243
- yield* keysStreamOpAsync(
5244
- this._ops,
5245
- this._ctx.rootId,
5246
- condition,
5247
- this.comparator,
5248
- this._verifierMap,
5249
- this._searchConfigs,
5250
- this._ensureValues,
5251
- options
5252
- );
5351
+ let lockId;
5352
+ try {
5353
+ lockId = await this.lock.readLock([0, 0.1], async (id) => id);
5354
+ yield* keysStreamOpAsync(
5355
+ this._ops,
5356
+ this._ctx.rootId,
5357
+ condition,
5358
+ this.comparator,
5359
+ this._verifierMap,
5360
+ this._searchConfigs,
5361
+ this._ensureValues,
5362
+ options
5363
+ );
5364
+ } finally {
5365
+ if (lockId) this.lock.readUnlock(lockId);
5366
+ }
5253
5367
  }
5254
5368
  async *whereStream(condition, options) {
5255
- yield* whereStreamOpAsync(
5256
- this._ops,
5257
- this._ctx.rootId,
5258
- condition,
5259
- this.comparator,
5260
- this._verifierMap,
5261
- this._searchConfigs,
5262
- this._ensureValues,
5263
- options
5264
- );
5369
+ let lockId;
5370
+ try {
5371
+ lockId = await this.lock.readLock([0, 0.1], async (id) => id);
5372
+ yield* whereStreamOpAsync(
5373
+ this._ops,
5374
+ this._ctx.rootId,
5375
+ condition,
5376
+ this.comparator,
5377
+ this._verifierMap,
5378
+ this._searchConfigs,
5379
+ this._ensureValues,
5380
+ options
5381
+ );
5382
+ } finally {
5383
+ if (lockId) this.lock.readUnlock(lockId);
5384
+ }
5265
5385
  }
5266
5386
  async keys(condition, options) {
5267
5387
  const set = /* @__PURE__ */ new Set();
@@ -5279,16 +5399,32 @@ var BPTreePureAsync = class {
5279
5399
  }
5280
5400
  // ─── Mutation ────────────────────────────────────────────────────
5281
5401
  async insert(key, value) {
5282
- await insertOpAsync(this._ops, this._ctx, key, value, this.comparator);
5402
+ return this.writeLock(async () => {
5403
+ const { ops, flush } = this._createBufferedOps();
5404
+ await insertOpAsync(ops, this._ctx, key, value, this.comparator);
5405
+ await flush();
5406
+ });
5283
5407
  }
5284
5408
  async delete(key, value) {
5285
- await deleteOpAsync(this._ops, this._ctx, key, this.comparator, value);
5409
+ return this.writeLock(async () => {
5410
+ const { ops, flush } = this._createBufferedOps();
5411
+ await deleteOpAsync(ops, this._ctx, key, this.comparator, value);
5412
+ await flush();
5413
+ });
5286
5414
  }
5287
5415
  async batchInsert(entries) {
5288
- await batchInsertOpAsync(this._ops, this._ctx, entries, this.comparator);
5416
+ return this.writeLock(async () => {
5417
+ const { ops, flush } = this._createBufferedOps();
5418
+ await batchInsertOpAsync(ops, this._ctx, entries, this.comparator);
5419
+ await flush();
5420
+ });
5289
5421
  }
5290
5422
  async bulkLoad(entries) {
5291
- await bulkLoadOpAsync(this._ops, this._ctx, entries, this.comparator);
5423
+ return this.writeLock(async () => {
5424
+ const { ops, flush } = this._createBufferedOps();
5425
+ await bulkLoadOpAsync(ops, this._ctx, entries, this.comparator);
5426
+ await flush();
5427
+ });
5292
5428
  }
5293
5429
  // ─── Head Data ───────────────────────────────────────────────────
5294
5430
  async getHeadData() {
@@ -5297,9 +5433,13 @@ var BPTreePureAsync = class {
5297
5433
  return head.data;
5298
5434
  }
5299
5435
  async setHeadData(data) {
5300
- const head = await this._ops.readHead();
5301
- if (head === null) throw new Error("Head not found");
5302
- await this._ops.writeHead({ root: head.root, order: head.order, data });
5436
+ return this.writeLock(async () => {
5437
+ const { ops, flush } = this._createBufferedOps();
5438
+ const head = await ops.readHead();
5439
+ if (head === null) throw new Error("Head not found");
5440
+ await ops.writeHead({ root: head.root, order: head.order, data });
5441
+ await flush();
5442
+ });
5303
5443
  }
5304
5444
  // ─── Static utilities ────────────────────────────────────────────
5305
5445
  static ChooseDriver = BPTreeTransaction.ChooseDriver;
@@ -4976,32 +4976,73 @@ var BPTreePureSync = class {
4976
4976
  createNode(leaf, keys, values, parent = null, next = null, prev = null) {
4977
4977
  const id = strategy.id(leaf);
4978
4978
  const node = { id, keys, values, leaf, parent, next, prev };
4979
- strategy.write(id, node);
4979
+ return node;
4980
+ },
4981
+ updateNode() {
4982
+ },
4983
+ deleteNode() {
4984
+ },
4985
+ readHead() {
4986
+ return strategy.readHead();
4987
+ },
4988
+ writeHead() {
4989
+ }
4990
+ };
4991
+ }
4992
+ _createBufferedOps() {
4993
+ const strategy = this.strategy;
4994
+ const writeBuffer = /* @__PURE__ */ new Map();
4995
+ const deleteBuffer = /* @__PURE__ */ new Set();
4996
+ let headBuffer = null;
4997
+ const ops = {
4998
+ getNode(id) {
4999
+ const buffered = writeBuffer.get(id);
5000
+ if (buffered) return buffered;
5001
+ return strategy.read(id);
5002
+ },
5003
+ createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5004
+ const id = strategy.id(leaf);
5005
+ const node = { id, keys, values, leaf, parent, next, prev };
5006
+ writeBuffer.set(id, node);
4980
5007
  return node;
4981
5008
  },
4982
5009
  updateNode(node) {
4983
- strategy.write(node.id, node);
5010
+ writeBuffer.set(node.id, node);
4984
5011
  },
4985
5012
  deleteNode(node) {
4986
- strategy.delete(node.id);
5013
+ deleteBuffer.add(node.id);
5014
+ writeBuffer.delete(node.id);
4987
5015
  },
4988
5016
  readHead() {
5017
+ if (headBuffer) return headBuffer;
4989
5018
  return strategy.readHead();
4990
5019
  },
4991
5020
  writeHead(head) {
4992
- strategy.writeHead(head);
5021
+ headBuffer = head;
4993
5022
  }
4994
5023
  };
5024
+ function flush() {
5025
+ for (const id of deleteBuffer) {
5026
+ strategy.delete(id);
5027
+ }
5028
+ for (const [id, node] of writeBuffer) {
5029
+ strategy.write(id, node);
5030
+ }
5031
+ if (headBuffer) {
5032
+ strategy.writeHead(headBuffer);
5033
+ }
5034
+ }
5035
+ return { ops, flush };
4995
5036
  }
4996
5037
  init() {
4997
- this._ops = this._createOps();
5038
+ const { ops, flush } = this._createBufferedOps();
4998
5039
  this._ctx = {
4999
5040
  rootId: "",
5000
5041
  order: this.strategy.order,
5001
5042
  headData: () => this.strategy.head.data
5002
5043
  };
5003
5044
  initOp(
5004
- this._ops,
5045
+ ops,
5005
5046
  this._ctx,
5006
5047
  this.strategy.order,
5007
5048
  this.strategy.head,
@@ -5009,6 +5050,8 @@ var BPTreePureSync = class {
5009
5050
  this.strategy.head = head;
5010
5051
  }
5011
5052
  );
5053
+ flush();
5054
+ this._ops = this._createOps();
5012
5055
  }
5013
5056
  /**
5014
5057
  * Returns the ID of the root node.
@@ -5082,16 +5125,24 @@ var BPTreePureSync = class {
5082
5125
  }
5083
5126
  // ─── Mutation ────────────────────────────────────────────────────
5084
5127
  insert(key, value) {
5085
- insertOp(this._ops, this._ctx, key, value, this.comparator);
5128
+ const { ops, flush } = this._createBufferedOps();
5129
+ insertOp(ops, this._ctx, key, value, this.comparator);
5130
+ flush();
5086
5131
  }
5087
5132
  delete(key, value) {
5088
- deleteOp(this._ops, this._ctx, key, this.comparator, value);
5133
+ const { ops, flush } = this._createBufferedOps();
5134
+ deleteOp(ops, this._ctx, key, this.comparator, value);
5135
+ flush();
5089
5136
  }
5090
5137
  batchInsert(entries) {
5091
- batchInsertOp(this._ops, this._ctx, entries, this.comparator);
5138
+ const { ops, flush } = this._createBufferedOps();
5139
+ batchInsertOp(ops, this._ctx, entries, this.comparator);
5140
+ flush();
5092
5141
  }
5093
5142
  bulkLoad(entries) {
5094
- bulkLoadOp(this._ops, this._ctx, entries, this.comparator);
5143
+ const { ops, flush } = this._createBufferedOps();
5144
+ bulkLoadOp(ops, this._ctx, entries, this.comparator);
5145
+ flush();
5095
5146
  }
5096
5147
  // ─── Head Data ───────────────────────────────────────────────────
5097
5148
  getHeadData() {
@@ -5102,15 +5153,17 @@ var BPTreePureSync = class {
5102
5153
  return head.data;
5103
5154
  }
5104
5155
  setHeadData(data) {
5105
- const head = this._ops.readHead();
5156
+ const { ops, flush } = this._createBufferedOps();
5157
+ const head = ops.readHead();
5106
5158
  if (head === null) {
5107
5159
  throw new Error("Head not found");
5108
5160
  }
5109
- this._ops.writeHead({
5161
+ ops.writeHead({
5110
5162
  root: head.root,
5111
5163
  order: head.order,
5112
5164
  data
5113
5165
  });
5166
+ flush();
5114
5167
  }
5115
5168
  // ─── Static utilities ────────────────────────────────────────────
5116
5169
  static ChooseDriver = BPTreeTransaction.ChooseDriver;
@@ -5121,6 +5174,7 @@ var BPTreePureAsync = class {
5121
5174
  strategy;
5122
5175
  comparator;
5123
5176
  option;
5177
+ lock = new Ryoiki2();
5124
5178
  _cachedRegexp = /* @__PURE__ */ new Map();
5125
5179
  _ctx;
5126
5180
  _ops;
@@ -5146,39 +5200,93 @@ var BPTreePureAsync = class {
5146
5200
  async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5147
5201
  const id = await strategy.id(leaf);
5148
5202
  const node = { id, keys, values, leaf, parent, next, prev };
5149
- await strategy.write(id, node);
5203
+ return node;
5204
+ },
5205
+ async updateNode() {
5206
+ },
5207
+ async deleteNode() {
5208
+ },
5209
+ async readHead() {
5210
+ return await strategy.readHead();
5211
+ },
5212
+ async writeHead() {
5213
+ }
5214
+ };
5215
+ }
5216
+ _createBufferedOps() {
5217
+ const strategy = this.strategy;
5218
+ const writeBuffer = /* @__PURE__ */ new Map();
5219
+ const deleteBuffer = /* @__PURE__ */ new Set();
5220
+ let headBuffer = null;
5221
+ const ops = {
5222
+ async getNode(id) {
5223
+ const buffered = writeBuffer.get(id);
5224
+ if (buffered) return buffered;
5225
+ return await strategy.read(id);
5226
+ },
5227
+ async createNode(leaf, keys, values, parent = null, next = null, prev = null) {
5228
+ const id = await strategy.id(leaf);
5229
+ const node = { id, keys, values, leaf, parent, next, prev };
5230
+ writeBuffer.set(id, node);
5150
5231
  return node;
5151
5232
  },
5152
5233
  async updateNode(node) {
5153
- await strategy.write(node.id, node);
5234
+ writeBuffer.set(node.id, node);
5154
5235
  },
5155
5236
  async deleteNode(node) {
5156
- await strategy.delete(node.id);
5237
+ deleteBuffer.add(node.id);
5238
+ writeBuffer.delete(node.id);
5157
5239
  },
5158
5240
  async readHead() {
5241
+ if (headBuffer) return headBuffer;
5159
5242
  return await strategy.readHead();
5160
5243
  },
5161
5244
  async writeHead(head) {
5162
- await strategy.writeHead(head);
5245
+ headBuffer = head;
5163
5246
  }
5164
5247
  };
5248
+ async function flush() {
5249
+ for (const id of deleteBuffer) {
5250
+ await strategy.delete(id);
5251
+ }
5252
+ for (const [id, node] of writeBuffer) {
5253
+ await strategy.write(id, node);
5254
+ }
5255
+ if (headBuffer) {
5256
+ await strategy.writeHead(headBuffer);
5257
+ }
5258
+ }
5259
+ return { ops, flush };
5260
+ }
5261
+ async writeLock(fn) {
5262
+ let lockId;
5263
+ return this.lock.writeLock(async (_lockId) => {
5264
+ lockId = _lockId;
5265
+ return fn();
5266
+ }).finally(() => {
5267
+ this.lock.writeUnlock(lockId);
5268
+ });
5165
5269
  }
5166
5270
  async init() {
5167
- this._ops = this._createOps();
5168
- this._ctx = {
5169
- rootId: "",
5170
- order: this.strategy.order,
5171
- headData: () => this.strategy.head.data
5172
- };
5173
- await initOpAsync(
5174
- this._ops,
5175
- this._ctx,
5176
- this.strategy.order,
5177
- this.strategy.head,
5178
- (head) => {
5179
- this.strategy.head = head;
5180
- }
5181
- );
5271
+ return this.writeLock(async () => {
5272
+ const { ops, flush } = this._createBufferedOps();
5273
+ this._ctx = {
5274
+ rootId: "",
5275
+ order: this.strategy.order,
5276
+ headData: () => this.strategy.head.data
5277
+ };
5278
+ await initOpAsync(
5279
+ ops,
5280
+ this._ctx,
5281
+ this.strategy.order,
5282
+ this.strategy.head,
5283
+ (head) => {
5284
+ this.strategy.head = head;
5285
+ }
5286
+ );
5287
+ await flush();
5288
+ this._ops = this._createOps();
5289
+ });
5182
5290
  }
5183
5291
  getRootId() {
5184
5292
  return this._ctx.rootId;
@@ -5202,28 +5310,40 @@ var BPTreePureAsync = class {
5202
5310
  return existsOpAsync(this._ops, this._ctx.rootId, key, value, this.comparator);
5203
5311
  }
5204
5312
  async *keysStream(condition, options) {
5205
- yield* keysStreamOpAsync(
5206
- this._ops,
5207
- this._ctx.rootId,
5208
- condition,
5209
- this.comparator,
5210
- this._verifierMap,
5211
- this._searchConfigs,
5212
- this._ensureValues,
5213
- options
5214
- );
5313
+ let lockId;
5314
+ try {
5315
+ lockId = await this.lock.readLock([0, 0.1], async (id) => id);
5316
+ yield* keysStreamOpAsync(
5317
+ this._ops,
5318
+ this._ctx.rootId,
5319
+ condition,
5320
+ this.comparator,
5321
+ this._verifierMap,
5322
+ this._searchConfigs,
5323
+ this._ensureValues,
5324
+ options
5325
+ );
5326
+ } finally {
5327
+ if (lockId) this.lock.readUnlock(lockId);
5328
+ }
5215
5329
  }
5216
5330
  async *whereStream(condition, options) {
5217
- yield* whereStreamOpAsync(
5218
- this._ops,
5219
- this._ctx.rootId,
5220
- condition,
5221
- this.comparator,
5222
- this._verifierMap,
5223
- this._searchConfigs,
5224
- this._ensureValues,
5225
- options
5226
- );
5331
+ let lockId;
5332
+ try {
5333
+ lockId = await this.lock.readLock([0, 0.1], async (id) => id);
5334
+ yield* whereStreamOpAsync(
5335
+ this._ops,
5336
+ this._ctx.rootId,
5337
+ condition,
5338
+ this.comparator,
5339
+ this._verifierMap,
5340
+ this._searchConfigs,
5341
+ this._ensureValues,
5342
+ options
5343
+ );
5344
+ } finally {
5345
+ if (lockId) this.lock.readUnlock(lockId);
5346
+ }
5227
5347
  }
5228
5348
  async keys(condition, options) {
5229
5349
  const set = /* @__PURE__ */ new Set();
@@ -5241,16 +5361,32 @@ var BPTreePureAsync = class {
5241
5361
  }
5242
5362
  // ─── Mutation ────────────────────────────────────────────────────
5243
5363
  async insert(key, value) {
5244
- await insertOpAsync(this._ops, this._ctx, key, value, this.comparator);
5364
+ return this.writeLock(async () => {
5365
+ const { ops, flush } = this._createBufferedOps();
5366
+ await insertOpAsync(ops, this._ctx, key, value, this.comparator);
5367
+ await flush();
5368
+ });
5245
5369
  }
5246
5370
  async delete(key, value) {
5247
- await deleteOpAsync(this._ops, this._ctx, key, this.comparator, value);
5371
+ return this.writeLock(async () => {
5372
+ const { ops, flush } = this._createBufferedOps();
5373
+ await deleteOpAsync(ops, this._ctx, key, this.comparator, value);
5374
+ await flush();
5375
+ });
5248
5376
  }
5249
5377
  async batchInsert(entries) {
5250
- await batchInsertOpAsync(this._ops, this._ctx, entries, this.comparator);
5378
+ return this.writeLock(async () => {
5379
+ const { ops, flush } = this._createBufferedOps();
5380
+ await batchInsertOpAsync(ops, this._ctx, entries, this.comparator);
5381
+ await flush();
5382
+ });
5251
5383
  }
5252
5384
  async bulkLoad(entries) {
5253
- await bulkLoadOpAsync(this._ops, this._ctx, entries, this.comparator);
5385
+ return this.writeLock(async () => {
5386
+ const { ops, flush } = this._createBufferedOps();
5387
+ await bulkLoadOpAsync(ops, this._ctx, entries, this.comparator);
5388
+ await flush();
5389
+ });
5254
5390
  }
5255
5391
  // ─── Head Data ───────────────────────────────────────────────────
5256
5392
  async getHeadData() {
@@ -5259,9 +5395,13 @@ var BPTreePureAsync = class {
5259
5395
  return head.data;
5260
5396
  }
5261
5397
  async setHeadData(data) {
5262
- const head = await this._ops.readHead();
5263
- if (head === null) throw new Error("Head not found");
5264
- await this._ops.writeHead({ root: head.root, order: head.order, data });
5398
+ return this.writeLock(async () => {
5399
+ const { ops, flush } = this._createBufferedOps();
5400
+ const head = await ops.readHead();
5401
+ if (head === null) throw new Error("Head not found");
5402
+ await ops.writeHead({ root: head.root, order: head.order, data });
5403
+ await flush();
5404
+ });
5265
5405
  }
5266
5406
  // ─── Static utilities ────────────────────────────────────────────
5267
5407
  static ChooseDriver = BPTreeTransaction.ChooseDriver;
@@ -2,10 +2,12 @@ import type { BPTreeCondition, BPTreeConstructorOption, BPTreePair, BPTreeSearch
2
2
  import { SerializeStrategyAsync } from './SerializeStrategyAsync';
3
3
  import { ValueComparator } from './base/ValueComparator';
4
4
  import { BPTreeTransaction } from './base/BPTreeTransaction';
5
+ import { Ryoiki } from 'ryoiki';
5
6
  export declare class BPTreePureAsync<K, V> {
6
7
  protected readonly strategy: SerializeStrategyAsync<K, V>;
7
8
  protected readonly comparator: ValueComparator<V>;
8
9
  protected readonly option: BPTreeConstructorOption;
10
+ protected readonly lock: Ryoiki;
9
11
  private readonly _cachedRegexp;
10
12
  private _ctx;
11
13
  private _ops;
@@ -14,6 +16,8 @@ export declare class BPTreePureAsync<K, V> {
14
16
  constructor(strategy: SerializeStrategyAsync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
15
17
  private _ensureValues;
16
18
  private _createOps;
19
+ private _createBufferedOps;
20
+ protected writeLock<T>(fn: () => Promise<T>): Promise<T>;
17
21
  init(): Promise<void>;
18
22
  getRootId(): string;
19
23
  getOrder(): number;
@@ -14,6 +14,7 @@ export declare class BPTreePureSync<K, V> {
14
14
  constructor(strategy: SerializeStrategySync<K, V>, comparator: ValueComparator<V>, option?: BPTreeConstructorOption);
15
15
  private _ensureValues;
16
16
  private _createOps;
17
+ private _createBufferedOps;
17
18
  init(): void;
18
19
  /**
19
20
  * Returns the ID of the root node.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serializable-bptree",
3
- "version": "9.0.0",
3
+ "version": "9.0.1",
4
4
  "description": "Store the B+tree flexibly, not only in-memory.",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "main": "./dist/cjs/index.cjs",