Core Concepts

Understanding the fundamental building blocks of the Platform SDK is crucial for effective development. This section details the core concepts that underpin the SDK's architecture and functionality.

Modules

Modules are the primary organizational units within the Platform SDK. They encapsulate related functionalities and resources, providing a clear separation of concerns. Each module exposes a well-defined API for interaction.

Key characteristics of modules:

For example, the Networking module handles all network-related operations, while the Storage module manages data persistence.


// Example of loading a module
import { Networking } from '@platform/sdk/networking';

const networkManager = new Networking();
networkManager.fetch('https://api.example.com/data')
    .then(response => console.log('Data received:', response))
    .catch(error => console.error('Network error:', error));
            

Components

Components are reusable, self-contained units of functionality that can be assembled to build applications. They often represent UI elements, business logic, or data services.

Components interact with each other through well-defined inputs (props) and outputs (events).

Component Lifecycle

Components typically follow a lifecycle with distinct phases:


// Example of a simple component definition
class Button {
    constructor(label, onClick) {
        this.label = label;
        this.onClick = onClick;
    }

    render() {
        const buttonElement = document.createElement('button');
        buttonElement.textContent = this.label;
        buttonElement.addEventListener('click', this.onClick);
        return buttonElement;
    }
}

const myButton = new Button('Click Me', () => alert('Button clicked!'));
document.body.appendChild(myButton.render());
            

Interfaces

Interfaces define contracts that classes must adhere to. They specify the methods, properties, and events that a particular type of object should expose, without providing the implementation details.

Interfaces are crucial for ensuring type safety and promoting loose coupling between different parts of the SDK.

Example Interface

Consider an interface for a data source:


interface DataSource {
    getData(id: string): Promise<any>;
    saveData(data: any): Promise<void>;
    subscribe(callback: (data: any) => void): UnsubscribeFunction;
}

type UnsubscribeFunction = () => void;
            

Any class implementing the DataSource interface must provide implementations for getData, saveData, and subscribe.

Events

Events are a mechanism for components and modules to signal that something has happened. Other parts of the system can listen for these events and react accordingly, enabling asynchronous communication and loose coupling.

The SDK utilizes an event-driven architecture, allowing for flexible and scalable solutions.

Event Types


// Example of event emission and handling
class EventEmitter {
    constructor() {
        this.listeners = {};
    }

    on(event, callback) {
        if (!this.listeners[event]) {
            this.listeners[event] = [];
        }
        this.listeners[event].push(callback);
    }

    emit(event, ...args) {
        if (this.listeners[event]) {
            this.listeners[event].forEach(callback => callback(...args));
        }
    }
}

const emitter = new EventEmitter();

emitter.on('message', (text) => {
    console.log('Received message:', text);
});

emitter.emit('message', 'Hello, SDK!');
            

Context

Context provides a way to pass data through the component tree without having to pass props down manually at every level. It's particularly useful for global data such as themes, user authentication, or configuration settings.

The SDK provides mechanisms for creating and consuming context.

Note: Context is intended for sharing data that can be considered global for a tree of React components, such as the authenticated user, theme, or preferred language. Avoid using context for any prop that can be passed down normally.

Using Context

A typical pattern involves a Provider component that wraps a part of the component tree and makes the context value available to any descendant component that consumes it.


// Simplified conceptual example (actual implementation may vary)

// 1. Define context
const ThemeContext = createContext({ theme: 'light' });

// 2. Provider component
function AppThemeProvider({ children }) {
    const [theme, setTheme] = useState('light');
    
    const toggleTheme = () => setTheme(prevTheme => (prevTheme === 'light' ? 'dark' : 'light'));

    return (
        <ThemeContext.Provider value={{ theme, toggleTheme }}>
            {children}
        </ThemeContext.Provider>
    );
}

// 3. Consumer component
function ThemedComponent() {
    const { theme, toggleTheme } = useContext(ThemeContext);

    return (
        <div style={{ backgroundColor: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#333' : '#fff' }}>
            <p>Current theme: {theme}</p>
            <button onClick={toggleTheme}>Toggle Theme</button>
        </div>
    );
}

// Usage:
// <AppThemeProvider>
//     <ThemedComponent />
// </AppThemeProvider>