Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(base config builder): allow async overrides #2177

Merged
merged 4 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .changeset/allow-async-config-builder-overrides.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"@equinor/modules": patch
---

## @equinor/modules

### Changes to `BaseConfigBuilder`

The `_createConfig` method in `BaseConfigBuilder` has been updated to return an `ObservableInput<TConfig>` instead of an `Observable<TConfig>`.
This allows for more flexibility in how the config is created, as the method can now return a Promise or other observable-like type.

Additionally, the `_createConfig` method now uses `from()` to convert the result of `_buildConfig` to an observable stream.

Here's an example of how the updated `_createConfig` method can be used:

```typescript
protected _createConfig(
init: ConfigBuilderCallbackArgs,
initial?: Partial<TConfig>
): ObservableInput<TConfig> {
return from(this._buildConfig(init, initial)).pipe(
mergeMap((config) => this._processConfig(config, init))
);
}
```

This change allows for asynchronous operations to be performed within the `_buildConfig` method, which can then be processed in the `_processConfig` method.

Consumers of the `BaseConfigBuilder` class should not need to update their code, as the public API remains the same.
20 changes: 20 additions & 0 deletions .changeset/improve-docs-baseconfig-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@equinor/fusion-framework": patch
---

## @equinor/fusion-framework

### Improved documentation for `BaseConfigBuilder`

The `BaseConfigBuilder` class has been updated with improved documentation to better explain its usage and capabilities.

#### What changed?

The `BaseConfigBuilder` class is an abstract class that provides a flexible and extensible way to build and configure modules. It allows you to define configuration callbacks for different parts of your module's configuration, and then combine and process these callbacks to generate the final configuration object.

The documentation has been expanded to include:

1. A detailed explanation of how the `BaseConfigBuilder` class is designed to be used, including an example of creating a configuration builder for a hypothetical `MyModule` module.
2. Descriptions of the key methods and properties provided by the `BaseConfigBuilder` class, such as `createConfig`, `createConfigAsync`, `_set`, `_buildConfig`, and `_processConfig`.
3. Guidance on how to override the `_processConfig` method to add additional logic or validation to the configuration object before it is returned.
4. Examples of how to use the `BaseConfigBuilder` class to handle common configuration scenarios, such as setting default values or validating configuration properties.
50 changes: 50 additions & 0 deletions .changeset/improve-extendability-config-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
"@equinor/modules": patch
---

## @equinor/modules

### Changes to `BaseConfigBuilder`

The `BaseConfigBuilder` class has been updated to improve its extendability and provide better access to the internal configuration callbacks.

#### Added `_get` and `_has` methods

Two new protected methods have been added to the `BaseConfigBuilder` class:

1. `_get<TTarget extends DotPath<TConfig>>(target: TTarget)`: This method retrieves the configuration callback for the specified target path in the configuration. It returns the callback or `undefined` if no callback is registered for the given target.

2. `_has<TTarget extends DotPath<TConfig>>(target: TTarget)`: This method checks if the given target path exists in the configuration callbacks. It returns `true` if the target path exists, `false` otherwise.

These methods allow subclasses of `BaseConfigBuilder` to easily access and check the existence of configuration callbacks for specific targets.

#### Example usage

Suppose you have a subclass of `BaseConfigBuilder` called `MyConfigBuilder`. You can use the new `_get` and `_has` methods like this:

```typescript
class MyConfigBuilder extends BaseConfigBuilder<MyConfig> {
// override the _buildConfig method
async _createConfig(
init: ConfigBuilderCallbackArgs,
initial?: Partial<TConfig>,
): ObservableInput<TConfig> {
// Check if a callback is registered for the'my.custom.config' target
if (this._has('my.custom.config')) {
// register a fallback value for the'my.custom.config' target if no callback is registered
this._set('my.custom.config', async() => { return 42; });
} else {
// if a callback is registered, call it and log the result
configCallback = this._get('my.custom.config');
configValue$ = from(configCallback(init, initial));
console.log(await lastValueFrom(configValue$));
}
return lastValueFrom(from(super._createConfig(init, initial)));
}
}
```

> [!WARNING]
> the example code is not intended to be a working implementation of the `MyConfigBuilder` class. It is only intended to demonstrate how the new `_get` and `_has` methods can be used.

This change allows for more flexibility and easier extensibility of the `BaseConfigBuilder` class.
Loading
Loading