on master help sign in
Fixes for running wasm on main thread; added check for WebAssembly Object
commit1486cdba4cb32f8a949c35021842e0a8965a1289 authorDivam <dfordivam@gmail.com> dateTue 7 Apr 2020, 19:27 (7 years ago) parentae3e0d5
4 files changed+58−30
default.nix+4−2 dep/reflex-platform/github.json+2−2 dep/webabi/default.nix+2−2 lib/backend/src/Obelisk/Backend.hs+50−24
default.nix+4−2
@@ -102,11 +102,13 @@ in rec {
102102 combinedJsWasmAssets = frontendJs: optimizationLevel: frontendWasm: pkgs.runCommand "combinedJsWasmAssets" {} ''
103103 mkdir $out
104104 cd $out
105− ln -s ${compressedJs frontendJs optimizationLevel}/* .
105+ ${if frontendJs != null then ''
106+ ln -s ${compressedJs frontendJs optimizationLevel}/* .
107+ '' else '' ''}
106108 ${if frontendWasm != null then ''
107109 ln -s ${stripWasm frontendWasm}/* .
108110 ln -s ${webabi}/lib/node_modules/webabi/jsaddleJS/* .
109− ln -s ${webabi}/lib/node_modules/webabi/build/worker_runner.js .
111+ ln -s ${webabi}/lib/node_modules/webabi/build/mainthread_runner.js .
110112 '' else '' ''}
111113 '';
112114
dep/reflex-platform/github.json+2−2
@@ -3,6 +3,6 @@
33 "repo": "reflex-platform",
44 "branch": "ob-1",
55 "private": false,
6− "rev": "d3db8e8a104788f8546b812180c5c20e2430cf98",
7− "sha256": "08zkn0whgvb0grw571r6bdawbi90c9jpii7hak7lmq9i29wxl3bv"
6+ "rev": "2ab56c00a3d1b5f0c026fa8b339968fab66bdcc3",
7+ "sha256": "05ilpykbp6ipzfack54zjkc9dvfdvl134vx2k36d0gvb0nswmlcm"
88}
dep/webabi/default.nix+2−2
@@ -12,8 +12,8 @@ let
1212 webabiSrc = pkgs.fetchFromGitHub {
1313 owner = "WebGHC";
1414 repo = "webabi";
15− rev = "7ffeff005dbdce60c96d830a5f67c4c461c0f5a1";
16− sha256 = "0znwbhgpgf6kk0zwbnhvnx26rgvqql6isnblh87q6wd0dnc57h2x";
15+ rev = "bd64537cbbc308d062a23ff81a172e74a5364396";
16+ sha256 = "1sg7h70rbiw75zmrzjnrnvzzw0nvzgr8pdn29jc5mgm2yqjkj8p7";
1717 };
1818
1919in (callNode2nix "webabi" webabiSrc).package.overrideAttrs (old: {
lib/backend/src/Obelisk/Backend.hs+50−24
@@ -99,7 +99,7 @@ data GhcjsWidgets a = GhcjsWidgets
9999
100100data GhcjsWasmAssets = GhcjsWasmAssets
101101 { _ghcjsWasmAssets_allJs :: Text
102− , _ghcjsWasmAssets_wasmPaths :: Maybe (Text, Text)
102+ , _ghcjsWasmAssets_wasmPathRoot :: Maybe Text
103103 }
104104
105105-- | Given the URL of all.js, return the widgets which are responsible for
@@ -179,10 +179,9 @@ renderAllJsPath :: Encoder Identity Identity (R (FullRoute a b)) PageName -> Tex
179179renderAllJsPath validFullEncoder =
180180 renderObeliskRoute validFullEncoder $ FullRoute_Frontend (ObeliskRoute_Resource ResourceRoute_Ghcjs) :/ ["all.js"]
181181
182−renderWasmPaths :: Encoder Identity Identity (R (FullRoute a b)) PageName -> (Text, Text)
183−renderWasmPaths validFullEncoder = (,)
184− (renderObeliskRoute validFullEncoder $ FullRoute_Frontend (ObeliskRoute_Resource ResourceRoute_Ghcjs) :/ [])
185− (renderObeliskRoute validFullEncoder $ FullRoute_Frontend (ObeliskRoute_Resource ResourceRoute_Ghcjs) :/ ["frontend.wasm"])
182+renderWasmPathRoot :: Encoder Identity Identity (R (FullRoute a b)) PageName -> Text
183+renderWasmPathRoot validFullEncoder =
184+ renderObeliskRoute validFullEncoder $ FullRoute_Frontend (ObeliskRoute_Resource ResourceRoute_Ghcjs) :/ []
186185
187186serveObeliskApp
188187 :: (MonadSnap m, HasCookies m, MonadFail m)
@@ -266,7 +265,7 @@ runBackendWith (BackendConfig runSnap staticAssets ghcjsAssets ghcjsWidgets) bac
266265 where
267266 routeToUrl (k :/ v) = renderObeliskRoute validFullEncoder $ FullRoute_Frontend (ObeliskRoute_App k) :/ v
268267 allJsUrl = renderAllJsPath validFullEncoder
269− mWasmUrls = if enableWasm then Just (renderWasmPaths validFullEncoder) else Nothing
268+ mWasmUrls = if enableWasm then Just (renderWasmPathRoot validFullEncoder) else Nothing
270269 widgets = ($ GhcjsWasmAssets allJsUrl mWasmUrls) <$> ghcjsWidgets
271270 frontendApp = GhcjsApp
272271 { _ghcjsApp_compiled = ghcjsAssets
@@ -296,30 +295,57 @@ renderGhcjsFrontend urlEnc ghcjsWidgets route configs f = do
296295preloadGhcjs :: GhcjsWasmAssets -> FrontendWidgetT r ()
297296preloadGhcjs (GhcjsWasmAssets allJsUrl mWasm) = case mWasm of
298297 Nothing -> elAttr "link" ("rel" =: "preload" <> "as" =: "script" <> "href" =: allJsUrl) blank
299− Just _ -> pure ()
298+ Just wasmAssets -> fst (wasmScripts allJsUrl wasmAssets)
300299
301300-- | Load the script from the given URL in a deferred script tag.
302301-- This is the default method.
303302deferredGhcjsScript :: GhcjsWasmAssets -> FrontendWidgetT r ()
304303deferredGhcjsScript (GhcjsWasmAssets allJsUrl mWasm) = case mWasm of
305304 Nothing -> elAttr "script" ("type" =: "text/javascript" <> "src" =: allJsUrl <> "defer" =: "defer") blank
306− Just v -> wasmScript v
307−
308−wasmScript :: (Text, Text) -> FrontendWidgetT r ()
309−wasmScript (jsaddleAssets, wasmUrl) = do
310− let sendMsgWorkerJs = jsaddleAssets <> "/jsaddle_sendMsgWorker.js"
311− jsaddleJs = jsaddleAssets <> "/jsaddle.js"
312− workerRunnerJs = jsaddleAssets <> "/worker_runner.js"
313− elAttr "script" ("type" =: "text/javascript" ) $ text $
314− "var jsaddle_sendMsgWorkerPath = '" <> sendMsgWorkerJs <> "';"
315− elAttr "script" ("type" =: "text/javascript" <> "src" =: jsaddleJs) blank
316− elAttr "script" ("type" =: "text/javascript") $ text $ mconcat $
317− [ "var jsaddleVals = jsaddleJsInit();"
318− , "const worker = new Worker(\"" <> workerRunnerJs <> "\");"
319− , "worker.postMessage({ url: \"" <> wasmUrl <> "\""
320− , " , jsaddleVals: jsaddleVals }"
321− , " , [jsaddleVals.jsaddleListener]);"
322− ]
305+ Just wasmAssets -> snd (wasmScripts allJsUrl wasmAssets)
306+
307+wasmScripts :: Text -> Text -> (FrontendWidgetT r (), FrontendWidgetT r ())
308+wasmScripts allJsUrl wasmRoot = (script preloadScript, script runJsScript)
309+ where
310+ script t = elAttr "script" ("type" =: "text/javascript") $ text t
311+ jsaddleJs = wasmRoot <> "/jsaddle_core.js"
312+ interfaceJs = wasmRoot <> "/jsaddle_mainthread_interface.js"
313+ runnerJs = wasmRoot <> "/mainthread_runner.js"
314+ wasmUrl = wasmRoot <> "/frontend.wasm"
315+
316+ preloadScript =
317+ "add_preload_tag = function (docSrc, docType) { \
318+ \ var link_tag = document.createElement('link'); \
319+ \ link_tag.rel = 'preload'; \
320+ \ link_tag.as = docType; \
321+ \ link_tag.href = docSrc; \
322+ \ document.head.appendChild(link_tag); \
323+ \}; \
324+ \if (typeof(WebAssembly) === 'undefined') { \
325+ \ add_preload_tag('" <> allJsUrl <> "', 'script'); \
326+ \} else { \
327+ \ add_preload_tag('" <> wasmUrl <> "', 'script'); \
328+ \ add_preload_tag('" <> jsaddleJs <> "', 'script'); \
329+ \ add_preload_tag('" <> interfaceJs <> "', 'script'); \
330+ \ add_preload_tag('" <> runnerJs <> "', 'script'); \
331+ \}"
332+
333+ runJsScript =
334+ "add_deferload_tag = function (docSrc) { \
335+ \ var tag = document.createElement('script'); \
336+ \ tag.type = 'text/javascript'; \
337+ \ tag.src = docSrc; \
338+ \ tag.setAttribute = ('defer', 'defer'); \
339+ \ document.body.appendChild(tag); \
340+ \}; \
341+ \if (typeof(WebAssembly) === 'undefined') { \
342+ \ add_deferload_tag('" <> allJsUrl <> "'); \
343+ \} else { \
344+ \ var wasmFile = '" <> wasmUrl <> "'; \
345+ \ add_deferload_tag('" <> jsaddleJs <> "'); \
346+ \ add_deferload_tag('" <> interfaceJs <> "'); \
347+ \ add_deferload_tag('" <> runnerJs <> "'); \
348+ \}"
323349
324350-- | An all.js script which is loaded after waiting for some time to pass. This
325351-- is useful to ensure any CSS animations on the page can play smoothly before