Skip to content

Commit 7e934ed

Browse files
review
1 parent 992bb05 commit 7e934ed

2 files changed

Lines changed: 63 additions & 51 deletions

File tree

packages/dev-playground/src/Main.res

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,8 @@ module App = {
658658
let urlTimerId: ref<option<int>> = ref(None)
659659
let toastTimerId: ref<option<int>> = ref(None)
660660
let firstCompilerLoad = ref(true)
661+
let compilerLoadSequence = ref(0)
662+
let compileSequence = ref(0)
661663
let shareToast: Signal.t<option<string>> = Signal.make(None)
662664

663665
let syncEditorState = event => {
@@ -685,6 +687,9 @@ module App = {
685687
}
686688

687689
let compileNow = () => {
690+
compileSequence := compileSequence.contents + 1
691+
let sequence = compileSequence.contents
692+
688693
let run = async () => {
689694
switch Signal.peek(status) {
690695
| Loading => ()
@@ -693,11 +698,19 @@ module App = {
693698
Signal.set(status, Compiling)
694699
try {
695700
let result = await CompilerApi.compile(Signal.peek(source), currentConfig())
696-
Signal.set(compileResult, Some(result))
697-
Signal.set(status, Ready)
701+
if sequence === compileSequence.contents {
702+
Signal.set(compileResult, Some(result))
703+
Signal.set(status, Ready)
704+
}
698705
} catch {
699-
| JsExn(obj) => Signal.set(status, Failed(Browser.jsErrorMessage(obj)))
700-
| _ => Signal.set(status, Failed("Compilation failed"))
706+
| JsExn(obj) =>
707+
if sequence === compileSequence.contents {
708+
Signal.set(status, Failed(Browser.jsErrorMessage(obj)))
709+
}
710+
| _ =>
711+
if sequence === compileSequence.contents {
712+
Signal.set(status, Failed("Compilation failed"))
713+
}
701714
}
702715
}
703716
}
@@ -768,35 +781,47 @@ module App = {
768781
}
769782

770783
let loadCompiler = (version, compileAfterLoad) => {
784+
compilerLoadSequence := compilerLoadSequence.contents + 1
785+
compileSequence := compileSequence.contents + 1
786+
let sequence = compilerLoadSequence.contents
787+
771788
let load = async () => {
772789
try {
773790
Signal.set(status, Loading)
774791
Signal.set(compileResult, None)
775792
let info = await CompilerApi.init(version)
776-
let useInitialSettings = firstCompilerLoad.contents
777-
firstCompilerLoad := false
778-
Signal.set(compilerInfo, Some(info))
779-
Signal.set(compilerVersion, info.bundleId)
780-
Signal.set(moduleSystem, useInitialSettings ? initialModuleSystem : info.moduleSystem)
781-
Signal.set(warnFlags, useInitialSettings ? initialWarnFlags : info.warnFlags)
782-
Signal.set(
783-
jsxPreserveMode,
784-
useInitialSettings ? initialJsxPreserveMode : info.jsxPreserveMode,
785-
)
786-
Signal.set(
787-
experimentalFeatures,
788-
useInitialSettings ? initialExperimentalFeatures : info.experimentalFeatures,
789-
)
790-
Signal.set(status, Ready)
791-
if !useInitialSettings {
792-
scheduleUrlSync()
793-
}
794-
if compileAfterLoad {
795-
compileNow()
793+
if sequence === compilerLoadSequence.contents {
794+
let useInitialSettings = firstCompilerLoad.contents
795+
firstCompilerLoad := false
796+
Signal.set(compilerInfo, Some(info))
797+
Signal.set(compilerVersion, info.bundleId)
798+
Signal.set(moduleSystem, useInitialSettings ? initialModuleSystem : info.moduleSystem)
799+
Signal.set(warnFlags, useInitialSettings ? initialWarnFlags : info.warnFlags)
800+
Signal.set(
801+
jsxPreserveMode,
802+
useInitialSettings ? initialJsxPreserveMode : info.jsxPreserveMode,
803+
)
804+
Signal.set(
805+
experimentalFeatures,
806+
useInitialSettings ? initialExperimentalFeatures : info.experimentalFeatures,
807+
)
808+
Signal.set(status, Ready)
809+
if !useInitialSettings {
810+
scheduleUrlSync()
811+
}
812+
if compileAfterLoad {
813+
compileNow()
814+
}
796815
}
797816
} catch {
798-
| JsExn(obj) => Signal.set(status, Failed(Browser.jsErrorMessage(obj)))
799-
| _ => Signal.set(status, Failed("Compiler failed to load"))
817+
| JsExn(obj) =>
818+
if sequence === compilerLoadSequence.contents {
819+
Signal.set(status, Failed(Browser.jsErrorMessage(obj)))
820+
}
821+
| _ =>
822+
if sequence === compilerLoadSequence.contents {
823+
Signal.set(status, Failed("Compiler failed to load"))
824+
}
800825
}
801826
}
802827

packages/dev-playground/src/UrlState.js

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ const maxEncodedCodeLength = 300 * 1024;
44
const maxDecodedSourceLength = 200 * 1024;
55
let replaceSequence = 0;
66

7-
function supportsCompression() {
8-
return (
9-
typeof CompressionStream !== "undefined" &&
10-
typeof DecompressionStream !== "undefined"
11-
);
7+
function supportsDecompression() {
8+
return typeof DecompressionStream !== "undefined";
129
}
1310

1411
function normalizeModuleSystem(value, fallback) {
@@ -45,13 +42,6 @@ function base64UrlToBytes(value) {
4542
return bytes;
4643
}
4744

48-
async function gzip(bytes) {
49-
const stream = new Blob([bytes])
50-
.stream()
51-
.pipeThrough(new CompressionStream("gzip"));
52-
return new Uint8Array(await new Response(stream).arrayBuffer());
53-
}
54-
5545
async function gunzip(bytes) {
5646
const stream = new Blob([bytes])
5747
.stream()
@@ -61,23 +51,19 @@ async function gunzip(bytes) {
6151

6252
async function encodeCode(source) {
6353
const sourceBytes = textEncoder.encode(source);
64-
65-
if (supportsCompression()) {
66-
try {
67-
const compressedBytes = await gzip(sourceBytes);
68-
if (compressedBytes.length < sourceBytes.length) {
69-
return `z:${bytesToBase64Url(compressedBytes)}`;
70-
}
71-
} catch {
72-
// Fall through to plain base64-url encoding.
73-
}
74-
}
75-
54+
// Keep newly generated share links browser-portable. Older z: links are still
55+
// decoded when the browser exposes DecompressionStream.
7656
return `b:${bytesToBase64Url(sourceBytes)}`;
7757
}
7858

7959
async function decodeCode(encoded) {
8060
if (encoded.startsWith("z:")) {
61+
if (!supportsDecompression()) {
62+
throw new Error(
63+
"Compressed shared links require browser DecompressionStream support",
64+
);
65+
}
66+
8167
const compressedBytes = base64UrlToBytes(encoded.slice(2));
8268
return textDecoder.decode(await gunzip(compressedBytes));
8369
}
@@ -161,7 +147,8 @@ export async function initialSource(defaultSource) {
161147
try {
162148
const decoded = await decodeCode(encoded);
163149
return decoded.length <= maxDecodedSourceLength ? decoded : defaultSource;
164-
} catch {
150+
} catch (error) {
151+
console.warn("Could not restore shared playground source", error);
165152
return defaultSource;
166153
}
167154
}

0 commit comments

Comments
 (0)