npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lazy-toolbox/portable

v0.0.18

Published

<p align="center"> <img src="/doc/img/logo.png" alt="logo" height="500" width="500"> </p>

Downloads

23

Readme

Lazy Toolbox - Portable

A NodeJS toolbox made for a lazy development anywhere you need.

Made to handle a bunch of cases that have to be handle on either a server or a client part.

The source code is available on GitHub.

There is also a bundle for thoses who don't want to use NodeJS. To use it, just add in your HTML:

<script src="./lazyPortable.js" type="module"></script>

You can change the type module if needed.

Suppose you have a test.js script in which you want to use the lazyPortable.js bundle like this for example:

<script src="./test.js" defer></script>

You can use the LazyPortable global variable to access all of the LazyPortable classes. Example:

console.log(LazyPortable.LazyMath.modulo(3, 2));

Index

Installation (NPM)

The installation is pretty straight forward:

npm i @lazy-toolbox/portable

Updates

v0.0.18 - Bundle and Singleton

New content was added:

  • Add LazySingleton class.
  • A bundle for portability.

v0.0.17 - Topological sort

New content was added:

  • Add LazyCounter class.
  • Add LazySort class.

v0.0.13 - New rules

New content was added:

  • Add simpleKeys to LazyRule.
  • Add parseString to LazyRule.
  • Add regex to LazyRule.

New modifications were introduced:

  • Introduction of an override of patternSet and IsPatternEnd in simpleCharbox for new rules in nested content.
  • Add exp parse for numbers.
  • Patch the wrong return type of combinationArrayNRNO in LazyMath.

v0.0.10 - Charbox failing

New modifications were introduced:

  • Correction of simpleCharbox from LazyRule not using it's end pattern and the spacing.
  • Patch LazyParser spacing.

v0.0.5 - Parsing rules

New content was added:

  • Add variable, keyword and any static functions to LazyRule.
  • Add toStringDebug static function to LazyParsing.

New modifications were introduced:

  • Change the parse return value to a PatternFound[]. Previously, it was any[].

v0.0.3 - Parsing fury

New content was added:

  • Add LazyParsing class.
  • Add LazyPattern class.
  • Add LazyRule class.
  • Add LazyText class.

v0.0.2 - Lazy Mapping

New content was added:

  • Add LazyMapper class for data filtering.
  • Add LazyDataGraph class for tangential analysis of graphs.
  • Add combinationArrayNRNO function to LazyMath.

v0.0.0 - Initial commit

Documentation

This part explain all tools with examples if it's needed.

Portable

dateLog

function dateLog(msg: any): string

Create a message with the time display up to the s. It will be showned as [HH:MM:SS] MY_MESSAGE.

Example:

const { dateLog } = require('@lazy-toolbox/portable');
console.log(dateLog("Hello world")); // [10:37:12] Hello world

dateLogMS

function dateLogMS(msg: any): string

Create a message with the time display up to the ms. It will be showned as [HH:MM:SS.DCM] MY_MESSAGE.

Example:

const { dateLogMS } = require('@lazy-toolbox/portable');
console.log(dateLogMS("Hello world")); // [10:37:12.123] Hello world

getType

function getType(parameter: any): string

Get the type of the parameter, extending typeof to support class and array as native options.

Example:

const { getType } = require('@lazy-toolbox/portable');
class Animal {
    constructor(name) {
        this.name = name;
    }
}
const x = Animal;
const y = [ 'a', 'b' ];
console.log(getType(x)); // class
console.log(getType(y)); // array
// Everything else is the same as typeof

LazyCounter

interface RequiredMaterial {
    name: string;
    quantity?: number;
    price?: number;
}
interface MaterialCounter {
    name: string;
    required?: RequiredMaterial[];
    price: number;
}
class LazyCounter {
    static fullPrice(itemName: string, ...materials: MaterialCounter[]): number;
    static allRowMaterials(itemName: string, ...materials: MaterialCounter[]): RequiredMaterial[];
}

A lazy way to count in crafting structure.

Example:

const { LazyCounter } = require('@lazy-toolbox/portable');
const materials = [
    {
        name: "wood",
        price: 1
    },
    {
        name: "steel",
        price: 5
    },
    {
        name: "sword",
        required: [
            {
                name: "wood",
                quantity: 1
            },
            {
                name: "steel",
                quantity: 2
            }
        ],
        price: 100
    }
]
console.log(LazyCounter.fullPrice("sword", materials)); // 111
for(const item of LazyCounter.allRowMaterials("sword", materials)) {
    console.log(`${item.name}: ${item.quantity}`);
}
/*
wood: 1
steel: 2
*/

LazyDataGraph

