xitdb 0.3.0 → 0.4.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.
Files changed (2) hide show
  1. package/README.md +33 -18
  2. package/package.json +6 -2
package/README.md CHANGED
@@ -1,10 +1,19 @@
1
- xitdb is an immutable database written in TypeScript.
1
+ <p align="center">
2
+ xitdb is an immutable database written in TypeScript
3
+ <br/>
4
+ <br/>
5
+ <b>Choose your flavor:</b>
6
+ <a href="https://github.com/radarroark/xitdb">Zig</a> |
7
+ <a href="https://github.com/radarroark/xitdb-java">Java</a> |
8
+ <a href="https://github.com/codeboost/xitdb-clj">Clojure</a> |
9
+ <a href="https://github.com/radarroark/xitdb-ts">TypeScript</a>
10
+ </p>
2
11
 
3
12
  * Each transaction efficiently creates a new "copy" of the database, and past copies can still be read from.
4
13
  * It supports writing to a file as well as purely in-memory use.
5
14
  * No query engine of any kind. You just write data structures (primarily an `ArrayList` and `HashMap`) that can be nested arbitrarily.
6
15
  * No dependencies besides the JavaScript standard library.
7
- * This project is a port of the [original Zig version](https://github.com/radarroark/xitdb) and the [Java version](https://github.com/radarroark/xitdb-java).
16
+ * It is available [on npm](https://www.npmjs.com/package/xitdb).
8
17
 
9
18
  This database was originally made for the [xit version control system](https://github.com/radarroark/xit), but I bet it has a lot of potential for other projects. The combination of being immutable and having an API similar to in-memory data structures is pretty powerful. Consider using it [instead of SQLite](https://gist.github.com/radarroark/03a0724484e1111ef4c05d72a935c42c) for your TypeScript projects: it's simpler, it's pure TypeScript, and it creates no impedance mismatch with your program the way SQL databases do.
10
19
 
@@ -82,18 +91,18 @@ const moment = await ReadHashMap.create(momentCursor!);
82
91
  // the cursor to "foo" and then calling readBytes on it
83
92
  const fooCursor = await moment.getCursorByString('foo');
84
93
  const fooValue = await fooCursor!.readBytes(MAX_READ_BYTES);
85
- console.log(new TextDecoder().decode(fooValue)); // "foo"
94
+ expect(new TextDecoder().decode(fooValue)).toBe('foo');
86
95
 
87
96
  // to get the "fruits" list, we get the cursor to it and
88
97
  // then pass it to the ReadArrayList constructor
89
98
  const fruitsCursor = await moment.getCursorByString('fruits');
90
99
  const fruits = new ReadArrayList(fruitsCursor!);
91
- console.log(await fruits.count()); // 3
100
+ expect(await fruits.count()).toBe(3);
92
101
 
93
102
  // now we can get the first item from the fruits list and read it
94
103
  const appleCursor = await fruits.getCursor(0);
95
104
  const appleValue = await appleCursor!.readBytes(MAX_READ_BYTES);
96
- console.log(new TextDecoder().decode(appleValue)); // "apple"
105
+ expect(new TextDecoder().decode(appleValue)).toBe('apple');
97
106
  ```
98
107
 
99
108
  ## Initializing a Database
@@ -142,7 +151,7 @@ Then, you can read it like this:
142
151
  ```typescript
143
152
  const randomNumberCursor = await moment.getCursorByString('random-number');
144
153
  const randomNumber = await randomNumberCursor!.readBytesObject(MAX_READ_BYTES);
145
- console.log(new TextDecoder().decode(randomNumber.formatTag!)); // "bi"
154
+ expect(new TextDecoder().decode(randomNumber.formatTag!)).toBe('bi');
146
155
  const randomBigInt = randomNumber.value;
147
156
  ```
148
157
 
@@ -176,12 +185,12 @@ const moment = await ReadHashMap.create(momentCursor!);
176
185
  // the food list includes the fruits
177
186
  const foodCursor = await moment.getCursorByString('food');
178
187
  const food = new ReadArrayList(foodCursor!);
179
- console.log(await food.count()); // 6
188
+ expect(await food.count()).toBe(6);
180
189
 
181
190
  // ...but the fruits list hasn't been changed
182
191
  const fruitsCursor = await moment.getCursorByString('fruits');
183
192
  const fruits = new ReadArrayList(fruitsCursor!);
184
- console.log(await fruits.count()); // 3
193
+ expect(await fruits.count()).toBe(3);
185
194
  ```
186
195
 
187
196
  Before we continue, let's save the latest history index, so we can revert back to this moment of the database later:
@@ -217,12 +226,12 @@ const moment = await ReadHashMap.create(momentCursor!);
217
226
  // the cities list contains all four
218
227
  const citiesCursor = await moment.getCursorByString('cities');
219
228
  const cities = new ReadArrayList(citiesCursor!);
220
- console.log(await cities.count()); // 4
229
+ expect(await cities.count()).toBe(4);
221
230
 
222
231
  // ..but so does big-cities! we did not intend to mutate this
223
232
  const bigCitiesCursor = await moment.getCursorByString('big-cities');
224
233
  const bigCities = new ReadArrayList(bigCitiesCursor!);
225
- console.log(await bigCities.count()); // 4
234
+ expect(await bigCities.count()).toBe(4);
226
235
  ```
227
236
 
228
237
  The reason that `big-cities` was mutated is because all data in a given transaction is temporarily mutable. This is a very important optimization, but in this case, it's not what we want.
@@ -263,12 +272,12 @@ const moment = await ReadHashMap.create(momentCursor!);
263
272
  // the cities list contains all four
264
273
  const citiesCursor = await moment.getCursorByString('cities');
265
274
  const cities = new ReadArrayList(citiesCursor!);
266
- console.log(await cities.count()); // 4
275
+ expect(await cities.count()).toBe(4);
267
276
 
268
277
  // and big-cities only contains the original two
269
278
  const bigCitiesCursor = await moment.getCursorByString('big-cities');
270
279
  const bigCities = new ReadArrayList(bigCitiesCursor!);
271
- console.log(await bigCities.count()); // 2
280
+ expect(await bigCities.count()).toBe(2);
272
281
  ```
273
282
 
274
283
  ## Large Byte Arrays
@@ -291,10 +300,16 @@ To read a byte array incrementally, get a reader from a cursor:
291
300
  ```typescript
292
301
  const longTextCursor = await moment.getCursorByString('long-text');
293
302
  const cursorReader = await longTextCursor!.reader();
294
- const content = new Uint8Array(Number(await longTextCursor!.count()));
295
- await cursorReader.readFully(content);
296
- const lines = new TextDecoder().decode(content).split('\n').filter(l => l.length > 0);
297
- console.log(lines.length); // 50
303
+ let lineCount = 0, line: number[] = [];
304
+ const buf = new Uint8Array(1024);
305
+ for (let n; (n = await cursorReader.read(buf)) > 0; ) {
306
+ for (let i = 0; i < n; i++) {
307
+ if (buf[i] === 0x0A) { lineCount++; line = []; }
308
+ else line.push(buf[i]);
309
+ }
310
+ }
311
+ if (line.length > 0) lineCount++;
312
+ expect(lineCount).toBe(50);
298
313
  ```
299
314
 
300
315
  ## Iterators
@@ -358,7 +373,7 @@ The size of the hash in bytes will be stored in the database's header. If you tr
358
373
  ```typescript
359
374
  await core.seek(0);
360
375
  const header = await Header.read(core);
361
- console.log(header.hashSize); // 20
376
+ expect(header.hashSize).toBe(20);
362
377
  ```
363
378
 
364
379
  The hash size alone does not disambiguate hashing algorithms, though. In addition, xitdb reserves four bytes in the header that you can use to put the name of the algorithm. You must provide it in the `Hasher` constructor:
@@ -372,7 +387,7 @@ The hash id is only written to the database header when it is first initialized.
372
387
  ```typescript
373
388
  await core.seek(0);
374
389
  const header = await Header.read(core);
375
- console.log(Hasher.idToString(header.hashId)); // "sha1"
390
+ expect(Hasher.idToString(header.hashId)).toBe("sha1");
376
391
  ```
377
392
 
378
393
  If you want to use SHA-256, I recommend using `sha2` as the hash id. You can then distinguish between SHA-256 and SHA-512 using the hash size, like this:
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "xitdb",
3
- "version": "0.3.0",
4
- "description": "An immutable database for TypeScript",
3
+ "version": "0.4.0",
4
+ "description": "An immutable database",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/radarroark/xitdb-ts.git"
9
+ },
6
10
  "type": "module",
7
11
  "main": "dist/index.js",
8
12
  "types": "dist/index.d.ts",