node-red-contrib-prib-functions 0.22.0 → 0.23.3
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/README.md +142 -92
- package/lib/AlphaBeta.js +32 -0
- package/lib/GraphDB.js +40 -9
- package/lib/MinMax.js +17 -0
- package/lib/Tree.js +64 -0
- package/lib/common.js +128 -0
- package/lib/objectExtensions.js +213 -80
- package/lib/timeDimension.js +36 -0
- package/lib/typedInput.js +77 -0
- package/matrix/matrixNode.html +2 -1
- package/package.json +15 -13
- package/test/00-objectExtensions.js +192 -1
- package/test/02-graphdb.js +46 -0
- package/test/data/.config.nodes.json +3 -3
- package/test/data/.config.nodes.json.backup +3 -3
- package/test/data/.config.users.json +3 -2
- package/test/data/.config.users.json.backup +3 -2
- package/test/data/.flow.json.backup +3875 -472
- package/test/data/flow.json +3874 -471
- package/test/data/package-lock.json +11 -11
- package/test/data/shares/.config.nodes.json +589 -0
- package/test/data/shares/.config.runtime.json +4 -0
- package/test/data/shares/.config.runtime.json.backup +3 -0
- package/test/data/shares/.config.users.json +32 -0
- package/test/data/shares/.config.users.json.backup +29 -0
- package/test/data/shares/.flow.json.backup +230 -0
- package/test/data/shares/.flow_cred.json.backup +3 -0
- package/test/data/shares/flow.json +267 -0
- package/test/data/shares/flow_cred.json +3 -0
- package/test/data/shares/package.json +6 -0
- package/test/data/shares/settings.js +544 -0
- package/testing/test.js +63 -29
- package/transform/transform.html +185 -20
- package/transform/transform.js +272 -265
- package/transform/xlsx2.js +74 -0
- package/visual/shapes/base..js +1 -0
- package/visual/visual.js +0 -0
- package/visual/visualNode.js +45 -0
package/README.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
[Node-Red][1] nodes for various functions:
|
|
4
4
|
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
5
|
+
* Data Analysis - statistical metrics that has real time option
|
|
6
|
+
* Matrix
|
|
7
|
+
* Transform
|
|
8
|
+
* Test
|
|
9
|
+
* Load Injector
|
|
10
|
+
* Monitor Flow
|
|
11
|
+
* append
|
|
12
|
+
* Spawn Process
|
|
13
|
+
* Host Available
|
|
14
|
+
* node.js os metrics
|
|
15
|
+
* Levenshtein Distance
|
|
16
16
|
|
|
17
17
|
------------------------------------------------------------
|
|
18
18
|
|
|
@@ -30,7 +30,8 @@ being outside 3 standard deviations from mean. This can be changed to median and
|
|
|
30
30
|
A set of data analysis functions that can be run over an array of data
|
|
31
31
|
|
|
32
32
|
Single value metrics:
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
* Autocorrelation
|
|
34
35
|
* Autocovariance
|
|
35
36
|
* Average/Mean
|
|
36
37
|
* Maximum
|
|
@@ -43,6 +44,7 @@ Single value metrics:
|
|
|
43
44
|
* Variance
|
|
44
45
|
|
|
45
46
|
Array metrics:
|
|
47
|
+
|
|
46
48
|
* Deltas
|
|
47
49
|
* Deltas Normalised
|
|
48
50
|
* difference
|
|
@@ -56,11 +58,11 @@ Array metrics:
|
|
|
56
58
|
* Standardization (Z-score Normalization)
|
|
57
59
|
|
|
58
60
|
Array data
|
|
59
|
-
|
|
61
|
+
|
|
62
|
+
* distances
|
|
60
63
|
* distance(s) minimum between points
|
|
61
64
|
* distance(s) maximum between points
|
|
62
65
|
|
|
63
|
-
|
|
64
66
|

