@allmightypush/push-storage-sqlite 1.0.0

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 ADDED
@@ -0,0 +1,108 @@
1
+ # @allmightypush/push-storage-sqlite
2
+
3
+ SQLite storage adapter for the push notification library.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @allmightypush/push-storage-sqlite
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { SQLiteStorageAdapter } from '@allmightypush/push-storage-sqlite';
15
+
16
+ // Create adapter with file-based database
17
+ const adapter = new SQLiteStorageAdapter({
18
+ filename: './push-notifications.db',
19
+ enableWAL: true, // Enable WAL mode for better concurrency (default: true)
20
+ autoMigrate: true, // Run migrations automatically (default: true)
21
+ });
22
+
23
+ // Or use in-memory database for testing
24
+ const testAdapter = new SQLiteStorageAdapter({
25
+ filename: ':memory:',
26
+ });
27
+
28
+ // Use with push core
29
+ import { PushCore } from '@allmightypush/push-core';
30
+
31
+ const push = new PushCore();
32
+ push.configure({
33
+ storageAdapter: adapter,
34
+ // ... other configuration
35
+ });
36
+ ```
37
+
38
+ ## Configuration Options
39
+
40
+ ### `SQLiteStorageOptions`
41
+
42
+ - **`filename`** (required): Path to the SQLite database file, or `':memory:'` for an in-memory database
43
+ - **`enableWAL`** (optional, default: `true`): Enable Write-Ahead Logging mode for better concurrency
44
+ - **`autoMigrate`** (optional, default: `true`): Automatically run database migrations on initialization
45
+
46
+ ## Database Schema
47
+
48
+ ### Subscriptions Table
49
+
50
+ Stores push notification subscriptions with the following columns:
51
+
52
+ - `id` (TEXT, PRIMARY KEY): UUID identifier
53
+ - `endpoint` (TEXT, NOT NULL): Push service endpoint URL
54
+ - `keys` (TEXT, NOT NULL): JSON-encoded encryption keys (p256dh and auth)
55
+ - `user_id` (TEXT): Optional user identifier
56
+ - `created_at` (INTEGER, NOT NULL): Creation timestamp (Unix milliseconds)
57
+ - `updated_at` (INTEGER, NOT NULL): Last update timestamp (Unix milliseconds)
58
+ - `last_used_at` (INTEGER): Last successful send timestamp (Unix milliseconds)
59
+ - `failed_count` (INTEGER, NOT NULL, DEFAULT 0): Consecutive failure count
60
+ - `status` (TEXT, NOT NULL): Subscription status ('active', 'blocked', or 'expired')
61
+ - `expires_at` (INTEGER): Optional expiration timestamp (Unix milliseconds)
62
+ - `metadata` (TEXT): JSON-encoded arbitrary metadata
63
+
64
+ **Indexes:**
65
+ - `idx_subscriptions_user_id` on `user_id`
66
+ - `idx_subscriptions_status` on `status`
67
+
68
+ ### Retry Queue Table
69
+
70
+ Stores failed notifications awaiting retry:
71
+
72
+ - `id` (TEXT, PRIMARY KEY): UUID identifier
73
+ - `subscription_id` (TEXT, NOT NULL): Foreign key to subscriptions table
74
+ - `payload` (TEXT, NOT NULL): JSON-encoded notification payload
75
+ - `attempt` (INTEGER, NOT NULL): Current attempt number (0-indexed)
76
+ - `next_retry_at` (INTEGER, NOT NULL): Next retry timestamp (Unix milliseconds)
77
+ - `last_error` (TEXT): Last error message
78
+ - `created_at` (INTEGER, NOT NULL): Creation timestamp (Unix milliseconds)
79
+
80
+ **Indexes:**
81
+ - `idx_retry_queue_next_retry` on `next_retry_at`
82
+
83
+ **Foreign Keys:**
84
+ - `subscription_id` references `subscriptions(id)` with CASCADE DELETE
85
+
86
+ ## Migrations
87
+
88
+ The adapter automatically creates the required tables and indexes on initialization (when `autoMigrate` is `true`). You can also run migrations manually:
89
+
90
+ ```typescript
91
+ await adapter.migrate();
92
+ ```
93
+
94
+ Migrations are idempotent and can be safely called multiple times.
95
+
96
+ ## Features
97
+
98
+ - ✅ Full StorageAdapter interface implementation
99
+ - ✅ Automatic schema creation and migrations
100
+ - ✅ WAL mode for better concurrency
101
+ - ✅ Efficient indexes for common queries
102
+ - ✅ Foreign key constraints with cascade delete
103
+ - ✅ In-memory database support for testing
104
+ - ✅ TypeScript type definitions included
105
+
106
+ ## License
107
+
108
+ MIT
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.version = exports.SQLiteStorageAdapter = void 0;
7
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
+ const push_core_1 = require("@allmightypush/push-core");
9
+ const crypto_1 = require("crypto");
10
+ class SQLiteStorageAdapter {
11
+ constructor(options) {
12
+ this.closed = false;
13
+ this.db = new better_sqlite3_1.default(options.filename);
14
+ if (options.enableWAL !== false) {
15
+ this.db.pragma('journal_mode = WAL');
16
+ }
17
+ if (options.autoMigrate !== false) {
18
+ this.migrateSync();
19
+ }
20
+ }
21
+ migrateSync() {
22
+ this.db.exec(`
23
+ CREATE TABLE IF NOT EXISTS subscriptions (
24
+ id TEXT PRIMARY KEY,
25
+ endpoint TEXT NOT NULL,
26
+ keys TEXT NOT NULL,
27
+ user_id TEXT,
28
+ created_at INTEGER NOT NULL,
29
+ updated_at INTEGER NOT NULL,
30
+ last_used_at INTEGER,
31
+ failed_count INTEGER NOT NULL DEFAULT 0,
32
+ status TEXT NOT NULL CHECK(status IN ('active', 'blocked', 'expired')),
33
+ expires_at INTEGER,
34
+ metadata TEXT
35
+ )
36
+ `);
37
+ this.db.exec(`
38
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON subscriptions(user_id)
39
+ `);
40
+ this.db.exec(`
41
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status)
42
+ `);
43
+ this.db.exec(`
44
+ CREATE TABLE IF NOT EXISTS retry_queue (
45
+ id TEXT PRIMARY KEY,
46
+ subscription_id TEXT NOT NULL,
47
+ payload TEXT NOT NULL,
48
+ attempt INTEGER NOT NULL,
49
+ next_retry_at INTEGER NOT NULL,
50
+ last_error TEXT,
51
+ created_at INTEGER NOT NULL,
52
+ FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE
53
+ )
54
+ `);
55
+ this.db.exec(`
56
+ CREATE INDEX IF NOT EXISTS idx_retry_queue_next_retry ON retry_queue(next_retry_at)
57
+ `);
58
+ }
59
+ async migrate() {
60
+ this.migrateSync();
61
+ }
62
+ async createSubscription(data) {
63
+ this.ensureNotClosed();
64
+ try {
65
+ const id = (0, crypto_1.randomUUID)();
66
+ const now = Date.now();
67
+ const subscription = {
68
+ id,
69
+ endpoint: data.endpoint,
70
+ keys: data.keys,
71
+ userId: data.userId,
72
+ createdAt: new Date(now),
73
+ updatedAt: new Date(now),
74
+ failedCount: 0,
75
+ status: 'active',
76
+ expiresAt: data.expiresAt,
77
+ metadata: data.metadata,
78
+ };
79
+ const stmt = this.db.prepare(`
80
+ INSERT INTO subscriptions (
81
+ id, endpoint, keys, user_id, created_at, updated_at,
82
+ last_used_at, failed_count, status, expires_at, metadata
83
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
84
+ `);
85
+ stmt.run(subscription.id, subscription.endpoint, JSON.stringify(subscription.keys), subscription.userId ?? null, now, now, null, subscription.failedCount, subscription.status, subscription.expiresAt ? subscription.expiresAt.getTime() : null, subscription.metadata ? JSON.stringify(subscription.metadata) : null);
86
+ return subscription;
87
+ }
88
+ catch (error) {
89
+ throw new push_core_1.StorageError(`Failed to create subscription: ${error instanceof Error ? error.message : String(error)}`, {
90
+ operation: 'createSubscription',
91
+ endpoint: data.endpoint,
92
+ originalError: error instanceof Error ? error.message : String(error),
93
+ });
94
+ }
95
+ }
96
+ async getSubscriptionById(id) {
97
+ this.ensureNotClosed();
98
+ try {
99
+ const stmt = this.db.prepare(`
100
+ SELECT * FROM subscriptions WHERE id = ?
101
+ `);
102
+ const row = stmt.get(id);
103
+ if (!row) {
104
+ return null;
105
+ }
106
+ return this.rowToSubscription(row);
107
+ }
108
+ catch (error) {
109
+ throw new push_core_1.StorageError(`Failed to get subscription by id: ${error instanceof Error ? error.message : String(error)}`, {
110
+ operation: 'getSubscriptionById',
111
+ subscriptionId: id,
112
+ originalError: error instanceof Error ? error.message : String(error),
113
+ });
114
+ }
115
+ }
116
+ async findSubscriptions(filter) {
117
+ this.ensureNotClosed();
118
+ try {
119
+ const conditions = [];
120
+ const params = [];
121
+ if (filter.userId !== undefined) {
122
+ conditions.push('user_id = ?');
123
+ params.push(filter.userId);
124
+ }
125
+ if (filter.status !== undefined) {
126
+ conditions.push('status = ?');
127
+ params.push(filter.status);
128
+ }
129
+ if (filter.ids !== undefined && filter.ids.length > 0) {
130
+ const placeholders = filter.ids.map(() => '?').join(', ');
131
+ conditions.push(`id IN (${placeholders})`);
132
+ params.push(...filter.ids);
133
+ }
134
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
135
+ const stmt = this.db.prepare(`
136
+ SELECT * FROM subscriptions ${whereClause}
137
+ `);
138
+ const rows = stmt.all(...params);
139
+ return rows.map((row) => this.rowToSubscription(row));
140
+ }
141
+ catch (error) {
142
+ throw new push_core_1.StorageError(`Failed to find subscriptions: ${error instanceof Error ? error.message : String(error)}`, {
143
+ operation: 'findSubscriptions',
144
+ filter,
145
+ originalError: error instanceof Error ? error.message : String(error),
146
+ });
147
+ }
148
+ }
149
+ async updateSubscription(id, updates) {
150
+ this.ensureNotClosed();
151
+ try {
152
+ const current = await this.getSubscriptionById(id);
153
+ if (!current) {
154
+ throw new push_core_1.StorageError(`Subscription not found: ${id}`, {
155
+ operation: 'updateSubscription',
156
+ subscriptionId: id,
157
+ });
158
+ }
159
+ const setClauses = [];
160
+ const params = [];
161
+ setClauses.push('updated_at = ?');
162
+ params.push(Date.now());
163
+ if (updates.endpoint !== undefined) {
164
+ setClauses.push('endpoint = ?');
165
+ params.push(updates.endpoint);
166
+ }
167
+ if (updates.keys !== undefined) {
168
+ setClauses.push('keys = ?');
169
+ params.push(JSON.stringify(updates.keys));
170
+ }
171
+ if (updates.userId !== undefined) {
172
+ setClauses.push('user_id = ?');
173
+ params.push(updates.userId);
174
+ }
175
+ if (updates.lastUsedAt !== undefined) {
176
+ setClauses.push('last_used_at = ?');
177
+ params.push(updates.lastUsedAt ? updates.lastUsedAt.getTime() : null);
178
+ }
179
+ if (updates.failedCount !== undefined) {
180
+ setClauses.push('failed_count = ?');
181
+ params.push(updates.failedCount);
182
+ }
183
+ if (updates.status !== undefined) {
184
+ setClauses.push('status = ?');
185
+ params.push(updates.status);
186
+ }
187
+ if (updates.expiresAt !== undefined) {
188
+ setClauses.push('expires_at = ?');
189
+ params.push(updates.expiresAt ? updates.expiresAt.getTime() : null);
190
+ }
191
+ if (updates.metadata !== undefined) {
192
+ setClauses.push('metadata = ?');
193
+ params.push(updates.metadata ? JSON.stringify(updates.metadata) : null);
194
+ }
195
+ params.push(id);
196
+ const stmt = this.db.prepare(`
197
+ UPDATE subscriptions
198
+ SET ${setClauses.join(', ')}
199
+ WHERE id = ?
200
+ `);
201
+ stmt.run(...params);
202
+ const updated = await this.getSubscriptionById(id);
203
+ if (!updated) {
204
+ throw new push_core_1.StorageError(`Failed to retrieve updated subscription: ${id}`, {
205
+ operation: 'updateSubscription',
206
+ subscriptionId: id,
207
+ });
208
+ }
209
+ return updated;
210
+ }
211
+ catch (error) {
212
+ if (error instanceof push_core_1.StorageError) {
213
+ throw error;
214
+ }
215
+ throw new push_core_1.StorageError(`Failed to update subscription: ${error instanceof Error ? error.message : String(error)}`, {
216
+ operation: 'updateSubscription',
217
+ subscriptionId: id,
218
+ updates,
219
+ originalError: error instanceof Error ? error.message : String(error),
220
+ });
221
+ }
222
+ }
223
+ async deleteSubscription(id) {
224
+ this.ensureNotClosed();
225
+ try {
226
+ const stmt = this.db.prepare(`
227
+ DELETE FROM subscriptions WHERE id = ?
228
+ `);
229
+ stmt.run(id);
230
+ }
231
+ catch (error) {
232
+ throw new push_core_1.StorageError(`Failed to delete subscription: ${error instanceof Error ? error.message : String(error)}`, {
233
+ operation: 'deleteSubscription',
234
+ subscriptionId: id,
235
+ originalError: error instanceof Error ? error.message : String(error),
236
+ });
237
+ }
238
+ }
239
+ async enqueueRetry(retry) {
240
+ this.ensureNotClosed();
241
+ try {
242
+ const stmt = this.db.prepare(`
243
+ INSERT INTO retry_queue (
244
+ id, subscription_id, payload, attempt, next_retry_at, last_error, created_at
245
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
246
+ `);
247
+ stmt.run(retry.id, retry.subscriptionId, JSON.stringify(retry.payload), retry.attempt, retry.nextRetryAt.getTime(), retry.lastError ?? null, retry.createdAt.getTime());
248
+ }
249
+ catch (error) {
250
+ throw new push_core_1.StorageError(`Failed to enqueue retry: ${error instanceof Error ? error.message : String(error)}`, {
251
+ operation: 'enqueueRetry',
252
+ retryId: retry.id,
253
+ subscriptionId: retry.subscriptionId,
254
+ originalError: error instanceof Error ? error.message : String(error),
255
+ });
256
+ }
257
+ }
258
+ async dequeueRetry(limit) {
259
+ this.ensureNotClosed();
260
+ try {
261
+ const now = Date.now();
262
+ const stmt = this.db.prepare(`
263
+ SELECT * FROM retry_queue
264
+ WHERE next_retry_at <= ?
265
+ ORDER BY next_retry_at ASC
266
+ LIMIT ?
267
+ `);
268
+ const rows = stmt.all(now, limit);
269
+ return rows.map((row) => this.rowToRetryEntry(row));
270
+ }
271
+ catch (error) {
272
+ throw new push_core_1.StorageError(`Failed to dequeue retry: ${error instanceof Error ? error.message : String(error)}`, {
273
+ operation: 'dequeueRetry',
274
+ limit,
275
+ originalError: error instanceof Error ? error.message : String(error),
276
+ });
277
+ }
278
+ }
279
+ async ackRetry(retryId) {
280
+ this.ensureNotClosed();
281
+ try {
282
+ const stmt = this.db.prepare(`
283
+ DELETE FROM retry_queue WHERE id = ?
284
+ `);
285
+ stmt.run(retryId);
286
+ }
287
+ catch (error) {
288
+ throw new push_core_1.StorageError(`Failed to acknowledge retry: ${error instanceof Error ? error.message : String(error)}`, {
289
+ operation: 'ackRetry',
290
+ retryId,
291
+ originalError: error instanceof Error ? error.message : String(error),
292
+ });
293
+ }
294
+ }
295
+ async getQueueStats() {
296
+ this.ensureNotClosed();
297
+ try {
298
+ const now = Date.now();
299
+ const pendingStmt = this.db.prepare(`
300
+ SELECT COUNT(*) as count FROM retry_queue WHERE next_retry_at <= ?
301
+ `);
302
+ const pendingRow = pendingStmt.get(now);
303
+ const pending = pendingRow.count;
304
+ const processing = 0;
305
+ const failed = 0;
306
+ return {
307
+ pending,
308
+ processing,
309
+ failed,
310
+ };
311
+ }
312
+ catch (error) {
313
+ throw new push_core_1.StorageError(`Failed to get queue stats: ${error instanceof Error ? error.message : String(error)}`, {
314
+ operation: 'getQueueStats',
315
+ originalError: error instanceof Error ? error.message : String(error),
316
+ });
317
+ }
318
+ }
319
+ async close() {
320
+ if (!this.closed) {
321
+ this.db.close();
322
+ this.closed = true;
323
+ }
324
+ }
325
+ ensureNotClosed() {
326
+ if (this.closed) {
327
+ throw new push_core_1.StorageError('Database connection is closed', {
328
+ operation: 'ensureNotClosed',
329
+ });
330
+ }
331
+ }
332
+ rowToSubscription(row) {
333
+ return {
334
+ id: row.id,
335
+ endpoint: row.endpoint,
336
+ keys: JSON.parse(row.keys),
337
+ userId: row.user_id ?? undefined,
338
+ createdAt: new Date(row.created_at),
339
+ updatedAt: new Date(row.updated_at),
340
+ lastUsedAt: row.last_used_at ? new Date(row.last_used_at) : undefined,
341
+ failedCount: row.failed_count,
342
+ status: row.status,
343
+ expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,
344
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
345
+ };
346
+ }
347
+ rowToRetryEntry(row) {
348
+ return {
349
+ id: row.id,
350
+ subscriptionId: row.subscription_id,
351
+ payload: JSON.parse(row.payload),
352
+ attempt: row.attempt,
353
+ nextRetryAt: new Date(row.next_retry_at),
354
+ lastError: row.last_error ?? undefined,
355
+ createdAt: new Date(row.created_at),
356
+ };
357
+ }
358
+ }
359
+ exports.SQLiteStorageAdapter = SQLiteStorageAdapter;
360
+ exports.version = '1.0.0';
361
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,354 @@
1
+ import Database from 'better-sqlite3';
2
+ import { StorageError, } from '@allmightypush/push-core';
3
+ import { randomUUID } from 'crypto';
4
+ export class SQLiteStorageAdapter {
5
+ constructor(options) {
6
+ this.closed = false;
7
+ this.db = new Database(options.filename);
8
+ if (options.enableWAL !== false) {
9
+ this.db.pragma('journal_mode = WAL');
10
+ }
11
+ if (options.autoMigrate !== false) {
12
+ this.migrateSync();
13
+ }
14
+ }
15
+ migrateSync() {
16
+ this.db.exec(`
17
+ CREATE TABLE IF NOT EXISTS subscriptions (
18
+ id TEXT PRIMARY KEY,
19
+ endpoint TEXT NOT NULL,
20
+ keys TEXT NOT NULL,
21
+ user_id TEXT,
22
+ created_at INTEGER NOT NULL,
23
+ updated_at INTEGER NOT NULL,
24
+ last_used_at INTEGER,
25
+ failed_count INTEGER NOT NULL DEFAULT 0,
26
+ status TEXT NOT NULL CHECK(status IN ('active', 'blocked', 'expired')),
27
+ expires_at INTEGER,
28
+ metadata TEXT
29
+ )
30
+ `);
31
+ this.db.exec(`
32
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_user_id ON subscriptions(user_id)
33
+ `);
34
+ this.db.exec(`
35
+ CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status)
36
+ `);
37
+ this.db.exec(`
38
+ CREATE TABLE IF NOT EXISTS retry_queue (
39
+ id TEXT PRIMARY KEY,
40
+ subscription_id TEXT NOT NULL,
41
+ payload TEXT NOT NULL,
42
+ attempt INTEGER NOT NULL,
43
+ next_retry_at INTEGER NOT NULL,
44
+ last_error TEXT,
45
+ created_at INTEGER NOT NULL,
46
+ FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE
47
+ )
48
+ `);
49
+ this.db.exec(`
50
+ CREATE INDEX IF NOT EXISTS idx_retry_queue_next_retry ON retry_queue(next_retry_at)
51
+ `);
52
+ }
53
+ async migrate() {
54
+ this.migrateSync();
55
+ }
56
+ async createSubscription(data) {
57
+ this.ensureNotClosed();
58
+ try {
59
+ const id = randomUUID();
60
+ const now = Date.now();
61
+ const subscription = {
62
+ id,
63
+ endpoint: data.endpoint,
64
+ keys: data.keys,
65
+ userId: data.userId,
66
+ createdAt: new Date(now),
67
+ updatedAt: new Date(now),
68
+ failedCount: 0,
69
+ status: 'active',
70
+ expiresAt: data.expiresAt,
71
+ metadata: data.metadata,
72
+ };
73
+ const stmt = this.db.prepare(`
74
+ INSERT INTO subscriptions (
75
+ id, endpoint, keys, user_id, created_at, updated_at,
76
+ last_used_at, failed_count, status, expires_at, metadata
77
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
78
+ `);
79
+ stmt.run(subscription.id, subscription.endpoint, JSON.stringify(subscription.keys), subscription.userId ?? null, now, now, null, subscription.failedCount, subscription.status, subscription.expiresAt ? subscription.expiresAt.getTime() : null, subscription.metadata ? JSON.stringify(subscription.metadata) : null);
80
+ return subscription;
81
+ }
82
+ catch (error) {
83
+ throw new StorageError(`Failed to create subscription: ${error instanceof Error ? error.message : String(error)}`, {
84
+ operation: 'createSubscription',
85
+ endpoint: data.endpoint,
86
+ originalError: error instanceof Error ? error.message : String(error),
87
+ });
88
+ }
89
+ }
90
+ async getSubscriptionById(id) {
91
+ this.ensureNotClosed();
92
+ try {
93
+ const stmt = this.db.prepare(`
94
+ SELECT * FROM subscriptions WHERE id = ?
95
+ `);
96
+ const row = stmt.get(id);
97
+ if (!row) {
98
+ return null;
99
+ }
100
+ return this.rowToSubscription(row);
101
+ }
102
+ catch (error) {
103
+ throw new StorageError(`Failed to get subscription by id: ${error instanceof Error ? error.message : String(error)}`, {
104
+ operation: 'getSubscriptionById',
105
+ subscriptionId: id,
106
+ originalError: error instanceof Error ? error.message : String(error),
107
+ });
108
+ }
109
+ }
110
+ async findSubscriptions(filter) {
111
+ this.ensureNotClosed();
112
+ try {
113
+ const conditions = [];
114
+ const params = [];
115
+ if (filter.userId !== undefined) {
116
+ conditions.push('user_id = ?');
117
+ params.push(filter.userId);
118
+ }
119
+ if (filter.status !== undefined) {
120
+ conditions.push('status = ?');
121
+ params.push(filter.status);
122
+ }
123
+ if (filter.ids !== undefined && filter.ids.length > 0) {
124
+ const placeholders = filter.ids.map(() => '?').join(', ');
125
+ conditions.push(`id IN (${placeholders})`);
126
+ params.push(...filter.ids);
127
+ }
128
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
129
+ const stmt = this.db.prepare(`
130
+ SELECT * FROM subscriptions ${whereClause}
131
+ `);
132
+ const rows = stmt.all(...params);
133
+ return rows.map((row) => this.rowToSubscription(row));
134
+ }
135
+ catch (error) {
136
+ throw new StorageError(`Failed to find subscriptions: ${error instanceof Error ? error.message : String(error)}`, {
137
+ operation: 'findSubscriptions',
138
+ filter,
139
+ originalError: error instanceof Error ? error.message : String(error),
140
+ });
141
+ }
142
+ }
143
+ async updateSubscription(id, updates) {
144
+ this.ensureNotClosed();
145
+ try {
146
+ const current = await this.getSubscriptionById(id);
147
+ if (!current) {
148
+ throw new StorageError(`Subscription not found: ${id}`, {
149
+ operation: 'updateSubscription',
150
+ subscriptionId: id,
151
+ });
152
+ }
153
+ const setClauses = [];
154
+ const params = [];
155
+ setClauses.push('updated_at = ?');
156
+ params.push(Date.now());
157
+ if (updates.endpoint !== undefined) {
158
+ setClauses.push('endpoint = ?');
159
+ params.push(updates.endpoint);
160
+ }
161
+ if (updates.keys !== undefined) {
162
+ setClauses.push('keys = ?');
163
+ params.push(JSON.stringify(updates.keys));
164
+ }
165
+ if (updates.userId !== undefined) {
166
+ setClauses.push('user_id = ?');
167
+ params.push(updates.userId);
168
+ }
169
+ if (updates.lastUsedAt !== undefined) {
170
+ setClauses.push('last_used_at = ?');
171
+ params.push(updates.lastUsedAt ? updates.lastUsedAt.getTime() : null);
172
+ }
173
+ if (updates.failedCount !== undefined) {
174
+ setClauses.push('failed_count = ?');
175
+ params.push(updates.failedCount);
176
+ }
177
+ if (updates.status !== undefined) {
178
+ setClauses.push('status = ?');
179
+ params.push(updates.status);
180
+ }
181
+ if (updates.expiresAt !== undefined) {
182
+ setClauses.push('expires_at = ?');
183
+ params.push(updates.expiresAt ? updates.expiresAt.getTime() : null);
184
+ }
185
+ if (updates.metadata !== undefined) {
186
+ setClauses.push('metadata = ?');
187
+ params.push(updates.metadata ? JSON.stringify(updates.metadata) : null);
188
+ }
189
+ params.push(id);
190
+ const stmt = this.db.prepare(`
191
+ UPDATE subscriptions
192
+ SET ${setClauses.join(', ')}
193
+ WHERE id = ?
194
+ `);
195
+ stmt.run(...params);
196
+ const updated = await this.getSubscriptionById(id);
197
+ if (!updated) {
198
+ throw new StorageError(`Failed to retrieve updated subscription: ${id}`, {
199
+ operation: 'updateSubscription',
200
+ subscriptionId: id,
201
+ });
202
+ }
203
+ return updated;
204
+ }
205
+ catch (error) {
206
+ if (error instanceof StorageError) {
207
+ throw error;
208
+ }
209
+ throw new StorageError(`Failed to update subscription: ${error instanceof Error ? error.message : String(error)}`, {
210
+ operation: 'updateSubscription',
211
+ subscriptionId: id,
212
+ updates,
213
+ originalError: error instanceof Error ? error.message : String(error),
214
+ });
215
+ }
216
+ }
217
+ async deleteSubscription(id) {
218
+ this.ensureNotClosed();
219
+ try {
220
+ const stmt = this.db.prepare(`
221
+ DELETE FROM subscriptions WHERE id = ?
222
+ `);
223
+ stmt.run(id);
224
+ }
225
+ catch (error) {
226
+ throw new StorageError(`Failed to delete subscription: ${error instanceof Error ? error.message : String(error)}`, {
227
+ operation: 'deleteSubscription',
228
+ subscriptionId: id,
229
+ originalError: error instanceof Error ? error.message : String(error),
230
+ });
231
+ }
232
+ }
233
+ async enqueueRetry(retry) {
234
+ this.ensureNotClosed();
235
+ try {
236
+ const stmt = this.db.prepare(`
237
+ INSERT INTO retry_queue (
238
+ id, subscription_id, payload, attempt, next_retry_at, last_error, created_at
239
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
240
+ `);
241
+ stmt.run(retry.id, retry.subscriptionId, JSON.stringify(retry.payload), retry.attempt, retry.nextRetryAt.getTime(), retry.lastError ?? null, retry.createdAt.getTime());
242
+ }
243
+ catch (error) {
244
+ throw new StorageError(`Failed to enqueue retry: ${error instanceof Error ? error.message : String(error)}`, {
245
+ operation: 'enqueueRetry',
246
+ retryId: retry.id,
247
+ subscriptionId: retry.subscriptionId,
248
+ originalError: error instanceof Error ? error.message : String(error),
249
+ });
250
+ }
251
+ }
252
+ async dequeueRetry(limit) {
253
+ this.ensureNotClosed();
254
+ try {
255
+ const now = Date.now();
256
+ const stmt = this.db.prepare(`
257
+ SELECT * FROM retry_queue
258
+ WHERE next_retry_at <= ?
259
+ ORDER BY next_retry_at ASC
260
+ LIMIT ?
261
+ `);
262
+ const rows = stmt.all(now, limit);
263
+ return rows.map((row) => this.rowToRetryEntry(row));
264
+ }
265
+ catch (error) {
266
+ throw new StorageError(`Failed to dequeue retry: ${error instanceof Error ? error.message : String(error)}`, {
267
+ operation: 'dequeueRetry',
268
+ limit,
269
+ originalError: error instanceof Error ? error.message : String(error),
270
+ });
271
+ }
272
+ }
273
+ async ackRetry(retryId) {
274
+ this.ensureNotClosed();
275
+ try {
276
+ const stmt = this.db.prepare(`
277
+ DELETE FROM retry_queue WHERE id = ?
278
+ `);
279
+ stmt.run(retryId);
280
+ }
281
+ catch (error) {
282
+ throw new StorageError(`Failed to acknowledge retry: ${error instanceof Error ? error.message : String(error)}`, {
283
+ operation: 'ackRetry',
284
+ retryId,
285
+ originalError: error instanceof Error ? error.message : String(error),
286
+ });
287
+ }
288
+ }
289
+ async getQueueStats() {
290
+ this.ensureNotClosed();
291
+ try {
292
+ const now = Date.now();
293
+ const pendingStmt = this.db.prepare(`
294
+ SELECT COUNT(*) as count FROM retry_queue WHERE next_retry_at <= ?
295
+ `);
296
+ const pendingRow = pendingStmt.get(now);
297
+ const pending = pendingRow.count;
298
+ const processing = 0;
299
+ const failed = 0;
300
+ return {
301
+ pending,
302
+ processing,
303
+ failed,
304
+ };
305
+ }
306
+ catch (error) {
307
+ throw new StorageError(`Failed to get queue stats: ${error instanceof Error ? error.message : String(error)}`, {
308
+ operation: 'getQueueStats',
309
+ originalError: error instanceof Error ? error.message : String(error),
310
+ });
311
+ }
312
+ }
313
+ async close() {
314
+ if (!this.closed) {
315
+ this.db.close();
316
+ this.closed = true;
317
+ }
318
+ }
319
+ ensureNotClosed() {
320
+ if (this.closed) {
321
+ throw new StorageError('Database connection is closed', {
322
+ operation: 'ensureNotClosed',
323
+ });
324
+ }
325
+ }
326
+ rowToSubscription(row) {
327
+ return {
328
+ id: row.id,
329
+ endpoint: row.endpoint,
330
+ keys: JSON.parse(row.keys),
331
+ userId: row.user_id ?? undefined,
332
+ createdAt: new Date(row.created_at),
333
+ updatedAt: new Date(row.updated_at),
334
+ lastUsedAt: row.last_used_at ? new Date(row.last_used_at) : undefined,
335
+ failedCount: row.failed_count,
336
+ status: row.status,
337
+ expiresAt: row.expires_at ? new Date(row.expires_at) : undefined,
338
+ metadata: row.metadata ? JSON.parse(row.metadata) : undefined,
339
+ };
340
+ }
341
+ rowToRetryEntry(row) {
342
+ return {
343
+ id: row.id,
344
+ subscriptionId: row.subscription_id,
345
+ payload: JSON.parse(row.payload),
346
+ attempt: row.attempt,
347
+ nextRetryAt: new Date(row.next_retry_at),
348
+ lastError: row.last_error ?? undefined,
349
+ createdAt: new Date(row.created_at),
350
+ };
351
+ }
352
+ }
353
+ export const version = '1.0.0';
354
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { StorageAdapter, Subscription, CreateSubscriptionData, SubscriptionFilter, RetryEntry, QueueStats } from '@allmightypush/push-core';
2
+ export interface SQLiteStorageOptions {
3
+ filename: string;
4
+ enableWAL?: boolean;
5
+ autoMigrate?: boolean;
6
+ }
7
+ export declare class SQLiteStorageAdapter implements StorageAdapter {
8
+ private db;
9
+ private closed;
10
+ constructor(options: SQLiteStorageOptions);
11
+ private migrateSync;
12
+ migrate(): Promise<void>;
13
+ createSubscription(data: CreateSubscriptionData): Promise<Subscription>;
14
+ getSubscriptionById(id: string): Promise<Subscription | null>;
15
+ findSubscriptions(filter: SubscriptionFilter): Promise<Subscription[]>;
16
+ updateSubscription(id: string, updates: Partial<Subscription>): Promise<Subscription>;
17
+ deleteSubscription(id: string): Promise<void>;
18
+ enqueueRetry(retry: RetryEntry): Promise<void>;
19
+ dequeueRetry(limit: number): Promise<RetryEntry[]>;
20
+ ackRetry(retryId: string): Promise<void>;
21
+ getQueueStats(): Promise<QueueStats>;
22
+ close(): Promise<void>;
23
+ private ensureNotClosed;
24
+ private rowToSubscription;
25
+ private rowToRetryEntry;
26
+ }
27
+ export declare const version = "1.0.0";
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,cAAc,EACd,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,UAAU,EACV,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,oBAAoB;IAEnC,QAAQ,EAAE,MAAM,CAAC;IAEjB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAKD,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAkB;gBAEpB,OAAO,EAAE,oBAAoB;IAiBzC,OAAO,CAAC,WAAW;IAkDb,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAMxB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC;IAsDvE,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA2B7D,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA4CtE,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAoGrF,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB7C,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAgC9C,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IA4BlD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxC,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IAwCpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,eAAe;CAWxB;AAGD,eAAO,MAAM,OAAO,UAAU,CAAC"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@allmightypush/push-storage-sqlite",
3
+ "version": "1.0.0",
4
+ "description": "SQLite storage adapter for push notification library",
5
+ "main": "dist/cjs/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "require": "./dist/cjs/index.js",
11
+ "import": "./dist/esm/index.js",
12
+ "types": "./dist/types/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "npm run build:cjs && npm run build:esm && npm run build:types",
20
+ "build:cjs": "tsc -p tsconfig.cjs.json",
21
+ "build:esm": "tsc -p tsconfig.esm.json",
22
+ "build:types": "tsc -p tsconfig.types.json",
23
+ "test": "jest --passWithNoTests",
24
+ "test:watch": "jest --watch",
25
+ "test:coverage": "jest --coverage --passWithNoTests",
26
+ "clean": "rm -rf dist"
27
+ },
28
+ "keywords": [
29
+ "push",
30
+ "notification",
31
+ "storage",
32
+ "sqlite"
33
+ ],
34
+ "author": "Samtes64",
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/Samtes64/all-mighty-push.git",
39
+ "directory": "packages/push-storage-sqlite"
40
+ },
41
+ "bugs": {
42
+ "url": "https://github.com/Samtes64/all-mighty-push/issues"
43
+ },
44
+ "homepage": "https://github.com/Samtes64/all-mighty-push/tree/main/packages/push-storage-sqlite#readme",
45
+ "dependencies": {
46
+ "@allmightypush/push-core": "^1.0.0",
47
+ "better-sqlite3": "^9.2.2"
48
+ },
49
+ "devDependencies": {
50
+ "@types/better-sqlite3": "^7.6.8"
51
+ },
52
+ "engines": {
53
+ "node": ">=16.0.0"
54
+ }
55
+ }