create-brainerce-store 1.12.2 → 1.12.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/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-brainerce-store",
|
|
34
|
-
version: "1.12.
|
|
34
|
+
version: "1.12.4",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
bin: {
|
|
37
37
|
"create-brainerce-store": "dist/index.js"
|
package/package.json
CHANGED
|
@@ -119,7 +119,9 @@ function OrderConfirmationContent() {
|
|
|
119
119
|
|
|
120
120
|
<p className="text-muted-foreground mt-2">{t('confirmationEmail')}</p>
|
|
121
121
|
|
|
122
|
-
{result.status.orderId &&
|
|
122
|
+
{result.status.orderId && (
|
|
123
|
+
<ConfirmationDownloads orderId={result.status.orderId} checkoutId={checkoutId!} />
|
|
124
|
+
)}
|
|
123
125
|
|
|
124
126
|
<div className="mt-8 flex flex-col items-center justify-center gap-3 sm:flex-row">
|
|
125
127
|
<Link
|
|
@@ -180,26 +182,35 @@ function OrderConfirmationContent() {
|
|
|
180
182
|
);
|
|
181
183
|
}
|
|
182
184
|
|
|
183
|
-
function ConfirmationDownloads({ orderId }: { orderId: string }) {
|
|
185
|
+
function ConfirmationDownloads({ orderId, checkoutId }: { orderId: string; checkoutId: string }) {
|
|
184
186
|
const t = useTranslations('orderConfirmation');
|
|
185
187
|
const [downloads, setDownloads] = useState<OrderDownloadLink[] | null>(null);
|
|
186
188
|
|
|
187
189
|
useEffect(() => {
|
|
188
190
|
let cancelled = false;
|
|
189
191
|
async function fetchDownloads() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
const client = getClient();
|
|
193
|
+
// Retry a few times — the worker may still be writing downloadMeta
|
|
194
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
195
|
+
try {
|
|
196
|
+
const links = await client.getOrderDownloads(orderId, { checkoutId });
|
|
197
|
+
if (!cancelled && links.length > 0) {
|
|
198
|
+
setDownloads(links);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
} catch {
|
|
202
|
+
// Not all orders have downloads
|
|
203
|
+
}
|
|
204
|
+
if (attempt < 2 && !cancelled) {
|
|
205
|
+
await new Promise((r) => setTimeout(r, 1500));
|
|
206
|
+
}
|
|
196
207
|
}
|
|
197
208
|
}
|
|
198
209
|
fetchDownloads();
|
|
199
210
|
return () => {
|
|
200
211
|
cancelled = true;
|
|
201
212
|
};
|
|
202
|
-
}, [orderId]);
|
|
213
|
+
}, [orderId, checkoutId]);
|
|
203
214
|
|
|
204
215
|
if (!downloads || downloads.length === 0) return null;
|
|
205
216
|
|
|
@@ -82,6 +82,7 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
82
82
|
onError: (_r: unknown) => {},
|
|
83
83
|
onTimeout: () => {},
|
|
84
84
|
onWalletChange: (_s: string) => {},
|
|
85
|
+
retryRender: () => {},
|
|
85
86
|
});
|
|
86
87
|
|
|
87
88
|
const handleSuccess = useCallback(
|
|
@@ -115,8 +116,9 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
115
116
|
];
|
|
116
117
|
const msg = extractMessage(response);
|
|
117
118
|
if (TRANSIENT.some((e) => msg.includes(e))) {
|
|
118
|
-
console.info('Payment SDK: transient
|
|
119
|
-
|
|
119
|
+
console.info('Payment SDK: transient error, retrying render in 1s:', msg);
|
|
120
|
+
setTimeout(() => cbRef.current.retryRender(), 1000);
|
|
121
|
+
return;
|
|
120
122
|
}
|
|
121
123
|
console.error('Payment SDK error:', response);
|
|
122
124
|
setError(msg || t('paymentError'));
|
|
@@ -133,6 +135,7 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
133
135
|
}
|
|
134
136
|
if (state === 'close') setSdkReady(false);
|
|
135
137
|
},
|
|
138
|
+
retryRender: () => {},
|
|
136
139
|
};
|
|
137
140
|
|
|
138
141
|
// =========================================================================
|
|
@@ -220,6 +223,8 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
220
223
|
|
|
221
224
|
// --- Init: called in s.onload (as Grow docs require) ---
|
|
222
225
|
function initSdk(sdk: PaymentClientSdk) {
|
|
226
|
+
if (sdkInitDone) return; // Guard against double init
|
|
227
|
+
|
|
223
228
|
const global = (window as any)[sdk.globalName!];
|
|
224
229
|
if (!global) {
|
|
225
230
|
setError(t('failedToLoadPaymentSdk'));
|
|
@@ -245,37 +250,47 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
245
250
|
sdkInitDone = true;
|
|
246
251
|
}
|
|
247
252
|
|
|
248
|
-
// --- Render:
|
|
249
|
-
//
|
|
250
|
-
|
|
253
|
+
// --- Render: call once, then safety-net retries if wallet doesn't open ---
|
|
254
|
+
// Grow SDK sometimes silently swallows renderPaymentOptions when its
|
|
255
|
+
// internal resources (mp.min.js etc.) aren't fully loaded yet.
|
|
256
|
+
// Strategy: render once, then retry up to 3 times with increasing delays
|
|
257
|
+
// (2s, 3s, 4s) if onWalletChange("open") hasn't fired.
|
|
258
|
+
let pendingRender: { sdk: PaymentClientSdk; intent: PaymentIntent } | null = null;
|
|
259
|
+
let renderAttempts = 0;
|
|
260
|
+
const MAX_RENDER_ATTEMPTS = 4;
|
|
261
|
+
|
|
262
|
+
function renderPayment(sdk: PaymentClientSdk, intent: PaymentIntent) {
|
|
251
263
|
const global = (window as any)[sdk.globalName!];
|
|
252
|
-
if (!global) return;
|
|
264
|
+
if (!global || walletOpenRef.current) return;
|
|
253
265
|
|
|
254
266
|
const renderMethod = sdk.renderMethod || 'renderPaymentOptions';
|
|
255
267
|
const renderArg = sdk.renderArg || intent.clientSecret;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
console.info('Payment SDK: render call accepted');
|
|
264
|
-
} catch (err) {
|
|
265
|
-
console.info('Payment SDK: render not ready yet, retrying...');
|
|
266
|
-
}
|
|
268
|
+
renderAttempts++;
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
global[renderMethod](renderArg);
|
|
272
|
+
console.info(`Payment SDK: renderPaymentOptions called (attempt ${renderAttempts})`);
|
|
273
|
+
} catch (err) {
|
|
274
|
+
console.info('Payment SDK: render threw, will retry in 1s');
|
|
267
275
|
}
|
|
268
276
|
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
// Safety net: if wallet doesn't open within a delay, retry
|
|
278
|
+
if (renderAttempts < MAX_RENDER_ATTEMPTS) {
|
|
279
|
+
const delay = 1000 + renderAttempts * 1000; // 2s, 3s, 4s
|
|
280
|
+
const retryId = setTimeout(() => {
|
|
281
|
+
if (!walletOpenRef.current) {
|
|
282
|
+
console.info(`Payment SDK: wallet not open after ${delay}ms, retrying render...`);
|
|
283
|
+
renderPayment(sdk, intent);
|
|
284
|
+
}
|
|
285
|
+
}, delay);
|
|
286
|
+
cleanups.push(() => clearTimeout(retryId));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function retryRender() {
|
|
291
|
+
if (pendingRender && !walletOpenRef.current) {
|
|
292
|
+
renderPayment(pendingRender.sdk, pendingRender.intent);
|
|
293
|
+
}
|
|
279
294
|
}
|
|
280
295
|
|
|
281
296
|
// =============================================
|
|
@@ -326,14 +341,18 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
326
341
|
}
|
|
327
342
|
if (sdk.renderType !== 'sdk-widget' || !sdk.globalName) return;
|
|
328
343
|
|
|
344
|
+
// Store for retryRender from onError callback
|
|
345
|
+
pendingRender = { sdk, intent };
|
|
346
|
+
cbRef.current.retryRender = retryRender;
|
|
347
|
+
|
|
329
348
|
// If SDK wasn't loaded from providers, load + init now
|
|
330
349
|
if (!sdkInitDone) {
|
|
331
350
|
loadScript(sdk);
|
|
332
|
-
// Wait for init to complete, then render
|
|
351
|
+
// Wait for init to complete, then render once
|
|
333
352
|
const id = setInterval(() => {
|
|
334
353
|
if (sdkInitDone) {
|
|
335
354
|
clearInterval(id);
|
|
336
|
-
|
|
355
|
+
renderPayment(sdk, intent);
|
|
337
356
|
}
|
|
338
357
|
}, 100);
|
|
339
358
|
cleanups.push(() => clearInterval(id));
|
|
@@ -358,8 +377,8 @@ export function PaymentStep({ checkoutId, className }: PaymentStepProps) {
|
|
|
358
377
|
}
|
|
359
378
|
}
|
|
360
379
|
|
|
361
|
-
// SDK ready — render
|
|
362
|
-
|
|
380
|
+
// SDK ready — render once
|
|
381
|
+
renderPayment(sdk, intent);
|
|
363
382
|
});
|
|
364
383
|
|
|
365
384
|
return () => cleanups.forEach((fn) => fn());
|