@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.
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * column positioning: // // !
8
8
  *
9
- * Copyright (c) 2019-2022 by Richard C. Zulch
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
- psmRemote(path, "shellOpen", { args: args }, false, callback)
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, nicc, local connClassID, connector, watch) {
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.api = nicc.api
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 filesystem"
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 = nicc.api.url
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.api
624
- else
625
- api = MakeNideAPIclient(creds.urlName, creds.authSecret) // API to remote NodeJS filesystem
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 == "NideExecutor"
630
- require("../browser/terminals.nlg").TermHost(nicc.track, api, args.0, args.1) // host executor, args: (name, workerID)
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(nicc, dbname, local importPSM) {
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, nicc) // HostFS access
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
@@ -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 >= 300 {
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 filesystem"
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"
@@ -1195,7 +1195,8 @@ closure Builder(rules, operation, fs, srcpath, destpath, local build, group, new
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}", "Run-${build.buildnum}", {
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)
@@ -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.0+1 etc.
299
+ * NaanIDE_version.txt - [default] substitution file defining 1.2.0+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
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * column positioning: // // !
7
7
  *
8
- * Copyright (c) 2020-2023 by Richard C. Zulch
8
+ * Copyright (c) 2020-2024 by Richard C. Zulch
9
9
  *
10
10
  */
11
11
 
@@ -18,6 +18,7 @@
18
18
  */
19
19
 
20
20
  closure ExecutorBase(track, type, name, local exec) {
21
+ global()
21
22
  exec = new(object, this)
22
23
  exec.type = type
23
24
  exec.name = name
@@ -76,7 +77,7 @@ closure ExecutorBase(track, type, name, local exec) {
76
77
  // execClosed
77
78
  // Note that the connection has closed, so signal all the waiters.
78
79
 
79
- exec.execClosed = closure execClosed(error, local xid) {
80
+ exec.execClosed = closure execClosed(error, local xid, pending) {
80
81
  for `(xid, pending) in exec.pending {
81
82
  pending.signal(list(error))
82
83
  pending[xid] = undefined
@@ -135,6 +136,7 @@ closure ExecutorBase(track, type, name, local exec) {
135
136
  */
136
137
 
137
138
  closure ExecutorContext(exec, contextID, local context, util) {
139
+ global(apply)
138
140
  context = new(object, this)
139
141
  util = modlist().Util.exports
140
142
 
@@ -212,12 +214,13 @@ closure ExecutorContext(exec, contextID, local context, util) {
212
214
  applyf(eval(proc), eargs)
213
215
  } (pop(args), reverse(args))
214
216
  }
217
+
215
218
  // rpc
216
219
  // Execute a remote procedure call without package translation, to reduce overhead. This will not
217
220
  // properly transfer Naan-specific types like symbols, and the results will be native JavaScript.
218
221
  // The procedure must be specified as a symbol or string.
219
222
 
220
- context.rpc = closure rpc(proc, args, local data, result) {
223
+ context.rpc = closure rpc(proc, args, local data, pending, result) {
221
224
  data = {
222
225
  contextID: contextID
223
226
  proc: proc
@@ -268,6 +271,7 @@ closure ExecutorContext(exec, contextID, local context, util) {
268
271
  */
269
272
 
270
273
  closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, crValue) {
274
+ global()
271
275
  maxcount = options.maxcount
272
276
  if !maxcount
273
277
  maxcount = 4 // default is 4 workers
@@ -294,7 +298,7 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
294
298
  return (false)
295
299
  parallel.workers[workdex] = false // reserve our spot
296
300
  name = basename.concat("-", workdex+1)
297
- worker = App.nide.track.spawn("Local", name, "ExecutorParallel")
301
+ worker = App.nide.track.spawn("Local", name, "ExecutorParallel") // ### App.nide.track.spawn may not exist
298
302
  if worker.0 { // ### wasting space on workers list
299
303
  debuglog("execParallel: cannot spawn worker:", ErrorString(worker.0))
300
304
  return (false)
@@ -444,6 +448,7 @@ closure ExecutorParallel(options, local maxcount, basename, parallel, exqueue, c
444
448
  */
445
449
 
446
450
  closure ExecutorTracker(local xtrak) {
451
+ global()
447
452
  xtrak = new(object, this)
448
453
  xtrak.instances = []
449
454
  xtrak.watchers = []
@@ -494,7 +499,7 @@ closure ExecutorTracker(local xtrak) {
494
499
  // enumlist
495
500
  // Enumerate the list of executors.
496
501
 
497
- xtrak.enumlist = function enumlist(local results) {
502
+ xtrak.enumlist = function enumlist(local results, instance) {
498
503
  results = []
499
504
  for instance in xtrak.instances
500
505
  results.push(instance.executor)
@@ -552,6 +557,7 @@ closure ExecutorTracker(local xtrak) {
552
557
  */
553
558
 
554
559
  closure execLambda(track, url, name, workerID, local target, nlregex, clientID, serverID) {
560
+ global()
555
561
  target = ExecutorBase(track, "Lambda", name)
556
562
  clientID = "DebugWorkers"
557
563
  serverID = "Workers"
@@ -800,7 +806,6 @@ closure execLambda(track, url, name, workerID, local target, nlregex, clientID,
800
806
  */
801
807
 
802
808
  function execInit(local manifest) {
803
-
804
809
  manifest = `(ExecutorBase, ExecutorContext, ExecutorParallel, ExecutorTracker, execLambda, execInit)
805
810
 
806
811
  Naan.module.build(module.id, "executors", function(modobj, compobj) {
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * column positioning: // // !
7
7
  *
8
- * Copyright (c) 2021-2023 by Richard C. Zulch
8
+ * Copyright (c) 2021-2024 by Richard C. Zulch
9
9
  *
10
10
  */
11
11
 
@@ -20,10 +20,11 @@
20
20
  */
21
21
 
22
22
  closure TaskDispatcher(replier, local contexts, gohome, util) {
23
+ global()
23
24
  contexts = { }
24
25
  gohome = makeActivator()
25
26
  util = modlist().Util.exports
26
- closure(data, local reply, restorens, expr, roots, proc, args, result) {
27
+ closure(data, local reply, restorens, context, expr, roots, proc, args, result) {
27
28
  reply = {
28
29
  xmsg: "error"
29
30
  xid: data.xid
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  closure MakePSMutil(fs, local util) {
23
+ global()
23
24
  util = new(object, this)
24
25
  util.fs = fs
25
26
 
@@ -310,7 +311,7 @@ closure MakePSMutil(fs, local util) {
310
311
  //
311
312
  if options.erase {
312
313
  asyncArray(keys(folders).toarray, 10, closure eraser(destpath
313
- local error, outfolder, folder, namesin, removes, delopt) {
314
+ local error, outfolder, folder, namesin, node, removes, delopt) {
314
315
  `(error, outfolder) = outfs.dirList(destpath) // existing files in our destination
315
316
  if error
316
317
  return
@@ -45,6 +45,14 @@ closure FSview(table, rootpath, local view) {
45
45
  view.rootpath = rootpath
46
46
  view.path = JSpath.posix // for view.path.join(), etc.
47
47
 
48
+ // dirPath
49
+ //
50
+ // True iff the path is a dirpath. If the path is empty this checks the rootpath.
51
+
52
+ function dirPath(path) {
53
+ path.slice(-1) == "/" || path == "" && rootpath.slice(-1) == "/"
54
+ }
55
+
48
56
  // dirName
49
57
  //
50
58
  // Return the directory portion of the specified path.
@@ -163,7 +171,7 @@ closure FSview(table, rootpath, local view) {
163
171
  else
164
172
  proc = view.table.get
165
173
  `(error, data) = proc(path)
166
- if error && error.status == 404 && path.slice(-1) != "/"
174
+ if error && error.status == 404 && !dirPath(path)
167
175
  `(error, data) = proc(path.concat("/"))
168
176
  callback(error, data)
169
177
  }
@@ -200,7 +208,7 @@ closure FSview(table, rootpath, local view) {
200
208
  birthtime: nowstr
201
209
  }
202
210
  }
203
- if path.slice(-1) == "/"
211
+ if dirPath(path)
204
212
  metadata.finfo.type = "directory"
205
213
  else
206
214
  metadata.finfo.type = "file"
@@ -268,7 +276,7 @@ closure FSview(table, rootpath, local view) {
268
276
  return (asyncResult(callback, false, { created: false })) // root always already exists
269
277
  if checkPath(path, callback)
270
278
  return
271
- if path.slice(-1) != "/"
279
+ if !dirPath(path)
272
280
  path = path.concat("/")
273
281
  view.table.get(path, function(error, data, local pathdirs, buildpath, item) {
274
282
  if !error
@@ -286,7 +294,7 @@ closure FSview(table, rootpath, local view) {
286
294
  name: "conflict"
287
295
  path: buildpath
288
296
  })))
289
- if buildpath.slice(-1) != "/"
297
+ if !dirPath(buildpath)
290
298
  buildpath = buildpath.concat("/")
291
299
  `(error, data) = view.table.head(buildpath) // get desired directory
292
300
  if error.status == 404
@@ -311,7 +319,7 @@ closure FSview(table, rootpath, local view) {
311
319
  if dest.indexOf("/") < 0
312
320
  newpath = dirName(srcpath).concat(dest) // renaming within same directory
313
321
  else {
314
- if dest.slice(-1) == "/" // moving to new directory location:
322
+ if dirPath(dest) // moving to new directory location:
315
323
  newpath = dest.concat(baseName(srcpath)) // new path is new pathname
316
324
  else { // moving and renaming:
317
325
  newpath = dest // new path is new pathname
@@ -361,7 +369,7 @@ closure FSview(table, rootpath, local view) {
361
369
  //
362
370
  closure copyDirectory(srcpath, dest, options,
363
371
  local error, nodes, data, destpath, errors, docpath, newpath, srcroot, item) {
364
- if srcpath.slice(-1) != "/"
372
+ if !dirPath(srcpath)
365
373
  srcpath = srcpath.concat("/") // normalize source as directory
366
374
  `(error, nodes) = view.table.records({ prefix: srcpath }) // each item has key/_id/_rev, not doc
367
375
  if error
@@ -380,13 +388,13 @@ closure FSview(table, rootpath, local view) {
380
388
  destpath = dirName(srcpath).concat(dest) // new directory name in same parent directory
381
389
  dest = dirName(srcpath) } // dest is new parent pathname
382
390
  else {
383
- if dest.slice(-1) == "/"
391
+ if dirPath(dest)
384
392
  destpath = dest.concat(baseName(srcpath)) // same name; new location
385
393
  else {
386
394
  destpath = dest // new full pathname
387
395
  dest = dirName(dest) } // dest is new parent pathname
388
396
  }
389
- if destpath != "" && destpath.slice(-1) != "/"
397
+ if destpath != "" && !dirPath(destpath)
390
398
  destpath = destpath.concat("/") // get actual path of new directory
391
399
  //
392
400
  // Change srcpath to destpath for all records. Note that dest is the name of our new parent
@@ -489,13 +497,13 @@ closure FSview(table, rootpath, local view) {
489
497
  finfo.length = data.length
490
498
  else if data._length
491
499
  finfo.length = data._length
492
- if finfo.length
500
+ if dirPath(path)
501
+ finfo.type = "directory"
502
+ else if finfo.length
493
503
  finfo.type = "file" }
494
504
  else if path == "" {
495
505
  error = false // we were asked for info on superoot
496
506
  finfo = {
497
- md5: HashMD5("")
498
- length: 0
499
507
  type: "directory"
500
508
  } }
501
509
  callback(error, finfo)
@@ -553,7 +561,7 @@ closure FSview(table, rootpath, local view) {
553
561
  return
554
562
  if !content
555
563
  return (asyncResult(callback, Error("content required")))
556
- if path.slice(-1) == "/"
564
+ if dirPath(path)
557
565
  return (asyncResult(callback, Error("cannot write to a directory", { path: path })))
558
566
  if !validName(path, true)
559
567
  return (asyncResult(callback, Error("invalid filename", { path: path })))
@@ -631,7 +639,7 @@ closure FSview(table, rootpath, local view) {
631
639
  name: "forbidden"
632
640
  path: path
633
641
  })))
634
- if path.slice(-1) != "/"
642
+ if !dirPath(path)
635
643
  path = path.concat("/") // avoid deleting longer filenames with same parent and prefix
636
644
  `(error, data) = dbDirRecords(path, true)
637
645
  if error
@@ -739,6 +747,8 @@ closure FSview(table, rootpath, local view) {
739
747
  prefix: path
740
748
  deep: true
741
749
  }
750
+ if name == "" && rootpath != ""
751
+ name = rootpath.split("/").slice(0,-1).pop() || ""
742
752
  treedict = {
743
753
  name: name
744
754
  data: {
@@ -526,7 +526,7 @@ exports.NaanControllerWeb = function() {
526
526
  statedoc.curversion = kStateCurrentVersion;
527
527
  statedoc.firstver = kStateFirstVersion;
528
528
  statedoc.licensee = "MIT-License";
529
- statedoc.verstring = "1.1.0+1";
529
+ statedoc.verstring = "1.2.0+1";
530
530
  statedoc.date = new Date().toISOString();
531
531
  statedoc.prefs = prefs;
532
532
  statedoc.naan = naanlib.saveState(false); // true to optimize, which is a bit slower
@@ -544,7 +544,7 @@ exports.NaanControllerWeb = function() {
544
544
  || statedoc.firstver > kStateCurrentVersion
545
545
  || statedoc.curversion < kStateFirstVersion
546
546
  || statedoc.licensee != "MIT-License"
547
- || statedoc.verstring != "1.1.0+1")
547
+ || statedoc.verstring != "1.2.0+1")
548
548
  {
549
549
  localStorage.removeItem("NaanState_Hosted");
550
550
  return (false);
@@ -603,7 +603,7 @@ exports.NaanControllerWeb = function() {
603
603
  op: "VsiteOpen",
604
604
  name: vsiteName,
605
605
  naancont: contSelf,
606
- title: vsiteName + " 1.1.0+1"
606
+ title: vsiteName + " 1.2.0+1"
607
607
  });
608
608
  }
609
609
  } catch (e) {
@@ -617,7 +617,7 @@ exports.NaanControllerWeb = function() {
617
617
  op: "VsiteClose",
618
618
  name: vsiteName,
619
619
  naancont: contSelf,
620
- title: vsiteName + " 1.1.0+1"
620
+ title: vsiteName + " 1.2.0+1"
621
621
  });
622
622
  termTextOut("\x1b[90m\x1b[3m".concat("\nwindow closed", "\x1b[0m\n"));
623
623
  }
@@ -632,8 +632,8 @@ exports.NaanControllerWeb = function() {
632
632
  naanlib.banner();
633
633
  var hostpath = naanlib.js.r("path").dirname(window.location.href);
634
634
  naanlib.start({
635
- cmd: 'App.version = "1.1.0+1";;\r\n'
636
- + 'App.cache = "241e1d15dfb0de008135e2de76886ccc";;\r\n'
635
+ cmd: 'App.version = "1.2.0+1";;\r\n'
636
+ + 'App.cache = "9659b00cb48debdc9726030789336e68";;\r\n'
637
637
  + 'Naan.module.requireQuery({ naanver: App.cache });;\r\n'
638
638
  + 'Naan.module.webparse("naan_init.nlg", "' + hostpath + '", { naanver: App.cache });;\r\n'
639
639
  });