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.
@@ -1,6 +1,8 @@
1
- export { Model, registerModel, field, setOnSaveCallback } from "./models.js";
2
- export { string, number, boolean, identifier, undef, opt, or, array, literal, link, } from "./types.js";
1
+ export { Model, registerModel, field, } from "./models.js";
2
+ import type { ChangedModel } from "./models.js";
3
+ export { string, orderedString, number, dateTime, boolean, identifier, undef, opt, or, array, literal, link, } from "./types.js";
3
4
  export { index, primary, unique, dump, } from "./indexes.js";
5
+ export { setLogLevel } from "./utils.js";
4
6
  export { BaseIndex, UniqueIndex, PrimaryIndex } from './indexes.js';
5
7
  export { init, onCommit, onRevert, getTransactionData, setTransactionData, DatabaseError } from "olmdb";
6
8
  /**
@@ -26,7 +28,7 @@ export { init, onCommit, onRevert, getTransactionData, setTransactionData, Datab
26
28
  * @example
27
29
  * ```typescript
28
30
  * const paid = await E.transact(() => {
29
- * const user = User.load("john_doe");
31
+ * const user = User.pk.get("john_doe");
30
32
  * // This is concurrency-safe - the function will rerun if it is raced by another transaction
31
33
  * if (user.credits > 0) {
32
34
  * user.credits--;
@@ -44,4 +46,14 @@ export { init, onCommit, onRevert, getTransactionData, setTransactionData, Datab
44
46
  * ```
45
47
  */
46
48
  export declare function transact<T>(fn: () => T): Promise<T>;
49
+ /**
50
+ * Set a callback function to be called after a model is saved and committed.
51
+ *
52
+ * @param callback The callback function to set. It gets called after each successful
53
+ * `transact()` commit that has changes, with the following arguments:
54
+ * - A sequential number. Higher numbers have been committed after lower numbers.
55
+ * - An array of model instances that have been modified, created, or deleted.
56
+ * You can used its {@link Model.changed} property to figure out what changed.
57
+ */
58
+ export declare function setOnSaveCallback(callback: ((commitId: number, items: ChangedModel[]) => void) | undefined): void;
47
59
  export declare function deleteEverything(): Promise<void>;
@@ -1,15 +1,17 @@
1
1
  import * as olmdb from "olmdb";
2
- import { MODIFIED_INSTANCES_SYMBOL, resetModelCaches } from "./models.js";
2
+ import { INSTANCES_SYMBOL, resetModelCaches } from "./models.js";
3
+ import { INSTANCES_BY_PK_SYMBOL } from "./indexes.js";
3
4
  // Re-export public API from models
4
- export { Model, registerModel, field, setOnSaveCallback } from "./models.js";
5
+ export { Model, registerModel, field, } from "./models.js";
5
6
  // Re-export public API from types (only factory functions and instances)
6
7
  export {
7
8
  // Pre-defined type instances
8
- string, number, boolean, identifier, undef,
9
+ string, orderedString, number, dateTime, boolean, identifier, undef,
9
10
  // Type factory functions
10
11
  opt, or, array, literal, link, } from "./types.js";
11
12
  // Re-export public API from indexes
12
13
  export { index, primary, unique, dump, } from "./indexes.js";
14
+ export { setLogLevel } from "./utils.js";
13
15
  export { BaseIndex, UniqueIndex, PrimaryIndex } from './indexes.js';
14
16
  // Re-export from OLMDB
15
17
  export { init, onCommit, onRevert, getTransactionData, setTransactionData, DatabaseError } from "olmdb";
