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.3.0 to 0.4.0

14

CHANGELOG.md

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

# 0.4.0 (2022-08-11)
* feat!: allow modules to displose ([32b69fb](https://github.com/equinor/fusion-framework/commit/32b69fb7cc61e78e503e67d0e77f21fb44b600b9))
### BREAKING CHANGES
* module.initialize now has object as arg
# [0.3.0](https://github.com/equinor/fusion-framework/compare/@equinor/fusion-framework-module@0.2.8...@equinor/fusion-framework-module@0.3.0) (2022-08-04)

@@ -8,0 +22,0 @@

51

dist/esm/initialize-modules.js

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

import { BehaviorSubject, filter, firstValueFrom, from, lastValueFrom, map, mergeMap, throwError, timeout, } from 'rxjs';
import { BehaviorSubject, filter, firstValueFrom, from, lastValueFrom, map, mergeMap, scan, throwError, timeout, } from 'rxjs';
class ConsoleLogger {

@@ -38,14 +38,11 @@ domain;

export const initializeModules = async (configure, modules, ref) => {
const moduleNames = modules.map((m) => m.name);
const instance$ = new BehaviorSubject({});
const moduleNames = modules.map((m) => m.name);
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 });
}, Promise.resolve({
const config = await lastValueFrom(from(modules).pipe(mergeMap(async (module) => {
const configurator = await module.configure?.(ref);
return { [module.name]: configurator };
}), scan((acc, module) => Object.assign(acc, module), {
onAfterConfiguration(cb) {

@@ -57,4 +54,8 @@ afterConfiguration.push(cb);

},
}));
config.requireInstance = (name, wait = 60) => {
})));
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 requireInstance = (name, wait = 60) => {
if (!moduleNames.includes(name)) {

@@ -73,11 +74,10 @@ throw Error(`cannot not require [${String(name)}] since module is not defined!`);

};
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))));
from(modules)
.pipe(mergeMap((module) => from(Promise.resolve(module.initialize(config, instance$.value))).pipe(map((instance) => {
logger.debug(`initialized ${logModuleName(module)}`);
return [module.name, instance];
}))))
.pipe(mergeMap((module) => {
const key = module.name;
return from(Promise.resolve(module.initialize({ ref, config: config[key], requireInstance }))).pipe(map((instance) => {
logger.debug(`initialized ${logModuleName(module)}`);
return [key, instance];
}));
}))
.subscribe({

@@ -91,3 +91,3 @@ next: ([name, module]) => {

logger.debug('✅ initialized');
Object.seal(ref);
Object.seal(instance);
const postInitialize = [...modules.map((x) => x.postInitialize), ...afterInit];

@@ -97,5 +97,14 @@ await Promise.all(postInitialize.map((x) => Promise.resolve(x?.(instance))));

logger.info(`🚀 ${!ref ? 'modules' : 'sub-modules'} ready`, process.env.NODE_ENV === 'development' && instance);
return instance;
const dispose = async () => {
await Promise.allSettled(modules.map((module) => {
Promise.resolve(module.dispose?.({
ref,
modules: instance,
instance: modules[module.name],
}));
}));
};
return Object.seal(Object.assign({}, instance, { dispose }));
};
export default initializeModules;
//# sourceMappingURL=initialize-modules.js.map
import type { AnyModule, ModulesConfigurator, ModulesInstanceType } from './types';
export declare const initializeModules: <TModules extends AnyModule[], TInstance = any>(configure: ModulesConfigurator<TModules, TInstance>, modules: TModules, ref?: TInstance | undefined) => Promise<ModulesInstanceType<TModules>>;
export declare const initializeModules: <TModules extends AnyModule[], TInstance = any>(configure: ModulesConfigurator<TModules, TInstance>, modules: TModules, ref?: TInstance | undefined) => Promise<ModulesInstanceType<TModules> & {
dispose: VoidFunction;
}>;
export default initializeModules;

@@ -1,4 +0,1 @@

export declare type ModuleInitializeConfig<TKey extends string, TConfig, TDeps extends Array<AnyModule> = []> = Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>> & {
requireInstance: <TKey extends keyof ModulesInstanceType<TDeps>>(name: TKey, wait?: number) => Promise<ModulesInstanceType<TDeps>[TKey]>;
};
export interface Module<TKey extends string, TType, TConfig, TDeps extends Array<AnyModule> = []> {

@@ -8,4 +5,13 @@ name: TKey;

postConfigure?: (config: Record<TKey, TConfig> & ModulesConfigType<ModulesType<TDeps>>) => void | Promise<void>;
initialize: (config: ModuleInitializeConfig<TKey, TConfig, TDeps>, instance: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>) => TType | Promise<TType>;
initialize: (args: {
ref?: any;
config: TConfig;
requireInstance: <TKey extends keyof ModulesInstanceType<TDeps>>(name: TKey, wait?: number) => Promise<ModulesInstanceType<TDeps>[TKey]>;
}) => TType | Promise<TType>;
postInitialize?: (modules: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>) => void | Promise<void>;
dispose?: (args: {
ref?: any;
instance: TType;
modules: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>;
}) => void | Promise<void>;
}

@@ -23,3 +29,3 @@ export declare type AnyModule = Module<any, any, any, any>;

export interface ModulesConfigurator<TModules extends Array<AnyModule>, TRef = ModuleInstance> {
(config: ModulesConfig<ModulesType<TModules>>, ref?: TRef): void | Promise<void>;
(config: ModulesConfig<TModules>, ref?: TRef): void | Promise<void>;
}

@@ -26,0 +32,0 @@ export declare type ModulesConfigType<TModules extends Array<AnyModule> | Record<string, AnyModule>> = TModules extends Array<AnyModule> ? ModulesObjectConfigType<ModulesType<TModules>> : TModules extends Record<string, AnyModule> ? ModulesObjectConfigType<TModules> : never;

{
"name": "@equinor/fusion-framework-module",
"version": "0.3.0",
"version": "0.4.0",
"description": "",

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

},
"gitHead": "65221b1abaf4e12d55349ddde5492c8facada168"
"gitHead": "b578e1812564df3aac4313c1b38e7252e7c9dd83"
}

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

mergeMap,
scan,
throwError,

@@ -75,3 +76,6 @@ timeout,

ref?: TInstance
): Promise<ModulesInstanceType<TModules>> => {
): Promise<ModulesInstanceType<TModules> & { dispose: VoidFunction }> => {
/** extract module names from provided modules */
const moduleNames = modules.map((m) => m.name);
const instance$ = new BehaviorSubject<ModulesInstanceType<TModules>>(

@@ -81,5 +85,2 @@ {} as ModulesInstanceType<TModules>

/** extract module names from provided modules */
const moduleNames = modules.map((m) => m.name);
const afterConfiguration: Array<(config: ModulesConfigType<TModules>) => void> = [];

@@ -94,29 +95,36 @@ const afterInit: Array<(instance: ModulesInstanceType<TModules>) => void> = [];

/** initialize config providers for all modules */
// TODO: make configs init in parallel
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 });
},
Promise.resolve({
onAfterConfiguration(cb: (config: ModulesConfigType<TModules>) => void) {
afterConfiguration.push(cb);
},
onAfterInit(cb: (instance: ModulesInstanceType<TModules>) => void) {
afterInit.push(cb);
},
} as ModulesConfig<TModules>)
const config = await lastValueFrom(
from(modules).pipe(
// TODO - handle config creation errors
mergeMap(async (module) => {
const configurator = await module.configure?.(ref);
return { [module.name]: configurator };
}),
scan((acc, module) => Object.assign(acc, module), {
onAfterConfiguration(cb) {
afterConfiguration.push(cb);
},
onAfterInit(cb) {
afterInit.push(cb);
},
} as ModulesConfig<TModules>)
)
);
/**
* Add method for allowing modules to await other module instance when initiating
* WARNING: this might create stall-lock if developer does not implement correctly!
*/
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
config.requireInstance = <TKey extends keyof ModulesInstanceType<TModules>>(
/** protected config instance */
Object.seal(config);
logger.debug(`✅ Configured ${modules.map(logModuleName)}`, config);
/** allow callback to configure */
configure && (await configure(config, ref));
/** call all added post config hooks */
await Promise.all(
[...modules.map((x) => x.postConfigure), ...afterConfiguration].map((x) =>
Promise.resolve(x?.(config))
)
);
const requireInstance = <TKey extends keyof ModulesInstanceType<TModules>>(
name: TKey,

@@ -145,30 +153,20 @@ wait = 60

/** protected config instance */
Object.seal(config);
logger.debug(`✅ Configured ${modules.map(logModuleName)}`, config);
/** allow callback to configure */
configure && (await configure(config as any, ref));
/** call all added post config hooks */
await Promise.all(
[...modules.map((x) => x.postConfigure), ...afterConfiguration].map((x) =>
Promise.resolve(x?.(config))
)
);
from(modules)
.pipe(
/** assign module to modules object */
mergeMap((module) =>
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
from(Promise.resolve(module.initialize(config, instance$.value))).pipe(
mergeMap((module) => {
const key = module.name;
return from(
Promise.resolve(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
module.initialize({ ref, config: config[key], requireInstance })
)
).pipe(
map((instance) => {
logger.debug(`initialized ${logModuleName(module)}`);
return [module.name, instance];
return [key, instance];
})
)
)
);
})
)

@@ -187,4 +185,3 @@ .subscribe({

/** Protected instances */
Object.seal(ref);
Object.seal(instance);

@@ -201,5 +198,19 @@ /** call all added post config hooks */

return instance;
const dispose = async () => {
await Promise.allSettled(
modules.map((module) => {
Promise.resolve(
module.dispose?.({
ref,
modules: instance,
instance: modules[module.name],
})
);
})
);
};
return Object.seal(Object.assign({}, instance, { dispose }));
};
export default initializeModules;
/* eslint-disable @typescript-eslint/no-explicit-any */
/** config object that are provided to modules when initiating */
// TODO - create a own class for config (ConfigureConfig and InitializeConfig)
export type ModuleInitializeConfig<
TKey extends string,
TConfig,
TDeps extends Array<AnyModule> = []
> = Record<TKey, TConfig> &
ModulesConfigType<ModulesType<TDeps>> & {
requireInstance: <TKey extends keyof ModulesInstanceType<TDeps>>(
name: TKey,
wait?: number
) => Promise<ModulesInstanceType<TDeps>[TKey]>;
};
export interface Module<TKey extends string, TType, TConfig, TDeps extends Array<AnyModule> = []> {

@@ -23,9 +9,18 @@ name: TKey;

) => void | Promise<void>;
initialize: (
config: ModuleInitializeConfig<TKey, TConfig, TDeps>,
instance: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>
) => TType | Promise<TType>;
initialize: (args: {
ref?: any;
config: TConfig;
requireInstance: <TKey extends keyof ModulesInstanceType<TDeps>>(
name: TKey,
wait?: number
) => Promise<ModulesInstanceType<TDeps>[TKey]>;
}) => TType | Promise<TType>;
postInitialize?: (
modules: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>
) => void | Promise<void>;
dispose?: (args: {
ref?: any;
instance: TType;
modules: Record<TKey, TType> & ModulesInstanceType<ModulesType<TDeps>>;
}) => void | Promise<void>;
}

@@ -52,3 +47,3 @@

export interface ModulesConfigurator<TModules extends Array<AnyModule>, TRef = ModuleInstance> {
(config: ModulesConfig<ModulesType<TModules>>, ref?: TRef): void | Promise<void>;
(config: ModulesConfig<TModules>, ref?: TRef): void | Promise<void>;
}

@@ -55,0 +50,0 @@

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