
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@locustjs/locator
Advanced tools
A locustjs library implementing Service Locator pattern to provide loose coupling through IoC (Inversion of Control).
This library implements Service Locator pattern in javascript as a method of dependency injection. Service Locator pattern is one of the different ways of implementing IoC (inversion of control) and achieving loose coupling in software development.
npm install @locustjs/locator
| Class | description |
|---|---|
LocatorBase | Base locator abstract class |
DefaultLocator | Default service locator implementation |
Locator | Static service locator class with a default singleton instance that is by default an instance of DefaultLocator |
{
PerRequest: 0, // instantiate new instance for each request
PerApp: 1, // return a single instance per application (uses localStroage to preserve the instance)
PerPage: 2, // return a single instance per page (insiance is created when page loads)
PerSession: 3 // return single instance per browser session (uses sessionStorage to preserve the instance)
}
| Method | description |
|---|---|
register(abstraction, concretion, resolveType = Resolve.PerRequest, state = null) | Register concretion class for abstraction class based on resolveType and state. concretion should be a subclass of abstraction. |
registerFactory(abstraction, factory, resolveType = Resolve.PerRequest, state = null) | Register an object that is instantiated by factory method for abstraction based on resolveType and state. The object returned by factory should be an instance of abstraction class. |
registerInstance(abstraction, instance, resolveType = Resolve.PerRequest, state = null) | Register instance object for abstraction based on resolveType and state. instance should be an instance of abstraction class. |
resolveBy(abstraction, state, ...args) | Resolve abstraction based on given state. Passes args when instantiating from the concretion that is already registered for abstraction. |
resolve(abstraction, ...args) | Resolve abstraction. Passes args when instantiating from the concretion that is already registered for abstraction. |
remove(abstraction, state) | Remove registration entry for abstraction based on the given state. |
exists(abstraction, state) | Check whether a registration entry exists for abstraction based on then given state. |
./src/services/foo/index.js
// Foo Service
class FooServiceBase {
getById(id) {
throw 'getById() is not implemented'
}
}
class FooServiceRemote extends FooServiceBase {
async getById(id) {
const response = await fetch(`/api/foo/${id}`);
const foo = await response.json();
return foo;
}
}
class FooServiceFake extends FooServiceBase {
constructor() {
super();
this._data = [
{ id: 1, name: 'Foo1'},
{ id: 2, name: 'Foo2'},
{ id: 3, name: 'Foo3'}
]
}
getById(id) {
return new Promise(res => setTimeout(() => res(this._data.find(x => x.id == id)), 1000))
}
}
export { FooServiceBase, FooServiceRemote, FooServiceFake }
./src/locator.config.js
import Locator from '@locustjs/locator';
import { FooServiceBase, FooServiceRemote, FooServiceFake } from './services/foo';
configureLocator(mode) {
if (mode.toLowerCase() == 'production') {
Locator.instance.register(FooServiceBase, FooServiceRemote);
} else {
Locator.instance.register(FooServiceBase, FooServiceFake);
}
}
export default configureLocator;
./src/index.js
// App startup
import configureLocator from './locator.config.js';
const exec_type = 'development'; // or 'production'
configureLocator(exec_type)
./src/app.js
// FooService Usage
import Locator from '@locustjs/locator';
import { FooServiceBase } from './services/foo';
// Here, our code is independent of any foo service implementation.
// It relies on an abstract foo service. So, we can easily use a fake
// service to develop our app. Whenever our rest api is developed, we
// can switch to FooServiceRemote. No change is needed to be applied on app.js.
const service = Locator.instance.resolve(FooServiceBase);
const foo = await service.getById(1);
console.log(foo)
index.js
import ReactDOM from 'react-dom';
import Locator, { Resolve } from '@locustjs/locator';
import { ColorServiceBase, ColorServiceDefault } from './services/color';
import App from './App';
Locator.instance.register(ColorServiceBase, ColorServiceDefault);
ReactDOM.render(<App />, document.getElementById('root'));
App.js
import React, { useEffect, useState } from 'react'
import { ColorServiceBase } from './services/color';
import Locator from '@locustjs/locator';
const App = () => {
const service = useMemo(() => Locator.instance.resolve(ColorServiceBase), []);
const [colors, setColors] = useState([]);
useEffect(() => this.service.getColors().then(colors => setColors(colors)), []);
return (
<>
<h3>Colors</h3>
<ul>
{colors.map(x => <li>{x}</li>)}
</ul>
</>
);
}
export default App;
/services/color/ColorServiceBase.js
class ColorServiceBase {
constructor() {
if (this.constructor === ColorServiceBase) {
throw 'ColorServiceBase is an abstract class. You cannot instantiate from it.'
}
}
getColors() {
throw 'getColors() is not implemented'
}
}
export default ColorServiceBase;
/services/color/ColorServiceDefault.js
import ColorServiceBase from './ColorServiceBase.js';
class ColorServiceDefault extends ColorServiceBase {
async getColors() {
const response = await fetch('/api/colors');
const data = await response.json();
return data;
}
}
export default ColorServiceDefault;
/services/color/ColorServiceFake.js
import ColorServiceBase from './ColorServiceDefault';
class ColorServiceFake extends ColorServiceBase {
getColors() {
return new Promise((res, rej) => {
res([ 'Red', 'Green', 'Blue', 'Yellow', 'White', 'Black', 'Purple' ]);
});
}
}
export default ColorServiceFake;
/services/color/index.js
import ColorServiceBase from './ColorServiceBase.js';
import ColorServiceDefault from './ColorServiceDefault.js';
import ColorServiceFake from './ColorServiceFake.js';
export { ColorServiceBase, ColorServiceDefault, ColorServiceFake }
Here, the App component is completely decoupled from its ColorService dependency.
FAQs
A locustjs library implementing Service Locator pattern to provide loose coupling through IoC (Inversion of Control).
We found that @locustjs/locator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 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
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.