()
| 220 | |
| 221 | /** Get or create device ID for sync tracking */ |
| 222 | export async function getDeviceId(): Promise<string> { |
| 223 | if (cachedDeviceId) return cachedDeviceId; |
| 224 | |
| 225 | const platform = getPlatformService(); |
| 226 | let kvAvailable = true; |
| 227 | |
| 228 | try { |
| 229 | const storedDeviceId = await platform.kvGetItem(DEVICE_ID_STORAGE_KEY); |
| 230 | if (storedDeviceId) { |
| 231 | cachedDeviceId = storedDeviceId; |
| 232 | try { |
| 233 | const database = await getDB(); |
| 234 | await database.execute( |
| 235 | "INSERT OR REPLACE INTO sync_metadata (key, value) VALUES ('device_id', ?)", |
| 236 | [storedDeviceId], |
| 237 | ); |
| 238 | } catch { |
| 239 | // Table might not exist yet during init |
| 240 | } |
| 241 | return storedDeviceId; |
| 242 | } |
| 243 | } catch { |
| 244 | kvAvailable = false; |
| 245 | } |
| 246 | |
| 247 | const database = await getDB(); |
| 248 | if (!kvAvailable) { |
| 249 | try { |
| 250 | const rows = await database.select<{ value: string }>( |
| 251 | "SELECT value FROM sync_metadata WHERE key = 'device_id'", |
| 252 | ); |
| 253 | if (rows.length > 0 && rows[0].value) { |
| 254 | cachedDeviceId = rows[0].value; |
| 255 | return rows[0].value; |
| 256 | } |
| 257 | } catch { |
| 258 | // Table might not exist yet |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | // Generate new device ID |
| 263 | const id = generateId(); |
| 264 | try { |
| 265 | await database.execute( |
| 266 | "INSERT OR REPLACE INTO sync_metadata (key, value) VALUES ('device_id', ?)", |
| 267 | [id], |
| 268 | ); |
| 269 | } catch { |
| 270 | // Table might not exist yet during init |
| 271 | } |
| 272 | try { |
| 273 | await platform.kvSetItem(DEVICE_ID_STORAGE_KEY, id); |
| 274 | } catch { |
| 275 | // Ignore KV persistence errors; DB copy will still exist. |
| 276 | } |
| 277 | cachedDeviceId = id; |
| 278 | return id; |
| 279 | } |
no test coverage detected