跳到主要内容

Adaptor Registry

What is the AdaptorRegistry?

The AdaptorRegistry is a manager that keeps track of all your SDK adaptors. It tells CDF which adaptor to use when your app starts and can switch between adaptors at runtime.

Simple job: Register adaptors → pick one to be active → CDF uses it

You need it when:

  • Starting your app (register adaptors before initCDF)
  • Supporting multiple SDKs at the same time
  • Building a custom adaptor for a backend that CDF doesn't support yet

API at a glance

MethodPurpose
getInstance()Get the singleton registry
register(adaptor)Add an adaptor (identified by _identifier)
setActiveAdaptor(identifier)Choose which adaptor to use
getActiveAdaptor()Get the active adaptor instance
getAdaptor(identifier)Get a specific adaptor without switching
getActiveAdaptorIdentifier()Get the active adaptor's ID
getRegisteredAdaptorIdentifiers()List all registered IDs
unregister(identifier)Remove an adaptor
clear()Remove all adaptors and reset

Basic Setup

Minimal: Register RainMaker Base SDK

import { AdaptorRegistry, initCDF } from "@espressif/rainmaker-base-cdf";
import { ESPRMBaseSDKAdaptor, ESPRMBaseAdaptorIdentifier } from "@sdk-adaptors/ESPRMBase";

const registry = AdaptorRegistry.getInstance();

// Register RainMaker Base SDK adaptor
registry.register(
new ESPRMBaseSDKAdaptor({
baseUrl: "https://api.rainmaker.espressif.com",
region: "us-east-1",
// Add other SDK config as needed
})
);

// Set as active
registry.setActiveAdaptor(ESPRMBaseAdaptorIdentifier);

// Initialize CDF
const cdf = await initCDF({ sdkAdaptorRegistry: registry });

Production: Multiple adaptors with a factory

For real apps supporting multiple SDKs, use a factory and bootstrap service. See the RainMaker Home app for the complete pattern:

import { AdaptorRegistry, initCDF } from "@espressif/rainmaker-base-cdf";
import { ESPRMBaseSDKAdaptor, ESPRMBaseAdaptorIdentifier } from "@sdk-adaptors/ESPRMBase";
import { ESPRMMatterBaseSDKAdaptor, ESPRMMatterBaseAdaptorIdentifier } from "@sdk-adaptors/ESPRMMatterBase";
import { getResolvedActiveSdk, getRMSDKConfig, getMatterSDKConfig } from "@config/sdk.config";

/**
* Factory that instantiates all adaptors.
* Add new adaptors here as integrations are added.
*/
class AdaptorFactory {
createAll() {
return [
new ESPRMBaseSDKAdaptor(getRMSDKConfig()),
new ESPRMMatterBaseSDKAdaptor(getMatterSDKConfig()),
];
}
}

/**
* Bootstrap service — handles registry setup and CDF initialization.
* Singleton so you initialize once and reuse throughout the app.
*/
class CDFBootstrap {
private static instance: CDFBootstrap;
private cdfInstance = null;
private sdkRegistry = AdaptorRegistry.getInstance();

static getInstance(factory = new AdaptorFactory()) {
if (!CDFBootstrap.instance) {
CDFBootstrap.instance = new CDFBootstrap(factory);
}
return CDFBootstrap.instance;
}

async initialize() {
const adaptors = this.adaptorFactory.createAll();

// Register all adaptors
adaptors.forEach(adaptor => {
this.sdkRegistry.register(adaptor);
});

// Set the active one
this.sdkRegistry.setActiveAdaptor(getResolvedActiveSdk());

// Initialize CDF
this.cdfInstance = await initCDF({ sdkAdaptorRegistry: this.sdkRegistry });
return this.cdfInstance;
}
}

// In your app entry point, call once:
export async function initializeApp() {
const cdf = await CDFBootstrap.getInstance().initialize();
// Now use cdf throughout your app
}

Switch adaptors at runtime

const registry = AdaptorRegistry.getInstance();
registry.setActiveAdaptor("matter-sdk"); // Switches immediately
// Your UI sees the new adaptor's data next

How the Registry Works

First, understand the architecture. Here's how adaptors and the registry fit together:

Proxy error surfacing

When a registered adaptor does not implement a method, the registry proxy throws a structured ESPCDFRegistryError with code ADAPTOR_METHOD_PROPERTY_NOT_IMPLEMENTED — failing early rather than silently returning undefined. This surfaces missing implementations during development instead of at runtime.


Build Your Own Adaptor

An adaptor implements ESPSDKAdaptor. Key rules:

  1. Every method returns { status, data, error } — Never raw SDK objects
  2. Use transformers — Convert SDK entities to CDF entities with operations
  3. _identifier must be unique — Used in setActiveAdaptor()

Pattern:

import { ESPSDKAdaptor } from "@espressif/rainmaker-base-cdf";
import MySDK from "my-custom-sdk";
import { transformToMyCDFUser } from "./transformers";

export class MySDKAdaptor implements ESPSDKAdaptor {
_identifier = "my-custom-sdk";

constructor(config: any) {
MySDK.init(config);
}

async login(input: any) {
const sdkUser = await MySDK.auth.login(input.request.username, input.request.password);
return { status: "success", data: transformToMyCDFUser(sdkUser) };
}

async getCurrentLoggedInUser() {
const sdkUser = await MySDK.auth.getCurrentUser();
return { status: "success", data: transformToMyCDFUser(sdkUser) };
}

// Implement all other required methods (see TypeDoc)
}

Refer to the RainMaker Base Adaptor for a complete implementation.


Create a Transformer

A transformer converts SDK data to CDF entities and wires up operations:

import { ESPCDFUser } from "@espressif/rainmaker-base-cdf";

export function transformToMyCDFUser(sdkUser: any) {
return new ESPCDFUser({
userInfo: {
id: sdkUser.userId,
name: sdkUser.fullName,
email: sdkUser.email,
},
operations: {
async getUserInfo() {
return { status: "success", data: await sdkUser.getProfile() };
},
async logout() {
await sdkUser.logout();
},
},
_raw: sdkUser, // Keep original SDK object
identifier: "my-custom-sdk",
});
}

Three steps:

  1. Map SDK fields to CDF fields
  2. Wire operations that call the SDK
  3. Store the original SDK object in _raw

For every interface method and transformer detail, refer to the TypeScript API (TypeDoc).


On this page