@framers/sql-storage-adapter 0.7.1 → 0.7.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 +43 -0
- package/dist/adapters/electron/preload.cjs +289 -0
- package/dist/adapters/electron/renderer.d.ts +9 -0
- package/dist/adapters/electron/renderer.d.ts.map +1 -0
- package/dist/adapters/electron/renderer.js +8 -0
- package/dist/adapters/electron/renderer.js.map +1 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.d.ts +2 -0
- package/dist/cjs/adapters/__tests__/indexedDbAdapter.spec.js +133 -0
- package/dist/cjs/adapters/baseStorageAdapter.d.ts +368 -0
- package/dist/cjs/adapters/baseStorageAdapter.js +744 -0
- package/dist/cjs/adapters/betterSqliteAdapter.d.ts +124 -0
- package/dist/cjs/adapters/betterSqliteAdapter.js +334 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.d.ts +83 -0
- package/dist/cjs/adapters/capacitorSqliteAdapter.js +250 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.d.ts +251 -0
- package/dist/cjs/adapters/electron/electronMainAdapter.js +392 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.d.ts +177 -0
- package/dist/cjs/adapters/electron/electronRendererAdapter.js +283 -0
- package/dist/cjs/adapters/electron/index.d.ts +74 -0
- package/dist/cjs/adapters/electron/index.js +86 -0
- package/dist/cjs/adapters/electron/ipc/channels.d.ts +196 -0
- package/dist/cjs/adapters/electron/ipc/channels.js +127 -0
- package/dist/cjs/adapters/electron/ipc/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/ipc/index.js +38 -0
- package/dist/cjs/adapters/electron/ipc/protocol.d.ts +78 -0
- package/dist/cjs/adapters/electron/ipc/protocol.js +341 -0
- package/dist/cjs/adapters/electron/ipc/types.d.ts +248 -0
- package/dist/cjs/adapters/electron/ipc/types.js +15 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.d.ts +184 -0
- package/dist/cjs/adapters/electron/migration/autoMigrator.js +441 -0
- package/dist/cjs/adapters/electron/migration/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/migration/index.js +29 -0
- package/dist/cjs/adapters/electron/preload.d.ts +126 -0
- package/dist/cjs/adapters/electron/preload.js +233 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.d.ts +214 -0
- package/dist/cjs/adapters/electron/recovery/corruptionDetector.js +359 -0
- package/dist/cjs/adapters/electron/recovery/index.d.ts +11 -0
- package/dist/cjs/adapters/electron/recovery/index.js +34 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.d.ts +186 -0
- package/dist/cjs/adapters/electron/recovery/walCheckpoint.js +263 -0
- package/dist/cjs/adapters/electron/renderer.d.ts +9 -0
- package/dist/cjs/adapters/electron/renderer.js +33 -0
- package/dist/cjs/adapters/electron/window/index.d.ts +9 -0
- package/dist/cjs/adapters/electron/window/index.js +29 -0
- package/dist/cjs/adapters/electron/window/windowManager.d.ts +190 -0
- package/dist/cjs/adapters/electron/window/windowManager.js +321 -0
- package/dist/cjs/adapters/indexedDbAdapter.d.ts +490 -0
- package/dist/cjs/adapters/indexedDbAdapter.js +993 -0
- package/dist/cjs/adapters/postgresAdapter.d.ts +424 -0
- package/dist/cjs/adapters/postgresAdapter.js +889 -0
- package/dist/cjs/adapters/sqlJsAdapter.d.ts +64 -0
- package/dist/cjs/adapters/sqlJsAdapter.js +268 -0
- package/dist/cjs/adapters/supabase.d.ts +58 -0
- package/dist/cjs/adapters/supabase.js +401 -0
- package/dist/cjs/codecs/BrowserBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/BrowserBlobCodec.js +57 -0
- package/dist/cjs/codecs/NodeBlobCodec.d.ts +14 -0
- package/dist/cjs/codecs/NodeBlobCodec.js +59 -0
- package/dist/cjs/core/contracts/blobCodec.d.ts +15 -0
- package/dist/cjs/core/contracts/blobCodec.js +15 -0
- package/dist/cjs/core/contracts/context.d.ts +221 -0
- package/dist/cjs/core/contracts/context.js +15 -0
- package/dist/cjs/core/contracts/dialect.d.ts +154 -0
- package/dist/cjs/core/contracts/dialect.js +15 -0
- package/dist/cjs/core/contracts/events.d.ts +225 -0
- package/dist/cjs/core/contracts/events.js +15 -0
- package/dist/cjs/core/contracts/exporter.d.ts +13 -0
- package/dist/cjs/core/contracts/exporter.js +15 -0
- package/dist/cjs/core/contracts/extensions.d.ts +73 -0
- package/dist/cjs/core/contracts/extensions.js +15 -0
- package/dist/cjs/core/contracts/features.d.ts +25 -0
- package/dist/cjs/core/contracts/features.js +61 -0
- package/dist/cjs/core/contracts/fts.d.ts +66 -0
- package/dist/cjs/core/contracts/fts.js +15 -0
- package/dist/cjs/core/contracts/hooks.d.ts +481 -0
- package/dist/cjs/core/contracts/hooks.js +140 -0
- package/dist/cjs/core/contracts/index.d.ts +260 -0
- package/dist/cjs/core/contracts/index.js +41 -0
- package/dist/cjs/core/contracts/limitations.d.ts +46 -0
- package/dist/cjs/core/contracts/limitations.js +218 -0
- package/dist/cjs/core/contracts/performance.d.ts +308 -0
- package/dist/cjs/core/contracts/performance.js +144 -0
- package/dist/cjs/core/database.d.ts +220 -0
- package/dist/cjs/core/database.js +136 -0
- package/dist/cjs/core/portable.d.ts +23 -0
- package/dist/cjs/core/portable.js +66 -0
- package/dist/cjs/core/resolver.d.ts +77 -0
- package/dist/cjs/core/resolver.js +235 -0
- package/dist/cjs/dialects/PostgresDialect.d.ts +35 -0
- package/dist/cjs/dialects/PostgresDialect.js +143 -0
- package/dist/cjs/dialects/SqliteDialect.d.ts +35 -0
- package/dist/cjs/dialects/SqliteDialect.js +142 -0
- package/dist/cjs/dialects/shared.d.ts +17 -0
- package/dist/cjs/dialects/shared.js +90 -0
- package/dist/cjs/exporters/PostgresExporter.d.ts +14 -0
- package/dist/cjs/exporters/PostgresExporter.js +61 -0
- package/dist/cjs/exporters/SqliteFileExporter.d.ts +16 -0
- package/dist/cjs/exporters/SqliteFileExporter.js +43 -0
- package/dist/cjs/features/backup/cloudBackup.d.ts +219 -0
- package/dist/cjs/features/backup/cloudBackup.js +209 -0
- package/dist/cjs/features/kv/idb.d.ts +79 -0
- package/dist/cjs/features/kv/idb.js +32 -0
- package/dist/cjs/features/kv/index.d.ts +14 -0
- package/dist/cjs/features/kv/index.js +40 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.d.ts +77 -0
- package/dist/cjs/features/kv/indexedDbKeyValueStore.js +116 -0
- package/dist/cjs/features/kv/keyValueStore.d.ts +48 -0
- package/dist/cjs/features/kv/keyValueStore.js +67 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.d.ts +34 -0
- package/dist/cjs/features/kv/sqlKeyValueStore.js +81 -0
- package/dist/cjs/features/kv/valueCodec.d.ts +35 -0
- package/dist/cjs/features/kv/valueCodec.js +426 -0
- package/dist/cjs/features/migrations/dataExport.d.ts +77 -0
- package/dist/cjs/features/migrations/dataExport.js +194 -0
- package/dist/cjs/features/migrations/dataImport.d.ts +54 -0
- package/dist/cjs/features/migrations/dataImport.js +300 -0
- package/dist/cjs/features/migrations/migration.d.ts +89 -0
- package/dist/cjs/features/migrations/migration.js +187 -0
- package/dist/cjs/features/migrations/schemaMigrations.d.ts +93 -0
- package/dist/cjs/features/migrations/schemaMigrations.js +220 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.d.ts +222 -0
- package/dist/cjs/features/sync/conflicts/conflictResolver.js +366 -0
- package/dist/cjs/features/sync/conflicts/index.d.ts +9 -0
- package/dist/cjs/features/sync/conflicts/index.js +21 -0
- package/dist/cjs/features/sync/crossPlatformSync.d.ts +281 -0
- package/dist/cjs/features/sync/crossPlatformSync.js +551 -0
- package/dist/cjs/features/sync/devices/deviceManager.d.ts +243 -0
- package/dist/cjs/features/sync/devices/deviceManager.js +450 -0
- package/dist/cjs/features/sync/devices/index.d.ts +10 -0
- package/dist/cjs/features/sync/devices/index.js +21 -0
- package/dist/cjs/features/sync/index.d.ts +37 -0
- package/dist/cjs/features/sync/index.js +111 -0
- package/dist/cjs/features/sync/protocol/index.d.ts +11 -0
- package/dist/cjs/features/sync/protocol/index.js +23 -0
- package/dist/cjs/features/sync/protocol/messages.d.ts +348 -0
- package/dist/cjs/features/sync/protocol/messages.js +215 -0
- package/dist/cjs/features/sync/protocol/vectorClock.d.ts +164 -0
- package/dist/cjs/features/sync/protocol/vectorClock.js +256 -0
- package/dist/cjs/features/sync/syncManager.d.ts +348 -0
- package/dist/cjs/features/sync/syncManager.js +455 -0
- package/dist/cjs/features/sync/tables/index.d.ts +10 -0
- package/dist/cjs/features/sync/tables/index.js +21 -0
- package/dist/cjs/features/sync/tables/syncLogManager.d.ts +216 -0
- package/dist/cjs/features/sync/tables/syncLogManager.js +423 -0
- package/dist/cjs/features/sync/transport/httpTransport.d.ts +123 -0
- package/dist/cjs/features/sync/transport/httpTransport.js +346 -0
- package/dist/cjs/features/sync/transport/index.d.ts +12 -0
- package/dist/cjs/features/sync/transport/index.js +25 -0
- package/dist/cjs/features/sync/transport/transport.d.ts +259 -0
- package/dist/cjs/features/sync/transport/transport.js +163 -0
- package/dist/cjs/features/sync/transport/websocketTransport.d.ts +126 -0
- package/dist/cjs/features/sync/transport/websocketTransport.js +342 -0
- package/dist/cjs/fts/PostgresFts.d.ts +29 -0
- package/dist/cjs/fts/PostgresFts.js +77 -0
- package/dist/cjs/fts/SqliteFts5.d.ts +22 -0
- package/dist/cjs/fts/SqliteFts5.js +58 -0
- package/dist/cjs/index.d.ts +30 -0
- package/dist/cjs/index.js +101 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/shared/connectionGate.d.ts +94 -0
- package/dist/cjs/shared/connectionGate.js +77 -0
- package/dist/cjs/shared/errors.d.ts +23 -0
- package/dist/cjs/shared/errors.js +45 -0
- package/dist/cjs/shared/logger.d.ts +26 -0
- package/dist/cjs/shared/logger.js +40 -0
- package/dist/cjs/shared/parameterUtils.d.ts +16 -0
- package/dist/cjs/shared/parameterUtils.js +59 -0
- package/dist/cjs/shared/postgresTarget.d.ts +11 -0
- package/dist/cjs/shared/postgresTarget.js +30 -0
- package/dist/cjs/shared/segment.d.ts +43 -0
- package/dist/cjs/shared/segment.js +63 -0
- package/dist/cjs/shared/serializedTransaction.d.ts +14 -0
- package/dist/cjs/shared/serializedTransaction.js +74 -0
- package/dist/cjs/shared/splitSqlStatements.d.ts +27 -0
- package/dist/cjs/shared/splitSqlStatements.js +163 -0
- package/dist/cjs/shared/sqlPlaceholders.d.ts +48 -0
- package/dist/cjs/shared/sqlPlaceholders.js +263 -0
- package/dist/cjs/types/index.d.ts +29 -0
- package/dist/cjs/types/index.js +33 -0
- package/dist/core/portable.d.ts +23 -0
- package/dist/core/portable.d.ts.map +1 -0
- package/dist/core/portable.js +23 -0
- package/dist/core/portable.js.map +1 -0
- package/dist/features/migrations/schemaMigrations.d.ts +93 -0
- package/dist/features/migrations/schemaMigrations.d.ts.map +1 -0
- package/dist/features/migrations/schemaMigrations.js +216 -0
- package/dist/features/migrations/schemaMigrations.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +139 -24
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud backup utilities for S3, R2, and other object storage providers.
|
|
3
|
+
*
|
|
4
|
+
* This module provides automatic scheduled backups and restore functionality
|
|
5
|
+
* for SQL databases using S3-compatible storage (AWS S3, Cloudflare R2, MinIO, etc.).
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Automatic scheduled backups with configurable intervals
|
|
9
|
+
* - Gzip compression to reduce storage costs
|
|
10
|
+
* - Retention policies (automatic cleanup of old backups)
|
|
11
|
+
* - JSON and SQL export formats
|
|
12
|
+
* - Manual backup/restore on demand
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { S3Client } from '@aws-sdk/client-s3';
|
|
17
|
+
* import { createCloudBackupManager } from '@framers/sql-storage-adapter';
|
|
18
|
+
*
|
|
19
|
+
* const s3Client = new S3Client({ region: 'us-east-1' });
|
|
20
|
+
* const manager = createCloudBackupManager(db, s3Client, 'my-backups', {
|
|
21
|
+
* interval: 3600000, // 1 hour
|
|
22
|
+
* maxBackups: 24,
|
|
23
|
+
* options: { compression: 'gzip', format: 'json' }
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* manager.start(); // Auto-schedule backups
|
|
27
|
+
* await manager.backupNow(); // Manual backup
|
|
28
|
+
* await manager.restore('backups/db-2024-01-15.json.gz');
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @module cloudBackup
|
|
32
|
+
*/
|
|
33
|
+
import type { StorageAdapter } from '../../core/contracts/index.js';
|
|
34
|
+
/** Supported backup export formats */
|
|
35
|
+
export type BackupFormat = 'json' | 'sql';
|
|
36
|
+
/** Supported compression algorithms */
|
|
37
|
+
export type CompressionType = 'gzip' | 'none';
|
|
38
|
+
/**
|
|
39
|
+
* Generic interface for cloud storage providers.
|
|
40
|
+
*
|
|
41
|
+
* Implement this interface to support custom storage backends
|
|
42
|
+
* beyond S3-compatible services.
|
|
43
|
+
*/
|
|
44
|
+
export interface CloudStorageProvider {
|
|
45
|
+
/**
|
|
46
|
+
* Upload data to cloud storage
|
|
47
|
+
* @param key - The storage key/path for the backup
|
|
48
|
+
* @param data - The backup data (string or Buffer)
|
|
49
|
+
*/
|
|
50
|
+
upload(key: string, data: string | Buffer): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Download data from cloud storage
|
|
53
|
+
* @param key - The storage key/path to download
|
|
54
|
+
* @returns The backup data
|
|
55
|
+
*/
|
|
56
|
+
download(key: string): Promise<string | Buffer>;
|
|
57
|
+
/**
|
|
58
|
+
* List available backups in cloud storage
|
|
59
|
+
* @param prefix - Optional prefix to filter backups
|
|
60
|
+
* @returns Array of backup keys
|
|
61
|
+
*/
|
|
62
|
+
list(prefix?: string): Promise<string[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Delete a backup from cloud storage
|
|
65
|
+
* @param key - The storage key/path to delete
|
|
66
|
+
*/
|
|
67
|
+
delete(key: string): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Configuration options for backup creation
|
|
71
|
+
*/
|
|
72
|
+
export interface BackupOptions {
|
|
73
|
+
/** Backup format (json or sql) - default: 'json' */
|
|
74
|
+
format?: BackupFormat;
|
|
75
|
+
/** Compression type - default: 'gzip' */
|
|
76
|
+
compression?: CompressionType;
|
|
77
|
+
/** Tables to include (undefined = all tables) */
|
|
78
|
+
tables?: string[];
|
|
79
|
+
/** Prefix for backup keys - default: 'backups/' */
|
|
80
|
+
prefix?: string;
|
|
81
|
+
/** Include timestamp in backup key - default: true */
|
|
82
|
+
includeTimestamp?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Configuration for automatic scheduled backups
|
|
86
|
+
*/
|
|
87
|
+
export interface ScheduledBackupConfig {
|
|
88
|
+
/** Backup interval in milliseconds (e.g., 3600000 = 1 hour) */
|
|
89
|
+
interval: number;
|
|
90
|
+
/** Maximum number of backups to keep (older backups auto-deleted) */
|
|
91
|
+
maxBackups?: number;
|
|
92
|
+
/** Backup creation options */
|
|
93
|
+
options?: BackupOptions;
|
|
94
|
+
/** Callback invoked on successful backup */
|
|
95
|
+
onSuccess?: (key: string) => void;
|
|
96
|
+
/** Callback invoked on backup error */
|
|
97
|
+
onError?: (error: Error) => void;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* S3-compatible cloud storage provider.
|
|
101
|
+
*
|
|
102
|
+
* Works with AWS S3, Cloudflare R2, MinIO, and other S3-compatible services.
|
|
103
|
+
* Uses the AWS SDK v3 for S3 operations.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* import { S3Client } from '@aws-sdk/client-s3';
|
|
108
|
+
*
|
|
109
|
+
* const s3Client = new S3Client({ region: 'us-east-1' });
|
|
110
|
+
* const provider = new S3StorageProvider(s3Client, 'my-bucket');
|
|
111
|
+
*
|
|
112
|
+
* await provider.upload('backups/test.json', JSON.stringify(data));
|
|
113
|
+
* const backups = await provider.list('backups/');
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare class S3StorageProvider implements CloudStorageProvider {
|
|
117
|
+
private client;
|
|
118
|
+
private bucket;
|
|
119
|
+
/**
|
|
120
|
+
* @param client - AWS SDK S3Client instance
|
|
121
|
+
* @param bucket - S3 bucket name
|
|
122
|
+
*/
|
|
123
|
+
constructor(client: {
|
|
124
|
+
send: (command: unknown) => Promise<unknown>;
|
|
125
|
+
}, bucket: string);
|
|
126
|
+
upload(key: string, data: string | Buffer): Promise<void>;
|
|
127
|
+
download(key: string): Promise<string>;
|
|
128
|
+
list(prefix?: string): Promise<string[]>;
|
|
129
|
+
delete(key: string): Promise<void>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Cloud backup manager for automatic scheduled backups.
|
|
133
|
+
*/
|
|
134
|
+
export declare class CloudBackupManager {
|
|
135
|
+
private adapter;
|
|
136
|
+
private storage;
|
|
137
|
+
private config;
|
|
138
|
+
private intervalId?;
|
|
139
|
+
constructor(adapter: StorageAdapter, storage: CloudStorageProvider, config: ScheduledBackupConfig);
|
|
140
|
+
/**
|
|
141
|
+
* Create a backup and upload to cloud storage.
|
|
142
|
+
*/
|
|
143
|
+
backup(options?: BackupOptions): Promise<string>;
|
|
144
|
+
/**
|
|
145
|
+
* Restore from a cloud backup.
|
|
146
|
+
*/
|
|
147
|
+
restore(key: string): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* List all backups in cloud storage.
|
|
150
|
+
*/
|
|
151
|
+
listBackups(prefix?: string): Promise<string[]>;
|
|
152
|
+
/**
|
|
153
|
+
* Delete old backups exceeding maxBackups limit.
|
|
154
|
+
*/
|
|
155
|
+
private cleanupOldBackups;
|
|
156
|
+
/**
|
|
157
|
+
* Start automatic scheduled backups.
|
|
158
|
+
*/
|
|
159
|
+
start(): void;
|
|
160
|
+
/**
|
|
161
|
+
* Stop automatic scheduled backups.
|
|
162
|
+
*/
|
|
163
|
+
stop(): void;
|
|
164
|
+
/**
|
|
165
|
+
* Perform a backup immediately (manual trigger).
|
|
166
|
+
*/
|
|
167
|
+
backupNow(options?: BackupOptions): Promise<string>;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a cloud backup manager with S3-compatible storage.
|
|
171
|
+
*
|
|
172
|
+
* This is the main factory function for setting up cloud backups.
|
|
173
|
+
* It creates an S3StorageProvider and CloudBackupManager configured
|
|
174
|
+
* with your database and S3-compatible storage.
|
|
175
|
+
*
|
|
176
|
+
* @param adapter - The StorageAdapter instance to backup
|
|
177
|
+
* @param s3Client - AWS SDK S3Client (works with S3, R2, MinIO, etc.)
|
|
178
|
+
* @param bucket - The S3 bucket name
|
|
179
|
+
* @param config - Scheduled backup configuration
|
|
180
|
+
* @returns CloudBackupManager instance ready to start
|
|
181
|
+
*
|
|
182
|
+
* @example AWS S3
|
|
183
|
+
* ```typescript
|
|
184
|
+
* import { S3Client } from '@aws-sdk/client-s3';
|
|
185
|
+
* import { createCloudBackupManager } from '@framers/sql-storage-adapter';
|
|
186
|
+
*
|
|
187
|
+
* const s3 = new S3Client({ region: 'us-east-1' });
|
|
188
|
+
* const manager = createCloudBackupManager(db, s3, 'my-bucket', {
|
|
189
|
+
* interval: 60 * 60 * 1000, // 1 hour
|
|
190
|
+
* maxBackups: 24,
|
|
191
|
+
* options: { compression: 'gzip' }
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* manager.start();
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* @example Cloudflare R2
|
|
198
|
+
* ```typescript
|
|
199
|
+
* import { S3Client } from '@aws-sdk/client-s3';
|
|
200
|
+
*
|
|
201
|
+
* const r2 = new S3Client({
|
|
202
|
+
* region: 'auto',
|
|
203
|
+
* endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
|
204
|
+
* credentials: {
|
|
205
|
+
* accessKeyId: process.env.R2_ACCESS_KEY_ID,
|
|
206
|
+
* secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
|
|
207
|
+
* },
|
|
208
|
+
* });
|
|
209
|
+
*
|
|
210
|
+
* const manager = createCloudBackupManager(db, r2, 'backups', {
|
|
211
|
+
* interval: 24 * 60 * 60 * 1000, // Daily
|
|
212
|
+
* maxBackups: 7
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
export declare function createCloudBackupManager(adapter: StorageAdapter, s3Client: {
|
|
217
|
+
send: (command: unknown) => Promise<unknown>;
|
|
218
|
+
}, bucket: string, config: ScheduledBackupConfig): CloudBackupManager;
|
|
219
|
+
//# sourceMappingURL=cloudBackup.d.ts.map
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
+
mod
|
|
26
|
+
));
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var cloudBackup_exports = {};
|
|
29
|
+
__export(cloudBackup_exports, {
|
|
30
|
+
CloudBackupManager: () => CloudBackupManager,
|
|
31
|
+
S3StorageProvider: () => S3StorageProvider,
|
|
32
|
+
createCloudBackupManager: () => createCloudBackupManager
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(cloudBackup_exports);
|
|
35
|
+
var import_dataExport = require("../migrations/dataExport.js");
|
|
36
|
+
var import_dataImport = require("../migrations/dataImport.js");
|
|
37
|
+
class S3StorageProvider {
|
|
38
|
+
/**
|
|
39
|
+
* @param client - AWS SDK S3Client instance
|
|
40
|
+
* @param bucket - S3 bucket name
|
|
41
|
+
*/
|
|
42
|
+
constructor(client, bucket) {
|
|
43
|
+
this.client = client;
|
|
44
|
+
this.bucket = bucket;
|
|
45
|
+
}
|
|
46
|
+
async upload(key, data) {
|
|
47
|
+
const { PutObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
|
|
48
|
+
await this.client.send(new PutObjectCommand({
|
|
49
|
+
Bucket: this.bucket,
|
|
50
|
+
Key: key,
|
|
51
|
+
Body: data
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
async download(key) {
|
|
55
|
+
const { GetObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
|
|
56
|
+
const response = await this.client.send(new GetObjectCommand({
|
|
57
|
+
Bucket: this.bucket,
|
|
58
|
+
Key: key
|
|
59
|
+
}));
|
|
60
|
+
if (response.Body.transformToString) {
|
|
61
|
+
return await response.Body.transformToString();
|
|
62
|
+
}
|
|
63
|
+
return response.Body.toString("utf-8");
|
|
64
|
+
}
|
|
65
|
+
async list(prefix) {
|
|
66
|
+
const { ListObjectsV2Command } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
|
|
67
|
+
const response = await this.client.send(new ListObjectsV2Command({
|
|
68
|
+
Bucket: this.bucket,
|
|
69
|
+
Prefix: prefix
|
|
70
|
+
}));
|
|
71
|
+
return response.Contents?.map((obj) => obj.Key).filter((key) => !!key) ?? [];
|
|
72
|
+
}
|
|
73
|
+
async delete(key) {
|
|
74
|
+
const { DeleteObjectCommand } = await Promise.resolve().then(() => __toESM(require("@aws-sdk/client-s3")));
|
|
75
|
+
await this.client.send(new DeleteObjectCommand({
|
|
76
|
+
Bucket: this.bucket,
|
|
77
|
+
Key: key
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function compress(data) {
|
|
82
|
+
const { gzip } = await Promise.resolve().then(() => __toESM(require("zlib")));
|
|
83
|
+
const { promisify } = await Promise.resolve().then(() => __toESM(require("util")));
|
|
84
|
+
const gzipAsync = promisify(gzip);
|
|
85
|
+
return await gzipAsync(Buffer.from(data));
|
|
86
|
+
}
|
|
87
|
+
async function decompress(data) {
|
|
88
|
+
const { gunzip } = await Promise.resolve().then(() => __toESM(require("zlib")));
|
|
89
|
+
const { promisify } = await Promise.resolve().then(() => __toESM(require("util")));
|
|
90
|
+
const gunzipAsync = promisify(gunzip);
|
|
91
|
+
const decompressed = await gunzipAsync(data);
|
|
92
|
+
return decompressed.toString("utf-8");
|
|
93
|
+
}
|
|
94
|
+
class CloudBackupManager {
|
|
95
|
+
constructor(adapter, storage, config) {
|
|
96
|
+
this.adapter = adapter;
|
|
97
|
+
this.storage = storage;
|
|
98
|
+
this.config = config;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create a backup and upload to cloud storage.
|
|
102
|
+
*/
|
|
103
|
+
async backup(options = {}) {
|
|
104
|
+
const format = options.format ?? this.config.options?.format ?? "json";
|
|
105
|
+
const compression = options.compression ?? this.config.options?.compression ?? "none";
|
|
106
|
+
const tables = options.tables ?? this.config.options?.tables;
|
|
107
|
+
const prefix = options.prefix ?? this.config.options?.prefix ?? "backups/";
|
|
108
|
+
const includeTimestamp = options.includeTimestamp ?? this.config.options?.includeTimestamp ?? true;
|
|
109
|
+
let data;
|
|
110
|
+
if (format === "json") {
|
|
111
|
+
data = await (0, import_dataExport.exportAsJSON)(this.adapter, { tables });
|
|
112
|
+
} else {
|
|
113
|
+
data = await (0, import_dataExport.exportAsSQL)(this.adapter, { tables });
|
|
114
|
+
}
|
|
115
|
+
let uploadData = data;
|
|
116
|
+
if (compression === "gzip") {
|
|
117
|
+
uploadData = await compress(data);
|
|
118
|
+
}
|
|
119
|
+
const timestamp = includeTimestamp ? `-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}` : "";
|
|
120
|
+
const ext = format === "json" ? "json" : "sql";
|
|
121
|
+
const compExt = compression === "gzip" ? ".gz" : "";
|
|
122
|
+
const key = `${prefix}backup${timestamp}.${ext}${compExt}`;
|
|
123
|
+
await this.storage.upload(key, uploadData);
|
|
124
|
+
if (this.config.maxBackups) {
|
|
125
|
+
await this.cleanupOldBackups(prefix);
|
|
126
|
+
}
|
|
127
|
+
return key;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Restore from a cloud backup.
|
|
131
|
+
*/
|
|
132
|
+
async restore(key) {
|
|
133
|
+
const data = await this.storage.download(key);
|
|
134
|
+
let restored;
|
|
135
|
+
if (key.endsWith(".gz")) {
|
|
136
|
+
restored = await decompress(Buffer.from(data));
|
|
137
|
+
} else {
|
|
138
|
+
restored = typeof data === "string" ? data : data.toString("utf-8");
|
|
139
|
+
}
|
|
140
|
+
if (key.includes(".json")) {
|
|
141
|
+
await (0, import_dataImport.importFromJSON)(this.adapter, restored);
|
|
142
|
+
} else {
|
|
143
|
+
await (0, import_dataImport.importFromSQL)(this.adapter, restored);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* List all backups in cloud storage.
|
|
148
|
+
*/
|
|
149
|
+
async listBackups(prefix) {
|
|
150
|
+
const searchPrefix = prefix ?? this.config.options?.prefix ?? "backups/";
|
|
151
|
+
return await this.storage.list(searchPrefix);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Delete old backups exceeding maxBackups limit.
|
|
155
|
+
*/
|
|
156
|
+
async cleanupOldBackups(prefix) {
|
|
157
|
+
if (!this.config.maxBackups)
|
|
158
|
+
return;
|
|
159
|
+
const backups = await this.storage.list(prefix);
|
|
160
|
+
if (backups.length <= this.config.maxBackups)
|
|
161
|
+
return;
|
|
162
|
+
const sorted = backups.sort();
|
|
163
|
+
const toDelete = sorted.slice(0, backups.length - this.config.maxBackups);
|
|
164
|
+
for (const key of toDelete) {
|
|
165
|
+
await this.storage.delete(key);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Start automatic scheduled backups.
|
|
170
|
+
*/
|
|
171
|
+
start() {
|
|
172
|
+
if (this.intervalId) {
|
|
173
|
+
throw new Error("Scheduled backups already started");
|
|
174
|
+
}
|
|
175
|
+
this.intervalId = setInterval(async () => {
|
|
176
|
+
try {
|
|
177
|
+
const key = await this.backup();
|
|
178
|
+
this.config.onSuccess?.(key);
|
|
179
|
+
} catch (error) {
|
|
180
|
+
this.config.onError?.(error);
|
|
181
|
+
}
|
|
182
|
+
}, this.config.interval);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Stop automatic scheduled backups.
|
|
186
|
+
*/
|
|
187
|
+
stop() {
|
|
188
|
+
if (this.intervalId) {
|
|
189
|
+
clearInterval(this.intervalId);
|
|
190
|
+
this.intervalId = void 0;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Perform a backup immediately (manual trigger).
|
|
195
|
+
*/
|
|
196
|
+
async backupNow(options) {
|
|
197
|
+
return await this.backup(options);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
function createCloudBackupManager(adapter, s3Client, bucket, config) {
|
|
201
|
+
const storage = new S3StorageProvider(s3Client, bucket);
|
|
202
|
+
return new CloudBackupManager(adapter, storage, config);
|
|
203
|
+
}
|
|
204
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
205
|
+
0 && (module.exports = {
|
|
206
|
+
CloudBackupManager,
|
|
207
|
+
S3StorageProvider,
|
|
208
|
+
createCloudBackupManager
|
|
209
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The part of IndexedDB the key-value store calls, typed structurally: the module compiles without the DOM
|
|
3
|
+
* library, and a page's IndexedDB satisfies these shapes.
|
|
4
|
+
* Moved unchanged from @framers/agentos src/core/storage/browser/idb.ts.
|
|
5
|
+
* @module sql-storage-adapter/kv/idb
|
|
6
|
+
*/
|
|
7
|
+
/** A request's outcome and its two events. */
|
|
8
|
+
export interface IdbRequestLike<T> {
|
|
9
|
+
/** What the request answered, once it is done. */
|
|
10
|
+
readonly result: T;
|
|
11
|
+
/** Why the request failed, once it is done; null when it did not. */
|
|
12
|
+
readonly error: unknown;
|
|
13
|
+
/** Called when the request has succeeded. */
|
|
14
|
+
onsuccess: (() => void) | null;
|
|
15
|
+
/** Called when the request has failed. */
|
|
16
|
+
onerror: (() => void) | null;
|
|
17
|
+
}
|
|
18
|
+
/** A key range; only made and passed on. */
|
|
19
|
+
export type IdbKeyRangeLike = object;
|
|
20
|
+
/** The object store's calls the store makes. */
|
|
21
|
+
export interface IdbObjectStoreLike {
|
|
22
|
+
/** Reads the value under a key. */
|
|
23
|
+
get(key: string): IdbRequestLike<unknown>;
|
|
24
|
+
/** Writes a value under a key, in place of what was there. */
|
|
25
|
+
put(value: unknown, key: string): IdbRequestLike<unknown>;
|
|
26
|
+
/** Removes one key, or every key of a range. */
|
|
27
|
+
delete(key: string | IdbKeyRangeLike): IdbRequestLike<unknown>;
|
|
28
|
+
/** Removes every key. */
|
|
29
|
+
clear(): IdbRequestLike<unknown>;
|
|
30
|
+
/** Lists the keys of a range, or every key. */
|
|
31
|
+
getAllKeys(range?: IdbKeyRangeLike): IdbRequestLike<unknown[]>;
|
|
32
|
+
}
|
|
33
|
+
/** A transaction and its three events. */
|
|
34
|
+
export interface IdbTransactionLike {
|
|
35
|
+
/** Why the transaction was aborted; null until it is, and after a plain abort. */
|
|
36
|
+
readonly error: unknown;
|
|
37
|
+
/** One of the object stores the transaction was opened over. */
|
|
38
|
+
objectStore(name: string): IdbObjectStoreLike;
|
|
39
|
+
/** Called when everything the transaction did is kept. */
|
|
40
|
+
oncomplete: (() => void) | null;
|
|
41
|
+
/** Called when one of the transaction's requests has failed, before the transaction is aborted for it. */
|
|
42
|
+
onerror: (() => void) | null;
|
|
43
|
+
/** Called when the transaction is aborted and nothing it did is kept. */
|
|
44
|
+
onabort: (() => void) | null;
|
|
45
|
+
}
|
|
46
|
+
/** An open database. */
|
|
47
|
+
export interface IdbDatabaseLike {
|
|
48
|
+
/** The names of the database's object stores. */
|
|
49
|
+
readonly objectStoreNames: {
|
|
50
|
+
contains(name: string): boolean;
|
|
51
|
+
};
|
|
52
|
+
/** Makes an object store with out-of-line keys; only inside an upgrade. */
|
|
53
|
+
createObjectStore(name: string): unknown;
|
|
54
|
+
/** Opens a transaction over one object store. */
|
|
55
|
+
transaction(storeName: string, mode: 'readonly' | 'readwrite'): IdbTransactionLike;
|
|
56
|
+
/** Closes the connection once its transactions are done. */
|
|
57
|
+
close(): void;
|
|
58
|
+
}
|
|
59
|
+
/** The request `open` answers. */
|
|
60
|
+
export interface IdbOpenRequestLike extends IdbRequestLike<IdbDatabaseLike> {
|
|
61
|
+
/** The upgrade's transaction while `onupgradeneeded` runs; null outside it. */
|
|
62
|
+
readonly transaction: {
|
|
63
|
+
abort(): void;
|
|
64
|
+
} | null;
|
|
65
|
+
/** Called when the database is new or older than the version asked for, inside the upgrade. */
|
|
66
|
+
onupgradeneeded: (() => void) | null;
|
|
67
|
+
/** Called when an upgrade waits for another connection to close. */
|
|
68
|
+
onblocked: (() => void) | null;
|
|
69
|
+
}
|
|
70
|
+
/** The page's `indexedDB` and `IDBKeyRange`, or an error when the page has none. */
|
|
71
|
+
export declare function idb(): {
|
|
72
|
+
factory: {
|
|
73
|
+
open(name: string, version?: number): IdbOpenRequestLike;
|
|
74
|
+
};
|
|
75
|
+
keyRange: {
|
|
76
|
+
bound(lower: string, upper: string): IdbKeyRangeLike;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=idb.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var idb_exports = {};
|
|
19
|
+
__export(idb_exports, {
|
|
20
|
+
idb: () => idb
|
|
21
|
+
});
|
|
22
|
+
module.exports = __toCommonJS(idb_exports);
|
|
23
|
+
function idb() {
|
|
24
|
+
const scope = globalThis;
|
|
25
|
+
if (!scope.indexedDB || !scope.IDBKeyRange)
|
|
26
|
+
throw new Error("IndexedDB is not available here.");
|
|
27
|
+
return { factory: scope.indexedDB, keyRange: scope.IDBKeyRange };
|
|
28
|
+
}
|
|
29
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
30
|
+
0 && (module.exports = {
|
|
31
|
+
idb
|
|
32
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The key-value module, `@framers/sql-storage-adapter/kv`: one `KeyValueStore` contract and its
|
|
3
|
+
* stores. `openIndexedDbStore` keeps values in one IndexedDB object store, moved unchanged from @framers/agentos, so a
|
|
4
|
+
* page's keys stay where they are; `createSqlKeyValueStore` keeps them in a SQL table on any adapter; the memory store
|
|
5
|
+
* keeps them for the page alone.
|
|
6
|
+
*
|
|
7
|
+
* The module imports no adapter, so a page that loads it for its key-value store loads neither sql.js nor pg.
|
|
8
|
+
* @module sql-storage-adapter/kv
|
|
9
|
+
*/
|
|
10
|
+
export { MemoryKeyValueStore, namespaced, type KeyValueStore } from './keyValueStore.js';
|
|
11
|
+
export { IndexedDbKeyValueStore, openIndexedDbStore, type IndexedDbStoreOptions } from './indexedDbKeyValueStore.js';
|
|
12
|
+
export { idb, type IdbDatabaseLike, type IdbKeyRangeLike, type IdbObjectStoreLike, type IdbOpenRequestLike, type IdbRequestLike, type IdbTransactionLike, } from './idb.js';
|
|
13
|
+
export { createSqlKeyValueStore, type SqlKeyValueStoreOptions } from './sqlKeyValueStore.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
var kv_exports = {};
|
|
19
|
+
__export(kv_exports, {
|
|
20
|
+
IndexedDbKeyValueStore: () => import_indexedDbKeyValueStore.IndexedDbKeyValueStore,
|
|
21
|
+
MemoryKeyValueStore: () => import_keyValueStore.MemoryKeyValueStore,
|
|
22
|
+
createSqlKeyValueStore: () => import_sqlKeyValueStore.createSqlKeyValueStore,
|
|
23
|
+
idb: () => import_idb.idb,
|
|
24
|
+
namespaced: () => import_keyValueStore.namespaced,
|
|
25
|
+
openIndexedDbStore: () => import_indexedDbKeyValueStore.openIndexedDbStore
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(kv_exports);
|
|
28
|
+
var import_keyValueStore = require("./keyValueStore.js");
|
|
29
|
+
var import_indexedDbKeyValueStore = require("./indexedDbKeyValueStore.js");
|
|
30
|
+
var import_idb = require("./idb.js");
|
|
31
|
+
var import_sqlKeyValueStore = require("./sqlKeyValueStore.js");
|
|
32
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
33
|
+
0 && (module.exports = {
|
|
34
|
+
IndexedDbKeyValueStore,
|
|
35
|
+
MemoryKeyValueStore,
|
|
36
|
+
createSqlKeyValueStore,
|
|
37
|
+
idb,
|
|
38
|
+
namespaced,
|
|
39
|
+
openIndexedDbStore
|
|
40
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The key-value store over one IndexedDB object store with out-of-line keys. It opens a database at
|
|
3
|
+
* the version given (1 by default) and creates the object store only when the open upgrades the database (a new one,
|
|
4
|
+
* or one below that version), so a database another page made at that version is read in place. A browser that
|
|
5
|
+
* refuses IndexedDB gets the memory store.
|
|
6
|
+
* Moved unchanged from @framers/agentos src/core/storage/browser/IndexedDbKeyValueStore.ts: the same database,
|
|
7
|
+
* object store, version and keys.
|
|
8
|
+
* @module sql-storage-adapter/kv/indexedDbKeyValueStore
|
|
9
|
+
*/
|
|
10
|
+
import { type IdbDatabaseLike } from './idb.js';
|
|
11
|
+
import { type KeyValueStore } from './keyValueStore.js';
|
|
12
|
+
/** Where the store lives. */
|
|
13
|
+
export interface IndexedDbStoreOptions {
|
|
14
|
+
/** The database's name. */
|
|
15
|
+
dbName: string;
|
|
16
|
+
/** The object store's name. It is made, with out-of-line keys, only when the open upgrades the database. */
|
|
17
|
+
storeName: string;
|
|
18
|
+
/**
|
|
19
|
+
* The version the database is opened at. A database that exists at this version is opened as it is, even when it
|
|
20
|
+
* lacks the object store, and every call of the store then rejects; one below it is upgraded, and gains the object
|
|
21
|
+
* store when it lacks it; one above it is refused by the browser.
|
|
22
|
+
* @default 1
|
|
23
|
+
*/
|
|
24
|
+
version?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The store over IndexedDB. Each call is one transaction over the object store: its promise is fulfilled when that
|
|
28
|
+
* transaction completes, and rejected with the reason when its request fails or the transaction is aborted.
|
|
29
|
+
*
|
|
30
|
+
* `keys` and `deletePrefix` read the keys between `prefix` and `prefix` followed by U+FFFF, so they miss a key that
|
|
31
|
+
* holds U+FFFF right after the prefix and goes on: keep keys to characters below it.
|
|
32
|
+
*
|
|
33
|
+
* The connection stays open until `close`: when another tab opens the database at a newer version, its upgrade waits
|
|
34
|
+
* for this tab to close the store or go. A connection the browser closes (the database deleted, the site's storage
|
|
35
|
+
* cleared) is not opened again, and every call then rejects.
|
|
36
|
+
*/
|
|
37
|
+
export declare class IndexedDbKeyValueStore implements KeyValueStore {
|
|
38
|
+
private readonly db;
|
|
39
|
+
private readonly storeName;
|
|
40
|
+
/** Always false: the values are in the browser's database. */
|
|
41
|
+
readonly memoryOnly = false;
|
|
42
|
+
/**
|
|
43
|
+
* @param db - An open database that holds the object store.
|
|
44
|
+
* @param storeName - The object store's name.
|
|
45
|
+
*/
|
|
46
|
+
constructor(db: IdbDatabaseLike, storeName: string);
|
|
47
|
+
private run;
|
|
48
|
+
private static range;
|
|
49
|
+
/** The value held under `key`, or undefined when there is none. */
|
|
50
|
+
get<T = unknown>(key: string): Promise<T | undefined>;
|
|
51
|
+
/** Holds a structured clone of `value` under `key`. */
|
|
52
|
+
set(key: string, value: unknown): Promise<void>;
|
|
53
|
+
/** Removes `key`. */
|
|
54
|
+
delete(key: string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Every key that begins with `prefix`, in order. With an empty prefix, every key of the object store, a key that is
|
|
57
|
+
* not a string (a number, a date or an array another page wrote) given as `String` writes it.
|
|
58
|
+
*/
|
|
59
|
+
keys(prefix: string): Promise<string[]>;
|
|
60
|
+
/** Removes every key that begins with `prefix`; with an empty prefix, everything the object store holds. */
|
|
61
|
+
deletePrefix(prefix: string): Promise<void>;
|
|
62
|
+
/** Closes the database connection. */
|
|
63
|
+
close(): void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Opens the store, or the memory store when the browser refuses IndexedDB: a page with no `indexedDB`, an `open`
|
|
67
|
+
* that throws or fails (a database above `version` among them), or an upgrade that waits on another tab. The
|
|
68
|
+
* answer's `memoryOnly` says which it is; the memory store's `close` does nothing.
|
|
69
|
+
*
|
|
70
|
+
* An upgrade that waited on another tab still has its turn once that tab closes the database. It is aborted then,
|
|
71
|
+
* so the database stays as it was and the connection it opened is closed: nothing is left open behind the memory
|
|
72
|
+
* store.
|
|
73
|
+
*/
|
|
74
|
+
export declare function openIndexedDbStore(options: IndexedDbStoreOptions): Promise<KeyValueStore & {
|
|
75
|
+
close(): void;
|
|
76
|
+
}>;
|
|
77
|
+
//# sourceMappingURL=indexedDbKeyValueStore.d.ts.map
|