edinburgh 0.4.6 → 0.6.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 +403 -461
- package/build/src/datapack.d.ts +9 -9
- package/build/src/datapack.js +10 -10
- package/build/src/datapack.js.map +1 -1
- package/build/src/edinburgh.d.ts +21 -10
- package/build/src/edinburgh.js +33 -55
- package/build/src/edinburgh.js.map +1 -1
- package/build/src/indexes.d.ts +99 -288
- package/build/src/indexes.js +253 -636
- package/build/src/indexes.js.map +1 -1
- package/build/src/migrate.js +17 -39
- package/build/src/migrate.js.map +1 -1
- package/build/src/models.d.ts +177 -113
- package/build/src/models.js +487 -259
- package/build/src/models.js.map +1 -1
- package/build/src/types.d.ts +41 -51
- package/build/src/types.js +39 -52
- package/build/src/types.js.map +1 -1
- package/build/src/utils.d.ts +4 -4
- package/build/src/utils.js +4 -4
- package/package.json +1 -3
- package/skill/AnyModelClass.md +7 -0
- package/skill/FindOptions.md +37 -0
- package/skill/Lifecycle Hooks.md +24 -0
- package/skill/{Model_delete.md → Lifecycle Hooks_delete.md } +2 -2
- package/skill/{Model_getPrimaryKeyHash.md → Lifecycle Hooks_getPrimaryKeyHash.md } +1 -1
- package/skill/{Model_isValid.md → Lifecycle Hooks_isValid.md } +1 -1
- package/skill/Lifecycle Hooks_migrate.md +26 -0
- package/skill/{Model_preCommit.md → Lifecycle Hooks_preCommit.md } +3 -5
- package/skill/{Model_preventPersist.md → Lifecycle Hooks_preventPersist.md } +2 -2
- package/skill/{Model_validate.md → Lifecycle Hooks_validate.md } +2 -2
- package/skill/ModelBase.md +7 -0
- package/skill/ModelClass.md +8 -0
- package/skill/SKILL.md +253 -215
- package/skill/Schema Evolution.md +19 -0
- package/skill/TypeWrapper_containsNull.md +11 -0
- package/skill/TypeWrapper_deserialize.md +9 -0
- package/skill/TypeWrapper_getError.md +11 -0
- package/skill/TypeWrapper_serialize.md +10 -0
- package/skill/TypeWrapper_serializeType.md +9 -0
- package/skill/array.md +2 -2
- package/skill/defineModel.md +23 -0
- package/skill/deleteEverything.md +8 -0
- package/skill/field.md +4 -4
- package/skill/link.md +12 -10
- package/skill/literal.md +1 -1
- package/skill/opt.md +1 -1
- package/skill/or.md +1 -1
- package/skill/record.md +1 -1
- package/skill/set.md +2 -2
- package/skill/setOnSaveCallback.md +2 -2
- package/skill/transact.md +3 -3
- package/src/datapack.ts +10 -10
- package/src/edinburgh.ts +46 -58
- package/src/indexes.ts +338 -802
- package/src/migrate.ts +15 -37
- package/src/models.ts +617 -314
- package/src/types.ts +61 -54
- package/src/utils.ts +4 -4
- package/skill/BaseIndex.md +0 -16
- package/skill/BaseIndex_batchProcess.md +0 -10
- package/skill/BaseIndex_find.md +0 -7
- package/skill/Model.md +0 -22
- package/skill/Model_findAll.md +0 -12
- package/skill/Model_migrate.md +0 -34
- package/skill/Model_replaceInto.md +0 -16
- package/skill/PrimaryIndex.md +0 -8
- package/skill/PrimaryIndex_get.md +0 -17
- package/skill/PrimaryIndex_getLazy.md +0 -13
- package/skill/SecondaryIndex.md +0 -9
- package/skill/UniqueIndex.md +0 -9
- package/skill/UniqueIndex_get.md +0 -17
- package/skill/dump.md +0 -8
- package/skill/index.md +0 -32
- package/skill/primary.md +0 -26
- package/skill/registerModel.md +0 -26
- package/skill/unique.md +0 -32
package/src/types.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import DataPack from "./datapack.js";
|
|
2
2
|
import { DatabaseError } from "olmdb/lowlevel";
|
|
3
|
-
import {
|
|
3
|
+
import { currentTxn } from "./edinburgh.js";
|
|
4
|
+
import { Model, modelRegistry } from "./models.js";
|
|
5
|
+
import type { AnyModelClass } from "./models.js";
|
|
4
6
|
import { assert, addErrorPath, dbGet } from "./utils.js";
|
|
5
|
-
import { PrimaryIndex, BaseIndex, IndexRangeIterator } from "./indexes.js";
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -25,34 +26,34 @@ export abstract class TypeWrapper<const T> {
|
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Serialize a value from an object property to a Pack.
|
|
28
|
-
* @param value
|
|
29
|
-
* @param pack
|
|
29
|
+
* @param value The value to serialize.
|
|
30
|
+
* @param pack The Pack instance to write to.
|
|
30
31
|
*/
|
|
31
32
|
abstract serialize(value: T, pack: DataPack): void;
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Deserialize a value from a Pack into an object property.
|
|
35
|
-
* @param pack
|
|
36
|
+
* @param pack The Pack instance to read from.
|
|
36
37
|
*/
|
|
37
38
|
abstract deserialize(pack: DataPack): T;
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Validate a value.
|
|
41
|
-
* @param value
|
|
42
|
+
* @param value The value to validate.
|
|
42
43
|
* @returns - A DatabaseError if validation fails.
|
|
43
44
|
*/
|
|
44
45
|
abstract getError(value: T): DatabaseError | void;
|
|
45
46
|
|
|
46
47
|
/**
|
|
47
48
|
* Serialize type metadata to a Pack (for schema serialization).
|
|
48
|
-
* @param pack
|
|
49
|
+
* @param pack The Pack instance to write to.
|
|
49
50
|
*/
|
|
50
51
|
serializeType(pack: DataPack) {}
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
54
|
* Check if indexing should be skipped for this field value.
|
|
54
|
-
* @param obj
|
|
55
|
-
* @param prop
|
|
55
|
+
* @param obj The object containing the value.
|
|
56
|
+
* @param prop The property name or index.
|
|
56
57
|
* @returns true if indexing should be skipped.
|
|
57
58
|
*/
|
|
58
59
|
containsNull(value: T): boolean {
|
|
@@ -71,7 +72,7 @@ export abstract class TypeWrapper<const T> {
|
|
|
71
72
|
return value1 === value2;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
|
-
getLinkedModel():
|
|
75
|
+
getLinkedModel(): undefined | AnyModelClass {
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
78
|
}
|
|
@@ -80,7 +81,7 @@ export abstract class TypeWrapper<const T> {
|
|
|
80
81
|
export interface TypeWrapper<T> {
|
|
81
82
|
/**
|
|
82
83
|
* Generate a default value for this type.
|
|
83
|
-
* @param model
|
|
84
|
+
* @param model The model instance.
|
|
84
85
|
* @returns The default value.
|
|
85
86
|
*/
|
|
86
87
|
default?(model: any): T;
|
|
@@ -181,8 +182,8 @@ class ArrayType<T> extends TypeWrapper<T[]> {
|
|
|
181
182
|
|
|
182
183
|
/**
|
|
183
184
|
* Create a new ArrayType.
|
|
184
|
-
* @param inner
|
|
185
|
-
* @param opts
|
|
185
|
+
* @param inner Type wrapper for array elements.
|
|
186
|
+
* @param opts Array constraints (min/max length).
|
|
186
187
|
*/
|
|
187
188
|
constructor(public inner: TypeWrapper<T>, public opts: {min?: number, max?: number} = {}) {
|
|
188
189
|
super();
|
|
@@ -262,7 +263,7 @@ export class SetType<T> extends TypeWrapper<Set<T>> {
|
|
|
262
263
|
|
|
263
264
|
/**
|
|
264
265
|
* Create a new SetType.
|
|
265
|
-
* @param inner
|
|
266
|
+
* @param inner Type wrapper for set elements.
|
|
266
267
|
*/
|
|
267
268
|
constructor(public inner: TypeWrapper<T>, public opts: {min?: number, max?: number} = {}) {
|
|
268
269
|
super();
|
|
@@ -355,7 +356,7 @@ class RecordType<T> extends TypeWrapper<Record<string | number, T>> {
|
|
|
355
356
|
|
|
356
357
|
serialize(value: Record<string | number, T>, pack: DataPack) {
|
|
357
358
|
pack.writeCollectionBoundary('object');
|
|
358
|
-
for (const key
|
|
359
|
+
for (const key in value) {
|
|
359
360
|
pack.writeObjectKey(key);
|
|
360
361
|
this.inner.serialize(value[key], pack);
|
|
361
362
|
}
|
|
@@ -374,7 +375,7 @@ class RecordType<T> extends TypeWrapper<Record<string | number, T>> {
|
|
|
374
375
|
}
|
|
375
376
|
|
|
376
377
|
getError(value: Record<string | number, T>) {
|
|
377
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
378
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value) || (typeof value.length === 'number' && typeof value[Symbol.iterator as any] === 'function')) {
|
|
378
379
|
return new DatabaseError(`Expected object, got ${typeof value}`, 'INVALID_TYPE');
|
|
379
380
|
}
|
|
380
381
|
for (const key of Object.keys(value)) {
|
|
@@ -431,7 +432,7 @@ class OrType<const T> extends TypeWrapper<T> {
|
|
|
431
432
|
|
|
432
433
|
/**
|
|
433
434
|
* Create a new OrType.
|
|
434
|
-
* @param choices
|
|
435
|
+
* @param choices Array of type wrappers representing the union choices.
|
|
435
436
|
*/
|
|
436
437
|
constructor(public choices: TypeWrapper<T>[]) {
|
|
437
438
|
super();
|
|
@@ -522,7 +523,7 @@ class LiteralType<const T> extends TypeWrapper<T> {
|
|
|
522
523
|
|
|
523
524
|
/**
|
|
524
525
|
* Create a new LiteralType.
|
|
525
|
-
* @param value
|
|
526
|
+
* @param value The literal value this type represents.
|
|
526
527
|
*/
|
|
527
528
|
constructor(public value: T) {
|
|
528
529
|
super();
|
|
@@ -596,7 +597,7 @@ class IdentifierType extends TypeWrapper<string> {
|
|
|
596
597
|
let id: string;
|
|
597
598
|
do {
|
|
598
599
|
id = DataPack.generateIdentifier();
|
|
599
|
-
} while (dbGet(model._txn.id, new DataPack().write(model.constructor.
|
|
600
|
+
} while (dbGet(model._txn.id, new DataPack().write(model.constructor._indexId!).writeIdentifier(id).toUint8Array()));
|
|
600
601
|
return id;
|
|
601
602
|
}
|
|
602
603
|
}
|
|
@@ -605,17 +606,22 @@ class IdentifierType extends TypeWrapper<string> {
|
|
|
605
606
|
* @internal Type wrapper for model relationships (foreign keys).
|
|
606
607
|
* @template T - The target model class type.
|
|
607
608
|
*/
|
|
608
|
-
export class LinkType<T extends
|
|
609
|
+
export class LinkType<T extends new (...args: any[]) => Model<any>> extends TypeWrapper<InstanceType<T>> {
|
|
609
610
|
kind = 'link';
|
|
610
|
-
|
|
611
|
+
private TargetModel: T | (() => T);
|
|
611
612
|
|
|
612
613
|
/**
|
|
613
614
|
* Create a new LinkType.
|
|
614
|
-
* @param TargetModel
|
|
615
|
+
* @param TargetModel The model class this link points to, or a thunk for forward references.
|
|
615
616
|
*/
|
|
616
|
-
constructor(TargetModel: T) {
|
|
617
|
+
constructor(TargetModel: T | (() => T)) {
|
|
617
618
|
super();
|
|
618
|
-
this.
|
|
619
|
+
this.TargetModel = TargetModel;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
getLinkedModel(): AnyModelClass {
|
|
623
|
+
if (!('getLazy' in this.TargetModel)) this.TargetModel = (this.TargetModel as unknown as () => T)();
|
|
624
|
+
return this.TargetModel as any;
|
|
619
625
|
}
|
|
620
626
|
|
|
621
627
|
serialize(model: InstanceType<T>, pack: DataPack) {
|
|
@@ -623,31 +629,28 @@ export class LinkType<T extends typeof Model<unknown>> extends TypeWrapper<Insta
|
|
|
623
629
|
}
|
|
624
630
|
|
|
625
631
|
deserialize(pack: DataPack) {
|
|
626
|
-
return
|
|
632
|
+
return this.getLinkedModel()._get(currentTxn(), pack.readUint8Array(), false);
|
|
627
633
|
}
|
|
628
634
|
|
|
629
635
|
getError(value: InstanceType<T>) {
|
|
630
|
-
|
|
631
|
-
|
|
636
|
+
const TargetModel = this.getLinkedModel();
|
|
637
|
+
if (!((value as any) instanceof TargetModel)) {
|
|
638
|
+
return new DatabaseError(`Expected instance of ${TargetModel.tableName}, got ${typeof value}`, 'VALUE_ERROR');
|
|
632
639
|
}
|
|
633
640
|
}
|
|
634
641
|
|
|
635
642
|
serializeType(pack: DataPack): void {
|
|
636
|
-
pack.write(this.tableName);
|
|
643
|
+
pack.write(this.getLinkedModel().tableName);
|
|
637
644
|
}
|
|
638
645
|
|
|
639
646
|
static deserializeType(pack: DataPack, featureFlags: number): LinkType<any> {
|
|
640
647
|
const tableName = pack.readString();
|
|
641
648
|
const targetModel = modelRegistry[tableName];
|
|
642
649
|
if (!targetModel) throw new DatabaseError(`Could not deserialize undefined model ${tableName}`, 'DESERIALIZATION_ERROR');
|
|
643
|
-
return new LinkType(targetModel);
|
|
650
|
+
return new LinkType(targetModel as any);
|
|
644
651
|
}
|
|
645
652
|
|
|
646
|
-
toString() { return `link<${this.tableName}>`; }
|
|
647
|
-
|
|
648
|
-
getLinkedModel(): T {
|
|
649
|
-
return modelRegistry[this.tableName] as T;
|
|
650
|
-
}
|
|
653
|
+
toString() { return `link<${this.getLinkedModel().tableName}>`; }
|
|
651
654
|
}
|
|
652
655
|
|
|
653
656
|
/** Type wrapper instance for the string type. */
|
|
@@ -679,7 +682,7 @@ export const undef = new LiteralType(undefined) as TypeWrapper<undefined>;
|
|
|
679
682
|
/**
|
|
680
683
|
* Create a literal type wrapper for a constant value.
|
|
681
684
|
* @template T - The literal type.
|
|
682
|
-
* @param value
|
|
685
|
+
* @param value The literal value.
|
|
683
686
|
* @returns A literal type instance.
|
|
684
687
|
*
|
|
685
688
|
* @example
|
|
@@ -695,7 +698,7 @@ export function literal<const T>(value: T): TypeWrapper<T> {
|
|
|
695
698
|
/**
|
|
696
699
|
* Create a union type wrapper from multiple type choices.
|
|
697
700
|
* @template T - Array of type wrapper or basic types.
|
|
698
|
-
* @param choices
|
|
701
|
+
* @param choices The type choices for the union.
|
|
699
702
|
* @returns A union type instance.
|
|
700
703
|
*
|
|
701
704
|
* @example
|
|
@@ -711,7 +714,7 @@ export function or<const T extends (TypeWrapper<unknown>|BasicType)[]>(...choice
|
|
|
711
714
|
/**
|
|
712
715
|
* Create an optional type wrapper (allows undefined).
|
|
713
716
|
* @template T - Type wrapper or basic type to make optional.
|
|
714
|
-
* @param inner
|
|
717
|
+
* @param inner The inner type to make optional.
|
|
715
718
|
* @returns A union type that accepts the inner type or undefined.
|
|
716
719
|
*
|
|
717
720
|
* @example
|
|
@@ -727,8 +730,8 @@ export function opt<const T extends TypeWrapper<unknown>|BasicType>(inner: T): T
|
|
|
727
730
|
/**
|
|
728
731
|
* Create an array type wrapper with optional length constraints.
|
|
729
732
|
* @template T - The element type.
|
|
730
|
-
* @param inner
|
|
731
|
-
* @param opts
|
|
733
|
+
* @param inner Type wrapper for array elements.
|
|
734
|
+
* @param opts Optional constraints (min/max length).
|
|
732
735
|
* @returns An array type instance.
|
|
733
736
|
*
|
|
734
737
|
* @example
|
|
@@ -744,8 +747,8 @@ export function array<const T>(inner: TypeWrapper<T>, opts: {min?: number, max?:
|
|
|
744
747
|
/**
|
|
745
748
|
* Create a Set type wrapper with optional length constraints.
|
|
746
749
|
* @template T - The element type.
|
|
747
|
-
* @param inner
|
|
748
|
-
* @param opts
|
|
750
|
+
* @param inner Type wrapper for set elements.
|
|
751
|
+
* @param opts Optional constraints (min/max length).
|
|
749
752
|
* @returns A set type instance.
|
|
750
753
|
*
|
|
751
754
|
* @example
|
|
@@ -761,7 +764,7 @@ export function set<const T>(inner: TypeWrapper<T>, opts: {min?: number, max?: n
|
|
|
761
764
|
/**
|
|
762
765
|
* Create a Record type wrapper for key-value objects with string or number keys.
|
|
763
766
|
* @template T - The value type.
|
|
764
|
-
* @param inner
|
|
767
|
+
* @param inner Type wrapper for record values.
|
|
765
768
|
* @returns A record type instance.
|
|
766
769
|
*
|
|
767
770
|
* @example
|
|
@@ -776,21 +779,25 @@ export function record<const T>(inner: TypeWrapper<T>): TypeWrapper<Record<strin
|
|
|
776
779
|
/**
|
|
777
780
|
* Create a link type wrapper for model relationships.
|
|
778
781
|
* @template T - The target model class.
|
|
779
|
-
* @param TargetModel
|
|
782
|
+
* @param TargetModel The model class this link points to.
|
|
780
783
|
* @returns A link type instance.
|
|
781
784
|
*
|
|
782
785
|
* @example
|
|
783
786
|
* ```typescript
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
+
* const Author = E.defineModel("Author", class {
|
|
788
|
+
* id = E.field(E.identifier);
|
|
789
|
+
* posts = E.field(E.array(E.link(() => Book)));
|
|
790
|
+
* }, { pk: "id" });
|
|
787
791
|
*
|
|
788
|
-
*
|
|
789
|
-
*
|
|
790
|
-
*
|
|
792
|
+
* const Book = E.defineModel("Book", class {
|
|
793
|
+
* id = E.field(E.identifier);
|
|
794
|
+
* author = E.field(E.link(Author));
|
|
795
|
+
* }, { pk: "id" });
|
|
791
796
|
* ```
|
|
792
797
|
*/
|
|
793
|
-
export function link<const T extends
|
|
798
|
+
export function link<const T extends new (...args: any[]) => Model<any>>(TargetModel: T): TypeWrapper<InstanceType<T>>;
|
|
799
|
+
export function link<const T extends new (...args: any[]) => Model<any>>(TargetModel: () => T): TypeWrapper<InstanceType<T>>;
|
|
800
|
+
export function link(TargetModel: any): TypeWrapper<any> {
|
|
794
801
|
return new LinkType(TargetModel);
|
|
795
802
|
}
|
|
796
803
|
|
|
@@ -810,8 +817,8 @@ function wrapIfLiteral(type: any) {
|
|
|
810
817
|
|
|
811
818
|
/**
|
|
812
819
|
* Serialize a type wrapper to a Pack for schema persistence.
|
|
813
|
-
* @param arg
|
|
814
|
-
* @param pack
|
|
820
|
+
* @param arg The type wrapper to serialize.
|
|
821
|
+
* @param pack The Pack instance to write to.
|
|
815
822
|
*/
|
|
816
823
|
export function serializeType(arg: TypeWrapper<any>, pack: DataPack) {
|
|
817
824
|
pack.write(arg.kind);
|
|
@@ -834,8 +841,8 @@ const TYPE_WRAPPERS: Record<string, TypeWrapper<any> | {deserializeType: (pack:
|
|
|
834
841
|
|
|
835
842
|
/**
|
|
836
843
|
* Deserialize a type wrapper from a Pack.
|
|
837
|
-
* @param pack
|
|
838
|
-
* @param featureFlags
|
|
844
|
+
* @param pack The Pack instance to read from.
|
|
845
|
+
* @param featureFlags Feature flags for version compatibility.
|
|
839
846
|
* @returns The deserialized type wrapper.
|
|
840
847
|
*/
|
|
841
848
|
export function deserializeType(pack: DataPack, featureFlags: number): TypeWrapper<any> {
|
package/src/utils.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as lowlevel from "olmdb/lowlevel";
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Assert function for runtime checks with TypeScript assertion support.
|
|
5
|
-
* @param cond
|
|
6
|
-
* @param message
|
|
5
|
+
* @param cond Condition to check.
|
|
6
|
+
* @param message Optional error message.
|
|
7
7
|
* @throws {Error} If condition is false.
|
|
8
8
|
*/
|
|
9
9
|
export function assert(cond: any, message?: string): asserts cond {
|
|
@@ -58,8 +58,8 @@ export const ERROR_AT = /^(.*) at ([a-zA-Z0-9_.]+)$/;
|
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Add a path segment to an exception for better error reporting.
|
|
61
|
-
* @param error
|
|
62
|
-
* @param path
|
|
61
|
+
* @param error The (Database)Error to modify.
|
|
62
|
+
* @param path The path segment to add (string or number).
|
|
63
63
|
* @returns The modified DatabaseError.
|
|
64
64
|
*/
|
|
65
65
|
export function addErrorPath<T>(error: T, path: string | number): T {
|
package/skill/BaseIndex.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
### BaseIndex · abstract class
|
|
2
|
-
|
|
3
|
-
Base class for database indexes for efficient lookups on model fields.
|
|
4
|
-
|
|
5
|
-
Indexes enable fast queries on specific field combinations and enforce uniqueness constraints.
|
|
6
|
-
|
|
7
|
-
**Type Parameters:**
|
|
8
|
-
|
|
9
|
-
- `M extends typeof Model` - The model class this index belongs to.
|
|
10
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
11
|
-
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
|
12
|
-
|
|
13
|
-
**Constructor Parameters:**
|
|
14
|
-
|
|
15
|
-
- `MyModel`: - The model class this index belongs to.
|
|
16
|
-
- `_fieldNames`: - Array of field names that make up this index.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#### baseIndex.batchProcess · method
|
|
2
|
-
|
|
3
|
-
[object Object],[object Object],[object Object]
|
|
4
|
-
|
|
5
|
-
**Signature:** `(opts: FindOptions<ARGS> & { limitSeconds?: number; limitRows?: number; }, callback: (row: InstanceType<M>) => void | Promise<void>) => Promise<...>`
|
|
6
|
-
|
|
7
|
-
**Parameters:**
|
|
8
|
-
|
|
9
|
-
- `opts: FindOptions<ARGS> & { limitSeconds?: number; limitRows?: number }` (optional) - - Query options (same as `find()`), plus:
|
|
10
|
-
- `callback: (row: InstanceType<M>) => void | Promise<void>` - - Called for each matching row within a transaction
|
package/skill/BaseIndex_find.md
DELETED
package/skill/Model.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
### Model · abstract class
|
|
2
|
-
|
|
3
|
-
[object Object],[object Object],[object Object],[object Object],[object Object]
|
|
4
|
-
|
|
5
|
-
**Type Parameters:**
|
|
6
|
-
|
|
7
|
-
- `SUB` - The concrete model subclass (for proper typing).
|
|
8
|
-
|
|
9
|
-
**Examples:**
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
@E.registerModel
|
|
13
|
-
class User extends E.Model<User> {
|
|
14
|
-
static pk = E.primary(User, "id");
|
|
15
|
-
|
|
16
|
-
id = E.field(E.identifier);
|
|
17
|
-
name = E.field(E.string);
|
|
18
|
-
email = E.field(E.string);
|
|
19
|
-
|
|
20
|
-
static byEmail = E.unique(User, "email");
|
|
21
|
-
}
|
|
22
|
-
```
|
package/skill/Model_findAll.md
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#### Model.findAll · static method
|
|
2
|
-
|
|
3
|
-
Find all instances of this model in the database, ordered by primary key.
|
|
4
|
-
|
|
5
|
-
**Signature:** `<T extends typeof Model<unknown>>(this: T, opts?: { reverse?: boolean; }) => IndexRangeIterator<T>`
|
|
6
|
-
|
|
7
|
-
**Parameters:**
|
|
8
|
-
|
|
9
|
-
- `this: T`
|
|
10
|
-
- `opts?: {reverse?: boolean}` - - Optional parameters.
|
|
11
|
-
|
|
12
|
-
**Returns:** An iterator.
|
package/skill/Model_migrate.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
#### Model.migrate · static method
|
|
2
|
-
|
|
3
|
-
Optional migration function called when deserializing rows written with an older schema version.
|
|
4
|
-
Receives a plain record with all fields (primary key fields + value fields) and should mutate it
|
|
5
|
-
in-place to match the current schema.
|
|
6
|
-
|
|
7
|
-
This is called both during lazy loading (when a row is read from disk) and during batch
|
|
8
|
-
migration (via `runMigration()` / `npx migrate-edinburgh`). The function's source code is hashed
|
|
9
|
-
to detect changes. Modifying `migrate()` triggers a new schema version.
|
|
10
|
-
|
|
11
|
-
If `migrate()` changes values of fields used in secondary or unique indexes, those indexes
|
|
12
|
-
will only be updated when `runMigration()` is run (not during lazy loading).
|
|
13
|
-
|
|
14
|
-
**Signature:** `(record: Record<string, any>) => void`
|
|
15
|
-
|
|
16
|
-
**Parameters:**
|
|
17
|
-
|
|
18
|
-
- `record: Record<string, any>` - - A plain object with all field values from the old schema version.
|
|
19
|
-
|
|
20
|
-
**Examples:**
|
|
21
|
-
|
|
22
|
-
```typescript
|
|
23
|
-
@E.registerModel
|
|
24
|
-
class User extends E.Model<User> {
|
|
25
|
-
static pk = E.primary(User, "id");
|
|
26
|
-
id = E.field(E.identifier);
|
|
27
|
-
name = E.field(E.string);
|
|
28
|
-
role = E.field(E.string); // new field
|
|
29
|
-
|
|
30
|
-
static migrate(record: Record<string, any>) {
|
|
31
|
-
record.role ??= "user"; // default for rows that predate the 'role' field
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
```
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
#### Model.replaceInto · static method
|
|
2
|
-
|
|
3
|
-
Load an existing instance by primary key and update it, or create a new one.
|
|
4
|
-
|
|
5
|
-
The provided object must contain all primary key fields. If a matching row exists,
|
|
6
|
-
the remaining properties from `obj` are set on the loaded instance. Otherwise a
|
|
7
|
-
new instance is created with `obj` as its initial properties.
|
|
8
|
-
|
|
9
|
-
**Signature:** `<T extends typeof Model<any>>(this: T, obj: Partial<Omit<InstanceType<T>, "constructor">>) => InstanceType<T>`
|
|
10
|
-
|
|
11
|
-
**Parameters:**
|
|
12
|
-
|
|
13
|
-
- `this: T`
|
|
14
|
-
- `obj: Partial<Omit<InstanceType<T>, "constructor">>` - - Partial model data that **must** include every primary key field.
|
|
15
|
-
|
|
16
|
-
**Returns:** The loaded-and-updated or newly created instance.
|
package/skill/PrimaryIndex.md
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
### PrimaryIndex · class
|
|
2
|
-
|
|
3
|
-
Primary index that stores the actual model data.
|
|
4
|
-
|
|
5
|
-
**Type Parameters:**
|
|
6
|
-
|
|
7
|
-
- `M extends typeof Model` - The model class this index belongs to.
|
|
8
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#### primaryIndex.get · method
|
|
2
|
-
|
|
3
|
-
Get a model instance by primary key values.
|
|
4
|
-
|
|
5
|
-
**Signature:** `(...args: IndexArgTypes<M, F>) => InstanceType<M>`
|
|
6
|
-
|
|
7
|
-
**Parameters:**
|
|
8
|
-
|
|
9
|
-
- `args: IndexArgTypes<M, F>` - - The primary key values.
|
|
10
|
-
|
|
11
|
-
**Returns:** The model instance if found, undefined otherwise.
|
|
12
|
-
|
|
13
|
-
**Examples:**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
const user = User.pk.get("john_doe");
|
|
17
|
-
```
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#### primaryIndex.getLazy · method
|
|
2
|
-
|
|
3
|
-
Does the same as as `get()`, but will delay loading the instance from disk until the first
|
|
4
|
-
property access. In case it turns out the instance doesn't exist, an error will be thrown
|
|
5
|
-
at that time.
|
|
6
|
-
|
|
7
|
-
**Signature:** `(...args: IndexArgTypes<M, F>) => InstanceType<M>`
|
|
8
|
-
|
|
9
|
-
**Parameters:**
|
|
10
|
-
|
|
11
|
-
- `args: IndexArgTypes<M, F>` - Primary key field values. (Or a single Uint8Array containing the key.)
|
|
12
|
-
|
|
13
|
-
**Returns:** The (lazily loaded) model instance.
|
package/skill/SecondaryIndex.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
### SecondaryIndex · class
|
|
2
|
-
|
|
3
|
-
Secondary index for non-unique lookups.
|
|
4
|
-
|
|
5
|
-
**Type Parameters:**
|
|
6
|
-
|
|
7
|
-
- `M extends typeof Model` - The model class this index belongs to.
|
|
8
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
9
|
-
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
package/skill/UniqueIndex.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
### UniqueIndex · class
|
|
2
|
-
|
|
3
|
-
Unique index that stores references to the primary key.
|
|
4
|
-
|
|
5
|
-
**Type Parameters:**
|
|
6
|
-
|
|
7
|
-
- `M extends typeof Model` - The model class this index belongs to.
|
|
8
|
-
- `F extends readonly (keyof InstanceType<M> & string)[]` - The field names that make up this index.
|
|
9
|
-
- `ARGS extends readonly any[] = IndexArgTypes<M, F>`
|
package/skill/UniqueIndex_get.md
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#### uniqueIndex.get · method
|
|
2
|
-
|
|
3
|
-
Get a model instance by unique index key values.
|
|
4
|
-
|
|
5
|
-
**Signature:** `(...args: ARGS) => InstanceType<M>`
|
|
6
|
-
|
|
7
|
-
**Parameters:**
|
|
8
|
-
|
|
9
|
-
- `args: ARGS` - - The unique index key values.
|
|
10
|
-
|
|
11
|
-
**Returns:** The model instance if found, undefined otherwise.
|
|
12
|
-
|
|
13
|
-
**Examples:**
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
const userByEmail = User.byEmail.get("john@example.com");
|
|
17
|
-
```
|
package/skill/dump.md
DELETED
package/skill/index.md
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
### index · function
|
|
2
|
-
|
|
3
|
-
Create a secondary index on model fields, or a computed secondary index using a function.
|
|
4
|
-
|
|
5
|
-
For field-based indexes, pass a field name or array of field names.
|
|
6
|
-
For computed indexes, pass a function that takes a model instance and returns an array of
|
|
7
|
-
index keys. Return `[]` to skip indexing for that instance. Each array element creates a
|
|
8
|
-
separate index entry, enabling multi-value indexes (e.g., indexing by each word in a name).
|
|
9
|
-
|
|
10
|
-
**Signature:** `{ <M extends typeof Model, V>(MyModel: M, fn: (instance: InstanceType<M>) => V[]): SecondaryIndex<M, [], [V]>; <M extends typeof Model, const F extends (keyof InstanceType<M> & string)>(MyModel: M, field: F): SecondaryIndex<...>; <M extends typeof Model, const FS extends readonly (keyof InstanceType<M> & string)[]>(...`
|
|
11
|
-
|
|
12
|
-
**Type Parameters:**
|
|
13
|
-
|
|
14
|
-
- `M extends typeof Model` - The model class.
|
|
15
|
-
- `V` - The computed index value type (for function-based indexes).
|
|
16
|
-
|
|
17
|
-
**Parameters:**
|
|
18
|
-
|
|
19
|
-
- `MyModel: M` - - The model class to create the index for.
|
|
20
|
-
- `fn: (instance: InstanceType<M>) => V[]`
|
|
21
|
-
|
|
22
|
-
**Returns:** A new SecondaryIndex instance.
|
|
23
|
-
|
|
24
|
-
**Examples:**
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
class User extends E.Model<User> {
|
|
28
|
-
static byAge = E.index(User, "age");
|
|
29
|
-
static byTagsDate = E.index(User, ["tags", "createdAt"]);
|
|
30
|
-
static byWord = E.index(User, (u: User) => u.name.split(" "));
|
|
31
|
-
}
|
|
32
|
-
```
|
package/skill/primary.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
### primary · function
|
|
2
|
-
|
|
3
|
-
Create a primary index on model fields.
|
|
4
|
-
|
|
5
|
-
**Signature:** `{ <M extends typeof Model, const F extends (keyof InstanceType<M> & string)>(MyModel: M, field: F): PrimaryIndex<M, [F]>; <M extends typeof Model, const FS extends readonly (keyof InstanceType<M> & string)[]>(MyModel: M, fields: FS): PrimaryIndex<...>; }`
|
|
6
|
-
|
|
7
|
-
**Type Parameters:**
|
|
8
|
-
|
|
9
|
-
- `M extends typeof Model` - The model class.
|
|
10
|
-
- `F extends (keyof InstanceType<M> & string)` - The field name (for single field index).
|
|
11
|
-
|
|
12
|
-
**Parameters:**
|
|
13
|
-
|
|
14
|
-
- `MyModel: M` - - The model class to create the index for.
|
|
15
|
-
- `field: F` - - Single field name for simple indexes.
|
|
16
|
-
|
|
17
|
-
**Returns:** A new PrimaryIndex instance.
|
|
18
|
-
|
|
19
|
-
**Examples:**
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
class User extends E.Model<User> {
|
|
23
|
-
static pk = E.primary(User, ["id"]);
|
|
24
|
-
static pkSingle = E.primary(User, "id");
|
|
25
|
-
}
|
|
26
|
-
```
|
package/skill/registerModel.md
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
### registerModel · function
|
|
2
|
-
|
|
3
|
-
Register a model class with the Edinburgh ORM system.
|
|
4
|
-
|
|
5
|
-
**Signature:** `<T extends typeof Model<unknown>>(MyModel: T) => T`
|
|
6
|
-
|
|
7
|
-
**Type Parameters:**
|
|
8
|
-
|
|
9
|
-
- `T extends typeof Model<unknown>` - The model class type.
|
|
10
|
-
|
|
11
|
-
**Parameters:**
|
|
12
|
-
|
|
13
|
-
- `MyModel: T` - - The model class to register.
|
|
14
|
-
|
|
15
|
-
**Returns:** The enhanced model class with ORM capabilities.
|
|
16
|
-
|
|
17
|
-
**Examples:**
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
@E.registerModel
|
|
21
|
-
class User extends E.Model<User> {
|
|
22
|
-
static pk = E.index(User, ["id"], "primary");
|
|
23
|
-
id = E.field(E.identifier);
|
|
24
|
-
name = E.field(E.string);
|
|
25
|
-
}
|
|
26
|
-
```
|