@naanlang/naan 1.0.2 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +10 -8
  3. package/bin/index.js +2 -2
  4. package/dist/env_web.js +172 -22
  5. package/dist/naan.min.js +6 -6
  6. package/frameworks/browser/https_request.nlg +120 -0
  7. package/frameworks/browser/sworker.js +299 -91
  8. package/frameworks/browser/terminals.nlg +28 -13
  9. package/frameworks/browser/workers.nlg +27 -12
  10. package/frameworks/client/apiclient.nlg +17 -4
  11. package/frameworks/client/psm_client.nlg +184 -81
  12. package/frameworks/common/common.nlg +105 -25
  13. package/frameworks/common/preferences.nlg +1 -0
  14. package/frameworks/common/watching.nlg +1 -0
  15. package/frameworks/node/apiserver.nlg +31 -15
  16. package/frameworks/node/filesystem.nlg +230 -46
  17. package/frameworks/node/gitter.nlg +27 -6
  18. package/frameworks/node/https_request.nlg +119 -0
  19. package/frameworks/node/node.nlg +1 -0
  20. package/frameworks/node/psm_server.nlg +113 -37
  21. package/frameworks/project/build.nlg +40 -23
  22. package/frameworks/project/proj_cliser.nlg +11 -3
  23. package/frameworks/project/proj_console.nlg +13 -4
  24. package/frameworks/project/proj_folder.nlg +10 -1
  25. package/frameworks/project/proj_lambda.nlg +13 -4
  26. package/frameworks/project/proj_static.nlg +11 -3
  27. package/frameworks/project/projects.nlg +128 -40
  28. package/frameworks/running/debugnub.nlg +2 -5
  29. package/frameworks/running/executors.nlg +1 -0
  30. package/frameworks/storage/csv.nlg +120 -0
  31. package/frameworks/storage/dbt_pouch.nlg +41 -25
  32. package/frameworks/storage/psm.nlg +108 -28
  33. package/frameworks/storage/psm_dbtables.nlg +7 -3
  34. package/frameworks/storage/resources.nlg +30 -2
  35. package/lib/browser/env_web.js +170 -20
  36. package/lib/browser/env_webworker.js +1 -1
  37. package/lib/browser/require.js +1 -1
  38. package/lib/core/naanlib.js +6 -6
  39. package/package.json +2 -1
  40. package/plugins/serviceAws/aws/aws-sdk-node.min.js +2 -0
  41. package/plugins/serviceAws/aws/aws-sdk.min.js +2 -88
  42. package/plugins/serviceAws/aws_cloudwatchlogs.nlg +8 -7
  43. package/plugins/serviceAws/aws_dynamo.nlg +715 -148
  44. package/plugins/serviceAws/aws_dynextra.nlg +294 -0
  45. package/plugins/serviceAws/aws_lambda.nlg +11 -4
  46. package/plugins/serviceAws/aws_s3.nlg +44 -14
  47. package/plugins/serviceAws/dbt_aws.nlg +58 -45
  48. package/plugins/serviceAws/psm_aws.nlg +61 -40
  49. package/plugins/serviceAws/serviceAws.nlg +7 -4
  50. package/plugins/serviceGitHub/psm_github.nlg +41 -25
  51. package/plugins/serviceGitLab/psm_gitlab.nlg +41 -25
  52. package/test/harness.nlg +3 -1
  53. package/test/test_01_core.nlg +5 -5
  54. package/test/test_02_context.nlg +4 -4
  55. package/test/test_03_jsinterop.nlg +9 -3
  56. package/plugins/serviceAws/aws_cognito.nlg +0 -76
