@shoppexio/storefront 1.0.87 → 1.0.88
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 +7 -0
- package/dist/index.cjs +68 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +68 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1923,14 +1923,14 @@ declare function trackPageView(cartValue?: number, itemCount?: number): Promise<
|
|
|
1923
1923
|
/**
|
|
1924
1924
|
* Reports a cart change for the live visitor map without counting a page view
|
|
1925
1925
|
* (`event_type: 'presence'`). Use it when the cart changes on a page that was
|
|
1926
|
-
* already counted. A cart state the server
|
|
1927
|
-
*
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1926
|
+
* already counted. A cart state the server holds, or will hold once a send in
|
|
1927
|
+
* flight lands, is not sent again, so a cross-tab `storage` echo of a change is
|
|
1928
|
+
* not a second ping. A failed send leaves nothing behind: the same state goes
|
|
1929
|
+
* out again on the next change or page load.
|
|
1930
1930
|
*
|
|
1931
|
-
* The check runs when the change's turn
|
|
1932
|
-
*
|
|
1933
|
-
* state is on the wire must still go out
|
|
1931
|
+
* The sequence is taken at call time; the check runs when the change's turn
|
|
1932
|
+
* comes, after this tab's earlier sends settled: a revert to the confirmed
|
|
1933
|
+
* cart while another state is on the wire must still go out.
|
|
1934
1934
|
*/
|
|
1935
1935
|
declare function trackCartActivity(cartValue: number, itemCount: number): Promise<void>;
|
|
1936
1936
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1923,14 +1923,14 @@ declare function trackPageView(cartValue?: number, itemCount?: number): Promise<
|
|
|
1923
1923
|
/**
|
|
1924
1924
|
* Reports a cart change for the live visitor map without counting a page view
|
|
1925
1925
|
* (`event_type: 'presence'`). Use it when the cart changes on a page that was
|
|
1926
|
-
* already counted. A cart state the server
|
|
1927
|
-
*
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1926
|
+
* already counted. A cart state the server holds, or will hold once a send in
|
|
1927
|
+
* flight lands, is not sent again, so a cross-tab `storage` echo of a change is
|
|
1928
|
+
* not a second ping. A failed send leaves nothing behind: the same state goes
|
|
1929
|
+
* out again on the next change or page load.
|
|
1930
1930
|
*
|
|
1931
|
-
* The check runs when the change's turn
|
|
1932
|
-
*
|
|
1933
|
-
* state is on the wire must still go out
|
|
1931
|
+
* The sequence is taken at call time; the check runs when the change's turn
|
|
1932
|
+
* comes, after this tab's earlier sends settled: a revert to the confirmed
|
|
1933
|
+
* cart while another state is on the wire must still go out.
|
|
1934
1934
|
*/
|
|
1935
1935
|
declare function trackCartActivity(cartValue: number, itemCount: number): Promise<void>;
|
|
1936
1936
|
|
package/dist/index.js
CHANGED
|
@@ -6082,6 +6082,7 @@ function isPlatformPageTrackerActive() {
|
|
|
6082
6082
|
// ../sdk/src/modules/analytics.ts
|
|
6083
6083
|
var CONFIRMED_CART_STORAGE_PREFIX = "reported_cart_";
|
|
6084
6084
|
var IN_FLIGHT_CART_STORAGE_PREFIX = "reporting_cart_";
|
|
6085
|
+
var CART_SEQUENCE_STORAGE_PREFIX = "presence_cart_seq_";
|
|
6085
6086
|
var CART_CLAIM_TTL_MS = 1e4;
|
|
6086
6087
|
function confirmedCartKey(storeSlug) {
|
|
6087
6088
|
return `${CONFIRMED_CART_STORAGE_PREFIX}${storeSlug}`;
|
|
@@ -6089,33 +6090,77 @@ function confirmedCartKey(storeSlug) {
|
|
|
6089
6090
|
function inFlightCartKey(storeSlug) {
|
|
6090
6091
|
return `${IN_FLIGHT_CART_STORAGE_PREFIX}${storeSlug}`;
|
|
6091
6092
|
}
|
|
6093
|
+
function cartSequenceKey(storeSlug) {
|
|
6094
|
+
return `${CART_SEQUENCE_STORAGE_PREFIX}${storeSlug}`;
|
|
6095
|
+
}
|
|
6092
6096
|
function cartSnapshot(cartValue, itemCount) {
|
|
6093
6097
|
return `${cartValue ?? ""}|${itemCount ?? ""}`;
|
|
6094
6098
|
}
|
|
6099
|
+
function isCartSequence(value) {
|
|
6100
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value > 0;
|
|
6101
|
+
}
|
|
6102
|
+
var CART_SEQUENCE_SCOPE_MAX_LENGTH = 64;
|
|
6103
|
+
function readCartCounter(storeSlug) {
|
|
6104
|
+
const counter = getItem(cartSequenceKey(storeSlug));
|
|
6105
|
+
if (!counter || typeof counter.scope !== "string" || counter.scope.length === 0 || counter.scope.length > CART_SEQUENCE_SCOPE_MAX_LENGTH || !isCartSequence(counter.seq)) {
|
|
6106
|
+
return null;
|
|
6107
|
+
}
|
|
6108
|
+
return counter;
|
|
6109
|
+
}
|
|
6110
|
+
var lastCartOrder = null;
|
|
6111
|
+
function nextCartOrder(storeSlug) {
|
|
6112
|
+
const stored = readCartCounter(storeSlug);
|
|
6113
|
+
const scope = stored?.scope ?? lastCartOrder?.scope ?? createClaimToken();
|
|
6114
|
+
const floor = Math.max(stored?.seq ?? 0, lastCartOrder?.scope === scope ? lastCartOrder.seq : 0);
|
|
6115
|
+
const order2 = { scope, seq: Math.max(Date.now(), floor + 1) };
|
|
6116
|
+
lastCartOrder = order2;
|
|
6117
|
+
setItem(cartSequenceKey(storeSlug), order2);
|
|
6118
|
+
return order2;
|
|
6119
|
+
}
|
|
6120
|
+
function cartSequenceLocks() {
|
|
6121
|
+
if (typeof navigator === "undefined") return null;
|
|
6122
|
+
const locks = navigator.locks;
|
|
6123
|
+
return locks && typeof locks.request === "function" ? locks : null;
|
|
6124
|
+
}
|
|
6125
|
+
function reserveCartOrder(storeSlug) {
|
|
6126
|
+
const take = () => nextCartOrder(storeSlug);
|
|
6127
|
+
const locks = cartSequenceLocks();
|
|
6128
|
+
if (!locks) return Promise.resolve(take());
|
|
6129
|
+
return locks.request(cartSequenceKey(storeSlug), take).catch(take);
|
|
6130
|
+
}
|
|
6131
|
+
function readConfirmedCart(storeSlug) {
|
|
6132
|
+
const confirmed = getItem(confirmedCartKey(storeSlug));
|
|
6133
|
+
if (!confirmed || typeof confirmed.snapshot !== "string" || !isCartSequence(confirmed.seq)) return null;
|
|
6134
|
+
return confirmed;
|
|
6135
|
+
}
|
|
6095
6136
|
function readInFlightCart(storeSlug) {
|
|
6096
6137
|
const claim = getItem(inFlightCartKey(storeSlug));
|
|
6097
|
-
if (!claim || typeof claim.snapshot !== "string" || typeof claim.token !== "string" || typeof claim.at !== "number") {
|
|
6138
|
+
if (!claim || typeof claim.snapshot !== "string" || !isCartSequence(claim.seq) || typeof claim.token !== "string" || typeof claim.at !== "number") {
|
|
6098
6139
|
return null;
|
|
6099
6140
|
}
|
|
6100
6141
|
return claim;
|
|
6101
6142
|
}
|
|
6102
6143
|
function isCartReportedOrInFlight(storeSlug, snapshot) {
|
|
6103
|
-
|
|
6144
|
+
const confirmed = readConfirmedCart(storeSlug);
|
|
6104
6145
|
const claim = readInFlightCart(storeSlug);
|
|
6105
|
-
|
|
6146
|
+
const liveClaim = claim && Date.now() - claim.at < CART_CLAIM_TTL_MS ? claim : null;
|
|
6147
|
+
const expected = liveClaim && (!confirmed || liveClaim.seq > confirmed.seq) ? liveClaim : confirmed;
|
|
6148
|
+
return expected?.snapshot === snapshot;
|
|
6106
6149
|
}
|
|
6107
6150
|
function createClaimToken() {
|
|
6108
6151
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
6109
6152
|
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
6110
6153
|
}
|
|
6111
|
-
function claimCartReport(storeSlug, cartValue, itemCount) {
|
|
6154
|
+
function claimCartReport(storeSlug, seq, cartValue, itemCount) {
|
|
6112
6155
|
const snapshot = cartSnapshot(cartValue, itemCount);
|
|
6113
6156
|
const token = createClaimToken();
|
|
6114
|
-
setItem(inFlightCartKey(storeSlug), { snapshot, token, at: Date.now() });
|
|
6157
|
+
setItem(inFlightCartKey(storeSlug), { snapshot, seq, token, at: Date.now() });
|
|
6115
6158
|
return (delivered) => {
|
|
6116
|
-
if (
|
|
6117
|
-
|
|
6118
|
-
|
|
6159
|
+
if (delivered) {
|
|
6160
|
+
const confirmed = readConfirmedCart(storeSlug);
|
|
6161
|
+
if (!confirmed || seq > confirmed.seq) setItem(confirmedCartKey(storeSlug), { snapshot, seq });
|
|
6162
|
+
}
|
|
6163
|
+
if (readInFlightCart(storeSlug)?.token === token) removeItem(inFlightCartKey(storeSlug));
|
|
6119
6164
|
};
|
|
6120
6165
|
}
|
|
6121
6166
|
var cartSendTail = Promise.resolve();
|
|
@@ -6156,42 +6201,50 @@ async function postPing(body) {
|
|
|
6156
6201
|
async function trackPageView(cartValue, itemCount) {
|
|
6157
6202
|
if (!isInitialized()) return;
|
|
6158
6203
|
if (typeof document === "undefined") return;
|
|
6204
|
+
const config = getConfig();
|
|
6159
6205
|
const carriesCart = cartValue !== void 0 || itemCount !== void 0;
|
|
6206
|
+
const reservedOrder = carriesCart ? reserveCartOrder(config.storeSlug) : void 0;
|
|
6160
6207
|
if (isPlatformPageTrackerActive()) {
|
|
6161
|
-
if (
|
|
6208
|
+
if (reservedOrder) await enqueueCartSend(async () => sendCartActivity(await reservedOrder, cartValue, itemCount));
|
|
6162
6209
|
return;
|
|
6163
6210
|
}
|
|
6164
|
-
const config = getConfig();
|
|
6165
6211
|
const sendView = async () => {
|
|
6166
|
-
const
|
|
6212
|
+
const order2 = reservedOrder ? await reservedOrder : void 0;
|
|
6213
|
+
const settle = order2 ? claimCartReport(config.storeSlug, order2.seq, cartValue, itemCount) : void 0;
|
|
6167
6214
|
const delivered = await postPing({
|
|
6168
6215
|
referer: document.referrer || void 0,
|
|
6169
6216
|
cart_value: cartValue,
|
|
6170
6217
|
item_count: itemCount,
|
|
6218
|
+
cart_seq: order2?.seq,
|
|
6219
|
+
cart_seq_scope: order2?.scope,
|
|
6171
6220
|
connection_id: getStorefrontConnectionId(config.storeSlug) ?? void 0,
|
|
6172
6221
|
path: resolveStorefrontPagePath(),
|
|
6173
6222
|
utm: resolveUtmParameters(config.storeSlug)
|
|
6174
6223
|
});
|
|
6175
6224
|
settle?.(delivered);
|
|
6176
6225
|
};
|
|
6177
|
-
await (
|
|
6226
|
+
await (reservedOrder ? enqueueCartSend(sendView) : sendView());
|
|
6178
6227
|
}
|
|
6179
6228
|
async function trackCartActivity(cartValue, itemCount) {
|
|
6180
6229
|
if (!isInitialized()) return;
|
|
6181
6230
|
if (typeof document === "undefined") return;
|
|
6182
6231
|
const snapshot = cartSnapshot(cartValue, itemCount);
|
|
6232
|
+
const reservedOrder = reserveCartOrder(getConfig().storeSlug);
|
|
6183
6233
|
await enqueueCartSend(async (isLatest) => {
|
|
6234
|
+
const order2 = await reservedOrder;
|
|
6184
6235
|
if (!isLatest() || isCartReportedOrInFlight(getConfig().storeSlug, snapshot)) return;
|
|
6185
|
-
await sendCartActivity(cartValue, itemCount);
|
|
6236
|
+
await sendCartActivity(order2, cartValue, itemCount);
|
|
6186
6237
|
});
|
|
6187
6238
|
}
|
|
6188
|
-
async function sendCartActivity(cartValue, itemCount) {
|
|
6239
|
+
async function sendCartActivity(order2, cartValue, itemCount) {
|
|
6189
6240
|
const config = getConfig();
|
|
6190
|
-
const settle = claimCartReport(config.storeSlug, cartValue, itemCount);
|
|
6241
|
+
const settle = claimCartReport(config.storeSlug, order2.seq, cartValue, itemCount);
|
|
6191
6242
|
const delivered = await postPing({
|
|
6192
6243
|
event_type: "presence",
|
|
6193
6244
|
cart_value: cartValue,
|
|
6194
6245
|
item_count: itemCount,
|
|
6246
|
+
cart_seq: order2.seq,
|
|
6247
|
+
cart_seq_scope: order2.scope,
|
|
6195
6248
|
connection_id: getStorefrontConnectionId(config.storeSlug) ?? void 0,
|
|
6196
6249
|
path: resolveStorefrontPagePath()
|
|
6197
6250
|
});
|