xitdb 0.8.0 → 0.9.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 CHANGED
@@ -59,27 +59,27 @@ const history = await WriteArrayList.create(db.rootCursor());
59
59
  await history.appendContext(await history.getSlot(-1), async (cursor) => {
60
60
  const moment = await WriteHashMap.create(cursor);
61
61
 
62
- await moment.putByString('foo', new Bytes('foo'));
63
- await moment.putByString('bar', new Bytes('bar'));
62
+ await moment.put('foo', new Bytes('foo'));
63
+ await moment.put('bar', new Bytes('bar'));
64
64
 
65
- const fruitsCursor = await moment.putCursorByString('fruits');
65
+ const fruitsCursor = await moment.putCursor('fruits');
66
66
  const fruits = await WriteArrayList.create(fruitsCursor);
67
67
  await fruits.append(new Bytes('apple'));
68
68
  await fruits.append(new Bytes('pear'));
69
69
  await fruits.append(new Bytes('grape'));
70
70
 
71
- const peopleCursor = await moment.putCursorByString('people');
71
+ const peopleCursor = await moment.putCursor('people');
72
72
  const people = await WriteArrayList.create(peopleCursor);
73
73
 
74
74
  const aliceCursor = await people.appendCursor();
75
75
  const alice = await WriteHashMap.create(aliceCursor);
76
- await alice.putByString('name', new Bytes('Alice'));
77
- await alice.putByString('age', new Uint(25));
76
+ await alice.put('name', new Bytes('Alice'));
77
+ await alice.put('age', new Uint(25));
78
78
 
79
79
  const bobCursor = await people.appendCursor();
80
80
  const bob = await WriteHashMap.create(bobCursor);
81
- await bob.putByString('name', new Bytes('Bob'));
82
- await bob.putByString('age', new Uint(42));
81
+ await bob.put('name', new Bytes('Bob'));
82
+ await bob.put('age', new Uint(42));
83
83
  });
84
84
 
85
85
  // get the most recent copy of the database, like a moment
@@ -89,13 +89,13 @@ const moment = await ReadHashMap.create(momentCursor!);
89
89
 
90
90
  // we can read the value of "foo" from the map by getting
91
91
  // the cursor to "foo" and then calling readBytes on it
92
- const fooCursor = await moment.getCursorByString('foo');
92
+ const fooCursor = await moment.getCursor('foo');
93
93
  const fooValue = await fooCursor!.readBytes(MAX_READ_BYTES);
94
94
  expect(new TextDecoder().decode(fooValue)).toBe('foo');
95
95
 
96
96
  // to get the "fruits" list, we get the cursor to it and
97
97
  // then pass it to the ReadArrayList constructor
98
- const fruitsCursor = await moment.getCursorByString('fruits');
98
+ const fruitsCursor = await moment.getCursor('fruits');
99
99
  const fruits = new ReadArrayList(fruitsCursor!);
100
100
  expect(await fruits.count()).toBe(3);
101
101
 
@@ -143,13 +143,13 @@ In xitdb, you can optionally store a format tag with a byte array. A format tag
143
143
  ```typescript
144
144
  const randomBytes = new Uint8Array(32);
145
145
  crypto.getRandomValues(randomBytes);
146
- await moment.putByString('random-number', new Bytes(randomBytes, new TextEncoder().encode('bi')));
146
+ await moment.put('random-number', new Bytes(randomBytes, new TextEncoder().encode('bi')));
147
147
  ```
148
148
 
149
149
  Then, you can read it like this:
150
150
 