interface GraphPoint {
    value: number;
    label: string;
    increasePercent?: number;
    localMean?: number;
    localVariance?: number;
}
class LazyDataGraph {
    constructor(...datas: GraphPoint[]);
    get points(): GraphPoint[];
    set points(pts: GraphPoint[]);
    isTangentGraph(): boolean;
    getTangentGraph(): LazyDataGraph;
    generateSlope(): GraphPoint[];
}

A non-visual graph to analyze variation in datas.

Example:

const { LazyDataGraph } = require('@lazy-toolbox/portable');
// Create the graph
const lazyGraph = new LazyDataGraph(
    // Set an ordered bunch of points
    {label:'d1', value:100},
    {label:'d2', value:100},
    {label:'d3', value:200},
    {label:'d4', value:150},
    {label:'d5', value:100}
);
// Generate the tangent of the graph to see the differentiation in the graph
const tangentGraph = lazyGraph.generateSlope();
// Just showing what was made on the way.
for(let tanPt of tangentGraph) {
    console.log(`- ${tanPt.label}: [value: ${tanPt.value}, increasePercent: ${tanPt.increasePercent}, localMean: ${tanPt.localMean}, localVariance: ${tanPt.localVariance}]`);
}
/* Result:
- d1-d2: [value: 0, increasePercent: 0.0 ]
- d2-d3: [value: 100, increasePercent: 2.0 ]
- d3-d4: [value: -50, increasePercent: -0.25 ]
- d4-d5: [value: -50, increasePercent: -0.33 ]
*/

LazyMapper

class LazyMapper {
    static filterData<T>(data: any, defaultValue: T, transform: (d: any) => T, filter: (d: T) => T): T;
    static defaultData<T>(data: any, defaultValue: T, transform: (d: any) => T): T;
    static boolean(data: any): boolean;
    static defaultBoolean(data: any, defaultValue: boolean): boolean;
    static number(data: any): number;
    static defaultNumber(data: any, defaultValue: number): number;
    static filterNumber(data: any, defaultValue: number, filter: (d: number) => number): number;
    static string(data: any): string;
    static defaultString(data: any, defaultValue: string): string;
    static filterString(data: any, defaultValue: string, filter: (d: string) => string): string;
}

A mapper to allow some filtering for retrieved variables that could be undefined.

Example:

const { LazyMapper } = require('@lazy-toolbox/portable');
const someData = {
    propA: "hello",
    propB: 123,
    propC: {
        subProp: "uwu"
    }
};
console.log(LazyMapper.defaultString(someData.propA, 'error!')); // hello
console.log(LazyMapper.defaultString(someData.propD, 'error!')); // error!

LazyMath

class LazyMath {
    static modulo(a: number, b: number): number;
    static frac(a: number): number;
    static saturate(a: number): number;
    static sum(k: number, n: number, f: (i: number) => number): number;
    static product(k: number, n: number, f: (i: number) => number): number;
    static isPrime(n: number): boolean;
    static step(n: number, x: number): number;
    static lerp(a: number, b: number, t: number): number;
    static unlerp(a: number, b: number, p: number): number;
    static binomialCoefficient(n: number, k: number): number;
    static derivative(x: number, f: (x: number) => number): number;
    static antiDerivative(x: number, f: (x: number) => number, subdivide: number = 1): number;
    static integral(a: number, b: number, f: (x: number) => number, subdivide: number = 1): number;
    static combinationArrayNRNO<T>(objects: T[], k: number): T[];
}

Add some lazy math that should have been available at first on JS.

Example:

const { LazyMath } = require('@lazy-toolbox/portable');
// The JS modulo operator violate the property (a + n) mod n = a mod n.
// So we've implemented a modulo that doesn't violate it.
// JS modulo = a - ([a / b] * b)
// where [a / b] is the truncature of a / b.
// LazyMath.modulo = a - (⌊a / b⌋ * b)
// where ⌊a / b⌋ is the floor of a / b.

// Positive value have the same answer
console.log(LazyMath.modulo(4, 3)); // 1
console.log(4 % 3) // 1
// The JS modulo problem lies over here.
console.log(LazyMath.modulo(-4, 3)); // 2
console.log(-4 % 3); // -1

// Get the leftover to obtain an integer less or equal to n.
console.log(LazyMath.frac(2.345)); // 0.345
console.log(LazyMath.frac(-2.345)); // 0.655

// Get a value between 0 and 1
console.log(LazyMath.saturate(2.345)); // 1

// sum and product are made to handle iterative function for sum and product.
// 1 + 2 + 3 + 4 = 10
console.log(LazyMath.sum(1, 4, (i) => i));
// 1 * 2 * 3 * 4 * 5 = 5! = 120
console.log(LazyMath.product(1, 5, (i) => i));

