speechflow 1.3.1 → 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 (156) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/etc/stx.conf +54 -58
  3. package/package.json +25 -106
  4. package/{etc → speechflow-cli/etc}/eslint.mjs +1 -2
  5. package/speechflow-cli/etc/stx.conf +77 -0
  6. package/speechflow-cli/package.json +116 -0
  7. package/{src → speechflow-cli/src}/speechflow-node-a2a-gender.ts +148 -64
  8. package/speechflow-cli/src/speechflow-node-a2a-meter.ts +217 -0
  9. package/{src → speechflow-cli/src}/speechflow-node-a2a-mute.ts +39 -11
  10. package/speechflow-cli/src/speechflow-node-a2a-vad.ts +384 -0
  11. package/{src → speechflow-cli/src}/speechflow-node-a2a-wav.ts +27 -11
  12. package/speechflow-cli/src/speechflow-node-a2t-deepgram.ts +313 -0
  13. package/{src → speechflow-cli/src}/speechflow-node-t2a-elevenlabs.ts +59 -12
  14. package/{src → speechflow-cli/src}/speechflow-node-t2a-kokoro.ts +11 -4
  15. package/{src → speechflow-cli/src}/speechflow-node-t2t-deepl.ts +9 -4
  16. package/{src → speechflow-cli/src}/speechflow-node-t2t-format.ts +2 -2
  17. package/{src → speechflow-cli/src}/speechflow-node-t2t-ollama.ts +1 -1
  18. package/{src → speechflow-cli/src}/speechflow-node-t2t-openai.ts +1 -1
  19. package/{src → speechflow-cli/src}/speechflow-node-t2t-sentence.ts +37 -20
  20. package/speechflow-cli/src/speechflow-node-t2t-subtitle.ts +276 -0
  21. package/{src → speechflow-cli/src}/speechflow-node-t2t-transformers.ts +4 -3
  22. package/{src → speechflow-cli/src}/speechflow-node-x2x-filter.ts +9 -5
  23. package/{src → speechflow-cli/src}/speechflow-node-x2x-trace.ts +16 -8
  24. package/{src → speechflow-cli/src}/speechflow-node-xio-device.ts +12 -8
  25. package/{src → speechflow-cli/src}/speechflow-node-xio-file.ts +9 -3
  26. package/{src → speechflow-cli/src}/speechflow-node-xio-mqtt.ts +5 -2
  27. package/{src → speechflow-cli/src}/speechflow-node-xio-websocket.ts +12 -12
  28. package/{src → speechflow-cli/src}/speechflow-node.ts +7 -0
  29. package/{src → speechflow-cli/src}/speechflow-utils.ts +78 -44
  30. package/{src → speechflow-cli/src}/speechflow.ts +188 -53
  31. package/speechflow-ui-db/etc/eslint.mjs +106 -0
  32. package/speechflow-ui-db/etc/htmllint.json +55 -0
  33. package/speechflow-ui-db/etc/stx.conf +79 -0
  34. package/speechflow-ui-db/etc/stylelint.js +46 -0
  35. package/speechflow-ui-db/etc/stylelint.yaml +33 -0
  36. package/speechflow-ui-db/etc/tsc-client.json +30 -0
  37. package/speechflow-ui-db/etc/tsc.node.json +9 -0
  38. package/speechflow-ui-db/etc/vite-client.mts +63 -0
  39. package/speechflow-ui-db/package.d/htmllint-cli+0.0.7.patch +20 -0
  40. package/speechflow-ui-db/package.json +75 -0
  41. package/speechflow-ui-db/src/app-icon.ai +1989 -4
  42. package/speechflow-ui-db/src/app-icon.svg +26 -0
  43. package/speechflow-ui-db/src/app.styl +64 -0
  44. package/speechflow-ui-db/src/app.vue +221 -0
  45. package/speechflow-ui-db/src/index.html +23 -0
  46. package/speechflow-ui-db/src/index.ts +26 -0
  47. package/{dst/speechflow.d.ts → speechflow-ui-db/src/lib.d.ts} +5 -3
  48. package/speechflow-ui-db/src/tsconfig.json +3 -0
  49. package/speechflow-ui-st/etc/eslint.mjs +106 -0
  50. package/speechflow-ui-st/etc/htmllint.json +55 -0
  51. package/speechflow-ui-st/etc/stx.conf +79 -0
  52. package/speechflow-ui-st/etc/stylelint.js +46 -0
  53. package/speechflow-ui-st/etc/stylelint.yaml +33 -0
  54. package/speechflow-ui-st/etc/tsc-client.json +30 -0
  55. package/speechflow-ui-st/etc/tsc.node.json +9 -0
  56. package/speechflow-ui-st/etc/vite-client.mts +63 -0
  57. package/speechflow-ui-st/package.d/htmllint-cli+0.0.7.patch +20 -0
  58. package/speechflow-ui-st/package.json +79 -0
  59. package/speechflow-ui-st/src/app-icon.ai +1989 -4
  60. package/speechflow-ui-st/src/app-icon.svg +26 -0
  61. package/speechflow-ui-st/src/app.styl +64 -0
  62. package/speechflow-ui-st/src/app.vue +142 -0
  63. package/speechflow-ui-st/src/index.html +23 -0
  64. package/speechflow-ui-st/src/index.ts +26 -0
  65. package/speechflow-ui-st/src/lib.d.ts +9 -0
  66. package/speechflow-ui-st/src/tsconfig.json +3 -0
  67. package/dst/speechflow-node-a2a-ffmpeg.d.ts +0 -13
  68. package/dst/speechflow-node-a2a-ffmpeg.js +0 -153
  69. package/dst/speechflow-node-a2a-ffmpeg.js.map +0 -1
  70. package/dst/speechflow-node-a2a-gender.d.ts +0 -18
  71. package/dst/speechflow-node-a2a-gender.js +0 -271
  72. package/dst/speechflow-node-a2a-gender.js.map +0 -1
  73. package/dst/speechflow-node-a2a-meter.d.ts +0 -12
  74. package/dst/speechflow-node-a2a-meter.js +0 -155
  75. package/dst/speechflow-node-a2a-meter.js.map +0 -1
  76. package/dst/speechflow-node-a2a-mute.d.ts +0 -16
  77. package/dst/speechflow-node-a2a-mute.js +0 -91
  78. package/dst/speechflow-node-a2a-mute.js.map +0 -1
  79. package/dst/speechflow-node-a2a-vad.d.ts +0 -16
  80. package/dst/speechflow-node-a2a-vad.js +0 -285
  81. package/dst/speechflow-node-a2a-vad.js.map +0 -1
  82. package/dst/speechflow-node-a2a-wav.d.ts +0 -11
  83. package/dst/speechflow-node-a2a-wav.js +0 -195
  84. package/dst/speechflow-node-a2a-wav.js.map +0 -1
  85. package/dst/speechflow-node-a2t-deepgram.d.ts +0 -15
  86. package/dst/speechflow-node-a2t-deepgram.js +0 -255
  87. package/dst/speechflow-node-a2t-deepgram.js.map +0 -1
  88. package/dst/speechflow-node-t2a-elevenlabs.d.ts +0 -16
  89. package/dst/speechflow-node-t2a-elevenlabs.js +0 -195
  90. package/dst/speechflow-node-t2a-elevenlabs.js.map +0 -1
  91. package/dst/speechflow-node-t2a-kokoro.d.ts +0 -13
  92. package/dst/speechflow-node-t2a-kokoro.js +0 -149
  93. package/dst/speechflow-node-t2a-kokoro.js.map +0 -1
  94. package/dst/speechflow-node-t2t-deepl.d.ts +0 -15
  95. package/dst/speechflow-node-t2t-deepl.js +0 -142
  96. package/dst/speechflow-node-t2t-deepl.js.map +0 -1
  97. package/dst/speechflow-node-t2t-format.d.ts +0 -11
  98. package/dst/speechflow-node-t2t-format.js +0 -82
  99. package/dst/speechflow-node-t2t-format.js.map +0 -1
  100. package/dst/speechflow-node-t2t-ollama.d.ts +0 -13
  101. package/dst/speechflow-node-t2t-ollama.js +0 -247
  102. package/dst/speechflow-node-t2t-ollama.js.map +0 -1
  103. package/dst/speechflow-node-t2t-openai.d.ts +0 -13
  104. package/dst/speechflow-node-t2t-openai.js +0 -227
  105. package/dst/speechflow-node-t2t-openai.js.map +0 -1
  106. package/dst/speechflow-node-t2t-sentence.d.ts +0 -17
  107. package/dst/speechflow-node-t2t-sentence.js +0 -234
  108. package/dst/speechflow-node-t2t-sentence.js.map +0 -1
  109. package/dst/speechflow-node-t2t-subtitle.d.ts +0 -13
  110. package/dst/speechflow-node-t2t-subtitle.js +0 -278
  111. package/dst/speechflow-node-t2t-subtitle.js.map +0 -1
  112. package/dst/speechflow-node-t2t-transformers.d.ts +0 -14
  113. package/dst/speechflow-node-t2t-transformers.js +0 -265
  114. package/dst/speechflow-node-t2t-transformers.js.map +0 -1
  115. package/dst/speechflow-node-x2x-filter.d.ts +0 -11
  116. package/dst/speechflow-node-x2x-filter.js +0 -117
  117. package/dst/speechflow-node-x2x-filter.js.map +0 -1
  118. package/dst/speechflow-node-x2x-trace.d.ts +0 -11
  119. package/dst/speechflow-node-x2x-trace.js +0 -111
  120. package/dst/speechflow-node-x2x-trace.js.map +0 -1
  121. package/dst/speechflow-node-xio-device.d.ts +0 -13
  122. package/dst/speechflow-node-xio-device.js +0 -226
  123. package/dst/speechflow-node-xio-device.js.map +0 -1
  124. package/dst/speechflow-node-xio-file.d.ts +0 -11
  125. package/dst/speechflow-node-xio-file.js +0 -210
  126. package/dst/speechflow-node-xio-file.js.map +0 -1
  127. package/dst/speechflow-node-xio-mqtt.d.ts +0 -13
  128. package/dst/speechflow-node-xio-mqtt.js +0 -185
  129. package/dst/speechflow-node-xio-mqtt.js.map +0 -1
  130. package/dst/speechflow-node-xio-websocket.d.ts +0 -13
  131. package/dst/speechflow-node-xio-websocket.js +0 -278
  132. package/dst/speechflow-node-xio-websocket.js.map +0 -1
  133. package/dst/speechflow-node.d.ts +0 -65
  134. package/dst/speechflow-node.js +0 -180
  135. package/dst/speechflow-node.js.map +0 -1
  136. package/dst/speechflow-utils.d.ts +0 -69
  137. package/dst/speechflow-utils.js +0 -486
  138. package/dst/speechflow-utils.js.map +0 -1
  139. package/dst/speechflow.js +0 -768
  140. package/dst/speechflow.js.map +0 -1
  141. package/src/speechflow-node-a2a-meter.ts +0 -130
  142. package/src/speechflow-node-a2a-vad.ts +0 -285
  143. package/src/speechflow-node-a2t-deepgram.ts +0 -234
  144. package/src/speechflow-node-t2t-subtitle.ts +0 -149
  145. /package/{etc → speechflow-cli/etc}/biome.jsonc +0 -0
  146. /package/{etc → speechflow-cli/etc}/oxlint.jsonc +0 -0
  147. /package/{etc → speechflow-cli/etc}/speechflow.bat +0 -0
  148. /package/{etc → speechflow-cli/etc}/speechflow.sh +0 -0
  149. /package/{etc → speechflow-cli/etc}/speechflow.yaml +0 -0
  150. /package/{etc → speechflow-cli/etc}/tsconfig.json +0 -0
  151. /package/{package.d → speechflow-cli/package.d}/@ericedouard+vad-node-realtime+0.2.0.patch +0 -0
  152. /package/{src → speechflow-cli/src}/lib.d.ts +0 -0
  153. /package/{src → speechflow-cli/src}/speechflow-logo.ai +0 -0
  154. /package/{src → speechflow-cli/src}/speechflow-logo.svg +0 -0
  155. /package/{src → speechflow-cli/src}/speechflow-node-a2a-ffmpeg.ts +0 -0
  156. /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
+