xitdb 0.11.0 → 0.13.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
@@ -6,7 +6,8 @@
6
6
  <a href="https://github.com/xit-vcs/xitdb">Zig</a> |
7
7
  <a href="https://github.com/xit-vcs/xitdb-java">Java</a> |
8
8
  <a href="https://github.com/codeboost/xitdb-clj">Clojure</a> |
9
- <a href="https://github.com/xit-vcs/xitdb-ts">TypeScript</a>
9
+ <a href="https://github.com/xit-vcs/xitdb-ts">TypeScript</a> |
10
+ <a href="https://github.com/xit-vcs/xitdb-go">Go</a>
10
11
  </p>
11
12
 
12
13
  * Each transaction efficiently creates a new "copy" of the database, and past copies can still be read from and reverted to.
@@ -16,9 +17,10 @@
16
17
  * Reads never block writes, and a database can be read from multiple threads/processes without locks.
17
18
  * No query engine of any kind. You just write data structures (primarily an `ArrayList` and `HashMap`) that can be nested arbitrarily.
18
19
  * No dependencies besides the JavaScript standard library.
20
+ * Fully synchronous API — no async/await needed.
19
21
  * Available [on npm](https://www.npmjs.com/package/xitdb).
20
22
 
21
- This database was originally made for the [xit version control system](https://github.com/xit-vcs/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.
23
+ This database was originally made for the [xit version control system](https://github.com/xit-vcs/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/xeubie/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.
22
24
 
23
25
  * [Example](#example)
24
26
  * [Initializing a Database](#initializing-a-database)
@@ -35,13 +37,13 @@ In this example, we create a new database, write some data in a transaction, and
35
37
 
36
38
  ```typescript
37
39
  // init the db
38
- using core = await CoreBufferedFile.create('main.db');
40
+ using core = new CoreBufferedFile('main.db');
39
41
  const hasher = new Hasher('SHA-1');
40
- const db = await Database.create(core, hasher);
42
+ const db = new Database(core, hasher);
41
43
 
42
44
  // to get the benefits of immutability, the top-level data structure
43
45
  // must be an ArrayList, so each transaction is stored as an item in it
44
- const history = await WriteArrayList.create(db.rootCursor());
46
+ const history = new WriteArrayList(db.rootCursor());
45
47
 
46
48
  // this is how a transaction is executed. we call history.appendContext,
47
49
  // providing it with the most recent copy of the db and a context
@@ -60,52 +62,52 @@ const history = await WriteArrayList.create(db.rootCursor());
60
62
  // {"name": "Alice", "age": 25},
61
63
  // {"name": "Bob", "age": 42}
62
64
  // ]}
63
- await history.appendContext(await history.getSlot(-1), async (cursor) => {
64
- const moment = await WriteHashMap.create(cursor);
65
-
66
- await moment.put('foo', new Bytes('foo'));
67
- await moment.put('bar', new Bytes('bar'));
68
-
69
- const fruitsCursor = await moment.putCursor('fruits');
70
- const fruits = await WriteArrayList.create(fruitsCursor);
71
- await fruits.append(new Bytes('apple'));
72
- await fruits.append(new Bytes('pear'));
73
- await fruits.append(new Bytes('grape'));
74
-
75
- const peopleCursor = await moment.putCursor('people');
76
- const people = await WriteArrayList.create(peopleCursor);
77
-
78
- const aliceCursor = await people.appendCursor();
79
- const alice = await WriteHashMap.create(aliceCursor);
80
- await alice.put('name', new Bytes('Alice'));
81
- await alice.put('age', new Uint(25));
82
-
83
- const bobCursor = await people.appendCursor();
84
- const bob = await WriteHashMap.create(bobCursor);
85
- await bob.put('name', new Bytes('Bob'));
86
- await bob.put('age', new Uint(42));
65
+ history.appendContext(history.getSlot(-1), (cursor) => {
66
+ const moment = new WriteHashMap(cursor);
67
+
68
+ moment.put('foo', new Bytes('foo'));
69
+ moment.put('bar', new Bytes('bar'));
70
+
71
+ const fruitsCursor = moment.putCursor('fruits');
72
+ const fruits = new WriteArrayList(fruitsCursor);
73
+ fruits.append(new Bytes('apple'));
74
+ fruits.append(new Bytes('pear'));
75
+ fruits.append(new Bytes('grape'));
76
+
77
+ const peopleCursor = moment.putCursor('people');
78
+ const people = new WriteArrayList(peopleCursor);
79
+
80
+ const aliceCursor = people.appendCursor();
81
+ const alice = new WriteHashMap(aliceCursor);
82
+ alice.put('name', new Bytes('Alice'));
83
+ alice.put('age', new Uint(25));
84
+
85
+ const bobCursor = people.appendCursor();
86
+ const bob = new WriteHashMap(bobCursor);
87
+ bob.put('name', new Bytes('Bob'));
88
+ bob.put('age', new Uint(42));
87
89
  });
88
90
 
89
91
  // get the most recent copy of the database, like a moment
90
92
  // in time. the -1 index will return the last index in the list.
91
- const momentCursor = await history.getCursor(-1);
93
+ const momentCursor = history.getCursor(-1);
92
94
  const moment = new ReadHashMap(momentCursor!);
93
95
 
94
96
  // we can read the value of "foo" from the map by getting
95
97
  // the cursor to "foo" and then calling readBytes on it
96
- const fooCursor = await moment.getCursor('foo');
97
- const fooValue = await fooCursor!.readBytes(MAX_READ_BYTES);
98
+ const fooCursor = moment.getCursor('foo');
99
+ const fooValue = fooCursor!.readBytes(MAX_READ_BYTES);
98
100
  expect(new TextDecoder().decode(fooValue)).toBe('foo');
99
101
 
100
102
  // to get the "fruits" list, we get the cursor to it and
101
103
  // then pass it to the ReadArrayList constructor
102
- const fruitsCursor = await moment.getCursor('fruits');
104
+ const fruitsCursor = moment.getCursor('fruits');
103
105
  const fruits = new ReadArrayList(fruitsCursor!);
104
- expect(await fruits.count()).toBe(3);
106
+ expect(fruits.count()).toBe(3);
105
107
 
106
108
  // now we can get the first item from the fruits list and read it
107
- const appleCursor = await fruits.getCursor(0);
108
- const appleValue = await appleCursor!.readBytes(MAX_READ_BYTES);
109
+ const appleCursor = fruits.getCursor(0);
110
+ const appleValue = appleCursor!.readBytes(MAX_READ_BYTES);
109
111
  expect(new TextDecoder().decode(appleValue)).toBe('apple');
110
112
  ```
111
113
 
@@ -147,14 +149,14 @@ In xitdb, you can optionally store a format tag with a byte array. A format tag
147
149
  ```typescript
148
150
  const randomBytes = new Uint8Array(32);
149
151
  crypto.getRandomValues(randomBytes);
150
- await moment.put('random-number', new Bytes(randomBytes, new TextEncoder().encode('bi')));
152
+ moment.put('random-number', new Bytes(randomBytes, new TextEncoder().encode('bi')));
151
153
  ```
152
154
 
153
155
  Then, you can read it like this:
154
156
 
155
157
  ```typescript
156
- const randomNumberCursor = await moment.getCursor('random-number');
157
- const randomNumber = await randomNumberCursor!.readBytesObject(MAX_READ_BYTES);
158
+ const randomNumberCursor = moment.getCursor('random-number');
159
+ const randomNumber = randomNumberCursor!.readBytesObject(MAX_READ_BYTES);
158
160
  expect(new TextDecoder().decode(randomNumber.formatTag!)).toBe('bi');
159
161
  const randomBigInt = randomNumber.value;
160
162
  ```
@@ -166,76 +168,76 @@ There are many types you may want to store this way. Maybe an ISO-8601 date like
166
168
  A powerful feature of immutable data is fast cloning. Any data structure can be instantly cloned and changed without affecting the original. Starting with the example code above, we can make a new transaction that creates a "food" list based on the existing "fruits" list:
167
169
 
168
170
  ```typescript
169
- await history.appendContext(await history.getSlot(-1), async (cursor) => {
170
- const moment = await WriteHashMap.create(cursor);
171
+ history.appendContext(history.getSlot(-1), (cursor) => {
172
+ const moment = new WriteHashMap(cursor);
171
173
 
172
- const fruitsCursor = await moment.getCursor('fruits');
174
+ const fruitsCursor = moment.getCursor('fruits');
173
175
  const fruits = new ReadArrayList(fruitsCursor!);
174
176
 
175
177
  // create a new key called "food" whose initial value is
176
178
  // based on the "fruits" list
177
- const foodCursor = await moment.putCursor('food');
178
- await foodCursor.write(fruits.slot());
179
+ const foodCursor = moment.putCursor('food');
180
+ foodCursor.write(fruits.slot());
179
181
 
180
- const food = await WriteArrayList.create(foodCursor);
181
- await food.append(new Bytes('eggs'));
182
- await food.append(new Bytes('rice'));
183
- await food.append(new Bytes('fish'));
182
+ const food = new WriteArrayList(foodCursor);
183
+ food.append(new Bytes('eggs'));
184
+ food.append(new Bytes('rice'));
185
+ food.append(new Bytes('fish'));
184
186
  });
185
187
 
186
- const momentCursor = await history.getCursor(-1);
188
+ const momentCursor = history.getCursor(-1);
187
189
  const moment = new ReadHashMap(momentCursor!);
188
190
 
189
191
  // the food list includes the fruits
190
- const foodCursor = await moment.getCursor('food');
192
+ const foodCursor = moment.getCursor('food');
191
193
  const food = new ReadArrayList(foodCursor!);
192
- expect(await food.count()).toBe(6);
194
+ expect(food.count()).toBe(6);
193
195
 
194
196
  // ...but the fruits list hasn't been changed
195
- const fruitsCursor = await moment.getCursor('fruits');
197
+ const fruitsCursor = moment.getCursor('fruits');
196
198
  const fruits = new ReadArrayList(fruitsCursor!);
197
- expect(await fruits.count()).toBe(3);
199
+ expect(fruits.count()).toBe(3);
198
200
  ```
199
201
 
200
202
  Before we continue, let's save the latest history index, so we can revert back to this moment of the database later:
201
203
 
202
204
  ```typescript
203
- const historyIndex = (await history.count()) - 1;
205
+ const historyIndex = history.count() - 1;
204
206
  ```
205
207
 
206
208
  There's one catch you'll run into when cloning. If we try cloning a data structure that was created in the same transaction, it doesn't seem to work:
207
209
 
208
210
  ```typescript
209
- await history.appendContext(await history.getSlot(-1), async (cursor) => {
210
- const moment = await WriteHashMap.create(cursor);
211
+ history.appendContext(history.getSlot(-1), (cursor) => {
212
+ const moment = new WriteHashMap(cursor);
211
213
 
212
- const bigCitiesCursor = await moment.putCursor('big-cities');
213
- const bigCities = await WriteArrayList.create(bigCitiesCursor);
214
- await bigCities.append(new Bytes('New York, NY'));
215
- await bigCities.append(new Bytes('Los Angeles, CA'));
214
+ const bigCitiesCursor = moment.putCursor('big-cities');
215
+ const bigCities = new WriteArrayList(bigCitiesCursor);
216
+ bigCities.append(new Bytes('New York, NY'));
217
+ bigCities.append(new Bytes('Los Angeles, CA'));
216
218
 
217
219
  // create a new key called "cities" whose initial value is
218
220
  // based on the "big-cities" list
219
- const citiesCursor = await moment.putCursor('cities');
220
- await citiesCursor.write(bigCities.slot());
221
+ const citiesCursor = moment.putCursor('cities');
222
+ citiesCursor.write(bigCities.slot());
221
223
 
222
- const cities = await WriteArrayList.create(citiesCursor);
223
- await cities.append(new Bytes('Charleston, SC'));
224
- await cities.append(new Bytes('Louisville, KY'));
224
+ const cities = new WriteArrayList(citiesCursor);
225
+ cities.append(new Bytes('Charleston, SC'));
226
+ cities.append(new Bytes('Louisville, KY'));
225
227
  });
226
228
 
227
- const momentCursor = await history.getCursor(-1);
229
+ const momentCursor = history.getCursor(-1);
228
230
  const moment = new ReadHashMap(momentCursor!);
229
231
 
230
232
  // the cities list contains all four
231
- const citiesCursor = await moment.getCursor('cities');
233
+ const citiesCursor = moment.getCursor('cities');
232
234
  const cities = new ReadArrayList(citiesCursor!);
233
- expect(await cities.count()).toBe(4);
235
+ expect(cities.count()).toBe(4);
234
236
 
235
237
  // ..but so does big-cities! we did not intend to mutate this
236
- const bigCitiesCursor = await moment.getCursor('big-cities');
238
+ const bigCitiesCursor = moment.getCursor('big-cities');
237
239
  const bigCities = new ReadArrayList(bigCitiesCursor!);
238
- expect(await bigCities.count()).toBe(4);
240
+ expect(bigCities.count()).toBe(4);
239
241
  ```
240
242
 
241
243
  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.
@@ -243,45 +245,45 @@ The reason that `big-cities` was mutated is because all data in a given transact
243
245
  To show how to fix this, let's first undo the transaction we just made. Here we use the `historyIndex` we saved before to revert back to the older database moment:
244
246
 
245
247
  ```typescript
246
- await history.append((await history.getSlot(historyIndex))!);
248
+ history.append(history.getSlot(historyIndex)!);
247
249
  ```
248
250
 
249
251
  This time, after making the "big cities" list, we call `freeze`, which tells xitdb to consider all data made so far in the transaction to be immutable. After that, we can clone it into the "cities" list and it will work the way we wanted:
250
252
 
251
253
  ```typescript
252
- await history.appendContext(await history.getSlot(-1), async (cursor) => {
253
- const moment = await WriteHashMap.create(cursor);
254
+ history.appendContext(history.getSlot(-1), (cursor) => {
255
+ const moment = new WriteHashMap(cursor);
254
256
 
255
- const bigCitiesCursor = await moment.putCursor('big-cities');
256
- const bigCities = await WriteArrayList.create(bigCitiesCursor);
257
- await bigCities.append(new Bytes('New York, NY'));
258
- await bigCities.append(new Bytes('Los Angeles, CA'));
257
+ const bigCitiesCursor = moment.putCursor('big-cities');
258
+ const bigCities = new WriteArrayList(bigCitiesCursor);
259
+ bigCities.append(new Bytes('New York, NY'));
260
+ bigCities.append(new Bytes('Los Angeles, CA'));
259
261
 
260
262
  // freeze here, so big-cities won't be mutated
261
263
  cursor.db.freeze();
262
264
 
263
265
  // create a new key called "cities" whose initial value is
264
266
  // based on the "big-cities" list
265
- const citiesCursor = await moment.putCursor('cities');
266
- await citiesCursor.write(bigCities.slot());
267
+ const citiesCursor = moment.putCursor('cities');
268
+ citiesCursor.write(bigCities.slot());
267
269
 
268
- const cities = await WriteArrayList.create(citiesCursor);
269
- await cities.append(new Bytes('Charleston, SC'));
270
- await cities.append(new Bytes('Louisville, KY'));
270
+ const cities = new WriteArrayList(citiesCursor);
271
+ cities.append(new Bytes('Charleston, SC'));
272
+ cities.append(new Bytes('Louisville, KY'));
271
273
  });
272
274
 
273
- const momentCursor = await history.getCursor(-1);
275
+ const momentCursor = history.getCursor(-1);
274
276
  const moment = new ReadHashMap(momentCursor!);
275
277
 
276
278
  // the cities list contains all four
277
- const citiesCursor = await moment.getCursor('cities');
279
+ const citiesCursor = moment.getCursor('cities');
278
280
  const cities = new ReadArrayList(citiesCursor!);
279
- expect(await cities.count()).toBe(4);
281
+ expect(cities.count()).toBe(4);
280
282
 
281
283
  // and big-cities only contains the original two
282
- const bigCitiesCursor = await moment.getCursor('big-cities');
284
+ const bigCitiesCursor = moment.getCursor('big-cities');
283
285
  const bigCities = new ReadArrayList(bigCitiesCursor!);
284
- expect(await bigCities.count()).toBe(2);
286
+ expect(bigCities.count()).toBe(2);
285
287
  ```
286
288
 
287
289
  ## Large Byte Arrays
@@ -289,12 +291,12 @@ expect(await bigCities.count()).toBe(2);
289
291
  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:
290
292
 
291
293
  ```typescript
292
- const longTextCursor = await moment.putCursor('long-text');
293
- const cursorWriter = await longTextCursor.writer();
294
+ const longTextCursor = moment.putCursor('long-text');
295
+ const cursorWriter = longTextCursor.writer();
294
296
  for (let i = 0; i < 50; i++) {
295
- await cursorWriter.write(new TextEncoder().encode('hello, world\n'));
297
+ cursorWriter.write(new TextEncoder().encode('hello, world\n'));
296
298
  }
297
- await cursorWriter.finish(); // remember to call this!
299
+ cursorWriter.finish(); // remember to call this!
298
300
  ```
299
301
 
300
302
  If you need to set a format tag for the byte array, put it in the `formatTag` field of the writer before you call `finish`.
@@ -302,11 +304,11 @@ If you need to set a format tag for the byte array, put it in the `formatTag` fi
302
304
  To read a byte array incrementally, get a reader from a cursor:
303
305
 
304
306
  ```typescript
305
- const longTextCursor = await moment.getCursor('long-text');
306
- const cursorReader = await longTextCursor!.reader();
307
+ const longTextCursor = moment.getCursor('long-text');
308
+ const cursorReader = longTextCursor!.reader();
307
309
  let lineCount = 0, line: number[] = [];
308
310
  const buf = new Uint8Array(1024);
309
- for (let n; (n = await cursorReader.read(buf)) > 0; ) {
311
+ for (let n; (n = cursorReader.read(buf)) > 0; ) {
310
312
  for (let i = 0; i < n; i++) {
311
313
  if (buf[i] === 0x0A) { lineCount++; line = []; }
312
314
  else line.push(buf[i]);
@@ -321,24 +323,24 @@ expect(lineCount).toBe(50);
321
323
  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:
322
324
 
323
325
  ```typescript
324
- const peopleCursor = await moment.getCursor('people');
326
+ const peopleCursor = moment.getCursor('people');
325
327
  const people = new ReadArrayList(peopleCursor!);
326
328
 
327
- const peopleIter = await people.iterator();
328
- while (await peopleIter.hasNext()) {
329
- const personCursor = await peopleIter.next();
329
+ const peopleIter = people.iterator();
330
+ while (peopleIter.hasNext()) {
331
+ const personCursor = peopleIter.next();
330
332
  const person = new ReadHashMap(personCursor!);
331
- const personIter = await person.iterator();
332
- while (await personIter.hasNext()) {
333
- const kvPairCursor = await personIter.next();
334
- const kvPair = await kvPairCursor!.readKeyValuePair();
333
+ const personIter = person.iterator();
334
+ while (personIter.hasNext()) {
335
+ const kvPairCursor = personIter.next();
336
+ const kvPair = kvPairCursor!.readKeyValuePair();
335
337
 
336
- const key = new TextDecoder().decode(await kvPair.keyCursor.readBytes(MAX_READ_BYTES));
338
+ const key = new TextDecoder().decode(kvPair.keyCursor.readBytes(MAX_READ_BYTES));
337
339
 
338
340
  switch (kvPair.valueCursor.slot().tag) {
339
341
  case Tag.SHORT_BYTES:
340
342
  case Tag.BYTES:
341
- console.log(`${key}: ${new TextDecoder().decode(await kvPair.valueCursor.readBytes(MAX_READ_BYTES))}`);
343
+ console.log(`${key}: ${new TextDecoder().decode(kvPair.valueCursor.readBytes(MAX_READ_BYTES))}`);
342
344
  break;
343
345
  case Tag.UINT:
344
346
  console.log(`${key}: ${kvPair.valueCursor.readUint()}`);
@@ -365,16 +367,16 @@ The hashing data structures will create the hash for you when you call methods l
365
367
  When initializing a database, you tell xitdb how to hash with the `Hasher`. If you're using SHA-1, it will look like this:
366
368
 
367
369
  ```typescript
368
- using core = await CoreBufferedFile.create('main.db');
370
+ using core = new CoreBufferedFile('main.db');
369
371
  const hasher = new Hasher('SHA-1');
370
- const db = await Database.create(core, hasher);
372
+ const db = new Database(core, hasher);
371
373
  ```
372
374
 
373
375
  The size of the hash in bytes will be stored in the database's header. If you try opening it later with a hashing algorithm that has the wrong hash size, it will throw an exception. If you are unsure what hash size the database uses, this creates a chicken-and-egg problem. You can read the header before initializing the database like this:
374
376
 
375
377
  ```typescript
376
- await core.seek(0);
377
- const header = await Header.read(core);
378
+ core.seek(0);
379
+ const header = Header.read(core);
378
380
  expect(header.hashSize).toBe(20);
379
381
  ```
380
382
 
@@ -387,8 +389,8 @@ const hasher = new Hasher('SHA-1', Hasher.stringToId('sha1'));
387
389
  The hash id is only written to the database header when it is first initialized. When you open it later, the hash id in the `Hasher` is ignored. You can read the hash id of an existing database like this:
388
390
 
389
391
  ```typescript
390
- await core.seek(0);
391
- const header = await Header.read(core);
392
+ core.seek(0);
393
+ const header = Header.read(core);
392
394
  expect(Hasher.idToString(header.hashId)).toBe("sha1");
393
395
  ```
394
396
 
@@ -424,12 +426,12 @@ switch (hashIdStr) {
424
426
  Normally, an immutable database grows forever, because old data is never deleted. To reclaim disk space and clear the history, xitdb supports compaction. This involves completely rebuilding the database file to only contain the data accessible from the latest copy (i.e., "moment") of the database.
425
427
 
426
428
  ```typescript
427
- // create the file and core for the new database
428
- using compactCore = await CoreBufferedFile.create('compact.db');
429
-
430
- const compactDb = await db.compact(compactCore);
429
+ using compactCore = new CoreBufferedFile('compact.db');
430
+ const compactDb = db.compact(compactCore);
431
431
 
432
432
  // read from the new compacted db
433
433
  const history = new ReadArrayList(compactDb.rootCursor());
434
- expect(await history.count()).toBe(1);
434
+ expect(history.count()).toBe(1);
435
435
  ```
436
+
437
+ This compacted database will be in a separate file. If you want to delete the original database and replace it with this one, you'll need to do that yourself. It is not possible to compact a database in-place (using the same file as the target database); doing so would fail and would render your original database unreadable.
@@ -2,16 +2,15 @@ import type { Core, DataReader, DataWriter } from './core';
2
2
  import { CoreFile } from './core-file';
3
3
  export declare class CoreBufferedFile implements Core {
4
4
  file: RandomAccessBufferedFile;
5
- constructor(file: RandomAccessBufferedFile);
6
- static create(filePath: string, bufferSize?: number): Promise<CoreBufferedFile>;
5
+ constructor(filePath: string, bufferSize?: number);
7
6
  reader(): DataReader;
8
7
  writer(): DataWriter;
9
- length(): Promise<number>;
10
- seek(pos: number): Promise<void>;
8
+ length(): number;
9
+ seek(pos: number): void;
11
10
  position(): number;
12
- setLength(len: number): Promise<void>;
13
- flush(): Promise<void>;
14
- sync(): Promise<void>;
11
+ setLength(len: number): void;
12
+ flush(): void;
13
+ sync(): void;
15
14
  [Symbol.dispose](): void;
16
15
  }
17
16
  declare class RandomAccessBufferedFile implements DataReader, DataWriter {
@@ -20,22 +19,21 @@ declare class RandomAccessBufferedFile implements DataReader, DataWriter {
20
19
  private bufferSize;
21
20
  private filePos;
22
21
  private memoryPos;
23
- private constructor();
24
- static create(filePath: string, bufferSize?: number): Promise<RandomAccessBufferedFile>;
25
- seek(pos: number): Promise<void>;
26
- length(): Promise<number>;
22
+ constructor(filePath: string, bufferSize?: number);
23
+ seek(pos: number): void;
24
+ length(): number;
27
25
  position(): number;
28
- setLength(len: number): Promise<void>;
29
- flush(): Promise<void>;
30
- sync(): Promise<void>;
31
- write(buffer: Uint8Array): Promise<void>;
32
- writeByte(v: number): Promise<void>;
33
- writeShort(v: number): Promise<void>;
34
- writeLong(v: number): Promise<void>;
35
- readFully(buffer: Uint8Array): Promise<void>;
36
- readByte(): Promise<number>;
37
- readShort(): Promise<number>;
38
- readInt(): Promise<number>;
39
- readLong(): Promise<number>;
26
+ setLength(len: number): void;
27
+ flush(): void;
28
+ sync(): void;
29
+ write(buffer: Uint8Array): void;
30
+ writeByte(v: number): void;
31
+ writeShort(v: number): void;
32
+ writeLong(v: number): void;
33
+ readFully(buffer: Uint8Array): void;
34
+ readByte(): number;
35
+ readShort(): number;
36
+ readInt(): number;
37
+ readLong(): number;
40
38
  }
41
39
  export {};
@@ -1,18 +1,16 @@
1
1
  import type { Core, DataReader, DataWriter } from './core';
2
- import type { FileHandle } from 'fs/promises';
3
2
  export declare class CoreFile implements Core {
4
3
  filePath: string;
5
4
  private _position;
6
- fileHandle: FileHandle;
7
- private constructor();
8
- static create(filePath: string): Promise<CoreFile>;
5
+ fd: number;
6
+ constructor(filePath: string);
9
7
  reader(): DataReader;
10
8
  writer(): DataWriter;
11
- length(): Promise<number>;
12
- seek(pos: number): Promise<void>;
9
+ length(): number;
10
+ seek(pos: number): void;
13
11
  position(): number;
14
- setLength(len: number): Promise<void>;
15
- flush(): Promise<void>;
16
- sync(): Promise<void>;
12
+ setLength(len: number): void;
13
+ flush(): void;
14
+ sync(): void;
17
15
  [Symbol.dispose](): void;
18
16
  }
@@ -4,12 +4,12 @@ export declare class CoreMemory implements Core {
4
4
  constructor();
5
5
  reader(): DataReader;
6
6
  writer(): DataWriter;
7
- length(): Promise<number>;
8
- seek(pos: number): Promise<void>;
7
+ length(): number;
8
+ seek(pos: number): void;
9
9
  position(): number;
10
- setLength(len: number): Promise<void>;
11
- flush(): Promise<void>;
12
- sync(): Promise<void>;
10
+ setLength(len: number): void;
11
+ flush(): void;
12
+ sync(): void;
13
13
  }
14
14
  declare class RandomAccessMemory implements DataReader, DataWriter {
15
15
  private buffer;
@@ -23,14 +23,14 @@ declare class RandomAccessMemory implements DataReader, DataWriter {
23
23
  setLength(len: number): void;
24
24
  reset(): void;
25
25
  toByteArray(): Uint8Array;
26
- write(data: Uint8Array): Promise<void>;
27
- writeByte(v: number): Promise<void>;
28
- writeShort(v: number): Promise<void>;
29
- writeLong(v: number): Promise<void>;
30
- readFully(b: Uint8Array): Promise<void>;
31
- readByte(): Promise<number>;
32
- readShort(): Promise<number>;
33
- readInt(): Promise<number>;
34
- readLong(): Promise<number>;
26
+ write(data: Uint8Array): void;
27
+ writeByte(v: number): void;
28
+ writeShort(v: number): void;
29
+ writeLong(v: number): void;
30
+ readFully(b: Uint8Array): void;
31
+ readByte(): number;
32
+ readShort(): number;
33
+ readInt(): number;
34
+ readLong(): number;
35
35
  }
36
36
  export {};
package/dist/core.d.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  export interface DataReader {
2
- readFully(buffer: Uint8Array): Promise<void>;
3
- readByte(): Promise<number>;
4
- readShort(): Promise<number>;
5
- readInt(): Promise<number>;
6
- readLong(): Promise<number>;
2
+ readFully(buffer: Uint8Array): void;
3
+ readByte(): number;
4
+ readShort(): number;
5
+ readInt(): number;
6
+ readLong(): number;
7
7
  }
8
8
  export interface DataWriter {
9
- write(buffer: Uint8Array): Promise<void>;
10
- writeByte(v: number): Promise<void>;
11
- writeShort(v: number): Promise<void>;
12
- writeLong(v: number): Promise<void>;
9
+ write(buffer: Uint8Array): void;
10
+ writeByte(v: number): void;
11
+ writeShort(v: number): void;
12
+ writeLong(v: number): void;
13
13
  }
14
14
  export interface Core {
15
15
  reader(): DataReader;
16
16
  writer(): DataWriter;
17
- length(): Promise<number>;
18
- seek(pos: number): Promise<void>;
17
+ length(): number;
18
+ seek(pos: number): void;
19
19
  position(): number;
20
- setLength(len: number): Promise<void>;
21
- flush(): Promise<void>;
22
- sync(): Promise<void>;
20
+ setLength(len: number): void;
21
+ flush(): void;
22
+ sync(): void;
23
23
  }