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