|
|
65
67
|
|
|
66
68
|
example:
|
|
@@ -69,36 +71,33 @@ example:
|
|
|
69
71
|
|
|
70
72
|

|
|
71
73
|
|
|
72
|
-
|
|
73
74
|

|
|
74
75
|
|
|
75
|
-
|
|
76
76
|
------------------------------------------------------------
|
|
77
77
|
|
|
78
78
|
## Matrix
|
|
79
79
|
|
|
80
80
|
Define a matrix and perform various functions
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
82
|
+
* Define / Define Empty / Create / Create Like/ clone
|
|
83
|
+
* Add / Add Row to Row / Add to Cell / Add Row / Subtract Cell
|
|
84
|
+
* Multiple / Multiple Cell / Divide Cell / Divide Row
|
|
85
|
+
* Transpose
|
|
86
|
+
* Adjoint
|
|
87
|
+
* Cofactor
|
|
88
|
+
* Complement Minor
|
|
89
|
+
* Identity
|
|
90
|
+
* Inverse
|
|
91
|
+
* Determinant
|
|
92
|
+
* Backward Substitution
|
|
93
|
+
* Forward Elimination
|
|
94
|
+
* Gaussian Elimination
|
|
95
|
+
* Reduced Row EchelonForm
|
|
96
|
+
* Row Echelon Form
|
|
97
|
+
* Nearly Equals / Is Square / Get Cell
|
|
98
|
+
* Sum Row
|
|
99
|
+
* Swap Rows
|
|
100
|
+
* To Array Object
|
|
102
101
|
|
|
103
102
|

