Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@equinor/fusion-framework-module

Package Overview
Dependencies
Maintainers
4
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@equinor/fusion-framework-module - npm Package Compare versions

Comparing version 4.1.0 to 4.2.0

dist/esm/lib/index.js

85

CHANGELOG.md
# Change Log
## 4.2.0
### Minor Changes
- [#902](https://github.com/equinor/fusion-framework/pull/902) [`3efbf0bb`](https://github.com/equinor/fusion-framework/commit/3efbf0bb93fc11aa158872cd6ab98a22bcfb59e5) Thanks [@odinr](https://github.com/odinr)! - **Feat(module)** add base module class
As a module developer there should be a base provider class to extend, which handles basic wireing.
Some aspects of providers should be the same for all, like `version` handling.
These new features does not change any existing code, only tooling for future development
- [#882](https://github.com/equinor/fusion-framework/pull/882) [`76b30c1e`](https://github.com/equinor/fusion-framework/commit/76b30c1e86db3db18adbe759bb1e39885de1c898) Thanks [@odinr](https://github.com/odinr)! - Add possibility to add multilevel config for module
```ts
type MyModuleConfig = {
foo: string;
bar?: number;
nested?: { up: boolean };
};
class MyModuleConfigurator extends BaseConfigBuilder<MyModuleConfig> {
public setFoo(cb: ModuleConfigCallback<string>) {
this._set('foo', cb);
}
public setBar(cb: ModuleConfigCallback<number>) {
this._set('bar', cb);
}
public setUp(cb: ModuleConfigCallback<boolean>) {
this._set('nested.up', cb);
}
}
```
- [#902](https://github.com/equinor/fusion-framework/pull/902) [`3efbf0bb`](https://github.com/equinor/fusion-framework/commit/3efbf0bb93fc11aa158872cd6ab98a22bcfb59e5) Thanks [@odinr](https://github.com/odinr)! - **Feat(module): add semver**
In some cases other modules might require features in sibling modules
```ts
if (modules.context.version.satisfies('>=7.2')) {
// do some code
} else {
throw Error(
'this feature requires ContextModule of 7.2 or higher, please update depencies'
);
}
```
Usage:
- log telemetry about module usage and outdated application
- debug code runtime by knowing version of implementation
- write inter-opt when breaking changes accour
### Patch Changes
- [#907](https://github.com/equinor/fusion-framework/pull/907) [`7500ec2c`](https://github.com/equinor/fusion-framework/commit/7500ec2c9ca9b926a19539fc97c61c67f76fc8d9) Thanks [@odinr](https://github.com/odinr)! - export `lib` assets:
- SemanticVersion
- ModuleProvider
- [#913](https://github.com/equinor/fusion-framework/pull/913) [`83ee5abf`](https://github.com/equinor/fusion-framework/commit/83ee5abf7bcab193c85980e5ae44895cd7f6f08d) Thanks [@odinr](https://github.com/odinr)! - **Change base behavior of BaseModuleProvider**
because of weird limitations of JavaScript, private fields are not accessible until all constructors are initialized (from ancestor to current child).
This causes the `abstract` init function could not access private members when overridden.
- **removed** `init` from `BaseModuleProvider`
- _this is a breaking change, but not yet published, yet the `patch` version_
- https://github.com/equinor/fusion-framework/blob/43854d9538ade189483c43e04b52eff7e1aa3b0c/packages/modules/module/src/lib/provider/BaseModuleProvider.ts#L31
- **added** `provider` sub-scope for package
> The usage when extending `BaseModuleProvider` is not as 😘, but now works
- [#907](https://github.com/equinor/fusion-framework/pull/907) [`7500ec2c`](https://github.com/equinor/fusion-framework/commit/7500ec2c9ca9b926a19539fc97c61c67f76fc8d9) Thanks [@odinr](https://github.com/odinr)! - allow `SemanticVersion` as `version` in ctor args for `BaseModuleProvider`
- [#924](https://github.com/equinor/fusion-framework/pull/924) [`060818eb`](https://github.com/equinor/fusion-framework/commit/060818eb04ebb9ed6deaed1f0b4530201b1181cf) Thanks [@asbjornhaland](https://github.com/asbjornhaland)! - fix(module): add config builder callback args to process config method so that
- [#905](https://github.com/equinor/fusion-framework/pull/905) [`a7858a1c`](https://github.com/equinor/fusion-framework/commit/a7858a1c01542e2dc94370709f122b4b99c3219c) Thanks [@odinr](https://github.com/odinr)! - **🚧 Chore: dedupe packages**
- align all versions of typescript
- update types to build
- a couple of typecasts did not [satisfies](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#satisfies-support-in-jsdoc) and was recasted as `unknwon`, marked with `TODO`, should be fixed in future
All notable changes to this project will be documented in this file.

@@ -4,0 +89,0 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

18

dist/esm/BaseConfigBuilder.js

@@ -18,2 +18,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

import { last, mergeMap, scan } from 'rxjs/operators';
const assignConfigValue = (obj, prop, value) => {
var _a;
const props = typeof prop === 'string' ? prop.split('.') : prop;
const attr = props.shift();
if (attr) {
(_a = obj[attr]) !== null && _a !== void 0 ? _a : (obj[attr] = {});
props.length
? assignConfigValue(obj[attr], props, value)
: Object.assign(obj, { [attr]: value });
}
return obj;
};
export class BaseConfigBuilder {

@@ -35,3 +47,3 @@ constructor() {

_createConfig(init, initial) {
return this._buildConfig(init, initial).pipe(mergeMap((config) => this._processConfig(config)));
return this._buildConfig(init, initial).pipe(mergeMap((config) => this._processConfig(config, init)));
}

@@ -42,5 +54,5 @@ _buildConfig(init, initial) {

return { target, value };
})), scan((acc, { target, value }) => Object.assign({}, acc, { [target]: value }), initial !== null && initial !== void 0 ? initial : {}), last());
})), scan((acc, { target, value }) => assignConfigValue(acc, target, value), initial !== null && initial !== void 0 ? initial : {}), last());
}
_processConfig(config) {
_processConfig(config, _init) {
return of(config);

@@ -47,0 +59,0 @@ }

@@ -13,2 +13,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {

import { ModuleConsoleLogger } from './logger';
import { SemanticVersion } from './lib/semantic-version';
import { BaseModuleProvider } from './lib/provider';
class RequiredModuleTimeoutError extends Error {

@@ -147,2 +149,16 @@ constructor() {

}))).pipe(map((instance) => {
var _a;
if (!(instance instanceof BaseModuleProvider) &&
!(instance.version instanceof SemanticVersion)) {
logger.debug(`🤷 module does not extends the [BaseModuleProvider] or exposes [SemanticVersion]`);
try {
instance.version =
module.version instanceof SemanticVersion
? module.version
: new SemanticVersion((_a = module.version) !== null && _a !== void 0 ? _a : '0.0.0-unknown');
}
catch (err) {
logger.error(`🚨 failed to set module version`);
}
}
logger.debug(`🚀 initialized ${logger.formatModuleName(module)}`);

@@ -149,0 +165,0 @@ return [key, instance];

export * from './types';
export * from './lib';
export { initializeModules } from './initialize-modules';

@@ -3,0 +4,0 @@ export { ModuleConsoleLogger } from './logger';

13

dist/types/BaseConfigBuilder.d.ts
import { type Observable, type ObservableInput } from 'rxjs';
import { Modules, ModuleType } from './types';
export type ConfigBuilderCallbackArgs<TRef = unknown> = {
type ConfigPropType<T, Path extends string> = string extends Path ? unknown : Path extends keyof T ? T[Path] : Path extends `${infer K}.${infer R}` ? K extends keyof T ? ConfigPropType<T[K], R> : unknown : unknown;
type DotPrefix<T extends string> = T extends '' ? '' : `.${T}`;
type DotNestedKeys<T> = (T extends object ? {
[K in Exclude<keyof T, symbol>]: K | `${K}${DotPrefix<DotNestedKeys<T[K]>>}`;
}[Exclude<keyof T, symbol>] : '') extends infer D ? Extract<D, string> : never;
export type ConfigBuilderCallbackArgs<TConfig = unknown, TRef = unknown> = {
config: TConfig;
ref?: TRef;

@@ -15,6 +21,7 @@ requireInstance<TKey extends string = Extract<keyof Modules, string>>(module: TKey): Promise<ModuleType<Modules[TKey]>>;

createConfigAsync(init: ConfigBuilderCallbackArgs, initial?: Partial<TConfig>): Promise<TConfig>;
protected _set<TKey extends keyof TConfig>(target: TKey, cb: ConfigBuilderCallback<TConfig[TKey]>): void;
protected _set<TTarget extends DotNestedKeys<TConfig>>(target: TTarget, cb: ConfigBuilderCallback<ConfigPropType<TConfig, TTarget>>): void;
protected _createConfig(init: ConfigBuilderCallbackArgs, initial?: Partial<TConfig>): Observable<TConfig>;
protected _buildConfig(init: ConfigBuilderCallbackArgs, initial?: Partial<TConfig>): Observable<Partial<TConfig>>;
protected _processConfig(config: Partial<TConfig>): ObservableInput<TConfig>;
protected _processConfig(config: Partial<TConfig>, _init: ConfigBuilderCallbackArgs): ObservableInput<TConfig>;
}
export {};
export * from './types';
export * from './lib';
export { initializeModules } from './initialize-modules';

@@ -3,0 +4,0 @@ export { ModuleConsoleLogger } from './logger';

@@ -0,1 +1,2 @@

import SemanticVersion from './lib/semantic-version';
import { ObservableInput } from 'rxjs';

@@ -9,2 +10,3 @@ export type ModuleInitializerArgs<TConfig, TDeps extends Array<AnyModule> = []> = {

export interface Module<TKey extends string, TType, TConfig, TDeps extends Array<AnyModule> = []> {
version?: SemanticVersion;
name: TKey;

@@ -11,0 +13,0 @@ configure?: (ref?: any) => TConfig | Promise<TConfig>;

{
"name": "@equinor/fusion-framework-module",
"version": "4.1.0",
"version": "4.2.0",
"description": "",
"main": "dist/esm/index.js",
"exports": {
".": "./dist/esm/index.js"
".": "./dist/esm/index.js",
"./provider": "./dist/esm/lib/provider/index.js"
},
"types": "dist/types/index.d.ts",
"types": "index.d.ts",
"typesVersions": {
">=4.2": {
"*": [
"dist/types/*"
],
"provider": [
"dist/types/lib/provider/index"
]
}
},
"scripts": {

@@ -26,8 +37,8 @@ "build": "tsc -b",

"dependencies": {
"rxjs": "^7.5.7"
"rxjs": "^7.5.7",
"semver": "^7.5.0"
},
"devDependencies": {
"typescript": "^4.9.3"
},
"gitHead": "753d04a18764d5a16d9491ec189df90089534879"
"typescript": "^5.0.4"
}
}

@@ -5,2 +5,42 @@ import { from, lastValueFrom, of, type Observable, type ObservableInput } from 'rxjs';

type ConfigPropType<T, Path extends string> = string extends Path
? unknown
: Path extends keyof T
? T[Path]
: Path extends `${infer K}.${infer R}`
? K extends keyof T
? ConfigPropType<T[K], R>
: unknown
: unknown;
type DotPrefix<T extends string> = T extends '' ? '' : `.${T}`;
type DotNestedKeys<T> = (
T extends object
? { [K in Exclude<keyof T, symbol>]: K | `${K}${DotPrefix<DotNestedKeys<T[K]>>}` }[Exclude<
keyof T,
symbol
>]
: ''
) extends infer D
? Extract<D, string>
: never;
/** helper function for extracting multilevel attribute keys */
const assignConfigValue = <T>(
obj: Record<string, unknown>,
prop: string | string[],
value: unknown
): T => {
const props = typeof prop === 'string' ? prop.split('.') : prop;
const attr = props.shift();
if (attr) {
obj[attr] ??= {};
props.length
? assignConfigValue(obj[attr] as Record<string, unknown>, props, value)
: Object.assign(obj, { [attr]: value });
}
return obj as T;
};
/**

@@ -10,3 +50,5 @@ * callback arguments for config builder callback function

*/
export type ConfigBuilderCallbackArgs<TRef = unknown> = {
export type ConfigBuilderCallbackArgs<TConfig = unknown, TRef = unknown> = {
config: TConfig;
/** reference, parent modules */

@@ -52,8 +94,9 @@ ref?: TRef;

*
* __Limitations:__
* this only allows configuring an attribute of config root level
*
* @example
* ```ts
* type MyModuleConfig = { foo: string; bar?: number };
* type MyModuleConfig = {
* foo: string;
* bar?: number,
* nested?: { up: boolean }
* };
*

@@ -68,2 +111,6 @@ * class MyModuleConfigurator extends BaseConfigBuilder<MyModuleConfig> {

* }
*
* public setUp(cb: ModuleConfigCallback<boolean>) {
* this._set('nested.up', cb);
* }
* }

@@ -75,3 +122,3 @@ * ```

/** internal hashmap of registered callback functions */
#configCallbacks = {} as Record<keyof TConfig, ConfigBuilderCallback>;
#configCallbacks = {} as Record<string, ConfigBuilderCallback>;

@@ -103,9 +150,9 @@ /**

* internally set configuration of a config attribute
* @param target attribute name of config
* @param target attribute name of config dot notaded
* @param cb callback function for setting the attribute
* @template TKey keyof config (attribute name
* @template TKey keyof config
*/
protected _set<TKey extends keyof TConfig>(
target: TKey,
cb: ConfigBuilderCallback<TConfig[TKey]>
protected _set<TTarget extends DotNestedKeys<TConfig>>(
target: TTarget,
cb: ConfigBuilderCallback<ConfigPropType<TConfig, TTarget>>
) {

@@ -123,3 +170,3 @@ this.#configCallbacks[target] = cb;

return this._buildConfig(init, initial).pipe(
mergeMap((config) => this._processConfig(config))
mergeMap((config) => this._processConfig(config, init))
);

@@ -141,3 +188,3 @@ }

scan(
(acc, { target, value }) => Object.assign({}, acc, { [target]: value }),
(acc, { target, value }) => assignConfigValue(acc, target, value),
initial ?? ({} as TConfig)

@@ -156,5 +203,8 @@ ),

*/
protected _processConfig(config: Partial<TConfig>): ObservableInput<TConfig> {
protected _processConfig(
config: Partial<TConfig>,
_init: ConfigBuilderCallbackArgs
): ObservableInput<TConfig> {
return of(config as TConfig);
}
}

@@ -19,2 +19,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

import { SemanticVersion } from './lib/semantic-version';
import { BaseModuleProvider, type IModuleProvider } from './lib/provider';
export interface IModulesConfigurator<

@@ -258,6 +261,27 @@ TModules extends Array<AnyModule> = Array<AnyModule>,

hasModule,
})
}) as IModuleProvider
)
).pipe(
map((instance) => {
if (
!(instance instanceof BaseModuleProvider) &&
!(instance.version instanceof SemanticVersion)
) {
// TODO change to warn in future
logger.debug(
`🤷 module does not extends the [BaseModuleProvider] or exposes [SemanticVersion]`
);
try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
instance.version =
module.version instanceof SemanticVersion
? module.version
: new SemanticVersion(
module.version ?? '0.0.0-unknown'
);
} catch (err) {
logger.error(`🚨 failed to set module version`);
}
}
logger.debug(`🚀 initialized ${logger.formatModuleName(module)}`);

@@ -264,0 +288,0 @@ return [key, instance];

export * from './types';
export * from './lib';
export { initializeModules } from './initialize-modules';

@@ -3,0 +4,0 @@

/* eslint-disable @typescript-eslint/no-explicit-any */
import SemanticVersion from './lib/semantic-version';
import { ObservableInput } from 'rxjs';

@@ -16,9 +17,70 @@

/**
* Interface which describes the structure of a module
*
* @TODO create a BaseModule which implements this interface
*
* @template TKey name of the module
* @template TType module instance type
* @template TConfig module configurator type
* @template TDeps optional peer module dependencies
*/
export interface Module<TKey extends string, TType, TConfig, TDeps extends Array<AnyModule> = []> {
/**
* package version
*/
version?: SemanticVersion;
/**
* uniq name of module, used as attribute name on module instances
*/
name: TKey;
/**
* _[optional]_
*
* Create a configurator builder which the consumer can use for configuring
*
* @TODO change return type to `ObservableInput`
* @TODO add reference to `IConfigurationBuilder`
*
* @param ref this would normally be the parent instance
* @returns a configurator build
*/
configure?: (ref?: any) => TConfig | Promise<TConfig>;
/**
* _[optional]_
*
* This method is called after the module initiator has created config.
* @see {@link Module.configure}
*
* @TODO change return type to `ObservableInput`
*
* @param config
* @returns void
*/
postConfigure?: (
config: Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>>
) => void | Promise<void>;
/**
* __[required]__
*
* Called after all configuration is done.
*
* Creates the instance to interact with
*
* @param args @see {@link ModuleInitializerArgs}
* @returns a provider instance which the consumer interact with
*/
initialize: (args: ModuleInitializerArgs<TConfig, TDeps>) => TType | Promise<TType>;
/**
* _[optional]_
*
* Called after the module is initialized
*
* @param args @see {@link ModuleInitializerArgs}
*/
postInitialize?: (args: {

@@ -29,2 +91,10 @@ ref?: any;

}) => ObservableInput<void>;
/**
* _[optional]_
*
* Cleanup callback
*
* @param args
*/
dispose?: (args: {

@@ -31,0 +101,0 @@ ref?: any;

@@ -7,3 +7,8 @@ {

"declarationDir": "./dist/types",
"baseUrl": "src"
"baseUrl": "src",
"paths": {
"@equinor/fusion-framework-module/provider": [
"lib/provider"
]
}
},

@@ -10,0 +15,0 @@ "include": [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc