@naanlang/naan 1.5.0 → 1.7.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 +2 -2
- package/bin/index.js +7 -3
- package/dist/env_web.js +162 -48
- package/dist/naan.min.js +11 -11
- package/frameworks/browser/https_request.nlg +2 -2
- package/frameworks/browser/sworker.js +28 -26
- package/frameworks/browser/terminals.nlg +295 -737
- package/frameworks/browser/worker.nlg +295 -0
- package/frameworks/browser/workers.nlg +6 -6
- package/frameworks/browser/ws_client.nlg +15 -10
- package/frameworks/client/apiclient.nlg +211 -9
- package/frameworks/client/psm_client.nlg +10 -14
- package/frameworks/client/relaycon.nlg +87 -161
- package/frameworks/common/common.nlg +2 -0
- package/frameworks/common/events.nlg +101 -0
- package/frameworks/common/repltools.nlg +80 -1
- package/frameworks/node/apiserver.nlg +38 -246
- package/frameworks/node/filesystem.nlg +31 -6
- package/frameworks/node/http_request.nlg +34 -13
- package/frameworks/node/https_request.nlg +8 -3
- package/frameworks/node/node.nlg +3 -0
- package/frameworks/node/pty.nlg +346 -0
- package/frameworks/node/shell.nlg +26 -3
- package/frameworks/node/worker.nlg +504 -560
- package/frameworks/node/ws_client.nlg +2 -2
- package/frameworks/project/build.nlg +56 -14
- package/frameworks/project/projects.nlg +1 -1
- package/frameworks/running/debugcom.nlg +20 -3
- package/frameworks/running/debugnub.nlg +33 -11
- package/frameworks/running/executors.nlg +40 -285
- package/frameworks/running/instances.nlg +394 -0
- package/frameworks/running/remote_req.nlg +139 -0
- package/frameworks/running/remote_res.nlg +89 -0
- package/frameworks/running/sourcecode.nlg +3 -2
- package/frameworks/running/taskexec.nlg +16 -59
- package/frameworks/service/imp.nlg +751 -0
- package/frameworks/service/model.nlg +71 -0
- package/frameworks/service/nubnode.nlg +136 -0
- package/frameworks/service/nubweb.nlg +124 -0
- package/frameworks/service/service.nlg +28 -0
- package/frameworks/storage/file_manager.nlg +3 -2
- package/lib/browser/env_web.js +169 -55
- package/lib/browser/env_webworker.js +89 -31
- package/lib/core/naanlib.js +11 -11
- package/lib/env_node.js +186 -27
- package/lib/env_nodeworker.js +82 -44
- package/lib/node_server_init.nlg +149 -0
- package/lib/node_worker.js +36 -0
- package/lib/node_worker_init.nlg +43 -0
- package/package.json +1 -1
- package/plugins/openSearch/openSearch.nlg +3 -2
- package/plugins/openSearch/os_dynamo.nlg +3 -2
- package/plugins/serviceAws/aws_cloudwatchlogs.nlg +44 -2
- package/plugins/serviceAws/aws_dynamo.nlg +144 -63
- package/plugins/serviceAws/aws_utils.nlg +6 -11
- package/plugins/serviceAws/serviceAws.nlg +3 -2
- package/plugins/serviceNexara/speechrec.nlg +10 -6
- package/test/test_01_core.nlg +2 -2
- package/test/test_02_context.nlg +32 -9
- package/test/test_03_jsinterop.nlg +3 -3
- package/test/test_07_lingo.nlg +1 -1
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* instances.nlg
|
|
3
|
+
* Naanlib/frameworks/browser
|
|
4
|
+
*
|
|
5
|
+
* Manage NaaN instances locally and remotely.
|
|
6
|
+
*
|
|
7
|
+
* NaaN instances are managed by a top/bottom pair of of objects. InBot (INstance BOTtom) objects
|
|
8
|
+
* reside in the same JavaScript environment (node/browser) as their worker and communicate with the
|
|
9
|
+
* appropriate env_xxx.js adapter for NaaN in that environment.
|
|
10
|
+
*
|
|
11
|
+
* Zero or more InTop objects connect to each InBot object via the IMP network, providing remote
|
|
12
|
+
* evaluation and terminal access services. Each InTop supports only one terminal simultaneously, but
|
|
13
|
+
* they can be attached and detached at any time.
|
|
14
|
+
*
|
|
15
|
+
* column positioning: // // !
|
|
16
|
+
*
|
|
17
|
+
* Copyright (c) 2026 by Richard C. Zulch
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* InTop
|
|
24
|
+
*
|
|
25
|
+
* Create an InTop executor for the specified InBot. The open and close methods select the specific
|
|
26
|
+
* InBot to be used. The design intent is to only connect to one InBot, but lifecycle and connection
|
|
27
|
+
* changes could theoretically change its instanceID. A terminal may attach and detach from this
|
|
28
|
+
* object, but only one at a time. Create more InTops if you need terminals simultaneously. All of
|
|
29
|
+
* the ExecutorBase methods are available, such as `context()`.
|
|
30
|
+
*
|
|
31
|
+
* Options:
|
|
32
|
+
* {
|
|
33
|
+
* name: <string> // target name, e.g. "Play"
|
|
34
|
+
* type: <string> // target category, e.g. "Local"
|
|
35
|
+
* workerID: <string> // target workerID
|
|
36
|
+
* create: <dictionary> // creation parameters, if creation is desired
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
closure InTop(track, options, local intop, nlregex, str, error) {
|
|
42
|
+
global(App)
|
|
43
|
+
intop = ExecutorBase(track, options.type, options.name)
|
|
44
|
+
intop.workerID = options.workerID || undefined
|
|
45
|
+
intop.msgQueue = []
|
|
46
|
+
nlregex = RegExp("\\n", "g")
|
|
47
|
+
|
|
48
|
+
// doMessage
|
|
49
|
+
//
|
|
50
|
+
// Process a message from our InBot.
|
|
51
|
+
//
|
|
52
|
+
intop.doMessage = function doMessage(msg) {
|
|
53
|
+
if msg.id == "textout"
|
|
54
|
+
intop.term.Write(msg.text.replace(nlregex, "\r\n"))
|
|
55
|
+
else if msg.id == "debugtext"
|
|
56
|
+
intop.debugWrite(msg.text, msg.level)
|
|
57
|
+
else if msg.id == "typed" { // echo in dark-grey, italic
|
|
58
|
+
if intop.ioctl_echo == 1 { // echo newline only
|
|
59
|
+
if str.firstIndexOf("\\n") >= 0
|
|
60
|
+
intop.term.Write("\r\n")
|
|
61
|
+
} else if intop.ioctl_echo != 0
|
|
62
|
+
formatTyped(msg.text)
|
|
63
|
+
} else if msg.id == "targetout"
|
|
64
|
+
intop.execReceived(msg.data)
|
|
65
|
+
else if msg.id == "status"
|
|
66
|
+
intop.notify.execStatus(intop, msg.status)
|
|
67
|
+
else if msg.id == "debugout"
|
|
68
|
+
intop.debugger.debugData(intop, msg.data)
|
|
69
|
+
else if msg.id == "download"
|
|
70
|
+
{ }
|
|
71
|
+
else if msg.id == "loaded"
|
|
72
|
+
{ }
|
|
73
|
+
else if msg.id == "ioctl" {
|
|
74
|
+
if msg.op == "echo" {
|
|
75
|
+
intop.ioctl_echo = msg.arg // control our typed echo
|
|
76
|
+
intop.term.EchoSet(msg.arg) // echo arg: 0, 1, 2
|
|
77
|
+
} else if msg.op == "sane" {
|
|
78
|
+
intop.ioctl_echo = 2 // enable typed echo
|
|
79
|
+
intop.term.Sane()
|
|
80
|
+
} else if msg.op == "raw"
|
|
81
|
+
intop.term.SetRawMode(msg.arg) // enable/disable raw mode
|
|
82
|
+
else if msg.op == "keystroke"
|
|
83
|
+
intop.term.PutKey(msg.arg) // simulate a keystroke
|
|
84
|
+
} else if msg.id == "error"
|
|
85
|
+
intop.execClosed(Error("instance error", msg.data))
|
|
86
|
+
else if msg.id == "terminated"
|
|
87
|
+
close()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// formatTyped
|
|
91
|
+
//
|
|
92
|
+
// Format typed text with distinctive style.
|
|
93
|
+
//
|
|
94
|
+
intop.formatTyped = function formatTyped(text, local str) {
|
|
95
|
+
str = text.replace(nlregex, "\r\n")
|
|
96
|
+
intop.term.Write("\x1b[90m\x1b[3m${str}\x1b[0m\n")
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// impUnknown
|
|
100
|
+
//
|
|
101
|
+
// Received an unknown destination notice from the other side.
|
|
102
|
+
//
|
|
103
|
+
intop.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
104
|
+
if !gateway
|
|
105
|
+
debuglog("InTop.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// impReceive
|
|
109
|
+
//
|
|
110
|
+
// Received a message from our InBot.
|
|
111
|
+
//
|
|
112
|
+
intop.impReceive = function impReceive(msg, sourceID) {
|
|
113
|
+
if msg.id == "workerDestID" {
|
|
114
|
+
intop.workerDestID = msg.workerDestID
|
|
115
|
+
return
|
|
116
|
+
}
|
|
117
|
+
if msg.id != "targetout" {
|
|
118
|
+
if msg.id == "status" {
|
|
119
|
+
intop.lastStatus = milliseconds()
|
|
120
|
+
intop.execSetStatus(msg.status)
|
|
121
|
+
}
|
|
122
|
+
if intop.msgQueue {
|
|
123
|
+
if msg.id != "status"
|
|
124
|
+
intop.msgQueue.push(msg)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
intop.doMessage(msg)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// replInterrupt
|
|
132
|
+
//
|
|
133
|
+
// User interrupt from the keyboard.
|
|
134
|
+
//
|
|
135
|
+
intop.replInterrupt = function replInterrupt() {
|
|
136
|
+
intop.sender(intop.botDestID, { // send interrupt to worker
|
|
137
|
+
id: "interrupt"
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// replReturn
|
|
142
|
+
//
|
|
143
|
+
// Return key hit.
|
|
144
|
+
//
|
|
145
|
+
intop.replReturn = function replReturn(local text) {
|
|
146
|
+
text = intop.term.TakeText()
|
|
147
|
+
echotyped(text)
|
|
148
|
+
intop.sender(intop.botDestID, { // send user-entered text to worker
|
|
149
|
+
id: "keyline",
|
|
150
|
+
text: text
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// replRaw
|
|
155
|
+
//
|
|
156
|
+
// Raw character received.
|
|
157
|
+
//
|
|
158
|
+
intop.replRaw = function(str, origin) {
|
|
159
|
+
ioctl_event("raw-key", { // send raw keystroke to worker
|
|
160
|
+
key: str
|
|
161
|
+
origin: origin
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// replResize
|
|
166
|
+
//
|
|
167
|
+
// The terminal was resized.
|
|
168
|
+
//
|
|
169
|
+
intop.replResize = function(columns, rows) {
|
|
170
|
+
ioctl_event("term-resize", { // send resize advice to worker
|
|
171
|
+
cols: columns
|
|
172
|
+
rows: rows
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// echotyped
|
|
177
|
+
//
|
|
178
|
+
// Echo text to other terminals.
|
|
179
|
+
//
|
|
180
|
+
function echotyped(text) {
|
|
181
|
+
intop.sender(intop.botDestID, {
|
|
182
|
+
id: "typed"
|
|
183
|
+
text: text
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// intop.KeyText
|
|
188
|
+
//
|
|
189
|
+
// Send text to the worker, with optional echo to terminal.
|
|
190
|
+
//
|
|
191
|
+
intop.KeyText = function KeyText(text, echo) {
|
|
192
|
+
if echo {
|
|
193
|
+
text = text.trim()
|
|
194
|
+
echotyped(text)
|
|
195
|
+
intop.term.WriteLn(text)
|
|
196
|
+
}
|
|
197
|
+
intop.sender(intop.botDestID, { // send text to worker
|
|
198
|
+
id: "keyline"
|
|
199
|
+
text: text
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
//
|
|
204
|
+
// ioctl_event
|
|
205
|
+
//
|
|
206
|
+
// A terminal-initiated event.
|
|
207
|
+
//
|
|
208
|
+
intop.ioctl_event = function ioctl_event(msg, arg) {
|
|
209
|
+
intop.sender(intop.botDestID, { // send ioctl event to worker
|
|
210
|
+
id: "ioctl-event",
|
|
211
|
+
msg: msg
|
|
212
|
+
arg: arg
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// DebugCmd
|
|
217
|
+
//
|
|
218
|
+
// Post a debug command to the worker.
|
|
219
|
+
//
|
|
220
|
+
intop.DebugCmd = function DebugCmd(data) {
|
|
221
|
+
intop.sender(intop.botDestID, { // send data to worker
|
|
222
|
+
id: "debugin"
|
|
223
|
+
data: data
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// PostMessage
|
|
228
|
+
//
|
|
229
|
+
// Post a message to the worker. This uses workerDestID if available, or the bottom itself
|
|
230
|
+
// otherwise. The former scenario covers use of NodeWorker where we want to send the packet all
|
|
231
|
+
// the way to the final destination. The second scenario covers the case that the bottom is
|
|
232
|
+
// communicating with the env_xxx.js code directly.
|
|
233
|
+
//
|
|
234
|
+
intop.PostMessage = function PostMessage(data, local destID) {
|
|
235
|
+
destID = intop.workerDestID || intop.botDestID
|
|
236
|
+
intop.sender(destID, { // send data to worker
|
|
237
|
+
id: "targetin",
|
|
238
|
+
data: data
|
|
239
|
+
})
|
|
240
|
+
list(false, { posted: true })
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// debugWrite
|
|
244
|
+
//
|
|
245
|
+
// Write a debug message to the terminal.
|
|
246
|
+
//
|
|
247
|
+
intop.debugWrite = function(text, level) {
|
|
248
|
+
text = text.replaceAll("\n", "\r\n")
|
|
249
|
+
if (level >= 5)
|
|
250
|
+
intop.term.WriteLn(text, intop.term.Cyan) // cyan for builtin logging
|
|
251
|
+
else if (level >= 4)
|
|
252
|
+
intop.term.WriteLn(text, intop.term.Blue) // blue for Naan function logging
|
|
253
|
+
else if (level >= 3)
|
|
254
|
+
intop.term.WriteLn(text, intop.term.Red) // light red for warnings
|
|
255
|
+
else if (level >= 2)
|
|
256
|
+
intop.term.WriteLn(text, intop.term.Green) // green for Naan.debug.debuglog logging
|
|
257
|
+
else
|
|
258
|
+
intop.term.WriteLn(text, intop.term.Red+intop.term.Bold) // heavy red for errors
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// termAttach
|
|
262
|
+
//
|
|
263
|
+
// A terminal was attached.
|
|
264
|
+
//
|
|
265
|
+
intop.termAttach = function termAttach(repl, db, notify, local msg) {
|
|
266
|
+
if !intop.msgQueue
|
|
267
|
+
return (list(Error("already attached")))
|
|
268
|
+
intop.sender(intop.botDestID, {
|
|
269
|
+
id: "attached",
|
|
270
|
+
guid: intop.instanceID
|
|
271
|
+
})
|
|
272
|
+
intop.term = repl
|
|
273
|
+
intop.debugger = db
|
|
274
|
+
intop.notify = notify
|
|
275
|
+
if intop.termSaved {
|
|
276
|
+
intop.term.StateLoad(intop.termSaved)
|
|
277
|
+
intop.termSaved = false }
|
|
278
|
+
else
|
|
279
|
+
intop.term.Reset()
|
|
280
|
+
intop.debugger.attach(intop)
|
|
281
|
+
intop.term.SetNotify(intop)
|
|
282
|
+
while intop.msgQueue.length > 0 { // replay saved and new messages
|
|
283
|
+
for msg in intop.msgQueue.splice(0)
|
|
284
|
+
intop.doMessage(msg)
|
|
285
|
+
}
|
|
286
|
+
intop.msgQueue = false
|
|
287
|
+
intop.term.Focus()
|
|
288
|
+
intop
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// termDetach
|
|
292
|
+
//
|
|
293
|
+
// The terminal is being detached.
|
|
294
|
+
//
|
|
295
|
+
intop.termDetach = function termDetach() {
|
|
296
|
+
if intop.msgQueue
|
|
297
|
+
return (list(Error("already detached")))
|
|
298
|
+
intop.term.SetNotify()
|
|
299
|
+
intop.msgQueue = []
|
|
300
|
+
intop.debugger.detach(intop)
|
|
301
|
+
intop.termSaved = intop.term.StateSave()
|
|
302
|
+
intop.notify = false
|
|
303
|
+
intop.debugger = false
|
|
304
|
+
intop.term = false
|
|
305
|
+
intop.sender(intop.botDestID, {
|
|
306
|
+
id: "detached",
|
|
307
|
+
guid: intop.instanceID
|
|
308
|
+
})
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// close
|
|
312
|
+
//
|
|
313
|
+
// Close our access to the worker.
|
|
314
|
+
//
|
|
315
|
+
intop.close = function close() {
|
|
316
|
+
if !intop.instanceID
|
|
317
|
+
return
|
|
318
|
+
intop.sender(intop.botDestID, {
|
|
319
|
+
id: "unsubscribe"
|
|
320
|
+
})
|
|
321
|
+
intop.execClosed(Error("instance closed"))
|
|
322
|
+
track.delete(intop)
|
|
323
|
+
termDetach()
|
|
324
|
+
sleep(10)
|
|
325
|
+
App.imp.unregister(intop.instanceID)
|
|
326
|
+
intop.instanceID = false
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// destroy
|
|
330
|
+
//
|
|
331
|
+
// Destroy the worker.
|
|
332
|
+
//
|
|
333
|
+
intop.destroy = function destroy() {
|
|
334
|
+
if intop.destroyed
|
|
335
|
+
return
|
|
336
|
+
intop.destroyed = true
|
|
337
|
+
intop.sender(intop.botDestID, {
|
|
338
|
+
id: "destroy",
|
|
339
|
+
guid: intop.instanceID
|
|
340
|
+
})
|
|
341
|
+
close()
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// open
|
|
345
|
+
//
|
|
346
|
+
// Open into the specified InBot destID, returning a result tuple.
|
|
347
|
+
//
|
|
348
|
+
intop.open = closure open(inbotID) {
|
|
349
|
+
if intop.destroyed
|
|
350
|
+
return (list(Error("InTop already destroyed")))
|
|
351
|
+
if intop.instanceID {
|
|
352
|
+
if inbotID != intop.botDestID
|
|
353
|
+
return (list(Error("InTop already open")))
|
|
354
|
+
} else
|
|
355
|
+
intop.instanceID = UUID()
|
|
356
|
+
intop.botDestID = inbotID
|
|
357
|
+
intop.sender = App.imp.register(intop, {
|
|
358
|
+
name: options.name
|
|
359
|
+
type: options.type
|
|
360
|
+
instanceID: intop.instanceID
|
|
361
|
+
services: [ "naan-executor" ]
|
|
362
|
+
})
|
|
363
|
+
`(error) = intop.sender(intop.botDestID, {
|
|
364
|
+
id: "subscribe"
|
|
365
|
+
})
|
|
366
|
+
if error
|
|
367
|
+
return(list(error))
|
|
368
|
+
track.add(intop)
|
|
369
|
+
list(false, { ok: true })
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// finis
|
|
373
|
+
|
|
374
|
+
intop
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
/*
|
|
379
|
+
* instInit
|
|
380
|
+
*
|
|
381
|
+
* Initialize the component.
|
|
382
|
+
*
|
|
383
|
+
*/
|
|
384
|
+
|
|
385
|
+
function instInit(local manifest) {
|
|
386
|
+
manifest = `(InTop, InBot, instInit)
|
|
387
|
+
|
|
388
|
+
Naan.module.build(module.id, "instances", function(modobj, compobj) {
|
|
389
|
+
require("./executors.nlg")
|
|
390
|
+
require("./running.nlg")
|
|
391
|
+
compobj.manifest = manifest
|
|
392
|
+
modobj.exports.InTop = InTop
|
|
393
|
+
})
|
|
394
|
+
} ();
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* remote_req.nlg
|
|
3
|
+
* Naanlib/frameworks/running
|
|
4
|
+
*
|
|
5
|
+
* Requester for accessing remote services.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* RemoteRequester
|
|
16
|
+
*
|
|
17
|
+
* Return an executor proxy for the specified remote responder.
|
|
18
|
+
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* name: <string> // name
|
|
22
|
+
* type: <string> // type
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
closure RemoteRequester(destID, options, local track)
|
|
28
|
+
{
|
|
29
|
+
global(App)
|
|
30
|
+
|
|
31
|
+
// remoteReq
|
|
32
|
+
//
|
|
33
|
+
// Executes on our worker thread to return an execution instance that can be used to create a
|
|
34
|
+
// proxy for remote evaluation.
|
|
35
|
+
//
|
|
36
|
+
closure remoteReq(track, name, local target) {
|
|
37
|
+
target = ExecutorBase(false, "proxy", options.name)
|
|
38
|
+
target.instanceID = UUID()
|
|
39
|
+
|
|
40
|
+
target.sender = App.imp.register(target, {
|
|
41
|
+
name: options.name
|
|
42
|
+
type: options.type
|
|
43
|
+
instanceID: target.instanceID
|
|
44
|
+
services: [ "naan-remote-requester" ]
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
// impUnknown
|
|
48
|
+
//
|
|
49
|
+
// Received an unknown destination notice from the other side.
|
|
50
|
+
//
|
|
51
|
+
target.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
52
|
+
if !gateway
|
|
53
|
+
debuglog("MainThread.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// impReceive
|
|
57
|
+
//
|
|
58
|
+
// Received a payload from the other side.
|
|
59
|
+
//
|
|
60
|
+
target.impReceive = function impReceive(message, sourceID) {
|
|
61
|
+
if message.id == "targetout"
|
|
62
|
+
target.execReceived(message.data)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// PostMessage
|
|
66
|
+
//
|
|
67
|
+
// Post a message to the target.
|
|
68
|
+
//
|
|
69
|
+
target.PostMessage = function PostMessage(data) {
|
|
70
|
+
target.sender(destID, {
|
|
71
|
+
id: "targetin",
|
|
72
|
+
data: data
|
|
73
|
+
})
|
|
74
|
+
list(false, { posted: true })
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// destroy
|
|
78
|
+
//
|
|
79
|
+
// Terminate the proxy and all its works.
|
|
80
|
+
//
|
|
81
|
+
target.destroy = function destroy() {
|
|
82
|
+
App.imp.unregister(target.instanceID)
|
|
83
|
+
track.delete(target)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// finis
|
|
87
|
+
|
|
88
|
+
track.add(target)
|
|
89
|
+
list(false, target)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
options = merge({
|
|
93
|
+
name: "Remote Eval"
|
|
94
|
+
type: "Remote Requester"
|
|
95
|
+
}, options)
|
|
96
|
+
track = ExecutorTracker()
|
|
97
|
+
track.register(options.type, remoteReq)
|
|
98
|
+
track.spawn(options.type, options.name) // returns result tuple
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* MainThread
|
|
104
|
+
*
|
|
105
|
+
* Return an executor proxy for the main thread. Only usable in workers.
|
|
106
|
+
*
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
function MainThread()
|
|
110
|
+
{
|
|
111
|
+
global(App)
|
|
112
|
+
if !App.mainInstanceID
|
|
113
|
+
throw("MainThread can only be used in workers")
|
|
114
|
+
|
|
115
|
+
RemoteRequester(App.mainInstanceID, {
|
|
116
|
+
name: "MainThread"
|
|
117
|
+
type: "mainProxy"
|
|
118
|
+
})
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
* maithInit
|
|
124
|
+
*
|
|
125
|
+
* Initialize the component.
|
|
126
|
+
*
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
function remreqInit(local manifest) {
|
|
130
|
+
manifest = `(RemoteRequester, MainThread, remreqInit)
|
|
131
|
+
|
|
132
|
+
Naan.module.build(module.id, "remote_req", function(modobj, compobj) {
|
|
133
|
+
require("./executors.nlg")
|
|
134
|
+
require("../service/imp.nlg")
|
|
135
|
+
compobj.manifest = manifest
|
|
136
|
+
modobj.exports.RemoteRequester = RemoteRequester
|
|
137
|
+
modobj.exports.MainThread = MainThread
|
|
138
|
+
})
|
|
139
|
+
} ();
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* remote_res.nlg
|
|
3
|
+
* Naanlib/frameworks/running
|
|
4
|
+
*
|
|
5
|
+
* Responder for providing remote services.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* RemoteResponder
|
|
16
|
+
*
|
|
17
|
+
* Make a generic IMP remoting target with optional destID.
|
|
18
|
+
*
|
|
19
|
+
* Options:
|
|
20
|
+
* {
|
|
21
|
+
* name: <string> // name of this responder
|
|
22
|
+
* type: <string> // type of this responder
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
closure RemoteResponder(destID, options, local remo, name)
|
|
28
|
+
{
|
|
29
|
+
global(App)
|
|
30
|
+
options = merge({
|
|
31
|
+
name: "Remote Nub"
|
|
32
|
+
type: "Remote Responder"
|
|
33
|
+
}, options)
|
|
34
|
+
remo = ExecutorBase(App.nide.track, "remote-responder", name)
|
|
35
|
+
remo.dispatcher = TaskDispatcher(false, false, "RemoteResponder")
|
|
36
|
+
remo.instanceID = destID || UUID()
|
|
37
|
+
remo.sender = App.imp.register(remo, {
|
|
38
|
+
name: options.name
|
|
39
|
+
type: options.type
|
|
40
|
+
instanceID: remo.instanceID
|
|
41
|
+
services: [ "naan-remote-responder" ]
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// impUnknown
|
|
45
|
+
//
|
|
46
|
+
// Received an unknown destination notice from the other side.
|
|
47
|
+
//
|
|
48
|
+
remo.impUnknown = function impUnknown(unknownID, sourceID, gateway) {
|
|
49
|
+
if !gateway
|
|
50
|
+
debuglog("RemoteResponder.impUnknownID:", unknownID, "sourceID:", sourceID)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// impReceive
|
|
54
|
+
//
|
|
55
|
+
// Received a payload from the other side.
|
|
56
|
+
//
|
|
57
|
+
remo.impReceive = closure impReceive(message, sourceID) {
|
|
58
|
+
remo.dispatcher(message.data, function(reply) {
|
|
59
|
+
remo.sender(sourceID, {
|
|
60
|
+
id: "targetout",
|
|
61
|
+
data: reply
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// finis
|
|
67
|
+
|
|
68
|
+
remo
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* remresInit
|
|
74
|
+
*
|
|
75
|
+
* Initialize the component.
|
|
76
|
+
*
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
function remresInit(local manifest) {
|
|
80
|
+
manifest = `(RemoteResponder, remresInit)
|
|
81
|
+
|
|
82
|
+
Naan.module.build(module.id, "remote_res", function(modobj, compobj) {
|
|
83
|
+
require("./executors.nlg")
|
|
84
|
+
require("./taskexec.nlg")
|
|
85
|
+
require("../service/imp.nlg")
|
|
86
|
+
compobj.manifest = manifest
|
|
87
|
+
modobj.exports.RemoteResponder = RemoteResponder
|
|
88
|
+
})
|
|
89
|
+
} ();
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
closure CodeManager(options, local coman, cache)
|
|
26
26
|
{
|
|
27
27
|
coman = modlist().CLI.exports.Utils(options)
|
|
28
|
-
coman.independent = new(nonce) // caches are ephemeral
|
|
29
28
|
|
|
30
29
|
// composite
|
|
31
30
|
//
|
|
@@ -70,6 +69,8 @@ closure CodeManager(options, local coman, cache)
|
|
|
70
69
|
else
|
|
71
70
|
modname = "<".concat(sym.namespace.tostring, ">") // create independent module
|
|
72
71
|
compname = "<".concat(sym, ">") // create independent component
|
|
72
|
+
if !coman.independent
|
|
73
|
+
coman.independent = new(nonce) // ephemeral cache
|
|
73
74
|
coman.independent[modname.concat(":-:", compname)] = CodeComposite(coman, sym, modname, compname)
|
|
74
75
|
}
|
|
75
76
|
|
|
@@ -114,7 +115,7 @@ closure CodeManager(options, local coman, cache)
|
|
|
114
115
|
coman.cacheAdd = function cacheAdd(cocode, manifest, local item, mandefs) {
|
|
115
116
|
for item in manifest
|
|
116
117
|
push(item.proc, mandefs)
|
|
117
|
-
|
|
118
|
+
cache = new(nonce)
|
|
118
119
|
cache.modname = cocode.modname
|
|
119
120
|
cache.compname = cocode.compname
|
|
120
121
|
cache.mandefs = mandefs
|