@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,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* node_worker.js
|
|
3
|
+
* naanide
|
|
4
|
+
*
|
|
5
|
+
* Start a Naanide worker.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2017-2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/*
|
|
17
|
+
* Begin
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var workerData = require('node:worker_threads').workerData || { }; // passed from creator
|
|
22
|
+
var jspath = require("path");
|
|
23
|
+
var naanpath = jspath.resolve(require.resolve('@naanlang/naan'), '../../../');
|
|
24
|
+
var envpath = jspath.resolve(naanpath, 'lib/env_nodeworker.js');
|
|
25
|
+
var naanenv = require(envpath);
|
|
26
|
+
|
|
27
|
+
naanenv.NaanWorkerActivate(function(naanworker) {
|
|
28
|
+
naanworker.setRequire(require); // require relative to this file
|
|
29
|
+
naanworker.setImport(function(m) { return (import(m)); }); // import relative to this file
|
|
30
|
+
|
|
31
|
+
naanworker.textCommand(""
|
|
32
|
+
+ `App.naanpath = '${ naanpath.replace(/\\/g, "\\\\") }';;` // path/to/our naan library
|
|
33
|
+
+ "App.rootpath = js.d;;" // path/to/our package.json
|
|
34
|
+
+ "Naan.module.defineLoc('naanlib', App.naanpath);;" // defines "naanlib:" prefix for require
|
|
35
|
+
+ "Naan.module.nodeparse('lib/node_worker_init.nlg');;\n"); // Naan initialization
|
|
36
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* nide_worker_init.nlg
|
|
3
|
+
* NaanIDE
|
|
4
|
+
*
|
|
5
|
+
* Loaded automatically for Node.js before REPL turned over to the user.
|
|
6
|
+
*
|
|
7
|
+
* column positioning: // // !
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
10
|
+
*
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
loglevel(3);
|
|
15
|
+
chns("Start");
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/*
|
|
19
|
+
* Debugging & Tools
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
function init(local metadata) {
|
|
24
|
+
sprint() // no interruptions
|
|
25
|
+
if !module.owner.list.running.components.debugnub {
|
|
26
|
+
require("naanlib:frameworks/common/repltools.nlg").ImportReplTools()
|
|
27
|
+
require("naanlib:frameworks/running/debugnub.nlg").DebugNub()
|
|
28
|
+
}
|
|
29
|
+
App.shell = require("naanlib:frameworks/node/shell.nlg").ShellConnect({
|
|
30
|
+
cwd: js.d
|
|
31
|
+
})
|
|
32
|
+
metadata = new(js.t.metadata())
|
|
33
|
+
App.mainInstanceID = metadata.mainInstanceID
|
|
34
|
+
App.imp = require("naanlib:frameworks/service/imp.nlg").Imp({
|
|
35
|
+
name: metadata.name
|
|
36
|
+
type: "node-worker"
|
|
37
|
+
})
|
|
38
|
+
require("naanlib:frameworks/service/nubnode.nlg").NodeWorkerNub(App.imp, {
|
|
39
|
+
name: App.imp.us.name
|
|
40
|
+
})
|
|
41
|
+
if metadata.maintext
|
|
42
|
+
textparse(metadata.maintext)
|
|
43
|
+
}();
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2023 by Richard C. Zulch
|
|
9
|
+
* Copyright (c) 2023-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -53,6 +53,7 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
53
53
|
osin = new(object, this)
|
|
54
54
|
if symbol(indexName)
|
|
55
55
|
indexName = indexName.tostring()
|
|
56
|
+
osin.name = indexName
|
|
56
57
|
osin.analyzers = { // map names, language to analyzer
|
|
57
58
|
english: "english"
|
|
58
59
|
hashtag: "hashtag"
|
|
@@ -335,7 +336,7 @@ closure openSearchIndex(prosc, indexName, ioptions, local osin) {
|
|
|
335
336
|
`(error, data) = prosc.request(indexName.concat("/_bulk"), {
|
|
336
337
|
method: "POST"
|
|
337
338
|
putdata: docs
|
|
338
|
-
contentType: "application/
|
|
339
|
+
contentType: "application/x-ndjson"
|
|
339
340
|
})
|
|
340
341
|
if data
|
|
341
342
|
data = data.items.map(function(item) {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2023-
|
|
9
|
+
* Copyright (c) 2023-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
closure OSDynIndexer(index, table, options,
|
|
43
43
|
local dbOptions, scanPending, indexPending, updatePending, output, error, records, data, ids) {
|
|
44
|
+
global()
|
|
44
45
|
if !options.converter
|
|
45
46
|
return (Error("OSDynIndexer: options.converter is required"))
|
|
46
47
|
dbOptions = {
|
|
@@ -78,7 +79,7 @@ closure OSDynIndexer(index, table, options,
|
|
|
78
79
|
//
|
|
79
80
|
// Batch index documents into OpenSearch, returning a nonce signaled with ids array.
|
|
80
81
|
//
|
|
81
|
-
closure batchIndex(records, local pending) {
|
|
82
|
+
closure batchIndex(records, local pending, docs) {
|
|
82
83
|
pending = new(nonce)
|
|
83
84
|
docs = asyncArray(records, 10, closure(record) {
|
|
84
85
|
options.converter(record)
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
closure CloudWatchLogs(local cwlogs) {
|
|
21
|
+
closure CloudWatchLogs(local cwlogs, delayf, backoffMS) {
|
|
22
22
|
global(awsSDK)
|
|
23
23
|
cwlogs = new(object, this)
|
|
24
24
|
|
|
@@ -35,7 +35,42 @@ closure CloudWatchLogs(local cwlogs) {
|
|
|
35
35
|
})
|
|
36
36
|
list(false, { ok: true })
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
// retrier
|
|
40
|
+
//
|
|
41
|
+
// Perform exponential backoff when throttled, returning true for retry or false otherwise.
|
|
42
|
+
//
|
|
43
|
+
function retrier(error, local waitms, newbo) {
|
|
44
|
+
if !error
|
|
45
|
+
delayf = false
|
|
46
|
+
else if error.name == "ThrottlingException" { // retriable errors
|
|
47
|
+
if backoffMS > milliseconds() {
|
|
48
|
+
debuglog("DynaTable.retrier: existing backoff", backoffMS - milliseconds(), "msec")
|
|
49
|
+
return (true) // use existing backoff
|
|
50
|
+
}
|
|
51
|
+
if !delayf
|
|
52
|
+
delayf = ExbackFactory(6,60) // 6s max backoff, 60s deadline
|
|
53
|
+
waitms = delayf()
|
|
54
|
+
debuglog("DynaTable.retrier: new backoff:", waitms, "msec")
|
|
55
|
+
if waitms { // returns false for no retry
|
|
56
|
+
newbo = milliseconds() + waitms // tick when proceeding is allowed
|
|
57
|
+
if !(backoffMS > newbo)
|
|
58
|
+
backoffMS = newbo
|
|
59
|
+
true
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
38
63
|
|
|
64
|
+
// delayer
|
|
65
|
+
//
|
|
66
|
+
// Delay until the current backoff is complete.
|
|
67
|
+
//
|
|
68
|
+
function delayer(local waitms) {
|
|
69
|
+
waitms = backoffMS - milliseconds()
|
|
70
|
+
if waitms > 0
|
|
71
|
+
sleep(waitms + waitms * Math.random()/2)
|
|
72
|
+
}
|
|
73
|
+
|
|
39
74
|
//
|
|
40
75
|
// cwlQueryPager
|
|
41
76
|
//
|
|
@@ -46,7 +81,14 @@ closure CloudWatchLogs(local cwlogs) {
|
|
|
46
81
|
if !remaining
|
|
47
82
|
remaining = 10 // default retrieve limit
|
|
48
83
|
params.limit = remaining
|
|
49
|
-
|
|
84
|
+
delayer()
|
|
85
|
+
QueryPager(cwlogs.aws, procname, params, function(error, data, local processed) {
|
|
86
|
+
if error {
|
|
87
|
+
if !retrier(error)
|
|
88
|
+
return (false)
|
|
89
|
+
delayer()
|
|
90
|
+
return (true)
|
|
91
|
+
}
|
|
50
92
|
processed = doneCB(data)
|
|
51
93
|
if processed
|
|
52
94
|
remaining -= processed
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2021-
|
|
9
|
+
* Copyright (c) 2021-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -562,7 +562,7 @@ closure DynaConverter(local conv) {
|
|
|
562
562
|
*
|
|
563
563
|
*/
|
|
564
564
|
|
|
565
|
-
closure DynaTable(dyna, tablename, options, local table) {
|
|
565
|
+
closure DynaTable(dyna, tablename, options, local table, delayf, backoffMS) {
|
|
566
566
|
global()
|
|
567
567
|
table = new(object, this)
|
|
568
568
|
table.name = tablename
|
|
@@ -577,6 +577,38 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
577
577
|
debuglog("DynaTable: invalid (hashKey/rangeKey) option:", tablename, list(options.hashKey, options.rangeKey))
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
+
// retrier
|
|
581
|
+
//
|
|
582
|
+
// Perform exponential backoff when throttled, returning true for retry or false otherwise.
|
|
583
|
+
//
|
|
584
|
+
function retrier(error, local waitms, newbo) {
|
|
585
|
+
if !error
|
|
586
|
+
delayf = false
|
|
587
|
+
else if error.name == "ThrottlingException" { // retriable errors
|
|
588
|
+
if backoffMS > milliseconds()
|
|
589
|
+
return (true) // use existing backoff
|
|
590
|
+
if !delayf
|
|
591
|
+
delayf = ExbackFactory(6,60) // 6s max backoff, 60s deadline
|
|
592
|
+
waitms = delayf()
|
|
593
|
+
if waitms { // returns false for no retry
|
|
594
|
+
newbo = milliseconds() + waitms // tick when proceeding is allowed
|
|
595
|
+
if !(backoffMS > newbo)
|
|
596
|
+
backoffMS = newbo
|
|
597
|
+
true
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// delayer
|
|
603
|
+
//
|
|
604
|
+
// Delay until the current backoff is complete.
|
|
605
|
+
//
|
|
606
|
+
function delayer(local waitms) {
|
|
607
|
+
waitms = backoffMS - milliseconds()
|
|
608
|
+
if waitms > 0
|
|
609
|
+
sleep(waitms + waitms * Math.random()/2)
|
|
610
|
+
}
|
|
611
|
+
|
|
580
612
|
// info
|
|
581
613
|
//
|
|
582
614
|
// Return info about the table, or an error, in standard (error, dictionary) tuple format.
|
|
@@ -694,16 +726,24 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
694
726
|
KeyType: "RANGE"
|
|
695
727
|
})
|
|
696
728
|
}
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
error
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
729
|
+
|
|
730
|
+
loop {
|
|
731
|
+
pending = new(nonce)
|
|
732
|
+
delayer()
|
|
733
|
+
dyna.aws.createTable(params, function(error, data) {
|
|
734
|
+
if error {
|
|
735
|
+
dynaTableError = error
|
|
736
|
+
if error.name != "ThrottlingException"
|
|
737
|
+
debuglog("aws.createTable failed", tablename, ErrorString(error))
|
|
738
|
+
error = Error("table.create(".concat(tablename, ") failed"), error)
|
|
739
|
+
}
|
|
740
|
+
pending.signal(list(error, data))
|
|
741
|
+
})
|
|
742
|
+
`(error, data) = pending.wait()
|
|
743
|
+
if !retrier(error)
|
|
744
|
+
break
|
|
745
|
+
}
|
|
746
|
+
|
|
707
747
|
if error
|
|
708
748
|
return(list(Error("aws.createTable failed", error)))
|
|
709
749
|
start = milliseconds()
|
|
@@ -764,7 +804,8 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
764
804
|
// The result is a standard result tuple `(error, record).
|
|
765
805
|
|
|
766
806
|
//
|
|
767
|
-
table.getRecord = closure getRecord(hashValue, options,
|
|
807
|
+
table.getRecord = closure getRecord(hashValue, options,
|
|
808
|
+
local params, rangeValue, pending, error, record) {
|
|
768
809
|
if preflightError(this)
|
|
769
810
|
return
|
|
770
811
|
params = {
|
|
@@ -776,17 +817,25 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
776
817
|
} else
|
|
777
818
|
rangeValue = options
|
|
778
819
|
params.Key = makeDynKey(list(hashValue, rangeValue))
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
error
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
820
|
+
|
|
821
|
+
loop {
|
|
822
|
+
pending = new(nonce)
|
|
823
|
+
delayer()
|
|
824
|
+
dyna.aws.getItem(params, function(error, data) {
|
|
825
|
+
if error {
|
|
826
|
+
dynaTableError = error
|
|
827
|
+
if error.name != "ThrottlingException"
|
|
828
|
+
debuglog("aws.getItem failed", tablename, ErrorString(error))
|
|
829
|
+
error = Error("table.getRecord(".concat(tablename, ") failed"), error)
|
|
830
|
+
} else
|
|
831
|
+
data = dyna.conv.recordDynToNaan(data.Item)
|
|
832
|
+
pending.signal(list(error, data))
|
|
833
|
+
})
|
|
834
|
+
`(error, record) = pending.wait()
|
|
835
|
+
if !retrier(error)
|
|
836
|
+
break
|
|
837
|
+
}
|
|
838
|
+
list(error, record)
|
|
790
839
|
}
|
|
791
840
|
|
|
792
841
|
//
|
|
@@ -794,23 +843,32 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
794
843
|
//
|
|
795
844
|
// Put a record in the table, replacing any existing record with the same key.
|
|
796
845
|
|
|
797
|
-
table.putRecord = closure putRecord(record,
|
|
846
|
+
table.putRecord = closure putRecord(record,
|
|
847
|
+
local params, pending, error) {
|
|
798
848
|
if preflightError(this)
|
|
799
849
|
return
|
|
800
850
|
params = {
|
|
801
851
|
TableName: tablename
|
|
802
852
|
Item: dyna.conv.recordNaanToDyn(record)
|
|
803
853
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
error
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
854
|
+
|
|
855
|
+
loop {
|
|
856
|
+
pending = new(nonce)
|
|
857
|
+
delayer()
|
|
858
|
+
dyna.aws.putItem(params, function(error, data) {
|
|
859
|
+
if error {
|
|
860
|
+
dynaTableError = error
|
|
861
|
+
if error.name != "ThrottlingException"
|
|
862
|
+
debuglog("aws.putItem failed", tablename, ErrorString(error))
|
|
863
|
+
error = Error("table.putRecord(".concat(tablename, ") failed"), error)
|
|
864
|
+
}
|
|
865
|
+
pending.signal(list(error, data))
|
|
866
|
+
})
|
|
867
|
+
`(error, record) = pending.wait()
|
|
868
|
+
if !retrier(error)
|
|
869
|
+
break
|
|
870
|
+
}
|
|
871
|
+
list(error, record)
|
|
814
872
|
}
|
|
815
873
|
|
|
816
874
|
//
|
|
@@ -831,7 +889,7 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
831
889
|
// The result is a standard result tuple `(error, record).
|
|
832
890
|
|
|
833
891
|
table.updateRecord = closure updateRecord(hashValue, rangeValue, options,
|
|
834
|
-
local error, params, pending) {
|
|
892
|
+
local error, params, pending, record) {
|
|
835
893
|
if preflightError(this)
|
|
836
894
|
return
|
|
837
895
|
params = {
|
|
@@ -856,18 +914,25 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
856
914
|
if !params.ReturnValues
|
|
857
915
|
params.ReturnValues = "NONE"
|
|
858
916
|
}
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
917
|
+
loop {
|
|
918
|
+
pending = new(nonce)
|
|
919
|
+
delayer()
|
|
920
|
+
dyna.aws.updateItem(params, function(error, data) {
|
|
921
|
+
if error {
|
|
922
|
+
dynaTableError = error
|
|
923
|
+
if error.name != "ThrottlingException"
|
|
924
|
+
debuglog("aws.updateItem failed", tablename, ErrorString(error), Dialect.print(params))
|
|
925
|
+
error = Error("table.updateRecord(".concat(tablename, ") failed"), error)
|
|
926
|
+
}
|
|
927
|
+
else
|
|
928
|
+
data = dyna.conv.recordDynToNaan(data.Attributes)
|
|
929
|
+
pending.signal(list(error, data))
|
|
930
|
+
})
|
|
931
|
+
`(error, record) = pending.wait()
|
|
932
|
+
if !retrier(error)
|
|
933
|
+
break
|
|
934
|
+
}
|
|
935
|
+
list(error, record)
|
|
871
936
|
}
|
|
872
937
|
|
|
873
938
|
//
|
|
@@ -881,7 +946,7 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
881
946
|
|
|
882
947
|
|
|
883
948
|
table.deleteRecord = closure deleteRecord(hashValue, rangeValue, options,
|
|
884
|
-
local params, error, pending) {
|
|
949
|
+
local params, error, pending, record) {
|
|
885
950
|
if preflightError(this)
|
|
886
951
|
return
|
|
887
952
|
params = {
|
|
@@ -902,16 +967,25 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
902
967
|
if !params.ReturnValues
|
|
903
968
|
params.ReturnValues = "NONE"
|
|
904
969
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
error
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
970
|
+
|
|
971
|
+
loop {
|
|
972
|
+
pending = new(nonce)
|
|
973
|
+
delayer()
|
|
974
|
+
dyna.aws.deleteItem(params, function(error, data) {
|
|
975
|
+
if error {
|
|
976
|
+
dynaTableError = error
|
|
977
|
+
if error.name != "ThrottlingException"
|
|
978
|
+
debuglog("aws.deleteItem failed", tablename, ErrorString(error))
|
|
979
|
+
error = Error("table.deleteRecord(".concat(tablename, ") failed"), error)
|
|
980
|
+
}
|
|
981
|
+
pending.signal(list(error, data))
|
|
982
|
+
})
|
|
983
|
+
pending.wait()
|
|
984
|
+
`(error, record) = pending.wait()
|
|
985
|
+
if !retrier(error)
|
|
986
|
+
break
|
|
987
|
+
}
|
|
988
|
+
list(error, record)
|
|
915
989
|
}
|
|
916
990
|
|
|
917
991
|
//
|
|
@@ -922,16 +996,23 @@ closure DynaTable(dyna, tablename, options, local table) {
|
|
|
922
996
|
//
|
|
923
997
|
closure dynQueryPager(procname, params, remaining, doneCB) {
|
|
924
998
|
if !remaining
|
|
925
|
-
remaining = 10
|
|
999
|
+
remaining = 10 // default retrieve limit
|
|
926
1000
|
params.Limit = remaining
|
|
927
|
-
|
|
1001
|
+
delayer()
|
|
1002
|
+
QueryPager(dyna.aws, procname, params, function(error, data, local processed) {
|
|
1003
|
+
if error {
|
|
1004
|
+
if !retrier(error)
|
|
1005
|
+
return (false)
|
|
1006
|
+
delayer()
|
|
1007
|
+
return (true)
|
|
1008
|
+
}
|
|
928
1009
|
processed = doneCB(data)
|
|
929
1010
|
if processed
|
|
930
1011
|
remaining -= processed
|
|
931
1012
|
params.ExclusiveStartKey = data.LastEvaluatedKey
|
|
932
1013
|
if processed && remaining > 0 && data.LastEvaluatedKey {
|
|
933
|
-
params.Limit = remaining
|
|
934
|
-
true
|
|
1014
|
+
params.Limit = remaining // set up for next iteration
|
|
1015
|
+
true // continue looping
|
|
935
1016
|
}
|
|
936
1017
|
})
|
|
937
1018
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2021-
|
|
9
|
+
* Copyright (c) 2021-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -27,19 +27,14 @@ closure queryPager(apiobject, procname, params, xargs, doneCB, local pending, lo
|
|
|
27
27
|
return (list(Error("queryPager method undefined:", procname)))
|
|
28
28
|
pending = new(nonce)
|
|
29
29
|
looping = true
|
|
30
|
-
while looping { // loop for multiple pages
|
|
30
|
+
while looping { // loop for multiple pages or retry
|
|
31
31
|
pending.reset()
|
|
32
32
|
xapply(apiobject, procname, append(cons(params, xargs), cons(function (error, data) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
debuglog(procname, "failed", error)
|
|
36
|
-
looping = false
|
|
37
|
-
pending.signal(list(error))
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
looping = doneCB(data)
|
|
33
|
+
looping = doneCB(error, data)
|
|
34
|
+
if looping || !error
|
|
41
35
|
pending.signal(list(false, {ok: true}))
|
|
42
|
-
|
|
36
|
+
else
|
|
37
|
+
pending.signal(list(error))
|
|
43
38
|
})))
|
|
44
39
|
result = pending.wait()
|
|
45
40
|
}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2020-
|
|
9
|
+
* Copyright (c) 2020-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -23,7 +23,8 @@ function sawsInit(local manifest) {
|
|
|
23
23
|
|
|
24
24
|
Naan.module.build(module.id, "serviceAws", function(modobj, compobj) {
|
|
25
25
|
compobj.manifest = manifest
|
|
26
|
-
require("naanlib:frameworks/common")
|
|
26
|
+
require("naanlib:frameworks/common/utils.nlg") // get ExbackFactory
|
|
27
|
+
require("naanlib:frameworks/common").LiveImport() // applies to all exports
|
|
27
28
|
require("./aws_utils.nlg")
|
|
28
29
|
function sawsPostload() {
|
|
29
30
|
if js.g
|
|
@@ -100,7 +100,7 @@ closure NexaraSpeechRec(local nxspr) {
|
|
|
100
100
|
// Convert a Nexara response to a Yandex SpeechKit structure. Hey, it was first.
|
|
101
101
|
//
|
|
102
102
|
function nexaraToYCSK(resp,
|
|
103
|
-
local output, wordx, segment, chunk, word, wordet) {
|
|
103
|
+
local output, wordx, segment, chunk, syncerror, word, wordet, wordtrim, tstart) {
|
|
104
104
|
output = {
|
|
105
105
|
\@type: "type.googleapis.com/yandex.cloud.ai.stt.v2.LongRunningRecognitionResponse"
|
|
106
106
|
chunks: []
|
|
@@ -120,14 +120,18 @@ closure NexaraSpeechRec(local nxspr) {
|
|
|
120
120
|
]
|
|
121
121
|
}
|
|
122
122
|
for word in segment.text.split(" ") {
|
|
123
|
+
if word == ""
|
|
124
|
+
continue // ignore extra spaces
|
|
123
125
|
wordet = resp.words[wordx++]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
wordtrim = wordet.word.trim() // detected word without spaces
|
|
127
|
+
tstart = wordet.start.toFixed(3).concat("s")
|
|
128
|
+
if !syncerror && wordtrim != word {
|
|
129
|
+
syncerror = true
|
|
130
|
+
debuglog("nexaraToYCSK: warning: at ${tstart} expected '${word}' but got '${wordtrim}'")
|
|
127
131
|
}
|
|
128
132
|
chunk.alternatives.0.words.push({
|
|
129
|
-
word:
|
|
130
|
-
startTime:
|
|
133
|
+
word: wordtrim
|
|
134
|
+
startTime: tstart
|
|
131
135
|
endTime: wordet.end.toFixed(3).concat("s")
|
|
132
136
|
})
|
|
133
137
|
}
|
package/test/test_01_core.nlg
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* column positioning: // // !
|
|
8
8
|
*
|
|
9
|
-
* Copyright (c) 2017-
|
|
9
|
+
* Copyright (c) 2017-2026 by Richard C. Zulch
|
|
10
10
|
*
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -881,7 +881,7 @@ RegisterTestCategory("core", [
|
|
|
881
881
|
|
|
882
882
|
[ "unintern(true) === true", "false"],
|
|
883
883
|
|
|
884
|
-
[ "length(stacktrace());", "
|
|
884
|
+
[ "length(stacktrace());", "57" ],
|
|
885
885
|
|
|
886
886
|
//
|
|
887
887
|
// relate builtin
|