-
-
Save DylanPiercey/9d65759ffa4ff7752a2bc8aa74f5da40 to your computer and use it in GitHub Desktop.
static var isBrowser = typeof window !== "undefined"; | |
static var LOADING = 0; | |
static var RESOLVED = 1; | |
static var REJECTED = 2; | |
static function isPromise(val) { | |
return val && val.then; | |
} | |
static function syncSSRPromise(state, value) { | |
if (value && "_settled" in value) { | |
if (value._settled === 0) { | |
throw new Error("Was unable to serialize promise data from server"); | |
} | |
state.settled = value._settled; | |
state.value = value._value; | |
return true; | |
} | |
} | |
class { | |
onCreate(input) { | |
var value = input.from; | |
if (isBrowser) { | |
var state = { settled: LOADING, value: undefined }; | |
syncSSRPromise(state, value); | |
this.state = state; | |
} else if (isPromise(value)) { | |
var resolvedData = { _settled: LOADING, _value: undefined }; | |
value.toJSON = function() { | |
return resolvedData; | |
}; | |
value.then( | |
function(value) { | |
resolvedData._settled = RESOLVED; | |
resolvedData._value = value; | |
}, | |
function(err) { | |
resolvedData._settled = REJECTED; | |
resolvedData._value = err; | |
} | |
); | |
} | |
} | |
onInput(input) { | |
if (isBrowser && this.hasMounted) { | |
var state = this.state; | |
var value = input.from; | |
if (!syncSSRPromise(state, value)) { | |
if (isPromise(value)) { | |
state.settled = LOADING; | |
value.then( | |
function(value) { | |
state.settled = RESOLVED; | |
state.value = value; | |
}, | |
function(err) { | |
state.settled = REJECTED; | |
state.value = value; | |
} | |
); | |
} else { | |
state.settled = RESOLVED; | |
state.value = value; | |
} | |
} | |
} | |
} | |
onMount() { | |
this.hasMounted = true; | |
} | |
} | |
<if(isBrowser)> | |
$ var renderer = ( | |
state.settled === RESOLVED | |
? input.then | |
: state.settled === REJECTED | |
? input.catch | |
: input.placeholder | |
); | |
$ renderer && renderer.renderBody && renderer.renderBody((out), state.value); | |
</if> | |
<else> | |
<await(input.from) then=input.then catch=input.catch timeout=input.timeout/> | |
</else> |
mlrawlings
commented
Aug 11, 2020
Some questions about the isBrowser
check:
-
What outcome would you want in a WebWorker? I assume
false
, in which case no change is needed (other than maybe a more-specific variable name). -
I think you can get it even shorter with
window != null
? But maybe the true end-goal is some sort of__BROWSER__
build-time var so entire branches are compiled out.
What outcome would you want in a WebWorker?
I think false
, so yeah the name could be better.
I think you can get it even shorter with
window != null
?
This would yield Uncaught ReferenceError: window is not defined
in eg Node. Also, it's usually pretty easy to configure a bundler to strip out typeof window
checks, like we're doing here: https://github.com/marko-js/examples/blob/master/examples/webpack-express/webpack.config.js#L76
Rad on both counts.