A decorator-driven application framework for TypeScript services with DI container, routing, intent events, lifecycle hooks, caching, and exception handling.
@Simand runtime resolution throughSimpleApplication.@Inject.@Router,@Route) and route manager integration.@Cache(key, delete, set, children-key strategies).bundle-entrysupport.npm install @dooboostore/simple-bootimport{SimpleApplication,Sim,Inject,Router,Route}from'@dooboostore/simple-boot';import{SimpleApplication}from'@dooboostore/simple-boot/bundle-entry';simple-boot is centered aroundSimpleApplication.
SimpleApplicationowns container/runtime managers.SimstanceManagermanages registered sims and proxies.RouterManagerhandles route resolution.IntentManagerhandles event-like intent publish/subscribe.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'));SimpleApplication,SimOptionalert/*,cache/*,decorators/*,errors/*,fetch/*intent/*,lifecycle/*,proxy/*,route/*,simstance/*,throwable/*,types/*Corenamespace re-export from@dooboostore/core(bundle-entry only)| Decorator | Purpose |
|---|---|
@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 |
@PostConstruct | Run a method after the instance is constructed |
@SimNoProxy | Exclude a class (or a property) from proxying |
@Router({ path })/@Route({ path }) | Declare a router class and its route methods |
@Before/@After/@Around | AOP 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)+@Valid | Declarative validation; built-in validatorsNotNull,NotEmpty,Regexp(re) |
constapp =newSimpleApplication();
app.run();constservice = app.getInstance(MyService);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);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!);import{SimpleApplication,SimOption}from'@dooboostore/simple-boot';constapp =newSimpleApplication(newSimOption({cache: {enable:true,ms:60000}
})
);
app.run();reflect-metadataonce at application bootstrap.@dooboostore/simple-boot.@Simand resolve throughSimpleApplication.@Cachefor predictable invalidation.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.
The detailed API documentation, including all decorators and usage examples, is available on our documentation website.
This package is licensed under theMIT License.