Update HTML test page to new template. Added Config file selection from UI.
[apps/agl-service-unicens.git] / htdocs / AFB-websock.js
1 var urlws;
2 var urlhttp;
3
4 AFB = function(base, initialtoken){
5
6 urlws = "ws://"+window.location.host+"/"+base;
7 urlhttp = "http://"+window.location.host+"/"+base;
8
9 /*********************************************/
10 /****                                     ****/
11 /****             AFB_context             ****/
12 /****                                     ****/
13 /*********************************************/
14 var AFB_context;
15 {
16         var UUID = undefined;
17         var TOKEN = initialtoken;
18
19         var context = function(token, uuid) {
20                 this.token = token;
21                 this.uuid = uuid;
22         }
23
24         context.prototype = {
25                 get token() {return TOKEN;},
26                 set token(tok) {if(tok) TOKEN=tok;},
27                 get uuid() {return UUID;},
28                 set uuid(id) {if(id) UUID=id;}
29         };
30
31         AFB_context = new context();
32 }
33 /*********************************************/
34 /****                                     ****/
35 /****             AFB_websocket           ****/
36 /****                                     ****/
37 /*********************************************/
38 var AFB_websocket;
39 {
40         var CALL = 2;
41         var RETOK = 3;
42         var RETERR = 4;
43         var EVENT = 5;
44
45         var PROTO1 = "x-afb-ws-json1";
46
47         AFB_websocket = function(onopen, onabort) {
48                 var u = urlws;
49                 if (AFB_context.token) {
50                         u = u + '?x-afb-token=' + AFB_context.token;
51                         if (AFB_context.uuid)
52                                 u = u + '&x-afb-uuid=' + AFB_context.uuid;
53                 }
54                 this.ws = new WebSocket(u, [ PROTO1 ]);
55                 this.pendings = {};
56                 this.awaitens = {};
57                 this.counter = 0;
58                 this.ws.onopen = onopen.bind(this);
59                 this.ws.onerror = onerror.bind(this);
60                 this.ws.onclose = onclose.bind(this);
61                 this.ws.onmessage = onmessage.bind(this);
62                 this.onopen = onopen;
63                 this.onabort = onabort;
64                 this.onclose = onabort;
65         }
66
67         function onerror(event) {
68                 var f = this.onabort;
69                 if (f) {
70                         delete this.onopen;
71                         delete this.onabort;
72                         f && f(this);
73                 }
74                 this.onerror && this.onerror(this);
75         }
76
77         function onopen(event) {
78                 var f = this.onopen;
79                 delete this.onopen;
80                 delete this.onabort;
81                 f && f(this);
82         }
83
84         function onclose(event) {
85                 for (var id in this.pendings) {
86                         var ferr = this.pendings[id].onerror;
87                         ferr && ferr(null, this);
88                 }
89                 this.pendings = {};
90                 this.onclose && this.onclose();
91         }
92
93         function fire(awaitens, name, data) {
94                 var a = awaitens[name];
95                 if (a)
96                         a.forEach(function(handler){handler(data);});
97                 var i = name.indexOf("/");
98                 if (i >= 0) {
99                         a = awaitens[name.substring(0,i)];
100                         if (a)
101                                 a.forEach(function(handler){handler(data);});
102                 }
103                 a = awaitens["*"];
104                 if (a)
105                         a.forEach(function(handler){handler(data);});
106         }
107
108         function reply(pendings, id, ans, offset) {
109                 if (id in pendings) {
110                         var p = pendings[id];
111                         delete pendings[id];
112                         var f = p[offset];
113                         f(ans);
114                 }
115         }
116
117         function onmessage(event) {
118                 var obj = JSON.parse(event.data);
119                 var code = obj[0];
120                 var id = obj[1];
121                 var ans = obj[2];
122                 AFB_context.token = obj[3];
123                 switch (code) {
124                 case RETOK:
125                         reply(this.pendings, id, ans, 0);
126                         break;
127                 case RETERR:
128                         reply(this.pendings, id, ans, 1);
129                         break;
130                 case EVENT:
131                 default:
132                         fire(this.awaitens, id, ans);
133                         break;
134                 }
135         }
136
137         function close() {
138                 this.ws.close();
139                 this.onabort();
140         }
141
142         function call(method, request) {
143                 return new Promise((function(resolve, reject){
144                         var id, arr;
145                         do {
146                            id = String(this.counter = 4095 & (this.counter + 1));
147                         } while (id in this.pendings);
148                         this.pendings[id] = [ resolve, reject ];
149                         arr = [CALL, id, method, request ];
150                         if (AFB_context.token) arr.push(AFB_context.token);
151                         this.ws.send(JSON.stringify(arr));
152                 }).bind(this));
153         }
154
155         function onevent(name, handler) {
156                 var id = name;
157                 var list = this.awaitens[id] || (this.awaitens[id] = []);
158                 list.push(handler);
159         }
160
161         AFB_websocket.prototype = {
162                 close: close,
163                 call: call,
164                 onevent: onevent
165         };
166 }
167 /*********************************************/
168 /****                                     ****/
169 /****                                     ****/
170 /****                                     ****/
171 /*********************************************/
172 return {
173         context: AFB_context,
174         ws: AFB_websocket
175 };
176 };
177