tangled
alpha
login
or
join now
tylur.dev
/
prototypey
prototypey.org - atproto lexicon typescript toolkit - mirror https://github.com/tylersayshi/prototypey
1
fork
atom
overview
issues
pulls
pipelines
custom parser
Tyler
3 months ago
00eaf1ac
ea22340a
+35
-18
2 changed files
expand all
collapse all
unified
split
packages
site
src
components
Playground.tsx
utils
parsers.ts
+4
-18
packages/site/src/components/Playground.tsx
···
4
4
import { lx } from "prototypey";
5
5
import { useMonaco } from "@monaco-editor/react";
6
6
import type * as Monaco from "monaco-editor";
7
7
-
import { parseAsString, useQueryState } from "nuqs";
8
8
-
import LZString from "lz-string";
7
7
+
import { useQueryState } from "nuqs";
9
8
import MonacoEditor from "@monaco-editor/react";
9
9
+
import { parseAsCompressed } from "../utils/parsers";
10
10
11
11
let tsWorkerInstance: Monaco.languages.typescript.TypeScriptWorker | null =
12
12
null;
13
13
14
14
export function Playground() {
15
15
-
const [compressedCode, setCompressedCode] = useQueryState(
15
15
+
const [code, setCode] = useQueryState(
16
16
"code",
17
17
-
parseAsString.withDefault(""),
17
17
+
parseAsCompressed.withDefault(DEFAULT_CODE),
18
18
);
19
19
-
20
20
-
const initialCode =
21
21
-
compressedCode && compressedCode.trim() !== ""
22
22
-
? LZString.decompressFromEncodedURIComponent(compressedCode) ||
23
23
-
DEFAULT_CODE
24
24
-
: DEFAULT_CODE;
25
25
-
26
26
-
const [code, setCode] = useState(initialCode);
27
19
const [output, setOutput] = useState({ json: "", typeInfo: "", error: "" });
28
20
const [editorReady, setEditorReady] = useState(false);
29
21
const [theme, setTheme] = useState<"vs-light" | "vs-dark">(
···
37
29
38
30
const handleCodeChange = (newCode: string) => {
39
31
setCode(newCode);
40
40
-
// Compress and update URL
41
41
-
const compressed = LZString.compressToEncodedURIComponent(newCode);
42
42
-
setCompressedCode(compressed);
43
32
};
44
33
45
34
const handleEditorReady = () => {
···
249
238
theme: "vs-light" | "vs-dark";
250
239
}) {
251
240
// Calculate line counts to size editors appropriately
252
252
-
const codeLines = code.split("\n").length;
253
253
-
const jsonLines = json.split("\n").length;
254
254
-
255
241
const estimateWrappedLines = (text: string, maxCharsPerLine: number) => {
256
242
return text.split("\n").reduce((total, line) => {
257
243
const wrappedLines = Math.ceil(
+31
packages/site/src/utils/parsers.ts
···
1
1
+
import { createParser } from "nuqs";
2
2
+
import LZString from "lz-string";
3
3
+
4
4
+
/**
5
5
+
* Custom nuqs parser for LZ-string compressed values
6
6
+
*
7
7
+
* This parser automatically compresses values when serializing to URL
8
8
+
* and decompresses when parsing from URL, keeping URLs shorter for large data.
9
9
+
*/
10
10
+
export const parseAsCompressed = createParser({
11
11
+
parse(query: string): string | null {
12
12
+
if (!query || query.trim() === "") {
13
13
+
return null;
14
14
+
}
15
15
+
16
16
+
// Decompress the value from the URL
17
17
+
const decompressed = LZString.decompressFromEncodedURIComponent(query);
18
18
+
19
19
+
// Return null if decompression fails
20
20
+
return decompressed || null;
21
21
+
},
22
22
+
23
23
+
serialize(value: string): string {
24
24
+
// Compress the value for the URL
25
25
+
return LZString.compressToEncodedURIComponent(value);
26
26
+
},
27
27
+
28
28
+
eq(a: string, b: string): boolean {
29
29
+
return a === b;
30
30
+
},
31
31
+
});