dt-toolbox 5.0.0 → 7.0.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/Changelog.md +15 -10
- package/LICENSE +1 -1
- package/Migration.guide.md +63 -1
- package/README.md +996 -346
- package/README_v.2.x.x.md +0 -1
- package/README_v.4.x.x.md +532 -0
- package/README_v.6.x.x.md +1158 -0
- package/package.json +21 -24
- package/src/convertors/index.js +43 -34
- package/src/convertors/midflat.js +76 -132
- package/src/convertors/standard.js +61 -86
- package/src/convertors/tuples.js +171 -0
- package/src/flatData/connect.js +50 -0
- package/src/flatData/export.js +46 -0
- package/src/flatData/filters/list.js +11 -0
- package/src/flatData/filters/listObject.js +13 -0
- package/src/flatData/filters/object.js +12 -0
- package/src/flatData/filters/root.js +12 -0
- package/src/flatData/find.js +20 -0
- package/src/flatData/from.js +33 -0
- package/src/flatData/get.js +29 -0
- package/src/flatData/index.js +101 -0
- package/src/flatData/insert.js +24 -0
- package/src/flatData/like.js +24 -0
- package/src/flatData/look.js +56 -0
- package/src/flatData/push.js +19 -0
- package/src/flatData/save.js +17 -0
- package/src/flatData/set.js +26 -0
- package/src/flatData/setupFilter.js +21 -0
- package/src/flatData/use.js +16 -0
- package/src/flatObject/copy.js +19 -0
- package/src/flatObject/export.js +13 -0
- package/src/flatObject/index.js +55 -0
- package/src/flatObject/insert.js +38 -0
- package/src/flatObject/model.js +32 -0
- package/src/flatObject/query.js +24 -0
- package/src/flatObject/setupFilter.js +12 -0
- package/src/main.js +21 -689
- package/src/mainLib.js +114 -0
- package/src/compareMethod/change.js +0 -21
- package/src/compareMethod/different.js +0 -18
- package/src/compareMethod/identical.js +0 -21
- package/src/compareMethod/index.js +0 -13
- package/src/compareMethod/missing.js +0 -18
- package/src/compareMethod/same.js +0 -18
- package/src/convertors/breadcrumbs.js +0 -148
- package/src/help/extractSelection.js +0 -12
- package/src/help/filterObject.js +0 -25
- package/src/help/hasNumbers.js +0 -14
- package/src/help/index.js +0 -35
- package/src/help/isItPrimitive.js +0 -10
- package/src/help/objectsByLevel.js +0 -16
- package/src/help/reduceTuples.js +0 -29
- package/src/help/sanitizeFlatKeys.js +0 -30
- package/src/help/toBreadcrumbsKeys.js +0 -28
- package/src/help/tuplesToBreadcrumbs.js +0 -25
- package/src/help/updateSelection.js +0 -12
- package/src/help/zipObject.js +0 -24
- package/src/lib/assemble.js +0 -45
- package/src/lib/attach.js +0 -20
- package/src/lib/block.js +0 -33
- package/src/lib/combine.js +0 -38
- package/src/lib/deep.js +0 -23
- package/src/lib/find.js +0 -36
- package/src/lib/folder.js +0 -42
- package/src/lib/index.js +0 -56
- package/src/lib/modify.js +0 -22
- package/src/lib/parent.js +0 -51
- package/src/lib/purify.js +0 -37
- package/src/lib/transform.js +0 -55
- package/src/modifiers/add.js +0 -18
- package/src/modifiers/append.js +0 -18
- package/src/modifiers/combineShallow.js +0 -119
- package/src/modifiers/flatten.js +0 -38
- package/src/modifiers/index.js +0 -34
- package/src/modifiers/insert.js +0 -21
- package/src/modifiers/keyPrefix.js +0 -27
- package/src/modifiers/mix.js +0 -25
- package/src/modifiers/overwrite.js +0 -18
- package/src/modifiers/prepend.js +0 -19
- package/src/modifiers/reverse.js +0 -23
- package/src/modifiers/update.js +0 -18
- package/src/simple.js +0 -49
package/README.md
CHANGED
|
@@ -1,24 +1,52 @@
|
|
|
1
|
-
# DT Toolbox
|
|
2
|
-
*Note: Document is valid for v.5.x.x, v.4.x.x and v.3.x.x*
|
|
1
|
+
# DT Toolbox v.7.x.x
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
- [Documentatation for old v.6.x.x is here](htts://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.6.x.x.md)
|
|
7
7
|
|
|
8
|
-
What you can do:
|
|
9
|
-
- Library knows some data-types and supports conversion among them;
|
|
10
|
-
- Modify objects: add/update/overwrite/insert/combine/append/prepend;
|
|
11
|
-
- Compare objects: identical/change/same/different/missing;
|
|
12
|
-
- Accumulative data selections: find/parent/folder;
|
|
13
|
-
- Accumulative filter selection: limit/keep/remove/deep;
|
|
14
|
-
- Extract and manipulate data chunks;
|
|
15
8
|
|
|
16
9
|
|
|
17
|
-
##
|
|
10
|
+
## Breaking changes
|
|
11
|
+
* In version 7 look functions have 2 new arguments: Function `finish` and `next`;
|
|
12
|
+
* Instead of returning a string 'next'(in version 6) to stop iteration on current dt-line, now you have to `return next()`;
|
|
13
|
+
* Function `finish` is a new option. Call `return finish()` to stop iteration on all dt-lines;
|
|
14
|
+
* Method `insert` was renamed to `insertSegment` to be clear that data is not mixed. Segments are separated peaces of data;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Other changes
|
|
19
|
+
* Method `listSegments` was added to show list of all segments in dt-object;
|
|
20
|
+
* Method `insertSegment` expect the incoming data as dt-object, but if is not - will assume it as a standard javascript object and will convert it to dt-object automatically;
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Description
|
|
24
|
+
|
|
25
|
+
DT-Toolbox is created to simplify the work with deep nested javascript objects. The library was created as an immutable data-storage(dt-object), internally based on data-model called `DT-model`.
|
|
26
|
+
|
|
27
|
+
## What is DT-model?
|
|
28
|
+
It's an internal 'dt-object' data description. Data is an array of lines where each line has 4 components:
|
|
29
|
+
```js
|
|
30
|
+
[ // dt-model
|
|
31
|
+
[ name, flatData, breadcrumbs, edges ] // dt-line
|
|
32
|
+
, [ name, flatData, breadcrumbs, edges ] // dt-line
|
|
33
|
+
// ...
|
|
34
|
+
]
|
|
35
|
+
// Where ->
|
|
36
|
+
// name: string. Name of the dt-line;
|
|
37
|
+
// flatData: object or array of primitive types;
|
|
38
|
+
// breadcrumbs: string. Bredcrumbs description of the current dt-line;
|
|
39
|
+
// edges: string[]. List of breadcrumbs of the related dt-lines;
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This data-description is easy to read, saved, or transfered.
|
|
18
43
|
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
19
46
|
Install for node.js projects by writing in your terminal:
|
|
47
|
+
|
|
20
48
|
```
|
|
21
|
-
npm install dt-toolbox
|
|
49
|
+
npm install dt-toolbox
|
|
22
50
|
```
|
|
23
51
|
|
|
24
52
|
Once it has been installed, it can be used by writing this line of JavaScript:
|
|
@@ -28,458 +56,910 @@ import dtbox from 'dt-toolbox'
|
|
|
28
56
|
|
|
29
57
|
|
|
30
58
|
|
|
31
|
-
##
|
|
59
|
+
## How it works?
|
|
60
|
+
|
|
61
|
+
Use Dt-toolbox methods(init and load) to create a `dt-object`.
|
|
62
|
+
|
|
63
|
+
DT-object:
|
|
64
|
+
- Provides multiple insertion of data segments. Data from each insertion stays differentiated;
|
|
65
|
+
- Has prebuilded filters for fast search of data;
|
|
66
|
+
- Can create and register a customized filters for fast search of data;
|
|
67
|
+
- Can apply `query functions` to find, extract and reshape the data;
|
|
68
|
+
- Can apply `model function` to reshape the final result;
|
|
69
|
+
- Can executes 'query' and 'model' function over all available data in the storage (All data segments);
|
|
70
|
+
- Execution of query/model functions will not change anything inside the host dt-object;
|
|
71
|
+
|
|
72
|
+
The **dt-object** contains internally a `dt-storage` object, that is available during call of the 'query' or 'model' functions. Dt-storage have couple of methods for searching data as well can create a new **DT-model** structures and fill them with data.
|
|
32
73
|
|
|
33
|
-
|
|
74
|
+
Query functions are returning a **new instance of dt-object** with the result, created by dt-storage. Remember - **data inside dt-object never get modified**.
|
|
75
|
+
|
|
76
|
+
**Filters** can significantly improve the speed of searching information inside dt-objects by creating a shorter scan-list according some specific preferences. Library is coming with `list of predefined filters`:
|
|
77
|
+
```js
|
|
78
|
+
'list' : 'Scan only dt-lines where flatData is an array'
|
|
79
|
+
, 'listObject' : 'Scan objects that are members of array'
|
|
80
|
+
, 'object' : 'Scan just dt-lines where flatData is an object'
|
|
81
|
+
, 'root' : 'Scan only root dt-lines of each data segment'
|
|
82
|
+
```
|
|
83
|
+
Filters are very simple functions to build. Here is one example of how we can create filter for finding object with specific key and value in it.
|
|
34
84
|
```js
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
85
|
+
function findBlueEyesFn ({ // We have named arguments
|
|
86
|
+
name // Name of dt-line
|
|
87
|
+
, flatData // The data. Flat object or array
|
|
88
|
+
, breadcrumbs // Location description
|
|
89
|
+
, edges // List of breadcrumbs related to this dt-line
|
|
90
|
+
}) {
|
|
91
|
+
if ( flatData.eyes === 'blue' ) return true // confirm that dt-line should be in that filter list
|
|
92
|
+
return false // ignore this dt-line
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Register a filter to some dt-object:
|
|
96
|
+
dt.setupFilter (
|
|
97
|
+
'blueEyes' // filter name
|
|
98
|
+
, findBlueEyesFn // provide a filter function
|
|
99
|
+
)
|
|
100
|
+
// Filter function will be executed on each dt-line to create a filter scan-list
|
|
101
|
+
|
|
102
|
+
// Using the filter during execution of query/model functions:
|
|
103
|
+
dt.query ( store => {
|
|
104
|
+
store
|
|
105
|
+
.use ( 'blueEyes' ) // Set the name of the filter
|
|
106
|
+
.look ( ({}) => {
|
|
107
|
+
// ... will scan only dt-lines selected by filter
|
|
108
|
+
})
|
|
109
|
+
})
|
|
110
|
+
```
|
|
40
111
|
|
|
41
|
-
|
|
42
|
-
, add : 'Add data and keep existing data'
|
|
43
|
-
, update : 'Updates only existing data fields'
|
|
44
|
-
, overwrite : 'Add new data to DT object. Overwrite existing fields'
|
|
45
|
-
, insert : 'Insert data on specified key, when the key represents an array'
|
|
46
|
-
, combine : 'Combine values for simular keys in arrays'
|
|
47
|
-
, append : 'Combine values for duplicated keys. main + update'
|
|
48
|
-
, prepend : 'Combine values for duplicated keys. update + main'
|
|
49
|
-
, log : 'Executes callback with errors list as argument'
|
|
50
|
-
, empty : 'Empty object with export methods'
|
|
112
|
+
Take a look on the library APIs and see the '**Examples**' section bellow.
|
|
51
113
|
|
|
52
|
-
|
|
53
|
-
, replace : 'Get this._selection.result as a main data'
|
|
54
|
-
, attach : 'Attach this._selection.result to the main data. Set point of connection'
|
|
55
|
-
, spread : 'Returns result of selection in a calback function'
|
|
56
|
-
, spreadAll : 'Select all and returns it with one command in a callback function'
|
|
57
|
-
, export : 'Returns result of selection'
|
|
58
|
-
, exportAll : 'Select all and returns it with one command'
|
|
114
|
+
### dt-toolbox API Fast Reference
|
|
59
115
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// Selectors
|
|
68
|
-
, select : 'Initialize a new selection'
|
|
69
|
-
, parent : 'Selector. Apply conditions starting from parent level'
|
|
70
|
-
, find : 'Selector. Fullfil select with list of arguments that contain specific string'
|
|
71
|
-
, all : "Selector. Same as find ('root')"
|
|
72
|
-
, folder : "Selector. Fullfil selection with 'midFlat' object props"
|
|
73
|
-
, space : "Selector. Same as 'folder'"
|
|
74
|
-
, deepObject : "Selector. Fullfil '_select' with deepest object elements"
|
|
75
|
-
, deepArray : "Selector. Fullfil '_select' with deepest array elements"
|
|
76
|
-
, invert : 'Selector. Invert existing selection'
|
|
77
|
-
, assemble : "Converts selection into 'array of objects' or 'single flat object'"
|
|
78
|
-
, purify : 'Removes all empty structures ( no props ) from the selection'
|
|
116
|
+
```js
|
|
117
|
+
init : 'Create a new dt-object from data that is not a DT-model and needs a convertion'
|
|
118
|
+
, load : 'Create a new dt-object from data that is a DT-model'
|
|
119
|
+
, flat : 'Convert a data to DT-model without creation of dt-object'
|
|
120
|
+
, convert : 'Direct convertion from model to model without creation of dt-object'
|
|
121
|
+
, getWalk : 'Returns a instance of "walk" library'
|
|
122
|
+
```
|
|
79
123
|
|
|
80
|
-
|
|
81
|
-
, limit : 'Filter. Reduces amount of records in the selection'
|
|
82
|
-
, keep : 'Filter. Keeps records in selection if check function returns true'
|
|
83
|
-
, remove : 'Filter. Removes records from selection if check function returns true'
|
|
84
|
-
, deep : "Filter. Arguments ( num, direction - optional). Num mean level of deep. Deep '0' mean root members"
|
|
124
|
+
### dt-object API Fast Reference
|
|
85
125
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
126
|
+
```js
|
|
127
|
+
insertSegment : 'Inserts a new data-segment in the dt-object. Insertion should be provided as a dt-object.'
|
|
128
|
+
, 'export' : 'Returns the DT-model from dt-object - part or full'
|
|
129
|
+
, copy : 'Creates a copy of original provided data'
|
|
130
|
+
, query : 'Executes a "query" function on the dt-object. Returns a new dt-object with the result'
|
|
131
|
+
, model : 'Executes a "model" function on the dt-object. Returns a data model'
|
|
132
|
+
, setupFilter : 'Evaluate data according "filter" function and create a shorter scan list that can be used by "dt-storage" during execution of query and model functions'
|
|
133
|
+
, index : 'Provides a copy of specified dt-line by breadcrumbs'
|
|
134
|
+
, listSegments : 'Returns a list of all segments in dt-object'
|
|
94
135
|
```
|
|
95
136
|
|
|
137
|
+
### dt-storage API Fast Reference
|
|
96
138
|
|
|
139
|
+
Object `dt-storage` is available as argument to '**query**' and '**model**' functions. Methods of
|
|
140
|
+
'dt-storage' can scan DT-model for data and build a new DT-model structure and fields.
|
|
97
141
|
|
|
142
|
+
*Important*: Result of building a DT-model returns as a separate dt-object and will not modify anything inside actual dt-object.
|
|
98
143
|
|
|
144
|
+
```js
|
|
145
|
+
// Scan methods
|
|
146
|
+
, from : 'Scan deeper from specified dt-line by location(breadcrumbs)'
|
|
147
|
+
, use : 'Use filter name to execute `look` on shorter list of dt-lines.'
|
|
148
|
+
, get : 'Take a single dt-line with specific breadcrumbs'
|
|
149
|
+
, find : 'String search for exact object name'
|
|
150
|
+
, like : 'String search in dt-line name'
|
|
151
|
+
, look : 'Executes on each object property in the selection list'
|
|
152
|
+
|
|
153
|
+
// DT-model structure and fields creation:
|
|
154
|
+
set : 'Define new dt-line record'
|
|
155
|
+
, connect : 'Creates a list of connections between two already existing dt-lines'
|
|
156
|
+
, save : 'Save a property to flatData object in existing dt-line'
|
|
157
|
+
, push : 'Save a value to flatData array of existing dt-line'
|
|
99
158
|
|
|
100
|
-
|
|
159
|
+
```
|
|
101
160
|
|
|
102
|
-
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.
|
|
103
161
|
|
|
104
|
-
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.
|
|
105
162
|
|
|
106
|
-
|
|
163
|
+
## DT Toolbox API
|
|
107
164
|
|
|
108
|
-
|
|
165
|
+
### dtbox.init ()
|
|
166
|
+
Create a new dt-object from data that is not a DT-model and needs a convertion. Please take a look on section `Init/Export Data-Models` for more details.
|
|
109
167
|
|
|
168
|
+
```js
|
|
169
|
+
const data = { // Standard JS object
|
|
170
|
+
name: 'Peter'
|
|
171
|
+
, familyMembers : [ 'Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
|
|
172
|
+
, shoes : {
|
|
173
|
+
winter : [ 'Keen', 'Head']
|
|
174
|
+
, summer : [ 'Lotto', 'Asics' ]
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const midData = { // Midflat model object
|
|
179
|
+
'root' : { name: 'Peter' }
|
|
180
|
+
, 'familyMembers' : ['Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
|
|
181
|
+
, 'shoes/winter' : [ 'Keen', 'Head' ]
|
|
182
|
+
, 'shoes/summer' : [ 'Lotto', 'Asics' ]
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const dtS = dtbox.init ( data ) // Creates dt-object from 'standard'(std) data-model
|
|
186
|
+
// it's equal to this: const dtS = dtbox.init ( data, { model:'std' })
|
|
187
|
+
const dtMid = dtbox.init ( midData, { model : 'midFlat' }) // Creates a dt-object from midFlat data.
|
|
188
|
+
```
|
|
110
189
|
|
|
111
190
|
|
|
112
191
|
|
|
192
|
+
### dtbox.load ()
|
|
193
|
+
Create a new dt-object from data that is a DT-model.
|
|
113
194
|
|
|
195
|
+
```js
|
|
196
|
+
const dtData = [
|
|
197
|
+
[
|
|
198
|
+
'root',
|
|
199
|
+
{ city: 'Varna', desc: 'Big city on the Black-sea seaside' },
|
|
200
|
+
'root',
|
|
201
|
+
[ 'root/location', 'root/extra' ]
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
'location',
|
|
205
|
+
{ continent: 'Europe', country: 'Bulgaria' },
|
|
206
|
+
'root/location',
|
|
207
|
+
[]
|
|
208
|
+
],
|
|
209
|
+
[
|
|
210
|
+
'extra',
|
|
211
|
+
{ port: 'Yes', airport: 'Yes' },
|
|
212
|
+
'root/extra',
|
|
213
|
+
[ 'root/extra/nearTo' ]
|
|
214
|
+
],
|
|
215
|
+
[
|
|
216
|
+
'nearTo',
|
|
217
|
+
[ 'Burgas', 'Shumen', 'Dobrich' ],
|
|
218
|
+
'root/extra/nearTo',
|
|
219
|
+
[]
|
|
220
|
+
]
|
|
221
|
+
];
|
|
114
222
|
|
|
223
|
+
const dtStore = dtbox.load ( dtData ); // Load DT-model data to dt-object
|
|
224
|
+
```
|
|
115
225
|
|
|
116
226
|
|
|
117
227
|
|
|
228
|
+
### dtbox.flat ()
|
|
229
|
+
Convert a data to DT-model without creation of dt-object.
|
|
118
230
|
|
|
119
|
-
|
|
231
|
+
```js
|
|
232
|
+
const a = {
|
|
233
|
+
city : 'Varna'
|
|
234
|
+
, desc: 'Big city on the Black-sea seaside'
|
|
235
|
+
, location : {
|
|
236
|
+
continent: 'Europe'
|
|
237
|
+
, country : 'Bulgaria'
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
, extra : {
|
|
241
|
+
port : 'Yes'
|
|
242
|
+
, airport : 'Yes'
|
|
243
|
+
, 'nearTo' : [ 'Burgas', 'Shumen', 'Dobrich' ]
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const inFlatModel = dtbox.flat ( a ) // Default data-model is set to 'standard'(std)
|
|
248
|
+
// it's equal to: const inFlatModel = dtbox.flat ( a, {model: 'std'})
|
|
249
|
+
/**
|
|
250
|
+
* inFlatModel = [
|
|
251
|
+
[
|
|
252
|
+
'root',
|
|
253
|
+
{ city: 'Varna', desc: 'Big city on the Black-sea seaside' },
|
|
254
|
+
'root',
|
|
255
|
+
[ 'root/location', 'root/extra' ]
|
|
256
|
+
],
|
|
257
|
+
[
|
|
258
|
+
'location',
|
|
259
|
+
{ continent: 'Europe', country: 'Bulgaria' },
|
|
260
|
+
'root/location',
|
|
261
|
+
[]
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
'extra',
|
|
265
|
+
{ port: 'Yes', airport: 'Yes' },
|
|
266
|
+
'root/extra',
|
|
267
|
+
[ 'root/extra/nearTo' ]
|
|
268
|
+
],
|
|
269
|
+
[
|
|
270
|
+
'nearTo',
|
|
271
|
+
[ 'Burgas', 'Shumen', 'Dobrich' ],
|
|
272
|
+
'root/extra/nearTo',
|
|
273
|
+
[]
|
|
274
|
+
]
|
|
275
|
+
]
|
|
276
|
+
*/
|
|
277
|
+
|
|
278
|
+
```
|
|
120
279
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
### dtbox.convert ()
|
|
283
|
+
Direct convertion from model to model without creation of dt-object.
|
|
124
284
|
|
|
125
285
|
```js
|
|
126
|
-
let st = {
|
|
127
|
-
name : {
|
|
128
|
-
firstName : 'Peter'
|
|
129
|
-
, surname : 'Naydenov'
|
|
130
|
-
}
|
|
131
|
-
, friends : [ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ]
|
|
132
|
-
}
|
|
133
286
|
|
|
287
|
+
let result = dtbox.convert ( a, {
|
|
288
|
+
model : 'std' // Model: Source data-model
|
|
289
|
+
, as : 'breadcrumbs' // as: Convert data to this data-model
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
result = {
|
|
294
|
+
'city': 'Varna'
|
|
295
|
+
, 'desc': 'Big city on the Black-sea seaside'
|
|
296
|
+
, 'location/continent': 'Europe'
|
|
297
|
+
, 'location/country': 'Bulgaria'
|
|
298
|
+
, 'extra/port': 'Yes'
|
|
299
|
+
, 'extra/airport': 'Yes'
|
|
300
|
+
, 'extra/nearTo/0': 'Burgas'
|
|
301
|
+
, 'extra/nearTo/1': 'Shumen'
|
|
302
|
+
, 'extra/nearTo/2': 'Dobrich'
|
|
303
|
+
}
|
|
304
|
+
*/
|
|
134
305
|
```
|
|
135
|
-
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
### dtbox.getWalk ()
|
|
310
|
+
Dt-Toolbox is using "walk" library. If you need to use it directly - get the version used by Dt-Toolbox.
|
|
136
311
|
|
|
137
312
|
```js
|
|
138
|
-
|
|
313
|
+
const walk = dtbox.getWalk ();
|
|
314
|
+
|
|
139
315
|
```
|
|
140
316
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
## DT-object API
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
### dt.insertSegment ()
|
|
325
|
+
Extend the dt-object with a new data segment. Insertion should be provided as dt-object.
|
|
144
326
|
|
|
145
327
|
```js
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
,
|
|
150
|
-
,
|
|
328
|
+
const a = [ // it's a 'file' data-model
|
|
329
|
+
'name/Peter'
|
|
330
|
+
, 'familyMembers/Veselina'
|
|
331
|
+
, 'familyMembers/Iskra'
|
|
332
|
+
, 'familyMembers/Maria'
|
|
333
|
+
, 'familyMembers/Vasil'
|
|
334
|
+
, 'familyMembers/Vladimir'
|
|
335
|
+
, 'familyMembers/Petya'
|
|
336
|
+
, 'shoes/winter/Keen'
|
|
337
|
+
, 'shoes/winter/Head'
|
|
338
|
+
, 'shoes/summer/Lotto'
|
|
339
|
+
, 'shoes/summer/Asics'
|
|
340
|
+
];
|
|
341
|
+
const b = { shoes: [ 'Puma', 'UA' ]}
|
|
342
|
+
const dt = dtbox.init ( a, { model : 'file' }) // create a dt-object
|
|
343
|
+
dt.insertSegment (
|
|
344
|
+
'extra' // object name
|
|
345
|
+
, dtbox.init(b) // the extra object
|
|
346
|
+
) // insert to 'dt' storage data segment named 'extra' with data from 'b' object
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
dt internal interpretation:
|
|
350
|
+
[
|
|
351
|
+
[
|
|
352
|
+
'root' // -> dt-line name
|
|
353
|
+
, {name:'Peter'} // -> flatData
|
|
354
|
+
, 'root' // -> location. For top element of each data segment breadcrumbs === name
|
|
355
|
+
, [ 'root/familyMembers', 'root/shoes' ] // -> edges
|
|
356
|
+
]
|
|
357
|
+
, [
|
|
358
|
+
'familyMembers' // -> dt-line name
|
|
359
|
+
, [ 'Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ] // -> flatData
|
|
360
|
+
, 'root/familyMembers' // -> location
|
|
361
|
+
, [] // -> edges
|
|
362
|
+
]
|
|
363
|
+
, [
|
|
364
|
+
'shoes' // -> dt-line name
|
|
365
|
+
, {} // -> flatData
|
|
366
|
+
, 'root/shoes' // -> location
|
|
367
|
+
, [ 'root/shoes/winter', 'root/shoes/summer' ] // -> edges
|
|
368
|
+
]
|
|
369
|
+
, [
|
|
370
|
+
'winter' // -> dt-line name
|
|
371
|
+
, [ 'Keen', 'Head' ] // -> flatData
|
|
372
|
+
, 'root/shoes/winter' // -> location
|
|
373
|
+
, [] // -> edges
|
|
374
|
+
]
|
|
375
|
+
, [
|
|
376
|
+
'summer' // -> dt-line name
|
|
377
|
+
, [ 'Lotto', 'Asics' ] // -> flatData
|
|
378
|
+
, 'root/shoes/summer' // -> location
|
|
379
|
+
, [] // -> edges
|
|
380
|
+
]
|
|
381
|
+
// ---> Here are the elements that are coming from 'insertSegment'
|
|
382
|
+
, [
|
|
383
|
+
'extra' // -> dt-line name. Object name of insert will become root element for data segment.
|
|
384
|
+
, {} // -> flatData
|
|
385
|
+
,'extra' // -> location. For top element of each data segment breadcrumbs === name
|
|
386
|
+
, [ 'extra/shoes' ] // -> edges
|
|
151
387
|
]
|
|
388
|
+
, [
|
|
389
|
+
'shoes' // -> dt-line name
|
|
390
|
+
, [ 'Puma', 'UA'] // -> flatData
|
|
391
|
+
, 'extra/shoes' // -> location
|
|
392
|
+
, [] // -> edges
|
|
393
|
+
]
|
|
394
|
+
]
|
|
152
395
|
|
|
153
|
-
|
|
154
|
-
'root/1/firstName' : 'Peter'
|
|
155
|
-
, 'root/1/surname' : 'Naydenov'
|
|
156
|
-
, 'root/2/0' : 'Tisho'
|
|
157
|
-
, 'root/2/1' : 'Dibo'
|
|
158
|
-
, 'root/2/2' : 'Ivo'
|
|
159
|
-
, 'root/2/3' : 'Vasil'
|
|
160
|
-
}
|
|
161
|
-
}
|
|
396
|
+
*/
|
|
162
397
|
```
|
|
163
398
|
|
|
164
|
-
::: warning
|
|
165
|
-
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 }`.
|
|
166
|
-
:::
|
|
167
399
|
|
|
168
400
|
|
|
401
|
+
### dt.export ()
|
|
402
|
+
Returns DT-model from dt-object.
|
|
169
403
|
|
|
170
|
-
Extract a flat information:
|
|
171
404
|
```js
|
|
172
|
-
dt.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
405
|
+
const all = dt.export () // will return all data from the storage
|
|
406
|
+
const root = dt.export ( 'root' ) // will return only initial data segment
|
|
407
|
+
const extra = dt.export ( 'extra' ) // will return only 'extra' data segment
|
|
408
|
+
/**
|
|
409
|
+
extra = [
|
|
410
|
+
, [
|
|
411
|
+
'root' // -> dt-line name was changed to 'root'. Name 'extra' has meaning just inside dt-object
|
|
412
|
+
, {} // -> flatData
|
|
413
|
+
,'root' // -> location. For top element of each data segment breadcrumbs === name
|
|
414
|
+
, [ 'root/shoes' ] // -> edges
|
|
415
|
+
]
|
|
416
|
+
, [
|
|
417
|
+
'shoes' // -> dt-line name
|
|
418
|
+
, [ 'Puma', 'UA'] // -> flatData
|
|
419
|
+
, 'root/shoes' // -> location
|
|
420
|
+
, [] // -> edges
|
|
421
|
+
]
|
|
422
|
+
]
|
|
423
|
+
*/
|
|
424
|
+
|
|
177
425
|
```
|
|
178
426
|
|
|
179
427
|
|
|
428
|
+
### dt.copy ()
|
|
429
|
+
During the initialization process `dt-object` will save a deep copy of original data inside and can provide a deep copy in any time.
|
|
430
|
+
Function `copy` can't provide copy of all data segments together because they are not related to each other. By default, when there is no name as argument, function will return the copy of 'root' object.
|
|
431
|
+
```js
|
|
432
|
+
const
|
|
433
|
+
b = { shoes: [ 'Puma', 'UA' ]}
|
|
434
|
+
, c = { vitamins : [ 'a', 'b', 'c' ]}
|
|
435
|
+
, dt = dtbox.init ( b )
|
|
436
|
+
;
|
|
437
|
+
dt.insertSegment ( 'extra', c )
|
|
438
|
+
const deepCopy = dt.copy ()
|
|
439
|
+
// it equal to: const deepCopy = dt.copy ('root')
|
|
440
|
+
const onlyExtra = dt.copy ( 'extra' )
|
|
441
|
+
// onlyExtra = { vitamins : [ 'a', 'b', 'c' ]}
|
|
442
|
+
```
|
|
180
443
|
|
|
181
|
-
Let's play with DT Toolbox:
|
|
182
444
|
|
|
445
|
+
|
|
446
|
+
### dt.query ()
|
|
447
|
+
Executes a "query" function on the dt-object. If there is something new, will return it. If there are no changes, it will return itself. For more details take a look on `store API` and especially **store.set(), store.save(), store.push(), store.connect()**.
|
|
183
448
|
```js
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
,
|
|
188
|
-
|
|
449
|
+
function queryFn ( store, a, b ) { // optional arguments will come directly after 'store' api
|
|
450
|
+
// ... body of queryFn
|
|
451
|
+
}
|
|
452
|
+
const dtOther = dt.query ( queryFn, a, b ) // queryFn is required arguments. All other arguments are optional
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
### dt.model ()
|
|
457
|
+
Executes a "model" function on the dt-object. Returns a data-model. Default choice is DT-model object. Change the response representation by returning an object as in example below:
|
|
458
|
+
```js
|
|
459
|
+
function modelFn ( store, a,v,g ) { // optional arguments will come directly after 'store' api
|
|
460
|
+
// ... body of modelFn
|
|
461
|
+
// to convert result in some of predefined and supported models, function should return an object
|
|
462
|
+
return {
|
|
463
|
+
as : 'std' // property 'as' will execute final conversion. Model name should be from supported list of the library.
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const result = dt.model ( modelFn, a,v,g ) // modelFn is the only required argument. All other arguments are optional.
|
|
189
468
|
|
|
190
|
-
dtbox
|
|
191
|
-
.init(st) // Init data. Converts ST to DT
|
|
192
|
-
.select() // Starting new selection
|
|
193
|
-
.all() // Select all data
|
|
194
|
-
.spread ( 'flat', dt => dtResult = dt ) // Returns as `flat` data-type
|
|
195
|
-
.spread ( 'std', dt => stResult = dt ) // Convert back to original 'st' object
|
|
196
|
-
.select () // Start new selection. Will remove previous selection.
|
|
197
|
-
.find ( 'friends' ) // select keys that contain 'friends'
|
|
198
|
-
.spread ( 'std', dt => friendList = dt ) //= { friends :[ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ] }
|
|
199
|
-
.assemble ()
|
|
200
|
-
.spread ( 'std' => friendList = dt ) // = [ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ]
|
|
201
|
-
// 'assemble' removes all duplicated elements in the keys and simplifies the result.
|
|
202
|
-
|
|
203
469
|
```
|
|
204
470
|
|
|
205
|
-
###
|
|
471
|
+
### dt.setupFilter ()
|
|
472
|
+
Evaluate data according "filter" function and create a shorter scan list that can be used by `dt-storage API` during the execution of query or model functions. For more details about filters look at function `store.use()` function.
|
|
206
473
|
|
|
207
474
|
```js
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
475
|
+
function blueFn ({
|
|
476
|
+
name // Name of dt-line
|
|
477
|
+
, flatData // The flat data
|
|
478
|
+
, breadcrumbs // Location description
|
|
479
|
+
, edges // List of breadcrumbs related to this dt-line
|
|
480
|
+
}) {
|
|
481
|
+
if ( flatData.hasOwnProperty('eyes') && flatData.eyes === 'blue' ) return true // confirm that dt-line should be in that filter list
|
|
482
|
+
return false // ignore this dt-line
|
|
483
|
+
// dt-lines that are
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
dt.setupFilter (
|
|
487
|
+
'blue' // Name of the filter
|
|
488
|
+
, blueFn // Provide a filter function
|
|
489
|
+
)
|
|
212
490
|
```
|
|
213
491
|
|
|
214
|
-
### Mixing objects - Add/Update/Overwrite
|
|
215
492
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
493
|
+
### dt.index ()
|
|
494
|
+
Provides a copy of specified by breadcrumbs DT-line.
|
|
495
|
+
```js
|
|
496
|
+
const br = 'root/friends'
|
|
497
|
+
const data = {
|
|
498
|
+
name: 'Peter'
|
|
499
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
500
|
+
, personal : {
|
|
501
|
+
age : 49
|
|
502
|
+
, eyes : 'blue'
|
|
503
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
504
|
+
, hobbies : {
|
|
505
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
506
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
const [ name, flatData, breadcrumbs, edges ] = dt.index ( br )
|
|
511
|
+
// name = friends
|
|
512
|
+
// flatData = [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
513
|
+
// breadcrumbs === br
|
|
514
|
+
// edges === []
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
### dt.listSegments ()
|
|
219
518
|
|
|
220
|
-
|
|
519
|
+
Returns a list of all data segment names. Result is always an array with at least one element - 'root'.
|
|
221
520
|
|
|
222
521
|
```js
|
|
522
|
+
dt.listSegments ()
|
|
523
|
+
// [ 'root', 'extra' ]
|
|
524
|
+
```
|
|
223
525
|
|
|
224
|
-
let user = {
|
|
225
|
-
name : 'Peter'
|
|
226
|
-
, age : 42
|
|
227
|
-
}
|
|
228
526
|
|
|
229
|
-
dtbox
|
|
230
|
-
.init ( user )
|
|
231
|
-
.add ({
|
|
232
|
-
age : 25 // 'add' will ignore this. Age is already defined.
|
|
233
|
-
, gender : 'male' // Will add this.
|
|
234
|
-
}, { type: 'std'})
|
|
235
|
-
.update ({
|
|
236
|
-
age : 50 // Will update
|
|
237
|
-
eyes : 'blue' // Will ignore this.
|
|
238
|
-
}, { type: 'std'})
|
|
239
|
-
.overwrite ({
|
|
240
|
-
age : 43 // Will update
|
|
241
|
-
, hobby : 'skating' // Will add
|
|
242
|
-
}, { type: 'std'})
|
|
243
527
|
|
|
244
|
-
// The object (dtbox.value) will look like:
|
|
245
|
-
/*
|
|
246
|
-
{
|
|
247
|
-
'root/0/name' : 'Peter'
|
|
248
|
-
, 'root/0/age' : 43
|
|
249
|
-
, 'root/0/gender' : 'male'
|
|
250
|
-
, 'root/0/hobby' : 'skating'
|
|
251
|
-
}
|
|
252
528
|
|
|
253
|
-
/*
|
|
254
529
|
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
## DT-store API
|
|
533
|
+
|
|
534
|
+
As we already mentioned, store is available in query/model functions and coming as the first argument.
|
|
535
|
+
|
|
536
|
+
### store.look ()
|
|
537
|
+
Function that will be executed on each object key/value from the selection list.
|
|
538
|
+
If selection is not explicitly mentioned, executes function on each dt-line data segments.
|
|
539
|
+
|
|
540
|
+
```js
|
|
541
|
+
const data = {
|
|
542
|
+
name: 'Peter'
|
|
543
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
544
|
+
, personal : {
|
|
545
|
+
age : 49
|
|
546
|
+
, eyes : 'blue'
|
|
547
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
548
|
+
, hobbies : {
|
|
549
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
550
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
const dt = dtbox.init ( data );
|
|
555
|
+
|
|
556
|
+
const result = dt.query ( store => {
|
|
557
|
+
// Direct call of look on store will be executed on each dt-line
|
|
558
|
+
store.look ( ({ // Named arguments. All available argument-names are listed here:
|
|
559
|
+
value
|
|
560
|
+
, key
|
|
561
|
+
, name // dt-line name;
|
|
562
|
+
, flatData // full flatData for specified dt-line;
|
|
563
|
+
, breadcrumbs // breadcrumbs for dt-line;
|
|
564
|
+
, links // List of tuples [[parent, child],...]. Parent and child are the dt-line names;
|
|
565
|
+
, empty // Will present only if object has no properties. Empty flatData for dt-line.
|
|
566
|
+
, next // Function that can be returned to move to next dt-line
|
|
567
|
+
, finish // Function that can be returned to stop execution of look function
|
|
568
|
+
}) => {
|
|
569
|
+
//... body of look function
|
|
570
|
+
// Move fast to next dt-line by returning a string 'next'
|
|
571
|
+
return next ()
|
|
572
|
+
// unconditional `return next()` will executes the 'look' function once per dt-line
|
|
573
|
+
})
|
|
574
|
+
})
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### store.from ()
|
|
578
|
+
Scan deeper from specified dt-line by location(breadcrumbs).
|
|
579
|
+
|
|
580
|
+
```js
|
|
581
|
+
const data = {
|
|
582
|
+
name: 'Peter'
|
|
583
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
584
|
+
, personal : {
|
|
585
|
+
age : 49
|
|
586
|
+
, eyes : 'blue'
|
|
587
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
588
|
+
, hobbies : {
|
|
589
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
590
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
const
|
|
595
|
+
dt = dtbox.init ( data )
|
|
596
|
+
, res = dt.query ( store => {
|
|
597
|
+
store
|
|
598
|
+
.from ( 'root/personal/hobbies' )
|
|
599
|
+
.look ( ({name, next }) => {
|
|
600
|
+
console.log ( name )
|
|
601
|
+
// -> hobbies, music, sport
|
|
602
|
+
return next () // because we want to iterate once on each dt-line
|
|
603
|
+
})
|
|
604
|
+
});
|
|
255
605
|
```
|
|
256
606
|
|
|
257
607
|
|
|
258
|
-
###
|
|
608
|
+
### store.use ()
|
|
609
|
+
Use filter to execute `look` on shorter list of dt-lines. Use the predefined or your own filters.
|
|
610
|
+
List of predefined filters:
|
|
611
|
+
- 'list' : Scan only dt-lines where flatData is an array;
|
|
612
|
+
- 'listObject' : Scan objects that are members of array;
|
|
613
|
+
- 'object' : Scan just dt-lines where flatData is an object;
|
|
614
|
+
- 'root' : Scan only root dt-lines of each data segment;
|
|
615
|
+
|
|
616
|
+
If filter do not exist, look function will be executed on each dt-line.
|
|
259
617
|
|
|
260
618
|
```js
|
|
619
|
+
const data = {
|
|
620
|
+
name: 'Peter'
|
|
621
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
622
|
+
, personal : {
|
|
623
|
+
age : 49
|
|
624
|
+
, eyes : 'blue'
|
|
625
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
626
|
+
, hobbies : {
|
|
627
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
628
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
const
|
|
633
|
+
dt = dtbox.init ( data )
|
|
634
|
+
, res = dt.query ( store => {
|
|
635
|
+
store
|
|
636
|
+
.use ( 'object' ) // predefined filter 'object'
|
|
637
|
+
.look ( ({name, next }) => {
|
|
638
|
+
console.log ( name )
|
|
639
|
+
// -> root, personal, hobbies
|
|
640
|
+
return next () // because we want to iterate once on each dt-line
|
|
641
|
+
})
|
|
642
|
+
});
|
|
643
|
+
```
|
|
261
644
|
|
|
262
|
-
let result;
|
|
263
|
-
let data = {
|
|
264
|
-
'school' : [
|
|
265
|
-
{ name: 'Ivan', age: 14 }
|
|
266
|
-
, { name: 'Georgy', age: 15 }
|
|
267
|
-
, { name: 'Adi', age: 11 }
|
|
268
|
-
, { name: 'Kati', age: 11 }
|
|
269
|
-
]
|
|
270
|
-
, 'sports' : [
|
|
271
|
-
{ name: 'Iva', age: 28 }
|
|
272
|
-
, { name: 'Stoyan', age: 36 }
|
|
273
|
-
]
|
|
274
|
-
, 'work' : [
|
|
275
|
-
{ name: 'Hristo', age: 38 }
|
|
276
|
-
, { name: 'Lachezar', age: 33 }
|
|
277
|
-
, { name: 'Veselina', age: 35 }
|
|
278
|
-
|
|
279
|
-
]
|
|
280
|
-
, 'recent' : {
|
|
281
|
-
'classmates' : [
|
|
282
|
-
{ name: 'Anton', age: 42 }
|
|
283
|
-
, { name: 'Miroslava', age: 42 }
|
|
284
|
-
]
|
|
285
|
-
, 'social' : [
|
|
286
|
-
{ name: 'Iliana', age: 61 }
|
|
287
|
-
, { name: 'Tzvetan', age: 19 }
|
|
288
|
-
]
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
645
|
|
|
292
|
-
// Let's create list of all contacts uder 40 years old:
|
|
293
|
-
|
|
294
|
-
dtbox
|
|
295
|
-
.init ( data )
|
|
296
|
-
.select ()
|
|
297
|
-
.parent ( 'name', person => person.age < 40 )
|
|
298
|
-
.assemble ()
|
|
299
|
-
.spread ( 'std' , dt => result = dt )
|
|
300
|
-
|
|
301
|
-
/*
|
|
302
|
-
result will look like this:
|
|
303
|
-
|
|
304
|
-
[
|
|
305
|
-
{ name: 'Tzvetan', age: 19 },
|
|
306
|
-
{ name: 'Ivan', age: 14 },
|
|
307
|
-
{ name: 'Iva', age: 28 },
|
|
308
|
-
{ name: 'Hristo', age: 38 },
|
|
309
|
-
{ name: 'Georgy', age: 15 },
|
|
310
|
-
{ name: 'Stoyan', age: 36 },
|
|
311
|
-
{ name: 'Lachezar', age: 33 },
|
|
312
|
-
{ name: 'Adi', age: 11 },
|
|
313
|
-
{ name: 'Veselina', age: 35 },
|
|
314
|
-
{ name: 'Kati', age: 11 }
|
|
315
|
-
]
|
|
316
646
|
|
|
317
|
-
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
### store.get ()
|
|
650
|
+
Take a single dt-line with specific breadcrumbs.
|
|
651
|
+
|
|
652
|
+
```js
|
|
653
|
+
const data = {
|
|
654
|
+
name: 'Peter'
|
|
655
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
656
|
+
, personal : {
|
|
657
|
+
age : 49
|
|
658
|
+
, eyes : 'blue'
|
|
659
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
660
|
+
, hobbies : {
|
|
661
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
662
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
const
|
|
667
|
+
dt = dtbox.init ( data )
|
|
668
|
+
, res = dt.query ( store => {
|
|
669
|
+
store
|
|
670
|
+
.get ( 'root/friends' )
|
|
671
|
+
.look ( ({ flatData, next }) => {
|
|
672
|
+
console.log ( flatData )
|
|
673
|
+
// -> [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
674
|
+
return next () // because we want to iterate once on each dt-line
|
|
675
|
+
})
|
|
676
|
+
});
|
|
318
677
|
```
|
|
319
678
|
|
|
320
679
|
|
|
321
680
|
|
|
322
|
-
###
|
|
681
|
+
### store.find ()
|
|
682
|
+
String search for exact object name
|
|
683
|
+
|
|
684
|
+
```js
|
|
685
|
+
const data = {
|
|
686
|
+
name: 'Peter'
|
|
687
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
688
|
+
, personal : {
|
|
689
|
+
age : 49
|
|
690
|
+
, eyes : 'blue'
|
|
691
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
692
|
+
, hobbies : {
|
|
693
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
694
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
const
|
|
699
|
+
dt = dtbox.init ( data )
|
|
700
|
+
, res = dt.query ( store => {
|
|
701
|
+
store
|
|
702
|
+
.find ( 'music' )
|
|
703
|
+
.look ( ({flatData, next }) => {
|
|
704
|
+
console.log ( flatData )
|
|
705
|
+
// -> [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
706
|
+
return next () // because we want to iterate once on each dt-line
|
|
707
|
+
})
|
|
708
|
+
});
|
|
709
|
+
```
|
|
323
710
|
|
|
324
|
-
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
### store.like ()
|
|
714
|
+
String search in dt-line name
|
|
325
715
|
|
|
326
716
|
```js
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
717
|
+
const data = {
|
|
718
|
+
name: 'Peter'
|
|
719
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
720
|
+
, personal : {
|
|
721
|
+
age : 49
|
|
722
|
+
, eyes : 'blue'
|
|
723
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
724
|
+
, hobbies : {
|
|
725
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
726
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
const
|
|
731
|
+
dt = dtbox.init ( data )
|
|
732
|
+
, res = dt.query ( store => {
|
|
733
|
+
store
|
|
734
|
+
.like ( 'per' )
|
|
735
|
+
.look ( ({flatData, breadcrumbs, next }) => {
|
|
736
|
+
console.log ( flatData )
|
|
737
|
+
// -> { age: 49, eyes: 'blue' }
|
|
738
|
+
console.log ( breadcrumbs )
|
|
739
|
+
// -> 'root/personal'
|
|
740
|
+
return next () // because we want to iterate once on each dt-line
|
|
741
|
+
})
|
|
742
|
+
});
|
|
349
743
|
```
|
|
350
744
|
|
|
351
745
|
|
|
352
|
-
## Data-types
|
|
353
746
|
|
|
354
|
-
|
|
747
|
+
// DT-model structure and fields creation:
|
|
748
|
+
### store.set ()
|
|
749
|
+
Define new dt-line record
|
|
750
|
+
|
|
355
751
|
```js
|
|
356
752
|
const data = {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
753
|
+
name: 'Peter'
|
|
754
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
755
|
+
, personal : {
|
|
756
|
+
age : 49
|
|
757
|
+
, eyes : 'blue'
|
|
758
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
759
|
+
, hobbies : {
|
|
760
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
761
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
const dt = dtbox.init ( data );
|
|
766
|
+
|
|
767
|
+
const result = dt
|
|
768
|
+
.query ( store => {
|
|
769
|
+
store.set ( 'root', [2,4,15]) // new dt-line structure was created
|
|
770
|
+
})
|
|
771
|
+
.model ( () => ({as:'std'}) )
|
|
772
|
+
console.log ( result )
|
|
773
|
+
// -> [2,4,15]
|
|
774
|
+
|
|
775
|
+
const result2 = dt
|
|
776
|
+
.query ( store => {}) // If there is no new dt-line, query will return itself
|
|
777
|
+
.model ( () => ({as:'std'}) )
|
|
778
|
+
console.log ( result2 )
|
|
779
|
+
/**
|
|
780
|
+
{
|
|
781
|
+
name: 'Peter'
|
|
782
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
783
|
+
, personal : {
|
|
784
|
+
age : 49
|
|
785
|
+
, eyes : 'blue'
|
|
786
|
+
, sizes : [ 10, 44, 'm', 'mid' ]
|
|
787
|
+
, hobbies : {
|
|
788
|
+
music : [ 'punk', 'ska', 'metal', 'guitar' ]
|
|
789
|
+
, sport : [ 'fencing', 'skating', 'ski' ]
|
|
790
|
+
}
|
|
791
|
+
}
|
|
363
792
|
}
|
|
793
|
+
*/
|
|
364
794
|
```
|
|
365
795
|
|
|
366
|
-
|
|
367
|
-
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
### store.connect ()
|
|
799
|
+
Creates a list of connections between two already existing dt-lines
|
|
800
|
+
|
|
368
801
|
```js
|
|
369
|
-
{
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
802
|
+
const data = {
|
|
803
|
+
name: 'Peter'
|
|
804
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
805
|
+
};
|
|
806
|
+
const
|
|
807
|
+
dt = dtbox.init ( data )
|
|
808
|
+
, result = dt
|
|
809
|
+
.query ( store => {
|
|
810
|
+
store.set ( 'root', { name: Stefan })
|
|
811
|
+
store.set ( 'friends', [ 'Stefan', 'Tommy', 'Maria'] )
|
|
812
|
+
store.connect (['root/friends'])
|
|
813
|
+
})
|
|
814
|
+
.model ( () => ({as:'std'}))
|
|
815
|
+
;
|
|
816
|
+
console.log ( result )
|
|
817
|
+
/**
|
|
818
|
+
{
|
|
819
|
+
name: Stefan
|
|
820
|
+
, friends: ['Stefan', 'Tommy', 'Maria' ]
|
|
821
|
+
}
|
|
822
|
+
*/
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
### store.save ()
|
|
828
|
+
Save a property to flatData object in existing dt-line.
|
|
829
|
+
|
|
830
|
+
```js
|
|
831
|
+
const data = {
|
|
832
|
+
name: 'Peter'
|
|
833
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
834
|
+
};
|
|
835
|
+
const
|
|
836
|
+
dt = dtbox.init ( data )
|
|
837
|
+
, result = dt
|
|
838
|
+
.query ( store => {
|
|
839
|
+
store.set ( 'root', { name: Stefan })
|
|
840
|
+
store.set ( 'friends', [ 'Stefan', 'Tommy', 'Maria'] )
|
|
841
|
+
store.connect (['root/friends'])
|
|
842
|
+
store.save ( 'root', 'age', 35 )
|
|
843
|
+
})
|
|
844
|
+
.model ( () => ({as:'std'}))
|
|
845
|
+
;
|
|
846
|
+
console.log ( result )
|
|
847
|
+
/**
|
|
848
|
+
{
|
|
849
|
+
name: Stefan
|
|
850
|
+
, age : 35
|
|
851
|
+
, friends: ['Stefan', 'Tommy', 'Maria' ]
|
|
852
|
+
}
|
|
853
|
+
*/
|
|
377
854
|
```
|
|
378
855
|
|
|
379
856
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
**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.
|
|
857
|
+
|
|
858
|
+
### store.push ()
|
|
859
|
+
Save a value to flatData of existing dt-line. FlatData should be an array.
|
|
860
|
+
|
|
385
861
|
```js
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
, 'root/4/1' : 'Asics'
|
|
409
|
-
}
|
|
410
|
-
]
|
|
862
|
+
const data = {
|
|
863
|
+
name: 'Peter'
|
|
864
|
+
, friends : [ 'Ivan', 'Dobroslav', 'Stefan' ]
|
|
865
|
+
};
|
|
866
|
+
const
|
|
867
|
+
dt = dtbox.init ( data )
|
|
868
|
+
, result = dt
|
|
869
|
+
.query ( store => {
|
|
870
|
+
store.set ( 'root', { name: Stefan })
|
|
871
|
+
store.set ( 'friends', [ 'Stefan', 'Tommy', 'Maria'] )
|
|
872
|
+
store.connect (['root/friends'])
|
|
873
|
+
store.push ( 'friends', 'Lily' )
|
|
874
|
+
})
|
|
875
|
+
.model ( () => ({as:'std'}))
|
|
876
|
+
;
|
|
877
|
+
console.log ( result )
|
|
878
|
+
/**
|
|
879
|
+
{
|
|
880
|
+
name: Stefan
|
|
881
|
+
, friends: ['Stefan', 'Tommy', 'Maria', 'Lily' ]
|
|
882
|
+
}
|
|
883
|
+
*/
|
|
411
884
|
```
|
|
412
885
|
|
|
413
886
|
|
|
887
|
+
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
## Init/Export Data-Models
|
|
896
|
+
The library has some predefined data-models and can read and convert data among them.
|
|
897
|
+
|
|
898
|
+
### Standard ( std )
|
|
899
|
+
Standard data model is a standard deep javascript object.
|
|
900
|
+
```js
|
|
901
|
+
const data = {
|
|
902
|
+
name: 'Peter'
|
|
903
|
+
, familyMembers : [ 'Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
|
|
904
|
+
, shoes : {
|
|
905
|
+
winter : [ 'Keen', 'Head']
|
|
906
|
+
, summer : [ 'Lotto', 'Asics' ]
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
```
|
|
910
|
+
|
|
414
911
|
### MidFlat
|
|
415
|
-
|
|
912
|
+
It's a two level deep javascript object. First object properties represent the location of the data, value is a flat object or array:
|
|
416
913
|
|
|
417
914
|
```js
|
|
418
915
|
{
|
|
419
916
|
'root' : { name: 'Peter' }
|
|
420
|
-
, '
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
, '2' : 'Maria'
|
|
424
|
-
, '3' : 'Vasil'
|
|
425
|
-
, '4' : 'Vladimir'
|
|
426
|
-
, '5' : 'Petya'
|
|
427
|
-
}
|
|
428
|
-
, 'root/shoes/winter' : {
|
|
429
|
-
'0' : 'Keen'
|
|
430
|
-
, '1' : 'Head'
|
|
431
|
-
}
|
|
432
|
-
, 'root/shoes/summer' : {
|
|
433
|
-
'0' : 'Lotto'
|
|
434
|
-
'1' : 'Asics'
|
|
435
|
-
}
|
|
917
|
+
, 'familyMembers' : ['Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
|
|
918
|
+
, 'shoes/winter' : [ 'Keen', 'Head' ]
|
|
919
|
+
, 'shoes/summer' : [ 'Lotto', 'Asics' ]
|
|
436
920
|
}
|
|
437
921
|
```
|
|
438
922
|
|
|
439
923
|
|
|
440
924
|
|
|
441
|
-
|
|
442
|
-
|
|
443
925
|
### Breadcrumbs
|
|
444
|
-
|
|
445
926
|
It's a flat interpratation of the data and looks like this:
|
|
927
|
+
|
|
446
928
|
```js
|
|
447
929
|
{
|
|
448
|
-
'
|
|
449
|
-
, '
|
|
450
|
-
, '
|
|
451
|
-
, '
|
|
452
|
-
, '
|
|
453
|
-
, '
|
|
454
|
-
, '
|
|
455
|
-
, '
|
|
456
|
-
, '
|
|
457
|
-
, '
|
|
458
|
-
, '
|
|
930
|
+
'name' : 'Peter'
|
|
931
|
+
, 'familyMembers/0' : 'Veselina'
|
|
932
|
+
, 'familyMembers/1' : 'Iskra'
|
|
933
|
+
, 'familyMembers/2' : 'Maria'
|
|
934
|
+
, 'familyMembers/3' : 'Vasil'
|
|
935
|
+
, 'familyMembers/4' : 'Vladimir'
|
|
936
|
+
, 'familyMembers/5' : 'Petya'
|
|
937
|
+
, 'shoes/winter/0' : 'Keen'
|
|
938
|
+
, 'shoes/winter/1' : 'Head'
|
|
939
|
+
, 'shoes/summer/0' : 'Lotto'
|
|
940
|
+
, 'shoes/summer/1' : 'Asics'
|
|
459
941
|
}
|
|
460
942
|
```
|
|
461
943
|
|
|
462
|
-
|
|
463
944
|
### Files
|
|
464
945
|
Data is interpreted like file/folder description.
|
|
946
|
+
|
|
465
947
|
```js
|
|
466
948
|
[
|
|
467
|
-
'
|
|
468
|
-
, '
|
|
469
|
-
, '
|
|
470
|
-
, '
|
|
471
|
-
, '
|
|
472
|
-
, '
|
|
473
|
-
, '
|
|
474
|
-
, '
|
|
475
|
-
, '
|
|
476
|
-
, '
|
|
477
|
-
, '
|
|
949
|
+
'name/Peter'
|
|
950
|
+
, 'familyMembers/Veselina'
|
|
951
|
+
, 'familyMembers/Iskra'
|
|
952
|
+
, 'familyMembers/Maria'
|
|
953
|
+
, 'familyMembers/Vasil'
|
|
954
|
+
, 'familyMembers/Vladimir'
|
|
955
|
+
, 'familyMembers/Petya'
|
|
956
|
+
, 'shoes/winter/Keen'
|
|
957
|
+
, 'shoes/winter/Head'
|
|
958
|
+
, 'shoes/summer/Lotto'
|
|
959
|
+
, 'shoes/summer/Asics'
|
|
478
960
|
]
|
|
479
961
|
```
|
|
480
962
|
|
|
481
|
-
|
|
482
|
-
|
|
483
963
|
### Tuples
|
|
484
964
|
|
|
485
965
|
Array of tuples. First element represents location + property name, second is the value.
|
|
@@ -487,7 +967,7 @@ Array of tuples. First element represents location + property name, second is th
|
|
|
487
967
|
```js
|
|
488
968
|
[
|
|
489
969
|
['name', 'Peter' ]
|
|
490
|
-
, ['
|
|
970
|
+
, ['familyMembers', 'Veselina']
|
|
491
971
|
, ['familyMembers', 'Iskra']
|
|
492
972
|
, ['familyMembers', 'Maria']
|
|
493
973
|
, ['familyMembers', 'Vasil']
|
|
@@ -501,25 +981,195 @@ Array of tuples. First element represents location + property name, second is th
|
|
|
501
981
|
```
|
|
502
982
|
|
|
503
983
|
|
|
984
|
+
## Examples
|
|
504
985
|
|
|
986
|
+
### Find people under 40
|
|
505
987
|
|
|
988
|
+
Find a people that are under 40 years old and provide the result as a list.
|
|
506
989
|
|
|
507
|
-
|
|
990
|
+
```js
|
|
991
|
+
let data = {
|
|
992
|
+
'school' : [
|
|
993
|
+
{ name: 'Ivan', age: 14 }
|
|
994
|
+
, { name: 'Georgy', age: 15 }
|
|
995
|
+
, { name: 'Adi', age: 11 }
|
|
996
|
+
, { name: 'Kati', age: 11 }
|
|
997
|
+
]
|
|
998
|
+
, 'sports' : [
|
|
999
|
+
{ name: 'Iva', age: 28 }
|
|
1000
|
+
, { name: 'Stoyan', age: 36, sport: 'fencing' }
|
|
1001
|
+
]
|
|
1002
|
+
, 'work' : [
|
|
1003
|
+
{ name: 'Hristo', age: 38 }
|
|
1004
|
+
, { name: 'Lachezar', age: 33 }
|
|
1005
|
+
, { name: 'Veselina', age: 35 }
|
|
1006
|
+
|
|
1007
|
+
]
|
|
1008
|
+
, 'recent' : {
|
|
1009
|
+
'classmates' : [
|
|
1010
|
+
{ name: 'Anton', age: 42 }
|
|
1011
|
+
, { name: 'Miroslava', age: 42 }
|
|
1012
|
+
]
|
|
1013
|
+
, 'social' : [
|
|
1014
|
+
{ name: 'Iliana', age: 61 }
|
|
1015
|
+
, { name: 'Tzvetan', age: 19 }
|
|
1016
|
+
]
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const dt = dtbox.init ( data ); // creates a dt-object
|
|
1021
|
+
|
|
1022
|
+
const result = dt.query ( store => {
|
|
1023
|
+
let
|
|
1024
|
+
i = 0
|
|
1025
|
+
, connectBuffer = []
|
|
1026
|
+
;
|
|
1027
|
+
store.set ( 'root', []) // setup a root array element
|
|
1028
|
+
store
|
|
1029
|
+
.use ( 'listObject' ) // use only objects that are members of array
|
|
1030
|
+
.look ( ({ name, flatData, next }) => {
|
|
1031
|
+
if ( flatData.age < 40 ) {
|
|
1032
|
+
store.set ( i, flatData )
|
|
1033
|
+
connectBuffer.push ( `root/${i}` )
|
|
1034
|
+
i++
|
|
1035
|
+
}
|
|
1036
|
+
return next ()
|
|
1037
|
+
})
|
|
1038
|
+
store.connect ( connectBuffer )
|
|
1039
|
+
})
|
|
1040
|
+
.model ( () => ({ as : 'std'}))
|
|
1041
|
+
console.log ( result )
|
|
1042
|
+
/** ->
|
|
1043
|
+
[
|
|
1044
|
+
{ name: 'Ivan', age: 14 },
|
|
1045
|
+
{ name: 'Georgy', age: 15 },
|
|
1046
|
+
{ name: 'Adi', age: 11 },
|
|
1047
|
+
{ name: 'Kati', age: 11 },
|
|
1048
|
+
{ name: 'Iva', age: 28 },
|
|
1049
|
+
{ name: 'Stoyan', age: 36, sport: 'fencing' },
|
|
1050
|
+
{ name: 'Hristo', age: 38 },
|
|
1051
|
+
{ name: 'Lachezar', age: 33 },
|
|
1052
|
+
{ name: 'Veselina', age: 35 },
|
|
1053
|
+
{ name: 'Tzvetan', age: 19 }
|
|
1054
|
+
]
|
|
1055
|
+
*/
|
|
1056
|
+
```
|
|
1057
|
+
### Provide just a list of names
|
|
1058
|
+
Use the same data from previous example but return only the list of names.
|
|
1059
|
+
|
|
1060
|
+
```js
|
|
1061
|
+
const result = dt.query ( store => {
|
|
1062
|
+
store.set ( 'root', [])
|
|
1063
|
+
store
|
|
1064
|
+
.use ( 'listObject' ) // use only objects that are members of array
|
|
1065
|
+
.look ( ({ flatData, next }) => {
|
|
1066
|
+
if ( flatData.age < 40 ) store.push ( 'root', flatData.name )
|
|
1067
|
+
return next ()
|
|
1068
|
+
})
|
|
1069
|
+
})
|
|
1070
|
+
.model ( () => ({as:'std'}) )
|
|
1071
|
+
console.log ( result )
|
|
1072
|
+
/** ->
|
|
1073
|
+
[
|
|
1074
|
+
'Ivan', 'Georgy',
|
|
1075
|
+
'Adi', 'Kati',
|
|
1076
|
+
'Iva', 'Stoyan',
|
|
1077
|
+
'Hristo', 'Lachezar',
|
|
1078
|
+
'Veselina', 'Tzvetan'
|
|
1079
|
+
]
|
|
1080
|
+
*/
|
|
1081
|
+
```
|
|
1082
|
+
|
|
1083
|
+
### Organize people in two groups
|
|
1084
|
+
Return an object with two groups
|
|
1085
|
+
- 'over40'
|
|
1086
|
+
- 'under40'
|
|
1087
|
+
Provide only the names.
|
|
1088
|
+
```js
|
|
1089
|
+
const result = dt.query ( store => {
|
|
1090
|
+
store.set ( 'root', {} )
|
|
1091
|
+
store.set ( 'under40', [])
|
|
1092
|
+
store.set ( 'over40' , [])
|
|
1093
|
+
store.connect ([ 'root/under40', 'root/over40' ])
|
|
1094
|
+
store
|
|
1095
|
+
.use ( 'listObject' ) // use only objects that are members of array
|
|
1096
|
+
.look ( ({ flatData, next }) => {
|
|
1097
|
+
let location = ( flatData.age > 40 ) ? 'over40' : 'under40';
|
|
1098
|
+
store.push ( location, flatData.name )
|
|
1099
|
+
return next ()
|
|
1100
|
+
})
|
|
1101
|
+
})
|
|
1102
|
+
.model ( () => ({ as : 'std'}))
|
|
1103
|
+
console.log ( result )
|
|
1104
|
+
/** ->
|
|
1105
|
+
{
|
|
1106
|
+
'under40': [
|
|
1107
|
+
'Ivan', 'Georgy',
|
|
1108
|
+
'Adi', 'Kati',
|
|
1109
|
+
'Iva', 'Stoyan',
|
|
1110
|
+
'Hristo', 'Lachezar',
|
|
1111
|
+
'Veselina', 'Tzvetan'
|
|
1112
|
+
],
|
|
1113
|
+
'over40': [ 'Anton', 'Miroslava', 'Iliana' ]
|
|
1114
|
+
}
|
|
1115
|
+
*/
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
### Create a deep copy of dt-object
|
|
508
1120
|
|
|
1121
|
+
```js
|
|
1122
|
+
const result = dt.query ( store => {
|
|
1123
|
+
store.look ( ({ name, flatData, breadcrumbs, next }) => {
|
|
1124
|
+
store.set ( name, flatData )
|
|
1125
|
+
if ( breadcrumbs.includes('/') ) store.connect ([breadcrumbs])
|
|
1126
|
+
return next ()
|
|
1127
|
+
})
|
|
1128
|
+
})
|
|
1129
|
+
.model ( () => ({as:'std'}))
|
|
1130
|
+
console.log ( result )
|
|
1131
|
+
/** ->
|
|
1132
|
+
{
|
|
1133
|
+
school: [
|
|
1134
|
+
{ name: 'Ivan', age: 14 },
|
|
1135
|
+
{ name: 'Georgy', age: 15 },
|
|
1136
|
+
{ name: 'Adi', age: 11 },
|
|
1137
|
+
{ name: 'Kati', age: 11 }
|
|
1138
|
+
],
|
|
1139
|
+
sports: [
|
|
1140
|
+
{ name: 'Iva', age: 28 },
|
|
1141
|
+
{ name: 'Stoyan', age: 36, sport: 'fencing' }
|
|
1142
|
+
],
|
|
1143
|
+
work: [
|
|
1144
|
+
{ name: 'Hristo', age: 38 },
|
|
1145
|
+
{ name: 'Lachezar', age: 33 },
|
|
1146
|
+
{ name: 'Veselina', age: 35 }
|
|
1147
|
+
],
|
|
1148
|
+
recent: {
|
|
1149
|
+
classmates: [ { name: 'Anton', age: 42 }, { name: 'Miroslava', age: 42 } ],
|
|
1150
|
+
social: [ { name: 'Iliana', age: 61 }, { name: 'Tzvetan', age: 19 } ]
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
*/
|
|
1154
|
+
```
|
|
1155
|
+
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
|
|
1159
|
+
## External Links
|
|
509
1160
|
- [Migration guide](https://github.com/PeterNaydenov/dt-toolbox/blob/master/Migration.guide.md)
|
|
510
1161
|
- [History of changes](https://github.com/PeterNaydenov/dt-toolbox/blob/master/Changelog.md)
|
|
1162
|
+
- [DT-Queries. Some useful query functions for DT-Toolbox](https://github.com/PeterNaydenov/dt-queries)
|
|
1163
|
+
- [Documentation v.4.x.x](https://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.4.x.x.md)
|
|
511
1164
|
- [Documentation v.2.x.x](https://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.2.x.x.md)
|
|
512
1165
|
|
|
513
1166
|
|
|
514
1167
|
|
|
515
|
-
|
|
516
1168
|
## Credits
|
|
517
1169
|
'dt-toolbox' was created and supported by Peter Naydenov.
|
|
518
1170
|
|
|
519
1171
|
|
|
520
1172
|
|
|
521
|
-
|
|
522
|
-
|
|
523
1173
|
## License
|
|
524
1174
|
'dt-toolbox' is released under the [MIT License](http://opensource.org/licenses/MIT).
|
|
525
1175
|
|