@dooboostore/simple-boot

NPM versionBuild and TestLicense: MIT

A decorator-driven application framework for TypeScript services with DI container, routing, intent events, lifecycle hooks, caching, and exception handling.


Features

  • Dependency injection with@Simand runtime resolution throughSimpleApplication.
  • Constructor parameter injection with@Inject.
  • Routing decorators (@Router,@Route) and route manager integration.
  • Intent publish/subscribe architecture for decoupled workflows.
  • Method-level caching with@Cache(key, delete, set, children-key strategies).
  • Lifecycle/event/exception decorators for robust service orchestration.
  • Root-first exports and explicitbundle-entrysupport.

Quick Start

npm install @dooboostore/simple-boot

Import Guide

Root import (recommended)

import{SimpleApplication,Sim,Inject,Router,Route}from'@dooboostore/simple-boot';

Bundle entry import

import{SimpleApplication}from'@dooboostore/simple-boot/bundle-entry';

Core Architecture

simple-boot is centered aroundSimpleApplication.

  • SimpleApplicationowns container/runtime managers.
  • SimstanceManagermanages registered sims and proxies.
  • RouterManagerhandles route resolution.
  • IntentManagerhandles event-like intent publish/subscribe.

Quick Start Example

import'reflect-metadata';import{SimpleApplication,Sim,Router,Route,Cache}from'@dooboostore/simple-boot';@SimclassUserRepository{findById(id:string) {return{ id,name:'dooboostore'};
    }
}@SimclassUserService{// Constructor params are resolved from `design:paramtypes`; use @Inject(Type | Symbol | config) to overrideconstructor(privatereadonlyrepo:UserRepository) {}@Cache({key:(id:string) =>`user:${id}`,ms:30000})getUser(id:string) {returnthis.repo.findById(id);
    }
}@Sim@Router({path:'/users'})classUserController{constructor(privatereadonlyuserService:UserService) {}// Path params use {name} (or {name:regex}), not Express-style :name@Route({path:'/{id}'})detail(id:string) {returnthis.userService.getUser(id);
    }
}constapp =newSimpleApplication();
app.run();constuserService = app.getInstance(UserService);console.log(userService.getUser('100'));

Public API Surface (Root)

  • SimpleApplication,SimOption
  • alert/*,cache/*,decorators/*,errors/*,fetch/*
  • intent/*,lifecycle/*,proxy/*,route/*,simstance/*,throwable/*,types/*
  • Corenamespace re-export from@dooboostore/core(bundle-entry only)

Decorator Reference

DecoratorPurpose
@Sim/@Sim({ symbol, scope, using, ... })Register a class in the container (scope: Lifecycle.Singletondefault, orLifecycle.Transient)
@Inject(Type | Symbol | config)Override constructor/method parameter resolution
@PostConstructRun a method after the instance is constructed
@SimNoProxyExclude a class (or a property) from proxying
@Router({ path })/@Route({ path })Declare a router class and its route methods
@Before/@After/@AroundAOP advice on methods
@ExceptionHandler({ type })Handle errors thrown from managed methods
@Cache({ key | deleteKey | setKey, ms })Method-level caching
@EventListener({ target, name })Event-listener method metadata
@Validation(validator)+@ValidDeclarative validation; built-in validatorsNotNull,NotEmpty,Regexp(re)

Common Patterns

1) Resolve instance from container

constapp =newSimpleApplication();
app.run();constservice = app.getInstance(MyService);

2) Intent publish

publishIntenttargets a@Simregistered with asymbol, addressed asSymbol.for(<name>)://<methodName>(seeIntent). Method parameters are bound positionally from the data array, and@Inject-decorated parameters are still resolved from the container:

import{Sim,Intent}from'@dooboostore/simple-boot';constNotifierSymbol=Symbol.for('Notifier');@Sim({symbol:NotifierSymbol})classNotifier{onUserCreated(id:string) {console.log('user created:', id);returnid;
    }
}constintent =newIntent('Symbol.for(Notifier)://onUserCreated', ['u-1']);const[result] =awaitapp.publishIntent(intent);

3) Route invoke

routing()resolves the match and returns aRouterModule— it doesnotcall the matched method for you. ReadpathDatafor path params and fetch the module instance to invoke it yourself:

constrouterModule =awaitapp.routing('/users/100', {router:UserController});constid = routerModule.getPathData<{id:string}>()?.id;// '100'constcontroller = routerModule.getModuleInstance<UserController>();constresult = controller?.detail(id!);

4) SimOption customization

import{SimpleApplication,SimOption}from'@dooboostore/simple-boot';constapp =newSimpleApplication(newSimOption({cache: {enable:true,ms:60000}
    })
);

app.run();

Best Practices

  • Importreflect-metadataonce at application bootstrap.
  • Prefer root imports from@dooboostore/simple-boot.
  • Register services with@Simand resolve throughSimpleApplication.
  • Keep route handlers thin and delegate business logic to service sims.
  • Use explicit cache keys in@Cachefor predictable invalidation.

Troubleshooting

Issue:DI target resolves asundefined
Solution:verify class is decorated with@Simand app has executedrun().

Issue:Decorators not working in runtime
Solution:ensurereflect-metadatais imported before decorated classes are evaluated.

Issue:Cache not applied
Solution:checkSimOption.cache.enableand verify method is invoked through managed instance.

Issue:Routing not matched
Solution:verify@Router({ path })+@Route({ path })path composition and run sequence.

Learn More

The detailed API documentation, including all decorators and usage examples, is available on our documentation website.

Related Packages

License

This package is licensed under theMIT License.