prototypey.org - atproto lexicon typescript toolkit - mirror https://github.com/tylersayshi/prototypey

custom parser

Tyler 00eaf1ac ea22340a

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