@naanlang/naan 1.0.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.
Files changed (98) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +46 -0
  3. package/dist/env_web.js +431 -0
  4. package/dist/naan.min.js +73 -0
  5. package/frameworks/browser/browser.nlg +30 -0
  6. package/frameworks/browser/pouchdb/pouchdb.min.js +7 -0
  7. package/frameworks/browser/spark-md5/spark-md5.min.js +1 -0
  8. package/frameworks/browser/sworker.js +192 -0
  9. package/frameworks/browser/terminals.nlg +787 -0
  10. package/frameworks/browser/workers.nlg +386 -0
  11. package/frameworks/client/apiclient.nlg +183 -0
  12. package/frameworks/client/client.nlg +29 -0
  13. package/frameworks/client/psm_client.nlg +572 -0
  14. package/frameworks/common/common.nlg +464 -0
  15. package/frameworks/common/preferences.nlg +131 -0
  16. package/frameworks/common/repltools.nlg +100 -0
  17. package/frameworks/common/watching.nlg +97 -0
  18. package/frameworks/node/apiserver.nlg +399 -0
  19. package/frameworks/node/filesystem.nlg +1012 -0
  20. package/frameworks/node/gitter.nlg +234 -0
  21. package/frameworks/node/node.nlg +81 -0
  22. package/frameworks/node/psm_server.nlg +465 -0
  23. package/frameworks/node/worker.nlg +560 -0
  24. package/frameworks/project/build.nlg +1229 -0
  25. package/frameworks/project/jszip.js +30 -0
  26. package/frameworks/project/jszip.nlg +87 -0
  27. package/frameworks/project/proj_cliser.nlg +139 -0
  28. package/frameworks/project/proj_console.nlg +137 -0
  29. package/frameworks/project/proj_folder.nlg +143 -0
  30. package/frameworks/project/proj_lambda.nlg +137 -0
  31. package/frameworks/project/proj_static.nlg +138 -0
  32. package/frameworks/project/project.nlg +29 -0
  33. package/frameworks/project/projects.nlg +587 -0
  34. package/frameworks/project/uglifyjs.js +1 -0
  35. package/frameworks/project/uglifyjs.nlg +79 -0
  36. package/frameworks/running/debugcom.nlg +163 -0
  37. package/frameworks/running/debugnub.nlg +565 -0
  38. package/frameworks/running/debugutil.nlg +510 -0
  39. package/frameworks/running/executors.nlg +767 -0
  40. package/frameworks/running/running.nlg +151 -0
  41. package/frameworks/running/sourcecode.nlg +346 -0
  42. package/frameworks/running/taskexec.nlg +196 -0
  43. package/frameworks/storage/dbt_pouch.nlg +773 -0
  44. package/frameworks/storage/file_manager.nlg +772 -0
  45. package/frameworks/storage/psm.nlg +326 -0
  46. package/frameworks/storage/psm_dbtables.nlg +814 -0
  47. package/frameworks/storage/resources.nlg +445 -0
  48. package/frameworks/storage/storage.nlg +52 -0
  49. package/lib/browser/env_web.js +431 -0
  50. package/lib/browser/env_webworker.js +146 -0
  51. package/lib/browser/require.js +1653 -0
  52. package/lib/core/naanlib.js +73 -0
  53. package/lib/env_node.js +282 -0
  54. package/lib/env_nodeworker.js +165 -0
  55. package/lib/node_repl.js +25 -0
  56. package/lib/node_repl_init.nlg +52 -0
  57. package/package.json +13 -0
  58. package/plugins/gitClient/clientops.nlg +317 -0
  59. package/plugins/gitClient/gitClient.nlg +63 -0
  60. package/plugins/gitClient/gitutils.nlg +1331 -0
  61. package/plugins/gitClient/minimatch.js +945 -0
  62. package/plugins/gitClient/minimatch_license.txt +15 -0
  63. package/plugins/gitClient/minimatch_readme.md +208 -0
  64. package/plugins/nodeLib/nodeLib.nlg +26 -0
  65. package/plugins/nodeLib/node_cp.nlg +65 -0
  66. package/plugins/nodeLib/node_fs.nlg +137 -0
  67. package/plugins/nodeLib/node_https.nlg +172 -0
  68. package/plugins/nodeLib/node_util.nlg +180 -0
  69. package/plugins/serviceAws/aws/aws-sdk.min.js +88 -0
  70. package/plugins/serviceAws/aws/lambda_rest_index.js +122 -0
  71. package/plugins/serviceAws/aws/lambda_rest_init.nlg +58 -0
  72. package/plugins/serviceAws/aws/lambda_ws_index.js +498 -0
  73. package/plugins/serviceAws/aws/lambda_ws_init.nlg +49 -0
  74. package/plugins/serviceAws/aws_cloudwatchlogs.nlg +122 -0
  75. package/plugins/serviceAws/aws_cognito.nlg +76 -0
  76. package/plugins/serviceAws/aws_dynamo.nlg +509 -0
  77. package/plugins/serviceAws/aws_lambda.nlg +95 -0
  78. package/plugins/serviceAws/aws_s3.nlg +134 -0
  79. package/plugins/serviceAws/aws_utils.nlg +86 -0
  80. package/plugins/serviceAws/dbt_aws.nlg +769 -0
  81. package/plugins/serviceAws/lambda_naan_control.nlg +175 -0
  82. package/plugins/serviceAws/psm_aws.nlg +258 -0
  83. package/plugins/serviceAws/serviceAws.nlg +38 -0
  84. package/plugins/serviceGitHub/gitops.nlg +522 -0
  85. package/plugins/serviceGitHub/psm_github.nlg +205 -0
  86. package/plugins/serviceGitHub/serviceGitHub.nlg +65 -0
  87. package/plugins/serviceGitLab/gitops.nlg +528 -0
  88. package/plugins/serviceGitLab/psm_gitlab.nlg +205 -0
  89. package/plugins/serviceGitLab/serviceGitLab.nlg +65 -0
  90. package/test/harness.nlg +312 -0
  91. package/test/node_test.js +33 -0
  92. package/test/test_01_core.nlg +768 -0
  93. package/test/test_02_context.nlg +269 -0
  94. package/test/test_03_jsinterop.nlg +137 -0
  95. package/test/test_04_numerics.nlg +450 -0
  96. package/test/test_05_strings.nlg +63 -0
  97. package/test/test_06_lingoparse.nlg +500 -0
  98. package/test/test_07_lingo.nlg +623 -0