@@ -0,0 +1,120 @@
1
+ /*
2
+ * https_browser.nlg
3
+ *
4
+ * Https operations for the browser.
5
+ *
6
+ * column positioning: // // !
7
+ *
8
+ * Copyright (c) 2021-2022 by Richard C. Zulch
9
+ *
10
+ */
11
+
12
+
13
+ /*
14
+ * HttpsApiRequest
15
+ *
16
+ * Perform an API request from the browser. This operates the same as HttpsApiRequest for NodeJS.
17
+ *
18
+ * Options:
19
+ * {
20
+ * method: <string> // HTTP method (defaults to GET/PUT)
21
+ * query: <dictionary> // query variables added to the URL
22
+ * putdata: <data> // data to put
23
+ * contentType: <string> // sets Content-Type header, otherwise auto-determined
24
+ * encoding: <string> // "binary" to receive binary data as arrayBuffer
25
+ * range: <string> // sets range header
26
+ * headers: [`(key, value)] // add header(s) to the request, overriding defaults
27
+ * }
28
+ *
29
+ */
30
+
31
+ closure HttpsApiRequest(url, options,
32
+ local urlq, fetchOptions, putdata, error, response, contentType, content) {
33
+ if !options
34
+ options = { }
35
+ if options.query
36
+ urlq = url.concat(EncodeQuery("?", options.query))
37
+ else
38
+ urlq = url
39
+ putdata = options.putdata
40
+ fetchOptions = {
41
+ mode: 'cors'
42
+ cache: 'no-cache'
43
+ credentials: 'same-origin'
44
+ headers: { }
45
+ redirect: 'follow'
46
+ referrerPolicy: 'no-referrer'
47
+ }
48
+ if options.method
49
+ fetchOptions.method = options.method
50
+ else if putdata
51
+ fetchOptions.method = "POST"
52
+ else
53
+ fetchOptions.method = "GET"
54
+ if putdata {
55
+ if options.contentType
56
+ fetchOptions.headers['Content-Type'] = options.contentType
57
+ else if jsTypedArray(options.putdata)
58
+ fetchOptions.headers['Content-Type'] = "application/octet-stream"
59
+ else if member(typeof(options.putdata), `(dictionary, array, xobject)) {
60
+ fetchOptions.headers['Content-Type'] = "application/json"
61
+ `(error, putdata) = JsonStringify(options.putdata)
62
+ if error
63
+ return (list(Error("HttpsApiRequest encode:", url)))
64
+ }
65
+ fetchOptions.body = putdata
66
+ }
67
+ if options.range
68
+ fetchOptions.headers.Range = options.range
69
+ if array(options.headers)
70
+ for item in options.headers
71
+ fetchOptions.headers[item.0] = item.1
72
+ //
73
+ // perform the fetch and return when complete
74
+ //
75
+ `(error, response) = await(js.w.fetch(urlq, fetchOptions))
76
+ if error
77
+ return (list(Error("HttpsApiRequest fetch failed:", error, url)))
78
+ contentType = response.headers.get("content-type")
79
+ if response.status < 200 || response.status >= 300
80
+ return (list(Error("HttpsApiRequest status:", url, response.status, {
81
+ status: response.status
82
+ })))
83
+ if contentType.startsWith("application/json") {
84
+ `(error, content) = await(response.text())
85
+ if !error
86
+ `(error, content) = JsonParse(content)
87
+ if error
88
+ error = Error("HttpsApiRequest decode:", url, error)
89
+ else
90
+ content = new(content)
91
+ if array(content) { // deencapsulate to get API result
92
+ content = totuple(content)
93
+ error = content.0
94
+ content = content.1
95
+ }
96
+ }
97
+ else if options.encoding == "binary"
98
+ `(error, content) = await(response.arrayBuffer())
99
+ else
100
+ `(error, content) = await(response.text())
101
+ list(error, content)
102
+ };
103
+
104
+
105
+ /*
106
+ * https_browserInit
107
+ *
108
+ * Initialize HTTPS request operations for browsers.
109
+ *
110
+ */
111
+
112
+ function https_browserInit(local manifest) {
113
+ manifest = `(HttpsApiRequest, https_browserInit)
114
+
115
+ Naan.module.build(module.id, "https_request", function(modobj, compobj) {
116
+ require("./browser.nlg")
117
+ compobj.manifest = manifest
118
+ modobj.exports.HttpsApiRequest = HttpsApiRequest
119
+ })
120
+ }();
@@ -4,66 +4,309 @@
4
4
  *
5
5
  * Nide service worker script.
6
6
  *
