Conversation
Browser storage is per-origin, so a user landing on web.phcode.dev sees an empty editor while their projects, preferences, theme and extensions stay behind on the old origin, invisible to the new one. On the origin being retired, every boot announces the move with a live countdown to the sunset date. On web.phcode.dev, a hidden iframe pointed at the old origin reports whether anything is worth moving. If there is nothing, absolutely nothing happens - no dialog, no interruption, normal boot. If there is, a progress modal runs the transfer once and sets a flag so it never runs again; after that it only happens if the user asks from Help > Migrate My Data. This works at all because phcode.dev, staging.phcode.dev and web.phcode.dev are the same site (eTLD+1). Browsers partition third party storage by site rather than by origin, so the helper frame is same-site and reads real unpartitioned IndexedDB. Had the new home been on a different registrable domain this would have silently reported "nothing to migrate" everywhere. src/migrateAssist.html is deliberately standalone. It loads only virtualfs.js and jszip.js rather than booting Phoenix, and zips one top level folder at a time so peak memory is one folder rather than the whole filesystem. The receiving side hands each zip to ZipUtils.unzipBinDataToLocation, which writes without unlinking first, so files from the old origin win on collision while files that only exist on the new side survive. That is the collision rule we want, with no extra code. Extensions are copied rather than reinstalled from the registry. Both origins serve the byte identical build, so a folder that worked on one is compatible with the other, and copying also preserves extensions that were sideloaded or have since been unpublished. That page hands out the user's entire browser filesystem to whoever embeds it, so the origin allowlist is exact match only, checked on every message and not just the handshake, replies always go to the validated origin rather than "*", and reads are confined to three known roots. Safari and iOS are out of scope by product decision, not because the mechanism would fail there. Those users still get the dialog, with a line asking them to download projects manually, rather than losing data without being told. Android and ChromeOS users launched from our Trusted Web Activity are offered an app update instead of the new site, because the shipped APK only trusts phcode.dev and navigating it elsewhere surfaces a browser URL bar inside what looks like an app. "Stay here" is a real choice there: managed school fleets can have the Play Store blocked entirely, so the update button may be a dead end through no fault of the user. The legacy origin is staging.phcode.dev while this is validated end to end. Switching it to phcode.dev is a one line change in constants.js.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Browser storage is per-origin, so a user landing on web.phcode.dev sees an empty editor while their projects, preferences, theme and extensions stay behind on the old origin, invisible to the new one.
On the origin being retired, every boot announces the move with a live countdown to the sunset date. On web.phcode.dev, a hidden iframe pointed at the old origin reports whether anything is worth moving. If there is nothing, absolutely nothing happens - no dialog, no interruption, normal boot. If there is, a progress modal runs the transfer once and sets a flag so it never runs again; after that it only happens if the user asks from Help > Migrate My Data.
This works at all because phcode.dev, staging.phcode.dev and web.phcode.dev are the same site (eTLD+1). Browsers partition third party storage by site rather than by origin, so the helper frame is same-site and reads real unpartitioned IndexedDB. Had the new home been on a different registrable domain this would have silently reported "nothing to migrate" everywhere.
src/migrateAssist.html is deliberately standalone. It loads only virtualfs.js and jszip.js rather than booting Phoenix, and zips one top level folder at a time so peak memory is one folder rather than the whole filesystem. The receiving side hands each zip to ZipUtils.unzipBinDataToLocation, which writes without unlinking first, so files from the old origin win on collision while files that only exist on the new side survive. That is the collision rule we want, with no extra code.
Extensions are copied rather than reinstalled from the registry. Both origins serve the byte identical build, so a folder that worked on one is compatible with the other, and copying also preserves extensions that were sideloaded or have since been unpublished.
That page hands out the user's entire browser filesystem to whoever embeds it, so the origin allowlist is exact match only, checked on every message and not just the handshake, replies always go to the validated origin rather than "*", and reads are confined to three known roots.
Safari and iOS are out of scope by product decision, not because the mechanism would fail there. Those users still get the dialog, with a line asking them to download projects manually, rather than losing data without being told.
Android and ChromeOS users launched from our Trusted Web Activity are offered an app update instead of the new site, because the shipped APK only trusts phcode.dev and navigating it elsewhere surfaces a browser URL bar inside what looks like an app. "Stay here" is a real choice there: managed school fleets can have the Play Store blocked entirely, so the update button may be a dead end through no fault of the user.
The legacy origin is staging.phcode.dev while this is validated end to end. Switching it to phcode.dev is a one line change in constants.js.