@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 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
+ ![img](https://cdn.openmindmap.org/content/1728588310213_msgtrace.gif)
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
 
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gregoriusrippenstein/node-red-contrib-introspection",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "dependencies": {
5
5
  "got": "^13",
6
6
  "uglify-js": "^3.17.4",
@@ -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
- $.ajax({
243
- url: "ClientCode/msgtracer/" + ($('#node-input-msgtracer-toggle').is(":checked") ? "on" : "off"),
244
- type: "POST",
245
- contentType: "application/json; charset=utf-8",
246
- data: {},
247
- success: function (resp) {
248
- RED.notify("Message tracing succeed", {
249
- type: "success",
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