7
+ * The goal of this service worker is to 1) cache fetch requests for static content, and 2) relay
8
+ * fetch requests in the /run/ URL path namespace to instances of the IDE that can provide it. The
9
+ * identifier for the various browser windows is by "clientId", which is a GUID reported by the
10
+ * service worker and message channel APIs. Here we use the term clientId to refer to windows that
11
+ * consume data in the /run/ path, i.e. the IDE targets, and the term sourceId to refer to windows
12
+ * that provide data, i.e. the IDE instances.
13
+ * When the service worker is first executed it sends messages to all known windows requesting
14
+ * that they establish a message channel and forward the service worker's port to it. This secondary
15
+ * channel is used to communicate fetch requests from the service worker to the source IDE and then
16
+ * get the response. If an IDE is executed subsequently then it registers itself by sending the port
17
+ * unilatterally, instead of waiting to be requested.
18
+ * The service worker gets a fetch request when a non-cached resource is requested by a client
19
+ * window. If the URL path is not within /run/ then this executes a normal network request. IF the
20
+ * URL path is within /run/ then this asks the IDE source(s) to fetch it. Initially every IDE source
21
+ * is sent the request, but when one provides a 200 response then this stores that source port under
22
+ * the clientId in fetchPorts so that subsequent requests can go only to the correct IDE. This works
23
+ * great until an IDE goes away or becomes unresponsive.
24
+ * Unfortunately there is no event that tells us when a window is closed or goes away. The first
25
+ * indication of trouble is when an IDE fails to respond within a reasonable amount of time, which
26
+ * could be anything. We can enumerates the valid clients, which gives us a chance to validate our
27
+ * knowledge of which ones are responding. If a request takes longer than a second to respond then
28
+ * this executes a validate operation, which eliminates any clients that have gone away and rejects
29
+ * their pending operations.
30
+ * One potential problem is stale caches. When an older version is discovered then we notify the
31
+ * client and invalidate the old cache.
32
+ *
7
33
  * column positioning: // // !
8
34
  *
9
- * Copyright (c) 2020 by Richard C. Zulch
35
+ * Copyright (c) 2020-2022 by Richard C. Zulch
10
36
  *
11
37
  */
12
38
 
13
- var CurrentCacheName = "Naan IDE 1.0.2-1"
39
+ var CurrentCacheName = "Naanlang-1.0.5-2";
14
40
 
15
41
 
16
42
  //
17
43
  // locals
18
44
  //
19
45
 
20
- var fetchQueue = [];
21
- var fetchNextSeq = 1;
22
- var msgport;
46
+ var fetchQueue = []; // queue for outstanding requests to sources
47
+ var fetchNextSeq = 1; // sequence number for source requests
48
+ var msgPorts = {}; // message ports keyed by sourceId
49
+ var fetchPorts = {}; // message ports keyed by clientId
50
+ var waitingForInit = []; // initialization functions, or false after done
23
51
 
24
52
 
25
53
  /*
26
- * message event
54
+ * initialize
27
55
  *
28
- * Received when someone sends us a.
56
+ * Initiate listening for incoming messages from our clients. This waits for any client responses
57
+ * and then quits. Any clients that want to participate after that must unilaterally send a port for
58
+ * communication.
29
59
  *
30
60
  */
31
61
 
