@naanlang/naan 1.1.0 → 1.2.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 +12 -10
- package/bin/index.js +2 -2
- package/dist/naan.min.js +13 -13
- package/frameworks/browser/https_request.nlg +4 -2
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +77 -45
- package/frameworks/browser/ws_client.nlg +6 -2
- package/frameworks/client/apiclient.nlg +80 -115
- package/frameworks/client/psm_client.nlg +39 -18
- package/frameworks/client/relaycon.nlg +2 -0
- package/frameworks/common/common.nlg +10 -4
- package/frameworks/node/https_request.nlg +2 -1
- package/frameworks/node/psm_server.nlg +2 -2
- package/frameworks/node/ws_client.nlg +7 -2
- package/frameworks/project/build.nlg +12 -11
- package/frameworks/project/projects.nlg +7 -5
- package/frameworks/running/executors.nlg +131 -38
- package/frameworks/running/taskexec.nlg +3 -2
- package/frameworks/storage/psm.nlg +2 -1
- package/frameworks/storage/psm_dbtables.nlg +23 -13
- package/lib/browser/env_web.js +6 -6
- package/lib/core/naanlib.js +13 -13
- package/package.json +1 -1
- package/plugins/serviceAws/aws_dynamo.nlg +91 -32
- package/plugins/serviceAws/dbt_aws.nlg +4 -4
- package/test/harness.nlg +1 -1
- package/test/test_02_context.nlg +1 -1
- package/test/test_03_jsinterop.nlg +2 -2
- package/test/test_05_strings.nlg +7 -4
- package/test/test_07_lingo.nlg +3 -0
|
@@ -6,171 +6,136 @@
|
|
|
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
|
|
|
13
13
|
|
|
14
14
|
/*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* Make a DAS API client object for browsers. This client API handles a single project at a
|
|
18
|
-
* time, from load() to close().
|
|
15
|
+
* NideAPIclient
|
|
19
16
|
*
|
|
17
|
+
* Make an API client object for browsers.
|
|
20
18
|
*
|
|
21
19
|
*/
|
|
22
20
|
|
|
23
|
-
closure
|
|
21
|
+
closure NideAPIclient(url, guid, apiRequester, local client) {
|
|
22
|
+
global()
|
|
24
23
|
client = new(object, this)
|
|
24
|
+
if !url.match(RegExp("^https?:\/\/", "i"))
|
|
25
|
+
url = "http://${url}"
|
|
25
26
|
client.url = url
|
|
26
27
|
client.guid = guid
|
|
27
28
|
client.notifyAfter = 0
|
|
28
29
|
client.instanceID = UUID() // our client's unique ID
|
|
29
30
|
|
|
30
|
-
// clientRequest() -
|
|
31
|
-
|
|
32
|
-
closure clientRequest(method, path, options, cbReq, local request) {
|
|
33
|
-
request = xnew(js.w.XMLHttpRequest)
|
|
34
|
-
request.addEventListener("load", function (event) {
|
|
35
|
-
cbReq(false, request, event)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
request.addEventListener("error", function reqFailed(event, local errtext) {
|
|
39
|
-
if request.status == 0
|
|
40
|
-
errtext = "connectivity"
|
|
41
|
-
else
|
|
42
|
-
errtext = "request failed"
|
|
43
|
-
error = Error(errtext, {
|
|
44
|
-
status: request.status
|
|
45
|
-
method: method
|
|
46
|
-
path: path
|
|
47
|
-
})
|
|
48
|
-
cbReq(error, request, event)
|
|
49
|
-
})
|
|
31
|
+
// clientRequest() - append our guid to the headers
|
|
50
32
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
request.responseType = options.responseType
|
|
54
|
-
if options.contentType
|
|
55
|
-
request.setRequestHeader("Content-Type", options.contentType)
|
|
33
|
+
closure clientRequest(url, options) {
|
|
34
|
+
options = merge(options)
|
|
56
35
|
if guid
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
options.headers = [list("x-naanlang-api-guid", guid)]
|
|
37
|
+
apiRequester(url, options)
|
|
59
38
|
}
|
|
60
39
|
|
|
61
40
|
//
|
|
62
41
|
// docs()
|
|
63
42
|
//
|
|
64
43
|
|
|
65
|
-
client.docs = closure docs() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
})
|
|
44
|
+
client.docs = closure docs(local error, content, extra) {
|
|
45
|
+
`(error, content, extra) = clientRequest(url.concat("/"))
|
|
46
|
+
printline(content)
|
|
69
47
|
}
|
|
70
48
|
|
|
71
49
|
//
|
|
72
50
|
// status(callback, timeoutMS)
|
|
73
51
|
//
|
|
74
52
|
|
|
75
|
-
client.status = closure status(cbStatus, timeoutms, local query,
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
query = EncodeQuery("/status/?", options)
|
|
80
|
-
clientRequest("GET", url.concat(query), false, function (error, req, event) {
|
|
81
|
-
if (error || req.status != 200)
|
|
82
|
-
cbStatus()
|
|
83
|
-
else if (length(req.responseText) == 0)
|
|
84
|
-
cbStatus([])
|
|
85
|
-
else {
|
|
86
|
-
queued = new(JSONparse(req.responseText))
|
|
87
|
-
queued.forEach(function(item,index,array) {
|
|
88
|
-
if client.notifyAfter < item.stamp
|
|
89
|
-
client.notifyAfter = item.stamp
|
|
90
|
-
})
|
|
91
|
-
cbStatus(queued)
|
|
92
|
-
}
|
|
53
|
+
client.status = closure status(cbStatus, timeoutms, local query, error, content, extra, queued) {
|
|
54
|
+
query = EncodeQuery("/status/?", {
|
|
55
|
+
timeout: timeoutms
|
|
56
|
+
after: client.notifyAfter
|
|
93
57
|
})
|
|
58
|
+
`(error, content, extra) = clientRequest(url.concat(query))
|
|
59
|
+
if (error || extra.status != 200)
|
|
60
|
+
cbStatus()
|
|
61
|
+
else if (length(content) == 0)
|
|
62
|
+
cbStatus([])
|
|
63
|
+
else {
|
|
64
|
+
queued = new(content)
|
|
65
|
+
queued.forEach(function(item, index, array) {
|
|
66
|
+
if client.notifyAfter < item.stamp
|
|
67
|
+
client.notifyAfter = item.stamp
|
|
68
|
+
})
|
|
69
|
+
cbStatus(queued)
|
|
70
|
+
}
|
|
94
71
|
}
|
|
95
72
|
|
|
96
73
|
//
|
|
97
74
|
// get
|
|
98
75
|
//
|
|
99
76
|
|
|
100
|
-
client.get = closure get(path,
|
|
101
|
-
|
|
102
|
-
|
|
77
|
+
client.get = closure get(path, options, local error, content, extra) {
|
|
78
|
+
`(error, content, extra) = clientRequest(url.concat("/", path))
|
|
79
|
+
if !error && extra.status != 200
|
|
80
|
+
error = Error("readFile failed: ".concat(extra.status), {
|
|
81
|
+
status: extra.status
|
|
82
|
+
})
|
|
83
|
+
if error
|
|
84
|
+
list(error)
|
|
85
|
+
else
|
|
86
|
+
list(error, content, extra)
|
|
103
87
|
}
|
|
104
88
|
|
|
105
89
|
//
|
|
106
|
-
// readFile(filepath,
|
|
90
|
+
// readFile(filepath, options)
|
|
107
91
|
//
|
|
108
92
|
|
|
109
|
-
client.readFile = closure readFile(filepath,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
93
|
+
client.readFile = closure readFile(filepath, options, local query, error, content, extra) {
|
|
94
|
+
query = EncodeQuery("/readfile/?", {
|
|
95
|
+
path: filepath
|
|
96
|
+
})
|
|
97
|
+
`(error, content, extra) = clientRequest(url.concat(query), options)
|
|
98
|
+
if !error && extra.status != 200
|
|
99
|
+
error = Error("readFile failed: ".concat(extra.status), {
|
|
100
|
+
status: extra.status
|
|
101
|
+
})
|
|
102
|
+
if error
|
|
103
|
+
list(error)
|
|
104
|
+
else
|
|
105
|
+
list(error, content, extra)
|
|
114
106
|
}
|
|
115
107
|
|
|
116
108
|
//
|
|
117
109
|
// psmRemote(options, data, callback)
|
|
118
110
|
//
|
|
119
|
-
// Perform an operation and call back when done.
|
|
120
|
-
// callback(false, (remote_error, remote_data)).
|
|
121
|
-
// Otherwise if communication failed then the result is:
|
|
122
|
-
// callback(<error>).
|
|
111
|
+
// Perform an operation and call back when done.
|
|
123
112
|
|
|
124
|
-
client.psmRemote = closure psmRemote(options, data, callback,
|
|
113
|
+
client.psmRemote = closure psmRemote(options, data, callback,
|
|
114
|
+
local query, reqOptions, error, content, extra) {
|
|
125
115
|
query = EncodeQuery("/psm/?", options)
|
|
126
|
-
if data
|
|
127
|
-
method = "PUT"
|
|
128
|
-
else
|
|
129
|
-
method = "GET"
|
|
130
116
|
reqOptions = {
|
|
131
117
|
putdata: data
|
|
132
118
|
}
|
|
133
|
-
if
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
reqOptions.contentType = "application/json;charset=UTF-8" // we are sending JSON
|
|
141
|
-
`(error, data) = JsonStringify(data)
|
|
142
|
-
if error
|
|
143
|
-
return (callback(Error("psmRemote failed:", error)))
|
|
144
|
-
reqOptions.putdata = data
|
|
145
|
-
}
|
|
146
|
-
else
|
|
147
|
-
reqOptions.responseType = "application/json" // we are requesting JSON
|
|
148
|
-
}
|
|
149
|
-
clientRequest(method, url.concat(query), reqOptions, function (error, req, event, local data) {
|
|
150
|
-
if !error && req.status != 200
|
|
151
|
-
error = Error("NodeFS request failed: ".concat(req.status), {
|
|
152
|
-
status: req.status
|
|
153
|
-
method: method
|
|
154
|
-
query: query
|
|
155
|
-
})
|
|
119
|
+
if !data
|
|
120
|
+
reqOptions.encoding = options.encoding // expected response format
|
|
121
|
+
else if options.encoding == "binary"
|
|
122
|
+
reqOptions.contentType = "application/octet-stream" // we are sending binary data
|
|
123
|
+
else if options.encoding == "json" {
|
|
124
|
+
reqOptions.contentType = "application/json;charset=UTF-8" // we are sending JSON
|
|
125
|
+
`(error, data) = JsonStringify(data)
|
|
156
126
|
if error
|
|
157
|
-
callback(error)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
else
|
|
171
|
-
data = req.response // e.g. when reading binary content
|
|
172
|
-
callback(error, data) }
|
|
173
|
-
})
|
|
127
|
+
return (callback(Error("psmRemote encoding failed:", error)))
|
|
128
|
+
reqOptions.putdata = data
|
|
129
|
+
}
|
|
130
|
+
`(error, content, extra) = clientRequest(url.concat(query), reqOptions)
|
|
131
|
+
if !error && extra.status != 200
|
|
132
|
+
error = Error("NodeFS request failed: ".concat(extra.status), {
|
|
133
|
+
status: extra.status
|
|
134
|
+
})
|
|
135
|
+
if error
|
|
136
|
+
callback(error)
|
|
137
|
+
else
|
|
138
|
+
callback(error, content)
|
|
174
139
|
}
|
|
175
140
|
|
|
176
141
|
client
|
|
@@ -186,12 +151,12 @@ closure MakeNideAPIclient(url, guid, local client) {
|
|
|
186
151
|
|
|
187
152
|
function apicInit(local manifest) {
|
|
188
153
|
|
|
189
|
-
manifest = `(
|
|
154
|
+
manifest = `(NideAPIclient, apicInit)
|
|
190
155
|
|
|
191
156
|
Naan.module.build(module.id, "apiclient", function(modobj, compobj) {
|
|
192
157
|
Naan.module.require("./client.nlg")
|
|
193
158
|
compobj.manifest = manifest
|
|
194
|
-
modobj.exports.
|
|
159
|
+
modobj.exports.NideAPIclient = NideAPIclient
|
|
195
160
|
})
|
|
196
161
|
|
|
197
162
|
} ();
|
|
@@ -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
|
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
22
|
+
global(JSpath)
|
|
22
23
|
view = new(object, this)
|
|
23
24
|
view.api = api
|
|
24
25
|
view.rootpath = rootpath
|
|
@@ -154,6 +155,8 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
154
155
|
// Read a file at the specified path
|
|
155
156
|
|
|
156
157
|
view.readFile = function readFile(path, options, callback) {
|
|
158
|
+
if !path
|
|
159
|
+
throw("psmcFsView.readFile: path is false")
|
|
157
160
|
psmRemote(path, "readFile", options, false, callback)
|
|
158
161
|
}
|
|
159
162
|
|
|
@@ -354,7 +357,9 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
354
357
|
// Tell the shell to open the specified file.
|
|
355
358
|
|
|
356
359
|
view.shellOpen = function shellOpen(path, args, callback) {
|
|
357
|
-
|
|
360
|
+
if args
|
|
361
|
+
args = { args: args }
|
|
362
|
+
psmRemote(path, "shellOpen", args, false, callback)
|
|
358
363
|
}
|
|
359
364
|
|
|
360
365
|
// grepLines
|
|
@@ -424,11 +429,14 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
424
429
|
*
|
|
425
430
|
*/
|
|
426
431
|
|
|
427
|
-
closure psmcFsConnector(psm,
|
|
432
|
+
closure psmcFsConnector(psm, api, local connClassID, connector, watch) {
|
|
433
|
+
global()
|
|
428
434
|
connClassID = "NodeFS"
|
|
429
435
|
connector = new(object, this)
|
|
430
436
|
connector.psm = psm
|
|
431
|
-
connector.
|
|
437
|
+
connector.apis = {
|
|
438
|
+
HostFS: api
|
|
439
|
+
}
|
|
432
440
|
connector.vault = psm.vault(connClassID)
|
|
433
441
|
connector.label = "Naan-Server"
|
|
434
442
|
watch = psm.watchable(connector)
|
|
@@ -563,7 +571,7 @@ closure psmcFsConnector(psm, nicc, local connClassID, connector, watch) {
|
|
|
563
571
|
// listResources
|
|
564
572
|
//
|
|
565
573
|
// List saved resources in our database
|
|
566
|
-
connector.listResources = function listResources(local error, original) {
|
|
574
|
+
connector.listResources = function listResources(local error, output, original) {
|
|
567
575
|
`(error, output) = connector.vault.listResources()
|
|
568
576
|
if error
|
|
569
577
|
return (list(error)) // can't access our saved resources
|
|
@@ -579,14 +587,14 @@ closure psmcFsConnector(psm, nicc, local connClassID, connector, watch) {
|
|
|
579
587
|
connector.info = function info(resID, local info, error, creds) {
|
|
580
588
|
info = {
|
|
581
589
|
classID: connClassID
|
|
582
|
-
type: "remote
|
|
583
|
-
services: ["NideFS", "NideHostAPI"]
|
|
590
|
+
type: "remote server"
|
|
591
|
+
services: ["NideFS", "NideHostAPI", "NideTerminal"]
|
|
584
592
|
}
|
|
585
593
|
if resID == "Host" {
|
|
586
594
|
info.name = "Host"
|
|
587
595
|
info.type = "host filesystem"
|
|
588
596
|
info.locked = true
|
|
589
|
-
info.where =
|
|
597
|
+
info.where = api.url
|
|
590
598
|
info.access = "HostFS"
|
|
591
599
|
} else {
|
|
592
600
|
`(error, creds) = connector.vault.accessResource(resID)
|
|
@@ -620,14 +628,26 @@ closure psmcFsConnector(psm, nicc, local connClassID, connector, watch) {
|
|
|
620
628
|
`(error, creds) = connector.access(resID)
|
|
621
629
|
if !error {
|
|
622
630
|
if creds == "HostFS"
|
|
623
|
-
api = connector.
|
|
624
|
-
else
|
|
625
|
-
api =
|
|
631
|
+
api = connector.apis[creds]
|
|
632
|
+
else {
|
|
633
|
+
api = connector.apis[creds.urlName]
|
|
634
|
+
if !api // get API to remote server
|
|
635
|
+
connector.apis[creds.urlName] = api = NideAPIclient(creds.urlName, creds.authSecret)
|
|
636
|
+
}
|
|
626
637
|
}
|
|
627
638
|
if error
|
|
628
639
|
list(error)
|
|
629
|
-
else if service == "
|
|
630
|
-
|
|
640
|
+
else if service == "NideTerminal" {
|
|
641
|
+
if !App.nide.track
|
|
642
|
+
return (list(Error("NideTerminal not supported in this environment")))
|
|
643
|
+
list(false, App.nide.track.spawn(App.nide.registerRemote(api),
|
|
644
|
+
args.0, // terminal display name
|
|
645
|
+
args.1)) // options:
|
|
646
|
+
// {
|
|
647
|
+
// workerID: "NideServer" -- for main thread; other strings for worker threads
|
|
648
|
+
// type: "My Remotes" -- display name of terminal group; e.g. URL
|
|
649
|
+
// }
|
|
650
|
+
}
|
|
631
651
|
else if service == "NideHostAPI"
|
|
632
652
|
list(false, api) // connect to the Host API
|
|
633
653
|
else if service == "NideFS" {
|
|
@@ -647,17 +667,18 @@ closure psmcFsConnector(psm, nicc, local connClassID, connector, watch) {
|
|
|
647
667
|
|
|
648
668
|
|
|
649
669
|
/*
|
|
650
|
-
*
|
|
670
|
+
* MakeClientPSM
|
|
651
671
|
*
|
|
652
672
|
* Return a new client PSM with our known connectors.
|
|
653
673
|
*
|
|
654
674
|
*/
|
|
655
675
|
|
|
656
|
-
function
|
|
676
|
+
function MakeClientPSM(api, dbname, local importPSM) {
|
|
677
|
+
global(App)
|
|
657
678
|
importPSM = require("../storage/psm.nlg")
|
|
658
679
|
App.psm = importPSM.MakePSM(dbname).1
|
|
659
680
|
if App.psm {
|
|
660
|
-
psmcFsConnector(App.psm,
|
|
681
|
+
psmcFsConnector(App.psm, api) // HostFS access
|
|
661
682
|
require("../storage/dbt_pouch.nlg").DbConnector(App.psm) // Pouch databases as filesystems
|
|
662
683
|
}
|
|
663
684
|
App.psm
|
|
@@ -673,12 +694,12 @@ function psmcMakeClientPSM(nicc, dbname, local importPSM) {
|
|
|
673
694
|
|
|
674
695
|
function psmcInit(local manifest) {
|
|
675
696
|
|
|
676
|
-
manifest = `(psmcFsView, psmcFsConnector,
|
|
697
|
+
manifest = `(psmcFsView, psmcFsConnector, MakeClientPSM, psmcInit)
|
|
677
698
|
|
|
678
699
|
Naan.module.build(module.id, "psm_client", function(modobj, compobj) {
|
|
679
700
|
require("./client.nlg")
|
|
680
701
|
compobj.manifest = manifest
|
|
681
|
-
modobj.exports.MakeClientPSM =
|
|
702
|
+
modobj.exports.MakeClientPSM = MakeClientPSM
|
|
682
703
|
})
|
|
683
704
|
|
|
684
705
|
} ();
|
|
@@ -35,6 +35,7 @@ wsMod;; // websocket module
|
|
|
35
35
|
* workerID: <string> // worker on server (server destinations only)
|
|
36
36
|
* }
|
|
37
37
|
* startup: <dictionary> // worker spawn init (server destinations only)
|
|
38
|
+
* wss: <boolean> // true to use secure connection
|
|
38
39
|
* debug: <boolean> // debug logging
|
|
39
40
|
* }
|
|
40
41
|
*
|
|
@@ -74,6 +75,7 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
74
75
|
relay.guid = secret
|
|
75
76
|
relay.host = host // e.g. "localhost:8009"
|
|
76
77
|
relay.wscon = wsMod.WebSocket(host, {
|
|
78
|
+
wss: options.wss || undefined
|
|
77
79
|
onopen: onopen
|
|
78
80
|
onmessage: onmessage
|
|
79
81
|
onerror: onerror
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2024 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -193,8 +193,14 @@ closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
|
|
|
193
193
|
else
|
|
194
194
|
fpath = "/".concat(libpath)
|
|
195
195
|
if js.s.importScripts && tostring(js.s.importScripts) == "[Function importScripts]" {
|
|
196
|
-
js.
|
|
197
|
-
|
|
196
|
+
fpath = JSpath.dirname(js.w.location.href).concat(fpath)
|
|
197
|
+
try {
|
|
198
|
+
js.s.importScripts(fpath) // load in worker context
|
|
199
|
+
jsScripts[libpath] = js.s[globalID]
|
|
200
|
+
} catch {
|
|
201
|
+
debuglog("JsLoadScript:", libpath, "failed", exception)
|
|
202
|
+
js.s.console.log("JsLoadScript:", libpath, "failed", exception) // ensure visibility in JS console
|
|
203
|
+
}
|
|
198
204
|
} else if js.w { // load in browser context
|
|
199
205
|
pending = new(nonce)
|
|
200
206
|
scriptTag = js.w.document.createElement("script")
|
|
@@ -205,7 +211,7 @@ closure JsLoadScript(libpath, globalID, local scriptTag, fpath) {
|
|
|
205
211
|
true
|
|
206
212
|
}
|
|
207
213
|
scriptTag.onerror = function (event) {
|
|
208
|
-
debuglog("
|
|
214
|
+
debuglog("JsLoadScript:", libpath, "not found")
|
|
209
215
|
pending.signal(false)
|
|
210
216
|
true
|
|
211
217
|
}
|
|
@@ -105,7 +105,7 @@ closure httpsApiReqOnce(url, options,
|
|
|
105
105
|
})
|
|
106
106
|
response.on("end", function (local content, error, headers) {
|
|
107
107
|
content = js.g.Buffer.concat(chunks)
|
|
108
|
-
if response.statusCode < 200 || response.statusCode >=
|
|
108
|
+
if response.statusCode < 200 || response.statusCode >= 299 { // 299 is "cancelled"
|
|
109
109
|
if options.debug
|
|
110
110
|
debuglog("HttpsApiRequest status:", url, response.statusCode, "message:", content)
|
|
111
111
|
pending.signal(list(Error("HttpsApiRequest statusCode:", url, response.statusCode, {
|
|
@@ -132,6 +132,7 @@ closure httpsApiReqOnce(url, options,
|
|
|
132
132
|
pending.signal(list(error, content, {
|
|
133
133
|
headers: response.headers
|
|
134
134
|
status: response.statusCode
|
|
135
|
+
contentType: response.headers["content-type"]
|
|
135
136
|
}))
|
|
136
137
|
})
|
|
137
138
|
})
|
|
@@ -450,8 +450,8 @@ closure psmsFsConnector(psm, api, local connClassID, connector, watch) {
|
|
|
450
450
|
connector.info = function info(resID, local info, error, creds) {
|
|
451
451
|
info = {
|
|
452
452
|
classID: connClassID
|
|
453
|
-
type: "remote
|
|
454
|
-
services: ["NideFS", "NideHostAPI"]
|
|
453
|
+
type: "remote server"
|
|
454
|
+
services: ["NideFS", "NideHostAPI", "NideTerminal"]
|
|
455
455
|
}
|
|
456
456
|
if resID == "Host" {
|
|
457
457
|
info.name = "Host"
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Options:
|
|
22
22
|
* {
|
|
23
|
+
* wss: <boolean> // true to use secure connection
|
|
23
24
|
* onopen: <proc>(e) // connection has opened
|
|
24
25
|
* onmessage: <proc>(e, message) // message received
|
|
25
26
|
* onerror: <proc>(e) // error occurred
|
|
@@ -37,13 +38,17 @@ closure WebSocket(host, options, local wsock) {
|
|
|
37
38
|
//
|
|
38
39
|
// Connect with the host if not already connected, returning a result tuple.
|
|
39
40
|
//
|
|
40
|
-
wsock.connect = closure connect(local
|
|
41
|
+
wsock.connect = closure connect(local error, ws, url, pending) {
|
|
41
42
|
if wsock.ws
|
|
42
43
|
return (list(false, { open: true }))
|
|
43
44
|
`(error, ws) = await(js.i("ws"))
|
|
44
45
|
if error
|
|
45
46
|
return (list(error))
|
|
46
|
-
|
|
47
|
+
if options.wss
|
|
48
|
+
url = "wss://${host}"
|
|
49
|
+
else
|
|
50
|
+
url = "ws://${host}"
|
|
51
|
+
wsock.ws = xnew(ws.default, url)
|
|
47
52
|
pending = new(nonce)
|
|
48
53
|
|
|
49
54
|
// onopen
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
* ]
|
|
119
119
|
* }
|
|
120
120
|
*
|
|
121
|
-
* build = Builder(rulesDict, operation, fs, srcpath, destpath)
|
|
121
|
+
* build = Builder(rulesDict, operation, fs, srcpath, destpath, track) // create a builder object
|
|
122
122
|
* build.increment() // increment the build counter
|
|
123
123
|
* build.make() // run the build
|
|
124
124
|
* build.clean() // clear all output folders
|
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
*
|
|
141
141
|
*/
|
|
142
142
|
|
|
143
|
-
closure Builder(rules, operation, fs, srcpath, destpath, local build, group, newgroup) {
|
|
143
|
+
closure Builder(rules, operation, fs, srcpath, destpath, track, local build, group, newgroup) {
|
|
144
144
|
build = new(object, this)
|
|
145
145
|
build.srcpath = srcpath
|
|
146
146
|
build.destpath = destpath
|
|
@@ -393,7 +393,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
393
393
|
|
|
394
394
|
closure zip(files, options, local result) {
|
|
395
395
|
if !build.zipper
|
|
396
|
-
build.zipper = ExecutorParallel({
|
|
396
|
+
build.zipper = ExecutorParallel(track, { // create worker for zipping
|
|
397
397
|
maxcount: 1 // stupid Zip lib can't do more than one
|
|
398
398
|
basename: "zip"
|
|
399
399
|
initeval: `(false, (zip1))
|
|
@@ -529,7 +529,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
529
529
|
|
|
530
530
|
closure parseAndPack(text, fpath, options, local result) {
|
|
531
531
|
if !build.parallel
|
|
532
|
-
build.parallel = ExecutorParallel({
|
|
532
|
+
build.parallel = ExecutorParallel(track, { // create worker pool
|
|
533
533
|
basename: "build"
|
|
534
534
|
initeval: `(false, (parseAndPack1))
|
|
535
535
|
})
|
|
@@ -1190,12 +1190,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1190
1190
|
//
|
|
1191
1191
|
// Run the current build product by spawning a new worker.
|
|
1192
1192
|
//
|
|
1193
|
-
build.runSpawn = function runSpawn(
|
|
1193
|
+
build.runSpawn = function runSpawn(local error, maintext, executor, vpath, site) {
|
|
1194
1194
|
`(error, maintext) = fs.readFile(JSpath.join(build.destpath, build.runway.main))
|
|
1195
1195
|
if error
|
|
1196
1196
|
error = Error("Builder: cannot read main file", error)
|
|
1197
1197
|
else {
|
|
1198
|
-
`(error, executor) = track.spawn(build.runway.spawn.0, "${rules.name} ${build.version}",
|
|
1198
|
+
`(error, executor) = track.spawn(build.runway.spawn.0, "${rules.name} ${build.version}", {
|
|
1199
|
+
workerID: "Run-${build.buildnum}"
|
|
1199
1200
|
startup: {
|
|
1200
1201
|
initcmds: maintext
|
|
1201
1202
|
dirpath: fs.path.resolve(fs.path.sep, fs.rootpath, build.destpath)
|
|
@@ -1227,7 +1228,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1227
1228
|
//
|
|
1228
1229
|
// Run the current build product by opening a new window.
|
|
1229
1230
|
//
|
|
1230
|
-
build.runWindow = function runWindow(
|
|
1231
|
+
build.runWindow = function runWindow(
|
|
1231
1232
|
local title, main, url, features, vpath, error, window, site) {
|
|
1232
1233
|
if !js.w
|
|
1233
1234
|
return (list(Error('Run method "window" requires browser host')))
|
|
@@ -1259,13 +1260,13 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1259
1260
|
// Run the current build product, which would be after the make call. Returns a standard result
|
|
1260
1261
|
// tuple.
|
|
1261
1262
|
//
|
|
1262
|
-
build.run = function run(
|
|
1263
|
+
build.run = function run() {
|
|
1263
1264
|
if build.runway.open
|
|
1264
1265
|
fs.shellOpen(JSpath.join(build.destpath, build.runway.open), build.runway.args)
|
|
1265
1266
|
else if build.runway.spawn
|
|
1266
|
-
build.runSpawn(
|
|
1267
|
+
build.runSpawn()
|
|
1267
1268
|
else if build.runway.window
|
|
1268
|
-
build.runWindow(
|
|
1269
|
+
build.runWindow()
|
|
1269
1270
|
else
|
|
1270
1271
|
list(false, { ok: true })
|
|
1271
1272
|
}
|
|
@@ -1275,7 +1276,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
|
|
|
1275
1276
|
//
|
|
1276
1277
|
// Refresh after updating the v-site, returning true iff an existing vsite was found.
|
|
1277
1278
|
//
|
|
1278
|
-
build.refresh = function refresh(
|
|
1279
|
+
build.refresh = function refresh(local url_origin, found) {
|
|
1279
1280
|
if build.runway."v-site" {
|
|
1280
1281
|
url_origin = js.w.location.origin.concat("/run", build.runway."v-site")
|
|
1281
1282
|
for target in track.enumlist() {
|
|
@@ -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.1
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.2.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
|
|
@@ -614,7 +614,7 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
614
614
|
rules.typeID = procon.where_typeID
|
|
615
615
|
if !rules.operation
|
|
616
616
|
rules.operation = "debug"
|
|
617
|
-
`(error, builder) = Builder(rules, rules.operation, fs, "", buildpath)
|
|
617
|
+
`(error, builder) = Builder(rules, rules.operation, fs, "", buildpath, projman.track)
|
|
618
618
|
if error
|
|
619
619
|
return (list(error))
|
|
620
620
|
procon.builder = builder
|
|
@@ -628,10 +628,10 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
628
628
|
buildnum: buildnum
|
|
629
629
|
})
|
|
630
630
|
if !error {
|
|
631
|
-
if builder.refresh(
|
|
631
|
+
if builder.refresh()
|
|
632
632
|
buildonly = !buildonly // reverse if refresh
|
|
633
633
|
if !buildonly
|
|
634
|
-
`(error) = builder.run(
|
|
634
|
+
`(error) = builder.run()
|
|
635
635
|
}
|
|
636
636
|
builder.destroy()
|
|
637
637
|
procon.builder = false
|
|
@@ -662,7 +662,9 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
662
662
|
publish = rules.publish
|
|
663
663
|
where = procon.localDict.publish[stage].where
|
|
664
664
|
if !rules || !where
|
|
665
|
-
return (list(Error("no project publish location
|
|
665
|
+
return (list(Error("no project publish location set")))
|
|
666
|
+
if !publish.input || !publish.sources || !publish.output
|
|
667
|
+
return (list(Error("project configuration has no publish instructions")))
|
|
666
668
|
if publish.cacheControl
|
|
667
669
|
outOptions = {
|
|
668
670
|
cacheControl: publish.cacheControl
|