@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,177 @@
1
+ /**
2
+ * @fileoverview Introspection metadata for categorize node.
3
+ *
4
+ * Defines supported stats (category, index), control methods, capabilities,
5
+ * DSL schema with cross-field validators, and tunable params (thresholds).
6
+ * All getters return defensive copies.
7
+ */
8
+
9
+ import { validators } from '../../core/utils/validate/index.js';
10
+ import { resolveArray } from '../../core/utils/options/resolve-field-keyed.js';
11
+
12
+ /** Single source of truth for what this plugin can do */
13
+ const SUPPORTED_STATS = [
14
+ 'category', // Assigned category name (string)
15
+ 'index' // Category index (number: 0, 1, 2, ...)
16
+ ];
17
+
18
+ /** Human-readable descriptions (for introspection) */
19
+ const STAT_DESCRIPTIONS = {
20
+ category: 'Assigned category name based on threshold comparison',
21
+ index: 'Zero-based index of the assigned category for efficient comparisons'
22
+ };
23
+
24
+ /** Control methods available for triggers */
25
+ const SUPPORTED_CONTROL_METHODS = {
26
+ reset: 'Clears accumulated state and restarts computation',
27
+ enable: 'Enables node processing',
28
+ disable: 'Disables node processing',
29
+ pause: 'Pauses node processing while keeping state visible',
30
+ unpause: 'Resumes node processing after pause'
31
+ };
32
+
33
+ /** The type of this node */
34
+ const NODE_TYPE = 'Categorize';
35
+
36
+ /** Node capabilities for documentation */
37
+ const CAPABILITIES = {
38
+ description: 'Assigns numeric values to discrete categories using threshold boundaries',
39
+ features: [
40
+ 'Deterministic threshold-based categorization',
41
+ 'Outputs both category name and numeric index',
42
+ 'O(n) linear search for typical threshold counts',
43
+ 'Validates threshold ordering at initialization',
44
+ 'Handles out-of-range values gracefully'
45
+ ]
46
+ };
47
+
48
+ /** Spec default values */
49
+ export const DEFAULT_OPTIONS = {
50
+ // No defaults needed for this node
51
+ };
52
+
53
+ /** Parameters that support tunable (dynamic) values */
54
+ export const TUNABLE_PARAMS = [ 'thresholds' ];
55
+
56
+ // Export functions for accessing metadata
57
+ export const getSupportedStats = () => SUPPORTED_STATS.slice();
58
+ export const getStatDescriptions = () => ( { ...STAT_DESCRIPTIONS } );
59
+ export const getSupportedControlMethods = () => ( { ...SUPPORTED_CONTROL_METHODS } );
60
+ export const getNodeType = () => NODE_TYPE;
61
+ export const getCapabilities = () => ( { ...CAPABILITIES, features: CAPABILITIES.features.slice() } );
62
+
63
+ // DSL Metadata for transpilation
64
+ const DSL_METADATA = {
65
+ // Spec schema for validation
66
+ specSchema: {
67
+ nodeType: {
68
+ type: 'string',
69
+ required: true,
70
+ value: NODE_TYPE
71
+ },
72
+ name: {
73
+ type: 'string',
74
+ required: true,
75
+ validator: validators.identifier,
76
+ error: 'Name must be a valid identifier'
77
+ },
78
+ from: {
79
+ type: 'object',
80
+ required: true,
81
+ properties: {
82
+ x: {
83
+ type: 'string',
84
+ required: true,
85
+ validator: validators.noSpaces,
86
+ error: 'Field name cannot contain spaces'
87
+ }
88
+ }
89
+ },
90
+ thresholds: {
91
+ type: 'arrayOrFunctionOrFieldKeyed',
92
+ required: true,
93
+ minItems: 1,
94
+ // Supports tunable for shift/mode-based category boundaries
95
+ itemSchema: {
96
+ type: 'number',
97
+ validator: validators.isFinite,
98
+ error: 'Threshold values must be finite numbers'
99
+ }
100
+ },
101
+ categories: {
102
+ type: 'arrayOrFieldKeyed',
103
+ required: true,
104
+ minItems: 2,
105
+ itemSchema: {
106
+ type: 'string',
107
+ minLength: 1,
108
+ error: 'Category names must be non-empty strings'
109
+ }
110
+ },
111
+ stats: {
112
+ type: 'object',
113
+ required: true,
114
+ minProperties: 1,
115
+ propertyNames: SUPPORTED_STATS,
116
+ propertySchema: {
117
+ type: 'object',
118
+ required: true,
119
+ properties: {
120
+ storeAs: {
121
+ type: 'string',
122
+ required: true,
123
+ validator: validators.identifier,
124
+ error: 'storeAs must be a valid identifier'
125
+ }
126
+ }
127
+ }
128
+ }
129
+ },
130
+
131
+ // Cross-field validators
132
+ crossFieldValidators: [
133
+ {
134
+ fields: [ 'thresholds', 'categories' ],
135
+ // Must have exactly n+1 categories for n thresholds (skip if thresholds is function).
136
+ // Resolve both for the node's field the way the runtime does, so a direct
137
+ // array and a field-keyed map are checked the same way.
138
+ validator: ( spec ) => {
139
+ if ( typeof spec.thresholds === 'function' ) return true;
140
+ const t = resolveArray( spec.thresholds, spec.from?.x );
141
+ const c = resolveArray( spec.categories, spec.from?.x );
142
+ if ( !Array.isArray( t ) || !Array.isArray( c ) ) return false;
143
+ return c.length === ( t.length + 1 );
144
+ },
145
+ error: 'Categories array must have exactly one more element than thresholds array'
146
+ },
147
+ {
148
+ fields: [ 'thresholds' ],
149
+ validator: ( spec ) => {
150
+ // If thresholds is a function, validation deferred to runtime
151
+ if ( typeof spec.thresholds === 'function' ) return true;
152
+ // Resolve for the node's field; the count validator owns the
153
+ // "did not resolve to an array" error, so defer here.
154
+ const t = resolveArray( spec.thresholds, spec.from?.x );
155
+ if ( !Array.isArray( t ) ) return true;
156
+ // Thresholds must be in strictly ascending order
157
+ for ( let i = 1; i < t.length; i += 1 ) {
158
+ if ( t[ i ] <= t[ i - 1 ] ) return false;
159
+ }
160
+ return true;
161
+ },
162
+ error: 'Thresholds must be in strictly ascending order with no duplicates'
163
+ }
164
+ ],
165
+
166
+ // How to build the spec from DSL params
167
+ buildSpec: ( name, x, stats, options ) => ( {
168
+ nodeType: NODE_TYPE,
169
+ name,
170
+ from: { x },
171
+ stats,
172
+ ...options
173
+ } ),
174
+
175
+ };
176
+
177
+ export const getDSLMetadata = () => ( { ...DSL_METADATA } );
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Publish function for categorize node.
3
+ *
4
+ * Copies the assigned category name and/or index to the output message.
5
+ * Propagates NaN via publishNaN when the last input was invalid.
6
+ * Skipped entirely when the node is disabled.
7
+ */
8
+
9
+ import { publishNaN } from '../../core/utils/node/index.js';
10
+
11
+ const publishTo = function ( state, msg ) {
12
+ if ( state.disable ) return;
13
+ // Propagate NaN if unhealthy
14
+ if ( state.inputValidationFailed ) {
15
+ publishNaN( state, msg );
16
+ return;
17
+ }
18
+
19
+ // Publish requested stats
20
+ if ( state.stats.category ) {
21
+ msg[ state.stats.category.storeAs ] = state.category;
22
+ }
23
+
24
+ if ( state.stats.index ) {
25
+ msg[ state.stats.index.storeAs ] = state.categoryIndex;
26
+ }
27
+ }; // publishTo()
28
+
29
+ export default publishTo;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @fileoverview Recompute for categorize node.
3
+ *
4
+ * No-op: categorization is computed fresh from the input value on every
5
+ * update — there is no accumulated state that can drift over time.
6
+ */
7
+
8
+ const recompute = function () {
9
+ // Nothing to recompute - categorization is stateless
10
+ // No accumulations or numerical drift possible
11
+ return true;
12
+ }; // recompute()
13
+
14
+ export default recompute;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @fileoverview Reset categorize node state.
3
+ *
4
+ * Restores categorization to init-time defaults: first category, cleared
5
+ * error flags, and reset tunable error suppression.
6
+ */
7
+
8
+ const reset = function ( state ) {
9
+ state.inputValidationFailed = false;
10
+ state.categoryIndex = 0;
11
+ state.category = state.categories[ 0 ];
12
+ state.tunableErrorLogged = false;
13
+ return true;
14
+ }; // reset()
15
+
16
+ export default reset;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview Update function for categorize node.
3
+ *
4
+ * Extracts the input value, resolves tunable thresholds for the current
5
+ * message, and finds the matching category via linear search. For typical
6
+ * threshold counts (3–5), linear search outperforms binary search.
7
+ */
8
+
9
+ const update = function ( state, msg ) {
10
+ if ( state.disable || state.pause ) return state;
11
+ const xVal = msg[ state.x ];
12
+ // Reset on each update
13
+ state.inputValidationFailed = false;
14
+ // Handle faults gracefully: ensure their isolation
15
+ if ( !Number.isFinite( xVal ) ) {
16
+ // Signals publishing NaN for all demanded `stats` in publishTo.
17
+ state.inputValidationFailed = true;
18
+ return state;
19
+ }
20
+
21
+ // Resolve thresholds tunable for this message
22
+ try {
23
+ state.resolvedThresholds = state.thresholdsFn( msg );
24
+ if ( state.tunableErrorLogged ) state.tunableErrorLogged = false;
25
+ } catch ( error ) {
26
+ if ( !state.tunableErrorLogged ) {
27
+ state.tunableErrorLogged = true;
28
+ console.error( `WinkComposer/${state.nodeType}: tunable threw: ${error.message}` );
29
+ }
30
+ }
31
+
32
+ if ( !state.resolvedThresholds ) {
33
+ state.inputValidationFailed = true;
34
+ return state;
35
+ }
36
+
37
+ // Find category using linear search
38
+ // For typical threshold counts (3-5), this is faster than binary search
39
+ // Convention: value >= threshold belongs to upper category
40
+ let categoryIndex = 0;
41
+
42
+ for ( categoryIndex = 0; categoryIndex < state.resolvedThresholds.length; categoryIndex += 1 ) {
43
+ if ( xVal < state.resolvedThresholds[ categoryIndex ] ) break;
44
+ }
45
+
46
+ // Update state
47
+ state.categoryIndex = categoryIndex;
48
+ state.category = state.categories[ categoryIndex ];
49
+
50
+ return state;
51
+ }; // update()
52
+
53
+ export default update;
@@ -0,0 +1,9 @@
1
+ // nodes/controller/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
+ // Re-export everything from introspection.js
9
+ export * from './introspect.js';
@@ -0,0 +1,55 @@
1
+ // nodes/controller/init.js
2
+
3
+ import { validateWithSchema } from '../../core/utils/validate/index.js';
4
+ import { getDSLMetadata, getNodeType } from './introspect.js';
5
+
6
+ const init = function ( spec ) {
7
+ // Get validation schema from introspect
8
+ const metadata = getDSLMetadata();
9
+ const schema = {
10
+ ...metadata.specSchema,
11
+ _crossFieldValidators: metadata.crossFieldValidators
12
+ };
13
+
14
+ // Validate spec
15
+ const validation = validateWithSchema( schema, spec, 'spec' );
16
+ validation.throwIfInvalid( getNodeType() );
17
+
18
+ // Create state after validation passes
19
+ const state = Object.create( null );
20
+
21
+ // Copy logic array with structure as the placeholder resolved triggers,
22
+ // computed during the partition time.
23
+ state.logic = [];
24
+ for ( let i = 0; i < spec.logic.length; i += 1 ) {
25
+ const condition = Object.create( null );
26
+ condition.when = spec.logic[ i ].when;
27
+ // Keep spec for partition manager
28
+ condition.triggers = spec.logic[ i ].triggers;
29
+ // PLACEHOLDER: will be resolved by partition manager
30
+ condition.resolvedTriggers = null;
31
+ state.logic.push( condition );
32
+ }
33
+
34
+ // Controller metadata
35
+ state.name = spec.name;
36
+ state.nodeType = getNodeType();
37
+
38
+ // Observability fields
39
+ state.lastMatchedCondition = -1;
40
+ state.matchCount = 0;
41
+ state.errorCount = 0;
42
+ state.lastError = null;
43
+
44
+ // Log suppression: one log per error episode; reset on recovery.
45
+ state.predicateErrorLogged = false;
46
+
47
+ // Control phase tracking (executeTriggers re-entrancy guard)
48
+ state.inControlPhase = false;
49
+ // Points to the matched condition's triggers during execution
50
+ state.resolvedTriggers = null;
51
+
52
+ return state;
53
+ }; // init()
54
+
55
+ export default init;
@@ -0,0 +1,91 @@
1
+ // nodes/controller/introspect.js
2
+
3
+ import { validators, composerValidators } from '../../core/utils/validate/index.js';
4
+
5
+ /** Single source of truth for what this node can do */
6
+ const SUPPORTED_STATS = []; // Controller doesn't publish stats
7
+
8
+ /** Human-readable descriptions (for introspection) */
9
+ const STAT_DESCRIPTIONS = {}; // No stats, no descriptions
10
+
11
+ /** Control methods available for triggers (none - pure orchestrator) */
12
+ const SUPPORTED_CONTROL_METHODS = {};
13
+
14
+ /** Default options (none for this node) */
15
+ const DEFAULT_OPTIONS = {};
16
+
17
+ /** The type of this node */
18
+ const NODE_TYPE = 'Controller';
19
+
20
+ /** Node capabilities for documentation */
21
+ const CAPABILITIES = {
22
+ description: 'Pure orchestration node that monitors messages and coordinates other nodes without modifying data',
23
+ features: [
24
+ 'Multi-condition state machine support',
25
+ 'First-match-wins execution model',
26
+ 'Re-entrancy protected trigger execution',
27
+ 'No data transformation - pure control flow'
28
+ ]
29
+ };
30
+
31
+ // Export functions for accessing metadata
32
+ export const getSupportedStats = () => SUPPORTED_STATS.slice();
33
+ export const getStatDescriptions = () => ( { ...STAT_DESCRIPTIONS } );
34
+ export const getSupportedControlMethods = () => ( { ...SUPPORTED_CONTROL_METHODS } );
35
+ export const getNodeType = () => NODE_TYPE;
36
+ export const getCapabilities = () => ( { ...CAPABILITIES, features: CAPABILITIES.features.slice() } );
37
+
38
+ // DSL Metadata for transpilation and validation
39
+ const DSL_METADATA = {
40
+ specSchema: {
41
+ nodeType: {
42
+ type: 'string',
43
+ required: true,
44
+ value: NODE_TYPE
45
+ },
46
+ name: {
47
+ type: 'string',
48
+ required: true,
49
+ validator: validators.identifier,
50
+ error: 'Name must be a valid JavaScript identifier'
51
+ },
52
+ logic: {
53
+ type: 'array',
54
+ required: true,
55
+ minItems: 1,
56
+ itemSchema: {
57
+ type: 'object',
58
+ properties: {
59
+ when: {
60
+ type: 'function',
61
+ required: true,
62
+ arity: 1,
63
+ error: 'when must be a predicate function with one parameter'
64
+ },
65
+ triggers: {
66
+ type: 'array',
67
+ required: true,
68
+ minItems: 1,
69
+ itemSchema: {
70
+ type: 'object',
71
+ validator: composerValidators.trigger,
72
+ error: 'Invalid trigger specification'
73
+ }
74
+ }
75
+ }
76
+ }
77
+ }
78
+ },
79
+
80
+ crossFieldValidators: [], // No cross-field validation needed
81
+
82
+ buildSpec: ( name, logic ) => ( {
83
+ nodeType: NODE_TYPE,
84
+ name,
85
+ logic
86
+ } ),
87
+
88
+ };
89
+
90
+ export const getDSLMetadata = () => ( { ...DSL_METADATA } );
91
+ export { DEFAULT_OPTIONS };
@@ -0,0 +1,8 @@
1
+ // nodes/controller/publish-to.js
2
+
3
+ const publishTo = function ( _state, _msg ) {
4
+ // Controller is pure orchestration - it doesn't publish any data
5
+ // Messages pass through unchanged
6
+ }; // publishTo()
7
+
8
+ export default publishTo;
@@ -0,0 +1,9 @@
1
+ // nodes/controller/recompute.js
2
+
3
+ const recompute = function ( _state ) {
4
+ // Controller has no numerical state to recompute
5
+ // All state is discrete (counters, flags)
6
+ return true;
7
+ }; // recompute()
8
+
9
+ export default recompute;
@@ -0,0 +1,17 @@
1
+ // nodes/controller/reset.js
2
+
3
+ const reset = function ( state ) {
4
+ // Reset observability counters
5
+ state.lastMatchedCondition = -1;
6
+ state.matchCount = 0;
7
+ state.errorCount = 0;
8
+ state.lastError = null;
9
+ // Clear error suppression so next error episode is logged
10
+ state.predicateErrorLogged = false;
11
+
12
+ // Note: We don't reset logic or resolvedTriggers
13
+ // as they are structural, not runtime state
14
+ return true;
15
+ }; // reset()
16
+
17
+ export default reset;
@@ -0,0 +1,63 @@
1
+ // nodes/controller/update.js
2
+
3
+ import { executeTriggers } from '../../core/utils/node/index.js';
4
+
5
+ const update = function ( state, msg ) {
6
+ // Track whether any predicate threw during this pass
7
+ let anyError = false;
8
+
9
+ // Iterate through conditions in order
10
+ for ( let i = 0; i < state.logic.length; i += 1 ) {
11
+ const condition = state.logic[ i ];
12
+
13
+ // Evaluate predicate with error handling
14
+ let predicateResult = false;
15
+ try {
16
+ predicateResult = condition.when( msg );
17
+ } catch ( error ) {
18
+ anyError = true;
19
+ // Track predicate errors
20
+ state.errorCount += 1;
21
+ state.lastError = error.message;
22
+ // Log first error per episode; suppress subsequent until recovery
23
+ if ( !state.predicateErrorLogged ) {
24
+ state.predicateErrorLogged = true;
25
+ console.error( `WinkComposer/controller: predicate threw exception: ${error.message}` );
26
+ }
27
+ // Skip to next condition
28
+ continue; // eslint-disable-line no-continue
29
+ }
30
+
31
+ // Check if condition matches
32
+ if ( predicateResult === true ) {
33
+ // Recovery: clear flag only when entire pass is exception-free
34
+ if ( !anyError && state.predicateErrorLogged ) state.predicateErrorLogged = false;
35
+
36
+ // Update observability
37
+ state.lastMatchedCondition = i;
38
+ state.matchCount += 1;
39
+
40
+ // Check for resolved triggers
41
+ if ( !condition.resolvedTriggers || condition.resolvedTriggers.length === 0 ) {
42
+ return state; // No triggers to execute
43
+ }
44
+
45
+ // Point to this condition's triggers; it is an executeTriggers' requirement.
46
+ state.resolvedTriggers = condition.resolvedTriggers;
47
+
48
+ // Execute triggers with re-entrancy protection
49
+ executeTriggers( state );
50
+
51
+ // First match wins - stop processing
52
+ return state;
53
+ }
54
+ }
55
+
56
+ // Recovery: clear flag only when entire pass is exception-free
57
+ if ( !anyError && state.predicateErrorLogged ) state.predicateErrorLogged = false;
58
+
59
+ // No conditions matched
60
+ return state;
61
+ }; // update()
62
+
63
+ export default update;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @fileoverview Entry point for diff node.
3
+ *
4
+ * Re-exports all lifecycle functions (init, update, publishTo, reset, recompute),
5
+ * shared control signals (disable, enable, pause, unpause), and introspection metadata.
6
+ */
7
+
8
+ export { default as init } from './init.js';
9
+ export { default as update } from './update.js';
10
+ export { default as reset } from './reset.js';
11
+ export { default as recompute } from './recompute.js';
12
+ export { default as publishTo } from './publish-to.js';
13
+ // Direct imports for common control functions
14
+ export { default as disable } from '../../core/utils/node/disable.js';
15
+ export { default as enable } from '../../core/utils/node/enable.js';
16
+ export { default as pause } from '../../core/utils/node/pause.js';
17
+ export { default as unpause } from '../../core/utils/node/unpause.js';
18
+ // Re-export everything from introspection.js
19
+ export * from './introspect.js';
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @fileoverview Initialization for diff node.
3
+ *
4
+ * Validates the spec, extracts field names and the absolute option,
5
+ * and returns the fully initialized state object.
6
+ */
7
+
8
+ import { validateSpec } from '../../core/utils/node/index.js';
9
+ import * as introspect from './introspect.js';
10
+
11
+ const init = function ( spec ) {
12
+ validateSpec( spec, introspect );
13
+
14
+ const state = Object.create( null );
15
+ // Standard input parameter health flag during update: false means healthy
16
+ state.inputValidationFailed = false;
17
+ // Ensure node is enabled by default
18
+ state.disable = false;
19
+ state.pause = false;
20
+
21
+ // Extract field name & option.
22
+ state.x = spec.from.x;
23
+ state.y = spec.from.y;
24
+ state.absolute = spec.absolute ?? introspect.DEFAULT_OPTIONS.absolute;
25
+
26
+ // Config copy.
27
+ state.stats = spec.stats;
28
+
29
+ // State variables.
30
+ state.diff = 0;
31
+
32
+ state.nodeType = introspect.getNodeType();
33
+
34
+ return state;
35
+ }; // init()
36
+
37
+ export default init;