@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
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL-backed implementation of SMTNodeStore.
|
|
3
|
+
*
|
|
4
|
+
* Storage layout:
|
|
5
|
+
* - Nodes are stored in the `stateIndexNodes` table, keyed by hex-encoded hash
|
|
6
|
+
* - The root hash is stored in the `stateIndexRoots` table
|
|
7
|
+
* - Node values are serialized with Uint8Array fields encoded as hex strings
|
|
8
|
+
*
|
|
9
|
+
* Each SMTStoreSql instance represents a single tree (identified by a tenant + scope key).
|
|
10
|
+
* Multiple instances share the same underlying Kysely database connection.
|
|
11
|
+
*/
|
|
12
|
+
import { hashToHex, hexToHash } from '@enbox/dwn-sdk-js';
|
|
13
|
+
export class SMTStoreSql {
|
|
14
|
+
#db;
|
|
15
|
+
#tenant;
|
|
16
|
+
#scope;
|
|
17
|
+
constructor({ db, tenant, scope }) {
|
|
18
|
+
this.#db = db;
|
|
19
|
+
this.#tenant = tenant;
|
|
20
|
+
this.#scope = scope;
|
|
21
|
+
}
|
|
22
|
+
async open() {
|
|
23
|
+
// No-op: the Kysely DB is already open and tables are created by StateIndexSql.
|
|
24
|
+
}
|
|
25
|
+
async close() {
|
|
26
|
+
// No-op: the Kysely DB lifecycle is managed by StateIndexSql.
|
|
27
|
+
}
|
|
28
|
+
async clear() {
|
|
29
|
+
await this.#db
|
|
30
|
+
.deleteFrom('stateIndexNodes')
|
|
31
|
+
.where('tenant', '=', this.#tenant)
|
|
32
|
+
.where('scope', '=', this.#scope)
|
|
33
|
+
.execute();
|
|
34
|
+
await this.#db
|
|
35
|
+
.deleteFrom('stateIndexRoots')
|
|
36
|
+
.where('tenant', '=', this.#tenant)
|
|
37
|
+
.where('scope', '=', this.#scope)
|
|
38
|
+
.execute();
|
|
39
|
+
}
|
|
40
|
+
async getNode(hash) {
|
|
41
|
+
const hexKey = hashToHex(hash);
|
|
42
|
+
const result = await this.#db
|
|
43
|
+
.selectFrom('stateIndexNodes')
|
|
44
|
+
.selectAll()
|
|
45
|
+
.where('tenant', '=', this.#tenant)
|
|
46
|
+
.where('scope', '=', this.#scope)
|
|
47
|
+
.where('nodeHash', '=', hexKey)
|
|
48
|
+
.executeTakeFirst();
|
|
49
|
+
if (!result) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
return this.deserializeNode(result);
|
|
53
|
+
}
|
|
54
|
+
async putNode(hash, node) {
|
|
55
|
+
const hexKey = hashToHex(hash);
|
|
56
|
+
const values = this.serializeNodeToRow(hexKey, node);
|
|
57
|
+
// Use INSERT ... ON CONFLICT REPLACE pattern.
|
|
58
|
+
// Since different SQL dialects handle upsert differently, we use
|
|
59
|
+
// delete-then-insert as a portable approach.
|
|
60
|
+
await this.#db
|
|
61
|
+
.deleteFrom('stateIndexNodes')
|
|
62
|
+
.where('tenant', '=', this.#tenant)
|
|
63
|
+
.where('scope', '=', this.#scope)
|
|
64
|
+
.where('nodeHash', '=', hexKey)
|
|
65
|
+
.execute();
|
|
66
|
+
await this.#db
|
|
67
|
+
.insertInto('stateIndexNodes')
|
|
68
|
+
.values(values)
|
|
69
|
+
.execute();
|
|
70
|
+
}
|
|
71
|
+
async deleteNode(hash) {
|
|
72
|
+
const hexKey = hashToHex(hash);
|
|
73
|
+
await this.#db
|
|
74
|
+
.deleteFrom('stateIndexNodes')
|
|
75
|
+
.where('tenant', '=', this.#tenant)
|
|
76
|
+
.where('scope', '=', this.#scope)
|
|
77
|
+
.where('nodeHash', '=', hexKey)
|
|
78
|
+
.execute();
|
|
79
|
+
}
|
|
80
|
+
async getRoot() {
|
|
81
|
+
const result = await this.#db
|
|
82
|
+
.selectFrom('stateIndexRoots')
|
|
83
|
+
.select('rootHash')
|
|
84
|
+
.where('tenant', '=', this.#tenant)
|
|
85
|
+
.where('scope', '=', this.#scope)
|
|
86
|
+
.executeTakeFirst();
|
|
87
|
+
if (!result) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
return hexToHash(result.rootHash);
|
|
91
|
+
}
|
|
92
|
+
async setRoot(hash) {
|
|
93
|
+
const hexRoot = hashToHex(hash);
|
|
94
|
+
// Delete-then-insert as a portable upsert.
|
|
95
|
+
await this.#db
|
|
96
|
+
.deleteFrom('stateIndexRoots')
|
|
97
|
+
.where('tenant', '=', this.#tenant)
|
|
98
|
+
.where('scope', '=', this.#scope)
|
|
99
|
+
.execute();
|
|
100
|
+
await this.#db
|
|
101
|
+
.insertInto('stateIndexRoots')
|
|
102
|
+
.values({
|
|
103
|
+
tenant: this.#tenant,
|
|
104
|
+
scope: this.#scope,
|
|
105
|
+
rootHash: hexRoot,
|
|
106
|
+
})
|
|
107
|
+
.execute();
|
|
108
|
+
}
|
|
109
|
+
// ─── Serialization helpers ──────────────────────────────────────────────
|
|
110
|
+
serializeNodeToRow(hexKey, node) {
|
|
111
|
+
if (node.type === 'internal') {
|
|
112
|
+
return {
|
|
113
|
+
tenant: this.#tenant,
|
|
114
|
+
scope: this.#scope,
|
|
115
|
+
nodeHash: hexKey,
|
|
116
|
+
nodeType: 'internal',
|
|
117
|
+
leftHash: hashToHex(node.leftHash),
|
|
118
|
+
rightHash: hashToHex(node.rightHash),
|
|
119
|
+
leafKeyHash: null,
|
|
120
|
+
leafValueCid: null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
tenant: this.#tenant,
|
|
125
|
+
scope: this.#scope,
|
|
126
|
+
nodeHash: hexKey,
|
|
127
|
+
nodeType: 'leaf',
|
|
128
|
+
leftHash: null,
|
|
129
|
+
rightHash: null,
|
|
130
|
+
leafKeyHash: hashToHex(node.keyHash),
|
|
131
|
+
leafValueCid: node.valueCid,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
deserializeNode(row) {
|
|
135
|
+
if (row.nodeType === 'internal') {
|
|
136
|
+
const node = {
|
|
137
|
+
type: 'internal',
|
|
138
|
+
leftHash: hexToHash(row.leftHash),
|
|
139
|
+
rightHash: hexToHash(row.rightHash),
|
|
140
|
+
};
|
|
141
|
+
return node;
|
|
142
|
+
}
|
|
143
|
+
const node = {
|
|
144
|
+
type: 'leaf',
|
|
145
|
+
keyHash: hexToHash(row.leafKeyHash),
|
|
146
|
+
valueCid: row.leafValueCid,
|
|
147
|
+
};
|
|
148
|
+
return node;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=smt-store-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smt-store-sql.js","sourceRoot":"","sources":["../../../src/smt-store-sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQL-backed implementation of the StateIndex interface.
|
|
3
|
+
*
|
|
4
|
+
* Manages per-tenant Sparse Merkle Trees (global + per-protocol sub-trees) backed by SQL tables.
|
|
5
|
+
*
|
|
6
|
+
* Tables:
|
|
7
|
+
* - `stateIndexNodes`: stores SMT nodes (internal + leaf), keyed by (tenant, scope, nodeHash)
|
|
8
|
+
* - `stateIndexRoots`: stores the current root hash per (tenant, scope)
|
|
9
|
+
* - `stateIndexMeta`: reverse lookup from messageCid → protocol (for deletion)
|
|
10
|
+
*/
|
|
11
|
+
import { initDefaultHashes } from '@enbox/dwn-sdk-js';
|
|
12
|
+
import { Kysely } from 'kysely';
|
|
13
|
+
import { SMTStoreSql } from './smt-store-sql.js';
|
|
14
|
+
import { SparseMerkleTree } from '@enbox/dwn-sdk-js';
|
|
15
|
+
export class StateIndexSql {
|
|
16
|
+
#dialect;
|
|
17
|
+
#db = null;
|
|
18
|
+
/**
|
|
19
|
+
* Cache of per-tenant global SMTs. Lazily populated on first access.
|
|
20
|
+
* Stores promises to avoid race conditions when multiple concurrent operations
|
|
21
|
+
* trigger lazy initialization for the same tenant.
|
|
22
|
+
*/
|
|
23
|
+
#globalTrees = new Map();
|
|
24
|
+
/**
|
|
25
|
+
* Cache of per-tenant, per-protocol SMTs. Key format: `{tenant}\x00{protocol}`.
|
|
26
|
+
* Stores promises to avoid race conditions.
|
|
27
|
+
*/
|
|
28
|
+
#protocolTrees = new Map();
|
|
29
|
+
constructor(dialect) {
|
|
30
|
+
this.#dialect = dialect;
|
|
31
|
+
}
|
|
32
|
+
async open() {
|
|
33
|
+
if (this.#db) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.#db = new Kysely({ dialect: this.#dialect });
|
|
37
|
+
// Ensure default hashes are initialized for the SMT
|
|
38
|
+
await initDefaultHashes();
|
|
39
|
+
// ─── Create stateIndexNodes table ─────────────────────────────────────
|
|
40
|
+
const nodesTableName = 'stateIndexNodes';
|
|
41
|
+
const nodesTableExists = await this.#dialect.hasTable(this.#db, nodesTableName);
|
|
42
|
+
if (!nodesTableExists) {
|
|
43
|
+
await this.#db.schema
|
|
44
|
+
.createTable(nodesTableName)
|
|
45
|
+
.ifNotExists()
|
|
46
|
+
.addColumn('tenant', 'varchar(255)', (col) => col.notNull())
|
|
47
|
+
.addColumn('scope', 'varchar(200)', (col) => col.notNull())
|
|
48
|
+
.addColumn('nodeHash', 'varchar(64)', (col) => col.notNull())
|
|
49
|
+
.addColumn('nodeType', 'varchar(10)', (col) => col.notNull())
|
|
50
|
+
.addColumn('leftHash', 'varchar(64)')
|
|
51
|
+
.addColumn('rightHash', 'varchar(64)')
|
|
52
|
+
.addColumn('leafKeyHash', 'varchar(64)')
|
|
53
|
+
.addColumn('leafValueCid', 'varchar(60)')
|
|
54
|
+
.execute();
|
|
55
|
+
// Not UNIQUE because the delete-then-insert upsert pattern in SMTStoreSql
|
|
56
|
+
// can race under concurrent access, causing duplicate key violations.
|
|
57
|
+
await this.#db.schema
|
|
58
|
+
.createIndex('index_stateIndexNodes_tenant_scope_nodeHash')
|
|
59
|
+
.on(nodesTableName)
|
|
60
|
+
.columns(['tenant', 'scope', 'nodeHash'])
|
|
61
|
+
.execute();
|
|
62
|
+
}
|
|
63
|
+
// ─── Create stateIndexRoots table ─────────────────────────────────────
|
|
64
|
+
const rootsTableName = 'stateIndexRoots';
|
|
65
|
+
const rootsTableExists = await this.#dialect.hasTable(this.#db, rootsTableName);
|
|
66
|
+
if (!rootsTableExists) {
|
|
67
|
+
await this.#db.schema
|
|
68
|
+
.createTable(rootsTableName)
|
|
69
|
+
.ifNotExists()
|
|
70
|
+
.addColumn('tenant', 'varchar(255)', (col) => col.notNull())
|
|
71
|
+
.addColumn('scope', 'varchar(200)', (col) => col.notNull())
|
|
72
|
+
.addColumn('rootHash', 'varchar(64)', (col) => col.notNull())
|
|
73
|
+
.execute();
|
|
74
|
+
await this.#db.schema
|
|
75
|
+
.createIndex('index_stateIndexRoots_tenant_scope')
|
|
76
|
+
.on(rootsTableName)
|
|
77
|
+
.columns(['tenant', 'scope'])
|
|
78
|
+
.execute();
|
|
79
|
+
}
|
|
80
|
+
// ─── Create stateIndexMeta table ──────────────────────────────────────
|
|
81
|
+
const metaTableName = 'stateIndexMeta';
|
|
82
|
+
const metaTableExists = await this.#dialect.hasTable(this.#db, metaTableName);
|
|
83
|
+
if (!metaTableExists) {
|
|
84
|
+
await this.#db.schema
|
|
85
|
+
.createTable(metaTableName)
|
|
86
|
+
.ifNotExists()
|
|
87
|
+
.addColumn('tenant', 'varchar(255)', (col) => col.notNull())
|
|
88
|
+
.addColumn('messageCid', 'varchar(60)', (col) => col.notNull())
|
|
89
|
+
.addColumn('protocol', 'varchar(200)')
|
|
90
|
+
.execute();
|
|
91
|
+
await this.#db.schema
|
|
92
|
+
.createIndex('index_stateIndexMeta_tenant_messageCid')
|
|
93
|
+
.on(metaTableName)
|
|
94
|
+
.columns(['tenant', 'messageCid'])
|
|
95
|
+
.execute();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async close() {
|
|
99
|
+
this.#globalTrees.clear();
|
|
100
|
+
this.#protocolTrees.clear();
|
|
101
|
+
await this.#db?.destroy();
|
|
102
|
+
this.#db = null;
|
|
103
|
+
}
|
|
104
|
+
async clear() {
|
|
105
|
+
if (!this.#db) {
|
|
106
|
+
throw new Error('Connection to database not open. Call `open` before using `clear`.');
|
|
107
|
+
}
|
|
108
|
+
this.#globalTrees.clear();
|
|
109
|
+
this.#protocolTrees.clear();
|
|
110
|
+
await this.#db.deleteFrom('stateIndexNodes').execute();
|
|
111
|
+
await this.#db.deleteFrom('stateIndexRoots').execute();
|
|
112
|
+
await this.#db.deleteFrom('stateIndexMeta').execute();
|
|
113
|
+
}
|
|
114
|
+
async insert(tenant, messageCid, indexes) {
|
|
115
|
+
if (!this.#db) {
|
|
116
|
+
throw new Error('Connection to database not open. Call `open` before using `insert`.');
|
|
117
|
+
}
|
|
118
|
+
// Insert into the global tree
|
|
119
|
+
const globalSmt = await this.getGlobalTree(tenant);
|
|
120
|
+
await globalSmt.insert(messageCid);
|
|
121
|
+
// If the message is associated with a protocol, insert into the protocol-scoped tree
|
|
122
|
+
const protocol = indexes.protocol;
|
|
123
|
+
if (protocol !== undefined) {
|
|
124
|
+
const protoSmt = await this.getProtocolTree(tenant, protocol);
|
|
125
|
+
await protoSmt.insert(messageCid);
|
|
126
|
+
}
|
|
127
|
+
// Store reverse lookup metadata for deletion
|
|
128
|
+
await this.#db
|
|
129
|
+
.insertInto('stateIndexMeta')
|
|
130
|
+
.values({
|
|
131
|
+
tenant,
|
|
132
|
+
messageCid,
|
|
133
|
+
protocol: protocol ?? null,
|
|
134
|
+
})
|
|
135
|
+
.execute();
|
|
136
|
+
}
|
|
137
|
+
async delete(tenant, messageCids) {
|
|
138
|
+
if (!this.#db) {
|
|
139
|
+
throw new Error('Connection to database not open. Call `open` before using `delete`.');
|
|
140
|
+
}
|
|
141
|
+
if (messageCids.length === 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const globalSmt = await this.getGlobalTree(tenant);
|
|
145
|
+
for (const messageCid of messageCids) {
|
|
146
|
+
// Look up stored metadata to find the protocol
|
|
147
|
+
const meta = await this.#db
|
|
148
|
+
.selectFrom('stateIndexMeta')
|
|
149
|
+
.select('protocol')
|
|
150
|
+
.where('tenant', '=', tenant)
|
|
151
|
+
.where('messageCid', '=', messageCid)
|
|
152
|
+
.executeTakeFirst();
|
|
153
|
+
// Delete from global tree
|
|
154
|
+
await globalSmt.delete(messageCid);
|
|
155
|
+
// Delete from protocol tree if applicable
|
|
156
|
+
if (meta?.protocol) {
|
|
157
|
+
const protoSmt = await this.getProtocolTree(tenant, meta.protocol);
|
|
158
|
+
await protoSmt.delete(messageCid);
|
|
159
|
+
}
|
|
160
|
+
// Remove the reverse lookup
|
|
161
|
+
await this.#db
|
|
162
|
+
.deleteFrom('stateIndexMeta')
|
|
163
|
+
.where('tenant', '=', tenant)
|
|
164
|
+
.where('messageCid', '=', messageCid)
|
|
165
|
+
.execute();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async getRoot(tenant) {
|
|
169
|
+
const smt = await this.getGlobalTree(tenant);
|
|
170
|
+
return smt.getRoot();
|
|
171
|
+
}
|
|
172
|
+
async getProtocolRoot(tenant, protocol) {
|
|
173
|
+
const smt = await this.getProtocolTree(tenant, protocol);
|
|
174
|
+
return smt.getRoot();
|
|
175
|
+
}
|
|
176
|
+
async getSubtreeHash(tenant, prefix) {
|
|
177
|
+
const smt = await this.getGlobalTree(tenant);
|
|
178
|
+
return smt.getSubtreeHash(prefix);
|
|
179
|
+
}
|
|
180
|
+
async getProtocolSubtreeHash(tenant, protocol, prefix) {
|
|
181
|
+
const smt = await this.getProtocolTree(tenant, protocol);
|
|
182
|
+
return smt.getSubtreeHash(prefix);
|
|
183
|
+
}
|
|
184
|
+
async getLeaves(tenant, prefix) {
|
|
185
|
+
const smt = await this.getGlobalTree(tenant);
|
|
186
|
+
return smt.getLeaves(prefix);
|
|
187
|
+
}
|
|
188
|
+
async getProtocolLeaves(tenant, protocol, prefix) {
|
|
189
|
+
const smt = await this.getProtocolTree(tenant, protocol);
|
|
190
|
+
return smt.getLeaves(prefix);
|
|
191
|
+
}
|
|
192
|
+
// ─── Private helpers ────────────────────────────────────────────────────
|
|
193
|
+
/**
|
|
194
|
+
* Get or create the global SMT for a tenant.
|
|
195
|
+
* Uses a promise-based cache to prevent concurrent callers from racing.
|
|
196
|
+
*/
|
|
197
|
+
getGlobalTree(tenant) {
|
|
198
|
+
let smtPromise = this.#globalTrees.get(tenant);
|
|
199
|
+
if (smtPromise !== undefined) {
|
|
200
|
+
return smtPromise;
|
|
201
|
+
}
|
|
202
|
+
smtPromise = this.createTree(tenant, '');
|
|
203
|
+
this.#globalTrees.set(tenant, smtPromise);
|
|
204
|
+
return smtPromise;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get or create a protocol-scoped SMT for a tenant.
|
|
208
|
+
* Uses a promise-based cache to prevent concurrent callers from racing.
|
|
209
|
+
*/
|
|
210
|
+
getProtocolTree(tenant, protocol) {
|
|
211
|
+
const cacheKey = `${tenant}\x00${protocol}`;
|
|
212
|
+
let smtPromise = this.#protocolTrees.get(cacheKey);
|
|
213
|
+
if (smtPromise !== undefined) {
|
|
214
|
+
return smtPromise;
|
|
215
|
+
}
|
|
216
|
+
smtPromise = this.createTree(tenant, protocol);
|
|
217
|
+
this.#protocolTrees.set(cacheKey, smtPromise);
|
|
218
|
+
return smtPromise;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Create and initialize a new SparseMerkleTree backed by SQL via SMTStoreSql.
|
|
222
|
+
*/
|
|
223
|
+
async createTree(tenant, scope) {
|
|
224
|
+
const store = new SMTStoreSql({
|
|
225
|
+
db: this.#db,
|
|
226
|
+
tenant,
|
|
227
|
+
scope,
|
|
228
|
+
});
|
|
229
|
+
const smt = new SparseMerkleTree(store);
|
|
230
|
+
await smt.initialize();
|
|
231
|
+
return smt;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=state-index-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-index-sql.js","sourceRoot":"","sources":["../../../src/state-index-sql.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DynamicModule } from 'kysely';
|
|
2
|
-
import {
|
|
2
|
+
import { sanitizedValue, sanitizeFiltersAndSeparateTags } from './sanitize.js';
|
|
3
3
|
/**
|
|
4
4
|
* Takes multiple Filters and returns a single query.
|
|
5
5
|
* Each filter is evaluated as an OR operation.
|
|
@@ -29,7 +29,7 @@ export function filterSelectQuery(filters, query) {
|
|
|
29
29
|
* @param filter The filter to be evaluated.
|
|
30
30
|
*/
|
|
31
31
|
function processFilter(eb, andOperands, filter) {
|
|
32
|
-
for (
|
|
32
|
+
for (const property in filter) {
|
|
33
33
|
const value = filter[property];
|
|
34
34
|
const column = new DynamicModule().ref(property);
|
|
35
35
|
if (Array.isArray(value)) { // OneOfFilter
|
|
@@ -67,7 +67,7 @@ function processTags(eb, andOperands, tags) {
|
|
|
67
67
|
const valueNumber = new DynamicModule().ref('valueNumber');
|
|
68
68
|
const valueString = new DynamicModule().ref('valueString');
|
|
69
69
|
// process each tag and add it to the andOperands from the rest of the filters
|
|
70
|
-
for (
|
|
70
|
+
for (const property in tags) {
|
|
71
71
|
andOperands.push(eb(tagColumn, '=', property));
|
|
72
72
|
const value = tags[property];
|
|
73
73
|
if (Array.isArray(value)) { // OneOfFilter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../src/utils/filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../src/utils/filter.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,9 +4,9 @@ export function extractTagsAndSanitizeIndexes(records) {
|
|
|
4
4
|
sanitizeIndexes(indexes);
|
|
5
5
|
// tag values are prefixed with 'tag.', we extract them to be inserted separately into the tags reference tables.
|
|
6
6
|
// we delete them from the `indexes` object so they are not included in the main insert.
|
|
7
|
-
for (
|
|
7
|
+
for (const key in indexes) {
|
|
8
8
|
if (key.startsWith('tag.')) {
|
|
9
|
-
|
|
9
|
+
const value = indexes[key];
|
|
10
10
|
delete indexes[key];
|
|
11
11
|
tags[key.slice(4)] = value;
|
|
12
12
|
}
|
|
@@ -14,8 +14,8 @@ export function extractTagsAndSanitizeIndexes(records) {
|
|
|
14
14
|
return { tags, indexes };
|
|
15
15
|
}
|
|
16
16
|
export function sanitizeIndexes(records) {
|
|
17
|
-
for (
|
|
18
|
-
|
|
17
|
+
for (const key in records) {
|
|
18
|
+
const value = records[key];
|
|
19
19
|
if (Array.isArray(value)) {
|
|
20
20
|
const sanitizedValues = [];
|
|
21
21
|
for (const valueItem of value) {
|
|
@@ -48,7 +48,7 @@ export function sanitizeFiltersAndSeparateTags(filters) {
|
|
|
48
48
|
const tagFilter = {};
|
|
49
49
|
const nonTagFilter = {};
|
|
50
50
|
// tag values are prefixed with 'tag.', we extract them to be queried separately in the tags tables.
|
|
51
|
-
for (
|
|
51
|
+
for (const key in filter) {
|
|
52
52
|
const value = sanitizeFilterValue(filter[key]);
|
|
53
53
|
if (key.startsWith('tag.')) {
|
|
54
54
|
tagFilter[key.slice(4)] = value;
|
|
@@ -70,7 +70,6 @@ export function sanitizeFiltersAndSeparateTags(filters) {
|
|
|
70
70
|
* NOTE: sqlite3 we use does not support inserting boolean values,
|
|
71
71
|
* so we convert them to a number during insertions/updates, as a result we need to align the filter values in queries.
|
|
72
72
|
*/
|
|
73
|
-
// TODO: export filter types from `dwn-sdk-js`
|
|
74
73
|
export function sanitizeFilterValue(value) {
|
|
75
74
|
switch (typeof value) {
|
|
76
75
|
case 'boolean':
|
|
@@ -83,8 +82,8 @@ export function sanitizeFilters(filters) {
|
|
|
83
82
|
filters.forEach(sanitizeFilter);
|
|
84
83
|
}
|
|
85
84
|
export function sanitizeFilter(filter) {
|
|
86
|
-
for (
|
|
87
|
-
|
|
85
|
+
for (const key in filter) {
|
|
86
|
+
const value = filter[key];
|
|
88
87
|
filter[key] = sanitizeFilterValue(value);
|
|
89
88
|
}
|
|
90
89
|
return filter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../../src/utils/sanitize.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,6BAA6B,CAAC,OAAkB;IAK9D,MAAM,IAAI,GAAG,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;IAE/B,eAAe,CAAC,OAAO,CAAC,CAAC;IAEzB,iHAAiH;IACjH,wFAAwF;IACxF,KAAK,
|
|
1
|
+
{"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../../../src/utils/sanitize.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,6BAA6B,CAAC,OAAkB;IAK9D,MAAM,IAAI,GAAG,EAAE,CAAC;IAChB,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;IAE/B,eAAe,CAAC,OAAO,CAAC,CAAC;IAEzB,iHAAiH;IACjH,wFAAwF;IACxF,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAkB;IAChD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,eAAe,GAAU,EAAE,CAAC;YAClC,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;gBAC9B,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;YAClD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAAC,OAAiB;IAK9D,MAAM,gBAAgB,GAAuC,EAAE,CAAC;IAEhE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,EAAE,CAAC;QACrB,MAAM,YAAY,GAAG,EAAE,CAAC;QAExB,oGAAoG;QACpG,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAE/C,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,gBAAgB,CAAC,IAAI,CAAC;YACpB,IAAI,EAAK,SAAS;YAClB,MAAM,EAAG,YAAY;SACtB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,0EAA0E;AAE1E;;;;EAIE;AACF,MAAM,UAAU,mBAAmB,CAAC,KAAU;IAC5C,QAAQ,OAAO,KAAK,EAAE,CAAC;QACrB,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAiB;IAC/C,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -4,21 +4,18 @@ import { sanitizedValue } from './sanitize.js';
|
|
|
4
4
|
*/
|
|
5
5
|
export class TagTables {
|
|
6
6
|
dialect;
|
|
7
|
-
table;
|
|
8
7
|
/**
|
|
9
8
|
* @param dialect the target dialect, necessary for returning the `insertId`
|
|
10
|
-
* @param table the DB Table in order to index the tags and values in the correct tables. Choice between `messageStoreMessages` and `eventLogMessages`
|
|
11
9
|
*/
|
|
12
|
-
constructor(dialect
|
|
10
|
+
constructor(dialect) {
|
|
13
11
|
this.dialect = dialect;
|
|
14
|
-
this.table = table;
|
|
15
12
|
}
|
|
16
13
|
/**
|
|
17
14
|
* Inserts the given tags associated with the given foreign `insertId`.
|
|
18
15
|
*/
|
|
19
16
|
async executeTagsInsert(foreignInsertId, tags, tx) {
|
|
20
|
-
const tagTable =
|
|
21
|
-
const foreignKeyReference =
|
|
17
|
+
const tagTable = 'messageStoreRecordsTags';
|
|
18
|
+
const foreignKeyReference = { messageInsertId: foreignInsertId };
|
|
22
19
|
for (const tag in tags) {
|
|
23
20
|
const tagValues = tags[tag];
|
|
24
21
|
const values = Array.isArray(tagValues) ? tagValues : [tagValues];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../../src/utils/tags.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,SAAS;
|
|
1
|
+
{"version":3,"file":"tags.js","sourceRoot":"","sources":["../../../../src/utils/tags.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,SAAS;IAKA;IAHpB;;OAEG;IACH,YAAoB,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAE,CAAC;IAEvC;;OAEG;IACH,KAAK,CAAC,iBAAiB,CACrB,eAAuB,EACvB,IAAe,EACf,EAAgC;QAEhC,MAAM,QAAQ,GAAG,yBAAkC,CAAC;QACpD,MAAM,mBAAmB,GAAG,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC;QAEjE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,SAAS,CAAE,CAAC;YAEpE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,cAAc,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;gBAC7C,MAAM,YAAY,GAAG;oBACnB,GAAG;oBACH,WAAW,EAAG,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;oBACxE,WAAW,EAAG,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;oBACxE,GAAG,mBAAmB;iBACvB,CAAC;gBACF,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC,uBAAuB,EAAE,CAAC;YAChH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -1,25 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Executes the provided
|
|
2
|
+
* Executes the provided operation atomically within a database transaction.
|
|
3
3
|
*/
|
|
4
|
-
export async function
|
|
5
|
-
|
|
6
|
-
let success = false;
|
|
7
|
-
while (!success) {
|
|
8
|
-
try {
|
|
9
|
-
await database.transaction().execute(operation);
|
|
10
|
-
success = true;
|
|
11
|
-
}
|
|
12
|
-
catch (error) {
|
|
13
|
-
// if error is "database is locked", we retry the transaction
|
|
14
|
-
// this mainly happens when multiple transactions are trying to access the database at the same time in SQLite implementation.
|
|
15
|
-
if (error.code === 'SQLITE_BUSY') {
|
|
16
|
-
retryCount++;
|
|
17
|
-
console.log(`Database is locked when attempting SQL operation, retrying #${retryCount}...`);
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
throw error;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
4
|
+
export async function executeWithTransaction(database, operation) {
|
|
5
|
+
await database.transaction().execute(operation);
|
|
24
6
|
}
|
|
25
7
|
//# sourceMappingURL=transaction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../../src/utils/transaction.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../../../src/utils/transaction.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAiC,EACjC,SAAuE;IAEvE,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { Dialect } from './dialect/dialect.js';
|
|
1
|
+
import type { Dialect } from './dialect/dialect.js';
|
|
2
|
+
import type { DataStore, DataStoreGetResult, DataStorePutResult } from '@enbox/dwn-sdk-js';
|
|
4
3
|
export declare class DataStoreSql implements DataStore {
|
|
5
4
|
#private;
|
|
6
5
|
constructor(dialect: Dialect);
|
|
7
6
|
open(): Promise<void>;
|
|
8
7
|
close(): Promise<void>;
|
|
9
8
|
get(tenant: string, recordId: string, dataCid: string): Promise<DataStoreGetResult | undefined>;
|
|
10
|
-
put(tenant: string, recordId: string, dataCid: string, dataStream:
|
|
9
|
+
put(tenant: string, recordId: string, dataCid: string, dataStream: ReadableStream<Uint8Array>): Promise<DataStorePutResult>;
|
|
11
10
|
delete(tenant: string, recordId: string, dataCid: string): Promise<void>;
|
|
12
11
|
clear(): Promise<void>;
|
|
13
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-store-sql.d.ts","sourceRoot":"","sources":["../../../src/data-store-sql.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"data-store-sql.d.ts","sourceRoot":"","sources":["../../../src/data-store-sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK3F,qBAAa,YAAa,YAAW,SAAS;;gBAIhC,OAAO,EAAE,OAAO;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsCrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,GAAG,CACP,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IA+BpC,GAAG,CACP,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,cAAc,CAAC,UAAU,CAAC,GACrC,OAAO,CAAC,kBAAkB,CAAC;IAoBxB,MAAM,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC;IAeV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAY7B"}
|