@yarkivaev/scada 2.3.66 → 2.3.68

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yarkivaev/scada",
3
- "version": "2.3.66",
3
+ "version": "2.3.68",
4
4
  "description": "SCADA domain objects, state persistence, and plant monitoring",
5
5
  "repository": {
6
6
  "type": "git",
@@ -29,7 +29,7 @@
29
29
  "dependencies": {
30
30
  "@clickhouse/client": "^1.0.0",
31
31
  "@yarkivaev/simple-server": "1.0.2",
32
- "@yarkivaev/source-to-sink": "1.3.4",
32
+ "@yarkivaev/source-to-sink": "1.3.6",
33
33
  "amqplib": "^0.10.9",
34
34
  "pg": "^8.0.0",
35
35
  "stompit": "^1.0.0"
@@ -94,6 +94,7 @@ body {
94
94
  fill: none;
95
95
  stroke: #3a5166;
96
96
  stroke-width: 1.4;
97
+ pointer-events: none;
97
98
  }
98
99
 
99
100
  .link--feeds {
@@ -26,18 +26,21 @@ function machines(nodes, area, x, base, placed) {
26
26
 
27
27
  function extras(nodes, area, x, placed) {
28
28
  const items = children(nodes, area.id, 'collector');
29
+ if (items.length === 0) {
30
+ return 150;
31
+ }
32
+ const pitch = 64;
33
+ const head = 124;
29
34
  items.forEach((col, k) => {
30
- placed[col.id] = { x, y: 108 + k * 28 };
35
+ placed[col.id] = { x, y: head + k * pitch };
31
36
  });
32
- return items.length;
37
+ return head + items.length * pitch + 48;
33
38
  }
34
39
 
35
40
  function column(area, index, nodes, placed) {
36
41
  const x = 170 + index * 280;
37
42
  placed[area.id] = { x, y: 56 };
38
- const count = extras(nodes, area, x, placed);
39
- const base = count === 0 ? 150 : 108 + count * 28 + 50;
40
- machines(nodes, area, x, base, placed);
43
+ machines(nodes, area, x, extras(nodes, area, x, placed), placed);
41
44
  }
42
45
 
43
46
  function leftovers(nodes, placed) {
@@ -16,6 +16,7 @@ export const segmentColumns = ['machine', 'kind', 'name', 'start_time', 'end_tim
16
16
  export const segmentConflict = ['machine', 'kind', 'start_time'];
17
17
  export const segmentUpdateColumns = ['name', 'end_time', 'duration', 'options', 'resolved'];
18
18
  export const splitUpdateColumns = ['name', 'end_time', 'duration', 'tags', 'options', 'resolved'];
19
+ export const segmentUpdateWhere = 'segments.duration = 0 OR EXCLUDED.duration > 0';
19
20
  export const segmentsIngestDestination = '/queue/scada.segments.ingest';
20
21
 
21
22
  export { default as segmentDispatch } from '../../../domain/segment/dispatch.js';
@@ -28,7 +29,7 @@ export { default as segmentDispatch } from '../../../domain/segment/dispatch.js'
28
29
  * @returns {{ segmentSink: object, splitSink: object }}
29
30
  */
30
31
  function segmentSinks(postgres, pool) {
31
- const shared = { pool, conflict: segmentConflict };
32
+ const shared = { pool, conflict: segmentConflict, updateWhere: segmentUpdateWhere };
32
33
  return {
33
34
  segmentSink: postgresSink(postgres, 'segments', segmentColumns,
34
35
  { ...shared, update: segmentUpdateColumns }),
@@ -40,7 +41,8 @@ function segmentSinks(postgres, pool) {
40
41
  /**
41
42
  * Pipeline for streaming STOMP segment data to PostgreSQL segments table.
42
43
  * Subscribes to the durable ingest queue so shovel traffic survives consumer gaps.
43
- * Pending heartbeats are coalesced per machine; machines run in parallel lanes.
44
+ * Pending heartbeats are coalesced per machine; machines persist in
45
+ * parallel lanes. Arrivals enqueue in broker FIFO before coalesce.
44
46
  *
45
47
  * @param {string} stomp - STOMP broker URL
46
48
  * @param {string} postgres - PostgreSQL connection URL