Skip to content

Commit e52c882

Browse files
lydellsupermario
authored andcommitted
elm-pages support
1 parent 2e43205 commit e52c882

File tree

1 file changed

+174
-50
lines changed

1 file changed

+174
-50
lines changed

extra/Lamdera/Injection.hs

Lines changed: 174 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -146,17 +146,27 @@ inspect graph =
146146
debugHaskellPass "graphModifications keys" (graph & Map.filterWithKey pick & Map.toList & take 5) graph
147147

148148

149+
data OutputType = LamderaBackend | LamderaFrontend | LamderaLive | NotLamdera deriving (Eq)
150+
151+
149152
source :: Mode.Mode -> Mains -> B.Builder
150153
source mode mains =
151154
let
152-
isBackend = mains & mainsInclude ["Backend", "LBR"]
153-
isLocalDev = mains & mainsInclude ["LocalDev"]
155+
outputType =
156+
if mains & mainsInclude ["Backend", "LBR"] then
157+
LamderaBackend
158+
else if mains & mainsInclude ["Frontend", "LFR"] then
159+
LamderaFrontend
160+
else if mains & mainsInclude ["LocalDev"] then
161+
LamderaLive
162+
else
163+
NotLamdera
154164
in
155-
B.byteString $ Text.encodeUtf8 $ injections mode isBackend isLocalDev
165+
B.byteString $ Text.encodeUtf8 $ injections outputType
156166

157167

158-
injections :: Mode.Mode -> Bool -> Bool -> Text
159-
injections mode isBackend isLocalDev =
168+
injections :: OutputType -> Text
169+
injections outputType =
160170
let
161171
previousVersionInt =
162172
-- @TODO maybe its time to consolidate the global config...
@@ -167,34 +177,42 @@ injections mode isBackend isLocalDev =
167177

168178
previousVersion = show_ previousVersionInt
169179

180+
-- @TODO: Simplify once we know why there’s a try-catch.
181+
-- Kinda silly to match on outputType twice.
170182
runUpdate =
171-
if isLocalDev
172-
then
183+
case outputType of
184+
LamderaBackend ->
185+
-- @TODO: Add comment about why we are swallowing errors
186+
-- for non-lamdera runtime. Also, why explicitly catch errors?
187+
-- Bugsnag would catch them anyway?
188+
-- https://github.com/lamdera/compiler/commit/7bd9d403954c09f24bf0e57a86210e8e5c1a97ee
189+
[text|
190+
try {
191+
var pair = A2(update, msg, model);
192+
} catch(err) {
193+
if (isLamderaRuntime) bugsnag.notify(err);
194+
return;
195+
}
196+
|]
197+
198+
LamderaFrontend ->
199+
-- @TODO: Add comment about why we are swallowing errors
200+
[text|
201+
try {
202+
var pair = A2(update, msg, model);
203+
} catch(err) {
204+
return;
205+
}
206+
|]
207+
208+
-- LamderaLive or NotLamdera
209+
_ ->
173210
[text|
174211
var pair = A2(update, msg, model);
175212
|]
176-
else
177-
if isBackend
178-
then
179-
[text|
180-
try {
181-
var pair = A2(update, msg, model);
182-
} catch(err) {
183-
bugsnag.notify(err);
184-
return;
185-
}
186-
|]
187-
else
188-
[text|
189-
try {
190-
var pair = A2(update, msg, model);
191-
} catch(err) {
192-
return;
193-
}
194-
|]
195213

