SiamCafe.net Blog
Technology

Stencil.js Machine Learning Pipeline

stenciljs machine learning pipeline
Stencil.js Machine Learning Pipeline | SiamCafe Blog
2025-06-16· อ. บอม — SiamCafe.net· 9,371 คำ

Stencil.js สำหรับ ML Dashboard

Stencil.js เป็น Compiler สร้าง Web Components ใช้ได้ทุก Framework TypeScript JSX Native Web Components ขนาดเล็ก Performance สูง

ML Pipeline Dashboard ต้องการ Components แสดง Model Metrics, Training Progress, Prediction Results ใช้ Stencil.js สร้าง Reusable Components

Stencil.js Component Development

// === Stencil.js ML Dashboard Components ===
// npm init stencil
// เลือก component

// 1. ML Metric Card Component
// src/components/ml-metric-card/ml-metric-card.tsx

import { Component, Prop, h, State, Watch } from '@stencil/core';

@Component({
  tag: 'ml-metric-card',
  styleUrl: 'ml-metric-card.css',
  shadow: true,
})
export class MlMetricCard {
  @Prop() metricName: string = '';
  @Prop() metricValue: number = 0;
  @Prop() unit: string = '';
  @Prop() trend: 'up' | 'down' | 'stable' = 'stable';
  @Prop() threshold: number = 0;
  @State() isAlert: boolean = false;

  @Watch('metricValue')
  handleValueChange(newValue: number) {
    this.isAlert = this.threshold > 0 && newValue < this.threshold;
  }

  componentWillLoad() {
    this.handleValueChange(this.metricValue);
  }

  private getTrendIcon(): string {
    switch (this.trend) {
      case 'up': return '▲';
      case 'down': return '▼';
      default: return '●';
    }
  }

  private getTrendColor(): string {
    switch (this.trend) {
      case 'up': return '#22c55e';
      case 'down': return '#ef4444';
      default: return '#6b7280';
    }
  }

  render() {
    return (
      
{this.metricName}
{this.metricValue.toFixed(4)} {this.unit}
{this.getTrendIcon()} {this.trend}
); } } // 2. Training Progress Component // src/components/ml-training-progress/ml-training-progress.tsx @Component({ tag: 'ml-training-progress', styleUrl: 'ml-training-progress.css', shadow: true, }) export class MlTrainingProgress { @Prop() currentEpoch: number = 0; @Prop() totalEpochs: number = 100; @Prop() loss: number = 0; @Prop() accuracy: number = 0; @Prop() status: 'training' | 'completed' | 'failed' = 'training'; private getProgressPercent(): number { return (this.currentEpoch / this.totalEpochs) * 100; } render() { const percent = this.getProgressPercent(); return (
Training Progress {this.status}
Epoch: {this.currentEpoch}/{this.totalEpochs} Loss: {this.loss.toFixed(4)} Accuracy: {(this.accuracy * 100).toFixed(1)}%
); } } // 3. Prediction Result Component @Component({ tag: 'ml-prediction', shadow: true, }) export class MlPrediction { @Prop() predictions: string = '[]'; // JSON string @State() parsedPredictions: Array<{label: string, confidence: number}> = []; componentWillLoad() { try { this.parsedPredictions = JSON.parse(this.predictions); } catch (e) { this.parsedPredictions = []; } } render() { return (

Predictions

{this.parsedPredictions.map(pred => (
{pred.label}
{(pred.confidence * 100).toFixed(1)}%
))}
); } } console.log("Stencil.js ML Components:"); console.log(" ml-metric-card: แสดง Metric พร้อม Trend"); console.log(" ml-training-progress: Training Progress Bar"); console.log(" ml-prediction: Prediction Results");

ML Model Integration

# ml_api_server.py — FastAPI ML Model Server
# pip install fastapi uvicorn scikit-learn numpy

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from typing import List, Dict, Optional
from datetime import datetime
import numpy as np

app = FastAPI(title="ML Pipeline API")

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
)

# Models
class PredictionRequest(BaseModel):
    features: List[float]
    model_name: str = "default"

class PredictionResponse(BaseModel):
    predictions: List[Dict[str, float]]
    model_name: str
    latency_ms: float

class TrainingStatus(BaseModel):
    model_name: str
    current_epoch: int
    total_epochs: int
    loss: float
    accuracy: float
    status: str  # training, completed, failed

class ModelMetrics(BaseModel):
    model_name: str
    accuracy: float
    precision: float
    recall: float
    f1_score: float
    latency_p50_ms: float
    latency_p99_ms: float
    predictions_today: int

