@naanlang/naan 1.1.0 → 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 +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 +65 -43
- package/frameworks/client/apiclient.nlg +80 -115
- package/frameworks/client/psm_client.nlg +36 -15
- package/frameworks/node/https_request.nlg +2 -1
- package/frameworks/node/psm_server.nlg +2 -2
- package/frameworks/project/build.nlg +2 -1
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/executors.nlg +11 -6
- 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 +3 -3
- package/test/harness.nlg +1 -1
- package/test/test_02_context.nlg +2 -2
- package/test/test_07_lingo.nlg +3 -0
|
@@ -90,7 +90,7 @@ closure HttpsApiRequest(url, options,
|
|
|
90
90
|
debuglog("HttpsApiRequest error:", url, "error:", error)
|
|
91
91
|
return (list(Error("HttpsApiRequest fetch failed:", error, url)))
|
|
92
92
|
}
|
|
93
|
-
if response.status < 200 || response.status >=
|
|
93
|
+
if response.status < 200 || response.status >= 299 { // 299 is "cancelled"
|
|
94
94
|
if options.debug
|
|
95
95
|
debuglog("HttpsApiRequest status:", url, response.statusCode)
|
|
96
96
|
error = Error("HttpsApiRequest status:", url, response.status, {
|
|
@@ -104,7 +104,8 @@ closure HttpsApiRequest(url, options,
|
|
|
104
104
|
break
|
|
105
105
|
}
|
|
106
106
|
contentType = response.headers.get("content-type")
|
|
107
|
-
if contentType.startsWith("application/json")
|
|
107
|
+
if contentType.startsWith("application/json")
|
|
108
|
+
|| contentType.startsWith("application/octet-stream") && options.encoding == "json" {
|
|
108
109
|
`(error, content) = await(response.text())
|
|
109
110
|
if !error
|
|
110
111
|
`(error, content) = JsonParse(content)
|
|
@@ -129,6 +130,7 @@ closure HttpsApiRequest(url, options,
|
|
|
129
130
|
list(error, content, {
|
|
130
131
|
headers: headers
|
|
131
132
|
status: response.status
|
|
133
|
+
contentType: contentType
|
|
132
134
|
})
|
|
133
135
|
};
|
|
134
136
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
var CurrentCacheName = "Naanlang-1.
|
|
39
|
+
var CurrentCacheName = "Naanlang-1.2.0+1";
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
//
|
|
@@ -92,18 +92,18 @@ var terminated; // flag that this service worker
|
|
|
92
92
|
var pubVersion = event.data.hereIsMyVersion;
|
|
93
93
|
var sourceId = event.source.id; // client id of sender of message
|
|
94
94
|
msgPorts[sourceId] = msgport;
|
|
95
|
-
console.log("[1.
|
|
96
|
-
if (pubVersion != "1.
|
|
95
|
+
console.log("[1.2.0+1] received new msgport for", sourceId, pubID, "-", pubVersion);
|
|
96
|
+
if (pubVersion != "1.2.0+1") {
|
|
97
97
|
if (upgradeMsgPorts) { // if not activated
|
|
98
|
-
console.log("[1.
|
|
98
|
+
console.log("[1.2.0+1] update pending for", sourceId);
|
|
99
99
|
upgradeMsgPorts[sourceId] = msgport;
|
|
100
100
|
}
|
|
101
101
|
else {
|
|
102
102
|
msgport.postMessage({ // notify new version available
|
|
103
103
|
id: "upgrade",
|
|
104
|
-
version: "1.
|
|
104
|
+
version: "1.2.0+1"
|
|
105
105
|
});
|
|
106
|
-
console.log("[1.
|
|
106
|
+
console.log("[1.2.0+1] update sent for:", sourceId);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
Reaper(); // clean up obsolete info
|
|
@@ -134,10 +134,10 @@ var terminated; // flag that this service worker
|
|
|
134
134
|
msgport.onmessage = function(msg) {
|
|
135
135
|
msg = msg.data;
|
|
136
136
|
if (msg.id == "skipWaiting") { // try to activate this SW now
|
|
137
|
-
console.log("[1.
|
|
137
|
+
console.log("[1.2.0+1] attempting skipWaiting");
|
|
138
138
|
self.skipWaiting();
|
|
139
139
|
} else if (msg.id == "terminate") { // termiante this SW now
|
|
140
|
-
console.log("[1.
|
|
140
|
+
console.log("[1.2.0+1] terminated");
|
|
141
141
|
terminate();
|
|
142
142
|
} else if (msg.id == "abortURL") { // abort an I/O transaction
|
|
143
143
|
var href = new URL(msg.url).href;
|
|
@@ -150,7 +150,7 @@ var terminated; // flag that this service worker
|
|
|
150
150
|
} else if (msg.id == "response") // response from fetch request
|
|
151
151
|
processResponse(msg);
|
|
152
152
|
else if (msg.id == "text") // just log some text
|
|
153
|
-
console.log("[1.
|
|
153
|
+
console.log("[1.2.0+1] msg received:", msg.text);
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
// send text to IDE log
|
|
@@ -161,7 +161,7 @@ var terminated; // flag that this service worker
|
|
|
161
161
|
// don't clutter the log
|
|
162
162
|
msgport.postMessage({
|
|
163
163
|
id: "text",
|
|
164
|
-
text: "port received by 1.
|
|
164
|
+
text: "port received by 1.2.0+1",
|
|
165
165
|
});
|
|
166
166
|
*/
|
|
167
167
|
if (--pending === 0)
|
|
@@ -178,7 +178,7 @@ var terminated; // flag that this service worker
|
|
|
178
178
|
includeUncontrolled: true
|
|
179
179
|
}).then(function(clientList) {
|
|
180
180
|
clientList.every(function(client) {
|
|
181
|
-
console.log("[1.
|
|
181
|
+
console.log("[1.2.0+1] requesting new msgport for", client.id);
|
|
182
182
|
++pending;
|
|
183
183
|
client.postMessage({ // tell client(s) we need this fetch source
|
|
184
184
|
msg: "Naan_need_fetch_port",
|
|
@@ -224,12 +224,12 @@ function Reaper() {
|
|
|
224
224
|
clients[clientList[clidex].id] = clientList[clidex];
|
|
225
225
|
for (var sourceId in msgPorts)
|
|
226
226
|
if (!clients[sourceId]) {
|
|
227
|
-
console.log("[1.
|
|
227
|
+
console.log("[1.2.0+1] source gone:", sourceId);
|
|
228
228
|
delete msgPorts[sourceId]; // no longer a source
|
|
229
229
|
}
|
|
230
230
|
for (var clientId in fetchPorts)
|
|
231
231
|
if (!clients[clientId]) {
|
|
232
|
-
console.log("[1.
|
|
232
|
+
console.log("[1.2.0+1] client gone:", clientId);
|
|
233
233
|
delete fetchPorts[clientId]; // no longer a client
|
|
234
234
|
}
|
|
235
235
|
for (var fqdex = 0; fqdex < fetchQueue.length; ++fqdex) {
|
|
@@ -263,16 +263,16 @@ function ClearCaches() {
|
|
|
263
263
|
return (Promise.all(
|
|
264
264
|
cacheNames.map(function(cacheName) {
|
|
265
265
|
if (cacheName != CurrentCacheName) {
|
|
266
|
-
console.log('[1.
|
|
266
|
+
console.log('[1.2.0+1] deleting old cache:', cacheName);
|
|
267
267
|
return (caches.delete(cacheName));
|
|
268
268
|
}
|
|
269
269
|
})
|
|
270
270
|
));
|
|
271
271
|
}).then(function() { // claim all clients
|
|
272
|
-
console.log('[1.
|
|
272
|
+
console.log('[1.2.0+1] claiming clients');
|
|
273
273
|
return (self.clients.claim());
|
|
274
274
|
}).then(function() {
|
|
275
|
-
console.log('[1.
|
|
275
|
+
console.log('[1.2.0+1] clients claimed');
|
|
276
276
|
return (Promise.resolve(true));
|
|
277
277
|
});
|
|
278
278
|
return (promise);
|
|
@@ -315,7 +315,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
315
315
|
msgport.postMessage({
|
|
316
316
|
id: "fetch",
|
|
317
317
|
seq: seqno,
|
|
318
|
-
version: "1.
|
|
318
|
+
version: "1.2.0+1",
|
|
319
319
|
request: {
|
|
320
320
|
method: event.request.method,
|
|
321
321
|
url: event.request.url
|
|
@@ -363,7 +363,7 @@ function GetClientResponse(event, urlpath) {
|
|
|
363
363
|
*/
|
|
364
364
|
|
|
365
365
|
self.addEventListener('install', function(event) {
|
|
366
|
-
console.log("[1.
|
|
366
|
+
console.log("[1.2.0+1] install");
|
|
367
367
|
self.skipWaiting();
|
|
368
368
|
});
|
|
369
369
|
|
|
@@ -376,20 +376,20 @@ self.addEventListener('install', function(event) {
|
|
|
376
376
|
*/
|
|
377
377
|
|
|
378
378
|
self.addEventListener('activate', function(event) {
|
|
379
|
-
console.log("[1.
|
|
379
|
+
console.log("[1.2.0+1] activate");
|
|
380
380
|
self.clients.matchAll({ // for debugging, list controlled clients
|
|
381
381
|
includeUncontrolled: true
|
|
382
382
|
}).then(function(clientList) {
|
|
383
383
|
var urls = clientList.map(function(client) {
|
|
384
384
|
return (client.url);
|
|
385
385
|
});
|
|
386
|
-
console.log('[1.
|
|
386
|
+
console.log('[1.2.0+1] matching clients:', urls.join(', '));
|
|
387
387
|
});
|
|
388
388
|
var promise = ClearCaches().then(function() {
|
|
389
389
|
for (var sourceId in upgradeMsgPorts) {
|
|
390
390
|
upgradeMsgPorts[sourceId].postMessage({ // notify new version available
|
|
391
391
|
id: "upgrade",
|
|
392
|
-
version: "1.
|
|
392
|
+
version: "1.2.0+1"
|
|
393
393
|
});
|
|
394
394
|
}
|
|
395
395
|
upgradeMsgPorts = false;
|
|
@@ -421,7 +421,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
421
421
|
var promise;
|
|
422
422
|
var url = new URL(request.url);
|
|
423
423
|
var nocache = request.method != "GET"
|
|
424
|
-
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "
|
|
424
|
+
|| url.search.length !== 0 && url.searchParams.get("naanver") !== "d20959c47030d94a5b0694e7b9df2dc1"
|
|
425
425
|
|| request.headers.get('range');
|
|
426
426
|
if (url.pathname.startsWith("/run/")) {
|
|
427
427
|
nocache = true;
|
|
@@ -455,7 +455,7 @@ self.addEventListener('fetch', function(event) {
|
|
|
455
455
|
statusText: "Request Cancelled"
|
|
456
456
|
}));
|
|
457
457
|
}
|
|
458
|
-
console.log("[1.
|
|
458
|
+
console.log("[1.2.0+1] fetch failed", request.url, e);
|
|
459
459
|
return (new Response(undefined, {
|
|
460
460
|
status: 404,
|
|
461
461
|
statusText: "Fetch Failed"
|
|
@@ -14,30 +14,54 @@
|
|
|
14
14
|
/*
|
|
15
15
|
* TermHost
|
|
16
16
|
*
|
|
17
|
-
* Make
|
|
17
|
+
* Make an Nide API Server debugger target.
|
|
18
|
+
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* type: <string> // target category, e.g. "Host", "api.yyy.com"
|
|
22
|
+
* workerID: <string> // kind of worker in server subsystem
|
|
23
|
+
* dispatcher: <tuple> // dispatcher function for incoming messages
|
|
24
|
+
* startup: <dictionary> // startup options
|
|
25
|
+
* clientID: <string> // (rare) our identification on client
|
|
26
|
+
* serverID: <string> // (rare) server subsystem for us
|
|
27
|
+
* }
|
|
18
28
|
*
|
|
19
29
|
*/
|
|
20
30
|
|
|
21
|
-
closure TermHost(track, api, name,
|
|
22
|
-
local target, nlregex, clientID, serverID)
|
|
31
|
+
closure TermHost(track, api, name, options, local target, nlregex, xtarg)
|
|
23
32
|
{
|
|
24
33
|
global(window)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
options = merge({
|
|
35
|
+
type: "Host"
|
|
36
|
+
workerID: "myDebugWorker"
|
|
37
|
+
clientID: "DebugWorkers"
|
|
38
|
+
serverID: "Workers"
|
|
39
|
+
}, options)
|
|
40
|
+
target = require("../running/executors.nlg").ExecutorBase(track, options.type, name)
|
|
28
41
|
nlregex = RegExp("\\n", "g")
|
|
29
|
-
|
|
30
|
-
workerID = "myDebugWorker"
|
|
31
|
-
target.workerID = workerID
|
|
42
|
+
target.workerID = options.workerID
|
|
32
43
|
target.msgQueue = []
|
|
33
44
|
target.dispatcher = call(options.dispatcher, function(reply) { reply })
|
|
34
|
-
|
|
45
|
+
|
|
46
|
+
// findWorker
|
|
47
|
+
//
|
|
48
|
+
function findWorker(testID, local instance) {
|
|
49
|
+
for instance in track.instances {
|
|
50
|
+
if instance.executor.hostWorkerMatch(api, testID)
|
|
51
|
+
return (instance.executor)
|
|
52
|
+
}
|
|
53
|
+
false
|
|
54
|
+
}
|
|
55
|
+
|
|
35
56
|
// connect
|
|
36
57
|
// Connect with the host if not already connected.
|
|
37
|
-
closure connect(local pending) {
|
|
58
|
+
closure connect(local host, pending) {
|
|
38
59
|
if target.ws
|
|
39
|
-
return
|
|
40
|
-
|
|
60
|
+
return(list(false, { connected: true }))
|
|
61
|
+
host = xnew(window.URL, api.url).host
|
|
62
|
+
if !host || host == ""
|
|
63
|
+
return(list(Error("invalid URL ${api.url}")))
|
|
64
|
+
target.ws = xnew(window.WebSocket,"ws://${host}")
|
|
41
65
|
pending = new(nonce)
|
|
42
66
|
|
|
43
67
|
// onopen
|
|
@@ -45,7 +69,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
45
69
|
target.ws.onopen = function onopen(e, local info, spawner) {
|
|
46
70
|
info = {
|
|
47
71
|
name: name
|
|
48
|
-
workerID: workerID
|
|
72
|
+
workerID: target.workerID
|
|
49
73
|
}
|
|
50
74
|
if options.dispatcher
|
|
51
75
|
info.destID = api.instanceID // valid destination for relay
|
|
@@ -61,7 +85,6 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
61
85
|
|
|
62
86
|
// onmessage
|
|
63
87
|
// A message was received from the worker via WebSockets.
|
|
64
|
-
|
|
65
88
|
target.ws.onmessage = function onmessage(e, message, local msg) {
|
|
66
89
|
try {
|
|
67
90
|
message = new(window.JSON.parse(e.data))
|
|
@@ -137,27 +160,16 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
137
160
|
// New workers created/discovered on this host.
|
|
138
161
|
//
|
|
139
162
|
function hostWorkerUpdate(msg, local localID, worker) {
|
|
140
|
-
|
|
141
|
-
// findWorker
|
|
142
|
-
//
|
|
143
|
-
function findWorker(testID, local instance) {
|
|
144
|
-
for instance in track.instances {
|
|
145
|
-
if instance.executor.hostWorkerMatch(api, testID)
|
|
146
|
-
return (instance.executor)
|
|
147
|
-
}
|
|
148
|
-
false
|
|
149
|
-
}
|
|
150
|
-
|
|
151
163
|
if msg.id == "spawned" {
|
|
152
164
|
if !findWorker(msg.workerID)
|
|
153
|
-
TermHost(track, api, msg.name, msg.workerID)
|
|
165
|
+
TermHost(track, api, msg.name, { type: options.type, workerID: msg.workerID })
|
|
154
166
|
}
|
|
155
167
|
else if msg.id == "termination"
|
|
156
168
|
track.delete(findWorker(msg.workerID))
|
|
157
|
-
else {
|
|
169
|
+
else if msg.id == "workerlist" {
|
|
158
170
|
for `(localID, worker) in msg.workers
|
|
159
171
|
if !findWorker(localID)
|
|
160
|
-
TermHost(track, api, worker.name, localID)
|
|
172
|
+
TermHost(track, api, worker.name, { type: options.type, workerID: localID })
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
|
|
@@ -167,7 +179,7 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
167
179
|
// True iff the specified information matches us.
|
|
168
180
|
//
|
|
169
181
|
target.hostWorkerMatch = function hostWorkerMatch(testApi, testID) {
|
|
170
|
-
testApi === api && testID == workerID
|
|
182
|
+
testApi === api && testID == target.workerID
|
|
171
183
|
}
|
|
172
184
|
|
|
173
185
|
//
|
|
@@ -203,8 +215,8 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
203
215
|
target.sendControl = function sendControl(workerOp, payload) {
|
|
204
216
|
target.ws.send(window.JSON.stringify({
|
|
205
217
|
guid: api.guid
|
|
206
|
-
clientID: clientID
|
|
207
|
-
serverID: serverID
|
|
218
|
+
clientID: options.clientID
|
|
219
|
+
serverID: options.serverID
|
|
208
220
|
workerID: target.workerID
|
|
209
221
|
workerOp: workerOp
|
|
210
222
|
payload: payload
|
|
@@ -374,6 +386,9 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
374
386
|
target.ws.close(1000) // 1000: normal close
|
|
375
387
|
}
|
|
376
388
|
|
|
389
|
+
xtarg = findWorker(target.workerID)
|
|
390
|
+
if xtarg
|
|
391
|
+
return (list(false, xtarg)) // already exists
|
|
377
392
|
track.add(target)
|
|
378
393
|
connect() // connect right away to start receiving messages
|
|
379
394
|
|
|
@@ -388,27 +403,34 @@ closure TermHost(track, api, name, workerID, options,
|
|
|
388
403
|
*
|
|
389
404
|
* Make a local debugger target, returning a standard (error, object) tuple.
|
|
390
405
|
*
|
|
406
|
+
* Options:
|
|
407
|
+
* {
|
|
408
|
+
* workerID: <string> // kind of worker in server subsystem
|
|
409
|
+
* // "NaanIDE" for local IDE
|
|
410
|
+
* // "NaanIDE-Debug" for browser debug target
|
|
411
|
+
* startup: <dictionary> // startup options
|
|
412
|
+
* type: <string> // (rare) target category, e.g. "Local"
|
|
413
|
+
* }
|
|
414
|
+
*
|
|
391
415
|
*/
|
|
392
416
|
|
|
393
|
-
closure TermLocal(track, name,
|
|
394
|
-
local target, nlregex, listener)
|
|
417
|
+
closure TermLocal(track, name, options, local target, nlregex, listener)
|
|
395
418
|
{
|
|
396
419
|
global(js, window)
|
|
397
|
-
|
|
420
|
+
options = merge({
|
|
421
|
+
type: "Local"
|
|
422
|
+
}, options)
|
|
423
|
+
if options.workerID == "NaanIDE" {
|
|
398
424
|
if !js.t
|
|
399
425
|
return (list(Error("Cannot access Local IDE executor")))
|
|
400
426
|
termInstallVirtualWatcher(track, js.t)
|
|
401
|
-
return (termIDE(track, name, workerID, js.t))
|
|
427
|
+
return (termIDE(track, name, options.workerID, js.t)) // connect to IDE execution instance itself
|
|
402
428
|
}
|
|
403
|
-
|
|
404
|
-
options = new(options)
|
|
405
|
-
else
|
|
406
|
-
options = { }
|
|
407
|
-
target = require("../running/executors.nlg").ExecutorBase(track, "Local", name)
|
|
429
|
+
target = require("../running/executors.nlg").ExecutorBase(track, options.type, name)
|
|
408
430
|
nlregex = RegExp("\\n", "g")
|
|
409
|
-
target.workerID = workerID
|
|
431
|
+
target.workerID = options.workerID
|
|
410
432
|
target.msgQueue = []
|
|
411
|
-
if workerID == "NaanIDE-Debug" {
|
|
433
|
+
if options.workerID == "NaanIDE-Debug" {
|
|
412
434
|
target.worker = window.open(window.location.href, "_blank")
|
|
413
435
|
target.worker.addEventListener("beforeunload", function(e) { // our target is closing
|
|
414
436
|
destroy()
|
|
@@ -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
|
} ();
|