// A method to test if a number is prime.
// It's not an optimal method, it can be slow as hell but you'll be 100% sure it's a prime number.
console.log(LazyMath.isPrime(7)); // True
console.log(LazyMath.isPrime(24)); // False

// Return 1 if x is gequal to n, otherwise n.
console.log(LazyMath.step(0.3, 0.5)); // 0.3
console.log(LazyMath.step(0.4, 0.5)); // 0.4
console.log(LazyMath.step(0.5, 0.5)); // 1

// Do a linear interpolation between a and b using the parameter t for the interpolated distance.
console.log(LazyMath.lerp(1, 3, 0.5)); // 2

// Get the interpolated distance of p on the line from a to b.
console.log(LazyMath.unlerp(1, 3, 2)); // 0.5

// Compute the number of ways to choose an unordered subset of k elements from a fixed set of n elements.
console.log(LazyMath.binomialCoefficient(5, 2)); // 10

// Evaluate the derivative of a function f at a point x. d/dx f(x)
// For this example, we use the function f(x) = x² and evaluate it's derivative at x = 3.
// The result should be 6 if the approximation was perfect.
console.log(LazyMath.derivative(3, (x) => { return x * x; })); // 5.921189464667501

// Evaluate the anti-derivative of a function f' at a point x.
// For this example, we use the function f'(x) = 2x and evaluate it's anti derivative at x = 3.
// The result should be 9 if the approximation was perfect.
console.log(LazyMath.antiDerivative(3, (x) => { return 2 * x; })); // 8.819999999999999

// Evaluate the area under the curve of a function f' from a to b.
// The result should be 15 if the approximation was perfect.
console.log(LazyMath.integral(1, 4, (x) => { return 2 * x; })); // 14.819999999999997

// Return an array of ordered combination without repetition of n objets (a string array) classified in k groups.
console.log(LazyMath.combinationArrayNRNO([7, 6, 3, 4], 2));
/* Result:
[
    [7, 6],
    [7, 3],
    [7, 4],
    [6, 3],
    [6, 4],
    [3, 4]
]
*/

LazyParsing

interface PatternResult {
    isPatternEnd: boolean;
    result: PatternFound[];
    lastIndex: number;
}
class LazyParsing {
    constructor(...rules: BasicRule[]);
    addRules(...rules: BasicRule[]): void;
    removeRules(...rulesName: string[]): void;
    parse(text: string): PatternFound[];
    static createSet(...rules: BasicRule[]): LazyPattern[];
    static parse(txtContent: string, patternSet: LazyPattern[], i: number = 0, endPattern: (i: number, c: string, t: string) => boolean = (i: number, c: string, t: string) => { return false; }): PatternResult;
    static toString(content: PatternResult | PatternFound[], spacing: boolean = false): string;
    static toStringDebug(content: PatternResult | PatternFound[], spacing: boolean = false): string;
}

A more natural way to parse datas with custom rules set in specific testing order.

Example:

const { LazyParsing, LazyRule } = require('@lazy-toolbox/portable');
// Create some keywords
const keywordList = [
    "if",
    "as"
];
// Create a bunch of rules for the parser
const ruleSet = LazyParsing.createSet(
    LazyRule.keyword(keywordList), // Should look first for keywords
    // If not a keyword, check for a variable
    LazyRule.variable(), // This order is to make sure we don't treat a keyword as variable
    LazyRule.number() // Last case scenario for the parsing is to check for a number
);
// Create a string to parse
const contentToParse = "select a content as aswell 100 _times if needed!";
// Get the parsing result
const parsedResult = LazyParsing.parse(contentToParse, ruleSet);
// Debug your datas visually
console.log(LazyParsing.toStringDebug(parsedResult, true));
/* Result:
    [variable]: select
    [variable]: a
    [variable]: content
    [keyword]: as
    [variable]: aswell
    [number]: 100
    [variable]: _times
    [keyword]: if
    [variable]: needed
*/
// Everything after this is up to you, it's your datas, handle them the way you want to.

LazyPattern

interface PatternFound {
    name?: string,
    currentName?: string,
    begin?: string,
    end?: string,
    nested?: boolean,
    content?: any,
    error?: boolean,
    line?: number,
    lineChar?: number,
    lastIndex?: number
}
class LazyPattern {
    constructor(pattern: BasicRule);
    get name(): string;
    isActualPattern(i: number, c: string, t: string): boolean;
    isEndPattern(i: number, c: string, t: string): boolean;
    fetchContent(i: number, c: string, t: string, patternSet: LazyPattern[], actualPattern: LazyPattern): PatternFound;
}

