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
3
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 0.1.1 to 0.2.0

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# 0.2.0 (2022-06-10)
### Features
* **module:** allow modules to have deps ([#128](https://github.com/equinor/fusion-framework/issues/128)) ([2466b1a](https://github.com/equinor/fusion-framework/commit/2466b1ad9d43aa472da9daf8c59b350844c0dae9))
## 0.1.1 (2022-02-09)

@@ -8,0 +19,0 @@

68

dist/esm/initialize-modules.js

@@ -0,7 +1,62 @@

import { BehaviorSubject, delayWhen, filter, from, lastValueFrom, map, mergeMap, of } from 'rxjs';
class ConsoleLogger {
domain;
constructor(domain) {
this.domain = domain;
}
_createMessage(msg) {
return [
`%c FUSION FRAMEWORK %c ${this.domain} %c %s`,
'background: rgb(179, 13, 47); color: white; padding: 1px;',
'background: rgb(244, 244, 244); color: rgb(36, 55, 70); padding: 1px;',
'background: none; color: inherit',
...msg.reduce((c, n) => [...c, n, '\n'], []),
];
}
debug(...msg) {
process.env.NODE_ENV === 'development' && console.debug(...this._createMessage(msg));
}
info(...msg) {
console.info(...this._createMessage(msg));
}
warn(...msg) {
console.warn(...this._createMessage(msg));
}
error(...msg) {
console.error(...this._createMessage(msg));
}
}
const logModuleName = (module) => `\u001b[1;32m${module.name.replace(/([A-Z])/g, ' $1').toUpperCase()}\x1b[0m`;
const logger = new ConsoleLogger('MODULES');
const _initializeModules = async (modules, config) => {
const instance$ = new BehaviorSubject({});
from(modules)
.pipe(delayWhen((module) => {
const hasDeps = !!module.deps;
if (hasDeps) {
logger.debug(`module ${logModuleName(module)} requires dependencies`, module.deps);
return instance$.pipe(filter((instance) => !!module.deps?.every((dep) => Object.keys(instance).includes(String(dep)))));
}
return of(0);
}), mergeMap((module) => from(Promise.resolve(module.initialize(config, instance$.value))).pipe(map((instance) => {
logger.debug(`initialized ${logModuleName(module)}`);
return [module.name, instance];
}))))
.subscribe({
next: ([name, module]) => {
instance$.next(Object.assign(instance$.value, { [name]: module }));
},
complete: () => instance$.complete(),
});
return lastValueFrom(instance$);
};
export const initializeModules = async (configure, modules, ref) => {
const afterConfiguration = [];
const afterInit = [];
logger.debug(`🛠 initializing ${!ref ? 'modules' : 'sub-modules'} ${modules.map(logModuleName)}`, modules, ref);
const config = await Object.values(modules).reduce(async (acc, module) => {
logger.debug(`configuring ${logModuleName(module)}`);
const obj = await acc;
const res = await Promise.resolve(module.configure?.(ref));
logger.debug(`configured ${logModuleName(module)}`);
return Object.assign(obj, { [module.name]: res });

@@ -17,11 +72,12 @@ }, Promise.resolve({

Object.seal(config);
logger.debug(`✅ Configured ${modules.map(logModuleName)}`, config);
configure && (await configure(config, ref));
await Promise.all([...modules.map((x) => x.postConfigure), ...afterConfiguration].map((x) => Promise.resolve(x?.(config))));
const instance = await modules.reduce(async (acc, module) => {
const obj = await acc;
const res = await Promise.resolve(module.initialize(config, obj));
return Object.assign(obj, { [module.name]: res });
}, Promise.resolve({}));
const instance = await _initializeModules(modules, config);
logger.debug('✅ initialized');
Object.seal(ref);
await Promise.all([...modules.map((x) => x.postInitialize), ...afterInit].map((x) => Promise.resolve(x?.(instance))));
const postInitialize = [...modules.map((x) => x.postInitialize), ...afterInit];
await Promise.all(postInitialize.map((x) => Promise.resolve(x?.(instance))));
logger.debug('✅ post initialized');
logger.info(`🚀 ${!ref ? 'modules' : 'sub-modules'} ready`, process.env.NODE_ENV === 'development' && instance);
return instance;

@@ -28,0 +84,0 @@ };

export interface Module<TKey extends string, TType, TConfig, TDeps extends Array<AnyModule> = []> {
name: TKey;
configure?: (ref?: any) => TConfig | Promise<TConfig>;
deps?: Array<keyof ModulesInstanceType<ModulesType<TDeps>>>;
postConfigure?: (config: Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>>) => void | Promise<void>;

@@ -5,0 +6,0 @@ initialize: (config: Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>>, instance: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>) => TType;

7

package.json
{
"name": "@equinor/fusion-framework-module",
"version": "0.1.1",
"version": "0.2.0",
"description": "",

@@ -31,3 +31,6 @@ "main": "./dist/esm/index.js",

},
"gitHead": "ca79b01fcc32c2c4e4aeea2f7c251fe9d91a2d04"
"dependencies": {
"rxjs": "^7.5.5"
},
"gitHead": "7b2e61bf8bffa9307238b32397b1ce3c5fc5380d"
}
/* eslint-disable @typescript-eslint/no-explicit-any */
import { BehaviorSubject, delayWhen, filter, from, lastValueFrom, map, mergeMap, of } from 'rxjs';
import type {

@@ -10,2 +12,86 @@ AnyModule,

// TODO - move to own lib ;)
class ConsoleLogger {
constructor(protected domain: string) {}
/** @inheritdoc */
protected _createMessage(msg: unknown[]): unknown[] {
return [
`%c FUSION FRAMEWORK %c ${this.domain} %c %s`,
'background: rgb(179, 13, 47); color: white; padding: 1px;',
'background: rgb(244, 244, 244); color: rgb(36, 55, 70); padding: 1px;',
'background: none; color: inherit',
...msg.reduce((c: unknown[], n: unknown) => [...c, n, '\n'], []),
];
}
debug(...msg: unknown[]) {
process.env.NODE_ENV === 'development' && console.debug(...this._createMessage(msg));
}
info(...msg: unknown[]) {
console.info(...this._createMessage(msg));
}
warn(...msg: unknown[]) {
console.warn(...this._createMessage(msg));
}
error(...msg: unknown[]) {
console.error(...this._createMessage(msg));
}
}
const logModuleName = (module: AnyModule) =>
`\u001b[1;32m${module.name.replace(/([A-Z])/g, ' $1').toUpperCase()}\x1b[0m`;
const logger = new ConsoleLogger('MODULES');
// TODO - create a class for initializing
const _initializeModules = async <TModules extends Array<AnyModule>>(
modules: TModules,
config: ModulesConfigType<TModules>
) => {
const instance$ = new BehaviorSubject<ModulesInstanceType<TModules>>(
{} as ModulesInstanceType<TModules>
);
from(modules)
.pipe(
delayWhen((module) => {
const hasDeps = !!module.deps;
if (hasDeps) {
logger.debug(
`module ${logModuleName(module)} requires dependencies`,
module.deps
);
return instance$.pipe(
filter(
(instance) =>
/** check that all dependencies are created */
!!module.deps?.every((dep) =>
Object.keys(instance).includes(String(dep))
)
)
);
}
return of(0);
}),
mergeMap((module) =>
/** assign module to modules object */
from(Promise.resolve(module.initialize(config, instance$.value))).pipe(
map((instance) => {
logger.debug(`initialized ${logModuleName(module)}`);
return [module.name, instance];
})
)
)
)
.subscribe({
next: ([name, module]) => {
instance$.next(Object.assign(instance$.value, { [name]: module }));
},
complete: () => instance$.complete(),
});
return lastValueFrom(instance$);
};
/**

@@ -26,7 +112,15 @@ * Create an instances of provided instances

logger.debug(
`🛠 initializing ${!ref ? 'modules' : 'sub-modules'} ${modules.map(logModuleName)}`,
modules,
ref
);
/** initialize config providers for all modules */
const config: ModulesConfig<TModules> = await Object.values(modules).reduce(
async (acc, module) => {
logger.debug(`configuring ${logModuleName(module)}`);
const obj = await acc;
const res = await Promise.resolve(module.configure?.(ref));
logger.debug(`configured ${logModuleName(module)}`);
return Object.assign(obj, { [module.name]: res });

@@ -47,2 +141,4 @@ },

logger.debug(`✅ Configured ${modules.map(logModuleName)}`, config);
/** allow callback to configure */

@@ -58,10 +154,4 @@ configure && (await configure(config as any, ref));

/** call module initializers */
const instance = await modules.reduce(async (acc, module) => {
const obj = await acc;
const res = await Promise.resolve(
module.initialize(config as unknown as ModulesConfigType<TModules>, obj)
);
return Object.assign(obj, { [module.name]: res });
}, Promise.resolve({} as ModulesInstanceType<TModules>));
const instance = await _initializeModules(modules, config);
logger.debug('✅ initialized');

@@ -72,6 +162,9 @@ /** Protected instances */

/** call all added post config hooks */
await Promise.all(
[...modules.map((x) => x.postInitialize), ...afterInit].map((x) =>
Promise.resolve(x?.(instance))
)
const postInitialize = [...modules.map((x) => x.postInitialize), ...afterInit];
await Promise.all(postInitialize.map((x) => Promise.resolve(x?.(instance))));
logger.debug('✅ post initialized');
logger.info(
`🚀 ${!ref ? 'modules' : 'sub-modules'} ready`,
process.env.NODE_ENV === 'development' && instance
);

@@ -78,0 +171,0 @@

@@ -6,2 +6,3 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

configure?: (ref?: any) => TConfig | Promise<TConfig>;
deps?: Array<keyof ModulesInstanceType<ModulesType<TDeps>>>;
postConfigure?: (

@@ -8,0 +9,0 @@ config: Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>>

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