@winkjs/composer 0.0.2 → 0.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 (451) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +42 -103
  3. package/package.json +53 -29
  4. package/src/composer.js +75 -0
  5. package/src/core/batch/aoo-encoder.js +148 -0
  6. package/src/core/batch/index.js +12 -0
  7. package/src/core/batch/sliding-window.js +91 -0
  8. package/src/core/codec/index.js +137 -0
  9. package/src/core/emitter-manager/mqtt/constants.js +102 -0
  10. package/src/core/emitter-manager/mqtt/emitter.js +780 -0
  11. package/src/core/emitter-manager/mqtt/index.js +190 -0
  12. package/src/core/emitter-manager/mqtt/mqtt-store.js +538 -0
  13. package/src/core/emitter-manager/terminal/assert-columns.js +98 -0
  14. package/src/core/emitter-manager/terminal/formatters.js +160 -0
  15. package/src/core/emitter-manager/terminal/index.js +341 -0
  16. package/src/core/env-vars.js +245 -0
  17. package/src/core/mqtt-protocol.js +47 -0
  18. package/src/core/partition-manager/index.js +7 -0
  19. package/src/core/partition-manager/init.js +44 -0
  20. package/src/core/partition-manager/introspect.js +15 -0
  21. package/src/core/partition-manager/publish-to.js +6 -0
  22. package/src/core/partition-manager/recompute.js +5 -0
  23. package/src/core/partition-manager/reset.js +5 -0
  24. package/src/core/partition-manager/update.js +264 -0
  25. package/src/core/partition-manager/validate-flow.js +157 -0
  26. package/src/core/semantics/digest.js +128 -0
  27. package/src/core/semantics/index.js +83 -0
  28. package/src/core/semantics/loader.js +571 -0
  29. package/src/core/semantics/schemas/asset-class-schema.js +218 -0
  30. package/src/core/semantics/schemas/column-schema.js +651 -0
  31. package/src/core/semantics/schemas/enum-schema.js +153 -0
  32. package/src/core/semantics/schemas/index.js +51 -0
  33. package/src/core/semantics/warnings.js +141 -0
  34. package/src/core/shutdown-manager/index.js +289 -0
  35. package/src/core/source-manager/csv/index.js +171 -0
  36. package/src/core/source-manager/csv/start.js +456 -0
  37. package/src/core/source-manager/mqtt/client.js +406 -0
  38. package/src/core/source-manager/mqtt/constants.js +147 -0
  39. package/src/core/source-manager/mqtt/dedup.js +244 -0
  40. package/src/core/source-manager/mqtt/index.js +260 -0
  41. package/src/core/source-manager/mqtt/status.js +546 -0
  42. package/src/core/source-manager/test-harness/comparator.js +226 -0
  43. package/src/core/source-manager/test-harness/field-generator.js +85 -0
  44. package/src/core/source-manager/test-harness/fuzz.js +87 -0
  45. package/src/core/source-manager/test-harness/index.js +115 -0
  46. package/src/core/source-manager/test-harness/prng.js +57 -0
  47. package/src/core/source-manager/test-harness/start.js +232 -0
  48. package/src/core/source-manager/test-harness/validate.js +213 -0
  49. package/src/core/storage-manager/questdb/assert-columns.js +120 -0
  50. package/src/core/storage-manager/questdb/ensure-tables.js +187 -0
  51. package/src/core/storage-manager/questdb/index.js +1251 -0
  52. package/src/core/storage-manager/questdb/persist-plan.js +488 -0
  53. package/src/core/storage-manager/questdb/writers.js +142 -0
  54. package/src/core/test-utils/sealed-record.js +80 -0
  55. package/src/core/test-utils/soak-signature.js +149 -0
  56. package/src/core/test-utils/tcp-proxy.js +106 -0
  57. package/src/core/tunable/helpers.js +254 -0
  58. package/src/core/tunable/index.js +87 -0
  59. package/src/core/utils/console-formatter/index.js +207 -0
  60. package/src/core/utils/create-smart-store-as/index.js +98 -0
  61. package/src/core/utils/create-smart-store-as/sanitize-field.js +46 -0
  62. package/src/core/utils/create-smart-store-as/smart-truncate.js +93 -0
  63. package/src/core/utils/flow/index.js +5 -0
  64. package/src/core/utils/flow/make-collision-checker.js +23 -0
  65. package/src/core/utils/flow/to-kebab.js +20 -0
  66. package/src/core/utils/half-life/index.js +111 -0
  67. package/src/core/utils/node/disable.js +11 -0
  68. package/src/core/utils/node/enable.js +11 -0
  69. package/src/core/utils/node/execute-triggers.js +40 -0
  70. package/src/core/utils/node/index.js +10 -0
  71. package/src/core/utils/node/pause.js +11 -0
  72. package/src/core/utils/node/populate-predicate-inputs.js +14 -0
  73. package/src/core/utils/node/publish-nan.js +19 -0
  74. package/src/core/utils/node/reset-predicate-inputs.js +11 -0
  75. package/src/core/utils/node/unpause.js +11 -0
  76. package/src/core/utils/node/validate-spec.js +22 -0
  77. package/src/core/utils/options/resolve-field-keyed.js +115 -0
  78. package/src/core/utils/quantize/index.js +75 -0
  79. package/src/core/utils/stats/formulas.js +67 -0
  80. package/src/core/utils/stats/index.js +3 -0
  81. package/src/core/utils/validate/composer-validators.js +141 -0
  82. package/src/core/utils/validate/helpers.js +206 -0
  83. package/src/core/utils/validate/index.js +12 -0
  84. package/src/core/utils/validate/type-validators.js +538 -0
  85. package/src/core/utils/validate/validate.js +107 -0
  86. package/src/core/utils/validate/validators.js +177 -0
  87. package/src/core/wiring/assert-handle.js +57 -0
  88. package/src/core/wiring/assert-module.js +63 -0
  89. package/src/core/wiring/index.js +5 -0
  90. package/src/core/wiring/node-type-to-module.js +17 -0
  91. package/src/core/wiring/wire-emitters.js +256 -0
  92. package/src/core/wiring/wire-linear-graph.js +25 -0
  93. package/src/core/wiring/wire-node.js +157 -0
  94. package/src/core/wiring/wire-semantics.js +173 -0
  95. package/src/core/wiring/wire-storages.js +344 -0
  96. package/src/flow/check-output-collisions.js +93 -0
  97. package/src/flow/consts.js +9 -0
  98. package/src/flow/deep-clone-spec.js +64 -0
  99. package/src/flow/driver.js +171 -0
  100. package/src/flow/expand-single-input-array.js +76 -0
  101. package/src/flow/expand-template-spec.js +93 -0
  102. package/src/flow/flow-api-schemas.js +300 -0
  103. package/src/flow/flow.js +658 -0
  104. package/src/flow/for-each.js +225 -0
  105. package/src/flow/get-signature-pattern.js +31 -0
  106. package/src/flow/get-target-array.js +46 -0
  107. package/src/flow/inspect.js +67 -0
  108. package/src/flow/load-node-module.js +81 -0
  109. package/src/flow/make-node-method.js +112 -0
  110. package/src/flow/resolve-pick-by-field.js +77 -0
  111. package/src/flow/resolve-tunables.js +76 -0
  112. package/src/flow/run.js +392 -0
  113. package/src/flow/serialize.js +161 -0
  114. package/src/flow/signatures-schema.js +222 -0
  115. package/src/flow/spec-builder.js +65 -0
  116. package/src/flow/validate-triggers.js +250 -0
  117. package/src/flow/validate.js +261 -0
  118. package/src/nodes/accumulate/index.js +21 -0
  119. package/src/nodes/accumulate/init.js +48 -0
  120. package/src/nodes/accumulate/introspect.js +123 -0
  121. package/src/nodes/accumulate/publish-to.js +34 -0
  122. package/src/nodes/accumulate/recompute.js +27 -0
  123. package/src/nodes/accumulate/reset.js +25 -0
  124. package/src/nodes/accumulate/update.js +42 -0
  125. package/src/nodes/appraise/calibrate.js +64 -0
  126. package/src/nodes/appraise/decision.js +66 -0
  127. package/src/nodes/appraise/deviation.js +140 -0
  128. package/src/nodes/appraise/index.js +23 -0
  129. package/src/nodes/appraise/init.js +165 -0
  130. package/src/nodes/appraise/integrate.js +45 -0
  131. package/src/nodes/appraise/introspect.js +352 -0
  132. package/src/nodes/appraise/publish-to.js +93 -0
  133. package/src/nodes/appraise/receptor.js +69 -0
  134. package/src/nodes/appraise/recompute.js +79 -0
  135. package/src/nodes/appraise/reset.js +53 -0
  136. package/src/nodes/appraise/update.js +130 -0
  137. package/src/nodes/archive/csv/index.js +6 -0
  138. package/src/nodes/archive/csv/init.js +36 -0
  139. package/src/nodes/archive/csv/load.js +70 -0
  140. package/src/nodes/archive/csv/reset.js +14 -0
  141. package/src/nodes/archive/csv/simple-parser.js +216 -0
  142. package/src/nodes/archive/csv/test.js +173 -0
  143. package/src/nodes/archive/csv/update.js +63 -0
  144. package/src/nodes/butterworth-filter/index.js +18 -0
  145. package/src/nodes/butterworth-filter/init.js +184 -0
  146. package/src/nodes/butterworth-filter/introspect.js +228 -0
  147. package/src/nodes/butterworth-filter/publish-to.js +21 -0
  148. package/src/nodes/butterworth-filter/recompute.js +13 -0
  149. package/src/nodes/butterworth-filter/reset.js +30 -0
  150. package/src/nodes/butterworth-filter/update.js +38 -0
  151. package/src/nodes/categorize/index.js +19 -0
  152. package/src/nodes/categorize/init.js +58 -0
  153. package/src/nodes/categorize/introspect.js +177 -0
  154. package/src/nodes/categorize/publish-to.js +29 -0
  155. package/src/nodes/categorize/recompute.js +14 -0
  156. package/src/nodes/categorize/reset.js +16 -0
  157. package/src/nodes/categorize/update.js +53 -0
  158. package/src/nodes/controller/index.js +9 -0
  159. package/src/nodes/controller/init.js +55 -0
  160. package/src/nodes/controller/introspect.js +91 -0
  161. package/src/nodes/controller/publish-to.js +8 -0
  162. package/src/nodes/controller/recompute.js +9 -0
  163. package/src/nodes/controller/reset.js +17 -0
  164. package/src/nodes/controller/update.js +63 -0
  165. package/src/nodes/diff/index.js +19 -0
  166. package/src/nodes/diff/init.js +37 -0
  167. package/src/nodes/diff/introspect.js +132 -0
  168. package/src/nodes/diff/publish-to.js +21 -0
  169. package/src/nodes/diff/recompute.js +12 -0
  170. package/src/nodes/diff/reset.js +12 -0
  171. package/src/nodes/diff/update.js +37 -0
  172. package/src/nodes/digest-moments/formulas.js +12 -0
  173. package/src/nodes/digest-moments/index.js +14 -0
  174. package/src/nodes/digest-moments/init.js +67 -0
  175. package/src/nodes/digest-moments/introspect.js +154 -0
  176. package/src/nodes/digest-moments/publish-to.js +34 -0
  177. package/src/nodes/digest-moments/recompute.js +14 -0
  178. package/src/nodes/digest-moments/reset.js +14 -0
  179. package/src/nodes/digest-moments/update.js +120 -0
  180. package/src/nodes/dwell-time-tracker/index.js +14 -0
  181. package/src/nodes/dwell-time-tracker/init.js +59 -0
  182. package/src/nodes/dwell-time-tracker/introspect.js +137 -0
  183. package/src/nodes/dwell-time-tracker/publish-to.js +22 -0
  184. package/src/nodes/dwell-time-tracker/recompute.js +8 -0
  185. package/src/nodes/dwell-time-tracker/reset.js +23 -0
  186. package/src/nodes/dwell-time-tracker/update.js +103 -0
  187. package/src/nodes/emit-if/helpers.js +94 -0
  188. package/src/nodes/emit-if/index.js +16 -0
  189. package/src/nodes/emit-if/init.js +67 -0
  190. package/src/nodes/emit-if/introspect.js +102 -0
  191. package/src/nodes/emit-if/publish-to.js +13 -0
  192. package/src/nodes/emit-if/recompute.js +12 -0
  193. package/src/nodes/emit-if/reset.js +27 -0
  194. package/src/nodes/emit-if/update.js +93 -0
  195. package/src/nodes/es-correlation/index.js +19 -0
  196. package/src/nodes/es-correlation/init.js +73 -0
  197. package/src/nodes/es-correlation/introspect.js +176 -0
  198. package/src/nodes/es-correlation/publish-to.js +32 -0
  199. package/src/nodes/es-correlation/recompute.js +56 -0
  200. package/src/nodes/es-correlation/reset.js +27 -0
  201. package/src/nodes/es-correlation/update.js +110 -0
  202. package/src/nodes/es-mean/index.js +20 -0
  203. package/src/nodes/es-mean/init.js +58 -0
  204. package/src/nodes/es-mean/introspect.js +129 -0
  205. package/src/nodes/es-mean/publish-to.js +19 -0
  206. package/src/nodes/es-mean/recompute.js +16 -0
  207. package/src/nodes/es-mean/reset.js +24 -0
  208. package/src/nodes/es-mean/update.js +69 -0
  209. package/src/nodes/es-pairwise-correlation/index.js +19 -0
  210. package/src/nodes/es-pairwise-correlation/init.js +98 -0
  211. package/src/nodes/es-pairwise-correlation/introspect.js +187 -0
  212. package/src/nodes/es-pairwise-correlation/publish-to.js +31 -0
  213. package/src/nodes/es-pairwise-correlation/recompute.js +69 -0
  214. package/src/nodes/es-pairwise-correlation/reset.js +29 -0
  215. package/src/nodes/es-pairwise-correlation/update.js +89 -0
  216. package/src/nodes/es-stats/index.js +21 -0
  217. package/src/nodes/es-stats/init.js +105 -0
  218. package/src/nodes/es-stats/introspect.js +157 -0
  219. package/src/nodes/es-stats/publish-to.js +42 -0
  220. package/src/nodes/es-stats/recompute.js +74 -0
  221. package/src/nodes/es-stats/reset.js +49 -0
  222. package/src/nodes/es-stats/update-envelope.js +44 -0
  223. package/src/nodes/es-stats/update-welford.js +64 -0
  224. package/src/nodes/es-stats/update.js +59 -0
  225. package/src/nodes/index.js +83 -0
  226. package/src/nodes/invert-flag/index.js +20 -0
  227. package/src/nodes/invert-flag/init.js +36 -0
  228. package/src/nodes/invert-flag/introspect.js +115 -0
  229. package/src/nodes/invert-flag/publish-to.js +23 -0
  230. package/src/nodes/invert-flag/recompute.js +12 -0
  231. package/src/nodes/invert-flag/reset.js +12 -0
  232. package/src/nodes/invert-flag/update.js +32 -0
  233. package/src/nodes/kalman1d/index.js +20 -0
  234. package/src/nodes/kalman1d/init.js +103 -0
  235. package/src/nodes/kalman1d/introspect.js +250 -0
  236. package/src/nodes/kalman1d/publish-to.js +34 -0
  237. package/src/nodes/kalman1d/recompute.js +23 -0
  238. package/src/nodes/kalman1d/reset.js +29 -0
  239. package/src/nodes/kalman1d/update.js +144 -0
  240. package/src/nodes/kernel/index.js +18 -0
  241. package/src/nodes/kernel/init.js +66 -0
  242. package/src/nodes/kernel/introspect.js +163 -0
  243. package/src/nodes/kernel/presets.js +74 -0
  244. package/src/nodes/kernel/publish-to.js +25 -0
  245. package/src/nodes/kernel/recompute.js +14 -0
  246. package/src/nodes/kernel/reset.js +20 -0
  247. package/src/nodes/kernel/update.js +69 -0
  248. package/src/nodes/lag/index.js +21 -0
  249. package/src/nodes/lag/init.js +87 -0
  250. package/src/nodes/lag/introspect.js +202 -0
  251. package/src/nodes/lag/publish-to.js +64 -0
  252. package/src/nodes/lag/recompute.js +33 -0
  253. package/src/nodes/lag/reset.js +49 -0
  254. package/src/nodes/lag/update.js +133 -0
  255. package/src/nodes/median3/index.js +19 -0
  256. package/src/nodes/median3/init.js +40 -0
  257. package/src/nodes/median3/introspect.js +116 -0
  258. package/src/nodes/median3/publish-to.js +21 -0
  259. package/src/nodes/median3/recompute.js +12 -0
  260. package/src/nodes/median3/reset.js +15 -0
  261. package/src/nodes/median3/update.js +58 -0
  262. package/src/nodes/moments-digest/copy-from.js +12 -0
  263. package/src/nodes/moments-digest/flush.js +17 -0
  264. package/src/nodes/moments-digest/index.js +132 -0
  265. package/src/nodes/moments-digest/init.js +84 -0
  266. package/src/nodes/moments-digest/introspect.js +122 -0
  267. package/src/nodes/moments-digest/prelude.js +28 -0
  268. package/src/nodes/moments-digest/publish-to.js +31 -0
  269. package/src/nodes/moments-digest/recompute.js +9 -0
  270. package/src/nodes/moments-digest/reset.js +20 -0
  271. package/src/nodes/moments-digest/update.js +182 -0
  272. package/src/nodes/node-names.js +67 -0
  273. package/src/nodes/page-hinkley/index.js +20 -0
  274. package/src/nodes/page-hinkley/init.js +66 -0
  275. package/src/nodes/page-hinkley/introspect.js +193 -0
  276. package/src/nodes/page-hinkley/publish-to.js +28 -0
  277. package/src/nodes/page-hinkley/recompute.js +14 -0
  278. package/src/nodes/page-hinkley/reset.js +23 -0
  279. package/src/nodes/page-hinkley/update.js +105 -0
  280. package/src/nodes/pass-if/index.js +21 -0
  281. package/src/nodes/pass-if/init.js +37 -0
  282. package/src/nodes/pass-if/introspect.js +93 -0
  283. package/src/nodes/pass-if/publish-to.js +15 -0
  284. package/src/nodes/pass-if/recompute.js +15 -0
  285. package/src/nodes/pass-if/reset.js +18 -0
  286. package/src/nodes/pass-if/update.js +37 -0
  287. package/src/nodes/persist-if/helpers.js +111 -0
  288. package/src/nodes/persist-if/index.js +9 -0
  289. package/src/nodes/persist-if/init.js +98 -0
  290. package/src/nodes/persist-if/introspect.js +106 -0
  291. package/src/nodes/persist-if/publish-to.js +21 -0
  292. package/src/nodes/persist-if/recompute.js +20 -0
  293. package/src/nodes/persist-if/reset.js +35 -0
  294. package/src/nodes/persist-if/update.js +112 -0
  295. package/src/nodes/persistence-check/index.js +14 -0
  296. package/src/nodes/persistence-check/init.js +38 -0
  297. package/src/nodes/persistence-check/introspect.js +144 -0
  298. package/src/nodes/persistence-check/publish-to.js +11 -0
  299. package/src/nodes/persistence-check/recompute.js +7 -0
  300. package/src/nodes/persistence-check/reset.js +12 -0
  301. package/src/nodes/persistence-check/update.js +57 -0
  302. package/src/nodes/process-index/index.js +15 -0
  303. package/src/nodes/process-index/init.js +48 -0
  304. package/src/nodes/process-index/introspect.js +182 -0
  305. package/src/nodes/process-index/publish-to.js +29 -0
  306. package/src/nodes/process-index/recompute.js +8 -0
  307. package/src/nodes/process-index/reset.js +8 -0
  308. package/src/nodes/process-index/update.js +75 -0
  309. package/src/nodes/ratio/index.js +14 -0
  310. package/src/nodes/ratio/init.js +37 -0
  311. package/src/nodes/ratio/introspect.js +155 -0
  312. package/src/nodes/ratio/publish-to.js +15 -0
  313. package/src/nodes/ratio/recompute.js +7 -0
  314. package/src/nodes/ratio/reset.js +7 -0
  315. package/src/nodes/ratio/update.js +47 -0
  316. package/src/nodes/sanitize/index.js +82 -0
  317. package/src/nodes/sanitize/init.js +82 -0
  318. package/src/nodes/sanitize/introspect.js +194 -0
  319. package/src/nodes/sanitize/publish-to.js +15 -0
  320. package/src/nodes/sanitize/recompute.js +8 -0
  321. package/src/nodes/sanitize/reset.js +14 -0
  322. package/src/nodes/sanitize/update.js +102 -0
  323. package/src/nodes/spike-guard/index.js +14 -0
  324. package/src/nodes/spike-guard/init.js +47 -0
  325. package/src/nodes/spike-guard/introspect.js +130 -0
  326. package/src/nodes/spike-guard/publish-to.js +35 -0
  327. package/src/nodes/spike-guard/recompute.js +14 -0
  328. package/src/nodes/spike-guard/reset.js +19 -0
  329. package/src/nodes/spike-guard/update.js +89 -0
  330. package/src/nodes/sse-emitter/index.js +7 -0
  331. package/src/nodes/sse-emitter/init.js +105 -0
  332. package/src/nodes/sse-emitter/introspect.js +134 -0
  333. package/src/nodes/sse-emitter/publish-to.js +6 -0
  334. package/src/nodes/sse-emitter/recompute.js +16 -0
  335. package/src/nodes/sse-emitter/reset.js +19 -0
  336. package/src/nodes/sse-emitter/update.js +69 -0
  337. package/src/nodes/sse-emitter/utils/broadcast-heartbeat.js +36 -0
  338. package/src/nodes/sse-emitter/utils/build-message.js +31 -0
  339. package/src/nodes/sse-emitter/utils/connection-manager.js +45 -0
  340. package/src/nodes/sse-emitter/utils/endpoint-initializer.js +20 -0
  341. package/src/nodes/sse-emitter/utils/health-monitor.js +38 -0
  342. package/src/nodes/sse-emitter/utils/qos-handler.js +41 -0
  343. package/src/nodes/state-change-detector/helpers.js +35 -0
  344. package/src/nodes/state-change-detector/index.js +12 -0
  345. package/src/nodes/state-change-detector/init.js +56 -0
  346. package/src/nodes/state-change-detector/introspect.js +146 -0
  347. package/src/nodes/state-change-detector/publish-to.js +20 -0
  348. package/src/nodes/state-change-detector/recompute.js +6 -0
  349. package/src/nodes/state-change-detector/reset.js +20 -0
  350. package/src/nodes/state-change-detector/update.js +97 -0
  351. package/src/nodes/sw-stats/index.js +14 -0
  352. package/src/nodes/sw-stats/init.js +51 -0
  353. package/src/nodes/sw-stats/introspect.js +131 -0
  354. package/src/nodes/sw-stats/publish-to.js +45 -0
  355. package/src/nodes/sw-stats/recompute.js +33 -0
  356. package/src/nodes/sw-stats/reset.js +15 -0
  357. package/src/nodes/sw-stats/update.js +39 -0
  358. package/src/nodes/swing-watch/index.js +17 -0
  359. package/src/nodes/swing-watch/init.js +144 -0
  360. package/src/nodes/swing-watch/introspect.js +188 -0
  361. package/src/nodes/swing-watch/publish-to.js +53 -0
  362. package/src/nodes/swing-watch/recompute.js +22 -0
  363. package/src/nodes/swing-watch/reset.js +55 -0
  364. package/src/nodes/swing-watch/update.js +767 -0
  365. package/src/nodes/tally/index.js +15 -0
  366. package/src/nodes/tally/init.js +32 -0
  367. package/src/nodes/tally/introspect.js +116 -0
  368. package/src/nodes/tally/publish-to.js +28 -0
  369. package/src/nodes/tally/recompute.js +10 -0
  370. package/src/nodes/tally/reset.js +10 -0
  371. package/src/nodes/tally/update.js +44 -0
  372. package/src/nodes/threshold/index.js +14 -0
  373. package/src/nodes/threshold/init.js +121 -0
  374. package/src/nodes/threshold/introspect.js +192 -0
  375. package/src/nodes/threshold/publish-to.js +11 -0
  376. package/src/nodes/threshold/recompute.js +8 -0
  377. package/src/nodes/threshold/reset.js +14 -0
  378. package/src/nodes/threshold/update.js +54 -0
  379. package/src/nodes/transform/helpers.js +39 -0
  380. package/src/nodes/transform/index.js +15 -0
  381. package/src/nodes/transform/init.js +35 -0
  382. package/src/nodes/transform/introspect.js +118 -0
  383. package/src/nodes/transform/publish-to.js +23 -0
  384. package/src/nodes/transform/recompute.js +12 -0
  385. package/src/nodes/transform/reset.js +11 -0
  386. package/src/nodes/transform/update.js +32 -0
  387. package/src/nodes/trend/compute-confidence.js +112 -0
  388. package/src/nodes/trend/index.js +14 -0
  389. package/src/nodes/trend/init.js +81 -0
  390. package/src/nodes/trend/introspect.js +151 -0
  391. package/src/nodes/trend/publish-to.js +22 -0
  392. package/src/nodes/trend/recompute.js +15 -0
  393. package/src/nodes/trend/reset.js +26 -0
  394. package/src/nodes/trend/update.js +93 -0
  395. package/src/nodes/tw-stats/copy-from.js +16 -0
  396. package/src/nodes/tw-stats/flush.js +12 -0
  397. package/src/nodes/tw-stats/index.js +41 -0
  398. package/src/nodes/tw-stats/init.js +92 -0
  399. package/src/nodes/tw-stats/introspect.js +171 -0
  400. package/src/nodes/tw-stats/publish-to.js +108 -0
  401. package/src/nodes/tw-stats/recompute.js +9 -0
  402. package/src/nodes/tw-stats/reset.js +16 -0
  403. package/src/nodes/tw-stats/update.js +113 -0
  404. package/src/nodes/unbalance/index.js +15 -0
  405. package/src/nodes/unbalance/init.js +59 -0
  406. package/src/nodes/unbalance/introspect.js +167 -0
  407. package/src/nodes/unbalance/publish-to.js +52 -0
  408. package/src/nodes/unbalance/recompute.js +11 -0
  409. package/src/nodes/unbalance/reset.js +10 -0
  410. package/src/nodes/unbalance/update.js +83 -0
  411. package/src/nodes/vector-distance/index.js +14 -0
  412. package/src/nodes/vector-distance/init.js +54 -0
  413. package/src/nodes/vector-distance/introspect.js +149 -0
  414. package/src/nodes/vector-distance/publish-to.js +35 -0
  415. package/src/nodes/vector-distance/recompute.js +11 -0
  416. package/src/nodes/vector-distance/reset.js +20 -0
  417. package/src/nodes/vector-distance/update.js +139 -0
  418. package/src/nodes/winnow/index.js +12 -0
  419. package/src/nodes/winnow/init.js +82 -0
  420. package/src/nodes/winnow/introspect.js +253 -0
  421. package/src/nodes/winnow/publish-to.js +51 -0
  422. package/src/nodes/winnow/recompute.js +14 -0
  423. package/src/nodes/winnow/reset.js +34 -0
  424. package/src/nodes/winnow/update.js +203 -0
  425. package/src/tools/training/features.js +227 -0
  426. package/src/tools/training/index.js +21 -0
  427. package/src/tools/training/logistic.js +238 -0
  428. package/src/tools/training/metrics.js +126 -0
  429. package/src/tools/training/scale.js +239 -0
  430. package/src/tools/training/validate.js +103 -0
  431. package/src/windowing/count-sliding/create.js +16 -0
  432. package/src/windowing/count-sliding/get-reverse-chronological-index.js +19 -0
  433. package/src/windowing/count-sliding/index.js +6 -0
  434. package/src/windowing/count-sliding/is-not-full.js +5 -0
  435. package/src/windowing/count-sliding/push.js +15 -0
  436. package/src/windowing/count-sliding/reset.js +11 -0
  437. package/src/windowing/count-sliding/size.js +5 -0
  438. package/src/windowing/time-sliding/create.js +25 -0
  439. package/src/windowing/time-sliding/push.js +42 -0
  440. package/CODE_OF_CONDUCT.md +0 -46
  441. package/CONTRIBUTING.md +0 -132
  442. package/docs/.nojekyll +0 -0
  443. package/docs/CONTRIBUTING.md +0 -134
  444. package/docs/README.md +0 -132
  445. package/docs/_coverpage.md +0 -26
  446. package/docs/_media/bg.png +0 -0
  447. package/docs/_media/wink-logo.png +0 -0
  448. package/docs/_navbar.md +0 -14
  449. package/docs/_sidebar.md +0 -2
  450. package/docs/index.html +0 -44
  451. package/eslint.config.js +0 -283
