@usethrottle/catalog 1.2.0 → 1.4.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 +27 -0
- package/README.md +111 -15
- package/dist/admin.cjs +16 -16
- package/dist/admin.d.cts +15 -2
- package/dist/admin.d.ts +15 -2
- package/dist/admin.js +1 -1
- package/dist/{catalog-error-yTBMAdCv.d.cts → catalog-error-BKN5hNWP.d.cts} +11 -1
- package/dist/{catalog-error-7DCsTyB2.d.ts → catalog-error-BnabMMEy.d.ts} +11 -1
- package/dist/{chunk-JNBKKAMP.js → chunk-3FX2HISB.js} +97 -2
- package/dist/{chunk-B2DYAHNR.cjs → chunk-J2GHGQY6.cjs} +334 -43
- package/dist/{chunk-TDMDOHD3.cjs → chunk-OKWXS3FD.cjs} +110 -15
- package/dist/chunk-PZ3SFYH4.cjs +192 -0
- package/dist/chunk-SN6STYPW.js +192 -0
- package/dist/{chunk-55G4ZTD5.js → chunk-VJHA7J7B.js} +315 -24
- package/dist/{client-Dm6I4nAZ.d.ts → client-B6CsU_v9.d.ts} +1 -1
- package/dist/{client-BrHJCyBP.d.cts → client-terkEl6u.d.cts} +1 -1
- package/dist/{contract-types-BPSzY_Co.d.cts → contract-types-D2-SSPM9.d.cts} +241 -11
- package/dist/{contract-types-BPSzY_Co.d.ts → contract-types-D2-SSPM9.d.ts} +241 -11
- package/dist/index.cjs +34 -2
- package/dist/index.d.cts +56 -7
- package/dist/index.d.ts +56 -7
- package/dist/index.js +35 -3
- package/dist/next.cjs +180 -0
- package/dist/next.d.cts +60 -0
- package/dist/next.d.ts +60 -0
- package/dist/next.js +180 -0
- package/dist/react-extras.cjs +27 -9
- package/dist/react-extras.d.cts +7 -4
- package/dist/react-extras.d.ts +7 -4
- package/dist/react-extras.js +20 -2
- package/dist/react.cjs +130 -54
- package/dist/react.d.cts +52 -11
- package/dist/react.d.ts +52 -11
- package/dist/react.js +112 -36
- package/dist/server.cjs +58 -66
- package/dist/server.d.cts +58 -10
- package/dist/server.d.ts +58 -10
- package/dist/server.js +52 -60
- package/dist/{types-BlYCKzB8.d.ts → types-jNpOwEUw.d.cts} +81 -8
- package/dist/{types-BTrqSprj.d.cts → types-z57bkjjB.d.ts} +81 -8
- package/dist/url.d.cts +2 -1
- package/dist/url.d.ts +2 -1
- package/dist/{use-query-QOEBuYlp.d.ts → use-query-COqRZJnC.d.ts} +1 -1
- package/dist/{use-query-BZgjxGPO.d.cts → use-query-H1xgL3_e.d.cts} +1 -1
- package/package.json +17 -2
package/dist/react.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
@@ -15,14 +15,17 @@
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
var _chunkTDMDOHD3cjs = require('./chunk-TDMDOHD3.cjs');
|
|
19
18
|
|
|
20
19
|
|
|
20
|
+
var _chunkOKWXS3FDcjs = require('./chunk-OKWXS3FD.cjs');
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
var _chunkJ2GHGQY6cjs = require('./chunk-J2GHGQY6.cjs');
|
|
26
29
|
require('./chunk-ETV4XYOV.cjs');
|
|
27
30
|
|
|
28
31
|
// src/react/use-cart.ts
|
|
@@ -39,7 +42,7 @@ function newKey() {
|
|
|
39
42
|
return out;
|
|
40
43
|
}
|
|
41
44
|
function refuse(message, path) {
|
|
42
|
-
return new (0,
|
|
45
|
+
return new (0, _chunkJ2GHGQY6cjs.CatalogError)({
|
|
43
46
|
code: "INVALID_REQUEST",
|
|
44
47
|
message,
|
|
45
48
|
statusCode: 0,
|
|
@@ -52,7 +55,7 @@ var UNSAFE = /[\x00-\x20\x7f]/u;
|
|
|
52
55
|
function isHttpUrl(value) {
|
|
53
56
|
return typeof value === "string" && /^https?:\/\/[^/?#\\]/iu.test(value) && !UNSAFE.test(value);
|
|
54
57
|
}
|
|
55
|
-
var wrap = (error) =>
|
|
58
|
+
var wrap = (error) => _chunkJ2GHGQY6cjs.isCatalogError.call(void 0, error) ? error : new (0, _chunkJ2GHGQY6cjs.CatalogError)({
|
|
56
59
|
code: "CLIENT_ERROR",
|
|
57
60
|
message: "The action failed.",
|
|
58
61
|
statusCode: 0,
|
|
@@ -63,7 +66,7 @@ var wrap = (error) => _chunkB2DYAHNRcjs.isCatalogError.call(void 0, error) ? err
|
|
|
63
66
|
function checkPause(store) {
|
|
64
67
|
const until = store.pausedUntil();
|
|
65
68
|
if (until > 0) {
|
|
66
|
-
throw new (0,
|
|
69
|
+
throw new (0, _chunkJ2GHGQY6cjs.RateLimitedError)({
|
|
67
70
|
code: "RATE_LIMITED",
|
|
68
71
|
message: "Too many requests.",
|
|
69
72
|
statusCode: 429,
|
|
@@ -73,7 +76,7 @@ function checkPause(store) {
|
|
|
73
76
|
}
|
|
74
77
|
}
|
|
75
78
|
function notePause(store, error) {
|
|
76
|
-
if (error instanceof
|
|
79
|
+
if (error instanceof _chunkJ2GHGQY6cjs.RateLimitedError && error.source === "catalog" && error.code === "RATE_LIMITED")
|
|
77
80
|
store.pause(Date.now() + error.retryAfterSeconds * 1e3, error);
|
|
78
81
|
}
|
|
79
82
|
function createBox(initial) {
|
|
@@ -99,7 +102,8 @@ var EMPTY = {
|
|
|
99
102
|
cartUrl: null,
|
|
100
103
|
status: "idle",
|
|
101
104
|
error: void 0,
|
|
102
|
-
pending: false
|
|
105
|
+
pending: false,
|
|
106
|
+
warnings: []
|
|
103
107
|
};
|
|
104
108
|
var ENDED = /* @__PURE__ */ new Set([
|
|
105
109
|
"cart_session_expired",
|
|
@@ -107,7 +111,7 @@ var ENDED = /* @__PURE__ */ new Set([
|
|
|
107
111
|
"cart_not_open",
|
|
108
112
|
"cart_not_found"
|
|
109
113
|
]);
|
|
110
|
-
var ended = (error) =>
|
|
114
|
+
var ended = (error) => _chunkJ2GHGQY6cjs.isCatalogError.call(void 0, error) && ENDED.has(error.code);
|
|
111
115
|
var converted = (error) => _optionalChain([error, 'access', _2 => _2.details, 'optionalAccess', _3 => _3.reason]) === "converted";
|
|
112
116
|
function itemsOf(cart) {
|
|
113
117
|
const items = /* @__PURE__ */ new Map();
|
|
@@ -132,6 +136,7 @@ function createController(home) {
|
|
|
132
136
|
moving: void 0,
|
|
133
137
|
unremoved: false,
|
|
134
138
|
reads: /* @__PURE__ */ new Map(),
|
|
139
|
+
slots: /* @__PURE__ */ new Set(),
|
|
135
140
|
abort: new AbortController(),
|
|
136
141
|
writing: Promise.resolve(),
|
|
137
142
|
tail: Promise.resolve()
|
|
@@ -150,7 +155,7 @@ function createController(home) {
|
|
|
150
155
|
throttleBaseUrl === void 0 ? void 0 : { throttleBaseUrl }
|
|
151
156
|
);
|
|
152
157
|
};
|
|
153
|
-
const fallbackUrl = (id) => `${(_nullishCoalesce(ctx().throttleCheckoutUrl, () => (
|
|
158
|
+
const fallbackUrl = (id) => `${(_nullishCoalesce(ctx().throttleCheckoutUrl, () => ( _chunkJ2GHGQY6cjs.THROTTLE_CHECKOUT_URL))).replace(/\/+$/u, "")}/cart/${encodeURIComponent(id)}`;
|
|
154
159
|
const live = async (signal, value) => {
|
|
155
160
|
const out = await value;
|
|
156
161
|
if (signal.aborted) throw signal.reason;
|
|
@@ -168,7 +173,7 @@ function createController(home) {
|
|
|
168
173
|
if (signal.aborted) throw error;
|
|
169
174
|
}
|
|
170
175
|
}
|
|
171
|
-
async function find(signal, wantedCurrency) {
|
|
176
|
+
async function find(signal, wantedCurrency, strict = false) {
|
|
172
177
|
const source = ctx().customerCart;
|
|
173
178
|
if (source === void 0 || wantedCurrency === void 0) return null;
|
|
174
179
|
const asked = wantedCurrency.toUpperCase();
|
|
@@ -176,9 +181,27 @@ function createController(home) {
|
|
|
176
181
|
const found = await live(signal, source.getOpenCart({ currency: asked }));
|
|
177
182
|
return found !== null && found.currency.toUpperCase() === asked ? found : null;
|
|
178
183
|
} catch (error) {
|
|
179
|
-
if (signal.aborted) throw error;
|
|
184
|
+
if (signal.aborted || strict) throw error;
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async function findTarget(signal, code, storage) {
|
|
189
|
+
if (resuming()) {
|
|
190
|
+
const found = await find(signal, code, true);
|
|
191
|
+
return found === null ? null : { id: found.sessionId, cartUrl: fallbackUrl(found.sessionId) };
|
|
192
|
+
}
|
|
193
|
+
if (ctx().customerKey !== null || storage.getFor === void 0) return null;
|
|
194
|
+
const id = await live(signal, storage.getFor(code));
|
|
195
|
+
if (id === null || id === "") return null;
|
|
196
|
+
try {
|
|
197
|
+
const answer = await live(signal, session(id).get({ signal }));
|
|
198
|
+
if (answer.cart.status !== "open" || answer.cart.currency.toUpperCase() !== code)
|
|
199
|
+
return null;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (signal.aborted || !ended(error)) throw error;
|
|
180
202
|
return null;
|
|
181
203
|
}
|
|
204
|
+
return { id, cartUrl: fallbackUrl(id) };
|
|
182
205
|
}
|
|
183
206
|
async function findOnce(signal, storage) {
|
|
184
207
|
var _a2;
|
|
@@ -197,13 +220,21 @@ function createController(home) {
|
|
|
197
220
|
}
|
|
198
221
|
if (found !== null) await soft(signal, () => adopt(signal, found, storage));
|
|
199
222
|
}
|
|
223
|
+
async function forgetSlots(storage, codes) {
|
|
224
|
+
for (const code of codes)
|
|
225
|
+
if (storage.removeFor !== void 0) await storage.removeFor(code);
|
|
226
|
+
else await _optionalChain([storage, 'access', _15 => _15.setFor, 'optionalCall', _16 => _16(code, "")]);
|
|
227
|
+
}
|
|
228
|
+
async function save(signal, storage, id) {
|
|
229
|
+
const write = storage.set(id);
|
|
230
|
+
me.writing = Promise.resolve(write).catch(() => void 0);
|
|
231
|
+
await live(signal, write);
|
|
232
|
+
}
|
|
200
233
|
async function adopt(signal, found, storage) {
|
|
201
234
|
const id = found.sessionId;
|
|
202
235
|
const answer = await live(signal, session(id).get({ signal }));
|
|
203
236
|
me.reads.set(id, Date.now());
|
|
204
|
-
|
|
205
|
-
me.writing = Promise.resolve(write).catch(() => void 0);
|
|
206
|
-
await live(signal, write);
|
|
237
|
+
await save(signal, storage, id);
|
|
207
238
|
box.set({
|
|
208
239
|
sessionId: id,
|
|
209
240
|
cartUrl: fallbackUrl(id),
|
|
@@ -229,7 +260,7 @@ function createController(home) {
|
|
|
229
260
|
if (converted(error)) reset();
|
|
230
261
|
else box.set({ sessionId: null, cartUrl: null });
|
|
231
262
|
}
|
|
232
|
-
async function
|
|
263
|
+
async function start(signal, options, items) {
|
|
233
264
|
const context = ctx();
|
|
234
265
|
const body = {
|
|
235
266
|
items: [...items].map(([sku, quantity]) => ({ sku, quantity }))
|
|
@@ -238,9 +269,9 @@ function createController(home) {
|
|
|
238
269
|
if (chosen !== void 0) body.currency = chosen;
|
|
239
270
|
if (options.locale !== void 0) body.locale = options.locale;
|
|
240
271
|
const urls = context.cartUrls;
|
|
241
|
-
if (_optionalChain([urls, 'optionalAccess',
|
|
242
|
-
if (_optionalChain([urls, 'optionalAccess',
|
|
243
|
-
if (_optionalChain([urls, 'optionalAccess',
|
|
272
|
+
if (_optionalChain([urls, 'optionalAccess', _17 => _17.returnUrl]) !== void 0) body.returnUrl = urls.returnUrl;
|
|
273
|
+
if (_optionalChain([urls, 'optionalAccess', _18 => _18.cancelUrl]) !== void 0) body.cancelUrl = urls.cancelUrl;
|
|
274
|
+
if (_optionalChain([urls, 'optionalAccess', _19 => _19.storefrontUrl]) !== void 0)
|
|
244
275
|
body.storefrontUrl = urls.storefrontUrl;
|
|
245
276
|
let answer;
|
|
246
277
|
try {
|
|
@@ -253,28 +284,18 @@ function createController(home) {
|
|
|
253
284
|
throw error;
|
|
254
285
|
}
|
|
255
286
|
const id = answer.sessionId;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
sessionId: id,
|
|
265
|
-
cartUrl,
|
|
266
|
-
cart: snapshot.cart,
|
|
267
|
-
status: "ready",
|
|
268
|
-
error: void 0
|
|
269
|
-
});
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
287
|
+
return {
|
|
288
|
+
id,
|
|
289
|
+
cartUrl: isHttpUrl(answer.cartUrl) ? answer.cartUrl : fallbackUrl(id)
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async function create(signal, options, items) {
|
|
293
|
+
const storage = ctx().cartStorage;
|
|
294
|
+
const { id, cartUrl } = await start(signal, options, items);
|
|
272
295
|
box.set({ sessionId: id, cartUrl });
|
|
273
296
|
let unsaved;
|
|
274
297
|
try {
|
|
275
|
-
|
|
276
|
-
me.writing = Promise.resolve(write).catch(() => void 0);
|
|
277
|
-
await live(signal, write);
|
|
298
|
+
await save(signal, storage, id);
|
|
278
299
|
} catch (error) {
|
|
279
300
|
if (signal.aborted) throw error;
|
|
280
301
|
unsaved = error;
|
|
@@ -432,6 +453,11 @@ function createController(home) {
|
|
|
432
453
|
if (signal.aborted) return;
|
|
433
454
|
if (fresh && !me.unremoved) await restore(signal, guest, false);
|
|
434
455
|
if (signal.aborted) return;
|
|
456
|
+
const codes = new Set(me.slots);
|
|
457
|
+
const shown = _optionalChain([box, 'access', _20 => _20.get, 'call', _21 => _21(), 'access', _22 => _22.cart, 'optionalAccess', _23 => _23.currency]);
|
|
458
|
+
if (shown !== void 0) codes.add(shown.toUpperCase());
|
|
459
|
+
await live(signal, forgetSlots(guest, codes));
|
|
460
|
+
me.slots.clear();
|
|
435
461
|
const id = box.get().sessionId;
|
|
436
462
|
if (id === null) {
|
|
437
463
|
if (box.get().cart === null && !me.unremoved) {
|
|
@@ -472,7 +498,7 @@ function createController(home) {
|
|
|
472
498
|
me.abort = new AbortController();
|
|
473
499
|
me.reads.clear();
|
|
474
500
|
for (const key2 of _nullishCoalesce(home.shared.looked, () => ( [])))
|
|
475
|
-
if (key2.startsWith(`${was}\0`)) _optionalChain([home, 'access',
|
|
501
|
+
if (key2.startsWith(`${was}\0`)) _optionalChain([home, 'access', _24 => _24.shared, 'access', _25 => _25.looked, 'optionalAccess', _26 => _26.delete, 'call', _27 => _27(key2)]);
|
|
476
502
|
currency = void 0;
|
|
477
503
|
loaded = true;
|
|
478
504
|
reset();
|
|
@@ -480,9 +506,15 @@ function createController(home) {
|
|
|
480
506
|
const outgoing = _nullishCoalesce(prior, () => ( me.seen));
|
|
481
507
|
const left = me.moving;
|
|
482
508
|
me.moving = void 0;
|
|
509
|
+
const slots = [...me.slots];
|
|
510
|
+
me.slots.clear();
|
|
483
511
|
const remove = async () => {
|
|
484
512
|
await outgoing.remove();
|
|
485
|
-
|
|
513
|
+
await forgetSlots(outgoing, slots);
|
|
514
|
+
if (left !== void 0 && left !== outgoing) {
|
|
515
|
+
await left.remove();
|
|
516
|
+
await forgetSlots(left, slots);
|
|
517
|
+
}
|
|
486
518
|
};
|
|
487
519
|
me.tail = me.writing.then(remove).catch(remove).then(
|
|
488
520
|
() => {
|
|
@@ -508,6 +540,7 @@ function createController(home) {
|
|
|
508
540
|
mutate,
|
|
509
541
|
create,
|
|
510
542
|
session,
|
|
543
|
+
wanted,
|
|
511
544
|
async switchCurrency(signal, options, next) {
|
|
512
545
|
checkPause(ctx().store);
|
|
513
546
|
const storage = ctx().cartStorage;
|
|
@@ -524,28 +557,67 @@ function createController(home) {
|
|
|
524
557
|
}
|
|
525
558
|
const before = currency;
|
|
526
559
|
currency = next;
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
560
|
+
const code = next.toUpperCase();
|
|
561
|
+
const from = box.get().sessionId;
|
|
562
|
+
const cart = box.get().cart;
|
|
563
|
+
const items = itemsOf(cart);
|
|
564
|
+
if (from === null || items.size === 0) {
|
|
565
|
+
if (from !== null) await live(signal, storage.remove());
|
|
566
|
+
if (items.size === 0) reset();
|
|
531
567
|
return;
|
|
532
568
|
}
|
|
569
|
+
if (_optionalChain([cart, 'optionalAccess', _28 => _28.currency, 'access', _29 => _29.toUpperCase, 'call', _30 => _30()]) === code) return;
|
|
570
|
+
let target;
|
|
571
|
+
let moved;
|
|
533
572
|
try {
|
|
534
|
-
await
|
|
573
|
+
target = await _asyncNullishCoalesce(await findTarget(signal, code, storage), async () => ( await start(signal, options, /* @__PURE__ */ new Map())));
|
|
574
|
+
moved = await live(signal, session(target.id).absorb(from, { signal }));
|
|
535
575
|
} catch (error) {
|
|
536
576
|
if (!signal.aborted) currency = before;
|
|
537
577
|
throw error;
|
|
538
578
|
}
|
|
579
|
+
me.reads.set(target.id, Date.now());
|
|
580
|
+
box.set({
|
|
581
|
+
sessionId: target.id,
|
|
582
|
+
cartUrl: target.cartUrl,
|
|
583
|
+
cart: moved.cart,
|
|
584
|
+
status: "ready",
|
|
585
|
+
error: void 0,
|
|
586
|
+
warnings: moved.warnings.filter(
|
|
587
|
+
(warning) => warning.code !== "lines_stale"
|
|
588
|
+
)
|
|
589
|
+
});
|
|
590
|
+
let unsaved;
|
|
591
|
+
try {
|
|
592
|
+
await save(signal, storage, target.id);
|
|
593
|
+
} catch (error) {
|
|
594
|
+
if (signal.aborted) throw error;
|
|
595
|
+
unsaved = error;
|
|
596
|
+
try {
|
|
597
|
+
await live(signal, storage.remove());
|
|
598
|
+
} catch (failure) {
|
|
599
|
+
if (signal.aborted) throw failure;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (ctx().customerKey === null && storage.setFor !== void 0) {
|
|
603
|
+
me.slots.add(code);
|
|
604
|
+
await live(signal, storage.setFor(code, target.id));
|
|
605
|
+
}
|
|
606
|
+
if (unsaved !== void 0) throw unsaved;
|
|
539
607
|
},
|
|
540
608
|
async clear(signal) {
|
|
541
|
-
|
|
609
|
+
const storage = ctx().cartStorage;
|
|
610
|
+
const shown = _optionalChain([box, 'access', _31 => _31.get, 'call', _32 => _32(), 'access', _33 => _33.cart, 'optionalAccess', _34 => _34.currency]);
|
|
611
|
+
await live(signal, storage.remove());
|
|
612
|
+
if (shown !== void 0)
|
|
613
|
+
await live(signal, _optionalChain([storage, 'access', _35 => _35.removeFor, 'optionalCall', _36 => _36(shown.toUpperCase())]));
|
|
542
614
|
currency = void 0;
|
|
543
615
|
reset();
|
|
544
616
|
}
|
|
545
617
|
};
|
|
546
618
|
}
|
|
547
619
|
function useCart(options = {}) {
|
|
548
|
-
const context =
|
|
620
|
+
const context = _chunkOKWXS3FDcjs.useCatalogContext.call(void 0, );
|
|
549
621
|
const home = context.cart;
|
|
550
622
|
const controller = _nullishCoalesce(home.current, () => ( (home.current = createController(home))));
|
|
551
623
|
const state = _react.useSyncExternalStore.call(void 0,
|
|
@@ -595,8 +667,8 @@ function useCart(options = {}) {
|
|
|
595
667
|
),
|
|
596
668
|
checkout: (input) => controller.run(async (signal) => {
|
|
597
669
|
const { cartUrls } = home.context;
|
|
598
|
-
const returnUrl = _nullishCoalesce(_optionalChain([input, 'optionalAccess',
|
|
599
|
-
const cancelUrl = _nullishCoalesce(_optionalChain([input, 'optionalAccess',
|
|
670
|
+
const returnUrl = _nullishCoalesce(_optionalChain([input, 'optionalAccess', _37 => _37.returnUrl]), () => ( _optionalChain([cartUrls, 'optionalAccess', _38 => _38.returnUrl])));
|
|
671
|
+
const cancelUrl = _nullishCoalesce(_optionalChain([input, 'optionalAccess', _39 => _39.cancelUrl]), () => ( _optionalChain([cartUrls, 'optionalAccess', _40 => _40.cancelUrl])));
|
|
600
672
|
if (returnUrl === void 0 || cancelUrl === void 0)
|
|
601
673
|
throw refuse(
|
|
602
674
|
"checkout() needs returnUrl and cancelUrl, given or from the provider cartUrls."
|
|
@@ -619,7 +691,7 @@ function useCart(options = {}) {
|
|
|
619
691
|
{ signal: callSignal }
|
|
620
692
|
);
|
|
621
693
|
} catch (error) {
|
|
622
|
-
const repriced =
|
|
694
|
+
const repriced = _chunkJ2GHGQY6cjs.isCatalogError.call(void 0, error) && error.code === "cart_prices_changed" ? _optionalChain([error, 'access', _41 => _41.details, 'optionalAccess', _42 => _42.cart]) : void 0;
|
|
623
695
|
if (!callSignal.aborted && typeof repriced === "object" && repriced !== null)
|
|
624
696
|
controller.box.set({ cart: repriced });
|
|
625
697
|
throw error;
|
|
@@ -639,7 +711,7 @@ function useCart(options = {}) {
|
|
|
639
711
|
if (out === void 0)
|
|
640
712
|
throw _nullishCoalesce(met, () => ( refuse("There is no cart to check out.")));
|
|
641
713
|
if (!isHttpUrl(out.checkoutUrl))
|
|
642
|
-
throw new (0,
|
|
714
|
+
throw new (0, _chunkJ2GHGQY6cjs.CatalogError)({
|
|
643
715
|
code: "INVALID_RESPONSE",
|
|
644
716
|
message: "Throttle answered a checkout URL that is not http or https.",
|
|
645
717
|
statusCode: 200,
|
|
@@ -656,7 +728,9 @@ function useCart(options = {}) {
|
|
|
656
728
|
}, [controller, home, currency, locale]);
|
|
657
729
|
const owner = controller.owner();
|
|
658
730
|
const view = owner !== void 0 && owner !== null && owner !== customerKey ? { ...EMPTY, pending: state.pending } : state;
|
|
659
|
-
|
|
731
|
+
const shownCurrency = _nullishCoalesce(_nullishCoalesce(_optionalChain([view, 'access', _43 => _43.cart, 'optionalAccess', _44 => _44.currency]), () => ( controller.wanted(options))), () => ( ""));
|
|
732
|
+
const format = (minor) => _chunkJ2GHGQY6cjs.formatMoney.call(void 0, minor, shownCurrency);
|
|
733
|
+
return { ...view, ...actions, format };
|
|
660
734
|
}
|
|
661
735
|
|
|
662
736
|
// src/react/use-submit-review.ts
|
|
@@ -667,7 +741,7 @@ var IDLE = {
|
|
|
667
741
|
result: void 0
|
|
668
742
|
};
|
|
669
743
|
function useSubmitReview(handle) {
|
|
670
|
-
const { client, store, customerKey } =
|
|
744
|
+
const { client, store, customerKey } = _chunkOKWXS3FDcjs.useCatalogContext.call(void 0, );
|
|
671
745
|
const scope = _react.useMemo.call(void 0,
|
|
672
746
|
() => ({
|
|
673
747
|
box: createBox(IDLE),
|
|
@@ -738,4 +812,6 @@ function useSubmitReview(handle) {
|
|
|
738
812
|
|
|
739
813
|
|
|
740
814
|
|
|
741
|
-
|
|
815
|
+
|
|
816
|
+
|
|
817
|
+
exports.CatalogProvider = _chunkOKWXS3FDcjs.CatalogProvider; exports.SDK_VERSION = _chunkJ2GHGQY6cjs.SDK_VERSION; exports.catalogQueryKey = _chunkOKWXS3FDcjs.catalogQueryKey; exports.createMemoryCartStorage = _chunkOKWXS3FDcjs.createMemoryCartStorage; exports.useCart = useCart; exports.useCatalog = _chunkOKWXS3FDcjs.useCatalog; exports.useCategories = _chunkOKWXS3FDcjs.useCategories; exports.useCollection = _chunkOKWXS3FDcjs.useCollection; exports.useConfig = _chunkOKWXS3FDcjs.useConfig; exports.useCustomerKey = _chunkOKWXS3FDcjs.useCustomerKey; exports.useFilterValues = _chunkOKWXS3FDcjs.useFilterValues; exports.useGenerationWatch = _chunkOKWXS3FDcjs.useGenerationWatch; exports.useProduct = _chunkOKWXS3FDcjs.useProduct; exports.useProducts = _chunkOKWXS3FDcjs.useProducts; exports.useRelated = _chunkOKWXS3FDcjs.useRelated; exports.useReviews = _chunkOKWXS3FDcjs.useReviews; exports.useStorefrontSettings = _chunkOKWXS3FDcjs.useStorefrontSettings; exports.useSubmitReview = useSubmitReview; exports.useSuggest = _chunkOKWXS3FDcjs.useSuggest;
|
package/dist/react.d.cts
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
export { ReviewEligibility } from './index.cjs';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { CatalogClient } from './index.cjs';
|
|
4
|
-
import { C as CustomerCartSource } from './types-
|
|
5
|
-
import { CategoryTreeDepth, ProductsQuery, ThrottleCart } from './index.cjs';
|
|
6
|
-
export { O as OpenCartRef } from './types-
|
|
7
|
-
import { Q as QueryOptions, a as QueryResult } from './use-query-
|
|
8
|
-
export { c as catalogQueryKey } from './use-query-
|
|
4
|
+
import { C as CustomerCartSource } from './types-jNpOwEUw.cjs';
|
|
5
|
+
import { CategoryTreeDepth, ProductsQuery, ThrottleCart, CartWarning } from './index.cjs';
|
|
6
|
+
export { O as OpenCartRef } from './types-jNpOwEUw.cjs';
|
|
7
|
+
import { Q as QueryOptions, a as QueryResult } from './use-query-H1xgL3_e.cjs';
|
|
8
|
+
export { c as catalogQueryKey } from './use-query-H1xgL3_e.cjs';
|
|
9
9
|
import { CatalogError } from './admin.cjs';
|
|
10
10
|
import { ReviewSubmitAnswer, ReviewSubmitInput } from './index.cjs';
|
|
11
11
|
export { S as SDK_VERSION } from './version-ev3p03v2.cjs';
|
|
12
|
+
import '@usethrottle/money';
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Where `useCart` keeps the cart session id (P6-R15). The default is memory
|
|
16
|
+
* only. The optional per-currency slots let a guest's `switchCurrency` find
|
|
17
|
+
* the cart it already has in that currency (MC2-R41); without them a guest
|
|
18
|
+
* switch makes a new cart. They hold a guest's carts only: `useCart` never
|
|
19
|
+
* writes them while signed in, and forgets them on a sign-in, a sign-out or
|
|
20
|
+
* a customer change (`removeFor`, else `setFor(currency, '')`).
|
|
21
|
+
*/
|
|
14
22
|
type CartStorage = {
|
|
15
23
|
get(): string | null | Promise<string | null>;
|
|
16
24
|
set(id: string): void | Promise<void>;
|
|
17
25
|
remove(): void | Promise<void>;
|
|
26
|
+
/** The session id last saved for `currency` (upper case), or `null`. */
|
|
27
|
+
getFor?(currency: string): string | null | Promise<string | null>;
|
|
28
|
+
setFor?(currency: string, id: string): void | Promise<void>;
|
|
29
|
+
removeFor?(currency: string): void | Promise<void>;
|
|
18
30
|
};
|
|
19
31
|
/** In memory only: the cart is forgotten on reload. The default `cartStorage`. */
|
|
20
32
|
declare function createMemoryCartStorage(): CartStorage;
|
|
@@ -87,6 +99,23 @@ declare function useReviews(handle: string | null, options?: QueryOptions<Answer
|
|
|
87
99
|
cursor?: string;
|
|
88
100
|
}): QueryResult<Answer<ReviewsList>>;
|
|
89
101
|
declare function useConfig(options?: QueryOptions<Answer<CatalogClient['config']>>): QueryResult<Answer<CatalogClient['config']>>;
|
|
102
|
+
/** The storefront settings with what versions them: `{ settings, settingsVersion, generation }`. */
|
|
103
|
+
declare function useStorefrontSettings(options?: QueryOptions<Answer<CatalogClient['settings']>>): QueryResult<Answer<CatalogClient['settings']>>;
|
|
104
|
+
/**
|
|
105
|
+
* Watches the storefront's generation: every `intervalMs` (60 s), while the
|
|
106
|
+
* page is visible, it asks `config` (conditionally, so an unchanged answer is
|
|
107
|
+
* a `304`), and checks at once when the page becomes visible after being
|
|
108
|
+
* hidden for at least the interval (or before a first answer). When the
|
|
109
|
+
* generation changes, the provider's cache is invalidated (hooks on screen
|
|
110
|
+
* keep their data and read again) and every mounted watcher's `onChange` is
|
|
111
|
+
* called once with the new generation. One timer and one request per
|
|
112
|
+
* provider however many watchers are mounted (the first one's `intervalMs`
|
|
113
|
+
* applies). Nothing runs on the server.
|
|
114
|
+
*/
|
|
115
|
+
declare function useGenerationWatch({ intervalMs, onChange, }?: {
|
|
116
|
+
intervalMs?: number;
|
|
117
|
+
onChange?: (generation: number) => void;
|
|
118
|
+
}): void;
|
|
90
119
|
/** The values of one filter for a selection. */
|
|
91
120
|
declare function useFilterValues(key: string | null, query?: ProductsQuery, options?: QueryOptions<Answer<CatalogClient['filters']['values']>>): QueryResult<Answer<CatalogClient['filters']['values']>>;
|
|
92
121
|
|
|
@@ -98,6 +127,12 @@ type CartState = {
|
|
|
98
127
|
error: CatalogError | undefined;
|
|
99
128
|
/** A change is queued or running. */
|
|
100
129
|
pending: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* What the last `switchCurrency` could not carry over: `lines_removed`
|
|
132
|
+
* (lines with no price in the new currency, left behind) and
|
|
133
|
+
* `discount_dropped` (a code the new currency refuses). Empty otherwise.
|
|
134
|
+
*/
|
|
135
|
+
warnings: CartWarning[];
|
|
101
136
|
};
|
|
102
137
|
type CartOptions = {
|
|
103
138
|
currency?: string;
|
|
@@ -120,14 +155,20 @@ type UseCartResult = CartState & {
|
|
|
120
155
|
checkoutUrl: string;
|
|
121
156
|
}>;
|
|
122
157
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
158
|
+
* Moves the cart into `currency`, keeping one cart per currency (MC2-R41):
|
|
159
|
+
* the shopper's open cart in `currency` (the signed-in customer's from
|
|
160
|
+
* `customerCart`, a guest's from `cartStorage.getFor`), else a new empty
|
|
161
|
+
* one, absorbs the current cart, which Throttle then closes as merged. Lines
|
|
162
|
+
* with no price in `currency` stay behind and a discount it refuses is
|
|
163
|
+
* dropped; both show in `warnings`. If anything fails before the absorb
|
|
164
|
+
* lands, it rejects and the old cart, its stored id and the old currency
|
|
165
|
+
* stay (an unused new cart is left to Throttle).
|
|
127
166
|
*/
|
|
128
167
|
switchCurrency(currency: string): Promise<void>;
|
|
129
168
|
/** Forgets the cart (no request). */
|
|
130
169
|
clear(): Promise<void>;
|
|
170
|
+
/** `formatMoney(minor, currency)` in the cart's currency (before a cart, the hook's or the client's). */
|
|
171
|
+
format(minor: number): string;
|
|
131
172
|
};
|
|
132
173
|
/**
|
|
133
174
|
* The provider's cart (P6-R15). The session id is kept in the provider's
|
|
@@ -160,5 +201,5 @@ type SubmitReviewResult = SubmitReviewState & {
|
|
|
160
201
|
*/
|
|
161
202
|
declare function useSubmitReview(handle: string): SubmitReviewResult;
|
|
162
203
|
|
|
163
|
-
export { CatalogProvider, CustomerCartSource, QueryOptions, QueryResult, createMemoryCartStorage, useCart, useCatalog, useCategories, useCollection, useConfig, useCustomerKey, useFilterValues, useProduct, useProducts, useRelated, useReviews, useSubmitReview, useSuggest };
|
|
204
|
+
export { CatalogProvider, CustomerCartSource, QueryOptions, QueryResult, createMemoryCartStorage, useCart, useCatalog, useCategories, useCollection, useConfig, useCustomerKey, useFilterValues, useGenerationWatch, useProduct, useProducts, useRelated, useReviews, useStorefrontSettings, useSubmitReview, useSuggest };
|
|
164
205
|
export type { CartOptions, CartState, CartStorage, CartUrls, CatalogProviderProps, SubmitReviewResult, SubmitReviewState, UseCartResult };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,20 +1,32 @@
|
|
|
1
1
|
export { ReviewEligibility } from './index.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { CatalogClient } from './index.js';
|
|
4
|
-
import { C as CustomerCartSource } from './types-
|
|
5
|
-
import { CategoryTreeDepth, ProductsQuery, ThrottleCart } from './index.js';
|
|
6
|
-
export { O as OpenCartRef } from './types-
|
|
7
|
-
import { Q as QueryOptions, a as QueryResult } from './use-query-
|
|
8
|
-
export { c as catalogQueryKey } from './use-query-
|
|
4
|
+
import { C as CustomerCartSource } from './types-z57bkjjB.js';
|
|
5
|
+
import { CategoryTreeDepth, ProductsQuery, ThrottleCart, CartWarning } from './index.js';
|
|
6
|
+
export { O as OpenCartRef } from './types-z57bkjjB.js';
|
|
7
|
+
import { Q as QueryOptions, a as QueryResult } from './use-query-COqRZJnC.js';
|
|
8
|
+
export { c as catalogQueryKey } from './use-query-COqRZJnC.js';
|
|
9
9
|
import { CatalogError } from './admin.js';
|
|
10
10
|
import { ReviewSubmitAnswer, ReviewSubmitInput } from './index.js';
|
|
11
11
|
export { S as SDK_VERSION } from './version-ev3p03v2.js';
|
|
12
|
+
import '@usethrottle/money';
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Where `useCart` keeps the cart session id (P6-R15). The default is memory
|
|
16
|
+
* only. The optional per-currency slots let a guest's `switchCurrency` find
|
|
17
|
+
* the cart it already has in that currency (MC2-R41); without them a guest
|
|
18
|
+
* switch makes a new cart. They hold a guest's carts only: `useCart` never
|
|
19
|
+
* writes them while signed in, and forgets them on a sign-in, a sign-out or
|
|
20
|
+
* a customer change (`removeFor`, else `setFor(currency, '')`).
|
|
21
|
+
*/
|
|
14
22
|
type CartStorage = {
|
|
15
23
|
get(): string | null | Promise<string | null>;
|
|
16
24
|
set(id: string): void | Promise<void>;
|
|
17
25
|
remove(): void | Promise<void>;
|
|
26
|
+
/** The session id last saved for `currency` (upper case), or `null`. */
|
|
27
|
+
getFor?(currency: string): string | null | Promise<string | null>;
|
|
28
|
+
setFor?(currency: string, id: string): void | Promise<void>;
|
|
29
|
+
removeFor?(currency: string): void | Promise<void>;
|
|
18
30
|
};
|
|
19
31
|
/** In memory only: the cart is forgotten on reload. The default `cartStorage`. */
|
|
20
32
|
declare function createMemoryCartStorage(): CartStorage;
|
|
@@ -87,6 +99,23 @@ declare function useReviews(handle: string | null, options?: QueryOptions<Answer
|
|
|
87
99
|
cursor?: string;
|
|
88
100
|
}): QueryResult<Answer<ReviewsList>>;
|
|
89
101
|
declare function useConfig(options?: QueryOptions<Answer<CatalogClient['config']>>): QueryResult<Answer<CatalogClient['config']>>;
|
|
102
|
+
/** The storefront settings with what versions them: `{ settings, settingsVersion, generation }`. */
|
|
103
|
+
declare function useStorefrontSettings(options?: QueryOptions<Answer<CatalogClient['settings']>>): QueryResult<Answer<CatalogClient['settings']>>;
|
|
104
|
+
/**
|
|
105
|
+
* Watches the storefront's generation: every `intervalMs` (60 s), while the
|
|
106
|
+
* page is visible, it asks `config` (conditionally, so an unchanged answer is
|
|
107
|
+
* a `304`), and checks at once when the page becomes visible after being
|
|
108
|
+
* hidden for at least the interval (or before a first answer). When the
|
|
109
|
+
* generation changes, the provider's cache is invalidated (hooks on screen
|
|
110
|
+
* keep their data and read again) and every mounted watcher's `onChange` is
|
|
111
|
+
* called once with the new generation. One timer and one request per
|
|
112
|
+
* provider however many watchers are mounted (the first one's `intervalMs`
|
|
113
|
+
* applies). Nothing runs on the server.
|
|
114
|
+
*/
|
|
115
|
+
declare function useGenerationWatch({ intervalMs, onChange, }?: {
|
|
116
|
+
intervalMs?: number;
|
|
117
|
+
onChange?: (generation: number) => void;
|
|
118
|
+
}): void;
|
|
90
119
|
/** The values of one filter for a selection. */
|
|
91
120
|
declare function useFilterValues(key: string | null, query?: ProductsQuery, options?: QueryOptions<Answer<CatalogClient['filters']['values']>>): QueryResult<Answer<CatalogClient['filters']['values']>>;
|
|
92
121
|
|
|
@@ -98,6 +127,12 @@ type CartState = {
|
|
|
98
127
|
error: CatalogError | undefined;
|
|
99
128
|
/** A change is queued or running. */
|
|
100
129
|
pending: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* What the last `switchCurrency` could not carry over: `lines_removed`
|
|
132
|
+
* (lines with no price in the new currency, left behind) and
|
|
133
|
+
* `discount_dropped` (a code the new currency refuses). Empty otherwise.
|
|
134
|
+
*/
|
|
135
|
+
warnings: CartWarning[];
|
|
101
136
|
};
|
|
102
137
|
type CartOptions = {
|
|
103
138
|
currency?: string;
|
|
@@ -120,14 +155,20 @@ type UseCartResult = CartState & {
|
|
|
120
155
|
checkoutUrl: string;
|
|
121
156
|
}>;
|
|
122
157
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
158
|
+
* Moves the cart into `currency`, keeping one cart per currency (MC2-R41):
|
|
159
|
+
* the shopper's open cart in `currency` (the signed-in customer's from
|
|
160
|
+
* `customerCart`, a guest's from `cartStorage.getFor`), else a new empty
|
|
161
|
+
* one, absorbs the current cart, which Throttle then closes as merged. Lines
|
|
162
|
+
* with no price in `currency` stay behind and a discount it refuses is
|
|
163
|
+
* dropped; both show in `warnings`. If anything fails before the absorb
|
|
164
|
+
* lands, it rejects and the old cart, its stored id and the old currency
|
|
165
|
+
* stay (an unused new cart is left to Throttle).
|
|
127
166
|
*/
|
|
128
167
|
switchCurrency(currency: string): Promise<void>;
|
|
129
168
|
/** Forgets the cart (no request). */
|
|
130
169
|
clear(): Promise<void>;
|
|
170
|
+
/** `formatMoney(minor, currency)` in the cart's currency (before a cart, the hook's or the client's). */
|
|
171
|
+
format(minor: number): string;
|
|
131
172
|
};
|
|
132
173
|
/**
|
|
133
174
|
* The provider's cart (P6-R15). The session id is kept in the provider's
|
|
@@ -160,5 +201,5 @@ type SubmitReviewResult = SubmitReviewState & {
|
|
|
160
201
|
*/
|
|
161
202
|
declare function useSubmitReview(handle: string): SubmitReviewResult;
|
|
162
203
|
|
|
163
|
-
export { CatalogProvider, CustomerCartSource, QueryOptions, QueryResult, createMemoryCartStorage, useCart, useCatalog, useCategories, useCollection, useConfig, useCustomerKey, useFilterValues, useProduct, useProducts, useRelated, useReviews, useSubmitReview, useSuggest };
|
|
204
|
+
export { CatalogProvider, CustomerCartSource, QueryOptions, QueryResult, createMemoryCartStorage, useCart, useCatalog, useCategories, useCollection, useConfig, useCustomerKey, useFilterValues, useGenerationWatch, useProduct, useProducts, useRelated, useReviews, useStorefrontSettings, useSubmitReview, useSuggest };
|
|
164
205
|
export type { CartOptions, CartState, CartStorage, CartUrls, CatalogProviderProps, SubmitReviewResult, SubmitReviewState, UseCartResult };
|