151
151
  ```typescript
152
- const randomNumberCursor = await moment.getCursorByString('random-number');
152
+ const randomNumberCursor = await moment.getCursor('random-number');
153
153
  const randomNumber = await randomNumberCursor!.readBytesObject(MAX_READ_BYTES);
154
154
  expect(new TextDecoder().decode(randomNumber.formatTag!)).toBe('bi');
155
155
  const randomBigInt = randomNumber.value;
@@ -165,12 +165,12 @@ A powerful feature of immutable data is fast cloning. Any data structure can be
165
165
  await history.appendContext(await history.getSlot(-1), async (cursor) => {
166
166
  const moment = await WriteHashMap.create(cursor);
167
167
 
168
- const fruitsCursor = await moment.getCursorByString('fruits');
168
+ const fruitsCursor = await moment.getCursor('fruits');
169
169
  const fruits = new ReadArrayList(fruitsCursor!);
170
170
 
171
171
  // create a new key called "food" whose initial value is
172
172
  // based on the "fruits" list
173
- const foodCursor = await moment.putCursorByString('food');
173
+ const foodCursor = await moment.putCursor('food');
174
174
  await foodCursor.write(fruits.slot());
175
175
 
176
176
  const food = await WriteArrayList.create(foodCursor);
@@ -183,12 +183,12 @@ const momentCursor = await history.getCursor(-1);
183
183
  const moment = await ReadHashMap.create(momentCursor!);
184
184
 
185
185
  // the food list includes the fruits
186
- const foodCursor = await moment.getCursorByString('food');
186
+ const foodCursor = await moment.getCursor('food');
187
187
  const food = new ReadArrayList(foodCursor!);
188
188
  expect(await food.count()).toBe(6);
189
189
 
190
190
  // ...but the fruits list hasn't been changed
191
- const fruitsCursor = await moment.getCursorByString('fruits');
191
+ const fruitsCursor = await moment.getCursor('fruits');
192
192
  const fruits = new ReadArrayList(fruitsCursor!);
193
193
  expect(await fruits.count()).toBe(3);
194
194
  ```