|
|
104
103
|
|
|
@@ -107,68 +106,118 @@ Define a matrix and perform various functions
|
|
|
107
106
|
## Transform
|
|
108
107
|
|
|
109
108
|
Translates a selected msg property to a target property.
|
|
110
|
-
Messages generates a message for each row or record.
|
|
109
|
+
Messages generates a message for each row or record.
|
|
111
110
|
|
|
112
111
|
Transformations:
|
|
113
112
|
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
113
|
+
* Array to
|
|
114
|
+
* CSV
|
|
115
|
+
* HTML
|
|
116
|
+
* ISO8385
|
|
117
|
+
* Messages
|
|
118
|
+
* xlsx / xlsx object (excel uses [xlsx][7])
|
|
119
|
+
* AVRO to JSON (uses [avsc][6])
|
|
120
|
+
* Buffer to compressed
|
|
121
|
+
* Confluence to JSON
|
|
122
|
+
* Compressed to
|
|
123
|
+
* Buffer
|
|
124
|
+
* String
|
|
125
|
+
* JSON
|
|
126
|
+
* CSV to
|
|
127
|
+
* Array
|
|
128
|
+
* HTML
|
|
129
|
+
* Messages
|
|
130
|
+
* CSVWithHeader to
|
|
131
|
+
* Array
|
|
132
|
+
* HTML
|
|
133
|
+
* JSON
|
|
134
|
+
* Date to
|
|
135
|
+
* is between
|
|
136
|
+
* ISO string
|
|
137
|
+
* locale string
|
|
138
|
+
* range limit
|
|
139
|
+
* ISO8385 to Array
|
|
140
|
+
* ISO8385 to JSON
|
|
141
|
+
* JSON to
|
|
142
|
+
* Array
|
|
143
|
+
* Confluence
|
|
144
|
+
* CSV
|
|
145
|
+
* AVRO (uses [avsc][6])
|
|
146
|
+
* ISO8385
|
|
147
|
+
* Messages
|
|
148
|
+
* String
|
|
149
|
+
* xlsx / xlsx object (excel uses [xlsx][7])
|
|
150
|
+
* XML (uses [fast-xml-parser][4])
|
|
151
|
+
* Number
|
|
152
|
+
* is between
|
|
153
|
+
* range limit
|
|
154
|
+
* path
|
|
155
|
+
* Basename
|
|
156
|
+
* Dirname
|
|
157
|
+
* Extname
|
|
158
|
+
* Format
|
|
159
|
+
* Is Absolute
|
|
160
|
+
* Join
|
|
161
|
+
* Parse
|
|
162
|
+
* Normalize
|
|
163
|
+
* Resolve
|
|
164
|
+
* snappy compress (uses [snappy][5], must install separately)
|
|
165
|
+
* snappy uncompress (uses [snappy][5], must install separately)
|
|
166
|
+
* String to
|
|
167
|
+
* Append
|
|
168
|
+
* Array By Delimiter
|
|
169
|
+
* At
|
|
170
|
+
* Camelize
|
|
171
|
+
* Capitalize
|
|
172
|
+
* Compressed
|
|
173
|
+
* Char At
|
|
174
|
+
* Char Code At"
|
|
175
|
+
* Code Point At
|
|
176
|
+
* Concat
|
|
177
|
+
* Date
|
|
178
|
+
* Delimiter On Case
|
|
179
|
+
* _ to space
|
|
180
|
+
* _ to space Capitilize
|
|
181
|
+
* Drop square bracket prefix
|
|
182
|
+
* Ends With
|
|
183
|
+
* Float
|
|
184
|
+
* Get Word
|
|
185
|
+
* Integer
|
|
186
|
+
* is Between
|
|
187
|
+
* Lower Case
|
|
188
|
+
* Number
|
|
189
|
+
* Prepend
|
|
190
|
+
* JSON
|
|
191
|
+
* Range Limit
|
|
192
|
+
* Split
|
|
193
|
+
* Starts With
|
|
194
|
+
* Timestamp
|
|
195
|
+
* Title
|
|
196
|
+
* Title Grammatical
|
|
197
|
+
* Trim
|
|
198
|
+
* Trim End
|
|
199
|
+
* Trim Start
|
|
200
|
+
* Upper Case
|
|
201
|
+
* Xml String Encode
|
|
202
|
+
|
|
203
|
+
* xlsx / xlsx object to array/JSON (excel uses [xlsx][7])
|
|
204
|
+
* XML to JSON (uses [fast-xml-parser][4])
|
|
156
205
|
|
|
157
206
|
Note, snappy needs to be installed separately as can have issues with auto install as build binaries.
|
|
158
207
|
|
|
159
208
|
With xlsx object one can use the function in [xlsx][7] against the object in functions node.
|
|
160
|
-
|
|
209
|
+
"
|
|
161
210
|
Example AVRO with schema
|
|
162
211
|
|
|
163
212
|

