on 63243ca help sign in
elk/libraries/Native/Ports.js
68 lines 2.5 kB history raw
1Elm.Native.Ports = {};
2Elm.Native.Ports.make = function(elm) {
3 elm.Native = elm.Native || {};
4 elm.Native.Ports = elm.Native.Ports || {};
5 if (elm.Native.Ports.values) return elm.Native.Ports.values;
7 var Signal = Elm.Signal.make(elm);
9 // On failure, return message. On success, return the value in an array.
10 // Wrapping in an array allows the programmer to pass in a null value.
11 function processInput(converter, v) {
12 try { var elmValue = converter(v); }
13 catch(e) { return "The given value caused a runtime error!\n" + e.toString(); }
15 var ctor = elmValue.ctor;
16 if (ctor === 'Nothing' || ctor === 'Left') {
17 return "The port's conversion function failed.";
18 } else if (ctor === 'Just' || ctor === 'Right') {
19 return [elmValue._0];
20 }
21 return [elmValue];
22 }
23 function portIn(name, converter) {
24 var port = elm.ports.incoming[name];
25 if (!port) {
26 throw new Error("Initialization Error: port '" + name +
27 "' was not given an input!");
28 }
29 elm.ports.uses[name] += 1;
30 var result = processInput(converter, port.internal.defaultValue);
31 if (typeof result === 'string') {
32 throw new Error("Initialization Error: The default value for port '" +
33 name + "' is invalid.\n" + result);
34 }
35 var signal = Signal.constant(result[0]);
36 port.internal.subscribe(function(v) {
37 var result = processInput(converter, v);
38 if (typeof result === 'string') {
39 port.internal.errorHandler(v)
40 } else {
41 elm.notify(signal.id, result[0]);
42 }
43 });
44 return signal;
45 }
46 function portOut(name, signal) {
47 var subscribers = []
48 function subscribe(handler) {
49 subscribers.push(handler);
50 }
51 function unsubscribe(handler) {
52 subscribers.pop(subscribers.indexOf(handler));
53 }
54 A2( Signal.lift, function(value) {
55 var len = subscribers.length;
56 for (var i = 0; i < len; ++i) {
57 subscribers[i](value);
58 }
59 }, signal);
60 elm.ports.outgoing[name] = { subscribe:subscribe, unsubscribe:unsubscribe };
61 return signal;
62 }
64 return elm.Native.Ports.values = {
65 portOut: portOut,
66 portIn: portIn
67 };
68};