nirs4all 0.2.8 → 0.2.9

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/README.md CHANGED
@@ -25,6 +25,12 @@ Savitzky-Golay defaults to `mode: "interp"` for full nirs4all parity and
25
25
  preserves explicit methods-backed modes (`mirror`, `constant`, `nearest`,
26
26
  `wrap`, `interp`) plus `cval` in the serialized preprocessing chain.
27
27
 
28
+ Custom app hosts can inspect `capabilityManifest()`, `controllerCapabilities`,
29
+ and `runtimeSurfaces` before rendering graph nodes or selecting a runtime. The
30
+ manifest schema is `nirs4all-core.capabilities.v1`; it exposes the stable V1
31
+ controller IDs for Kennard-Stone, SNV, Savitzky-Golay, PLS regression, and the
32
+ portable methods pipeline, with parameter lists matching the executable parser.
33
+
28
34
  For a browser-only custom host, pair this package with `nirs4all-ui`: keep
29
35
  runtime loading and portable execution in `nirs4all`, and consume shared React
30
36
  components / view-model helpers / brand assets from `nirs4all-ui`. The
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nirs4all",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Portable nirs4all aggregate binding for JavaScript and WASM",
5
5
  "type": "module",
6
6
  "exports": {
package/src/index.d.ts CHANGED
@@ -16,6 +16,33 @@ export interface PipelineDefinition {
16
16
  pipeline: unknown[];
17
17
  }
18
18
 
19
+ export type RuntimeSurface = 'python' | 'r' | 'javascript_wasm' | 'rust' | 'matlab_octave';
20
+ export type CapabilityLevel = 'metadata' | 'plan' | 'execute-local' | 'execute-remote' | 'parity-validated';
21
+
22
+ export interface ControllerCapability {
23
+ id: string;
24
+ kind: 'splitter' | 'transform' | 'model' | 'pipeline';
25
+ domain: Upstream['key'];
26
+ label: string;
27
+ operatorClasses: readonly string[];
28
+ ports: {
29
+ inputs: readonly string[];
30
+ outputs: readonly string[];
31
+ };
32
+ parameters: readonly string[];
33
+ runtime: Readonly<Record<RuntimeSurface, CapabilityLevel>>;
34
+ executionPath: 'portable_pipeline' | 'run_portable_pipeline';
35
+ composes?: readonly string[];
36
+ }
37
+
38
+ export interface CapabilityManifest {
39
+ schema: 'nirs4all-core.capabilities.v1';
40
+ aggregate: 'nirs4all-core';
41
+ runtimeSurfaces: readonly RuntimeSurface[];
42
+ portableOperatorClasses: readonly string[];
43
+ controllers: readonly ControllerCapability[];
44
+ }
45
+
19
46
  export interface PortableMatrixDataset {
20
47
  X: Float64Array | number[] | readonly number[] | readonly (readonly number[])[];
21
48
  y: Float64Array | number[] | readonly number[] | readonly (readonly number[])[];
@@ -68,6 +95,9 @@ export interface PortablePredictionResult {
68
95
 
69
96
  export const upstreams: readonly Upstream[];
70
97
  export const portableOperatorClasses: readonly string[];
98
+ export const runtimeSurfaces: readonly RuntimeSurface[];
99
+ export const controllerCapabilities: readonly ControllerCapability[];
100
+ export function capabilityManifest(): CapabilityManifest;
71
101
 
72
102
  export function upstream(name: string): Upstream | null;
73
103
  export function importUpstream(name: string): Promise<unknown>;
package/src/index.js CHANGED
@@ -45,6 +45,120 @@ export const portableOperatorClasses = Object.freeze([
45
45
  'sklearn.cross_decomposition._pls.PLSRegression',
46
46
  ]);
47
47
 
48
+ export const runtimeSurfaces = Object.freeze([
49
+ 'python',
50
+ 'r',
51
+ 'javascript_wasm',
52
+ 'rust',
53
+ 'matlab_octave',
54
+ ]);
55
+
56
+ const parityRuntime = Object.freeze(Object.fromEntries(
57
+ runtimeSurfaces.map((surface) => [surface, 'parity-validated']),
58
+ ));
59
+
60
+ export const controllerCapabilities = Object.freeze([
61
+ Object.freeze({
62
+ id: 'split.kennard_stone',
63
+ kind: 'splitter',
64
+ domain: 'methods',
65
+ label: 'Kennard-Stone split',
66
+ operatorClasses: Object.freeze([
67
+ 'nirs4all.operators.splitters.KennardStoneSplitter',
68
+ 'nirs4all.operators.splitters.splitters.KennardStoneSplitter',
69
+ ]),
70
+ ports: Object.freeze({
71
+ inputs: Object.freeze(['X']),
72
+ outputs: Object.freeze(['train_indices', 'test_indices']),
73
+ }),
74
+ parameters: Object.freeze(['test_size']),
75
+ runtime: parityRuntime,
76
+ executionPath: 'portable_pipeline',
77
+ }),
78
+ Object.freeze({
79
+ id: 'preprocess.snv',
80
+ kind: 'transform',
81
+ domain: 'methods',
82
+ label: 'Standard normal variate',
83
+ operatorClasses: Object.freeze([
84
+ 'nirs4all.operators.transforms.SNV',
85
+ 'nirs4all.operators.transforms.StandardNormalVariate',
86
+ 'nirs4all.operators.transforms.scalers.StandardNormalVariate',
87
+ ]),
88
+ ports: Object.freeze({
89
+ inputs: Object.freeze(['X']),
90
+ outputs: Object.freeze(['X_transformed']),
91
+ }),
92
+ parameters: Object.freeze([]),
93
+ runtime: parityRuntime,
94
+ executionPath: 'portable_pipeline',
95
+ }),
96
+ Object.freeze({
97
+ id: 'preprocess.savgol',
98
+ kind: 'transform',
99
+ domain: 'methods',
100
+ label: 'Savitzky-Golay',
101
+ operatorClasses: Object.freeze([
102
+ 'nirs4all.operators.transforms.SavitzkyGolay',
103
+ 'nirs4all.operators.transforms.nirs.SavitzkyGolay',
104
+ ]),
105
+ ports: Object.freeze({
106
+ inputs: Object.freeze(['X']),
107
+ outputs: Object.freeze(['X_transformed']),
108
+ }),
109
+ parameters: Object.freeze(['window_length', 'polyorder', 'deriv', 'mode', 'cval']),
110
+ runtime: parityRuntime,
111
+ executionPath: 'portable_pipeline',
112
+ }),
113
+ Object.freeze({
114
+ id: 'model.pls_regression',
115
+ kind: 'model',
116
+ domain: 'methods',
117
+ label: 'PLS regression',
118
+ operatorClasses: Object.freeze([
119
+ 'sklearn.cross_decomposition.PLSRegression',
120
+ 'sklearn.cross_decomposition._pls.PLSRegression',
121
+ ]),
122
+ ports: Object.freeze({
123
+ inputs: Object.freeze(['X', 'y']),
124
+ outputs: Object.freeze(['predictions', 'model']),
125
+ }),
126
+ parameters: Object.freeze(['n_components', '_range_']),
127
+ runtime: parityRuntime,
128
+ executionPath: 'portable_pipeline',
129
+ }),
130
+ Object.freeze({
131
+ id: 'pipeline.portable_methods',
132
+ kind: 'pipeline',
133
+ domain: 'methods',
134
+ label: 'Portable methods pipeline',
135
+ operatorClasses: Object.freeze([]),
136
+ ports: Object.freeze({
137
+ inputs: Object.freeze(['pipeline', 'dataset']),
138
+ outputs: Object.freeze(['execution_result', 'predictions', 'model']),
139
+ }),
140
+ parameters: Object.freeze([]),
141
+ runtime: parityRuntime,
142
+ executionPath: 'run_portable_pipeline',
143
+ composes: Object.freeze([
144
+ 'split.kennard_stone',
145
+ 'preprocess.snv',
146
+ 'preprocess.savgol',
147
+ 'model.pls_regression',
148
+ ]),
149
+ }),
150
+ ]);
151
+
152
+ export function capabilityManifest() {
153
+ return clone({
154
+ schema: 'nirs4all-core.capabilities.v1',
155
+ aggregate: 'nirs4all-core',
156
+ runtimeSurfaces,
157
+ portableOperatorClasses,
158
+ controllers: controllerCapabilities,
159
+ });
160
+ }
161
+
48
162
  const portableOperatorSet = new Set(portableOperatorClasses);
49
163
 
50
164
  const upstreamByKey = new Map(upstreams.map((item) => [item.key, item]));