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 🙏

© 2026 – Pkg Stats / Ryan Hefner

thematrix-entities

v1.0.3

Published

Client Data Processing Library

Readme

TheMatrix-Entities

Lightweight JavaScript Client Processing Library

Installation

Install with npm

  npm install thematrix-entities

Usage/Examples

  1. Initialize Entities Object
    let _baseUsers = [
      {
        id: 1,
        name: "user1",
        role_id: 1,
        role_name: "admin",
        country_id: 1,
        country_name: "Country 1",
        hourly_rate: 50,
        hours: 180
      },
      {
        id: 2,
        name: "user2",
        role_id: 2,
        role_name: "operator",
        country_id: 1,
        country_name: "Country 1",
        hourly_rate: 30,
        hours: 120
      }
    ];
    let eUsers=new Entities({
      list: _baseUsers,
      key: "id", //add new custom key if id is not unique
      init: function () {
        //called on each object once when adding to list
        this.icon = this._isAdmin()?<FaUserCircle />:<FaUser />; //jsx if supported by primary framework
        this.salary=0; //initialize any custom field
      },
      calculateSalary: function () {
          //custom function, need to be called with "_" prefix as eUsers._master[1]._callcuateSalary();
        this.salary = "$ " + Entities._u._formatComma(this.hourly_rate * this.hours, 2);
      },
      isAdmin: function () {
        //custom function, need to be called with "_" prefix as eUsers._master[1]._isAdmin();
        return this.role_id === 1;
      }
    });
  1. Entities-Object is made up of Entity objects indexed by key. Entity objects can be accessed under "_master" branch of Entities object.
console.log(eUsers._master[1]._isAdmin());
  1. Entities can be updated with _refresh(NEW_LIST) method.
eUsers._refresh([
    {},{},..
]);
//will call init method
  1. Entities can be appended with _append(NEXT_DATA) method.
eUsers._append([
    {},{},..
]);
//will call init method for new entries
  1. Branches list supplied to an Entities objects are assigned as "master" branch with branch key "_master". Other branches can be folked or filtered with _folk() method and _where() method.

5.1 Folking as new branch (not cloned)

eUsers._folk('to_branch','from_branch');

5.2 Folking as new branch by _where() method (not cloned)

//args:rules object or function array, source branch (default branch master=""), key column for new branch, new branch name 
eUsers._where({role_id:1},"","id","admins"); //listing only admin users as "admins" branch.

//with function array for advanced rules
eUsers._where([
    function(me){
        return me.role_id==1;
    }
],"","id","admins"); //listing only admin users as "admins" branch with advanced filtering.
  1. Creating JSON object/string
let json=eUsers._toJson();  
//with full arguments   
//args: branch, rules, is_javascript_object, pre_object + post_object, sortby  
let json=eUser._toJson('',[],true,null,'name') 
  1. Get a field value by other field's value
