@pol-studios/powersync 1.0.4 → 1.0.7
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/dist/CacheSettingsManager-1exbOC6S.d.ts +261 -0
- package/dist/attachments/index.d.ts +65 -355
- package/dist/attachments/index.js +24 -6
- package/dist/{types-Cd7RhNqf.d.ts → background-sync-ChCXW-EV.d.ts} +53 -2
- package/dist/chunk-4C3RY5SU.js +204 -0
- package/dist/chunk-4C3RY5SU.js.map +1 -0
- package/dist/{chunk-3AYXHQ4W.js → chunk-53WH2JJV.js} +111 -47
- package/dist/chunk-53WH2JJV.js.map +1 -0
- package/dist/chunk-A4IBBWGO.js +377 -0
- package/dist/chunk-A4IBBWGO.js.map +1 -0
- package/dist/chunk-BREGB4WL.js +1768 -0
- package/dist/chunk-BREGB4WL.js.map +1 -0
- package/dist/{chunk-EJ23MXPQ.js → chunk-CGL33PL4.js} +3 -1
- package/dist/chunk-CGL33PL4.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DHYUBVP7.js +131 -0
- package/dist/chunk-DHYUBVP7.js.map +1 -0
- package/dist/chunk-FV2HXEIY.js +124 -0
- package/dist/chunk-FV2HXEIY.js.map +1 -0
- package/dist/chunk-GKF7TOMT.js +1 -0
- package/dist/{chunk-OTJXIRWX.js → chunk-H772V6XQ.js} +304 -51
- package/dist/chunk-H772V6XQ.js.map +1 -0
- package/dist/{chunk-C2RSTGDC.js → chunk-HFOFLW5F.js} +525 -87
- package/dist/chunk-HFOFLW5F.js.map +1 -0
- package/dist/chunk-KGSFAE5B.js +1 -0
- package/dist/chunk-LNL64IJZ.js +1 -0
- package/dist/chunk-MKD2VCX3.js +32 -0
- package/dist/chunk-MKD2VCX3.js.map +1 -0
- package/dist/{chunk-7EMDVIZX.js → chunk-N75DEF5J.js} +19 -1
- package/dist/chunk-N75DEF5J.js.map +1 -0
- package/dist/chunk-P6WOZO7H.js +49 -0
- package/dist/chunk-P6WOZO7H.js.map +1 -0
- package/dist/chunk-TGBT5XBE.js +1 -0
- package/dist/chunk-TGBT5XBE.js.map +1 -0
- package/dist/chunk-UEYRTLKE.js +72 -0
- package/dist/chunk-UEYRTLKE.js.map +1 -0
- package/dist/chunk-WGHNIAF7.js +329 -0
- package/dist/chunk-WGHNIAF7.js.map +1 -0
- package/dist/chunk-WQ5MPAVC.js +449 -0
- package/dist/chunk-WQ5MPAVC.js.map +1 -0
- package/dist/{chunk-FPTDATY5.js → chunk-XQAJM2MW.js} +22 -11
- package/dist/chunk-XQAJM2MW.js.map +1 -0
- package/dist/chunk-YSTEESEG.js +676 -0
- package/dist/chunk-YSTEESEG.js.map +1 -0
- package/dist/chunk-ZEOKPWUC.js +1165 -0
- package/dist/chunk-ZEOKPWUC.js.map +1 -0
- package/dist/connector/index.d.ts +182 -2
- package/dist/connector/index.js +14 -3
- package/dist/core/index.d.ts +5 -3
- package/dist/core/index.js +5 -2
- package/dist/error/index.d.ts +54 -0
- package/dist/error/index.js +8 -0
- package/dist/error/index.js.map +1 -0
- package/dist/index.d.ts +237 -11
- package/dist/index.js +183 -27
- package/dist/index.native.d.ts +20 -9
- package/dist/index.native.js +183 -28
- package/dist/index.web.d.ts +20 -9
- package/dist/index.web.js +184 -28
- package/dist/maintenance/index.d.ts +118 -0
- package/dist/maintenance/index.js +17 -0
- package/dist/maintenance/index.js.map +1 -0
- package/dist/platform/index.d.ts +16 -1
- package/dist/platform/index.js +2 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/platform/index.native.d.ts +2 -2
- package/dist/platform/index.native.js +2 -1
- package/dist/platform/index.web.d.ts +1 -1
- package/dist/platform/index.web.js +2 -1
- package/dist/pol-attachment-queue-C7YNXXhK.d.ts +676 -0
- package/dist/provider/index.d.ts +693 -12
- package/dist/provider/index.js +57 -12
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.js +28 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/index.native.d.ts +6 -0
- package/dist/storage/index.native.js +26 -0
- package/dist/storage/index.native.js.map +1 -0
- package/dist/storage/index.web.d.ts +6 -0
- package/dist/storage/index.web.js +26 -0
- package/dist/storage/index.web.js.map +1 -0
- package/dist/storage/upload/index.d.ts +55 -0
- package/dist/storage/upload/index.js +15 -0
- package/dist/storage/upload/index.js.map +1 -0
- package/dist/storage/upload/index.native.d.ts +57 -0
- package/dist/storage/upload/index.native.js +14 -0
- package/dist/storage/upload/index.native.js.map +1 -0
- package/dist/storage/upload/index.web.d.ts +5 -0
- package/dist/storage/upload/index.web.js +14 -0
- package/dist/storage/upload/index.web.js.map +1 -0
- package/dist/{index-Cb-NI0Ct.d.ts → supabase-connector-qLm-WHkM.d.ts} +146 -10
- package/dist/sync/index.d.ts +288 -22
- package/dist/sync/index.js +23 -5
- package/dist/types-BVacP54t.d.ts +52 -0
- package/dist/types-Bgvx7-E8.d.ts +187 -0
- package/dist/{types-afHtE1U_.d.ts → types-CDqWh56B.d.ts} +2 -0
- package/package.json +72 -2
- package/dist/chunk-32OLICZO.js +0 -1
- package/dist/chunk-3AYXHQ4W.js.map +0 -1
- package/dist/chunk-7EMDVIZX.js.map +0 -1
- package/dist/chunk-7JQZBZ5N.js +0 -1
- package/dist/chunk-C2RSTGDC.js.map +0 -1
- package/dist/chunk-EJ23MXPQ.js.map +0 -1
- package/dist/chunk-FPTDATY5.js.map +0 -1
- package/dist/chunk-GMFDCVMZ.js +0 -1285
- package/dist/chunk-GMFDCVMZ.js.map +0 -1
- package/dist/chunk-OLHGI472.js +0 -1
- package/dist/chunk-OTJXIRWX.js.map +0 -1
- package/dist/chunk-V6LJ6MR2.js +0 -740
- package/dist/chunk-V6LJ6MR2.js.map +0 -1
- package/dist/chunk-VJCL2SWD.js +0 -1
- /package/dist/{chunk-32OLICZO.js.map → chunk-DGUM43GV.js.map} +0 -0
- /package/dist/{chunk-7JQZBZ5N.js.map → chunk-GKF7TOMT.js.map} +0 -0
- /package/dist/{chunk-OLHGI472.js.map → chunk-KGSFAE5B.js.map} +0 -0
- /package/dist/{chunk-VJCL2SWD.js.map → chunk-LNL64IJZ.js.map} +0 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import {
|
|
2
|
+
usePowerSync
|
|
3
|
+
} from "./chunk-YSTEESEG.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/format.ts
|
|
6
|
+
function formatBytes(bytes, decimals = 2) {
|
|
7
|
+
if (bytes === 0) return "0 B";
|
|
8
|
+
const k = 1024;
|
|
9
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
10
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
11
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
12
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/maintenance/database-maintenance.ts
|
|
16
|
+
var CACHE_STATS_TIMEOUT_MS = 1e4;
|
|
17
|
+
var TABLE_COUNT_BATCH_SIZE = 50;
|
|
18
|
+
var STORAGE_WARNING_THRESHOLD = 100 * 1024 * 1024;
|
|
19
|
+
var STORAGE_CRITICAL_THRESHOLD = 50 * 1024 * 1024;
|
|
20
|
+
var INTERNAL_TABLES = /* @__PURE__ */ new Set(["ps_crud", "ps_oplog", "ps_buckets", "ps_untyped", "ps_tx"]);
|
|
21
|
+
var USER_TABLE_PATTERN = /^ps_data__(local__)?(.+)$/;
|
|
22
|
+
async function getCacheStatsImpl(db, logger) {
|
|
23
|
+
let timeoutId = null;
|
|
24
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
25
|
+
timeoutId = setTimeout(() => {
|
|
26
|
+
logger?.warn("[getCacheStats] Query timed out after 10 seconds");
|
|
27
|
+
resolve(null);
|
|
28
|
+
}, CACHE_STATS_TIMEOUT_MS);
|
|
29
|
+
});
|
|
30
|
+
const fetchStatsPromise = (async () => {
|
|
31
|
+
try {
|
|
32
|
+
const allTables = await db.getAll(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
|
|
33
|
+
const tableSizes = /* @__PURE__ */ new Map();
|
|
34
|
+
let dbstatAvailable = false;
|
|
35
|
+
try {
|
|
36
|
+
const sizeResults = await db.getAll(`SELECT COALESCE(tbl, name) as name, SUM(pgsize) as size FROM dbstat GROUP BY COALESCE(tbl, name)`);
|
|
37
|
+
logger?.debug("[getCacheStats] DBSTAT query returned", sizeResults?.length, "entries");
|
|
38
|
+
for (const row of sizeResults) {
|
|
39
|
+
const size = Number(row.size) || 0;
|
|
40
|
+
if (size > 0) {
|
|
41
|
+
tableSizes.set(row.name, size);
|
|
42
|
+
dbstatAvailable = true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
logger?.debug("[getCacheStats] tableSizes map has", tableSizes.size, "tables with sizes");
|
|
46
|
+
} catch (dbstatError) {
|
|
47
|
+
logger?.debug("[getCacheStats] DBSTAT query FAILED:", dbstatError);
|
|
48
|
+
}
|
|
49
|
+
const countMap = /* @__PURE__ */ new Map();
|
|
50
|
+
for (let i = 0; i < allTables.length; i += TABLE_COUNT_BATCH_SIZE) {
|
|
51
|
+
const batch = allTables.slice(i, i + TABLE_COUNT_BATCH_SIZE);
|
|
52
|
+
const batchQuery = batch.map(({
|
|
53
|
+
name
|
|
54
|
+
}) => {
|
|
55
|
+
const escapedLiteral = name.replace(/'/g, "''");
|
|
56
|
+
const escapedIdentifier = name.replace(/"/g, '""');
|
|
57
|
+
return `SELECT '${escapedLiteral}' as name, COUNT(*) as c FROM "${escapedIdentifier}"`;
|
|
58
|
+
}).join(" UNION ALL ");
|
|
59
|
+
if (batchQuery) {
|
|
60
|
+
const batchCounts = await db.getAll(batchQuery);
|
|
61
|
+
batchCounts.forEach((row) => countMap.set(row.name, Number(row.c) || 0));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!dbstatAvailable && allTables.length > 0) {
|
|
65
|
+
logger?.debug("[getCacheStats] DBSTAT unavailable, using row-count estimation fallback");
|
|
66
|
+
try {
|
|
67
|
+
const pageSizeResult = await db.get("PRAGMA page_size");
|
|
68
|
+
const pageCountResult = await db.get("PRAGMA page_count");
|
|
69
|
+
const pageSizeBytes2 = pageSizeResult?.page_size ?? 4096;
|
|
70
|
+
const totalPages2 = pageCountResult?.page_count ?? 0;
|
|
71
|
+
const totalDbBytes = pageSizeBytes2 * totalPages2;
|
|
72
|
+
let totalRowCount = 0;
|
|
73
|
+
countMap.forEach((count) => {
|
|
74
|
+
totalRowCount += count;
|
|
75
|
+
});
|
|
76
|
+
const usableBytes = totalDbBytes * 0.9;
|
|
77
|
+
if (totalRowCount > 0) {
|
|
78
|
+
for (const {
|
|
79
|
+
name
|
|
80
|
+
} of allTables) {
|
|
81
|
+
const rowCount = countMap.get(name) ?? 0;
|
|
82
|
+
if (rowCount > 0) {
|
|
83
|
+
const estimatedBytes = Math.round(rowCount / totalRowCount * usableBytes);
|
|
84
|
+
tableSizes.set(name, estimatedBytes);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
logger?.debug("[getCacheStats] Estimated sizes for", tableSizes.size, "tables from", totalRowCount, "total rows");
|
|
88
|
+
}
|
|
89
|
+
} catch (fallbackError) {
|
|
90
|
+
logger?.debug("[getCacheStats] Size estimation fallback FAILED:", fallbackError);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const tableStats = [];
|
|
94
|
+
for (const {
|
|
95
|
+
name
|
|
96
|
+
} of allTables) {
|
|
97
|
+
const rowCount = countMap.get(name) ?? 0;
|
|
98
|
+
const storageBytes = tableSizes.get(name) ?? 0;
|
|
99
|
+
const match = name.match(USER_TABLE_PATTERN);
|
|
100
|
+
if (match) {
|
|
101
|
+
tableStats.push({
|
|
102
|
+
name: match[2],
|
|
103
|
+
internalName: name,
|
|
104
|
+
rowCount,
|
|
105
|
+
storageBytes,
|
|
106
|
+
storageFormatted: storageBytes > 0 ? formatBytes(storageBytes) : "N/A",
|
|
107
|
+
isInternal: false,
|
|
108
|
+
isLocalOnly: !!match[1]
|
|
109
|
+
});
|
|
110
|
+
} else if (INTERNAL_TABLES.has(name) || name.startsWith("ps_") || name.startsWith("__powersync") || name.startsWith("_powersync")) {
|
|
111
|
+
tableStats.push({
|
|
112
|
+
name,
|
|
113
|
+
internalName: name,
|
|
114
|
+
rowCount,
|
|
115
|
+
storageBytes,
|
|
116
|
+
storageFormatted: storageBytes > 0 ? formatBytes(storageBytes) : "N/A",
|
|
117
|
+
isInternal: true,
|
|
118
|
+
isLocalOnly: false
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
tableStats.sort((a, b) => {
|
|
123
|
+
if (a.isInternal !== b.isInternal) return a.isInternal ? 1 : -1;
|
|
124
|
+
return b.rowCount - a.rowCount;
|
|
125
|
+
});
|
|
126
|
+
const userTables = tableStats.filter((t) => !t.isInternal);
|
|
127
|
+
const totalRows = userTables.reduce((sum, t) => sum + t.rowCount, 0);
|
|
128
|
+
const pageSize = await db.get("PRAGMA page_size");
|
|
129
|
+
const pageCount = await db.get("PRAGMA page_count");
|
|
130
|
+
const freelistCount = await db.get("PRAGMA freelist_count");
|
|
131
|
+
const pageSizeBytes = pageSize?.page_size ?? 4096;
|
|
132
|
+
const totalPages = pageCount?.page_count ?? 0;
|
|
133
|
+
const freePages = freelistCount?.freelist_count ?? 0;
|
|
134
|
+
const usedPages = totalPages - freePages;
|
|
135
|
+
const totalBytes = pageSizeBytes * totalPages;
|
|
136
|
+
const usedBytes = pageSizeBytes * usedPages;
|
|
137
|
+
const reclaimableBytes = pageSizeBytes * freePages;
|
|
138
|
+
return {
|
|
139
|
+
tables: tableStats,
|
|
140
|
+
totalTables: userTables.length,
|
|
141
|
+
totalRows,
|
|
142
|
+
storage: {
|
|
143
|
+
used: usedBytes,
|
|
144
|
+
usedFormatted: formatBytes(usedBytes),
|
|
145
|
+
total: totalBytes,
|
|
146
|
+
totalFormatted: formatBytes(totalBytes),
|
|
147
|
+
reclaimable: reclaimableBytes,
|
|
148
|
+
reclaimableFormatted: formatBytes(reclaimableBytes)
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
} catch (err) {
|
|
152
|
+
logger?.error("[getCacheStats] error:", err);
|
|
153
|
+
return null;
|
|
154
|
+
} finally {
|
|
155
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
156
|
+
}
|
|
157
|
+
})();
|
|
158
|
+
return Promise.race([fetchStatsPromise, timeoutPromise]);
|
|
159
|
+
}
|
|
160
|
+
async function compactDatabaseImpl(db) {
|
|
161
|
+
try {
|
|
162
|
+
const pageSizeBefore = await db.get("PRAGMA page_size");
|
|
163
|
+
const pageCountBefore = await db.get("PRAGMA page_count");
|
|
164
|
+
const bytesBefore = (pageSizeBefore?.page_size ?? 0) * (pageCountBefore?.page_count ?? 0);
|
|
165
|
+
await db.execute("VACUUM");
|
|
166
|
+
const pageCountAfter = await db.get("PRAGMA page_count");
|
|
167
|
+
const bytesAfter = (pageSizeBefore?.page_size ?? 0) * (pageCountAfter?.page_count ?? 0);
|
|
168
|
+
return {
|
|
169
|
+
success: true,
|
|
170
|
+
bytesReclaimed: Math.max(0, bytesBefore - bytesAfter)
|
|
171
|
+
};
|
|
172
|
+
} catch (err) {
|
|
173
|
+
return {
|
|
174
|
+
success: false,
|
|
175
|
+
bytesReclaimed: 0,
|
|
176
|
+
error: err instanceof Error ? err.message : String(err)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
async function checkIntegrityImpl(db) {
|
|
181
|
+
try {
|
|
182
|
+
const results = await db.getAll("PRAGMA integrity_check");
|
|
183
|
+
const issues = [];
|
|
184
|
+
for (const row of results) {
|
|
185
|
+
const value = row.integrity_check;
|
|
186
|
+
if (value && value !== "ok") {
|
|
187
|
+
issues.push(String(value));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
isHealthy: issues.length === 0,
|
|
192
|
+
issues
|
|
193
|
+
};
|
|
194
|
+
} catch (err) {
|
|
195
|
+
return {
|
|
196
|
+
isHealthy: false,
|
|
197
|
+
issues: [err instanceof Error ? err.message : String(err)]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async function checkStorageQuotaImpl(db, getFreeDiskSpace) {
|
|
202
|
+
try {
|
|
203
|
+
const freeSpace = await getFreeDiskSpace();
|
|
204
|
+
let databaseSize = 0;
|
|
205
|
+
if (db) {
|
|
206
|
+
const pageSize = await db.get("PRAGMA page_size");
|
|
207
|
+
const pageCount = await db.get("PRAGMA page_count");
|
|
208
|
+
databaseSize = (pageSize?.page_size ?? 0) * (pageCount?.page_count ?? 0);
|
|
209
|
+
}
|
|
210
|
+
let status = "ok";
|
|
211
|
+
if (freeSpace < STORAGE_CRITICAL_THRESHOLD) {
|
|
212
|
+
status = "critical";
|
|
213
|
+
} else if (freeSpace < STORAGE_WARNING_THRESHOLD) {
|
|
214
|
+
status = "warning";
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
deviceFreeSpace: freeSpace,
|
|
218
|
+
databaseSize,
|
|
219
|
+
warningThreshold: STORAGE_WARNING_THRESHOLD,
|
|
220
|
+
criticalThreshold: STORAGE_CRITICAL_THRESHOLD,
|
|
221
|
+
status
|
|
222
|
+
};
|
|
223
|
+
} catch {
|
|
224
|
+
return {
|
|
225
|
+
deviceFreeSpace: 0,
|
|
226
|
+
databaseSize: 0,
|
|
227
|
+
warningThreshold: STORAGE_WARNING_THRESHOLD,
|
|
228
|
+
criticalThreshold: STORAGE_CRITICAL_THRESHOLD,
|
|
229
|
+
status: "critical"
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// src/maintenance/useDatabaseMaintenance.ts
|
|
235
|
+
import { c as _c } from "react/compiler-runtime";
|
|
236
|
+
function useDatabaseMaintenance() {
|
|
237
|
+
const $ = _c(15);
|
|
238
|
+
const {
|
|
239
|
+
db,
|
|
240
|
+
platform
|
|
241
|
+
} = usePowerSync();
|
|
242
|
+
let t0;
|
|
243
|
+
if ($[0] !== db || $[1] !== platform.logger) {
|
|
244
|
+
t0 = async () => {
|
|
245
|
+
if (!db) {
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
return getCacheStatsImpl(db, platform.logger);
|
|
249
|
+
};
|
|
250
|
+
$[0] = db;
|
|
251
|
+
$[1] = platform.logger;
|
|
252
|
+
$[2] = t0;
|
|
253
|
+
} else {
|
|
254
|
+
t0 = $[2];
|
|
255
|
+
}
|
|
256
|
+
const getCacheStats = t0;
|
|
257
|
+
let t1;
|
|
258
|
+
if ($[3] !== db) {
|
|
259
|
+
t1 = async () => {
|
|
260
|
+
if (!db) {
|
|
261
|
+
return {
|
|
262
|
+
success: false,
|
|
263
|
+
bytesReclaimed: 0,
|
|
264
|
+
error: "Database not initialized"
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return compactDatabaseImpl(db);
|
|
268
|
+
};
|
|
269
|
+
$[3] = db;
|
|
270
|
+
$[4] = t1;
|
|
271
|
+
} else {
|
|
272
|
+
t1 = $[4];
|
|
273
|
+
}
|
|
274
|
+
const compactDatabase = t1;
|
|
275
|
+
let t2;
|
|
276
|
+
if ($[5] !== db) {
|
|
277
|
+
t2 = async () => {
|
|
278
|
+
if (!db) {
|
|
279
|
+
return {
|
|
280
|
+
isHealthy: false,
|
|
281
|
+
issues: ["Database not initialized"]
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return checkIntegrityImpl(db);
|
|
285
|
+
};
|
|
286
|
+
$[5] = db;
|
|
287
|
+
$[6] = t2;
|
|
288
|
+
} else {
|
|
289
|
+
t2 = $[6];
|
|
290
|
+
}
|
|
291
|
+
const checkIntegrity = t2;
|
|
292
|
+
let t3;
|
|
293
|
+
if ($[7] !== db || $[8] !== platform.fileSystem) {
|
|
294
|
+
t3 = async () => checkStorageQuotaImpl(db, () => platform.fileSystem.getFreeDiskSpace());
|
|
295
|
+
$[7] = db;
|
|
296
|
+
$[8] = platform.fileSystem;
|
|
297
|
+
$[9] = t3;
|
|
298
|
+
} else {
|
|
299
|
+
t3 = $[9];
|
|
300
|
+
}
|
|
301
|
+
const checkStorageQuota = t3;
|
|
302
|
+
let t4;
|
|
303
|
+
if ($[10] !== checkIntegrity || $[11] !== checkStorageQuota || $[12] !== compactDatabase || $[13] !== getCacheStats) {
|
|
304
|
+
t4 = {
|
|
305
|
+
getCacheStats,
|
|
306
|
+
compactDatabase,
|
|
307
|
+
checkIntegrity,
|
|
308
|
+
checkStorageQuota
|
|
309
|
+
};
|
|
310
|
+
$[10] = checkIntegrity;
|
|
311
|
+
$[11] = checkStorageQuota;
|
|
312
|
+
$[12] = compactDatabase;
|
|
313
|
+
$[13] = getCacheStats;
|
|
314
|
+
$[14] = t4;
|
|
315
|
+
} else {
|
|
316
|
+
t4 = $[14];
|
|
317
|
+
}
|
|
318
|
+
return t4;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export {
|
|
322
|
+
formatBytes,
|
|
323
|
+
getCacheStatsImpl,
|
|
324
|
+
compactDatabaseImpl,
|
|
325
|
+
checkIntegrityImpl,
|
|
326
|
+
checkStorageQuotaImpl,
|
|
327
|
+
useDatabaseMaintenance
|
|
328
|
+
};
|
|
329
|
+
//# sourceMappingURL=chunk-WGHNIAF7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/format.ts","../src/maintenance/database-maintenance.ts","../src/maintenance/useDatabaseMaintenance.ts"],"sourcesContent":["/**\n * Format bytes to human-readable string\n *\n * @param bytes - Number of bytes to format\n * @param decimals - Number of decimal places (default: 2)\n * @returns Formatted string like \"1.5 MB\", \"256 KB\", etc.\n */\nexport function formatBytes(bytes: number, decimals = 2): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const dm = decimals < 0 ? 0 : decimals;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;\n}","/**\n * Pure Database Maintenance Functions for @pol-studios/powersync\n *\n * This module contains stateless, pure functions for database maintenance operations.\n * These functions can be called by hooks or used directly in other contexts.\n *\n * All functions accept the database as a parameter rather than accessing it from context,\n * making them testable and reusable across different environments.\n */\n\nimport type { AbstractPowerSyncDatabase } from '../core/types';\nimport type { LoggerAdapter } from '../platform/types';\nimport type { CacheStats, CompactResult, IntegrityResult, StorageQuota, TableCacheStats } from '../core/types';\nimport { formatBytes } from '../utils/format';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\n/** Timeout for getCacheStats to prevent hanging if db is locked */\nconst CACHE_STATS_TIMEOUT_MS = 10000;\n\n/** Batch size for table count queries to avoid N+1 queries */\nconst TABLE_COUNT_BATCH_SIZE = 50;\n\n/** Storage warning threshold (100MB free space) */\nconst STORAGE_WARNING_THRESHOLD = 100 * 1024 * 1024;\n\n/** Storage critical threshold (50MB free space) */\nconst STORAGE_CRITICAL_THRESHOLD = 50 * 1024 * 1024;\n\n/** Known internal PowerSync tables */\nconst INTERNAL_TABLES = new Set(['ps_crud', 'ps_oplog', 'ps_buckets', 'ps_untyped', 'ps_tx']);\n\n/** Pattern to match user tables: ps_data__[local__]tablename */\nconst USER_TABLE_PATTERN = /^ps_data__(local__)?(.+)$/;\n\n// ─── Helper Types ─────────────────────────────────────────────────────────────\n\ninterface SqliteTableRow {\n name: string;\n}\ninterface DbStatRow {\n name: string;\n size: number;\n}\ninterface TableCountRow {\n name: string;\n c: number;\n}\ninterface PageSizeRow {\n page_size: number;\n}\ninterface PageCountRow {\n page_count: number;\n}\ninterface FreelistCountRow {\n freelist_count: number;\n}\ninterface IntegrityCheckRow {\n integrity_check: string;\n}\n\n// ─── getCacheStatsImpl ────────────────────────────────────────────────────────\n\n/**\n * Get detailed cache statistics for all tables in the database.\n *\n * This function:\n * - Queries all tables from sqlite_master\n * - Tries to get table sizes from dbstat (with fallback estimation)\n * - Batches table row counts in groups of 50\n * - Calculates storage info from PRAGMA page_size, page_count, freelist_count\n *\n * @param db - The PowerSync database instance\n * @param logger - Optional logger for debug output\n * @returns Cache statistics or null if operation times out or fails\n */\nexport async function getCacheStatsImpl(db: AbstractPowerSyncDatabase, logger?: LoggerAdapter): Promise<CacheStats | null> {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const timeoutPromise = new Promise<null>(resolve => {\n timeoutId = setTimeout(() => {\n logger?.warn('[getCacheStats] Query timed out after 10 seconds');\n resolve(null);\n }, CACHE_STATS_TIMEOUT_MS);\n });\n const fetchStatsPromise = (async (): Promise<CacheStats | null> => {\n try {\n // Get all tables from SQLite (excluding sqlite internal tables)\n const allTables = await db.getAll<SqliteTableRow>(`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);\n\n // Query all table sizes from dbstat in one go\n // Use COALESCE(tbl, name) to attribute index sizes to their parent tables\n const tableSizes = new Map<string, number>();\n let dbstatAvailable = false;\n try {\n const sizeResults = await db.getAll<DbStatRow>(`SELECT COALESCE(tbl, name) as name, SUM(pgsize) as size FROM dbstat GROUP BY COALESCE(tbl, name)`);\n logger?.debug('[getCacheStats] DBSTAT query returned', sizeResults?.length, 'entries');\n for (const row of sizeResults) {\n // Handle potential type coercion issues - SQLite may return size as string or null\n const size = Number(row.size) || 0;\n if (size > 0) {\n tableSizes.set(row.name, size);\n dbstatAvailable = true;\n }\n }\n logger?.debug('[getCacheStats] tableSizes map has', tableSizes.size, 'tables with sizes');\n } catch (dbstatError) {\n logger?.debug('[getCacheStats] DBSTAT query FAILED:', dbstatError);\n }\n\n // Batch table counts to avoid N+1 queries (50+ tables = 1+ second freeze)\n const countMap = new Map<string, number>();\n for (let i = 0; i < allTables.length; i += TABLE_COUNT_BATCH_SIZE) {\n const batch = allTables.slice(i, i + TABLE_COUNT_BATCH_SIZE);\n const batchQuery = batch.map(({\n name\n }) => {\n // Escape quotes for SQL safety\n const escapedLiteral = name.replace(/'/g, \"''\");\n const escapedIdentifier = name.replace(/\"/g, '\"\"');\n return `SELECT '${escapedLiteral}' as name, COUNT(*) as c FROM \"${escapedIdentifier}\"`;\n }).join(' UNION ALL ');\n if (batchQuery) {\n const batchCounts = await db.getAll<TableCountRow>(batchQuery);\n batchCounts.forEach(row => countMap.set(row.name, Number(row.c) || 0));\n }\n }\n\n // Fallback: estimate table sizes based on row count if DBSTAT is not available\n if (!dbstatAvailable && allTables.length > 0) {\n logger?.debug('[getCacheStats] DBSTAT unavailable, using row-count estimation fallback');\n try {\n const pageSizeResult = await db.get<PageSizeRow>('PRAGMA page_size');\n const pageCountResult = await db.get<PageCountRow>('PRAGMA page_count');\n const pageSizeBytes = pageSizeResult?.page_size ?? 4096;\n const totalPages = pageCountResult?.page_count ?? 0;\n const totalDbBytes = pageSizeBytes * totalPages;\n\n // Calculate total rows across all tables\n let totalRowCount = 0;\n countMap.forEach(count => {\n totalRowCount += count;\n });\n\n // Distribute bytes proportionally by row count\n // Reserve ~10% for overhead (indexes, metadata, etc.)\n const usableBytes = totalDbBytes * 0.9;\n if (totalRowCount > 0) {\n for (const {\n name\n } of allTables) {\n const rowCount = countMap.get(name) ?? 0;\n if (rowCount > 0) {\n const estimatedBytes = Math.round(rowCount / totalRowCount * usableBytes);\n tableSizes.set(name, estimatedBytes);\n }\n }\n logger?.debug('[getCacheStats] Estimated sizes for', tableSizes.size, 'tables from', totalRowCount, 'total rows');\n }\n } catch (fallbackError) {\n logger?.debug('[getCacheStats] Size estimation fallback FAILED:', fallbackError);\n }\n }\n\n // Build table stats array\n const tableStats: TableCacheStats[] = [];\n for (const {\n name\n } of allTables) {\n const rowCount = countMap.get(name) ?? 0;\n const storageBytes = tableSizes.get(name) ?? 0;\n const match = name.match(USER_TABLE_PATTERN);\n if (match) {\n // User table (ps_data__[local__]tablename)\n tableStats.push({\n name: match[2],\n internalName: name,\n rowCount,\n storageBytes,\n storageFormatted: storageBytes > 0 ? formatBytes(storageBytes) : 'N/A',\n isInternal: false,\n isLocalOnly: !!match[1]\n });\n } else if (INTERNAL_TABLES.has(name) || name.startsWith('ps_') || name.startsWith('__powersync') || name.startsWith('_powersync')) {\n // Internal PowerSync table\n tableStats.push({\n name,\n internalName: name,\n rowCount,\n storageBytes,\n storageFormatted: storageBytes > 0 ? formatBytes(storageBytes) : 'N/A',\n isInternal: true,\n isLocalOnly: false\n });\n }\n }\n\n // Sort: user tables first (by row count desc), then internal tables\n tableStats.sort((a, b) => {\n if (a.isInternal !== b.isInternal) return a.isInternal ? 1 : -1;\n return b.rowCount - a.rowCount;\n });\n\n // Calculate totals for user tables only\n const userTables = tableStats.filter(t => !t.isInternal);\n const totalRows = userTables.reduce((sum, t) => sum + t.rowCount, 0);\n\n // Get storage info from SQLite PRAGMAs\n const pageSize = await db.get<PageSizeRow>('PRAGMA page_size');\n const pageCount = await db.get<PageCountRow>('PRAGMA page_count');\n const freelistCount = await db.get<FreelistCountRow>('PRAGMA freelist_count');\n const pageSizeBytes = pageSize?.page_size ?? 4096;\n const totalPages = pageCount?.page_count ?? 0;\n const freePages = freelistCount?.freelist_count ?? 0;\n const usedPages = totalPages - freePages;\n const totalBytes = pageSizeBytes * totalPages;\n const usedBytes = pageSizeBytes * usedPages;\n const reclaimableBytes = pageSizeBytes * freePages;\n return {\n tables: tableStats,\n totalTables: userTables.length,\n totalRows,\n storage: {\n used: usedBytes,\n usedFormatted: formatBytes(usedBytes),\n total: totalBytes,\n totalFormatted: formatBytes(totalBytes),\n reclaimable: reclaimableBytes,\n reclaimableFormatted: formatBytes(reclaimableBytes)\n }\n };\n } catch (err) {\n logger?.error('[getCacheStats] error:', err);\n return null;\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n }\n })();\n\n // Race between actual fetch and timeout\n return Promise.race([fetchStatsPromise, timeoutPromise]);\n}\n\n// ─── compactDatabaseImpl ──────────────────────────────────────────────────────\n\n/**\n * Compact the database by running VACUUM.\n * This reclaims free pages and reduces the database file size.\n *\n * @param db - The PowerSync database instance\n * @returns Result of the compaction operation including bytes reclaimed\n */\nexport async function compactDatabaseImpl(db: AbstractPowerSyncDatabase): Promise<CompactResult> {\n try {\n // Get page count before VACUUM\n const pageSizeBefore = await db.get<PageSizeRow>('PRAGMA page_size');\n const pageCountBefore = await db.get<PageCountRow>('PRAGMA page_count');\n const bytesBefore = (pageSizeBefore?.page_size ?? 0) * (pageCountBefore?.page_count ?? 0);\n\n // Run VACUUM to compact the database\n await db.execute('VACUUM');\n\n // Get page count after VACUUM\n const pageCountAfter = await db.get<PageCountRow>('PRAGMA page_count');\n const bytesAfter = (pageSizeBefore?.page_size ?? 0) * (pageCountAfter?.page_count ?? 0);\n return {\n success: true,\n bytesReclaimed: Math.max(0, bytesBefore - bytesAfter)\n };\n } catch (err) {\n return {\n success: false,\n bytesReclaimed: 0,\n error: err instanceof Error ? err.message : String(err)\n };\n }\n}\n\n// ─── checkIntegrityImpl ───────────────────────────────────────────────────────\n\n/**\n * Check the integrity of the database.\n * Runs SQLite's PRAGMA integrity_check.\n *\n * @param db - The PowerSync database instance\n * @returns Result indicating health status and any issues found\n */\nexport async function checkIntegrityImpl(db: AbstractPowerSyncDatabase): Promise<IntegrityResult> {\n try {\n const results = await db.getAll<IntegrityCheckRow>('PRAGMA integrity_check');\n const issues: string[] = [];\n for (const row of results) {\n const value = row.integrity_check;\n if (value && value !== 'ok') {\n issues.push(String(value));\n }\n }\n return {\n isHealthy: issues.length === 0,\n issues\n };\n } catch (err) {\n return {\n isHealthy: false,\n issues: [err instanceof Error ? err.message : String(err)]\n };\n }\n}\n\n// ─── checkStorageQuotaImpl ────────────────────────────────────────────────────\n\n/**\n * Check device storage quota and database size.\n * Useful for warning users about low storage situations.\n *\n * @param db - The PowerSync database instance (can be null)\n * @param getFreeDiskSpace - Callback to get free disk space in bytes\n * @returns Storage quota information with status\n */\nexport async function checkStorageQuotaImpl(db: AbstractPowerSyncDatabase | null, getFreeDiskSpace: () => Promise<number>): Promise<StorageQuota> {\n try {\n const freeSpace = await getFreeDiskSpace();\n\n // Get database size if db is available\n let databaseSize = 0;\n if (db) {\n const pageSize = await db.get<PageSizeRow>('PRAGMA page_size');\n const pageCount = await db.get<PageCountRow>('PRAGMA page_count');\n databaseSize = (pageSize?.page_size ?? 0) * (pageCount?.page_count ?? 0);\n }\n\n // Determine status based on free space thresholds\n let status: 'ok' | 'warning' | 'critical' = 'ok';\n if (freeSpace < STORAGE_CRITICAL_THRESHOLD) {\n status = 'critical';\n } else if (freeSpace < STORAGE_WARNING_THRESHOLD) {\n status = 'warning';\n }\n return {\n deviceFreeSpace: freeSpace,\n databaseSize,\n warningThreshold: STORAGE_WARNING_THRESHOLD,\n criticalThreshold: STORAGE_CRITICAL_THRESHOLD,\n status\n };\n } catch {\n // On error, return critical status as a safety measure\n return {\n deviceFreeSpace: 0,\n databaseSize: 0,\n warningThreshold: STORAGE_WARNING_THRESHOLD,\n criticalThreshold: STORAGE_CRITICAL_THRESHOLD,\n status: 'critical'\n };\n }\n}","import { c as _c } from \"react/compiler-runtime\";\n/**\n * React Hook for Database Maintenance Utilities\n *\n * This module provides a React hook that wraps the pure database maintenance\n * functions with stable function references via useCallback.\n */\n\nimport { useCallback } from 'react';\nimport { usePowerSync } from '../provider/hooks';\nimport type { DatabaseMaintenanceUtils } from './types';\nimport { getCacheStatsImpl, compactDatabaseImpl, checkIntegrityImpl, checkStorageQuotaImpl } from './database-maintenance';\n\n/**\n * Hook for database maintenance utilities.\n *\n * Use this hook when you need to perform database maintenance operations.\n * These operations are expensive - call sparingly (e.g., settings screens).\n *\n * Each function has a stable reference via useCallback.\n *\n * @example\n * const { getCacheStats, compactDatabase } = useDatabaseMaintenance();\n * const stats = await getCacheStats();\n */\nexport function useDatabaseMaintenance() {\n const $ = _c(15);\n const {\n db,\n platform\n } = usePowerSync();\n let t0;\n if ($[0] !== db || $[1] !== platform.logger) {\n t0 = async () => {\n if (!db) {\n return null;\n }\n return getCacheStatsImpl(db, platform.logger);\n };\n $[0] = db;\n $[1] = platform.logger;\n $[2] = t0;\n } else {\n t0 = $[2];\n }\n const getCacheStats = t0;\n let t1;\n if ($[3] !== db) {\n t1 = async () => {\n if (!db) {\n return {\n success: false,\n bytesReclaimed: 0,\n error: \"Database not initialized\"\n };\n }\n return compactDatabaseImpl(db);\n };\n $[3] = db;\n $[4] = t1;\n } else {\n t1 = $[4];\n }\n const compactDatabase = t1;\n let t2;\n if ($[5] !== db) {\n t2 = async () => {\n if (!db) {\n return {\n isHealthy: false,\n issues: [\"Database not initialized\"]\n };\n }\n return checkIntegrityImpl(db);\n };\n $[5] = db;\n $[6] = t2;\n } else {\n t2 = $[6];\n }\n const checkIntegrity = t2;\n let t3;\n if ($[7] !== db || $[8] !== platform.fileSystem) {\n t3 = async () => checkStorageQuotaImpl(db, () => platform.fileSystem.getFreeDiskSpace());\n $[7] = db;\n $[8] = platform.fileSystem;\n $[9] = t3;\n } else {\n t3 = $[9];\n }\n const checkStorageQuota = t3;\n let t4;\n if ($[10] !== checkIntegrity || $[11] !== checkStorageQuota || $[12] !== compactDatabase || $[13] !== getCacheStats) {\n t4 = {\n getCacheStats,\n compactDatabase,\n checkIntegrity,\n checkStorageQuota\n };\n $[10] = checkIntegrity;\n $[11] = checkStorageQuota;\n $[12] = compactDatabase;\n $[13] = getCacheStats;\n $[14] = t4;\n } else {\n t4 = $[14];\n }\n return t4;\n}"],"mappings":"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","names":["pageSizeBytes","totalPages"]}
|