@naanlang/naan 1.0.16 → 1.2.0
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.
- package/LICENSE.md +2 -2
- package/README.md +13 -11
- package/bin/index.js +4 -4
- package/dist/naan.min.js +14 -14
- package/frameworks/browser/https_request.nlg +26 -10
- package/frameworks/browser/sworker.js +26 -25
- package/frameworks/browser/terminals.nlg +118 -55
- package/frameworks/browser/ws_client.nlg +124 -0
- package/frameworks/client/apiclient.nlg +82 -116
- package/frameworks/client/psm_client.nlg +37 -16
- package/frameworks/client/relaycon.nlg +308 -0
- package/frameworks/common/common.nlg +1 -1
- package/frameworks/common/utils.nlg +40 -2
- package/frameworks/node/apiserver.nlg +342 -103
- package/frameworks/node/https_request.nlg +32 -6
- package/frameworks/node/node.nlg +60 -2
- package/frameworks/node/psm_server.nlg +11 -7
- package/frameworks/node/worker.nlg +22 -9
- package/frameworks/node/ws_client.nlg +127 -0
- package/frameworks/project/build.nlg +3 -2
- package/frameworks/project/projects.nlg +8 -2
- package/frameworks/running/debugnub.nlg +2 -2
- package/frameworks/running/debugutil.nlg +1 -1
- package/frameworks/running/executors.nlg +69 -17
- package/frameworks/running/sourcecode.nlg +2 -2
- package/frameworks/running/taskexec.nlg +25 -25
- package/frameworks/storage/dbt_pouch.nlg +8 -6
- package/frameworks/storage/file_manager.nlg +6 -3
- package/frameworks/storage/psm.nlg +5 -3
- package/frameworks/storage/psm_dbtables.nlg +75 -53
- package/frameworks/storage/resources.nlg +4 -2
- package/lib/browser/env_web.js +6 -6
- package/lib/browser/env_webworker.js +1 -1
- package/lib/core/naanlib.js +14 -14
- package/lib/env_node.js +97 -8
- package/lib/env_nodeworker.js +22 -4
- package/package.json +1 -1
- package/plugins/serviceAws/aws/lambda_rest_index.js +5 -1
- package/plugins/serviceAws/aws_dynamo.nlg +91 -32
- package/plugins/serviceAws/dbt_aws.nlg +5 -5
- package/plugins/serviceAws/psm_aws.nlg +2 -2
- package/test/harness.nlg +1 -1
- package/test/test_01_core.nlg +30 -4
- package/test/test_02_context.nlg +2 -2
- package/test/test_07_lingo.nlg +3 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
*
|
|
2
|
+
* https_request.nlg
|
|
3
3
|
*
|
|
4
4
|
* Https operations for the browser.
|
|
5
5
|
*
|
|
6
6
|
* column positioning: // // !
|
|
7
7
|
*
|
|
8
|
-
* Copyright (c) 2021-
|
|
8
|
+
* Copyright (c) 2021-2024 by Richard C. Zulch
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -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
|
+
* debug: <boolean> // log errors and status results
|
|
27
28
|
* }
|
|
28
29
|
*
|
|
29
30
|
* The return is a result tuple comprising:
|
|
@@ -82,15 +83,29 @@ closure HttpsApiRequest(url, options,
|
|
|
82
83
|
//
|
|
83
84
|
// perform the fetch and return when complete
|
|
84
85
|
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
loop { // loop for retries
|
|
87
|
+
`(error, response) = await(window.fetch(urlq, fetchOptions))
|
|
88
|
+
if error {
|
|
89
|
+
if options.debug
|
|
90
|
+
debuglog("HttpsApiRequest error:", url, "error:", error)
|
|
91
|
+
return (list(Error("HttpsApiRequest fetch failed:", error, url)))
|
|
92
|
+
}
|
|
93
|
+
if response.status < 200 || response.status >= 299 { // 299 is "cancelled"
|
|
94
|
+
if options.debug
|
|
95
|
+
debuglog("HttpsApiRequest status:", url, response.statusCode)
|
|
96
|
+
error = Error("HttpsApiRequest status:", url, response.status, {
|
|
97
|
+
status: response.status
|
|
98
|
+
})
|
|
99
|
+
if options.retrier(error)
|
|
100
|
+
continue // optional retry/delay logic
|
|
101
|
+
else
|
|
102
|
+
return (list(error, false, { status: response.status }))
|
|
103
|
+
} else
|
|
104
|
+
break
|
|
105
|
+
}
|
|
88
106
|
contentType = response.headers.get("content-type")
|
|
89
|
-
if
|
|
90
|
-
|
|
91
|
-
status: response.status
|
|
92
|
-
}), false, { status: response.status }))
|
|
93
|
-
if contentType.startsWith("application/json") {
|
|
107
|
+
if contentType.startsWith("application/json")
|
|
108
|
+
|| contentType.startsWith("application/octet-stream") && options.encoding == "json" {
|
|
94
109
|
`(error, content) = await(response.text())
|
|
95
110
|
if !error
|
|
96
111
|
`(error, content) = JsonParse(content)
|
|
@@ -115,6 +130,7 @@ closure HttpsApiRequest(url, options,
|
|
|
115
130
|
list(error, content, {
|
|
116
131
|
headers: headers
|
|
117
132
|
status: response.status
|
|
133
|
+
contentType: contentType
|
|
118
134
|
})
|
|
119
135
|
};
|
|
120
136
|
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
*
|
|
33
33
|
* column positioning: // // !
|
|
34
34
|
*
|
|
35
|
-
* Copyright (c) 2020-
|
|
35
|
+
* Copyright (c) 2020-2024 by Richard C. Zulch
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
var CurrentCacheName = "Naanlang-1.0
|
|
39
|
+
var CurrentCacheName = "Naanlang-1.2.0+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.0
|
|
96
|
-
if (pubVersion != "1.0
|
|
95
|
+
console.log("[1.2.0+1] received new msgport for", sourceId, pubID, "-", pubVersion);
|
|
96
|
+
if (pubVersion != "1.2.0+1") {
|
|
97
97
|
if (upgradeMsgPorts) { // if not activated
|
|
98
|
-
console.log("[1.0
|
|
98
|
+
console.log("[1.2.0+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.0
|
|
104
|
+
version: "1.2.0+1"
|
|
105
105
|
});
|
|
106
|
-
console.log("[1.0
|
|
106
|
+
console.log("[1.2.0+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.0
|
|
137
|
+
console.log("[1.2.0+1] attempting skipWaiting");
|
|
138
138
|
self.skipWaiting();
|
|
139
139
|
} else if (msg.id == "terminate") { // termiante this SW now
|
|
140
|
-
console.log("[1.0
|
|
140
|
+
console.log("[1.2.0+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.0
|
|
153
|
+
console.log("[1.2.0+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.0
|
|
164
|
+
text: "port received by 1.2.0+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.0
|
|
181
|
+
console.log("[1.2.0+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.0
|
|
227
|
+
console.log("[1.2.0+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.0
|
|
232
|
+
console.log("[1.2.0+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.0
|
|
266
|
+
console.log('[1.2.0+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.0
|
|
272
|
+
console.log('[1.2.0+1] claiming clients');
|
|
273
273
|
return (self.clients.claim());
|
|
274
274
|
}).then(function() {
|
|
275
|
-
console.log('[1.0
|
|
275
|
+
console.log('[1.2.0+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.0
|
|
318
|
+
version: "1.2.0+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.0
|
|
366
|
+
console.log("[1.2.0+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.0
|
|
379
|
+
console.log("[1.2.0+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.0
|
|
386
|
+
console.log('[1.2.0+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.0
|
|
392
|
+
version: "1.2.0+1"
|
|
393
393
|
});
|
|
394
394
|
}
|
|
395
395
|
upgradeMsgPorts = false;
|
|
@@ -410,7 +410,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
410
410
|
event.respondWith(
|
|
411
411
|
caches.match(event.request).then(function(response)
|
|
412
412
|
{
|
|
413
|
-
if (response)
|
|
413
|
+
if (response && response.status != 299)
|
|
414
414
|
return (response);
|
|
415
415
|
if (terminated)
|
|
416
416
|
return (new Response(undefined, {
|
|
@@ -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") !== "
|
|
424
|
+
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "d20959c47030d94a5b0694e7b9df2dc1"
|
|
425
425
|
|| request.headers.get('range');
|
|
426
426
|
if (url.pathname.startsWith("/run/")) {
|
|
427
427
|
nocache = true;
|
|
@@ -449,12 +449,13 @@ self.addEventListener('fetch', function(event) {
|
|
|
449
449
|
return (item !== abortItem);
|
|
450
450
|
});
|
|
451
451
|
if (abortItem.aborted) {
|
|
452
|
+
nocache = true; // don't cache the 299!
|
|
452
453
|
return (new Response(undefined, {
|
|
453
454
|
status: 299,
|
|
454
455
|
statusText: "Request Cancelled"
|
|
455
456
|
}));
|
|
456
457
|
}
|
|
457
|
-
console.log("[1.0
|
|
458
|
+
console.log("[1.2.0+1] fetch failed", request.url, e);
|
|
458
459
|
return (new Response(undefined, {
|
|
459
460
|
status: 404,
|
|
460
461
|
statusText: "Fetch Failed"
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2024 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -14,42 +14,77 @@
|
|
|
14
14
|
/*
|
|
15
15
|
* TermHost
|
|
16
16
|
*
|
|
17
|
-
* Make
|
|
17
|
+
* Make an Nide API Server debugger target.
|
|
18
|
+
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* type: <string> // target category, e.g. "Host", "api.yyy.com"
|
|
22
|
+
* workerID: <string> // kind of worker in server subsystem
|
|
23
|
+
* dispatcher: <tuple> // dispatcher function for incoming messages
|
|
24
|
+
* startup: <dictionary> // startup options
|
|
25
|
+
* clientID: <string> // (rare) our identification on client
|
|
26
|
+
* serverID: <string> // (rare) server subsystem for us
|
|
27
|
+
* }
|
|
18
28
|
*
|
|
19
29
|
*/
|
|
20
30
|
|
|
21
|
-
closure TermHost(track, api, name,
|
|
22
|
-
local target, nlregex, clientID, serverID)
|
|
31
|
+
closure TermHost(track, api, name, options, local target, nlregex, xtarg)
|
|
23
32
|
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
global(window)
|
|
34
|
+
options = merge({
|
|
35
|
+
type: "Host"
|
|
36
|
+
workerID: "myDebugWorker"
|
|
37
|
+
clientID: "DebugWorkers"
|
|
38
|
+
serverID: "Workers"
|
|
39
|
+
}, options)
|
|
40
|
+
target = require("../running/executors.nlg").ExecutorBase(track, options.type, name)
|
|
27
41
|
nlregex = RegExp("\\n", "g")
|
|
28
|
-
|
|
29
|
-
workerID = "myDebugWorker"
|
|
30
|
-
target.workerID = workerID
|
|
42
|
+
target.workerID = options.workerID
|
|
31
43
|
target.msgQueue = []
|
|
32
|
-
|
|
44
|
+
target.dispatcher = call(options.dispatcher, function(reply) { reply })
|
|
45
|
+
|
|
46
|
+
// findWorker
|
|
47
|
+
//
|
|
48
|
+
function findWorker(testID, local instance) {
|
|
49
|
+
for instance in track.instances {
|
|
50
|
+
if instance.executor.hostWorkerMatch(api, testID)
|
|
51
|
+
return (instance.executor)
|
|
52
|
+
}
|
|
53
|
+
false
|
|
54
|
+
}
|
|
55
|
+
|
|
33
56
|
// connect
|
|
34
57
|
// Connect with the host if not already connected.
|
|
35
|
-
closure connect(local pending) {
|
|
58
|
+
closure connect(local host, pending) {
|
|
36
59
|
if target.ws
|
|
37
|
-
return
|
|
38
|
-
|
|
60
|
+
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
|
+
target.ws = xnew(window.WebSocket,"ws://${host}")
|
|
39
65
|
pending = new(nonce)
|
|
40
|
-
|
|
66
|
+
|
|
41
67
|
// onopen
|
|
42
68
|
// The WebSocket connection is now open.
|
|
43
|
-
target.ws.onopen = function onopen(e, local spawner) {
|
|
44
|
-
|
|
45
|
-
|
|
69
|
+
target.ws.onopen = function onopen(e, local info, spawner) {
|
|
70
|
+
info = {
|
|
71
|
+
name: name
|
|
72
|
+
workerID: target.workerID
|
|
73
|
+
}
|
|
74
|
+
if options.dispatcher
|
|
75
|
+
info.destID = api.instanceID // valid destination for relay
|
|
76
|
+
target.ws.send(window.JSON.stringify({
|
|
77
|
+
guid: api.guid
|
|
78
|
+
init: info
|
|
79
|
+
}))
|
|
80
|
+
spawner = new(options.startup) || { }
|
|
46
81
|
spawner.name = name
|
|
47
82
|
sendControl("spawn", spawner)
|
|
83
|
+
pending.signal(list(false, { ok: true }))
|
|
48
84
|
}
|
|
49
85
|
|
|
50
86
|
// onmessage
|
|
51
87
|
// A message was received from the worker via WebSockets.
|
|
52
|
-
|
|
53
88
|
target.ws.onmessage = function onmessage(e, message, local msg) {
|
|
54
89
|
try {
|
|
55
90
|
message = new(window.JSON.parse(e.data))
|
|
@@ -77,10 +112,29 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
77
112
|
if !target.written
|
|
78
113
|
target.term.WriteLn("(reconnected)")
|
|
79
114
|
}, 1000).run()
|
|
80
|
-
else if message.
|
|
81
|
-
|
|
115
|
+
else if message.workerOp == "msgin" && message.payload.id == "targetin"
|
|
116
|
+
dispatcher(message) // request from Host
|
|
117
|
+
else if message.respOp || message.id
|
|
118
|
+
debuglog("unknown host response message:", message.respOp || message.id)
|
|
82
119
|
}
|
|
83
|
-
|
|
120
|
+
|
|
121
|
+
// dispatcher
|
|
122
|
+
// Respond to a host request while preserving context to permit reply routing
|
|
123
|
+
closure dispatcher(message, local reply) {
|
|
124
|
+
reply = target.dispatcher(message.payload.data)
|
|
125
|
+
target.ws.send(window.JSON.stringify({
|
|
126
|
+
guid: api.guid
|
|
127
|
+
clientID: message.clientID
|
|
128
|
+
serverID: message.serverID
|
|
129
|
+
workerID: message.workerID
|
|
130
|
+
respOp: "msgout"
|
|
131
|
+
payload: {
|
|
132
|
+
id: "targetout",
|
|
133
|
+
data: reply
|
|
134
|
+
}
|
|
135
|
+
}))
|
|
136
|
+
}
|
|
137
|
+
|
|
84
138
|
// onerror
|
|
85
139
|
// An error occurred on the WebSocket connection.
|
|
86
140
|
target.ws.onerror = function onerror(e) {
|
|
@@ -91,7 +145,8 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
91
145
|
// onclose
|
|
92
146
|
// The WebSocket connection was closed.
|
|
93
147
|
target.ws.onclose = function onclose(e) {
|
|
94
|
-
|
|
148
|
+
if e.code != 1000 && e.code != 1001 && e.code != 1005 && e.code != 1006
|
|
149
|
+
debuglog("ws close:", e.code, e.reason)
|
|
95
150
|
target.execClosed(Error("socket closed", e.code, e.reason))
|
|
96
151
|
target.ws = false
|
|
97
152
|
}
|
|
@@ -104,28 +159,17 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
104
159
|
//
|
|
105
160
|
// New workers created/discovered on this host.
|
|
106
161
|
//
|
|
107
|
-
function hostWorkerUpdate(msg, local localID) {
|
|
108
|
-
|
|
109
|
-
// findWorker
|
|
110
|
-
//
|
|
111
|
-
function findWorker(testID, local instance) {
|
|
112
|
-
for instance in track.instances {
|
|
113
|
-
if instance.executor.hostWorkerMatch(api, testID)
|
|
114
|
-
return (instance.executor)
|
|
115
|
-
}
|
|
116
|
-
false
|
|
117
|
-
}
|
|
118
|
-
|
|
162
|
+
function hostWorkerUpdate(msg, local localID, worker) {
|
|
119
163
|
if msg.id == "spawned" {
|
|
120
164
|
if !findWorker(msg.workerID)
|
|
121
|
-
TermHost(track, api, msg.name, msg.workerID)
|
|
165
|
+
TermHost(track, api, msg.name, { type: options.type, workerID: msg.workerID })
|
|
122
166
|
}
|
|
123
167
|
else if msg.id == "termination"
|
|
124
168
|
track.delete(findWorker(msg.workerID))
|
|
125
|
-
else {
|
|
126
|
-
for localID in msg.
|
|
169
|
+
else if msg.id == "workerlist" {
|
|
170
|
+
for `(localID, worker) in msg.workers
|
|
127
171
|
if !findWorker(localID)
|
|
128
|
-
TermHost(track, api,
|
|
172
|
+
TermHost(track, api, worker.name, { type: options.type, workerID: localID })
|
|
129
173
|
}
|
|
130
174
|
}
|
|
131
175
|
|
|
@@ -135,7 +179,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
135
179
|
// True iff the specified information matches us.
|
|
136
180
|
//
|
|
137
181
|
target.hostWorkerMatch = function hostWorkerMatch(testApi, testID) {
|
|
138
|
-
testApi === api && testID == workerID
|
|
182
|
+
testApi === api && testID == target.workerID
|
|
139
183
|
}
|
|
140
184
|
|
|
141
185
|
//
|
|
@@ -171,8 +215,8 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
171
215
|
target.sendControl = function sendControl(workerOp, payload) {
|
|
172
216
|
target.ws.send(window.JSON.stringify({
|
|
173
217
|
guid: api.guid
|
|
174
|
-
clientID: clientID
|
|
175
|
-
serverID: serverID
|
|
218
|
+
clientID: options.clientID
|
|
219
|
+
serverID: options.serverID
|
|
176
220
|
workerID: target.workerID
|
|
177
221
|
workerOp: workerOp
|
|
178
222
|
payload: payload
|
|
@@ -243,12 +287,15 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
243
287
|
// Post a message to the target.
|
|
244
288
|
//
|
|
245
289
|
|
|
246
|
-
target.PostMessage = function PostMessage(data) {
|
|
247
|
-
connect()
|
|
290
|
+
target.PostMessage = function PostMessage(data, local result) {
|
|
291
|
+
result = connect()
|
|
292
|
+
if result.0
|
|
293
|
+
return (result)
|
|
248
294
|
send({ // send data to worker
|
|
249
295
|
id: "targetin",
|
|
250
296
|
data: data
|
|
251
297
|
})
|
|
298
|
+
list(false, { posted: true })
|
|
252
299
|
}
|
|
253
300
|
|
|
254
301
|
//
|
|
@@ -339,6 +386,9 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
339
386
|
target.ws.close(1000) // 1000: normal close
|
|
340
387
|
}
|
|
341
388
|
|
|
389
|
+
xtarg = findWorker(target.workerID)
|
|
390
|
+
if xtarg
|
|
391
|
+
return (list(false, xtarg)) // already exists
|
|
342
392
|
track.add(target)
|
|
343
393
|
connect() // connect right away to start receiving messages
|
|
344
394
|
|
|
@@ -353,26 +403,34 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
353
403
|
*
|
|
354
404
|
* Make a local debugger target, returning a standard (error, object) tuple.
|
|
355
405
|
*
|
|
406
|
+
* Options:
|
|
407
|
+
* {
|
|
408
|
+
* workerID: <string> // kind of worker in server subsystem
|
|
409
|
+
* // "NaanIDE" for local IDE
|
|
410
|
+
* // "NaanIDE-Debug" for browser debug target
|
|
411
|
+
* startup: <dictionary> // startup options
|
|
412
|
+
* type: <string> // (rare) target category, e.g. "Local"
|
|
413
|
+
* }
|
|
414
|
+
*
|
|
356
415
|
*/
|
|
357
416
|
|
|
358
|
-
closure TermLocal(track, name,
|
|
359
|
-
local target, nlregex, listener)
|
|
417
|
+
closure TermLocal(track, name, options, local target, nlregex, listener)
|
|
360
418
|
{
|
|
361
|
-
|
|
419
|
+
global(js, window)
|
|
420
|
+
options = merge({
|
|
421
|
+
type: "Local"
|
|
422
|
+
}, options)
|
|
423
|
+
if options.workerID == "NaanIDE" {
|
|
362
424
|
if !js.t
|
|
363
425
|
return (list(Error("Cannot access Local IDE executor")))
|
|
364
426
|
termInstallVirtualWatcher(track, js.t)
|
|
365
|
-
return (termIDE(track, name, workerID, js.t))
|
|
427
|
+
return (termIDE(track, name, options.workerID, js.t)) // connect to IDE execution instance itself
|
|
366
428
|
}
|
|
367
|
-
|
|
368
|
-
options = new(options)
|
|
369
|
-
else
|
|
370
|
-
options = { }
|
|
371
|
-
target = require("../running/executors.nlg").ExecutorBase(track, "Local", name)
|
|
429
|
+
target = require("../running/executors.nlg").ExecutorBase(track, options.type, name)
|
|
372
430
|
nlregex = RegExp("\\n", "g")
|
|
373
|
-
target.workerID = workerID
|
|
431
|
+
target.workerID = options.workerID
|
|
374
432
|
target.msgQueue = []
|
|
375
|
-
if workerID == "NaanIDE-Debug" {
|
|
433
|
+
if options.workerID == "NaanIDE-Debug" {
|
|
376
434
|
target.worker = window.open(window.location.href, "_blank")
|
|
377
435
|
target.worker.addEventListener("beforeunload", function(e) { // our target is closing
|
|
378
436
|
destroy()
|
|
@@ -500,6 +558,7 @@ closure TermLocal(track, name, workerID, options,
|
|
|
500
558
|
id: "targetin",
|
|
501
559
|
data: data
|
|
502
560
|
})
|
|
561
|
+
list(false, { posted: true })
|
|
503
562
|
}
|
|
504
563
|
|
|
505
564
|
//
|
|
@@ -591,6 +650,7 @@ closure TermLocal(track, name, workerID, options,
|
|
|
591
650
|
*/
|
|
592
651
|
|
|
593
652
|
closure findIDEtarget(track, name, workerID, naancont, local target) {
|
|
653
|
+
global()
|
|
594
654
|
for target in track.enumlist()
|
|
595
655
|
if target.name == name && target.workerID == workerID && (!target.naancont || target.naancont === naancont)
|
|
596
656
|
return (target)
|
|
@@ -608,6 +668,7 @@ closure findIDEtarget(track, name, workerID, naancont, local target) {
|
|
|
608
668
|
*/
|
|
609
669
|
|
|
610
670
|
closure termIDE(track, name, workerID, naancont, title, local target, connected) {
|
|
671
|
+
global()
|
|
611
672
|
target = findIDEtarget(track, name, workerID, naancont)
|
|
612
673
|
if target { // new naancont on existing target
|
|
613
674
|
target.updateController(naancont)
|
|
@@ -640,6 +701,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
640
701
|
|
|
641
702
|
target.PostMessage = function PostMessage(data) {
|
|
642
703
|
naancont.DispatchMessage(data)
|
|
704
|
+
list(false, { posted: true })
|
|
643
705
|
}
|
|
644
706
|
|
|
645
707
|
// termAttach
|
|
@@ -770,6 +832,7 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
770
832
|
*/
|
|
771
833
|
|
|
772
834
|
closure termInstallVirtualWatcher(track, naancont) {
|
|
835
|
+
global()
|
|
773
836
|
|
|
774
837
|
function watchVsites(msg, local error, target) {
|
|
775
838
|
if msg.op == "VsiteOpen" {
|