Improve script URL ecoding
added some magic to get scripts to efficiently encoded into the URL. We're using pako to compress the script, but this outputs to a 8bit array. Stringifying this array adds a lot of overhead, because "125" has three characters in it. Instead we're using the character codes to turn these a bit numbers into single characters base64 is used as well because not all of the characters are allowed in a url (and b64 is better than encodeURIComponent).
This commit is contained in:
@@ -4,11 +4,13 @@ import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
||||
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
|
||||
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||
import { encode, decode } from 'src/helpers/compress'
|
||||
|
||||
export const IdeContext = createContext()
|
||||
const IdeToolbarNew = ({ cadPackage }) => {
|
||||
const [state, thunkDispatch] = useIdeState()
|
||||
const scriptKey = 'encoded_script'
|
||||
const scriptKeyV2 = 'encoded_script_v2'
|
||||
useEffect(() => {
|
||||
thunkDispatch({
|
||||
type: 'initIde',
|
||||
@@ -19,9 +21,12 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
||||
if (isBrowser) {
|
||||
hash = window.location.hash
|
||||
}
|
||||
const [key, scriptBase64] = hash.slice(1).split('=')
|
||||
const [key, encodedScript] = hash.slice(1).split('=')
|
||||
if (key === scriptKey) {
|
||||
const script = atob(scriptBase64)
|
||||
const script = atob(encodedScript)
|
||||
thunkDispatch({ type: 'updateCode', payload: script })
|
||||
} else if (key === scriptKeyV2) {
|
||||
const script = decode(encodedScript)
|
||||
thunkDispatch({ type: 'updateCode', payload: script })
|
||||
}
|
||||
window.location.hash = ''
|
||||
@@ -43,8 +48,8 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
||||
}
|
||||
function handleMakeLink() {
|
||||
if (isBrowser) {
|
||||
const scriptBase64 = btoa(state.code)
|
||||
window.location.hash = `encoded_script=${scriptBase64}`
|
||||
const encodedScript = encode(state.code)
|
||||
window.location.hash = `${scriptKeyV2}=${encodedScript}`
|
||||
copyTextToClipboard(window.location.href)
|
||||
}
|
||||
}
|
||||
|
||||
21
app/web/src/helpers/compress.ts
Normal file
21
app/web/src/helpers/compress.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { inflate, deflate } from 'pako'
|
||||
|
||||
/*
|
||||
some magic to get scripts to efficiently encoded into the URL.
|
||||
We're using pako to compress the script, but this outputs to a 8bit array. Stringifying this array adds a lot of overhead, because "125" has three characters in it
|
||||
Instead we're using the character codes to turn these a bit numbers into single characters
|
||||
base64 is used as well because not all of the characters are allowed in a url (and b64 is better than encodeURIComponent)
|
||||
*/
|
||||
|
||||
export const encode = (string: string): string =>
|
||||
btoa(String.fromCharCode.apply(null, deflate(string)))
|
||||
|
||||
export const decode = (string: string): string =>
|
||||
inflate(
|
||||
new Uint8Array(
|
||||
atob(string)
|
||||
.split('')
|
||||
.map((character) => character.charCodeAt(0))
|
||||
),
|
||||
{ to: 'string' }
|
||||
)
|
||||
Reference in New Issue
Block a user