This repository has been archived by the owner. It is now read-only.
Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
Fetching contributors…
| //import // | |
| var _elm_lang$core$Native_Platform = function() { | |
| // PROGRAMS | |
| function program(impl) | |
| { | |
| return function(flagDecoder) | |
| { | |
| return function(object, moduleName) | |
| { | |
| object['worker'] = function worker(flags) | |
| { | |
| if (typeof flags !== 'undefined') | |
| { | |
| throw new Error( | |
| 'The `' + moduleName + '` module does not need flags.\n' | |
| + 'Call ' + moduleName + '.worker() with no arguments and you should be all set!' | |
| ); | |
| } | |
| return initialize( | |
| impl.init, | |
| impl.update, | |
| impl.subscriptions, | |
| renderer | |
| ); | |
| }; | |
| }; | |
| }; | |
| } | |
| function programWithFlags(impl) | |
| { | |
| return function(flagDecoder) | |
| { | |
| return function(object, moduleName) | |
| { | |
| object['worker'] = function worker(flags) | |
| { | |
| if (typeof flagDecoder === 'undefined') | |
| { | |
| throw new Error( | |
| 'Are you trying to sneak a Never value into Elm? Trickster!\n' | |
| + 'It looks like ' + moduleName + '.main is defined with `programWithFlags` but has type `Program Never`.\n' | |
| + 'Use `program` instead if you do not want flags.' | |
| ); | |
| } | |
| var result = A2(_elm_lang$core$Native_Json.run, flagDecoder, flags); | |
| if (result.ctor === 'Err') | |
| { | |
| throw new Error( | |
| moduleName + '.worker(...) was called with an unexpected argument.\n' | |
| + 'I tried to convert it to an Elm value, but ran into this problem:\n\n' | |
| + result._0 | |
| ); | |
| } | |
| return initialize( | |
| impl.init(result._0), | |
| impl.update, | |
| impl.subscriptions, | |
| renderer | |
| ); | |
| }; | |
| }; | |
| }; | |
| } | |
| function renderer(enqueue, _) | |
| { | |
| return function(_) {}; | |
| } | |
| // HTML TO PROGRAM | |
| function htmlToProgram(vnode) | |
| { | |
| var emptyBag = batch(_elm_lang$core$Native_List.Nil); | |
| var noChange = _elm_lang$core$Native_Utils.Tuple2( | |
| _elm_lang$core$Native_Utils.Tuple0, | |
| emptyBag | |
| ); | |
| return _elm_lang$virtual_dom$VirtualDom$program({ | |
| init: noChange, | |
| view: function(model) { return main; }, | |
| update: F2(function(msg, model) { return noChange; }), | |
| subscriptions: function (model) { return emptyBag; } | |
| }); | |
| } | |
| // INITIALIZE A PROGRAM | |
| function initialize(init, update, subscriptions, renderer) | |
| { | |
| // ambient state | |
| var managers = {}; | |
| var updateView; | |
| // init and update state in main process | |
| var initApp = _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) { | |
| var model = init._0; | |
| updateView = renderer(enqueue, model); | |
| var cmds = init._1; | |
| var subs = subscriptions(model); | |
| dispatchEffects(managers, cmds, subs); | |
| callback(_elm_lang$core$Native_Scheduler.succeed(model)); | |
| }); | |
| function onMessage(msg, model) | |
| { | |
| return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) { | |
| var results = A2(update, msg, model); | |
| model = results._0; | |
| updateView(model); | |
| var cmds = results._1; | |
| var subs = subscriptions(model); | |
| dispatchEffects(managers, cmds, subs); | |
| callback(_elm_lang$core$Native_Scheduler.succeed(model)); | |
| }); | |
| } | |
| var mainProcess = spawnLoop(initApp, onMessage); | |
| function enqueue(msg) | |
| { | |
| _elm_lang$core$Native_Scheduler.rawSend(mainProcess, msg); | |
| } | |
| var ports = setupEffects(managers, enqueue); | |
| return ports ? { ports: ports } : {}; | |
| } | |
| // EFFECT MANAGERS | |
| var effectManagers = {}; | |
| function setupEffects(managers, callback) | |
| { | |
| var ports; | |
| // setup all necessary effect managers | |
| for (var key in effectManagers) | |
| { | |
| var manager = effectManagers[key]; | |
| if (manager.isForeign) | |
| { | |
| ports = ports || {}; | |
| ports[key] = manager.tag === 'cmd' | |
| ? setupOutgoingPort(key) | |
| : setupIncomingPort(key, callback); | |
| } | |
| managers[key] = makeManager(manager, callback); | |
| } | |
| return ports; | |
| } | |
| function makeManager(info, callback) | |
| { | |
| var router = { | |
| main: callback, | |
| self: undefined | |
| }; | |
| var tag = info.tag; | |
| var onEffects = info.onEffects; | |
| var onSelfMsg = info.onSelfMsg; | |
| function onMessage(msg, state) | |
| { | |
| if (msg.ctor === 'self') | |
| { | |
| return A3(onSelfMsg, router, msg._0, state); | |
| } | |
| var fx = msg._0; | |
| switch (tag) | |
| { | |
| case 'cmd': | |
| return A3(onEffects, router, fx.cmds, state); | |
| case 'sub': | |
| return A3(onEffects, router, fx.subs, state); | |
| case 'fx': | |
| return A4(onEffects, router, fx.cmds, fx.subs, state); | |
| } | |
| } | |
| var process = spawnLoop(info.init, onMessage); | |
| router.self = process; | |
| return process; | |
| } | |
| function sendToApp(router, msg) | |
| { | |
| return _elm_lang$core$Native_Scheduler.nativeBinding(function(callback) | |
| { | |
| router.main(msg); | |
| callback(_elm_lang$core$Native_Scheduler.succeed(_elm_lang$core$Native_Utils.Tuple0)); | |
| }); | |
| } | |
| function sendToSelf(router, msg) | |
| { | |
| return A2(_elm_lang$core$Native_Scheduler.send, router.self, { | |
| ctor: 'self', | |
| _0: msg | |
| }); | |
| } | |
| // HELPER for STATEFUL LOOPS | |
| function spawnLoop(init, onMessage) | |
| { | |
| var andThen = _elm_lang$core$Native_Scheduler.andThen; | |
| function loop(state) | |
| { | |
| var handleMsg = _elm_lang$core$Native_Scheduler.receive(function(msg) { | |
| return onMessage(msg, state); | |
| }); | |
| return A2(andThen, loop, handleMsg); | |
| } | |
| var task = A2(andThen, loop, init); | |
| return _elm_lang$core$Native_Scheduler.rawSpawn(task); | |
| } | |
| // BAGS | |
| function leaf(home) | |
| { | |
| return function(value) | |
| { | |
| return { | |
| type: 'leaf', | |
| home: home, | |
| value: value | |
| }; | |
| }; | |
| } | |
| function batch(list) | |
| { | |
| return { | |
| type: 'node', | |
| branches: list | |
| }; | |
| } | |
| function map(tagger, bag) | |
| { | |
| return { | |
| type: 'map', | |
| tagger: tagger, | |
| tree: bag | |
| } | |
| } | |
| // PIPE BAGS INTO EFFECT MANAGERS | |
| function dispatchEffects(managers, cmdBag, subBag) | |
| { | |
| var effectsDict = {}; | |
| gatherEffects(true, cmdBag, effectsDict, null); | |
| gatherEffects(false, subBag, effectsDict, null); | |
| for (var home in managers) | |
| { | |
| var fx = home in effectsDict | |
| ? effectsDict[home] | |
| : { | |
| cmds: _elm_lang$core$Native_List.Nil, | |
| subs: _elm_lang$core$Native_List.Nil | |
| }; | |
| _elm_lang$core$Native_Scheduler.rawSend(managers[home], { ctor: 'fx', _0: fx }); | |
| } | |
| } | |
| function gatherEffects(isCmd, bag, effectsDict, taggers) | |
| { | |
| switch (bag.type) | |
| { | |
| case 'leaf': | |
| var home = bag.home; | |
| var effect = toEffect(isCmd, home, taggers, bag.value); | |
| effectsDict[home] = insert(isCmd, effect, effectsDict[home]); | |
| return; | |
| case 'node': | |
| var list = bag.branches; | |
| while (list.ctor !== '[]') | |
| { | |
| gatherEffects(isCmd, list._0, effectsDict, taggers); | |
| list = list._1; | |
| } | |
| return; | |
| case 'map': | |
| gatherEffects(isCmd, bag.tree, effectsDict, { | |
| tagger: bag.tagger, | |
| rest: taggers | |
| }); | |
| return; | |
| } | |
| } | |
| function toEffect(isCmd, home, taggers, value) | |
| { | |
| function applyTaggers(x) | |
| { | |
| var temp = taggers; | |
| while (temp) | |
| { | |
| x = temp.tagger(x); | |
| temp = temp.rest; | |
| } | |
| return x; | |
| } | |
| var map = isCmd | |
| ? effectManagers[home].cmdMap | |
| : effectManagers[home].subMap; | |
| return A2(map, applyTaggers, value) | |
| } | |
| function insert(isCmd, newEffect, effects) | |
| { | |
| effects = effects || { | |
| cmds: _elm_lang$core$Native_List.Nil, | |
| subs: _elm_lang$core$Native_List.Nil | |
| }; | |
| if (isCmd) | |
| { | |
| effects.cmds = _elm_lang$core$Native_List.Cons(newEffect, effects.cmds); | |
| return effects; | |
| } | |
| effects.subs = _elm_lang$core$Native_List.Cons(newEffect, effects.subs); | |
| return effects; | |
| } | |
| // PORTS | |
| function checkPortName(name) | |
| { | |
| if (name in effectManagers) | |
| { | |
| throw new Error('There can only be one port named `' + name + '`, but your program has multiple.'); | |
| } | |
| } | |
| // OUTGOING PORTS | |
| function outgoingPort(name, converter) | |
| { | |
| checkPortName(name); | |
| effectManagers[name] = { | |
| tag: 'cmd', | |
| cmdMap: outgoingPortMap, | |
| converter: converter, | |
| isForeign: true | |
| }; | |
| return leaf(name); | |
| } | |
| var outgoingPortMap = F2(function cmdMap(tagger, value) { | |
| return value; | |
| }); | |
| function setupOutgoingPort(name) | |
| { | |
| var subs = []; | |
| var converter = effectManagers[name].converter; | |
| // CREATE MANAGER | |
| var init = _elm_lang$core$Native_Scheduler.succeed(null); | |
| function onEffects(router, cmdList, state) | |
| { | |
| while (cmdList.ctor !== '[]') | |
| { | |
| // grab a separate reference to subs in case unsubscribe is called | |
| var currentSubs = subs; | |
| var value = converter(cmdList._0); | |
| for (var i = 0; i < currentSubs.length; i++) | |
| { | |
| currentSubs[i](value); | |
| } | |
| cmdList = cmdList._1; | |
| } | |
| return init; | |
| } | |
| effectManagers[name].init = init; | |
| effectManagers[name].onEffects = F3(onEffects); | |
| // PUBLIC API | |
| function subscribe(callback) | |
| { | |
| subs.push(callback); | |
| } | |
| function unsubscribe(callback) | |
| { | |
| // copy subs into a new array in case unsubscribe is called within a | |
| // subscribed callback | |
| subs = subs.slice(); | |
| var index = subs.indexOf(callback); | |
| if (index >= 0) | |
| { | |
| subs.splice(index, 1); | |
| } | |
| } | |
| return { | |
| subscribe: subscribe, | |
| unsubscribe: unsubscribe | |
| }; | |
| } | |
| // INCOMING PORTS | |
| function incomingPort(name, converter) | |
| { | |
| checkPortName(name); | |
| effectManagers[name] = { | |
| tag: 'sub', | |
| subMap: incomingPortMap, | |
| converter: converter, | |
| isForeign: true | |
| }; | |
| return leaf(name); | |
| } | |
| var incomingPortMap = F2(function subMap(tagger, finalTagger) | |
| { | |
| return function(value) | |
| { | |
| return tagger(finalTagger(value)); | |
| }; | |
| }); | |
| function setupIncomingPort(name, callback) | |
| { | |
| var sentBeforeInit = []; | |
| var subs = _elm_lang$core$Native_List.Nil; | |
| var converter = effectManagers[name].converter; | |
| var currentOnEffects = preInitOnEffects; | |
| var currentSend = preInitSend; | |
| // CREATE MANAGER | |
| var init = _elm_lang$core$Native_Scheduler.succeed(null); | |
| function preInitOnEffects(router, subList, state) | |
| { | |
| var postInitResult = postInitOnEffects(router, subList, state); | |
| for(var i = 0; i < sentBeforeInit.length; i++) | |
| { | |
| postInitSend(sentBeforeInit[i]); | |
| } | |
| sentBeforeInit = null; // to release objects held in queue | |
| currentSend = postInitSend; | |
| currentOnEffects = postInitOnEffects; | |
| return postInitResult; | |
| } | |
| function postInitOnEffects(router, subList, state) | |
| { | |
| subs = subList; | |
| return init; | |
| } | |
| function onEffects(router, subList, state) | |
| { | |
| return currentOnEffects(router, subList, state); | |
| } | |
| effectManagers[name].init = init; | |
| effectManagers[name].onEffects = F3(onEffects); | |
| // PUBLIC API | |
| function preInitSend(value) | |
| { | |
| sentBeforeInit.push(value); | |
| } | |
| function postInitSend(value) | |
| { | |
| var temp = subs; | |
| while (temp.ctor !== '[]') | |
| { | |
| callback(temp._0(value)); | |
| temp = temp._1; | |
| } | |
| } | |
| function send(incomingValue) | |
| { | |
| var result = A2(_elm_lang$core$Json_Decode$decodeValue, converter, incomingValue); | |
| if (result.ctor === 'Err') | |
| { | |
| throw new Error('Trying to send an unexpected type of value through port `' + name + '`:\n' + result._0); | |
| } | |
| currentSend(result._0); | |
| } | |
| return { send: send }; | |
| } | |
| return { | |
| // routers | |
| sendToApp: F2(sendToApp), | |
| sendToSelf: F2(sendToSelf), | |
| // global setup | |
| effectManagers: effectManagers, | |
| outgoingPort: outgoingPort, | |
| incomingPort: incomingPort, | |
| htmlToProgram: htmlToProgram, | |
| program: program, | |
| programWithFlags: programWithFlags, | |
| initialize: initialize, | |
| // effect bags | |
| leaf: leaf, | |
| batch: batch, | |
| map: F2(map) | |
| }; | |
| }(); |