@teleporthq/teleport-plugin-next-data-source 0.43.54 → 0.43.57
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__/array-mapper-cache-wiring.test.ts +425 -0
- package/__tests__/data-source-cache-wrapping.test.ts +152 -0
- package/__tests__/ecommerce-product-storefront-tax.test.ts +118 -0
- package/__tests__/ecommerce-product-variant-availability.test.ts +264 -0
- package/dist/cjs/cache/ast.d.ts +71 -0
- package/dist/cjs/cache/ast.d.ts.map +1 -0
- package/dist/cjs/cache/ast.js +229 -0
- package/dist/cjs/cache/ast.js.map +1 -0
- package/dist/cjs/cache/config.d.ts +22 -0
- package/dist/cjs/cache/config.d.ts.map +1 -0
- package/dist/cjs/cache/config.js +67 -0
- package/dist/cjs/cache/config.js.map +1 -0
- package/dist/cjs/cache/types.d.ts +31 -0
- package/dist/cjs/cache/types.d.ts.map +1 -0
- package/dist/cjs/cache/types.js +3 -0
- package/dist/cjs/cache/types.js.map +1 -0
- package/dist/cjs/data-source-fetchers.d.ts +5 -3
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +51 -8
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts +2 -2
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +3 -2
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/loading-state.d.ts.map +1 -1
- package/dist/cjs/loading-state.js +74 -2
- 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 +204 -64
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts +15 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.js +7 -3
- package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
- package/dist/cjs/transformations/index.d.ts +13 -2
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +33 -5
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +4 -3
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +6 -4
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/cache/ast.d.ts +71 -0
- package/dist/esm/cache/ast.d.ts.map +1 -0
- package/dist/esm/cache/ast.js +196 -0
- package/dist/esm/cache/ast.js.map +1 -0
- package/dist/esm/cache/config.d.ts +22 -0
- package/dist/esm/cache/config.d.ts.map +1 -0
- package/dist/esm/cache/config.js +62 -0
- package/dist/esm/cache/config.js.map +1 -0
- package/dist/esm/cache/types.d.ts +31 -0
- package/dist/esm/cache/types.d.ts.map +1 -0
- package/dist/esm/cache/types.js +2 -0
- package/dist/esm/cache/types.js.map +1 -0
- package/dist/esm/data-source-fetchers.d.ts +5 -3
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +51 -8
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts +2 -2
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +3 -2
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +12 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/loading-state.d.ts.map +1 -1
- package/dist/esm/loading-state.js +74 -2
- 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 +205 -65
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/transformations/ecommerce-product.d.ts +15 -1
- package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/esm/transformations/ecommerce-product.js +7 -3
- package/dist/esm/transformations/ecommerce-product.js.map +1 -1
- package/dist/esm/transformations/index.d.ts +13 -2
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +32 -5
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +4 -3
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +6 -4
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/cache/ast.ts +265 -0
- package/src/cache/config.ts +79 -0
- package/src/cache/types.ts +31 -0
- package/src/data-source-fetchers.ts +66 -12
- package/src/fetchers/teleport.ts +3 -3
- package/src/index.ts +10 -4
- package/src/loading-state.ts +65 -2
- package/src/pagination-plugin.ts +315 -116
- package/src/transformations/ecommerce-product.ts +107 -11
- package/src/transformations/index.ts +48 -7
- package/src/utils.ts +10 -5
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { generateEcommerceProductTransformationCode } from '../src/transformations/ecommerce-product'
|
|
2
|
+
import { generateSharedTransformationCode } from '../src/transformations/shared-utils'
|
|
3
|
+
import { getTransformWrapperCode } from '../src/transformations'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A product whose variant combinations are ALL out of stock — or whose axes have
|
|
7
|
+
* no combinations behind them at all — must reach the storefront saying so, in
|
|
8
|
+
* two ways the picker and the buy button read directly:
|
|
9
|
+
*
|
|
10
|
+
* - every value carries `isDead: 'true'`, so the picker strikes them through;
|
|
11
|
+
* - `hasPurchasableVariant: 'false'`, so the Add to Cart button is replaced by
|
|
12
|
+
* the "select an available option" notice instead of adding a cart line with
|
|
13
|
+
* no variant at all (`data-default-variant-id` is empty in that state).
|
|
14
|
+
*
|
|
15
|
+
* The hinge is knowing the difference between "we looked and there are none" and
|
|
16
|
+
* "we could not look": `options.variantsByProductId` is NULL for the latter, and
|
|
17
|
+
* a null must stay permissive — a missing table or a failed query must never
|
|
18
|
+
* make a whole catalogue unbuyable.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const evalBuildProduct = (): ((r: unknown, o?: unknown) => Record<string, unknown>) => {
|
|
22
|
+
const code =
|
|
23
|
+
generateSharedTransformationCode() + '\n' + generateEcommerceProductTransformationCode()
|
|
24
|
+
return new Function(code + '\nreturn buildEcommerceProduct;')() as (
|
|
25
|
+
r: unknown,
|
|
26
|
+
o?: unknown
|
|
27
|
+
) => Record<string, unknown>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type Axis = { key: string; values: Array<Record<string, unknown>> }
|
|
31
|
+
|
|
32
|
+
const buildEcommerceProduct = evalBuildProduct()
|
|
33
|
+
|
|
34
|
+
const SIZE_AXIS = JSON.stringify([
|
|
35
|
+
{
|
|
36
|
+
key: 'size',
|
|
37
|
+
name: 'Size',
|
|
38
|
+
type: 'text',
|
|
39
|
+
values: [
|
|
40
|
+
{ value: 'xs', label: 'XS' },
|
|
41
|
+
{ value: 's', label: 'S' },
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
])
|
|
45
|
+
|
|
46
|
+
const variantProduct = (overrides: Record<string, unknown> = {}) => ({
|
|
47
|
+
id: 'p1',
|
|
48
|
+
name: 'Tee',
|
|
49
|
+
slug: 'tee',
|
|
50
|
+
price: 20,
|
|
51
|
+
currency: 'USD',
|
|
52
|
+
variant_options: SIZE_AXIS,
|
|
53
|
+
...overrides,
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const values = (product: Record<string, unknown>): Array<Record<string, unknown>> =>
|
|
57
|
+
(product.variantOptions as Axis[])[0].values
|
|
58
|
+
|
|
59
|
+
describe('ecommerce product transform — variant availability', () => {
|
|
60
|
+
it('combinations UNKNOWN (no map at all): nothing dead, still purchasable', () => {
|
|
61
|
+
const product = buildEcommerceProduct(variantProduct())
|
|
62
|
+
expect(values(product).every((v) => v.isDead === 'false')).toBe(true)
|
|
63
|
+
expect(product.hasPurchasableVariant).toBe('true')
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('combinations UNKNOWN (the lookup failed → null map): unchanged', () => {
|
|
67
|
+
const product = buildEcommerceProduct(variantProduct(), { variantsByProductId: null })
|
|
68
|
+
expect(values(product).every((v) => v.isDead === 'false')).toBe(true)
|
|
69
|
+
expect(product.hasPurchasableVariant).toBe('true')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('looked up and there are NO combinations: every value dead, not purchasable', () => {
|
|
73
|
+
const product = buildEcommerceProduct(variantProduct(), { variantsByProductId: {} })
|
|
74
|
+
expect(values(product).every((v) => v.isDead === 'true')).toBe(true)
|
|
75
|
+
expect(product.hasPurchasableVariant).toBe('false')
|
|
76
|
+
expect(product.defaultVariantId).toBe('')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('every combination sold out: every value dead, not purchasable', () => {
|
|
80
|
+
const product = buildEcommerceProduct(variantProduct(), {
|
|
81
|
+
variantsByProductId: {
|
|
82
|
+
p1: [
|
|
83
|
+
{ id: 'v-xs', options: { size: 'xs' }, quantity: 0 },
|
|
84
|
+
{ id: 'v-s', options: { size: 's' }, quantity: 0 },
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
expect(values(product).every((v) => v.isDead === 'true')).toBe(true)
|
|
89
|
+
expect(product.hasPurchasableVariant).toBe('false')
|
|
90
|
+
expect(product.defaultVariantId).toBe('')
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('one combination in stock: only the sold-out value is dead, and it is purchasable', () => {
|
|
94
|
+
const product = buildEcommerceProduct(variantProduct(), {
|
|
95
|
+
variantsByProductId: {
|
|
96
|
+
p1: [
|
|
97
|
+
{ id: 'v-xs', options: { size: 'xs' }, quantity: 0 },
|
|
98
|
+
{ id: 'v-s', options: { size: 's' }, quantity: 4 },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
expect(values(product)[0].isDead).toBe('true')
|
|
103
|
+
expect(values(product)[1].isDead).toBe('false')
|
|
104
|
+
expect(values(product)[1].isDefault).toBe('true')
|
|
105
|
+
expect(product.hasPurchasableVariant).toBe('true')
|
|
106
|
+
expect(product.defaultVariantId).toBe('v-s')
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('unlimited stock (null quantity) counts as in stock', () => {
|
|
110
|
+
const product = buildEcommerceProduct(variantProduct(), {
|
|
111
|
+
variantsByProductId: { p1: [{ id: 'v-xs', options: { size: 'xs' }, quantity: null }] },
|
|
112
|
+
})
|
|
113
|
+
expect(product.hasPurchasableVariant).toBe('true')
|
|
114
|
+
expect(values(product)[0].isDead).toBe('false')
|
|
115
|
+
// The value with no combination behind it is still dead.
|
|
116
|
+
expect(values(product)[1].isDead).toBe('true')
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
it('a FLAT product is always purchasable — outOfStock governs its stock', () => {
|
|
120
|
+
const flat = buildEcommerceProduct(
|
|
121
|
+
{ id: 'f', name: 'Mug', slug: 'mug', price: 9, currency: 'USD', quantity: 0 },
|
|
122
|
+
{ variantsByProductId: {} }
|
|
123
|
+
)
|
|
124
|
+
expect(flat.hasPurchasableVariant).toBe('true')
|
|
125
|
+
expect(flat.outOfStock).toBe('true')
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('always emits hasPurchasableVariant as a STRING (never boolean/undefined)', () => {
|
|
129
|
+
for (const options of [undefined, { variantsByProductId: null }, { variantsByProductId: {} }]) {
|
|
130
|
+
const product = buildEcommerceProduct(variantProduct(), options)
|
|
131
|
+
expect(typeof product.hasPurchasableVariant).toBe('string')
|
|
132
|
+
expect(['true', 'false']).toContain(product.hasPurchasableVariant)
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('a related product inherits the same known/unknown answer as its parent', () => {
|
|
137
|
+
const built = buildEcommerceProduct(variantProduct({ related_product_ids: '["p2"]' }), {
|
|
138
|
+
// Unknown for everybody — the nested build must NOT read this as "none".
|
|
139
|
+
variantsByProductId: null,
|
|
140
|
+
relatedProductsById: { p2: variantProduct({ id: 'p2', slug: 'p2' }) },
|
|
141
|
+
})
|
|
142
|
+
const related = (built.relatedProducts as Array<Record<string, unknown>>)[0]
|
|
143
|
+
expect(related.hasPurchasableVariant).toBe('true')
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Runs the EMITTED `transformRecords` against a stub pg client, which is the only
|
|
149
|
+
* way to prove the wrapper's control flow — the order of the two lookups, and
|
|
150
|
+
* which ids reach the combinations query — rather than its text.
|
|
151
|
+
*/
|
|
152
|
+
describe('transform wrapper — executed end to end', () => {
|
|
153
|
+
interface StubQuery {
|
|
154
|
+
sql: string
|
|
155
|
+
params: unknown[]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const runWrapper = async (
|
|
159
|
+
records: Array<Record<string, unknown>>,
|
|
160
|
+
rows: {
|
|
161
|
+
related?: Array<Record<string, unknown>>
|
|
162
|
+
variants?: Array<Record<string, unknown>>
|
|
163
|
+
failVariantsQuery?: boolean
|
|
164
|
+
}
|
|
165
|
+
): Promise<{ out: Array<Record<string, unknown>>; queries: StubQuery[] }> => {
|
|
166
|
+
const bundle =
|
|
167
|
+
generateSharedTransformationCode() +
|
|
168
|
+
'\n' +
|
|
169
|
+
generateEcommerceProductTransformationCode() +
|
|
170
|
+
'\n' +
|
|
171
|
+
getTransformWrapperCode('teleport_products')
|
|
172
|
+
const transformRecords = new Function(bundle + '\nreturn transformRecords;')() as (
|
|
173
|
+
r: unknown,
|
|
174
|
+
getClient: unknown,
|
|
175
|
+
q: unknown
|
|
176
|
+
) => Promise<Array<Record<string, unknown>>>
|
|
177
|
+
|
|
178
|
+
const queries: StubQuery[] = []
|
|
179
|
+
const query = async (
|
|
180
|
+
sql: string,
|
|
181
|
+
params: unknown[] = []
|
|
182
|
+
): Promise<{ rows: Array<Record<string, unknown>> }> => {
|
|
183
|
+
queries.push({ sql, params })
|
|
184
|
+
if (sql.includes('teleport_assets')) {
|
|
185
|
+
return { rows: [] }
|
|
186
|
+
}
|
|
187
|
+
if (sql.includes('teleport_product_variants')) {
|
|
188
|
+
if (rows.failVariantsQuery) {
|
|
189
|
+
throw new Error('relation "teleport_product_variants" does not exist')
|
|
190
|
+
}
|
|
191
|
+
return { rows: rows.variants || [] }
|
|
192
|
+
}
|
|
193
|
+
if (sql.includes('teleport_products')) {
|
|
194
|
+
return { rows: rows.related || [] }
|
|
195
|
+
}
|
|
196
|
+
return { rows: [] }
|
|
197
|
+
}
|
|
198
|
+
const getClientFn = () => ({
|
|
199
|
+
connect: async (): Promise<void> => undefined,
|
|
200
|
+
end: async (): Promise<void> => undefined,
|
|
201
|
+
query,
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
const out = await transformRecords(records, getClientFn, {})
|
|
205
|
+
return { out, queries }
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const variantQueryOf = (queries: StubQuery[]): StubQuery | undefined =>
|
|
209
|
+
queries.find((q) => q.sql.includes('teleport_product_variants'))
|
|
210
|
+
|
|
211
|
+
it("asks for the RELATED products' combinations in the same batched query", async () => {
|
|
212
|
+
const { out, queries } = await runWrapper([variantProduct({ related_product_ids: '["p2"]' })], {
|
|
213
|
+
related: [variantProduct({ id: 'p2', slug: 'p2' })],
|
|
214
|
+
variants: [
|
|
215
|
+
{ id: 'v-p1', product_id: 'p1', options: { size: 's' }, quantity: 5 },
|
|
216
|
+
{ id: 'v-p2', product_id: 'p2', options: { size: 'xs' }, quantity: 2 },
|
|
217
|
+
],
|
|
218
|
+
})
|
|
219
|
+
// Both the page's own product AND the related one.
|
|
220
|
+
expect(variantQueryOf(queries)?.params[0]).toEqual(['p1', 'p2'])
|
|
221
|
+
|
|
222
|
+
const related = (out[0].relatedProducts as Array<Record<string, unknown>>)[0]
|
|
223
|
+
expect(related.hasPurchasableVariant).toBe('true')
|
|
224
|
+
expect(related.defaultVariantId).toBe('v-p2')
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
it('a FAILED combinations query leaves every product permissive, not unbuyable', async () => {
|
|
228
|
+
const { out, queries } = await runWrapper([variantProduct()], { failVariantsQuery: true })
|
|
229
|
+
expect(variantQueryOf(queries)).toBeTruthy()
|
|
230
|
+
expect(out[0].hasPurchasableVariant).toBe('true')
|
|
231
|
+
expect(values(out[0]).every((v) => v.isDead === 'false')).toBe(true)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('a query that RAN and returned nothing marks the product unbuyable', async () => {
|
|
235
|
+
const { out } = await runWrapper([variantProduct()], { variants: [] })
|
|
236
|
+
expect(out[0].hasPurchasableVariant).toBe('false')
|
|
237
|
+
expect(values(out[0]).every((v) => v.isDead === 'true')).toBe(true)
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
describe('transform wrapper — the batched combinations query', () => {
|
|
242
|
+
const wrapper = getTransformWrapperCode('teleport_products')
|
|
243
|
+
|
|
244
|
+
it('starts the map at NULL so a failed lookup reads as unknown, not as none', () => {
|
|
245
|
+
expect(wrapper).toContain('var variantsByProductId = null')
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
it('resolves related items BEFORE variants, and asks for their combinations too', () => {
|
|
249
|
+
// The details page draws each related product as a real card with its own
|
|
250
|
+
// picker; fetching only the page's own ids left every one of them looking
|
|
251
|
+
// like a product with no combinations.
|
|
252
|
+
expect(wrapper.indexOf('relatedProductsById = await')).toBeGreaterThan(-1)
|
|
253
|
+
expect(wrapper.indexOf('relatedProductsById = await')).toBeLessThan(
|
|
254
|
+
wrapper.indexOf('getVariantsMap(')
|
|
255
|
+
)
|
|
256
|
+
expect(wrapper).toContain('__variantPids.push(__rrow.id)')
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
it('leaves the blog wrapper without any variant enrichment', () => {
|
|
260
|
+
const blog = getTransformWrapperCode('teleport_blog_posts')
|
|
261
|
+
expect(blog).not.toContain('getVariantsMap')
|
|
262
|
+
expect(blog).toContain('relatedPostsById')
|
|
263
|
+
})
|
|
264
|
+
})
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as types from '@babel/types';
|
|
2
|
+
import { UIDLDependency } from '@teleporthq/teleport-types';
|
|
3
|
+
import { ResolvedDataSourceCache } from './types';
|
|
4
|
+
/** Identifiers the emitted page imports from `utils/tq-cache/client`. */
|
|
5
|
+
export declare const CACHE_CLIENT_IMPORTS: string[];
|
|
6
|
+
export declare const cachedValueVarFor: (index: number) => string;
|
|
7
|
+
/**
|
|
8
|
+
* Registers the client runtime's named imports on the page.
|
|
9
|
+
*
|
|
10
|
+
* Each identifier is its own dependency entry because that is how the
|
|
11
|
+
* import-statements plugin keys them; they share one path, so they collapse
|
|
12
|
+
* into a single `import { … } from '…/utils/tq-cache/client'`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const registerCacheClientImports: (dependencies: Record<string, UIDLDependency>, folderPath: string[] | undefined) => void;
|
|
15
|
+
/**
|
|
16
|
+
* The terminal `.then` of a cached fetch: record the version the server
|
|
17
|
+
* answered with (which purges the scope if it moved) and store the rows.
|
|
18
|
+
*
|
|
19
|
+
* `tqCacheSet` returns the value it was given, so the promise still resolves to
|
|
20
|
+
* exactly what the uncached chain resolved to — `response?.data`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const buildCacheStoreThen: (cache: ResolvedDataSourceCache) => types.ArrowFunctionExpression;
|
|
23
|
+
/** Wraps a network chain in the peek preamble, producing the cached body. */
|
|
24
|
+
export declare const buildCachedFetchBody: (networkChain: types.Expression, cache: ResolvedDataSourceCache) => types.BlockStatement;
|
|
25
|
+
/**
|
|
26
|
+
* Finds the `return <fetch(...)…>` statement inside a cached `fetchData` body.
|
|
27
|
+
*
|
|
28
|
+
* Shared with `loading-state` so both modules agree on what "the network chain"
|
|
29
|
+
* means: the body also contains an early `return Promise.resolve(hit)`, and
|
|
30
|
+
* attaching in-flight bookkeeping to THAT would flip the loading flag on every
|
|
31
|
+
* cache hit — the exact flash this feature exists to remove.
|
|
32
|
+
*/
|
|
33
|
+
export declare const findCachedFetchNetworkChain: (body: types.BlockStatement) => {
|
|
34
|
+
statement: types.ReturnStatement;
|
|
35
|
+
index: number;
|
|
36
|
+
} | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Hoists a cached provider's `params` into a component const and adds the
|
|
39
|
+
* synchronous cache peek beside it.
|
|
40
|
+
*
|
|
41
|
+
* The peek is what removes the loading flash on a page or search change: those
|
|
42
|
+
* change the provider's `key`, so it REMOUNTS with `data: undefined` and paints
|
|
43
|
+
* `renderLoading()` before any promise — even an already-resolved one — can
|
|
44
|
+
* resume. Feeding a hit into `initialData` makes the provider skip its first
|
|
45
|
+
* fetch entirely and paint the cached rows on the very first frame.
|
|
46
|
+
*
|
|
47
|
+
* `sticky` is set because this value is handed to a mounted provider: once it
|
|
48
|
+
* has been, TTL expiry must not flip it back to `undefined`, or the list would
|
|
49
|
+
* blank out without refetching (its `params` never changed).
|
|
50
|
+
*
|
|
51
|
+
* Reference identity comes from the runtime's own map, not from this `useMemo`
|
|
52
|
+
* — the memo only keeps the peek from re-running on unrelated renders.
|
|
53
|
+
*/
|
|
54
|
+
export declare const buildCachedParamsDeclarations: (params: {
|
|
55
|
+
index: number;
|
|
56
|
+
paramsMemo: types.Expression;
|
|
57
|
+
cache: ResolvedDataSourceCache;
|
|
58
|
+
}) => {
|
|
59
|
+
declarations: types.Statement[];
|
|
60
|
+
paramsIdentifier: string;
|
|
61
|
+
cachedIdentifier: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* `useEffect(() => { tqMarkHydrated(); tqCacheRevalidate([...]) }, [])`
|
|
65
|
+
*
|
|
66
|
+
* One effect per page, covering every scope on it in a single request. Flipping
|
|
67
|
+
* the hydration latch here rather than at import time is what keeps the first
|
|
68
|
+
* client render byte-identical to the server render.
|
|
69
|
+
*/
|
|
70
|
+
export declare const buildCacheHydrationEffect: (scopes: string[]) => types.Statement;
|
|
71
|
+
//# sourceMappingURL=ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.d.ts","sourceRoot":"","sources":["../../../src/cache/ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAEjD,yEAAyE;AACzE,eAAO,MAAM,oBAAoB,UAOhC,CAAA;AAMD,eAAO,MAAM,iBAAiB,UAAW,MAAM,KAAG,MAA8B,CAAA;AAEhF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,iBACvB,OAAO,MAAM,EAAE,cAAc,CAAC,cAChC,MAAM,EAAE,GAAG,SAAS,KAC/B,IAaF,CAAA;AAyCD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,UACvB,uBAAuB,KAC7B,MAAM,uBAkCR,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB,iBACjB,MAAM,UAAU,SACvB,uBAAuB,KAC7B,MAAM,cAIL,CAAA;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,SAChC,MAAM,cAAc,KACzB;IAAE,SAAS,EAAE,MAAM,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAcxD,CAAA;AAkBD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,6BAA6B,WAAY;IACpD,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,UAAU,CAAA;IAC5B,KAAK,EAAE,uBAAuB,CAAA;CAC/B;kBACe,MAAM,SAAS,EAAE;sBACb,MAAM;sBACN,MAAM;CAkCzB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,WAAY,MAAM,EAAE,KAAG,MAAM,SAgBhE,CAAA"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
26
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
27
|
+
if (ar || !(i in from)) {
|
|
28
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
29
|
+
ar[i] = from[i];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.buildCacheHydrationEffect = exports.buildCachedParamsDeclarations = exports.findCachedFetchNetworkChain = exports.buildCachedFetchBody = exports.buildCacheStoreThen = exports.registerCacheClientImports = exports.cachedValueVarFor = exports.CACHE_CLIENT_IMPORTS = void 0;
|
|
36
|
+
var types = __importStar(require("@babel/types"));
|
|
37
|
+
/** Identifiers the emitted page imports from `utils/tq-cache/client`. */
|
|
38
|
+
exports.CACHE_CLIENT_IMPORTS = [
|
|
39
|
+
'tqCacheKey',
|
|
40
|
+
'tqCacheGet',
|
|
41
|
+
'tqCacheSet',
|
|
42
|
+
'tqCacheSetVersion',
|
|
43
|
+
'tqMarkHydrated',
|
|
44
|
+
'tqCacheRevalidate',
|
|
45
|
+
];
|
|
46
|
+
/** Local identifiers used inside the generated `fetchData` body. */
|
|
47
|
+
var KEY_VAR = '__tqKey';
|
|
48
|
+
var HIT_VAR = '__tqHit';
|
|
49
|
+
var cachedValueVarFor = function (index) { return "ds_".concat(index, "_cached"); };
|
|
50
|
+
exports.cachedValueVarFor = cachedValueVarFor;
|
|
51
|
+
/**
|
|
52
|
+
* Registers the client runtime's named imports on the page.
|
|
53
|
+
*
|
|
54
|
+
* Each identifier is its own dependency entry because that is how the
|
|
55
|
+
* import-statements plugin keys them; they share one path, so they collapse
|
|
56
|
+
* into a single `import { … } from '…/utils/tq-cache/client'`.
|
|
57
|
+
*/
|
|
58
|
+
var registerCacheClientImports = function (dependencies, folderPath) {
|
|
59
|
+
var depth = (folderPath ? folderPath.length : 0) + 1;
|
|
60
|
+
var path = "".concat('../'.repeat(depth), "utils/tq-cache/client");
|
|
61
|
+
exports.CACHE_CLIENT_IMPORTS.forEach(function (identifier) {
|
|
62
|
+
if (!dependencies[identifier]) {
|
|
63
|
+
dependencies[identifier] = {
|
|
64
|
+
type: 'local',
|
|
65
|
+
path: path,
|
|
66
|
+
meta: { namedImport: true },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
exports.registerCacheClientImports = registerCacheClientImports;
|
|
72
|
+
/**
|
|
73
|
+
* `const __tqKey = tqCacheKey(params)` +
|
|
74
|
+
* `const __tqHit = tqCacheGet(SCOPE, __tqKey)` +
|
|
75
|
+
* `if (__tqHit !== undefined) return Promise.resolve(__tqHit)`
|
|
76
|
+
*
|
|
77
|
+
* The early return is what keeps a hit from ever touching the network — and,
|
|
78
|
+
* just as importantly, from raising the in-flight flag that would paint the
|
|
79
|
+
* loading slot. `loading-state` deliberately attaches its bookkeeping to the
|
|
80
|
+
* network chain BELOW this, never to the `Promise.resolve`.
|
|
81
|
+
*/
|
|
82
|
+
var buildCachePeekPreamble = function (scope) { return [
|
|
83
|
+
types.variableDeclaration('const', [
|
|
84
|
+
types.variableDeclarator(types.identifier(KEY_VAR), types.callExpression(types.identifier('tqCacheKey'), [types.identifier('params')])),
|
|
85
|
+
]),
|
|
86
|
+
types.variableDeclaration('const', [
|
|
87
|
+
types.variableDeclarator(types.identifier(HIT_VAR), types.callExpression(types.identifier('tqCacheGet'), [
|
|
88
|
+
types.stringLiteral(scope),
|
|
89
|
+
types.identifier(KEY_VAR),
|
|
90
|
+
])),
|
|
91
|
+
]),
|
|
92
|
+
types.ifStatement(types.binaryExpression('!==', types.identifier(HIT_VAR), types.identifier('undefined')), types.blockStatement([
|
|
93
|
+
types.returnStatement(types.callExpression(types.memberExpression(types.identifier('Promise'), types.identifier('resolve')), [types.identifier(HIT_VAR)])),
|
|
94
|
+
])),
|
|
95
|
+
]; };
|
|
96
|
+
/**
|
|
97
|
+
* The terminal `.then` of a cached fetch: record the version the server
|
|
98
|
+
* answered with (which purges the scope if it moved) and store the rows.
|
|
99
|
+
*
|
|
100
|
+
* `tqCacheSet` returns the value it was given, so the promise still resolves to
|
|
101
|
+
* exactly what the uncached chain resolved to — `response?.data`.
|
|
102
|
+
*/
|
|
103
|
+
var buildCacheStoreThen = function (cache) {
|
|
104
|
+
var responseData = types.optionalMemberExpression(types.identifier('response'), types.identifier('data'), false, true);
|
|
105
|
+
var responseVersion = types.optionalMemberExpression(types.identifier('response'), types.identifier('version'), false, true);
|
|
106
|
+
return types.arrowFunctionExpression([types.identifier('response')], types.blockStatement([
|
|
107
|
+
types.expressionStatement(types.callExpression(types.identifier('tqCacheSetVersion'), [
|
|
108
|
+
types.stringLiteral(cache.scope),
|
|
109
|
+
types.cloneNode(responseVersion, true),
|
|
110
|
+
])),
|
|
111
|
+
types.returnStatement(types.callExpression(types.identifier('tqCacheSet'), [
|
|
112
|
+
types.stringLiteral(cache.scope),
|
|
113
|
+
types.identifier(KEY_VAR),
|
|
114
|
+
responseData,
|
|
115
|
+
types.numericLiteral(cache.ttlSeconds),
|
|
116
|
+
types.cloneNode(responseVersion, true),
|
|
117
|
+
])),
|
|
118
|
+
]));
|
|
119
|
+
};
|
|
120
|
+
exports.buildCacheStoreThen = buildCacheStoreThen;
|
|
121
|
+
/** Wraps a network chain in the peek preamble, producing the cached body. */
|
|
122
|
+
var buildCachedFetchBody = function (networkChain, cache) {
|
|
123
|
+
return types.blockStatement(__spreadArray(__spreadArray([], buildCachePeekPreamble(cache.scope), true), [
|
|
124
|
+
types.returnStatement(networkChain),
|
|
125
|
+
], false));
|
|
126
|
+
};
|
|
127
|
+
exports.buildCachedFetchBody = buildCachedFetchBody;
|
|
128
|
+
/**
|
|
129
|
+
* Finds the `return <fetch(...)…>` statement inside a cached `fetchData` body.
|
|
130
|
+
*
|
|
131
|
+
* Shared with `loading-state` so both modules agree on what "the network chain"
|
|
132
|
+
* means: the body also contains an early `return Promise.resolve(hit)`, and
|
|
133
|
+
* attaching in-flight bookkeeping to THAT would flip the loading flag on every
|
|
134
|
+
* cache hit — the exact flash this feature exists to remove.
|
|
135
|
+
*/
|
|
136
|
+
var findCachedFetchNetworkChain = function (body) {
|
|
137
|
+
for (var index = body.body.length - 1; index >= 0; index--) {
|
|
138
|
+
var statement = body.body[index];
|
|
139
|
+
if (statement.type !== 'ReturnStatement' || !statement.argument) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (statement.argument.type === 'CallExpression' &&
|
|
143
|
+
callChainStartsWithFetch(statement.argument)) {
|
|
144
|
+
return { statement: statement, index: index };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
};
|
|
149
|
+
exports.findCachedFetchNetworkChain = findCachedFetchNetworkChain;
|
|
150
|
+
var callChainStartsWithFetch = function (expression) {
|
|
151
|
+
var current = expression;
|
|
152
|
+
while (current.type === 'CallExpression') {
|
|
153
|
+
var callee = current.callee;
|
|
154
|
+
if (callee.type === 'Identifier' && callee.name === 'fetch') {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (callee.type === 'MemberExpression') {
|
|
158
|
+
current = callee.object;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Hoists a cached provider's `params` into a component const and adds the
|
|
167
|
+
* synchronous cache peek beside it.
|
|
168
|
+
*
|
|
169
|
+
* The peek is what removes the loading flash on a page or search change: those
|
|
170
|
+
* change the provider's `key`, so it REMOUNTS with `data: undefined` and paints
|
|
171
|
+
* `renderLoading()` before any promise — even an already-resolved one — can
|
|
172
|
+
* resume. Feeding a hit into `initialData` makes the provider skip its first
|
|
173
|
+
* fetch entirely and paint the cached rows on the very first frame.
|
|
174
|
+
*
|
|
175
|
+
* `sticky` is set because this value is handed to a mounted provider: once it
|
|
176
|
+
* has been, TTL expiry must not flip it back to `undefined`, or the list would
|
|
177
|
+
* blank out without refetching (its `params` never changed).
|
|
178
|
+
*
|
|
179
|
+
* Reference identity comes from the runtime's own map, not from this `useMemo`
|
|
180
|
+
* — the memo only keeps the peek from re-running on unrelated renders.
|
|
181
|
+
*/
|
|
182
|
+
var buildCachedParamsDeclarations = function (params) {
|
|
183
|
+
var paramsIdentifier = "ds_".concat(params.index, "_params");
|
|
184
|
+
var cachedIdentifier = (0, exports.cachedValueVarFor)(params.index);
|
|
185
|
+
return {
|
|
186
|
+
paramsIdentifier: paramsIdentifier,
|
|
187
|
+
cachedIdentifier: cachedIdentifier,
|
|
188
|
+
declarations: [
|
|
189
|
+
types.variableDeclaration('const', [
|
|
190
|
+
types.variableDeclarator(types.identifier(paramsIdentifier), params.paramsMemo),
|
|
191
|
+
]),
|
|
192
|
+
types.variableDeclaration('const', [
|
|
193
|
+
types.variableDeclarator(types.identifier(cachedIdentifier), types.callExpression(types.identifier('useMemo'), [
|
|
194
|
+
types.arrowFunctionExpression([], types.callExpression(types.identifier('tqCacheGet'), [
|
|
195
|
+
types.stringLiteral(params.cache.scope),
|
|
196
|
+
types.callExpression(types.identifier('tqCacheKey'), [
|
|
197
|
+
types.identifier(paramsIdentifier),
|
|
198
|
+
]),
|
|
199
|
+
types.objectExpression([
|
|
200
|
+
types.objectProperty(types.identifier('sticky'), types.booleanLiteral(true)),
|
|
201
|
+
]),
|
|
202
|
+
])),
|
|
203
|
+
types.arrayExpression([types.identifier(paramsIdentifier)]),
|
|
204
|
+
])),
|
|
205
|
+
]),
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
exports.buildCachedParamsDeclarations = buildCachedParamsDeclarations;
|
|
210
|
+
/**
|
|
211
|
+
* `useEffect(() => { tqMarkHydrated(); tqCacheRevalidate([...]) }, [])`
|
|
212
|
+
*
|
|
213
|
+
* One effect per page, covering every scope on it in a single request. Flipping
|
|
214
|
+
* the hydration latch here rather than at import time is what keeps the first
|
|
215
|
+
* client render byte-identical to the server render.
|
|
216
|
+
*/
|
|
217
|
+
var buildCacheHydrationEffect = function (scopes) {
|
|
218
|
+
return types.expressionStatement(types.callExpression(types.identifier('useEffect'), [
|
|
219
|
+
types.arrowFunctionExpression([], types.blockStatement([
|
|
220
|
+
types.expressionStatement(types.callExpression(types.identifier('tqMarkHydrated'), [])),
|
|
221
|
+
types.expressionStatement(types.callExpression(types.identifier('tqCacheRevalidate'), [
|
|
222
|
+
types.arrayExpression(scopes.map(function (scope) { return types.stringLiteral(scope); })),
|
|
223
|
+
])),
|
|
224
|
+
])),
|
|
225
|
+
types.arrayExpression([]),
|
|
226
|
+
]));
|
|
227
|
+
};
|
|
228
|
+
exports.buildCacheHydrationEffect = buildCacheHydrationEffect;
|
|
229
|
+
//# sourceMappingURL=ast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast.js","sourceRoot":"","sources":["../../../src/cache/ast.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { UIDLDataCacheConfig } from '@teleporthq/teleport-types';
|
|
2
|
+
import { DataSourceServerCacheOptions, ResolvedDataSourceCache } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Reads the `cache` block off a `cms-list-repeater`.
|
|
5
|
+
*
|
|
6
|
+
* Returns `undefined` — meaning "emit exactly what this generator emitted
|
|
7
|
+
* before caching existed" — for anything that is off, incomplete, or caches
|
|
8
|
+
* into neither layer.
|
|
9
|
+
*/
|
|
10
|
+
export declare const resolveCacheFromRepeaterContent: (cache: UIDLDataCacheConfig | undefined, resourceDefinition: {
|
|
11
|
+
dataSourceId?: string;
|
|
12
|
+
tableName?: string;
|
|
13
|
+
} | undefined) => ResolvedDataSourceCache | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Folds several mappers' requests for the same generated file into one.
|
|
16
|
+
*
|
|
17
|
+
* Enabled if ANY mapper wants it, but with the SHORTEST requested TTL and the
|
|
18
|
+
* shortest shared-cache window — a mapper that asked for fresher data must
|
|
19
|
+
* never be made staler by a sibling that asked for less.
|
|
20
|
+
*/
|
|
21
|
+
export declare const mergeServerCacheOptions: (entries: DataSourceServerCacheOptions[]) => DataSourceServerCacheOptions | undefined;
|
|
22
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/cache/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAA;AAChE,OAAO,EAAE,4BAA4B,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAA;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,UACnC,mBAAmB,GAAG,SAAS,sBAClB;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,KAC5E,uBAAuB,GAAG,SAoC5B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,YACzB,4BAA4B,EAAE,KACtC,4BAA4B,GAAG,SAiBjC,CAAA"}
|