@peerbit/indexer-sqlite3 3.0.0-e6ea5c0 → 3.0.1

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.
Files changed (47) hide show
  1. package/dist/assets/sqlite3/sqlite3.worker.min.js +168 -52
  2. package/dist/index.min.js +277 -53
  3. package/dist/index.min.js.map +3 -3
  4. package/dist/src/engine.d.ts +9 -3
  5. package/dist/src/engine.d.ts.map +1 -1
  6. package/dist/src/engine.js +75 -9
  7. package/dist/src/engine.js.map +1 -1
  8. package/dist/src/index.d.ts +7 -3
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +5 -4
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/schema.d.ts +5 -1
  13. package/dist/src/schema.d.ts.map +1 -1
  14. package/dist/src/schema.js +42 -12
  15. package/dist/src/schema.js.map +1 -1
  16. package/dist/src/sqlite3-messages.worker.d.ts +47 -8
  17. package/dist/src/sqlite3-messages.worker.d.ts.map +1 -1
  18. package/dist/src/sqlite3-messages.worker.js +42 -3
  19. package/dist/src/sqlite3-messages.worker.js.map +1 -1
  20. package/dist/src/sqlite3.browser.d.ts +22 -1
  21. package/dist/src/sqlite3.browser.d.ts.map +1 -1
  22. package/dist/src/sqlite3.browser.js +138 -31
  23. package/dist/src/sqlite3.browser.js.map +1 -1
  24. package/dist/src/sqlite3.d.ts +4 -1
  25. package/dist/src/sqlite3.d.ts.map +1 -1
  26. package/dist/src/sqlite3.js +14 -5
  27. package/dist/src/sqlite3.js.map +1 -1
  28. package/dist/src/sqlite3.wasm.d.ts +4 -1
  29. package/dist/src/sqlite3.wasm.d.ts.map +1 -1
  30. package/dist/src/sqlite3.wasm.js +15 -3
  31. package/dist/src/sqlite3.wasm.js.map +1 -1
  32. package/dist/src/sqlite3.worker.js +146 -53
  33. package/dist/src/sqlite3.worker.js.map +1 -1
  34. package/dist/src/utils.d.ts +1 -0
  35. package/dist/src/utils.d.ts.map +1 -1
  36. package/dist/src/utils.js +11 -0
  37. package/dist/src/utils.js.map +1 -1
  38. package/package.json +10 -9
  39. package/src/engine.ts +99 -11
  40. package/src/index.ts +39 -4
  41. package/src/schema.ts +67 -11
  42. package/src/sqlite3-messages.worker.ts +104 -10
  43. package/src/sqlite3.browser.ts +246 -88
  44. package/src/sqlite3.ts +19 -5
  45. package/src/sqlite3.wasm.ts +25 -3
  46. package/src/sqlite3.worker.ts +170 -49
  47. package/src/utils.ts +14 -0
@@ -1,24 +1,67 @@
1
1
  import * as messages from "./sqlite3-messages.worker.js";
2
2
  import { create } from "./sqlite3.wasm.js";