@@ -0,0 +1,787 @@
1
+ /*
2
+ * terminals.nlg
3
+ * Naanlib/frameworks/browser
4
+ *
5
+ * Terminal access to Naan executors (execution instances.)
6
+ *
7
+ * column positioning: // // !
8
+ *
9
+ * Copyright (c) 2019-2021 by Richard C. Zulch
10
+ *
11
+ */
12
+
13
+
14
+ /*
15
+ * TermHost
16
+ *
17
+ * Make a host debugger target.
18
+ *
19
+ */
20
+
21
+ closure TermHost(track, api, name, workerID, options,
22
+ local target, nlregex, clientID, serverID)
23
+ {
24
+ target = runningExecutors.ExecutorBase(track, "Host", name)
25
+ clientID = "DebugWorkers"
26
+ serverID = "Workers"
27
+ nlregex = RegExp("\\n", "g")
28
+ if !workerID
29
+ workerID = "myDebugWorker"
30
+ target.workerID = workerID
31
+ target.msgQueue = []
32
+
33
+ // connect
34
+ // Connect with the host if not already connected.
35
+ closure connect(local pending) {
36
+ if target.ws
37
+ return
38
+ target.ws = xnew(js.w.WebSocket,"ws://".concat(js.w.location.host)) // ### use api parameter
39
+ pending = new(nonce)
40
+
41
+ // onopen
42
+ // The WebSocket connection is now open.
43
+ target.ws.onopen = function onopen(e, local spawner) {
44
+ pending.signal(list(false, { ok: true }))
45
+ spawner = new(options.startup)
46
+ spawner.name = name
47
+ sendControl("spawn", spawner)
48
+ }
49
+
50
+ // onmessage
51
+ // A message was received from the worker via WebSockets.
52
+
53
+ target.ws.onmessage = function onmessage(e, message, local msg) {
54
+ try {
55
+ message = new(js.w.JSON.parse(e.data))
56
+ } catch {
57
+ if true {
58
+ debuglog("can't decode incoming ws message:", exception)
59
+ return }
60
+ }
61
+ if message.respOp == "msgout" {
62
+ msg = message.payload
63
+ if msg.id == "spawned" || msg.id == "workerlist" || msg.id == "termination"
64
+ return (hostWorkerUpdate(msg))
65
+ if msg.id != "targetout" {
66
+ if msg.id == "status"
67
+ target.lastStatus = milliseconds()
68
+ if target.msgQueue {
69
+ if msg.id != "status"
70
+ target.msgQueue.push(msg)
71
+ return } }
72
+ target.doMessage(msg) }
73
+ else if message.respOp == "error"
74
+ debuglog("worker controller error:", ErrorString(message.payload[0]))
75
+ else if message.respOp == "linked"
76
+ future(function termLinked(){
77
+ if !target.written
78
+ target.term.WriteLn("(reconnected)")
79
+ }, 1000).run()
80
+ else
81
+ debuglog("unknown host response message:", message.respOp)
82
+ }
83
+
84
+ // onerror
85
+ // An error occurred on the WebSocket connection.
86
+ target.ws.onerror = function onerror(e) {
87
+ pending.signal(list(Error("websocket failed", e)))
88
+ debuglog("ws error:", e)
89
+ }
90
+
91
+ // onclose
92
+ // The WebSocket connection was closed.
93
+ target.ws.onclose = function onclose(e) {
94
+ debuglog("ws close:", e.code, e.reason)
95
+ target.execClosed(Error("socket closed", e.code, e.reason))
96
+ target.ws = false
97
+ }
98
+
99
+ pending.wait()
100
+ }
101
+
102
+ //
103
+ // hostWorkerUpdate
104
+ //
105
+ // New workers created/discovered on this host.
106
+ //
107
+ function hostWorkerUpdate(msg, local localID) {
108
+
109
+ // findWorker
110
+ //
111
+ function findWorker(testID, local instance) {
112
+ for instance in track.instances {
113
+ if instance.executor.hostWorkerMatch(api, testID)
114
+ return (instance.executor)
115
+ }
116
+ false
117
+ }
118
+
119
+ if msg.id == "spawned" {
120
+ if !findWorker(msg.workerID)
121
+ TermHost(track, api, msg.name, msg.workerID)
122
+ }
123
+ else if msg.id == "termination"
124
+ track.delete(findWorker(msg.workerID))
125
+ else {
126
+ for localID in msg.workerIDs
127
+ if !findWorker(localID)
128
+ TermHost(track, api, localID, localID)
129
+ }
130
+ }
131
+
132
+ //
133
+ // hostWorkerMatch
134
+ //
135
+ // True iff the specified information matches us.
136
+ //
137
+ target.hostWorkerMatch = function hostWorkerMatch(testApi, testID) {
138
+ testApi === api && testID == workerID
139
+ }
140
+
141
+ //
142
+ // doMessage
143
+ //
144
+ // Process the specified undecoded message.
145
+ target.doMessage = function doMessage(msg) {
146
+ if msg.id == "textout" {
147
+ target.written = true
148
+ target.term.Write(msg.text.replace(nlregex, "\r\n")) }
149
+ else if msg.id == "debugtext" {
150
+ target.written = true
151
+ target.debugWrite(msg.text, msg.level) }
152
+ else if msg.id == "targetout"
153
+ target.execReceived(msg.data)
154
+ else if msg.id == "started"
155
+ { }
156
+ else if msg.id == "typed"
157
+ target.term.Write(msg.text.replace(nlregex, "\r\n"))
158
+ else if msg.id == "status"
159
+ target.statusCB(target, msg.status)
160
+ else if msg.id == "debugout"
161
+ target.debugger.debugData(target, msg.data)
162
+ else
163
+ debuglog("unknown host worker message:", msg.id)
164
+ }
165
+
166
+ //
167
+ // sendControl
168
+ //
169
+ // Send a message to the worker controller.
170
+
171
+ target.sendControl = function sendControl(workerOp, payload) {
172
+ target.ws.send(js.w.JSON.stringify({
173
+ clientID: clientID
174
+ serverID: serverID
175
+ workerID: target.workerID
176
+ workerOp: workerOp
177
+ payload: payload
178
+ }))
179
+ }
180
+
181
+ //
182
+ // send
183
+ //
184
+ // Send a message to the worker.
185
+
186
+ target.send = function send(msg) {
187
+ sendControl("msgin", msg)
188
+ }
189
+
190
+ //
191
+ // oninterrupt
192
+ //
193
+
194
+ function oninterrupt() {
195
+ send({ // send interrupt to worker
196
+ id: "interrupt"
197
+ })
198
+ }
199
+
200
+ //
201
+ // onreturn
202
+ //
203
+
204
+ function onreturn(local text) {
205
+ text = target.term.TakeText()
206
+ echotext(text)
207
+ send({ // send user-entered text to worker
208
+ id: "keyline",
209
+ text: text
210
+ })
211
+ }
212
+
213
+ // echotext
214
+ //
215
+ // Echo text to other terminals.
216
+
217
+ function echotext(text) {
218
+ sendControl("echo", { // send user-entered text to worker
219
+ id: "typed",
220
+ text: "\x1b[90m\x1b[3m".concat(text, "\x1b[0m\n") // dark-grey, italic
221
+ })
222
+ }
223
+
224
+ // target.KeyText
225
+ //
226
+ // Send text to the worker, with optional echo to terminal.
227
+
228
+ target.KeyText = function KeyText(text, echo) {
229
+ if echo {
230
+ target.term.WriteLn(text.trim())
231
+ echotext(text.trim())
232
+ }
233
+ send({ // send user-entered text to worker
234
+ id: "keyline",
235
+ text: text
236
+ })
237
+ }
238
+
239
+ //
240
+ // target.PostMessage
241
+ //
242
+ // Post a message to the target.
243
+ //
244
+
245
+ target.PostMessage = function PostMessage(data) {
246
+ connect()
247
+ send({ // send data to worker
248
+ id: "targetin",
249
+ data: data
250
+ })
251
+ }
252
+
253
+ //
254
+ // target.DebugCmd
255
+ //
256
+ // Post a debug command to the target.
257
+ //
258
+
259
+ target.DebugCmd = function DebugCmd(data) {
260
+ connect()
261
+ send({ // send debug command to worker
262
+ id: "debugin",
263
+ data: data
264
+ })
265
+ }
266
+
267
+ //
268
+ // target.debugWrite
269
+ //
270
+ // Write a debug message to the repl.
271
+ //
272
+
273
+ target.debugWrite = function(text, level) {
274
+ if (level >= 5)
275
+ target.term.WriteLn(text, target.term.Cyan) // cyan for builtin logging
276
+ else if (level >= 4)
277
+ target.term.WriteLn(text, target.term.Blue) // blue for Naan function logging
278
+ else if (level >= 3)
279
+ target.term.WriteLn(text, target.term.Red) // light red for warnings
280
+ else if (level >= 2)
281
+ target.term.WriteLn(text, target.term.Green) // green for Naan.debug.debuglog logging
282
+ else
283
+ target.term.WriteLn(text, target.term.Red+target.term.Bold) // heavy red for errors
284
+ }
285
+
286
+ //
287
+ // termAttach
288
+ //
289
+ // A terminal and/or debugger was attached to our instance.
290
+
291
+ target.termAttach = function termAttach(repl, db, statusCB, local msg) {
292
+ target.term = repl
293
+ target.debugger = db
294
+ target.statusCB = statusCB
295
+ if target.termSaved {
296
+ target.term.StateLoad(target.termSaved)
297
+ target.termSaved = false }
298
+ else
299
+ target.term.Reset()
300
+ target.debugger.attach(target)
301
+ while target.msgQueue.length > 0 {
302
+ for msg in target.msgQueue.splice(0) // all current messages
303
+ target.doMessage(msg)
304
+ }
305
+ target.msgQueue = false
306
+ target.term.On("interrupt", oninterrupt.proc)
307
+ target.term.On("return", onreturn.proc)
308
+ target.term.Focus()
309
+ connect() // ensure we are connected
310
+ target
311
+ }
312
+
313
+ //
314
+ // termDetach
315
+ //
316
+ // The terminal is being deattached from our instance.
317
+
318
+ target.termDetach = function termDetach(repl, db) {
319
+ target.term.On("interrupt")
320
+ target.term.On("return")
321
+ target.msgQueue = []
322
+ target.debugger.detach(target)
323
+ target.termSaved = target.term.StateSave()
324
+ target.term.Reset()
325
+ target.statusCB = false
326
+ target.debugger = false
327
+ target.term = false
328
+ }
329
+
330
+ // destroy
331
+ //
332
+ // Destroy the execution instance.
333
+
334
+ target.destroy = function destroy() {
335
+ track.delete(target)
336
+ termDetach()
337
+ sendControl("terminate", { })
338
+ target.ws.close(1000) // 1000: normal close
339
+ }
340
+
341
+ track.add(target)
342
+ connect() // connect right away to start receiving messages
343
+
344
+ // finis
345
+
346
+ list(false, target)
347
+ };
348
+
349
+
350
+ /*
351
+ * TermLocal
352
+ *
353
+ * Make a local debugger target, returning a standard (error, object) tuple.
354
+ *
355
+ */
356
+
357
+ closure TermLocal(track, name, workerID, options,
358
+ local target, nlregex)
359
+ {
360
+ if workerID == "NaanIDE" {
361
+ if !js.t
362
+ return (list(Error("Cannot access Local IDE executor")))
363
+ termInstallVirtualWatcher(track, js.t)
364
+ return (termIDE(track, name, workerID, js.t)) // connect to IDE execution instance itself
365
+ }
366
+ if not js.w.Worker
367
+ return (list(Error("Local environment does not support workers")))
368
+ if dictionary(options)
369
+ options = new(options)
370
+ else
371
+ options = { }
372
+ target = runningExecutors.ExecutorBase(track, "Local", name)
373
+ nlregex = RegExp("\\n", "g")
374
+ target.workerID = workerID
375
+ target.worker = xnew(js.w.Worker, "env_webworker.js")
376
+ target.msgQueue = []
377
+
378
+ // onmessage
379
+ // A message was received from the worker.
380
+
381
+ target.worker.onmessage = function(e, msg) {
382
+ msg = new(e.data)
383
+ if msg.id != "targetout" && msg.id != "loaded" {
384
+ if msg.id == "status"
385
+ target.lastStatus = milliseconds()
386
+ if target.msgQueue {
387
+ if msg.id != "status"
388
+ target.msgQueue.push(msg)
389
+ return } }
390
+ target.doMessage(msg)
391
+ }
392
+
393
+ // onerror
394
+ // The worker had an error.
395
+
396
+ target.worker.onerror = function(e) {
397
+ target.execClosed(Error("instance error", e.message))
398
+ }
399
+
400
+ //
401
+ // oninterrupt
402
+ //
403
+
404
+ function oninterrupt() {
405
+ target.worker.postMessage({ // send interrupt to worker
406
+ id: "interrupt"
407
+ })
408
+ }
409
+
410
+ //
411
+ // onreturn
412
+ //
413
+
414
+ function onreturn() {
415
+ target.worker.postMessage({ // send user-entered text to worker
416
+ id: "keyline",
417
+ text: target.term.TakeText()
418
+ })
419
+ }
420
+
421
+ // target.KeyText
422
+ //
423
+ // Send text to the worker, with optional echo to terminal.
424
+
425
+ target.KeyText = function KeyText(text, echo) {
426
+ if echo
427
+ target.term.WriteLn(text.trim())
428
+ target.worker.postMessage({ // send text to worker
429
+ id: "keyline",
430
+ text: text
431
+ })
432
+ }
433
+
434
+ //
435
+ // doMessage
436
+ //
437
+ // Process the specified undecoded message.
438
+
439
+ target.doMessage = function doMessage(msg) {
440
+ if msg.id == "textout"
441
+ target.term.Write(msg.text.replace(nlregex, "\r\n"))
442
+ else if msg.id == "debugtext"
443
+ target.debugWrite(msg.text, msg.level)
444
+ else if msg.id == "targetout"
445
+ target.execReceived(msg.data)
446
+ else if msg.id == "status"
447
+ target.statusCB(target, msg.status)
448
+ else if msg.id == "debugout"
449
+ target.debugger.debugData(target, msg.data)
450
+ else if msg.id == "loaded" {
451
+ if !target.started
452
+ target.worker.postMessage({
453
+ id: "start",
454
+ state: false // resume state, if we have any
455
+ altcmd: options.startup.initcmds
456
+ })
457
+ target.started = true
458
+ }
459
+ }
460
+
461
+ //
462
+ // target.DebugCmd
463
+ //
464
+ // Post a debug command to the target.
465
+ //
466
+
467
+ target.DebugCmd = function DebugCmd(data) {
468
+ target.worker.postMessage({ // send data to worker
469
+ id: "debugin"
470
+ data: data
471
+ })
472
+ }
473
+
474
+ //
475
+ // target.PostMessage
476
+ //
477
+ // Post a message to the target, if it has registered a listener.
478
+ //
479
+
480
+ target.PostMessage = function PostMessage(data) {
481
+ target.worker.postMessage({ // send data to worker
482
+ id: "targetin",
483
+ data: data
484
+ })
485
+ }
486
+
487
+ //
488
+ // target.debugWrite
489
+ //
490
+ // Write a debug message to the repl.
491
+ //
492
+
493
+ target.debugWrite = function(text, level) {
494
+ if (level >= 5)
495
+ target.term.WriteLn(text, target.term.Cyan) // cyan for builtin logging
496
+ else if (level >= 4)
497
+ target.term.WriteLn(text, target.term.Blue) // blue for Naan function logging
498
+ else if (level >= 3)
499
+ target.term.WriteLn(text, target.term.Red) // light red for warnings
500
+ else if (level >= 2)
501
+ target.term.WriteLn(text, target.term.Green) // green for Naan.debug.debuglog logging
502
+ else
503
+ target.term.WriteLn(text, target.term.Red+target.term.Bold) // heavy red for errors
504
+ }
505
+
506
+ //
507
+ // termAttach
508
+ //
509
+ // A terminal was attached to our instance.
510
+
511
+ target.termAttach = function termAttach(repl, db, statusCB, local msg) {
512
+ target.term = repl
513
+ target.debugger = db
514
+ target.statusCB = statusCB
515
+ if target.termSaved {
516
+ target.term.StateLoad(target.termSaved)
517
+ target.termSaved = false }
518
+ else
519
+ target.term.Reset()
520
+ target.debugger.attach(target)
521
+ while target.msgQueue.length > 0 {
522
+ for msg in target.msgQueue.splice(0) // all current messages
523
+ target.doMessage(msg)
524
+ }
525
+ target.msgQueue = false
526
+ target.term.On("interrupt", oninterrupt.proc)
527
+ target.term.On("return", onreturn.proc)
528
+ target.term.Focus()
529
+ target
530
+ }
531
+
532
+ //
533
+ // termDetach
534
+ //
535
+ // The terminal is being deattached from our instance.
536
+
537
+ target.termDetach = function termDetach() {
538
+ target.term.On("interrupt")
539
+ target.term.On("return")
540
+ target.msgQueue = []
541
+ target.debugger.detach(target)
542
+ target.termSaved = target.term.StateSave()
543
+ target.statusCB = false
544
+ target.debugger = false
545
+ target.term = false
546
+ }
547
+
548
+ // destroy
549
+ //
550
+ // Destroy the execution instance.
551
+
552
+ target.destroy = function destroy() {
553
+ target.execClosed(Error("instance destroyed"))
554
+ track.delete(target)
555
+ termDetach()
556
+ target.worker.terminate() // kill without saving
557
+ target.worker = false
558
+ }
559
+
560
+ track.add(target)
561
+
562
+ // finis
563
+
564
+ list(false, target)
565
+ };
566
+
567
+
568
+ /*
569
+ * findIDEtarget
570
+ *
571
+ * Find a target for our IDE that matches the specified name, workerID, and naancont.
572
+ *
573
+ */
574
+
575
+ closure findIDEtarget(track, name, workerID, naancont, local target) {
576
+ for target in track.enumlist()
577
+ if target.name == name && target.workerID == workerID && (!target.naancont || target.naancont === naancont)
578
+ return (target)
579
+ false
580
+ };
581
+
582
+
583
+ /*
584
+ * termIDE
585
+ *
586
+ * Make an IDE debugger target. The Naan controller in this case, env_web.js, iterates through
587
+ * all connected terminals so we just have to provide unique connection object for it to talk with.
588
+ * This is used for both the IDE itself as well as any additional virtual website windows.
589
+ *
590
+ */
591
+
592
+ closure termIDE(track, name, workerID, naancont, local target, connected) {
593
+ target = findIDEtarget(track, name, workerID, naancont)
594
+ if target { // new naancont on existing target
595
+ target.updateController(naancont)
596
+ return (target)
597
+ }
598
+ target = runningExecutors.ExecutorBase(track, "Local", name)
599
+ target.name = name
600
+ target.workerID = workerID
601
+ target.naancont = naancont
602
+ connected = []
603
+
604
+ //
605
+ // target.DebugCmd
606
+ //
607
+ // Post a debug command to the target, ourselves.
608
+ //
609
+
610
+ target.DebugCmd = function DebugCmd(data) {
611
+ naancont.DispatchDebugger(data)
612
+ }
613
+
614
+ //
615
+ // target.PostMessage
616
+ //
617
+ // Post a message to the target, ourselves.
618
+ //
619
+
620
+ target.PostMessage = function PostMessage(data) {
621
+ naancont.DispatchMessage(data)
622
+ }
623
+
624
+ // termAttach
625
+ //
626
+ // Create a closure for an attaching terminal.
627
+
628
+ target.termAttach = closure termAttach(term, db, statusCB, local connection, inbound) {
629
+ connection = new(object, this)
630
+
631
+ function oninterrupt() {
632
+ naancont.Interrupt(inbound)
633
+ }
634
+
635
+ function onreturn(local text) {
636
+ naancont.Return(term.TakeText(), inbound)
637
+ }
638
+
639
+ function onstatus(status) {
640
+ statusCB(target, status)
641
+ }
642
+
643
+ function onmessageout(data) {
644
+ target.execReceived(data)
645
+ }
646
+
647
+ function ondebugout(data) {
648
+ db.debugData(target, data)
649
+ }
650
+
651
+ connection.KeyText = function KeyText(text, echo) { // send text to instance
652
+ if echo
653
+ term.WriteLn(text.trim()) // echo to terminal
654
+ naancont.Return(text, inbound)
655
+ }
656
+
657
+ connection.termActive = function termActive(active) {
658
+ if inbound
659
+ inbound.active = active
660
+ }
661
+
662
+ connection.termDetach = function termDetach() { // disconnect the terminal
663
+ db.detach(target)
664
+ term.On("interrupt")
665
+ term.On("return")
666
+ if inbound
667
+ naancont.Detach(inbound)
668
+ connected = connected.filter(function(conn) { conn !== connection })
669
+ }
670
+
671
+ connection.popup = true // we can handle multiple terminals
672
+
673
+ let (replstate) {
674
+ replstate = naancont.StateGet()
675
+ if (replstate)
676
+ term.StateLoad(replstate)
677
+ else
678
+ term.Reset()
679
+ term.On("interrupt", oninterrupt.proc)
680
+ term.On("return", onreturn.proc)
681
+ term.Focus()
682
+ inbound = xnew({
683
+ OnMessage: term.OnMessage
684
+ StateSave: term.StateSave
685
+ OnStatus: onstatus.proc
686
+ OnMessageOut: onmessageout.proc
687
+ OnDebugOut: ondebugout.proc
688
+ })
689
+ naancont.Attach(inbound)
690
+ connection.inbound = inbound
691
+ connection.db = db
692
+ connected.push(connection)
693
+ db.attach(target)
694
+ } ()
695
+
696
+ // finis
697
+ connection
698
+ }
699
+
700
+ // updateController
701
+ //
702
+ // Update the naan controller on this target, which means updating for all the terminals.
703
+
704
+ target.updateController = function updateController(newnc, local conn) {
705
+ naancont = newnc
706
+ target.naancont = newnc
707
+ for conn in connected {
708
+ if naancont {
709
+ naancont.Attach(conn.inbound) // tell the controller about terminals
710
+ conn.db.attach(target) // re-attach since remote changed
711
+ conn.termActive()
712
+ } else
713
+ conn.db.detach(target) // nothing left to debug
714
+ }
715
+ target.execReset() // reset our parent class
716
+ }
717
+
718
+ // vsiteRefresh
719
+ //
720
+ // The vsite upon which we are based has changed.
721
+
722
+ target.vsiteRefresh = function vsiteRefresh(url_origin) {
723
+ naancont.VsiteRefresh(url_origin)
724
+ }
725
+
726
+ // destroy
727
+ //
728
+ // Destroy the execution instance.
729
+
730
+ target.destroy = function destroy() {
731
+ target.execClosed(Error("instance destroyed"))
732
+ track.delete(target)
733
+ }
734
+
735
+ track.add(target)
736
+
737
+ // finis
738
+
739
+ list(false, target)
740
+ };
741
+
742
+
743
+ /*
744
+ * termInstallVirtualWatcher
745
+ *
746
+ * column positioning: // // !
747
+ * Install a persistent watcher to note when virtual terminals come and go, and manage their
748
+ * execution target lifetimes.
749
+ *
750
+ */
751
+
752
+ closure termInstallVirtualWatcher(track, naancont) {
753
+
754
+ function watchVsites(msg, local error, target) {
755
+ if msg.op == "VsiteOpen" {
756
+ `(error, target) = termIDE(track, msg.name, "NaanVsite", msg.naancont)
757
+ target.attention()
758
+ }
759
+ else if msg.op == "VsiteClose" {
760
+ target = findIDEtarget(track, msg.name, "NaanVsite", msg.naancont)
761
+ if target
762
+ target.updateController()
763
+ }
764
+ }
765
+
766
+ runningExecutors.TaskOnMessageHook(watchVsites)
767
+ };
768
+
769
+
770
+ /*
771
+ * termInit
772
+ *
773
+ * Initialize the debugger page.
774
+ *
775
+ */
776
+
777
+ function termInit(local manifest) {
778
+
779
+ manifest = `(TermHost, TermLocal, findIDEtarget, termIDE, termInstallVirtualWatcher, termInit)
780
+
781
+ Naan.module.build(module.id, "terminals", function(modobj, compobj) {
782
+ require("./browser.nlg")
783
+ compobj.manifest = manifest
784
+ modobj.exports.TermLocal = TermLocal
785
+ modobj.exports.TermHost = TermHost
786
+ })
787
+ } ();