@naanlang/naan 1.0.16 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +2 -2
- package/README.md +13 -11
- package/bin/index.js +4 -4
- package/dist/naan.min.js +14 -14
- package/frameworks/browser/https_request.nlg +26 -10
- package/frameworks/browser/sworker.js +26 -25
- package/frameworks/browser/terminals.nlg +118 -55
- package/frameworks/browser/ws_client.nlg +124 -0
- package/frameworks/client/apiclient.nlg +82 -116
- package/frameworks/client/psm_client.nlg +37 -16
- package/frameworks/client/relaycon.nlg +308 -0
- package/frameworks/common/common.nlg +1 -1
- package/frameworks/common/utils.nlg +40 -2
- package/frameworks/node/apiserver.nlg +342 -103
- package/frameworks/node/https_request.nlg +32 -6
- package/frameworks/node/node.nlg +60 -2
- package/frameworks/node/psm_server.nlg +11 -7
- package/frameworks/node/worker.nlg +22 -9
- package/frameworks/node/ws_client.nlg +127 -0
- package/frameworks/project/build.nlg +3 -2
- package/frameworks/project/projects.nlg +8 -2
- package/frameworks/running/debugnub.nlg +2 -2
- package/frameworks/running/debugutil.nlg +1 -1
- package/frameworks/running/executors.nlg +69 -17
- package/frameworks/running/sourcecode.nlg +2 -2
- package/frameworks/running/taskexec.nlg +25 -25
- package/frameworks/storage/dbt_pouch.nlg +8 -6
- package/frameworks/storage/file_manager.nlg +6 -3
- package/frameworks/storage/psm.nlg +5 -3
- package/frameworks/storage/psm_dbtables.nlg +75 -53
- package/frameworks/storage/resources.nlg +4 -2
- package/lib/browser/env_web.js +6 -6
- package/lib/browser/env_webworker.js +1 -1
- package/lib/core/naanlib.js +14 -14
- package/lib/env_node.js +97 -8
- package/lib/env_nodeworker.js +22 -4
- package/package.json +1 -1
- package/plugins/serviceAws/aws/lambda_rest_index.js +5 -1
- package/plugins/serviceAws/aws_dynamo.nlg +91 -32
- package/plugins/serviceAws/dbt_aws.nlg +5 -5
- package/plugins/serviceAws/psm_aws.nlg +2 -2
- package/test/harness.nlg +1 -1
- package/test/test_01_core.nlg +30 -4
- package/test/test_02_context.nlg +2 -2
- package/test/test_07_lingo.nlg +3 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ws_client.nlg
|
|
3
|
+
*
|
|
4
|
+
* WebSocket client operations for the browser.
|
|
5
|
+
*
|
|
6
|
+
* column positioning: // // !
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2023 by Richard C. Zulch
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* WebSocket
|
|
15
|
+
*
|
|
16
|
+
* Create a WebSocket client connection object using the existing HTTPS connection.
|
|
17
|
+
*
|
|
18
|
+
* Options:
|
|
19
|
+
* {
|
|
20
|
+
* host: <string> // host:port
|
|
21
|
+
* onopen: <proc>(e) // connection has opened
|
|
22
|
+
* onmessage: <proc>(e, message) // message received
|
|
23
|
+
* onerror: <proc>(e) // error occurred
|
|
24
|
+
* onclose: <proc>(e) // connection has closed
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
closure WebSocket(options, local wsock) {
|
|
30
|
+
global(window)
|
|
31
|
+
wsock = new(object, this)
|
|
32
|
+
options = new(options) || { }
|
|
33
|
+
if !options.host
|
|
34
|
+
options.host = window.location.host
|
|
35
|
+
|
|
36
|
+
// connect
|
|
37
|
+
//
|
|
38
|
+
// Connect with the host if not already connected, returning a result tuple.
|
|
39
|
+
//
|
|
40
|
+
wsock.connect = closure connect(local pending) {
|
|
41
|
+
if wsock.ws
|
|
42
|
+
return (list(false, { open: true }))
|
|
43
|
+
wsock.ws = xnew(window.WebSocket, "ws://${options.host}")
|
|
44
|
+
pending = new(nonce)
|
|
45
|
+
|
|
46
|
+
// onopen
|
|
47
|
+
// The WebSocket connection is now open.
|
|
48
|
+
wsock.ws.onopen = closure onopen(e, local spawner) {
|
|
49
|
+
pending.signal(list(false, { ok: true }))
|
|
50
|
+
options.onopen(e)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// onmessage
|
|
54
|
+
// A message was received from the worker via WebSockets.
|
|
55
|
+
wsock.ws.onmessage = closure onmessage(e, message) {
|
|
56
|
+
try {
|
|
57
|
+
message = new(JSONparse(e.data))
|
|
58
|
+
} catch {
|
|
59
|
+
debuglog("can't decode incoming ws message:", exception)
|
|
60
|
+
options.onerror(Error("can't decode incoming message:", exception))
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
options.onmessage(e, message)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// onerror
|
|
67
|
+
// An error occurred on the WebSocket connection.
|
|
68
|
+
wsock.ws.onerror = closure onerror(e, local error) {
|
|
69
|
+
error = Error("websocket failed", e)
|
|
70
|
+
options.onerror(e, error)
|
|
71
|
+
pending.signal(list(error)) // ensure connect completes
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// onclose
|
|
75
|
+
// The WebSocket connection was closed.
|
|
76
|
+
wsock.ws.onclose = closure onclose(e) {
|
|
77
|
+
options.onclose(e, e.code, e.reason)
|
|
78
|
+
pending.signal(list(Error("connection closed"))) // ensure connect completes
|
|
79
|
+
wsock.ws = false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
pending.wait()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// send
|
|
86
|
+
//
|
|
87
|
+
// Send a message dictionary.
|
|
88
|
+
//
|
|
89
|
+
wsock.send = function send(message) {
|
|
90
|
+
wsock.ws.send(JSONstringify(message))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// close
|
|
94
|
+
//
|
|
95
|
+
// Close the connection.
|
|
96
|
+
//
|
|
97
|
+
wsock.close = function close(reason) {
|
|
98
|
+
if !reason
|
|
99
|
+
reason = 1000 // normal close
|
|
100
|
+
wsock.ws.close(reason)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// finis
|
|
104
|
+
|
|
105
|
+
wsock
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* ws_clientInit
|
|
111
|
+
*
|
|
112
|
+
* Initialize WebSocket client operations for browsers.
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
function ws_clientInit(local manifest) {
|
|
117
|
+
manifest = `(WebSocket, ws_clientInit)
|
|
118
|
+
|
|
119
|
+
Naan.module.build(module.id, "ws_client", function(modobj, compobj) {
|
|
120
|
+
require("browser.nlg")
|
|
121
|
+
compobj.manifest = manifest
|
|
122
|
+
modobj.exports.WebSocket = WebSocket
|
|
123
|
+
})
|
|
124
|
+
}();
|
|
@@ -2,174 +2,140 @@
|
|
|
2
2
|
* apiclient.nlg
|
|
3
3
|
* Naanlib/frameworks/client
|
|
4
4
|
*
|
|
5
|
-
* Access to Nide API with HTTP client.
|
|
5
|
+
* Access to Nide API with browser HTTP client.
|
|
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
|
|
29
|
+
client.instanceID = UUID() // our client's unique ID
|
|
28
30
|
|
|
29
|
-
// clientRequest() -
|
|
30
|
-
|
|
31
|
-
closure clientRequest(method, path, options, cbReq, local request) {
|
|
32
|
-
request = xnew(js.w.XMLHttpRequest)
|
|
33
|
-
request.addEventListener("load", function (event) {
|
|
34
|
-
cbReq(false, request, event)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
request.addEventListener("error", function reqFailed(event, local errtext) {
|
|
38
|
-
if request.status == 0
|
|
39
|
-
errtext = "connectivity"
|
|
40
|
-
else
|
|
41
|
-
errtext = "request failed"
|
|
42
|
-
error = Error(errtext, {
|
|
43
|
-
status: request.status
|
|
44
|
-
method: method
|
|
45
|
-
path: path
|
|
46
|
-
})
|
|
47
|
-
cbReq(error, request, event)
|
|
48
|
-
})
|
|
31
|
+
// clientRequest() - append our guid to the headers
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
request.responseType = options.responseType
|
|
53
|
-
if options.contentType
|
|
54
|
-
request.setRequestHeader("Content-Type", options.contentType)
|
|
33
|
+
closure clientRequest(url, options) {
|
|
34
|
+
options = merge(options)
|
|
55
35
|
if guid
|
|
56
|
-
|
|
57
|
-
|
|
36
|
+
options.headers = [list("x-naanlang-api-guid", guid)]
|
|
37
|
+
apiRequester(url, options)
|
|
58
38
|
}
|
|
59
39
|
|
|
60
40
|
//
|
|
61
41
|
// docs()
|
|
62
42
|
//
|
|
63
43
|
|
|
64
|
-
client.docs = closure docs() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
})
|
|
44
|
+
client.docs = closure docs(local error, content, extra) {
|
|
45
|
+
`(error, content, extra) = clientRequest(url.concat("/"))
|
|
46
|
+
printline(content)
|
|
68
47
|
}
|
|
69
48
|
|
|
70
49
|
//
|
|
71
50
|
// status(callback, timeoutMS)
|
|
72
51
|
//
|
|
73
52
|
|
|
74
|
-
client.status = closure status(cbStatus, timeoutms, local query,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
query = EncodeQuery("/status/?", options)
|
|
79
|
-
clientRequest("GET", url.concat(query), false, function (error, req, event) {
|
|
80
|
-
if (error || req.status != 200)
|
|
81
|
-
cbStatus()
|
|
82
|
-
else if (length(req.responseText) == 0)
|
|
83
|
-
cbStatus([])
|
|
84
|
-
else {
|
|
85
|
-
queued = new(JSONparse(req.responseText))
|
|
86
|
-
queued.forEach(function(item,index,array) {
|
|
87
|
-
if client.notifyAfter < item.stamp
|
|
88
|
-
client.notifyAfter = item.stamp
|
|
89
|
-
})
|
|
90
|
-
cbStatus(queued)
|
|
91
|
-
}
|
|
53
|
+
client.status = closure status(cbStatus, timeoutms, local query, error, content, extra, queued) {
|
|
54
|
+
query = EncodeQuery("/status/?", {
|
|
55
|
+
timeout: timeoutms
|
|
56
|
+
after: client.notifyAfter
|
|
92
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
|
+
}
|
|
93
71
|
}
|
|
94
72
|
|
|
95
73
|
//
|
|
96
74
|
// get
|
|
97
75
|
//
|
|
98
76
|
|
|
99
|
-
client.get = closure get(path,
|
|
100
|
-
|
|
101
|
-
|
|
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)
|
|
102
87
|
}
|
|
103
88
|
|
|
104
89
|
//
|
|
105
|
-
// readFile(filepath,
|
|
90
|
+
// readFile(filepath, options)
|
|
106
91
|
//
|
|
107
92
|
|
|
108
|
-
client.readFile = closure readFile(filepath,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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)
|
|
113
106
|
}
|
|
114
107
|
|
|
115
108
|
//
|
|
116
109
|
// psmRemote(options, data, callback)
|
|
117
110
|
//
|
|
118
|
-
// Perform an operation and call back when done.
|
|
119
|
-
// callback(false, (remote_error, remote_data)).
|
|
120
|
-
// Otherwise if communication failed then the result is:
|
|
121
|
-
// callback(<error>).
|
|
111
|
+
// Perform an operation and call back when done.
|
|
122
112
|
|
|
123
|
-
client.psmRemote = closure psmRemote(options, data, callback,
|
|
113
|
+
client.psmRemote = closure psmRemote(options, data, callback,
|
|
114
|
+
local query, reqOptions, error, content, extra) {
|
|
124
115
|
query = EncodeQuery("/psm/?", options)
|
|
125
|
-
if data
|
|
126
|
-
method = "PUT"
|
|
127
|
-
else
|
|
128
|
-
method = "GET"
|
|
129
116
|
reqOptions = {
|
|
130
117
|
putdata: data
|
|
131
118
|
}
|
|
132
|
-
if
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
reqOptions.contentType = "application/json;charset=UTF-8" // we are sending JSON
|
|
140
|
-
`(error, data) = JsonStringify(data)
|
|
141
|
-
if error
|
|
142
|
-
return (callback(Error("psmRemote failed:", error)))
|
|
143
|
-
reqOptions.putdata = data
|
|
144
|
-
}
|
|
145
|
-
else
|
|
146
|
-
reqOptions.responseType = "application/json" // we are requesting JSON
|
|
147
|
-
}
|
|
148
|
-
clientRequest(method, url.concat(query), reqOptions, function (error, req, event, local data) {
|
|
149
|
-
if !error && req.status != 200
|
|
150
|
-
error = Error("NodeFS request failed: ".concat(req.status), {
|
|
151
|
-
status: req.status
|
|
152
|
-
method: method
|
|
153
|
-
query: query
|
|
154
|
-
})
|
|
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)
|
|
155
126
|
if error
|
|
156
|
-
callback(error)
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
else
|
|
170
|
-
data = req.response // e.g. when reading binary content
|
|
171
|
-
callback(error, data) }
|
|
172
|
-
})
|
|
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)
|
|
173
139
|
}
|
|
174
140
|
|
|
175
141
|
client
|
|
@@ -185,12 +151,12 @@ closure MakeNideAPIclient(url, guid, local client) {
|
|
|
185
151
|
|
|
186
152
|
function apicInit(local manifest) {
|
|
187
153
|
|
|
188
|
-
manifest = `(
|
|
154
|
+
manifest = `(NideAPIclient, apicInit)
|
|
189
155
|
|
|
190
156
|
Naan.module.build(module.id, "apiclient", function(modobj, compobj) {
|
|
191
157
|
Naan.module.require("./client.nlg")
|
|
192
158
|
compobj.manifest = manifest
|
|
193
|
-
modobj.exports.
|
|
159
|
+
modobj.exports.NideAPIclient = NideAPIclient
|
|
194
160
|
})
|
|
195
161
|
|
|
196
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
|
|
@@ -114,7 +115,7 @@ closure psmcFsView(api, rootpath, local view, pathmod) {
|
|
|
114
115
|
// that a transient error will give a bad path, but that will be detected downstream.
|
|
115
116
|
|
|
116
117
|
view.path = new(object, this)
|
|
117
|
-
view.path[".undefined"] = function path args {
|
|
118
|
+
view.path@[".undefined"] = function path args {
|
|
118
119
|
if !pathmod
|
|
119
120
|
pathInit()
|
|
120
121
|
xapply(pathmod, args.0, args.-1)
|
|
@@ -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" {
|
|
@@ -653,11 +673,12 @@ closure psmcFsConnector(psm, nicc, local connClassID, connector, watch) {
|
|
|
653
673
|
*
|
|
654
674
|
*/
|
|
655
675
|
|
|
656
|
-
function psmcMakeClientPSM(
|
|
676
|
+
function psmcMakeClientPSM(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
|