@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.
- package/LICENSE.md +1 -1
- package/README.md +1 -1
- package/bin/index.js +5 -2
- package/dist/env_web.js +12 -2
- package/dist/naan.min.js +4 -4
- package/frameworks/browser/https_request.nlg +2 -0
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +123 -21
- package/frameworks/browser/workers.nlg +4 -1
- package/frameworks/browser/ws_client.nlg +5 -3
- package/frameworks/client/apiclient.nlg +8 -6
- package/frameworks/client/relaycon.nlg +3 -1
- package/frameworks/common/common.nlg +16 -3
- package/frameworks/node/apiserver.nlg +205 -5
- package/frameworks/node/worker.nlg +112 -10
- package/frameworks/node/ws_client.nlg +5 -3
- package/frameworks/project/build.nlg +5 -1
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/executors.nlg +3 -1
- package/frameworks/running/taskexec.nlg +5 -1
- package/lib/browser/env_web.js +18 -8
- package/lib/browser/env_webworker.js +22 -3
- package/lib/core/naanlib.js +4 -4
- package/lib/env_node.js +15 -4
- package/lib/env_nodeworker.js +21 -1
- package/package.json +8 -5
- package/plugins/serviceAws/aws/aws-sdk-node.min.js +2 -2
- package/plugins/serviceAws/aws/aws-sdk.min.js +3 -2
- package/plugins/serviceAws/aws_dynamo.nlg +19 -19
- package/plugins/serviceYC/generic_api.yaml +36 -0
- package/plugins/serviceYC/naanide-relay-index.js +148 -0
- package/plugins/serviceYC/serviceYC.nlg +60 -0
- package/plugins/serviceYC/yc_apigateway.nlg +205 -0
- package/plugins/serviceYC/yc_function.nlg +163 -0
- package/plugins/serviceYC/yc_vm.nlg +207 -0
- package/test/test_03_jsinterop.nlg +2 -2
- package/test/test_04_numerics.nlg +170 -2
- package/test/test_07_lingo.nlg +1 -1
|
@@ -16,6 +16,17 @@
|
|
|
16
16
|
*
|
|
17
17
|
* Make an API server object.
|
|
18
18
|
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* name: <string> // server name (default "NaanServer")
|
|
22
|
+
* abspath: <string> // absolute pathname for web root
|
|
23
|
+
* relpath: <string> // web root pth relative to js.d
|
|
24
|
+
* fixedPort: <number> // fixed
|
|
25
|
+
* basePort: <number> // starting point for search
|
|
26
|
+
* gateway: <string> // websocket gateway URL
|
|
27
|
+
* statics: [<string>, ...] // search paths for static content
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
19
30
|
*/
|
|
20
31
|
|
|
21
32
|
closure APIServer(options, local server, chroot) {
|
|
@@ -30,7 +41,10 @@ closure APIServer(options, local server, chroot) {
|
|
|
30
41
|
relpath: ""
|
|
31
42
|
name: "NaanServer"
|
|
32
43
|
}, options)
|
|
33
|
-
|
|
44
|
+
if options.abspath
|
|
45
|
+
chroot = options.abspath
|
|
46
|
+
else
|
|
47
|
+
chroot = JSpath.join(js.d, options.relpath)
|
|
34
48
|
server.root = chroot
|
|
35
49
|
|
|
36
50
|
// updatePort
|
|
@@ -83,7 +97,16 @@ closure APIServer(options, local server, chroot) {
|
|
|
83
97
|
if server.guid
|
|
84
98
|
server.oururl = server.oururl.concat("?guid=", server.guid)
|
|
85
99
|
App.api = server // used remotely by client/relaycon.nlg
|
|
86
|
-
|
|
100
|
+
if options.gateway { // processes at /wsgw endpoint
|
|
101
|
+
server.ws = WebSocketGatewayServer()
|
|
102
|
+
`(error) = server.ws.open(server, options.gateway)
|
|
103
|
+
if error {
|
|
104
|
+
error = Error("APIServer: cannot establish websocket gateway", options.gateway, error)
|
|
105
|
+
ErrorDebuglog(error)
|
|
106
|
+
return (list(error))
|
|
107
|
+
}
|
|
108
|
+
} else // default is native websocket protocols
|
|
109
|
+
server.ws = WebSocketServer(server)
|
|
87
110
|
WesRelay(server) // registers as subsystem
|
|
88
111
|
server.psm = psmServerMod.MakeServerPSM(server, options.name)
|
|
89
112
|
`(error, hostfs) = server.psm.conns.NodeFS.connect("Host", "NideFS", list(""))
|
|
@@ -267,7 +290,7 @@ closure APIServer(options, local server, chroot) {
|
|
|
267
290
|
|
|
268
291
|
server.app.all("/psm", closure(req, res, local guid) {
|
|
269
292
|
guid = req.get("x-naanlang-api-guid")
|
|
270
|
-
if server.guid && guid != server.guid
|
|
293
|
+
if server.guid && guid != server.guid
|
|
271
294
|
res.status(403).send("unauthorized")
|
|
272
295
|
else if !server.hostfs
|
|
273
296
|
res.status(503).send("host filesystem not available")
|
|
@@ -275,12 +298,187 @@ closure APIServer(options, local server, chroot) {
|
|
|
275
298
|
server.hostfs.api(req, res)
|
|
276
299
|
})
|
|
277
300
|
|
|
301
|
+
// "/wsgw"
|
|
302
|
+
|
|
303
|
+
server.app.all("/wsgw", closure(req, res) {
|
|
304
|
+
if !server.ws.requested
|
|
305
|
+
res.status(503).send("websocket gateway not available")
|
|
306
|
+
else
|
|
307
|
+
server.ws.requested(req, res)
|
|
308
|
+
res.set('Content-Type', 'application/json')
|
|
309
|
+
res.status(200).send("")
|
|
310
|
+
})
|
|
311
|
+
|
|
278
312
|
// finis
|
|
279
313
|
|
|
280
314
|
server
|
|
281
315
|
};
|
|
282
316
|
|
|
283
317
|
|
|
318
|
+
/*
|
|
319
|
+
* WebSocketGatewayServer
|
|
320
|
+
*
|
|
321
|
+
* Process websocket operations forwarded by an API Gateway. This connects to the specified gateway
|
|
322
|
+
* component to process the details.
|
|
323
|
+
*
|
|
324
|
+
* Gateway handler methods:
|
|
325
|
+
* handler = Gateway(server) -- constructor, returns gateway object
|
|
326
|
+
* `(error) = open(wsgate) -- initialize for any API Gateway
|
|
327
|
+
* `(error, data) = requested(req, res) -- process incoming requests
|
|
328
|
+
* `(error) = send(connID, message) -- send a message
|
|
329
|
+
* close() -- close the gateway for all connections
|
|
330
|
+
*
|
|
331
|
+
*/
|
|
332
|
+
|
|
333
|
+
closure WebSocketGatewayServer(local wsgate) {
|
|
334
|
+
wsgate = new(object, this)
|
|
335
|
+
wsgate.conns = {} // our connections indexed by connID
|
|
336
|
+
wsgate.subsystems = { } // registered subsystems
|
|
337
|
+
|
|
338
|
+
// open
|
|
339
|
+
//
|
|
340
|
+
// Open the server with the specified gateway.
|
|
341
|
+
//
|
|
342
|
+
wsgate.open = closure open(server, gatewayPath) {
|
|
343
|
+
try {
|
|
344
|
+
wsgate.handler = require(gatewayPath).Gateway(server)
|
|
345
|
+
result = wsgate.handler.open()
|
|
346
|
+
if result.0
|
|
347
|
+
return (list(result.0))
|
|
348
|
+
} catch {
|
|
349
|
+
return (list(exception))
|
|
350
|
+
}
|
|
351
|
+
wsgate.guid = server.guid
|
|
352
|
+
list(false, { ok: true })
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// requested
|
|
356
|
+
//
|
|
357
|
+
// We have an incoming request translated from WS by the API Gateway. This finds out from our
|
|
358
|
+
// gateway handler the client this pertains to and connects/disconnects/messages as appropriate.
|
|
359
|
+
//
|
|
360
|
+
wsgate.requested = closure requested(req, res, local error, data, conn, message) {
|
|
361
|
+
// reqOpen
|
|
362
|
+
// Get our connection or make one.
|
|
363
|
+
function reqOpen(connID) {
|
|
364
|
+
conn = wsgate.conns[connID]
|
|
365
|
+
if !conn {
|
|
366
|
+
conn = WebSocketConn(wsgate, connID)
|
|
367
|
+
wsgate.conns[connID] = conn
|
|
368
|
+
for serverID in wsgate.subsystems
|
|
369
|
+
wsgate.subsystems[serverID].wsOpen(conn)
|
|
370
|
+
}
|
|
371
|
+
conn
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
`(error, data) = wsgate.handler.requested(req, res)
|
|
375
|
+
if data.op == "connect"
|
|
376
|
+
conn = reqOpen(data.connID)
|
|
377
|
+
else if data.op == "message"
|
|
378
|
+
reqOpen(data.connID).msgin(data.message)
|
|
379
|
+
else if data.op == "disconnect" {
|
|
380
|
+
conn = wsgate.conns[data.connID]
|
|
381
|
+
wsgate.conns[data.connID] = undefined
|
|
382
|
+
if conn {
|
|
383
|
+
conn.close(data.code, data.reason)
|
|
384
|
+
for serverID in wsgate.subsystems
|
|
385
|
+
wsgate.subsystems[serverID].wsClose(conn)
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// close
|
|
391
|
+
//
|
|
392
|
+
// Respond to server closing.
|
|
393
|
+
//
|
|
394
|
+
wsgate.close = function close(conn, local serverID) {
|
|
395
|
+
wsgate.handler.close()
|
|
396
|
+
wsgate.handler = false
|
|
397
|
+
for serverID in wsgate.subsystems
|
|
398
|
+
wsgate.subsystems[serverID].wsClose()
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// finis
|
|
402
|
+
wsgate
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
/*
|
|
407
|
+
* WebSocketConn
|
|
408
|
+
*
|
|
409
|
+
* WebSocketConn objects represent a connection with a particular client. These are created when
|
|
410
|
+
* a new client connects. The protocol is JSON with the top level being a dictionary having the
|
|
411
|
+
* following static keys specified by the client:
|
|
412
|
+
* serverID: defined by the server, this string defines where requests should be routed.
|
|
413
|
+
* clientID: defined by the client, this string defines where replies should be sent.
|
|
414
|
+
* These are class (code) designators. Further keys can be defined to identify a specific instance on
|
|
415
|
+
* the client or server.
|
|
416
|
+
*
|
|
417
|
+
*/
|
|
418
|
+
|
|
419
|
+
closure WebSocketConn(wsgate, connID, local wsconn) {
|
|
420
|
+
global()
|
|
421
|
+
wsconn = new(object, this)
|
|
422
|
+
wsconn.info = {
|
|
423
|
+
destID: UUID()
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// msgin
|
|
427
|
+
//
|
|
428
|
+
// This finds the appropriate target for an incoming message, which can be a relay message that
|
|
429
|
+
// we send on to the next node on the network.
|
|
430
|
+
//
|
|
431
|
+
wsconn.msgin = closure msgin(message, local error) {
|
|
432
|
+
if wsgate.guid && message.guid != wsgate.guid
|
|
433
|
+
error = Error("unauthorized")
|
|
434
|
+
else if message.init {
|
|
435
|
+
if message.init.destID {
|
|
436
|
+
wsconn.relay = true
|
|
437
|
+
wsgate.subsystems.Relay.wsChangeDestID(conn, wsconn.info.destID, message.init.destID)
|
|
438
|
+
}
|
|
439
|
+
wsconn.info = merge(wsconn.info, message.init)
|
|
440
|
+
}
|
|
441
|
+
else if message.respOp && wsgate.subsystems.Relay
|
|
442
|
+
wsgate.subsystems.Relay.wsReceive(message, wsconn) // with respOp, must be a relay
|
|
443
|
+
else if message.clientID && wsgate.subsystems[message.serverID]
|
|
444
|
+
wsgate.subsystems[message.serverID].wsReceive(message, wsconn)
|
|
445
|
+
else
|
|
446
|
+
error = Error("can't route message")
|
|
447
|
+
if error
|
|
448
|
+
ErrorDebuglog("WebSocketConn.msgin error:", error)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
// on close
|
|
452
|
+
//
|
|
453
|
+
// Connection has closed.
|
|
454
|
+
//
|
|
455
|
+
wsconn.close = closure close(code, reason) {
|
|
456
|
+
if code != 1000 && code != 1001 && code != 1005 && code != 1006
|
|
457
|
+
debuglog("WebSocketConn: connection has closed:", code, reason, JSONstringify(wsconn.info))
|
|
458
|
+
wsconn.closed = {
|
|
459
|
+
code: code
|
|
460
|
+
reason: reason
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// send
|
|
465
|
+
//
|
|
466
|
+
// Send a dictionary, which must have a clientID defined.
|
|
467
|
+
//
|
|
468
|
+
wsconn.send = function send(message) {
|
|
469
|
+
if !message.clientID || !message.serverID
|
|
470
|
+
throw("WebSocketConn.send: client and server IDs required")
|
|
471
|
+
if wsgate.closed
|
|
472
|
+
list(Error("cannot send - websocket closed"))
|
|
473
|
+
wsgate.handler.send(connID, JSONstringify(message))
|
|
474
|
+
list(false, { ok: true })
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// finis
|
|
478
|
+
wsconn
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
|
|
284
482
|
/*
|
|
285
483
|
* WebSocketServer
|
|
286
484
|
*
|
|
@@ -322,8 +520,9 @@ closure WebSocketServer(server, local websocks) {
|
|
|
322
520
|
})
|
|
323
521
|
|
|
324
522
|
// closeConn
|
|
523
|
+
//
|
|
325
524
|
// respond to connection closing
|
|
326
|
-
|
|
525
|
+
//
|
|
327
526
|
websocks.closeConn = function closeConn(conn, local serverID) {
|
|
328
527
|
websocks.conns = websocks.conns.filter(function(item) {
|
|
329
528
|
item !== conn
|
|
@@ -641,7 +840,8 @@ function apisLoadLibs() {
|
|
|
641
840
|
};
|
|
642
841
|
|
|
643
842
|
function ApisInit(local manifest) {
|
|
644
|
-
manifest = `(APIServer, WebSocketServer, WesCon, WesRelay,
|
|
843
|
+
manifest = `(APIServer, WebSocketGatewayServer, WebSocketConn, WebSocketServer, WesCon, WesRelay,
|
|
844
|
+
apisLoadLibs, ApisInit)
|
|
645
845
|
|
|
646
846
|
Naan.module.build(module.id, "apiserver", function(modobj, compobj) {
|
|
647
847
|
require("./node.nlg")
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
closure workCurrent(workerID, startup, local current) {
|
|
21
|
+
closure workCurrent(workco, workerID, startup, local current) {
|
|
22
22
|
global()
|
|
23
23
|
current = new(object, this)
|
|
24
24
|
current.workerID = workerID
|
|
@@ -31,9 +31,22 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
31
31
|
debugout: ONdebugOut.proc
|
|
32
32
|
messageout: ONmessageOut.proc
|
|
33
33
|
})
|
|
34
|
+
current.guid = 1
|
|
35
|
+
current.host = js.t // our magic Naan controller reference
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
// replyHook
|
|
38
|
+
//
|
|
39
|
+
// Intercept the ReplyMessage function to see if we should handle it.
|
|
40
|
+
//
|
|
41
|
+
function replyHook(data) {
|
|
42
|
+
if data._guid
|
|
43
|
+
workco.uworkers[data._guid].msgport.postMessage({
|
|
44
|
+
id: "targetreceive"
|
|
45
|
+
data: data
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
current.host.OnReplyHook(replyHook.proc)
|
|
49
|
+
|
|
37
50
|
// ONtextOut
|
|
38
51
|
// Process console text output by Naan.
|
|
39
52
|
|
|
@@ -79,6 +92,8 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
79
92
|
// Process message output.
|
|
80
93
|
|
|
81
94
|
function ONmessageOut(data) {
|
|
95
|
+
if data._guid
|
|
96
|
+
return // already replied
|
|
82
97
|
sendAll({
|
|
83
98
|
id: "targetout",
|
|
84
99
|
data: data
|
|
@@ -98,6 +113,7 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
98
113
|
// Notify all links that we have terminated.
|
|
99
114
|
|
|
100
115
|
function exitNotify(exitCode, local link) {
|
|
116
|
+
workco.uworkers[current.guid] = undefined
|
|
101
117
|
for link in current.links
|
|
102
118
|
link.exitWorker(exitCode)
|
|
103
119
|
}
|
|
@@ -157,7 +173,7 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
157
173
|
if !(linkref.link eq thislink)
|
|
158
174
|
linkref.responder(msg)
|
|
159
175
|
}
|
|
160
|
-
|
|
176
|
+
|
|
161
177
|
//
|
|
162
178
|
// vitalUpdate
|
|
163
179
|
//
|
|
@@ -172,6 +188,81 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
172
188
|
};
|
|
173
189
|
|
|
174
190
|
|
|
191
|
+
/*
|
|
192
|
+
* workMainProxy
|
|
193
|
+
*
|
|
194
|
+
* Make a nodejs proxy representing the main thread. This runs inside the worker and allows it
|
|
195
|
+
* to do remote execution with Main.
|
|
196
|
+
*
|
|
197
|
+
*/
|
|
198
|
+
|
|
199
|
+
closure workMainProxy(track, name, options, local target) {
|
|
200
|
+
global(js)
|
|
201
|
+
target = require("../running/executors.nlg").ExecutorBase(track, "mainProxy", name)
|
|
202
|
+
target.name = name
|
|
203
|
+
|
|
204
|
+
//
|
|
205
|
+
// target.PostMessage
|
|
206
|
+
//
|
|
207
|
+
// Post a message to the main thread.
|
|
208
|
+
//
|
|
209
|
+
target.PostMessage = function PostMessage(data) {
|
|
210
|
+
js.t.DispatchMessage(data)
|
|
211
|
+
list(false, { posted: true })
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
//
|
|
215
|
+
// onreceive
|
|
216
|
+
//
|
|
217
|
+
// Process a received message from the main thread, typically in response.
|
|
218
|
+
//
|
|
219
|
+
function onreceive(data) {
|
|
220
|
+
target.execReceived(data)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// destroy
|
|
224
|
+
//
|
|
225
|
+
// Destroy the execution instance.
|
|
226
|
+
//
|
|
227
|
+
target.destroy = function destroy() {
|
|
228
|
+
target.execClosed(Error("instance destroyed"))
|
|
229
|
+
track.delete(target)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
js.t.OnReceive(onreceive.proc)
|
|
233
|
+
track.add(target)
|
|
234
|
+
|
|
235
|
+
// finis
|
|
236
|
+
|
|
237
|
+
list(false, target)
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* WorkerToMain
|
|
243
|
+
*
|
|
244
|
+
* Connect our worker to the main thread, returning a result tuple with an executor representing
|
|
245
|
+
* Main. Use this to create a context object for Main, allowing remote evaluation.
|
|
246
|
+
*
|
|
247
|
+
*/
|
|
248
|
+
|
|
249
|
+
closure WorkerToMain(local nideRunning, track) {
|
|
250
|
+
// mainProxy -- link tracker to main thread proxy
|
|
251
|
+
function mainProxy(track, name, options) {
|
|
252
|
+
workMainProxy(track, name, options)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if !js.g {
|
|
256
|
+
error = Error("WorkerToMain only available in node workers")
|
|
257
|
+
return (list(error))
|
|
258
|
+
}
|
|
259
|
+
nideRunning = require("naanlib:frameworks/running/executors.nlg")
|
|
260
|
+
track = nideRunning.ExecutorTracker()
|
|
261
|
+
track.register(mainProxy, "proxy")
|
|
262
|
+
track.spawn("proxy") // returns result tuple
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
|
|
175
266
|
/*
|
|
176
267
|
* workThread
|
|
177
268
|
*
|
|
@@ -179,12 +270,13 @@ closure workCurrent(workerID, startup, local current) {
|
|
|
179
270
|
*
|
|
180
271
|
*/
|
|
181
272
|
|
|
182
|
-
closure workThread(workerID, startup, local worker, options, subChannel, deathWatcher) {
|
|
273
|
+
closure workThread(workco, workerID, startup, local worker, options, subChannel, deathWatcher) {
|
|
183
274
|
global(threads, JSpath)
|
|
184
275
|
worker = new(object, this)
|
|
185
276
|
worker.name = startup.name
|
|
186
277
|
worker.workerID = workerID
|
|
187
278
|
worker.links = []
|
|
279
|
+
worker.guid = UUID()
|
|
188
280
|
|
|
189
281
|
// create our worker thread
|
|
190
282
|
|
|
@@ -207,6 +299,7 @@ closure workThread(workerID, startup, local worker, options, subChannel, deathWa
|
|
|
207
299
|
// Notify all links that we have terminated.
|
|
208
300
|
|
|
209
301
|
function exitNotify(exitCode, local link) {
|
|
302
|
+
workco.uworkers[worker.guid] = undefined
|
|
210
303
|
for link in worker.links
|
|
211
304
|
link.exitWorker(exitCode)
|
|
212
305
|
worker.links = []
|
|
@@ -262,6 +355,12 @@ closure workThread(workerID, startup, local worker, options, subChannel, deathWa
|
|
|
262
355
|
worker.links[0].responder({ // only send this to first link
|
|
263
356
|
id: "started" // don't want multiple initializers
|
|
264
357
|
}) }
|
|
358
|
+
else if msg.id == "targetsend" {
|
|
359
|
+
msg.data._guid = worker.guid
|
|
360
|
+
js.t.DispatchMessage({
|
|
361
|
+
id: "targetin"
|
|
362
|
+
data: msg.data
|
|
363
|
+
}) }
|
|
265
364
|
else {
|
|
266
365
|
if msg.id == "status"
|
|
267
366
|
worker.lastStatus = milliseconds()
|
|
@@ -403,6 +502,7 @@ closure workController(api, local workco) {
|
|
|
403
502
|
workco = new(object, this)
|
|
404
503
|
workco.serverID = "Workers" // our serverID, used for communications
|
|
405
504
|
workco.workers = { } // dictionary of workers by workerID
|
|
505
|
+
workco.uworkers = { } // dictionary of workers by GUID
|
|
406
506
|
workco.links = new(weakmap)
|
|
407
507
|
api.Register(workco.serverID, workco)
|
|
408
508
|
|
|
@@ -487,9 +587,10 @@ closure workController(api, local workco) {
|
|
|
487
587
|
else if message.workerOp == "spawn" {
|
|
488
588
|
if !worker { // create worker if needed
|
|
489
589
|
if message.workerID == "NideServer"
|
|
490
|
-
worker = workco.current = workCurrent(message.workerID, message.payload)
|
|
590
|
+
worker = workco.current = workCurrent(workco, message.workerID, message.payload)
|
|
491
591
|
else
|
|
492
|
-
worker = workThread(message.workerID, message.payload)
|
|
592
|
+
worker = workThread(workco, message.workerID, message.payload)
|
|
593
|
+
workco.uworkers[worker.guid] = worker
|
|
493
594
|
workco.workers[message.workerID] = worker }
|
|
494
595
|
if !link
|
|
495
596
|
makeLink(message, conn) // make sure we have a link for responses
|
|
@@ -521,7 +622,7 @@ closure workController(api, local workco) {
|
|
|
521
622
|
return } }
|
|
522
623
|
error = Error("invalid parameters", message.workerOp, message.workerID)
|
|
523
624
|
}
|
|
524
|
-
|
|
625
|
+
ErrorDebuglog("workController.wsReceive error:", error)
|
|
525
626
|
}
|
|
526
627
|
|
|
527
628
|
//
|
|
@@ -562,12 +663,13 @@ closure workController(api, local workco) {
|
|
|
562
663
|
*/
|
|
563
664
|
|
|
564
665
|
function workInit(local manifest) {
|
|
565
|
-
|
|
566
|
-
|
|
666
|
+
manifest = `(workCurrent, workMainProxy, WorkerToMain, workThread, workLink, workController,
|
|
667
|
+
workInit)
|
|
567
668
|
|
|
568
669
|
Naan.module.build(module.id, "worker", function(modobj, compobj) {
|
|
569
670
|
require("./node.nlg")
|
|
570
671
|
compobj.manifest = manifest
|
|
571
672
|
modobj.exports.WorkerController = workController
|
|
673
|
+
modobj.exports.WorkerToMain = WorkerToMain
|
|
572
674
|
})
|
|
573
675
|
}();
|
|
@@ -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
|
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
* onmessage: <proc>(e, message) // message received
|
|
26
26
|
* onerror: <proc>(e) // error occurred
|
|
27
27
|
* onclose: <proc>(e) // connection has closed
|
|
28
|
+
* query: <string> // query string starting with ? for insecure connections
|
|
29
|
+
* querys: <string> // query string starting with ? for secure connections
|
|
28
30
|
* }
|
|
29
31
|
*
|
|
30
32
|
*/
|
|
@@ -45,9 +47,9 @@ closure WebSocket(host, options, local wsock) {
|
|
|
45
47
|
if error
|
|
46
48
|
return (list(error))
|
|
47
49
|
if options.wss
|
|
48
|
-
url = "wss://${host}"
|
|
50
|
+
url = "wss://${host}${options.querys||''}"
|
|
49
51
|
else
|
|
50
|
-
url = "ws://${host}"
|
|
52
|
+
url = "ws://${host}${options.query||''}"
|
|
51
53
|
wsock.ws = xnew(ws.default, url)
|
|
52
54
|
pending = new(nonce)
|
|
53
55
|
|
|
@@ -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
|
|
|
@@ -728,6 +728,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
728
728
|
tasks: group.tasks
|
|
729
729
|
readpath: infile,
|
|
730
730
|
writepath: outfile
|
|
731
|
+
follow: group.follow || undefined
|
|
731
732
|
}
|
|
732
733
|
if group.input.startsWith("@")
|
|
733
734
|
entry.insource = JSpath.join(group.input.substring(1), group.sources[sdex])
|
|
@@ -982,6 +983,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
982
983
|
overwrite: true // overwrite files
|
|
983
984
|
force: true // ignore modify date
|
|
984
985
|
idmode: true // preserve ids and mode
|
|
986
|
+
follow: entry.follow // optional follow links
|
|
985
987
|
})
|
|
986
988
|
if error // deepcopy returns a list of errors
|
|
987
989
|
error = error.0 // but we're only doing one item
|
|
@@ -1296,6 +1298,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1296
1298
|
//
|
|
1297
1299
|
build.increment = closure increment(newnum, local error, filecon, buildnum) {
|
|
1298
1300
|
build.buildnum = undefined
|
|
1301
|
+
if !build.buildnopath
|
|
1302
|
+
return (list(false, { version: false }))
|
|
1299
1303
|
`(error, filecon) = fs.readFile(build.buildnopath)
|
|
1300
1304
|
if !error
|
|
1301
1305
|
buildnum = toint(filecon.trim())
|
|
@@ -296,7 +296,7 @@ closure projConnector(projman, projtype, local connector, watch) {
|
|
|
296
296
|
*
|
|
297
297
|
* Nide.proj/
|
|
298
298
|
* nide_cliser.cfg - JSON definition of the project (see below)
|
|
299
|
-
* NaanIDE_version.txt - [default] substitution file defining 1.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.3.1+1 etc.
|
|
300
300
|
* NaanIDE_version_builds.txt - [default] contains current build number as decimal string
|
|
301
301
|
* build/ - [optional] default build output location
|
|
302
302
|
* NaanIDE.lic - [optional] defines Zulch Laboratories, Inc. and other license info
|
|
@@ -56,9 +56,11 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
56
56
|
|
|
57
57
|
exec.execReceived = closure execReceived(data, local pending) {
|
|
58
58
|
pending = exec.pending[data.xid]
|
|
59
|
-
if !pending {
|
|
59
|
+
if !pending { // not waiting on message
|
|
60
60
|
if data.xmsg == "xready"
|
|
61
61
|
exec.pending.ready = true
|
|
62
|
+
if data.xmsg == "xattention"
|
|
63
|
+
{ }
|
|
62
64
|
return
|
|
63
65
|
}
|
|
64
66
|
exec.pending[data.xid] = undefined
|
|
@@ -28,12 +28,16 @@ closure TaskDispatcher(replier, local contexts, gohome, util) {
|
|
|
28
28
|
reply = {
|
|
29
29
|
xmsg: "error"
|
|
30
30
|
xid: data.xid
|
|
31
|
+
_guid: data._guid || undefined
|
|
31
32
|
error: "unknown operation"
|
|
32
33
|
}
|
|
33
34
|
try {
|
|
34
35
|
restorens = makeActivator()
|
|
35
36
|
if data.xmsg == "xstart"
|
|
36
|
-
reply = {
|
|
37
|
+
reply = { // ready to accept messages
|
|
38
|
+
xmsg: "xready"
|
|
39
|
+
_guid: data._guid || undefined
|
|
40
|
+
}
|
|
37
41
|
else if data.xmsg == "register" {
|
|
38
42
|
//
|
|
39
43
|
// register a new context to default namespace
|
package/lib/browser/env_web.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2017-
|
|
9
|
+
* Copyright (c) 2017-2024 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -223,7 +223,17 @@ exports.NaanControllerWeb = function() {
|
|
|
223
223
|
}, 1);
|
|
224
224
|
};
|
|
225
225
|
|
|
226
|
+
var replyHook;
|
|
227
|
+
this.OnReplyHook = function OnReplyHook(proc) {
|
|
228
|
+
replyHook = proc;
|
|
229
|
+
return (proc);
|
|
230
|
+
};
|
|
231
|
+
|
|
226
232
|
this.ReplyMessage = function ReplyMessage(data) { // "remote" -> "local"
|
|
233
|
+
if (replyHook)
|
|
234
|
+
setTimeout(function() {
|
|
235
|
+
replyHook(data);
|
|
236
|
+
}, 1);
|
|
227
237
|
termlist.forEach(function(term) {
|
|
228
238
|
if (term.OnMessageOut)
|
|
229
239
|
term.OnMessageOut(data);
|
|
@@ -526,7 +536,7 @@ exports.NaanControllerWeb = function() {
|
|
|
526
536
|
statedoc.curversion = kStateCurrentVersion;
|
|
527
537
|
statedoc.firstver = kStateFirstVersion;
|
|
528
538
|
statedoc.licensee = "MIT-License";
|
|
529
|
-
statedoc.verstring = "1.
|
|
539
|
+
statedoc.verstring = "1.3.1+1";
|
|
530
540
|
statedoc.date = new Date().toISOString();
|
|
531
541
|
statedoc.prefs = prefs;
|
|
532
542
|
statedoc.naan = naanlib.saveState(false); // true to optimize, which is a bit slower
|
|
@@ -544,7 +554,7 @@ exports.NaanControllerWeb = function() {
|
|
|
544
554
|
|| statedoc.firstver > kStateCurrentVersion
|
|
545
555
|
|| statedoc.curversion < kStateFirstVersion
|
|
546
556
|
|| statedoc.licensee != "MIT-License"
|
|
547
|
-
|| statedoc.verstring != "1.
|
|
557
|
+
|| statedoc.verstring != "1.3.1+1")
|
|
548
558
|
{
|
|
549
559
|
localStorage.removeItem("NaanState_Hosted");
|
|
550
560
|
return (false);
|
|
@@ -603,7 +613,7 @@ exports.NaanControllerWeb = function() {
|
|
|
603
613
|
op: "VsiteOpen",
|
|
604
614
|
name: vsiteName,
|
|
605
615
|
naancont: contSelf,
|
|
606
|
-
title: vsiteName + " 1.
|
|
616
|
+
title: vsiteName + " 1.3.1+1"
|
|
607
617
|
});
|
|
608
618
|
}
|
|
609
619
|
} catch (e) {
|
|
@@ -617,7 +627,7 @@ exports.NaanControllerWeb = function() {
|
|
|
617
627
|
op: "VsiteClose",
|
|
618
628
|
name: vsiteName,
|
|
619
629
|
naancont: contSelf,
|
|
620
|
-
title: vsiteName + " 1.
|
|
630
|
+
title: vsiteName + " 1.3.1+1"
|
|
621
631
|
});
|
|
622
632
|
termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
|
|
623
633
|
}
|
|
@@ -630,10 +640,10 @@ exports.NaanControllerWeb = function() {
|
|
|
630
640
|
if (querystrings["restart"] || !loadLocal())
|
|
631
641
|
{ // don't load state or can't load state
|
|
632
642
|
naanlib.banner();
|
|
633
|
-
var hostpath = naanlib.js.r("path").dirname(window.location.
|
|
643
|
+
var hostpath = window.location.origin.concat(naanlib.js.r("path").dirname(window.location.pathname));
|
|
634
644
|
naanlib.start({
|
|
635
|
-
cmd: 'App.version = "1.
|
|
636
|
-
+ 'App.cache = "
|
|
645
|
+
cmd: 'App.version = "1.3.1+1";;\r\n'
|
|
646
|
+
+ 'App.cache = "1f0eccb08fd1a57ede0bd91dc0e934cc";;\r\n'
|
|
637
647
|
+ 'Naan.module.requireQuery({ naanver: App.cache });;\r\n'
|
|
638
648
|
+ 'Naan.module.webparse("naan_init.nlg", "' + hostpath + '", { naanver: App.cache });;\r\n'
|
|
639
649
|
});
|