196214
shouldProxy =
197-
onlyIf isLocalDev
215+
onlyIf (outputType == LamderaLive)
198216
[text|
199217
shouldProxy = $$author$$project$$LocalDev$$shouldProxy(msg)
200218
|]
@@ -388,8 +406,132 @@ injections mode isBackend isLocalDev =
388406
}
389407
|]
390408
in
391-
if isBackend
392-
then
409+
case outputType of
410+
-- NotLamdera was added when we fixed the hot loading of a new app version in the browser.
411+
-- The frontend version of the injections – which used to be what you got when using the
412+
-- lamdera compiler for non-lamdera things – then became much more complicated.
413+
-- In order not to break elm-pages (which calls `app.die()`) we preserved the old frontend
414+
-- injections. Note that the `.die()` method is incomplete: It does not kill all apps completely
415+
-- and does not help the garbage collector enough for a killed app to be fully garbage collected.
416+
NotLamdera ->
417+
[text|
418+
function _Platform_initialize(flagDecoder, args, init, update, subscriptions, stepperBuilder)
419+
{
420+
var result = A2(_Json_run, flagDecoder, _Json_wrap(args ? args['flags'] : undefined));
421+
422+
// @TODO need to figure out how to get this to automatically escape by mode?
423+
//$$elm$$core$$Result$$isOk(result) || _Debug_crash(2 /**/, _Json_errorToString(result.a) /**/);
424+
$$elm$$core$$Result$$isOk(result) || _Debug_crash(2 /**_UNUSED/, _Json_errorToString(result.a) /**/);
425+
426+
var managers = {};
427+
var initPair = init(result.a);
428+
var model = (args && args['model']) || initPair.a;
429+
430+
var stepper = stepperBuilder(sendToApp, model);
431+
var ports = _Platform_setupEffects(managers, sendToApp);
432+
433+
var upgradeMode = false;
434+
435+
function sendToApp(msg, viewMetadata)
436+
{
437+
if (upgradeMode) {
438+
// No more messages should run in upgrade mode
439+
_Platform_enqueueEffects(managers, $$elm$$core$$Platform$$Cmd$$none, $$elm$$core$$Platform$$Sub$$none);
440+
return;
441+
}
442+
443+
$runUpdate
444+
445+
stepper(model = pair.a, viewMetadata);
446+
_Platform_enqueueEffects(managers, pair.b, subscriptions(model));
447+
}
448+
449+
if ((args && args['model']) === undefined) {
450+
_Platform_enqueueEffects(managers, initPair.b, subscriptions(model));
451+
}
452+
453+
const die = function() {
454+
// Stop all subscriptions.
455+
// This must be done before clearing the stuff below.
456+
_Platform_enqueueEffects(managers, _Platform_batch(_List_Nil), _Platform_batch(_List_Nil));
457+
458+
managers = null;
459+
model = null;
460+
stepper = null;
461+
ports = null;
462+
_Platform_effectsQueue = [];
463+
}
464+
465+
return ports ? {
466+
ports: ports,
467+
gm: function() { return model },
468+
eum: function() { upgradeMode = true },
469+
die: die,
470+
fns: {}
471+
} : {};
472+
}
473+
|]
474+
475+
LamderaBackend ->
476+
[text|
477+
function _Platform_initialize(flagDecoder, args, init, update, subscriptions, stepperBuilder)
478+
{
479+
var result = A2(_Json_run, flagDecoder, _Json_wrap(args ? args['flags'] : undefined));
480+
481+
// @TODO need to figure out how to get this to automatically escape by mode?
482+
//$$elm$$core$$Result$$isOk(result) || _Debug_crash(2 /**/, _Json_errorToString(result.a) /**/);
483+
$$elm$$core$$Result$$isOk(result) || _Debug_crash(2 /**_UNUSED/, _Json_errorToString(result.a) /**/);
484+
485+
var managers = {};
486+
var initPair = init(result.a);
487+
var model = (args && args['model']) || initPair.a;
488+
489+
var stepper = stepperBuilder(sendToApp, model);
490+
var ports = _Platform_setupEffects(managers, sendToApp);
491+
492+
var upgradeMode = false;
493+
494+
function sendToApp(msg, viewMetadata)
495+
{
496+
if (upgradeMode) {
497+
// No more messages should run in upgrade mode
498+
_Platform_enqueueEffects(managers, $$elm$$core$$Platform$$Cmd$$none, $$elm$$core$$Platform$$Sub$$none);
499+
return;
500+
}
501+
502+
$runUpdate
503+
504+
stepper(model = pair.a, viewMetadata);
505+
_Platform_enqueueEffects(managers, pair.b, subscriptions(model));
506+
}
507+
508+
if ((args && args['model']) === undefined) {
509+
_Platform_enqueueEffects(managers, initPair.b, subscriptions(model));
510+
}
511+
512+
const die = function() {
513+
// Stop all subscriptions.
514+
// This must be done before clearing the stuff below.
515+
_Platform_enqueueEffects(managers, _Platform_batch(_List_Nil), _Platform_batch(_List_Nil));
516+
517+
managers = null;
518+
model = null;
519+
stepper = null;
520+
ports = null;
521+
_Platform_effectsQueue = [];
522+
}
523+
524+
return ports ? {
525+
ports: ports,
526+
gm: function() { return model },
527+
eum: function() { upgradeMode = true },
528+
die: die,
529+
fns: {}
530+
} : {};
531+
}
532+
|]
533+
534+
LamderaBackend ->
393535
[text|
394536

395537
$debugToAnsiStringOverride
@@ -464,9 +606,6 @@ injections mode isBackend isLocalDev =
464606

465607
var pos = 0;
466608

467-
//console.log('managers', managers)
468-
//console.log('ports', ports)
469-
470609
function mtime() { // microseconds
471610
if (!isLamderaRuntime) { return 0; }
472611
const hrTime = process.hrtime();
@@ -492,8 +631,6 @@ injections mode isBackend isLocalDev =
492631
return;
493632
}
494633

495-
$shouldProxy
496-
497634
var serializeDuration, logDuration = null;
498635
var start = mtime();
499636

@@ -511,16 +648,8 @@ injections mode isBackend isLocalDev =
511648
logDuration = mtime() - start;
512649
}
513650

