@naanlang/naan 1.7.0 → 1.7.2
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 +2 -2
- package/dist/env_web.js +0 -1
- package/dist/naan.min.js +4 -4
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +117 -90
- package/frameworks/browser/worker.nlg +16 -8
- package/frameworks/browser/workers.nlg +12 -1
- package/frameworks/browser/ws_client.nlg +23 -87
- package/frameworks/client/apiclient.nlg +24 -21
- package/frameworks/client/client.nlg +22 -2
- package/frameworks/client/relaycon.nlg +1 -1
- package/frameworks/common/common.nlg +11 -9
- package/frameworks/node/apiserver.nlg +1 -1
- package/frameworks/node/worker.nlg +15 -7
- package/frameworks/node/ws_client.nlg +25 -84
- package/frameworks/project/build.nlg +76 -55
- package/frameworks/project/projects.nlg +2 -2
- package/frameworks/running/executors.nlg +23 -15
- package/frameworks/running/instances.nlg +34 -23
- package/frameworks/running/remote_req.nlg +2 -1
- package/frameworks/running/remote_res.nlg +1 -1
- package/frameworks/service/imp.nlg +22 -5
- package/frameworks/service/nubnode.nlg +4 -4
- package/frameworks/service/nubweb.nlg +6 -6
- package/lib/browser/env_web.js +7 -8
- package/lib/core/naanlib.js +4 -4
- package/package.json +1 -1
|
@@ -208,6 +208,7 @@ closure APIClient(imp, options, local client, url, guid) {
|
|
|
208
208
|
closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
209
209
|
global(js)
|
|
210
210
|
wesc = new(object, this)
|
|
211
|
+
|
|
211
212
|
|
|
212
213
|
// reconnect
|
|
213
214
|
//
|
|
@@ -226,40 +227,29 @@ closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
|
226
227
|
//
|
|
227
228
|
// Establish a websocket connection with the host.
|
|
228
229
|
//
|
|
229
|
-
wesc.connect = closure connect(local url, result) {
|
|
230
|
+
wesc.connect = closure connect(local url, result, error) {
|
|
230
231
|
if ws {
|
|
231
232
|
if pending
|
|
232
233
|
return (pending.wait()) // connect in process
|
|
233
234
|
if !wesc.fatal
|
|
234
235
|
return(list(false, { connected: true })) // already open
|
|
235
236
|
}
|
|
236
|
-
try {
|
|
237
|
-
url = xnew(js.w.URL, options.url)
|
|
238
|
-
} catch {
|
|
239
|
-
return(list(Error("invalid URL ${options.url}", exception)))
|
|
240
|
-
}
|
|
241
|
-
if url.protocol == "https:"
|
|
242
|
-
url.protocol = "wss:"
|
|
243
|
-
else
|
|
244
|
-
url.protocol = "ws:"
|
|
245
|
-
ws = xnew(js.w.WebSocket, url.href)
|
|
246
|
-
if wesc.fatal
|
|
247
|
-
debuglog("WebSocketClient reopen") // ### not pretty to see this
|
|
248
|
-
wesc.fatal = false
|
|
249
|
-
pending = new(nonce)
|
|
250
237
|
|
|
251
238
|
// onopen
|
|
252
239
|
// The WebSocket connection is now open.
|
|
253
|
-
|
|
240
|
+
function onopen(e) {
|
|
254
241
|
if wesc.impconn {
|
|
255
242
|
result = wesc.impconn.reopen()
|
|
256
243
|
pending.signal(result)
|
|
257
244
|
return
|
|
258
245
|
}
|
|
259
|
-
wesc.impconn = imp.requester(function(data) {
|
|
246
|
+
wesc.impconn = imp.requester(function(data, local error, text) {
|
|
260
247
|
if !pending && reconnect() // !pending means not opening/reopening
|
|
261
248
|
return // failed to reconnect
|
|
262
|
-
|
|
249
|
+
`(error, text) = JsonStringify(data)
|
|
250
|
+
if error
|
|
251
|
+
return (list(error))
|
|
252
|
+
ws.send(text)
|
|
263
253
|
list(false, { sent: true })
|
|
264
254
|
}, {
|
|
265
255
|
secret: options.guid
|
|
@@ -274,7 +264,7 @@ closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
|
274
264
|
|
|
275
265
|
// onmessage
|
|
276
266
|
// A message was received via WebSockets.
|
|
277
|
-
|
|
267
|
+
function onmessage(e, local error, message) {
|
|
278
268
|
`(error, message) = JsonParse(e.data)
|
|
279
269
|
if !error {
|
|
280
270
|
message = new(message)
|
|
@@ -289,7 +279,7 @@ closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
|
289
279
|
// onerror
|
|
290
280
|
// An error occurred on the WebSocket connection.
|
|
291
281
|
// This can happen in normal operation when the connection times out.
|
|
292
|
-
|
|
282
|
+
function onerror(e) {
|
|
293
283
|
if !wesc.fatal
|
|
294
284
|
wesc.fatal = Error("websocket failed", e)
|
|
295
285
|
pending.signal(list(wesc.fatal))
|
|
@@ -298,7 +288,7 @@ closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
|
298
288
|
|
|
299
289
|
// onclose
|
|
300
290
|
// The WebSocket connection was closed.
|
|
301
|
-
|
|
291
|
+
function onclose(e) {
|
|
302
292
|
// if e.code != 1000 && e.code != 1001 && e.code != 1005 && e.code != 1006
|
|
303
293
|
debuglog("WebSocketClient: closed:", e.code, e.reason) // ### not pretty to see this
|
|
304
294
|
ws = false
|
|
@@ -308,6 +298,19 @@ closure WebSocketClient(options, imp, local wesc, ws, pending) {
|
|
|
308
298
|
pending = false
|
|
309
299
|
}
|
|
310
300
|
|
|
301
|
+
`(error, ws) = call(clirWebsocket(), options.url, {
|
|
302
|
+
onopen: onopen.proc
|
|
303
|
+
onmessage: onmessage.proc
|
|
304
|
+
onerror: onerror.proc
|
|
305
|
+
onclose: onclose.proc
|
|
306
|
+
})
|
|
307
|
+
if error
|
|
308
|
+
return (list(wesc.fatal = error)) // failed to even get started
|
|
309
|
+
|
|
310
|
+
if wesc.fatal
|
|
311
|
+
debuglog("WebSocketClient reopen") // ### not pretty to see this
|
|
312
|
+
wesc.fatal = false
|
|
313
|
+
pending = new(nonce)
|
|
311
314
|
result = pending.wait(10000, list(Error("IMP connection timeout")))
|
|
312
315
|
pending = false
|
|
313
316
|
result
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -31,6 +31,26 @@ function clirRequester() {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
|
|
34
|
+
/*
|
|
35
|
+
* clirWebsocket
|
|
36
|
+
*
|
|
37
|
+
* Return an appropriate Websocket client based on our environment.
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
clirWebsocketApi = false;
|
|
42
|
+
|
|
43
|
+
function clirWebsocket() {
|
|
44
|
+
if !clirWebsocketApi {
|
|
45
|
+
if js.w
|
|
46
|
+
clirWebsocketApi = require("naanlib:frameworks/browser/ws_client.nlg").WebSocket
|
|
47
|
+
else
|
|
48
|
+
clirWebsocketApi = require("naanlib:frameworks/node/ws_client.nlg").WebSocket
|
|
49
|
+
}
|
|
50
|
+
clirWebsocketApi
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
|
|
34
54
|
/*
|
|
35
55
|
* clirInit
|
|
36
56
|
*
|
|
@@ -40,7 +60,7 @@ function clirRequester() {
|
|
|
40
60
|
*/
|
|
41
61
|
|
|
42
62
|
function clirInit(local manifest) {
|
|
43
|
-
manifest = `(clirRequester, clirInit)
|
|
63
|
+
manifest = `(clirRequester, clirWebsocket, clirInit)
|
|
44
64
|
|
|
45
65
|
Naan.module.build(module.id, "client", function(modobj, compobj) {
|
|
46
66
|
require("../common/").LiveImport()
|
|
@@ -52,7 +52,7 @@ closure RelayCon(imp, options, local relay, nlregex)
|
|
|
52
52
|
serverID: "Workers"
|
|
53
53
|
workerID: "NideServer"
|
|
54
54
|
}, options.config)
|
|
55
|
-
relay.instanceID =
|
|
55
|
+
relay.instanceID = imp.getUUID("RelayCon(${options.name}) instanceID")
|
|
56
56
|
relay.exec = execsMod.ExecutorBase(false, "Host", options.name)
|
|
57
57
|
nlregex = RegExp("\\n", "g")
|
|
58
58
|
|
|
@@ -252,14 +252,16 @@ macro LiveExport() {
|
|
|
252
252
|
importList = []
|
|
253
253
|
//
|
|
254
254
|
// LiveImport
|
|
255
|
-
// Return a new LiveImport function to be exported by the module who called
|
|
255
|
+
// Return a new LiveImport function to be exported by the module who called LiveExport.
|
|
256
256
|
//
|
|
257
|
-
macro LiveImport(fixproc, local importingMod,
|
|
257
|
+
macro LiveImport(fixproc, local importingMod, item, updater) {
|
|
258
258
|
importingMod = car(nsrights().lookup("module"))
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
for item in importList
|
|
260
|
+
if item.proc.1.namespace === importingMod.namespace {
|
|
261
|
+
updater = item
|
|
262
|
+
break
|
|
263
|
+
}
|
|
264
|
+
if !updater {
|
|
263
265
|
updater = closure(importingMod, fixproc) { // create new updater
|
|
264
266
|
putproc(compress(updateImports), function updateImports(local goback) {
|
|
265
267
|
if importingMod !== exporterMod {
|
|
@@ -269,10 +271,10 @@ macro LiveExport() {
|
|
|
269
271
|
try {
|
|
270
272
|
call(fixproc, exporterMod) // let caller do any fixups
|
|
271
273
|
} catch {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
+
debuglog("LiveImport fixup failed in", nsrights(), "exception:", exception)
|
|
275
|
+
} finally {
|
|
276
|
+
goback()
|
|
274
277
|
}
|
|
275
|
-
goback()
|
|
276
278
|
})
|
|
277
279
|
updateImports
|
|
278
280
|
} (importingMod, eval(fixproc))
|
|
@@ -44,7 +44,7 @@ closure APIServer(options, local server, chroot) {
|
|
|
44
44
|
server.guid = options.guid
|
|
45
45
|
server.notifyq = []
|
|
46
46
|
server.responseq = []
|
|
47
|
-
server.instanceID =
|
|
47
|
+
server.instanceID = App.imp.getUUID("APIServer instanceID")
|
|
48
48
|
options = merge({
|
|
49
49
|
relpath: ""
|
|
50
50
|
name: "NaanServer"
|
|
@@ -44,7 +44,7 @@ closure CurBot(options, local curbot) {
|
|
|
44
44
|
curbot.guid = 1
|
|
45
45
|
curbot.host = js.t // our magic Naan controller reference
|
|
46
46
|
|
|
47
|
-
curbot.instanceID =
|
|
47
|
+
curbot.instanceID = App.imp.getUUID("CurBot(${options.name}) instanceID")
|
|
48
48
|
curbot.sender = App.imp.register(curbot, {
|
|
49
49
|
name: curbot.name
|
|
50
50
|
type: curbot.type
|
|
@@ -266,7 +266,7 @@ closure NowBot(options, local nowbot, nodeops, subChannel, ptySpawned) {
|
|
|
266
266
|
nowbot.thread.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1])
|
|
267
267
|
nowbot.msgport = subChannel.port2
|
|
268
268
|
|
|
269
|
-
nowbot.instanceID =
|
|
269
|
+
nowbot.instanceID = App.imp.getUUID("NowBot(${options.name}) instanceID")
|
|
270
270
|
nowbot.sender = App.imp.register(nowbot, {
|
|
271
271
|
name: options.name
|
|
272
272
|
type: options.type
|
|
@@ -428,6 +428,16 @@ closure NowBot(options, local nowbot, nodeops, subChannel, ptySpawned) {
|
|
|
428
428
|
nowbot.thread = false
|
|
429
429
|
destroy()
|
|
430
430
|
})
|
|
431
|
+
|
|
432
|
+
// close
|
|
433
|
+
//
|
|
434
|
+
// Close and remove our IMP resources, but leave the worker alone.
|
|
435
|
+
//
|
|
436
|
+
nowbot.close = function close() {
|
|
437
|
+
nowbot.impconn.destroy()
|
|
438
|
+
nowbot.impconn = false
|
|
439
|
+
App.imp.unregister(nowbot.instanceID)
|
|
440
|
+
}
|
|
431
441
|
|
|
432
442
|
// destroy
|
|
433
443
|
//
|
|
@@ -436,9 +446,7 @@ closure NowBot(options, local nowbot, nodeops, subChannel, ptySpawned) {
|
|
|
436
446
|
nowbot.destroy = function destroy() {
|
|
437
447
|
terminate()
|
|
438
448
|
nowbot.thread = false
|
|
439
|
-
|
|
440
|
-
nowbot.impconn = false
|
|
441
|
-
App.imp.unregister(nowbot.instanceID)
|
|
449
|
+
close()
|
|
442
450
|
}
|
|
443
451
|
|
|
444
452
|
// NaaN message
|
|
@@ -446,7 +454,7 @@ closure NowBot(options, local nowbot, nodeops, subChannel, ptySpawned) {
|
|
|
446
454
|
// A message has been received from NaaN running on the worker thread.
|
|
447
455
|
//
|
|
448
456
|
nowbot.msgport.on("message", function (msg, local startmsg) {
|
|
449
|
-
if msg.id == "naan-imp-
|
|
457
|
+
if msg.id == "naan-imp-out" {
|
|
450
458
|
nowbot.impconn.dispatch(new(msg.data))
|
|
451
459
|
return
|
|
452
460
|
} else if msg.id == "loaded" {
|
|
@@ -542,7 +550,7 @@ closure NobBot(options, local nobbot)
|
|
|
542
550
|
|
|
543
551
|
nobbot.impconn = App.imp.responder(function(data) {
|
|
544
552
|
nobbot.msgport.postMessage({ // send to worker
|
|
545
|
-
id: "naan-imp-
|
|
553
|
+
id: "naan-imp-in" // scoped for NodeWorkerNub
|
|
546
554
|
data: data
|
|
547
555
|
})
|
|
548
556
|
list(false, { sent: true })
|
|
@@ -13,106 +13,47 @@
|
|
|
13
13
|
/*
|
|
14
14
|
* WebSocket
|
|
15
15
|
*
|
|
16
|
-
* Create a WebSocket client connection object.
|
|
16
|
+
* Create a WebSocket client connection object, returning a tuple.
|
|
17
17
|
*
|
|
18
18
|
* Required:
|
|
19
|
-
*
|
|
19
|
+
* urlstr: <string>
|
|
20
20
|
*
|
|
21
21
|
* Options:
|
|
22
22
|
* {
|
|
23
23
|
* wss: <boolean> // true to use secure connection
|
|
24
|
+
* query: <string> // query string starting with ?
|
|
24
25
|
* onopen: <proc>(e) // connection has opened
|
|
25
26
|
* onmessage: <proc>(e, message) // message received
|
|
26
27
|
* onerror: <proc>(e) // error occurred
|
|
27
28
|
* 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
|
|
30
29
|
* }
|
|
31
30
|
*
|
|
32
31
|
*/
|
|
33
32
|
|
|
34
|
-
closure WebSocket(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
closure WebSocket(urlstr, options, local error, wslib, url, ws) {
|
|
34
|
+
`(error, wslib) = await(js.i("ws"))
|
|
35
|
+
if error
|
|
36
|
+
return (list(error))
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
wsock.connect = closure connect(local error, ws, url, pending) {
|
|
44
|
-
if wsock.ws
|
|
45
|
-
return (list(false, { open: true }))
|
|
46
|
-
`(error, ws) = await(js.i("ws"))
|
|
47
|
-
if error
|
|
48
|
-
return (list(error))
|
|
49
|
-
if options.wss
|
|
50
|
-
url = "wss://${host}${options.querys||''}"
|
|
51
|
-
else
|
|
52
|
-
url = "ws://${host}${options.query||''}"
|
|
53
|
-
wsock.ws = xnew(ws.default, url)
|
|
54
|
-
pending = new(nonce)
|
|
55
|
-
|
|
56
|
-
// onopen
|
|
57
|
-
// The WebSocket connection is now open.
|
|
58
|
-
wsock.ws.onopen = closure onopen(e) {
|
|
59
|
-
pending.signal(list(false, { ok: true }))
|
|
60
|
-
options.onopen(e, e.target, e.type)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// onmessage
|
|
64
|
-
// A message was received from the worker via WebSockets.
|
|
65
|
-
wsock.ws.onmessage = closure onmessage(e, local message) {
|
|
66
|
-
try {
|
|
67
|
-
message = new(JSONparse(e.data))
|
|
68
|
-
} catch {
|
|
69
|
-
debuglog("can't decode incoming ws message:", exception)
|
|
70
|
-
options.onerror(Error("can't decode incoming message:", exception))
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
options.onmessage(e, message)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// onerror
|
|
77
|
-
// An error occurred on the WebSocket connection.
|
|
78
|
-
wsock.ws.onerror = closure onerror(e, local error) {
|
|
79
|
-
error = Error("websocket failed", e)
|
|
80
|
-
options.onerror(e, error)
|
|
81
|
-
pending.signal(list(error)) // ensure connect completes
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// onclose
|
|
85
|
-
// The WebSocket connection was closed.
|
|
86
|
-
wsock.ws.onclose = closure onclose(e) {
|
|
87
|
-
options.onclose(e, e.code, e.reason)
|
|
88
|
-
pending.signal(list(Error("connection closed"))) // ensure connect completes
|
|
89
|
-
wsock.ws = false
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
pending.wait()
|
|
38
|
+
try {
|
|
39
|
+
url = xnew(js.g.URL, urlstr)
|
|
40
|
+
} catch {
|
|
41
|
+
return (list(Error("invalid URL ${urlstr}", exception)))
|
|
93
42
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if !reason
|
|
109
|
-
reason = 1000 // normal close
|
|
110
|
-
wsock.ws.close(reason)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// finis
|
|
114
|
-
|
|
115
|
-
wsock
|
|
43
|
+
options = merge({
|
|
44
|
+
query: url.search || ''
|
|
45
|
+
wss: url.protocol == "https:"
|
|
46
|
+
}, options)
|
|
47
|
+
if options.wss
|
|
48
|
+
url = "wss://${url.host}${options.query}"
|
|
49
|
+
else
|
|
50
|
+
url = "ws://${url.host}${options.query}"
|
|
51
|
+
ws = xnew(wslib.default, url)
|
|
52
|
+
ws.onopen = options.onopen
|
|
53
|
+
ws.onmessage = options.onmessage
|
|
54
|
+
ws.onerror = options.onerror
|
|
55
|
+
ws.onclose = options.onclose
|
|
56
|
+
list(false, ws)
|
|
116
57
|
};
|
|
117
58
|
|
|
118
59
|
|
|
@@ -304,18 +304,26 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
304
304
|
//
|
|
305
305
|
// Apply substitutions from readSubstitutionFile to string, returning a tuple of the resulting
|
|
306
306
|
// text and the number of substitution patterns actually used from the supplied dictionary.
|
|
307
|
-
//
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
subst
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
307
|
+
// Specify iterative to repeat the substitution on the result until no more substitutions occur.
|
|
308
|
+
//
|
|
309
|
+
function applySubstitutions(text, subs, iterative, local count, subbed) {
|
|
310
|
+
count = 0
|
|
311
|
+
loop {
|
|
312
|
+
subbed = { }
|
|
313
|
+
text = text.replace(RegExp("[$][^$\\s]+[$]", "g"), function(match, local subst) {
|
|
314
|
+
subst = subs[match.slice(1,-1)]
|
|
315
|
+
if subst {
|
|
316
|
+
subbed[match] = true
|
|
317
|
+
subst
|
|
318
|
+
}
|
|
319
|
+
else
|
|
320
|
+
match
|
|
321
|
+
})
|
|
322
|
+
count += length(subbed)
|
|
323
|
+
if length(subbed) == 0 || !iterative
|
|
324
|
+
break
|
|
325
|
+
}
|
|
326
|
+
list(text, count)
|
|
319
327
|
}
|
|
320
328
|
|
|
321
329
|
//
|
|
@@ -418,6 +426,16 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
418
426
|
result
|
|
419
427
|
}
|
|
420
428
|
|
|
429
|
+
//
|
|
430
|
+
// init1
|
|
431
|
+
//
|
|
432
|
+
// Initialize a build worker.
|
|
433
|
+
//
|
|
434
|
+
|
|
435
|
+
function init1() {
|
|
436
|
+
require("../common").LiveImport()
|
|
437
|
+
}
|
|
438
|
+
|
|
421
439
|
//
|
|
422
440
|
// parseAndPack1
|
|
423
441
|
//
|
|
@@ -426,7 +444,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
426
444
|
// autoquoted to itself, a symbol. This can be used to detect build time vs. runtime.
|
|
427
445
|
|
|
428
446
|
function parseAndPack1(text, fpath, options, operation,
|
|
429
|
-
local util, lib, penv, naansym, dlogsym, pmod, pcomp, ournn,
|
|
447
|
+
local util, lib, modid, penv, naansym, dlogsym, pmod, pcomp, ournn,
|
|
448
|
+
output, textout, annotations, package)
|
|
430
449
|
{
|
|
431
450
|
//
|
|
432
451
|
// textline
|
|
@@ -445,6 +464,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
445
464
|
lib = Naan.module.modlist().Lib.exports
|
|
446
465
|
if !util || !lib
|
|
447
466
|
return (list("Build packager cannot access support functions"))
|
|
467
|
+
modid = JSpath.basename(JSpath.dirname(fpath))
|
|
448
468
|
//
|
|
449
469
|
// The following crazy rigmarole is about customizing the ParsEnvironment so we can glean
|
|
450
470
|
// enough information to build a package without actually executing the code. To do this we
|
|
@@ -461,7 +481,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
461
481
|
pcomp = { } // our component object
|
|
462
482
|
ournn.module = {
|
|
463
483
|
build: function(modname, compname, proc) {
|
|
464
|
-
pmod.id =
|
|
484
|
+
pmod.id = modid
|
|
465
485
|
pmod.exports = { }
|
|
466
486
|
pcomp.name = compname
|
|
467
487
|
call(proc, pmod, pcomp) // obtain manifest
|
|
@@ -505,23 +525,39 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
505
525
|
//
|
|
506
526
|
textout = ""
|
|
507
527
|
try {
|
|
508
|
-
if
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
528
|
+
if output.annotations.length == 0 && output.errors.length == 0
|
|
529
|
+
&& (options.naanpack || options.jspack) { // actually building a package
|
|
530
|
+
if !pcomp.name {
|
|
531
|
+
//
|
|
532
|
+
// Some components cannot use a build function because they are too early in the
|
|
533
|
+
// boot process, but we still need a component. We look for NaanBuildComponent
|
|
534
|
+
// to define a dictionary with filename, name and manifest fields. For example,
|
|
535
|
+
// see Util:Module.nlg
|
|
536
|
+
//
|
|
537
|
+
pcomp = penv.evalq(car(compress(NaanBuildComponent)))
|
|
538
|
+
if !pcomp || !fpath.endsWith("/".concat(pcomp.filename))
|
|
539
|
+
output.errors.push("Build cannot package without component, use NaanBuildComponent?")
|
|
540
|
+
}
|
|
541
|
+
if output.errors.length == 0 {
|
|
542
|
+
package = util.pkgSave(compress(pcomp.name), pcomp.manifest)
|
|
543
|
+
if string(package) {
|
|
544
|
+
output.errors.push("Build cannot generate package: ".concat(package))
|
|
545
|
+
package = false
|
|
546
|
+
}
|
|
547
|
+
}
|
|
524
548
|
}
|
|
549
|
+
|
|
550
|
+
annotations = output.annotations
|
|
551
|
+
if annotations.length == 0 { // empty annotations list
|
|
552
|
+
if output.errors.length > 0
|
|
553
|
+
annotations.push({ // first error becomes annotation
|
|
554
|
+
row: 0
|
|
555
|
+
column: 0
|
|
556
|
+
text: output.errors[0]
|
|
557
|
+
type: "error"
|
|
558
|
+
})
|
|
559
|
+
else
|
|
560
|
+
annotations = false } // no errors or annotations
|
|
525
561
|
if output.errors.length > 0 || output.text.length > 0 {
|
|
526
562
|
textline("-".repeat(79))
|
|
527
563
|
textline("While processing ", fpath)
|
|
@@ -540,22 +576,6 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
540
576
|
//
|
|
541
577
|
// Build the package, if not just doing syntax checking
|
|
542
578
|
//
|
|
543
|
-
if options.naanpack || options.jspack { // actually building a package?
|
|
544
|
-
if !pcomp.name {
|
|
545
|
-
//
|
|
546
|
-
// Some components cannot use a build function because they are too early in the
|
|
547
|
-
// boot process, but we still need a component. We look for NaanBuildComponent
|
|
548
|
-
// to define a dictionary with filename, name and manifest fields. For example,
|
|
549
|
-
// see Util:Module.nlg
|
|
550
|
-
//
|
|
551
|
-
pcomp = penv.evalq(car(compress(NaanBuildComponent)))
|
|
552
|
-
if !pcomp || !fpath.endsWith("/".concat(pcomp.filename))
|
|
553
|
-
return (list("Build cannot package without component in ".concat(fpath), false, annotations, textout))
|
|
554
|
-
}
|
|
555
|
-
package = util.pkgSave(compress(pcomp.name), pcomp.manifest)
|
|
556
|
-
if string(package)
|
|
557
|
-
return (list("Build cannot generate package for ".concat(fpath), false, annotations, textout))
|
|
558
|
-
}
|
|
559
579
|
} catch {
|
|
560
580
|
if true
|
|
561
581
|
return (list("Packaging exception in ".concat(fpath, ": ", tostring(exception)), false, annotations, textout))
|
|
@@ -585,7 +605,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
585
605
|
if !build.parallel
|
|
586
606
|
build.parallel = ExecutorParallel(track, { // create worker pool
|
|
587
607
|
basename: "build"
|
|
588
|
-
initeval: `(
|
|
608
|
+
initeval: list(quote(init1()), `(init1, parseAndPack1))
|
|
589
609
|
})
|
|
590
610
|
result = build.parallel.rpc(parseAndPack1, list(text, fpath, options, operation))
|
|
591
611
|
if !result.0 {
|
|
@@ -1044,9 +1064,9 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1044
1064
|
}
|
|
1045
1065
|
else if ((`(error, content) = fs.readFile(entry.readpath, readOptions)) && !error) {
|
|
1046
1066
|
if entry.license
|
|
1047
|
-
`(content) = applySubstitutions(content, licFileDefs)
|
|
1067
|
+
`(content) = applySubstitutions(content, licFileDefs, true)
|
|
1048
1068
|
if entry.version
|
|
1049
|
-
`(content) = applySubstitutions(content, verFileDefs)
|
|
1069
|
+
`(content) = applySubstitutions(content, verFileDefs, true)
|
|
1050
1070
|
if entry.naanpack
|
|
1051
1071
|
`(error, content) = parseAndPack(content, entry.readpath, { naanpack: true })
|
|
1052
1072
|
else if entry.jspack
|
|
@@ -1251,7 +1271,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1251
1271
|
//
|
|
1252
1272
|
// Run the current build product by spawning a new worker.
|
|
1253
1273
|
//
|
|
1254
|
-
build.runSpawn = function runSpawn(
|
|
1274
|
+
build.runSpawn = function runSpawn(stage,
|
|
1275
|
+
local error, maintext, executor, vpath, site, dirpath) {
|
|
1255
1276
|
`(error, maintext) = fs.readFile(JSpath.join(build.destpath, build.runway.main))
|
|
1256
1277
|
if error
|
|
1257
1278
|
error = Error("Builder: cannot read main file", error)
|
|
@@ -1291,13 +1312,12 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1291
1312
|
//
|
|
1292
1313
|
// Run the current build product by opening a new window.
|
|
1293
1314
|
//
|
|
1294
|
-
build.runWindow = function runWindow(
|
|
1315
|
+
build.runWindow = function runWindow(stage,
|
|
1295
1316
|
local title, main, url, features, vpath, error, window, site) {
|
|
1296
1317
|
if !js.w
|
|
1297
1318
|
return (list(Error('Run method "window" requires browser host')))
|
|
1298
1319
|
if !build.runway."v-site"
|
|
1299
1320
|
return (list(Error('Run method "window" requires v-site specification')))
|
|
1300
|
-
title = rules.name.concat("-", build.buildnum)
|
|
1301
1321
|
main = build.runway.main
|
|
1302
1322
|
if !main
|
|
1303
1323
|
main = "index.html"
|
|
@@ -1313,6 +1333,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1313
1333
|
if error
|
|
1314
1334
|
return (list(Error("Builder: cannot create virtual site", error)))
|
|
1315
1335
|
sleep(1) // needed on Windows or it won't open, fiik why
|
|
1336
|
+
title = rules.name.concat("-", stage, "-", operation)
|
|
1316
1337
|
window = js.w.open(url, title, features)
|
|
1317
1338
|
list(false, { ok: true }) // we don't know the executor
|
|
1318
1339
|
}
|
|
@@ -1323,13 +1344,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
1323
1344
|
// Run the current build product, which would be after the make call. Returns a standard result
|
|
1324
1345
|
// tuple.
|
|
1325
1346
|
//
|
|
1326
|
-
build.run = function run() {
|
|
1347
|
+
build.run = function run(stage) {
|
|
1327
1348
|
if build.runway.open
|
|
1328
1349
|
fs.shellOpen(JSpath.join(build.destpath, build.runway.open), build.runway.args)
|
|
1329
1350
|
else if build.runway.spawn
|
|
1330
|
-
build.runSpawn()
|
|
1351
|
+
build.runSpawn(stage)
|
|
1331
1352
|
else if build.runway.window
|
|
1332
|
-
build.runWindow()
|
|
1353
|
+
build.runWindow(stage)
|
|
1333
1354
|
else
|
|
1334
1355
|
list(false, { ok: true })
|
|
1335
1356
|
}
|
|
@@ -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.7.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.7.2+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
|
|
@@ -646,7 +646,7 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
646
646
|
if builder.refresh()
|
|
647
647
|
buildonly = !buildonly // reverse if refresh
|
|
648
648
|
if !buildonly
|
|
649
|
-
`(error) = builder.run()
|
|
649
|
+
`(error) = builder.run(stage)
|
|
650
650
|
}
|
|
651
651
|
builder.destroy()
|
|
652
652
|
procon.builder = false
|