nirs4all 0.2.7 → 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
@@ -11,7 +11,7 @@ application lives in `nirs4all-web`; this directory is for the reusable
11
11
  JavaScript/WASM binding and package metadata.
12
12
 
13
13
  The portable execution API delegates Kennard-Stone, SNV, Savitzky-Golay, and
14
- PLS component sweeps to `@nirs4all/methods-wasm`:
14
+ PLS component sweeps to `@nirs4all/methods`:
15
15
 
16
16
  - `runPortablePipeline(source, dataset)` parses the shared nirs4all JSON/YAML
17
17
  syntax, executes the portable subset, and returns parity-checkable split,
@@ -24,3 +24,16 @@ PLS component sweeps to `@nirs4all/methods-wasm`:
24
24
  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
+
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
+
34
+ For a browser-only custom host, pair this package with `nirs4all-ui`: keep
35
+ runtime loading and portable execution in `nirs4all`, and consume shared React
36
+ components / view-model helpers / brand assets from `nirs4all-ui`. The
37
+ reference composition lives in `../../nirs4all-web/studio-lite`, whose contract
38
+ tests exercise `runPortablePipeline()` / `predictPortablePipeline()` together
39
+ with the shared UI package in a no-backend environment.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nirs4all",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Portable nirs4all aggregate binding for JavaScript and WASM",
5
5
  "type": "module",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "@nirs4all/datasets-wasm": "*",
48
48
  "@nirs4all/formats-wasm": "*",
49
49
  "@nirs4all/io-wasm": "*",
50
- "@nirs4all/methods-wasm": "*",
50
+ "@nirs4all/methods": "*",
51
51
  "@nirs4all/nirs4all-datasets-wasm": "*",
52
52
  "dag-ml-data-wasm": "*",
53
53
  "dag-ml-wasm": "*",
@@ -64,7 +64,7 @@
64
64
  "@nirs4all/io-wasm": {
65
65
  "optional": true
66
66
  },
67
- "@nirs4all/methods-wasm": {
67
+ "@nirs4all/methods": {
68
68
  "optional": true
69
69
  },
70
70
  "@nirs4all/nirs4all-datasets-wasm": {
@@ -82,5 +82,9 @@
82
82
  "dag-ml-data-wasm": {
83
83
  "optional": true
84
84
  }
85
+ },
86
+ "publishConfig": {
87
+ "access": "public",
88
+ "provenance": true
85
89
  }
86
90
  }
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
@@ -28,7 +28,7 @@ export const upstreams = Object.freeze([
28
28
  },
29
29
  {
30
30
  key: 'methods',
31
- candidates: ['@nirs4all/methods-wasm'],
31
+ candidates: ['@nirs4all/methods'],
32
32
  role: 'Portable C ABI PLS/NIRS numerical engine',
33
33
  },
34
34
  ]);
@@ -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]));
@@ -213,8 +327,8 @@ function importUpstreamCandidate(candidate) {
213
327
  return import('@nirs4all/datasets-wasm');
214
328
  case '@nirs4all/nirs4all-datasets-wasm':
215
329
  return import('@nirs4all/nirs4all-datasets-wasm');
216
- case '@nirs4all/methods-wasm':
217
- return import('@nirs4all/methods-wasm');
330
+ case '@nirs4all/methods':
331
+ return import('@nirs4all/methods');
218
332
  default:
219
333
  return import(candidate);
220
334
  }