1@ = require(['sjs:observable', 'mho:surface', 'sjs:sequence', './ui', 'mho:app']);
2
3var fakeDelay = 0;
4
5exports.withFakeNetwork = function(block) {
6 var lsKey = 'fake-slow-network';
7 var initialValue = localStorage.getItem(lsKey) === 'true';
8
9 // create an observable boolean for this value. We
10 // can put this into a checkbox element, and the variable
11 // will be updated whenever the checkbox changes (and vice versa)
12 var fakeNetworkDelay = @ObservableVar(initialValue);
13 var elem = @fakeNetworkElem(fakeNetworkDelay);
14
15 @mainContent .. @appendContent(elem) {||
16
17 // run the following block for each new value of `fakeNetworkDelay`
18 fakeNetworkDelay .. @each {|delay|
19 localStorage.setItem(lsKey, String(delay));
20 // used in the `get` function at the end of this file
21 fakeDelay = delay ? 1 : 0;
22
23 waitfor {
24 block();
25 } or {
26 // abort the above block immediately when
27 // fakeNetworkDelay gets a new value
28 fakeNetworkDelay .. @changes() .. @first();
29 }
30 }
31 }
32};
33
34exports.getJSON = (url) -> get(url) .. JSON.parse;
35exports.appendHTML = (parent, html) -> parent .. @appendContent(html .. @RawHTML);
36
37function get(url) {
38 hold(3000 * Math.random() * fakeDelay);
39
40 /*
41 * NOTE: we would normally just use the builtin `sjs:http` module, as:
42 *
43 * return http.get(url);
44 *
45 * But for the sake of this demonstration, we'll show how
46 * you would wrap a nontrivial asynchronous API like XMLHttpRequest
47 * into a suspending StratifiedJS function.
48 */
49
50 var req = new XMLHttpRequest();
51 try {
52 waitfor (var err, response) {
53 // Inside a waitfor() {} block, the compiler provides
54 // a `resume` variable which is a callback function.
55 // After the contents of the waitfor() {} block
56 // has executed, the current strata will suspend
57 // until `resume` is called.
58
59 // Do the usual XHR stuff
60 req.open('GET', url);
61
62 req.onload = function() {
63 // This is called even on 404 etc
64 // so check the status
65 if (req.status == 200) {
66 resume(null, req.response);
67 }
68 else {
69 resume(Error(req.statusText));
70 }
71 };
72
73 // Handle network errors
74 req.onerror = function() {
75 resume(Error("Network Error"));
76 };
77
78 // Make the request
79 req.send();
80 }
81
82 // code past the end of the waitfor() block won't be executed until
83 // the block's resume() function has been called. The `err` and `response`
84 // variables are assigned the arguments passed to `resume`.
85 if (err) throw(err);
86 } retract {
87 req.abort();
88 }
89 return response;
90}
91
92