@v4fire/core
Version:
V4Fire core library
186 lines (145 loc) • 4.05 kB
Markdown
# core/lazy
This module provides a function to create a lazy structure based on the provided function or class.
The created structure is a function with the pre-defined methods and properties from the passed scheme and/or class prototype.
All property or method actions will be intercepted and accumulated in a queue. After invoking the result function,
all accumulated actions will be executed.
## Usage
### With a function that returns an object
```js
import makeLazy from 'core/lazy';
function createUser(name, age) {
return {
name,
age,
showInfo() {
console.log(`Name: ${this.name}; Age: ${this.age}`);
}
};
}
const lazyUser = makeLazy(
createUser,
// Declaring a scheme with the result of the original function invoking
{
// A string property with the default value
name: '',
// A number property with the default value
age: 0,
// A method
showInfo: Function
}
);
// Nothing happens at all
lazyUser.age = 45;
lazyUser.showInfo();
// Invoking the lazy function and passing necessary arguments.
// After invoking we can see in a console the result of calling `showInfo`:
// `Name: Bob; Age: 45`
const user = lazyUser('Bob', 10);
```
### With a class
```js
import makeLazy from 'core/lazy';
class User {
constructor(name, age) {
this.name = name;
this.age = age;
this.config = {
errorHandler() {
console.log('Boom!');
}
};
}
showInfo() {
console.log(`Name: ${this.name}; Age: ${this.age}`);
}
}
const LazyUser = makeLazy(
User,
// Declaring only properties.
// All methods are taken automatically from the class prototype.
{
config: {
attr: {},
errorHandler: Function
}
}
);
// Nothing happens at all
LazyUser.showInfo();
LazyUser.config.attr = 'value';
LazyUser.config.errorHandler();
// Creating an instance of the lazy class and passing necessary arguments to its constructor.
// After invoking we can see in a console the results of calling `showInfo` and `config.errorHandler()`:
// `Name: Bob; Age: 23`
// `Boom!`
const user = new LazyUser('Bob', 23);
// Because of `LazyUser.config.attr = 'value'`
console.log(user.config.attr === 'value');
// After invoking we can see in a console the results of `showInfo` and `config.errorHandler()`:
// `Name: Fred; Age: 56`
// `Boom!`
const user2 = new LazyUser('Fred', 56);
```
## Action hooks
There is possibility to provide hook handlers on of some structure actions,
like getting or setting a property value or method invoking. These handlers take an array of the already created `Lazy` instances.
Other arguments depend on the hook type.
```js
import makeLazy from 'core/lazy';
class RenderEngine {
component(name, opts) {
if (opts == null) {
return /* Component declaration */;
}
return /* Create a component */;
}
}
const LazyRenderEngine = makeLazy(
RenderEngine,
{
config: {
attr: {},
errorHandler: Function
}
},
{
get: {
'config.attrs'(contexts) {
return contexts.at(-1).config.attrs;
}
},
set: {
'config.attrs'(contexts, value) {
contexts.forEach((ctx) => {
ctx.config.attrs = value;
});
}
},
call: {
component(contexts, ...args) {
if (args.length > 1) {
contexts.forEach((ctx) => {
ctx.component(...args);
});
return;
}
return contexts.at(-1).component(...args);
}
}
}
);
const
engine1 = new LazyRenderEngine(),
engine2 = new LazyRenderEngine();
// These actions will be provided to the already created instances,
// because we specify hook handlers with this logic
// Will invoke a handler `set.config.attrs`
LazyRenderEngine.config.attrs = 'value';
// Will invoke a handler `get.config.attrs`
console.log(LazyRenderEngine.config.attrs);
// Will invoke a handler `call.component`
LazyRenderEngine.component('newAwesomeComponent', {
props: { /* ... */ },
render: () => { /* ... */ }
});
```