LazyPattern is a generic class made to check for pattern while looking inside a string. It fetch it's inner value with the pattern founded and then return it's last index.

LazyRule

interface BasicRule {
    name?: string,
    defaultValue?: any,
    begin?: string,
    end?: string,
    isPattern: (i: number, c: string, t: string) => boolean,
    isPatternEnd?: (i: number, c: string, t: string) => boolean,
    fetch?: (i: number, c: string, t: string, isPatternEnd?: (i: number, c: string, t: string) => boolean, patternSet?: LazyPattern[]) => PatternFound
}
class LazyRule {
    static simpleChar(name: string, predicate: (c:string)=>boolean): BasicRule;
    static simpleKeys(name: string, ...extractStrings: string[]): BasicRule;
    static simpleCharbox(name: string, begin: string, end: string, overridePatternSet?: LazyPattern[], overrideIsPatternEnd?: (i: number, c: string, txt: string) => boolean): BasicRule;
    static word(): BasicRule;
    static number(comaOverDot: boolean = false, exp: boolean = false): BasicRule;
    static variable(): BasicRule;
    static keyword(...keywordList: string[]): BasicRule;
    static any(name: string): BasicRule;
    static parseString(name: string, between: string): BasicRule;
    static regex(name: string, regex: RegExp): BasicRule;
}

A generic rule maker. It creates rules for LazyParsing.

Example:

const { LazyParsing, LazyRule } = require('@lazy-toolbox/portable');
const parsingRules = LazyParsing.createSet(LazyRule.number(), LazyRule.word());

LazySingleton

class LazySingleton {
    protected constructor();
    static instanceFactory<T extends LazySingleton>(this: new (...args: any[]) => T, ...args: any[]): T;
    static getInstance<T extends LazySingleton>(): T;
}

A lazy singleton representation to not bother about doing it at all nor ever.

Example:

const { LazySingleton } = require('@lazy-toolbox/portable');
class ExampleSingleton extends LazySingleton {
    constructor(name) {
        super();
        this.name = name;
    }
    sayName() {
        return `My name is ${this.name}`;
    }
}
const myExampleSingleton = new ExampleSingleton.instanceFactory("Amazing");
console.log(myExampleSingleton.sayName(myExampleSingleton));

LazySort

interface RequiredOrder {
    name: string,
    content: any,
    required?: string[]
}
class LazySort {
    static byRequired(myDatas: RequiredOrder[], allMustExist: boolean = false): RequiredOrder[];
}

A lazy way to sort some particular structure.

Example:

const { LazySort } = require('@lazy-toolbox/portable');
const testDatas = [
    {
        name: "Cart",
        content: "Cart making",
        required: [
            "Fire",
            "Wheel",
            "Iron",
        ]
    },
    {
        name: "Minerals",
        content: "Minerals extraction"
    },
    {
        name: "Wheel",
        content: "Wheel discovery"
    },
    {
        name: "Car",
        content: "Car making",
        required: [
            "Engine",
            "Cart",
            "Wheel"
        ]
    },
    {
        name: "Fire",
        content: "Fire discovery"
    },
    {
        name: "Iron",
        content: "Iron discovery",
        required: [
            "Fire",
            "Minerals"
        ]
    }
];
const showContent = (label, ds) => {
    console.log(label);
    let i = 1;
    for(const d of ds) {
        console.log(`${i++}) ${d.name}`);
    }
}
showContent("Not all must exist", LazySort.byRequired(testDatas, false));
showContent("All must exist", LazySort.byRequired(testDatas, true));
/*
Not all must exist
1) Fire
2) Wheel
3) Minerals
4) Iron
5) Cart
6) Car
All must exist
1) Fire
2) Wheel
3) Minerals
4) Iron
5) Cart
*/

LazyText

class LazyText {
    static extract(content: string, index: number, nbrLetters: number): string;
    static extractFromUntil(content: string, startIndex: number, predicate: (c: string, i: number, txt: string)=>boolean): { value: string; lastIndex: number; };
    static countLines(content: string): number;
    static countLinesChar(content: string, maxIndex: number): { lines: number; lineChar: number; };
}

Shorthand static class for special string functions.

Example:

const { LazyText } = require('@lazy-toolbox/portable');
const someContent = "Hello World.\nNice to meet you all.";
console.log(LazyText.extract(someContent, 2, 3)); // "llo"
console.log(LazyText.extractFromUntil(someContent, 2, (c, i, txt) => {
    c === '/n'
})); // "llo World."
console.log(LazyText.countLines(someContent));// 2
console.log(LazyText.countLinesChar(someContent));
/*
{
    lines: 2
    lineChar: 21
}
*/