@@ -205,14 +205,14 @@ There's one catch you'll run into when cloning. If we try cloning a data structu
205
205
  await history.appendContext(await history.getSlot(-1), async (cursor) => {
206
206
  const moment = await WriteHashMap.create(cursor);
207
207
 
208
- const bigCitiesCursor = await moment.putCursorByString('big-cities');
208
+ const bigCitiesCursor = await moment.putCursor('big-cities');
209
209
  const bigCities = await WriteArrayList.create(bigCitiesCursor);
210
210
  await bigCities.append(new Bytes('New York, NY'));
211
211
  await bigCities.append(new Bytes('Los Angeles, CA'));
212
212
 
213
213
  // create a new key called "cities" whose initial value is
214
214
  // based on the "big-cities" list
215
- const citiesCursor = await moment.putCursorByString('cities');
215
+ const citiesCursor = await moment.putCursor('cities');
216
216
  await citiesCursor.write(bigCities.slot());
217
217
 
218
218
  const cities = await WriteArrayList.create(citiesCursor);
@@ -224,12 +224,12 @@ const momentCursor = await history.getCursor(-1);
224
224
  const moment = await ReadHashMap.create(momentCursor!);
225
225
 
226
226
  // the cities list contains all four
227
- const citiesCursor = await moment.getCursorByString('cities');
227
+ const citiesCursor = await moment.getCursor('cities');
228
228
  const cities = new ReadArrayList(citiesCursor!);
229
229
  expect(await cities.count()).toBe(4);
230
230
 
231
231
  // ..but so does big-cities! we did not intend to mutate this
232
- const bigCitiesCursor = await moment.getCursorByString('big-cities');
232
+ const bigCitiesCursor = await moment.getCursor('big-cities');
233
233
  const bigCities = new ReadArrayList(bigCitiesCursor!);
234
234
  expect(await bigCities.count()).toBe(4);
235
235
  ```
@@ -248,7 +248,7 @@ This time, after making the "big cities" list, we call `freeze`, which tells xit
248
248
  await history.appendContext(await history.getSlot(-1), async (cursor) => {
249
249
  const moment = await WriteHashMap.create(cursor);
250
250
 
251
- const bigCitiesCursor = await moment.putCursorByString('big-cities');
251
+ const bigCitiesCursor = await moment.putCursor('big-cities');
252
252
  const bigCities = await WriteArrayList.create(bigCitiesCursor);
253
253
  await bigCities.append(new Bytes('New York, NY'));
254
254
  await bigCities.append(new Bytes('Los Angeles, CA'));
@@ -258,7 +258,7 @@ await history.appendContext(await history.getSlot(-1), async (cursor) => {
258
258
 
259
259
  // create a new key called "cities" whose initial value is
260
260
  // based on the "big-cities" list
261
- const citiesCursor = await moment.putCursorByString('cities');
261
+ const citiesCursor = await moment.putCursor('cities');
262
262
  await citiesCursor.write(bigCities.slot());
263
263
 
264
264
  const cities = await WriteArrayList.create(citiesCursor);
@@ -270,12 +270,12 @@ const momentCursor = await history.getCursor(-1);
270
270
  const moment = await ReadHashMap.create(momentCursor!);
271
271
 
272
272
  // the cities list contains all four
273
- const citiesCursor = await moment.getCursorByString('cities');
273
+ const citiesCursor = await moment.getCursor('cities');
274
274
  const cities = new ReadArrayList(citiesCursor!);
275
275
  expect(await cities.count()).toBe(4);
276
276
 
277
277
  // and big-cities only contains the original two
278
- const bigCitiesCursor = await moment.getCursorByString('big-cities');
278
+ const bigCitiesCursor = await moment.getCursor('big-cities');
279
279
  const bigCities = new ReadArrayList(bigCitiesCursor!);
280
280
  expect(await bigCities.count()).toBe(2);
281
281
  ```
@@ -285,7 +285,7 @@ expect(await bigCities.count()).toBe(2);
285
285
  When reading and writing large byte arrays, you probably don't want to have all of their contents in memory at once. To incrementally write to a byte array, just get a writer from a cursor:
286
286
 
287
287
  ```typescript
288
- const longTextCursor = await moment.putCursorByString('long-text');
288
+ const longTextCursor = await moment.putCursor('long-text');
289
289
  const cursorWriter = await longTextCursor.writer();
290
290
  for (let i = 0; i < 50; i++) {
291
291
  await cursorWriter.write(new TextEncoder().encode('hello, world\n'));
@@ -298,7 +298,7 @@ If you need to set a format tag for the byte array, put it in the `formatTag` fi
298
298
  To read a byte array incrementally, get a reader from a cursor:
299
299
 
300
300
  ```typescript
301
- const longTextCursor = await moment.getCursorByString('long-text');
301
+ const longTextCursor = await moment.getCursor('long-text');
302
302
  const cursorReader = await longTextCursor!.reader();
303
303
  let lineCount = 0, line: number[] = [];
304
304
  const buf = new Uint8Array(1024);
@@ -317,7 +317,7 @@ expect(lineCount).toBe(50);
317
317
  All data structures support iteration. Here's an example of iterating over an `ArrayList` and printing all of the keys and values of each `HashMap` contained in it:
318
318
 
319
319
  ```typescript
320
- const peopleCursor = await moment.getCursorByString('people');
320
+ const peopleCursor = await moment.getCursor('people');
321
321
  const people = new ReadArrayList(peopleCursor!);
322
322
 
323
323
  const peopleIter = await people.iterator();
@@ -356,7 +356,7 @@ The iteration of the `HashMap` looks the same with `HashSet`, `CountedHashMap`,
356
356
 
357
357
  ## Hashing
358
358
 
359
- The hashing data structures will create the hash for you when you call methods like `putByString` or `getCursorByString` and provide the key as a string. If you want to do the hashing yourself, there are methods like `put` and `getCursor` that take a `Uint8Array` as the key, which should be the hash that you computed.
359
+ The hashing data structures will create the hash for you when you call methods like `put` or `getCursor` and provide the key as a string or `Bytes`. If you want to do the hashing yourself, there is an overload of those methods that take a `Uint8Array` as the key, which should be the hash that you computed.
360
360
 
361
361
  When initializing a database, you tell xitdb how to hash with the `Hasher`. If you're using SHA-1, it will look like this:
362
362
 
package/dist/index.js CHANGED
@@ -3243,59 +3243,24 @@ class ReadHashMap {
3243
3243
  async* [Symbol.asyncIterator]() {
3244
3244
  yield* this.cursor;
3245
3245
  }
3246
- async getCursorByString(key) {
3247
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3248
- return this.getCursor(hash);
3249
- }
3250
- async getSlotByString(key) {
3251
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3252
- return this.getSlot(hash);
3253
- }
3254
- async getKeyCursorByString(key) {
3255
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3256
- return this.getKeyCursor(hash);
3257
- }
3258
- async getKeySlotByString(key) {
3259
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3260
- return this.getKeySlot(hash);
3261
- }
3262
- async getKeyValuePairByString(key) {
3263
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3264
- return this.getKeyValuePair(hash);
3265
- }
3266
- async getCursorByBytes(key) {
3267
- const hash = await this.cursor.db.hasher.digest(key.value);
3268
- return this.getCursor(hash);
3269
- }
3270
- async getSlotByBytes(key) {
3271
- const hash = await this.cursor.db.hasher.digest(key.value);
3272
- return this.getSlot(hash);
3273
- }
3274
- async getKeyCursorByBytes(key) {
3275
- const hash = await this.cursor.db.hasher.digest(key.value);
3276
- return this.getKeyCursor(hash);
3277
- }
3278
- async getKeySlotByBytes(key) {
3279
- const hash = await this.cursor.db.hasher.digest(key.value);
3280
- return this.getKeySlot(hash);
3281
- }
3282
- async getKeyValuePairByBytes(key) {
3283
- const hash = await this.cursor.db.hasher.digest(key.value);
3284
- return this.getKeyValuePair(hash);
3285
- }
3286
- async getCursor(hash) {
3246
+ async getCursor(key) {
3247
+ const hash = await this.resolveHash(key);
3287
3248
  return this.cursor.readPath([new HashMapGet(new HashMapGetValue(hash))]);
3288
3249
  }
3289
- async getSlot(hash) {
3250
+ async getSlot(key) {
3251
+ const hash = await this.resolveHash(key);
3290
3252
  return this.cursor.readPathSlot([new HashMapGet(new HashMapGetValue(hash))]);
3291
3253
  }
3292
- async getKeyCursor(hash) {
3254
+ async getKeyCursor(key) {
3255
+ const hash = await this.resolveHash(key);
3293
3256
  return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
3294
3257
  }
3295
- async getKeySlot(hash) {
3258
+ async getKeySlot(key) {
3259
+ const hash = await this.resolveHash(key);
3296
3260
  return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
3297
3261
  }
3298
- async getKeyValuePair(hash) {
3262
+ async getKeyValuePair(key) {
3263
+ const hash = await this.resolveHash(key);
3299
3264
  const cursor = await this.cursor.readPath([new HashMapGet(new HashMapGetKVPair(hash))]);
3300
3265
  if (cursor === null) {
3301
3266
  return null;
@@ -3303,6 +3268,15 @@ class ReadHashMap {
3303
3268
  return cursor.readKeyValuePair();
3304
3269
  }
3305
3270
  }
3271
+ async resolveHash(key) {
3272
+ if (key instanceof Uint8Array) {
3273
+ return key;
3274
+ } else if (typeof key === "string") {
3275
+ return this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3276
+ } else {
3277
+ return this.cursor.db.hasher.digest(key.value);
3278
+ }
3279
+ }
3306
3280
  }
3307
3281
  // src/write-hash-map.ts
3308
3282
  class WriteHashMap extends ReadHashMap {
@@ -3321,83 +3295,74 @@ class WriteHashMap extends ReadHashMap {
3321
3295
  async* [Symbol.asyncIterator]() {
3322
3296
  yield* this.cursor;
3323
3297
  }
3324
- async putByString(key, data) {
3325
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3326
- await this.putKey(hash, new Bytes(key));
3327
- await this.put(hash, data);
3328
- }
3329
- async putCursorByString(key) {
3330
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3331
- await this.putKey(hash, new Bytes(key));
3332
- return this.putCursor(hash);
3333
- }
3334
- async putKeyByString(key, data) {
3335
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3336
- await this.putKey(hash, data);
3337
- }
3338
- async putKeyCursorByString(key) {
3339
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3340
- return this.putKeyCursor(hash);
3341
- }
3342
- async removeByString(key) {
3343
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3344
- return this.remove(hash);
3345
- }
3346
- async putByBytes(key, data) {
3347
- const hash = await this.cursor.db.hasher.digest(key.value);
3348
- await this.putKey(hash, key);
3349
- await this.put(hash, data);
3350
- }
3351
- async putCursorByBytes(key) {
3352
- const hash = await this.cursor.db.hasher.digest(key.value);
3353
- await this.putKey(hash, key);
3354
- return this.putCursor(hash);
3298
+ async put(key, data) {
3299
+ if (typeof key === "string") {
3300
+ const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3301
+ await this.putKeyInternal(hash, new Bytes(key));
3302
+ await this.putInternal(hash, data);
3303
+ } else if (key instanceof Bytes) {
3304
+ const hash = await this.cursor.db.hasher.digest(key.value);
3305
+ await this.putKeyInternal(hash, key);
3306
+ await this.putInternal(hash, data);
3307
+ } else {
3308
+ await this.putInternal(key, data);
3309
+ }
3310
+ }
3311
+ async putCursor(key) {
3312
+ if (typeof key === "string") {
3313
+ const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3314
+ await this.putKeyInternal(hash, new Bytes(key));
3315
+ return this.putCursorInternal(hash);
3316
+ } else if (key instanceof Bytes) {
3317
+ const hash = await this.cursor.db.hasher.digest(key.value);
3318
+ await this.putKeyInternal(hash, key);
3319
+ return this.putCursorInternal(hash);
3320
+ } else {
3321
+ return this.putCursorInternal(key);
3322
+ }
3355
3323
  }
3356
- async putKeyByBytes(key, data) {
3357
- const hash = await this.cursor.db.hasher.digest(key.value);
3358
- await this.putKey(hash, data);
3324
+ async putKey(key, data) {
3325
+ const hash = await this.resolveHash(key);
3326
+ await this.putKeyInternal(hash, data);
3359
3327
  }
3360
- async putKeyCursorByBytes(key) {
3361
- const hash = await this.cursor.db.hasher.digest(key.value);
3362
- return this.putKeyCursor(hash);
3328
+ async putKeyCursor(key) {
3329
+ const hash = await this.resolveHash(key);
3330
+ return this.putKeyCursorInternal(hash);
3363
3331
  }
3364
- async removeByBytes(key) {
3365
- const hash = await this.cursor.db.hasher.digest(key.value);
3366
- return this.remove(hash);
3332
+ async remove(key) {
3333
+ const hash = await this.resolveHash(key);
3334
+ try {
3335
+ await this.cursor.writePath([new HashMapRemove(hash)]);
3336
+ } catch (e) {
3337
+ if (e instanceof KeyNotFoundException) {
3338
+ return false;
3339
+ }
3340
+ throw e;
3341
+ }
3342
+ return true;
3367
3343
  }
3368
- async put(hash, data) {
3344
+ async putInternal(hash, data) {
3369
3345
  await this.cursor.writePath([
3370
3346
  new HashMapGet(new HashMapGetValue(hash)),
3371
3347
  new WriteData(data)
3372
3348
  ]);
3373
3349
  }
3374
- async putCursor(hash) {
3350
+ async putCursorInternal(hash) {
3375
3351
  return this.cursor.writePath([
3376
3352
  new HashMapGet(new HashMapGetValue(hash))
3377
3353
  ]);
3378
3354
  }
3379
- async putKey(hash, data) {
3355
+ async putKeyInternal(hash, data) {
3380
3356
  const cursor = await this.cursor.writePath([
3381
3357
  new HashMapGet(new HashMapGetKey(hash))
3382
3358
  ]);
3383
3359
  await cursor.writeIfEmpty(data);
3384
3360
  }
3385
- async putKeyCursor(hash) {
3361
+ async putKeyCursorInternal(hash) {
3386
3362
  return this.cursor.writePath([
3387
3363
  new HashMapGet(new HashMapGetKey(hash))
3388
3364
  ]);
3389
3365
  }
3390
- async remove(hash) {
3391
- try {
3392
- await this.cursor.writePath([new HashMapRemove(hash)]);
3393
- } catch (e) {
3394
- if (e instanceof KeyNotFoundException) {
3395
- return false;
3396
- }
3397
- throw e;
3398
- }
3399
- return true;
3400
- }
3401
3366
  }
3402
3367
  // src/read-hash-set.ts
3403
3368
  class ReadHashSet {
@@ -3425,28 +3390,23 @@ class ReadHashSet {
3425
3390
  async* [Symbol.asyncIterator]() {
3426
3391
  yield* this.cursor;
3427
3392
  }
3428
- async getCursorByString(key) {
3429
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3430
- return this.getCursor(hash);
3431
- }
3432
- async getSlotByString(key) {
3433
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3434
- return this.getSlot(hash);
3435
- }
3436
- async getCursorByBytes(key) {
3437
- const hash = await this.cursor.db.hasher.digest(key.value);
3438
- return this.getCursor(hash);
3439
- }
3440
- async getSlotByBytes(key) {
3441
- const hash = await this.cursor.db.hasher.digest(key.value);
3442
- return this.getSlot(hash);
3443
- }
3444
- async getCursor(hash) {
3393
+ async getCursor(key) {
3394
+ const hash = await this.resolveHash(key);
3445
3395
  return this.cursor.readPath([new HashMapGet(new HashMapGetKey(hash))]);
3446
3396
  }
3447
- async getSlot(hash) {
3397
+ async getSlot(key) {
3398
+ const hash = await this.resolveHash(key);
3448
3399
  return this.cursor.readPathSlot([new HashMapGet(new HashMapGetKey(hash))]);
3449
3400
  }
3401
+ async resolveHash(key) {
3402
+ if (key instanceof Uint8Array) {
3403
+ return key;
3404
+ } else if (typeof key === "string") {
3405
+ return this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3406
+ } else {
3407
+ return this.cursor.db.hasher.digest(key.value);
3408
+ }
3409
+ }
3450
3410
  }
3451
3411
  // src/write-hash-set.ts
3452
3412
  class WriteHashSet extends ReadHashSet {
@@ -3465,43 +3425,24 @@ class WriteHashSet extends ReadHashSet {
3465
3425
  async* [Symbol.asyncIterator]() {
3466
3426
  yield* this.cursor;
3467
3427
  }
3468
- async putByString(key) {
3469
- const bytes = new TextEncoder().encode(key);
3470
- const hash = await this.cursor.db.hasher.digest(bytes);
3471
- await this.put(hash, new Bytes(bytes));
3472
- }
3473
- async putCursorByString(key) {
3474
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3475
- return this.putCursor(hash);
3476
- }
3477
- async removeByString(key) {
3478
- const hash = await this.cursor.db.hasher.digest(new TextEncoder().encode(key));
3479
- return this.remove(hash);
3480
- }
3481
- async putByBytes(key) {
3482
- const hash = await this.cursor.db.hasher.digest(key.value);
3483
- await this.put(hash, key);
3484
- }
3485
- async putCursorByBytes(key) {
3486
- const hash = await this.cursor.db.hasher.digest(key.value);
3487
- return this.putCursor(hash);
3488
- }
3489
- async removeByBytes(key) {
3490
- const hash = await this.cursor.db.hasher.digest(key.value);
3491
- return this.remove(hash);
3492
- }
3493
- async put(hash, data) {
3494
- const cursor = await this.cursor.writePath([
3495
- new HashMapGet(new HashMapGetKey(hash))
3496
- ]);
3497
- await cursor.writeIfEmpty(data);
3428
+ async put(key, data) {
3429
+ if (typeof key === "string") {
3430
+ const bytes = new TextEncoder().encode(key);
3431
+ const hash = await this.cursor.db.hasher.digest(bytes);
3432
+ await this.putInternal(hash, new Bytes(bytes));
3433
+ } else if (key instanceof Bytes) {
3434
+ const hash = await this.cursor.db.hasher.digest(key.value);
3435
+ await this.putInternal(hash, key);
3436
+ } else {
3437
+ await this.putInternal(key, data);
3438
+ }
3498
3439
  }
3499
- async putCursor(hash) {
3500
- return this.cursor.writePath([
3501
- new HashMapGet(new HashMapGetKey(hash))
3502
- ]);
3440
+ async putCursor(key) {
3441
+ const hash = await this.resolveHash(key);
3442
+ return this.putCursorInternal(hash);
3503
3443
  }
3504
- async remove(hash) {
3444
+ async remove(key) {
3445
+ const hash = await this.resolveHash(key);
3505
3446
  try {
3506
3447
  await this.cursor.writePath([new HashMapRemove(hash)]);
3507
3448
  } catch (e) {
@@ -3512,6 +3453,17 @@ class WriteHashSet extends ReadHashSet {
3512
3453
  }
3513
3454
  return true;
3514
3455
  }
3456
+ async putInternal(hash, data) {
3457
+ const cursor = await this.cursor.writePath([
3458
+ new HashMapGet(new HashMapGetKey(hash))
3459
+ ]);
3460
+ await cursor.writeIfEmpty(data);
3461
+ }
3462
+ async putCursorInternal(hash) {
3463
+ return this.cursor.writePath([
3464
+ new HashMapGet(new HashMapGetKey(hash))
3465
+ ]);
3466
+ }
3515
3467
  }
3516
3468
  // src/read-linked-array-list.ts
3517
3469
  class ReadLinkedArrayList {
@@ -9,19 +9,20 @@ export declare class ReadHashMap implements Slotted {
9
9
  slot(): Slot;
10
10
  iterator(): Promise<CursorIterator>;
11
11
  [Symbol.asyncIterator](): AsyncIterator<ReadCursor>;
12
- getCursorByString(key: string): Promise<ReadCursor | null>;
13
- getSlotByString(key: string): Promise<Slot | null>;
14
- getKeyCursorByString(key: string): Promise<ReadCursor | null>;
15
- getKeySlotByString(key: string): Promise<Slot | null>;
16
- getKeyValuePairByString(key: string): Promise<KeyValuePairCursor | null>;
17
- getCursorByBytes(key: Bytes): Promise<ReadCursor | null>;
18
- getSlotByBytes(key: Bytes): Promise<Slot | null>;
19
- getKeyCursorByBytes(key: Bytes): Promise<ReadCursor | null>;
20
- getKeySlotByBytes(key: Bytes): Promise<Slot | null>;
21
- getKeyValuePairByBytes(key: Bytes): Promise<KeyValuePairCursor | null>;
12
+ getCursor(key: string): Promise<ReadCursor | null>;
13
+ getCursor(key: Bytes): Promise<ReadCursor | null>;
22
14
  getCursor(hash: Uint8Array): Promise<ReadCursor | null>;
15
+ getSlot(key: string): Promise<Slot | null>;
16
+ getSlot(key: Bytes): Promise<Slot | null>;
23
17
  getSlot(hash: Uint8Array): Promise<Slot | null>;
18
+ getKeyCursor(key: string): Promise<ReadCursor | null>;
19
+ getKeyCursor(key: Bytes): Promise<ReadCursor | null>;
24
20
  getKeyCursor(hash: Uint8Array): Promise<ReadCursor | null>;
21
+ getKeySlot(key: string): Promise<Slot | null>;
22
+ getKeySlot(key: Bytes): Promise<Slot | null>;
25
23
  getKeySlot(hash: Uint8Array): Promise<Slot | null>;
24
+ getKeyValuePair(key: string): Promise<KeyValuePairCursor | null>;
25
+ getKeyValuePair(key: Bytes): Promise<KeyValuePairCursor | null>;
26
26
  getKeyValuePair(hash: Uint8Array): Promise<KeyValuePairCursor | null>;
27
+ protected resolveHash(key: string | Bytes | Uint8Array): Promise<Uint8Array>;
27
28
  }
@@ -9,10 +9,11 @@ export declare class ReadHashSet implements Slotted {
9
9
  slot(): Slot;
10
10
  iterator(): Promise<CursorIterator>;
11
11
  [Symbol.asyncIterator](): AsyncIterator<ReadCursor>;
12
- getCursorByString(key: string): Promise<ReadCursor | null>;
13
- getSlotByString(key: string): Promise<Slot | null>;
14
- getCursorByBytes(key: Bytes): Promise<ReadCursor | null>;
15
- getSlotByBytes(key: Bytes): Promise<Slot | null>;
12
+ getCursor(key: string): Promise<ReadCursor | null>;
13
+ getCursor(key: Bytes): Promise<ReadCursor | null>;
16
14
  getCursor(hash: Uint8Array): Promise<ReadCursor | null>;
15
+ getSlot(key: string): Promise<Slot | null>;
16
+ getSlot(key: Bytes): Promise<Slot | null>;
17
17
  getSlot(hash: Uint8Array): Promise<Slot | null>;
18
+ protected resolveHash(key: string | Bytes | Uint8Array): Promise<Uint8Array>;
18
19
  }
@@ -7,19 +7,23 @@ export declare class WriteHashMap extends ReadHashMap {
7
7
  static create(cursor: WriteCursor): Promise<WriteHashMap>;
8
8
  iterator(): Promise<WriteCursorIterator>;
9
9
  [Symbol.asyncIterator](): AsyncIterator<WriteCursor>;
10
- putByString(key: string, data: WriteableData): Promise<void>;
11
- putCursorByString(key: string): Promise<WriteCursor>;
12
- putKeyByString(key: string, data: WriteableData): Promise<void>;
13
- putKeyCursorByString(key: string): Promise<WriteCursor>;
14
- removeByString(key: string): Promise<boolean>;
15
- putByBytes(key: Bytes, data: WriteableData): Promise<void>;
16
- putCursorByBytes(key: Bytes): Promise<WriteCursor>;
17
- putKeyByBytes(key: Bytes, data: WriteableData): Promise<void>;
18
- putKeyCursorByBytes(key: Bytes): Promise<WriteCursor>;
19
- removeByBytes(key: Bytes): Promise<boolean>;
10
+ put(key: string, data: WriteableData): Promise<void>;
11
+ put(key: Bytes, data: WriteableData): Promise<void>;
20
12
  put(hash: Uint8Array, data: WriteableData): Promise<void>;
13
+ putCursor(key: string): Promise<WriteCursor>;
14
+ putCursor(key: Bytes): Promise<WriteCursor>;
21
15
  putCursor(hash: Uint8Array): Promise<WriteCursor>;
16
+ putKey(key: string, data: WriteableData): Promise<void>;
17
+ putKey(key: Bytes, data: WriteableData): Promise<void>;
22
18
  putKey(hash: Uint8Array, data: WriteableData): Promise<void>;
19
+ putKeyCursor(key: string): Promise<WriteCursor>;
20
+ putKeyCursor(key: Bytes): Promise<WriteCursor>;
23
21
  putKeyCursor(hash: Uint8Array): Promise<WriteCursor>;
22
+ remove(key: string): Promise<boolean>;
23
+ remove(key: Bytes): Promise<boolean>;
24
24
  remove(hash: Uint8Array): Promise<boolean>;
25
+ private putInternal;
26
+ private putCursorInternal;
27
+ private putKeyInternal;
28
+ private putKeyCursorInternal;
25
29
  }
@@ -7,13 +7,15 @@ export declare class WriteHashSet extends ReadHashSet {
7
7
  static create(cursor: WriteCursor): Promise<WriteHashSet>;
8
8
  iterator(): Promise<WriteCursorIterator>;
9
9
  [Symbol.asyncIterator](): AsyncIterator<WriteCursor>;
10
- putByString(key: string): Promise<void>;
11
- putCursorByString(key: string): Promise<WriteCursor>;
12
- removeByString(key: string): Promise<boolean>;
13
- putByBytes(key: Bytes): Promise<void>;
14
- putCursorByBytes(key: Bytes): Promise<WriteCursor>;
15
- removeByBytes(key: Bytes): Promise<boolean>;
10
+ put(key: string): Promise<void>;
11
+ put(key: Bytes): Promise<void>;
16
12
  put(hash: Uint8Array, data: WriteableData): Promise<void>;
13
+ putCursor(key: string): Promise<WriteCursor>;
14
+ putCursor(key: Bytes): Promise<WriteCursor>;
17
15
  putCursor(hash: Uint8Array): Promise<WriteCursor>;
16
+ remove(key: string): Promise<boolean>;
17
+ remove(key: Bytes): Promise<boolean>;
18
18
  remove(hash: Uint8Array): Promise<boolean>;
19
+ private putInternal;
20
+ private putCursorInternal;
19
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xitdb",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "An immutable database",
5
5
  "license": "MIT",
6
6
  "repository": {