@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,11 +1,58 @@
1
1
  import * as messages from "./sqlite3-messages.worker.js";
2
2
  import { create } from "./sqlite3.wasm.js";
3
3
 
4
+ const resolveValues = (
5
+ values: messages.EncodedValue[] | undefined,
6
+ profile = false,
7
+ ) => {
8
+ if (!values || values.length === 0) {
9
+ return {
10
+ values: undefined,
11
+ timing: profile
12
+ ? {
13
+ decodeMs: 0,
14
+ valueCount: 0,
15
+ blobValueCount: 0,
16
+ blobBytes: 0,
17
+ }
18
+ : undefined,
19
+ };
20
+ }
21
+
22
+ let blobBytes = 0;
23
+ let blobValueCount = 0;
24
+ const startedAt = profile ? performance.now() : 0;
25
+ const resolvedValues = values.map((value) => {
26
+ const resolved = messages.resolveValue(value);
27
+ if (profile && resolved instanceof Uint8Array) {
28
+ blobValueCount++;
29
+ blobBytes += resolved.byteLength;
30
+ }
31
+ return resolved;
32
+ });
33
+
34
+ return {
35
+ values: resolvedValues,
36
+ timing: profile
37
+ ? {
38
+ decodeMs: performance.now() - startedAt,
39
+ valueCount: values.length,
40
+ blobValueCount,
41
+ blobBytes,
42
+ }
43
+ : undefined,
44
+ };
45
+ };
46
+
4
47
  class SqliteWorkerHandler {
5
48
  databases: Map<string, Awaited<ReturnType<typeof create>>> = new Map();
6
49
 
7
- async create(databaseId: string, directory?: string) {
8
- const db = await create(directory);
50
+ async create(
51
+ databaseId: string,
52
+ directory?: string,
53
+ options?: { pragmas?: messages.SQLitePragmaOptions },
54
+ ) {
55
+ const db = await create(directory, options);
9
56
  this.databases.set(databaseId, db);
10
57
  return db;
11
58
  }
@@ -13,16 +60,25 @@ class SqliteWorkerHandler {
13
60
  async onMessage(
14
61
  message: messages.DatabaseMessages | messages.StatementMessages,
15
62
  ) {
16
- if (message.type === "create") {
17
- await this.create(message.databaseId, message.directory);
18
- } else {
63
+ const profile = Boolean(message.profile);
64
+ const startedAt = profile ? performance.now() : 0;
65
+ let decodeMs = 0;
66
+ let valueCount = 0;
67
+ let blobValueCount = 0;
68
+ let blobBytes = 0;
69
+
70
+ const execute = async () => {
71
+ if (message.type === "create") {
72
+ await this.create(message.databaseId, message.directory, {
73
+ pragmas: message.pragmas,
74
+ });
75
+ return undefined;
76
+ }
77
+
19
78
  const db = this.databases.get(message.databaseId);
20
79
  if (!db) {
21
- if (message.type === "close") {
22
- return; // ignore close message if database is not found
23
- }
24
- if (message.type === "drop") {
25
- return; // ignore close message if database is not found
80
+ if (message.type === "close" || message.type === "drop") {
81
+ return undefined;
26
82
  }
27
83
  if (message.type === "status") {
28
84
  return "closed";
@@ -35,57 +91,109 @@ class SqliteWorkerHandler {
35
91
  message.type,
36
92
  );
37
93
  }
94
+
38
95
  if (message.type === "exec") {
39
96
  return db.exec(message.sql);
40
- } else if (message.type === "status") {
97
+ }
98
+ if (message.type === "status") {
41
99
  return db.status();
42
- } else if (message.type === "prepare") {
100
+ }
101
+ if (message.type === "prepare") {
43
102
  const statementId = message.id;
44
103
  await db.prepare(message.sql, message.id);
45
- // db.statements.get(statementId) -> statement, because sqlite3.wasm stores the statement in a map like this
46
104
  return statementId;
47
- } else if (message.type === "close") {
105
+ }
106
+ if (message.type === "close") {
48
107
  await db.close();
49
108
  this.databases.delete(message.databaseId);
50
- } else if (message.type === "drop") {
109
+ return undefined;
110
+ }
111
+ if (message.type === "drop") {
51
112
  await db.drop();
52
113
  this.databases.delete(message.databaseId);
53
- } else if (message.type === "open") {
114
+ return undefined;
115
+ }
116
+ if (message.type === "open") {
54
117
  await db.open();
55
118
  this.databases.set(message.databaseId, db);
56
- } else if (message.type === "run") {
57
- return db.run(message.sql, message.values.map(messages.resolveValue));
58
- } else {
59
- const statement = db.statements.get(message.statementId);
60
- if (!statement) {
61
- throw new Error(
62
- "Statement not found with id: " + message.statementId,
63
- );
64
- }
119
+ return undefined;
120
+ }
121
+ if (message.type === "run") {
122
+ const resolved = resolveValues(message.values, profile);
123
+ decodeMs = resolved.timing?.decodeMs ?? 0;
124
+ valueCount = resolved.timing?.valueCount ?? 0;
125
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
126
+ blobBytes = resolved.timing?.blobBytes ?? 0;
127
+ return db.run(message.sql, resolved.values ?? []);
128
+ }
65
129
 
66
- if (message.type === "bind") {
67
- return statement.bind(message.values.map(messages.resolveValue));
68
- } else if (message.type === "finalize") {
69
- return statement.finalize();
70
- } else if (message.type === "reset") {
71
- return statement.reset();
72
- } else if (message.type === "get") {
73
- return statement.get(
74
- message.values
75
- ? message.values.map(messages.resolveValue)
76
- : undefined,
77
- );
78
- } else if (message.type === "step") {
79
- return statement.step();
80
- } else if (message.type === "run-statement") {
81
- return statement.run(message.values.map(messages.resolveValue));
82
- } else if (message.type === "all") {
83
- return statement.all(message.values.map(messages.resolveValue));
84
- } else {
85
- throw new Error("Unknown statement message type: " + message["type"]);
86
- }
130
+ const statement = db.statements.get(message.statementId);
131
+ if (!statement) {
132
+ throw new Error("Statement not found with id: " + message.statementId);
87
133
  }
88
- }
134
+
135
+ if (message.type === "bind") {
136
+ const resolved = resolveValues(message.values, profile);
137
+ decodeMs = resolved.timing?.decodeMs ?? 0;
138
+ valueCount = resolved.timing?.valueCount ?? 0;
139
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
140
+ blobBytes = resolved.timing?.blobBytes ?? 0;
141
+ return statement.bind(resolved.values ?? []);
142
+ }
143
+ if (message.type === "finalize") {
144
+ return statement.finalize();
145
+ }
146
+ if (message.type === "reset") {
147
+ return statement.reset();
148
+ }
149
+ if (message.type === "get") {
150
+ const resolved = resolveValues(message.values, profile);
151
+ decodeMs = resolved.timing?.decodeMs ?? 0;
152
+ valueCount = resolved.timing?.valueCount ?? 0;
153
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
154
+ blobBytes = resolved.timing?.blobBytes ?? 0;
155
+ return statement.get(resolved.values);
156
+ }
157
+ if (message.type === "step") {
158
+ return statement.step();
159
+ }
160
+ if (message.type === "run-statement") {
161
+ const resolved = resolveValues(message.values, profile);
162
+ decodeMs = resolved.timing?.decodeMs ?? 0;
163
+ valueCount = resolved.timing?.valueCount ?? 0;
164
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
165
+ blobBytes = resolved.timing?.blobBytes ?? 0;
166
+ return statement.run(resolved.values ?? []);
167
+ }
168
+ if (message.type === "all") {
169
+ const resolved = resolveValues(message.values, profile);
170
+ decodeMs = resolved.timing?.decodeMs ?? 0;
171
+ valueCount = resolved.timing?.valueCount ?? 0;
172
+ blobValueCount = resolved.timing?.blobValueCount ?? 0;
173
+ blobBytes = resolved.timing?.blobBytes ?? 0;
174
+ return statement.all(resolved.values ?? []);
175
+ }
176
+
177
+ throw new Error("Unknown statement message type: " + message["type"]);
178
+ };
179
+
180
+ const execStart = profile ? performance.now() : 0;
181
+ const result = await execute();
182
+ const execMs = profile ? performance.now() - execStart - decodeMs : 0;
183
+
184
+ return {
185
+ result,
186
+ timing: profile
187
+ ? {
188
+ decodeMs,
189
+ execMs,
190
+ totalMs: performance.now() - startedAt,
191
+ valueCount,
192
+ blobValueCount,
193
+ blobBytes,
194
+ }
195
+ : undefined,
196
+ };
89
197
  }
90
198
  }
91
199
  const worker = new SqliteWorkerHandler();
@@ -95,18 +203,31 @@ self.onmessage = async (
95
203
  messages.DatabaseMessages | messages.StatementMessages
96
204
  >,
97
205
  ) => {
206
+ const profile = Boolean(messageEvent.data.profile);
207
+ const startedAt = profile ? performance.now() : 0;
98
208
  try {
99
- const results = await worker.onMessage(messageEvent.data);
209
+ const response = await worker.onMessage(messageEvent.data);
100
210
  self.postMessage({
101
211
  type: "response",
102
212
  id: messageEvent.data.id,
103
- result: results,
213
+ result: response.result,
214
+ timing: response.timing,
104
215
  });
105
216
  } catch (error: any) {
106
217
  self.postMessage({
107
218
  type: "error",
108
219
  id: messageEvent.data.id,
109
220
  message: error?.message,
221
+ timing: profile
222
+ ? {
223
+ decodeMs: 0,
224
+ execMs: 0,
225
+ totalMs: performance.now() - startedAt,
226
+ valueCount: 0,
227
+ blobValueCount: 0,
228
+ blobBytes: 0,
229
+ }
230
+ : undefined,
110
231
  });
111
232
  }
112
233
  };
package/src/utils.ts CHANGED
@@ -7,3 +7,17 @@ export const isFKError = (e: any) => {
7
7
  e.message.includes("FOREIGN KEY constraint failed")))
8
8
  );
9
9
  };
10
+
11
+ export const isUniqueConstraintError = (e: any) => {
12
+ return (
13
+ e?.code === "SQLITE_CONSTRAINT_PRIMARYKEY" ||
14
+ e?.code === "SQLITE_CONSTRAINT_UNIQUE" ||
15
+ e?.rc === 1555 ||
16
+ e?.rc === 2067 ||
17
+ (e?.message &&
18
+ (e.message.includes("SQLITE_CONSTRAINT_PRIMARYKEY") ||
19
+ e.message.includes("SQLITE_CONSTRAINT_UNIQUE") ||
20
+ e.message.includes("UNIQUE constraint failed") ||
21
+ e.message.includes("PRIMARY KEY constraint failed")))
22
+ );
23
+ };