speechflow 1.3.2 → 1.4.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.
Files changed (154) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/etc/stx.conf +54 -58
  3. package/package.json +25 -106
  4. package/speechflow-cli/etc/stx.conf +77 -0
  5. package/speechflow-cli/package.json +116 -0
  6. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +217 -0
  7. package/{src → speechflow-cli/src}/speechflow-node-a2a-vad.ts +14 -21
  8. package/{src → speechflow-cli/src}/speechflow-node-a2t-deepgram.ts +21 -38
  9. package/{src → speechflow-cli/src}/speechflow-node-t2a-elevenlabs.ts +10 -16
  10. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +276 -0
  11. package/{src → speechflow-cli/src}/speechflow-node-x2x-filter.ts +5 -1
  12. package/{src → speechflow-cli/src}/speechflow-node-x2x-trace.ts +15 -7
  13. package/{src → speechflow-cli/src}/speechflow-node.ts +7 -0
  14. package/{src → speechflow-cli/src}/speechflow.ts +81 -25
  15. package/speechflow-ui-db/etc/eslint.mjs +106 -0
  16. package/speechflow-ui-db/etc/htmllint.json +55 -0
  17. package/speechflow-ui-db/etc/stx.conf +79 -0
  18. package/speechflow-ui-db/etc/stylelint.js +46 -0
  19. package/speechflow-ui-db/etc/stylelint.yaml +33 -0
  20. package/speechflow-ui-db/etc/tsc-client.json +30 -0
  21. package/speechflow-ui-db/etc/tsc.node.json +9 -0
  22. package/speechflow-ui-db/etc/vite-client.mts +63 -0
  23. package/speechflow-ui-db/package.d/htmllint-cli+0.0.7.patch +20 -0
  24. package/speechflow-ui-db/package.json +75 -0
  25. package/speechflow-ui-db/src/app-icon.ai +1989 -4
  26. package/speechflow-ui-db/src/app-icon.svg +26 -0
  27. package/speechflow-ui-db/src/app.styl +64 -0
  28. package/speechflow-ui-db/src/app.vue +221 -0
  29. package/speechflow-ui-db/src/index.html +23 -0
  30. package/speechflow-ui-db/src/index.ts +26 -0
  31. package/{dst/speechflow.d.ts → speechflow-ui-db/src/lib.d.ts} +5 -3
  32. package/speechflow-ui-db/src/tsconfig.json +3 -0
  33. package/speechflow-ui-st/etc/eslint.mjs +106 -0
  34. package/speechflow-ui-st/etc/htmllint.json +55 -0
  35. package/speechflow-ui-st/etc/stx.conf +79 -0
  36. package/speechflow-ui-st/etc/stylelint.js +46 -0
  37. package/speechflow-ui-st/etc/stylelint.yaml +33 -0
  38. package/speechflow-ui-st/etc/tsc-client.json +30 -0
  39. package/speechflow-ui-st/etc/tsc.node.json +9 -0
  40. package/speechflow-ui-st/etc/vite-client.mts +63 -0
  41. package/speechflow-ui-st/package.d/htmllint-cli+0.0.7.patch +20 -0
  42. package/speechflow-ui-st/package.json +79 -0
  43. package/speechflow-ui-st/src/app-icon.ai +1989 -4
  44. package/speechflow-ui-st/src/app-icon.svg +26 -0
  45. package/speechflow-ui-st/src/app.styl +64 -0
  46. package/speechflow-ui-st/src/app.vue +142 -0
  47. package/speechflow-ui-st/src/index.html +23 -0
  48. package/speechflow-ui-st/src/index.ts +26 -0
  49. package/speechflow-ui-st/src/lib.d.ts +9 -0
  50. package/speechflow-ui-st/src/tsconfig.json +3 -0
  51. package/dst/speechflow-node-a2a-ffmpeg.d.ts +0 -13
  52. package/dst/speechflow-node-a2a-ffmpeg.js +0 -153
  53. package/dst/speechflow-node-a2a-ffmpeg.js.map +0 -1
  54. package/dst/speechflow-node-a2a-gender.d.ts +0 -20
  55. package/dst/speechflow-node-a2a-gender.js +0 -349
  56. package/dst/speechflow-node-a2a-gender.js.map +0 -1
  57. package/dst/speechflow-node-a2a-meter.d.ts +0 -14
  58. package/dst/speechflow-node-a2a-meter.js +0 -196
  59. package/dst/speechflow-node-a2a-meter.js.map +0 -1
  60. package/dst/speechflow-node-a2a-mute.d.ts +0 -17
  61. package/dst/speechflow-node-a2a-mute.js +0 -117
  62. package/dst/speechflow-node-a2a-mute.js.map +0 -1
  63. package/dst/speechflow-node-a2a-vad.d.ts +0 -19
  64. package/dst/speechflow-node-a2a-vad.js +0 -383
  65. package/dst/speechflow-node-a2a-vad.js.map +0 -1
  66. package/dst/speechflow-node-a2a-wav.d.ts +0 -11
  67. package/dst/speechflow-node-a2a-wav.js +0 -211
  68. package/dst/speechflow-node-a2a-wav.js.map +0 -1
  69. package/dst/speechflow-node-a2t-deepgram.d.ts +0 -19
  70. package/dst/speechflow-node-a2t-deepgram.js +0 -345
  71. package/dst/speechflow-node-a2t-deepgram.js.map +0 -1
  72. package/dst/speechflow-node-t2a-elevenlabs.d.ts +0 -18
  73. package/dst/speechflow-node-t2a-elevenlabs.js +0 -244
  74. package/dst/speechflow-node-t2a-elevenlabs.js.map +0 -1
  75. package/dst/speechflow-node-t2a-kokoro.d.ts +0 -14
  76. package/dst/speechflow-node-t2a-kokoro.js +0 -155
  77. package/dst/speechflow-node-t2a-kokoro.js.map +0 -1
  78. package/dst/speechflow-node-t2t-deepl.d.ts +0 -15
  79. package/dst/speechflow-node-t2t-deepl.js +0 -146
  80. package/dst/speechflow-node-t2t-deepl.js.map +0 -1
  81. package/dst/speechflow-node-t2t-format.d.ts +0 -11
  82. package/dst/speechflow-node-t2t-format.js +0 -82
  83. package/dst/speechflow-node-t2t-format.js.map +0 -1
  84. package/dst/speechflow-node-t2t-ollama.d.ts +0 -13
  85. package/dst/speechflow-node-t2t-ollama.js +0 -247
  86. package/dst/speechflow-node-t2t-ollama.js.map +0 -1
  87. package/dst/speechflow-node-t2t-openai.d.ts +0 -13
  88. package/dst/speechflow-node-t2t-openai.js +0 -227
  89. package/dst/speechflow-node-t2t-openai.js.map +0 -1
  90. package/dst/speechflow-node-t2t-sentence.d.ts +0 -17
  91. package/dst/speechflow-node-t2t-sentence.js +0 -250
  92. package/dst/speechflow-node-t2t-sentence.js.map +0 -1
  93. package/dst/speechflow-node-t2t-subtitle.d.ts +0 -12
  94. package/dst/speechflow-node-t2t-subtitle.js +0 -166
  95. package/dst/speechflow-node-t2t-subtitle.js.map +0 -1
  96. package/dst/speechflow-node-t2t-transformers.d.ts +0 -14
  97. package/dst/speechflow-node-t2t-transformers.js +0 -265
  98. package/dst/speechflow-node-t2t-transformers.js.map +0 -1
  99. package/dst/speechflow-node-x2x-filter.d.ts +0 -11
  100. package/dst/speechflow-node-x2x-filter.js +0 -117
  101. package/dst/speechflow-node-x2x-filter.js.map +0 -1
  102. package/dst/speechflow-node-x2x-trace.d.ts +0 -11
  103. package/dst/speechflow-node-x2x-trace.js +0 -104
  104. package/dst/speechflow-node-x2x-trace.js.map +0 -1
  105. package/dst/speechflow-node-xio-device.d.ts +0 -13
  106. package/dst/speechflow-node-xio-device.js +0 -230
  107. package/dst/speechflow-node-xio-device.js.map +0 -1
  108. package/dst/speechflow-node-xio-file.d.ts +0 -11
  109. package/dst/speechflow-node-xio-file.js +0 -216
  110. package/dst/speechflow-node-xio-file.js.map +0 -1
  111. package/dst/speechflow-node-xio-mqtt.d.ts +0 -13
  112. package/dst/speechflow-node-xio-mqtt.js +0 -188
  113. package/dst/speechflow-node-xio-mqtt.js.map +0 -1
  114. package/dst/speechflow-node-xio-websocket.d.ts +0 -13
  115. package/dst/speechflow-node-xio-websocket.js +0 -278
  116. package/dst/speechflow-node-xio-websocket.js.map +0 -1
  117. package/dst/speechflow-node.d.ts +0 -63
  118. package/dst/speechflow-node.js +0 -177
  119. package/dst/speechflow-node.js.map +0 -1
  120. package/dst/speechflow-utils.d.ts +0 -74
  121. package/dst/speechflow-utils.js +0 -519
  122. package/dst/speechflow-utils.js.map +0 -1
  123. package/dst/speechflow.js +0 -787
  124. package/dst/speechflow.js.map +0 -1
  125. package/src/speechflow-node-a2a-meter.ts +0 -177
  126. package/src/speechflow-node-t2t-subtitle.ts +0 -149
  127. /package/{etc → speechflow-cli/etc}/biome.jsonc +0 -0
  128. /package/{etc → speechflow-cli/etc}/eslint.mjs +0 -0
  129. /package/{etc → speechflow-cli/etc}/oxlint.jsonc +0 -0
  130. /package/{etc → speechflow-cli/etc}/speechflow.bat +0 -0
  131. /package/{etc → speechflow-cli/etc}/speechflow.sh +0 -0
  132. /package/{etc → speechflow-cli/etc}/speechflow.yaml +0 -0
  133. /package/{etc → speechflow-cli/etc}/tsconfig.json +0 -0
  134. /package/{package.d → speechflow-cli/package.d}/@ericedouard+vad-node-realtime+0.2.0.patch +0 -0
  135. /package/{src → speechflow-cli/src}/lib.d.ts +0 -0
  136. /package/{src → speechflow-cli/src}/speechflow-logo.ai +0 -0
  137. /package/{src → speechflow-cli/src}/speechflow-logo.svg +0 -0
  138. /package/{src → speechflow-cli/src}/speechflow-node-a2a-ffmpeg.ts +0 -0
  139. /package/{src → speechflow-cli/src}/speechflow-node-a2a-gender.ts +0 -0
  140. /package/{src → speechflow-cli/src}/speechflow-node-a2a-mute.ts +0 -0
  141. /package/{src → speechflow-cli/src}/speechflow-node-a2a-wav.ts +0 -0
  142. /package/{src → speechflow-cli/src}/speechflow-node-t2a-kokoro.ts +0 -0
  143. /package/{src → speechflow-cli/src}/speechflow-node-t2t-deepl.ts +0 -0
  144. /package/{src → speechflow-cli/src}/speechflow-node-t2t-format.ts +0 -0
  145. /package/{src → speechflow-cli/src}/speechflow-node-t2t-ollama.ts +0 -0
  146. /package/{src → speechflow-cli/src}/speechflow-node-t2t-openai.ts +0 -0
  147. /package/{src → speechflow-cli/src}/speechflow-node-t2t-sentence.ts +0 -0
  148. /package/{src → speechflow-cli/src}/speechflow-node-t2t-transformers.ts +0 -0
  149. /package/{src → speechflow-cli/src}/speechflow-node-xio-device.ts +0 -0
  150. /package/{src → speechflow-cli/src}/speechflow-node-xio-file.ts +0 -0
  151. /package/{src → speechflow-cli/src}/speechflow-node-xio-mqtt.ts +0 -0
  152. /package/{src → speechflow-cli/src}/speechflow-node-xio-websocket.ts +0 -0
  153. /package/{src → speechflow-cli/src}/speechflow-utils.ts +0 -0
  154. /package/{tsconfig.json → speechflow-cli/tsconfig.json} +0 -0
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 512 512">
3
+ <!-- Generator: Adobe Illustrator 29.6.0, SVG Export Plug-In . SVG Version: 2.1.1 Build 207) -->
4
+ <defs>
5
+ <style>
6
+ .st0 {
7
+ fill: #fff;
8
+ fill-rule: evenodd;
9
+ }
10
+
11
+ .st1 {
12
+ fill: #222;
13
+ }
14
+ </style>
15
+ </defs>
16
+ <rect class="st1" x="-.2" y="0" width="512.6" height="512.1" rx="71.9" ry="71.9"/>
17
+ <g id="Icon">
18
+ <path class="st0" d="M201.8,235v35.2c0,10.5,4.2,20.6,11.6,28,7.4,7.4,17.5,11.6,28,11.6h35.2c10.5,0,20.6-4.2,28-11.6,7.4-7.4,11.6-17.5,11.6-28v-35.2c0-10.5-4.2-20.6-11.6-28-7.4-7.4-17.5-11.6-28-11.6h-35.2c-10.5,0-20.6,4.2-28,11.6s-11.6,17.5-11.6,28Z"/>
19
+ <path class="st0" d="M69.8,103v35.2c0,10.5,4.2,20.6,11.6,28,7.4,7.4,17.5,11.6,28,11.6h35.2c10.5,0,20.6-4.2,28-11.6,7.4-7.4,11.6-17.5,11.6-28v-35.2c0-10.5-4.2-20.6-11.6-28-7.4-7.4-17.5-11.6-28-11.6h-35.2c-10.5,0-20.6,4.2-28,11.6s-11.6,17.5-11.6,28Z"/>
20
+ <path class="st0" d="M333.7,367v35.2c0,10.5,4.2,20.6,11.6,28,7.4,7.4,17.5,11.6,28,11.6h35.2c10.5,0,20.6-4.2,28-11.6,7.4-7.4,11.6-17.5,11.6-28v-35.2c0-10.5-4.2-20.6-11.6-28-7.4-7.4-17.5-11.6-28-11.6h-35.2c-10.5,0-20.6,4.2-28,11.6-7.4,7.4-11.6,17.5-11.6,28Z"/>
21
+ <path class="st0" d="M171,133.8h228.8c5.8,0,11.4,2.3,15.6,6.4,4.1,4.1,6.4,9.7,6.4,15.6v61.6c0,5.8-2.3,11.4-6.4,15.6-4.1,4.1-9.7,6.4-15.6,6.4h-52.8c-7.3,0-13.2,5.9-13.2,13.2s5.9,13.2,13.2,13.2h52.8c12.8,0,25.1-5.1,34.2-14.2,9.1-9.1,14.2-21.4,14.2-34.2v-61.6c0-12.8-5.1-25.1-14.2-34.2-9.1-9.1-21.4-14.2-34.2-14.2h-228.8c-7.3,0-13.2,5.9-13.2,13.2s5.9,13.2,13.2,13.2Z"/>
22
+ <path class="st0" d="M276.5,371.4H118.2c-5.8,0-11.4-2.3-15.6-6.4-4.1-4.1-6.4-9.7-6.4-15.6v-61.6c0-5.8,2.3-11.4,6.4-15.6,4.1-4.1,9.7-6.4,15.6-6.4h96.8c7.3,0,13.2-5.9,13.2-13.2s-5.9-13.2-13.2-13.2h-96.8c-12.8,0-25.1,5.1-34.2,14.2-9.1,9.1-14.2,21.4-14.2,34.2v61.6c0,12.8,5.1,25.1,14.2,34.2,9.1,9.1,21.4,14.2,34.2,14.2h158.4c7.3,0,13.2-5.9,13.2-13.2s-5.9-13.2-13.2-13.2Z"/>
23
+ <path class="st0" d="M391.5,278.5l-25.9-25.9,25.9-25.9c5.2-5.1,5.2-13.5,0-18.7-5.1-5.2-13.5-5.2-18.7,0l-35.2,35.2c-5.2,5.2-5.2,13.5,0,18.7l35.2,35.2c5.1,5.2,13.5,5.2,18.7,0,5.2-5.1,5.2-13.5,0-18.7h0Z"/>
24
+ <path class="st0" d="M268.3,429.1l35.2-35.2c5.2-5.2,5.2-13.5,0-18.7l-35.2-35.2c-5.1-5.2-13.5-5.2-18.7,0-5.2,5.1-5.2,13.5,0,18.7l25.9,25.9-25.9,25.9c-5.2,5.1-5.2,13.5,0,18.7,5.1,5.2,13.5,5.2,18.7,0h0Z"/>
25
+ </g>
26
+ </svg>
@@ -0,0 +1,64 @@
1
+ /*
2
+ ** SpeechFlow - Speech Processing Flow Graph
3
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ :root
8
+ --color-std-bg-0: #000000
9
+ --color-std-bg-1: #1a1a1a
10
+ --color-std-bg-2: #242424
11
+ --color-std-bg-3: #2e2e2e
12
+ --color-std-bg-4: #383838
13
+ --color-std-bg-5: #424242
14
+
15
+ --color-std-fg-0: #606060
16
+ --color-std-fg-1: #808080
17
+ --color-std-fg-2: #a0a0a0
18
+ --color-std-fg-3: #c0c0c0
19
+ --color-std-fg-4: #e0e0e0
20
+ --color-std-fg-5: #ffffff
21
+
22
+ --color-acc-bg-1: #114477
23
+ --color-acc-bg-2: #225588
24
+ --color-acc-bg-3: #336699
25
+ --color-acc-bg-4: #4477aa
26
+ --color-acc-bg-5: #5588bb
27
+
28
+ --color-acc-fg-0: #6090c0
29
+ --color-acc-fg-1: #80b0e0
30
+ --color-acc-fg-2: #88b8e8
31
+ --color-acc-fg-3: #90c0f0
32
+ --color-acc-fg-4: #98c8f8
33
+ --color-acc-fg-5: #a0d0ff
34
+
35
+ --color-sig-bg-1: #904800
36
+ --color-sig-bg-2: #a05810
37
+ --color-sig-bg-3: #b06820
38
+ --color-sig-bg-4: #c07830
39
+ --color-sig-bg-5: #d08840
40
+
41
+ --color-sig-fg-0: #c0b090
42
+ --color-sig-fg-1: #e0d0b0
43
+ --color-sig-fg-2: #e8d8b8
44
+ --color-sig-fg-3: #f0e0c0
45
+ --color-sig-fg-4: #f8e8c8
46
+ --color-sig-fg-5: #fff0d0
47
+
48
+ --font-family: "TypoPRO Source Sans Pro", sans-serif
49
+
50
+
51
+ html,
52
+ body
53
+ margin: 0
54
+ padding: 0
55
+ width: 100vw
56
+ height: 100vh
57
+ overflow: hidden
58
+ color: var(--color-std-fg-3)
59
+ background-color: var(--color-std-bg-0)
60
+ font-family: var(--font-family)
61
+ font-weight: normal
62
+ user-select: none
63
+ font-size: 11pt
64
+
@@ -0,0 +1,221 @@
1
+ <!--
2
+ **
3
+ ** SpeechFlow - Speech Processing Flow Graph
4
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
+ **
7
+ -->
8
+
9
+ <template>
10
+ <div class="app">
11
+ <div class="dashboard">
12
+ <div v-bind:key="block.id" v-for="block of info" class="block">
13
+ <div v-if="block.type === 'audio'" class="audio-col">
14
+ <div class="audio-meter" v-bind:style="{
15
+ height: (100 * (1 - ((block.value as number) / - 60.0))) + '%'
16
+ }">
17
+ <div class="audio-value">
18
+ {{ (block.value as number).toFixed(1) }}
19
+ </div>
20
+ </div>
21
+ <div class="audio-name">
22
+ {{ block.name }}
23
+ </div>
24
+ </div>
25
+ <div ref="textCol"
26
+ v-if="block.type === 'text'"
27
+ class="text-col"
28
+ v-bind:class="{ intermediate: block.lastKind === 'intermediate' }">
29
+ <div v-bind:key="value"
30
+ v-for="value of block.value"
31
+ class="text-value">
32
+ {{ value as unknown as string }}
33
+ </div>
34
+ <div class="text-name">
35
+ {{ block.name }}
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </template>
42
+
43
+ <style lang="stylus">
44
+ .app
45
+ position: relative
46
+ width: 100vw
47
+ height: 100vh
48
+ margin: 0
49
+ padding: 0
50
+ display: flex
51
+ flex-direction: column
52
+ justify-content: center
53
+ align-items: center
54
+ .dashboard
55
+ height: 100%
56
+ width: 100%
57
+ display: flex
58
+ flex-direction: row
59
+ align-items: center
60
+ justify-content: center
61
+ .block
62
+ height: calc(100% - 0.5vw)
63
+ margin-right: 0.5vw
64
+ &:has(.audio-col)
65
+ width: 10vw
66
+ &:has(.text-col)
67
+ flex-grow: 1
68
+ flex-shrink: 1
69
+ flex-basis: 0
70
+ .audio-col
71
+ width: 10vw
72
+ height: 100vh
73
+ display: flex
74
+ flex-direction: column
75
+ align-items: flex-end
76
+ justify-content: flex-end
77
+ background-color: var(--color-acc-bg-3)
78
+ .audio-meter
79
+ width: 100%
80
+ display: flex
81
+ flex-direction: column
82
+ align-items: flex-end
83
+ justify-content: flex-end
84
+ background-color: var(--color-acc-fg-3)
85
+ .audio-value
86
+ width: 100%
87
+ font-size: 3vw
88
+ text-align: center
89
+ color: var(--color-std-bg-0)
90
+ .audio-name
91
+ width: 100%
92
+ text-align: center
93
+ background-color: var(--color-acc-bg-1)
94
+ color: var(--color-acc-fg-3)
95
+ font-size: 2vw
96
+ .text-col
97
+ width: 100%
98
+ height: 100vh
99
+ overflow-x: hidden
100
+ overflow-y: scroll
101
+ display: flex
102
+ flex-direction: column
103
+ align-items: flex-end
104
+ justify-content: flex-end
105
+ .text-value
106
+ width: calc(100% - 2 * 1.0vw)
107
+ background-color: var(--color-acc-bg-3)
108
+ color: var(--color-acc-fg-3)
109
+ border-radius: 1vw
110
+ font-size: 1.5vw
111
+ padding: 0.5vw 1.0vw
112
+ margin-bottom: 0.5vw
113
+ overflow-wrap: break-word
114
+ .text-name
115
+ width: 100%
116
+ text-align: center
117
+ background-color: var(--color-acc-bg-1)
118
+ color: var(--color-acc-fg-3)
119
+ font-size: 2vw
120
+ .text-col.intermediate
121
+ .text-value:nth-last-child(2)
122
+ background-color: var(--color-sig-bg-3)
123
+ color: var(--color-sig-fg-3)
124
+ </style>
125
+
126
+ <script setup lang="ts">
127
+ import { defineComponent } from "vue"
128
+ import moment from "moment"
129
+ import ReconnectingWebSocket from "@opensumi/reconnecting-websocket"
130
+ import axios from "axios"
131
+ </script>
132
+
133
+ <script lang="ts">
134
+ type Info = {
135
+ type: string,
136
+ id: string,
137
+ name: string,
138
+ value: number | string[],
139
+ lastKind: string
140
+ }
141
+ export default defineComponent({
142
+ name: "app",
143
+ components: {
144
+ },
145
+ data: () => ({
146
+ info: [] as Info[]
147
+ }),
148
+ created () {
149
+ },
150
+ async mounted () {
151
+ /* determine API URL */
152
+ let url = document.location.href
153
+ url = url.replace(/#.+$/, "")
154
+ url = url.replace(/\/[^/]*$/, "")
155
+ url = url + "/api"
156
+
157
+ /* load dashboard configuration */
158
+ const response = await axios.get(`${url}/dashboard`)
159
+ for (const block of response.data) {
160
+ if (block.type === "audio")
161
+ this.info.push({ type: block.type, id: block.id, name: block.name, value: 0, lastKind: "" })
162
+ else if (block.type === "text")
163
+ this.info.push({ type: block.type, id: block.id, name: block.name, value: [], lastKind: "" })
164
+ }
165
+
166
+ /* connect to WebSocket API for receiving dashboard information */
167
+ const ws = new ReconnectingWebSocket(url, [], {
168
+ reconnectionDelayGrowFactor: 1.3,
169
+ maxReconnectionDelay: 4000,
170
+ minReconnectionDelay: 1000,
171
+ connectionTimeout: 4000,
172
+ minUptime: 5000
173
+ })
174
+ ws.addEventListener("open", (ev) => {
175
+ })
176
+ ws.addEventListener("message", (ev) => {
177
+ const event = JSON.parse(ev.data)
178
+ if (event.response !== "DASHBOARD")
179
+ return
180
+ const [ type, id, kind, value ] = event.args
181
+ for (const block of this.info) {
182
+ if (block.type === type && block.id === id) {
183
+ if (block.type === "audio") {
184
+ if (kind === "final")
185
+ block.value = value
186
+ }
187
+ else {
188
+ if (block.lastKind === "intermediate") {
189
+ const arr = block.value as string[]
190
+ arr[arr.length - 1] = value
191
+ }
192
+ else {
193
+ const arr = block.value as string[]
194
+ arr.push(value)
195
+ block.value = arr.slice(-20)
196
+ }
197
+ block.lastKind = kind
198
+ this.$nextTick(() => {
199
+ for (const textCol of this.$refs.textCol as HTMLDivElement[])
200
+ textCol.scrollTop = textCol.scrollHeight
201
+ })
202
+ }
203
+ }
204
+ }
205
+ })
206
+ },
207
+ methods: {
208
+ log (level: string, msg: string, data: { [ key: string ]: any } | null = null) {
209
+ const timestamp = moment().format("YYYY-MM-DD hh:mm:ss.SSS")
210
+ let output = `${timestamp} [${level}]: ${msg}`
211
+ if (data !== null)
212
+ output += ` (${Object.keys(data)
213
+ .map((key) => key + ": " + JSON.stringify(data[key]))
214
+ .join(", ")
215
+ })`
216
+ console.log(output)
217
+ }
218
+ }
219
+ })
220
+ </script>
221
+
@@ -0,0 +1,23 @@
1
+ <!DOCTYPE html>
2
+ <!--
3
+ **
4
+ ** SpeechFlow - Speech Processing Flow Graph
5
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
6
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
7
+ **
8
+ -->
9
+ <html>
10
+ <head>
11
+ <meta charset="utf-8" />
12
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
13
+ <meta name="viewport" content="width=device-width, minimum-scale=0.1, initial-scale=1.0, maximum-scale=10, user-scalable=no" />
14
+ <link rel="icon" type="image/svg+xml" href="./app-icon.svg" />
15
+ <title>SpeechFlow</title>
16
+ <script type="module" src="index.ts"></script>
17
+ </head>
18
+ <body>
19
+ <div id="app">
20
+ <app></app>
21
+ </div>
22
+ </body>
23
+ </html>
@@ -0,0 +1,26 @@
1
+ /*
2
+ ** SpeechFlow - Speech Processing Flow Graph
3
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ /* external dependencies */
8
+ import * as Vue from "vue"
9
+ import "typopro-web/web/TypoPRO-SourceSansPro/TypoPRO-SourceSansPro-Regular.css"
10
+ import "typopro-web/web/TypoPRO-SourceSansPro/TypoPRO-SourceSansPro-Bold.css"
11
+ import "@fortawesome/fontawesome-free/js/all.min.js"
12
+ import "@fortawesome/fontawesome-free/css/all.min.css"
13
+
14
+ /* internal dependencies */
15
+ import App from "./app.vue"
16
+ import "./app.styl"
17
+
18
+ document.addEventListener("DOMContentLoaded", (ev: Event) => {
19
+ (async () => {
20
+ const app = Vue.createApp(App)
21
+ app.mount("#app")
22
+ })().catch((err) => {
23
+ console.error(`app: ERROR: top-level: ${err}`)
24
+ })
25
+ })
26
+
@@ -1,7 +1,9 @@
1
- #!/usr/bin/env node
2
- /*!
1
+ /*
3
2
  ** SpeechFlow - Speech Processing Flow Graph
4
3
  ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
5
4
  ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
6
5
  */
