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