Skip to content

Commit 9e08510

Browse files
committed
documentation
1 parent 2481a1e commit 9e08510

5 files changed

Lines changed: 363 additions & 334 deletions

File tree

README.md

Lines changed: 356 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
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
20155
import { 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
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stackpress/lib",
3-
"version": "0.3.19",
3+
"version": "0.3.20",
44
"license": "Apache-2.0",
55
"description": "Shared library used across stackpress projects",
66
"author": "Chris <chris@incept.asia>",

src/queue/ItemQueue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { Item } from '../types';
44
/**
55
* An item queue that consumes in order of priority and FIFO
66
*/
7-
export default class TaskQueue<I> {
7+
export default class ItemQueue<I> {
88
//The in memory task queue. Dont use
99
//Set because we will be sorting constantly
1010
public readonly queue: Item<I>[] = [];

src/system/FileLoader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export default class FileLoader {
7070
if (cwd === '/') {
7171
throw Exception.for('Cannot find node_modules');
7272
}
73-
if (this._fs.existsSync(path.resolve(cwd, 'node_modules', '@stackpress', 'types'))) {
73+
if (this._fs.existsSync(path.resolve(cwd, 'node_modules', '@stackpress', 'lib'))) {
7474
return path.resolve(cwd, 'node_modules');
7575
}
7676
return this.modules(path.dirname(cwd));

0 commit comments

Comments
 (0)