@wordpress/core-data 7.41.2-next.v.202603102151.0 → 7.42.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 +1 -1
- package/README.md +19 -0
- package/build/actions.cjs +17 -25
- package/build/actions.cjs.map +2 -2
- package/build/awareness/post-editor-awareness.cjs +46 -6
- package/build/awareness/post-editor-awareness.cjs.map +2 -2
- package/build/awareness/types.cjs.map +1 -1
- package/build/entities.cjs +33 -7
- package/build/entities.cjs.map +2 -2
- package/build/hooks/use-entity-prop.cjs +2 -1
- package/build/hooks/use-entity-prop.cjs.map +2 -2
- package/build/hooks/use-post-editor-awareness-state.cjs +84 -3
- package/build/hooks/use-post-editor-awareness-state.cjs.map +2 -2
- package/build/index.cjs +3 -0
- package/build/index.cjs.map +2 -2
- package/build/private-apis.cjs +3 -1
- package/build/private-apis.cjs.map +2 -2
- package/build/queried-data/get-query-parts.cjs +7 -0
- package/build/queried-data/get-query-parts.cjs.map +2 -2
- package/build/queried-data/selectors.cjs +19 -5
- package/build/queried-data/selectors.cjs.map +2 -2
- package/build/reducer.cjs +6 -0
- package/build/reducer.cjs.map +2 -2
- package/build/resolvers.cjs +110 -74
- package/build/resolvers.cjs.map +2 -2
- package/build/selectors.cjs +29 -0
- package/build/selectors.cjs.map +2 -2
- package/build/sync.cjs +3 -0
- package/build/sync.cjs.map +2 -2
- package/build/types.cjs +16 -0
- package/build/types.cjs.map +3 -3
- package/build/utils/block-selection-history.cjs +1 -1
- package/build/utils/block-selection-history.cjs.map +2 -2
- package/build/utils/crdt-blocks.cjs +17 -3
- package/build/utils/crdt-blocks.cjs.map +2 -2
- package/build/utils/crdt-selection.cjs +4 -1
- package/build/utils/crdt-selection.cjs.map +2 -2
- package/build/utils/crdt-user-selections.cjs +9 -6
- package/build/utils/crdt-user-selections.cjs.map +2 -2
- package/build/utils/crdt-utils.cjs +54 -2
- package/build/utils/crdt-utils.cjs.map +2 -2
- package/build/utils/crdt.cjs +4 -23
- package/build/utils/crdt.cjs.map +2 -2
- package/build/utils/index.cjs +3 -0
- package/build/utils/index.cjs.map +2 -2
- package/build/utils/normalize-query-for-resolution.cjs +35 -0
- package/build/utils/normalize-query-for-resolution.cjs.map +7 -0
- package/build-module/actions.mjs +17 -25
- package/build-module/actions.mjs.map +2 -2
- package/build-module/awareness/post-editor-awareness.mjs +46 -6
- package/build-module/awareness/post-editor-awareness.mjs.map +2 -2
- package/build-module/entities.mjs +33 -7
- package/build-module/entities.mjs.map +2 -2
- package/build-module/hooks/use-entity-prop.mjs +2 -1
- package/build-module/hooks/use-entity-prop.mjs.map +2 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs +81 -2
- package/build-module/hooks/use-post-editor-awareness-state.mjs.map +2 -2
- package/build-module/index.mjs +2 -0
- package/build-module/index.mjs.map +2 -2
- package/build-module/private-apis.mjs +6 -2
- package/build-module/private-apis.mjs.map +2 -2
- package/build-module/queried-data/get-query-parts.mjs +7 -0
- package/build-module/queried-data/get-query-parts.mjs.map +2 -2
- package/build-module/queried-data/selectors.mjs +19 -5
- package/build-module/queried-data/selectors.mjs.map +2 -2
- package/build-module/reducer.mjs +6 -0
- package/build-module/reducer.mjs.map +2 -2
- package/build-module/resolvers.mjs +112 -75
- package/build-module/resolvers.mjs.map +2 -2
- package/build-module/selectors.mjs +28 -0
- package/build-module/selectors.mjs.map +2 -2
- package/build-module/sync.mjs +2 -0
- package/build-module/sync.mjs.map +2 -2
- package/build-module/types.mjs +9 -0
- package/build-module/types.mjs.map +4 -4
- package/build-module/utils/block-selection-history.mjs +5 -2
- package/build-module/utils/block-selection-history.mjs.map +2 -2
- package/build-module/utils/crdt-blocks.mjs +17 -3
- package/build-module/utils/crdt-blocks.mjs.map +2 -2
- package/build-module/utils/crdt-selection.mjs +8 -2
- package/build-module/utils/crdt-selection.mjs.map +2 -2
- package/build-module/utils/crdt-user-selections.mjs +10 -7
- package/build-module/utils/crdt-user-selections.mjs.map +2 -2
- package/build-module/utils/crdt-utils.mjs +51 -1
- package/build-module/utils/crdt-utils.mjs.map +2 -2
- package/build-module/utils/crdt.mjs +4 -23
- package/build-module/utils/crdt.mjs.map +2 -2
- package/build-module/utils/index.mjs +2 -0
- package/build-module/utils/index.mjs.map +2 -2
- package/build-module/utils/normalize-query-for-resolution.mjs +14 -0
- package/build-module/utils/normalize-query-for-resolution.mjs.map +7 -0
- package/build-types/actions.d.ts.map +1 -1
- package/build-types/awareness/post-editor-awareness.d.ts +2 -2
- package/build-types/awareness/post-editor-awareness.d.ts.map +1 -1
- package/build-types/awareness/types.d.ts +1 -1
- package/build-types/awareness/types.d.ts.map +1 -1
- package/build-types/entities.d.ts +1 -1
- package/build-types/entities.d.ts.map +1 -1
- package/build-types/hooks/use-entity-prop.d.ts.map +1 -1
- package/build-types/hooks/use-post-editor-awareness-state.d.ts +34 -10
- package/build-types/hooks/use-post-editor-awareness-state.d.ts.map +1 -1
- package/build-types/index.d.ts +2 -0
- package/build-types/index.d.ts.map +1 -1
- package/build-types/private-apis.d.ts.map +1 -1
- package/build-types/queried-data/get-query-parts.d.ts +7 -0
- package/build-types/queried-data/get-query-parts.d.ts.map +1 -1
- package/build-types/queried-data/selectors.d.ts.map +1 -1
- package/build-types/reducer.d.ts.map +1 -1
- package/build-types/resolvers.d.ts +2 -1
- package/build-types/resolvers.d.ts.map +1 -1
- package/build-types/selectors.d.ts +17 -0
- package/build-types/selectors.d.ts.map +1 -1
- package/build-types/sync.d.ts +2 -2
- package/build-types/sync.d.ts.map +1 -1
- package/build-types/types.d.ts +18 -1
- package/build-types/types.d.ts.map +1 -1
- package/build-types/utils/block-selection-history.d.ts.map +1 -1
- package/build-types/utils/crdt-blocks.d.ts.map +1 -1
- package/build-types/utils/crdt-selection.d.ts.map +1 -1
- package/build-types/utils/crdt-user-selections.d.ts +9 -5
- package/build-types/utils/crdt-user-selections.d.ts.map +1 -1
- package/build-types/utils/crdt-utils.d.ts +20 -0
- package/build-types/utils/crdt-utils.d.ts.map +1 -1
- package/build-types/utils/crdt.d.ts +6 -7
- package/build-types/utils/crdt.d.ts.map +1 -1
- package/build-types/utils/index.d.ts +1 -0
- package/build-types/utils/normalize-query-for-resolution.d.ts +12 -0
- package/build-types/utils/normalize-query-for-resolution.d.ts.map +1 -0
- package/build-types/utils/test/crdt-utils.d.ts +2 -0
- package/build-types/utils/test/crdt-utils.d.ts.map +1 -0
- package/package.json +18 -18
- package/src/actions.js +25 -40
- package/src/awareness/post-editor-awareness.ts +106 -7
- package/src/awareness/test/post-editor-awareness.ts +50 -10
- package/src/awareness/types.ts +1 -1
- package/src/entities.js +38 -6
- package/src/hooks/test/use-post-editor-awareness-state.ts +446 -3
- package/src/hooks/use-entity-prop.js +2 -0
- package/src/hooks/use-post-editor-awareness-state.ts +160 -8
- package/src/index.js +1 -0
- package/src/private-apis.js +6 -2
- package/src/queried-data/get-query-parts.js +13 -0
- package/src/queried-data/selectors.js +33 -8
- package/src/queried-data/test/get-query-parts.js +34 -0
- package/src/queried-data/test/selectors.js +183 -0
- package/src/reducer.js +11 -0
- package/src/resolvers.js +136 -88
- package/src/selectors.ts +56 -0
- package/src/sync.ts +2 -0
- package/src/test/entities.js +185 -1
- package/src/test/resolvers.js +64 -11
- package/src/test/selectors.js +150 -0
- package/src/test/store.js +66 -0
- package/src/types.ts +26 -1
- package/src/utils/block-selection-history.ts +5 -2
- package/src/utils/crdt-blocks.ts +32 -3
- package/src/utils/crdt-selection.ts +8 -2
- package/src/utils/crdt-user-selections.ts +20 -8
- package/src/utils/crdt-utils.ts +99 -0
- package/src/utils/crdt.ts +8 -32
- package/src/utils/index.js +1 -0
- package/src/utils/normalize-query-for-resolution.js +23 -0
- package/src/utils/test/crdt-blocks.ts +146 -0
- package/src/utils/test/crdt-user-selections.ts +5 -0
- package/src/utils/test/crdt-utils.ts +387 -0
- package/src/utils/test/crdt.ts +120 -53
package/src/private-apis.js
CHANGED
|
@@ -6,7 +6,9 @@ import { RECEIVE_INTERMEDIATE_RESULTS } from './utils';
|
|
|
6
6
|
import {
|
|
7
7
|
useActiveCollaborators,
|
|
8
8
|
useResolvedSelection,
|
|
9
|
-
|
|
9
|
+
useOnCollaboratorJoin,
|
|
10
|
+
useOnCollaboratorLeave,
|
|
11
|
+
useOnPostSave,
|
|
10
12
|
} from './hooks/use-post-editor-awareness-state';
|
|
11
13
|
import { lock } from './lock-unlock';
|
|
12
14
|
import { retrySyncConnection } from './sync';
|
|
@@ -18,5 +20,7 @@ lock( privateApis, {
|
|
|
18
20
|
retrySyncConnection,
|
|
19
21
|
useActiveCollaborators,
|
|
20
22
|
useResolvedSelection,
|
|
21
|
-
|
|
23
|
+
useOnCollaboratorJoin,
|
|
24
|
+
useOnCollaboratorLeave,
|
|
25
|
+
useOnPostSave,
|
|
22
26
|
} );
|
|
@@ -15,6 +15,8 @@ import { withWeakMapCache, getNormalizedCommaSeparable } from '../utils';
|
|
|
15
15
|
*
|
|
16
16
|
* @property {number} page The query page (1-based index, default 1).
|
|
17
17
|
* @property {number} perPage Items per page for query (default 10).
|
|
18
|
+
* @property {number} offset Absolute item offset (default undefined).
|
|
19
|
+
* When present, also encoded into stableKey.
|
|
18
20
|
* @property {string} stableKey An encoded stable string of all non-
|
|
19
21
|
* pagination, non-fields query parameters.
|
|
20
22
|
* @property {?(string[])} fields Target subset of fields to derive from
|
|
@@ -41,6 +43,7 @@ export function getQueryParts( query ) {
|
|
|
41
43
|
stableKey: '',
|
|
42
44
|
page: 1,
|
|
43
45
|
perPage: 10,
|
|
46
|
+
offset: undefined,
|
|
44
47
|
fields: null,
|
|
45
48
|
include: null,
|
|
46
49
|
context: 'default',
|
|
@@ -67,6 +70,16 @@ export function getQueryParts( query ) {
|
|
|
67
70
|
break;
|
|
68
71
|
|
|
69
72
|
default:
|
|
73
|
+
// Extract offset for use in pagination calculations while
|
|
74
|
+
// still including it in the stableKey (different offsets
|
|
75
|
+
// produce different result sets).
|
|
76
|
+
if ( key === 'offset' ) {
|
|
77
|
+
const numericOffset = Number( value );
|
|
78
|
+
if ( Number.isFinite( numericOffset ) ) {
|
|
79
|
+
parts.offset = numericOffset;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
70
83
|
// While in theory, we could exclude "_fields" from the stableKey
|
|
71
84
|
// because two request with different fields have the same results
|
|
72
85
|
// We're not able to ensure that because the server can decide to omit
|
|
@@ -32,14 +32,17 @@ const queriedItemsCacheByState = new WeakMap();
|
|
|
32
32
|
* @return {?Array} Query items.
|
|
33
33
|
*/
|
|
34
34
|
function getQueriedItemsUncached( state, query ) {
|
|
35
|
-
const {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
const {
|
|
36
|
+
stableKey,
|
|
37
|
+
page,
|
|
38
|
+
perPage,
|
|
39
|
+
offset: queryOffset,
|
|
40
|
+
include,
|
|
41
|
+
fields,
|
|
42
|
+
context,
|
|
43
|
+
} = getQueryParts( query );
|
|
44
|
+
|
|
45
|
+
const itemIds = state.queries?.[ context ]?.[ stableKey ]?.itemIds;
|
|
43
46
|
if ( ! itemIds ) {
|
|
44
47
|
return null;
|
|
45
48
|
}
|
|
@@ -50,6 +53,28 @@ function getQueriedItemsUncached( state, query ) {
|
|
|
50
53
|
? itemIds.length
|
|
51
54
|
: Math.min( startOffset + perPage, itemIds.length );
|
|
52
55
|
|
|
56
|
+
// If the requested page range exceeds the stored itemIds, the data for
|
|
57
|
+
// this specific pagination window may not have been fetched yet. Return
|
|
58
|
+
// null unless totalItems confirms we already have all available items.
|
|
59
|
+
if ( perPage !== -1 && itemIds.length < startOffset + perPage ) {
|
|
60
|
+
const totalItems =
|
|
61
|
+
state.queries[ context ][ stableKey ].meta?.totalItems;
|
|
62
|
+
if ( Number.isFinite( totalItems ) ) {
|
|
63
|
+
// For offset-based queries, totalItems (from X-WP-Total)
|
|
64
|
+
// reflects the global count of all matching items, not the
|
|
65
|
+
// count remaining after the offset. The number of items
|
|
66
|
+
// available for this query is (totalItems - offset), so a
|
|
67
|
+
// partial last page is expected and valid.
|
|
68
|
+
const effectiveTotal =
|
|
69
|
+
queryOffset !== undefined
|
|
70
|
+
? totalItems - queryOffset
|
|
71
|
+
: totalItems;
|
|
72
|
+
if ( itemIds.length < effectiveTotal ) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
53
78
|
const items = [];
|
|
54
79
|
for ( let i = startOffset; i < endOffset; i++ ) {
|
|
55
80
|
const itemId = itemIds[ i ];
|
|
@@ -11,6 +11,7 @@ describe( 'getQueryParts', () => {
|
|
|
11
11
|
context: 'default',
|
|
12
12
|
page: 2,
|
|
13
13
|
perPage: 2,
|
|
14
|
+
offset: undefined,
|
|
14
15
|
stableKey: '',
|
|
15
16
|
fields: null,
|
|
16
17
|
include: null,
|
|
@@ -28,6 +29,7 @@ describe( 'getQueryParts', () => {
|
|
|
28
29
|
context: 'default',
|
|
29
30
|
page: 1,
|
|
30
31
|
perPage: 10,
|
|
32
|
+
offset: undefined,
|
|
31
33
|
stableKey: 'include=1',
|
|
32
34
|
fields: null,
|
|
33
35
|
include: [ 1 ],
|
|
@@ -43,6 +45,7 @@ describe( 'getQueryParts', () => {
|
|
|
43
45
|
context: 'default',
|
|
44
46
|
page: 1,
|
|
45
47
|
perPage: 10,
|
|
48
|
+
offset: undefined,
|
|
46
49
|
stableKey: '%3F=%26&b=2',
|
|
47
50
|
fields: null,
|
|
48
51
|
include: null,
|
|
@@ -56,6 +59,7 @@ describe( 'getQueryParts', () => {
|
|
|
56
59
|
context: 'default',
|
|
57
60
|
page: 1,
|
|
58
61
|
perPage: 10,
|
|
62
|
+
offset: undefined,
|
|
59
63
|
stableKey: 'a%5B0%5D=1&a%5B1%5D=2',
|
|
60
64
|
fields: null,
|
|
61
65
|
include: null,
|
|
@@ -71,6 +75,7 @@ describe( 'getQueryParts', () => {
|
|
|
71
75
|
context: 'default',
|
|
72
76
|
page: 1,
|
|
73
77
|
perPage: 10,
|
|
78
|
+
offset: undefined,
|
|
74
79
|
stableKey: 'b=2',
|
|
75
80
|
fields: null,
|
|
76
81
|
include: null,
|
|
@@ -84,6 +89,7 @@ describe( 'getQueryParts', () => {
|
|
|
84
89
|
context: 'default',
|
|
85
90
|
page: 1,
|
|
86
91
|
perPage: -1,
|
|
92
|
+
offset: undefined,
|
|
87
93
|
stableKey: 'b=2',
|
|
88
94
|
fields: null,
|
|
89
95
|
include: null,
|
|
@@ -97,6 +103,7 @@ describe( 'getQueryParts', () => {
|
|
|
97
103
|
context: 'default',
|
|
98
104
|
page: 1,
|
|
99
105
|
perPage: 10,
|
|
106
|
+
offset: undefined,
|
|
100
107
|
stableKey: '_fields=id%2Ctitle',
|
|
101
108
|
fields: [ 'id', 'title' ],
|
|
102
109
|
include: null,
|
|
@@ -109,10 +116,37 @@ describe( 'getQueryParts', () => {
|
|
|
109
116
|
expect( parts ).toEqual( {
|
|
110
117
|
page: 1,
|
|
111
118
|
perPage: 10,
|
|
119
|
+
offset: undefined,
|
|
112
120
|
stableKey: '',
|
|
113
121
|
include: null,
|
|
114
122
|
fields: null,
|
|
115
123
|
context: 'view',
|
|
116
124
|
} );
|
|
117
125
|
} );
|
|
126
|
+
|
|
127
|
+
it( 'extracts offset and includes it in stableKey', () => {
|
|
128
|
+
const parts = getQueryParts( {
|
|
129
|
+
per_page: 50,
|
|
130
|
+
offset: 100,
|
|
131
|
+
} );
|
|
132
|
+
|
|
133
|
+
expect( parts ).toEqual( {
|
|
134
|
+
context: 'default',
|
|
135
|
+
page: 1,
|
|
136
|
+
perPage: 50,
|
|
137
|
+
offset: 100,
|
|
138
|
+
stableKey: 'offset=100',
|
|
139
|
+
fields: null,
|
|
140
|
+
include: null,
|
|
141
|
+
} );
|
|
142
|
+
} );
|
|
143
|
+
|
|
144
|
+
it( 'ignores non-numeric offset values', () => {
|
|
145
|
+
const parts = getQueryParts( {
|
|
146
|
+
per_page: 10,
|
|
147
|
+
offset: 'abc',
|
|
148
|
+
} );
|
|
149
|
+
|
|
150
|
+
expect( parts.offset ).toBeUndefined();
|
|
151
|
+
} );
|
|
118
152
|
} );
|
|
@@ -239,4 +239,187 @@ describe( 'getQueriedItems', () => {
|
|
|
239
239
|
|
|
240
240
|
expect( result ).toBe( null );
|
|
241
241
|
} );
|
|
242
|
+
|
|
243
|
+
it( 'should return null when per_page exceeds stored itemIds and more items exist', () => {
|
|
244
|
+
const state = {
|
|
245
|
+
items: {
|
|
246
|
+
default: {
|
|
247
|
+
1: { id: 1 },
|
|
248
|
+
2: { id: 2 },
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
itemIsComplete: {
|
|
252
|
+
default: { 1: true, 2: true },
|
|
253
|
+
},
|
|
254
|
+
queries: {
|
|
255
|
+
default: {
|
|
256
|
+
'': {
|
|
257
|
+
itemIds: [ 1, 2 ],
|
|
258
|
+
meta: { totalItems: 5 },
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const result = getQueriedItems( state, { per_page: 3 } );
|
|
265
|
+
expect( result ).toBe( null );
|
|
266
|
+
} );
|
|
267
|
+
|
|
268
|
+
it( 'should return items for offset-based query on the last partial page', () => {
|
|
269
|
+
// Infinite scroll scenario: 103 total items, perPage=50, and the
|
|
270
|
+
// last batch starts at offset=100. The API returns 3 items (items
|
|
271
|
+
// 101-103). X-WP-Total is 103 (the global count). The selector
|
|
272
|
+
// should recognise this as a complete response since
|
|
273
|
+
// 103 - 100 = 3 expected items.
|
|
274
|
+
const state = {
|
|
275
|
+
items: {
|
|
276
|
+
default: {
|
|
277
|
+
101: { id: 101 },
|
|
278
|
+
102: { id: 102 },
|
|
279
|
+
103: { id: 103 },
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
itemIsComplete: {
|
|
283
|
+
default: { 101: true, 102: true, 103: true },
|
|
284
|
+
},
|
|
285
|
+
queries: {
|
|
286
|
+
default: {
|
|
287
|
+
'offset=100': {
|
|
288
|
+
itemIds: [ 101, 102, 103 ],
|
|
289
|
+
meta: { totalItems: 103 },
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const result = getQueriedItems( state, {
|
|
296
|
+
per_page: 50,
|
|
297
|
+
offset: 100,
|
|
298
|
+
} );
|
|
299
|
+
expect( result ).toEqual( [ { id: 101 }, { id: 102 }, { id: 103 } ] );
|
|
300
|
+
} );
|
|
301
|
+
|
|
302
|
+
it( 'should return null for offset-based query when items are still missing', () => {
|
|
303
|
+
// Offset=50, perPage=50, totalItems=200: the API should return
|
|
304
|
+
// 50 items for this batch but only 2 are stored so far.
|
|
305
|
+
const state = {
|
|
306
|
+
items: {
|
|
307
|
+
default: {
|
|
308
|
+
51: { id: 51 },
|
|
309
|
+
52: { id: 52 },
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
itemIsComplete: {
|
|
313
|
+
default: { 51: true, 52: true },
|
|
314
|
+
},
|
|
315
|
+
queries: {
|
|
316
|
+
default: {
|
|
317
|
+
'offset=50': {
|
|
318
|
+
itemIds: [ 51, 52 ],
|
|
319
|
+
meta: { totalItems: 200 },
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const result = getQueriedItems( state, {
|
|
326
|
+
per_page: 50,
|
|
327
|
+
offset: 50,
|
|
328
|
+
} );
|
|
329
|
+
expect( result ).toBe( null );
|
|
330
|
+
} );
|
|
331
|
+
|
|
332
|
+
it( 'should return null for offset query when items are still missing', () => {
|
|
333
|
+
// Query Block scenario: offset=3 with per_page=10. The effective
|
|
334
|
+
// total is totalItems - offset = 47. Only 5 items are stored, so
|
|
335
|
+
// the data is still incomplete.
|
|
336
|
+
const state = {
|
|
337
|
+
items: {
|
|
338
|
+
default: {
|
|
339
|
+
4: { id: 4 },
|
|
340
|
+
5: { id: 5 },
|
|
341
|
+
6: { id: 6 },
|
|
342
|
+
7: { id: 7 },
|
|
343
|
+
8: { id: 8 },
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
itemIsComplete: {
|
|
347
|
+
default: { 4: true, 5: true, 6: true, 7: true, 8: true },
|
|
348
|
+
},
|
|
349
|
+
queries: {
|
|
350
|
+
default: {
|
|
351
|
+
'offset=3': {
|
|
352
|
+
itemIds: [ 4, 5, 6, 7, 8 ],
|
|
353
|
+
meta: { totalItems: 50 },
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
},
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
const result = getQueriedItems( state, {
|
|
360
|
+
per_page: 10,
|
|
361
|
+
offset: 3,
|
|
362
|
+
} );
|
|
363
|
+
expect( result ).toBe( null );
|
|
364
|
+
} );
|
|
365
|
+
|
|
366
|
+
it( 'should treat offset=0 the same as no offset', () => {
|
|
367
|
+
// The Query Block defaults to offset=0. Since
|
|
368
|
+
// effectiveTotal = totalItems - 0 = totalItems, this should
|
|
369
|
+
// behave identically to a query without offset.
|
|
370
|
+
const state = {
|
|
371
|
+
items: {
|
|
372
|
+
default: {
|
|
373
|
+
1: { id: 1 },
|
|
374
|
+
2: { id: 2 },
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
itemIsComplete: {
|
|
378
|
+
default: { 1: true, 2: true },
|
|
379
|
+
},
|
|
380
|
+
queries: {
|
|
381
|
+
default: {
|
|
382
|
+
'offset=0': {
|
|
383
|
+
itemIds: [ 1, 2 ],
|
|
384
|
+
meta: { totalItems: 5 },
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
// 2 items stored, but 5 total exist — should return null.
|
|
391
|
+
const result = getQueriedItems( state, {
|
|
392
|
+
per_page: 3,
|
|
393
|
+
offset: 0,
|
|
394
|
+
} );
|
|
395
|
+
expect( result ).toBe( null );
|
|
396
|
+
} );
|
|
397
|
+
|
|
398
|
+
it( 'should return empty array when offset equals totalItems', () => {
|
|
399
|
+
// Edge case: offset lands exactly at the end (e.g. 84 items,
|
|
400
|
+
// per_page=7, offset=84). The API returns 0 items and that is
|
|
401
|
+
// a complete response — effectiveTotal is 0.
|
|
402
|
+
const state = {
|
|
403
|
+
items: {
|
|
404
|
+
default: {},
|
|
405
|
+
},
|
|
406
|
+
itemIsComplete: {
|
|
407
|
+
default: {},
|
|
408
|
+
},
|
|
409
|
+
queries: {
|
|
410
|
+
default: {
|
|
411
|
+
'offset=84': {
|
|
412
|
+
itemIds: [],
|
|
413
|
+
meta: { totalItems: 84 },
|
|
414
|
+
},
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const result = getQueriedItems( state, {
|
|
420
|
+
per_page: 7,
|
|
421
|
+
offset: 84,
|
|
422
|
+
} );
|
|
423
|
+
expect( result ).toEqual( [] );
|
|
424
|
+
} );
|
|
242
425
|
} );
|
package/src/reducer.js
CHANGED
|
@@ -16,6 +16,7 @@ import { createUndoManager } from '@wordpress/undo-manager';
|
|
|
16
16
|
import { ifMatchingAction, replaceAction } from './utils';
|
|
17
17
|
import { reducer as queriedDataReducer } from './queried-data';
|
|
18
18
|
import { rootEntitiesConfig, DEFAULT_ENTITY_KEY } from './entities';
|
|
19
|
+
import { ConnectionErrorCode } from './sync';
|
|
19
20
|
|
|
20
21
|
/** @typedef {import('./types').AnyFunction} AnyFunction */
|
|
21
22
|
|
|
@@ -706,6 +707,16 @@ export function collaborationSupported( state = true, action ) {
|
|
|
706
707
|
switch ( action.type ) {
|
|
707
708
|
case 'SET_COLLABORATION_SUPPORTED':
|
|
708
709
|
return action.supported;
|
|
710
|
+
|
|
711
|
+
case 'SET_SYNC_CONNECTION_STATUS':
|
|
712
|
+
if (
|
|
713
|
+
ConnectionErrorCode.DOCUMENT_SIZE_LIMIT_EXCEEDED ===
|
|
714
|
+
action.status?.error?.code
|
|
715
|
+
) {
|
|
716
|
+
return false;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return state;
|
|
709
720
|
}
|
|
710
721
|
return state;
|
|
711
722
|
}
|