dt-toolbox 7.4.8 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README_v.4.x.x.md DELETED
@@ -1,532 +0,0 @@
1
- # DT Toolbox v.4.x.x and v.3.x.x
2
-
3
- - [Documentation for old v.2.x.x is here](https://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.2.x.x.md)
4
-
5
- Execute operations over deep object structures without worries. Compare, modify, reshape or extract data. Immutability is taken as consideration by this library.
6
-
7
- What you can do:
8
- - Library knows some data-types and supports conversion among them;
9
- - Modify objects: add/update/overwrite/insert/combine/append/prepend;
10
- - Compare objects: identical/change/same/different/missing;
11
- - Accumulative data selections: find/parent/folder;
12
- - Accumulative filter selection: limit/keep/remove/deep;
13
- - Extract and manipulate data chunks;
14
-
15
-
16
- ## Installation
17
-
18
- Install for node.js projects by writing in your terminal:
19
- ```
20
- npm install dt-toolbox --save
21
- ```
22
-
23
- Once it has been installed, it can be used by writing this line of JavaScript:
24
- ```js
25
- let dtbox = require ( 'dt-toolbox')
26
- ```
27
-
28
- **Installation for browsers**: Grab file 'dist/dt-toolbox.min.js' and put it inside the project. Request the file from HTML page. Global variable 'dtbox' is available for use.
29
-
30
-
31
- Note:
32
- Library is using 'generator functions'. If support for old browsers
33
- is required, add a polyfill for 'generators' or get back to version 2.x.x of
34
- the library.
35
-
36
-
37
-
38
- ## APIs Reference
39
-
40
- Dtbox API methods with a short description:
41
- ```js
42
- const API = {
43
- // DT I/O Operations
44
- init : 'Convert any object to flat data-type'
45
- , load : 'Load a flat data-type'
46
- , loadFast : 'Important! Method is depricated. Use load instead'
47
-
48
- , preprocess : 'Apply custom modifier to initial data.
49
- , add : 'Add data and keep existing data'
50
- , update : 'Updates only existing data fields'
51
- , overwrite : 'Add new data to DT object. Overwrite existing fields'
52
- , insert : 'Insert data on specified key, when the key represents an array'
53
- , combine : 'Combine values for simular keys in arrays'
54
- , append : 'Combine values for duplicated keys. main + update'
55
- , prepend : 'Combine values for duplicated keys. update + main'
56
- , log : 'Executes callback with errors list as argument'
57
- , empty : 'Empty object with export methods'
58
-
59
- // Provide Results
60
- , replace : 'Get this._selection.result as a main data'
61
- , attach : 'Attach this._selection.result to the main data. Set point of connection'
62
- , spread : 'Returns result of selection in a calback function'
63
- , spreadAll : 'Select all and returns it with one command in a callback function'
64
- , export : 'Returns result of selection'
65
- , exportAll : 'Select all and returns it with one command'
66
-
67
- // Compare Operations
68
- , identical : 'Value compare. Reduce data to identical key/value pairs'
69
- , change : 'Value compare. Reduce to key/value pairs with different values'
70
- , same : 'Key compare. Returns key/value pairs where keys are the same'
71
- , different : 'Key compare. Returns key/value pairs where key does not exist'
72
- , missing : 'Key compare. Returns key/value pairs that are missing'
73
-
74
- // Selectors
75
- , select : 'Initialize a new selection'
76
- , parent : 'Selector. Apply conditions starting from parent level'
77
- , find : 'Selector. Fullfil select with list of arguments that contain specific string'
78
- , all : "Selector. Same as find ('root')"
79
- , folder : "Selector. Fullfil selection with 'midFlat' object props"
80
- , space : "Selector. Same as 'folder'"
81
- , deepObject : "Selector. Fullfil '_select' with deepest object elements"
82
- , deepArray : "Selector. Fullfil '_select' with deepest array elements"
83
- , invert : 'Selector. Invert existing selection'
84
- , assemble : "Converts selection into 'array of objects' or 'single flat object'"
85
- , purify : 'Removes all empty structures ( no props ) from the selection'
86
-
87
- // Filters
88
- , limit : 'Filter. Reduces amount of records in the selection'
89
- , keep : 'Filter. Keeps records in selection if check function returns true'
90
- , remove : 'Filter. Removes records from selection if check function returns true'
91
- , deep : "Filter. Arguments ( num, direction - optional). Num mean level of deep. Deep '0' mean root members"
92
-
93
- // Modifiers
94
- , withData : 'Generate "this._select.result" from the official data. Modifier will work with this data'
95
- , withSelection : 'Generate "this._select.result" content. Modifier will work with this data'
96
- , flatten : 'Mix existing objects in a single object'
97
- , mix : 'Mix objects in order. Start with a host and provide guests list []'
98
- , keyPrefix : 'Modify key as object name+key. Separator-symbol default: emptySpace. It can be modified'
99
- , reverse : 'Change place of keys and values'
100
- }; // API
101
- ```
102
-
103
-
104
-
105
-
106
-
107
- # How it works?
108
-
109
- 1. First: Insert data in dt-toolbox. Use `load` for `flat` data-type or `init` for other data-types. Mix with other objects by using 'add/update/overwrite/combine' if you need. Use 'preprocess' to change data-type before assimilate it.
110
-
111
- 2. Select! Without selection, dt-toolbox will return an empty object. Selection respresents the information that should be extracted from the data. Result of selectors is accumulative. Filters will be applied to already selected data.
112
-
113
- 3. Spread/Export the result. Create new data structure according selection and provide it in required data-type.
114
-
115
- DT Toolbox supports chaining syntax and is that simple. Let's see some examples...
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
- ## Examples
127
-
128
- Here are some use cases, but if you're interested, test-cases are on your disposal.
129
- ### Basics
130
- Let's have a standard JS object:
131
-
132
- ```js
133
- let st = {
134
- name : {
135
- firstName : 'Peter'
136
- , surname : 'Naydenov'
137
- }
138
- , friends : [ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ]
139
- }
140
-
141
- ```
142
- Put the **st** data into dt-toolbox:
143
-
144
- ```js
145
- let dt = dtbox.init ( standard )
146
- ```
147
-
148
- Internal representation of data is based on `flat` data-type. Type `flat` has two elements: value and structure.
149
- **Value** represents primitive values and their location. **Structure** represents existing flat objects and their relations.
150
- Our standard object inside the library will look like:
151
-
152
- ```js
153
- dt.structure = [
154
- // type i object descriptors [i, name]
155
- [ 'object', 0, [1, name], [2, friends] ] // Root object and relation with other objects
156
- , [ 'object', 1 ] // st.name object. Object has only primitive values.
157
- , [ 'array' , 2 ] // st.friends array. Array has only primitive values.
158
- ]
159
-
160
- dt.value = { // Represents a primitive props and their location
161
- 'root/1/firstName' : 'Peter'
162
- , 'root/1/surname' : 'Naydenov'
163
- , 'root/2/0' : 'Tisho'
164
- , 'root/2/1' : 'Dibo'
165
- , 'root/2/2' : 'Ivo'
166
- , 'root/2/3' : 'Vasil'
167
- }
168
- }
169
- ```
170
-
171
- ::: warning
172
- Internal representation is '*LIKE*' flat data-type but not the data-type itself. Type `flat` is array with two elements: structure and value `[structure, value]`. Internal representation has these two elements but they are like props. `dt = { structure, value }`.
173
- :::
174
-
175
-
176
-
177
- Extract a flat information:
178
- ```js
179
- dt.spreadAll ( 'flat', res => {
180
- // Data-type 'Flat': An array with 2 entries: [structure, value]
181
- })
182
- // other way to receive same result:
183
- let myFlat = dt.exportAll ( 'flat' )
184
- ```
185
-
186
-
187
-
188
- Let's play with DT Toolbox:
189
-
190
- ```js
191
- let
192
- dtResult
193
- , stResult
194
- , friendList
195
- ;
196
-
197
- dtbox
198
- .init(st) // Init data. Converts ST to DT
199
- .select() // Starting new selection
200
- .all() // Select all data
201
- .spread ( 'flat', dt => dtResult = dt ) // Returns as `flat` data-type
202
- .spread ( 'std', dt => stResult = dt ) // Convert back to original 'st' object
203
- .select () // Start new selection. Will remove previous selection.
204
- .find ( 'friends' ) // select keys that contain 'friends'
205
- .spread ( 'std', dt => friendList = dt ) //= { friends :[ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ] }
206
- .assemble ()
207
- .spread ( 'std' => friendList = dt ) // = [ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ]
208
- // 'assemble' removes all duplicated elements in the keys and simplifies the result.
209
-
210
- ```
211
-
212
- ### Convert ST to DT objects
213
-
214
- ```js
215
- let result;
216
- dtbox
217
- .init(st)
218
- .spreadAll ( 'flat', dt => result = dt );
219
- ```
220
-
221
- ### Mixing objects - Add/Update/Overwrite
222
-
223
- Add and update will consider existing data:
224
- - 'Add' method will be applied only for non-existing properties;
225
- - 'Update' method will works only on existing properties;
226
-
227
- Overwrite will 'add' and 'update'.
228
-
229
- ```js
230
-
231
- let user = {
232
- name : 'Peter'
233
- , age : 42
234
- }
235
-
236
- dtbox
237
- .init ( user )
238
- .add ({
239
- age : 25 // 'add' will ignore this. Age is already defined.
240
- , gender : 'male' // Will add this.
241
- }, { type: 'std'})
242
- .update ({
243
- age : 50 // Will update
244
- eyes : 'blue' // Will ignore this.
245
- }, { type: 'std'})
246
- .overwrite ({
247
- age : 43 // Will update
248
- , hobby : 'skating' // Will add
249
- }, { type: 'std'})
250
-
251
- // The object (dtbox.value) will look like:
252
- /*
253
- {
254
- 'root/0/name' : 'Peter'
255
- , 'root/0/age' : 43
256
- , 'root/0/gender' : 'male'
257
- , 'root/0/hobby' : 'skating'
258
- }
259
-
260
- /*
261
-
262
- ```
263
-
264
-
265
- ### Parent
266
-
267
- ```js
268
-
269
- let result;
270
- let data = {
271
- 'school' : [
272
- { name: 'Ivan', age: 14 }
273
- , { name: 'Georgy', age: 15 }
274
- , { name: 'Adi', age: 11 }
275
- , { name: 'Kati', age: 11 }
276
- ]
277
- , 'sports' : [
278
- { name: 'Iva', age: 28 }
279
- , { name: 'Stoyan', age: 36 }
280
- ]
281
- , 'work' : [
282
- { name: 'Hristo', age: 38 }
283
- , { name: 'Lachezar', age: 33 }
284
- , { name: 'Veselina', age: 35 }
285
-
286
- ]
287
- , 'recent' : {
288
- 'classmates' : [
289
- { name: 'Anton', age: 42 }
290
- , { name: 'Miroslava', age: 42 }
291
- ]
292
- , 'social' : [
293
- { name: 'Iliana', age: 61 }
294
- , { name: 'Tzvetan', age: 19 }
295
- ]
296
- }
297
- }
298
-
299
- // Let's create list of all contacts uder 40 years old:
300
-
301
- dtbox
302
- .init ( data )
303
- .select ()
304
- .parent ( 'name', person => person.age < 40 )
305
- .assemble ()
306
- .spread ( 'std' , dt => result = dt )
307
-
308
- /*
309
- result will look like this:
310
-
311
- [
312
- { name: 'Tzvetan', age: 19 },
313
- { name: 'Ivan', age: 14 },
314
- { name: 'Iva', age: 28 },
315
- { name: 'Hristo', age: 38 },
316
- { name: 'Georgy', age: 15 },
317
- { name: 'Stoyan', age: 36 },
318
- { name: 'Lachezar', age: 33 },
319
- { name: 'Adi', age: 11 },
320
- { name: 'Veselina', age: 35 },
321
- { name: 'Kati', age: 11 }
322
- ]
323
-
324
- */
325
- ```
326
-
327
-
328
-
329
- ### Purify
330
-
331
- Cleaning empty structures till version 3 of the library was without alternative. Keep empty structures was recognized as a need and it's now a default behaviour. Remove empty structures by using 'purify' function as in this example:
332
-
333
- ```js
334
- const test = {
335
- name : 'Peter'
336
- , arr : [ 1, 15 ]
337
- , de : { me: ['eho', 'ha'] }
338
- , se : { le: {} }
339
- , ze : []
340
- };
341
- dtbox
342
- .init ( test )
343
- .select ()
344
- .all ()
345
- .purify ()
346
- .spread ( 'std', x => {
347
- /** Result after purify will be:
348
- * x = {
349
- * name: Peter
350
- * , arr : [1,15]
351
- * , de : { me: ['eho','ha']}
352
- * }
353
- */
354
- })
355
- }) // it purify
356
- ```
357
-
358
-
359
- ## Data-types
360
-
361
- The library can spread data-selection as different data-types. Let's see how initial data will be interpreted in available data-types. Here is our initial `standard`(std) data:
362
- ```js
363
- const data = {
364
- name: 'Peter'
365
- , familyMembers : [ 'Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
366
- , shoes : {
367
- winter : [ 'Keen', 'Head']
368
- , summer : [ 'Lotto', 'Asics' ]
369
- }
370
- }
371
- ```
372
-
373
- ### Standard ( std )
374
- Standard data-type will look exactly as initial data.
375
- ```js
376
- {
377
- name: 'Peter'
378
- , familyMembers : [ 'Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
379
- , shoes : {
380
- winter : [ 'Keen', 'Head']
381
- , summer : [ 'Lotto', 'Asics' ]
382
- }
383
- }
384
- ```
385
-
386
-
387
- ### Flat ( shortFlat )
388
- It's a flat description of the object. It's an array with two elements. First element describes the structure of the object, second element - the values.
389
- **Structure**: Array of flatDescriptions. FlatDescription is array where first element is the type of the object (object or array), second is the index. If there are more then 2 elements, we have connection descriptions. ConnectionDescription is array of 2 elements. First is the index of connected other object, second is the property name of the connection.
390
- In our example: We have object, that have property `familyMembers` that is array and other property `shoes` that is an object. Object `shoes` have 2 properties (winter,summer) that are arrays.
391
- **Value**: Key describes the position of the property that have a primitive value. Value is just that primitive value. Key always have 3 elements separated by '/'. First element is always `root`, second is the `id` of the object (from structure description), third is the name of the property. If structure object is 'array' then property name will be a number representing the position into the array.
392
- ```js
393
- [
394
- // the structure description
395
- [
396
- [ 'object', 0, [1,'familyMembers'], [2,'shoes'] ]
397
- , [ 'array' , 1 ]
398
- , [ 'object', 2 , [3, 'winter'], [4, 'summer'] ]
399
- , [ 'array' , 3 ]
400
- , [ 'array' , 4 ]
401
- ]
402
- // the value description
403
- , {
404
- 'root/0/name' : 'Peter'
405
- , 'root/1/0' : 'Veselina'
406
- , 'root/1/0' : 'Veselina'
407
- , 'root/1/1' : 'Iskra'
408
- , 'root/1/2' : 'Maria'
409
- , 'root/1/3' : 'Vasil'
410
- , 'root/1/4' : 'Vladimir'
411
- , 'root/1/5' : 'Petya'
412
- , 'root/3/0' : 'Keen'
413
- , 'root/3/1' : 'Head'
414
- , 'root/4/0' : 'Lotto'
415
- , 'root/4/1' : 'Asics'
416
- }
417
- ]
418
- ```
419
-
420
-
421
- ### MidFlat
422
- Object where keys represents "location" of the flat object. Value is always an object. Props are names. If data-structure is array, props are numbers:
423
-
424
- ```js
425
- {
426
- 'root' : { name: 'Peter' }
427
- , 'root/familyMembers' : {
428
- '0' : 'Veselina'
429
- , '1' : 'Iskra'
430
- , '2' : 'Maria'
431
- , '3' : 'Vasil'
432
- , '4' : 'Vladimir'
433
- , '5' : 'Petya'
434
- }
435
- , 'root/shoes/winter' : {
436
- '0' : 'Keen'
437
- , '1' : 'Head'
438
- }
439
- , 'root/shoes/summer' : {
440
- '0' : 'Lotto'
441
- '1' : 'Asics'
442
- }
443
- }
444
- ```
445
-
446
-
447
-
448
-
449
-
450
- ### Breadcrumbs
451
-
452
- It's a flat interpratation of the data and looks like this:
453
- ```js
454
- {
455
- 'root/name' : 'Peter'
456
- , 'root/familiMembers/0' : 'Veselina'
457
- , 'root/familyMembers/1' : 'Iskra'
458
- , 'root/familyMembers/2' : 'Maria'
459
- , 'root/familyMembers/3' : 'Vasil'
460
- , 'root/familyMembers/4' : 'Vladimir'
461
- , 'root/familyMembers/5' : 'Petya'
462
- , 'root/shoes/winter/0' : 'Keen'
463
- , 'root/shoes/winter/1' : 'Head'
464
- , 'root/shoes/summer/0' : 'Lotto'
465
- , 'root/shoes/summer/1' : 'Asics'
466
- }
467
- ```
468
-
469
-
470
- ### Files
471
- Data is interpreted like file/folder description.
472
- ```js
473
- [
474
- 'root/name/Peter'
475
- , 'root/familiMembers/Veselina'
476
- , 'root/familyMembers/Iskra'
477
- , 'root/familyMembers/Maria'
478
- , 'root/familyMembers/Vasil'
479
- , 'root/familyMembers/Vladimir'
480
- , 'root/familyMembers/Petya'
481
- , 'root/shoes/winter/Keen'
482
- , 'root/shoes/winter/Head'
483
- , 'root/shoes/summer/Lotto'
484
- , 'root/shoes/summer/Asics'
485
- ]
486
- ```
487
-
488
-
489
-
490
- ### Tuples
491
-
492
- Array of tuples. First element represents location + property name, second is the value.
493
-
494
- ```js
495
- [
496
- ['name', 'Peter' ]
497
- , ['familiMembers', 'Veselina']
498
- , ['familyMembers', 'Iskra']
499
- , ['familyMembers', 'Maria']
500
- , ['familyMembers', 'Vasil']
501
- , ['familyMembers', 'Vladimir']
502
- , ['familyMembers', 'Petya']
503
- , ['shoes/winter' , 'Keen']
504
- , ['shoes/winter' , 'Head']
505
- , ['shoes/summer' , 'Lotto']
506
- , ['shoes/summer' , 'Asics']
507
- ]
508
- ```
509
-
510
-
511
-
512
-
513
-
514
- ## External Links
515
-
516
- - [Migration guide](https://github.com/PeterNaydenov/dt-toolbox/blob/master/Migration.guide.md)
517
- - [History of changes](https://github.com/PeterNaydenov/dt-toolbox/blob/master/Changelog.md)
518
- - [Documentation v.2.x.x](https://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.2.x.x.md)
519
-
520
-
521
-
522
-
523
- ## Credits
524
- 'dt-toolbox' was created and supported by Peter Naydenov.
525
-
526
-
527
-
528
-
529
-
530
- ## License
531
- 'dt-toolbox' is released under the [MIT License](http://opensource.org/licenses/MIT).
532
-