Verify persisted settings and save-before-play through production updates
This commit is contained in:
@@ -335,3 +335,24 @@ No product behavior changes are involved in these measurement corrections.
|
||||
Keep browser/build/test processes idle during full timing measurements. WebKit's
|
||||
zero long-task field means unavailable, not zero work. Autoplay-blocked/media-ready
|
||||
null results do not establish playback performance or iPhone audio continuity.
|
||||
|
||||
## Existing-install settings preservation
|
||||
|
||||
```sh
|
||||
node perf/settings-persist.mjs --browser all --target main --allow-unsupported-webkit
|
||||
node perf/settings-persist.mjs --browser all --target 0b8e398 --allow-unsupported-webkit --out perf/results/settings-persist-live-base.json
|
||||
```
|
||||
|
||||
The harness archives b77938a and the requested target into worktree-local scratch,
|
||||
serves actual Bun servers at the same origin, sets values through Settings UI
|
||||
handlers, reloads, invokes the old banner's actual Refresh UI button, and diffs
|
||||
every `_ytpdata.settings` key and control. A real local H.264/AAC clip verifies
|
||||
OPFS storage and blob playback before/after in Chromium. A local HTTP proxy
|
||||
mocks profile timestamps for worker-owned fetches on both engines and tests
|
||||
backup import. There are no external profile writes or media requests.
|
||||
|
||||
Failures exit 1. Linux WebKit has no native OPFS; without the explicit allowance
|
||||
the unverified storage capability exits 2. The allowance only skips unsupported
|
||||
storage assertions; every preservation/profile/import assertion still runs.
|
||||
No storage shim substitutes for a genuine iPhone test. Snapshot results and the
|
||||
per-key table are in `plans/settings-persist-investigation.md`.
|
||||
|
||||
708
perf/results/settings-persist-live-base.json
Normal file
708
perf/results/settings-persist-live-base.json
Normal file
@@ -0,0 +1,708 @@
|
||||
{
|
||||
"revision": "0b8e39846990eb178a28746d3d111bb0790d8275",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"results": [
|
||||
{
|
||||
"engine": "chromium",
|
||||
"errors": [
|
||||
"Cannot read properties of null (reading 'addEventListener')",
|
||||
"Cannot read properties of null (reading 'addEventListener')"
|
||||
],
|
||||
"profileChecks": [
|
||||
{
|
||||
"stage": "older timestamp ignored",
|
||||
"serverUpdatedAt": 100,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": true
|
||||
},
|
||||
{
|
||||
"stage": "older settings with newer timestamp adopted",
|
||||
"serverUpdatedAt": 300,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": false
|
||||
}
|
||||
],
|
||||
"behaviour": [
|
||||
{
|
||||
"stage": "old",
|
||||
"supported": true,
|
||||
"bytes": 30290,
|
||||
"cached": true,
|
||||
"localPlayback": true
|
||||
},
|
||||
{
|
||||
"stage": "upgraded",
|
||||
"supported": true,
|
||||
"bytes": 30290,
|
||||
"cached": true,
|
||||
"localPlayback": true
|
||||
}
|
||||
],
|
||||
"diff": [
|
||||
{
|
||||
"key": "quality",
|
||||
"before": "360p",
|
||||
"after": "360p",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "volume",
|
||||
"before": 1,
|
||||
"after": 1,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "audioOnly",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoPreload",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pShare",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pReceive",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "saveBeforePlay",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "repeatMode",
|
||||
"before": "all",
|
||||
"after": "all",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "loopOne",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "shuffle",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "theme",
|
||||
"before": "light",
|
||||
"after": "light",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "fontScale",
|
||||
"before": "large",
|
||||
"after": "large",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "levelVolume",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "liveAudioIOS",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "parallelSaves",
|
||||
"before": 2,
|
||||
"after": 2,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "density",
|
||||
"before": "compact",
|
||||
"after": "compact",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "perfMode",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "reduceMotion",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "layout",
|
||||
"before": "f7-swipe",
|
||||
"after": "f7-swipe",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupEnabled",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupIntervalDays",
|
||||
"before": 7,
|
||||
"after": 7,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "serviceVideo",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "foldedCards",
|
||||
"before": {},
|
||||
"after": {},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "eq",
|
||||
"before": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"after": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
}
|
||||
],
|
||||
"old": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"oldUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"oldRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newTag": "00d7fed5abcb",
|
||||
"upgraded": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"newRaw": "{\"playlists\":[],\"history\":[{\"id\":\"benchmedia01\",\"title\":\"Persisted settings local clip\",\"channel\":\"Settings probe\",\"channelId\":\"\",\"channelUrl\":\"\",\"duration\":3,\"thumbnail\":\"\"}],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{\"benchmedia01\":1},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"profile\":null}",
|
||||
"newUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"importPreserved": true,
|
||||
"userDataGets": 0
|
||||
},
|
||||
{
|
||||
"engine": "webkit",
|
||||
"errors": [],
|
||||
"profileChecks": [
|
||||
{
|
||||
"stage": "older timestamp ignored",
|
||||
"serverUpdatedAt": 100,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": true
|
||||
},
|
||||
{
|
||||
"stage": "older settings with newer timestamp adopted",
|
||||
"serverUpdatedAt": 300,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": false
|
||||
}
|
||||
],
|
||||
"behaviour": [
|
||||
{
|
||||
"stage": "old",
|
||||
"supported": false,
|
||||
"note": "Native OPFS unavailable; no shim"
|
||||
},
|
||||
{
|
||||
"stage": "upgraded",
|
||||
"supported": false,
|
||||
"note": "Native OPFS unavailable; no shim"
|
||||
}
|
||||
],
|
||||
"diff": [
|
||||
{
|
||||
"key": "quality",
|
||||
"before": "360p",
|
||||
"after": "360p",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "volume",
|
||||
"before": 1,
|
||||
"after": 1,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "audioOnly",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoPreload",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pShare",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pReceive",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "saveBeforePlay",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "repeatMode",
|
||||
"before": "all",
|
||||
"after": "all",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "loopOne",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "shuffle",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "theme",
|
||||
"before": "light",
|
||||
"after": "light",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "fontScale",
|
||||
"before": "large",
|
||||
"after": "large",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "levelVolume",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "liveAudioIOS",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "parallelSaves",
|
||||
"before": 2,
|
||||
"after": 2,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "density",
|
||||
"before": "compact",
|
||||
"after": "compact",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "perfMode",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "reduceMotion",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "layout",
|
||||
"before": "f7-swipe",
|
||||
"after": "f7-swipe",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupEnabled",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupIntervalDays",
|
||||
"before": 7,
|
||||
"after": 7,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "serviceVideo",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "foldedCards",
|
||||
"before": {},
|
||||
"after": {},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "eq",
|
||||
"before": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"after": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
}
|
||||
],
|
||||
"old": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"oldUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"oldRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newTag": "00d7fed5abcb",
|
||||
"upgraded": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"newRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"importPreserved": true,
|
||||
"userDataGets": 0
|
||||
}
|
||||
],
|
||||
"failures": [],
|
||||
"unsupported": [
|
||||
"webkit",
|
||||
"webkit"
|
||||
]
|
||||
}
|
||||
708
perf/results/settings-persist.json
Normal file
708
perf/results/settings-persist.json
Normal file
@@ -0,0 +1,708 @@
|
||||
{
|
||||
"revision": "cf27d4f15a29747123437862ab4e461fd78178e6",
|
||||
"oldTag": "1175f1a1d2c1",
|
||||
"results": [
|
||||
{
|
||||
"engine": "chromium",
|
||||
"errors": [
|
||||
"Cannot read properties of null (reading 'addEventListener')",
|
||||
"Cannot read properties of null (reading 'addEventListener')"
|
||||
],
|
||||
"profileChecks": [
|
||||
{
|
||||
"stage": "older timestamp ignored",
|
||||
"serverUpdatedAt": 100,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": true
|
||||
},
|
||||
{
|
||||
"stage": "older settings with newer timestamp adopted",
|
||||
"serverUpdatedAt": 300,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": false
|
||||
}
|
||||
],
|
||||
"behaviour": [
|
||||
{
|
||||
"stage": "old",
|
||||
"supported": true,
|
||||
"bytes": 30290,
|
||||
"cached": true,
|
||||
"localPlayback": true
|
||||
},
|
||||
{
|
||||
"stage": "upgraded",
|
||||
"supported": true,
|
||||
"bytes": 30290,
|
||||
"cached": true,
|
||||
"localPlayback": true
|
||||
}
|
||||
],
|
||||
"diff": [
|
||||
{
|
||||
"key": "quality",
|
||||
"before": "360p",
|
||||
"after": "360p",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "volume",
|
||||
"before": 1,
|
||||
"after": 1,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "audioOnly",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoPreload",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pShare",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pReceive",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "saveBeforePlay",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "repeatMode",
|
||||
"before": "all",
|
||||
"after": "all",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "loopOne",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "shuffle",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "theme",
|
||||
"before": "light",
|
||||
"after": "light",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "fontScale",
|
||||
"before": "large",
|
||||
"after": "large",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "levelVolume",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "liveAudioIOS",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "parallelSaves",
|
||||
"before": 2,
|
||||
"after": 2,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "density",
|
||||
"before": "compact",
|
||||
"after": "compact",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "perfMode",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "reduceMotion",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "layout",
|
||||
"before": "f7-swipe",
|
||||
"after": "f7-swipe",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupEnabled",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupIntervalDays",
|
||||
"before": 7,
|
||||
"after": 7,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "serviceVideo",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "foldedCards",
|
||||
"before": {},
|
||||
"after": {},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "eq",
|
||||
"before": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"after": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
}
|
||||
],
|
||||
"old": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"oldUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"oldRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newTag": "ad9d32e3feb3",
|
||||
"upgraded": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"newRaw": "{\"playlists\":[],\"history\":[{\"id\":\"benchmedia01\",\"title\":\"Persisted settings local clip\",\"channel\":\"Settings probe\",\"channelId\":\"\",\"channelUrl\":\"\",\"duration\":3,\"thumbnail\":\"\"}],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{\"benchmedia01\":1},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"profile\":null}",
|
||||
"newUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"importPreserved": true,
|
||||
"userDataGets": 0
|
||||
},
|
||||
{
|
||||
"engine": "webkit",
|
||||
"errors": [],
|
||||
"profileChecks": [
|
||||
{
|
||||
"stage": "older timestamp ignored",
|
||||
"serverUpdatedAt": 100,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": true
|
||||
},
|
||||
{
|
||||
"stage": "older settings with newer timestamp adopted",
|
||||
"serverUpdatedAt": 300,
|
||||
"localSyncedAt": 200,
|
||||
"saveBeforePlay": false
|
||||
}
|
||||
],
|
||||
"behaviour": [
|
||||
{
|
||||
"stage": "old",
|
||||
"supported": false,
|
||||
"note": "Native OPFS unavailable; no shim"
|
||||
},
|
||||
{
|
||||
"stage": "upgraded",
|
||||
"supported": false,
|
||||
"note": "Native OPFS unavailable; no shim"
|
||||
}
|
||||
],
|
||||
"diff": [
|
||||
{
|
||||
"key": "quality",
|
||||
"before": "360p",
|
||||
"after": "360p",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "volume",
|
||||
"before": 1,
|
||||
"after": 1,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "audioOnly",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoPreload",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pShare",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "p2pReceive",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "saveBeforePlay",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "repeatMode",
|
||||
"before": "all",
|
||||
"after": "all",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "loopOne",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "shuffle",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "theme",
|
||||
"before": "light",
|
||||
"after": "light",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "fontScale",
|
||||
"before": "large",
|
||||
"after": "large",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "levelVolume",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "liveAudioIOS",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "parallelSaves",
|
||||
"before": 2,
|
||||
"after": 2,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "density",
|
||||
"before": "compact",
|
||||
"after": "compact",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "perfMode",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "reduceMotion",
|
||||
"before": true,
|
||||
"after": true,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "layout",
|
||||
"before": "f7-swipe",
|
||||
"after": "f7-swipe",
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupEnabled",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "autoBackupIntervalDays",
|
||||
"before": 7,
|
||||
"after": 7,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "serviceVideo",
|
||||
"before": false,
|
||||
"after": false,
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "foldedCards",
|
||||
"before": {},
|
||||
"after": {},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
},
|
||||
{
|
||||
"key": "eq",
|
||||
"before": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"after": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
},
|
||||
"equal": true,
|
||||
"expectedMigration": false
|
||||
}
|
||||
],
|
||||
"old": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"oldUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"oldRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newTag": "ad9d32e3feb3",
|
||||
"upgraded": {
|
||||
"quality": "360p",
|
||||
"volume": 1,
|
||||
"audioOnly": false,
|
||||
"autoPreload": true,
|
||||
"p2pShare": true,
|
||||
"p2pReceive": true,
|
||||
"saveBeforePlay": true,
|
||||
"repeatMode": "all",
|
||||
"loopOne": true,
|
||||
"shuffle": false,
|
||||
"theme": "light",
|
||||
"fontScale": "large",
|
||||
"levelVolume": false,
|
||||
"liveAudioIOS": false,
|
||||
"parallelSaves": 2,
|
||||
"density": "compact",
|
||||
"perfMode": true,
|
||||
"reduceMotion": true,
|
||||
"layout": "f7-swipe",
|
||||
"autoBackupEnabled": false,
|
||||
"autoBackupIntervalDays": 7,
|
||||
"serviceVideo": false,
|
||||
"foldedCards": {},
|
||||
"eq": {
|
||||
"preset": "bass",
|
||||
"g": [
|
||||
5,
|
||||
7,
|
||||
5,
|
||||
3,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
}
|
||||
},
|
||||
"newRaw": "{\"playlists\":[],\"history\":[],\"queue\":[],\"customVideos\":[],\"pinnedPlaylists\":[],\"settings\":{\"quality\":\"360p\",\"volume\":1,\"audioOnly\":false,\"autoPreload\":true,\"p2pShare\":true,\"p2pReceive\":true,\"saveBeforePlay\":true,\"repeatMode\":\"all\",\"loopOne\":true,\"shuffle\":false,\"theme\":\"light\",\"fontScale\":\"large\",\"levelVolume\":false,\"liveAudioIOS\":false,\"parallelSaves\":2,\"density\":\"compact\",\"perfMode\":true,\"reduceMotion\":true,\"layout\":\"f7-swipe\",\"autoBackupEnabled\":false,\"autoBackupIntervalDays\":7,\"serviceVideo\":false,\"foldedCards\":{},\"eq\":{\"preset\":\"bass\",\"g\":[5,7,5,3,1,0,0,0,0,0]}},\"resumePositions\":{},\"rememberPos\":{},\"playCount\":{},\"abMarkers\":{},\"bookmarks\":{},\"lyricOffsets\":{},\"stats\":null,\"lastAutoBackup\":0,\"profile\":null}",
|
||||
"newUI": {
|
||||
"setSaveBeforePlay": true,
|
||||
"setAutoPreload": true,
|
||||
"setAudioOnly": false,
|
||||
"setQuality": "360p",
|
||||
"setRepeat": true,
|
||||
"setLoopOne": true,
|
||||
"setTheme": "light",
|
||||
"setFont": "large",
|
||||
"setDensity": "compact",
|
||||
"setPerf": true,
|
||||
"setMotion": true,
|
||||
"setParallelSaves": "2",
|
||||
"setLevelVolume": false,
|
||||
"setLayout": "f7-swipe"
|
||||
},
|
||||
"importPreserved": true,
|
||||
"userDataGets": 0
|
||||
}
|
||||
],
|
||||
"failures": [],
|
||||
"unsupported": [
|
||||
"webkit",
|
||||
"webkit"
|
||||
]
|
||||
}
|
||||
82
perf/settings-persist.mjs
Normal file
82
perf/settings-persist.mjs
Normal file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env node
|
||||
// Existing-install migration and profile/import settings gate; all servers and media stay local.
|
||||
import assert from 'node:assert/strict';
|
||||
import {spawn,execFileSync} from 'node:child_process';
|
||||
import {mkdtempSync,mkdirSync,writeFileSync,readFileSync,symlinkSync,unlinkSync,rmSync,statSync} from 'node:fs';
|
||||
import {join,resolve} from 'node:path';
|
||||
import {createServer} from 'node:net';
|
||||
import {createServer as createHttpServer, request as httpRequest} from 'node:http';
|
||||
import {createRequire} from 'node:module';
|
||||
import {chromium,webkit} from 'playwright';
|
||||
const repo=resolve(import.meta.dirname,'..'),args=process.argv.slice(2);
|
||||
const opt=(k,d)=>args.includes(k)?args[args.indexOf(k)+1]:d;
|
||||
const oldTag='1175f1a1d2c1',target=opt('--target','main'),engine=opt('--browser','all');
|
||||
assert.ok(['all','chromium','webkit'].includes(engine));
|
||||
execFileSync('bash',[join(repo,'perf/make-shell-fixture.sh'),'b77938a',oldTag],{cwd:repo,stdio:'inherit'});
|
||||
const scratch=mkdtempSync(join(repo,'perf/.tmp/settings-'));
|
||||
function archive(rev,dest){mkdirSync(dest,{recursive:true});const tar=join(dest,'source.tar');writeFileSync(tar,execFileSync('git',['archive',rev,'frontend','server'],{cwd:repo,maxBuffer:40*1024*1024}));execFileSync('tar',['-xf',tar,'-C',dest]);symlinkSync(join(repo,'server/node_modules'),join(dest,'server/node_modules'));}
|
||||
const revision=execFileSync('git',['rev-parse',target],{cwd:repo,encoding:'utf8'}).trim();
|
||||
archive('b77938a',join(scratch,'old'));archive(revision,join(scratch,'new'));
|
||||
symlinkSync(join(repo,'perf/fixtures/shell-'+oldTag),join(scratch,'old/server/public'));
|
||||
symlinkSync(join(scratch,'new/frontend'),join(scratch,'new/server/public'));
|
||||
const results={revision,oldTag,results:[],failures:[],unsupported:[]};
|
||||
const sleep=ms=>new Promise(r=>setTimeout(r,ms));
|
||||
async function poll(fn,timeout=90000){const until=Date.now()+timeout;while(Date.now()<until){if(await fn())return;await sleep(100);}throw Error('Condition timed out');}
|
||||
const ui={saveBeforePlay:['setSaveBeforePlay',true],autoPreload:['setAutoPreload',true],audioOnly:['setAudioOnly',false],quality:['setQuality','360p'],repeatMode:['setRepeat',true],loopOne:['setLoopOne',true],theme:['setTheme','light'],fontScale:['setFont','large'],density:['setDensity','compact'],perfMode:['setPerf',true],reduceMotion:['setMotion',true],parallelSaves:['setParallelSaves','2'],levelVolume:['setLevelVolume',false],layout:['setLayout','f7-swipe']};
|
||||
async function run(name){
|
||||
const cwd=join(scratch,name);mkdirSync(cwd);mkdirSync(join(cwd,'media'));
|
||||
const sock=createServer();await new Promise(r=>sock.listen(0,'127.0.0.1',r));const port=sock.address().port;await new Promise(r=>sock.close(r));let origin='http://127.0.0.1:'+port;
|
||||
let child,browser,proxy,profileReply=null,userDataGets=0,log='';
|
||||
const result={engine:name,errors:[],profileChecks:[],behaviour:[],diff:[]};results.results.push(result);
|
||||
async function stop(){if(!child)return;const c=child;child=null;if(c.exitCode===null){c.kill('SIGTERM');await new Promise(r=>c.once('exit',r));}}
|
||||
async function start(old){symlinkSync(old?join(repo,'perf/fixtures/shell-'+oldTag):join(scratch,'new/frontend'),join(cwd,'public'));child=spawn('bun',[join(scratch,old?'old':'new','server/server.js')],{cwd,env:{...process.env,PORT:String(port),DB_PATH:join(cwd,'db.sqlite'),MEDIA_DIR:join(cwd,'media'),UPLOAD_DIR:join(cwd,'uploads'),DATA_DIR:join(cwd,'data'),ASSET_HASHING:old?'0':'1',ASSET_SYNC:old?'0':'1',BUILD_TAG:''},stdio:['ignore','pipe','pipe']});for(const s of [child.stdout,child.stderr])s.on('data',c=>log=(log+c).slice(-5000));await poll(async()=>{if(child.exitCode!==null)throw Error(log);try{return(await fetch(origin+'/api/version')).ok;}catch{return false;}});}
|
||||
try{
|
||||
await start(true);
|
||||
const clip={id:'benchmedia01',title:'Persisted settings local clip',channel:'Settings probe',duration:3,thumbnail:''};
|
||||
const mp4=join(cwd,'media',clip.id+'.1.mp4');execFileSync('ffmpeg',['-y','-f','lavfi','-i','color=c=blue:s=160x90:r=10:d=3','-f','lavfi','-i','sine=frequency=440:duration=3','-c:v','libx264','-pix_fmt','yuv420p','-c:a','aac','-movflags','+faststart','-shortest',mp4],{stdio:'ignore'});
|
||||
execFileSync('ffmpeg',['-y','-i',mp4,'-vn','-c:a','copy',join(cwd,'media',clip.id+'.1.m4a')],{stdio:'ignore'});
|
||||
const require=createRequire(import.meta.url),{createClient}=require(join(repo,'server/node_modules/@libsql/client'));
|
||||
const db=createClient({url:'file:'+join(cwd,'db.sqlite')});await db.execute({sql:'INSERT OR REPLACE INTO media_cache (video_id,status,gen,size,height,vcodec,acodec,duration,meta,last_access) VALUES (?,?,?,?,?,?,?,?,?,?)',args:[clip.id,'ready',1,statSync(mp4).size,90,'h264','aac',3,JSON.stringify(clip),Date.now()]});db.close();
|
||||
browser=await({chromium,webkit}[name]).launch({headless:true});const context=await browser.newContext({viewport:{width:414,height:896}});
|
||||
// Server-side mocks also cover WebKit worker-owned fetches, which bypass page routing.
|
||||
proxy=createHttpServer((req,res)=>{
|
||||
const pathname=new URL(req.url,'http://local').pathname;
|
||||
if(pathname==='/api/user/data'){userDataGets++;res.setHeader('Content-Type','application/json');res.end(JSON.stringify({ok:true,data:{settings:{saveBeforePlay:false}}}));return;}
|
||||
if(pathname==='/api/profile/load'&&profileReply){res.setHeader('Cache-Control','no-store');res.setHeader('Content-Type','application/json');res.end(JSON.stringify(profileReply));return;}
|
||||
if(pathname==='/api/profile/save'){res.setHeader('Content-Type','application/json');res.end(JSON.stringify({ok:false,error:'probe blocks writes'}));return;}
|
||||
const upstream=httpRequest({hostname:'127.0.0.1',port,path:req.url,method:req.method,headers:req.headers},r=>{res.writeHead(r.statusCode,r.headers);r.pipe(res);});upstream.on('error',()=>{res.statusCode=503;res.end();});req.pipe(upstream);
|
||||
});await new Promise(r=>proxy.listen(0,'127.0.0.1',r));origin='http://127.0.0.1:'+proxy.address().port;
|
||||
await context.route('**/*',route=>route.request().url().startsWith(origin)?route.continue():route.abort());
|
||||
const page=await context.newPage();page.on('pageerror',e=>result.errors.push(e.message));
|
||||
const boot=async()=>{await page.goto(origin);await page.waitForFunction(()=>typeof data!=='undefined'&&document.querySelector('#sidebarToggle'));await page.waitForTimeout(800);};
|
||||
const settings=()=>page.evaluate(()=>JSON.parse(localStorage.getItem('_ytpdata')).settings);
|
||||
const openSettings=async()=>{await page.locator('[data-view="settings"]').first().evaluate(e=>e.click());await page.waitForSelector('#setSaveBeforePlay',{state:'attached'});};
|
||||
const readUI=()=>page.evaluate(ids=>Object.fromEntries(ids.map(id=>{const e=document.getElementById(id);return[id,e.type==='checkbox'?e.checked:e.value];})),Object.values(ui).map(x=>x[0]));
|
||||
await boot();await page.waitForFunction(()=>!!navigator.serviceWorker.controller);
|
||||
await openSettings();
|
||||
for(const [key,[id,value]]of Object.entries(ui)){await page.locator('#'+id).evaluate((e,value)=>{if(e.type==='checkbox')e.checked=value;else e.value=value;e.dispatchEvent(new Event('change',{bubbles:true}));},value);}
|
||||
await page.evaluate(()=>EQ.open());await page.waitForSelector('[data-preset="bass"]',{state:'attached'});await page.locator('[data-preset="bass"]').click();await page.evaluate(()=>closeModal());await sleep(600);
|
||||
await boot();await openSettings();result.old=await settings();result.oldUI=await readUI();result.oldRaw=await page.evaluate(()=>localStorage.getItem('_ytpdata'));
|
||||
async function behaviour(stage){const supported=await page.evaluate(()=>OPFS.isSupported());if(!supported){result.behaviour.push({stage,supported:false,note:'Native OPFS unavailable; no shim'});results.unsupported.push(name);return;}
|
||||
await page.evaluate(async id=>{await OPFS.deleteVideo(id);cachedIds.delete(id);Player.pause();},clip.id);
|
||||
await page.evaluate(clip=>Player.loadVideo(clip),clip);await page.waitForFunction(id=>cachedIds.has(id)&&!!current?.localUrl,clip.id,{timeout:20000});
|
||||
const state=await page.evaluate(async id=>({cached:cachedIds.has(id),files:await OPFS.listVideos(),localUrl:current.localUrl,src:Player.master?.src}),clip.id);assert.equal(state.files.find(f=>f.id===clip.id)?.size,statSync(mp4).size);assert.ok(state.src?.startsWith('blob:'),'player must use OPFS blob');await page.waitForFunction(()=>Player.master?.readyState>=3);await page.evaluate(()=>Player.play());await page.waitForFunction(()=>Player.master?.currentTime>0);await page.evaluate(()=>Player.pause());result.behaviour.push({stage,supported:true,bytes:state.files.find(f=>f.id===clip.id).size,cached:true,localPlayback:true});}
|
||||
await behaviour('old');console.log(name,'old settings and save verified');await page.evaluate(()=>Player.pause());
|
||||
await stop();unlinkSync(join(cwd,'public'));await start(false);result.newTag=(await(await fetch(origin+'/api/version')).json()).buildTag;
|
||||
await page.evaluate(async()=>{await checkBuildTag();await(await navigator.serviceWorker.getRegistration()).update();});await poll(()=>page.evaluate(async()=>!!(await navigator.serviceWorker.getRegistration())?.waiting));
|
||||
await page.waitForFunction(()=>!document.getElementById('modal').classList.contains('hidden')&&/Update available/.test(document.getElementById('modalTitle').textContent));
|
||||
await page.locator('#modal').getByRole('button',{name:'Refresh UI',exact:true}).evaluate(e=>e.click());await page.waitForFunction(tag=>document.querySelector('meta[name="ytp-build"]')?.content===tag,result.newTag,{timeout:90000});await sleep(1000);await openSettings();
|
||||
console.log(name,'real Refresh UI completed');result.upgraded=await settings();result.newRaw=await page.evaluate(()=>localStorage.getItem('_ytpdata'));result.newUI=await readUI();assert.deepEqual(result.newUI,result.oldUI,'checkbox/select values preserved');
|
||||
const {migrate}=require(join(scratch,'new/frontend/eq-parameters.js'));const expected=structuredClone(result.old);if(expected.eq?.g?.length===5)expected.eq.g=migrate(expected.eq.g);
|
||||
for(const key of new Set([...Object.keys(result.old),...Object.keys(result.upgraded)]))result.diff.push({key,before:result.old[key],after:result.upgraded[key],equal:JSON.stringify(result.old[key])===JSON.stringify(result.upgraded[key]),expectedMigration:key==='eq'&&result.old.eq?.g?.length===5});
|
||||
assert.deepEqual(result.upgraded,expected,'all persisted settings preserved except deliberate 5→10 EQ migration');await behaviour('upgraded');
|
||||
const local=await settings(),remote={...local,saveBeforePlay:false,autoPreload:false,layout:'classic',quality:'auto'};
|
||||
async function profileCheck(updatedAt,expectedSave,stage){profileReply={ok:true,name:'probe',updatedAt,data:{settings:remote,playlists:[]}};await page.evaluate(s=>{data.settings=s;data.profile={name:'probe',syncedAt:200};localStorage.setItem('_ytpdata',JSON.stringify(data));},local);await boot();await page.waitForFunction(()=>_syncBusy===0);await openSettings();const s=await settings();assert.equal(s.saveBeforePlay,expectedSave);assert.equal(await page.locator('#setSaveBeforePlay').isChecked(),expectedSave);if(!expectedSave)assert.equal(s.layout,'classic');else assert.deepEqual(s,local);result.profileChecks.push({stage,serverUpdatedAt:updatedAt,localSyncedAt:200,saveBeforePlay:s.saveBeforePlay});}
|
||||
await profileCheck(100,true,'older timestamp ignored');await profileCheck(300,false,'older settings with newer timestamp adopted');
|
||||
profileReply=null;await page.evaluate(s=>{data.profile=null;data.settings=s;localStorage.setItem('_ytpdata',JSON.stringify(data));},local);await boot();await openSettings();
|
||||
await page.locator('#backupFileInput').setInputFiles({name:'settings-probe.json',mimeType:'application/json',buffer:Buffer.from(JSON.stringify({playlists:[],settings:remote}))});await page.waitForFunction(()=>document.getElementById('modalTitle').textContent==='Import backup?');await page.locator('#modal').getByRole('button',{name:'Import',exact:true}).evaluate(e=>e.click());await sleep(600);assert.deepEqual(await settings(),local,'backup import does not replace settings');result.importPreserved=true;result.userDataGets=userDataGets;assert.equal(userDataGets,0,'boot does not pull settings from fingerprint user-data endpoint');
|
||||
console.log(name,JSON.stringify({keys:result.diff.length,changed:result.diff.filter(x=>!x.equal),behaviour:result.behaviour,profileChecks:result.profileChecks,importPreserved:result.importPreserved,errors:result.errors}));
|
||||
}finally{await browser?.close();await stop();if(proxy){proxy.closeAllConnections();await new Promise(r=>proxy.close(r));}}
|
||||
}
|
||||
try{for(const name of ['chromium','webkit'])if(engine==='all'||engine===name){try{await run(name);}catch(e){results.failures.push({engine:name,error:e.stack});console.error(name,e.message);}}}finally{const out=resolve(opt('--out','perf/results/settings-persist.json'));mkdirSync(resolve(out,'..'),{recursive:true});writeFileSync(out,JSON.stringify(results,null,2)+'\n');rmSync(scratch,{recursive:true,force:true});}
|
||||
if(results.failures.length)process.exitCode=1;else if(results.unsupported.length&&!args.includes('--allow-unsupported-webkit')){console.error('Native WebKit OPFS unverified; use --allow-unsupported-webkit for persistence/UI coverage');process.exitCode=2;}
|
||||
Reference in New Issue
Block a user