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:
Kurt Hutten
2021-05-08 09:07:54 +10:00
parent 53985dd250
commit 053b1d642c
5 changed files with 40 additions and 7 deletions

1
app/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
dist

View File

@@ -30,6 +30,7 @@
"monaco-editor-webpack-plugin": "^1.9.1",
"netlify-identity-widget": "^1.9.1",
"opencascade.js": "^0.1.15",
"pako": "^2.0.3",
"prop-types": "^15.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
@@ -44,10 +45,10 @@
"three": "^0.118.3"
},
"devDependencies": {
"postcss": "^8.2.13",
"autoprefixer": "^10.2.5",
"html-webpack-plugin": "^4.5.0",
"opentype.js": "^1.3.3",
"postcss": "^8.2.13",
"postcss-loader": "4.0.2",
"tailwindcss": "^2.1.2",
"worker-loader": "^3.0.7"

View File

@@ -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)
}
}

View 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' }
)

View File

@@ -11816,6 +11816,11 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.3.tgz#cdf475e31b678565251406de9e759196a0ea7a43"
integrity sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==
pako@~1.0.5:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@@ -13134,7 +13139,7 @@ react-docgen@^5.0.0:
node-dir "^0.1.10"
strip-indent "^3.0.0"
react-dom@17.0.1, react-dom@^17.0.1:
react-dom@^17.0.1:
version "17.0.1"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==
@@ -13367,7 +13372,7 @@ react-use-measure@^2.0.3:
dependencies:
debounce "^1.2.0"
react@17.0.1, react@^17.0.1:
react@^17.0.1:
version "17.0.1"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==