66[ ![ Commits] ( https://img.shields.io/github/last-commit/stackpress/lib )] ( https://github.com/stackpress/lib/commits/main/ )
77[ ![ License] ( https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat )] ( https://github.com/stackpress/lib/blob/main/LICENSE )
88
9- Shared library used across stackpress projects
9+ Shared library used across Stackpress projects. Standardize type
10+ definitions across different projects and potentially save time for
11+ developers who would otherwise need to define these common types
12+ themselves.
1013
1114## Install
1215
@@ -16,6 +19,358 @@ $ npm i @stackpress/lib
1619
1720## Usage
1821
22+ - [ Data] ( #data )
23+ - [ Nest] ( #nest )
24+ - [ ReadonlyMap] ( #rmap )
25+ - [ ReadonlyNest] ( #rnest )
26+ - [ ReadonlySet] ( #rset )
27+ - [ Event] ( #event )
28+ - [ EventEmitter] ( #emitter )
29+ - [ EventRouter] ( #router )
30+ - [ EventTerminal] ( #terminal )
31+ - [ Queue] ( #queue )
32+ - [ ItemQueue] ( #item )
33+ - [ TaskQueue] ( #task )
34+ - [ File System] ( #system )
35+ - [ Exception] ( #exception )
36+ - [ Reflection] ( #reflection )
37+ - [ Status] ( #status )
38+
39+ <a name =" data " ></a >
40+
41+ ## Data
42+
43+ The data library helps with common data management scenarios.
44+
45+ - [ Nest] ( #nest )
46+ - [ ReadonlyMap] ( #rmap )
47+ - [ ReadonlyNest] ( #rnest )
48+ - [ ReadonlySet] ( #rset )
49+
50+ <a name =" nest " ></a >
51+
52+ ### Nest
53+
54+ A nest is a data object that contain other nested data objects or arrays.
55+
56+ ``` js
57+ import { Nest , UnknownNest } from ' @stackpress/lib' ;
58+
59+ const nest = new Nest < UnknownNest> ({
60+ foo: { bar: ' zoo' }
61+ });
62+
63+ registry .set (' foo' , ' zoo' , [' foo' , ' bar' , ' zoo' ])
64+
65+ nest .has (' foo' ) // --> true
66+ nest .has (' foo' , ' bar' ) // --> true
67+ nest .has (' bar' , ' foo' ) // --> false
68+ nest .get (' foo' , ' zoo' ) // --> ['foo', 'bar', 'zoo']
69+ nest .get (' foo' , ' zoo' , 1 ) // --> 'bar'
70+ nest .get < string> (' foo' , ' zoo' , 1 ) // as string
71+
72+ registry .remove (' foo' , ' bar' )
73+
74+ nest .has (' foo' , ' bar' ) // --> false
75+ nest .has (' foo' , ' zoo' ) // --> true
76+ ```
77+
78+ <a name =" rmap " ></a >
79+
80+ ### Readonly Map
81+
82+ A type of ` Map ` that is readonly.
83+
84+ ``` js
85+ import { ReadonlyMap } from ' @stackpress/lib' ;
86+
87+ const map = new ReadonlyMap ([[' foo' , ' bar' ], [' bar' , ' zoo' ]]);
88+
89+ map .get (' foo' ) // --> bar
90+ map .has (' bar' ) // --> zoo
91+
92+ map .entries () // --> [['foo', 'bar'], ['bar', 'zoo']]
93+
94+ map .forEach (console .log );
95+ ```
96+
97+ <a name =" rnest " ></a >
98+
99+ ### Readonly Nest
100+
101+ A type of ` Nest ` that is readonly.
102+
103+ ``` js
104+ import { ReadonlyNest , UnknownNest } from ' @stackpress/lib' ;
105+
106+ const nest = new Nest < UnknownNest> ({
107+ foo: { bar: ' zoo' }
108+ });
109+
110+ nest .has (' foo' ) // --> true
111+ nest .has (' foo' , ' bar' ) // --> true
112+ nest .has (' bar' , ' foo' ) // --> false
113+ nest .get (' foo' , ' zoo' ) // --> ['foo', 'bar', 'zoo']
114+ nest .get (' foo' , ' zoo' , 1 ) // --> 'bar'
115+ nest .get < string> (' foo' , ' zoo' , 1 ) // as string
116+ ```
117+
118+ <a name =" rset " ></a >
119+
120+ ### Readonly Set
121+
122+ A type of ` Set ` that is readonly.
123+
124+ ``` js
125+ import { ReadonlySet } from ' @stackpress/lib' ;
126+
127+ const set = new ReadonlySet ([' foo' , ' bar' , ' zoo' ]);
128+
129+ set .size // --> 3
130+ set .has (' bar' ) // --> true
131+ set .values () // --> ['foo', 'bar', 'zoo']
132+
133+ set .forEach (console .log );
134+ ```
135+
136+ <a name =" event " ></a >
137+
138+ ## Event
139+
140+ The event library is a set of tools for event driven projects.
141+
142+ - [ EventEmitter] ( #emitter )
143+ - [ EventRouter] ( #router )
144+ - [ EventTerminal] ( #terminal )
145+
146+ <a name =" emitter " ></a >
147+
148+ ### EventEmitter
149+
150+ A class that implements the observer pattern for handling events.
151+ The interface follows ` node:events ` , but you can set priority levels per
152+ event action. EventEmitter works on server and browser.
153+
19154``` js
20155import { EventEmitter } from ' @stackpress/lib' ;
156+
157+ type EventMap = Record< string, [ number ]> & {
158+ ' trigger something' : [ number ]
159+ };
160+
161+ const emitter = new EventEmitter < EventMap> ()
162+
163+ emitter .on (' trigger something' , async x => {
164+ console .log (' something triggered' , x + 1 )
165+ })
166+
167+ emitter .on (/ trigger (something)/ , async x => {
168+ console .log (' (something) triggered' , x + 2 )
169+ }, 2 )
170+
171+ await emitter .trigger (' trigger something' , 1 )
172+ ```
173+
174+ <a name =" router " ></a >
175+
176+ ### EventRouter
177+
178+ An ` expressjs ` like router that uses ` EventEmitter ` in the back-end.
179+ Like ` EventEmitter ` , you can set priority levels per route and works
180+ also in the browser.
181+
182+ ``` js
183+ import { EventRouter } from ' @stackpress/lib' ;
184+
185+ type RouteMap = Record< string, [ Map , Map ]> ;
186+
187+ const router = new EventRouter < RouteMap> ()
188+
189+ router .get (' /foo/bar' , async (req , res ) => {
190+ res .set (' foo' , ' bar' )
191+ })
192+
193+ router .all (' /foo/bar' , async (req , res ) => {
194+ res .set (' bar' , req .get (' bar' ))
195+ }, 2 )
196+
197+ // router.connect('/foo/bar', async (req, res) => {})
198+ // router.delete('/foo/bar', async (req, res) => {})
199+ // router.head('/foo/bar', async (req, res) => {})
200+ // router.options('/foo/bar', async (req, res) => {})
201+ // router.patch('/foo/bar', async (req, res) => {})
202+ // router.post('/foo/bar', async (req, res) => {})
203+ // router.put('/foo/bar', async (req, res) => {})
204+ // router.trace('/foo/bar', async (req, res) => {})
205+ // router.route('METHOD', '/foo/bar', async (req, res) => {})
206+
207+ await router .emit (' GET /foo/bar' , new Map ([[' foo' , ' zoo' ]]), new Map ())
208+ ```
209+
210+ <a name =" terminal " ></a >
211+
212+ ### EventTerminal
213+
214+ A basic event driven cli toolset that uses events in the background.
215+ This enables using events on the command line.
216+
217+ ``` js
218+ import { EventTerminal } from ' @stackpress/lib' ;
219+
220+ const cli = new EventTerminal (process .argv )
221+
222+ cli .on (' foo' , async params => {
223+ const foo = cli .expect ([ ' foo' , ' f' ], ' bar' )
224+ EventTerminal .info (foo) // --> bar
225+ console .log (params) // --> { foo: 'bar' }
226+ })
227+
228+ await cli .run ()
229+ ```
230+
231+ <a name =" queue " ></a >
232+
233+ ## Queue
234+
235+ The queue library is used to order items like callbacks and return
236+ the correct sequence.
237+
238+ - [ ItemQueue] ( #item )
239+ - [ TaskQueue] ( #task )
240+
241+ <a name =" item " ></a >
242+
243+ ### ItemQueue
244+
245+ An item queue orders and consumes items sequencially (FIFO by default).
246+
247+ ``` js
248+ import { ItemQueue } from ' @stackpress/lib' ;
249+
250+ const queue = new ItemQueue < string> ()
251+
252+ queue .push (' a' )
253+
254+ queue .shift (' b' )
255+
256+ queue .add (' c' , 10 )
257+
258+ queue .consume () // --> c
259+ queue .consume () // --> b
260+ queue .consume () // --> a
261+ ```
262+
263+ <a name =" task " ></a >
264+
265+ ### TaskQueue
266+
267+ A task queue orders and runs callbacks sequencially.
268+
269+ ``` js
270+ import { TaskQueue } from ' @stackpress/lib' ;
271+
272+ const queue = new TaskQueue ()
273+
274+ queue .push (async x => {
275+ console .log (x + 1 )
276+ })
277+
278+ queue .shift (async x => {
279+ await Helper .sleep (2000 )
280+ console .log (x + 2 )
281+ })
282+
283+ queue .add (async x => {
284+ console .log (x + 3 )
285+ }, 10 )
286+
287+ await queue .run (1 )
288+ ```
289+
290+ <a name =" system " ></a >
291+
292+ ## FileSystem
293+
294+ The file system library is an interface to interact with various file
295+ systems * (ie. node: fs , virtual fs, browser fs, webpack fs, etc..)* .
296+ It just requires the minimum functions compared to ` node:fs ` .
297+
298+ ``` js
299+ interface FileSystem {
300+ existsSync (path: string): boolean;
301+ readFileSync (path: string, encoding: BufferEncoding): string;
302+ realpathSync (string: string): string;
303+ lstatSync (path: string): FileStat;
304+ writeFileSync (path: string, data: string): void ;
305+ mkdirSync (path: string, options?: FileRecursiveOption): void
306+ createReadStream (path: string): FileStream;
307+ unlinkSync (path: string): void ;
308+ };
309+ ```
310+
311+ A file loader is a set of common tools for locating, loading, importing
312+ files through out your project and ` node_modules ` .
313+
314+ ``` js
315+ import { NodeFS , FileLoader } from ' @stackpress/lib' ;
316+
317+ const loader = new FileLoader (new NodeFS ());
318+
319+ loader .modules () // --> ./node_modules/
320+ loader .relative (' /path/from/source.file' , ' /path/to/destination.file' ) // --> '../destination'
321+ loader .resolve (' @/project/index' ) // --> [cwd]/project/index.js
322+ loader .absolute (' ../project/index' ) // --> [cwd]/project/index.js
323+ ```
324+
325+ <a name =" exception " ></a >
326+
327+ ## Exception
328+
329+ Exceptions are used to give more information of an error that has occured.
330+
331+ ``` js
332+ import { Exception } from ' @stackpress/lib' ;
333+
334+ const exception = new Exception (' Invalid Parameters: %s' , 2 )
335+ .withErrors ({
336+ name: ' required' ,
337+ pass: ' missing number'
338+ })
339+ .withCode (500 )
340+ .withPosition (100 , 200 )
341+
342+ exception .toResponse () // -->
343+ /* {
344+ code: 500,
345+ status: 'Server Error',
346+ error: 'Invalid Parameters 2',
347+ start: 100,
348+ end: 200
349+ }*/
350+
351+ exception .trace () // --> [{ method, file, line, char}, ...]
352+
353+ throw Exception .for (' Unknown Error' )
354+ ```
355+
356+ <a name =" reflection " ></a >
357+
358+ ## Reflection
359+
360+ Uses ` CallSite ` to produce proper stack tracing and information about
361+ functions being executed.
362+
363+ ``` js
364+ import { Reflection } from ' @stackpress/lib' ;
365+
366+ const reflection = Reflection .stack (); // --> Reflection
367+
368+ reflection[0 ].column // --> 3
369+ reflection[0 ].file // --> /path/to/file
370+ reflection[0 ].func // --> Function
371+ reflection[0 ].funcName // --> 'main'
372+ reflection[0 ].line // --> 3
373+ reflection[0 ].method // --> <none>
374+ reflection[0 ].self // --> undefined
375+ reflection[0 ].toObject ()
21376```
0 commit comments