3
+ const resolveValues = (values, profile = false) => {
4
+ if (!values || values.length === 0) {
5
+ return {
6
+ values: undefined,
7
+ timing: profile
8
+ ? {
9
+ decodeMs: 0,
10
+ valueCount: 0,
11
+ blobValueCount: 0,
12
+ blobBytes: 0,
13
+ }
14
+ : undefined,
15
+ };
16
+ }
17
+ let blobBytes = 0;
18
+ let blobValueCount = 0;
19
+ const startedAt = profile ? performance.now() : 0;
20
+ const resolvedValues = values.map((value) => {
21
+ const resolved = messages.resolveValue(value);
22
+ if (profile && resolved instanceof Uint8Array) {
23
+ blobValueCount++;
24
+ blobBytes += resolved.byteLength;
25
+ }
26
+ return resolved;
27
+ });
28
+ return {
29
+ values: resolvedValues,
30
+ timing: profile
31
+ ? {
32
+ decodeMs: performance.now() - startedAt,
33
+ valueCount: values.length,
34
+ blobValueCount,
35
+ blobBytes,
36
+ }
37
+ : undefined,
38
+ };
39
+ };
3
40
  class SqliteWorkerHandler {
4
41
  databases = new Map();
5
- async create(databaseId, directory) {
6
- const db = await create(directory);
42
+ async create(databaseId, directory, options) {
43
+ const db = await create(directory, options);
7
44
  this.databases.set(databaseId, db);
8
45
  return db;
9
46
  }
10
47
  async onMessage(message) {
11
- if (message.type === "create") {
12
- await this.create(message.databaseId, message.directory);
13
- }
14
- else {
48
+ const profile = Boolean(message.profile);
49
+ const startedAt = profile ? performance.now() : 0;
50
+ let decodeMs = 0;
51
+ let valueCount = 0;
52
+ let blobValueCount = 0;
53
+ let blobBytes = 0;
54
+ const execute = async () => {
55
+ if (message.type === "create") {
56
+ await this.create(message.databaseId, message.directory, {
57
+ pragmas: message.pragmas,
58
+ });
59
+ return undefined;
60
+ }
15
61
  const db = this.databases.get(message.databaseId);
16
62
  if (!db) {
17
- if (message.type === "close") {
18
- return; // ignore close message if database is not found
19
- }
20
- if (message.type === "drop") {
21
- return; // ignore close message if database is not found
63
+ if (message.type === "close" || message.type === "drop") {
64
+ return undefined;
22
65
  }
23
66
  if (message.type === "status") {
24
67
  return "closed";
@@ -31,73 +74,113 @@ class SqliteWorkerHandler {
31
74
  if (message.type === "exec") {
32
75
  return db.exec(message.sql);
33
76
  }
34
- else if (message.type === "status") {
77
+ if (message.type === "status") {
35
78
  return db.status();
36
79
  }
37
- else if (message.type === "prepare") {
80
+ if (message.type === "prepare") {
38
81
  const statementId = message.id;
39
82
  await db.prepare(message.sql, message.id);
40
- // db.statements.get(statementId) -> statement, because sqlite3.wasm stores the statement in a map like this
41
83
  return statementId;
42
84
  }
43
- else if (message.type === "close") {
85
+ if (message.type === "close") {
44
86
  await db.close();
45
87
  this.databases.delete(message.databaseId);
88
+ return undefined;
46
89
  }
47
- else if (message.type === "drop") {
90
+ if (message.type === "drop") {
48
91
  await db.drop();
49
92
  this.databases.delete(message.databaseId);
93
+ return undefined;
50
94
  }
51
- else if (message.type === "open") {
95
+ if (message.type === "open") {
52
96
  await db.open();
53
97
  this.databases.set(message.databaseId, db);
98
+ return undefined;
54
99
  }
55
- else if (message.type === "run") {
56
- return db.run(message.sql, message.values.map(messages.resolveValue));
100
+ if (message.type === "run") {
101
+ const resolved = resolveValues(message.values, profile);
102
+ decodeMs = resolved.timing?.decodeMs ?? 0;
103
+ valueCount = resolved.timing?.valueCount ?? 0;
104
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
105
+ blobBytes = resolved.timing?.blobBytes ?? 0;
106
+ return db.run(message.sql, resolved.values ?? []);
57
107
  }
58
- else {
59
- const statement = db.statements.get(message.statementId);
60
- if (!statement) {
61
- throw new Error("Statement not found with id: " + message.statementId);
62
- }
63
- if (message.type === "bind") {
64
- return statement.bind(message.values.map(messages.resolveValue));
65
- }
66
- else if (message.type === "finalize") {
67
- return statement.finalize();
68
- }
69
- else if (message.type === "reset") {
70
- return statement.reset();
71
- }
72
- else if (message.type === "get") {
73
- return statement.get(message.values
74
- ? message.values.map(messages.resolveValue)
75
- : undefined);
76
- }
77
- else if (message.type === "step") {
78
- return statement.step();
79
- }
80
- else if (message.type === "run-statement") {
81
- return statement.run(message.values.map(messages.resolveValue));
82
- }
83
- else if (message.type === "all") {
84
- return statement.all(message.values.map(messages.resolveValue));
85
- }
86
- else {
87
- throw new Error("Unknown statement message type: " + message["type"]);
88
- }
108
+ const statement = db.statements.get(message.statementId);
109
+ if (!statement) {
110
+ throw new Error("Statement not found with id: " + message.statementId);
89
111
  }
90
- }
112
+ if (message.type === "bind") {
113
+ const resolved = resolveValues(message.values, profile);
114
+ decodeMs = resolved.timing?.decodeMs ?? 0;
115
+ valueCount = resolved.timing?.valueCount ?? 0;
116
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
117
+ blobBytes = resolved.timing?.blobBytes ?? 0;
118
+ return statement.bind(resolved.values ?? []);
119
+ }
120
+ if (message.type === "finalize") {
121
+ return statement.finalize();
122
+ }
123
+ if (message.type === "reset") {
124
+ return statement.reset();
125
+ }
126
+ if (message.type === "get") {
127
+ const resolved = resolveValues(message.values, profile);
128
+ decodeMs = resolved.timing?.decodeMs ?? 0;
129
+ valueCount = resolved.timing?.valueCount ?? 0;
130
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
131
+ blobBytes = resolved.timing?.blobBytes ?? 0;
132
+ return statement.get(resolved.values);
133
+ }
134
+ if (message.type === "step") {
135
+ return statement.step();
136
+ }
137
+ if (message.type === "run-statement") {
138
+ const resolved = resolveValues(message.values, profile);
139
+ decodeMs = resolved.timing?.decodeMs ?? 0;
140
+ valueCount = resolved.timing?.valueCount ?? 0;
141
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
142
+ blobBytes = resolved.timing?.blobBytes ?? 0;
143
+ return statement.run(resolved.values ?? []);
144
+ }
145
+ if (message.type === "all") {
146
+ const resolved = resolveValues(message.values, profile);
147
+ decodeMs = resolved.timing?.decodeMs ?? 0;
148
+ valueCount = resolved.timing?.valueCount ?? 0;
149
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
150
+ blobBytes = resolved.timing?.blobBytes ?? 0;
151
+ return statement.all(resolved.values ?? []);
152
+ }
153
+ throw new Error("Unknown statement message type: " + message["type"]);
154
+ };
155
+ const execStart = profile ? performance.now() : 0;
156
+ const result = await execute();
157
+ const execMs = profile ? performance.now() - execStart - decodeMs : 0;
158
+ return {
159
+ result,
160
+ timing: profile
161
+ ? {
162
+ decodeMs,
163
+ execMs,
164
+ totalMs: performance.now() - startedAt,
165
+ valueCount,
166
+ blobValueCount,
167
+ blobBytes,
168
+ }
169
+ : undefined,
170
+ };
91
171
  }
92
172
  }
93
173
  const worker = new SqliteWorkerHandler();
94
174
  self.onmessage = async (messageEvent) => {
175
+ const profile = Boolean(messageEvent.data.profile);
176
+ const startedAt = profile ? performance.now() : 0;
95
177
  try {
96
- const results = await worker.onMessage(messageEvent.data);
178
+ const response = await worker.onMessage(messageEvent.data);
97
179
  self.postMessage({
98
180
  type: "response",
99
181
  id: messageEvent.data.id,
100
- result: results,
182
+ result: response.result,
183
+ timing: response.timing,
101
184
  });
102
185
  }
103
186
  catch (error) {
@@ -105,6 +188,16 @@ self.onmessage = async (messageEvent) => {
105
188
  type: "error",
106
189
  id: messageEvent.data.id,
107
190
  message: error?.message,
191
+ timing: profile
192
+ ? {
193
+ decodeMs: 0,
194
+ execMs: 0,
195
+ totalMs: performance.now() - startedAt,
196
+ valueCount: 0,
197
+ blobValueCount: 0,
198
+ blobBytes: 0,
199
+ }
200
+ : undefined,
108
201
  });
109
202
  }
110
203
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite3.worker.js","sourceRoot":"","sources":["../../src/sqlite3.worker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,mBAAmB;IACxB,SAAS,GAAoD,IAAI,GAAG,EAAE,CAAC;IAEvE,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,SAAkB;QAClD,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO,EAAE,CAAC;IACX,CAAC;IAED,KAAK,CAAC,SAAS,CACd,OAA+D;QAE/D,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACP,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,EAAE,EAAE,CAAC;gBACT,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC9B,OAAO,CAAC,gDAAgD;gBACzD,CAAC;gBACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC7B,OAAO,CAAC,gDAAgD;gBACzD,CAAC;gBACD,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC/B,OAAO,QAAQ,CAAC;gBACjB,CAAC;gBAED,MAAM,IAAI,KAAK,CACd,8BAA8B;oBAC7B,OAAO,CAAC,UAAU;oBAClB,qBAAqB;oBACrB,OAAO,CAAC,IAAI,CACb,CAAC;YACH,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC7B,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,OAAO,EAAE,CAAC,MAAM,EAAE,CAAC;YACpB,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvC,MAAM,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC;gBAC/B,MAAM,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC1C,4GAA4G;gBAC5G,OAAO,WAAW,CAAC;YACpB,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;gBACjB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC3C,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC3C,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;gBAChB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC5C,CAAC;iBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnC,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;YACvE,CAAC;iBAAM,CAAC;gBACP,MAAM,SAAS,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CACd,+BAA+B,GAAG,OAAO,CAAC,WAAW,CACrD,CAAC;gBACH,CAAC;gBAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC7B,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;gBAClE,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;oBACxC,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC7B,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACrC,OAAO,SAAS,CAAC,KAAK,EAAE,CAAC;gBAC1B,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBACnC,OAAO,SAAS,CAAC,GAAG,CACnB,OAAO,CAAC,MAAM;wBACb,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC;wBAC3C,CAAC,CAAC,SAAS,CACZ,CAAC;gBACH,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBACpC,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC;gBACzB,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;oBAC7C,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;gBACjE,CAAC;qBAAM,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBACnC,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;gBACjE,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;gBACvE,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;CACD;AACD,MAAM,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;AAEzC,IAAI,CAAC,SAAS,GAAG,KAAK,EACrB,YAEC,EACA,EAAE;IACH,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,CAAC,WAAW,CAAC;YAChB,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE;YACxB,MAAM,EAAE,OAAO;SACf,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACrB,IAAI,CAAC,WAAW,CAAC;YAChB,IAAI,EAAE,OAAO;YACb,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE;YACxB,OAAO,EAAE,KAAK,EAAE,OAAO;SACvB,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC;AAEF,IAAI,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"sqlite3.worker.js","sourceRoot":"","sources":["../../src/sqlite3.worker.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  export declare const isFKError: (e: any) => any;
2
+ export declare const isUniqueConstraintError: (e: any) => any;
2
3
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,GAAI,GAAG,GAAG,QAQ/B,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,GAAI,GAAG,GAAG,QAQ/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,GAAG,GAAG,QAY7C,CAAC"}
package/dist/src/utils.js CHANGED
@@ -5,4 +5,15 @@ export const isFKError = (e) => {
5
5
  (e.message.includes("SQLITE_CONSTRAINT_FOREIGNKEY") ||
6
6
  e.message.includes("FOREIGN KEY constraint failed"))));
7
7
  };
8
+ export const isUniqueConstraintError = (e) => {
9
+ return (e?.code === "SQLITE_CONSTRAINT_PRIMARYKEY" ||
10
+ e?.code === "SQLITE_CONSTRAINT_UNIQUE" ||
11
+ e?.rc === 1555 ||
12
+ e?.rc === 2067 ||
13
+ (e?.message &&
14
+ (e.message.includes("SQLITE_CONSTRAINT_PRIMARYKEY") ||
15
+ e.message.includes("SQLITE_CONSTRAINT_UNIQUE") ||
16
+ e.message.includes("UNIQUE constraint failed") ||
17
+ e.message.includes("PRIMARY KEY constraint failed"))));
18
+ };
8
19
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAM,EAAE,EAAE;IACnC,OAAO,CACN,CAAC,EAAE,IAAI,KAAK,8BAA8B;QAC1C,CAAC,EAAE,EAAE,KAAK,GAAG;QACb,CAAC,CAAC,EAAE,OAAO;YACV,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC;gBAClD,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,CAAC,CACvD,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAM,EAAE,EAAE;IACnC,OAAO,CACN,CAAC,EAAE,IAAI,KAAK,8BAA8B;QAC1C,CAAC,EAAE,EAAE,KAAK,GAAG;QACb,CAAC,CAAC,EAAE,OAAO;YACV,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC;gBAClD,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,CAAC,CACvD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAM,EAAE,EAAE;IACjD,OAAO,CACN,CAAC,EAAE,IAAI,KAAK,8BAA8B;QAC1C,CAAC,EAAE,IAAI,KAAK,0BAA0B;QACtC,CAAC,EAAE,EAAE,KAAK,IAAI;QACd,CAAC,EAAE,EAAE,KAAK,IAAI;QACd,CAAC,CAAC,EAAE,OAAO;YACV,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,8BAA8B,CAAC;gBAClD,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC;gBAC9C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC;gBAC9C,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC,CAAC,CACvD,CAAC;AACH,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/indexer-sqlite3",
3
- "version": "3.0.0-e6ea5c0",
3
+ "version": "3.0.1",
4
4
  "description": "SQLite index for document store",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -61,20 +61,20 @@
61
61
  "dependencies": {
62
62
  "better-sqlite3": "^12.5.0",
63
63
  "@dao-xyz/borsh": "^6.0.0",
64
- "@peerbit/indexer-interface": "3.0.0-e6ea5c0",
65
- "@peerbit/crypto": "3.0.0-e6ea5c0",
66
- "@peerbit/time": "3.0.0-e6ea5c0",
67
64
  "@sqlite.org/sqlite-wasm": "^3.51.1-build2",
68
65
  "p-defer": "^4.0.0",
69
66
  "uint8arrays": "^5.1.0",
70
67
  "uuid": "^10.0.0",
71
- "libsodium-wrappers": "0.7.15"
68
+ "libsodium-wrappers": "0.7.15",
69
+ "@peerbit/indexer-interface": "3.0.0",
70
+ "@peerbit/crypto": "3.0.0",
71
+ "@peerbit/time": "3.0.0"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@types/better-sqlite3": "^7.6.13",
75
- "@peerbit/indexer-tests": "3.0.0-e6ea5c0",
76
- "@peerbit/build-assets": "1.1.0-e6ea5c0",
77
- "esbuild": "0.27.0"
75
+ "esbuild": "0.27.0",
76
+ "@peerbit/indexer-tests": "3.0.0",
77
+ "@peerbit/build-assets": "1.1.0"
78
78
  },
79
79
  "scripts": {
80
80
  "clean": "aegir clean",
@@ -84,6 +84,7 @@
84
84
  "test": "aegir test",
85
85
  "test:browser": "aegir clean && aegir test -t browser",
86
86
  "test:node": "aegir clean && aegir test -t node",
87
- "lint": "aegir lint"
87
+ "lint": "aegir lint",
88
+ "test:cov": "aegir test -t node --cov"
88
89
  }
89
90
  }
package/src/engine.ts CHANGED
@@ -30,13 +30,17 @@ import {
30
30
  selectChildren,
31
31
  } from "./schema.js";
32
32
  import type { Database, Statement } from "./types.js";
33
- import { isFKError } from "./utils.js";
33
+ import { isFKError, isUniqueConstraintError } from "./utils.js";
34
34
 
35
35
  const escapePathToSQLName = (path: string[]) => {
36
36
  return path.map((x) => x.replace(/[^a-zA-Z0-9]/g, "_"));
37
37
  };
38
38
 
39
39
  const putStatementKey = (table: Table) => table.name + "_put";
40
+ const insertKnownIdStatementKey = (table: Table) =>
41
+ table.name + "_insert_known_id";
42
+ const putStatementBatchNoReturnKey = (table: Table, rows: number) =>
43
+ table.name + "_put_batch_noreturn_" + rows;
40
44
  const replaceStatementKey = (table: Table) => table.name + "_replicate";
41
45
  const resolveChildrenStatement = (table: Table) =>
42
46
  table.name + "_resolve_children";
@@ -84,7 +88,24 @@ async function getIgnoreFK(stmt: Statement, values: any[]) {
84
88
  }
85
89
  }
86
90
 
87
- export class SQLLiteIndex<T extends Record<string, any>>
91
+ const createBatchInsertSQL = (table: Table, rows: number) => {
92
+ const columns = table.fields.map((field) => escapeColumnName(field.name)).join(", ");
93
+ const rowPlaceholder = `(${table.fields.map(() => "?").join(", ")})`;
94
+ return `insert into ${table.name} (${columns}) VALUES ${Array.from({
95
+ length: rows,
96
+ })
97
+ .map(() => rowPlaceholder)
98
+ .join(", ")};`;
99
+ };
100
+
101
+ const canUseWithoutRowId = (table: Table) => {
102
+ if (table.inline || table.primary === false || !table.primaryField) {
103
+ return false;
104
+ }
105
+ return !/^INTEGER\b/i.test(table.primaryField.type);
106
+ };
107
+
108
+ export class SQLiteIndex<T extends Record<string, any>>
88
109
  implements Index<T, any>
89
110
  {
90
111
  // SQLite writes are inherently serialized per connection.
@@ -145,6 +166,7 @@ export class SQLLiteIndex<T extends Record<string, any>>
145
166
  scope: string[];
146
167
  db: Database;
147
168
  schema: AbstractType<any>;
169
+ persisted?: boolean;
148
170
  start?: () => Promise<void> | void;
149
171
  stop?: () => Promise<void> | void;
150
172
  },
@@ -163,6 +185,10 @@ export class SQLLiteIndex<T extends Record<string, any>>
163
185
  });
164
186
  }
165
187
 
188
+ persisted(): boolean {
189
+ return this.properties.persisted ?? true;
190
+ }
191
+
166
192
  get tables() {
167
193
  if (this.closed) {
168
194
  throw new types.NotStartedError();
@@ -251,7 +277,10 @@ export class SQLLiteIndex<T extends Record<string, any>>
251
277
  continue;
252
278
  }
253
279
 
254
- const sqlCreateTable = `create table if not exists ${table.name} (${[...table.fields, ...table.constraints].map((s) => s.definition).join(", ")}) strict`;
280
+ const tableOptions = canUseWithoutRowId(table)
281
+ ? " strict, without rowid"
282
+ : " strict";
283
+ const sqlCreateTable = `create table if not exists ${table.name} (${[...table.fields, ...table.constraints].map((s) => s.definition).join(", ")})${tableOptions}`;
255
284
  this.properties.db.exec(sqlCreateTable);
256
285
 
257
286
  /* const fieldsToIndex = table.fields.filter(
@@ -290,10 +319,17 @@ export class SQLLiteIndex<T extends Record<string, any>>
290
319
  // put and return the id
291
320
  let sqlPut = `insert into ${table.name} (${table.fields.map((field) => escapeColumnName(field.name)).join(", ")}) VALUES (${table.fields.map((_x) => "?").join(", ")}) RETURNING ${table.primary};`;
292
321
 
322
+ // insert without replace when the caller already knows the id is fresh
323
+ let sqlInsertKnownId = `insert into ${table.name} (${table.fields.map((field) => escapeColumnName(field.name)).join(", ")}) VALUES (${table.fields.map((_x) => "?").join(", ")});`;
324
+
293
325
  // insert or replace with id already defined
294
326
  let sqlReplace = `insert or replace into ${table.name} (${table.fields.map((field) => escapeColumnName(field.name)).join(", ")}) VALUES (${table.fields.map((_x) => "?").join(", ")});`;
295
327
 
296
328
  await this.properties.db.prepare(sqlPut, putStatementKey(table));
329
+ await this.properties.db.prepare(
330
+ sqlInsertKnownId,
331
+ insertKnownIdStatementKey(table),
332
+ );
297
333
  await this.properties.db.prepare(sqlReplace, replaceStatementKey(table));
298
334
 
299
335
  if (table.parent) {
@@ -428,7 +464,11 @@ export class SQLLiteIndex<T extends Record<string, any>>
428
464
  return undefined;
429
465
  }
430
466
 
431
- async put(value: T, _id?: any): Promise<void> {
467
+ async put(
468
+ value: T,
469
+ _id?: any,
470
+ options?: { replace?: boolean },
471
+ ): Promise<void> {
432
472
  return this.withWriteBarrier(async () => {
433
473
  const classOfValue = value.constructor as Constructor<T>;
434
474
  return insert(
@@ -437,12 +477,35 @@ export class SQLLiteIndex<T extends Record<string, any>>
437
477
  let statement: Statement | undefined = undefined;
438
478
  try {
439
479
  if (preId != null) {
440
- statement = this.properties.db.statements.get(
441
- replaceStatementKey(table),
442
- )!;
443
- this.fkMode === "race-tolerant"
444
- ? await runIgnoreFK(statement, values)
445
- : await statement.run(values);
480
+ const shouldReplace = options?.replace ?? true;
481
+ if (!shouldReplace) {
482
+ statement = this.properties.db.statements.get(
483
+ insertKnownIdStatementKey(table),
484
+ )!;
485
+ try {
486
+ this.fkMode === "race-tolerant"
487
+ ? await runIgnoreFK(statement, values)
488
+ : await statement.run(values);
489
+ } catch (error) {
490
+ if (!isUniqueConstraintError(error)) {
491
+ throw error;
492
+ }
493
+ await statement.reset?.();
494
+ statement = this.properties.db.statements.get(
495
+ replaceStatementKey(table),
496
+ )!;
497
+ this.fkMode === "race-tolerant"
498
+ ? await runIgnoreFK(statement, values)
499
+ : await statement.run(values);
500
+ }
501
+ } else {
502
+ statement = this.properties.db.statements.get(
503
+ replaceStatementKey(table),
504
+ )!;
505
+ this.fkMode === "race-tolerant"
506
+ ? await runIgnoreFK(statement, values)
507
+ : await statement.run(values);
508
+ }
446
509
  return preId;
447
510
  } else {
448
511
  statement = this.properties.db.statements.get(
@@ -475,6 +538,24 @@ export class SQLLiteIndex<T extends Record<string, any>>
475
538
  (_fn) => {
476
539
  throw new Error("Unexpected");
477
540
  },
541
+ undefined,
542
+ undefined,
543
+ {
544
+ insertSimpleVecRows: async (rows, table) => {
545
+ if (rows.length === 0) {
546
+ return;
547
+ }
548
+ const key = putStatementBatchNoReturnKey(table, rows.length);
549
+ const sql = createBatchInsertSQL(table, rows.length);
550
+ const statement =
551
+ this.properties.db.statements.get(key) ||
552
+ (await this.properties.db.prepare(sql, key));
553
+ const values = rows.flat();
554
+ this.fkMode === "race-tolerant"
555
+ ? await runIgnoreFK(statement, values)
556
+ : await statement.run(values);
557
+ },
558
+ },
478
559
  );
479
560
  });
480
561
  }
@@ -821,10 +902,11 @@ export class SQLiteIndices implements types.Indices {
821
902
  return existing.index;
822
903
  }
823
904
 
824
- const index: types.Index<T, any> = new SQLLiteIndex({
905
+ const index: types.Index<T, any> = new SQLiteIndex({
825
906
  db: this.properties.db,
826
907
  schema: properties.schema,
827
908
  scope: this._scope,
909
+ persisted: await this.persisted(),
828
910
  });
829
911
  await index.init(properties);
830
912
  this.indices.push({ schema: properties.schema, index });
@@ -859,6 +941,10 @@ export class SQLiteIndices implements types.Indices {
859
941
  return scope;
860
942
  }
861
943
 
944
+ persisted(): boolean {
945
+ return this.properties.directory != null;
946
+ }
947
+
862
948
  async start(): Promise<void> {
863
949
  this.closed = false;
864
950
 
@@ -908,3 +994,5 @@ export class SQLiteIndices implements types.Indices {
908
994
  this.scopes.clear();
909
995
  }
910
996
  }
997
+
998
+ export { SQLiteIndex as SQLLiteIndex };
package/src/index.ts CHANGED
@@ -1,7 +1,18 @@
1
1
  import { BinaryWriter } from "@dao-xyz/borsh";
2
2
  import { sha256Sync, toBase58 } from "@peerbit/crypto";
3
- import { SQLLiteIndex, SQLiteIndices } from "./engine.js";
3
+ import { SQLiteIndex, SQLiteIndices } from "./engine.js";
4
4
  import { create as sqlite3 } from "./sqlite3.js";
5
+ import type {
6
+ SQLiteBrowserOptions,
7
+ SQLiteProfileSample,
8
+ } from "./sqlite3.browser.js";
9
+ import type {
10
+ SQLiteLockingMode,
11
+ SQLitePragmaOptions,
12
+ SQLiteSynchronousMode,
13
+ SQLiteTempStoreMode,
14
+ SqliteWorkerProtocol,
15
+ } from "./sqlite3-messages.worker.js";
5
16
 
6
17
  export const encodeName = (name: string): string => {
7
18
  const writer = new BinaryWriter();
@@ -9,8 +20,32 @@ export const encodeName = (name: string): string => {
9
20
  return toBase58(sha256Sync(writer.finalize()));
10
21
  };
11
22
 
12
- const create = async (directory?: string): Promise<SQLiteIndices> => {
13
- const db = await sqlite3(directory);
23
+ const create = async (
24
+ directory?: string,
25
+ options?: SQLiteBrowserOptions,
26
+ ): Promise<SQLiteIndices> => {
27
+ const db = await sqlite3(directory, options);
14
28
  return new SQLiteIndices({ db, directory });
15
29
  };
16
- export { create, SQLiteIndices, SQLLiteIndex };
30
+
31
+ const createDatabase = (
32
+ directory?: string,
33
+ options?: SQLiteBrowserOptions,
34
+ ) => sqlite3(directory, options);
35
+
36
+ export {
37
+ create,
38
+ createDatabase,
39
+ SQLiteIndices,
40
+ SQLiteIndex,
41
+ SQLiteIndex as SQLLiteIndex,
42
+ };
43
+ export type {
44
+ SQLiteBrowserOptions,
45
+ SQLiteLockingMode,
46
+ SQLitePragmaOptions,
47
+ SQLiteProfileSample,
48
+ SQLiteSynchronousMode,
49
+ SQLiteTempStoreMode,
50
+ SqliteWorkerProtocol,
51
+ };