514-
// console.log(`model size: ${global.sizeof(pair.a)}`);
515-
// console.log(pair.a);
516-
517651
stepper(model = pair.a, viewMetadata);
518-
//console.log('cmds', pair.b);
519652
_Platform_enqueueEffects(managers, pair.b, subscriptions(model));
520-
521-
//const stepEnqueueDuration = mtime() - start;
522-
523-
//console.log({serialize: serializeDuration, log: logDuration, update: updateDuration, stepEnqueue: stepEnqueueDuration})
524653
}
525654

526655
if ((args && args['model']) === undefined) {
@@ -559,7 +688,9 @@ injections mode isBackend isLocalDev =
559688
} : {};
560689
}
561690
|]
562-
else
691+
692+
-- LamderaFrontend or LamderaLive
693+
_ ->
563694
[text|
564695
function _Platform_initialize(flagDecoder, args, init, update, subscriptions, stepperBuilder)
565696
{
@@ -669,12 +800,8 @@ injections mode isBackend isLocalDev =
669800
}
670801
}
671802

672-
673803
var ports = _Platform_setupEffects(managers, sendToApp);
674804

675-
//console.log('managers', managers)
676-
//console.log('ports', ports)
677-
678805
var buriedTimestamp = null;
679806

680807
function sendToApp(msg, viewMetadata)
@@ -699,7 +826,6 @@ injections mode isBackend isLocalDev =
699826
$runUpdate
700827

701828
stepper(model = pair.a, viewMetadata);
702-
//console.log('cmds', pair.b);
703829
_Platform_enqueueEffects(managers, pair.b, subscriptions(model));
704830
}
705831

@@ -709,8 +835,6 @@ injections mode isBackend isLocalDev =
709835
// It doesn't die completely: Already running cmds will still run, and
710836
// hit the update function, which then redirects the messages to the new app.
711837
const die = function() {
712-
//console.log('App dying');
713-
714838
// Render one last time, synchronously, in case there is a scheduled
715839
// render with requestAnimationFrame (which then become no-ops).
716840
// Rendering mutates the vdom, and we want those mutations.

0 commit comments

Comments
 (0)