32
- var promiseport = new Promise(function (resolve, reject) {
62
+ (function initialize() {
63
+ if (!waitingForInit)
64
+ return; // already initialized
65
+ var pending = 0;
66
+
67
+ // doneInit
68
+ //
69
+ // Call this to resolve any waiting promises and release them for attempting to fetch from the
70
+ // IDEs (sources.)
71
+ //
72
+ function doneInit() {
73
+ if (!waitingForInit)
74
+ return; // already done
75
+ var waiters = waitingForInit;
76
+ waitingForInit = false; // no more waiters allowed
77
+ for (var wdex in waiters)
78
+ waiters[wdex](); // call each waiter
79
+ }
80
+
81
+ // self.onmessage events
82
+ //
83
+ // This receives channel port messages from the IDEs as they either 1) respond to a request to
84
+ // register, or 2) spontaneously register themselves as they notice that we're running.
85
+ //
33
86
  self.addEventListener('message', function(event) {
34
- console.log("[1.0.2-1] port received");
35
- msgport = event.data.hereIsYourPort;
87
+ var msgport = event.data.hereIsYourPort; // message port of a client
88
+ var pubID = event.data.hereIsMyID;
89
+ var pubVersion = event.data.hereIsMyVersion;
90
+ var sourceId = event.source.id; // client id of sender of message
91
+ msgPorts[sourceId] = msgport;
92
+ console.log("[1.0.5-2] received new msgport for", sourceId, pubID, "-", pubVersion);
93
+ if (pubVersion != "1.0.5-2")
94
+ msgport.postMessage({ // notify new version available
95
+ id: "upgrade",
96
+ version: "1.0.5-2"
97
+ });
98
+ Reaper(); // clean up obsolete info
99
+
100
+ // msgport.onmessage events
101
+ //
102
+ // This receives channel port messages that are responding to our fetch requests. The IDE
103
+ // can also send a text message for logging, but that is used only for debugging.
104
+ //
36
105
  msgport.onmessage = function(msg) {
37
106
  msg = msg.data;
38
107
  if (msg.id == "response")
39
- postResponse(msg);
108
+ processResponse(msg);
40
109
  else if (msg.id == "text")
41
- console.log("[1.0.2-1] msg received:", msg.text);
110
+ console.log("[1.0.5-2] msg received:", msg.text);
42
111
  };
43
- /*
44
- // don't clutter the log
45
- msgport.postMessage({
46
- id: "text",
47
- text: "port received by 1.0.2-1",
48
- });
49
- */
50
- resolve(msgport);
51
-
112
+
113
+ // send text to IDE log
52
114
  //
53
- // postResponse
115
+ // This is only for debugging.
54
116
  //
55
-
56
- function postResponse(msg) {
57
- var fqdex, response, item;
58
- for (fqdex = 0; fqdex < fetchQueue.length; ++fqdex)
59
- if (fetchQueue[fqdex].seq === msg.seq) {
60
- item = fetchQueue.splice(fqdex, 1);
61
- item[0].resolve(new Response(msg.body, msg.init));
62
- break;
63
- }
117
+ /*
118
+ // don't clutter the log
119
+ msgport.postMessage({
120
+ id: "text",
121
+ text: "port received by 1.0.5-2",
122
+ });
123
+ */
124
+ if (--pending === 0)
125
+ doneInit(); // we finished all known clients
126
+ });
127
+
128
+ // initialize known IDE instances.
129
+ //
130
+ // This sends a port request to each known IDE instance. Fetches that occur prior to completion
131
+ // of initialization will wait for these instances to respond. A timeout prevents one errant IDE
132
+ // from hanging all requests, by releasing the fetches even before all source IDEs respond.
133
+ //
134
+ self.clients.matchAll({
135
+ includeUncontrolled: true
136
+ }).then(function(clientList) {
137
+ clientList.every(function(client) {
138
+ console.log("[1.0.5-2] requesting new msgport for", client.id);
139
+ ++pending;
140
+ client.postMessage({ // tell client(s) we need this fetch source
141
+ msg: "Naan_need_fetch_port",
142
+ });
143
+ });
144
+ setTimeout(doneInit, 10000); // release fetches
145
+ });
146
+
147
+ // processResponse
148
+ //
149
+ // An IDE source has responded to our fetch request. If this was successful then we record the
150
+ // IDE (sourceId) so that subsequent requests from that target (clientId) will go to the same
151
+ // source.
152
+ //
153
+ function processResponse(msg) {
154
+ var fqdex, response, item;
155
+ for (fqdex = 0; fqdex < fetchQueue.length; ++fqdex)
156
+ if (fetchQueue[fqdex].seq === msg.seq) {
157
+ item = fetchQueue.splice(fqdex, 1)[0];
158
+ if (item.clientId && msg.init.status == 200)
159
+ fetchPorts[item.clientId] = item.msgport; // successful lookup
160
+ item.resolve(new Response(msg.body, msg.init));
161
+ break;
162
+ }
163
+ }
164
+ })();
165
+
166
+
167
+ /*
168
+ * Reaper
169
+ *
170
+ * Periodic cleanup returning a promise. This removes anything that is obsolete and resolve all
171
+ * associated transactions.
172
+ *
173
+ */
174
+
175
+ function Reaper() {
176
+ var promise = self.clients.matchAll({
177
+ includeUncontrolled: true
178
+ }).then(function(clientList) { // both sources and clients
179
+ var clients = {};
180
+ for (var clidex in clientList)
181
+ clients[clientList[clidex].id] = clientList[clidex];
182
+ for (var sourceId in msgPorts)
183
+ if (!clients[sourceId]) {
184
+ console.log("[1.0.5-2] source gone:", sourceId);
185
+ delete msgPorts[sourceId]; // no longer a source
186
+ }
187
+ for (var clientId in fetchPorts)
188
+ if (!clients[clientId]) {
189
+ console.log("[1.0.5-2] client gone:", clientId);
190
+ delete fetchPorts[clientId]; // no longer a client
191
+ }
192
+ for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
193
+ var item = fetchQueue[fqdex];
194
+ while (item.clientId && !clients[item.clientId]
195
+ || !Object.values(msgPorts).includes(item.msgport)) {
196
+ fetchQueue.splice(fqdex, 1); // either client or source missing
197
+ item.resolve(new Response(undefined, {
198
+ status: 404,
199
+ statusText: "Source Disappeared" // if client is gone this disappears too
200
+ }));
201
+ if (fqdex >= fetchQueue.length)
202
+ break; // we've run out of transactions
203
+ item = fetchQueue[fqdex];
204
+ }
64
205
  }
65
206
  });
66
- });
207
+ return (promise);
208
+ }
209
+
210
+
211
+ /*
212
+ * ClearCaches
213
+ *
214
+ * Clear obsolete caches, returning a promise.
215
+ *
216
+ */
217
+
218
+ function ClearCaches() {
219
+ var promise = caches.keys().then(function(cacheNames) { // delete old cache entries
220
+ return (Promise.all(
221
+ cacheNames.map(function(cacheName) {
222
+ if (cacheName != CurrentCacheName) {
223
+ console.log('[1.0.5-2] deleting old cache:', cacheName);
224
+ return (caches.delete(cacheName));
225
+ }
226
+ })
227
+ ));
228
+ }).then(function() { // claim all clients
229
+ console.log('[1.0.5-2] claiming clients');
230
+ return (self.clients.claim());
231
+ });
232
+ return (promise);
233
+ }
234
+
235
+
236
+ /*
237
+ * GetClientResponse
238
+ *
239
+ * Get message ports from the current clients if they can supply contents for the specified URL.
240
+ * This returns a promise that is resolved after the msgPorts object is updated. Note that the
241
+ * clientId argument is the requester, but the client that actually has the available data will
242
+ * often be a different window.
243
+ * On the first request from a given client, every source is requested to respond to the URL
244
+ * pathname, and the first one that does is designated the official source for that client. While
245
+ * asking all the sources, this checks every second to see if any of them have gone away so that it
246
+ * does not hang waiting. A source can be unresponsive and delay the fetch forever, e.g. in the
247
+ * debugger, but if the window has closed then it will get reaped and the fetch will complete.
248
+ * On subsequent requests, to a known source, this does not have a timeout. If the source goes
249
+ * away then the fetch will not complete, but the client is screwed anyway in that case. Eventually
250
+ * the reaper will be called for other reasons and it will clean things up then.
251
+ *
252
+ */
253
+
254
+ function GetClientResponse(event, urlpath) {
255
+
256
+ // delegate
257
+ //
258
+ // Delegate to a source window and return a promise
259
+ //
260
+ function delegate(msgport, clientId) {
261
+ return (new Promise(function(resolve, reject) {
262
+ var seqno = fetchNextSeq++;
263
+ fetchQueue.push({
264
+ seq: seqno,
265
+ msgport: msgport,
266
+ clientId: clientId,
267
+ resolve: resolve
268
+ });
269
+ msgport.postMessage({
270
+ id: "fetch",
271
+ seq: seqno,
272
+ version: "1.0.5-2",
273
+ request: {
274
+ method: event.request.method,
275
+ url: event.request.url
276
+ },
277
+ });
278
+ }));
279
+ }
280
+
281
+ var clientId;
282
+ if (event.clientId !== "") {
283
+ clientId = event.clientId;
284
+ if (fetchPorts[clientId])
285
+ return (delegate(fetchPorts[clientId], false));
286
+ }
287
+ else
288
+ clientId = event.resultingClientId; // new window
289
+ var pending = [];
290
+ var sourceIds = Object.getOwnPropertyNames(msgPorts);
291
+ for (var mdex = 0; mdex < sourceIds.length; ++mdex)
292
+ {
293
+ var sourceId = sourceIds[mdex];
294
+ pending.push(delegate(msgPorts[sourceId], clientId));
295
+ }
296
+ if (pending.length === 0)
297
+ return (Promise.resolve(new Response(undefined, {
298
+ status: 404,
299
+ statusText: "No Sources"
300
+ })));
301
+ var toid = setInterval(Reaper, 1000); // reap every second while pending
302
+ return (Promise.all(pending).then(function(responses) {
303
+ clearInterval(toid); // all completed
304
+ for (var idex in responses)
305
+ if (responses[idex].status == 200)
306
+ return (responses[idex]); // this is the one we want
307
+ return (responses[0]); // fall back to first
308
+ }));
309
+ }
67
310
 