@@ -36,7 +38,7 @@ export { init, onCommit, onRevert, getTransactionData, setTransactionData, Datab
36
38
  * @example
37
39
  * ```typescript
38
40
  * const paid = await E.transact(() => {
39
- * const user = User.load("john_doe");
41
+ * const user = User.pk.get("john_doe");
40
42
  * // This is concurrency-safe - the function will rerun if it is raced by another transaction
41
43
  * if (user.credits > 0) {
42
44
  * user.credits--;
@@ -53,34 +55,66 @@ export { init, onCommit, onRevert, getTransactionData, setTransactionData, Datab
53
55
  * });
54
56
  * ```
55
57
  */
56
- export function transact(fn) {
57
- return olmdb.transact(() => {
58
- const modifiedInstances = new Set();
59
- olmdb.setTransactionData(MODIFIED_INSTANCES_SYMBOL, modifiedInstances);
60
- const savedInstances = new Set();
61
- try {
62
- const result = fn();
63
- // Save all modified instances before committing.
64
- while (modifiedInstances.size > 0) {
65
- // Back referencing can cause models to be scheduled for save() a second time,
66
- // which is why we require the outer loop.
67
- for (const instance of modifiedInstances) {
68
- instance._save();
69
- savedInstances.add(instance);
70
- modifiedInstances.delete(instance);
58
+ export async function transact(fn) {
59
+ try {
60
+ const onSaveQueue = onSaveCallback ? [] : undefined;
61
+ return await olmdb.transact(async () => {
62
+ const instances = new Set();
63
+ olmdb.setTransactionData(INSTANCES_SYMBOL, instances);
64
+ olmdb.setTransactionData(INSTANCES_BY_PK_SYMBOL, new Map());
65
+ const savedInstances = new Set();
66
+ try {
67
+ const result = await fn();
68
+ // Save all modified instances before committing.
69
+ while (instances.size > 0) {
70
+ // Back referencing can cause models to be scheduled for save() a second time,
71
+ // which is why we require the outer loop.
72
+ for (const instance of instances) {
73
+ instance._onCommit(onSaveQueue);
74
+ savedInstances.add(instance);
75
+ instances.delete(instance);
76
+ }
71
77
  }
78
+ if (onSaveQueue?.length) {
79
+ olmdb.onCommit((commitId) => {
80
+ if (onSaveCallback)
81
+ onSaveCallback(commitId, onSaveQueue);
82
+ });
83
+ }
84
+ return result;
72
85
  }
73
- return result;
74
- }
75
- catch (error) {
76
- // Discard changes on all saved and still unsaved instances
77
- for (const instance of savedInstances)
78
- instance.preventPersist();
79
- for (const instance of modifiedInstances)
80
- instance.preventPersist();
81
- throw error;
82
- }
83
- });
86
+ catch (error) {
87
+ // Discard changes on all saved and still unsaved instances
88
+ for (const instance of savedInstances)
89
+ instance.preventPersist();
90
+ for (const instance of instances)
91
+ instance.preventPersist();
92
+ throw error;
93
+ }
94
+ });
95
+ }
96
+ catch (e) {
97
+ // This hackery is required to provide useful stack traces. Without this,
98
+ // both Bun and Node (even with --async-stack-traces) don't show which
99
+ // line called the transact(), which is pretty important info when validation
100
+ // fails, for instance. Though the line numbers in Bun still don't really
101
+ // make sense. Probably this bug: https://github.com/oven-sh/bun/issues/15859
102
+ e.stack += "\nat async:\n" + new Error().stack?.replace(/^.*?\n/, '');
103
+ throw e;
104
+ }
105
+ }
106
+ let onSaveCallback;
107
+ /**
108
+ * Set a callback function to be called after a model is saved and committed.
109
+ *
110
+ * @param callback The callback function to set. It gets called after each successful
111
+ * `transact()` commit that has changes, with the following arguments:
112
+ * - A sequential number. Higher numbers have been committed after lower numbers.
113
+ * - An array of model instances that have been modified, created, or deleted.
114
+ * You can used its {@link Model.changed} property to figure out what changed.
115
+ */
116
+ export function setOnSaveCallback(callback) {
117
+ onSaveCallback = callback;
84
118
  }
85
119
  export async function deleteEverything() {
86
120
  await olmdb.transact(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"edinburgh.js","sourceRoot":"","sources":["../../src/edinburgh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAS,yBAAyB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEjF,mCAAmC;AACnC,OAAO,EACH,KAAK,EACL,aAAa,EACb,KAAK,EACL,iBAAiB,EACpB,MAAM,aAAa,CAAC;AAGrB,yEAAyE;AACzE,OAAO;AACH,6BAA6B;AAC7B,MAAM,EACN,MAAM,EACN,OAAO,EACP,UAAU,EACV,KAAK;AACL,yBAAyB;AACzB,GAAG,EACH,EAAE,EACF,KAAK,EACL,OAAO,EACP,IAAI,GACP,MAAM,YAAY,CAAC;AAEpB,oCAAoC;AACpC,OAAO,EACH,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,GACP,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE,uBAAuB;AACvB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGxG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCE;AACF,MAAM,UAAU,QAAQ,CAAI,EAAW;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACvB,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAc,CAAC;QAChD,KAAK,CAAC,kBAAkB,CAAC,yBAAyB,EAAE,iBAAiB,CAAC,CAAC;QAEvE,MAAM,cAAc,GAAoB,IAAI,GAAG,EAAE,CAAC;QAClD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,EAAE,EAAE,CAAC;YACpB,iDAAiD;YACjD,OAAM,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC/B,8EAA8E;gBAC9E,0CAA0C;gBAC1C,KAAK,MAAM,QAAQ,IAAI,iBAAiB,EAAE,CAAC;oBACvC,QAAQ,CAAC,KAAK,EAAE,CAAC;oBACjB,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBAC7B,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACvC,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,2DAA2D;YAC3D,KAAK,MAAM,QAAQ,IAAI,cAAc;gBAAE,QAAQ,CAAC,cAAc,EAAE,CAAC;YACjE,KAAK,MAAM,QAAQ,IAAI,iBAAiB;gBAAE,QAAQ,CAAC,cAAc,EAAE,CAAC;YACpE,MAAM,KAAK,CAAC;QAChB,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IAClC,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACtB,KAAK,MAAM,EAAC,GAAG,EAAC,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,gBAAgB,EAAE,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"edinburgh.js","sourceRoot":"","sources":["../../src/edinburgh.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAS,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,mCAAmC;AACnC,OAAO,EACH,KAAK,EACL,aAAa,EACb,KAAK,GACR,MAAM,aAAa,CAAC;AAIrB,yEAAyE;AACzE,OAAO;AACH,6BAA6B;AAC7B,MAAM,EACN,aAAa,EACb,MAAM,EACN,QAAQ,EACR,OAAO,EACP,UAAU,EACV,KAAK;AACL,yBAAyB;AACzB,GAAG,EACH,EAAE,EACF,KAAK,EACL,OAAO,EACP,IAAI,GACP,MAAM,YAAY,CAAC;AAEpB,oCAAoC;AACpC,OAAO,EACH,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,GACP,MAAM,cAAc,CAAC;AAEtB,OAAO,EACH,WAAW,EACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE,uBAAuB;AACvB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAExG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuCE;AACF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,EAAW;IACzC,IAAI,CAAC;QACD,MAAM,WAAW,GAA+B,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAChF,OAAO,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAgB,EAAE;YAC/C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;YACxC,KAAK,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;YACtD,KAAK,CAAC,kBAAkB,CAAC,sBAAsB,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;YAE5D,MAAM,cAAc,GAAoB,IAAI,GAAG,EAAE,CAAC;YAClD,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;gBAC1B,iDAAiD;gBACjD,OAAM,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;oBACvB,8EAA8E;oBAC9E,0CAA0C;oBAC1C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;wBAC/B,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;wBAChC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;wBAC7B,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBAC/B,CAAC;gBACL,CAAC;gBACD,IAAI,WAAW,EAAE,MAAM,EAAE,CAAC;oBACtB,KAAK,CAAC,QAAQ,CAAC,CAAC,QAAgB,EAAE,EAAE;wBAChC,IAAI,cAAc;4BAAE,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;oBAC9D,CAAC,CAAC,CAAC;gBACP,CAAC;gBAED,OAAO,MAAM,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,2DAA2D;gBAC3D,KAAK,MAAM,QAAQ,IAAI,cAAc;oBAAE,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACjE,KAAK,MAAM,QAAQ,IAAI,SAAS;oBAAE,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAC5D,MAAM,KAAK,CAAC;YAChB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAAC,OAAO,CAAc,EAAE,CAAC;QACtB,yEAAyE;QACzE,sEAAsE;QACtE,6EAA6E;QAC7E,yEAAyE;QACzE,6EAA6E;QAC7E,CAAC,CAAC,KAAK,IAAI,eAAe,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,CAAC,CAAC;IACZ,CAAC;AACL,CAAC;AAED,IAAI,cAA+E,CAAC;AAEpF;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAyE;IACvG,cAAc,GAAG,QAAQ,CAAC;AAC9B,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,gBAAgB;IAClC,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACtB,KAAK,MAAM,EAAC,GAAG,EAAC,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,gBAAgB,EAAE,CAAC;AAC7B,CAAC"}
@@ -1,8 +1,7 @@
1
1
  import * as olmdb from "olmdb";
2
- import { Bytes } from "./bytes.js";
2
+ import { DataPack } from "./datapack.js";
3
3
  import { Model } from "./models.js";
4
- /** @internal Symbol used to access the underlying model from a proxy */
5
- export declare const TARGET_SYMBOL: unique symbol;
4
+ import { TypeWrapper } from "./types.js";
6
5
  type IndexArgTypes<M extends typeof Model<any>, F extends readonly (keyof InstanceType<M> & string)[]> = {
7
6
  [I in keyof F]: InstanceType<M>[F[I]];
8
7
  };
@@ -11,11 +10,11 @@ type IndexArgTypes<M extends typeof Model<any>, F extends readonly (keyof Instan
11
10
  * Handles common iteration logic for both primary and unique indexes.
12
11
  * Implements both Iterator and Iterable interfaces for efficiency.
13
12
  */
14
- declare class IndexRangeIterator<M extends typeof Model, F extends readonly (keyof InstanceType<M> & string)[]> implements Iterator<InstanceType<M>>, Iterable<InstanceType<M>> {
13
+ export declare class IndexRangeIterator<M extends typeof Model> implements Iterator<InstanceType<M>>, Iterable<InstanceType<M>> {
15
14
  private iterator;
16
15
  private indexId;
17
16
  private parentIndex;
18
- constructor(iterator: olmdb.DbIterator<any, any> | undefined, indexId: number, parentIndex: BaseIndex<M, F>);
17
+ constructor(iterator: olmdb.DbIterator<any, any> | undefined, indexId: number, parentIndex: BaseIndex<M, any>);
19
18
  [Symbol.iterator](): Iterator<InstanceType<M>>;
20
19
  next(): IteratorResult<InstanceType<M>>;
21
20
  count(): number;
@@ -35,6 +34,7 @@ type FindOptions<ARG_TYPES extends readonly any[]> = (({
35
34
  } | {}))) & {
36
35
  reverse?: boolean;
37
36
  });
37
+ export declare function testArraysEqual(array1: Uint8Array, array2: Uint8Array): boolean;
38
38
  /**
39
39
  * Base class for database indexes for efficient lookups on model fields.
40
40
  *
@@ -46,72 +46,42 @@ type FindOptions<ARG_TYPES extends readonly any[]> = (({
46
46
  export declare abstract class BaseIndex<M extends typeof Model, const F extends readonly (keyof InstanceType<M> & string)[]> {
47
47
  _fieldNames: F;
48
48
  _MyModel: M;
49
+ _fieldTypes: Map<keyof InstanceType<M> & string, TypeWrapper<any>>;
50
+ _fieldCount: number;
49
51
  /**
50
52
  * Create a new index.
51
53
  * @param MyModel - The model class this index belongs to.
52
54
  * @param _fieldNames - Array of field names that make up this index.
53
55
  */
54
- constructor(MyModel: M, _fieldNames: F, isPrimary?: boolean);
56
+ constructor(MyModel: M, _fieldNames: F);
57
+ _delayedInit(): boolean;
55
58
  _cachedIndexId?: number;
56
59
  /**
57
- * Deserialize index key bytes back to field values.
58
- * @param bytes - Bytes to read from.
59
- * @returns Array of field values.
60
+ * Serialize array of key values to a (index-id prefixed) Bytes instance that can be used as a key.
61
+ * @param args - Field values to serialize (can be partial for range queries).
62
+ * @returns A Bytes instance containing the index id and serialized key parts.
63
+ * @internal
60
64
  */
61
- _deserializeKey(bytes: Bytes): IndexArgTypes<M, F>;
65
+ _argsToKeyBytes(args: [], allowPartial: boolean): DataPack;
66
+ _argsToKeyBytes(args: Partial<IndexArgTypes<M, F>>, allowPartial: boolean): DataPack;
67
+ _argsToKeySingleton(args: IndexArgTypes<M, F>): Uint8Array;
62
68
  /**
63
69
  * Extract model from iterator entry - implemented differently by each index type.
64
70
  * @param keyBytes - Key bytes with index ID already read.
65
- * @param valueBytes - Value bytes from the entry.
71
+ * @param valueBuffer - Value Uint8Array from the entry.
66
72
  * @returns Model instance or undefined.
67
73
  * @internal
68
74
  */
69
- abstract _getModelFromEntry(keyBytes: Bytes, valueBytes: Bytes): InstanceType<M> | undefined;
70
- /**
71
- * Serialize field values to bytes for index key.
72
- * @param args - Field values to serialize (can be partial for range queries).
73
- * @param bytes - Bytes to write to.
74
- * @internal
75
- */
76
- _serializeArgs(args: Partial<IndexArgTypes<M, F>> | readonly any[], bytes: Bytes): void;
77
- /**
78
- * Create database key from field values.
79
- * @param args - Field values.
80
- * @returns Database key bytes.
81
- */
82
- _getKeyFromArgs(args: IndexArgTypes<M, F>): Uint8Array;
83
- /**
84
- * Serialize model fields to bytes for index key.
85
- * @param model - Model instance.
86
- * @param bytes - Bytes to write to.
87
- */
88
- _serializeModel(model: InstanceType<M>, bytes: Bytes): void;
89
- /**
90
- * Create database key from model instance.
91
- * @param model - Model instance.
92
- * @param includeIndexId - Whether to include index ID in key.
93
- * @returns Database key bytes or undefined if skipped.
94
- * @internal
95
- */
96
- _getKeyFromModel(model: InstanceType<M>, includeIndexId: boolean): Uint8Array;
97
- /**
98
- * Extract field values from model for this index.
99
- * @param model - Model instance.
100
- * @returns Field values or undefined if should be skipped.
101
- * @internal
102
- */
103
- _modelToArgs(model: InstanceType<M>): IndexArgTypes<M, F> | undefined;
75
+ abstract _pairToInstance(keyBytes: DataPack, valueBuffer: Uint8Array): InstanceType<M> | undefined;
76
+ _hasNullIndexValues(model: InstanceType<M>): boolean;
77
+ _instanceToKeyBytes(model: InstanceType<M>): DataPack;
104
78
  /**
105
79
  * Get or create unique index ID for this index.
106
80
  * @returns Numeric index ID.
107
81
  */
108
82
  _getIndexId(): number;
109
- /**
110
- * Check if indexing should be skipped for a model instance.
111
- * @param model - Model instance.
112
- * @returns true if indexing should be skipped.
113
- */
114
- _checkSkip(model: InstanceType<M>): boolean;
83
+ abstract _delete(model: InstanceType<M>): void;
84
+ abstract _write(model: InstanceType<M>): void;
115
85
  /**
116
86
  * Find model instances using flexible range query options.
117
87
  *
@@ -170,15 +140,12 @@ export declare abstract class BaseIndex<M extends typeof Model, const F extends
170
140
  * }
171
141
  * ```
172
142
  */
173
- find(opts?: FindOptions<IndexArgTypes<M, F>>): IndexRangeIterator<M, F>;
174
- /**
175
- * Save index entry for a model instance.
176
- * @param model - Model instance to save.
177
- * @param originalKey - Original key if updating.
178
- */
179
- abstract _save(model: InstanceType<M>, originalKey?: Uint8Array): Uint8Array | undefined;
143
+ find(opts?: FindOptions<IndexArgTypes<M, F>>): IndexRangeIterator<M>;
180
144
  abstract _getTypeName(): string;
145
+ toString(): string;
181
146
  }
147
+ /** @internal Symbol used to attach modified instances, keyed by singleton primary key, to a transaction */
148
+ export declare const INSTANCES_BY_PK_SYMBOL: unique symbol;
182
149
  /**
183
150
  * Primary index that stores the actual model data.
184
151
  *
@@ -186,7 +153,11 @@ export declare abstract class BaseIndex<M extends typeof Model, const F extends
186
153
  * @template F - The field names that make up this index.
187
154
  */
188
155
  export declare class PrimaryIndex<M extends typeof Model, const F extends readonly (keyof InstanceType<M> & string)[]> extends BaseIndex<M, F> {
156
+ _nonKeyFields: (keyof InstanceType<M> & string)[];
157
+ _lazyDescriptors: Record<string | symbol | number, PropertyDescriptor>;
158
+ _resetDescriptors: Record<string | symbol | number, PropertyDescriptor>;
189
159
  constructor(MyModel: M, fieldNames: F);
160
+ _delayedInit(): boolean;
190
161
  /**
191
162
  * Get a model instance by primary key values.
192
163
  * @param args - The primary key values.
@@ -197,22 +168,29 @@ export declare class PrimaryIndex<M extends typeof Model, const F extends readon
197
168
  * const user = User.pk.get("john_doe");
198
169
  * ```
199
170
  */
200
- get(...args: IndexArgTypes<M, F>): InstanceType<M> | undefined;
171
+ get(...args: IndexArgTypes<M, F> | [Uint8Array]): InstanceType<M> | undefined;
201
172
  /**
202
- * Extract model from iterator entry for primary index.
203
- * @param keyBytes - Key bytes with index ID already read.
204
- * @param valueBytes - Value bytes from the entry.
205
- * @returns Model instance or undefined.
206
- * @internal
173
+ * Does the same as as `get()`, but will delay loading the instance from disk until the first
174
+ * property access. In case it turns out the instance doesn't exist, an error will be thrown
175
+ * at that time.
176
+ * @param args Primary key field values. (Or a single Uint8Array containing the key.)
177
+ * @returns The (lazily loaded) model instance.
207
178
  */
208
- _getModelFromEntry(keyBytes: Bytes, valueBytes: Bytes): InstanceType<M> | undefined;
179
+ getLazy(...args: IndexArgTypes<M, F> | [Uint8Array]): InstanceType<M>;
180
+ _get(args: IndexArgTypes<M, F> | [Uint8Array], lazy: true): InstanceType<M>;
181
+ _get(args: IndexArgTypes<M, F> | [Uint8Array], lazy: false): InstanceType<M> | undefined;
209
182
  /**
210
- * Save primary index entry.
211
- * @param model - Model instance.
212
- * @param originalKey - Original key if updating.
183
+ * Create a canonical primary key buffer for the given model instance.
184
+ * Returns a singleton Uint8Array for stable Map/Set identity usage.
213
185
  */
214
- _save(model: InstanceType<M>, originalKey?: Uint8Array): Uint8Array;
186
+ _instanceToKeySingleton(model: InstanceType<M>): Uint8Array;
187
+ _lazyNow(model: InstanceType<M>): void;
188
+ _setNonKeyValues(model: InstanceType<M>, valueBytes: DataPack): void;
189
+ _keyToArray(key: Uint8Array): IndexArgTypes<M, F>;
190
+ _pairToInstance(keyBytes: DataPack, valueBuffer: Uint8Array): InstanceType<M> | undefined;
215
191
  _getTypeName(): string;
192
+ _write(model: InstanceType<M>): void;
193
+ _delete(model: InstanceType<M>): void;
216
194
  }
217
195
  /**
218
196
  * Unique index that stores references to the primary key.
@@ -221,6 +199,7 @@ export declare class PrimaryIndex<M extends typeof Model, const F extends readon
221
199
  * @template F - The field names that make up this index.
222
200
  */
223
201
  export declare class UniqueIndex<M extends typeof Model, const F extends readonly (keyof InstanceType<M> & string)[]> extends BaseIndex<M, F> {
202
+ constructor(MyModel: M, fieldNames: F);
224
203
  /**
225
204
  * Get a model instance by unique index key values.
226
205
  * @param args - The unique index key values.
@@ -232,6 +211,8 @@ export declare class UniqueIndex<M extends typeof Model, const F extends readonl
232
211
  * ```
233
212
  */
234
213
  get(...args: IndexArgTypes<M, F>): InstanceType<M> | undefined;
214
+ _delete(model: InstanceType<M>): void;
215
+ _write(model: InstanceType<M>): void;
235
216
  /**
236
217
  * Extract model from iterator entry for unique index.
237
218
  * @param keyBytes - Key bytes with index ID already read.
@@ -239,13 +220,7 @@ export declare class UniqueIndex<M extends typeof Model, const F extends readonl
239
220
  * @returns Model instance or undefined.
240
221
  * @internal
241
222
  */
242
- _getModelFromEntry(keyBytes: Bytes, valueBytes: Bytes): InstanceType<M> | undefined;
243
- /**
244
- * Save unique index entry.
245
- * @param model - Model instance.
246
- * @param originalKey - Original key if updating.
247
- */
248
- _save(model: InstanceType<M>, originalKey?: Uint8Array): Uint8Array | undefined;
223
+ _pairToInstance(keyBytes: DataPack, valueBuffer: Uint8Array): InstanceType<M> | undefined;
249
224
  _getTypeName(): string;
250
225
  }
251
226
  /**
@@ -255,26 +230,18 @@ export declare class UniqueIndex<M extends typeof Model, const F extends readonl
255
230
  * @template F - The field names that make up this index.
256
231
  */
257
232
  export declare class SecondaryIndex<M extends typeof Model, const F extends readonly (keyof InstanceType<M> & string)[]> extends BaseIndex<M, F> {
258
- /**
259
- * Save secondary index entry.
260
- * @param model - Model instance.
261
- * @param originalKey - Original key if updating.
262
- */
263
- _save(model: InstanceType<M>, originalKey?: Uint8Array): Uint8Array | undefined;
233
+ constructor(MyModel: M, fieldNames: F);
264
234
  /**
265
235
  * Extract model from iterator entry for secondary index.
266
236
  * @param keyBytes - Key bytes with index ID already read.
267
- * @param valueBytes - Value bytes from the entry.
237
+ * @param valueBuffer - Value Uint8Array from the entry.
268
238
  * @returns Model instance or undefined.
269
239
  * @internal
270
240
  */
271
- _getModelFromEntry(keyBytes: Bytes, valueBytes: Bytes): InstanceType<M> | undefined;
272
- /**
273
- * Create secondary index key that includes both index fields and primary key.
274
- * @param model - Model instance.
275
- * @returns Database key bytes or undefined if skipped.
276
- */
277
- _getKeyFromModel(model: InstanceType<M>, includeIndexId: boolean): Uint8Array;
241
+ _pairToInstance(keyBytes: DataPack, valueBuffer: Uint8Array): InstanceType<M> | undefined;
242
+ _instanceToKeyBytes(model: InstanceType<M>): DataPack;
243
+ _write(model: InstanceType<M>): void;
244
+ _delete(model: InstanceType<M>): void;
278
245
  _getTypeName(): string;
279
246
  }
280
247
  export type Index<M extends typeof Model, F extends readonly (keyof InstanceType<M> & string)[]> = PrimaryIndex<M, F> | UniqueIndex<M, F> | SecondaryIndex<M, F>;