@naanlang/naan 1.4.4 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +2 -2
- package/README.md +4 -4
- package/bin/index.js +25 -3
- package/dist/env_web.js +164 -22
- package/dist/naan.min.js +5 -5
- package/frameworks/browser/browser.nlg +2 -2
- package/frameworks/browser/https_request.nlg +2 -2
- package/frameworks/browser/sworker.js +28 -26
- package/frameworks/browser/terminals.nlg +342 -700
- package/frameworks/browser/worker.nlg +255 -0
- package/frameworks/browser/workers.nlg +5 -5
- package/frameworks/browser/ws_client.nlg +15 -10
- package/frameworks/client/apiclient.nlg +204 -19
- package/frameworks/client/client.nlg +22 -2
- package/frameworks/client/psm_client.nlg +12 -3
- package/frameworks/client/relaycon.nlg +87 -161
- package/frameworks/common/events.nlg +101 -0
- package/frameworks/common/repltools.nlg +80 -1
- package/frameworks/node/apiserver.nlg +39 -246
- package/frameworks/node/filesystem.nlg +39 -12
- package/frameworks/node/gitter.nlg +9 -7
- package/frameworks/node/http_request.nlg +34 -13
- package/frameworks/node/https_request.nlg +8 -3
- package/frameworks/node/node.nlg +2 -0
- package/frameworks/node/pty.nlg +346 -0
- package/frameworks/node/shell.nlg +4 -4
- package/frameworks/node/worker.nlg +409 -539
- package/frameworks/node/ws_client.nlg +2 -2
- package/frameworks/project/build.nlg +1 -1
- package/frameworks/project/projects.nlg +2 -1
- package/frameworks/running/debugnub.nlg +17 -4
- package/frameworks/running/executors.nlg +27 -274
- package/frameworks/running/instances.nlg +393 -0
- package/frameworks/running/remote_req.nlg +143 -0
- package/frameworks/running/remote_res.nlg +89 -0
- package/frameworks/running/taskexec.nlg +2 -2
- package/frameworks/service/imp.nlg +736 -0
- package/frameworks/service/model.nlg +71 -0
- package/frameworks/service/nubnode.nlg +105 -0
- package/frameworks/service/nubweb.nlg +106 -0
- package/frameworks/service/service.nlg +28 -0
- package/frameworks/storage/dbt_pouch.nlg +26 -13
- package/frameworks/storage/psm.nlg +39 -5
- package/frameworks/storage/psm_dbtables.nlg +10 -2
- package/lib/browser/env_web.js +171 -29
- package/lib/browser/env_webworker.js +91 -5
- package/lib/core/naanlib.js +5 -5
- package/lib/env_node.js +184 -8
- package/lib/env_nodeworker.js +74 -1
- package/package.json +1 -1
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +2 -1
- package/plugins/serviceAws/aws_dynamo.nlg +1 -0
- package/plugins/serviceAws/aws_s3.nlg +3 -3
- package/plugins/serviceAws/aws_sqs.nlg +3 -1
- package/plugins/serviceAws/aws_utils.nlg +3 -1
- package/plugins/serviceAws/dbt_aws.nlg +22 -20
- package/plugins/serviceAws/psm_aws.nlg +2 -1
- package/plugins/serviceNexara/speechrec.nlg +10 -6
- package/test/test_02_context.nlg +24 -1
- package/test/test_03_jsinterop.nlg +32 -3
- package/plugins/serviceGC/russian_trusted_root_ca_pem.crt +0 -33
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2019-
|
|
9
|
+
* Copyright (c) 2019-2025 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -633,8 +633,17 @@ closure psmcFsConnector(psm, api, local connClassID, connector, watch) {
|
|
|
633
633
|
api = connector.apis[creds]
|
|
634
634
|
else {
|
|
635
635
|
api = connector.apis[creds.urlName]
|
|
636
|
-
if !api
|
|
637
|
-
connector.apis[creds.urlName] = api =
|
|
636
|
+
if !api { // create API to remote server
|
|
637
|
+
connector.apis[creds.urlName] = api = APIClient({
|
|
638
|
+
url: creds.urlName
|
|
639
|
+
guid: creds.authSecret
|
|
640
|
+
instanceID: creds.instanceID
|
|
641
|
+
})
|
|
642
|
+
if creds.instanceID != api.instanceID { // update our client instanceID
|
|
643
|
+
creds.instanceID = api.instanceID
|
|
644
|
+
`(error) = connector.vault.updateResource(resID, creds)
|
|
645
|
+
}
|
|
646
|
+
}
|
|
638
647
|
}
|
|
639
648
|
}
|
|
640
649
|
if error
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* relaycon.nlg
|
|
3
3
|
* Naanlib/frameworks/client
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Remote control of NaaN execution instances through the IMP network.
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c)
|
|
9
|
+
* Copyright (c) 2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -17,33 +17,32 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
execsMod;; // running/executors module
|
|
20
|
-
wsMod;; // websocket module
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
/*
|
|
24
23
|
* RelayCon
|
|
25
24
|
*
|
|
26
|
-
*
|
|
25
|
+
* Connect with an existing or new remote instance via IMP.
|
|
26
|
+
*
|
|
27
|
+
* Example usage:
|
|
28
|
+
*
|
|
29
|
+
comMod = require("naanlib:frameworks/client/relaycon.nlg")
|
|
30
|
+
relay = comMod.RelayCon(App.imp)
|
|
31
|
+
relay.clients()
|
|
32
|
+
// find desired instance
|
|
33
|
+
relay.context(<destID>)
|
|
27
34
|
*
|
|
28
35
|
* Options:
|
|
29
36
|
* {
|
|
30
|
-
* destID: <string> // client UUID or "server"
|
|
31
37
|
* name: <string> // internal identification
|
|
32
|
-
* config: {
|
|
33
|
-
* clientID: <string> // distinguishes clients
|
|
34
|
-
* serverID: <string> // subsystem on server (server destinations only)
|
|
35
|
-
* workerID: <string> // worker on server (server destinations only)
|
|
36
|
-
* }
|
|
37
|
-
* startup: <dictionary> // worker spawn init (server destinations only)
|
|
38
|
-
* wss: <boolean> // true to use secure connection
|
|
39
38
|
* debug: <boolean> // debug logging
|
|
40
39
|
* }
|
|
41
40
|
*
|
|
42
41
|
*/
|
|
43
42
|
|
|
44
|
-
closure RelayCon(
|
|
43
|
+
closure RelayCon(imp, options, local relay, nlregex)
|
|
45
44
|
{
|
|
46
|
-
global(App, execsMod
|
|
45
|
+
global(App, execsMod)
|
|
47
46
|
relay = new(object, this)
|
|
48
47
|
options = merge({
|
|
49
48
|
name: "NaanIDE Server"
|
|
@@ -53,125 +52,71 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
53
52
|
serverID: "Workers"
|
|
54
53
|
workerID: "NideServer"
|
|
55
54
|
}, options.config)
|
|
56
|
-
|
|
57
|
-
relay.config.endServerID = relay.config.serverID
|
|
58
|
-
relay.config.serverID = "Relay"
|
|
59
|
-
relay.config.destID = options.destID
|
|
60
|
-
relay.config.workerID = undefined
|
|
61
|
-
}
|
|
55
|
+
relay.instanceID = UUID()
|
|
62
56
|
relay.exec = execsMod.ExecutorBase(false, "Host", options.name)
|
|
63
57
|
nlregex = RegExp("\\n", "g")
|
|
64
58
|
|
|
65
59
|
// connect
|
|
66
60
|
//
|
|
67
|
-
// Connect with the
|
|
68
|
-
// it sends a "spawn" message, which establishes the connection with the server's "worker" which
|
|
69
|
-
// in the case of NideServer is just the main NodeJS process itself. It could also spawn a new
|
|
70
|
-
// worker thread, but we don't expose that functionality for the time being.
|
|
61
|
+
// Connect with the destination if not already connected.
|
|
71
62
|
//
|
|
72
|
-
closure connect(
|
|
73
|
-
if relay.
|
|
74
|
-
return (list(false, {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
relay.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
querys: secret && EncodeQuery("?", { guid: secret })
|
|
63
|
+
relay.connect = closure connect(destID) {
|
|
64
|
+
if relay.curDestID
|
|
65
|
+
return (list(false, { connectedID: relay.curDestID }))
|
|
66
|
+
if !string(destID)
|
|
67
|
+
return (list(Error("invalid connect destination")))
|
|
68
|
+
relay.curDestID = destID
|
|
69
|
+
|
|
70
|
+
relay.sender = imp.register(relay, {
|
|
71
|
+
name: options.name
|
|
72
|
+
type: relay.config.workerID
|
|
73
|
+
instanceID: relay.instanceID
|
|
74
|
+
services: [ "term_client" ]
|
|
85
75
|
})
|
|
86
|
-
result = relay.wscon.connect()
|
|
87
|
-
if !result.0
|
|
88
|
-
sendControl("spawn", { name: options.name }) // ensure worker is connected
|
|
89
|
-
else if options.debug
|
|
90
|
-
ErrorDebuglog("WebSocket connect failed:", result.0)
|
|
91
|
-
result
|
|
92
|
-
}
|
|
93
76
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
sendControl("spawn", spawner)
|
|
105
|
-
|
|
77
|
+
function initWorker(local spawner) {
|
|
78
|
+
return // ###
|
|
79
|
+
relay.sender(relay.curDestID, {
|
|
80
|
+
init: { // initialize our worker (or main)...
|
|
81
|
+
name: options.name
|
|
82
|
+
workerID: relay.config.workerID
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
spawner = new(options.startup) || { }
|
|
86
|
+
spawner.name = options.name
|
|
87
|
+
// sendControl("spawn", spawner)
|
|
88
|
+
}
|
|
106
89
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// The WebSocket connection has closed.
|
|
110
|
-
//
|
|
111
|
-
closure onclose(e, code, reason) {
|
|
112
|
-
if options.debug && code != 1000 && code != 1001 && code != 1005
|
|
113
|
-
debuglog("WebSocket onclose", relay.host, code, reason, e.*)
|
|
114
|
-
relay.wscon = false
|
|
115
|
-
relay.exec.execClosed(Error("socket closed", e.code, e.reason))
|
|
90
|
+
initWorker()
|
|
91
|
+
list(false, { connectedID: relay.curDestID })
|
|
116
92
|
}
|
|
117
93
|
|
|
118
|
-
//
|
|
94
|
+
// impUnknown
|
|
119
95
|
//
|
|
120
|
-
//
|
|
96
|
+
// Received an unknown destination notice from the other side.
|
|
121
97
|
//
|
|
122
|
-
|
|
123
|
-
if
|
|
124
|
-
debuglog("
|
|
125
|
-
relay.exec.execFailed(Error("WebSocket onerror"))
|
|
98
|
+
relay.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
99
|
+
if !gateway
|
|
100
|
+
debuglog("RelayCon.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
126
101
|
}
|
|
127
102
|
|
|
128
|
-
//
|
|
103
|
+
// impReceive
|
|
129
104
|
//
|
|
130
|
-
//
|
|
105
|
+
// Received a payload from the other side.
|
|
131
106
|
//
|
|
132
|
-
|
|
133
|
-
if options.debug
|
|
134
|
-
printline("Relay response:", Dialect.print(message))
|
|
135
|
-
if
|
|
136
|
-
relay.
|
|
137
|
-
|
|
138
|
-
msg = message.payload
|
|
139
|
-
if msg.id == "spawned" || msg.id == "workerlist" || msg.id == "termination"
|
|
140
|
-
return (hostWorkerUpdate(msg))
|
|
141
|
-
if msg.id != "targetout" {
|
|
142
|
-
if msg.id == "status"
|
|
143
|
-
relay.lastStatus = milliseconds() }
|
|
144
|
-
doMessage(msg) }
|
|
145
|
-
else if options.debug {
|
|
146
|
-
if message.respOp == "error"
|
|
147
|
-
debuglog("worker controller error:", ErrorString(message.payload[0]))
|
|
148
|
-
else if message.respOp == "linked"
|
|
149
|
-
debuglog("terminal linked")
|
|
150
|
-
else if message.respOp
|
|
151
|
-
debuglog("unknown host response message:", message.respOp)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// hostWorkerUpdate
|
|
156
|
-
//
|
|
157
|
-
// New workers created/discovered on this host.
|
|
158
|
-
//
|
|
159
|
-
closure hostWorkerUpdate(msg) {
|
|
160
|
-
if options.debug {
|
|
161
|
-
if msg.id == "spawned"
|
|
162
|
-
debuglog("host worker spawned", msg.name, "(${msg.workerID})")
|
|
163
|
-
else if msg.id == "termination"
|
|
164
|
-
debuglog("host worker terminated", msg.workerID)
|
|
165
|
-
else if msg.id == "workerlist"
|
|
166
|
-
printline("host workers:", Dialect.print(msg.workers))
|
|
167
|
-
}
|
|
107
|
+
relay.impReceive = function impReceive(message, sourceID) {
|
|
108
|
+
if options.debug
|
|
109
|
+
printline("Relay response:", Dialect.print(new(message)))
|
|
110
|
+
if message.id == "status"
|
|
111
|
+
relay.lastStatus = milliseconds()
|
|
112
|
+
doMessage(message)
|
|
168
113
|
}
|
|
169
114
|
|
|
170
115
|
// doMessage
|
|
171
116
|
//
|
|
172
|
-
//
|
|
117
|
+
// Process the specified undecoded message.
|
|
173
118
|
//
|
|
174
|
-
|
|
119
|
+
relay.doMessage = function doMessage(msg) {
|
|
175
120
|
if msg.id == "targetout"
|
|
176
121
|
relay.exec.execReceived(msg.data)
|
|
177
122
|
else if msg.id == "debugout"
|
|
@@ -191,34 +136,23 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
191
136
|
debuglog("unknown host worker message:", msg.id)
|
|
192
137
|
}
|
|
193
138
|
}
|
|
194
|
-
|
|
195
|
-
// sendControl
|
|
196
|
-
//
|
|
197
|
-
// Send a message to the worker controller.
|
|
198
|
-
//
|
|
199
|
-
relay.sendControl = function sendControl(workerOp, payload) {
|
|
200
|
-
relay.wscon.send(merge({
|
|
201
|
-
guid: relay.guid
|
|
202
|
-
workerOp: workerOp
|
|
203
|
-
payload: payload
|
|
204
|
-
}, relay.config))
|
|
205
|
-
}
|
|
206
|
-
|
|
139
|
+
|
|
207
140
|
// send
|
|
208
141
|
//
|
|
209
|
-
//
|
|
142
|
+
// Send a message to the worker.
|
|
210
143
|
//
|
|
211
144
|
relay.send = function send(msg) {
|
|
212
|
-
|
|
145
|
+
relay.sender(relay.curDestID, msg)
|
|
213
146
|
}
|
|
214
147
|
|
|
215
148
|
// exec.PostMessage
|
|
216
149
|
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
150
|
+
// Post a message to the target, returning a result tuple with an error if the connection has
|
|
151
|
+
// closed.
|
|
219
152
|
//
|
|
220
153
|
relay.exec.PostMessage = function PostMessage(data, local result) {
|
|
221
|
-
|
|
154
|
+
if !relay.curDestID
|
|
155
|
+
return (list(Error("connection not open")))
|
|
222
156
|
if result.0
|
|
223
157
|
return (result)
|
|
224
158
|
send({ // send data to worker
|
|
@@ -230,27 +164,10 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
230
164
|
|
|
231
165
|
// clients
|
|
232
166
|
//
|
|
233
|
-
// Return an array of available clients (destination browsers) with which we can communicate
|
|
234
|
-
// a result tuple like the following array:
|
|
167
|
+
// Return an array of available clients (destination browsers) with which we can communicate.
|
|
235
168
|
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
// destID : "52733f52-869b-4758-b553-611df95eb5fe",
|
|
239
|
-
// address : { address: "::1", family: "IPv6", port: 8009 },
|
|
240
|
-
// name : "NaanIDE Server",
|
|
241
|
-
// workerID: "NideServer" },
|
|
242
|
-
// {
|
|
243
|
-
// destID : "ba4b7e69-abe5-4d13-b091-7abe833fd029",
|
|
244
|
-
// address : { address: "::1", family: "IPv6", port: 8009 },
|
|
245
|
-
// name : "NaanIDE Server",
|
|
246
|
-
// workerID: "NideServer" }
|
|
247
|
-
// ]
|
|
248
|
-
//
|
|
249
|
-
relay.clients = closure clients(excon, local error) {
|
|
250
|
-
if !excon
|
|
251
|
-
`(error, excon) = context()
|
|
252
|
-
if excon
|
|
253
|
-
excon.evalq(App.api.Relays())
|
|
169
|
+
relay.clients = closure clients(destID) {
|
|
170
|
+
imp.discover(destID)
|
|
254
171
|
}
|
|
255
172
|
|
|
256
173
|
// context
|
|
@@ -268,10 +185,20 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
268
185
|
// context.rpc(test3, `(45))
|
|
269
186
|
// (rpc does JSON serialization)
|
|
270
187
|
// 4. Call via RPC showing Date object conversion
|
|
271
|
-
// context.rpc(test3)
|
|
188
|
+
// context.rpc(test3, list(Date()))
|
|
272
189
|
// (JSON serializationn converts the date to an ISO string)
|
|
273
190
|
//
|
|
274
|
-
relay.context = closure context() {
|
|
191
|
+
relay.context = closure context(destID, local result) {
|
|
192
|
+
if destID != relay.curDestID {
|
|
193
|
+
if relay.curDestID
|
|
194
|
+
close()
|
|
195
|
+
result = connect(destID)
|
|
196
|
+
if result.0
|
|
197
|
+
return (result)
|
|
198
|
+
}
|
|
199
|
+
connect(destID)
|
|
200
|
+
if imp.us.instanceID != destID
|
|
201
|
+
imp.inform(imp.us.instanceID, destID) // ensure our IMP is reachable by them
|
|
275
202
|
relay.exec.context()
|
|
276
203
|
}
|
|
277
204
|
|
|
@@ -280,8 +207,11 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
280
207
|
// Close the connection, though it can be reopened
|
|
281
208
|
//
|
|
282
209
|
relay.close = closure close() {
|
|
283
|
-
relay.
|
|
284
|
-
|
|
210
|
+
if relay.curDestID {
|
|
211
|
+
imp.unregister(relay.instanceID)
|
|
212
|
+
relay.curDestID = false
|
|
213
|
+
}
|
|
214
|
+
list(false, { closed: true })
|
|
285
215
|
}
|
|
286
216
|
|
|
287
217
|
// finis
|
|
@@ -291,22 +221,18 @@ closure RelayCon(host, secret, options, local relay, nlregex)
|
|
|
291
221
|
|
|
292
222
|
|
|
293
223
|
/*
|
|
294
|
-
*
|
|
224
|
+
* relayInit
|
|
295
225
|
*
|
|
296
|
-
*
|
|
226
|
+
* Initialize the component.
|
|
297
227
|
*
|
|
298
228
|
*/
|
|
299
229
|
|
|
300
|
-
function
|
|
301
|
-
manifest = `(RelayCon,
|
|
230
|
+
function relayInit(local manifest) {
|
|
231
|
+
manifest = `(RelayCon, relayInit)
|
|
302
232
|
|
|
303
233
|
Naan.module.build(module.id, "relaycon", function(modobj, compobj) {
|
|
304
234
|
require("./client.nlg")
|
|
305
235
|
execsMod = require("../running/executors.nlg")
|
|
306
|
-
if js.w
|
|
307
|
-
wsMod = require("../browser/ws_client.nlg")
|
|
308
|
-
else
|
|
309
|
-
wsMod = require("../node/ws_client.nlg")
|
|
310
236
|
compobj.manifest = manifest
|
|
311
237
|
module.exports.RelayCon = RelayCon
|
|
312
238
|
})
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* events.nlg
|
|
3
|
+
* naanlib/frameworks/common/events
|
|
4
|
+
*
|
|
5
|
+
* A simple notification system replicating JS events.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* Events
|
|
16
|
+
*
|
|
17
|
+
* Events objects provide a common protocol for adding/removing event listeners and sending events
|
|
18
|
+
* to them. Events are dispatched via a future, so they are asynchronous to the caller but invoked
|
|
19
|
+
* serially. Initialize this on an object to define the methods directly on it.
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
closure Events(target, local events, eventsdb) {
|
|
24
|
+
global()
|
|
25
|
+
if target
|
|
26
|
+
events = target
|
|
27
|
+
else
|
|
28
|
+
events = new(object, this)
|
|
29
|
+
|
|
30
|
+
// dispatch
|
|
31
|
+
//
|
|
32
|
+
// Dispatch the specified event, which will be sent to all listeners.
|
|
33
|
+
//
|
|
34
|
+
events.dispatchEvent = function dispatch args {
|
|
35
|
+
closure Event(type, args, local event) {
|
|
36
|
+
event = new(object, this)
|
|
37
|
+
event.type = type
|
|
38
|
+
event.target = target || undefined
|
|
39
|
+
event.timeStamp = milliseconds()
|
|
40
|
+
future(function(local listener) {
|
|
41
|
+
for listener in eventsdb[type]
|
|
42
|
+
apply(listener.code, cons(event, args))
|
|
43
|
+
},0)
|
|
44
|
+
} (pop(args), args)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// addEventListener
|
|
48
|
+
//
|
|
49
|
+
// Add the specified function to the call list for events of the type.
|
|
50
|
+
//
|
|
51
|
+
events.addEventListener = function addEventListener(type, code, option) {
|
|
52
|
+
if !eventsdb[type]
|
|
53
|
+
eventsdb[type] = []
|
|
54
|
+
else if eventsdb[type].find(function(listener) { listener.code === code })
|
|
55
|
+
return // no duplicates
|
|
56
|
+
eventsdb[type].push({
|
|
57
|
+
code: code
|
|
58
|
+
option: option
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// removeEventListener
|
|
63
|
+
//
|
|
64
|
+
// Remove the specified function from the call list for events of the type.
|
|
65
|
+
//
|
|
66
|
+
events.removeEventListener = function removeEventListener(type, code) {
|
|
67
|
+
eventsdb[type] = eventsdb[type].filter(function(listener) {
|
|
68
|
+
listener.code !== code
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// reset
|
|
73
|
+
//
|
|
74
|
+
// Reset the events list, which is done at construction time.
|
|
75
|
+
//
|
|
76
|
+
events.reset = function reset() {
|
|
77
|
+
eventsdb = {}
|
|
78
|
+
} ()
|
|
79
|
+
|
|
80
|
+
// finis
|
|
81
|
+
events
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* eventsInit
|
|
87
|
+
*
|
|
88
|
+
* Initialize the component.
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
function eventsInit(local manifest) {
|
|
93
|
+
manifest = `(Events, eventsInit)
|
|
94
|
+
|
|
95
|
+
Naan.module.build(module.id, "events", function(modobj, compobj) {
|
|
96
|
+
require("./common.nlg")
|
|
97
|
+
compobj.manifest = manifest
|
|
98
|
+
module.exports.Events = Events
|
|
99
|
+
updateExports()
|
|
100
|
+
})
|
|
101
|
+
} ();
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* column positioning: // // !
|
|
7
7
|
*
|
|
8
|
-
* Copyright (c) 2017-
|
|
8
|
+
* Copyright (c) 2017-2026 by Richard C. Zulch
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -70,6 +70,85 @@ function dcaller(proc, lambdaOK, local x, found) {
|
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
/*
|
|
74
|
+
* dwrapper
|
|
75
|
+
*
|
|
76
|
+
* Wrap an object so that all calls in or out are logged.
|
|
77
|
+
*
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
closure dwrapper(obj, name, local wrap, indents) {
|
|
81
|
+
indents = dwrapper@indents
|
|
82
|
+
if !indents {
|
|
83
|
+
dwrapper@indents = indents = unintern(`indents)
|
|
84
|
+
assign(indents, 0)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
wrap = new(object, dwrapper)
|
|
88
|
+
|
|
89
|
+
function indent(callin) {
|
|
90
|
+
debuglog("${spaces()}${callin} ==>")
|
|
91
|
+
assign(indents, indents.value+1)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function outdent(result) {
|
|
95
|
+
assign(indents, indents.value-1)
|
|
96
|
+
debuglog("${spaces()}<== ${result}", )
|
|
97
|
+
result
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function spaces() {
|
|
101
|
+
"| ".repeat(indents.value)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function swap(o) {
|
|
105
|
+
if tuple(o)
|
|
106
|
+
o.map(function(item){ item === wrap && name || item })
|
|
107
|
+
else if o === wrap
|
|
108
|
+
name
|
|
109
|
+
else
|
|
110
|
+
o
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
wrap@[".undefined"] = function trampoline args {
|
|
114
|
+
function (selector, arglist, result) {
|
|
115
|
+
indent("${name}.${selector}${swap(arglist)||'()'}")
|
|
116
|
+
try {
|
|
117
|
+
result = eval(list(`deref, obj, selector, arglist))
|
|
118
|
+
outdent(result)
|
|
119
|
+
} catch {
|
|
120
|
+
outdent("${selector}() exception: ${exception}")
|
|
121
|
+
result = mu()
|
|
122
|
+
}
|
|
123
|
+
} (args.0, args.-1)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
wrap@["..undefined"] = function getter(selector) {
|
|
127
|
+
indent("${name}[${selector}]")
|
|
128
|
+
try {
|
|
129
|
+
result = obj[selector]
|
|
130
|
+
outdent(result)
|
|
131
|
+
} catch {
|
|
132
|
+
outdent("${selector}[] exception: ${exception}")
|
|
133
|
+
result = mu()
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
wrap@[".=undefined"] = function setter(selector, value) {
|
|
138
|
+
indent("${name}[${selector}] = ${swap(value)}")
|
|
139
|
+
try {
|
|
140
|
+
result = obj[selector] = value
|
|
141
|
+
outdent(result)
|
|
142
|
+
} catch {
|
|
143
|
+
outdent("${selector}[]= exception: ${exception}")
|
|
144
|
+
result = mu()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
wrap
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
|
|
73
152
|
/*
|
|
74
153
|
* ImportReplTools
|
|
75
154
|
*
|