Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
@lskjs/module
Advanced tools
Module system with dependency injection, event emitter, logger and submodules tree
@lskjs/module – Module system with dependency injection, event emitter, logger and submodules tree
# yarn
yarn i @lskjs/module @types/lodash bluebird lodash
# npm
npm i @lskjs/module @types/lodash bluebird lodash
Весь мир модуль и мы в нём подмодули
Модуль - модули это классы с определнным жизненным циклом. Из модулей будет собираться комплексное приложение, у модулей могут быть подмодули.
module.init() - как консструктор но асинхронный, делает необходимые импорты и устанвливет правильное состояние модуля
module.run() - запускает все процессы в модуле
module.start() - init and run and some magic?
Module.new() - only create object
Module.create() - new + init
Module.start() - new + init + run -- init and run and some magic?
const theModule = await TheModule.start();
theModule.name === 'TheModule'
const theModule = await TheModule.start({
mode: 'private',
config: {
value: 1
},
});
theModule.mode === 'private'
theModule.config.value === 1
// === Example 1 - common use ===
const m = await Module.start(props);
// === Example 2 - if you need inited modules for connection ===
const m1 = await Module.create(props);
const m2 = await Module.create(props);
m1.m2 = m2;
m2.m1 = m1;
await m1.start();
await m2.start();
// === Example 3 – if you need uninited module ===
const m = Module.new(props);
await m.start()
class SomeModule extends Module {
async run() {
await super.run(); // очень важно не забывать super
if (this.param) {
doSomething();
}
}
}
// Прокидывание параметров через конструктор
const sm = await SomeModule.start({
param: 1312,
});
class OtherModule extends Module {
async init() {
await super.init(); // очень важно не забывать super
if (this.config.param) {
doSomething();
}
}
}
// SomeModule from the previous example
const some = await SomeModule.start({
param: 1,
modules: {
other: OtherModule,
},
config: {
param: 2
some
}
});
const other = await m.module('other');
const theModule = new TheModule({
modules: {
permit: require('@lskjs/permit/server'),
upload: import('@lskjs/upload/server'),
mailer: () => import('@lskjs/mailer/server'),
}
});
await theModule.start()
const theModule = new TheModule({
modules: {
permit: [require('@lskjs/permit/server'), { value: 1 }],
upload: [import('@lskjs/upload/server'), { value:2 } ],
mailer: () => [import('@lskjs/mailer/server', { value: 3 })],
}
});
await theModule.start()
class TheModule extends Module {
modules = {
permit: require('@lskjs/permit/server'),
upload: import('@lskjs/upload/server'),
mailer: () => import('@lskjs/mailer/server'),
}
}
class TheModule extends Module {
async getModules() {
return {
...await super.getModules(),
permit: require('@lskjs/permit/server'),
upload: import('@lskjs/upload/server'),
mailer: () => import('@lskjs/mailer/server'),
}
}
}
class TheModule extends Module {
name = 'TheModule2'; // можно переопределить имя, чтобы это имя было в логгере например
async init() {
await super.init();
// делаем то, что нам нужно для инициализации
this.client = new Telegraf(this.config)
}
async run() {
await super.run();
// делаем то, что нам нужно для запуска модуля
this.client.launch();
}
}
проблема провайдеров
у модуля должен быть логгер
у модуля должен быть event emitter
проблема конфигов, централизованных конфигов
проблема моделей и модуля db (в init нужен mongoose)
модуль
подмодули
провайдеры
модели
ee
inject
getModules
modules={}
new TheModule(, {providers: {}})
как прокидывать конфиги дальше?
class SomeModule extends Module { }
const some = await SomeModule.start();
console.log(some.config); // {}
class SomeModule extends Module {
config = {
a: 1,
b: 2
};
}
const some = await SomeModule.start();
console.log(some.config);
// {
// a: 1,
// b: 2,
// }
const some = await SomeModule.start({
config: {
a: 11,
}
});
console.log(some.config);
// {
// a: 11,
// }
class SomeModule extends Module {
config = {
a: 1,
b: 2,
z: {
za: 1,
zb: 2
}
};
other = {
e: 5,
f: 6,
};
}
const some = await SomeModule.create({
config: {
a: 11,
c: 33,
z: {
za: 11,
zc: 33
}
},
other: {
e: 55,
g: 77,
};
})
// Мердж работает только с плоскими, конфигами. Но если очень хочется можно сделать глубокий merge
console.log(some.config);
// {
// a: 11,
// b: 2,
// c: 33,
// z: {
// za: 11,
// zc: 33,
// },
// }
// Другие объекты перетираются, но если очень хочется то можно сделать как в конфигах
console.log(some.other);
// {
// e: 55,
// g: 77,
// }
class SomeModule extends Module {
config = {
a: 1,
b: 2,
};
async getConfigFromDb() {
return {
fields: true,
from: true,
db: true,
}
}
async getConfig() {
const localConfig = await super.getConfig();
const dbConfig = await this.getConfigFromDb().catch(err => {
this.log.error('something wrong', err);
if (neededFallApp) throw err
// throw err;
return {}
})
return {
...localConfig,
...dbConfig,
};
}
}
const some = await SomeModule.create({
config: {
a: 11,
c: 33
}
})
// if all ok
some.config === {
a: 11,
b: 2,
c: 33,
fields: true,
from: true,
db: true,
}
// if all error not ok
some.config === {
a: 11,
b: 2,
c: 33,
}
class Module {
async getConfig() {
return {
...this.defaultConfig,
...this.config,
}
}
}
class Module {
async getConfig() {
return {
...this.defaultConfig,
...this.config,
...this.__config,
deep: {
...this.defaultConfig.deep,
...this.config.deep,
...this.__config.deep,
deepest: {
...this.defaultConfig.deep.deepest,
...this.config.deep.deepest,
...this.__config.deep.deepest,
}
}
}
}
// or
async getConfig() {
return mergeDeep(
this.defaultConfig,
this.config,
this.__config,
}
}
defaultConfig = {
a: 1,
b: 2,
};
}
const some = await SomeModule.create({
config: {
a: 2,
c: 3
}
})
some.config === {
a: 2,
b: 2,
c: 3,
}
=================
class Uapp {
getModules() {
return {
appstate: () => import('./modules/appstate'),
i18: () => import('./modules/i18'),
}
}
provide() {
return {
...super.provide(),
i18: this.modules.i18
}
}
}
async injectAndAwait(props) {
const i18 = await props.i18;
const res = {};
if (!i18.runned) {
await i18.run();
res.i18 = i18;
}
return res;
}
@injectAndAwait('i18')
class Component {
render() {
const {i18} = this.props;
return <div />
}
}
This project is licensed under the MIT License - see the LICENSE file for details
Igor Suvorov 💻 🎨 🤔 |
git checkout -b features/fooBar
)git commit -am 'feat(image): Add some fooBar'
)git push origin feature/fooBar
)FAQs
Module system with dependency injection, event emitter, logger and submodules tree
The npm package @lskjs/module receives a total of 1,355 weekly downloads. As such, @lskjs/module popularity was classified as popular.
We found that @lskjs/module demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 12 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.