@espressif/rainmaker-base-cdf is CDF for RainMaker apps. It provides one app-facing contract across adaptor implementations: unified entities, adaptor registration, event-driven operations, and MobX-backed stores coordinated by synchronizers.
CDF lets apps integrate multiple adaptors through a single, consistent model:
ESPCDFNode, ESPCDFGroup, ESPCDFUser, …) in src/entities — the app contract; apps work with CDF types, not raw adaptor-specific types.src/registry.ts (AdaptorRegistry, capabilities, active adaptor).src/utils/OperationEventEmitter.ts; entities do not own long-lived store coupling.src/store/sync applies all observable state updates and cross-store work after operations (user, group, node, scene, schedule, automation).userStore, groupStore, nodeStore, sceneStore, scheduleStore, automationStore, subscriptionStore)._raw and property-change sync — adaptors keep the underlying source entity in sync with CDF property changes where needed.Together, this yields one API to learn, predictable state transitions, and type-safe TypeScript across implementations.
| Piece | Role |
|---|---|
| Adaptors | Implement ESPSDKAdaptorCore (and feature interfaces); transform source entities into CDF entities and supply operations delegates. |
| CDF entities | Thin wrappers: call operations, emit success/failure on OperationEventEmitter; synchronizers apply property updates via stores — entities do not self-mutate app-visible state in the unified pattern. |
| Stores | Hold observable maps/lists; expose @action update helpers for synchronizers; typically exclude _raw and operations from deep MobX tracking where appropriate. |
| Synchronizers | Subscribe to entity events, map operation payloads to store updates, coordinate multi-store effects, manage attach/detach lifecycle. |
Typical operation path through CDF:
group.getNodes(), automation.update(...)).operations (underlying implementation call).@action / observable updates).npm install @espressif/rainmaker-base-cdf
yarn add @espressif/rainmaker-base-cdf
pnpm add @espressif/rainmaker-base-cdf
import { AdaptorRegistry, initCDF } from "@espressif/rainmaker-base-cdf";
// import { ESPRMBaseSDKAdaptor } from "<your-adaptor-package>";
const sdkAdaptorRegistry = AdaptorRegistry.getInstance();
sdkAdaptorRegistry.clear();
// Register one or more adaptors that implement ESPSDKAdaptor
// const esprmAdaptor = new ESPRMBaseSDKAdaptor({ ...config });
// sdkAdaptorRegistry.register(esprmAdaptor);
// sdkAdaptorRegistry.setActiveAdaptor(esprmAdaptor._identifier);
const cdf = await initCDF({ sdkAdaptorRegistry });
await cdf.userStore.auth.login({
username: "user@example.com",
password: "password",
});
const user = cdf.userStore.user;
For multi-adaptor flows, you can resolve the authorization entity per adaptor. After login, userStore.user is often the right handle:
if (!user) throw new Error("No active user");
await user.getGroups();
const groups = cdf.groupStore.groupsList;
const group = groups[0];
if (group) {
await group.getNodes();
}
const nodes = cdf.nodeStore.nodesList;
const automation = cdf.automationStore.getAutomationById("automation-id");
if (automation) {
await automation.update({ name: "New Automation Name", enabled: true });
}
CDF separates concerns so app code stays adaptor-agnostic:
This project is licensed under the Apache 2.0 license - see the LICENSE file for details.