@gregoriusrippenstein/node-red-contrib-introspection 0.8.1 → 0.8.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 +12 -0
- package/nodes/60-client-code.html +40 -0
- package/nodes/60-client-code.js +6 -0
- package/package.json +1 -1
- package/plugins/sidebar.html +41 -18
package/README.md
CHANGED
|
@@ -78,6 +78,18 @@ Sidebar for visually obfuscating flows:
|
|
|
78
78
|
|
|
79
79
|
The plugin replaces the name with the node Id, resets the nodes info content to empty and moves all nodes to the same location. The intention is to having a *working* flow but not an *understandable* flow. The generated flow is meant to be only usable and not modifiable nor maintainable.
|
|
80
80
|
|
|
81
|
+
### Message tracing
|
|
82
|
+
|
|
83
|
+
Sometimes it would be nice to observe the flow of messages through a flow. This is possible by using 'Trace Messages' found at the bottom of the 'Lint' tab:
|
|
84
|
+
|
|
85
|
+

|
|
86
|
+
|
|
87
|
+
Message tracing can be toggled on & off *without* redeploying the flow. So this can be used as a quick check for observing tricky situation.
|
|
88
|
+
|
|
89
|
+
The nodes status will be replaced by 'msg received', so if the status should be showing something else, that is lost.
|
|
90
|
+
|
|
91
|
+
Also this is an experimental feature liable to be [improved](https://discourse.nodered.org/t/message-tracing-for-beginners/92287).
|
|
92
|
+
|
|
81
93
|
## Palette Nodes
|
|
82
94
|
|
|
83
95
|
### Sink & Seeker
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
2
|
|
|
3
|
+
RED.comms.subscribe('msgtracer:node-received', (event,data) => {
|
|
4
|
+
if ( data.nodeid) {
|
|
5
|
+
let node = RED.nodes.node(data.nodeid)
|
|
6
|
+
let olddata = $("#node-input-msgtracer-trace-treelist").treeList('data')
|
|
7
|
+
let foundItem = false;
|
|
8
|
+
|
|
9
|
+
olddata.forEach( itm => {
|
|
10
|
+
if ( itm.id == node.id ) {
|
|
11
|
+
foundItem = true
|
|
12
|
+
itm.sublabel = "" + (parseInt(itm.sublabel) + 1)
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
if ( !foundItem ) {
|
|
17
|
+
let nodeDef = RED.nodes.getType(node.type);
|
|
18
|
+
let label;
|
|
19
|
+
|
|
20
|
+
if (nodeDef) {
|
|
21
|
+
let l = nodeDef.label;
|
|
22
|
+
label = (typeof l === "function" ? l.call(node) : l) || node.type;
|
|
23
|
+
} else {
|
|
24
|
+
label = node.type
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let newitem = {
|
|
28
|
+
id: node.id,
|
|
29
|
+
label: label,
|
|
30
|
+
sublabel: "1",
|
|
31
|
+
selected: false,
|
|
32
|
+
checkbox: false,
|
|
33
|
+
node: node
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
$("#node-input-msgtracer-trace-treelist").treeList('data',[newitem, ...olddata])
|
|
37
|
+
} else {
|
|
38
|
+
$("#node-input-msgtracer-trace-treelist").treeList('data',olddata)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
|
|
3
43
|
RED.comms.subscribe('introspect:client-code-perform', (event,data) => {
|
|
4
44
|
if ( data.msg == "execfunc" ) {
|
|
5
45
|
|
package/nodes/60-client-code.js
CHANGED
|
@@ -10,6 +10,12 @@ module.exports = function(RED) {
|
|
|
10
10
|
let nde = RED.nodes.getNode(evnt.destination.id)
|
|
11
11
|
nde.status({ fill: "green", shape: "ring", text: "msg received" })
|
|
12
12
|
setTimeout(() => { nde.status({}) }, 1000)
|
|
13
|
+
|
|
14
|
+
RED.comms.publish("msgtracer:node-received",
|
|
15
|
+
RED.util.encodeObject({
|
|
16
|
+
nodeid: evnt.destination.id
|
|
17
|
+
})
|
|
18
|
+
)
|
|
13
19
|
} catch (ex) {
|
|
14
20
|
console.error(ex)
|
|
15
21
|
}
|
package/package.json
CHANGED
package/plugins/sidebar.html
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
function setupTreelistAllLinksForLinkIn(e){e=collectAllLinksNodes(e);if(0==e.length){RED.notify("No links found",{type:"error",timeout:2e3});try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){}}else{try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var n;t.node&&(n=t.node.id,setTimeout(()=>{var e=RED.nodes.node(n);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e,"editor-tab-description")),n==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e.sort((e,t)=>e.node.z>t.node.z))}}function collectAllLinksNodes(t){let n=[];RED.nodes.eachNode(e=>{"link call"!=e.type&&"link out"!=e.type||-1<e.links.indexOf(t)&&n.push(e)});var i=[],r={};return n.forEach(function(e){var t=RED.nodes.getType(e.type);if(t){var n,o=t.label,o=("function"==typeof o?o.call(e):o)||"";if(0===(n=e.type).indexOf("subflow:"))return}t&&o||(o=e.type),r[e.id]={node:e,label:o,sublabel:n,selected:!1,checkbox:!1},i.push(r[e.id])}),i}function collectNodeStats(){let t={},n=[],o={workspaces:0,junctions:0,subflows:0,configs:0,groups:0,wires:0,nodes:0},i=(RED.nodes.eachConfig(e=>{o.configs+=1}),RED.nodes.eachLink(e=>{o.wires+=1}),RED.nodes.eachJunction(e=>{o.junctions+=1}),RED.nodes.eachGroup(e=>{o.groups+=1}),RED.nodes.eachWorkspace(e=>{o.workspaces+=1}),RED.nodes.eachSubflow(e=>{o.subflows+=1}),RED.nodes.eachNode(e=>{o.nodes+=1,t[e.type]=(t[e.type]||0)+1}),Object.keys(t).forEach(e=>{n.push({label:e,sublabel:t[e],selected:!1,checkbox:!1})}),[]),r=0;return Object.keys(o).forEach(e=>{r+=o[e],i.push({label:e,sublabel:o[e],selected:!1,checkbox:!1})}),[{label:"__ TOTALS",sublabel:r,selected:!1,checkbox:!1,children:i}].concat(n.sort((e,t)=>e.label>t.label))}function setupTreeListForNodeStats(){var e=collectNodeStats();try{$("#node-input-orphan-target-container-div").treeList("empty")}catch(e){$("#node-input-orphan-target-container-div").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){}).on("treelistconfirm",function(e,t){}),$("#node-input-orphan-target-filter").show();var n=$("#node-input-orphan-target-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-orphan-target-container-div").treeList("filter",null),n.searchBox("count","")):(e=$("#node-input-orphan-target-container-div").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)}),n.searchBox("count",e+" / "+$("#node-input-orphan-target-container-div").treeList("data").length))}})}$("#node-input-orphan-target-container-div").treeList("data",e)}
|
|
16
16
|
|
|
17
|
+
function setupTreeMsgTracerlist(){try{$("#node-input-msgtracer-trace-treelist").treeList("empty"),$("#node-input-msgtracer-trace-treelist").treeList("data",[])}catch(e){$("#node-input-msgtracer-trace-treelist").css({width:"100%",height:"calc(100%)"}).treeList({multi:!1}).on("treelistitemmouseover",function(e,t){}).on("treelistitemmouseout",function(e,t){}).on("treelistselect",function(e,t){t.node&&(RED.workspaces.show(t.node.z,!1,!1,!0),RED.view.reveal(t.node.id,!0),RED.view.redraw())}).on("treelistconfirm",function(e,t){var r;t.node&&(r=t.node.id,setTimeout(()=>{var e=RED.nodes.node(r);e&&(RED.view.reveal(e.id),RED.view.select(e.id),RED.editor.edit(e)),r==RED.workspaces.active()&&RED.workspaces.edit()},50))}),$("#node-input-msgtracer-trace-treelist-filter").show();var r=$("#node-input-msgtracer-trace-treelist-filter").searchBox({style:"compact",delay:300,change:function(){var e,t=$(this).val().trim().toLowerCase();""===t?($("#node-input-msgtracer-trace-treelist").treeList("filter",null),r.searchBox("count","")):(e=$("#node-input-msgtracer-trace-treelist").treeList("filter",function(e){return-1<e.label.toLowerCase().indexOf(t)||-1<e.node.type.toLowerCase().indexOf(t)}),r.searchBox("count",e+" / "+$("#node-input-msgtracer-trace-treelist").treeList("data").length))}})}}
|
|
18
|
+
|
|
17
19
|
// Add your plugin as a new tabsheet in the right sidebar AFTER the flow editor is completely started
|
|
18
20
|
var initialiseConfigNodeOnce = () => {
|
|
19
21
|
RED.events.off('runtime-state', initialiseConfigNodeOnce);
|
|
@@ -238,26 +240,37 @@
|
|
|
238
240
|
$('.red-ui-linkcall-link-indicator').remove()
|
|
239
241
|
})
|
|
240
242
|
|
|
243
|
+
$('#node-input-msgtrace-clear-trace-btn').on('click', (e) => {
|
|
244
|
+
if ( e ) { e.preventDefault() }
|
|
245
|
+
setupTreeMsgTracerlist()
|
|
246
|
+
$("#node-input-msgtracer-trace-treelist").treeList('empty')
|
|
247
|
+
$("#node-input-msgtracer-trace-treelist").treeList('data', [])
|
|
248
|
+
})
|
|
249
|
+
|
|
241
250
|
$('#node-input-msgtracer-toggle').on("change", function (e) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
251
|
+
if ( $('#node-input-msgtracer-toggle').is(":checked") ) {
|
|
252
|
+
setupTreeMsgTracerlist()
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
$.ajax({
|
|
256
|
+
url: "ClientCode/msgtracer/" + ($('#node-input-msgtracer-toggle').is(":checked") ? "on" : "off"),
|
|
257
|
+
type: "POST",
|
|
258
|
+
contentType: "application/json; charset=utf-8",
|
|
259
|
+
data: {},
|
|
260
|
+
success: function (resp) {
|
|
261
|
+
RED.notify("Message tracing succeed", {
|
|
262
|
+
type: "success",
|
|
263
|
+
timeout: 3000
|
|
264
|
+
})
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
error: function (jqXHR, textStatus, errorThrown) {
|
|
268
|
+
RED.notify("Message tracing failed: " +textStatus, {
|
|
269
|
+
type: "error",
|
|
250
270
|
timeout: 3000
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
error: function (jqXHR, textStatus, errorThrown) {
|
|
255
|
-
RED.notify("Message tracing failed: " +textStatus, {
|
|
256
|
-
type: "error",
|
|
257
|
-
timeout: 3000
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
});
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
261
274
|
})
|
|
262
275
|
|
|
263
276
|
RED.actions.add( "introspection:show-link-call-links", highlightAllLinkCalls)
|
|
@@ -388,6 +401,16 @@
|
|
|
388
401
|
</label>
|
|
389
402
|
<input type="checkbox" id="node-input-msgtracer-toggle"
|
|
390
403
|
style="display:inline-block; width:15px; vertical-align:baseline;">
|
|
404
|
+
<button id="node-input-msgtrace-clear-trace-btn"
|
|
405
|
+
class="red-ui-button">Clear Trace</button>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<div class="form-row"
|
|
409
|
+
style="margin-left: 10px; position: relative; min-height: 200px; height: 450px; margin-right: 15px;">
|
|
410
|
+
<div style="margin-bottom: 5px; width: 35%; padding-left: 60%;">
|
|
411
|
+
<input type="text" id="node-input-msgtracer-trace-treelist-filter" style="display: none;">
|
|
412
|
+
</div>
|
|
413
|
+
<div id="node-input-msgtracer-trace-treelist"></div>
|
|
391
414
|
</div>
|
|
392
415
|
</div>
|
|
393
416
|
|