# In-memory state
training_status = TrainingStatus(
    model_name="image-classifier-v2",
    current_epoch=75, total_epochs=100,
    loss=0.0823, accuracy=0.9456,
    status="training",
)

@app.get("/api/metrics", response_model=ModelMetrics)
async def get_metrics():
    """Get Model Metrics สำหรับ Dashboard"""
    return ModelMetrics(
        model_name="image-classifier-v2",
        accuracy=0.9456,
        precision=0.9312,
        recall=0.9589,
        f1_score=0.9449,
        latency_p50_ms=12.5,
        latency_p99_ms=45.2,
        predictions_today=15234,
    )

@app.get("/api/training/status", response_model=TrainingStatus)
async def get_training_status():
    """Get Training Status"""
    return training_status

@app.post("/api/predict", response_model=PredictionResponse)
async def predict(request: PredictionRequest):
    """Run Prediction"""
    start = datetime.now()

    # Simulated prediction
    np.random.seed(42)
    labels = ["cat", "dog", "bird", "fish"]
    confidences = np.random.dirichlet(np.ones(len(labels)))

    predictions = [
        {"label": label, "confidence": float(conf)}
        for label, conf in sorted(
            zip(labels, confidences),
            key=lambda x: x[1], reverse=True
        )
    ]

    latency = (datetime.now() - start).total_seconds() * 1000

    return PredictionResponse(
        predictions=predictions,
        model_name=request.model_name,
        latency_ms=latency,
    )

@app.get("/api/pipeline/status")
async def pipeline_status():
    """Pipeline Status Overview"""
    return {
        "stages": [
            {"name": "Data Ingestion", "status": "completed", "records": 50000},
            {"name": "Feature Engineering", "status": "completed", "features": 128},
            {"name": "Model Training", "status": "running", "epoch": 75},
            {"name": "Evaluation", "status": "pending"},
            {"name": "Deployment", "status": "pending"},
        ],
        "last_updated": datetime.now().isoformat(),
    }

# uvicorn ml_api_server:app --host 0.0.0.0 --port 8000

print("ML API Server:")
print("  GET  /api/metrics          - Model Metrics")
print("  GET  /api/training/status  - Training Status")
print("  POST /api/predict          - Run Prediction")
print("  GET  /api/pipeline/status  - Pipeline Overview")

Dashboard Integration










 -->

// Stencil.js Build Commands
// npm run build          — Production build
// npm run generate       — Generate new component
// npm run test           — Run tests
// npm run test.watch     — Watch mode

// stencil.config.ts
// import { Config } from '@stencil/core';
// export const config: Config = {
//   namespace: 'ml-components',
//   outputTargets: [
//     { type: 'dist', esmLoaderPath: '../loader' },
//     { type: 'dist-custom-elements' },
//     { type: 'www', serviceWorker: null },
//   ],
// };

console.log("Dashboard Integration:");
console.log("  Components: ml-metric-card, ml-training-progress, ml-prediction");
console.log("  API: FastAPI ML Server");
console.log("  Update: Auto-refresh every 5s");

Best Practices

Stencil.js คืออะไร

Compiler สร้าง Web Components ใช้ได้ทุก Framework React Angular Vue Ionic TypeScript JSX Native Web Components ขนาดเล็ก Performance สูง

Web Components คืออะไร

Web Standard Custom Elements Shadow DOM HTML Templates Reusable UI Components ทุก Browser ทุก Framework ไม่ Style Leaking Shadow DOM แยก CSS

Stencil.js เหมาะกับงานอะไร

Design System ข้าม Framework Component Library องค์กร Dashboard Components Embed หลาย App Micro-frontend ไม่เหมาะ Full App ใช้ร่วม Framework หลัก

วิธีเชื่อม ML Model กับ Frontend ทำอย่างไร

REST API เรียก ML Model Server FastAPI Flask ส่งข้อมูล Predict TensorFlow.js รัน Browser WebSocket Real-time Streaming Chart Libraries แสดงผล

สรุป

Stencil.js สร้าง Web Components สำหรับ ML Dashboard ใช้ได้ทุก Framework Shadow DOM แยก CSS Components แสดง Metrics Training Progress Predictions เชื่อม FastAPI ML Server ด้วย REST API Real-time ด้วย WebSocket

📖 บทความที่เกี่ยวข้อง

machine learning reinforcement learning คืออ่านบทความ → Linux io_uring Machine Learning Pipelineอ่านบทความ → Stencil.js RBAC ABAC Policyอ่านบทความ → BGP Routing Advanced Learning Path Roadmapอ่านบทความ → GraphQL Subscriptions Machine Learning Pipelineอ่านบทความ →

📚 ดูบทความทั้งหมด →