UNPKG

@v4fire/core

Version:
186 lines (145 loc) 4.05 kB
# 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: () => { /* ... */ } }); ```