mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 22:26:16 -08:00
fix(server-storage): Stalker keys by category, keepalive ordering, cut-off probe
- Moving Stalker favorites and history keys items by id and category, so a channel and a movie with one id both survive. - Writes after a page-hide flush wait for its keepalive requests. - A probe whose body is cut off counts as unreachable and keeps the remembered server. - Settings → Server renders without @defer so settings search can reveal its rows on the first visit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6820b87005
commit
676733cd7b
8 files changed
+101
-39
No files matched your search
@@ -78,6 +78,14 @@ describe('probeServerInstance', () => {
|
||||
for (const fetchFn of [
|
||||
jest.fn().mockRejectedValue(new TypeError('Failed to fetch')),
|
||||
answer('Bad Gateway', 502),
|
||||
// Headers arrived, then the body was cut off.
|
||||
jest.fn().mockResolvedValue({
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => {
|
||||
throw new DOMException('aborted', 'AbortError');
|
||||
},
|
||||
}),
|
||||
]) {
|
||||
await expect(
|
||||
probeServerInstance({ ...config, fetchFn: fetchFn as never })
|
||||
|
||||
@@ -64,8 +64,11 @@ export async function probeServerInstance(
|
||||
return isServerInstance(body) && body.storage === 'server'
|
||||
? { kind: 'server', instance: body }
|
||||
: { kind: 'none' };
|
||||
} catch {
|
||||
return { kind: 'none' };
|
||||
} catch (error) {
|
||||
// Unparseable JSON is an answer; a cut-off body is an outage.
|
||||
return error instanceof SyntaxError
|
||||
? { kind: 'none' }
|
||||
: { kind: 'unreachable' };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ import type { ServerStorageStatusResponse } from '@iptvnator/shared/interfaces';
|
||||
|
||||
/**
|
||||
* Settings → Server: shown only when the PWA runs against self-hosted
|
||||
* server storage. Loaded with `@defer`, so other builds never fetch the
|
||||
* server-storage code for the settings page.
|
||||
* server storage. Rendered without `@defer` so settings search can reveal
|
||||
* its rows on the first visit; the code rides in the lazy settings chunk.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-settings-server-section',
|
||||
|
||||
@@ -120,13 +120,9 @@
|
||||
/>
|
||||
}
|
||||
@case ('server') {
|
||||
<!-- Deferred: keeps the server-storage code out of
|
||||
the settings chunk in every other build. -->
|
||||
@defer {
|
||||
<app-settings-server-section
|
||||
(exportData)="exportData()"
|
||||
/>
|
||||
}
|
||||
<app-settings-server-section
|
||||
(exportData)="exportData()"
|
||||
/>
|
||||
}
|
||||
@case ('backup') {
|
||||
<!-- Backup & data: the former Reset page is this
|
||||
|
||||
Reference in new issue
Block a user