7
- export {};
6
+
7
+ declare global {}
8
+ export {}
9
+
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "../etc/tsc-client.json"
3
+ }
@@ -0,0 +1,106 @@
1
+ /*
2
+ ** SpeechFlow - Speech Processing Flow Graph
3
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ import pluginJs from "@eslint/js"
8
+ import pluginStd from "neostandard"
9
+ import pluginN from "eslint-plugin-n"
10
+ import pluginImport from "eslint-plugin-import"
11
+ import pluginPromise from "eslint-plugin-promise"
12
+ import pluginVue from "eslint-plugin-vue"
13
+ import pluginTS from "typescript-eslint"
14
+ import globals from "globals"
15
+ import parserTS from "@typescript-eslint/parser"
16
+ import parserVue from "vue-eslint-parser"
17
+
18
+ export default [
19
+ pluginJs.configs.recommended,
20
+ ...pluginTS.configs.strict,
21
+ ...pluginTS.configs.stylistic,
22
+ ...pluginStd({
23
+ ignores: pluginStd.resolveIgnoresFromGitignore()
24
+ }),
25
+ ...pluginVue.configs["flat/recommended"],
26
+ {
27
+ plugins: {
28
+ "n": pluginN,
29
+ "import": pluginImport,
30
+ "promise": pluginPromise
31
+ },
32
+ files: [ "**/*.{vue,ts}" ],
33
+ ignores: [ "dst/" ],
34
+ languageOptions: {
35
+ ecmaVersion: 2022,
36
+ sourceType: "module",
37
+ parser: parserVue,
38
+ parserOptions: {
39
+ parser: parserTS,
40
+ extraFileExtensions: [ ".vue" ],
41
+ ecmaFeatures: {
42
+ jsx: false
43
+ }
44
+ },
45
+ globals: {
46
+ ...globals.browser,
47
+ ...globals.node,
48
+ ...globals.commonjs
49
+ }
50
+ },
51
+ rules: {
52
+ "curly": "off",
53
+ "require-atomic-updates": "off",
54
+ "dot-notation": "off",
55
+ "no-labels": "off",
56
+ "no-useless-constructor": "off",
57
+
58
+ "@stylistic/indent": [ "error", 4, { SwitchCase: 1 } ],
59
+ "@stylistic/linebreak-style": [ "error", "unix" ],
60
+ "@stylistic/semi": [ "error", "never" ],
61
+ "@stylistic/operator-linebreak": [ "error", "after", { overrides: { "&&": "before", "||": "before", ":": "after" } } ],
62
+ "@stylistic/brace-style": [ "error", "stroustrup", { allowSingleLine: true } ],
63
+ "@stylistic/quotes": [ "error", "double" ],
64
+
65
+ "@stylistic/no-multi-spaces": "off",
66
+ "@stylistic/no-multi-spaces": "off",
67
+ "@stylistic/no-multiple-empty-lines": "off",
68
+ "@stylistic/key-spacing": "off",
69
+ "@stylistic/object-property-newline": "off",
70
+ "@stylistic/space-in-parens": "off",
71
+ "@stylistic/array-bracket-spacing": "off",
72
+ "@stylistic/lines-between-class-members": "off",
73
+ "@stylistic/multiline-ternary": "off",
74
+ "@stylistic/quote-props": "off",
75
+
76
+ "vue/html-indent": "off",
77
+ "vue/v-bind-style": [ "error", "longform" ],
78
+ "vue/max-attributes-per-line": "off",
79
+ "vue/html-self-closing": "off",
80
+ "vue/no-multi-spaces": "off",
81
+ "vue/html-closing-bracket-newline": "off",
82
+ "vue/html-closing-bracket-spacing": "off",
83
+ "vue/singleline-html-element-content-newline": "off",
84
+ "vue/no-v-html": "off",
85
+ "vue/v-on-style": "off",
86
+ "vue/component-tags-order": "off",
87
+ "vue/first-attribute-linebreak": "off",
88
+ "vue/attributes-order": "off",
89
+ "vue/component-definition-name-casing": "off",
90
+ "vue/block-order": "off",
91
+
92
+ "@typescript-eslint/no-empty-function": "off",
93
+ "@typescript-eslint/no-explicit-any": "off",
94
+ "@typescript-eslint/no-unused-vars": "off",
95
+ "@typescript-eslint/ban-ts-comment": "off",
96
+ "@typescript-eslint/no-this-alias": "off",
97
+ "@typescript-eslint/no-non-null-assertion": "off",
98
+ "@typescript-eslint/consistent-type-definitions": "off",
99
+ "@typescript-eslint/array-type": "off",
100
+ "@typescript-eslint/no-extraneous-class": "off",
101
+ "@typescript-eslint/consistent-indexed-object-style": "off",
102
+ "@typescript-eslint/adjacent-overload-signatures": "off"
103
+ }
104
+ }
105
+ ]
106
+
@@ -0,0 +1,55 @@
1
+ {
2
+ "plugins": [],
3
+ "maxerr": false,
4
+ "raw-ignore-regex": false,
5
+ "attr-bans": [ "align", "background", "bgcolor", "border", "frameborder", "longdesc", "marginwidth", "marginheight", "scrolling", "style", "width" ],
6
+ "indent-delta": false,
7
+ "indent-style": "nonmixed",
8
+ "indent-width": 4,
9
+ "indent-width-cont": false,
10
+ "spec-char-escape": true,
11
+ "text-ignore-regex": false,
12
+ "tag-bans": [ "b", "i" ],
13
+ "tag-close": true,
14
+ "tag-name-lowercase": true,
15
+ "tag-name-match": true,
16
+ "tag-self-close": false,
17
+ "doctype-first": false,
18
+ "doctype-html5": false,
19
+ "attr-name-style": "dash",
20
+ "attr-name-ignore-regex": false,
21
+ "attr-no-dup": true,
22
+ "attr-no-unsafe-char": true,
23
+ "attr-order": false,
24
+ "attr-quote-style": "double",
25
+ "attr-req-value": true,
26
+ "attr-new-line": false,
27
+ "attr-validate": true,
28
+ "id-no-dup": true,
29
+ "id-class-no-ad": true,
30
+ "id-class-style": "underscore",
31
+ "class-no-dup": true,
32
+ "class-style": false,
33
+ "id-class-ignore-regex": false,
34
+ "img-req-alt": true,
35
+ "img-req-src": true,
36
+ "html-valid-content-model": true,
37
+ "head-valid-content-model": true,
38
+ "href-style": false,
39
+ "label-req-for": true,
40
+ "line-end-style": "lf",
41
+ "line-no-trailing-whitespace": false,
42
+ "line-max-len": false,
43
+ "line-max-len-ignore-regex": false,
44
+ "head-req-title": true,
45
+ "title-no-dup": true,
46
+ "title-max-len": 60,
47
+ "html-req-lang": false,
48
+ "lang-style": "case",
49
+ "fig-req-figcaption": false,
50
+ "focusable-tabindex-style": false,
51
+ "input-radio-req-name": true,
52
+ "input-req-label": false,
53
+ "table-req-caption": false,
54
+ "table-req-header": false
55
+ }
@@ -0,0 +1,79 @@
1
+ ##
2
+ ## SpeechFlow - Speech Processing Flow Graph
3
+ ## Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ## Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ ##
6
+
7
+ # (internal): create patch set for NPM dependencies
8
+ patch-make
9
+ npm shrinkwrap && \
10
+ patch-package --patch-dir package.d \
11
+ "@typescript-eslint/typescript-estree" \
12
+ htmllint-cli && \
13
+ shx rm -f npm-shrinkwrap.json
14
+
15
+ # (internal): apply patch set for NPM dependencies
16
+ patch-apply
17
+ patch-package --patch-dir package.d
18
+
19
+ # static code analysis (continuous file watching)
20
+ lint-watch
21
+ nodemon --exec "npm start lint" --watch src --ext html,styl,js,ts,vue
22
+
23
+ # static code analysis
24
+ lint : lint-vue-tsc lint-eslint lint-stylelint lint-htmllint
25
+
26
+ # static code analysis (Vue language)
27
+ lint-vue-tsc
28
+ vue-tsc --project etc/tsc-client.json --noEmit
29
+
30
+ # static code analysis (TypeScript language)
31
+ lint-eslint
32
+ eslint --config etc/eslint.mjs src/**/*.vue src/**/*.ts
33
+
34
+ # static code analysis (CSS/Stylus languages)
35
+ lint-stylelint
36
+ stylelint --config etc/stylelint.yaml src/**/*.styl src/**/*.vue
37
+
38
+ # static code analysis (HTML language)
39
+ lint-htmllint
40
+ htmllint --rc etc/htmllint.json src/**/*.html
41
+
42
+ # build components for production
43
+ build
44
+ npm start build-client
45
+
46
+ # build components for development
47
+ build-dev
48
+ npm start build-client-dev
49
+
50
+ # build client components for production
51
+ build-client
52
+ vite --config etc/vite-client.mts build --mode production
53
+
54
+ # build client components for development
55
+ build-client-dev
56
+ vite --config etc/vite-client.mts build --mode development
57
+
58
+ # build client components for development (continuous file watching)
59
+ build-client-dev-watch
60
+ cross-env NODE_OPTIONS="--max-old-space-size=4096" \
61
+ vite --config etc/vite-client.mts build --mode development --watch
62
+
63
+ # run server
64
+ server
65
+ serve -d --listen 12345 --single dst
66
+
67
+ # remove all development-only NPM dependencies
68
+ prune
69
+ npm prune --omit=dev
70
+
71
+ # remove all generated artifacts (reverse of "npm start build")
72
+ clean
73
+ shx rm -rf dst-stage1 dst-stage2
74
+
75
+ # remove all generated artifacts (reverse of "npm install" and "npm start build")
76
+ clean:dist : clean
77
+ shx rm -f package-lock.json && \
78
+ shx rm -rf node_modules
79
+
@@ -0,0 +1,46 @@
1
+ /*
2
+ ** SpeechFlow - Speech Processing Flow Graph
3
+ ** Copyright (c) 2024-2025 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under GPL 3.0 <https://spdx.org/licenses/GPL-3.0-only>
5
+ */
6
+
7
+ /* read original rules */
8
+ const recommended = require("stylelint-stylus/recommended")
9
+ const standard = require("stylelint-stylus/standard")
10
+
11
+ /* mix standard over recommended manually */
12
+ const mixed = {}
13
+ Object.assign(mixed, recommended)
14
+ Object.assign(mixed.rules, standard.rules)
15
+
16
+ /* remove deprecated rules */
17
+ const deprecated = [
18
+ "at-rule-name-newline-after",
19
+ "at-rule-name-space-after",
20
+ "block-closing-brace-empty-line-before",
21
+ "block-closing-brace-newline-after",
22
+ "block-closing-brace-newline-before",
23
+ "block-closing-brace-space-after",
24
+ "block-closing-brace-space-before",
25
+ "block-opening-brace-newline-after",
26
+ "block-opening-brace-newline-before",
27
+ "block-opening-brace-space-after",
28
+ "block-opening-brace-space-before",
29
+ "color-hex-case",
30
+ "declaration-block-trailing-semicolon",
31
+ "no-eol-whitespace",
32
+ "number-leading-zero",
33
+ "number-no-trailing-zeros",
34
+ "selector-list-comma-newline-after",
35
+ "selector-list-comma-newline-before",
36
+ "selector-list-comma-space-after",
37
+ "selector-list-comma-space-before",
38
+ "selector-pseudo-class-case",
39
+ "indentation"
40
+ ]
41
+ for (const d of deprecated)
42
+ delete mixed.rules[d]
43
+
44
+ /* export as replacement configuration */
45
+ module.exports = mixed
46
+