@enbox/dwn-sql-store 0.0.1 → 0.0.3
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 +36 -53
- package/dist/esm/src/data-store-sql.js +5 -5
- package/dist/esm/src/data-store-sql.js.map +1 -1
- package/dist/esm/src/dialect/bun-sqlite-adapter.js +46 -0
- package/dist/esm/src/dialect/bun-sqlite-adapter.js.map +1 -0
- package/dist/esm/src/dialect/mysql-dialect.js +1 -1
- package/dist/esm/src/dialect/mysql-dialect.js.map +1 -1
- package/dist/esm/src/dialect/postgres-dialect.js +1 -1
- package/dist/esm/src/dialect/postgres-dialect.js.map +1 -1
- package/dist/esm/src/dialect/sqlite-dialect.js +1 -1
- package/dist/esm/src/dialect/sqlite-dialect.js.map +1 -1
- package/dist/esm/src/main.js +3 -1
- package/dist/esm/src/main.js.map +1 -1
- package/dist/esm/src/message-store-sql.js +54 -25
- package/dist/esm/src/message-store-sql.js.map +1 -1
- package/dist/esm/src/resumable-task-store-sql.js +5 -6
- package/dist/esm/src/resumable-task-store-sql.js.map +1 -1
- package/dist/esm/src/smt-store-sql.js +151 -0
- package/dist/esm/src/smt-store-sql.js.map +1 -0
- package/dist/esm/src/state-index-sql.js +234 -0
- package/dist/esm/src/state-index-sql.js.map +1 -0
- package/dist/esm/src/utils/filter.js +3 -3
- package/dist/esm/src/utils/filter.js.map +1 -1
- package/dist/esm/src/utils/sanitize.js +7 -8
- package/dist/esm/src/utils/sanitize.js.map +1 -1
- package/dist/esm/src/utils/tags.js +3 -6
- package/dist/esm/src/utils/tags.js.map +1 -1
- package/dist/esm/src/utils/transaction.js +3 -21
- package/dist/esm/src/utils/transaction.js.map +1 -1
- package/dist/types/src/data-store-sql.d.ts +3 -4
- package/dist/types/src/data-store-sql.d.ts.map +1 -1
- package/dist/types/src/dialect/bun-sqlite-adapter.d.ts +33 -0
- package/dist/types/src/dialect/bun-sqlite-adapter.d.ts.map +1 -0
- package/dist/types/src/dialect/dialect.d.ts +1 -2
- package/dist/types/src/dialect/dialect.d.ts.map +1 -1
- package/dist/types/src/dialect/mysql-dialect.d.ts +3 -2
- package/dist/types/src/dialect/mysql-dialect.d.ts.map +1 -1
- package/dist/types/src/dialect/postgres-dialect.d.ts +3 -2
- package/dist/types/src/dialect/postgres-dialect.d.ts.map +1 -1
- package/dist/types/src/dialect/sqlite-dialect.d.ts +3 -2
- package/dist/types/src/dialect/sqlite-dialect.d.ts.map +1 -1
- package/dist/types/src/main.d.ts +3 -1
- package/dist/types/src/main.d.ts.map +1 -1
- package/dist/types/src/message-store-sql.d.ts +4 -3
- package/dist/types/src/message-store-sql.d.ts.map +1 -1
- package/dist/types/src/resumable-task-store-sql.d.ts +2 -2
- package/dist/types/src/resumable-task-store-sql.d.ts.map +1 -1
- package/dist/types/src/smt-store-sql.d.ts +37 -0
- package/dist/types/src/smt-store-sql.d.ts.map +1 -0
- package/dist/types/src/state-index-sql.d.ts +44 -0
- package/dist/types/src/state-index-sql.d.ts.map +1 -0
- package/dist/types/src/types.d.ts +24 -42
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/src/utils/filter.d.ts +3 -3
- package/dist/types/src/utils/filter.d.ts.map +1 -1
- package/dist/types/src/utils/sanitize.d.ts +2 -2
- package/dist/types/src/utils/sanitize.d.ts.map +1 -1
- package/dist/types/src/utils/tags.d.ts +3 -5
- package/dist/types/src/utils/tags.d.ts.map +1 -1
- package/dist/types/src/utils/transaction.d.ts +4 -4
- package/dist/types/src/utils/transaction.d.ts.map +1 -1
- package/package.json +19 -31
- package/src/data-store-sql.ts +11 -9
- package/src/dialect/bun-sqlite-adapter.ts +82 -0
- package/src/dialect/dialect.ts +4 -5
- package/src/dialect/mysql-dialect.ts +8 -6
- package/src/dialect/postgres-dialect.ts +11 -6
- package/src/dialect/sqlite-dialect.ts +11 -6
- package/src/main.ts +4 -2
- package/src/message-store-sql.ts +90 -45
- package/src/resumable-task-store-sql.ts +9 -7
- package/src/smt-store-sql.ts +206 -0
- package/src/state-index-sql.ts +283 -0
- package/src/types.ts +32 -47
- package/src/utils/filter.ts +8 -6
- package/src/utils/sanitize.ts +19 -20
- package/src/utils/tags.ts +6 -7
- package/src/utils/transaction.ts +7 -23
- package/dist/cjs/main.js +0 -3784
- package/dist/cjs/package.json +0 -1
- package/dist/esm/src/event-log-sql.js +0 -169
- package/dist/esm/src/event-log-sql.js.map +0 -1
- package/dist/types/src/event-log-sql.d.ts +0 -24
- package/dist/types/src/event-log-sql.d.ts.map +0 -1
- package/src/event-log-sql.ts +0 -227
package/src/utils/sanitize.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Filter } from '@enbox/dwn-sdk-js';
|
|
2
|
-
import { KeyValues } from '../types.js';
|
|
1
|
+
import type { Filter } from '@enbox/dwn-sdk-js';
|
|
2
|
+
import type { KeyValues } from '../types.js';
|
|
3
3
|
|
|
4
4
|
export function extractTagsAndSanitizeIndexes(records: KeyValues): {
|
|
5
5
|
tags: KeyValues;
|
|
@@ -13,9 +13,9 @@ export function extractTagsAndSanitizeIndexes(records: KeyValues): {
|
|
|
13
13
|
|
|
14
14
|
// tag values are prefixed with 'tag.', we extract them to be inserted separately into the tags reference tables.
|
|
15
15
|
// we delete them from the `indexes` object so they are not included in the main insert.
|
|
16
|
-
for (
|
|
16
|
+
for (const key in indexes) {
|
|
17
17
|
if (key.startsWith('tag.')) {
|
|
18
|
-
|
|
18
|
+
const value = indexes[key];
|
|
19
19
|
delete indexes[key];
|
|
20
20
|
tags[key.slice(4)] = value;
|
|
21
21
|
}
|
|
@@ -24,9 +24,9 @@ export function extractTagsAndSanitizeIndexes(records: KeyValues): {
|
|
|
24
24
|
return { tags, indexes };
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function sanitizeIndexes(records: KeyValues) {
|
|
28
|
-
for (
|
|
29
|
-
|
|
27
|
+
export function sanitizeIndexes(records: KeyValues): void {
|
|
28
|
+
for (const key in records) {
|
|
29
|
+
const value = records[key];
|
|
30
30
|
if (Array.isArray(value)) {
|
|
31
31
|
const sanitizedValues: any[] = [];
|
|
32
32
|
for (const valueItem of value) {
|
|
@@ -46,10 +46,10 @@ export function sanitizeIndexes(records: KeyValues) {
|
|
|
46
46
|
*/
|
|
47
47
|
export function sanitizedValue(value: string | number | boolean): string | number {
|
|
48
48
|
switch (typeof value) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
case 'boolean':
|
|
50
|
+
return value ? 1 : 0;
|
|
51
|
+
default:
|
|
52
|
+
return value;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -68,7 +68,7 @@ export function sanitizeFiltersAndSeparateTags(filters: Filter[]): {
|
|
|
68
68
|
const nonTagFilter = {};
|
|
69
69
|
|
|
70
70
|
// tag values are prefixed with 'tag.', we extract them to be queried separately in the tags tables.
|
|
71
|
-
for (
|
|
71
|
+
for (const key in filter) {
|
|
72
72
|
const value = sanitizeFilterValue(filter[key]);
|
|
73
73
|
|
|
74
74
|
if (key.startsWith('tag.')) {
|
|
@@ -94,23 +94,22 @@ export function sanitizeFiltersAndSeparateTags(filters: Filter[]): {
|
|
|
94
94
|
* NOTE: sqlite3 we use does not support inserting boolean values,
|
|
95
95
|
* so we convert them to a number during insertions/updates, as a result we need to align the filter values in queries.
|
|
96
96
|
*/
|
|
97
|
-
// TODO: export filter types from `dwn-sdk-js`
|
|
98
97
|
export function sanitizeFilterValue(value: any): any {
|
|
99
98
|
switch (typeof value) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
case 'boolean':
|
|
100
|
+
return value ? 1 : 0;
|
|
101
|
+
default:
|
|
102
|
+
return value;
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
export function sanitizeFilters(filters: Filter[]) {
|
|
106
|
+
export function sanitizeFilters(filters: Filter[]): void {
|
|
108
107
|
filters.forEach(sanitizeFilter);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
export function sanitizeFilter(filter: Filter): Filter {
|
|
112
|
-
for (
|
|
113
|
-
|
|
111
|
+
for (const key in filter) {
|
|
112
|
+
const value = filter[key];
|
|
114
113
|
filter[key] = sanitizeFilterValue(value);
|
|
115
114
|
}
|
|
116
115
|
return filter;
|
package/src/utils/tags.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Transaction } from 'kysely';
|
|
1
|
+
import type { Transaction } from 'kysely';
|
|
2
2
|
|
|
3
3
|
import type { DwnDatabaseType, KeyValues } from '../types.js';
|
|
4
4
|
|
|
5
|
-
import { Dialect } from '../dialect/dialect.js';
|
|
5
|
+
import type { Dialect } from '../dialect/dialect.js';
|
|
6
6
|
import { sanitizedValue } from './sanitize.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -12,9 +12,8 @@ export class TagTables {
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @param dialect the target dialect, necessary for returning the `insertId`
|
|
15
|
-
* @param table the DB Table in order to index the tags and values in the correct tables. Choice between `messageStoreMessages` and `eventLogMessages`
|
|
16
15
|
*/
|
|
17
|
-
constructor(private dialect: Dialect
|
|
16
|
+
constructor(private dialect: Dialect){}
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* Inserts the given tags associated with the given foreign `insertId`.
|
|
@@ -24,14 +23,14 @@ export class TagTables {
|
|
|
24
23
|
tags: KeyValues,
|
|
25
24
|
tx: Transaction<DwnDatabaseType>,
|
|
26
25
|
):Promise<void> {
|
|
27
|
-
const tagTable =
|
|
28
|
-
const foreignKeyReference =
|
|
26
|
+
const tagTable = 'messageStoreRecordsTags' as const;
|
|
27
|
+
const foreignKeyReference = { messageInsertId: foreignInsertId };
|
|
29
28
|
|
|
30
29
|
for (const tag in tags) {
|
|
31
30
|
const tagValues = tags[tag];
|
|
32
31
|
const values = Array.isArray(tagValues) ? tagValues : [ tagValues ];
|
|
33
32
|
|
|
34
|
-
for(const value of values) {
|
|
33
|
+
for (const value of values) {
|
|
35
34
|
const tagInsertValue = sanitizedValue(value);
|
|
36
35
|
const insertValues = {
|
|
37
36
|
tag,
|
package/src/utils/transaction.ts
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
import { DwnDatabaseType } from '../types.js';
|
|
2
|
-
import { Kysely, Transaction } from 'kysely';
|
|
1
|
+
import type { DwnDatabaseType } from '../types.js';
|
|
2
|
+
import type { Kysely, Transaction } from 'kysely';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Executes the provided
|
|
5
|
+
* Executes the provided operation atomically within a database transaction.
|
|
6
6
|
*/
|
|
7
|
-
export async function
|
|
7
|
+
export async function executeWithTransaction(
|
|
8
8
|
database: Kysely<DwnDatabaseType>,
|
|
9
9
|
operation: (transaction: Transaction<DwnDatabaseType>) => Promise<void>
|
|
10
|
-
): Promise<void>{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
while (!success) {
|
|
14
|
-
try {
|
|
15
|
-
await database.transaction().execute(operation);
|
|
16
|
-
success = true;
|
|
17
|
-
} catch (error) {
|
|
18
|
-
// if error is "database is locked", we retry the transaction
|
|
19
|
-
// this mainly happens when multiple transactions are trying to access the database at the same time in SQLite implementation.
|
|
20
|
-
if (error.code === 'SQLITE_BUSY') {
|
|
21
|
-
retryCount++;
|
|
22
|
-
console.log(`Database is locked when attempting SQL operation, retrying #${retryCount}...`);
|
|
23
|
-
} else {
|
|
24
|
-
throw error;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
await database.transaction().execute(operation);
|
|
12
|
+
}
|