@naanlang/naan 1.4.1 → 1.4.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 +10 -10
- package/bin/index.js +2 -2
- package/dist/env_web.js +68 -73
- package/dist/naan.min.js +3 -3
- package/frameworks/browser/sworker.js +23 -23
- package/frameworks/browser/terminals.nlg +51 -2
- package/frameworks/common/common.nlg +5 -52
- package/frameworks/project/build.nlg +18 -4
- package/frameworks/project/projects.nlg +12 -1
- package/frameworks/running/executors.nlg +7 -3
- package/frameworks/running/running.nlg +25 -5
- package/frameworks/running/taskexec.nlg +1 -1
- package/frameworks/storage/dbt_pouch.nlg +8 -3
- package/frameworks/storage/psm_dbtables.nlg +2 -2
- package/lib/browser/env_web.js +73 -78
- package/lib/core/naanlib.js +3 -3
- package/package.json +1 -1
- package/plugins/serviceAws/aws_s3.nlg +17 -1
- package/plugins/serviceGC/russian_trusted_root_ca_pem.crt +33 -0
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
var CurrentCacheName = "Naanlang-1.4.
|
|
39
|
+
var CurrentCacheName = "Naanlang-1.4.2+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.4.
|
|
96
|
-
if (pubVersion != "1.4.
|
|
95
|
+
console.log("[1.4.2+1] received new msgport for", sourceId, pubID, "-", pubVersion);
|
|
96
|
+
if (pubVersion != "1.4.2+1") {
|
|
97
97
|
if (upgradeMsgPorts) { // if not activated
|
|
98
|
-
console.log("[1.4.
|
|
98
|
+
console.log("[1.4.2+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.4.
|
|
104
|
+
version: "1.4.2+1"
|
|
105
105
|
});
|
|
106
|
-
console.log("[1.4.
|
|
106
|
+
console.log("[1.4.2+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.4.
|
|
137
|
+
console.log("[1.4.2+1] attempting skipWaiting");
|
|
138
138
|
self.skipWaiting();
|
|
139
139
|
} else if (msg.id == "terminate") { // termiante this SW now
|
|
140
|
-
console.log("[1.4.
|
|
140
|
+
console.log("[1.4.2+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.4.
|
|
153
|
+
console.log("[1.4.2+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.4.
|
|
164
|
+
text: "port received by 1.4.2+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.4.
|
|
181
|
+
console.log("[1.4.2+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.4.
|
|
227
|
+
console.log("[1.4.2+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.4.
|
|
232
|
+
console.log("[1.4.2+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.4.
|
|
266
|
+
console.log('[1.4.2+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.4.
|
|
272
|
+
console.log('[1.4.2+1] claiming clients');
|
|
273
273
|
return (self.clients.claim());
|
|
274
274
|
}).then(function() {
|
|
275
|
-
console.log('[1.4.
|
|
275
|
+
console.log('[1.4.2+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.4.
|
|
318
|
+
version: "1.4.2+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.4.
|
|
366
|
+
console.log("[1.4.2+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.4.
|
|
379
|
+
console.log("[1.4.2+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.4.
|
|
386
|
+
console.log('[1.4.2+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.4.
|
|
392
|
+
version: "1.4.2+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") !== "9f1a6b0c23c290d0ee26783e99bdccc1"
|
|
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.4.
|
|
458
|
+
console.log("[1.4.2+1] fetch failed", request.url, e);
|
|
459
459
|
return (new Response(undefined, {
|
|
460
460
|
status: 404,
|
|
461
461
|
statusText: "Fetch Failed"
|
|
@@ -152,9 +152,9 @@ closure TermHost(track, api, name, options, local target, nlregex, xtarg)
|
|
|
152
152
|
|
|
153
153
|
// onerror
|
|
154
154
|
// An error occurred on the WebSocket connection.
|
|
155
|
+
// This can happen in normal operation when the connection times out.
|
|
155
156
|
target.ws.onerror = function onerror(e) {
|
|
156
157
|
pending.signal(list(Error("websocket failed", e)))
|
|
157
|
-
debuglog("ws error")
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
// onclose
|
|
@@ -655,6 +655,7 @@ closure TermLocal(track, name, options, local target, nlregex, listener)
|
|
|
655
655
|
// Destroy the execution instance.
|
|
656
656
|
|
|
657
657
|
target.destroy = function destroy() {
|
|
658
|
+
gWorkers[target.guid] = undefined
|
|
658
659
|
target.execClosed(Error("instance destroyed"))
|
|
659
660
|
track.delete(target)
|
|
660
661
|
termDetach()
|
|
@@ -865,6 +866,10 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
865
866
|
if inbound
|
|
866
867
|
inbound.active = active
|
|
867
868
|
}
|
|
869
|
+
|
|
870
|
+
connection.WriteLn = function WriteLn(text) {
|
|
871
|
+
term.WriteLn(text)
|
|
872
|
+
}
|
|
868
873
|
|
|
869
874
|
connection.termDetach = function termDetach() { // disconnect the terminal
|
|
870
875
|
db.detach(target)
|
|
@@ -921,7 +926,46 @@ closure termIDE(track, name, workerID, naancont, title, local target, connected)
|
|
|
921
926
|
}
|
|
922
927
|
target.execReset() // reset our parent class
|
|
923
928
|
}
|
|
924
|
-
|
|
929
|
+
|
|
930
|
+
// targetClose
|
|
931
|
+
//
|
|
932
|
+
// Mark the target window as closed.
|
|
933
|
+
//
|
|
934
|
+
function targetClose(local conn) {
|
|
935
|
+
for conn in connected {
|
|
936
|
+
conn.db.detach(target)
|
|
937
|
+
conn.WriteLn("\x1b[90m\x1b[3m".concat("\ntarget closed", "\x1b[0m"))
|
|
938
|
+
}
|
|
939
|
+
target.execReset()
|
|
940
|
+
target.naancont = naancont = false
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
// setCheckStatus
|
|
944
|
+
//
|
|
945
|
+
// Begin or end checking status on the worker to see if stopped responding. The challenge
|
|
946
|
+
// here is that we open vsite windows in the main thread, but there is no reliable event to learn
|
|
947
|
+
// when they are closed. The solution is to start checking if the window is closed after it gets
|
|
948
|
+
// a visibilityChange event to hidden. This terminates when the window gets marked closed or when
|
|
949
|
+
// it becomes visible again--which is quite unlikely unless someone uses the explicit hide/show
|
|
950
|
+
// window methods.
|
|
951
|
+
//
|
|
952
|
+
target.setCheckStatus = closure setCheckStatus(hidden, window) {
|
|
953
|
+
if hidden {
|
|
954
|
+
if !target.statusPoll
|
|
955
|
+
target.statusPoll = future(function() {
|
|
956
|
+
while target.statusPoll {
|
|
957
|
+
if window.closed {
|
|
958
|
+
targetClose()
|
|
959
|
+
target.statusPoll = false
|
|
960
|
+
break
|
|
961
|
+
} else
|
|
962
|
+
sleep(100) // check 10x/second
|
|
963
|
+
}
|
|
964
|
+
}, 10) // start after 10 msec
|
|
965
|
+
} else
|
|
966
|
+
target.statusPoll = false
|
|
967
|
+
}
|
|
968
|
+
|
|
925
969
|
// vsiteRefresh
|
|
926
970
|
//
|
|
927
971
|
// The vsite upon which we are based has changed.
|
|
@@ -969,6 +1013,11 @@ closure termInstallVirtualWatcher(track, naancont) {
|
|
|
969
1013
|
if target
|
|
970
1014
|
target.updateController()
|
|
971
1015
|
}
|
|
1016
|
+
else if msg.op == "VsiteVisibilityChange" {
|
|
1017
|
+
target = findIDEtarget(track, msg.name, "NaanVsite", msg.naancont)
|
|
1018
|
+
if target
|
|
1019
|
+
target.setCheckStatus(msg.hidden, msg.window)
|
|
1020
|
+
}
|
|
972
1021
|
}
|
|
973
1022
|
|
|
974
1023
|
require("../running/executors.nlg").TaskOnMessageHook(watchVsites)
|
|
@@ -182,53 +182,6 @@ function JsonStringify(data) {
|
|
|
182
182
|
}
|
|
183
183
|
};
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
/*
|
|
187
|
-
* JsLoadScript
|
|
188
|
-
*
|
|
189
|
-
* Load the specified script, or return its main entry point if already loaded. This blocks the
|
|
190
|
-
* caller until the script load completes. The return value is false if an error occurred.
|
|
191
|
-
*
|
|
192
|
-
*/
|
|
193
|
-
|
|
194
|
-
jsScripts = { }; // script values become false on reload
|
|
195
|
-
|
|
196
|
-
closure JsLoadScript(libpath, globalID, local savens, hostpath, pending, scriptTag) {
|
|
197
|
-
global(jsScripts, JSpath, js)
|
|
198
|
-
if jsScripts[libpath]
|
|
199
|
-
return // already loaded
|
|
200
|
-
savens = nsactive()
|
|
201
|
-
hostpath = js.w.location.origin.concat(JSpath.join(JSpath.dirname(js.w.location.pathname), libpath))
|
|
202
|
-
if js.s.importScripts && tostring(js.s.importScripts) == "[Function importScripts]" {
|
|
203
|
-
try {
|
|
204
|
-
js.s.importScripts(hostpath) // load in worker context
|
|
205
|
-
jsScripts[libpath] = js.s[globalID]
|
|
206
|
-
} catch {
|
|
207
|
-
debuglog("JsLoadScript:", libpath, "failed", exception)
|
|
208
|
-
js.s.console.log("JsLoadScript:", libpath, "failed", exception) // ensure visibility in JS console
|
|
209
|
-
}
|
|
210
|
-
} else if js.w { // load in browser context
|
|
211
|
-
pending = new(nonce)
|
|
212
|
-
scriptTag = js.w.document.createElement("script")
|
|
213
|
-
scriptTag.src = hostpath.concat(requireQuery())
|
|
214
|
-
scriptTag.onload = function (event) {
|
|
215
|
-
jsScripts[libpath] = js.w[globalID]
|
|
216
|
-
pending.signal(js.w[globalID])
|
|
217
|
-
true
|
|
218
|
-
}
|
|
219
|
-
scriptTag.onerror = function (event) {
|
|
220
|
-
debuglog("JsLoadScript:", libpath, "not found")
|
|
221
|
-
pending.signal(false)
|
|
222
|
-
true
|
|
223
|
-
}
|
|
224
|
-
js.w.document.body.appendChild(scriptTag)
|
|
225
|
-
pending.wait()
|
|
226
|
-
} else if js.g
|
|
227
|
-
jsScripts[libpath] = js.r(libpath) // load in NodeJS context
|
|
228
|
-
nsactive(savens)
|
|
229
|
-
jsScripts[libpath]
|
|
230
|
-
};
|
|
231
|
-
|
|
232
185
|
|
|
233
186
|
/*
|
|
234
187
|
* LoadComponentOnDemand
|
|
@@ -365,7 +318,7 @@ Uint8ArrayFromString = false;
|
|
|
365
318
|
|
|
366
319
|
function comrInit(local manifest) {
|
|
367
320
|
manifest = `(EncodeQuery, DecodeQuery, ContentTypeFromFileExt, UUID, VersionCheck, JsonParse,
|
|
368
|
-
JsonStringify,
|
|
321
|
+
JsonStringify, LoadComponentOnDemand, LiveExport, comrInit)
|
|
369
322
|
|
|
370
323
|
Naan.module.build(module.id, "common", closure(modobj, compobj) {
|
|
371
324
|
compobj.manifest = manifest
|
|
@@ -373,8 +326,9 @@ function comrInit(local manifest) {
|
|
|
373
326
|
modobj.exports.DecodeQuery = DecodeQuery
|
|
374
327
|
modobj.exports.ContentTypeFromFileExt = ContentTypeFromFileExt
|
|
375
328
|
modobj.exports.UUID = UUID
|
|
376
|
-
modobj.exports.JsLoadScript = JsLoadScript
|
|
377
329
|
modobj.exports.LoadComponentOnDemand = LoadComponentOnDemand
|
|
330
|
+
letimport(module.owner.list.Util.exports.JsLoadScript) // use the Util version
|
|
331
|
+
modobj.exports.JsLoadScript = JsLoadScript
|
|
378
332
|
modobj.exports.LiveExport = LiveExport // allow others to create export updaters
|
|
379
333
|
updateExports = LiveExport() // export LiveImport() so we can update
|
|
380
334
|
|
|
@@ -481,13 +435,12 @@ function comrInit(local manifest) {
|
|
|
481
435
|
}
|
|
482
436
|
//
|
|
483
437
|
// MD5 functions
|
|
484
|
-
if symbol(NideBuild) { // execute if we are not building
|
|
485
|
-
JsLoadScript("frameworks/browser/spark-md5/spark-md5.min.js", "SparkMD5")
|
|
486
|
-
}
|
|
487
438
|
//
|
|
488
439
|
// hasMD5 in hex
|
|
489
440
|
HashMD5 = function browserMD5(data, raw) {
|
|
490
441
|
data = binaryFrom(data)
|
|
442
|
+
if !wsg.SparkMD5
|
|
443
|
+
JsLoadScript("frameworks/browser/spark-md5/spark-md5.min.js", "SparkMD5")
|
|
491
444
|
if xobject(data)
|
|
492
445
|
wsg.SparkMD5.ArrayBuffer.hash(data, raw)
|
|
493
446
|
else
|
|
@@ -230,17 +230,26 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
230
230
|
// <substitute text, one or more lines>
|
|
231
231
|
// [File EOF]
|
|
232
232
|
//
|
|
233
|
+
// Special line starts:
|
|
234
|
+
// # comment
|
|
235
|
+
// \# line starts with #
|
|
236
|
+
// \\ line starts with \
|
|
237
|
+
//
|
|
233
238
|
// Note that the newlines before and after the substitute text are not included. This returns a
|
|
234
239
|
// a dictionary of variables and replacement text. The defs argument is optional, and defines a
|
|
235
240
|
// substitution dictionary applied to the replacement text defined in this file.
|
|
236
241
|
//
|
|
237
|
-
function parseSubstitutionLines(lines, defs,
|
|
242
|
+
function parseSubstitutionLines(lines, defs,
|
|
243
|
+
local ignoregex, escapex, varegex, line, find, subs, curvar, sub) {
|
|
238
244
|
subs = { }
|
|
239
245
|
ignoregex = RegExp("^#")
|
|
246
|
+
escapex = RegExp("^\\\\(#|\\\\)")
|
|
240
247
|
varegex = RegExp("^[$]([^$]+)[$]")
|
|
241
248
|
for line in lines {
|
|
242
|
-
if ignoregex.
|
|
243
|
-
continue
|
|
249
|
+
if ignoregex.test(line)
|
|
250
|
+
continue // comment
|
|
251
|
+
if escapex.test(line)
|
|
252
|
+
line = line.slice(1) // not-a-comment escape
|
|
244
253
|
if find = line.match(varegex) {
|
|
245
254
|
curvar = find[1]
|
|
246
255
|
subs[curvar] = ""
|
|
@@ -271,6 +280,11 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
271
280
|
// <substitute text, one or more lines>
|
|
272
281
|
// [File EOF]
|
|
273
282
|
//
|
|
283
|
+
// Special line starts:
|
|
284
|
+
// # comment
|
|
285
|
+
// \# line starts with #
|
|
286
|
+
// \\ line starts with \
|
|
287
|
+
//
|
|
274
288
|
// Note that the newlines before and after the substitute text are not included. This returns a
|
|
275
289
|
// standard `(error, subs) result tuple where subs is a dictionary of variables and replacement
|
|
276
290
|
// text. The defs argument is optional, and defines a substitution dictionary applied to the
|
|
@@ -293,7 +307,7 @@ closure Builder(rules, operation, fs, srcpath, destpath, track, local build, gro
|
|
|
293
307
|
//
|
|
294
308
|
function applySubstitutions(text, subs, local subbed) {
|
|
295
309
|
subbed = { }
|
|
296
|
-
list(text.replace(RegExp("[$][
|
|
310
|
+
list(text.replace(RegExp("[$][^$\\s]+[$]", "g"), function(match, local subst) {
|
|
297
311
|
subst = subs[match.slice(1,-1)]
|
|
298
312
|
if subst {
|
|
299
313
|
subbed[match] = true
|
|
@@ -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.4.
|
|
299
|
+
* NaanIDE_version.txt - [default] substitution file defining 1.4.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
|
|
@@ -563,6 +563,17 @@ closure projConfig(projman, where, projID, local procon, fs, configpath) {
|
|
|
563
563
|
}
|
|
564
564
|
}
|
|
565
565
|
|
|
566
|
+
// persist
|
|
567
|
+
//
|
|
568
|
+
// Return a dictionary for persistent local project state, like view configuration.
|
|
569
|
+
//
|
|
570
|
+
procon.persist = function persist() {
|
|
571
|
+
if procon.localDict.persist {
|
|
572
|
+
}
|
|
573
|
+
else
|
|
574
|
+
procon.localDict.persist = {}
|
|
575
|
+
}
|
|
576
|
+
|
|
566
577
|
// buildrules
|
|
567
578
|
//
|
|
568
579
|
// Get the build rules for the named stage, reloading the project configuration if changed.
|
|
@@ -71,10 +71,14 @@ closure ExecutorBase(track, type, name, local exec) {
|
|
|
71
71
|
|
|
72
72
|
// execSetStatus
|
|
73
73
|
//
|
|
74
|
-
// Received a status update from the instance.
|
|
74
|
+
// Received a status update from the instance. This makes a copy of the specified dictionary for
|
|
75
|
+
// garbage collection, because if we store the status from a separate vsite window then it can
|
|
76
|
+
// cause the main window to retain a vsite window after it's closed. The last status update sets
|
|
77
|
+
// an object in the context of the detached window, and then it never gets updated until the
|
|
78
|
+
// executor goes away. That doesn't always happen as soon as you think.
|
|
75
79
|
//
|
|
76
80
|
exec.execSetStatus = function execSetStatus(status) {
|
|
77
|
-
exec.xstatus = status
|
|
81
|
+
exec.xstatus = new(status) // for GC (!)
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
// execFailed
|
|
@@ -218,7 +222,7 @@ closure ExecutorContext(exec, state, local context, coder, util) {
|
|
|
218
222
|
else if result.1.result
|
|
219
223
|
list(false, caar(util.pkgLoad(result.1.result, {
|
|
220
224
|
localroots: false
|
|
221
|
-
intern:
|
|
225
|
+
intern: "symbols"
|
|
222
226
|
execute: false
|
|
223
227
|
objectDecoder: coder.decodeObject
|
|
224
228
|
})))
|
|
@@ -207,12 +207,26 @@ closure packageCoder(evalf, local coder) {
|
|
|
207
207
|
quote(x@\.tostring = function() { "{proxy ${nn}}" }),
|
|
208
208
|
quote(x@\.undefined = closure undef args {
|
|
209
209
|
let (result) {
|
|
210
|
-
result = evalf(list(`\.
|
|
210
|
+
result = evalf(list(`\.invoke\-method, objectID, args))
|
|
211
211
|
if result.0
|
|
212
212
|
throw("remoting failure: ${ErrorString(result.0)}")
|
|
213
213
|
else
|
|
214
214
|
result.1
|
|
215
215
|
} ()
|
|
216
|
+
}),
|
|
217
|
+
quote(x@\.\.undefined = function (key, local result) {
|
|
218
|
+
result = evalf(list(`\.invoke\-method, objectID, list(`\.\.undefined, key)))
|
|
219
|
+
if result.0
|
|
220
|
+
throw("remoting failure: ${ErrorString(result.0)}")
|
|
221
|
+
else
|
|
222
|
+
result.1
|
|
223
|
+
}),
|
|
224
|
+
quote(x@\.\=undefined = function (key, value, local result) {
|
|
225
|
+
result = evalf(list(`\.invoke\-method, objectID, list(`\.\=undefined, key, value)))
|
|
226
|
+
if result.0
|
|
227
|
+
throw("remoting failure: ${ErrorString(result.0)}")
|
|
228
|
+
else
|
|
229
|
+
result.1
|
|
216
230
|
}), `x)))
|
|
217
231
|
} (ident.name, ident.objectID)
|
|
218
232
|
coder.wmapEncoding[obj] = ident
|
|
@@ -225,11 +239,17 @@ closure packageCoder(evalf, local coder) {
|
|
|
225
239
|
//
|
|
226
240
|
// Invoke a local object method from the remote proxy, returning a result tuple.
|
|
227
241
|
//
|
|
228
|
-
coder.invokeMethod = closure invokeMethod(objectID, args, local obj) {
|
|
242
|
+
coder.invokeMethod = closure invokeMethod(objectID, args, local obj, method) {
|
|
229
243
|
obj = coder.mapDecoding[objectID]
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
244
|
+
method = pop(args)
|
|
245
|
+
if obj {
|
|
246
|
+
if method == `\.\.undefined
|
|
247
|
+
obj[args.0]
|
|
248
|
+
else if method == `\.\=undefined
|
|
249
|
+
obj[args.0] = args.1
|
|
250
|
+
else
|
|
251
|
+
eval(list(deref, obj, method, args))
|
|
252
|
+
} else
|
|
233
253
|
throw("remoting error: object ${objectID} not found")
|
|
234
254
|
}
|
|
235
255
|
|
|
@@ -88,7 +88,7 @@ closure TaskDispatcher(replier, local contexts, gohome, coder, util) {
|
|
|
88
88
|
objectDecoder: coder.decodeObject
|
|
89
89
|
})
|
|
90
90
|
expr = caar(expr)
|
|
91
|
-
if expr.0 == `\.
|
|
91
|
+
if expr.0 == `\.invoke\-method
|
|
92
92
|
expr = coder.invokeMethod(expr.1, expr.2) // object method, args
|
|
93
93
|
else
|
|
94
94
|
expr = evalactive(expr) // evaluate expression
|
|
@@ -529,7 +529,7 @@ closure DbConnector(psm, local connClassID, connector, watch) {
|
|
|
529
529
|
|
|
530
530
|
// localDBcred
|
|
531
531
|
//
|
|
532
|
-
// True iff the specified credential dictionary is for a local
|
|
532
|
+
// True iff the specified credential dictionary is for a local DB.
|
|
533
533
|
function localDBcred(creds) {
|
|
534
534
|
!creds.authName && creds.urlName.indexOf("://") < 0
|
|
535
535
|
}
|
|
@@ -722,8 +722,13 @@ closure DbConnector(psm, local connClassID, connector, watch) {
|
|
|
722
722
|
if creds {
|
|
723
723
|
if creds.label
|
|
724
724
|
info.name = creds.label
|
|
725
|
-
if localDBcred(creds)
|
|
726
|
-
|
|
725
|
+
if localDBcred(creds) {
|
|
726
|
+
if js.w
|
|
727
|
+
info.type = "PouchDB-browser"
|
|
728
|
+
else
|
|
729
|
+
info.type = "PouchDB-filesystem"
|
|
730
|
+
} else
|
|
731
|
+
info.type = "PouchDB-network"
|
|
727
732
|
if creds.locked
|
|
728
733
|
info.locked = true
|
|
729
734
|
if creds.hidden
|
|
@@ -715,8 +715,8 @@ closure FSview(table, rootpath, local view) {
|
|
|
715
715
|
finfo.type = "directory"
|
|
716
716
|
} else if !finfo.type
|
|
717
717
|
finfo.type = "file" // everything is a file in UNIX
|
|
718
|
-
finfo.md5 = item.doc._md5 || undefined
|
|
719
|
-
finfo.length = item.doc._length || item.doc.length || undefined
|
|
718
|
+
finfo.md5 = item._md5 || item.doc._md5 || undefined
|
|
719
|
+
finfo.length = item._length || item.doc._length || item.doc.length || undefined
|
|
720
720
|
if item.key.length > offset // not the directory itself
|
|
721
721
|
dirdict.children.push({
|
|
722
722
|
name: name
|