UNPKG

3.17 kBMarkdownView Raw
1<div align="right">
2<h1><code>tabling</code></h1>
3<br />
4<br />
5
6<p><code>npm add tabling</code> makes objects lazy</p>
7<span>
8<a href="https://github.com/maraisr/tabling/actions/workflows/ci.yml">
9 <img src="https://github.com/maraisr/tabling/actions/workflows/ci.yml/badge.svg"/>
10</a>
11<a href="https://npm-stat.com/charts.html?package=tabling">
12 <img src="https://badgen.net/npm/dw/tabling?labelColor=black&color=black&cache=600" alt="downloads"/>
13</a>
14<a href="https://packagephobia.com/result?p=tabling">
15 <img src="https://badgen.net/packagephobia/install/tabling?labelColor=black&color=black" alt="size"/>
16</a>
17<a href="https://bundlephobia.com/result?p=tabling">
18 <img src="https://badgen.net/bundlephobia/minzip/tabling?labelColor=black&color=black" alt="size"/>
19</a>
20</span>
21
22<br />
23<br />
24</div>
25
26Commit a getter's result for one-time evaluation.
27
28## ⚙️ Install
29
30```sh
31npm add tabling
32```
33
34## 🚀 Usage
35
36```ts
37import { tabling } from "tabling";
38
39const myObject = tabling({
40 get answer() {
41 return discover_the_meaning_of_life();
42 },
43});
44
45myObject.answer; // 42
46```
47
48Where ordinarily, that would look like `{ answer: discover_the_meaning_of_life() }` for a value
49somebody may never read.
50
51## 🔎 API
52
53#### Module: [`tabling`](./src/index.js)
54
55The main and _default_ module and us `Proxy` based. Everything is lazy here, the object is built-up
56over which keys are consumed.
57
58> No upfront cost, and slightly slower read time.
59
60#### Module: [`tabling/warm`](./src/warm.js)
61
62A `object` based implementation, whereby the result is setup at evaluation time.
63
64> Upfront cost, but no read time.
65
66### 🤔 But which one should I use?
67
68Naturally riddled with assumptions. But If you see the benchmarks below, generally the advice is.
69
701. if you've got a long-running process with many reads, the `/warm` sub-module is what youre after.
71 - think like a web-server, where the object is module-scope.
722. browsers, you're probably after the `default` (proxy based) api. Very minimal reads, and want
73 fast as possible startup time.
74
75So with that, and by no means bullet-proof answer;
76
77- server — `tabling/warm`
78- browser - `tabling`
79
80## 💨 Benchmark
81
82> via the [`/bench`](/bench) directory with Node v17.2.0
83
84```
85benchmark :: setup
86 default x 2,442,456 ops/sec ±1.92% (89 runs sampled)
87 warm x 503,581 ops/sec ±0.69% (93 runs sampled)
88
89benchmark :: jit
90 default x 2,168,685 ops/sec ±1.25% (91 runs sampled)
91 warm x 430,936 ops/sec ±1.49% (91 runs sampled)
92
93benchmark :: aot
94 default x 27,579,584 ops/sec ±0.52% (89 runs sampled)
95 warm x 133,821,620 ops/sec ±0.34% (93 runs sampled)
96```
97
98> **setup** — the time to construct the object, _without_ reading from it.
99>
100> **jit** — the object is constructed on the hot path, and read from immediately. Think "request
101> bound" objects.
102>
103> **aot** — the object is constructed _ahead of time_, and read later on the hot path. Think "module
104> scope" objects.
105
106## ❤️ Thanks
107
108Special thanks to [@wongmjane](http://twitter.com/wongmjane) for idea!
109
110## License
111
112MIT © [Marais Rossouw](https://marais.io)