Skip to content

Commit

Permalink
Run-length + custom dictionary compression for playground query URLs. (
Browse files Browse the repository at this point in the history
…#393)

* Run-length + custom dictionary compression for playground query URLs.

Cuts length to approx. ~60% of prior size. Bigger queries benefit more.

* Implement format switching and upgrade logic.
  • Loading branch information
obi1kenobi authored Jul 26, 2023
1 parent de91110 commit 5eb6aef
Show file tree
Hide file tree
Showing 2 changed files with 387 additions and 10 deletions.
36 changes: 26 additions & 10 deletions experiments/browser_based_querying/src/TrustfallPlayground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,37 @@ import { NumberParam, StringParam, useQueryParams } from 'use-query-params';
import { InPortal, OutPortal, createHtmlPortalNode } from 'react-reverse-portal';

import SimpleDocExplorer from './components/SimpleDocExplorer';
import { decompress, compress } from './urlCompression';

const DEFAULT_ENCODING_FORMAT = 1;
const DEFAULT_ENCODING_FORMAT = 2;
const DEFAULT_QUERY = '';
const DEFAULT_VARS = '{\n\n}';
const DEFAULT_VARS = '{\n \n}';

function decodeFormat(format: number | null, str: string): string | null {
switch (format) {
case 1:
return decodeV1(str);
case 2:
return decodeV2(str);
default:
return decodeV1(str) || decodeV2(str);
}
}

function decodeB64(str: string): string | null {
function decodeV1(str: string): string | null {
try {
return decodeURIComponent(escape(window.atob(str)));
} catch {
return null;
}
}

function encodeB64(str: string): string {
return window.btoa(unescape(encodeURIComponent(str)));
function decodeV2(str: string): string | null {
return decompress(str);
}

function encode(str: string): string {
return compress(str);
}

// Position absolute is necessary to keep the editor from growing constantly on window resize
Expand Down Expand Up @@ -158,14 +174,14 @@ export default function TrustfallPlayground(props: TrustfallPlaygroundProps): JS
q: StringParam, // Query
v: StringParam, // Vars
});
const { q: encodedQuery, v: encodedVars } = queryParams;
const { f: format, q: encodedQuery, v: encodedVars } = queryParams;

// Use useState to grab the first value and cache it (unlike useMemo, which will update)
const [initialQuery, _setInitialQuery] = useState<string>(
() => decodeB64(encodedQuery ?? '') || (exampleQueries[0]?.value[0] ?? DEFAULT_QUERY)
() => decodeFormat(format ?? null, encodedQuery ?? '') || (exampleQueries[0]?.value[0] ?? DEFAULT_QUERY)
);
const [initialVars, _setInitialVars] = useState<string>(
() => decodeB64(encodedVars ?? '') || (exampleQueries[0]?.value[1] ?? DEFAULT_VARS)
() => decodeFormat(format ?? null, encodedVars ?? '') || (exampleQueries[0]?.value[1] ?? DEFAULT_VARS)
);
const [exampleQuery, setExampleQuery] = useState<{
name: string;
Expand Down Expand Up @@ -308,8 +324,8 @@ export default function TrustfallPlayground(props: TrustfallPlaygroundProps): JS
setQueryParams(
{
f: DEFAULT_ENCODING_FORMAT,
q: encodeB64(queryEditor.getValue()),
v: encodeB64(varsEditor.getValue()),
q: encode(queryEditor.getValue()),
v: encode(varsEditor.getValue()),
},
'replaceIn'
);
Expand Down
Loading

0 comments on commit 5eb6aef

Please sign in to comment.