@winkjs/composer 0.0.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +106 -80
- package/package.json +56 -28
- package/src/composer.js +75 -0
- package/src/core/batch/aoo-encoder.js +148 -0
- package/src/core/batch/index.js +12 -0
- package/src/core/batch/sliding-window.js +91 -0
- package/src/core/codec/index.js +137 -0
- package/src/core/emitter-manager/mqtt/constants.js +102 -0
- package/src/core/emitter-manager/mqtt/emitter.js +780 -0
- package/src/core/emitter-manager/mqtt/index.js +190 -0
- package/src/core/emitter-manager/mqtt/mqtt-store.js +538 -0
- package/src/core/emitter-manager/terminal/assert-columns.js +98 -0
- package/src/core/emitter-manager/terminal/formatters.js +160 -0
- package/src/core/emitter-manager/terminal/index.js +341 -0
- package/src/core/env-vars.js +245 -0
- package/src/core/mqtt-protocol.js +47 -0
- package/src/core/partition-manager/index.js +7 -0
- package/src/core/partition-manager/init.js +44 -0
- package/src/core/partition-manager/introspect.js +15 -0
- package/src/core/partition-manager/publish-to.js +6 -0
- package/src/core/partition-manager/recompute.js +5 -0
- package/src/core/partition-manager/reset.js +5 -0
- package/src/core/partition-manager/update.js +264 -0
- package/src/core/partition-manager/validate-flow.js +157 -0
- package/src/core/semantics/digest.js +128 -0
- package/src/core/semantics/index.js +83 -0
- package/src/core/semantics/loader.js +571 -0
- package/src/core/semantics/schemas/asset-class-schema.js +218 -0
- package/src/core/semantics/schemas/column-schema.js +651 -0
- package/src/core/semantics/schemas/enum-schema.js +153 -0
- package/src/core/semantics/schemas/index.js +51 -0
- package/src/core/semantics/warnings.js +141 -0
- package/src/core/shutdown-manager/index.js +289 -0
- package/src/core/source-manager/csv/index.js +171 -0
- package/src/core/source-manager/csv/start.js +456 -0
- package/src/core/source-manager/mqtt/client.js +406 -0
- package/src/core/source-manager/mqtt/constants.js +147 -0
- package/src/core/source-manager/mqtt/dedup.js +244 -0
- package/src/core/source-manager/mqtt/index.js +260 -0
- package/src/core/source-manager/mqtt/status.js +546 -0
- package/src/core/source-manager/test-harness/comparator.js +226 -0
- package/src/core/source-manager/test-harness/field-generator.js +85 -0
- package/src/core/source-manager/test-harness/fuzz.js +87 -0
- package/src/core/source-manager/test-harness/index.js +115 -0
- package/src/core/source-manager/test-harness/prng.js +57 -0
- package/src/core/source-manager/test-harness/start.js +232 -0
- package/src/core/source-manager/test-harness/validate.js +213 -0
- package/src/core/storage-manager/questdb/assert-columns.js +120 -0
- package/src/core/storage-manager/questdb/ensure-tables.js +187 -0
- package/src/core/storage-manager/questdb/index.js +1251 -0
- package/src/core/storage-manager/questdb/persist-plan.js +488 -0
- package/src/core/storage-manager/questdb/writers.js +142 -0
- package/src/core/test-utils/sealed-record.js +80 -0
- package/src/core/test-utils/soak-signature.js +149 -0
- package/src/core/test-utils/tcp-proxy.js +106 -0
- package/src/core/tunable/helpers.js +254 -0
- package/src/core/tunable/index.js +87 -0
- package/src/core/utils/console-formatter/index.js +207 -0
- package/src/core/utils/create-smart-store-as/index.js +98 -0
- package/src/core/utils/create-smart-store-as/sanitize-field.js +46 -0
- package/src/core/utils/create-smart-store-as/smart-truncate.js +93 -0
- package/src/core/utils/flow/index.js +5 -0
- package/src/core/utils/flow/make-collision-checker.js +23 -0
- package/src/core/utils/flow/to-kebab.js +20 -0
- package/src/core/utils/half-life/index.js +111 -0
- package/src/core/utils/node/disable.js +11 -0
- package/src/core/utils/node/enable.js +11 -0
- package/src/core/utils/node/execute-triggers.js +40 -0
- package/src/core/utils/node/index.js +10 -0
- package/src/core/utils/node/pause.js +11 -0
- package/src/core/utils/node/populate-predicate-inputs.js +14 -0
- package/src/core/utils/node/publish-nan.js +19 -0
- package/src/core/utils/node/reset-predicate-inputs.js +11 -0
- package/src/core/utils/node/unpause.js +11 -0
- package/src/core/utils/node/validate-spec.js +22 -0
- package/src/core/utils/options/resolve-field-keyed.js +115 -0
- package/src/core/utils/quantize/index.js +75 -0
- package/src/core/utils/stats/formulas.js +67 -0
- package/src/core/utils/stats/index.js +3 -0
- package/src/core/utils/validate/composer-validators.js +141 -0
- package/src/core/utils/validate/helpers.js +206 -0
- package/src/core/utils/validate/index.js +12 -0
- package/src/core/utils/validate/type-validators.js +538 -0
- package/src/core/utils/validate/validate.js +107 -0
- package/src/core/utils/validate/validators.js +177 -0
- package/src/core/wiring/assert-handle.js +57 -0
- package/src/core/wiring/assert-module.js +63 -0
- package/src/core/wiring/index.js +5 -0
- package/src/core/wiring/node-type-to-module.js +17 -0
- package/src/core/wiring/wire-emitters.js +256 -0
- package/src/core/wiring/wire-linear-graph.js +25 -0
- package/src/core/wiring/wire-node.js +157 -0
- package/src/core/wiring/wire-semantics.js +173 -0
- package/src/core/wiring/wire-storages.js +344 -0
- package/src/flow/check-output-collisions.js +93 -0
- package/src/flow/consts.js +9 -0
- package/src/flow/deep-clone-spec.js +64 -0
- package/src/flow/driver.js +171 -0
- package/src/flow/expand-single-input-array.js +76 -0
- package/src/flow/expand-template-spec.js +93 -0
- package/src/flow/flow-api-schemas.js +300 -0
- package/src/flow/flow.js +658 -0
- package/src/flow/for-each.js +225 -0
- package/src/flow/get-signature-pattern.js +31 -0
- package/src/flow/get-target-array.js +46 -0
- package/src/flow/inspect.js +67 -0
- package/src/flow/load-node-module.js +81 -0
- package/src/flow/make-node-method.js +112 -0
- package/src/flow/resolve-pick-by-field.js +77 -0
- package/src/flow/resolve-tunables.js +76 -0
- package/src/flow/run.js +392 -0
- package/src/flow/serialize.js +161 -0
- package/src/flow/signatures-schema.js +222 -0
- package/src/flow/spec-builder.js +65 -0
- package/src/flow/validate-triggers.js +250 -0
- package/src/flow/validate.js +261 -0
- package/src/nodes/accumulate/index.js +21 -0
- package/src/nodes/accumulate/init.js +48 -0
- package/src/nodes/accumulate/introspect.js +123 -0
- package/src/nodes/accumulate/publish-to.js +34 -0
- package/src/nodes/accumulate/recompute.js +27 -0
- package/src/nodes/accumulate/reset.js +25 -0
- package/src/nodes/accumulate/update.js +42 -0
- package/src/nodes/appraise/calibrate.js +64 -0
- package/src/nodes/appraise/decision.js +66 -0
- package/src/nodes/appraise/deviation.js +140 -0
- package/src/nodes/appraise/index.js +23 -0
- package/src/nodes/appraise/init.js +165 -0
- package/src/nodes/appraise/integrate.js +45 -0
- package/src/nodes/appraise/introspect.js +352 -0
- package/src/nodes/appraise/publish-to.js +93 -0
- package/src/nodes/appraise/receptor.js +69 -0
- package/src/nodes/appraise/recompute.js +79 -0
- package/src/nodes/appraise/reset.js +53 -0
- package/src/nodes/appraise/update.js +130 -0
- package/src/nodes/archive/csv/index.js +6 -0
- package/src/nodes/archive/csv/init.js +36 -0
- package/src/nodes/archive/csv/load.js +70 -0
- package/src/nodes/archive/csv/reset.js +14 -0
- package/src/nodes/archive/csv/simple-parser.js +216 -0
- package/src/nodes/archive/csv/test.js +173 -0
- package/src/nodes/archive/csv/update.js +63 -0
- package/src/nodes/butterworth-filter/index.js +18 -0
- package/src/nodes/butterworth-filter/init.js +184 -0
- package/src/nodes/butterworth-filter/introspect.js +228 -0
- package/src/nodes/butterworth-filter/publish-to.js +21 -0
- package/src/nodes/butterworth-filter/recompute.js +13 -0
- package/src/nodes/butterworth-filter/reset.js +30 -0
- package/src/nodes/butterworth-filter/update.js +38 -0
- package/src/nodes/categorize/index.js +19 -0
- package/src/nodes/categorize/init.js +58 -0
- package/src/nodes/categorize/introspect.js +177 -0
- package/src/nodes/categorize/publish-to.js +29 -0
- package/src/nodes/categorize/recompute.js +14 -0
- package/src/nodes/categorize/reset.js +16 -0
- package/src/nodes/categorize/update.js +53 -0
- package/src/nodes/controller/index.js +9 -0
- package/src/nodes/controller/init.js +55 -0
- package/src/nodes/controller/introspect.js +91 -0
- package/src/nodes/controller/publish-to.js +8 -0
- package/src/nodes/controller/recompute.js +9 -0
- package/src/nodes/controller/reset.js +17 -0
- package/src/nodes/controller/update.js +63 -0
- package/src/nodes/diff/index.js +19 -0
- package/src/nodes/diff/init.js +37 -0
- package/src/nodes/diff/introspect.js +132 -0
- package/src/nodes/diff/publish-to.js +21 -0
- package/src/nodes/diff/recompute.js +12 -0
- package/src/nodes/diff/reset.js +12 -0
- package/src/nodes/diff/update.js +37 -0
- package/src/nodes/digest-moments/formulas.js +12 -0
- package/src/nodes/digest-moments/index.js +14 -0
- package/src/nodes/digest-moments/init.js +67 -0
- package/src/nodes/digest-moments/introspect.js +154 -0
- package/src/nodes/digest-moments/publish-to.js +34 -0
- package/src/nodes/digest-moments/recompute.js +14 -0
- package/src/nodes/digest-moments/reset.js +14 -0
- package/src/nodes/digest-moments/update.js +120 -0
- package/src/nodes/dwell-time-tracker/index.js +14 -0
- package/src/nodes/dwell-time-tracker/init.js +59 -0
- package/src/nodes/dwell-time-tracker/introspect.js +137 -0
- package/src/nodes/dwell-time-tracker/publish-to.js +22 -0
- package/src/nodes/dwell-time-tracker/recompute.js +8 -0
- package/src/nodes/dwell-time-tracker/reset.js +23 -0
- package/src/nodes/dwell-time-tracker/update.js +103 -0
- package/src/nodes/emit-if/helpers.js +94 -0
- package/src/nodes/emit-if/index.js +16 -0
- package/src/nodes/emit-if/init.js +67 -0
- package/src/nodes/emit-if/introspect.js +102 -0
- package/src/nodes/emit-if/publish-to.js +13 -0
- package/src/nodes/emit-if/recompute.js +12 -0
- package/src/nodes/emit-if/reset.js +27 -0
- package/src/nodes/emit-if/update.js +93 -0
- package/src/nodes/es-correlation/index.js +19 -0
- package/src/nodes/es-correlation/init.js +73 -0
- package/src/nodes/es-correlation/introspect.js +176 -0
- package/src/nodes/es-correlation/publish-to.js +32 -0
- package/src/nodes/es-correlation/recompute.js +56 -0
- package/src/nodes/es-correlation/reset.js +27 -0
- package/src/nodes/es-correlation/update.js +110 -0
- package/src/nodes/es-mean/index.js +20 -0
- package/src/nodes/es-mean/init.js +58 -0
- package/src/nodes/es-mean/introspect.js +129 -0
- package/src/nodes/es-mean/publish-to.js +19 -0
- package/src/nodes/es-mean/recompute.js +16 -0
- package/src/nodes/es-mean/reset.js +24 -0
- package/src/nodes/es-mean/update.js +69 -0
- package/src/nodes/es-pairwise-correlation/index.js +19 -0
- package/src/nodes/es-pairwise-correlation/init.js +98 -0
- package/src/nodes/es-pairwise-correlation/introspect.js +187 -0
- package/src/nodes/es-pairwise-correlation/publish-to.js +31 -0
- package/src/nodes/es-pairwise-correlation/recompute.js +69 -0
- package/src/nodes/es-pairwise-correlation/reset.js +29 -0
- package/src/nodes/es-pairwise-correlation/update.js +89 -0
- package/src/nodes/es-stats/index.js +21 -0
- package/src/nodes/es-stats/init.js +105 -0
- package/src/nodes/es-stats/introspect.js +157 -0
- package/src/nodes/es-stats/publish-to.js +42 -0
- package/src/nodes/es-stats/recompute.js +74 -0
- package/src/nodes/es-stats/reset.js +49 -0
- package/src/nodes/es-stats/update-envelope.js +44 -0
- package/src/nodes/es-stats/update-welford.js +64 -0
- package/src/nodes/es-stats/update.js +59 -0
- package/src/nodes/index.js +83 -0
- package/src/nodes/invert-flag/index.js +20 -0
- package/src/nodes/invert-flag/init.js +36 -0
- package/src/nodes/invert-flag/introspect.js +115 -0
- package/src/nodes/invert-flag/publish-to.js +23 -0
- package/src/nodes/invert-flag/recompute.js +12 -0
- package/src/nodes/invert-flag/reset.js +12 -0
- package/src/nodes/invert-flag/update.js +32 -0
- package/src/nodes/kalman1d/index.js +20 -0
- package/src/nodes/kalman1d/init.js +103 -0
- package/src/nodes/kalman1d/introspect.js +250 -0
- package/src/nodes/kalman1d/publish-to.js +34 -0
- package/src/nodes/kalman1d/recompute.js +23 -0
- package/src/nodes/kalman1d/reset.js +29 -0
- package/src/nodes/kalman1d/update.js +144 -0
- package/src/nodes/kernel/index.js +18 -0
- package/src/nodes/kernel/init.js +66 -0
- package/src/nodes/kernel/introspect.js +163 -0
- package/src/nodes/kernel/presets.js +74 -0
- package/src/nodes/kernel/publish-to.js +25 -0
- package/src/nodes/kernel/recompute.js +14 -0
- package/src/nodes/kernel/reset.js +20 -0
- package/src/nodes/kernel/update.js +69 -0
- package/src/nodes/lag/index.js +21 -0
- package/src/nodes/lag/init.js +87 -0
- package/src/nodes/lag/introspect.js +202 -0
- package/src/nodes/lag/publish-to.js +64 -0
- package/src/nodes/lag/recompute.js +33 -0
- package/src/nodes/lag/reset.js +49 -0
- package/src/nodes/lag/update.js +133 -0
- package/src/nodes/median3/index.js +19 -0
- package/src/nodes/median3/init.js +40 -0
- package/src/nodes/median3/introspect.js +116 -0
- package/src/nodes/median3/publish-to.js +21 -0
- package/src/nodes/median3/recompute.js +12 -0
- package/src/nodes/median3/reset.js +15 -0
- package/src/nodes/median3/update.js +58 -0
- package/src/nodes/moments-digest/copy-from.js +12 -0
- package/src/nodes/moments-digest/flush.js +17 -0
- package/src/nodes/moments-digest/index.js +132 -0
- package/src/nodes/moments-digest/init.js +84 -0
- package/src/nodes/moments-digest/introspect.js +122 -0
- package/src/nodes/moments-digest/prelude.js +28 -0
- package/src/nodes/moments-digest/publish-to.js +31 -0
- package/src/nodes/moments-digest/recompute.js +9 -0
- package/src/nodes/moments-digest/reset.js +20 -0
- package/src/nodes/moments-digest/update.js +182 -0
- package/src/nodes/node-names.js +67 -0
- package/src/nodes/page-hinkley/index.js +20 -0
- package/src/nodes/page-hinkley/init.js +66 -0
- package/src/nodes/page-hinkley/introspect.js +193 -0
- package/src/nodes/page-hinkley/publish-to.js +28 -0
- package/src/nodes/page-hinkley/recompute.js +14 -0
- package/src/nodes/page-hinkley/reset.js +23 -0
- package/src/nodes/page-hinkley/update.js +105 -0
- package/src/nodes/pass-if/index.js +21 -0
- package/src/nodes/pass-if/init.js +37 -0
- package/src/nodes/pass-if/introspect.js +93 -0
- package/src/nodes/pass-if/publish-to.js +15 -0
- package/src/nodes/pass-if/recompute.js +15 -0
- package/src/nodes/pass-if/reset.js +18 -0
- package/src/nodes/pass-if/update.js +37 -0
- package/src/nodes/persist-if/helpers.js +111 -0
- package/src/nodes/persist-if/index.js +9 -0
- package/src/nodes/persist-if/init.js +98 -0
- package/src/nodes/persist-if/introspect.js +106 -0
- package/src/nodes/persist-if/publish-to.js +21 -0
- package/src/nodes/persist-if/recompute.js +20 -0
- package/src/nodes/persist-if/reset.js +35 -0
- package/src/nodes/persist-if/update.js +112 -0
- package/src/nodes/persistence-check/index.js +14 -0
- package/src/nodes/persistence-check/init.js +38 -0
- package/src/nodes/persistence-check/introspect.js +144 -0
- package/src/nodes/persistence-check/publish-to.js +11 -0
- package/src/nodes/persistence-check/recompute.js +7 -0
- package/src/nodes/persistence-check/reset.js +12 -0
- package/src/nodes/persistence-check/update.js +57 -0
- package/src/nodes/process-index/index.js +15 -0
- package/src/nodes/process-index/init.js +48 -0
- package/src/nodes/process-index/introspect.js +182 -0
- package/src/nodes/process-index/publish-to.js +29 -0
- package/src/nodes/process-index/recompute.js +8 -0
- package/src/nodes/process-index/reset.js +8 -0
- package/src/nodes/process-index/update.js +75 -0
- package/src/nodes/ratio/index.js +14 -0
- package/src/nodes/ratio/init.js +37 -0
- package/src/nodes/ratio/introspect.js +155 -0
- package/src/nodes/ratio/publish-to.js +15 -0
- package/src/nodes/ratio/recompute.js +7 -0
- package/src/nodes/ratio/reset.js +7 -0
- package/src/nodes/ratio/update.js +47 -0
- package/src/nodes/sanitize/index.js +82 -0
- package/src/nodes/sanitize/init.js +82 -0
- package/src/nodes/sanitize/introspect.js +194 -0
- package/src/nodes/sanitize/publish-to.js +15 -0
- package/src/nodes/sanitize/recompute.js +8 -0
- package/src/nodes/sanitize/reset.js +14 -0
- package/src/nodes/sanitize/update.js +102 -0
- package/src/nodes/spike-guard/index.js +14 -0
- package/src/nodes/spike-guard/init.js +47 -0
- package/src/nodes/spike-guard/introspect.js +130 -0
- package/src/nodes/spike-guard/publish-to.js +35 -0
- package/src/nodes/spike-guard/recompute.js +14 -0
- package/src/nodes/spike-guard/reset.js +19 -0
- package/src/nodes/spike-guard/update.js +89 -0
- package/src/nodes/sse-emitter/index.js +7 -0
- package/src/nodes/sse-emitter/init.js +105 -0
- package/src/nodes/sse-emitter/introspect.js +134 -0
- package/src/nodes/sse-emitter/publish-to.js +6 -0
- package/src/nodes/sse-emitter/recompute.js +16 -0
- package/src/nodes/sse-emitter/reset.js +19 -0
- package/src/nodes/sse-emitter/update.js +69 -0
- package/src/nodes/sse-emitter/utils/broadcast-heartbeat.js +36 -0
- package/src/nodes/sse-emitter/utils/build-message.js +31 -0
- package/src/nodes/sse-emitter/utils/connection-manager.js +45 -0
- package/src/nodes/sse-emitter/utils/endpoint-initializer.js +20 -0
- package/src/nodes/sse-emitter/utils/health-monitor.js +38 -0
- package/src/nodes/sse-emitter/utils/qos-handler.js +41 -0
- package/src/nodes/state-change-detector/helpers.js +35 -0
- package/src/nodes/state-change-detector/index.js +12 -0
- package/src/nodes/state-change-detector/init.js +56 -0
- package/src/nodes/state-change-detector/introspect.js +146 -0
- package/src/nodes/state-change-detector/publish-to.js +20 -0
- package/src/nodes/state-change-detector/recompute.js +6 -0
- package/src/nodes/state-change-detector/reset.js +20 -0
- package/src/nodes/state-change-detector/update.js +97 -0
- package/src/nodes/sw-stats/index.js +14 -0
- package/src/nodes/sw-stats/init.js +51 -0
- package/src/nodes/sw-stats/introspect.js +131 -0
- package/src/nodes/sw-stats/publish-to.js +45 -0
- package/src/nodes/sw-stats/recompute.js +33 -0
- package/src/nodes/sw-stats/reset.js +15 -0
- package/src/nodes/sw-stats/update.js +39 -0
- package/src/nodes/swing-watch/index.js +17 -0
- package/src/nodes/swing-watch/init.js +144 -0
- package/src/nodes/swing-watch/introspect.js +188 -0
- package/src/nodes/swing-watch/publish-to.js +53 -0
- package/src/nodes/swing-watch/recompute.js +22 -0
- package/src/nodes/swing-watch/reset.js +55 -0
- package/src/nodes/swing-watch/update.js +767 -0
- package/src/nodes/tally/index.js +15 -0
- package/src/nodes/tally/init.js +32 -0
- package/src/nodes/tally/introspect.js +116 -0
- package/src/nodes/tally/publish-to.js +28 -0
- package/src/nodes/tally/recompute.js +10 -0
- package/src/nodes/tally/reset.js +10 -0
- package/src/nodes/tally/update.js +44 -0
- package/src/nodes/threshold/index.js +14 -0
- package/src/nodes/threshold/init.js +121 -0
- package/src/nodes/threshold/introspect.js +192 -0
- package/src/nodes/threshold/publish-to.js +11 -0
- package/src/nodes/threshold/recompute.js +8 -0
- package/src/nodes/threshold/reset.js +14 -0
- package/src/nodes/threshold/update.js +54 -0
- package/src/nodes/transform/helpers.js +39 -0
- package/src/nodes/transform/index.js +15 -0
- package/src/nodes/transform/init.js +35 -0
- package/src/nodes/transform/introspect.js +118 -0
- package/src/nodes/transform/publish-to.js +23 -0
- package/src/nodes/transform/recompute.js +12 -0
- package/src/nodes/transform/reset.js +11 -0
- package/src/nodes/transform/update.js +32 -0
- package/src/nodes/trend/compute-confidence.js +112 -0
- package/src/nodes/trend/index.js +14 -0
- package/src/nodes/trend/init.js +81 -0
- package/src/nodes/trend/introspect.js +151 -0
- package/src/nodes/trend/publish-to.js +22 -0
- package/src/nodes/trend/recompute.js +15 -0
- package/src/nodes/trend/reset.js +26 -0
- package/src/nodes/trend/update.js +93 -0
- package/src/nodes/tw-stats/copy-from.js +16 -0
- package/src/nodes/tw-stats/flush.js +12 -0
- package/src/nodes/tw-stats/index.js +41 -0
- package/src/nodes/tw-stats/init.js +92 -0
- package/src/nodes/tw-stats/introspect.js +171 -0
- package/src/nodes/tw-stats/publish-to.js +108 -0
- package/src/nodes/tw-stats/recompute.js +9 -0
- package/src/nodes/tw-stats/reset.js +16 -0
- package/src/nodes/tw-stats/update.js +113 -0
- package/src/nodes/unbalance/index.js +15 -0
- package/src/nodes/unbalance/init.js +59 -0
- package/src/nodes/unbalance/introspect.js +167 -0
- package/src/nodes/unbalance/publish-to.js +52 -0
- package/src/nodes/unbalance/recompute.js +11 -0
- package/src/nodes/unbalance/reset.js +10 -0
- package/src/nodes/unbalance/update.js +83 -0
- package/src/nodes/vector-distance/index.js +14 -0
- package/src/nodes/vector-distance/init.js +54 -0
- package/src/nodes/vector-distance/introspect.js +149 -0
- package/src/nodes/vector-distance/publish-to.js +35 -0
- package/src/nodes/vector-distance/recompute.js +11 -0
- package/src/nodes/vector-distance/reset.js +20 -0
- package/src/nodes/vector-distance/update.js +139 -0
- package/src/nodes/winnow/index.js +12 -0
- package/src/nodes/winnow/init.js +82 -0
- package/src/nodes/winnow/introspect.js +253 -0
- package/src/nodes/winnow/publish-to.js +51 -0
- package/src/nodes/winnow/recompute.js +14 -0
- package/src/nodes/winnow/reset.js +34 -0
- package/src/nodes/winnow/update.js +203 -0
- package/src/tools/training/features.js +227 -0
- package/src/tools/training/index.js +21 -0
- package/src/tools/training/logistic.js +238 -0
- package/src/tools/training/metrics.js +126 -0
- package/src/tools/training/scale.js +239 -0
- package/src/tools/training/validate.js +103 -0
- package/src/windowing/count-sliding/create.js +16 -0
- package/src/windowing/count-sliding/get-reverse-chronological-index.js +19 -0
- package/src/windowing/count-sliding/index.js +6 -0
- package/src/windowing/count-sliding/is-not-full.js +5 -0
- package/src/windowing/count-sliding/push.js +15 -0
- package/src/windowing/count-sliding/reset.js +11 -0
- package/src/windowing/count-sliding/size.js +5 -0
- package/src/windowing/time-sliding/create.js +25 -0
- package/src/windowing/time-sliding/push.js +42 -0
- package/CODE_OF_CONDUCT.md +0 -46
- package/CONTRIBUTING.md +0 -132
- package/docs/.nojekyll +0 -0
- package/docs/CONTRIBUTING.md +0 -134
- package/docs/README.md +0 -132
- package/docs/_coverpage.md +0 -26
- package/docs/_media/bg.png +0 -0
- package/docs/_media/wink-logo.png +0 -0
- package/docs/_navbar.md +0 -14
- package/docs/_sidebar.md +0 -2
- package/docs/index.html +0 -44
- package/eslint.config.js +0 -283
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// nodes/persistence-check/introspect.js
|
|
2
|
+
|
|
3
|
+
import { validators, composerValidators } from '../../core/utils/validate/index.js';
|
|
4
|
+
|
|
5
|
+
/** Single source of truth for what this plugin can do */
|
|
6
|
+
const SUPPORTED_STATS = [
|
|
7
|
+
'persistenceConfirmed'
|
|
8
|
+
];
|
|
9
|
+
|
|
10
|
+
/** Human-readable descriptions (for introspection) */
|
|
11
|
+
const STAT_DESCRIPTIONS = {
|
|
12
|
+
persistenceConfirmed: 'True if a predicate meets or exceeds the minimum votes out of a given total'
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/** Control methods available for triggers */
|
|
16
|
+
const SUPPORTED_CONTROL_METHODS = {
|
|
17
|
+
reset: 'Clears accumulated state and restarts computation',
|
|
18
|
+
enable: 'Enables node processing',
|
|
19
|
+
disable: 'Disables node processing',
|
|
20
|
+
pause: 'Pauses node processing while keeping state visible',
|
|
21
|
+
unpause: 'Resumes node processing after pause'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** The type of this node */
|
|
25
|
+
const NODE_TYPE = 'Persistence Check';
|
|
26
|
+
|
|
27
|
+
/** Node capabilities for documentation */
|
|
28
|
+
const CAPABILITIES = {
|
|
29
|
+
description: 'Confirms persistence when a predicate satisfies a minimum threshold within a window',
|
|
30
|
+
features: [
|
|
31
|
+
'Evaluates predicate with filtered inputs and counter arguments',
|
|
32
|
+
'Voting mechanism for stability confirmation',
|
|
33
|
+
'Configurable minimum votes and window size',
|
|
34
|
+
'Automatic reset after publishing confirmation'
|
|
35
|
+
]
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Export functions for accessing metadata
|
|
39
|
+
export const getSupportedStats = () => SUPPORTED_STATS.slice();
|
|
40
|
+
export const getStatDescriptions = () => ( { ...STAT_DESCRIPTIONS } );
|
|
41
|
+
export const getSupportedControlMethods = () => ( { ...SUPPORTED_CONTROL_METHODS } );
|
|
42
|
+
export const getNodeType = () => NODE_TYPE;
|
|
43
|
+
export const getCapabilities = () => ( { ...CAPABILITIES, features: CAPABILITIES.features.slice() } );
|
|
44
|
+
|
|
45
|
+
// Spec default values
|
|
46
|
+
export const DEFAULT_OPTIONS = {
|
|
47
|
+
minVotes: 3,
|
|
48
|
+
outOfTotal: 5
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// DSL Metadata for transpilation
|
|
52
|
+
const DSL_METADATA = {
|
|
53
|
+
// Spec schema for validation
|
|
54
|
+
specSchema: {
|
|
55
|
+
nodeType: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
required: true,
|
|
58
|
+
value: NODE_TYPE
|
|
59
|
+
},
|
|
60
|
+
name: {
|
|
61
|
+
type: 'string',
|
|
62
|
+
required: true,
|
|
63
|
+
validator: validators.identifier,
|
|
64
|
+
error: 'Name must be a valid identifier'
|
|
65
|
+
},
|
|
66
|
+
predicate: {
|
|
67
|
+
type: 'function',
|
|
68
|
+
required: true,
|
|
69
|
+
arity: 1,
|
|
70
|
+
error: 'Predicate must be a function with exactly one parameters (msg)'
|
|
71
|
+
},
|
|
72
|
+
minVotes: {
|
|
73
|
+
type: 'number',
|
|
74
|
+
required: false,
|
|
75
|
+
default: 3,
|
|
76
|
+
integer: true,
|
|
77
|
+
min: 1,
|
|
78
|
+
validator: validators.positiveInteger,
|
|
79
|
+
error: 'minVotes must be a positive integer'
|
|
80
|
+
},
|
|
81
|
+
outOfTotal: {
|
|
82
|
+
type: 'number',
|
|
83
|
+
required: false,
|
|
84
|
+
default: 5,
|
|
85
|
+
integer: true,
|
|
86
|
+
min: 1,
|
|
87
|
+
validator: validators.positiveInteger,
|
|
88
|
+
error: 'outOfTotal must be a positive integer'
|
|
89
|
+
},
|
|
90
|
+
stats: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
required: true,
|
|
93
|
+
propertyNames: SUPPORTED_STATS,
|
|
94
|
+
propertySchema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
required: true,
|
|
97
|
+
properties: {
|
|
98
|
+
storeAs: {
|
|
99
|
+
type: 'string',
|
|
100
|
+
required: true,
|
|
101
|
+
minLength: 1,
|
|
102
|
+
validator: validators.identifier,
|
|
103
|
+
error: 'storeAs must be a valid identifier'
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
triggers: {
|
|
109
|
+
type: 'array',
|
|
110
|
+
required: false,
|
|
111
|
+
itemSchema: {
|
|
112
|
+
type: 'object',
|
|
113
|
+
validator: composerValidators.trigger,
|
|
114
|
+
error: 'Invalid trigger specification'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// Cross-field validators
|
|
120
|
+
crossFieldValidators: [
|
|
121
|
+
{
|
|
122
|
+
fields: [ 'minVotes', 'outOfTotal' ],
|
|
123
|
+
validator: (spec) => {
|
|
124
|
+
const minVotes = spec.minVotes || 3;
|
|
125
|
+
const outOfTotal = spec.outOfTotal || 5;
|
|
126
|
+
return outOfTotal >= minVotes;
|
|
127
|
+
},
|
|
128
|
+
error: 'outOfTotal must be greater than or equal to minVotes'
|
|
129
|
+
},
|
|
130
|
+
composerValidators.noSelfTriggers
|
|
131
|
+
],
|
|
132
|
+
|
|
133
|
+
// How to build the spec from DSL params
|
|
134
|
+
buildSpec: ( name, predicate, stats, options ) => ( {
|
|
135
|
+
nodeType: NODE_TYPE,
|
|
136
|
+
name,
|
|
137
|
+
predicate,
|
|
138
|
+
stats,
|
|
139
|
+
...options
|
|
140
|
+
} ),
|
|
141
|
+
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const getDSLMetadata = () => ( { ...DSL_METADATA } );
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// nodes/persistence-check/publish-to.js
|
|
2
|
+
|
|
3
|
+
const publishTo = function ( state, msg ) {
|
|
4
|
+
if ( state.disable ) return;
|
|
5
|
+
|
|
6
|
+
msg[ state.stats.persistenceConfirmed.storeAs ] = state.persistenceConfirmed;
|
|
7
|
+
// Reset immediately after publishing it.
|
|
8
|
+
state.persistenceConfirmed = false;
|
|
9
|
+
}; // publishTo()
|
|
10
|
+
|
|
11
|
+
export default publishTo;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// nodes/persistence-check/reset.js
|
|
2
|
+
|
|
3
|
+
const reset = function ( state ) {
|
|
4
|
+
state.voteCount = 0;
|
|
5
|
+
state.unvoteCount = 0;
|
|
6
|
+
state.persistenceConfirmed = false;
|
|
7
|
+
// Clear error suppression so next error episode is logged
|
|
8
|
+
state.predicateErrorLogged = false;
|
|
9
|
+
return state;
|
|
10
|
+
}; // reset()
|
|
11
|
+
|
|
12
|
+
export default reset;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// nodes/persistence-check/update.js
|
|
2
|
+
|
|
3
|
+
import { executeTriggers } from '../../core/utils/node/index.js';
|
|
4
|
+
|
|
5
|
+
const update = function ( state, msg ) {
|
|
6
|
+
if ( state.disable || state.pause ) return state;
|
|
7
|
+
|
|
8
|
+
let predicateResult;
|
|
9
|
+
try {
|
|
10
|
+
predicateResult = state.predicate( msg );
|
|
11
|
+
// Recovery: clear log-suppression flag on success
|
|
12
|
+
if ( state.predicateErrorLogged ) state.predicateErrorLogged = false;
|
|
13
|
+
} catch ( error ) {
|
|
14
|
+
// Assume it to be a case of predicate evaluating to false
|
|
15
|
+
predicateResult = false;
|
|
16
|
+
// Log first error per episode; suppress subsequent until recovery
|
|
17
|
+
if ( !state.predicateErrorLogged ) {
|
|
18
|
+
state.predicateErrorLogged = true;
|
|
19
|
+
console.error( `WinkComposer/persistenceCheck: predicate threw exception: ${error.message}` );
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Update vote counts
|
|
24
|
+
if ( predicateResult ) {
|
|
25
|
+
state.voteCount += 1;
|
|
26
|
+
} else {
|
|
27
|
+
state.unvoteCount += 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Check for success
|
|
31
|
+
if ( state.voteCount >= state.minVotes ) {
|
|
32
|
+
state.voteCount = 0;
|
|
33
|
+
state.unvoteCount = 0;
|
|
34
|
+
state.persistenceConfirmed = true;
|
|
35
|
+
|
|
36
|
+
// Trigger controls
|
|
37
|
+
executeTriggers( state );
|
|
38
|
+
|
|
39
|
+
return state; // Early return on success
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check for window completion or mathematical impossibility
|
|
43
|
+
const totalProcessed = state.voteCount + state.unvoteCount;
|
|
44
|
+
const remaining = state.outOfTotal - totalProcessed;
|
|
45
|
+
|
|
46
|
+
if ( totalProcessed >= state.outOfTotal || // Window completition check
|
|
47
|
+
( state.voteCount + remaining ) < state.minVotes ) { // Mathematical impossibility check
|
|
48
|
+
// Window complete or success impossible - reset
|
|
49
|
+
state.voteCount = 0;
|
|
50
|
+
state.unvoteCount = 0;
|
|
51
|
+
state.persistenceConfirmed = false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return state;
|
|
55
|
+
}; // update()
|
|
56
|
+
|
|
57
|
+
export default update;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// nodes/process-index/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';
|
|
15
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// nodes/process-index/init.js
|
|
2
|
+
|
|
3
|
+
import { validateSpec } from '../../core/utils/node/index.js';
|
|
4
|
+
import * as introspect from './introspect.js';
|
|
5
|
+
import { DEFAULT_OPTIONS } 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
|
+
// Input fields
|
|
18
|
+
state.x = spec.from.x; // mean field
|
|
19
|
+
state.y = spec.from.y; // stddev field
|
|
20
|
+
|
|
21
|
+
// Spec limits (at least one required, validated by specSchema)
|
|
22
|
+
state.hasUpperSpecLimit = spec.upperSpecLimit !== undefined;
|
|
23
|
+
state.hasLowerSpecLimit = spec.lowerSpecLimit !== undefined;
|
|
24
|
+
state.upperSpecLimit = state.hasUpperSpecLimit ? spec.upperSpecLimit : NaN;
|
|
25
|
+
state.lowerSpecLimit = state.hasLowerSpecLimit ? spec.lowerSpecLimit : NaN;
|
|
26
|
+
|
|
27
|
+
// Options
|
|
28
|
+
state.epsilon = spec.epsilon ?? DEFAULT_OPTIONS.epsilon;
|
|
29
|
+
state.maxIndex = spec.maxIndex ?? DEFAULT_OPTIONS.maxIndex;
|
|
30
|
+
state.capableThreshold = spec.capableThreshold ?? DEFAULT_OPTIONS.capableThreshold;
|
|
31
|
+
state.marginalThreshold = spec.marginalThreshold ?? DEFAULT_OPTIONS.marginalThreshold;
|
|
32
|
+
|
|
33
|
+
// Config copy
|
|
34
|
+
state.stats = spec.stats;
|
|
35
|
+
|
|
36
|
+
// Output values
|
|
37
|
+
state.index = NaN;
|
|
38
|
+
state.upper = NaN;
|
|
39
|
+
state.lower = NaN;
|
|
40
|
+
state.status = 'incapable';
|
|
41
|
+
|
|
42
|
+
state.nodeType = introspect.getNodeType();
|
|
43
|
+
|
|
44
|
+
return state;
|
|
45
|
+
}; // init()
|
|
46
|
+
|
|
47
|
+
export default init;
|
|
48
|
+
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// nodes/process-index/introspect.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Introspection metadata for processIndex node.
|
|
5
|
+
*
|
|
6
|
+
* Computes process capability/performance index from mean and standard deviation
|
|
7
|
+
* with specification limits. Uses neutral terminology since interpretation as
|
|
8
|
+
* Cpk vs Ppk depends on upstream window configuration.
|
|
9
|
+
*
|
|
10
|
+
* Formulas:
|
|
11
|
+
* - upper = (upperSpecLimit - mean) / (3 * stddev)
|
|
12
|
+
* - lower = (mean - lowerSpecLimit) / (3 * stddev)
|
|
13
|
+
* - index = min(upper, lower) for two-sided, or the applicable one for one-sided
|
|
14
|
+
*
|
|
15
|
+
* DSL: .processIndex( 'tempPI', 'tempMean', 'tempStddev', { index: {...} }, { upperSpecLimit, lowerSpecLimit } )
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { validators } from '../../core/utils/validate/index.js';
|
|
19
|
+
|
|
20
|
+
/** Single source of truth for what this plugin can do */
|
|
21
|
+
const SUPPORTED_STATS = [
|
|
22
|
+
'index',
|
|
23
|
+
'upper',
|
|
24
|
+
'lower',
|
|
25
|
+
'status'
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
/** Human-readable descriptions (for introspection) */
|
|
29
|
+
const STAT_DESCRIPTIONS = {
|
|
30
|
+
index: 'Process index: min(upper, lower) for two-sided specs',
|
|
31
|
+
upper: 'Upper process index: (upperSpecLimit - mean) / (3 * stddev)',
|
|
32
|
+
lower: 'Lower process index: (mean - lowerSpecLimit) / (3 * stddev)',
|
|
33
|
+
status: 'Classification: capable, marginal, or incapable'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Control methods available for triggers */
|
|
37
|
+
const SUPPORTED_CONTROL_METHODS = {
|
|
38
|
+
reset: 'Clears accumulated state and restarts computation',
|
|
39
|
+
enable: 'Enables node processing',
|
|
40
|
+
disable: 'Disables node processing',
|
|
41
|
+
pause: 'Pauses node processing while keeping state visible',
|
|
42
|
+
unpause: 'Resumes node processing after pause'
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/** The type of this node */
|
|
46
|
+
const NODE_TYPE = 'Process Index';
|
|
47
|
+
|
|
48
|
+
/** Node capabilities for documentation */
|
|
49
|
+
const CAPABILITIES = {
|
|
50
|
+
description: 'Computes process capability/performance index from mean and stddev',
|
|
51
|
+
features: [
|
|
52
|
+
'Two-sided specs: index = min(upper, lower)',
|
|
53
|
+
'One-sided specs: upperSpecLimit only or lowerSpecLimit only supported',
|
|
54
|
+
'Status classification: capable (>=1.33), marginal (1.0-1.33), incapable (<1.0)',
|
|
55
|
+
'Configurable thresholds for status classification',
|
|
56
|
+
'Caps index at maxIndex (default 12) for near-zero stddev'
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Attach static metadata once, from our constants by making a shallow copy.
|
|
61
|
+
export const getSupportedStats = () => SUPPORTED_STATS.slice();
|
|
62
|
+
export const getStatDescriptions = () => ( { ...STAT_DESCRIPTIONS } );
|
|
63
|
+
export const getSupportedControlMethods = () => ( { ...SUPPORTED_CONTROL_METHODS } );
|
|
64
|
+
export const getNodeType = () => NODE_TYPE;
|
|
65
|
+
export const getCapabilities = () => ( { ...CAPABILITIES, features: CAPABILITIES.features.slice() } );
|
|
66
|
+
|
|
67
|
+
export const DEFAULT_OPTIONS = {
|
|
68
|
+
epsilon: 1e-12,
|
|
69
|
+
maxIndex: 12,
|
|
70
|
+
capableThreshold: 1.33,
|
|
71
|
+
marginalThreshold: 1.0
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// DSL Metadata for transpilation
|
|
75
|
+
const DSL_METADATA = {
|
|
76
|
+
// Spec schema for validation
|
|
77
|
+
specSchema: {
|
|
78
|
+
nodeType: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
required: true,
|
|
81
|
+
value: NODE_TYPE
|
|
82
|
+
},
|
|
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: 'string',
|
|
95
|
+
required: true,
|
|
96
|
+
validator: validators.noSpaces,
|
|
97
|
+
error: 'Mean field name cannot contain spaces'
|
|
98
|
+
},
|
|
99
|
+
y: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
required: true,
|
|
102
|
+
validator: validators.noSpaces,
|
|
103
|
+
error: 'Stddev field name cannot contain spaces'
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
upperSpecLimit: {
|
|
108
|
+
type: 'number',
|
|
109
|
+
required: false
|
|
110
|
+
},
|
|
111
|
+
lowerSpecLimit: {
|
|
112
|
+
type: 'number',
|
|
113
|
+
required: false
|
|
114
|
+
},
|
|
115
|
+
epsilon: {
|
|
116
|
+
type: 'number',
|
|
117
|
+
required: false,
|
|
118
|
+
default: DEFAULT_OPTIONS.epsilon
|
|
119
|
+
},
|
|
120
|
+
maxIndex: {
|
|
121
|
+
type: 'number',
|
|
122
|
+
required: false,
|
|
123
|
+
default: DEFAULT_OPTIONS.maxIndex
|
|
124
|
+
},
|
|
125
|
+
capableThreshold: {
|
|
126
|
+
type: 'number',
|
|
127
|
+
required: false,
|
|
128
|
+
default: DEFAULT_OPTIONS.capableThreshold
|
|
129
|
+
},
|
|
130
|
+
marginalThreshold: {
|
|
131
|
+
type: 'number',
|
|
132
|
+
required: false,
|
|
133
|
+
default: DEFAULT_OPTIONS.marginalThreshold
|
|
134
|
+
},
|
|
135
|
+
stats: {
|
|
136
|
+
type: 'object',
|
|
137
|
+
required: true,
|
|
138
|
+
propertyNames: SUPPORTED_STATS,
|
|
139
|
+
propertySchema: {
|
|
140
|
+
type: 'object',
|
|
141
|
+
required: true,
|
|
142
|
+
properties: {
|
|
143
|
+
storeAs: {
|
|
144
|
+
type: 'string',
|
|
145
|
+
required: true,
|
|
146
|
+
minLength: 1,
|
|
147
|
+
validator: validators.identifier,
|
|
148
|
+
error: 'storeAs must be a valid identifier'
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
// Cross-field validators
|
|
156
|
+
crossFieldValidators: [
|
|
157
|
+
{
|
|
158
|
+
fields: [ 'upperSpecLimit', 'lowerSpecLimit' ],
|
|
159
|
+
validator: ( spec ) => spec.upperSpecLimit !== undefined || spec.lowerSpecLimit !== undefined,
|
|
160
|
+
error: 'At least one of upperSpecLimit or lowerSpecLimit must be provided'
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
fields: [ 'from.x', 'from.y' ],
|
|
164
|
+
validator: ( spec ) => spec.from.x !== spec.from.y,
|
|
165
|
+
error: 'from.x (mean) and from.y (stddev) must be different fields'
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
|
|
169
|
+
// How to build the spec from DSL params
|
|
170
|
+
// DSL: .processIndex( 'tempPI', 'tempMean', 'tempStddev', { index: {...} }, { upperSpecLimit, lowerSpecLimit } )
|
|
171
|
+
buildSpec: ( name, x, y, stats, options ) => ( {
|
|
172
|
+
nodeType: NODE_TYPE,
|
|
173
|
+
name,
|
|
174
|
+
from: { x, y },
|
|
175
|
+
stats,
|
|
176
|
+
...options
|
|
177
|
+
} ),
|
|
178
|
+
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
export const getDSLMetadata = () => ( { ...DSL_METADATA } );
|
|
182
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// nodes/process-index/publish-to.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Publish function for processIndex node.
|
|
5
|
+
*
|
|
6
|
+
* Publishes computed index values and status to the message.
|
|
7
|
+
* On inputValidationFailed, publishes NaN for numeric stats and 'incapable' for status.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const publishTo = function ( state, msg ) {
|
|
11
|
+
if ( state.disable ) return;
|
|
12
|
+
|
|
13
|
+
if ( state.inputValidationFailed ) {
|
|
14
|
+
// Publish NaN for numeric stats, 'incapable' for status
|
|
15
|
+
if ( state.stats.index ) msg[ state.stats.index.storeAs ] = NaN;
|
|
16
|
+
if ( state.stats.upper ) msg[ state.stats.upper.storeAs ] = NaN;
|
|
17
|
+
if ( state.stats.lower ) msg[ state.stats.lower.storeAs ] = NaN;
|
|
18
|
+
if ( state.stats.status ) msg[ state.stats.status.storeAs ] = 'incapable';
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if ( state.stats.index ) msg[ state.stats.index.storeAs ] = state.index;
|
|
23
|
+
if ( state.stats.upper ) msg[ state.stats.upper.storeAs ] = state.upper;
|
|
24
|
+
if ( state.stats.lower ) msg[ state.stats.lower.storeAs ] = state.lower;
|
|
25
|
+
if ( state.stats.status ) msg[ state.stats.status.storeAs ] = state.status;
|
|
26
|
+
}; // publishTo()
|
|
27
|
+
|
|
28
|
+
export default publishTo;
|
|
29
|
+
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// nodes/process-index/update.js
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Update function for processIndex node.
|
|
5
|
+
*
|
|
6
|
+
* Computes process capability/performance index from mean and stddev.
|
|
7
|
+
* Supports two-sided specs (upperSpecLimit + lowerSpecLimit) and one-sided specs.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Clamp a value to [-maxIdx, maxIdx] range.
|
|
12
|
+
* @param {number} value - Raw index value
|
|
13
|
+
* @param {number} maxIdx - Maximum absolute value
|
|
14
|
+
* @returns {number} Clamped value
|
|
15
|
+
*/
|
|
16
|
+
const clampIndex = function ( value, maxIdx ) {
|
|
17
|
+
return Math.max( Math.min( value, maxIdx ), -maxIdx );
|
|
18
|
+
}; // clampIndex()
|
|
19
|
+
|
|
20
|
+
const update = function ( state, msg ) {
|
|
21
|
+
if ( state.disable || state.pause ) return state;
|
|
22
|
+
|
|
23
|
+
state.inputValidationFailed = false;
|
|
24
|
+
|
|
25
|
+
const mean = msg[ state.x ];
|
|
26
|
+
const stddev = msg[ state.y ];
|
|
27
|
+
|
|
28
|
+
// Validate inputs: mean must be finite, stddev must be finite and positive
|
|
29
|
+
if ( !Number.isFinite( mean ) || !Number.isFinite( stddev ) || stddev <= 0 ) {
|
|
30
|
+
state.inputValidationFailed = true;
|
|
31
|
+
return state;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const maxIdx = state.maxIndex;
|
|
35
|
+
const denominator = 3 * stddev;
|
|
36
|
+
|
|
37
|
+
// Compute upper index (if upperSpecLimit provided)
|
|
38
|
+
if ( state.hasUpperSpecLimit ) {
|
|
39
|
+
const rawUpper = ( state.upperSpecLimit - mean ) / denominator;
|
|
40
|
+
state.upper = clampIndex( rawUpper, maxIdx );
|
|
41
|
+
} else {
|
|
42
|
+
state.upper = NaN;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Compute lower index (if lowerSpecLimit provided)
|
|
46
|
+
if ( state.hasLowerSpecLimit ) {
|
|
47
|
+
const rawLower = ( mean - state.lowerSpecLimit ) / denominator;
|
|
48
|
+
state.lower = clampIndex( rawLower, maxIdx );
|
|
49
|
+
} else {
|
|
50
|
+
state.lower = NaN;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Combined index: explicit handling to avoid Math.min(NaN, value) = NaN
|
|
54
|
+
if ( state.hasUpperSpecLimit && state.hasLowerSpecLimit ) {
|
|
55
|
+
state.index = Math.min( state.upper, state.lower );
|
|
56
|
+
} else if ( state.hasUpperSpecLimit ) {
|
|
57
|
+
state.index = state.upper;
|
|
58
|
+
} else {
|
|
59
|
+
state.index = state.lower;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Status classification based on combined index
|
|
63
|
+
if ( state.index >= state.capableThreshold ) {
|
|
64
|
+
state.status = 'capable';
|
|
65
|
+
} else if ( state.index >= state.marginalThreshold ) {
|
|
66
|
+
state.status = 'marginal';
|
|
67
|
+
} else {
|
|
68
|
+
state.status = 'incapable';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return state;
|
|
72
|
+
}; // update()
|
|
73
|
+
|
|
74
|
+
export default update;
|
|
75
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// nodes/ratio/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,37 @@
|
|
|
1
|
+
// nodes/ratio/init.js
|
|
2
|
+
|
|
3
|
+
import { validateSpec } from '../../core/utils/node/index.js';
|
|
4
|
+
import * as introspect from './introspect.js';
|
|
5
|
+
|
|
6
|
+
const init = function ( spec ) {
|
|
7
|
+
validateSpec( spec, introspect );
|
|
8
|
+
|
|
9
|
+
// Create state after validation passes
|
|
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
|
+
// Extract field names - x is numerator, y is denominator.
|
|
18
|
+
state.x = spec.from.x;
|
|
19
|
+
state.y = spec.from.y;
|
|
20
|
+
|
|
21
|
+
// Config copy.
|
|
22
|
+
state.stats = spec.stats;
|
|
23
|
+
|
|
24
|
+
// Apply defaults from introspect (validation doesn't enforce them)
|
|
25
|
+
state.logScale = spec.logScale ?? introspect.DEFAULT_OPTIONS.logScale;
|
|
26
|
+
state.minY = spec.minY ?? introspect.DEFAULT_OPTIONS.minY;
|
|
27
|
+
state.scaleBy = spec.scaleBy ?? introspect.DEFAULT_OPTIONS.scaleBy;
|
|
28
|
+
|
|
29
|
+
// State variables.
|
|
30
|
+
state.ratio = 0;
|
|
31
|
+
|
|
32
|
+
state.nodeType = introspect.getNodeType();
|
|
33
|
+
|
|
34
|
+
return state;
|
|
35
|
+
}; // init()
|
|
36
|
+
|
|
37
|
+
export default init;
|