|
|
164
213
|
|
|
165
|
-
For Confluence schema contains a list of schemas in form {"
|
|
214
|
+
For Confluence schema contains a list of schemas in form {"\<schema id\>",\<schema\>}
|
|
166
215
|
|
|
167
216
|
------------------------------------------------------------
|
|
168
217
|
|
|
169
218
|
## Test
|
|
170
219
|
|
|
171
|
-
Allows a test case for a message to allow simple testing of nodes. Injects a new message via mouse or message. Message sent to first port which can be consumed by other nodes and returned back to node in a loop. The Test node then checks against detailed expected payload result.
|
|
220
|
+
Allows a test case for a message to allow simple testing of nodes. Injects a new message via mouse or message. Message sent to first port which can be consumed by other nodes and returned back to node in a loop. The Test node then checks against detailed expected payload result.
|
|
172
221
|
|
|
173
222
|

|
|
174
223
|
|
|
@@ -209,11 +258,11 @@ Inject messages for a set period of time with varying think time.
|
|
|
209
258
|
Primary purpose is testing and useful for load/stress testing.
|
|
210
259
|
|
|
211
260
|
Has 3 extra data types
|
|
261
|
+
|
|
212
262
|
1. generated id - Unique id for each message
|
|
213
263
|
2. generated data - string text generated using [dummy-json][3]
|
|
214
264
|
3. generated json - json generated using [dummy-json][3]
|
|
215
265
|
|
|
216
|
-
|
|
217
266
|

|
|
218
267
|
|
|
219
268
|
Test example:
|
|
@@ -249,7 +298,7 @@ Test example:
|
|
|
249
298
|
|
|
250
299
|
------------------------------------------------------------
|
|
251
300
|
|
|
252
|
-
## Monitor System
|
|
301
|
+
## Monitor System
|
|
253
302
|
|
|
254
303
|
System monitoring metrics
|
|
255
304
|
|
|
@@ -279,7 +328,7 @@ Spawn process as per node.js manual with ability to set working directory, envir
|
|
|
279
328
|
and argument passed to process. STDOUT and STDERR are sent as individual messages.
|
|
280
329
|
RC port is sent a message on closure.
|
|
281
330
|
Takes in messages that starts a process with ability to add environment values.
|
|
282
|
-
Message can be sent to kill the process.
|
|
331
|
+
Message can be sent to kill the process.
|
|
283
332
|
|
|
284
333
|

|
|
285
334
|
|
|
@@ -289,19 +338,23 @@ Test example:
|
|
|
289
338
|
|
|
290
339
|
------------------------------------------------------------
|
|
291
340
|
|
|
292
|
-
|
|
341
|
+
## Install
|
|
293
342
|
|
|
294
343
|
Run the following command in the root directory of your Node-RED install
|
|
295
344
|
|
|
296
345
|
npm install node-red-contrib-prib-functions
|
|
297
346
|
|
|
298
|
-
|
|
347
|
+
## Tests
|
|
299
348
|
|
|
300
349
|
Test/example flow in test/generalTest.json
|
|
301
350
|
|
|
302
351
|
------------------------------------------------------------
|
|
303
352
|
|
|
304
|
-
|
|
353
|
+
## Version
|
|
354
|
+
|
|
355
|
+
0.23.3 Removes bug in test, more translation
|
|
356
|
+
|
|
357
|
+
0.23.0 Removes bug in test, more translation
|
|
305
358
|
|
|
306
359
|
0.22.0 Add autocovariance + autocorealationship to real time data analystics, improves test
|
|
307
360
|
|
|
@@ -315,8 +368,7 @@ Test/example flow in test/generalTest.json
|
|
|
315
368
|
|
|
316
369
|
0.17.0 Add finished wire to load injector
|
|
317
370
|
|
|
318
|
-
|
|
319
|
-
# Author
|
|
371
|
+
## Author
|
|
320
372
|
|
|
321
373
|
[Peter Prib][3]
|
|
322
374
|
|
|
@@ -333,5 +385,3 @@ Test/example flow in test/generalTest.json
|
|
|
333
385
|
[6]: https://www.npmjs.com/package/avsc "avsc"
|
|
334
386
|
|
|
335
387
|
[7]: https://www.npmjs.com/package/xlsx "xlsx"
|
|
336
|
-
|
|
337
|
-
[8]: https://www.npmjs.com/package/dummy-json "dummy-json"
|
package/lib/AlphaBeta.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
function alphabeta(node, depth,
|
|
2
|
+
isTerminalNode=node=>node.children.lenght==0 ,
|
|
3
|
+
forEachChild=call=>this.children.forEach(c=>call(c)),
|
|
4
|
+
getHeuristicValue=node=>node.value,
|
|
5
|
+
alpha=-Infinity, beta=Infinity,
|
|
6
|
+
maximizingPlayer=true
|
|
7
|
+
){
|
|
8
|
+
if( depth == 0 || isTerminalNode(node)) return getHeuristicValue (node)
|
|
9
|
+
const notMaximizingPlayer=!maximizingPlayer
|
|
10
|
+
const minMaxFunction=maximizingPlayer?Math.max:Math.min
|
|
11
|
+
let value=Infinity*(maximizingPlayer?-1:1)
|
|
12
|
+
let loopFunction=maximizingPlayer?
|
|
13
|
+
child=>{
|
|
14
|
+
value = minMaxFunction(value,
|
|
15
|
+
minimax(child,depth-1,isTerminalNode,forEachChild,getHeuristicValue ,alpha, beta, notMaximizingPlayer))
|
|
16
|
+
if(value >= beta ) throw Error("break")
|
|
17
|
+
else alpha = minMaxFunction(alpha, value)
|
|
18
|
+
}:child=>{
|
|
19
|
+
value = minMaxFunction(value,
|
|
20
|
+
minimax(child,depth-1,isTerminalNode,forEachChild,getHeuristicValue ,alpha, beta, notMaximizingPlayer))
|
|
21
|
+
if(value <= alpha) throw Error("break")
|
|
22
|
+
beta = minMaxFunction(beta, value)
|
|
23
|
+
}
|
|
24
|
+
try{
|
|
25
|
+
forEachChild(loopFunction)
|
|
26
|
+
} catch(ex){
|
|
27
|
+
if(ex.message!=="break") throw ex
|
|
28
|
+
}
|
|
29
|
+
return value
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports=alphabeta
|
package/lib/GraphDB.js
CHANGED
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
require("../lib/objectExtensions")
|
|
2
|
+
function Edge(from,to,properties){
|
|
3
|
+
if(!from) throw Error("from vertix is not defined")
|
|
4
|
+
if(!to) throw Error("to vertix is not defined")
|
|
5
|
+
if(!from instanceof Vertex) throw Error("from not type Vertex")
|
|
6
|
+
if(!to instanceof Vertex) throw Error("to not type Vertex")
|
|
7
|
+
Object.assign(this,{_from:from,_to:to},properties)
|
|
8
|
+
from.addTo(this)
|
|
9
|
+
to.addFrom(this)
|
|
10
|
+
}
|
|
11
|
+
function Vertex(properties){
|
|
12
|
+
Object.assign(this,{_to:[],_from:[]},properties)
|
|
13
|
+
}
|
|
14
|
+
Vertex.prototype.addTo=function(r){
|
|
15
|
+
this._to.push(r)
|
|
16
|
+
}
|
|
17
|
+
Vertex.prototype.addFrom=function(r){
|
|
18
|
+
this._from.push(r)
|
|
19
|
+
}
|
|
2
20
|
function GraphDB(properties){
|
|
3
|
-
|
|
4
|
-
|
|
21
|
+
Object.assign(this,{vertices:[],edges:[]},properties)
|
|
22
|
+
}
|
|
23
|
+
GraphDB.prototype.addEdge=function(from,to,properties) {
|
|
24
|
+
const edge=new Edge(from,to,properties)
|
|
25
|
+
this.edges.push(edge)
|
|
26
|
+
return edge
|
|
27
|
+
}
|
|
28
|
+
GraphDB.prototype.addVertex=function(vertexDetails) {
|
|
29
|
+
const vertex=new Vertex(vertexDetails)
|
|
30
|
+
this.vertices.push(vertex)
|
|
31
|
+
return vertex
|
|
32
|
+
}
|
|
33
|
+
GraphDB.prototype.getEdgesCount=function() {
|
|
34
|
+
return this.edges.length
|
|
35
|
+
}
|
|
36
|
+
GraphDB.prototype.getVerticesCount=function() {
|
|
37
|
+
return this.vertices.length
|
|
5
38
|
}
|
|
6
|
-
GraphDB.prototype.
|
|
7
|
-
|
|
39
|
+
GraphDB.prototype.getVertices=function(filterFunction) {
|
|
40
|
+
return this.vertices.filter(filterFunction)
|
|
8
41
|
}
|
|
9
|
-
GraphDB.prototype.
|
|
10
|
-
|
|
42
|
+
GraphDB.prototype.getEdges=function(filterFunction) {
|
|
43
|
+
return this.Edges.filter(filterFunction)
|
|
11
44
|
}
|
|
12
|
-
|
|
13
|
-
this.addErrorFunctions()
|
|
14
|
-
module.exports=GraphDB
|
|
45
|
+
module.exports=GraphDB
|
package/lib/MinMax.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
function minimax(node, depth,
|
|
2
|
+
isTerminalNode=node=>node.children.lenght==0 ,
|
|
3
|
+
forEachChild=call=>this.children.forEach(c=>call(c)),
|
|
4
|
+
getHeuristicValue =node=>node.value,
|
|
5
|
+
maximizingPlayer=true
|
|
6
|
+
){
|
|
7
|
+
if( depth == 0 || isTerminalNode(node)) return getHeuristicValue (node)
|
|
8
|
+
const notMaximizingPlayer=!maximizingPlayer
|
|
9
|
+
const minMaxFunction=maximizingPlayer?Math.max:Math.min
|
|
10
|
+
let value=Infinity*(maximizingPlayer?-1:1)
|
|
11
|
+
forEachChild(child=> value = minMaxFunction(value,
|
|
12
|
+
minimax(child,depth-1,isTerminalNode,forEachChild,getHeuristicValue ,notMaximizingPlayer))
|
|
13
|
+
)
|
|
14
|
+
return value
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports=minimax
|
package/lib/Tree.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
function Level(parent,...children){
|
|
2
|
+
this.children=children
|
|
3
|
+
this.setBTree(10)
|
|
4
|
+
}
|
|
5
|
+
function Leaf(parent,value){
|
|
6
|
+
this.values=[]
|
|
7
|
+
}
|
|
8
|
+
Leaf.prototype.find=function(value,foundCall,notFoundCall=foundCall,notFoundAllCall=v=>notFoundCall(0,v)){
|
|
9
|
+
let i=this.keys.length
|
|
10
|
+
const key=this.getKey(value)
|
|
11
|
+
while (i >= 0){
|
|
12
|
+
const currentKey=this.getKey(this.values[i])
|
|
13
|
+
if(key>currentKey) return notFoundCall(i,key)
|
|
14
|
+
if(key==currentKey) return foundCall(i,key)
|
|
15
|
+
i--
|
|
16
|
+
}
|
|
17
|
+
notFoundAllCall(key)
|
|
18
|
+
}
|
|
19
|
+
Leaf.prototype.getKey=function(node){return node}
|
|
20
|
+
Leaf.prototype.insert=function(value){
|
|
21
|
+
const _this=this
|
|
22
|
+
this.find(value,i=>_this.values.splice(i, 0, value))
|
|
23
|
+
}
|
|
24
|
+
function Tree (root=new Level(null)){
|
|
25
|
+
this.root=root
|
|
26
|
+
}
|
|
27
|
+
Tree.prototype.setDegree=function(v){this.degree=v}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
Tree.prototype.insert(key,value) {
|
|
32
|
+
const root = this.root;
|
|
33
|
+
if(root.keys.length === (2 * this.degree - 1)) { // Root is full
|
|
34
|
+
const newRoot = new BTreeNode(false);
|
|
35
|
+
newRoot.children.push(root);
|
|
36
|
+
this.splitChild(newRoot, 0, root);
|
|
37
|
+
this.root = newRoot;
|
|
38
|
+
this.insertNonFull(newRoot, key);
|
|
39
|
+
} else {
|
|
40
|
+
this.insertNonFull(root, key);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Tree.prototype.insertNonFull(node, key) {
|
|
45
|
+
let i = node.keys.length - 1;
|
|
46
|
+
if (node.isLeaf) {
|
|
47
|
+
|
|
48
|
+
} else {
|
|
49
|
+
while (i >= 0 && key < node.keys[i]) {
|
|
50
|
+
i--;
|
|
51
|
+
}
|
|
52
|
+
i++;
|
|
53
|
+
if (node.children[i].keys.length === (2 * this.degree - 1)) {
|
|
54
|
+
this.splitChild(node, i, node.children[i]);
|
|
55
|
+
if (key > node.keys[i]) {
|
|
56
|
+
i++;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
this.insertNonFull(node.children[i], key);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
module.exports=Tree
|
package/lib/common.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const error=(node,message,shortMessage,logger)=>{
|
|
2
|
+
if(logger && logger.active) logger.send({label:"error",node:node.id,error:error,shortMessage});
|
|
3
|
+
node.error(message);
|
|
4
|
+
node.status({fill:"red",shape:"ring",text:shortMessage});
|
|
5
|
+
}
|
|
6
|
+
const evalFunction(id,mapping,logger)=>{
|
|
7
|
+
logger&&logger.sendInfo({label:"evalFunction",id:id,mapping:mapping})
|
|
8
|
+
try{
|
|
9
|
+
return eval(mapping);
|
|
10
|
+
} catch(ex) {
|
|
11
|
+
logger.sendError({label:"evalFunction error",id:id,mapping:mapping,error:ex.message})
|
|
12
|
+
throw Error(id+" "+ex.message);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const evalInFunction=(node,propertyName)=>{
|
|
16
|
+
try{
|
|
17
|
+
const nodeContext = node.context();
|
|
18
|
+
const flow = nodeContext.flow;
|
|
19
|
+
const global = nodeContext.global;
|
|
20
|
+
const property=node[propertyName];
|
|
21
|
+
if(property==null) throw Error("no value for "+propertyName);
|
|
22
|
+
const propertyType=propertyName+"-type";
|
|
23
|
+
if(! (propertyType in node)) return evalFunction(propertyName,"()=>node."+property)
|
|
24
|
+
switch (node[propertyType]){
|
|
25
|
+
case "num":
|
|
26
|
+
case "json":
|
|
27
|
+
return evalFunction(propertyName,"()=>"+property);
|
|
28
|
+
case "node":
|
|
29
|
+
return evalFunction(propertyName,"()=>nodeContext.get("+property+")");
|
|
30
|
+
case "flow":
|
|
31
|
+
if(flow) throw Error("context store may be memoryonly so flow doesn't work")
|
|
32
|
+
return evalFunction(propertyName,"()=>flow.get("+property+")");
|
|
33
|
+
case "global":
|
|
34
|
+
return evalFunction(propertyName,"()=>global.get("+property+")");
|
|
35
|
+
case "env":
|
|
36
|
+
return evalFunction(propertyName,"()=>env.get("+property+")");
|
|
37
|
+
case "msg":
|
|
38
|
+
return evalFunction(propertyName,"(msg)=>msg."+property);
|
|
39
|
+
default:
|
|
40
|
+
logger.sendInfo({label:"setData unknown type",action:node.action,propertyType:propertyType,type:node[propertyType]});
|
|
41
|
+
throw Error("unknown type "+node[propertyType])
|
|
42
|
+
}
|
|
43
|
+
} catch(ex) {
|
|
44
|
+
logger.sendError({label:"setup",error:ex.message,stack:ex.stack});
|
|
45
|
+
throw Error(property+" "+ex.message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const argsArray=(node,msg)=>{
|
|
50
|
+
const args=[];
|
|
51
|
+
node.argFunction.forEach(callFunction=> {
|
|
52
|
+
const result=callFunction(msg);
|
|
53
|
+
args.push(result);
|
|
54
|
+
});
|
|
55
|
+
return args;
|
|
56
|
+
}
|
|
57
|
+
const setArgsFunction=(node)=>{
|
|
58
|
+
node.argFunction=[];
|
|
59
|
+
node.args.forEach(property=>{
|
|
60
|
+
try{
|
|
61
|
+
node.argFunction.push(evalInFunction(node,property).bind(this));
|
|
62
|
+
} catch(ex) {
|
|
63
|
+
throw Error("args "+property+" "+ex.message)
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
const setTargetFunction=(node)=>{
|
|
70
|
+
if(node.target) throw Error("target is null")
|
|
71
|
+
if(node.hasOwnProperty("target-type")) {
|
|
72
|
+
node.setData=evalFunction("target","data=>data)")
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
const nodeContext = node.context()
|
|
76
|
+
const type=node["target-type"]
|
|
77
|
+
switch(type){
|
|
78
|
+
case "node":
|
|
79
|
+
node.setData=evalFunction("target","data=>nodeContext.set("+node.target+",data)")
|
|
80
|
+
break
|
|
81
|
+
case "flow":
|
|
82
|
+
if(nodeContext.flow) throw Error("context store may be memory only so flow doesn't work")
|
|
83
|
+
node.setData=evalFunction("target","data=>nodeContext.flow.set("+node.target+",data)")
|
|
84
|
+
break
|
|
85
|
+
case "global":
|
|
86
|
+
node.setData=evalFunction("target","data=>nodeContext.global.set("+node.target+",data)")
|
|
87
|
+
break
|
|
88
|
+
case "msg":
|
|
89
|
+
node.setData=evalFunction("target","(data,msg)=>{msg."+node.target+"=data;}")
|
|
90
|
+
break
|
|
91
|
+
default:
|
|
92
|
+
throw Error("setData unknown type "+type)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const baseProcess=(msg,call=sourceMatrix[node.action])=>{
|
|
97
|
+
const value=node.getSource(msg);
|
|
98
|
+
if(value==null) throw Error("source data not found");
|
|
99
|
+
const valueObject=(value instanceof Matrix?value:new Matrix(value));
|
|
100
|
+
return call.apply(valueObject,argsArray(node,msg));
|
|
101
|
+
}
|
|
102
|
+
const baseProcessAndSet=(msg)=>{
|
|
103
|
+
const result=baseProcess(msg);
|
|
104
|
+
node.setData.apply(node,[result,msg]);
|
|
105
|
+
}
|
|
106
|
+
function createProcess(msg){
|
|
107
|
+
const sourceMatrix=new Matrix({rowsMax:node.rows,columns:node.columns,dataType:node.dataType});
|
|
108
|
+
if(!(node.initialState in sourceMatrix)) throw Error("Invalid initial state "+node.initialState);
|
|
109
|
+
sourceMatrix[node.initialState]()
|
|
110
|
+
node.setData.apply(node,[sourceMatrix,msg]);
|
|
111
|
+
}
|
|
112
|
+
function defineProcess(msg){
|
|
113
|
+
const sourceMatrix=new Matrix({rows:node.rows,columns:node.columns,dataType:node.dataType});
|
|
114
|
+
node.setData.apply(node,[sourceMatrix,msg]);
|
|
115
|
+
}
|
|
116
|
+
function defineEmptyProcess(msg){
|
|
117
|
+
if(logger.active) logger.sendInfo({label:"define",arg:{rowsMax:node.row,columns:node.column}});
|
|
118
|
+
const sourceMatrix=new Matrix({rowsMax:node.rows,columns:node.columns});
|
|
119
|
+
node.setData.apply(node,[sourceMatrix,msg]);
|
|
120
|
+
}
|
|
121
|
+
function createSize(msg){
|
|
122
|
+
const sourceMatrix=new Matrix({rows:node.size,columns:node.size});
|
|
123
|
+
node.setData.apply(node,[sourceMatrix[node.action](),msg]);
|
|
124
|
+
}
|
|
125
|
+
function createDummy(msg){
|
|
126
|
+
const sourceMatrix=new Matrix(1,1);
|
|
127
|
+
node.setData.apply(node,[sourceMatrix[node.action].apply(sourceMatrix,argsArray(node,msg)),msg]);
|
|
128
|
+
}
|