dt-toolbox 5.0.0 → 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 -15
- package/LICENSE +1 -1
- package/Migration.guide.md +14 -1
- package/README.md +978 -347
- package/README_v.2.x.x.md +0 -1
- package/README_v.4.x.x.md +532 -0
- package/package.json +22 -25
- 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 +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 -689
- package/src/mainLib.js +105 -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,44 @@
|
|
|
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.6.x.x
|
|
3
2
|
|
|
4
|
-
- [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)
|
|
5
4
|
|
|
6
|
-
Execute operations over deep object structures without worries. Compare, modify, reshape or extract data. Immutability is taken as consideration by this library.
|
|
7
5
|
|
|
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
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.
|
|
16
36
|
|
|
17
|
-
## Installation
|
|
18
37
|
|
|
38
|
+
## Installation
|
|
19
39
|
Install for node.js projects by writing in your terminal:
|
|
20
40
|
```
|
|
21
|
-
npm install dt-toolbox
|
|
41
|
+
npm install dt-toolbox
|
|
22
42
|
```
|
|
23
43
|
|
|
24
44
|
Once it has been installed, it can be used by writing this line of JavaScript:
|
|
@@ -28,458 +48,900 @@ import dtbox from 'dt-toolbox'
|
|
|
28
48
|
|
|
29
49
|
|
|
30
50
|
|
|
31
|
-
##
|
|
51
|
+
## How it works?
|
|
52
|
+
|
|
53
|
+
Use Dt-toolbox methods(init and load) to create a `dt-object`.
|
|
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;
|
|
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.
|
|
32
65
|
|
|
33
|
-
|
|
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**.
|
|
67
|
+
|
|
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.
|
|
34
76
|
```js
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
+
```
|
|
40
103
|
|
|
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'
|
|
104
|
+
Take a look on the library APIs and see the '**Examples**' section bellow.
|
|
51
105
|
|
|
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'
|
|
106
|
+
### dt-toolbox API Fast Reference
|
|
59
107
|
|
|
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'
|
|
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
|
+
```
|
|
79
115
|
|
|
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"
|
|
116
|
+
### dt-object API Fast Reference
|
|
85
117
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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'
|
|
94
126
|
```
|
|
95
127
|
|
|
128
|
+
### dt-storage API Fast Reference
|
|
96
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.
|
|
97
132
|
|
|
133
|
+
*Important*: Result of building a DT-model returns as a separate dt-object and will not modify anything inside actual dt-object.
|
|
98
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'
|
|
99
149
|
|
|
100
|
-
|
|
150
|
+
```
|
|
101
151
|
|
|
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
152
|
|
|
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
153
|
|
|
106
|
-
|
|
154
|
+
## DT Toolbox API
|
|
107
155
|
|
|
108
|
-
|
|
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.
|
|
109
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
|
+
```
|
|
110
180
|
|
|
111
181
|
|
|
112
182
|
|
|
183
|
+
### dtbox.load ()
|
|
184
|
+
Create a new dt-object from data that is a DT-model.
|
|
113
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
|
+
];
|
|
114
213
|
|
|
214
|
+
const dtStore = dtbox.load ( dtData ); // Load DT-model data to dt-object
|
|
215
|
+
```
|
|
115
216
|
|
|
116
217
|
|
|
117
218
|
|
|
219
|
+
### dtbox.flat ()
|
|
220
|
+
Convert a data to DT-model without creation of dt-object.
|
|
118
221
|
|
|
119
|
-
|
|
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
|
+
```
|
|
120
270
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
### dtbox.convert ()
|
|
274
|
+
Direct convertion from model to model without creation of dt-object.
|
|
124
275
|
|
|
125
276
|
```js
|
|
126
|
-
let st = {
|
|
127
|
-
name : {
|
|
128
|
-
firstName : 'Peter'
|
|
129
|
-
, surname : 'Naydenov'
|
|
130
|
-
}
|
|
131
|
-
, friends : [ 'Tisho', 'Dibo', 'Ivo', 'Vasil' ]
|
|
132
|
-
}
|
|
133
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
|
+
*/
|
|
134
296
|
```
|
|
135
|
-
|
|
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.
|
|
136
302
|
|
|
137
303
|
```js
|
|
138
|
-
|
|
304
|
+
const walk = dtbox.getWalk ();
|
|
305
|
+
|
|
139
306
|
```
|
|
140
307
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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.
|
|
144
317
|
|
|
145
318
|
```js
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
,
|
|
150
|
-
,
|
|
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
|
|
151
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
|
|
384
|
+
]
|
|
385
|
+
]
|
|
152
386
|
|
|
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
|
-
}
|
|
387
|
+
*/
|
|
162
388
|
```
|
|
163
389
|
|
|
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
390
|
|
|
168
391
|
|
|
392
|
+
### dt.export ()
|
|
393
|
+
Returns DT-model from dt-object.
|
|
169
394
|
|
|
170
|
-
Extract a flat information:
|
|
171
395
|
```js
|
|
172
|
-
dt.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
+
|
|
177
416
|
```
|
|
178
417
|
|
|
179
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
|
+
```
|
|
434
|
+
|
|
180
435
|
|
|
181
|
-
Let's play with DT Toolbox:
|
|
182
436
|
|
|
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()**.
|
|
183
439
|
```js
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
,
|
|
188
|
-
;
|
|
189
|
-
|
|
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
|
-
|
|
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
|
|
203
444
|
```
|
|
204
445
|
|
|
205
|
-
### Convert ST to DT objects
|
|
206
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:
|
|
207
449
|
```js
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
+
|
|
212
460
|
```
|
|
213
461
|
|
|
214
|
-
###
|
|
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.
|
|
215
464
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
+
```
|
|
219
482
|
|
|
220
|
-
Overwrite will 'add' and 'update'.
|
|
221
483
|
|
|
484
|
+
### dt.index ()
|
|
485
|
+
Provides a copy of specified by breadcrumbs DT-line.
|
|
222
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
|
+
```
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
223
512
|
|
|
224
|
-
let user = {
|
|
225
|
-
name : 'Peter'
|
|
226
|
-
, age : 42
|
|
227
|
-
}
|
|
228
513
|
|
|
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
514
|
|
|
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
515
|
|
|
253
|
-
|
|
516
|
+
## DT-store API
|
|
254
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
|
+
})
|
|
255
557
|
```
|
|
256
558
|
|
|
559
|
+
### store.from ()
|
|
560
|
+
Scan deeper from specified dt-line by location(breadcrumbs).
|
|
257
561
|
|
|
258
|
-
|
|
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
|
+
});
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
|
|
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.
|
|
259
599
|
|
|
260
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
|
+
```
|
|
261
626
|
|
|
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
627
|
|
|
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
628
|
|
|
317
|
-
|
|
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
|
+
});
|
|
318
659
|
```
|
|
319
660
|
|
|
320
661
|
|
|
321
662
|
|
|
322
|
-
###
|
|
663
|
+
### store.find ()
|
|
664
|
+
String search for exact object name
|
|
323
665
|
|
|
324
|
-
|
|
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
|
+
```
|
|
692
|
+
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
### store.like ()
|
|
696
|
+
String search in dt-line name
|
|
325
697
|
|
|
326
698
|
```js
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
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
|
+
});
|
|
349
725
|
```
|
|
350
726
|
|
|
351
727
|
|
|
352
|
-
## Data-types
|
|
353
728
|
|
|
354
|
-
|
|
729
|
+
// DT-model structure and fields creation:
|
|
730
|
+
### store.set ()
|
|
731
|
+
Define new dt-line record
|
|
732
|
+
|
|
355
733
|
```js
|
|
356
734
|
const data = {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
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
|
+
}
|
|
363
774
|
}
|
|
775
|
+
*/
|
|
364
776
|
```
|
|
365
777
|
|
|
366
|
-
|
|
367
|
-
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
### store.connect ()
|
|
781
|
+
Creates a list of connections between two already existing dt-lines
|
|
782
|
+
|
|
368
783
|
```js
|
|
369
|
-
{
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
+
*/
|
|
377
805
|
```
|
|
378
806
|
|
|
379
807
|
|
|
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.
|
|
808
|
+
|
|
809
|
+
### store.save ()
|
|
810
|
+
Save a property to flatData object in existing dt-line.
|
|
811
|
+
|
|
385
812
|
```js
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
]
|
|
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
|
+
*/
|
|
411
836
|
```
|
|
412
837
|
|
|
413
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
|
+
|
|
414
893
|
### MidFlat
|
|
415
|
-
|
|
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:
|
|
416
895
|
|
|
417
896
|
```js
|
|
418
897
|
{
|
|
419
898
|
'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
|
-
}
|
|
899
|
+
, 'familyMembers' : ['Veselina', 'Iskra', 'Maria', 'Vasil', 'Vladimir', 'Petya' ]
|
|
900
|
+
, 'shoes/winter' : [ 'Keen', 'Head' ]
|
|
901
|
+
, 'shoes/summer' : [ 'Lotto', 'Asics' ]
|
|
436
902
|
}
|
|
437
903
|
```
|
|
438
904
|
|
|
439
905
|
|
|
440
906
|
|
|
441
|
-
|
|
442
|
-
|
|
443
907
|
### Breadcrumbs
|
|
444
|
-
|
|
445
908
|
It's a flat interpratation of the data and looks like this:
|
|
909
|
+
|
|
446
910
|
```js
|
|
447
911
|
{
|
|
448
|
-
'
|
|
449
|
-
, '
|
|
450
|
-
, '
|
|
451
|
-
, '
|
|
452
|
-
, '
|
|
453
|
-
, '
|
|
454
|
-
, '
|
|
455
|
-
, '
|
|
456
|
-
, '
|
|
457
|
-
, '
|
|
458
|
-
, '
|
|
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'
|
|
459
923
|
}
|
|
460
924
|
```
|
|
461
925
|
|
|
462
|
-
|
|
463
926
|
### Files
|
|
464
927
|
Data is interpreted like file/folder description.
|
|
928
|
+
|
|
465
929
|
```js
|
|
466
930
|
[
|
|
467
|
-
'
|
|
468
|
-
, '
|
|
469
|
-
, '
|
|
470
|
-
, '
|
|
471
|
-
, '
|
|
472
|
-
, '
|
|
473
|
-
, '
|
|
474
|
-
, '
|
|
475
|
-
, '
|
|
476
|
-
, '
|
|
477
|
-
, '
|
|
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'
|
|
478
942
|
]
|
|
479
943
|
```
|
|
480
944
|
|
|
481
|
-
|
|
482
|
-
|
|
483
945
|
### Tuples
|
|
484
946
|
|
|
485
947
|
Array of tuples. First element represents location + property name, second is the value.
|
|
@@ -487,7 +949,7 @@ Array of tuples. First element represents location + property name, second is th
|
|
|
487
949
|
```js
|
|
488
950
|
[
|
|
489
951
|
['name', 'Peter' ]
|
|
490
|
-
, ['
|
|
952
|
+
, ['familyMembers', 'Veselina']
|
|
491
953
|
, ['familyMembers', 'Iskra']
|
|
492
954
|
, ['familyMembers', 'Maria']
|
|
493
955
|
, ['familyMembers', 'Vasil']
|
|
@@ -501,25 +963,194 @@ Array of tuples. First element represents location + property name, second is th
|
|
|
501
963
|
```
|
|
502
964
|
|
|
503
965
|
|
|
966
|
+
## Examples
|
|
504
967
|
|
|
968
|
+
### Find people under 40
|
|
505
969
|
|
|
970
|
+
Find a people that are under 40 years old and provide the result as a list.
|
|
506
971
|
|
|
507
|
-
|
|
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
|
+
}
|
|
508
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
|
|
509
1142
|
- [Migration guide](https://github.com/PeterNaydenov/dt-toolbox/blob/master/Migration.guide.md)
|
|
510
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)
|
|
511
1145
|
- [Documentation v.2.x.x](https://github.com/PeterNaydenov/dt-toolbox/blob/master/README_v.2.x.x.md)
|
|
512
1146
|
|
|
513
1147
|
|
|
514
1148
|
|
|
515
|
-
|
|
516
1149
|
## Credits
|
|
517
1150
|
'dt-toolbox' was created and supported by Peter Naydenov.
|
|
518
1151
|
|
|
519
1152
|
|
|
520
1153
|
|
|
521
|
-
|
|
522
|
-
|
|
523
1154
|
## License
|
|
524
1155
|
'dt-toolbox' is released under the [MIT License](http://opensource.org/licenses/MIT).
|
|
525
1156
|
|