edinburgh 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # Edinburgh
2
- **Very fast object persistence for TypeScript, supporting optimistic transactions, on-demand reference loading, automatic back-references and indexes.**
2
+ **Very fast object persistence for TypeScript, supporting optimistic transactions, lazy loading and indexes.**
3
3
 
4
4
  Edinburgh is a high-performance ORM built on [OLMDB](https://github.com/vanviegen/olmdb), providing type-safe model definitions with automatic field validation, ACID transactions, and efficient LMDB-based storage.
5
5
 
@@ -7,9 +7,9 @@ Edinburgh is a high-performance ORM built on [OLMDB](https://github.com/vanviege
7
7
 
8
8
  - 🚀 **Type-Safe Models**: Define models with automatic TypeScript type inference and runtime validation
9
9
  - 🔒 **ACID Transactions**: Optimistic locking with automatic retry on conflicts
10
- - 🔗 **Relationship Management**: Automatic back-references and link handling between models
10
+ - 🔗 **Relationships**: Model instances can reference each other, and will be lazy-loaded on access
11
+ - 📦 **Embedded Database**: Negligible query latency, due to a blazing fast embedded database (LMDB)
11
12
  - 📊 **Custom Indexing**: Efficient querying with primary, unique, and multi-value indexes
12
- - 📦 **Zero Dependencies**: Minimal footprint, built on LMDB for maximum performance
13
13
 
14
14
  ## Quick Demo
15
15
  ```typescript
@@ -57,7 +57,7 @@ await E.transact(() => {
57
57
 
58
58
  The following is auto-generated from `src/edinburgh.ts`:
59
59
 
60
- ### transact · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L83)
60
+ ### transact · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L89)
61
61
 
62
62
  Executes a function within a database transaction context.
63
63
 
@@ -93,7 +93,7 @@ times.
93
93
 
94
94
  ```typescript
95
95
  const paid = await E.transact(() => {
96
- const user = User.load("john_doe");
96
+ const user = User.pk.get("john_doe");
97
97
  // This is concurrency-safe - the function will rerun if it is raced by another transaction
98
98
  if (user.credits > 0) {
99
99
  user.credits--;
@@ -110,11 +110,21 @@ await E.transact(() => {
110
110
  });
111
111
  ```
112
112
 
113
- ### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L112)
113
+ ### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L146)
114
+
115
+ Set a callback function to be called after a model is saved and committed.
116
+
117
+ **Signature:** `(callback: (commitId: number, items: ChangedModel[]) => void) => void`
118
+
119
+ **Parameters:**
120
+
121
+ - `callback: ((commitId: number, items: ChangedModel[]) => void) | undefined` - [object Object],[object Object],[object Object]
122
+
123
+ ### deleteEverything · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L151)
114
124
 
115
125
  **Signature:** `() => Promise<void>`
116
126
 
117
- ### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
127
+ ### Model · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
118
128
 
119
129
  Base class for all database models in the Edinburgh ORM.
120
130
 
@@ -141,44 +151,62 @@ class User extends E.Model<User> {
141
151
  }
142
152
  ```
143
153
 
144
- #### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
154
+ #### Model.tableName · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
145
155
 
146
156
  The database table name (defaults to class name).
147
157
 
148
158
  **Type:** `string`
149
159
 
150
- #### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
160
+ #### Model.fields · [static property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
151
161
 
152
162
  Field configuration metadata.
153
163
 
154
- **Type:** `Record<string, FieldConfig<unknown>>`
164
+ **Type:** `Record<string | number | symbol, FieldConfig<unknown>>`
155
165
 
156
- #### Model.load · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
166
+ #### Model.findAll · [static method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
157
167
 
158
- Load a model instance by primary key.
168
+ Find all instances of this model in the database, ordered by primary key.
159
169
 
160
- **Signature:** `<SUB>(this: typeof Model<SUB>, ...args: any[]) => SUB`
170
+ **Signature:** `<T extends typeof Model<unknown>>(this: T, opts?: { reverse?: boolean; }) => IndexRangeIterator<T>`
161
171
 
162
172
  **Parameters:**
163
173
 
164
- - `this: typeof Model<SUB>`
165
- - `args: any[]` - - Primary key field values.
174
+ - `this: T`
175
+ - `opts?: {reverse?: boolean}` - - Optional parameters.
166
176
 
167
- **Returns:** The model instance if found, undefined otherwise.
177
+ **Returns:** An iterator.
168
178
 
169
- **Examples:**
179
+ #### model.changed · [property](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
170
180
 
171
- ```typescript
172
- const user = User.load("user123");
173
- const post = Post.load("post456", "en");
174
- ```
181
+ This property can be used in `setOnSave` callbacks to determine how a model instance has changed.
182
+ If the value is undefined, the instance has been created. If it's "deleted" the instance has
183
+ been deleted. If its an object, the instance has been modified and the object contains the old values.
175
184
 
176
- #### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
185
+ Note: this property should **not** be accessed *during* a `transact()` -- it's state is an implementation
186
+ detail that may change semantics at any minor release.
177
187
 
178
- Prevent this instance from being persisted to the database.
188
+ **Type:** `Record<any, any> | "deleted" | "created"`
179
189
 
180
- Removes the instance from the modified instances set and disables
181
- automatic persistence at transaction commit.
190
+ #### model.getPrimaryKey · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
191
+
192
+ **Signature:** `() => Uint8Array<ArrayBufferLike>`
193
+
194
+ **Parameters:**
195
+
196
+
197
+ **Returns:** The primary key for this instance, or undefined if not yet saved.
198
+
199
+ #### model.isLazyField · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
200
+
201
+ **Signature:** `(field: keyof this) => boolean`
202
+
203
+ **Parameters:**
204
+
205
+ - `field: keyof this`
206
+
207
+ #### model.preventPersist · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
208
+
209
+ Prevent this instance from being persisted to the database.
182
210
 
183
211
  **Signature:** `() => this`
184
212
 
@@ -195,7 +223,7 @@ user.name = "New Name";
195
223
  user.preventPersist(); // Changes won't be saved
196
224
  ```
197
225
 
198
- #### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
226
+ #### model.delete · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
199
227
 
200
228
  Delete this model instance from the database.
201
229
 
@@ -213,11 +241,11 @@ const user = User.load("user123");
213
241
  user.delete(); // Removes from database
214
242
  ```
215
243
 
216
- #### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
244
+ #### model.validate · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
217
245
 
218
246
  Validate all fields in this model instance.
219
247
 
220
- **Signature:** `(raise?: boolean) => DatabaseError[]`
248
+ **Signature:** `(raise?: boolean) => Error[]`
221
249
 
222
250
  **Parameters:**
223
251
 
@@ -235,7 +263,7 @@ if (errors.length > 0) {
235
263
  }
236
264
  ```
237
265
 
238
- #### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
266
+ #### model.isValid · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
239
267
 
240
268
  Check if this model instance is valid.
241
269
 
@@ -253,14 +281,10 @@ const user = new User({name: "John"});
253
281
  if (!user.isValid()) shoutAtTheUser();
254
282
  ```
255
283
 
256
- ### registerModel · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
284
+ ### registerModel · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L91)
257
285
 
258
286
  Register a model class with the Edinburgh ORM system.
259
287
 
260
- This decorator function transforms the model class to use a proxy-based constructor
261
- that enables change tracking and automatic field initialization. It also extracts
262
- field metadata and sets up default values on the prototype.
263
-
264
288
  **Signature:** `<T extends typeof Model<unknown>>(MyModel: T) => T`
265
289
 
266
290
  **Type Parameters:**
@@ -284,7 +308,7 @@ class User extends E.Model<User> {
284
308
  }
285
309
  ```
286
310
 
287
- ### field · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L55)
311
+ ### field · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L60)
288
312
 
289
313
  Create a field definition for a model property.
290
314
 
@@ -314,51 +338,57 @@ class User extends E.Model<User> {
314
338
  }
315
339
  ```
316
340
 
317
- ### setOnSaveCallback · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L85)
341
+ ### string · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
318
342
 
319
- Set a callback function to be called after a model is saved and committed.
343
+ Type wrapper instance for the string type.
320
344
 
321
- **Signature:** `(callback: OnSaveType) => void`
345
+ **Value:** `TypeWrapper<string>`
322
346
 
323
- **Parameters:**
347
+ ### orderedString · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
348
+
349
+ Type wrapper instance for the ordered string type, which is just like a string
350
+ except that it sorts lexicographically in the database (instead of by incrementing
351
+ length first), making it suitable for index fields that want lexicographic range
352
+ scans. Ordered strings are implemented as null-terminated UTF-8 strings, so they
353
+ may not contain null characters.
324
354
 
325
- - `callback: OnSaveType | undefined` - The callback function to set. As arguments, it receives the model instance, the new key (undefined in case of a delete), and the old key (undefined in case of a create).
355
+ **Value:** `TypeWrapper<string>`
326
356
 
327
- ### string · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
357
+ ### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
328
358
 
329
- Constant representing the string type.
359
+ Type wrapper instance for the number type.
330
360
 
331
- **Value:** `StringType`
361
+ **Value:** `TypeWrapper<number>`
332
362
 
333
- ### number · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
363
+ ### dateTime · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
334
364
 
335
- Constant representing the number type.
365
+ Type wrapper instance for the date/time type.
336
366
 
337
- **Value:** `NumberType`
367
+ **Value:** `TypeWrapper<Date>`
338
368
 
339
- ### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
369
+ ### boolean · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
340
370
 
341
- Constant representing the boolean type.
371
+ Type wrapper instance for the boolean type.
342
372
 
343
- **Value:** `BooleanType`
373
+ **Value:** `TypeWrapper<boolean>`
344
374
 
345
- ### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
375
+ ### identifier · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
346
376
 
347
- Constant representing the identifier type.
377
+ Type wrapper instance for the identifier type.
348
378
 
349
- **Value:** `IdentifierType`
379
+ **Value:** `TypeWrapper<string>`
350
380
 
351
- ### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
381
+ ### undef · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
352
382
 
353
- Constant representing the 'undefined' type.
383
+ Type wrapper instance for the 'undefined' type.
354
384
 
355
- **Value:** `LiteralType<any>`
385
+ **Value:** `TypeWrapper<undefined>`
356
386
 
357
- ### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
387
+ ### opt · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
358
388
 
359
389
  Create an optional type wrapper (allows undefined).
360
390
 
361
- **Signature:** `<const T extends TypeWrapper<unknown> | BasicType>(inner: T) => OrType<any>`
391
+ **Signature:** `<const T extends TypeWrapper<unknown> | BasicType>(inner: T) => TypeWrapper<T extends TypeWrapper<infer U> ? U : T>`
362
392
 
363
393
  **Type Parameters:**
364
394
 
@@ -377,11 +407,11 @@ const optionalString = E.opt(E.string);
377
407
  const optionalNumber = E.opt(E.number);
378
408
  ```
379
409
 
380
- ### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
410
+ ### or · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
381
411
 
382
412
  Create a union type wrapper from multiple type choices.
383
413
 
384
- **Signature:** `<const T extends (TypeWrapper<unknown> | BasicType)[]>(...choices: T) => OrType<UnwrapTypes<T>>`
414
+ **Signature:** `<const T extends (TypeWrapper<unknown> | BasicType)[]>(...choices: T) => TypeWrapper<UnwrapTypes<T>>`
385
415
 
386
416
  **Type Parameters:**
387
417
 
@@ -400,11 +430,11 @@ const stringOrNumber = E.or(E.string, E.number);
400
430
  const status = E.or("active", "inactive", "pending");
401
431
  ```
402
432
 
403
- ### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
433
+ ### array · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
404
434
 
405
435
  Create an array type wrapper with optional length constraints.
406
436
 
407
- **Signature:** `<const T>(inner: TypeWrapper<T>, opts?: { min?: number; max?: number; }) => ArrayType<T>`
437
+ **Signature:** `<const T>(inner: TypeWrapper<T>, opts?: { min?: number; max?: number; }) => TypeWrapper<T[]>`
408
438
 
409
439
  **Type Parameters:**
410
440
 
@@ -424,11 +454,11 @@ const stringArray = E.array(E.string);
424
454
  const boundedArray = E.array(E.number, {min: 1, max: 10});
425
455
  ```
426
456
 
427
- ### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
457
+ ### literal · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
428
458
 
429
459
  Create a literal type wrapper for a constant value.
430
460
 
431
- **Signature:** `<const T>(value: T) => LiteralType<T>`
461
+ **Signature:** `<const T>(value: T) => TypeWrapper<T>`
432
462
 
433
463
  **Type Parameters:**
434
464
 
@@ -447,11 +477,11 @@ const statusType = E.literal("active");
447
477
  const countType = E.literal(42);
448
478
  ```
449
479
 
450
- ### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
480
+ ### link · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
451
481
 
452
482
  Create a link type wrapper for model relationships.
453
483
 
454
- **Signature:** `<const T extends typeof Model<any>>(TargetModel: T) => LinkType<T>`
484
+ **Signature:** `<const T extends typeof Model<any>>(TargetModel: T) => TypeWrapper<InstanceType<T>>`
455
485
 
456
486
  **Type Parameters:**
457
487
 
@@ -475,7 +505,7 @@ class Post extends E.Model<Post> {
475
505
  }
476
506
  ```
477
507
 
478
- ### index · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
508
+ ### index · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
479
509
 
480
510
  Create a secondary index on model fields.
481
511
 
@@ -502,7 +532,7 @@ class User extends E.Model<User> {
502
532
  }
503
533
  ```
504
534
 
505
- ### primary · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
535
+ ### primary · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
506
536
 
507
537
  Create a primary index on model fields.
508
538
 
@@ -529,7 +559,7 @@ class User extends E.Model<User> {
529
559
  }
530
560
  ```
531
561
 
532
- ### unique · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
562
+ ### unique · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
533
563
 
534
564
  Create a unique index on model fields.
535
565
 
@@ -556,7 +586,7 @@ class User extends E.Model<User> {
556
586
  }
557
587
  ```
558
588
 
559
- ### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
589
+ ### dump · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
560
590
 
561
591
  Dump database contents for debugging.
562
592
 
@@ -565,7 +595,18 @@ This is primarily useful for development and debugging purposes.
565
595
 
566
596
  **Signature:** `() => void`
567
597
 
568
- ### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L104)
598
+ ### setLogLevel · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L55)
599
+
600
+ Global log level for debugging output.
601
+ 0 = no logging, 1 = model-level logs, 2 = update logs, 3 = read logs.
602
+
603
+ **Signature:** `(level: number) => void`
604
+
605
+ **Parameters:**
606
+
607
+ - `level: number`
608
+
609
+ ### BaseIndex · [abstract class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L129)
569
610
 
570
611
  Base class for database indexes for efficient lookups on model fields.
571
612
 
@@ -581,7 +622,7 @@ Indexes enable fast queries on specific field combinations and enforce uniquenes
581
622
  - `MyModel`: - The model class this index belongs to.
582
623
  - `_fieldNames`: - Array of field names that make up this index.
583
624
 
584
- #### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
625
+ #### baseIndex.find · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
585
626
 
586
627
  Find model instances using flexible range query options.
587
628
 
@@ -589,7 +630,7 @@ Supports exact matches, inclusive/exclusive range queries, and reverse iteration
589
630
  For single-field indexes, you can pass values directly or in arrays.
590
631
  For multi-field indexes, pass arrays or partial arrays for prefix matching.
591
632
 
592
- **Signature:** `(opts?: FindOptions<IndexArgTypes<M, F>>) => IndexRangeIterator<M, F>`
633
+ **Signature:** `(opts?: FindOptions<IndexArgTypes<M, F>>) => IndexRangeIterator<M>`
593
634
 
594
635
  **Parameters:**
595
636
 
@@ -640,7 +681,14 @@ for (const user of User.byEmail.find({is: "john@example.com"})) {
640
681
  }
641
682
  ```
642
683
 
643
- ### UniqueIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
684
+ #### baseIndex.toString · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
685
+
686
+ **Signature:** `() => string`
687
+
688
+ **Parameters:**
689
+
690
+
691
+ ### UniqueIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
644
692
 
645
693
  Unique index that stores references to the primary key.
646
694
 
@@ -649,7 +697,7 @@ Unique index that stores references to the primary key.
649
697
  - `M extends typeof Model` - The model class this index belongs to.
650
698
  - `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
651
699
 
652
- #### uniqueIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
700
+ #### uniqueIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
653
701
 
654
702
  Get a model instance by unique index key values.
655
703
 
@@ -667,7 +715,7 @@ Get a model instance by unique index key values.
667
715
  const userByEmail = User.byEmail.get("john@example.com");
668
716
  ```
669
717
 
670
- ### PrimaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
718
+ ### PrimaryIndex · [class](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
671
719
 
672
720
  Primary index that stores the actual model data.
673
721
 
@@ -676,15 +724,15 @@ Primary index that stores the actual model data.
676
724
  - `M extends typeof Model` - The model class this index belongs to.
677
725
  - `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
678
726
 
679
- #### primaryIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
727
+ #### primaryIndex.get · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
680
728
 
681
729
  Get a model instance by primary key values.
682
730
 
683
- **Signature:** `(...args: IndexArgTypes<M, F>) => InstanceType<M>`
731
+ **Signature:** `(...args: IndexArgTypes<M, F> | [Uint8Array<ArrayBufferLike>]) => InstanceType<M>`
684
732
 
685
733
  **Parameters:**
686
734
 
687
- - `args: IndexArgTypes<M, F>` - - The primary key values.
735
+ - `args: IndexArgTypes<M, F> | [Uint8Array]` - - The primary key values.
688
736
 
689
737
  **Returns:** The model instance if found, undefined otherwise.
690
738
 
@@ -694,7 +742,21 @@ Get a model instance by primary key values.
694
742
  const user = User.pk.get("john_doe");
695
743
  ```
696
744
 
697
- ### init · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
745
+ #### primaryIndex.getLazy · [method](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
746
+
747
+ Does the same as as `get()`, but will delay loading the instance from disk until the first
748
+ property access. In case it turns out the instance doesn't exist, an error will be thrown
749
+ at that time.
750
+
751
+ **Signature:** `(...args: IndexArgTypes<M, F> | [Uint8Array<ArrayBufferLike>]) => InstanceType<M>`
752
+
753
+ **Parameters:**
754
+
755
+ - `args: IndexArgTypes<M, F> | [Uint8Array]` - Primary key field values. (Or a single Uint8Array containing the key.)
756
+
757
+ **Returns:** The (lazily loaded) model instance.
758
+
759
+ ### init · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L141)
698
760
 
699
761
  Initialize the database with the specified directory path.
700
762
  This function may only be called once. If it is not called before the first transact(),
@@ -718,7 +780,7 @@ the database will be automatically initialized with the default directory.
718
780
  init("./my-database");
719
781
  ```
720
782
 
721
- ### onCommit · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
783
+ ### onCommit · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L159)
722
784
 
723
785
  Registers a callback to be executed when the current transaction commits successfully.
724
786
  The callback will be executed outside of transaction context.
@@ -733,7 +795,7 @@ The callback will be executed outside of transaction context.
733
795
 
734
796
  - If called outside of a transaction context
735
797
 
736
- ### onRevert · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
798
+ ### onRevert · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L151)
737
799
 
738
800
  Registers a callback to be executed when the current transaction is reverted (aborted due to error).
739
801
  The callback will be executed outside of transaction context.
@@ -748,7 +810,7 @@ The callback will be executed outside of transaction context.
748
810
 
749
811
  - If called outside of a transaction context
750
812
 
751
- ### getTransactionData · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L51)
813
+ ### getTransactionData · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L55)
752
814
 
753
815
  Retrieves data from the current transaction context.
754
816
 
@@ -764,7 +826,7 @@ Retrieves data from the current transaction context.
764
826
 
765
827
  - If called outside of a transaction context.
766
828
 
767
- ### setTransactionData · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L44)
829
+ ### setTransactionData · [function](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L46)
768
830
 
769
831
  Attach some arbitrary user data to the current transaction context, which is
770
832
  attached to the currently running (async) task.
@@ -792,7 +854,7 @@ await transact(async () => {
792
854
  });
793
855
  ```
794
856
 
795
- ### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L120)
857
+ ### DatabaseError · [constant](https://github.com/vanviegen/edinburgh/blob/main/src/edinburgh.ts#L142)
796
858
 
797
859
  The DatabaseError class is used to represent errors that occur during database operations.
798
860
  It extends the built-in Error class and has a machine readable error code string property.
@@ -0,0 +1,119 @@
1
+ /**
2
+ * A byte buffer for efficient reading and writing of primitive values and bit sequences.
3
+ *
4
+ * The DataPack class provides methods for serializing and deserializing various data types
5
+ * including numbers, strings, bit sequences, and other primitive values to/from byte buffers.
6
+ * It supports both reading and writing operations with automatic buffer management.
7
+ */
8
+ export declare class DataPack {
9
+ private buffer;
10
+ private dataView?;
11
+ readPos: number;
12
+ writePos: number;
13
+ /**
14
+ * Backward compatibility: Access to the internal buffer
15
+ */
16
+ get _buffer(): Uint8Array;
17
+ /**
18
+ * Create a new DataPack instance.
19
+ * @param data - Optional initial data as Uint8Array or buffer size as number.
20
+ */
21
+ constructor(data?: Uint8Array | number);
22
+ /**
23
+ * Helper function to write a multi-byte integer with length prefix
24
+ * @param value - The value to write
25
+ * @param headerType - The type bits (0-7) for the header
26
+ * @param invertBytes - Whether to invert bytes (for negative numbers)
27
+ * @param invertByteCount - Whether to invert the byte count (for type 0)
28
+ */
29
+ private writeMultiByteNumber;
30
+ /**
31
+ * Helper function to read a multi-byte integer with length prefix
32
+ * @param byteCount - Number of bytes to read
33
+ * @param invertBytes - Whether to invert bytes (for negative numbers)
34
+ * @returns The read value
35
+ */
36
+ private readMultiByteNumber;
37
+ private notEnoughData;
38
+ /**
39
+ * Each data item starts with a single byte. The high 3 bits indicate the type.
40
+ * The low 5 bits indicate a size or a subtype, depending on the type.
41
+ *
42
+ * 0: negative integer (byte count encoded as bitwise NOT in lower bits)
43
+ * 1: small integer 0..31 (encoded in lower bits)
44
+ * 2: small integer 32...63 (encoded in lower bits)
45
+ * 3: integer (byte count encoded in lower bits)
46
+ * 4:
47
+ * 0: float64 (8 bytes follow)
48
+ * 1: undefined
49
+ * 2: null
50
+ * 3: true
51
+ * 4: false
52
+ * 5: array start (followed by a items until EOD)
53
+ * 6: object start (followed by key+value pairs until EOD)
54
+ * 7: map start (followed by key+value pairs until EOD)
55
+ * 8: set start (followed by items until EOD)
56
+ * 9: EOD
57
+ * 10: identifier (6 byte positive int follows, represented as a base64 string of length 8)
58
+ * 11: null-terminated string
59
+ * 5: short string (length in lower bits, 0-31)
60
+ * 6: string (byte count of length in lower bits)
61
+ * 7: blob (byte count of length in lower bits)
62
+ */
63
+ write(data: any): DataPack;
64
+ read(): any;
65
+ /**
66
+ * Ensure the buffer has capacity for additional bytes.
67
+ * @param bytesNeeded - Number of additional bytes needed.
68
+ */
69
+ private ensureCapacity;
70
+ readNumber(): number;
71
+ readDate(): Date;
72
+ readPositiveInt(limit?: number): number;
73
+ readBoolean(): boolean;
74
+ readUint8Array(): Uint8Array;
75
+ readString(): string;
76
+ writeIdentifier(id: string): DataPack;
77
+ readIdentifier(): string;
78
+ /**
79
+ * Like writeString but writes without a length prefix and with a null terminator, for ordered storage.
80
+ * Can be read with {@link read} or {@link readString} just like any other string.
81
+ * @param str - The string to write. May not contain null characters.
82
+ */
83
+ writeOrderedString(str: string): DataPack;
84
+ toUint8Array(copyBuffer?: boolean, startPos?: number, endPos?: number): Uint8Array;
85
+ clone(copyBuffer: boolean, readPos?: number, writePos?: number): DataPack;
86
+ /**
87
+ * Write a collection (array, set, object, or map) using a callback to add items/fields.
88
+ * @param type 'array' | 'set' | 'object' | 'map'
89
+ * @param bodyFunc Callback function to add items/fields. It accepts a function to add values or key-value pairs (depending on the collection type).
90
+ * @returns The DataPack instance for chaining.
91
+ * @example
92
+ * // Writing an array
93
+ * pack.writeCollection('array', add => {
94
+ * add(1);
95
+ * add(2);
96
+ * add(3);
97
+ * });
98
+ *
99
+ * // Writing an object
100
+ * pack.writeCollection('object', (add) => {
101
+ * add('key1', 'value1');
102
+ * add('key2', 42);
103
+ * });
104
+ */
105
+ writeCollection(type: 'array' | 'set', bodyFunc: (addField: (value: any) => void) => void): DataPack;
106
+ writeCollection(type: 'object', bodyFunc: (addField: (field: number | string | symbol, value: any) => void) => void): DataPack;
107
+ writeCollection(type: 'map', bodyFunc: (addField: (field: any, value: any) => void) => void): DataPack;
108
+ /**
109
+ * Increment the last byte of the buffer. If it was already 255 set it to 0 and
110
+ * increment the previous byte, and so on. If all bytes were 255, return undefined.
111
+ * This is useful for creating an exclusive end key for range scans.
112
+ * This may result in a DataPack instance that cannot be parsed (or represented by
113
+ * {@link toString}).
114
+ */
115
+ increment(): DataPack | undefined;
116
+ toString(extended?: boolean | undefined, startPos?: number, endPos?: number): string;
117
+ readAvailable(): boolean;
118
+ static generateIdentifier(): string;
119
+ }