@@ -0,0 +1,113 @@
1
+ // nodes/tw-stats/update.js
2
+
3
+ /**
4
+ * @fileoverview TW Stats Update — Pébay incremental moment accumulation
5
+ * with selective tier gating and tumbling window management.
6
+ *
7
+ * ────────────────────────────────────────────────────────────────────────
8
+ * Execution Flow (per message)
9
+ *
10
+ * 1) Prelude
11
+ * • Clear planPublish from last tick.
12
+ * • If flush is latched and n > 0: snapshot → planPublish → reset.
13
+ * The current message becomes the first sample of the next window.
14
+ *
15
+ * 2) Core update
16
+ * • Guard: disabled, invalid input (skip and return).
17
+ * • Pébay accumulation with tier gates (maxMoment 1–4).
18
+ * • Critical: update order is M4 → M3 → M2 → M1 because each
19
+ * formula uses the previous values of lower moments.
20
+ *
21
+ * 3) Epilogue
22
+ * • Increment valid sample counter.
23
+ * • If window complete and no flush snapshot already planned:
24
+ * snapshot → planPublish → reset.
25
+ *
26
+ * ────────────────────────────────────────────────────────────────────────
27
+ * Invalid input handling
28
+ * • Non-finite samples are skipped (not counted).
29
+ * • currentCount only increments on valid samples.
30
+ * • A flush snapshot planned in prelude still publishes this tick.
31
+ *
32
+ * ────────────────────────────────────────────────────────────────────────
33
+ * References
34
+ * [1] Pébay, P. (2008). Formulas for robust, one-pass parallel computation
35
+ * of covariances and arbitrary-order statistical moments.
36
+ * Sandia Report SAND2008-6212.
37
+ */
38
+
39
+ /* eslint-disable camelcase */
40
+ import { copyFrom } from './copy-from.js';
41
+ import reset from './reset.js';
42
+
43
+ const update = function ( state, msg ) {
44
+ if ( state.disable || state.pause ) return state;
45
+
46
+ // ── Prelude ─────────────────────────────────────────────────────────
47
+ state.planPublish = false;
48
+
49
+ if ( state.flushLatched ) {
50
+ if ( state.n > 0 ) {
51
+ copyFrom( state, state.snapshot );
52
+ state.planPublish = true;
53
+ reset( state );
54
+ }
55
+ state.flushLatched = false;
56
+ }
57
+
58
+ // ── Core update ─────────────────────────────────────────────────────
59
+ state.inputValidationFailed = false;
60
+
61
+ const xVal = msg[ state.x ];
62
+
63
+ if ( !Number.isFinite( xVal ) ) {
64
+ state.inputValidationFailed = true;
65
+ return state;
66
+ }
67
+
68
+ // Pébay single-value update with selective tier gating
69
+ const n1 = state.n;
70
+ state.n += 1;
71
+
72
+ const delta = xVal - state.M1;
73
+ const delta_n = delta / state.n;
74
+ const delta_n2 = delta_n * delta_n;
75
+ const term1 = delta * delta_n * n1;
76
+
77
+ // Update order: M1, then M4 → M3 → M2 (matches momentsDigest).
78
+ // M4 and M3 formulas use the previous values of M2 and M3;
79
+ // none depend on M1 (delta_n is already computed from old M1).
80
+ state.M1 += delta_n;
81
+
82
+ if ( state.maxMoment >= 4 ) {
83
+ state.M4 += ( term1 * delta_n2 * ( ( state.n * state.n ) - ( 3 * state.n ) + 3 ) ) +
84
+ ( 6 * delta_n2 * state.M2 ) - ( 4 * delta_n * state.M3 );
85
+ }
86
+
87
+ if ( state.maxMoment >= 3 ) {
88
+ state.M3 += ( term1 * delta_n * ( state.n - 2 ) ) - ( 3 * delta_n * state.M2 );
89
+ }
90
+
91
+ if ( state.maxMoment >= 2 ) {
92
+ state.M2 += term1;
93
+ }
94
+
95
+ // Min/max tracking
96
+ if ( state.needsMinMax ) {
97
+ if ( xVal < state.min ) state.min = xVal;
98
+ if ( xVal > state.max ) state.max = xVal;
99
+ }
100
+
101
+ // ── Epilogue ────────────────────────────────────────────────────────
102
+ state.currentCount += 1;
103
+
104
+ if ( ( state.currentCount >= state.windowSize ) && !state.planPublish ) {
105
+ copyFrom( state, state.snapshot );
106
+ state.planPublish = true;
107
+ reset( state );
108
+ }
109
+
110
+ return state;
111
+ }; // update()
112
+
113
+ export default update;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview Entry point for the unbalance node. Re-exports lifecycle
3
+ * functions, the shared control signals, and introspection metadata.
4
+ */
5
+
6
+ export { default as init } from './init.js';
7
+ export { default as update } from './update.js';
8
+ export { default as reset } from './reset.js';
9
+ export { default as recompute } from './recompute.js';
10
+ export { default as publishTo } from './publish-to.js';
11
+ export { default as disable } from '../../core/utils/node/disable.js';
12
+ export { default as enable } from '../../core/utils/node/enable.js';
13
+ export { default as pause } from '../../core/utils/node/pause.js';
14
+ export { default as unpause } from '../../core/utils/node/unpause.js';
15
+ export * from './introspect.js';
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Initializes unbalance node state from a validated spec.
3
+ * Pre-resolves the field-name list, the missing-channel policy, and which stats
4
+ * need the deviation step. Keeps state.stats so publishNaN() can target every
5
+ * configured output. Stateless: no buffers, no temporal state.
6
+ */
7
+
8
+ import { validateSpec } from '../../core/utils/node/index.js';
9
+ import * as introspect from './introspect.js';
10
+
11
+ /** Mean magnitudes below this make the percentage undefined. */
12
+ const EPSILON = 1e-12;
13
+
14
+ const init = function ( spec ) {
15
+ validateSpec( spec, introspect );
16
+
17
+ const state = Object.create( null );
18
+ state.inputValidationFailed = false;
19
+ state.disable = false;
20
+ state.pause = false;
21
+
22
+ state.fields = spec.from.x.slice( 0 );
23
+ state.n = state.fields.length;
24
+ state.stats = spec.stats;
25
+ state.epsilon = EPSILON;
26
+
27
+ // Missing-channel policy, resolved once. With skipOnNaN off (the default) any
28
+ // non-finite input blanks the tick, so the floor is the full width n. With
29
+ // skipOnNaN on, the metric is computed over the present channels, down to
30
+ // minPresent ( default 2, the fewest where a spread is defined ). The hot path
31
+ // only compares the present count against state.minPresent.
32
+ state.skipOnNaN = spec.skipOnNaN ?? introspect.DEFAULT_OPTIONS.skipOnNaN;
33
+ state.minPresent = state.skipOnNaN ?
34
+ ( spec.minPresent ?? introspect.DEFAULT_OPTIONS.minPresent ) :
35
+ state.n;
36
+
37
+ // The deviation step is only needed for these four stats.
38
+ state.needDev = Boolean(
39
+ spec.stats.maxDev || spec.stats.unbalance ||
40
+ spec.stats.worstIndex || spec.stats.worstDev
41
+ );
42
+
43
+ // Computed outputs (fixed shape, overwritten each tick).
44
+ state.mean = 0;
45
+ state.min = 0;
46
+ state.max = 0;
47
+ state.range = 0;
48
+ state.maxDev = 0;
49
+ state.unbalance = 0;
50
+ state.worstIndex = 0;
51
+ state.worstDev = 0;
52
+ state.presentCount = 0;
53
+
54
+ state.nodeType = introspect.getNodeType();
55
+
56
+ return state;
57
+ }; // init()
58
+
59
+ export default init;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * @fileoverview Single source of truth for the unbalance node — supported
3
+ * stats, capabilities, control methods, and the DSL/validation schema.
4
+ * All getters return defensive copies. The `unbalance` stat is the general
5
+ * normalized maximum deviation from the mean across N nominally-equal
6
+ * channels; NEMA / IEEE PVUR is the named electrical instance of the same
7
+ * computation. The `unbalance` percentage is relative: it divides by the mean,
8
+ * so it means something only when the channels are energized/loaded. At idle the
9
+ * inputs are sensor noise and the value comes out large but meaningless; gate
10
+ * idle/off states upstream (the operating-gated metric composition pattern).
11
+ *
12
+ * Missing channels: by default any non-finite input blanks every output, because
13
+ * an incomplete set is an undefined cross-field metric. The opt-in `skipOnNaN`
14
+ * mode instead reports over the channels that are present, down to a `minPresent`
15
+ * floor. The `presentCount` output reports how many channels reported and is
16
+ * always the real count, even on a blanked tick.
17
+ */
18
+
19
+ import { validators } from '../../core/utils/validate/index.js';
20
+
21
+ const SUPPORTED_STATS = [
22
+ 'mean',
23
+ 'min',
24
+ 'max',
25
+ 'range',
26
+ 'maxDev',
27
+ 'unbalance',
28
+ 'worstIndex',
29
+ 'worstDev',
30
+ 'presentCount'
31
+ ];
32
+
33
+ const STAT_DESCRIPTIONS = {
34
+ mean: 'Arithmetic mean of the N input magnitudes',
35
+ min: 'Minimum input magnitude',
36
+ max: 'Maximum input magnitude',
37
+ range: 'max - min (peak-to-peak spread)',
38
+ maxDev: 'Maximum absolute deviation from the mean',
39
+ unbalance: 'Normalized max-deviation: ( maxDev / |mean| ) * 100. Relative metric — meaningful only when channels are energized/loaded; gate idle/off states (see the operating-gated metric pattern)',
40
+ worstIndex: 'Zero-based index of the most-deviating input',
41
+ worstDev: 'Signed deviation ( value - mean ) of the worst input',
42
+ presentCount: 'How many channels reported (were finite) this tick. Always the real count, even when the metric blanks, because it describes the input not the result. Use it with skipOnNaN to gate on coverage'
43
+ };
44
+
45
+ const SUPPORTED_CONTROL_METHODS = {
46
+ reset: 'No-op (stateless node)',
47
+ enable: 'Enables node processing',
48
+ disable: 'Disables node processing',
49
+ pause: 'Pauses update() while keeping last values visible via publishTo()',
50
+ unpause: 'Resumes update() after pause'
51
+ };
52
+
53
+ const NODE_TYPE = 'Unbalance';
54
+
55
+ const CAPABILITIES = {
56
+ description: 'Instantaneous cross-field unbalance over N nominally-equal magnitudes',
57
+ features: [
58
+ 'Stateless and allocation-free',
59
+ 'Domain-agnostic (electrical, thermal, mechanical, process)',
60
+ 'Blank-on-miss by default: any missing channel makes every output NaN',
61
+ 'Opt-in skipOnNaN: report over the present channels, down to a minPresent floor',
62
+ 'presentCount output: how many channels reported, always the real count',
63
+ 'Worst-channel diagnostics (index and signed deviation)',
64
+ 'Single pass: worst channel derived from the min/max extremes'
65
+ ]
66
+ };
67
+
68
+ export const getSupportedStats = () => SUPPORTED_STATS.slice();
69
+ export const getStatDescriptions = () => ( { ...STAT_DESCRIPTIONS } );
70
+ export const getSupportedControlMethods = () => ( { ...SUPPORTED_CONTROL_METHODS } );
71
+ export const getNodeType = () => NODE_TYPE;
72
+ export const getCapabilities = () => ( { ...CAPABILITIES, features: CAPABILITIES.features.slice() } );
73
+
74
+ // Spec default values.
75
+ export const DEFAULT_OPTIONS = {
76
+ skipOnNaN: false, // blank every output if any channel is missing (the safe default)
77
+ minPresent: 2 // when skipOnNaN is true, the fewest present channels that still compute
78
+ };
79
+
80
+ const DSL_METADATA = {
81
+ specSchema: {
82
+ nodeType: { type: 'string', required: true, value: NODE_TYPE },
83
+ name: {
84
+ type: 'string',
85
+ required: true,
86
+ validator: validators.identifier,
87
+ error: 'name must be a valid identifier'
88
+ },
89
+ from: {
90
+ type: 'object',
91
+ required: true,
92
+ properties: {
93
+ x: {
94
+ type: 'array',
95
+ required: true,
96
+ minItems: 2,
97
+ itemSchema: {
98
+ type: 'string',
99
+ validator: validators.noSpaces,
100
+ error: 'field names cannot contain spaces'
101
+ }
102
+ }
103
+ }
104
+ },
105
+ stats: {
106
+ type: 'object',
107
+ required: true,
108
+ minProperties: 1,
109
+ propertyNames: SUPPORTED_STATS,
110
+ propertySchema: {
111
+ type: 'object',
112
+ required: true,
113
+ properties: {
114
+ storeAs: {
115
+ type: 'string',
116
+ required: true,
117
+ minLength: 1,
118
+ validator: validators.identifier,
119
+ error: 'storeAs must be a valid identifier'
120
+ }
121
+ }
122
+ }
123
+ },
124
+ skipOnNaN: {
125
+ type: 'boolean',
126
+ required: false
127
+ },
128
+ minPresent: {
129
+ // The effective default is conditional — n channels in blank mode, 2 in
130
+ // skip mode (see DEFAULT_OPTIONS), so it is not a flat schema default. The
131
+ // floor of 2 is where a spread is defined.
132
+ type: 'number',
133
+ required: false,
134
+ integer: true,
135
+ min: 2,
136
+ error: 'minPresent must be an integer >= 2'
137
+ }
138
+ },
139
+
140
+ crossFieldValidators: [
141
+ {
142
+ fields: [ 'from.x' ],
143
+ validator: ( spec ) => ( new Set( spec.from.x ).size === spec.from.x.length ),
144
+ error: 'field names must be unique'
145
+ },
146
+ {
147
+ fields: [ 'minPresent', 'skipOnNaN' ],
148
+ validator: ( spec ) => ( spec.minPresent === undefined ) || ( spec.skipOnNaN === true ),
149
+ error: 'minPresent applies only when skipOnNaN is true'
150
+ },
151
+ {
152
+ fields: [ 'minPresent', 'from.x' ],
153
+ validator: ( spec ) => ( spec.minPresent === undefined ) || ( spec.minPresent <= spec.from.x.length ),
154
+ error: 'minPresent cannot exceed the number of fields'
155
+ }
156
+ ],
157
+
158
+ buildSpec: ( name, x, stats, options ) => ( {
159
+ nodeType: NODE_TYPE,
160
+ name,
161
+ from: { x },
162
+ stats,
163
+ ...options
164
+ } )
165
+ };
166
+
167
+ export const getDSLMetadata = () => ( { ...DSL_METADATA } );
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @fileoverview Copies the computed unbalance stats onto the message, or
3
+ * propagates NaN to every configured metric when the last input was invalid.
4
+ * presentCount is written separately and always carries the real count, because
5
+ * it describes the input, not the result. Skipped when disabled; still runs when
6
+ * paused so last values stay visible.
7
+ */
8
+
9
+ import { publishNaN } from '../../core/utils/node/index.js';
10
+
11
+ const publishTo = function ( state, msg ) {
12
+ if ( state.disable ) return;
13
+
14
+ const stats = state.stats;
15
+
16
+ if ( state.inputValidationFailed ) {
17
+ publishNaN( state, msg );
18
+ } else {
19
+ if ( stats.mean ) {
20
+ msg[ stats.mean.storeAs ] = state.mean;
21
+ }
22
+ if ( stats.min ) {
23
+ msg[ stats.min.storeAs ] = state.min;
24
+ }
25
+ if ( stats.max ) {
26
+ msg[ stats.max.storeAs ] = state.max;
27
+ }
28
+ if ( stats.range ) {
29
+ msg[ stats.range.storeAs ] = state.range;
30
+ }
31
+ if ( stats.maxDev ) {
32
+ msg[ stats.maxDev.storeAs ] = state.maxDev;
33
+ }
34
+ if ( stats.unbalance ) {
35
+ msg[ stats.unbalance.storeAs ] = state.unbalance;
36
+ }
37
+ if ( stats.worstIndex ) {
38
+ msg[ stats.worstIndex.storeAs ] = state.worstIndex;
39
+ }
40
+ if ( stats.worstDev ) {
41
+ msg[ stats.worstDev.storeAs ] = state.worstDev;
42
+ }
43
+ }
44
+
45
+ // presentCount describes the input, so it carries the real count on every
46
+ // tick — including a blanked one, where publishNaN above set it to NaN.
47
+ if ( stats.presentCount ) {
48
+ msg[ stats.presentCount.storeAs ] = state.presentCount;
49
+ }
50
+ }; // publishTo()
51
+
52
+ export default publishTo;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Recompute for the unbalance node. The computation is exact and
3
+ * stateless — there is no incremental drift to correct — so recompute is a
4
+ * no-op.
5
+ */
6
+
7
+ const recompute = function () {
8
+ return true;
9
+ }; // recompute()
10
+
11
+ export default recompute;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fileoverview Reset for the unbalance node. Nothing accumulates — every
3
+ * output is recomputed from scratch each tick — so reset is a no-op.
4
+ */
5
+
6
+ const reset = function () {
7
+ return true;
8
+ }; // reset()
9
+
10
+ export default reset;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @fileoverview Hot path for the unbalance node.
3
+ *
4
+ * One linear pass computes the sum, the min and max, and the indices of those
5
+ * extremes. The most-deviating-from-mean channel is always one of the extremes
6
+ * ( for any xi, |xi - mean| <= max( max - mean, mean - min ) ), so maxDev,
7
+ * worstIndex and worstDev follow with no second pass.
8
+ *
9
+ * Missing channels: a non-finite field ( NaN or +/-Infinity ) is skipped and the
10
+ * present channels are counted. The tick blanks ( publishTo writes NaN to every
11
+ * metric ) when fewer than state.minPresent channels are present. In the default
12
+ * blank mode minPresent equals the full width, so any one missing field blanks
13
+ * the tick — an incomplete set is an undefined cross-field metric. In skip mode
14
+ * minPresent is lower, so the metric is computed over the channels present.
15
+ * presentCount always carries the real count, even on a blanked tick.
16
+ */
17
+
18
+ const update = function ( state, msg ) {
19
+ if ( state.disable || state.pause ) return state;
20
+ state.inputValidationFailed = false;
21
+
22
+ const fields = state.fields;
23
+ const n = state.n;
24
+
25
+ let sum = 0;
26
+ let minVal = Infinity;
27
+ let maxVal = -Infinity;
28
+ let minIdx = 0;
29
+ let maxIdx = 0;
30
+ let present = 0;
31
+ let i = 0;
32
+
33
+ while ( i < n ) {
34
+ const v = msg[ fields[ i ] ];
35
+ if ( Number.isFinite( v ) ) {
36
+ sum += v;
37
+ present += 1;
38
+ if ( v < minVal ) {
39
+ minVal = v;
40
+ minIdx = i;
41
+ }
42
+ if ( v > maxVal ) {
43
+ maxVal = v;
44
+ maxIdx = i;
45
+ }
46
+ }
47
+ i += 1;
48
+ }
49
+
50
+ // A fact about the input, always defined — set before any blank return.
51
+ state.presentCount = present;
52
+
53
+ if ( present < state.minPresent ) {
54
+ state.inputValidationFailed = true;
55
+ return state;
56
+ }
57
+
58
+ const mean = sum / present;
59
+ state.mean = mean;
60
+ state.min = minVal;
61
+ state.max = maxVal;
62
+ state.range = ( maxVal - minVal );
63
+
64
+ if ( state.needDev === false ) return state;
65
+
66
+ const devHigh = ( maxVal - mean );
67
+ const devLow = ( mean - minVal );
68
+ const highWins = ( devHigh >= devLow );
69
+
70
+ const maxAbsDev = highWins ? devHigh : devLow;
71
+ state.maxDev = maxAbsDev;
72
+ state.worstIndex = highWins ? maxIdx : minIdx;
73
+ state.worstDev = highWins ? devHigh : ( -devLow );
74
+
75
+ const absMean = Math.abs( mean );
76
+ state.unbalance = ( absMean < state.epsilon ) ?
77
+ NaN :
78
+ ( ( 100 * maxAbsDev ) / absMean );
79
+
80
+ return state;
81
+ }; // update()
82
+
83
+ export default update;
@@ -0,0 +1,14 @@
1
+ // nodes/vector-distance/index.js
2
+
3
+ export { default as init } from './init.js';
4
+ export { default as update } from './update.js';
5
+ export { default as reset } from './reset.js';
6
+ export { default as recompute } from './recompute.js';
7
+ export { default as publishTo } from './publish-to.js';
8
+ // Direct imports for common control functions
9
+ export { default as disable } from '../../core/utils/node/disable.js';
10
+ export { default as enable } from '../../core/utils/node/enable.js';
11
+ export { default as pause } from '../../core/utils/node/pause.js';
12
+ export { default as unpause } from '../../core/utils/node/unpause.js';
13
+ // Re-export everything from introspection.js
14
+ export * from './introspect.js';
@@ -0,0 +1,54 @@
1
+ // nodes/vector-distance/init.js
2
+
3
+ /* eslint-disable no-bitwise */
4
+ import { validateSpec } from '../../core/utils/node/index.js';
5
+ import * as introspect from './introspect.js';
6
+
7
+ const init = function ( spec ) {
8
+ validateSpec( spec, introspect );
9
+
10
+ const state = Object.create( null );
11
+ // Standard input parameter health flag during update: false means healthy
12
+ state.inputValidationFailed = false;
13
+ // Ensure node is enabled by default
14
+ state.disable = false;
15
+ state.pause = false;
16
+
17
+ // Vector source configuration - following standard pattern
18
+ state.x = spec.from.x;
19
+ state.y = spec.from.y;
20
+
21
+ state.accumulator = new Float64Array( 6 );
22
+ state.accumulator.fill( 0 );
23
+
24
+ // Distance values - pre-allocate all even if not used
25
+ state.distances = Object.create( null );
26
+ state.distances.mad = 0;
27
+ state.distances.rms = 0;
28
+ state.distances.maximum = 0;
29
+ state.distances.cosine = 0;
30
+ state.distances.angular = 0;
31
+
32
+ // Track if we've computed at least once i.e. downstream
33
+ // node has warmed up!
34
+ state.computed = false;
35
+
36
+ // Output configuration
37
+ state.stats = spec.stats;
38
+
39
+ state.mask = 0;
40
+ if ( state.stats.mad || state.stats.maximum ) state.mask |= 1;
41
+ if ( state.stats.rms ) state.mask |= 2;
42
+ if ( state.stats.cosine || state.stats.angular ) state.mask |= 4;
43
+
44
+ // Optimization flags based on requested stats
45
+ state.needsAbs = state.stats.mad || state.stats.maximum;
46
+ state.needsSquare = state.stats.rms;
47
+ state.needsDotProduct = state.stats.cosine || state.stats.angular;
48
+
49
+ state.nodeType = introspect.getNodeType();
50
+
51
+ return state;
52
+ }; // init()
53
+
54
+ export default init;