68
311
 
69
312
  /*
@@ -74,7 +317,7 @@ var promiseport = new Promise(function (resolve, reject) {
74
317
  */
75
318
 
76
319
  self.addEventListener('install', function(event) {
77
- console.log("[1.0.2-1] install");
320
+ console.log("[1.0.5-2] install");
78
321
  self.skipWaiting();
79
322
  });
80
323
 
@@ -95,53 +338,30 @@ self.addEventListener('fetch', function(event) {
95
338
  var tid;
96
339
  var promise;
97
340
  var url = new URL(event.request.url);
98
- var nocache = event.method != "GET" || url.search.length > 0;
99
- if (nocache && url.pathname.startsWith("/run/")) {
100
- if (msgport)
101
- promise = Promise.resolve(msgport);
102
- else {
103
- promise = self.clients.matchAll({
104
- includeUncontrolled: true
105
- }).then(function(clientList) {
106
- console.log("[1.0.2-1] requesting new msgport");
107
- var urls = clientList.map(function(client) {
108
- client.postMessage({ // tell client(s) we need a fetch source
109
- msg: "Naan_need_fetch_port"
110
- });
111
- return (client.url);
341
+ var nocache = event.request.method != "GET"
342
+ || url.search.length !== 0
343
+ || event.request.headers.get('range');
344
+ if (url.pathname.startsWith("/run/")) {
345
+ nocache = true;
346
+ if (waitingForInit) {
347
+ promise = new Promise(function(resolve, reject) {
348
+ waitingForInit.push(function(){
349
+ resolve(); // init was complete
112
350
  });
113
- console.log('[1.0.2-1] matching clients:', urls.join(', '));
114
- return (promiseport);
351
+ }).then(function(){
352
+ return (GetClientResponse(event, url.pathname)); // then get the response
115
353
  });
116
- }
117
- promise = promise.then(function(mp) { return new Promise(function(resolve, reject) {
118
- /*
119
- tid = setTimeout( function() {
120
- reject("timeout!");
121
- }, 250); */
122
- var seqno = fetchNextSeq++;
123
- if (msgport) {
124
- fetchQueue.push({
125
- seq: seqno,
126
- resolve: resolve
127
- });
128
- msgport.postMessage({
129
- id: "fetch",
130
- seq: seqno,
131
- version: "1.0.2-1",
132
- request: {
133
- method: event.request.method,
134
- url: event.request.url
135
- },
136
- });
137
- } else {
138
- console.log("[1.0.2-1] fetch has no msgport");
139
- return (reject("fatal delegation error"));
140
- }
141
- }) });
354
+ } else
355
+ promise = GetClientResponse(event, url.pathname);
142
356
  }
143
357
  else
144
- promise = fetch(event.request);
358
+ promise = fetch(event.request).catch(function (e) {
359
+ console.log("[1.0.5-2] fetch failed", e);
360
+ return (new Response(undefined, {
361
+ status: 404,
362
+ statusText: "Fetch Failed"
363
+ }));
364
+ });
145
365
  return (promise.then(function(response) {
146
366
  // delete tid timer ###
147
367
  if (!nocache) {
@@ -165,28 +385,16 @@ self.addEventListener('fetch', function(event) {
165
385
  */
166
386
 
167
387
  self.addEventListener('activate', function(event) {
168
- console.log("[1.0.2-1] activate");
388
+ console.log("[1.0.5-2] activate");
169
389
  self.clients.matchAll({ // for debugging, list controlled clients
170
390
  includeUncontrolled: true
171
391
  }).then(function(clientList) {
172
392
  var urls = clientList.map(function(client) {
173
393
  return (client.url);
174
394
  });
175
- console.log('[1.0.2-1] matching clients:', urls.join(', '));
395
+ console.log('[1.0.5-2] matching clients:', urls.join(', '));
176
396
  });
177
- var promise = caches.keys().then(function(cacheNames) { // delete old cache entries
178
- return (Promise.all(
179
- cacheNames.map(function(cacheName) {
180
- if (cacheName !== CurrentCacheName) {
181
- console.log('[1.0.2-1] deleting old cache:', cacheName);
182
- return (caches.delete(cacheName));
183
- }
184
- })
185
- ));
186
- }).then(function() { // claim all clients
187
- console.log('[1.0.2-1] claiming clients for version', CurrentCacheName);
188
- return (self.clients.claim());
189
- });
397
+ var promise = ClearCaches();
190
398
  if (event.waitUntil)
191
399
  event.waitUntil(promise);
192
400
  });