@cocreate/indexeddb 1.22.5 → 1.23.1
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 +23 -0
- package/package.json +1 -1
- package/prettier.config.js +16 -0
- package/src/index.js +923 -713
package/src/index.js
CHANGED
|
@@ -22,769 +22,979 @@
|
|
|
22
22
|
* For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
import {
|
|
26
|
+
ObjectId,
|
|
27
|
+
dotNotationToObject,
|
|
28
|
+
searchData,
|
|
29
|
+
sortData,
|
|
30
|
+
queryData,
|
|
31
|
+
createUpdate,
|
|
32
|
+
isEqualArray,
|
|
33
|
+
isEqualObject
|
|
34
|
+
} from "@cocreate/utils";
|
|
35
|
+
|
|
36
|
+
let indexedDbFunction;
|
|
28
37
|
|
|
29
38
|
function init() {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
// Check for support.
|
|
40
|
+
if (!("indexedDB" in window)) {
|
|
41
|
+
console.log("This browser doesn't support IndexedDB.");
|
|
42
|
+
setStatus(false);
|
|
43
|
+
return;
|
|
44
|
+
} else {
|
|
45
|
+
try {
|
|
46
|
+
indexedDB.databases();
|
|
47
|
+
if (
|
|
48
|
+
window.CoCreateConfig &&
|
|
49
|
+
window.CoCreateConfig.indexeddb !== false
|
|
50
|
+
)
|
|
51
|
+
setStatus(true);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
setStatus(false);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
44
56
|
}
|
|
45
57
|
|
|
46
58
|
function setStatus(value) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
indexedDbFunction = true
|
|
58
|
-
}
|
|
59
|
+
if (window.CoCreateConfig) window.CoCreateConfig.indexeddb = value;
|
|
60
|
+
else window.CoCreateConfig = { indexeddb: value };
|
|
61
|
+
|
|
62
|
+
if (!value) {
|
|
63
|
+
indexedDbFunction = indexedDb;
|
|
64
|
+
send = value;
|
|
65
|
+
} else if (!send) {
|
|
66
|
+
send = indexedDbFunction;
|
|
67
|
+
indexedDbFunction = true;
|
|
68
|
+
}
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
async function send(data) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
72
|
+
try {
|
|
73
|
+
let newData = [];
|
|
74
|
+
|
|
75
|
+
let type = data.method.split(".")[0];
|
|
76
|
+
if (type === "database") {
|
|
77
|
+
if (data.method === "database.get") {
|
|
78
|
+
return await processDatabase(data);
|
|
79
|
+
} else await processDatabase(data, newData, type);
|
|
80
|
+
} else {
|
|
81
|
+
if (!data["timeStamp"])
|
|
82
|
+
data["timeStamp"] = new Date().toISOString();
|
|
83
|
+
|
|
84
|
+
let databases = data.database;
|
|
85
|
+
if (!databases && data.organization_id)
|
|
86
|
+
databases = [data.organization_id];
|
|
87
|
+
if (!Array.isArray(databases)) databases = [databases];
|
|
88
|
+
|
|
89
|
+
let arrays = data.array || [];
|
|
90
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < databases.length; i++) {
|
|
93
|
+
let database = databases[i];
|
|
94
|
+
if (type === "array") {
|
|
95
|
+
await processArray(data, newData, database, type);
|
|
96
|
+
} else {
|
|
97
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
98
|
+
if (type === "index")
|
|
99
|
+
await processIndex(data, newData, database, type);
|
|
100
|
+
else if (type === "object")
|
|
101
|
+
await processObject(
|
|
102
|
+
data,
|
|
103
|
+
newData,
|
|
104
|
+
database,
|
|
105
|
+
arrays[j],
|
|
106
|
+
type
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return createData(data, newData, type);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
errorHandler(data, error);
|
|
116
|
+
}
|
|
105
117
|
}
|
|
106
118
|
|
|
107
|
-
const dbVersion = new Map()
|
|
119
|
+
const dbVersion = new Map();
|
|
108
120
|
const processDatabase = (data, newData, type) => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
121
|
+
return new Promise(
|
|
122
|
+
(resolve, reject) => {
|
|
123
|
+
if (!data) data = {};
|
|
124
|
+
if (!data[type]) data[type] = [];
|
|
125
|
+
|
|
126
|
+
if (data.method == "database.read") {
|
|
127
|
+
indexedDB.databases().then((databases) => {
|
|
128
|
+
for (let database of databases) {
|
|
129
|
+
if (data.$filter && data.$filter.query) {
|
|
130
|
+
let isFilter = queryData(
|
|
131
|
+
database,
|
|
132
|
+
data.$filter.query
|
|
133
|
+
);
|
|
134
|
+
if (isFilter)
|
|
135
|
+
newData.push({
|
|
136
|
+
$storage: ["indexeddb"],
|
|
137
|
+
...database
|
|
138
|
+
});
|
|
139
|
+
} else
|
|
140
|
+
newData.push({
|
|
141
|
+
$storage: ["indexeddb"],
|
|
142
|
+
...database
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
resolve();
|
|
147
|
+
});
|
|
148
|
+
} else {
|
|
149
|
+
let databases;
|
|
150
|
+
if (data.method == "database.update")
|
|
151
|
+
databases = Object.keys(data.database);
|
|
152
|
+
else databases = data.database;
|
|
153
|
+
|
|
154
|
+
if (!Array.isArray(databases)) databases = [databases];
|
|
155
|
+
|
|
156
|
+
for (let i = 0; i < databases.length; i++) {
|
|
157
|
+
let openRequest,
|
|
158
|
+
database = databases[i];
|
|
159
|
+
switch (data.method) {
|
|
160
|
+
case "database.get":
|
|
161
|
+
case "database.create":
|
|
162
|
+
case "database.update":
|
|
163
|
+
openRequest = indexedDB.open(database);
|
|
164
|
+
break;
|
|
165
|
+
case "database.delete":
|
|
166
|
+
openRequest =
|
|
167
|
+
indexedDB.deleteprocessDatabase(database);
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
errorHandler(data, "unknown method", database);
|
|
171
|
+
resolve(data);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
openRequest.onsuccess = function () {
|
|
175
|
+
let db = openRequest.result;
|
|
176
|
+
|
|
177
|
+
if (data.method == "database.update") {
|
|
178
|
+
let objectStoreNames = Array.from(
|
|
179
|
+
db.objectStoreNames
|
|
180
|
+
);
|
|
181
|
+
for (let array of objectStoreNames) {
|
|
182
|
+
let request = array.openCursor();
|
|
183
|
+
|
|
184
|
+
request.onsuccess = function () {
|
|
185
|
+
let cursor = request.result;
|
|
186
|
+
if (cursor) {
|
|
187
|
+
let value = cursor.value;
|
|
188
|
+
|
|
189
|
+
cursor.continue();
|
|
190
|
+
} else {
|
|
191
|
+
// -1
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
request.onerror = function () {
|
|
196
|
+
errorHandler(
|
|
197
|
+
data,
|
|
198
|
+
request.error,
|
|
199
|
+
database,
|
|
200
|
+
array
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
} else if (data.upgrade === true) {
|
|
205
|
+
db.close();
|
|
206
|
+
|
|
207
|
+
let version =
|
|
208
|
+
dbVersion.get(database) ||
|
|
209
|
+
openRequest.result.version;
|
|
210
|
+
resolve(
|
|
211
|
+
indexedDB.open(database, Number((version += 1)))
|
|
212
|
+
);
|
|
213
|
+
dbVersion.set(database, version);
|
|
214
|
+
} else if (data.array) {
|
|
215
|
+
db.close();
|
|
216
|
+
|
|
217
|
+
let version =
|
|
218
|
+
dbVersion.get(database) ||
|
|
219
|
+
openRequest.result.version;
|
|
220
|
+
let request = indexedDB.open(
|
|
221
|
+
database,
|
|
222
|
+
Number((version += 1))
|
|
223
|
+
);
|
|
224
|
+
dbVersion.set(database, version);
|
|
225
|
+
|
|
226
|
+
request.onupgradeneeded = function (event) {
|
|
227
|
+
const db = event.target.result;
|
|
228
|
+
|
|
229
|
+
let arrays = data.array;
|
|
230
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
231
|
+
|
|
232
|
+
for (let j = 0; j < arrays.length; j++) {
|
|
233
|
+
if (
|
|
234
|
+
!db.objectStoreNames.contains(arrays[j])
|
|
235
|
+
) {
|
|
236
|
+
try {
|
|
237
|
+
db.createObjectStore(arrays[j], {
|
|
238
|
+
keyPath: "_id",
|
|
239
|
+
autoIncrement: true
|
|
240
|
+
});
|
|
241
|
+
} catch (error) {
|
|
242
|
+
errorHandler(
|
|
243
|
+
data,
|
|
244
|
+
error,
|
|
245
|
+
database,
|
|
246
|
+
arrays[j]
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (data.indexName) {
|
|
252
|
+
const transaction =
|
|
253
|
+
event.target.transaction;
|
|
254
|
+
const objectStore =
|
|
255
|
+
transaction.objectStore(arrays[j]);
|
|
256
|
+
if (
|
|
257
|
+
!objectStore.indexNames.contains(
|
|
258
|
+
data.indexName
|
|
259
|
+
)
|
|
260
|
+
)
|
|
261
|
+
objectStore.createIndex(
|
|
262
|
+
data.indexName,
|
|
263
|
+
data.indexFields,
|
|
264
|
+
{ unique: data.unique || false }
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
request.onsuccess = function (event) {
|
|
271
|
+
if (databases.length - 1 === i) {
|
|
272
|
+
if (data.method == "database.get")
|
|
273
|
+
resolve(event.target.result);
|
|
274
|
+
else resolve(data);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
request.onerror = function (event) {
|
|
279
|
+
errorHandler(
|
|
280
|
+
data,
|
|
281
|
+
event.target.error,
|
|
282
|
+
database,
|
|
283
|
+
array
|
|
284
|
+
);
|
|
285
|
+
if (databases.length - 1 === i) {
|
|
286
|
+
if (data.method == "database.get")
|
|
287
|
+
resolve(event.target.result);
|
|
288
|
+
else resolve(data);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
} else if (databases.length - 1 === i) {
|
|
292
|
+
if (data.method == "database.get") resolve(db);
|
|
293
|
+
else resolve(data);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
openRequest.onerror = function () {
|
|
298
|
+
errorHandler(data, openRequest.error, database);
|
|
299
|
+
resolve(data);
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
(error) => {
|
|
305
|
+
errorHandler(data, error);
|
|
306
|
+
}
|
|
307
|
+
);
|
|
308
|
+
};
|
|
261
309
|
|
|
262
310
|
async function processArray(data, newData, database, type) {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
311
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
312
|
+
|
|
313
|
+
let objectStoreNames = Array.from(db.objectStoreNames);
|
|
314
|
+
if (data.method == "array.read") {
|
|
315
|
+
if (!data[type]) data[type] = [];
|
|
316
|
+
|
|
317
|
+
for (let i = 0; i < objectStoreNames.length; i++) {
|
|
318
|
+
if (data.$filter && data.$filter.query) {
|
|
319
|
+
let isFilter = queryData(
|
|
320
|
+
{ name: objectStoreNames[i] },
|
|
321
|
+
data.$filter.query
|
|
322
|
+
);
|
|
323
|
+
if (isFilter)
|
|
324
|
+
newData.push({
|
|
325
|
+
name: objectStoreNames,
|
|
326
|
+
$storage: ["indexeddb"],
|
|
327
|
+
$database: [database]
|
|
328
|
+
});
|
|
329
|
+
} else
|
|
330
|
+
newData.push({
|
|
331
|
+
name: objectStoreNames[i],
|
|
332
|
+
$storage: ["indexeddb"],
|
|
333
|
+
$database: [database]
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
db.close();
|
|
338
|
+
|
|
339
|
+
let request = await processDatabase({
|
|
340
|
+
method: "database.get",
|
|
341
|
+
database,
|
|
342
|
+
upgrade: true
|
|
343
|
+
});
|
|
344
|
+
await new Promise((resolve) => {
|
|
345
|
+
request.onupgradeneeded = function (event) {
|
|
346
|
+
let db = event.target.result;
|
|
347
|
+
let arrays;
|
|
348
|
+
if (data.method == "array.update")
|
|
349
|
+
arrays = Object.keys(data[type]);
|
|
350
|
+
else arrays = data[type];
|
|
351
|
+
if (!Array.isArray(arrays)) arrays = [arrays];
|
|
352
|
+
|
|
353
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
354
|
+
let error,
|
|
355
|
+
array = arrays[i];
|
|
356
|
+
|
|
357
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
358
|
+
if (arrayExist && data.method == "array.create") {
|
|
359
|
+
error = "array already exists";
|
|
360
|
+
} else if (data.method == "array.delete") {
|
|
361
|
+
if (objectStoreNames.includes(array)) {
|
|
362
|
+
db.deleteObjectStore(array);
|
|
363
|
+
} else {
|
|
364
|
+
error = "the array does not exist";
|
|
365
|
+
}
|
|
366
|
+
} else {
|
|
367
|
+
if (!arrayExist && data.method == "array.update")
|
|
368
|
+
array = data[type][arrays[i]];
|
|
369
|
+
|
|
370
|
+
if (arrayExist) {
|
|
371
|
+
if (data.method == "array.update") {
|
|
372
|
+
let transaction = event.target.transaction;
|
|
373
|
+
let objectStore =
|
|
374
|
+
transaction.objectStore(array);
|
|
375
|
+
|
|
376
|
+
if (
|
|
377
|
+
!objectStoreNames.includes(
|
|
378
|
+
data[type][arrays[i]]
|
|
379
|
+
)
|
|
380
|
+
)
|
|
381
|
+
array = objectStore.name =
|
|
382
|
+
data[type][arrays[i]];
|
|
383
|
+
else
|
|
384
|
+
error =
|
|
385
|
+
"An array with the new name already exist";
|
|
386
|
+
}
|
|
387
|
+
} else if (data.method == "array.update")
|
|
388
|
+
error = "array does not exists";
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if (!error)
|
|
392
|
+
newData.push({
|
|
393
|
+
name: array,
|
|
394
|
+
$storage: ["indexeddb"],
|
|
395
|
+
$database: [database]
|
|
396
|
+
});
|
|
397
|
+
else errorHandler(data, error, database);
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
request.onsuccess = function (event) {
|
|
402
|
+
event.target.result.close();
|
|
403
|
+
resolve();
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
request.onerror = function (event) {
|
|
407
|
+
errorHandler(data, event.target.error, database);
|
|
408
|
+
resolve();
|
|
409
|
+
};
|
|
410
|
+
});
|
|
411
|
+
}
|
|
344
412
|
}
|
|
345
413
|
|
|
346
414
|
async function processIndex(data, newData, database, array, type) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
415
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
416
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
417
|
+
if (arrayExist) {
|
|
418
|
+
// ToDO: switch here to types
|
|
419
|
+
let transaction = db.transaction(array, "readonly");
|
|
420
|
+
let objectStore = transaction.objectStore(array);
|
|
421
|
+
let indexNames = Array.from(objectStore.indexNames);
|
|
422
|
+
|
|
423
|
+
if (data.method == "index.read") {
|
|
424
|
+
for (let i = 0; i < indexNames.length; i++) {
|
|
425
|
+
let name = indexNames[i];
|
|
426
|
+
if (data.$filter && data.$filter.query)
|
|
427
|
+
if (!queryData({ name }, data.$filter.query)) continue;
|
|
428
|
+
|
|
429
|
+
newData.push({
|
|
430
|
+
name,
|
|
431
|
+
$storage: ["indexeddb"],
|
|
432
|
+
$database: [database],
|
|
433
|
+
$array: [array]
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
db.close();
|
|
437
|
+
} else {
|
|
438
|
+
db.close();
|
|
439
|
+
let indexes;
|
|
440
|
+
if (data.method == "index.update")
|
|
441
|
+
indexes = Object.keys(data[type]);
|
|
442
|
+
else indexes = data[type];
|
|
443
|
+
|
|
444
|
+
if (!Array.isArray(indexes)) indexes = [indexes];
|
|
445
|
+
|
|
446
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
447
|
+
let error,
|
|
448
|
+
index = indexes[i];
|
|
449
|
+
db = await processDatabase({
|
|
450
|
+
method: "database.get",
|
|
451
|
+
database,
|
|
452
|
+
upgrade: true
|
|
453
|
+
});
|
|
454
|
+
let transaction = db.transaction;
|
|
455
|
+
let objectStore = transaction.objectStore(array);
|
|
456
|
+
let indexExist = indexNames.includes(index);
|
|
457
|
+
|
|
458
|
+
if (data.method == "index.create") {
|
|
459
|
+
if (!indexExist)
|
|
460
|
+
objectStore.createIndex(index, index, {
|
|
461
|
+
unique: false
|
|
462
|
+
});
|
|
463
|
+
else error = "index already exist";
|
|
464
|
+
} else if (indexExist) {
|
|
465
|
+
if (data.method == "index.delete")
|
|
466
|
+
objectStore.deleteIndex(index);
|
|
467
|
+
else if (
|
|
468
|
+
data.method == "index.update" &&
|
|
469
|
+
!indexNames.includes(data[type][indexes[i]])
|
|
470
|
+
) {
|
|
471
|
+
if (!indexNames.includes(data[type][indexes[i]])) {
|
|
472
|
+
let indexObj = objectStore.index(index);
|
|
473
|
+
index = indexObj.name = data[type][indexes[i]];
|
|
474
|
+
} else error = "new index name already exist";
|
|
475
|
+
}
|
|
476
|
+
} else error = "index does not exist";
|
|
477
|
+
|
|
478
|
+
if (!error)
|
|
479
|
+
newData.push({
|
|
480
|
+
name: index,
|
|
481
|
+
$storage: ["indexeddb"],
|
|
482
|
+
$database: [database],
|
|
483
|
+
$array: [array]
|
|
484
|
+
});
|
|
485
|
+
else errorHandler(data, error, database, array);
|
|
486
|
+
|
|
487
|
+
db.result.close();
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
409
491
|
}
|
|
410
492
|
|
|
411
493
|
async function processObject(data, newData, database, array, type) {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
494
|
+
let db = await processDatabase({ method: "database.get", database });
|
|
495
|
+
|
|
496
|
+
try {
|
|
497
|
+
if (!data[type]) data[type] = [];
|
|
498
|
+
else if (typeof data[type] === "string")
|
|
499
|
+
data[type] = [{ _id: data[type] }];
|
|
500
|
+
else if (!Array.isArray(data[type])) data[type] = [data[type]];
|
|
501
|
+
|
|
502
|
+
let isFilter;
|
|
503
|
+
if (data.$filter) isFilter = true;
|
|
504
|
+
|
|
505
|
+
let arrayExist = db.objectStoreNames.contains(array);
|
|
506
|
+
if (!arrayExist) {
|
|
507
|
+
db.close();
|
|
508
|
+
if (
|
|
509
|
+
data.method == "object.create" ||
|
|
510
|
+
data.method == "object.update"
|
|
511
|
+
) {
|
|
512
|
+
db = await processDatabase({
|
|
513
|
+
method: "database.get",
|
|
514
|
+
database,
|
|
515
|
+
array
|
|
516
|
+
});
|
|
517
|
+
} else {
|
|
518
|
+
return errorHandler(
|
|
519
|
+
data,
|
|
520
|
+
"array does not exist",
|
|
521
|
+
database,
|
|
522
|
+
array
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
if (!array || !db)
|
|
528
|
+
throw new Error({ error: "This is an error message.", db, array });
|
|
529
|
+
|
|
530
|
+
let lastItem;
|
|
531
|
+
if ((isFilter && !data[type].length) || data.isFilter) {
|
|
532
|
+
if (data[type].length) lastItem = data[type][data[type].length - 1];
|
|
533
|
+
data[type] = [{ isFilter: "isEmptyObjectFilter" }];
|
|
534
|
+
|
|
535
|
+
// data[type].splice(0, 0, { isFilter: 'isEmptyObjectFilter' });
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
let transactionType = "readwrite";
|
|
539
|
+
if (data.method == "object.read") transactionType = "readonly";
|
|
540
|
+
|
|
541
|
+
let transaction = db.transaction([array], transactionType);
|
|
542
|
+
let objectStore = transaction.objectStore(array);
|
|
543
|
+
|
|
544
|
+
let globalOperators = getGlobalOperators(data);
|
|
545
|
+
let upsert = data.upsert;
|
|
546
|
+
|
|
547
|
+
for (let i = 0; i < data[type].length; i++) {
|
|
548
|
+
const reference = {
|
|
549
|
+
$storage: ["indexeddb"],
|
|
550
|
+
$database: [database],
|
|
551
|
+
$array: [array]
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
delete data[type][i].$storage;
|
|
555
|
+
delete data[type][i].$database;
|
|
556
|
+
delete data[type][i].$array;
|
|
557
|
+
|
|
558
|
+
if (data.method == "object.create") {
|
|
559
|
+
if (data.organization_id)
|
|
560
|
+
data[type][i]["organization_id"] = data.organization_id;
|
|
561
|
+
|
|
562
|
+
if (!data[type][i]._id)
|
|
563
|
+
data[type][i]["_id"] = ObjectId().toString();
|
|
564
|
+
data[type][i] = dotNotationToObject(data[type][i]);
|
|
565
|
+
|
|
566
|
+
// TODO: user_id || clientId shohould be retrieved from CoCreate
|
|
567
|
+
data[type][i]["created"] = {
|
|
568
|
+
on: data.timeStamp,
|
|
569
|
+
by: data.user_id || data.clientId
|
|
570
|
+
};
|
|
571
|
+
data[type][i] = await add(objectStore, data[type][i]);
|
|
572
|
+
data[type][i] = { ...reference, ...data[type][i] };
|
|
573
|
+
} else {
|
|
574
|
+
if (data[type][i].$filter) isFilter = true;
|
|
575
|
+
|
|
576
|
+
if (data.method == "object.update") {
|
|
577
|
+
if (data.organization_id)
|
|
578
|
+
data[type][i]["organization_id"] = data.organization_id;
|
|
579
|
+
|
|
580
|
+
if (data[type][i].$upsert) upsert = data[type][i].$upsert;
|
|
581
|
+
// TODO: user_id || clientId shohould be retrieved from CoCreate
|
|
582
|
+
if (!data[type][i].modified)
|
|
583
|
+
data[type][i].modified = {
|
|
584
|
+
on: data.timeStamp,
|
|
585
|
+
by: data.user_id || data.clientId
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
let index = 0,
|
|
590
|
+
limit,
|
|
591
|
+
range,
|
|
592
|
+
direction;
|
|
593
|
+
if (data[type][i]._id) {
|
|
594
|
+
range = IDBKeyRange.only(data[type][i]._id);
|
|
595
|
+
} else if (isFilter) {
|
|
596
|
+
let indexName;
|
|
597
|
+
let indexFields;
|
|
598
|
+
|
|
599
|
+
if (data.$filter) {
|
|
600
|
+
// TODO: requires a more robust sorting thats suports various directions
|
|
601
|
+
// Build compound index name from sort keys
|
|
602
|
+
if (data.$filter.sort && data.$filter.sort.length > 0) {
|
|
603
|
+
// Create a standard index name without _id
|
|
604
|
+
let sortKeys = data.$filter.sort
|
|
605
|
+
.map((sort) => sort.key)
|
|
606
|
+
.filter((key) => key !== "_id");
|
|
607
|
+
indexName = sortKeys.join("_"); // e.g., "createdAt_category"
|
|
608
|
+
|
|
609
|
+
// Define compound index fields
|
|
610
|
+
indexFields = [...sortKeys];
|
|
611
|
+
|
|
612
|
+
// Set cursor direction based on the first sort key direction
|
|
613
|
+
direction =
|
|
614
|
+
data.$filter.sort[0].direction === "desc"
|
|
615
|
+
? "prev"
|
|
616
|
+
: "next";
|
|
617
|
+
|
|
618
|
+
// Use last item's values, including _id, to set up the range for pagination
|
|
619
|
+
if (indexName && lastItem && lastItem._id) {
|
|
620
|
+
indexName += "_id";
|
|
621
|
+
indexFields.push("_id");
|
|
622
|
+
let lastKeyValues = [
|
|
623
|
+
...sortKeys.map((key) => lastItem[key]),
|
|
624
|
+
lastItem._id
|
|
625
|
+
]; // Compound key array with _id
|
|
626
|
+
|
|
627
|
+
// Create IDBKeyRange based on direction and lastKeyValues
|
|
628
|
+
if (direction === "next") {
|
|
629
|
+
range = IDBKeyRange.lowerBound(
|
|
630
|
+
lastKeyValues,
|
|
631
|
+
true
|
|
632
|
+
);
|
|
633
|
+
} else {
|
|
634
|
+
range = IDBKeyRange.upperBound(
|
|
635
|
+
lastKeyValues,
|
|
636
|
+
true
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
} else if (
|
|
641
|
+
data.$filter.query &&
|
|
642
|
+
data.$filter.query[0] &&
|
|
643
|
+
data.$filter.query[0].key
|
|
644
|
+
) {
|
|
645
|
+
if (data.$filter.query[0].operator === "$eq") {
|
|
646
|
+
range = IDBKeyRange.only(
|
|
647
|
+
data.$filter.query[0].value
|
|
648
|
+
);
|
|
649
|
+
} else if (
|
|
650
|
+
data.$filter.query[0].operator === "$gt"
|
|
651
|
+
) {
|
|
652
|
+
range = IDBKeyRange.lowerBound(
|
|
653
|
+
data.$filter.query[0].value,
|
|
654
|
+
true
|
|
655
|
+
);
|
|
656
|
+
} else if (
|
|
657
|
+
data.$filter.query[0].operator === "$lt"
|
|
658
|
+
) {
|
|
659
|
+
range = IDBKeyRange.upperBound(
|
|
660
|
+
data.$filter.query[0].value,
|
|
661
|
+
true
|
|
662
|
+
);
|
|
663
|
+
} else if (
|
|
664
|
+
data.$filter.query[0].operator === "$gte"
|
|
665
|
+
) {
|
|
666
|
+
range = IDBKeyRange.lowerBound(
|
|
667
|
+
data.$filter.query[0].value
|
|
668
|
+
);
|
|
669
|
+
} else if (
|
|
670
|
+
data.$filter.query[0].operator === "$lte"
|
|
671
|
+
) {
|
|
672
|
+
range = IDBKeyRange.upperBound(
|
|
673
|
+
data.$filter.query[0].value
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
indexName = data.$filter.query[0].key;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (indexName && !indexName.includes("-")) {
|
|
682
|
+
// Check if the compound index exists; create it if not
|
|
683
|
+
let indexNames = Array.from(objectStore.indexNames);
|
|
684
|
+
if (!indexNames.includes(indexName)) {
|
|
685
|
+
db.close();
|
|
686
|
+
db = await processDatabase({
|
|
687
|
+
method: "database.get",
|
|
688
|
+
database,
|
|
689
|
+
array,
|
|
690
|
+
indexName,
|
|
691
|
+
indexFields
|
|
692
|
+
});
|
|
693
|
+
transaction = db.transaction(array, "readwrite");
|
|
694
|
+
objectStore = transaction.objectStore(array);
|
|
695
|
+
}
|
|
696
|
+
objectStore = objectStore.index(indexName);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
let count = objectStore.count();
|
|
700
|
+
count.onsuccess = function () {
|
|
701
|
+
if (data.$filter) data.$filter.count = count.result;
|
|
702
|
+
else if (data.object.$filter)
|
|
703
|
+
data.object.$filter.count = count.result;
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
if (data.$filter) {
|
|
707
|
+
if (data.$filter.index) index = data.$filter.index;
|
|
708
|
+
if (data.$filter.limit) limit = data.$filter.limit;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (data[type][i].$filter) {
|
|
712
|
+
if (data[type][i].$filter.index)
|
|
713
|
+
index = data[type][i].$filter.index;
|
|
714
|
+
if (data[type][i].$filter.limit)
|
|
715
|
+
limit = data[type][i].$filter.limit;
|
|
716
|
+
}
|
|
717
|
+
} else if (
|
|
718
|
+
data.method == "object.delete" ||
|
|
719
|
+
(data.method == "object.update" &&
|
|
720
|
+
!range &&
|
|
721
|
+
!upsert &&
|
|
722
|
+
!isFilter)
|
|
723
|
+
) {
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
await openCursor(
|
|
728
|
+
objectStore,
|
|
729
|
+
range,
|
|
730
|
+
direction,
|
|
731
|
+
data,
|
|
732
|
+
newData,
|
|
733
|
+
isFilter,
|
|
734
|
+
index,
|
|
735
|
+
limit,
|
|
736
|
+
database,
|
|
737
|
+
array,
|
|
738
|
+
upsert,
|
|
739
|
+
type,
|
|
740
|
+
i,
|
|
741
|
+
globalOperators,
|
|
742
|
+
reference
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
if (index) newData = newData.slice(index);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (db.close) db.close();
|
|
750
|
+
} catch (error) {
|
|
751
|
+
errorHandler(data, error, database, array);
|
|
752
|
+
if (db.close) db.close();
|
|
753
|
+
}
|
|
581
754
|
}
|
|
582
755
|
|
|
583
|
-
function openCursor(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
756
|
+
function openCursor(
|
|
757
|
+
objectStore,
|
|
758
|
+
range,
|
|
759
|
+
direction,
|
|
760
|
+
data,
|
|
761
|
+
newData,
|
|
762
|
+
isFilter,
|
|
763
|
+
index,
|
|
764
|
+
limit,
|
|
765
|
+
database,
|
|
766
|
+
array,
|
|
767
|
+
upsert,
|
|
768
|
+
type,
|
|
769
|
+
i,
|
|
770
|
+
globalOperators,
|
|
771
|
+
reference
|
|
772
|
+
) {
|
|
773
|
+
return new Promise(async (resolve, reject) => {
|
|
774
|
+
const request = objectStore.openCursor(range || null, direction); // next, prev
|
|
775
|
+
|
|
776
|
+
let hasUpdated,
|
|
777
|
+
matchedLength = 0,
|
|
778
|
+
hasSkipped;
|
|
779
|
+
request.onsuccess = async () => {
|
|
780
|
+
let cursor = request.result;
|
|
781
|
+
|
|
782
|
+
if (
|
|
783
|
+
data.method === "object.create" ||
|
|
784
|
+
(data.method === "object.update" &&
|
|
785
|
+
((!range && !isFilter && upsert) ||
|
|
786
|
+
(!cursor && upsert && !hasUpdated)))
|
|
787
|
+
) {
|
|
788
|
+
let isMatch = true;
|
|
789
|
+
if (isFilter) {
|
|
790
|
+
if (cursor)
|
|
791
|
+
isMatch = filter(
|
|
792
|
+
objectStore,
|
|
793
|
+
data[type][i],
|
|
794
|
+
data[type][i],
|
|
795
|
+
cursor.value
|
|
796
|
+
);
|
|
797
|
+
else if (data.method === "object.update" && !upsert)
|
|
798
|
+
isMatch = false;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (isMatch !== false) {
|
|
802
|
+
try {
|
|
803
|
+
data[type][i]._id = ObjectId(
|
|
804
|
+
data[type][i]._id
|
|
805
|
+
).toString();
|
|
806
|
+
} catch (error) {
|
|
807
|
+
data[type][i]._id = ObjectId().toString();
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
let result;
|
|
811
|
+
if (data.method == "object.create") {
|
|
812
|
+
data[type][i] = await add(objectStore, data[type][i]);
|
|
813
|
+
} else if (data.method == "object.update") {
|
|
814
|
+
let update = createUpdate(
|
|
815
|
+
cursor && cursor.value ? cursor.value : {},
|
|
816
|
+
data[type][i],
|
|
817
|
+
globalOperators
|
|
818
|
+
);
|
|
819
|
+
if (update) {
|
|
820
|
+
await put(objectStore, update);
|
|
821
|
+
data[type][i].$update = update;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
data[type][i] = { ...reference, ...data[type][i] };
|
|
825
|
+
|
|
826
|
+
matchedLength++;
|
|
827
|
+
}
|
|
828
|
+
resolve();
|
|
829
|
+
} else if (cursor) {
|
|
830
|
+
if (index && !hasSkipped) {
|
|
831
|
+
cursor.advance(index);
|
|
832
|
+
hasSkipped = true;
|
|
833
|
+
} else {
|
|
834
|
+
let isMatch = true;
|
|
835
|
+
if (isFilter)
|
|
836
|
+
isMatch = filter(
|
|
837
|
+
objectStore,
|
|
838
|
+
data,
|
|
839
|
+
data[type][i],
|
|
840
|
+
cursor.value
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
if (isMatch !== false) {
|
|
844
|
+
let result = cursor.value;
|
|
845
|
+
|
|
846
|
+
if (data.method == "object.update") {
|
|
847
|
+
let update = createUpdate(
|
|
848
|
+
cursor.value,
|
|
849
|
+
data[type][i],
|
|
850
|
+
globalOperators
|
|
851
|
+
);
|
|
852
|
+
if (update) await cursorUpdate(cursor, update);
|
|
853
|
+
result = data[type][i];
|
|
854
|
+
result.$update = update;
|
|
855
|
+
// result = cursor.update(update)
|
|
856
|
+
hasUpdated = true;
|
|
857
|
+
// set dotnotation for keys with $operators for items that end in [] to be used by socket.id
|
|
858
|
+
// TODO: if update.$<operator>.someKey[] requires the index of inerted item added to the field name. update.$<operator>.someKey[<index>]
|
|
859
|
+
// TODO: if $addToSet get field name and item if it does not exist.
|
|
860
|
+
// TODO: if $pull get field name and find if item exist and delete.
|
|
861
|
+
} else if (data.method == "object.delete") {
|
|
862
|
+
result = cursor.value;
|
|
863
|
+
cursor.delete();
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
if (data[type][i]._id)
|
|
867
|
+
data[type][i] = { ...reference, ...result };
|
|
868
|
+
else {
|
|
869
|
+
let object = data[type].find(
|
|
870
|
+
(obj) => obj._id && obj._id === result._id
|
|
871
|
+
);
|
|
872
|
+
if (object)
|
|
873
|
+
object = { ...reference, ...object, ...result };
|
|
874
|
+
else newData.push({ ...reference, ...result });
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
if (
|
|
879
|
+
!limit ||
|
|
880
|
+
(limit && limit > newData.length + matchedLength)
|
|
881
|
+
) {
|
|
882
|
+
cursor.continue();
|
|
883
|
+
} else {
|
|
884
|
+
resolve();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
} else {
|
|
888
|
+
resolve();
|
|
889
|
+
}
|
|
890
|
+
};
|
|
891
|
+
|
|
892
|
+
request.onerror = () => {
|
|
893
|
+
reject(request.error);
|
|
894
|
+
};
|
|
895
|
+
});
|
|
682
896
|
}
|
|
683
897
|
|
|
684
898
|
function add(objectStore, object) {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
899
|
+
return new Promise((resolve, reject) => {
|
|
900
|
+
const store = objectStore.objectStore || objectStore;
|
|
901
|
+
let request = store.add(object);
|
|
902
|
+
request.onsuccess = () => resolve(object);
|
|
903
|
+
request.onerror = () => reject(request.error);
|
|
904
|
+
});
|
|
691
905
|
}
|
|
692
906
|
|
|
693
907
|
function get(objectStore, object) {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
908
|
+
return new Promise((resolve, reject) => {
|
|
909
|
+
const request = objectStore.get(object._id);
|
|
910
|
+
request.onsuccess = () => resolve(request.result);
|
|
911
|
+
request.onerror = () => reject(request.error);
|
|
912
|
+
});
|
|
699
913
|
}
|
|
700
914
|
|
|
701
915
|
function put(objectStore, object) {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
916
|
+
return new Promise((resolve, reject) => {
|
|
917
|
+
const store = objectStore.objectStore || objectStore;
|
|
918
|
+
let request = store.put(object);
|
|
705
919
|
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
920
|
+
request.onsuccess = () => resolve(object);
|
|
921
|
+
request.onerror = () => reject(request.error);
|
|
922
|
+
});
|
|
709
923
|
}
|
|
710
924
|
|
|
711
925
|
function deleteObject(objectStore, object) {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
926
|
+
return new Promise((resolve, reject) => {
|
|
927
|
+
const request = objectStore.delete(object._id);
|
|
928
|
+
request.onsuccess = () => resolve(object);
|
|
929
|
+
request.onerror = () => reject(request.error);
|
|
930
|
+
});
|
|
717
931
|
}
|
|
718
932
|
|
|
719
933
|
function cursorUpdate(cursor, update) {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
934
|
+
return new Promise((resolve, reject) => {
|
|
935
|
+
const request = cursor.update(update);
|
|
936
|
+
request.onsuccess = () => resolve(request.source.value);
|
|
937
|
+
request.onerror = () => reject(request.error);
|
|
938
|
+
});
|
|
725
939
|
}
|
|
726
940
|
|
|
727
|
-
|
|
728
941
|
function filter(objectStore, data, object, result) {
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
return isMatch
|
|
942
|
+
let isMatch = true;
|
|
943
|
+
let filter = data.$filter || object.$filter;
|
|
944
|
+
if (filter) {
|
|
945
|
+
if (filter.query) isMatch = queryData(result, filter.query);
|
|
946
|
+
if (isMatch && filter.search)
|
|
947
|
+
isMatch = searchData(result, filter.search);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return isMatch;
|
|
739
951
|
}
|
|
740
952
|
|
|
741
953
|
function getGlobalOperators(data, object = {}) {
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
return object
|
|
954
|
+
for (let operator of Object.keys(data)) {
|
|
955
|
+
if (!operator.startsWith("$")) return;
|
|
956
|
+
for (let key of Object.keys(data[operator]))
|
|
957
|
+
object[operator + "." + key] = data[operator][key];
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
return object;
|
|
750
961
|
}
|
|
751
962
|
|
|
752
963
|
function createData(data, newData, type) {
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
964
|
+
// data.request = data[type] || {}
|
|
965
|
+
if (
|
|
966
|
+
data[type] &&
|
|
967
|
+
data[type][0] &&
|
|
968
|
+
data[type][0].isFilter === "isEmptyObjectFilter"
|
|
969
|
+
) {
|
|
970
|
+
data[type].shift();
|
|
971
|
+
data.isFilter = true;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
data[type].push(...newData);
|
|
975
|
+
|
|
976
|
+
if (data.$filter) {
|
|
977
|
+
if (data.$filter.sort)
|
|
978
|
+
data[type] = sortData(data[type], data.$filter.sort);
|
|
979
|
+
|
|
980
|
+
data.$filter.startingIndex = data.$filter.index;
|
|
981
|
+
data.$filter.index += data[type].length;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
return data;
|
|
770
985
|
}
|
|
771
986
|
|
|
772
987
|
function errorHandler(data, error, database, array) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
error['array'] = array
|
|
782
|
-
if (data.error)
|
|
783
|
-
data.error.push(error)
|
|
784
|
-
else
|
|
785
|
-
data.error = [error]
|
|
988
|
+
console.error(error, data);
|
|
989
|
+
// if (typeof error == "object") error["storage"] = "indexeddb";
|
|
990
|
+
// else error = { storage: "indexeddb", message: error };
|
|
991
|
+
|
|
992
|
+
// if (database) error["database"] = database;
|
|
993
|
+
// if (array) error["array"] = array;
|
|
994
|
+
// if (data.error) data.error.push(error);
|
|
995
|
+
// else data.error = [error];
|
|
786
996
|
}
|
|
787
997
|
|
|
788
998
|
init();
|
|
789
999
|
|
|
790
|
-
export default { send, ObjectId }
|
|
1000
|
+
export default { send, ObjectId };
|