Component & State Utilities
A Blocklet State is a tree-like JSON structure that represents a running application and all its nested components. These helper functions simplify common tasks such as traversing the component tree, finding specific components, checking their operational status, and extracting configuration or metadata.
Tree Traversal#
These functions allow you to iterate over the component tree of a blocklet application. You can perform actions on each component, either synchronously or asynchronously.
forEachBlocklet#
Recursively traverses a blocklet and all its descendants. This is the primary function for iterating through a complete component tree. It can operate in three modes: serial (default), parallel, or synchronous.
Parameters
Name | Type | Description |
---|---|---|
|
| The root blocklet or component to start traversal from. |
|
| The callback function to execute for each component. It receives the component and an options object containing |
|
| An options object to configure the traversal. |
|
| If |
|
| The concurrency limit when |
|
| If |
Example
// Assuming 'myApp' is a BlockletState object
const componentNames = [];
forEachBlockletSync(myApp, (component, { level }) => {
const prefix = ' '.repeat(level);
componentNames.push(`${prefix}- ${component.meta.name}`);
});
console.log(componentNames.join('\n'));
This example synchronously traverses the myApp
tree and creates a hierarchical list of component names.
forEachChild#
A convenience wrapper around forEachBlocklet
that executes the callback for all descendants of a blocklet but skips the root blocklet itself (i.e., starts from level > 0
).
forEachComponentV2#
Iterates over the direct children of a blocklet application. This function does not traverse recursively into grandchildren.
Parameters
Name | Type | Description |
---|---|---|
|
| The root application state. |
|
| The callback function to execute for each direct child component. |
|
| Options object, supporting |
Component Discovery#
These functions help you locate one or more components within a blocklet's state tree based on specific criteria.
findComponent#
Recursively searches the component tree and returns the first component that satisfies the provided predicate function.
Parameters
Name | Type | Description |
---|---|---|
|
| The root component to start the search from. |
|
| A function that returns |
Example
// Find a component by its name
const targetComponent = findComponent(myApp, (component) => {
return component.meta.name === 'my-target-component';
});
if (targetComponent) {
console.log('Found component:', targetComponent.meta.did);
}
findComponentById#
Finds a component by its full component ID, which is a path-like string constructed from the DIDs of its ancestors.
Example
// The ID is constructed as 'root_did/child_did'
const componentId = 'z2q..../z8m....';
const result = findComponentById(myApp, componentId, { returnAncestors: true });
if (result) {
console.log('Component DID:', result.component.meta.did);
console.log('Number of ancestors:', result.ancestors.length);
}
findComponentV2 / findComponentByIdV2 / filterComponentsV2#
These are non-recursive versions that operate only on the direct children of a blocklet app, similar to forEachComponentV2
. filterComponentsV2
returns an array of all matching children instead of just the first one.
Information Extraction#
These utilities extract specific pieces of data from a blocklet state object, such as names, URLs, configurations, or structured information about components.
Function | Description |
---|---|
| Generates a unique, path-like ID for a component based on the DIDs of itself and its ancestors. |
| Generates a unique, path-like name for a component based on the names of itself and its ancestors. |
| Returns the bundle identifier in |
| Extracts the parent's component name from a child's full component name. |
| Gets the display name of the app, prioritizing the |
| Gets the description of the app, prioritizing |
| Determines the primary, most accessible URL for the application from its |
| Calculates the shared configuration object available to a component, inherited from the app and sibling components. |
| Scans all components in an app and returns a list of required configurations that are missing. |
| Checks a single component for missing required configurations. |
| Returns a list of all services defined across all components within the blocklet. |
| Gathers and returns an array of essential information for each component, such as title, DID, version, mount point, and port. |
| Returns a structured tree of components that have a mount point. |
| Extracts chain information (type, id, host) from a blocklet's configuration. |
| Generates a unique ID for a component process, using an MD5 hash for very long names to ensure compatibility. |
Example: Checking for Missing Configurations
const missing = getAppMissingConfigs(myApp);
if (missing.length > 0) {
console.warn('The application is missing required configurations:');
missing.forEach(config => {
console.warn(`- Component DID: ${config.did}, Key: ${config.key}, Description: ${config.description}`);
});
}
Status & State Checks#
These boolean functions provide a simple way to check the current status or characteristics of a blocklet or component.
Function | Description |
---|---|
| Returns |
| Returns |
| Returns |
| Returns |
| Checks if the |
| Checks if the blocklet contains any components other than a gateway. |
| Returns |
| Checks the payment metadata to determine if the blocklet is free. |
| Checks if a component's metadata defines a specific resource bundle. |
Example: Guarding an Operation
function restartApp(app) {
if (isRunning(app.status)) {
console.log('Stopping and restarting the app...');
// ... restart logic
} else if (isInProgress(app.status)) {
console.log('Cannot restart, an operation is already in progress.');
} else {
console.log('Starting the app...');
// ... start logic
}
}
Data Manipulation#
wipeSensitiveData#
This function is critical for security. It takes a blocklet state object and returns a deep clone with all sensitive data removed or obfuscated. This is useful before logging the state or sending it over a network.
Sensitive data includes:
- Secure configuration values (replaced with
__encrypted__
) - Specific environment variables like
BLOCKLET_APP_SK
,BLOCKLET_APP_PSK
- Application secrets from
migratedFrom
history - Session salt from settings
- User-specific preferences (keys starting with
_blocklet_preference_
)
Example
// 'fullState' contains secrets
const safeState = wipeSensitiveData(fullState);
// Now it's safe to log or serialize safeState.
console.log(JSON.stringify(safeState, null, 2));
This function is essential for maintaining security when handling blocklet state data in logs or external communications.