@holoscript/plugin-manufacturing-qc 2.0.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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/package.json +13 -0
- package/src/__tests__/runtime-integration.test.ts +165 -0
- package/src/__tests__/spc.test.ts +278 -0
- package/src/index.ts +30 -0
- package/src/runtime.ts +172 -0
- package/src/spc.ts +728 -0
- package/src/traits/BOMTrait.ts +22 -0
- package/src/traits/DefectTrackingTrait.ts +26 -0
- package/src/traits/ProductionLineTrait.ts +26 -0
- package/src/traits/QualityGateTrait.ts +27 -0
- package/src/traits/types.ts +4 -0
- package/tsconfig.json +1 -0
- package/vitest.config.ts +22 -0
package/src/runtime.ts
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime integration for @holoscript/plugin-manufacturing-qc.
|
|
3
|
+
*
|
|
4
|
+
* Bridges the previously dead-wired `spc` trait into a behavioral
|
|
5
|
+
* TraitHandler that the HoloScript runtime actually dispatches
|
|
6
|
+
* (HoloScriptRuntime.registerTrait -> applyDirectives / updateTraits).
|
|
7
|
+
*
|
|
8
|
+
* Before this module the plugin declared trait NAMES only (pluginMeta.traits)
|
|
9
|
+
* and exported the SPC solvers (computeCapability, buildSPCChart, …), but
|
|
10
|
+
* nothing invoked a solver THROUGH the runtime — the whole domain-plugin tier
|
|
11
|
+
* was built-but-dead-wired. This mirrors government-civic-plugin's reference
|
|
12
|
+
* integration (civic_decision): it wires the deterministic Statistical Process
|
|
13
|
+
* Control capability solver (`computeCapability`) behind the `spc` trait so the
|
|
14
|
+
* runtime's directive dispatch can run it. The remaining manufacturing-qc
|
|
15
|
+
* traits follow the same registrar shape.
|
|
16
|
+
*/
|
|
17
|
+
import { registerPluginTraits } from '@holoscript/core/runtime';
|
|
18
|
+
import {
|
|
19
|
+
computeCapability,
|
|
20
|
+
type Subgroup,
|
|
21
|
+
type ProcessCapability,
|
|
22
|
+
} from './spc';
|
|
23
|
+
|
|
24
|
+
/** Stable id for this plugin's trait ownership tagging. */
|
|
25
|
+
export const MANUFACTURING_QC_PLUGIN_ID = 'manufacturing-qc' as const;
|
|
26
|
+
|
|
27
|
+
/** Config carried by an orb's `@spc` trait directive. */
|
|
28
|
+
export interface SpcTraitConfig {
|
|
29
|
+
/** All individual measurements (flattened across subgroups). Required; absence emits `spc_error`. */
|
|
30
|
+
allValues?: number[];
|
|
31
|
+
/** Original subgroups (used for within-subgroup σ̂ via R̅/d₂). Required. */
|
|
32
|
+
subgroups?: Subgroup[];
|
|
33
|
+
/** Lower specification limit. Required. */
|
|
34
|
+
lsl?: number;
|
|
35
|
+
/** Upper specification limit. Required. */
|
|
36
|
+
usl?: number;
|
|
37
|
+
/** Nominal target (optional; used for Cpm). */
|
|
38
|
+
target?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Summary payload emitted on `spc_solved`. */
|
|
42
|
+
export interface SpcSolvedEvent {
|
|
43
|
+
nodeId: string;
|
|
44
|
+
/** Potential capability index (short-term, within-subgroup σ̂). */
|
|
45
|
+
Cp: number;
|
|
46
|
+
/** Actual capability index (within-subgroup σ̂, accounts for centering). */
|
|
47
|
+
Cpk: number;
|
|
48
|
+
/** Estimated process mean. */
|
|
49
|
+
processMean: number;
|
|
50
|
+
/** Overall (long-term) process standard deviation. */
|
|
51
|
+
processStdDev: number;
|
|
52
|
+
/** Whether the process is capable (Cpk >= 1.33). */
|
|
53
|
+
capable: boolean;
|
|
54
|
+
/** Number of individual measurements evaluated. */
|
|
55
|
+
valueCount: number;
|
|
56
|
+
/** Number of subgroups supplied. */
|
|
57
|
+
subgroupCount: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Structural view of the runtime trait-handler contract. Matches
|
|
62
|
+
* `@holoscript/core` TraitTypes.TraitHandler at the call sites the runtime
|
|
63
|
+
* actually uses (onAttach / onUpdate receive the node, the directive config,
|
|
64
|
+
* and a context exposing `emit`). Declared locally so the plugin stays
|
|
65
|
+
* decoupled from core's full trait surface.
|
|
66
|
+
*/
|
|
67
|
+
export interface TraitDispatchContext {
|
|
68
|
+
emit: (event: string, payload?: unknown) => void;
|
|
69
|
+
setState?: (updates: Record<string, unknown>) => void;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface RuntimeTraitHandler {
|
|
73
|
+
name: string;
|
|
74
|
+
onAttach?: (node: unknown, config: SpcTraitConfig, context: TraitDispatchContext) => void;
|
|
75
|
+
onUpdate?: (
|
|
76
|
+
node: unknown,
|
|
77
|
+
config: SpcTraitConfig,
|
|
78
|
+
context: TraitDispatchContext,
|
|
79
|
+
delta: number,
|
|
80
|
+
) => void;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface SpcNode {
|
|
84
|
+
id?: string;
|
|
85
|
+
name?: string;
|
|
86
|
+
properties?: Record<string, unknown>;
|
|
87
|
+
__spcResult?: ProcessCapability;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Run the SPC capability solver on the directive config, write the result onto the node, and emit. */
|
|
91
|
+
function solveOntoNode(
|
|
92
|
+
node: unknown,
|
|
93
|
+
config: SpcTraitConfig | undefined,
|
|
94
|
+
context: TraitDispatchContext,
|
|
95
|
+
): void {
|
|
96
|
+
const carrier = node as SpcNode;
|
|
97
|
+
const nodeId = carrier.id ?? carrier.name ?? 'unknown';
|
|
98
|
+
const allValues = config?.allValues;
|
|
99
|
+
const subgroups = config?.subgroups;
|
|
100
|
+
const lsl = config?.lsl;
|
|
101
|
+
const usl = config?.usl;
|
|
102
|
+
|
|
103
|
+
if (
|
|
104
|
+
!Array.isArray(allValues) ||
|
|
105
|
+
!Array.isArray(subgroups) ||
|
|
106
|
+
typeof lsl !== 'number' ||
|
|
107
|
+
typeof usl !== 'number'
|
|
108
|
+
) {
|
|
109
|
+
context.emit('spc_error', {
|
|
110
|
+
nodeId,
|
|
111
|
+
error:
|
|
112
|
+
'spc trait requires config.allValues (number[]), config.subgroups (Subgroup[]), config.lsl (number) and config.usl (number)',
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const result = computeCapability(allValues, subgroups, lsl, usl, config?.target);
|
|
119
|
+
carrier.__spcResult = result;
|
|
120
|
+
carrier.properties = {
|
|
121
|
+
...(carrier.properties ?? {}),
|
|
122
|
+
spcCp: result.Cp,
|
|
123
|
+
spcCpk: result.Cpk,
|
|
124
|
+
spcCapable: result.capable,
|
|
125
|
+
};
|
|
126
|
+
const summary: SpcSolvedEvent = {
|
|
127
|
+
nodeId,
|
|
128
|
+
Cp: result.Cp,
|
|
129
|
+
Cpk: result.Cpk,
|
|
130
|
+
processMean: result.processMean,
|
|
131
|
+
processStdDev: result.processStdDev,
|
|
132
|
+
capable: result.capable,
|
|
133
|
+
valueCount: allValues.length,
|
|
134
|
+
subgroupCount: subgroups.length,
|
|
135
|
+
};
|
|
136
|
+
context.setState?.({ [`spc:${nodeId}`]: summary });
|
|
137
|
+
context.emit('spc_solved', summary);
|
|
138
|
+
} catch (error) {
|
|
139
|
+
context.emit('spc_error', {
|
|
140
|
+
nodeId,
|
|
141
|
+
error: error instanceof Error ? error.message : String(error),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Behavioral handler for the manufacturing-qc `spc` trait. Runs the
|
|
148
|
+
* deterministic Statistical Process Control capability solver whenever an orb
|
|
149
|
+
* carrying the trait is attached (and on each per-frame update), writing the
|
|
150
|
+
* Cp/Cpk result onto the node and emitting `spc_solved` / `spc_error`.
|
|
151
|
+
*/
|
|
152
|
+
export const spcHandler: RuntimeTraitHandler = {
|
|
153
|
+
name: 'spc',
|
|
154
|
+
onAttach: (node, config, context) => solveOntoNode(node, config, context),
|
|
155
|
+
onUpdate: (node, config, context) => solveOntoNode(node, config, context),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/** A runtime that can register behavioral trait handlers. */
|
|
159
|
+
export interface TraitRegistrar {
|
|
160
|
+
registerTrait(name: string, handler: unknown): void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Register manufacturing-qc behavioral trait handlers into a runtime that
|
|
165
|
+
* exposes `registerTrait(name, handler)` — e.g. `@holoscript/core`
|
|
166
|
+
* HoloScriptRuntime. This is the consumption path the dead-wired tier was
|
|
167
|
+
* missing: after this call the runtime's directive dispatch (applyDirectives /
|
|
168
|
+
* updateTraits) will invoke the SPC capability solver for `@spc` orbs.
|
|
169
|
+
*/
|
|
170
|
+
export function registerManufacturingQcTraitHandlers(registrar: TraitRegistrar): void {
|
|
171
|
+
registerPluginTraits(registrar, MANUFACTURING_QC_PLUGIN_ID, [spcHandler]);
|
|
172
|
+
}
|