@naanlang/naan 1.2.1 → 1.3.1

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 (38) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +1 -1
  3. package/bin/index.js +5 -2
  4. package/dist/env_web.js +12 -2
  5. package/dist/naan.min.js +4 -4
  6. package/frameworks/browser/https_request.nlg +2 -0
  7. package/frameworks/browser/sworker.js +23 -23
  8. package/frameworks/browser/terminals.nlg +123 -21
  9. package/frameworks/browser/workers.nlg +4 -1
  10. package/frameworks/browser/ws_client.nlg +5 -3
  11. package/frameworks/client/apiclient.nlg +8 -6
  12. package/frameworks/client/relaycon.nlg +3 -1
  13. package/frameworks/common/common.nlg +16 -3
  14. package/frameworks/node/apiserver.nlg +205 -5
  15. package/frameworks/node/worker.nlg +112 -10
  16. package/frameworks/node/ws_client.nlg +5 -3
  17. package/frameworks/project/build.nlg +5 -1
  18. package/frameworks/project/projects.nlg +1 -1
  19. package/frameworks/running/executors.nlg +3 -1
  20. package/frameworks/running/taskexec.nlg +5 -1
  21. package/lib/browser/env_web.js +18 -8
  22. package/lib/browser/env_webworker.js +22 -3
  23. package/lib/core/naanlib.js +4 -4
  24. package/lib/env_node.js +15 -4
  25. package/lib/env_nodeworker.js +21 -1
  26. package/package.json +8 -5
  27. package/plugins/serviceAws/aws/aws-sdk-node.min.js +2 -2
  28. package/plugins/serviceAws/aws/aws-sdk.min.js +3 -2
  29. package/plugins/serviceAws/aws_dynamo.nlg +19 -19
  30. package/plugins/serviceYC/generic_api.yaml +36 -0
  31. package/plugins/serviceYC/naanide-relay-index.js +148 -0
  32. package/plugins/serviceYC/serviceYC.nlg +60 -0
  33. package/plugins/serviceYC/yc_apigateway.nlg +205 -0
  34. package/plugins/serviceYC/yc_function.nlg +163 -0
  35. package/plugins/serviceYC/yc_vm.nlg +207 -0
  36. package/test/test_03_jsinterop.nlg +2 -2
  37. package/test/test_04_numerics.nlg +170 -2
  38. package/test/test_07_lingo.nlg +1 -1
@@ -24,6 +24,7 @@
24
24
  * encoding: <string> // "binary" to receive binary data as arrayBuffer
25
25
  * range: <string> // sets range header
