@@ -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