@orkestrel/database 0.0.7 → 0.0.9
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/dist/src/browser/index.d.ts +14 -14
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +3 -3
- package/dist/src/core/index.d.ts +3 -3
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +39 -5
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +54 -23
- package/dist/src/server/index.d.ts +54 -23
- package/dist/src/server/index.js +39 -6
- package/dist/src/server/index.js.map +1 -1
- package/package.json +9 -8
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { AggregateOperation } from '
|
|
2
|
-
import { AggregateOperation as AggregateOperation_2 } from '
|
|
3
|
-
import { ColumnSchema } from '
|
|
4
|
-
import { ColumnStorage } from '
|
|
5
|
-
import { Condition } from '
|
|
6
|
-
import { DriverInterface } from '
|
|
7
|
-
import { DriverInterface as DriverInterface_2 } from '
|
|
8
|
-
import { DriverMetadata } from '
|
|
1
|
+
import { AggregateOperation } from '@orkestrel/database';
|
|
2
|
+
import { AggregateOperation as AggregateOperation_2 } from '@orkestrel/database';
|
|
3
|
+
import { ColumnSchema } from '@orkestrel/database';
|
|
4
|
+
import { ColumnStorage } from '@orkestrel/database';
|
|
5
|
+
import { Condition } from '@orkestrel/database';
|
|
6
|
+
import { DriverInterface } from '@orkestrel/database';
|
|
7
|
+
import { DriverInterface as DriverInterface_2 } from '@orkestrel/database';
|
|
8
|
+
import { DriverMetadata } from '@orkestrel/database';
|
|
9
9
|
import { FieldPath } from '@orkestrel/contract';
|
|
10
|
-
import { Key } from '
|
|
11
|
-
import { MigrationInput } from '
|
|
12
|
-
import { MigrationStep } from '
|
|
13
|
-
import { OperationOptions } from '
|
|
14
|
-
import { Order } from '
|
|
15
|
-
import { QueryInput } from '
|
|
16
|
-
import { QueryInput as QueryInput_2 } from '
|
|
17
|
-
import { Row } from '
|
|
18
|
-
import { Row as Row_2 } from '
|
|
10
|
+
import { Key } from '@orkestrel/database';
|
|
11
|
+
import { MigrationInput } from '@orkestrel/database';
|
|
12
|
+
import { MigrationStep } from '@orkestrel/database';
|
|
13
|
+
import { OperationOptions } from '@orkestrel/database';
|
|
14
|
+
import { Order } from '@orkestrel/database';
|
|
15
|
+
import { QueryInput } from '@orkestrel/database';
|
|
16
|
+
import { QueryInput as QueryInput_2 } from '@orkestrel/database';
|
|
17
|
+
import { Row } from '@orkestrel/database';
|
|
18
|
+
import { Row as Row_2 } from '@orkestrel/database';
|
|
19
19
|
import { SQLiteRow } from '@orkestrel/sqlite';
|
|
20
20
|
import { SQLiteValue } from '@orkestrel/sqlite';
|
|
21
|
-
import { StorageInterface } from '
|
|
22
|
-
import { TableSchema } from '
|
|
23
|
-
import { TableSchema as TableSchema_2 } from '
|
|
21
|
+
import { StorageInterface } from '@orkestrel/database';
|
|
22
|
+
import { TableSchema } from '@orkestrel/database';
|
|
23
|
+
import { TableSchema as TableSchema_2 } from '@orkestrel/database';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Compile an {@link AggregateOperation} over a {@link FieldPath}.
|
|
@@ -545,9 +545,11 @@ export declare function inferValueStorage(value: unknown): ColumnStorage;
|
|
|
545
545
|
* primary (the table contract), so the key is recovered on load with
|
|
546
546
|
* {@link extractKey} and the file need not store it. The parsed JSON crosses the
|
|
547
547
|
* boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},
|
|
548
|
-
* never asserted (AGENTS §14).
|
|
549
|
-
*
|
|
550
|
-
*
|
|
548
|
+
* never asserted (AGENTS §14). A read that reports no document there starts empty —
|
|
549
|
+
* `ENOENT` for a plain absence, and `ENOTDIR` for a path whose parent is not a
|
|
550
|
+
* directory, which no later write could find either; every other read failure or
|
|
551
|
+
* invalid existing document fails closed without publication, mutation, or
|
|
552
|
+
* automatic repair. It is scan-only — it implements none of
|
|
551
553
|
* the optional native `records` / `aggregate` hooks, so the core engine
|
|
552
554
|
* over `scan` answers every query. For development, small datasets, and portable /
|
|
553
555
|
* inspectable data; for large or concurrent workloads reach for a SQLite-backed
|
|
@@ -643,6 +645,35 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
643
645
|
migrate(input: MigrationInput): Promise<void>;
|
|
644
646
|
}
|
|
645
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Whether a caught filesystem error reports that nothing is there to read.
|
|
650
|
+
*
|
|
651
|
+
* @remarks
|
|
652
|
+
* Two codes carry that meaning: `ENOENT` is a plain absence, and `ENOTDIR` is a
|
|
653
|
+
* path whose parent is not a directory — an absence in the stronger sense, since
|
|
654
|
+
* no file can exist at that name and no later write could find one. Hosts
|
|
655
|
+
* disagree about which of the two they report for the second shape, so a driver
|
|
656
|
+
* that reads only `ENOENT` opens on one host and fails closed on another over
|
|
657
|
+
* the same tree.
|
|
658
|
+
*
|
|
659
|
+
* Every other code — a permission refusal, a symlink loop, an unreadable
|
|
660
|
+
* existing file — is a real failure and stays one.
|
|
661
|
+
*
|
|
662
|
+
* A caught value that is not a coded `Error` is not a report about a path, so it
|
|
663
|
+
* answers `false` rather than being read for a `code` any object could carry.
|
|
664
|
+
*
|
|
665
|
+
* @param error - The caught value to classify; any runtime is accepted
|
|
666
|
+
* @returns `true` when the error reports that the path holds nothing
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```ts
|
|
670
|
+
* matchesAbsentPath(Object.assign(new Error('gone'), { code: 'ENOENT' })) // true
|
|
671
|
+
* matchesAbsentPath(Object.assign(new Error('denied'), { code: 'EACCES' })) // false
|
|
672
|
+
* matchesAbsentPath('ENOENT') // false
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
export declare function matchesAbsentPath(error: unknown): boolean;
|
|
676
|
+
|
|
646
677
|
/**
|
|
647
678
|
* Determine whether SQLite can execute an aggregate exactly like the core engine.
|
|
648
679
|
*
|
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { AggregateOperation } from '
|
|
2
|
-
import { AggregateOperation as AggregateOperation_2 } from '
|
|
3
|
-
import { ColumnSchema } from '
|
|
4
|
-
import { ColumnStorage } from '
|
|
5
|
-
import { Condition } from '
|
|
6
|
-
import { DriverInterface } from '
|
|
7
|
-
import { DriverInterface as DriverInterface_2 } from '
|
|
8
|
-
import { DriverMetadata } from '
|
|
1
|
+
import { AggregateOperation } from '@orkestrel/database';
|
|
2
|
+
import { AggregateOperation as AggregateOperation_2 } from '@orkestrel/database';
|
|
3
|
+
import { ColumnSchema } from '@orkestrel/database';
|
|
4
|
+
import { ColumnStorage } from '@orkestrel/database';
|
|
5
|
+
import { Condition } from '@orkestrel/database';
|
|
6
|
+
import { DriverInterface } from '@orkestrel/database';
|
|
7
|
+
import { DriverInterface as DriverInterface_2 } from '@orkestrel/database';
|
|
8
|
+
import { DriverMetadata } from '@orkestrel/database';
|
|
9
9
|
import { FieldPath } from '@orkestrel/contract';
|
|
10
|
-
import { Key } from '
|
|
11
|
-
import { MigrationInput } from '
|
|
12
|
-
import { MigrationStep } from '
|
|
13
|
-
import { OperationOptions } from '
|
|
14
|
-
import { Order } from '
|
|
15
|
-
import { QueryInput } from '
|
|
16
|
-
import { QueryInput as QueryInput_2 } from '
|
|
17
|
-
import { Row } from '
|
|
18
|
-
import { Row as Row_2 } from '
|
|
10
|
+
import { Key } from '@orkestrel/database';
|
|
11
|
+
import { MigrationInput } from '@orkestrel/database';
|
|
12
|
+
import { MigrationStep } from '@orkestrel/database';
|
|
13
|
+
import { OperationOptions } from '@orkestrel/database';
|
|
14
|
+
import { Order } from '@orkestrel/database';
|
|
15
|
+
import { QueryInput } from '@orkestrel/database';
|
|
16
|
+
import { QueryInput as QueryInput_2 } from '@orkestrel/database';
|
|
17
|
+
import { Row } from '@orkestrel/database';
|
|
18
|
+
import { Row as Row_2 } from '@orkestrel/database';
|
|
19
19
|
import { SQLiteRow } from '@orkestrel/sqlite';
|
|
20
20
|
import { SQLiteValue } from '@orkestrel/sqlite';
|
|
21
|
-
import { StorageInterface } from '
|
|
22
|
-
import { TableSchema } from '
|
|
23
|
-
import { TableSchema as TableSchema_2 } from '
|
|
21
|
+
import { StorageInterface } from '@orkestrel/database';
|
|
22
|
+
import { TableSchema } from '@orkestrel/database';
|
|
23
|
+
import { TableSchema as TableSchema_2 } from '@orkestrel/database';
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Compile an {@link AggregateOperation} over a {@link FieldPath}.
|
|
@@ -545,9 +545,11 @@ export declare function inferValueStorage(value: unknown): ColumnStorage;
|
|
|
545
545
|
* primary (the table contract), so the key is recovered on load with
|
|
546
546
|
* {@link extractKey} and the file need not store it. The parsed JSON crosses the
|
|
547
547
|
* boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},
|
|
548
|
-
* never asserted (AGENTS §14).
|
|
549
|
-
*
|
|
550
|
-
*
|
|
548
|
+
* never asserted (AGENTS §14). A read that reports no document there starts empty —
|
|
549
|
+
* `ENOENT` for a plain absence, and `ENOTDIR` for a path whose parent is not a
|
|
550
|
+
* directory, which no later write could find either; every other read failure or
|
|
551
|
+
* invalid existing document fails closed without publication, mutation, or
|
|
552
|
+
* automatic repair. It is scan-only — it implements none of
|
|
551
553
|
* the optional native `records` / `aggregate` hooks, so the core engine
|
|
552
554
|
* over `scan` answers every query. For development, small datasets, and portable /
|
|
553
555
|
* inspectable data; for large or concurrent workloads reach for a SQLite-backed
|
|
@@ -643,6 +645,35 @@ export declare class JSONDriver implements DriverInterface_2 {
|
|
|
643
645
|
migrate(input: MigrationInput): Promise<void>;
|
|
644
646
|
}
|
|
645
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Whether a caught filesystem error reports that nothing is there to read.
|
|
650
|
+
*
|
|
651
|
+
* @remarks
|
|
652
|
+
* Two codes carry that meaning: `ENOENT` is a plain absence, and `ENOTDIR` is a
|
|
653
|
+
* path whose parent is not a directory — an absence in the stronger sense, since
|
|
654
|
+
* no file can exist at that name and no later write could find one. Hosts
|
|
655
|
+
* disagree about which of the two they report for the second shape, so a driver
|
|
656
|
+
* that reads only `ENOENT` opens on one host and fails closed on another over
|
|
657
|
+
* the same tree.
|
|
658
|
+
*
|
|
659
|
+
* Every other code — a permission refusal, a symlink loop, an unreadable
|
|
660
|
+
* existing file — is a real failure and stays one.
|
|
661
|
+
*
|
|
662
|
+
* A caught value that is not a coded `Error` is not a report about a path, so it
|
|
663
|
+
* answers `false` rather than being read for a `code` any object could carry.
|
|
664
|
+
*
|
|
665
|
+
* @param error - The caught value to classify; any runtime is accepted
|
|
666
|
+
* @returns `true` when the error reports that the path holds nothing
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```ts
|
|
670
|
+
* matchesAbsentPath(Object.assign(new Error('gone'), { code: 'ENOENT' })) // true
|
|
671
|
+
* matchesAbsentPath(Object.assign(new Error('denied'), { code: 'EACCES' })) // false
|
|
672
|
+
* matchesAbsentPath('ENOENT') // false
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
export declare function matchesAbsentPath(error: unknown): boolean;
|
|
676
|
+
|
|
646
677
|
/**
|
|
647
678
|
* Determine whether SQLite can execute an aggregate exactly like the core engine.
|
|
648
679
|
*
|
package/dist/src/server/index.js
CHANGED
|
@@ -55,6 +55,37 @@ var METADATA_TABLE = "_metadata";
|
|
|
55
55
|
//#endregion
|
|
56
56
|
//#region src/server/helpers.ts
|
|
57
57
|
/**
|
|
58
|
+
* Whether a caught filesystem error reports that nothing is there to read.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* Two codes carry that meaning: `ENOENT` is a plain absence, and `ENOTDIR` is a
|
|
62
|
+
* path whose parent is not a directory — an absence in the stronger sense, since
|
|
63
|
+
* no file can exist at that name and no later write could find one. Hosts
|
|
64
|
+
* disagree about which of the two they report for the second shape, so a driver
|
|
65
|
+
* that reads only `ENOENT` opens on one host and fails closed on another over
|
|
66
|
+
* the same tree.
|
|
67
|
+
*
|
|
68
|
+
* Every other code — a permission refusal, a symlink loop, an unreadable
|
|
69
|
+
* existing file — is a real failure and stays one.
|
|
70
|
+
*
|
|
71
|
+
* A caught value that is not a coded `Error` is not a report about a path, so it
|
|
72
|
+
* answers `false` rather than being read for a `code` any object could carry.
|
|
73
|
+
*
|
|
74
|
+
* @param error - The caught value to classify; any runtime is accepted
|
|
75
|
+
* @returns `true` when the error reports that the path holds nothing
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* matchesAbsentPath(Object.assign(new Error('gone'), { code: 'ENOENT' })) // true
|
|
80
|
+
* matchesAbsentPath(Object.assign(new Error('denied'), { code: 'EACCES' })) // false
|
|
81
|
+
* matchesAbsentPath('ENOENT') // false
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
function matchesAbsentPath(error) {
|
|
85
|
+
if (!(error instanceof Error) || !("code" in error)) return false;
|
|
86
|
+
return error.code === "ENOENT" || error.code === "ENOTDIR";
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
58
89
|
* Whether a value's runtime type matches a column's declared exact type —
|
|
59
90
|
* the operand side of the declared-type-trust proof.
|
|
60
91
|
*
|
|
@@ -1024,9 +1055,11 @@ var DriverIterator = class {
|
|
|
1024
1055
|
* primary (the table contract), so the key is recovered on load with
|
|
1025
1056
|
* {@link extractKey} and the file need not store it. The parsed JSON crosses the
|
|
1026
1057
|
* boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},
|
|
1027
|
-
* never asserted (AGENTS §14).
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1058
|
+
* never asserted (AGENTS §14). A read that reports no document there starts empty —
|
|
1059
|
+
* `ENOENT` for a plain absence, and `ENOTDIR` for a path whose parent is not a
|
|
1060
|
+
* directory, which no later write could find either; every other read failure or
|
|
1061
|
+
* invalid existing document fails closed without publication, mutation, or
|
|
1062
|
+
* automatic repair. It is scan-only — it implements none of
|
|
1030
1063
|
* the optional native `records` / `aggregate` hooks, so the core engine
|
|
1031
1064
|
* over `scan` answers every query. For development, small datasets, and portable /
|
|
1032
1065
|
* inspectable data; for large or concurrent workloads reach for a SQLite-backed
|
|
@@ -1438,7 +1471,7 @@ var JSONDriver = class {
|
|
|
1438
1471
|
try {
|
|
1439
1472
|
raw = await readFile(this.#path, "utf-8");
|
|
1440
1473
|
} catch (error) {
|
|
1441
|
-
if (
|
|
1474
|
+
if (matchesAbsentPath(error)) return void 0;
|
|
1442
1475
|
throw new DatabaseError("DRIVER", "Failed to read the JSON database file", {
|
|
1443
1476
|
path: this.#path,
|
|
1444
1477
|
cause: error
|
|
@@ -1616,7 +1649,7 @@ var JSONDriver = class {
|
|
|
1616
1649
|
try {
|
|
1617
1650
|
await rm(temp, { force: true });
|
|
1618
1651
|
} catch (cleanup) {
|
|
1619
|
-
throw new DatabaseError("DRIVER", "Failed to persist and clean the database file", {
|
|
1652
|
+
if (!matchesAbsentPath(cleanup)) throw new DatabaseError("DRIVER", "Failed to persist and clean the database file", {
|
|
1620
1653
|
path: this.#path,
|
|
1621
1654
|
temp,
|
|
1622
1655
|
cause,
|
|
@@ -2450,6 +2483,6 @@ function createSQLiteDriver(options) {
|
|
|
2450
2483
|
return new SQLiteDriver(options);
|
|
2451
2484
|
}
|
|
2452
2485
|
//#endregion
|
|
2453
|
-
export { EXACT_COLUMN_STORAGE, EXACT_RANGE_COLUMN_STORAGE, JSONDriver, METADATA_TABLE, SQLiteDriver, compileAggregateSQL, compileColumnSQL, compileConditionSQL, compileFieldSQL, compileJSONTypeSQL, compileOrder, compilePage, compileQuerySQL, compileWhere, createJSONDriver, createSQLiteDriver, decodeRow, decodeValue, deriveSQLiteIndexName, encodeRow, encodeValue, escapeLike, extractValues, findColumnStorage, inferValueStorage, matchesAggregateExactly, matchesConditionExactly, matchesDeclaredStorage, matchesOrderExactly, matchesQueryExactly, matchesSQLiteAffinity, quoteIdentifier, schemaToIndexes, schemaToTable, stepToSQL };
|
|
2486
|
+
export { EXACT_COLUMN_STORAGE, EXACT_RANGE_COLUMN_STORAGE, JSONDriver, METADATA_TABLE, SQLiteDriver, compileAggregateSQL, compileColumnSQL, compileConditionSQL, compileFieldSQL, compileJSONTypeSQL, compileOrder, compilePage, compileQuerySQL, compileWhere, createJSONDriver, createSQLiteDriver, decodeRow, decodeValue, deriveSQLiteIndexName, encodeRow, encodeValue, escapeLike, extractValues, findColumnStorage, inferValueStorage, matchesAbsentPath, matchesAggregateExactly, matchesConditionExactly, matchesDeclaredStorage, matchesOrderExactly, matchesQueryExactly, matchesSQLiteAffinity, quoteIdentifier, schemaToIndexes, schemaToTable, stepToSQL };
|
|
2454
2487
|
|
|
2455
2488
|
//# sourceMappingURL=index.js.map
|