Sharable playground state - #10
Conversation
|
This seems to be OK with excessively large files (though the scrolling seems to be broken in the editor so I won't demo that now). We will generate "pretty" URLs for the builtin examples. |
|
Thanks a lot, Jacob! 🎉 Would it make sense to spell out the query parameters and move the payload into the URL fragment after the hash ( /playground?version=0&compressed=false#<payload>This would make the parameters more self-describing and keep the payload separate from the format options. For the compression flag, I would prefer Would it also make sense to add an optional |
I would typically agree, but these parameters relate directly to the payload, rather than to the page, and I am think that making their meaning clearer would cause more harm as they are not meant to be user specified or read by users. They are completely dependent on the payload, so changing one without updating the other would break things. The only reason that they are not included in the hash themselves is so that they can talk about the encoding method used. Perhaps these could be prepended to the hash rather than stored as separate query parameters? Then that might avoid any confusion (particularly if we wanted to use query parameters that actually do effect the page e.g. we might want
Yes - though we don't support this yet. |
|
What about something like |
Those are good points. I like the idea of putting the current payload-related parameters—version and compression—in the URL fragment together with the payload.
I agree that this separation makes sense. Furthermore, I see three categories of information:
For example, in /playground?embed=true#<encoded-envelope>
{
"format_version": 1,
"compression": "deflate-raw",
"payload": "H4sIAJc5jGoC_6tW..."
}The {
"purepy_version": "1.0",
"entry_point": "main.py",
"files": [
{
"path": "main.py",
"data": "print('Hello')"
}
]
} |
…ms, encode version in first byte of the hash, drop separate compression configuration
Deploying purepy with
|
| Latest commit: |
5c589ce
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://18d50373.purepy.pages.dev |
| Branch Preview URL: | https://playground-sharable.purepy.pages.dev |
|
@antstei I have updated to use the URL fragment/hash like you suggested. I believe this has the advantage that the information is never sent across the wire i.e. it lives only in the URL bar, which is nice. I have removed the To reduce confusion, rather than keeping the version number as a separate parameter, it is prepended to the Uint8Array before it is base64 encoded. The share URL now looks like: If you are happy, I would like to merge this, and address any other concerns/improvements in a future PR. |
|
I have added a |
| @@ -0,0 +1,96 @@ | |||
| // The state is encoded in the URL hash fragment as: | |||
| // /playground#e215OiBvYmplY3QgaXMgdm... | |||
There was a problem hiding this comment.
/playground#share=AKtWSsvM...Sqja0FAA, since we added the share URL parameter.
| export const decode_state = async ( | ||
| version: Version, | ||
| payload: Uint8Array<ArrayBuffer>, | ||
| ) => { | ||
| const raw_bytes = await inflate_bytes(payload); | ||
| const object = bytes_to_object(raw_bytes); | ||
| return SharableState.parse(object); | ||
| }; |
There was a problem hiding this comment.
Maybe we can connect the supported versions, VERSIONS, with their decoder implementations through a decoder map:
const decoders = {
0: async (
payload: Uint8Array<ArrayBuffer>,
): Promise<SharableState> => {
const raw_bytes = await inflate_bytes(payload);
const object = bytes_to_object(raw_bytes);
return SharableState.parse(object);
},
} satisfies Record<
Version,
(payload: Uint8Array<ArrayBuffer>) => Promise<SharableState>
>;
export const decode_state = (
version: Version,
payload: Uint8Array<ArrayBuffer>,
) => {
return decoders[version](payload);
};The satisfies Record<Version, ...> constraint uses compile-time checking to ensure that the decoder map contains an entry for every version represented by the Version type:
VERSIONS: runtime list of versions accepted by the decoder.Version: compile-time union derived fromVERSIONS.VERSION: version used for newly encoded links.decoders: decoder implementation for every supported version represented by theVersiontype.is_valid_version: runtime validation for the numeric byte read from the URL.decode_state: dispatches to the decoder for the validated version.
Use a versioned decoder map with compile-time checks to ensure every supported version has a corresponding decoder implementation.
Adds the bones for sharable state via URL params