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:
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
dist
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
"monaco-editor-webpack-plugin": "^1.9.1",
|
"monaco-editor-webpack-plugin": "^1.9.1",
|
||||||
"netlify-identity-widget": "^1.9.1",
|
"netlify-identity-widget": "^1.9.1",
|
||||||
"opencascade.js": "^0.1.15",
|
"opencascade.js": "^0.1.15",
|
||||||
|
"pako": "^2.0.3",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
@@ -44,10 +45,10 @@
|
|||||||
"three": "^0.118.3"
|
"three": "^0.118.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"postcss": "^8.2.13",
|
|
||||||
"autoprefixer": "^10.2.5",
|
"autoprefixer": "^10.2.5",
|
||||||
"html-webpack-plugin": "^4.5.0",
|
"html-webpack-plugin": "^4.5.0",
|
||||||
"opentype.js": "^1.3.3",
|
"opentype.js": "^1.3.3",
|
||||||
|
"postcss": "^8.2.13",
|
||||||
"postcss-loader": "4.0.2",
|
"postcss-loader": "4.0.2",
|
||||||
"tailwindcss": "^2.1.2",
|
"tailwindcss": "^2.1.2",
|
||||||
"worker-loader": "^3.0.7"
|
"worker-loader": "^3.0.7"
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { isBrowser } from '@redwoodjs/prerender/browserUtils'
|
|||||||
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
|
import { useIdeState, codeStorageKey } from 'src/helpers/hooks/useIdeState'
|
||||||
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
import { copyTextToClipboard } from 'src/helpers/clipboard'
|
||||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||||
|
import { encode, decode } from 'src/helpers/compress'
|
||||||
|
|
||||||
export const IdeContext = createContext()
|
export const IdeContext = createContext()
|
||||||
const IdeToolbarNew = ({ cadPackage }) => {
|
const IdeToolbarNew = ({ cadPackage }) => {
|
||||||
const [state, thunkDispatch] = useIdeState()
|
const [state, thunkDispatch] = useIdeState()
|
||||||
const scriptKey = 'encoded_script'
|
const scriptKey = 'encoded_script'
|
||||||
|
const scriptKeyV2 = 'encoded_script_v2'
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
thunkDispatch({
|
thunkDispatch({
|
||||||
type: 'initIde',
|
type: 'initIde',
|
||||||
@@ -19,9 +21,12 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
|||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
hash = window.location.hash
|
hash = window.location.hash
|
||||||
}
|
}
|
||||||
const [key, scriptBase64] = hash.slice(1).split('=')
|
const [key, encodedScript] = hash.slice(1).split('=')
|
||||||
if (key === scriptKey) {
|
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 })
|
thunkDispatch({ type: 'updateCode', payload: script })
|
||||||
}
|
}
|
||||||
window.location.hash = ''
|
window.location.hash = ''
|
||||||
@@ -43,8 +48,8 @@ const IdeToolbarNew = ({ cadPackage }) => {
|
|||||||
}
|
}
|
||||||
function handleMakeLink() {
|
function handleMakeLink() {
|
||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
const scriptBase64 = btoa(state.code)
|
const encodedScript = encode(state.code)
|
||||||
window.location.hash = `encoded_script=${scriptBase64}`
|
window.location.hash = `${scriptKeyV2}=${encodedScript}`
|
||||||
copyTextToClipboard(window.location.href)
|
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' }
|
||||||
|
)
|
||||||
@@ -11816,6 +11816,11 @@ p-try@^2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
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:
|
pako@~1.0.5:
|
||||||
version "1.0.11"
|
version "1.0.11"
|
||||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
|
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"
|
node-dir "^0.1.10"
|
||||||
strip-indent "^3.0.0"
|
strip-indent "^3.0.0"
|
||||||
|
|
||||||
react-dom@17.0.1, react-dom@^17.0.1:
|
react-dom@^17.0.1:
|
||||||
version "17.0.1"
|
version "17.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
|
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6"
|
||||||
integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==
|
integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug==
|
||||||
@@ -13367,7 +13372,7 @@ react-use-measure@^2.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
debounce "^1.2.0"
|
debounce "^1.2.0"
|
||||||
|
|
||||||
react@17.0.1, react@^17.0.1:
|
react@^17.0.1:
|
||||||
version "17.0.1"
|
version "17.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
|
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
|
||||||
integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==
|
integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w==
|
||||||
|
|||||||
Reference in New Issue
Block a user