cozy-client 60.29.0 → 60.30.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/dist/CozyClient.js +1 -1
- package/dist/store/queries.js +110 -10
- package/dist/store/queries.spec.js +59 -0
- package/package.json +2 -2
- package/types/store/queries.d.ts +4 -0
package/dist/CozyClient.js
CHANGED
|
@@ -3126,7 +3126,7 @@ var CozyClient = /*#__PURE__*/function () {
|
|
|
3126
3126
|
CozyClient.hooks = CozyClient.hooks || {};
|
|
3127
3127
|
CozyClient.fetchPolicies = _policies.default; //COZY_CLIENT_VERSION_PACKAGE in replaced by babel. See babel config
|
|
3128
3128
|
|
|
3129
|
-
CozyClient.version = "60.
|
|
3129
|
+
CozyClient.version = "60.30.0";
|
|
3130
3130
|
|
|
3131
3131
|
_microee.default.mixin(CozyClient);
|
|
3132
3132
|
|
package/dist/store/queries.js
CHANGED
|
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.QueryIDGenerator = exports.getQueryFromSlice = exports.mapIdsToDocuments = exports.resetQuery = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports.default = exports.updateData = exports.makeSorterFromDefinition = exports.executeQueryFromState = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.sortAndLimitDocsIds = exports.isReceivingData = exports.isQueryAction = void 0;
|
|
8
|
+
exports.QueryIDGenerator = exports.getQueryFromSlice = exports.mapIdsToDocuments = exports.resetQuery = exports.receiveQueryError = exports.receiveQueryResult = exports.loadQuery = exports.initQuery = exports.default = exports.updateData = exports.computeMatchPartition = exports.makeSorterFromDefinition = exports.executeQueryFromState = exports.mergeSelectorAndPartialIndex = exports.convert$gtNullSelectors = exports.sortAndLimitDocsIds = exports.isReceivingData = exports.isQueryAction = void 0;
|
|
9
9
|
|
|
10
10
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
11
11
|
|
|
@@ -53,6 +53,12 @@ var _logger = _interopRequireDefault(require("../logger"));
|
|
|
53
53
|
|
|
54
54
|
var _stateHelpers = require("./stateHelpers");
|
|
55
55
|
|
|
56
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
57
|
+
|
|
58
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
59
|
+
|
|
60
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
61
|
+
|
|
56
62
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
57
63
|
|
|
58
64
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
@@ -497,6 +503,104 @@ var makeSorterFromDefinition = function makeSorterFromDefinition(definition) {
|
|
|
497
503
|
};
|
|
498
504
|
}
|
|
499
505
|
};
|
|
506
|
+
|
|
507
|
+
exports.makeSorterFromDefinition = makeSorterFromDefinition;
|
|
508
|
+
var dedupNewData = null;
|
|
509
|
+
var dedupCache = null;
|
|
510
|
+
var dedupIdIndex = null;
|
|
511
|
+
|
|
512
|
+
var makeDefinitionKey = function makeDefinitionKey(def) {
|
|
513
|
+
return JSON.stringify([def.doctype, def.selector, def.partialFilter, def.id, def.ids]);
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
var getDedupIdIndex = function getDedupIdIndex(newData) {
|
|
517
|
+
if (dedupIdIndex) return dedupIdIndex;
|
|
518
|
+
var idx = new Map();
|
|
519
|
+
|
|
520
|
+
var _iterator = _createForOfIteratorHelper(newData),
|
|
521
|
+
_step;
|
|
522
|
+
|
|
523
|
+
try {
|
|
524
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
525
|
+
var doc = _step.value;
|
|
526
|
+
if (doc && doc._id != null) idx.set(doc._id, doc);
|
|
527
|
+
}
|
|
528
|
+
} catch (err) {
|
|
529
|
+
_iterator.e(err);
|
|
530
|
+
} finally {
|
|
531
|
+
_iterator.f();
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
dedupIdIndex = idx;
|
|
535
|
+
return idx;
|
|
536
|
+
};
|
|
537
|
+
/**
|
|
538
|
+
* Splits `newData` into the ids matching a query definition and the ids that do not
|
|
539
|
+
*
|
|
540
|
+
* @param {QueryDefinition} definition - Definition of the query
|
|
541
|
+
* @param {Array<import("../types").CozyClientDocument>} newData - New documents
|
|
542
|
+
* @returns {{ matchedIds: Array<string>, unmatchedIds: Array<string> }}
|
|
543
|
+
*/
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
var computeMatchPartition = function computeMatchPartition(definition, newData) {
|
|
547
|
+
if (dedupNewData !== newData) {
|
|
548
|
+
dedupNewData = newData;
|
|
549
|
+
dedupCache = {};
|
|
550
|
+
dedupIdIndex = null;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
var key = makeDefinitionKey(definition);
|
|
554
|
+
var cached = dedupCache[key];
|
|
555
|
+
if (cached) return cached;
|
|
556
|
+
var partition;
|
|
557
|
+
|
|
558
|
+
if (definition.id || definition.ids) {
|
|
559
|
+
var idx = getDedupIdIndex(newData);
|
|
560
|
+
var wanted = definition.id ? [definition.id] : definition.ids;
|
|
561
|
+
var matchedIds = [];
|
|
562
|
+
var unmatchedIds = [];
|
|
563
|
+
|
|
564
|
+
var _iterator2 = _createForOfIteratorHelper(wanted),
|
|
565
|
+
_step2;
|
|
566
|
+
|
|
567
|
+
try {
|
|
568
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
569
|
+
var id = _step2.value;
|
|
570
|
+
var doc = idx.get(id);
|
|
571
|
+
|
|
572
|
+
if (doc) {
|
|
573
|
+
if (!doc._deleted && doc._type === definition.doctype) {
|
|
574
|
+
matchedIds.push((0, _helpers.properId)(doc));
|
|
575
|
+
} else {
|
|
576
|
+
unmatchedIds.push((0, _helpers.properId)(doc));
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
} catch (err) {
|
|
581
|
+
_iterator2.e(err);
|
|
582
|
+
} finally {
|
|
583
|
+
_iterator2.f();
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
partition = {
|
|
587
|
+
matchedIds: matchedIds,
|
|
588
|
+
unmatchedIds: unmatchedIds
|
|
589
|
+
};
|
|
590
|
+
} else {
|
|
591
|
+
var belongsToQuery = makeFilterDocumentFn(definition);
|
|
592
|
+
var res = (0, _mapValues.default)((0, _groupBy.default)(newData, belongsToQuery), function (docs) {
|
|
593
|
+
return docs.map(_helpers.properId);
|
|
594
|
+
});
|
|
595
|
+
partition = {
|
|
596
|
+
matchedIds: res.true === undefined ? [] : res.true,
|
|
597
|
+
unmatchedIds: res.false === undefined ? [] : res.false
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
dedupCache[key] = partition;
|
|
602
|
+
return partition;
|
|
603
|
+
};
|
|
500
604
|
/**
|
|
501
605
|
* Updates query state when new data comes in
|
|
502
606
|
*
|
|
@@ -507,17 +611,13 @@ var makeSorterFromDefinition = function makeSorterFromDefinition(definition) {
|
|
|
507
611
|
*/
|
|
508
612
|
|
|
509
613
|
|
|
510
|
-
exports.
|
|
614
|
+
exports.computeMatchPartition = computeMatchPartition;
|
|
511
615
|
|
|
512
616
|
var updateData = function updateData(query, newData, documents) {
|
|
513
|
-
var
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
var _res$true = res.true,
|
|
518
|
-
matchedIds = _res$true === void 0 ? [] : _res$true,
|
|
519
|
-
_res$false = res.false,
|
|
520
|
-
unmatchedIds = _res$false === void 0 ? [] : _res$false;
|
|
617
|
+
var _computeMatchPartitio = computeMatchPartition(query.definition, newData),
|
|
618
|
+
matchedIds = _computeMatchPartitio.matchedIds,
|
|
619
|
+
unmatchedIds = _computeMatchPartitio.unmatchedIds;
|
|
620
|
+
|
|
521
621
|
var originalIds = query.data;
|
|
522
622
|
var autoUpdate = query.options && query.options.autoUpdate;
|
|
523
623
|
var shouldRemove = !autoUpdate || autoUpdate.remove !== false;
|
|
@@ -9,6 +9,7 @@ import queries, {
|
|
|
9
9
|
loadQuery,
|
|
10
10
|
receiveQueryError,
|
|
11
11
|
updateData,
|
|
12
|
+
computeMatchPartition,
|
|
12
13
|
executeQueryFromState,
|
|
13
14
|
mapIdsToDocuments
|
|
14
15
|
} from './queries'
|
|
@@ -675,6 +676,64 @@ describe('updateData', () => {
|
|
|
675
676
|
})
|
|
676
677
|
})
|
|
677
678
|
|
|
679
|
+
describe('computeMatchPartition', () => {
|
|
680
|
+
it('should resolve a getById query without scanning the whole newData', () => {
|
|
681
|
+
const newData = [TODO_1, TODO_2, TODO_3]
|
|
682
|
+
const definition = Q('io.cozy.todos').getById(TODO_2._id)
|
|
683
|
+
const { matchedIds, unmatchedIds } = computeMatchPartition(
|
|
684
|
+
definition,
|
|
685
|
+
newData
|
|
686
|
+
)
|
|
687
|
+
expect(matchedIds).toEqual([TODO_2._id])
|
|
688
|
+
expect(unmatchedIds).toEqual([])
|
|
689
|
+
})
|
|
690
|
+
|
|
691
|
+
it('should not match a getById query for a missing or wrong-doctype id', () => {
|
|
692
|
+
const newData = [TODO_1, { ...TODO_2, _type: 'io.cozy.other' }]
|
|
693
|
+
expect(
|
|
694
|
+
computeMatchPartition(Q('io.cozy.todos').getById('missing'), newData)
|
|
695
|
+
).toEqual({ matchedIds: [], unmatchedIds: [] })
|
|
696
|
+
expect(
|
|
697
|
+
computeMatchPartition(Q('io.cozy.todos').getById(TODO_2._id), newData)
|
|
698
|
+
).toEqual({ matchedIds: [], unmatchedIds: [TODO_2._id] })
|
|
699
|
+
})
|
|
700
|
+
|
|
701
|
+
it('should treat a deleted document as unmatched for a getById query', () => {
|
|
702
|
+
const newData = [{ ...TODO_1, _deleted: true }]
|
|
703
|
+
expect(
|
|
704
|
+
computeMatchPartition(Q('io.cozy.todos').getById(TODO_1._id), newData)
|
|
705
|
+
).toEqual({ matchedIds: [], unmatchedIds: [TODO_1._id] })
|
|
706
|
+
})
|
|
707
|
+
|
|
708
|
+
it('should resolve a getByIds query', () => {
|
|
709
|
+
const newData = [TODO_1, TODO_2, TODO_3]
|
|
710
|
+
const definition = Q('io.cozy.todos').getByIds([TODO_1._id, 'missing'])
|
|
711
|
+
expect(computeMatchPartition(definition, newData)).toEqual({
|
|
712
|
+
matchedIds: [TODO_1._id],
|
|
713
|
+
unmatchedIds: []
|
|
714
|
+
})
|
|
715
|
+
})
|
|
716
|
+
|
|
717
|
+
it('should partition a selector query with the sift scan', () => {
|
|
718
|
+
const newData = [TODO_1, TODO_2, TODO_3]
|
|
719
|
+
const definition = Q('io.cozy.todos').where({ done: true })
|
|
720
|
+
const { matchedIds, unmatchedIds } = computeMatchPartition(
|
|
721
|
+
definition,
|
|
722
|
+
newData
|
|
723
|
+
)
|
|
724
|
+
expect(matchedIds).toEqual([TODO_3._id])
|
|
725
|
+
expect(unmatchedIds.sort()).toEqual([TODO_1._id, TODO_2._id].sort())
|
|
726
|
+
})
|
|
727
|
+
|
|
728
|
+
it('should memoize the partition per definition within the same newData', () => {
|
|
729
|
+
const newData = [TODO_1, TODO_2]
|
|
730
|
+
const definition = Q('io.cozy.todos').getById(TODO_1._id)
|
|
731
|
+
const first = computeMatchPartition(definition, newData)
|
|
732
|
+
const second = computeMatchPartition(definition, newData)
|
|
733
|
+
expect(second).toBe(first)
|
|
734
|
+
})
|
|
735
|
+
})
|
|
736
|
+
|
|
678
737
|
describe('execute query from state', () => {
|
|
679
738
|
const docState = {
|
|
680
739
|
'io.cozy.files': {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-client",
|
|
3
|
-
"version": "60.
|
|
3
|
+
"version": "60.30.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "dist/index.node.js",
|
|
6
6
|
"browser": "dist/index.js",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"react-native-ios11-devicecheck": "^0.0.3"
|
|
75
75
|
},
|
|
76
76
|
"sideEffects": false,
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "7f9e5753cc1e0b1e1a46e983ec1a556c516a0fc2"
|
|
78
78
|
}
|
package/types/store/queries.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export function convert$gtNullSelectors(selector: any): object;
|
|
|
8
8
|
export function mergeSelectorAndPartialIndex(queryDefinition: object): object;
|
|
9
9
|
export function executeQueryFromState(state: import('../types').CozyStore, queryDefinition: QueryDefinition): import("../types").QueryStateData;
|
|
10
10
|
export function makeSorterFromDefinition(definition: QueryDefinition): (arg0: Array<import("../types").CozyClientDocument>) => Array<import("../types").CozyClientDocument>;
|
|
11
|
+
export function computeMatchPartition(definition: QueryDefinition, newData: Array<import("../types").CozyClientDocument>): {
|
|
12
|
+
matchedIds: Array<string>;
|
|
13
|
+
unmatchedIds: Array<string>;
|
|
14
|
+
};
|
|
11
15
|
export function updateData(query: import("../types").QueryState, newData: Array<import("../types").CozyClientDocument>, documents: import("../types").DocumentsStateSlice): import("../types").QueryState;
|
|
12
16
|
export default queries;
|
|
13
17
|
export function initQuery(queryId: string, queryDefinition: QueryDefinition, options?: import("../types").QueryOptions): object;
|