@teleporthq/teleport-plugin-next-data-source 0.44.0 → 0.44.4
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/__tests__/_helpers/first-page-runtime.ts +184 -0
- package/__tests__/_helpers/pagination-widget-fixture.ts +67 -1
- package/__tests__/browser-row-policy.test.ts +202 -2
- package/__tests__/data-source-request-locale.test.ts +4 -3
- package/__tests__/fetchers.test.ts +6 -2
- package/__tests__/infinite-scroll.test.ts +210 -5
- package/__tests__/page-data-visitor-read.test.ts +196 -0
- package/__tests__/plain-list-sort.test.ts +1 -1
- package/__tests__/plain-list-starting-sort.test.ts +323 -0
- package/__tests__/refetch-loading-state.test.ts +158 -2
- package/__tests__/starting-sort-first-page.test.ts +285 -0
- package/dist/cjs/cache/ast.d.ts +2 -0
- package/dist/cjs/cache/ast.d.ts.map +1 -1
- package/dist/cjs/cache/ast.js +5 -2
- package/dist/cjs/cache/ast.js.map +1 -1
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +10 -2
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +1 -1
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.js +5 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/infinite-scroll.d.ts +64 -2
- package/dist/cjs/infinite-scroll.d.ts.map +1 -1
- package/dist/cjs/infinite-scroll.js +102 -3
- package/dist/cjs/infinite-scroll.js.map +1 -1
- package/dist/cjs/loading-state.d.ts +23 -2
- package/dist/cjs/loading-state.d.ts.map +1 -1
- package/dist/cjs/loading-state.js +50 -15
- package/dist/cjs/loading-state.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +200 -64
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/sort-utils.d.ts +53 -1
- package/dist/cjs/sort-utils.d.ts.map +1 -1
- package/dist/cjs/sort-utils.js +105 -13
- package/dist/cjs/sort-utils.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +3 -2
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +48 -18
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/cache/ast.d.ts +2 -0
- package/dist/esm/cache/ast.d.ts.map +1 -1
- package/dist/esm/cache/ast.js +3 -1
- package/dist/esm/cache/ast.js.map +1 -1
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +10 -2
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +1 -1
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.js +6 -2
- package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/infinite-scroll.d.ts +64 -2
- package/dist/esm/infinite-scroll.d.ts.map +1 -1
- package/dist/esm/infinite-scroll.js +97 -2
- package/dist/esm/infinite-scroll.js.map +1 -1
- package/dist/esm/loading-state.d.ts +23 -2
- package/dist/esm/loading-state.d.ts.map +1 -1
- package/dist/esm/loading-state.js +50 -15
- package/dist/esm/loading-state.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +204 -68
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/sort-utils.d.ts +53 -1
- package/dist/esm/sort-utils.d.ts.map +1 -1
- package/dist/esm/sort-utils.js +100 -12
- package/dist/esm/sort-utils.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +3 -2
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +49 -19
- package/dist/esm/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/ast.ts +4 -1
- package/src/data-source-fetchers.ts +33 -14
- package/src/fetchers/teleport.ts +8 -2
- package/src/fetchers/utils/browser-row-policy.ts +79 -5
- package/src/index.ts +8 -2
- package/src/infinite-scroll.ts +182 -4
- package/src/loading-state.ts +85 -13
- package/src/pagination-plugin.ts +369 -83
- package/src/sort-utils.ts +164 -21
- package/src/utils.ts +55 -18
package/src/sort-utils.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import * as types from '@babel/types'
|
|
2
2
|
import { ASTUtils } from '@teleporthq/teleport-plugin-common'
|
|
3
|
-
import {
|
|
3
|
+
import { JSIdentifiers } from '@teleporthq/teleport-shared'
|
|
4
|
+
import {
|
|
5
|
+
UIDLExpressionValue,
|
|
6
|
+
UIDLStateDefinition,
|
|
7
|
+
UIDLStaticValue,
|
|
8
|
+
} from '@teleporthq/teleport-types'
|
|
4
9
|
|
|
5
10
|
export interface DynamicSortAST {
|
|
6
11
|
field: types.Expression
|
|
@@ -18,22 +23,26 @@ const SKIP_IDENTIFIERS = new Set([
|
|
|
18
23
|
'console',
|
|
19
24
|
])
|
|
20
25
|
|
|
21
|
-
const collectIdentifiers = (
|
|
26
|
+
const collectIdentifiers = (
|
|
27
|
+
node: types.Node | null | undefined,
|
|
28
|
+
acc: Set<string>,
|
|
29
|
+
skip: ReadonlySet<string> = SKIP_IDENTIFIERS
|
|
30
|
+
): void => {
|
|
22
31
|
if (!node || typeof node !== 'object') {
|
|
23
32
|
return
|
|
24
33
|
}
|
|
25
34
|
|
|
26
35
|
if (node.type === 'Identifier') {
|
|
27
|
-
if (!
|
|
36
|
+
if (!skip.has(node.name)) {
|
|
28
37
|
acc.add(node.name)
|
|
29
38
|
}
|
|
30
39
|
return
|
|
31
40
|
}
|
|
32
41
|
|
|
33
42
|
if (node.type === 'MemberExpression') {
|
|
34
|
-
collectIdentifiers(node.object, acc)
|
|
43
|
+
collectIdentifiers(node.object, acc, skip)
|
|
35
44
|
if (node.computed) {
|
|
36
|
-
collectIdentifiers(node.property, acc)
|
|
45
|
+
collectIdentifiers(node.property, acc, skip)
|
|
37
46
|
}
|
|
38
47
|
return
|
|
39
48
|
}
|
|
@@ -43,9 +52,9 @@ const collectIdentifiers = (node: types.Node | null | undefined, acc: Set<string
|
|
|
43
52
|
// tslint:disable-next-line:no-any
|
|
44
53
|
const child = (node as any)[key]
|
|
45
54
|
if (Array.isArray(child)) {
|
|
46
|
-
child.forEach((c) => collectIdentifiers(c, acc))
|
|
55
|
+
child.forEach((c) => collectIdentifiers(c, acc, skip))
|
|
47
56
|
} else if (child && typeof child === 'object' && typeof child.type === 'string') {
|
|
48
|
-
collectIdentifiers(child, acc)
|
|
57
|
+
collectIdentifiers(child, acc, skip)
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
}
|
|
@@ -111,24 +120,158 @@ export const extractDynamicSort = (
|
|
|
111
120
|
}
|
|
112
121
|
}
|
|
113
122
|
|
|
114
|
-
//
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
types.identifier('
|
|
118
|
-
|
|
119
|
-
types.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
types.
|
|
123
|
-
types.objectProperty(types.identifier('field'), types.cloneNode(dynamicSort.field)),
|
|
124
|
-
types.objectProperty(types.identifier('order'), types.cloneNode(dynamicSort.order)),
|
|
125
|
-
]),
|
|
123
|
+
// `JSON.stringify([{ field: <fieldExpr>, order: <orderExpr> }])`
|
|
124
|
+
const buildDynamicSortsValue = (dynamicSort: DynamicSortAST): types.CallExpression =>
|
|
125
|
+
types.callExpression(
|
|
126
|
+
types.memberExpression(types.identifier('JSON'), types.identifier('stringify')),
|
|
127
|
+
[
|
|
128
|
+
types.arrayExpression([
|
|
129
|
+
types.objectExpression([
|
|
130
|
+
types.objectProperty(types.identifier('field'), types.cloneNode(dynamicSort.field, true)),
|
|
131
|
+
types.objectProperty(types.identifier('order'), types.cloneNode(dynamicSort.order, true)),
|
|
126
132
|
]),
|
|
127
|
-
]
|
|
128
|
-
|
|
133
|
+
]),
|
|
134
|
+
]
|
|
129
135
|
)
|
|
136
|
+
|
|
137
|
+
// Build the AST for `sorts: JSON.stringify([{ field: <fieldExpr>, order: <orderExpr> }])`
|
|
138
|
+
const buildDynamicSortsProperty = (dynamicSort: DynamicSortAST): types.ObjectProperty =>
|
|
139
|
+
types.objectProperty(types.identifier('sorts'), buildDynamicSortsValue(dynamicSort))
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A page state a state-bound sort reads, at the value the visitor starts with.
|
|
143
|
+
*/
|
|
144
|
+
export interface SortStateDefault {
|
|
145
|
+
/** The state's binding in the component: the name the sort expressions read. */
|
|
146
|
+
binding: string
|
|
147
|
+
value: string | number | boolean
|
|
130
148
|
}
|
|
131
149
|
|
|
150
|
+
// Names a sort expression may read besides its states: they mean the same on
|
|
151
|
+
// the server and in the browser.
|
|
152
|
+
const CONSTANT_IDENTIFIERS: ReadonlySet<string> = new Set(['undefined', 'NaN', 'Infinity'])
|
|
153
|
+
|
|
154
|
+
const isStartingValue = (value: unknown): value is SortStateDefault['value'] =>
|
|
155
|
+
typeof value === 'string' ||
|
|
156
|
+
typeof value === 'boolean' ||
|
|
157
|
+
(typeof value === 'number' && Number.isFinite(value))
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The states a state-bound sort reads, at their defaults: the sort a visitor
|
|
161
|
+
* starts with, which the build can fetch the first page by.
|
|
162
|
+
*
|
|
163
|
+
* Only when every name the column and the direction read is a state of this
|
|
164
|
+
* component starting at a fixed value. Anything else they read — a prop, the
|
|
165
|
+
* router, `window` — or a state the page seeds from its data leaves the build
|
|
166
|
+
* unable to know the starting sort: `undefined`, and the list fetches its first
|
|
167
|
+
* page in the browser. An empty list is a sort that reads nothing.
|
|
168
|
+
*/
|
|
169
|
+
export const readSortStateDefaults = (
|
|
170
|
+
dynamicSort: DynamicSortAST,
|
|
171
|
+
stateDefinitions: Record<string, UIDLStateDefinition> | undefined
|
|
172
|
+
): SortStateDefault[] | undefined => {
|
|
173
|
+
const read = new Set<string>()
|
|
174
|
+
collectIdentifiers(dynamicSort.field, read, CONSTANT_IDENTIFIERS)
|
|
175
|
+
collectIdentifiers(dynamicSort.order, read, CONSTANT_IDENTIFIERS)
|
|
176
|
+
|
|
177
|
+
// A state's binding is its sanitised name, as the component declares it.
|
|
178
|
+
const stateByBinding = new Map<string, UIDLStateDefinition>()
|
|
179
|
+
Object.entries(stateDefinitions ?? {}).forEach(([key, definition]) => {
|
|
180
|
+
stateByBinding.set(JSIdentifiers.createSafeJSIdentifier(key), definition)
|
|
181
|
+
})
|
|
182
|
+
|
|
183
|
+
const defaults: SortStateDefault[] = []
|
|
184
|
+
for (const binding of Array.from(read)) {
|
|
185
|
+
const definition = stateByBinding.get(binding)
|
|
186
|
+
if (
|
|
187
|
+
!definition ||
|
|
188
|
+
definition.dataSourceBinding ||
|
|
189
|
+
definition.query ||
|
|
190
|
+
!isStartingValue(definition.defaultValue)
|
|
191
|
+
) {
|
|
192
|
+
return undefined
|
|
193
|
+
}
|
|
194
|
+
defaults.push({ binding, value: definition.defaultValue })
|
|
195
|
+
}
|
|
196
|
+
return defaults
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* A list repeater's own sort, read the one way for every part of the plugin
|
|
201
|
+
* that fetches the list's rows — the build's fetch for a page and the
|
|
202
|
+
* browser's: a column the editor fixed (`fixed`), or one bound to state
|
|
203
|
+
* (`dynamic`) with, when the build can know them, the values a visitor starts
|
|
204
|
+
* with (`starting`, see `readSortStateDefaults`). Empty without a sort.
|
|
205
|
+
*/
|
|
206
|
+
export interface RepeaterSort {
|
|
207
|
+
fixed?: { field: string; order: 'asc' | 'desc' }
|
|
208
|
+
dynamic?: DynamicSortAST
|
|
209
|
+
starting?: SortStateDefault[]
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export const readRepeaterSort = (
|
|
213
|
+
sort: UIDLStaticValue | UIDLExpressionValue | undefined,
|
|
214
|
+
sortDirection: UIDLStaticValue | UIDLExpressionValue | undefined,
|
|
215
|
+
stateDefinitions: Record<string, UIDLStateDefinition> | undefined
|
|
216
|
+
): RepeaterSort => {
|
|
217
|
+
if (!sort) {
|
|
218
|
+
return {}
|
|
219
|
+
}
|
|
220
|
+
const fixed = readFixedSort(sort, sortDirection)
|
|
221
|
+
if (fixed) {
|
|
222
|
+
return { fixed }
|
|
223
|
+
}
|
|
224
|
+
const dynamic = extractDynamicSort(sort, sortDirection)
|
|
225
|
+
return dynamic ? { dynamic, starting: readSortStateDefaults(dynamic, stateDefinitions) } : {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The `sorts` param of the build-time fetch: the browser's own expression,
|
|
230
|
+
* evaluated with every state it reads at its default —
|
|
231
|
+
*
|
|
232
|
+
* ((sortBy) => JSON.stringify([{ field: sortBy.split("-")?.[0] || '', order: … }]))("name-asc")
|
|
233
|
+
*
|
|
234
|
+
* — so it is the very string the browser sends while the sort is untouched, and
|
|
235
|
+
* the data source orders the first page exactly as it orders every later one
|
|
236
|
+
* (the same columns, empty values last, the row's id breaking ties).
|
|
237
|
+
*/
|
|
238
|
+
export const buildStartingSortsValue = (
|
|
239
|
+
dynamicSort: DynamicSortAST,
|
|
240
|
+
defaults: SortStateDefault[]
|
|
241
|
+
): types.Expression => {
|
|
242
|
+
const sorts = buildDynamicSortsValue(dynamicSort)
|
|
243
|
+
if (defaults.length === 0) {
|
|
244
|
+
return sorts
|
|
245
|
+
}
|
|
246
|
+
return types.callExpression(
|
|
247
|
+
types.arrowFunctionExpression(
|
|
248
|
+
defaults.map((state) => types.identifier(state.binding)),
|
|
249
|
+
sorts
|
|
250
|
+
),
|
|
251
|
+
defaults.map((state) => types.valueToNode(state.value) as types.Expression)
|
|
252
|
+
)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* `sortBy === "name-asc"`: the sort is still the one the visitor starts with,
|
|
257
|
+
* so the rows fetched at build time are its first page. `null` for a sort that
|
|
258
|
+
* reads nothing, which never moves.
|
|
259
|
+
*/
|
|
260
|
+
export const buildSortAtStartGuard = (defaults: SortStateDefault[]): types.Expression | null =>
|
|
261
|
+
defaults
|
|
262
|
+
.map(
|
|
263
|
+
(state): types.Expression =>
|
|
264
|
+
types.binaryExpression(
|
|
265
|
+
'===',
|
|
266
|
+
types.identifier(state.binding),
|
|
267
|
+
types.valueToNode(state.value) as types.Expression
|
|
268
|
+
)
|
|
269
|
+
)
|
|
270
|
+
.reduce<types.Expression | null>(
|
|
271
|
+
(all, guard) => (all ? types.logicalExpression('&&', all, guard) : guard),
|
|
272
|
+
null
|
|
273
|
+
)
|
|
274
|
+
|
|
132
275
|
// Build the AST for the legacy static sorts array form.
|
|
133
276
|
// tslint:disable-next-line:no-any
|
|
134
277
|
const buildLegacySortsProperty = (sorts: any[]): types.ObjectProperty => {
|
package/src/utils.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
UIDLDataSource,
|
|
8
8
|
DataSourceType,
|
|
9
9
|
ChunkType,
|
|
10
|
+
UIDLStateDefinition,
|
|
10
11
|
} from '@teleporthq/teleport-types'
|
|
11
12
|
import * as types from '@babel/types'
|
|
12
13
|
import { ASTUtils } from '@teleporthq/teleport-plugin-common'
|
|
@@ -15,7 +16,7 @@ import { generateDataSourceFetcherWithCore } from './data-source-fetchers'
|
|
|
15
16
|
import type { EntityTransformOptions } from './transformations'
|
|
16
17
|
import { DATA_SOURCE_ISR_REVALIDATE_SECONDS } from './isr'
|
|
17
18
|
import { buildServerLocaleParam, hasLocaleParam, buildClientLocaleParam } from './request-locale'
|
|
18
|
-
import {
|
|
19
|
+
import { buildStartingSortsValue, readRepeaterSort, type RepeaterSort } from './sort-utils'
|
|
19
20
|
|
|
20
21
|
const VALID_DATA_SOURCE_TYPES: DataSourceType[] = [
|
|
21
22
|
'rest-api',
|
|
@@ -1180,16 +1181,16 @@ const isSortKeyed = (properties: types.ObjectProperty[]): boolean =>
|
|
|
1180
1181
|
(property.key.type === 'Identifier' && property.key.name === 'sorts')
|
|
1181
1182
|
)
|
|
1182
1183
|
|
|
1183
|
-
/** The
|
|
1184
|
+
/** The first list repeater inside a data-source node: the list its rows are fetched for. */
|
|
1184
1185
|
// tslint:disable-next-line:no-any
|
|
1185
|
-
const
|
|
1186
|
+
const findListRepeater = (node: any): Record<string, any> | undefined => {
|
|
1186
1187
|
// tslint:disable-next-line:no-any
|
|
1187
|
-
const visit = (current: any):
|
|
1188
|
+
const visit = (current: any): Record<string, any> | undefined => {
|
|
1188
1189
|
if (!current || typeof current !== 'object') {
|
|
1189
1190
|
return undefined
|
|
1190
1191
|
}
|
|
1191
1192
|
if (current.type === 'cms-list-repeater') {
|
|
1192
|
-
return
|
|
1193
|
+
return current.content ?? {}
|
|
1193
1194
|
}
|
|
1194
1195
|
const content = current.content
|
|
1195
1196
|
const children = [
|
|
@@ -1204,9 +1205,28 @@ const findRepeaterFixedSort = (node: any): { field: string; order: 'asc' | 'desc
|
|
|
1204
1205
|
}
|
|
1205
1206
|
return undefined
|
|
1206
1207
|
}
|
|
1207
|
-
return visit(node)
|
|
1208
|
+
return visit(node)
|
|
1208
1209
|
}
|
|
1209
1210
|
|
|
1211
|
+
/**
|
|
1212
|
+
* The order a list's page fetch carries, in what tells it apart from another
|
|
1213
|
+
* list's fetch with the same params (`claimParamsPropKey`): the column the
|
|
1214
|
+
* editor fixed, or a sort the visitor picks at the values they start with.
|
|
1215
|
+
*/
|
|
1216
|
+
const prefetchOrderOf = (
|
|
1217
|
+
// tslint:disable-next-line:no-any
|
|
1218
|
+
repeater: Record<string, any> | undefined,
|
|
1219
|
+
sort: RepeaterSort
|
|
1220
|
+
): unknown =>
|
|
1221
|
+
sort.fixed ??
|
|
1222
|
+
(sort.dynamic && sort.starting
|
|
1223
|
+
? {
|
|
1224
|
+
sort: repeater?.sort,
|
|
1225
|
+
sortDirection: repeater?.sortDirection ?? null,
|
|
1226
|
+
starting: sort.starting,
|
|
1227
|
+
}
|
|
1228
|
+
: undefined)
|
|
1229
|
+
|
|
1210
1230
|
export const extractDataSourceIntoGetStaticProps = (
|
|
1211
1231
|
node: UIDLDataSourceItemNode | UIDLDataSourceListNode,
|
|
1212
1232
|
dataSources: Record<string, UIDLDataSource>,
|
|
@@ -1217,7 +1237,13 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1217
1237
|
dependencies: Record<string, any>,
|
|
1218
1238
|
dynamicRouteAttr?: string,
|
|
1219
1239
|
folderPath?: string[],
|
|
1220
|
-
transformOptions: EntityTransformOptions = {}
|
|
1240
|
+
transformOptions: EntityTransformOptions = {},
|
|
1241
|
+
// What the read hands the module after its params: `{ as: 'visitor' }` on
|
|
1242
|
+
// every page but an admin page only trusted readers open (see
|
|
1243
|
+
// `RouteUtils.pageDataReadArguments`).
|
|
1244
|
+
readArguments: () => types.Expression[] = () => [],
|
|
1245
|
+
// The page's states: a list sorted by one is fetched by the value it starts at.
|
|
1246
|
+
stateDefinitions?: Record<string, UIDLStateDefinition>
|
|
1221
1247
|
): { success: boolean; chunk?: any } => {
|
|
1222
1248
|
try {
|
|
1223
1249
|
// Validate node content
|
|
@@ -1281,11 +1307,13 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1281
1307
|
}
|
|
1282
1308
|
// tslint:disable-next-line:no-any
|
|
1283
1309
|
const nodeResource = (node.content as any).resource
|
|
1310
|
+
const repeater = findListRepeater(node)
|
|
1311
|
+
const repeaterSort = readRepeaterSort(repeater?.sort, repeater?.sortDirection, stateDefinitions)
|
|
1284
1312
|
const propKey = claimParamsPropKey(
|
|
1285
1313
|
componentChunk,
|
|
1286
1314
|
resourcePropKey,
|
|
1287
1315
|
nodeResource,
|
|
1288
|
-
|
|
1316
|
+
prefetchOrderOf(repeater, repeaterSort)
|
|
1289
1317
|
)
|
|
1290
1318
|
|
|
1291
1319
|
// Find matching JSX nodes for this data source
|
|
@@ -1732,11 +1760,13 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1732
1760
|
}
|
|
1733
1761
|
})
|
|
1734
1762
|
|
|
1735
|
-
// The sort the list's repeater
|
|
1763
|
+
// The sort the list's repeater carries, when the resource names none — the
|
|
1736
1764
|
// rows the page is pre-rendered with come in the order the list shows them
|
|
1737
|
-
// (the browser keeps them: the provider skips its first fetch).
|
|
1738
|
-
|
|
1739
|
-
|
|
1765
|
+
// (the browser keeps them: the provider skips its first fetch). A sort the
|
|
1766
|
+
// visitor picks is fetched as they start with it, by the browser's own sort
|
|
1767
|
+
// expression (`buildStartingSortsValue`), and the list keeps the rows only
|
|
1768
|
+
// while the sort stays there (`seedPlainListWhileSortStarts`).
|
|
1769
|
+
if (!isSortKeyed(paramsProperties) && repeaterSort.fixed) {
|
|
1740
1770
|
paramsProperties.push(
|
|
1741
1771
|
types.objectProperty(
|
|
1742
1772
|
types.stringLiteral('sorts'),
|
|
@@ -1747,11 +1777,11 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1747
1777
|
types.objectExpression([
|
|
1748
1778
|
types.objectProperty(
|
|
1749
1779
|
types.identifier('field'),
|
|
1750
|
-
types.stringLiteral(repeaterSort.field)
|
|
1780
|
+
types.stringLiteral(repeaterSort.fixed.field)
|
|
1751
1781
|
),
|
|
1752
1782
|
types.objectProperty(
|
|
1753
1783
|
types.identifier('order'),
|
|
1754
|
-
types.stringLiteral(repeaterSort.order)
|
|
1784
|
+
types.stringLiteral(repeaterSort.fixed.order)
|
|
1755
1785
|
),
|
|
1756
1786
|
]),
|
|
1757
1787
|
]),
|
|
@@ -1759,6 +1789,13 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1759
1789
|
)
|
|
1760
1790
|
)
|
|
1761
1791
|
)
|
|
1792
|
+
} else if (!isSortKeyed(paramsProperties) && repeaterSort.dynamic && repeaterSort.starting) {
|
|
1793
|
+
paramsProperties.push(
|
|
1794
|
+
types.objectProperty(
|
|
1795
|
+
types.stringLiteral('sorts'),
|
|
1796
|
+
buildStartingSortsValue(repeaterSort.dynamic, repeaterSort.starting)
|
|
1797
|
+
)
|
|
1798
|
+
)
|
|
1762
1799
|
}
|
|
1763
1800
|
|
|
1764
1801
|
// getStaticProps runs once per language: the prefetch is for that language.
|
|
@@ -1768,7 +1805,7 @@ export const extractDataSourceIntoGetStaticProps = (
|
|
|
1768
1805
|
|
|
1769
1806
|
const fetchCallExpression = types.callExpression(
|
|
1770
1807
|
types.memberExpression(types.identifier(fetcherImportName), types.identifier('fetchData')),
|
|
1771
|
-
[types.objectExpression(paramsProperties)]
|
|
1808
|
+
[types.objectExpression(paramsProperties), ...readArguments()]
|
|
1772
1809
|
)
|
|
1773
1810
|
|
|
1774
1811
|
const safeFetchExpression = createSafeFetchExpression(fetchCallExpression, propKey)
|
|
@@ -1925,12 +1962,12 @@ const claimParamsPropKey = (
|
|
|
1925
1962
|
componentChunk: ChunkDefinition,
|
|
1926
1963
|
resourcePropKey: string,
|
|
1927
1964
|
resource: { params?: Record<string, unknown> } | undefined,
|
|
1928
|
-
// The list's own
|
|
1929
|
-
|
|
1965
|
+
// The list's own sort rides on its prefetch too (`prefetchOrderOf`).
|
|
1966
|
+
prefetchOrder?: unknown
|
|
1930
1967
|
): string => {
|
|
1931
1968
|
const meta = componentChunk.meta as { dataSourcePropKeyParams?: Record<string, string> }
|
|
1932
1969
|
const claimed = meta.dataSourcePropKeyParams ?? (meta.dataSourcePropKeyParams = {})
|
|
1933
|
-
const signature = JSON.stringify([resource?.params ?? {},
|
|
1970
|
+
const signature = JSON.stringify([resource?.params ?? {}, prefetchOrder ?? null])
|
|
1934
1971
|
|
|
1935
1972
|
let propKey = resourcePropKey
|
|
1936
1973
|
for (let suffix = 2; claimed[propKey] !== undefined && claimed[propKey] !== signature; suffix++) {
|