//args: by field, by field's value, field to get, source branch (default master="") 
let current_role_id=eUsers._getBy('id',1,'role_id',''); //get role_id where id=1
  1. Entities can be casted into an other model (with same columns, need to merge with _getColumnData() method.
//rules object or function array, unique key, source branch (default master="")
let roles=eUsers._model({},'role_id','');
//e.g. role model extracted with unique role_id
  1. Extracting sub model

7.1 Extracting a column data as sub model (with specified target fields)

//args: options object, source branch (default master=""), rules object or function array
let roles=eUsers._getColumnData(
        {
          columns: [
            ["role_id", "value"],
            ["role_name", "label"]
          ],
          mode: "unique", //remove duplicates
          orderBy: "label" //sort by sub-model-field
          topping:{role_id:-1,role_name:"No Role"}, //inject first custom item
          rottenEgg:{role_id:0,rolel_name:"Add New Role"} //append last custom item.
        },
        "", //source branch (default master="")
        {} //AND - rules, {column1:"value1",colum2:"value2"}
      );

7.2 Casting columns' data as sub model by custom rules

//args: options object, source branch (default master=""), rules object or function array   
let roles=eUsers._getColumnData(
        {
          columns: [
            ["role_id", "value"],
            ["role_name", "label"]
          ],
          mode: "unique", //remove duplicates
          orderBy: "label" //sort by sub-model-field
          topping:{role_id:-1,role_name:"No Role"}, //inject first custom item
          rottenEgg:{role_id:0,rolel_name:"Add New Role"} //append last custom item.
        },
        "", //source branch "" or "_mmaster" for default
        [
            function(me){
                return me.country_id=1;
            },
            function(me){
                return me.id>2;
            },
        ] //AND - rules
      );

Sample: https://codesandbox.io/s/crazy-pascal-jv4vl

import "./styles.css";
import React, { useState, useEffect } from "react";
import { Entity, Entities } from "thematrix-entities";
import Select from "react-select";
import { FaUser, FaUserCircle } from "react-icons/fa";
import SimpleTableComponent from "reactjs-simple-table";

export default function App() {
  const defC = []; //defC={value:0,label:'Select Countries'};
  const defR = { value: 0, label: "Select Role" };
  const defU = { value: 0, label: "Select User" };

  const [eUsers, setEUsers] = useState(
    new Entities({
      list: [],
      key: "id", //add new key if id is not unique
      init: function () {
        //called on each object once when adding to list
        this.icon = this._isAdmin()?<FaUserCircle />:<FaUser />;
        this.salary=0; //initialize any custom field
      },
      calculateSalary: function () {
        this.salary = "$ " + Entities._u._formatComma(this.hourly_rate * this.hours, 2);
      },
      isAdmin: function () {
        //custom function, need to be called with _ prefix
        // eUser._master[1]._isAdmin()
        return this.role_id === 1;
      }
    })
  );
  const [countries, setCountries] = useState([]);
  const [roles, setRoles] = useState([]);
  const [users, setUsers] = useState([]);
  const [tableUserData, setTableUserData] = useState([]);
  const [selCountries, setSelCountries] = useState(defC);
  const [selRoles, setSelRoles] = useState(defR);
  const [selUsers, setSelUsers] = useState(defU);
  const [loading, setLoading] = useState(true);
  const columns = [
    { field: "icon", headerName: "#" },
    { field: "name", headerName: "Name" },
    { field: "role_name", headerName: "Role" },
    { field: "country_name", headerName: "Country" },
    { field: "salary", headerName: "Salary" }
  ];
  
  const getSelectedArray = (sel) => {
    let _vals = [];
    if (!sel) return _vals;
    for (let i in sel) {
      _vals.push(sel[i].value);
    }
    return _vals;
  };

  useEffect(() => {
    //load data
    let _baseUsers = [
      {
        id: 1,
        name: "user1",
        role_id: 1,
        role_name: "admin",
        country_id: 1,
        country_name: "Country 1",
        hourly_rate: 50,
        hours: 180
      },
      {
        id: 2,
        name: "user2",
        role_id: 2,
        role_name: "operator",
        country_id: 1,
        country_name: "Country 1",
        hourly_rate: 30,
        hours: 120
      },
      {
        id: 3,
        name: "user3",
        role_id: 3,
        role_name: "user",
        country_id: 2,
        country_name: "Country 2",
        hourly_rate: 20,
        hours: 100
      },
      {
        id: 4,
        name: "user4",
        role_id: 3,
        role_name: "user",
        country_id: 3,
        country_name: "Country 3",
        hourly_rate: 20,
        hours: 75
      }
    ];

    eUsers._refresh(_baseUsers);
    //call calculateSalary method on each entity in list
    eUsers._calculateSalary(); 
    //can access filed of inner object by key under master branch
    //console.log(eUsers._master[1].salary);
    setEUsers({ ...eUsers });
  }, []);

  useEffect(() => {
    setCountries(
      eUsers._getColumnData(
        {
          columns: [
            ["country_id", "value"],
            ["country_name", "label"]
          ],
          mode: "unique",
          orderBy: "label"
          // topping:defC
        },
        "",
        {}
      )
    );
  }, [eUsers]);

  useEffect(() => {
   // console.log(selCountries);
    let _rule = []; //(selCountries.value===0)?[]:{country_id:selCountries.value};
    if (selCountries.length > 0) {
      let _cts = getSelectedArray(selCountries);
      _rule.push(function (me) {
        return _cts.includes(me.country_id);
      });
    }
    setRoles(
      eUsers._getColumnData(
        {
          columns: [
            ["role_id", "value"],
            ["role_name", "label"]
          ],
          mode: "unique",
          orderBy: "label",
          topping: defR
        },
        "",
        _rule
      )
    );
    setSelRoles(defR);
    setSelUsers(defU);
  }, [selCountries]);
  useEffect(() => {
    // let _rule=(selRoles.value===0)?[]:{role_id:selRoles.value};
    let _rule = [];

    if (selRoles.value > 0) {
      _rule.push(function (me) {
        return me.role_id == selRoles.value;
      });
    }
    if (selCountries.length > 0) {
      let _cts = getSelectedArray(selCountries);
      _rule.push(function (me) {
        return _cts.includes(me.country_id);
      });
    }

    //alert(_rule);
    setUsers(
      eUsers._getColumnData(
        {
          columns: [
            ["id", "value"],
            ["name", "label"]
          ],
          mode: "unique",
          orderBy: "label",
          topping: defU
        },
        "",
        _rule
      )
    );
    setSelUsers(defU);
  }, [selRoles]);
  useEffect(() => {
    let _rules = [];
    if (selCountries.length > 0) {
     // console.log(selCountries);
      let _cts = getSelectedArray(selCountries);
      _rules.push(function (me) {
        return _cts.includes(me.country_id);
      });
    }
    if (selRoles.value > 0) {
      _rules.push(function (me) {
        return me.role_id === selRoles.value;
      });
    }
   // console.log("rule", _rules);
    if (selUsers.value > 0) {
      _rules.push(function (me) {
        return me.id === selUsers.value;
      });
    }
    
    setLoading(true);
    //fillter data
    //approach 1: filter into a branch and convert json
    // eUsers._where(_rules, "filter", "id", "");
    // console.log('brs',eUsers._branches);
    //setTableUserData(eUsers._toJson('filter');

    //approach 2: convert json with filtering rule
    //first argument source branch
    setTableUserData(eUsers._toJson("", _rules));
  }, [selUsers]);
  useEffect(() => {
    setTimeout(function () {
      setLoading(false);
    }, 20);
  }, [tableUserData]);
  return (
    <>
      <Select
        id="countries_select"
        isMulti
        isSearchable
        name="country"
        value={selCountries}
        options={countries}
        onChange={(sel) => {
          setSelCountries(sel);
        }}
      />
      <Select
        id="roles_select"
        isSearchable
        name="role"
        options={roles}
        value={selRoles}
        onChange={(sel) => {
          setSelRoles(sel);
        }}
      />
      <Select
        id="users_select"
        isSearchable
        name="user"
        value={selUsers}
        options={users}
        onChange={(sel) => {
          setSelUsers(sel);
        }}
      />

      {loading ? (
        <></>
      ) : (
        <>
          <SimpleTableComponent columns={columns} list={tableUserData} />
        </>
      )}
    </>
  );
}