Skip to content

Commit 24443d9

Browse files
committed
fix: improve playground share url compression
1 parent 6c72110 commit 24443d9

File tree

6 files changed

+361
-228
lines changed

6 files changed

+361
-228
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@
266266
"bumpp": "^8.2.1",
267267
"conventional-changelog-cli": "^5.0.0",
268268
"eslint": "^9.39.4",
269+
"fflate": "^0.8.2",
269270
"lint-staged": "^13.3.0",
270271
"lz-string": "^1.5.0",
271272
"markdown-it-emoji": "^3.0.0",

playground-shared/testPageState.ts

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { deflateSync, inflateSync } from 'fflate'
12
import { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from 'lz-string'
23

34
export interface FrameworkTarget {
@@ -14,19 +15,63 @@ export interface LocationLike {
1415
export type TestPageViewMode = 'lab' | 'preview'
1516

1617
const FALLBACK_ORIGIN = 'https://markstream.local'
18+
const RAW_PREFIX = 'raw:'
19+
const DEFLATE_PREFIX = 'z:'
20+
const BASE64_CHUNK_SIZE = 0x8000
21+
22+
function encodeBase64Url(bytes: Uint8Array) {
23+
let binary = ''
24+
for (let index = 0; index < bytes.length; index += BASE64_CHUNK_SIZE)
25+
binary += String.fromCharCode(...bytes.subarray(index, index + BASE64_CHUNK_SIZE))
26+
27+
return btoa(binary)
28+
.replace(/\+/g, '-')
29+
.replace(/\//g, '_')
30+
.replace(/=+$/g, '')
31+
}
32+
33+
function decodeBase64Url(payload: string) {
34+
const normalized = payload
35+
.replace(/-/g, '+')
36+
.replace(/_/g, '/')
37+
.padEnd(payload.length + ((4 - payload.length % 4) % 4), '=')
38+
39+
const binary = atob(normalized)
40+
const bytes = new Uint8Array(binary.length)
41+
for (let index = 0; index < binary.length; index++)
42+
bytes[index] = binary.charCodeAt(index)
43+
44+
return bytes
45+
}
46+
47+
function encodeDeflatedPayload(markdown: string) {
48+
try {
49+
const compressed = deflateSync(new TextEncoder().encode(markdown), { level: 9 })
50+
return `${DEFLATE_PREFIX}${encodeBase64Url(compressed)}`
51+
}
52+
catch {
53+
return ''
54+
}
55+
}
1756

1857
export function isLocalHost(hostname: string) {
1958
return hostname === 'localhost' || hostname === '127.0.0.1'
2059
}
2160

2261
export function encodeMarkdownPayload(markdown: string) {
62+
if (!markdown)
63+
return ''
64+
2365
const encodedRaw = encodeURIComponent(markdown)
24-
const compressed = compressToEncodedURIComponent(markdown)
66+
const rawPayload = `${RAW_PREFIX}${encodedRaw}`
67+
const legacyCompressed = compressToEncodedURIComponent(markdown)
68+
const deflated = encodeDeflatedPayload(markdown)
2569

26-
if (!compressed && !encodedRaw)
70+
const candidates = [rawPayload, legacyCompressed, deflated].filter(Boolean)
71+
if (!candidates.length)
2772
return ''
2873

29-
return (compressed && compressed.length < encodedRaw.length) ? compressed : `raw:${encodedRaw}`
74+
return candidates.reduce((shortest, candidate) => candidate.length < shortest.length ? candidate : shortest)
3075
}
3176

3277
export function createMarkdownHash(markdown: string) {
@@ -40,9 +85,18 @@ export function decodeMarkdownHash(hash: string) {
4085
return null
4186

4287
const payload = matched[1]
43-
if (payload.startsWith('raw:')) {
88+
if (payload.startsWith(RAW_PREFIX)) {
89+
try {
90+
return decodeURIComponent(payload.slice(RAW_PREFIX.length))
91+
}
92+
catch {
93+
return null
94+
}
95+
}
96+
97+
if (payload.startsWith(DEFLATE_PREFIX)) {
4498
try {
45-
return decodeURIComponent(payload.slice(4))
99+
return new TextDecoder().decode(inflateSync(decodeBase64Url(payload.slice(DEFLATE_PREFIX.length))))
46100
}
47101
catch {
48102
return null

playground/src/pages/test.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ const previewCardRef = ref<HTMLElement | null>(null)
9898
const streamSettingsDialogRef = ref<HTMLDialogElement | null>(null)
9999
const isPreviewFullscreen = ref(false)
100100
const testPageViewMode = ref<TestPageViewMode>('lab')
101-
const MAX_URL_LEN = 2000
101+
const MAX_URL_LEN = 10000
102102
const LOCAL_SHARE_QUERY_KEY = 'share'
103103
const LOCAL_SHARE_STORAGE_PREFIX = 'vmr-test-share:'
104104

0 commit comments

Comments
 (0)