1.0.1 โ€ข Published 11 months ago

@mandarin3d/slicing-sdk v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
11 months ago

Mandarin3D Slicing SDK

A TypeScript SDK for interacting with the Mandarin3D slicing API. This package provides a simple interface for submitting 3D models for slicing and monitoring the slicing process, with built-in support for both production and development environments.

Features

  • ๐Ÿš€ Easy integration with Next.js and React applications
  • ๐Ÿ”„ Real-time status updates via WebSocket in development mode
  • ๐ŸŽฏ Type-safe API with full TypeScript support
  • ๐Ÿ›  Built-in React hooks for easy state management
  • ๐Ÿงช Development mode with local callback support
  • ๐Ÿ“ก Automatic polling in production mode

Installation

npm install @mandarin3d/slicing-sdk
# or
yarn add @mandarin3d/slicing-sdk
# or
pnpm add @mandarin3d/slicing-sdk

Quick Start

Basic Usage in Next.js

import { M3DSlicingClient } from '@mandarin3d/slicing-sdk';

// Create a client instance
const client = new M3DSlicingClient({
  apiKey: process.env.NEXT_PUBLIC_M3D_API_KEY!,
  mode: process.env.NODE_ENV === 'development' ? 'development' : 'production'
});

// Submit a slicing job
const response = await client.submitSlicingJob({
  stl_file_link: 'https://example.com/model.stl'
});

console.log('Job submitted:', response.job_id);

Using the React Hook

import { useSlicingJob } from '@mandarin3d/slicing-sdk';

