Next Planet of Monkeys

    @vgerbot/lazy

    1.0.0 • Public • Published

    @vgerbot/lazy NPM

    Test Codacy Badge Codacy Badge code style: prettier

    A library for defining lazily evaluated properties and variables powered by TypeScript.

    Motivation

    @vgerbot/lazy is a useful tool for managing lazy evaluation properties. It defers expensive property(or a variable) initialization until needed and avoids unnecessary repeated evaluation. This library supports adding reset tester for lazy properties, once the reset tester detects a change, the property will be re-evaluated and initialized the next time the property is accessed, which simplifies a lot of work

    Install

    npm i @vgerbot/lazy

    Usage

    @lazyMember decorator

    Requires the compilerOptions.experimentalDecorators in tsconfig.json to be set to true

    import { lazyMember } from '@vgerbot/lazy';
    
    function getFriends(id: string, params: Record<string, string | number> = {}): Promise<User[]> {
        const url = new URL('http://api.domain.com/friends');
        url.searchParams.append('userId', id);
        for(const key in params) {
            url.searchParams.append(key, params[key]);
        }
        console.log('fetch: ',url);
        return fetch(url)
            .then(resp => {
                return resp.json()
            })
            .then(data => userListOf(data));
    }
    
    class User {
        @lazyMember<User, 'friends'>(user => getFriends(user.id))
        friends!: Promise<User[]>;
    
        @lazyMember<User, 'littleBrothers'>({
            evaluate: user => getFriends(user.id, {maxAge: user.age}),
            resetBy: ['age']
        })
        littleBrothers!: Promise<User[]>;
    
        constructor(readonly id: string, age: number) {
        }
    }

    With the lazy properties ready, we can now use it:

    const user = new User('a5cba8f', 18)
    
    user.friends.then(() => {
    })
    // console output: "fetch:  http://api.domain.com/friends?userId=a5cba8f"
    
    user.friends.then(() => {
    }) // nothing output
    
    user.littleBrothers.then(() => {
    })
    // console output: "fetch:  http://api.domain.com/friends?userId=a5cba8f&maxAge=18"
    
    user.littleBrothers.then(() => {
    })
    // nothing is output
    
    user.age = 19;
    // The `age` property has changed, so the `littleBrothers` property will also be reset.
    
    user.littleBrothers.then(() => {
    })
    // console output: "fetch:  http://api.domain.com/friends?userId=a5cba8f&maxAge=<b>19</b>"

    lazyMemberOfClass

    If you don't like or can't use decorators, you can do this:

    import { lazyMemberOfClass } from '@vgerbot/lazy';
    
    class User {
        friends!: Promise<User[]>;
    
        littleBrothers!: Promise<User[]>;
    
        constructor(readonly id: string, age: number) {
        }
    }
    
    lazyMemberOfClass(User, 'friends', (user) => getFriends(user.id));
    lazyMemberOfClass(User, 'littleBrothers', {
        evaluate: user => getFriends(user.id, {maxAge: user.age}),
        resetBy: ['age']
    });

    The rest is the same as the appeal '@lazyMember', so I won't repeat it here.

    lazyProp

    Define lazily evaluated property on an object:

    import { lazyProp } from '@vgerbot/lazy';
    
    const giraffe = {} as { rainbow: string };
    
    lazyProp(object, 'rainbow', () => expansiveComputation());
    
    console.log(giraffe.rainbow);

    lazyVal

    Create a lazily evaluated value:

    import { lazyVal } from '@vgerbot/lazy';
    
    const value = lazyVal(() => expensiveComputation());
    
    button.onclick = () => {
        doSomthing(value.get());
    };

    For more usage, see the unit test code.

    License

    License under the MIT Licensed (MIT)

    Install

    npm i @vgerbot/lazy

    DownloadsWeekly Downloads

    2

    Version

    1.0.0

    License

    MIT

    Unpacked Size

    307 kB

    Total Files

    63

    Last publish

    Collaborators

    • y1j2x34