26
26
  * headers: [`(key, value)] // add header(s) to the request, overriding defaults
27
+ * keepalive: <boolean> // true to send data at unload
27
28
  * debug: <boolean> // log errors and status results
28
29
  * }
29
30
  *
@@ -55,6 +56,7 @@ closure HttpsApiRequest(url, options,
55
56
  headers: { }
56
57
  redirect: 'follow'
57
58
  referrerPolicy: 'no-referrer'
59
+ keepalive: options.keepalive || undefined
58
60
  }
59
61
  if options.method
60
62
  fetchOptions.method = options.method
@@ -36,7 +36,7 @@
36
36
  *
37
37
  */
38
38
 
39
- var CurrentCacheName = "Naanlang-1.2.1+1";
39
+ var CurrentCacheName = "Naanlang-1.3.1+1";
40
40
 
41
41
 
42
42
  //
@@ -92,18 +92,18 @@ var terminated; // flag that this service worker
92
92
  var pubVersion = event.data.hereIsMyVersion;
93
93
  var sourceId = event.source.id; // client id of sender of message
94
94
  msgPorts[sourceId] = msgport;
95
- console.log("[1.2.1+1] received new msgport for", sourceId, pubID, "-", pubVersion);
96
- if (pubVersion != "1.2.1+1") {
95
+ console.log("[1.3.1+1] received new msgport for", sourceId, pubID, "-", pubVersion);
96
+ if (pubVersion != "1.3.1+1") {
97
97
  if (upgradeMsgPorts) { // if not activated
98
- console.log("[1.2.1+1] update pending for", sourceId);
98
+ console.log("[1.3.1+1] update pending for", sourceId);
99
99
  upgradeMsgPorts[sourceId] = msgport;
100
100
  }
101
101
  else {
102
102
  msgport.postMessage({ // notify new version available
103
103
  id: "upgrade",
104
- version: "1.2.1+1"
104
+ version: "1.3.1+1"
105
105
  });
106
- console.log("[1.2.1+1] update sent for:", sourceId);
106
+ console.log("[1.3.1+1] update sent for:", sourceId);
107
107
  }
108
108
  }
109
109
  Reaper(); // clean up obsolete info
@@ -134,10 +134,10 @@ var terminated; // flag that this service worker
134
134
  msgport.onmessage = function(msg) {
135
135
  msg = msg.data;
136
136
  if (msg.id == "skipWaiting") { // try to activate this SW now
137
- console.log("[1.2.1+1] attempting skipWaiting");
137
+ console.log("[1.3.1+1] attempting skipWaiting");
138
138
  self.skipWaiting();
139
139
  } else if (msg.id == "terminate") { // termiante this SW now
140
- console.log("[1.2.1+1] terminated");
140
+ console.log("[1.3.1+1] terminated");
141
141
  terminate();
142
142
  } else if (msg.id == "abortURL") { // abort an I/O transaction
143
143
  var href = new URL(msg.url).href;
@@ -150,7 +150,7 @@ var terminated; // flag that this service worker
150
150
  } else if (msg.id == "response") // response from fetch request
151
151
  processResponse(msg);
152
152
  else if (msg.id == "text") // just log some text
153
- console.log("[1.2.1+1] msg received:", msg.text);
153
+ console.log("[1.3.1+1] msg received:", msg.text);
154
154
  };
155
155
 
156
156
  // send text to IDE log
@@ -161,7 +161,7 @@ var terminated; // flag that this service worker
161
161
  // don't clutter the log
162
162
  msgport.postMessage({
163
163
  id: "text",
164
- text: "port received by 1.2.1+1",
164
+ text: "port received by 1.3.1+1",
165
165
  });
166
166
  */
167
167
  if (--pending === 0)
@@ -178,7 +178,7 @@ var terminated; // flag that this service worker
178
178
  includeUncontrolled: true
179
179
  }).then(function(clientList) {
180
180
  clientList.every(function(client) {
181
- console.log("[1.2.1+1] requesting new msgport for", client.id);
181
+ console.log("[1.3.1+1] requesting new msgport for", client.id);
182
182
  ++pending;
183
183
  client.postMessage({ // tell client(s) we need this fetch source
184
184
  msg: "Naan_need_fetch_port",
@@ -224,12 +224,12 @@ function Reaper() {
224
224
  clients[clientList[clidex].id] = clientList[clidex];
225
225
  for (var sourceId in msgPorts)
226
226
  if (!clients[sourceId]) {
227
- console.log("[1.2.1+1] source gone:", sourceId);
227
+ console.log("[1.3.1+1] source gone:", sourceId);
228
228
  delete msgPorts[sourceId]; // no longer a source
229
229
  }
230
230
  for (var clientId in fetchPorts)
231
231
  if (!clients[clientId]) {
232
- console.log("[1.2.1+1] client gone:", clientId);
232
+ console.log("[1.3.1+1] client gone:", clientId);
233
233
  delete fetchPorts[clientId]; // no longer a client
234
234
  }
235
235
  for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
@@ -263,16 +263,16 @@ function ClearCaches() {
263
263
  return (Promise.all(
264
264
  cacheNames.map(function(cacheName) {
265
265
  if (cacheName != CurrentCacheName) {
266
- console.log('[1.2.1+1] deleting old cache:', cacheName);
266
+ console.log('[1.3.1+1] deleting old cache:', cacheName);
267
267
  return (caches.delete(cacheName));
268
268
  }
269
269
  })
270
270
  ));
271
271
  }).then(function() { // claim all clients
272
- console.log('[1.2.1+1] claiming clients');
272
+ console.log('[1.3.1+1] claiming clients');
273
273
  return (self.clients.claim());
274
274
  }).then(function() {
275
- console.log('[1.2.1+1] clients claimed');
275
+ console.log('[1.3.1+1] clients claimed');
276
276
  return (Promise.resolve(true));
277
277
  });
278
278
  return (promise);
@@ -315,7 +315,7 @@ function GetClientResponse(event, urlpath) {
315
315
  msgport.postMessage({
316
316
  id: "fetch",
317
317
  seq: seqno,
318
- version: "1.2.1+1",
318
+ version: "1.3.1+1",
319
319
  request: {
320
320
  method: event.request.method,
321
321
  url: event.request.url
@@ -363,7 +363,7 @@ function GetClientResponse(event, urlpath) {
363
363
  */
364
364
 
365
365
  self.addEventListener('install', function(event) {
366
- console.log("[1.2.1+1] install");
366
+ console.log("[1.3.1+1] install");
367
367
  self.skipWaiting();
368
368
  });
369
369
 
@@ -376,20 +376,20 @@ self.addEventListener('install', function(event) {
376
376
  */
377
377
 
378
378
  self.addEventListener('activate', function(event) {
379
- console.log("[1.2.1+1] activate");
379
+ console.log("[1.3.1+1] activate");
380
380
  self.clients.matchAll({ // for debugging, list controlled clients
381
381
  includeUncontrolled: true
382
382
  }).then(function(clientList) {
383
383
  var urls = clientList.map(function(client) {
384
384
  return (client.url);
385
385
  });
386
- console.log('[1.2.1+1] matching clients:', urls.join(', '));
386
+ console.log('[1.3.1+1] matching clients:', urls.join(', '));
387
387
  });
388
388
  var promise = ClearCaches().then(function() {
389
389
  for (var sourceId in upgradeMsgPorts) {
390
390
  upgradeMsgPorts[sourceId].postMessage({ // notify new version available
391
391
  id: "upgrade",
392
- version: "1.2.1+1"
392
+ version: "1.3.1+1"
393
393
  });
394
394
  }
395
395
  upgradeMsgPorts = false;
@@ -421,7 +421,7 @@ self.addEventListener('fetch', function(event) {
421
421
  var promise;
422
422
  var url = new URL(request.url);
423
423
  var nocache = request.method != "GET"
424
- || url.search.length !== 0 && url.searchParams.get("naanver") !== "ecffb6bced5a08a6d2fdd188410b1b50"
424
+ || url.search.length !== 0 && url.searchParams.get("naanver") !== "ecae8a62f4a0ae0408f1cbd16082d4ea"
425
425
  || request.headers.get('range');
426
426
  if (url.pathname.startsWith("/run/")) {
427
427
  nocache = true;
@@ -455,7 +455,7 @@ self.addEventListener('fetch', function(event) {
455
455
  statusText: "Request Cancelled"
456
456
  }));
457
457
  }
458
- console.log("[1.2.1+1] fetch failed", request.url, e);
458
+ console.log("[1.3.1+1] fetch failed", request.url, e);
459
459
  return (new Response(undefined, {
460
460
  status: 404,
461
461
  statusText: "Fetch Failed"
@@ -10,6 +10,13 @@
10
10
  *
11
11
  */
12
12
 
13
+ /*
14
+ * globals
15
+ *
16
+ */
17
+
18
+ workers;
19
+
13
20
 
14
21
  /*
15
22
  * TermHost
@@ -55,17 +62,19 @@ closure TermHost(track, api, name, options, local target, nlregex, xtarg)
55
62
 
56
63
  // connect
57
64
  // Connect with the host if not already connected.
58
- closure connect(local host, url, pending) {
65
+ closure connect(local url, pending) {
59
66
  if target.ws
60
67
  return(list(false, { connected: true }))
61
- host = xnew(window.URL, api.url).host
62
- if !host || host == ""
63
- return(list(Error("invalid URL ${api.url}")))
64
- if window.location.protocol == "https:"
65
- url = "wss://${host}"
68
+ try {
69
+ url = xnew(window.URL, api.url)
70
+ } catch {
71
+ return(list(Error("invalid URL ${api.url}", exception)))
72
+ }
73
+ if url.protocol == "https:"
74
+ url.protocol = "wss:"
66
75
  else
67
- url = "ws://${host}"
68
- target.ws = xnew(window.WebSocket, url)
76
+ url.protocol = "ws:"
77
+ target.ws = xnew(window.WebSocket, url.href)
69
78
  pending = new(nonce)
70
79
 
71
80
  // onopen
@@ -422,7 +431,9 @@ closure TermHost(track, api, name, options, local target, nlregex, xtarg)
422
431
 
423
432
  closure TermLocal(track, name, options, local target, nlregex, listener)
424
433
  {
425
- global(js, window)
434
+ global(js, window, workers)
435
+ if !dictionary(workers)
436
+ workers = {}
426
437
  options = merge({
427
438
  type: "Local"
428
439
  }, options)
@@ -450,6 +461,8 @@ closure TermLocal(track, name, options, local target, nlregex, listener)
450
461
  return (list(Error("Local environment does not support workers")))
451
462
  target.worker = xnew(window.Worker, "env_webworker.js")
452
463
  listener = target.worker
464
+ target.guid = UUID()
465
+ workers[target.guid] = target
453
466
  }
454
467
 
455
468
  // onmessage
@@ -540,8 +553,11 @@ closure TermLocal(track, name, options, local target, nlregex, listener)
540
553
  altcmd: options.startup.initcmds
541
554
  })
542
555
  target.started = true
556
+ } else if msg.id == "targetsend" {
557
+ msg.data._guid = target.guid
558
+ js.t.DispatchMessage(msg.data)
543
559
  }
544
- }
560
+ }
545
561
 
546
562
  //
547
563
  // target.DebugCmd
@@ -651,6 +667,82 @@ closure TermLocal(track, name, options, local target, nlregex, listener)
651
667
  };
652
668
 
653
669
 
670
+ /*
671
+ * termMainProxy
672
+ *
673
+ * column positioning: // // !
674
+ * Make a browser proxy representing the main thread. This runs inside the worker and allows it
675
+ * to do remote execution with Main.
676
+ *
677
+ */
678
+
679
+ closure termMainProxy(track, name, options, local target) {
680
+ global(js)
681
+ target = require("../running/executors.nlg").ExecutorBase(track, "mainProxy", name)
682
+ target.name = name
683
+
684
+ //
685
+ // target.PostMessage
686
+ //
687
+ // Post a message to the main thread.
688
+ //
689
+ target.PostMessage = function PostMessage(data) {
690
+ js.t.DispatchMessage(data)
691
+ list(false, { posted: true })
692
+ }
693
+
694
+ //
695
+ // onreceive
696
+ //
697
+ // Process a received message from the main thread, typically in response.
698
+ //
699
+ function onreceive(data) {
700
+ target.execReceived(data)
701
+ }
702
+
703
+ // destroy
704
+ //
705
+ // Destroy the execution instance.
706
+ //
707
+ target.destroy = function destroy() {
708
+ target.execClosed(Error("instance destroyed"))
709
+ track.delete(target)
710
+ }
711
+
712
+ js.t.OnReceive(onreceive.proc)
713
+ track.add(target)
714
+
715
+ // finis
716
+
717
+ list(false, target)
718
+ };
719
+
720
+
721
+ /*
722
+ * WorkerToMain
723
+ *
724
+ * Connect our worker to the main thread, returning a result tuple with an executor representing
725
+ * Main. Use this to create a context object for Main, allowing remote evaluation.
726
+ *
727
+ */
728
+
729
+ closure WorkerToMain(local nideRunning, track) {
730
+ // mainProxy -- link tracker to main thread proxy
731
+ function mainProxy(track, name, options) {
732
+ termMainProxy(track, name, options)
733
+ }
734
+
735
+ if !js.s {
736
+ error = Error("WorkerToMain only available in browser workers")
737
+ return (list(error))
738
+ }
739
+ nideRunning = require("frameworks/running/executors.nlg")
740
+ track = nideRunning.ExecutorTracker()
741
+ track.register(mainProxy, "proxy")
742
+ track.spawn("proxy") // returns result tuple
743
+ };
744
+
745
+
654
746
  /*
655
747
  * findIDEtarget
656
748
  *
@@ -677,7 +769,7 @@ closure findIDEtarget(track, name, workerID, naancont, local target) {
677
769
  */
678
770
 
679
771
  closure termIDE(track, name, workerID, naancont, title, local target, connected) {
680
- global()
772
+ global(workers)
681
773
  target = findIDEtarget(track, name, workerID, naancont)
682
774
  if target { // new naancont on existing target
683
775
  target.updateController(naancont)
@@ -691,23 +783,31 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
691
783
  target.workerID = workerID
692
784
  target.naancont = naancont
693
785
  connected = []
694
-
786
+
787
+ // replyHook
788
+ //
789
+ // Intercept the ReplyMessage function to see if we should handle it.
695
790
  //
791
+ function replyHook(data) {
792
+ if data._guid
793
+ workers[data._guid].worker.postMessage({
794
+ id: "targetreceive"
795
+ data: data
796
+ })
797
+ }
798
+
696
799
  // target.DebugCmd
697
800
  //
698
801
  // Post a debug command to the target, ourselves.
699
802
  //
700
-
701
803
  target.DebugCmd = function DebugCmd(data) {
702
804
  naancont.DispatchDebugger(data)
703
805
  }
704
806
 
705
- //
706
807
  // target.PostMessage
707
808
  //
708
809
  // Post a message to the target, ourselves.
709
810
  //
710
-
711
811
  target.PostMessage = function PostMessage(data) {
712
812
  naancont.DispatchMessage(data)
713
813
  list(false, { posted: true })
@@ -716,7 +816,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
716
816
  // termAttach
717
817
  //
718
818
  // Create a closure for an attaching terminal.
719
-
819
+ //
720
820
  target.termAttach = closure termAttach(term, db, statusCB, local connection, inbound) {
721
821
  connection = new(object, this)
722
822
 
@@ -793,7 +893,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
793
893
  // updateController
794
894
  //
795
895
  // Update the naan controller on this target, which means updating for all the terminals.
796
-
896
+ //
797
897
  target.updateController = function updateController(newnc, local conn) {
798
898
  naancont = newnc
799
899
  target.naancont = newnc
@@ -811,7 +911,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
811
911
  // vsiteRefresh
812
912
  //
813
913
  // The vsite upon which we are based has changed.
814
-
914
+ //
815
915
  target.vsiteRefresh = function vsiteRefresh(url_origin) {
816
916
  naancont.VsiteRefresh(url_origin)
817
917
  }
@@ -819,12 +919,13 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
819
919
  // destroy
820
920
  //
821
921
  // Destroy the execution instance.
822
-
922
+ //
823
923
  target.destroy = function destroy() {
824
924
  target.execClosed(Error("instance destroyed"))
825
925
  track.delete(target)
826
926
  }
827
927
 
928
+ js.t.OnReplyHook(replyHook.proc)
828
929
  track.add(target)
829
930
 
830
931
  // finis
@@ -868,13 +969,14 @@ closure termInstallVirtualWatcher(track, naancont) {
868
969
  */
869
970
 
870
971
  function termInit(local manifest) {
871
-
872
- manifest = `(TermHost, TermLocal, findIDEtarget, termIDE, termInstallVirtualWatcher, termInit)
972
+ manifest = `(TermHost, TermLocal, termMainProxy, WorkerToMain, findIDEtarget, termIDE,
973
+ termInstallVirtualWatcher, termInit)
873
974
 
874
975
  Naan.module.build(module.id, "terminals", function(modobj, compobj) {
875
976
  require("./browser.nlg")
876
977
  compobj.manifest = manifest
877
978
  modobj.exports.TermLocal = TermLocal
878
979
  modobj.exports.TermHost = TermHost
980
+ modobj.exports.WorkerToMain = WorkerToMain
879
981
  })
880
982
  } ();
@@ -234,7 +234,10 @@ closure ScopedServiceWorker(pubID, pubVersion, callback, local scoper, result) {
234
234
  scoper = new(object, ScopedServiceWorker)
235
235
  scoper.scopes = {}
236
236
  scoper.serv = ServiceWorker(pubID, pubVersion)
237
- result = scoper.serv.register("/", closure(error, data, local response, filepath, scope) {
237
+ scoper.root = js.r("path").dirname(js.w.location.pathname) // normally "/", but could be subfolder
238
+ if scoper.root.slice(-1) != "/"
239
+ scoper.root = scoper.root.concat("/") // must end in "/"
240
+ result = scoper.serv.register(scoper.root, closure(error, data, local response, filepath, scope) {
238
241
  if data.message == "fetch" {
239
242
  response = {
240
243
  id: "response"
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * column positioning: // // !
7
7
  *
8
- * Copyright (c) 2023 by Richard C. Zulch
8
+ * Copyright (c) 2023-2024 by Richard C. Zulch
9
9
  *
10
10
  */
11
11
 
@@ -22,6 +22,8 @@
22
22
  * onmessage: <proc>(e, message) // message received
23
23
  * onerror: <proc>(e) // error occurred
24
24
  * onclose: <proc>(e) // connection has closed
25
+ * query: <string> // query string starting with ? for insecure connections
26
+ * querys: <string> // query string starting with ? for secure connections
25
27
  * }
26
28
  *
27
29
  */
@@ -41,9 +43,9 @@ closure WebSocket(options, local wsock) {
41
43
  if wsock.ws
42
44
  return (list(false, { open: true }))
43
45
  if window.location.protocol == "https:"
44
- url = "wss://${options.host}"
46
+ url = "wss://${options.host}${options.querys||''}"
45
47
  else
46
- url = "ws://${options.host}"
48
+ url = "ws://${options.host}${options.query||''}"
47
49
  wsock.ws = xnew(window.WebSocket, url)
48
50
  pending = new(nonce)
49
51
 
@@ -22,7 +22,9 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
22
22
  global()
23
23
  client = new(object, this)
24
24
  if !url.match(RegExp("^https?:\/\/", "i"))
25
- url = "http://${url}"
25
+ url = "http://${url}" // a protocol is required
26
+ if url.slice(-1) != "/"
27
+ url = url.concat("/") // must end in "/"
26
28
  client.url = url
27
29
  client.guid = guid
28
30
  client.notifyAfter = 0
@@ -42,7 +44,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
42
44
  //
43
45
 
44
46
  client.docs = closure docs(local error, content, extra) {
45
- `(error, content, extra) = clientRequest(url.concat("/"))
47
+ `(error, content, extra) = clientRequest(url)
46
48
  printline(content)
47
49
  }
48
50
 
@@ -51,7 +53,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
51
53
  //
52
54
 
53
55
  client.status = closure status(cbStatus, timeoutms, local query, error, content, extra, queued) {
54
- query = EncodeQuery("/status/?", {
56
+ query = EncodeQuery("status/?", {
55
57
  timeout: timeoutms
56
58
  after: client.notifyAfter
57
59
  })
@@ -75,7 +77,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
75
77
  //
76
78
 
77
79
  client.get = closure get(path, options, local error, content, extra) {
78
- `(error, content, extra) = clientRequest(url.concat("/", path))
80
+ `(error, content, extra) = clientRequest(url.concat(path))
79
81
  if !error && extra.status != 200
80
82
  error = Error("readFile failed: ".concat(extra.status), {
81
83
  status: extra.status
@@ -91,7 +93,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
91
93
  //
92
94
 
93
95
  client.readFile = closure readFile(filepath, options, local query, error, content, extra) {
94
- query = EncodeQuery("/readfile/?", {
96
+ query = EncodeQuery("readfile/?", {
95
97
  path: filepath
96
98
  })
97
99
  `(error, content, extra) = clientRequest(url.concat(query), options)
@@ -112,7 +114,7 @@ closure NideAPIclient(url, guid, apiRequester, local client) {
112
114
 
113
115
  client.psmRemote = closure psmRemote(options, data, callback,
114
116
  local query, reqOptions, error, content, extra) {
115
- query = EncodeQuery("/psm/?", options)
117
+ query = EncodeQuery("psm/?", options)
116
118
  reqOptions = {
117
119
  putdata: data
118
120
  }
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * column positioning: // // !
8
8
  *
9
- * Copyright (c) 2023 by Richard C. Zulch
9
+ * Copyright (c) 2023-2024 by Richard C. Zulch
10
10
  *
11
11
  */
12
12
 
@@ -80,6 +80,8 @@ closure RelayCon(host, secret, options, local relay, nlregex)
80
80
  onmessage: onmessage
81
81
  onerror: onerror
82
82
  onclose: onclose
83
+ query: undefined // don't put secret on unsecure connections
84
+ querys: secret && EncodeQuery("?", { guid: secret })
83
85
  })
84
86
  result = relay.wscon.connect()
85
87
  if !result.0
@@ -19,6 +19,7 @@
19
19
  */
20
20
 
21
21
  function EncodeQuery(prefix, items, local result, item) {
22
+ global()
22
23
  result = []
23
24
  for item in items
24
25
  result.push(EncodeURIComponent(item).concat("=", EncodeURIComponent(items[item])))
@@ -38,6 +39,7 @@ function EncodeQuery(prefix, items, local result, item) {
38
39
  */
39
40
 
40
41
  function DecodeQuery(text, local output, rpreg, qarr, item, pair) {
42
+ global()
41
43
  output = {}
42
44
  rpreg = RegExp("\\+", "g")
43
45
  qarr = text.split("&")
@@ -62,6 +64,7 @@ function DecodeQuery(text, local output, rpreg, qarr, item, pair) {
62
64
  */
63
65
 
64
66
  function ContentTypeFromFileExt(filepath, local mimeType, encoding) {
67
+ global(JSpath)
65
68
  mimeType = {
66
69
  "css": "text/css",
67
70
  "csv": "text/csv",
@@ -103,6 +106,7 @@ function ContentTypeFromFileExt(filepath, local mimeType, encoding) {
103
106
  */
104
107
 
105
108
  function UUID(local rando) {
109
+ global(RandomBytes)
106
110
  if !RandomBytes
107
111
  return (false)
108
112
  rando = RandomBytes(36) // length of UUID
@@ -128,6 +132,7 @@ function UUID(local rando) {
128
132
  */
129
133
 
130
134
  function VersionCheck(testv, refv, local rxver, test, ref) {
135
+ global()
131
136
  rxver = RegExp("([0-9]+)[.]([0-9]+)[.]([0-9]+)-?[A-Za-z_]*[+]?([0-9]+)")
132
137
  function numerify(x){ Number.parseInt(x) }
133
138
  test = testv.match(rxver).map(numerify.proc)
@@ -147,6 +152,7 @@ function VersionCheck(testv, refv, local rxver, test, ref) {
147
152
  */
148
153
 
149
154
  function JsonParse(data) {
155
+ global(exception)
150
156
  try {
151
157
  data = JSONparse(data)
152
158
  list(false, data)
@@ -165,6 +171,7 @@ function JsonParse(data) {
165
171
  */
166
172
 
167
173
  function JsonStringify(data) {
174
+ global(exception)
168
175
  try {
169
176
  data = JSONstringify(data)
170
177
  list(false, data)
@@ -185,15 +192,18 @@ function JsonStringify(data) {
185
192
 
186
193
  jsScripts = { }; // script values become false on reload
187
194
 
188
- closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
195
+ closure JsLoadScript(libpath, globalID, local savens, fpath, hostpath, pending, scriptTag) {
196
+ global(jsScripts, js, JSpath)
189
197
  if jsScripts[libpath]
190
198
  return // already loaded
199
+ savens = nsactive()
191
200
  if libpath.startsWith("/")
192
201
  fpath = libpath
193
202
  else
194
203
  fpath = "/".concat(libpath)
204
+ hostpath = js.w.location.origin.concat(JSpath.dirname(js.w.location.pathname))
195
205
  if js.s.importScripts && tostring(js.s.importScripts) == "[Function importScripts]" {
196
- fpath = JSpath.dirname(js.w.location.href).concat(fpath)
206
+ fpath = hostpath.concat(fpath)
197
207
  try {
198
208
  js.s.importScripts(fpath) // load in worker context
199
209
  jsScripts[libpath] = js.s[globalID]
@@ -204,7 +214,7 @@ closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
204
214
  } else if js.w { // load in browser context
205
215
  pending = new(nonce)
206
216
  scriptTag = js.w.document.createElement("script")
207
- scriptTag.src = JSpath.dirname(js.w.location.href).concat(fpath, requireQuery())
217
+ scriptTag.src = hostpath.concat(fpath, requireQuery())
208
218
  scriptTag.onload = function (event) {
209
219
  jsScripts[libpath] = js.w[globalID]
210
220
  pending.signal(js.w[globalID])
@@ -219,6 +229,7 @@ closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
219
229
  pending.wait()
220
230
  } else if js.g
221
231
  jsScripts[libpath] = js.r(libpath) // load in NodeJS context
232
+ nsactive(savens)
222
233
  jsScripts[libpath]
223
234
  };
224
235
 
@@ -234,6 +245,7 @@ closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
234
245
  */
235
246
 
236
247
  macro LoadComponentOnDemand(functionKeys, componentPath, local modobj, key) {
248
+ global()
237
249
  modobj = car(nsrights().lookup("module"))
238
250
  functionKeys = eval(functionKeys)
239
251
  componentPath = eval(componentPath)
@@ -281,6 +293,7 @@ macro LoadComponentOnDemand(functionKeys, componentPath, local modobj, key) {
281
293
  */
282
294
 
283
295
  macro LiveExport() {
296
+ global()
284
297
  closure (exporterMod, local importList) {
285
298
  importList = []
286
299
  //