function SlicingComponent() {
  const { submitJob, status, isLoading, error } = useSlicingJob({
    client,
    onComplete: (status) => {
      console.log('Slicing completed!', status);
    }
  });

  const handleSubmit = async () => {
    await submitJob({
      stl_file_link: 'https://example.com/model.stl'
    });
  };

  return (
    <div>
      <button onClick={handleSubmit} disabled={isLoading}>
        Start Slicing
      </button>
      {status && (
        <div>
          <p>Status: {status.status}</p>
          <p>Message: {status.message}</p>
          {status.slicing_info && (
            <div>
              <p>Volume: {status.slicing_info.volume}mmยณ</p>
              <p>Size: {status.slicing_info.size_x}x{status.slicing_info.size_y}x{status.slicing_info.size_z}mm</p>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

Complete Next.js Example

// pages/slicing.tsx
import { useState } from 'react';
import { M3DSlicingClient, useSlicingJob } from '@mandarin3d/slicing-sdk';
import { FaUpload, FaSpinner, FaCheck, FaTimes } from 'react-icons/fa';

// Initialize the client
const client = new M3DSlicingClient({
  apiKey: process.env.NEXT_PUBLIC_M3D_API_KEY!,
  mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
  devPort: 3001 // Optional, defaults to 3001
});

export default function SlicingPage() {
  const [fileUrl, setFileUrl] = useState('');
  
  const { submitJob, status, isLoading, error } = useSlicingJob({
    client,
    onComplete: (status) => {
      if (status.status === 'completed') {
        // Handle completion
      }
    }
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!fileUrl) return;
    
    try {
      await submitJob({
        stl_file_link: fileUrl
      });
    } catch (err) {
      console.error('Failed to submit job:', err);
    }
  };

  return (
    <div className="max-w-2xl mx-auto p-6">
      <h1 className="text-3xl font-bold mb-6">3D Model Slicer</h1>
      
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-2">
            STL File URL
          </label>
          <input
            type="url"
            value={fileUrl}
            onChange={(e) => setFileUrl(e.target.value)}
            className="w-full px-4 py-2 border rounded"
            placeholder="https://example.com/model.stl"
            required
          />
        </div>
        
        <button
          type="submit"
          disabled={isLoading}
          className="flex items-center justify-center w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50"
        >
          {isLoading ? (
            <><FaSpinner className="animate-spin mr-2" /> Processing...</>
          ) : (
            <><FaUpload className="mr-2" /> Submit for Slicing</>
          )}
        </button>
      </form>

      {error && (
        <div className="mt-4 p-4 bg-red-50 text-red-700 rounded">
          <div className="flex items-center">
            <FaTimes className="mr-2" />
            {error.message}
          </div>
        </div>
      )}

      {status && (
        <div className="mt-6 p-4 border rounded">
          <h2 className="text-xl font-semibold mb-4">Slicing Status</h2>
          
          <div className="space-y-2">
            <div className="flex items-center">
              <span className="font-medium mr-2">Status:</span>
              <span className={status.status === 'completed' ? 'text-green-600' : 'text-blue-600'}>
                {status.status === 'completed' && <FaCheck className="inline mr-1" />}
                {status.status}
              </span>
            </div>
            
            <div>
              <span className="font-medium mr-2">Message:</span>
              {status.message}
            </div>

            {status.slicing_info && (
              <div className="mt-4 space-y-2">
                <h3 className="text-lg font-medium">Model Information</h3>
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <span className="font-medium">Volume:</span>
                    <span className="ml-2">{status.slicing_info.volume}mmยณ</span>
                  </div>
                  <div>
                    <span className="font-medium">Dimensions:</span>
                    <span className="ml-2">
                      {status.slicing_info.size_x}x{status.slicing_info.size_y}x{status.slicing_info.size_z}mm
                    </span>
                  </div>
                  {status.slicing_info.gcode_info && (
                    <>
                      <div>
                        <span className="font-medium">Print Time:</span>
                        <span className="ml-2">{status.slicing_info.gcode_info.print_time}</span>
                      </div>
                      <div>
                        <span className="font-medium">Layer Count:</span>
                        <span className="ml-2">{status.slicing_info.gcode_info.layer_count}</span>
                      </div>
                    </>
                  )}
                </div>
              </div>
            )}
          </div>
        </div>
      )}
    </div>
  );
}

API Reference

M3DSlicingClient

The main client class for interacting with the Mandarin3D slicing API.

Configuration

interface SlicingConfig {
  apiKey: string;                 // Your Mandarin3D API key
  baseUrl?: string;              // Optional custom API URL
  mode?: 'development' | 'production'; // Default: 'production'
  devPort?: number;              // Dev server port (default: 3001)
  onJobUpdate?: (status: JobStatus) => void; // Global status handler
}

Methods

  • submitSlicingJob(request: SlicingRequest): Promise<SlicingResponse>
  • getJobStatus(jobId: string): Promise<JobStatus>
  • onJobUpdate(jobId: string, callback: JobStatusCallback): JobStatusSubscription
  • destroy(): void

useSlicingJob Hook

A React hook for managing slicing jobs in your components.

const {
  submitJob,    // Function to submit a new job
  status,       // Current job status
  isLoading,    // Loading state
  error         // Error state
} = useSlicingJob({
  client: M3DSlicingClient,
  onComplete?: (status: JobStatus) => void,
  onError?: (error: Error) => void
});

Development Mode

The SDK includes a development mode that makes local development easier:

  1. Runs a local WebSocket server for real-time updates
  2. Handles callbacks locally without needing public URLs
  3. No polling required - uses WebSocket for instant updates

To enable development mode:

const client = new M3DSlicingClient({
  apiKey: process.env.NEXT_PUBLIC_M3D_API_KEY!,
  mode: 'development',
  devPort: 3001 // Optional
});

Types

JobStatus

interface JobStatus {
  status: 'initialized' | 'downloading' | 'processing' | 'completed' | 'failed';
  message: string;
  job_id: string;
  created_at?: string;
  updated_at: string;
  slicing_info?: {
    volume: number;
    size_x: number;
    size_y: number;
    size_z: number;
    gcode_info?: {
      filament_mm?: string;
      filament_cm3?: string;
      filament_g?: string;
      filament_cost?: string;
      layer_count?: string;
      print_time?: string;
    };
  };
}

Best Practices

  1. Always clean up resources:
useEffect(() => {
  return () => client.destroy();
}, []);
  1. Handle errors appropriately:
try {
  await submitJob(request);
} catch (error) {
  // Handle error
}
  1. Use TypeScript for better type safety and autocompletion.

  2. In development mode, ensure the port (default: 3001) is available.

License

MIT

Support

For support, please contact support@mandarin3d.com or visit our documentation.