@naanlang/naan 1.2.1 → 1.3.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 +1 -1
- package/README.md +1 -1
- package/bin/index.js +5 -2
- package/dist/env_web.js +11 -1
- 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/node/apiserver.nlg +190 -4
- package/frameworks/node/worker.nlg +112 -10
- package/frameworks/node/ws_client.nlg +5 -3
- package/frameworks/project/build.nlg +3 -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 +17 -7
- 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_07_lingo.nlg +1 -1
|
@@ -83,7 +83,16 @@ closure APIServer(options, local server, chroot) {
|
|
|
83
83
|
if server.guid
|
|
84
84
|
server.oururl = server.oururl.concat("?guid=", server.guid)
|
|
85
85
|
App.api = server // used remotely by client/relaycon.nlg
|
|
86
|
-
|
|
86
|
+
if options.gateway { // processes at /wsgw endpoint
|
|
87
|
+
server.ws = WebSocketGatewayServer()
|
|
88
|
+
`(error) = server.ws.open(server, options.gateway)
|
|
89
|
+
if error {
|
|
90
|
+
error = Error("APIServer: cannot establish websocket gateway", options.gateway, error)
|
|
91
|
+
ErrorDebuglog(error)
|
|
92
|
+
return (list(error))
|
|
93
|
+
}
|
|
94
|
+
} else // default is native websocket protocols
|
|
95
|
+
server.ws = WebSocketServer(server)
|
|
87
96
|
WesRelay(server) // registers as subsystem
|
|
88
97
|
server.psm = psmServerMod.MakeServerPSM(server, options.name)
|
|
89
98
|
`(error, hostfs) = server.psm.conns.NodeFS.connect("Host", "NideFS", list(""))
|
|
@@ -267,7 +276,7 @@ closure APIServer(options, local server, chroot) {
|
|
|
267
276
|
|
|
268
277
|
server.app.all("/psm", closure(req, res, local guid) {
|
|
269
278
|
guid = req.get("x-naanlang-api-guid")
|
|
270
|
-
if server.guid && guid != server.guid
|
|
279
|
+
if server.guid && guid != server.guid
|
|
271
280
|
res.status(403).send("unauthorized")
|
|
272
281
|
else if !server.hostfs
|
|
273
282
|
res.status(503).send("host filesystem not available")
|
|
@@ -275,12 +284,187 @@ closure APIServer(options, local server, chroot) {
|
|
|
275
284
|
server.hostfs.api(req, res)
|
|
276
285
|
})
|
|
277
286
|
|
|
287
|
+
// "/wsgw"
|
|
288
|
+
|
|
289
|
+
server.app.all("/wsgw", closure(req, res) {
|
|
290
|
+
if !server.ws.requested
|
|
291
|
+
res.status(503).send("websocket gateway not available")
|
|
292
|
+
else
|
|
293
|
+
server.ws.requested(req, res)
|
|
294
|
+
res.set('Content-Type', 'application/json')
|
|
295
|
+
res.status(200).send("")
|
|
296
|
+
})
|
|
297
|
+
|
|
278
298
|
// finis
|
|
279
299
|
|
|
280
300
|
server
|
|
281
301
|
};
|
|
282
302
|
|
|
283
303
|
|
|
304
|
+
/*
|
|
305
|
+
* WebSocketGatewayServer
|
|
306
|
+
*
|
|
307
|
+
* Process websocket operations forwarded by an API Gateway. This connects to the specified gateway
|
|
308
|
+
* component to process the details.
|
|
309
|
+
*
|
|
310
|
+
* Gateway handler methods:
|
|
311
|
+
* handler = Gateway(server) -- constructor, returns gateway object
|
|
312
|
+
* `(error) = open(wsgate) -- initialize for any API Gateway
|
|
313
|
+
* `(error, data) = requested(req, res) -- process incoming requests
|
|
314
|
+
* `(error) = send(connID, message) -- send a message
|
|
315
|
+
* close() -- close the gateway for all connections
|
|
316
|
+
*
|
|
317
|
+
*/
|
|
318
|
+
|
|
319
|
+
closure WebSocketGatewayServer(local wsgate) {
|
|
320
|
+
wsgate = new(object, this)
|
|
321
|
+
wsgate.conns = {} // our connections indexed by connID
|
|
322
|
+
wsgate.subsystems = { } // registered subsystems
|
|
323
|
+
|
|
324
|
+
// open
|
|
325
|
+
//
|
|
326
|
+
// Open the server with the specified gateway.
|
|
327
|
+
//
|
|
328
|
+
wsgate.open = closure open(server, gatewayPath) {
|
|
329
|
+
try {
|
|
330
|
+
wsgate.handler = require(gatewayPath).Gateway(server)
|
|
331
|
+
result = wsgate.handler.open()
|
|
332
|
+
if result.0
|
|
333
|
+
return (list(result.0))
|
|
334
|
+
} catch {
|
|
335
|
+
return (list(exception))
|
|
336
|
+
}
|
|
337
|
+
wsgate.guid = server.guid
|
|
338
|
+
list(false, { ok: true })
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// requested
|
|
342
|
+
//
|
|
343
|
+
// We have an incoming request translated from WS by the API Gateway. This finds out from our
|
|
344
|
+
// gateway handler the client this pertains to and connects/disconnects/messages as appropriate.
|
|
345
|
+
//
|
|
346
|
+
wsgate.requested = closure requested(req, res, local error, data, conn, message) {
|
|
347
|
+
// reqOpen
|
|
348
|
+
// Get our connection or make one.
|
|
349
|
+
function reqOpen(connID) {
|
|
350
|
+
conn = wsgate.conns[connID]
|
|
351
|
+
if !conn {
|
|
352
|
+
conn = WebSocketConn(wsgate, connID)
|
|
353
|
+
wsgate.conns[connID] = conn
|
|
354
|
+
for serverID in wsgate.subsystems
|
|
355
|
+
wsgate.subsystems[serverID].wsOpen(conn)
|
|
356
|
+
}
|
|
357
|
+
conn
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
`(error, data) = wsgate.handler.requested(req, res)
|
|
361
|
+
if data.op == "connect"
|
|
362
|
+
conn = reqOpen(data.connID)
|
|
363
|
+
else if data.op == "message"
|
|
364
|
+
reqOpen(data.connID).msgin(data.message)
|
|
365
|
+
else if data.op == "disconnect" {
|
|
366
|
+
conn = wsgate.conns[data.connID]
|
|
367
|
+
wsgate.conns[data.connID] = undefined
|
|
368
|
+
if conn {
|
|
369
|
+
conn.close(data.code, data.reason)
|
|
370
|
+
for serverID in wsgate.subsystems
|
|
371
|
+
wsgate.subsystems[serverID].wsClose(conn)
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// close
|
|
377
|
+
//
|
|
378
|
+
// Respond to server closing.
|
|
379
|
+
//
|
|
380
|
+
wsgate.close = function close(conn, local serverID) {
|
|
381
|
+
wsgate.handler.close()
|
|
382
|
+
wsgate.handler = false
|
|
383
|
+
for serverID in wsgate.subsystems
|
|
384
|
+
wsgate.subsystems[serverID].wsClose()
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// finis
|
|
388
|
+
wsgate
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
/*
|
|
393
|
+
* WebSocketConn
|
|
394
|
+
*
|
|
395
|
+
* WebSocketConn objects represent a connection with a particular client. These are created when
|
|
396
|
+
* a new client connects. The protocol is JSON with the top level being a dictionary having the
|
|
397
|
+
* following static keys specified by the client:
|
|
398
|
+
* serverID: defined by the server, this string defines where requests should be routed.
|
|
399
|
+
* clientID: defined by the client, this string defines where replies should be sent.
|
|
400
|
+
* These are class (code) designators. Further keys can be defined to identify a specific instance on
|
|
401
|
+
* the client or server.
|
|
402
|
+
*
|
|
403
|
+
*/
|
|
404
|
+
|
|
405
|
+
closure WebSocketConn(wsgate, connID, local wsconn) {
|
|
406
|
+
global()
|
|
407
|
+
wsconn = new(object, this)
|
|
408
|
+
wsconn.info = {
|
|
409
|
+
destID: UUID()
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// msgin
|
|
413
|
+
//
|
|
414
|
+
// This finds the appropriate target for an incoming message, which can be a relay message that
|
|
415
|
+
// we send on to the next node on the network.
|
|
416
|
+
//
|
|
417
|
+
wsconn.msgin = closure msgin(message, local error) {
|
|
418
|
+
if wsgate.guid && message.guid != wsgate.guid
|
|
419
|
+
error = Error("unauthorized")
|
|
420
|
+
else if message.init {
|
|
421
|
+
if message.init.destID {
|
|
422
|
+
wsconn.relay = true
|
|
423
|
+
wsgate.subsystems.Relay.wsChangeDestID(conn, wsconn.info.destID, message.init.destID)
|
|
424
|
+
}
|
|
425
|
+
wsconn.info = merge(wsconn.info, message.init)
|
|
426
|
+
}
|
|
427
|
+
else if message.respOp && wsgate.subsystems.Relay
|
|
428
|
+
wsgate.subsystems.Relay.wsReceive(message, wsconn) // with respOp, must be a relay
|
|
429
|
+
else if message.clientID && wsgate.subsystems[message.serverID]
|
|
430
|
+
wsgate.subsystems[message.serverID].wsReceive(message, wsconn)
|
|
431
|
+
else
|
|
432
|
+
error = Error("can't route message")
|
|
433
|
+
if error
|
|
434
|
+
ErrorDebuglog("WebSocketConn.msgin error:", error)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// on close
|
|
438
|
+
//
|
|
439
|
+
// Connection has closed.
|
|
440
|
+
//
|
|
441
|
+
wsconn.close = closure close(code, reason) {
|
|
442
|
+
if code != 1000 && code != 1001 && code != 1005 && code != 1006
|
|
443
|
+
debuglog("WebSocketConn: connection has closed:", code, reason, JSONstringify(wsconn.info))
|
|
444
|
+
wsconn.closed = {
|
|
445
|
+
code: code
|
|
446
|
+
reason: reason
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// send
|
|
451
|
+
//
|
|
452
|
+
// Send a dictionary, which must have a clientID defined.
|
|
453
|
+
//
|
|
454
|
+
wsconn.send = function send(message) {
|
|
455
|
+
if !message.clientID || !message.serverID
|
|
456
|
+
throw("WebSocketConn.send: client and server IDs required")
|
|
457
|
+
if wsgate.closed
|
|
458
|
+
list(Error("cannot send - websocket closed"))
|
|
459
|
+
wsgate.handler.send(connID, JSONstringify(message))
|
|
460
|
+
list(false, { ok: true })
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// finis
|
|
464
|
+
wsconn
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
|
|
284
468
|
/*
|
|
285
469
|
* WebSocketServer
|
|
286
470
|
*
|
|
@@ -322,8 +506,9 @@ closure WebSocketServer(server, local websocks) {
|
|
|
322
506
|
})
|
|
323
507
|
|
|
324
508
|
// closeConn
|
|
509
|
+
//
|
|
325
510
|
// respond to connection closing
|
|
326
|
-
|
|
511
|
+
//
|
|
327
512
|
websocks.closeConn = function closeConn(conn, local serverID) {
|
|
328
513
|
websocks.conns = websocks.conns.filter(function(item) {
|
|
329
514
|
item !== conn
|
|
@@ -641,7 +826,8 @@ function apisLoadLibs() {
|
|
|
641
826
|
};
|
|
642
827
|
|
|
643
828
|
function ApisInit(local manifest) {
|
|
644
|
-
manifest = `(APIServer, WebSocketServer, WesCon, WesRelay,
|
|
829
|
+
manifest = `(APIServer, WebSocketGatewayServer, WebSocketConn, WebSocketServer, WesCon, WesRelay,
|
|
830
|
+
apisLoadLibs, ApisInit)
|
|
645
831
|
|
|
646
832
|
Naan.module.build(module.id, "apiserver", function(modobj, compobj) {
|
|
647
833
|
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
|
|
@@ -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.0+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.0+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.0+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.0+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.0+1"
|
|
621
631
|
});
|
|
622
632
|
termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
|
|
623
633
|
}
|
|
@@ -632,8 +642,8 @@ exports.NaanControllerWeb = function() {
|
|
|
632
642
|
naanlib.banner();
|
|
633
643
|
var hostpath = naanlib.js.r("path").dirname(window.location.href);
|
|
634
644
|
naanlib.start({
|
|
635
|
-
cmd: 'App.version = "1.
|
|
636
|
-
+ 'App.cache = "
|
|
645
|
+
cmd: 'App.version = "1.3.0+1";;\r\n'
|
|
646
|
+
+ 'App.cache = "49a9b89fb804111a36026df163e15009";;\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
|
});
|
|
@@ -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
|
|
|
@@ -83,13 +83,27 @@ exports.NaanControllerWebWorker = function NaanControllerWebWorker() {
|
|
|
83
83
|
});
|
|
84
84
|
return (data);
|
|
85
85
|
};
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
var targetListener;
|
|
88
88
|
targSelf.OnMessage = function OnMessage(proc) {
|
|
89
89
|
targetListener = proc;
|
|
90
90
|
return (proc);
|
|
91
91
|
};
|
|
92
|
-
|
|
92
|
+
|
|
93
|
+
this.DispatchMessage = function DispatchMessage(data) {
|
|
94
|
+
postMessage({ // target is sending a message
|
|
95
|
+
id: "targetsend",
|
|
96
|
+
data: data
|
|
97
|
+
});
|
|
98
|
+
return (data);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
var targetReceiver;
|
|
102
|
+
targSelf.OnReceive = function OnReceive(proc) {
|
|
103
|
+
targetReceiver = proc;
|
|
104
|
+
return (proc);
|
|
105
|
+
};
|
|
106
|
+
|
|
93
107
|
targSelf.ReplyDebugger = function ReplyDebugger(data) {
|
|
94
108
|
postMessage({ // target is sending debug data
|
|
95
109
|
id: "debugout",
|
|
@@ -149,6 +163,11 @@ exports.NaanControllerWebWorker = function NaanControllerWebWorker() {
|
|
|
149
163
|
if (debugListener)
|
|
150
164
|
debugListener(msg.data); // target received a message
|
|
151
165
|
}
|
|
166
|
+
else if (msg.id == "targetreceive")
|
|
167
|
+
{
|
|
168
|
+
if (targetReceiver)
|
|
169
|
+
targetReceiver(msg.data);
|
|
170
|
+
}
|
|
152
171
|
};
|
|
153
172
|
|
|
154
173
|
//
|