@shoppexio/storefront 1.0.84 → 1.0.85
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 +6 -0
- package/dist/index.cjs +101 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +101 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1916,9 +1916,14 @@ declare function trackPageView(cartValue?: number, itemCount?: number): Promise<
|
|
|
1916
1916
|
/**
|
|
1917
1917
|
* Reports a cart change for the live visitor map without counting a page view
|
|
1918
1918
|
* (`event_type: 'presence'`). Use it when the cart changes on a page that was
|
|
1919
|
-
* already counted. A cart state
|
|
1920
|
-
* not sent again, so a cross-tab `storage`
|
|
1921
|
-
* ping.
|
|
1919
|
+
* already counted. A cart state the server already acknowledged, or that a tab
|
|
1920
|
+
* of this shop is sending right now, is not sent again, so a cross-tab `storage`
|
|
1921
|
+
* echo of a change is not a second ping. A failed send leaves nothing behind:
|
|
1922
|
+
* the same state goes out again on the next change or page load.
|
|
1923
|
+
*
|
|
1924
|
+
* The check runs when the change's turn comes, after this tab's earlier sends
|
|
1925
|
+
* settled, never at call time: a revert to the confirmed cart while another
|
|
1926
|
+
* state is on the wire must still go out once that send confirms its state.
|
|
1922
1927
|
*/
|
|
1923
1928
|
declare function trackCartActivity(cartValue: number, itemCount: number): Promise<void>;
|
|
1924
1929
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1916,9 +1916,14 @@ declare function trackPageView(cartValue?: number, itemCount?: number): Promise<
|
|
|
1916
1916
|
/**
|
|
1917
1917
|
* Reports a cart change for the live visitor map without counting a page view
|
|
1918
1918
|
* (`event_type: 'presence'`). Use it when the cart changes on a page that was
|
|
1919
|
-
* already counted. A cart state
|
|
1920
|
-
* not sent again, so a cross-tab `storage`
|
|
1921
|
-
* ping.
|
|
1919
|
+
* already counted. A cart state the server already acknowledged, or that a tab
|
|
1920
|
+
* of this shop is sending right now, is not sent again, so a cross-tab `storage`
|
|
1921
|
+
* echo of a change is not a second ping. A failed send leaves nothing behind:
|
|
1922
|
+
* the same state goes out again on the next change or page load.
|
|
1923
|
+
*
|
|
1924
|
+
* The check runs when the change's turn comes, after this tab's earlier sends
|
|
1925
|
+
* settled, never at call time: a revert to the confirmed cart while another
|
|
1926
|
+
* state is on the wire must still go out once that send confirms its state.
|
|
1922
1927
|
*/
|
|
1923
1928
|
declare function trackCartActivity(cartValue: number, itemCount: number): Promise<void>;
|
|
1924
1929
|
|
package/dist/index.js
CHANGED
|
@@ -3318,6 +3318,8 @@ function removeItem(key) {
|
|
|
3318
3318
|
// ../sdk/src/core/telemetry.ts
|
|
3319
3319
|
var CONNECTION_ID_STORAGE_PREFIX = "presence_connection_";
|
|
3320
3320
|
var CLIENT_ERROR_DEDUPE_WINDOW_MS = 15e3;
|
|
3321
|
+
var CLIENT_ERROR_TEXT_MAX_LENGTH = 500;
|
|
3322
|
+
var CLIENT_ERROR_URL_MAX_LENGTH = 2e3;
|
|
3321
3323
|
function createPresenceConnectionId() {
|
|
3322
3324
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
3323
3325
|
return crypto.randomUUID();
|
|
@@ -3368,14 +3370,14 @@ async function reportStorefrontClientError(payload) {
|
|
|
3368
3370
|
client_error: {
|
|
3369
3371
|
source: payload.source ?? "sdk",
|
|
3370
3372
|
phase: payload.phase ?? "request",
|
|
3371
|
-
endpoint: payload.endpoint,
|
|
3373
|
+
endpoint: payload.endpoint.slice(0, CLIENT_ERROR_TEXT_MAX_LENGTH),
|
|
3372
3374
|
method: payload.method,
|
|
3373
|
-
message: payload.message,
|
|
3375
|
+
message: payload.message.slice(0, CLIENT_ERROR_TEXT_MAX_LENGTH),
|
|
3374
3376
|
status_code: payload.statusCode,
|
|
3375
3377
|
attempt_count: payload.attemptCount,
|
|
3376
3378
|
response_received: payload.responseReceived ?? false,
|
|
3377
|
-
page_url: payload.pageUrl ?? window.location.href,
|
|
3378
|
-
request_url: payload.requestUrl,
|
|
3379
|
+
page_url: (payload.pageUrl ?? window.location.href).slice(0, CLIENT_ERROR_URL_MAX_LENGTH),
|
|
3380
|
+
request_url: payload.requestUrl?.slice(0, CLIENT_ERROR_URL_MAX_LENGTH),
|
|
3379
3381
|
online: payload.online ?? (typeof navigator !== "undefined" ? navigator.onLine : void 0),
|
|
3380
3382
|
visibility_state: payload.visibilityState ?? (typeof document !== "undefined" ? document.visibilityState : void 0)
|
|
3381
3383
|
}
|
|
@@ -6083,72 +6085,122 @@ function isPlatformPageTrackerActive() {
|
|
|
6083
6085
|
}
|
|
6084
6086
|
|
|
6085
6087
|
// ../sdk/src/modules/analytics.ts
|
|
6086
|
-
var
|
|
6087
|
-
|
|
6088
|
-
|
|
6088
|
+
var CONFIRMED_CART_STORAGE_PREFIX = "reported_cart_";
|
|
6089
|
+
var IN_FLIGHT_CART_STORAGE_PREFIX = "reporting_cart_";
|
|
6090
|
+
var CART_CLAIM_TTL_MS = 1e4;
|
|
6091
|
+
function confirmedCartKey(storeSlug) {
|
|
6092
|
+
return `${CONFIRMED_CART_STORAGE_PREFIX}${storeSlug}`;
|
|
6093
|
+
}
|
|
6094
|
+
function inFlightCartKey(storeSlug) {
|
|
6095
|
+
return `${IN_FLIGHT_CART_STORAGE_PREFIX}${storeSlug}`;
|
|
6089
6096
|
}
|
|
6090
6097
|
function cartSnapshot(cartValue, itemCount) {
|
|
6091
6098
|
return `${cartValue ?? ""}|${itemCount ?? ""}`;
|
|
6092
6099
|
}
|
|
6093
|
-
function
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
if (!isInitialized()) return;
|
|
6098
|
-
if (typeof document === "undefined") return;
|
|
6099
|
-
const carriesCart = cartValue !== void 0 || itemCount !== void 0;
|
|
6100
|
-
if (isPlatformPageTrackerActive()) {
|
|
6101
|
-
if (carriesCart) await sendCartActivity(cartValue ?? 0, itemCount ?? 0);
|
|
6102
|
-
return;
|
|
6100
|
+
function readInFlightCart(storeSlug) {
|
|
6101
|
+
const claim = getItem(inFlightCartKey(storeSlug));
|
|
6102
|
+
if (!claim || typeof claim.snapshot !== "string" || typeof claim.token !== "string" || typeof claim.at !== "number") {
|
|
6103
|
+
return null;
|
|
6103
6104
|
}
|
|
6105
|
+
return claim;
|
|
6106
|
+
}
|
|
6107
|
+
function isCartReportedOrInFlight(storeSlug, snapshot) {
|
|
6108
|
+
if (getItem(confirmedCartKey(storeSlug)) === snapshot) return true;
|
|
6109
|
+
const claim = readInFlightCart(storeSlug);
|
|
6110
|
+
return claim !== null && claim.snapshot === snapshot && Date.now() - claim.at < CART_CLAIM_TTL_MS;
|
|
6111
|
+
}
|
|
6112
|
+
function createClaimToken() {
|
|
6113
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
6114
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}`;
|
|
6115
|
+
}
|
|
6116
|
+
function claimCartReport(storeSlug, cartValue, itemCount) {
|
|
6117
|
+
const snapshot = cartSnapshot(cartValue, itemCount);
|
|
6118
|
+
const token = createClaimToken();
|
|
6119
|
+
setItem(inFlightCartKey(storeSlug), { snapshot, token, at: Date.now() });
|
|
6120
|
+
return (delivered) => {
|
|
6121
|
+
if (readInFlightCart(storeSlug)?.token !== token) return;
|
|
6122
|
+
if (delivered) setItem(confirmedCartKey(storeSlug), snapshot);
|
|
6123
|
+
removeItem(inFlightCartKey(storeSlug));
|
|
6124
|
+
};
|
|
6125
|
+
}
|
|
6126
|
+
var cartSendTail = Promise.resolve();
|
|
6127
|
+
var latestCartRequest = 0;
|
|
6128
|
+
function enqueueCartSend(send) {
|
|
6129
|
+
const request2 = ++latestCartRequest;
|
|
6130
|
+
const run = () => send(() => request2 === latestCartRequest);
|
|
6131
|
+
cartSendTail = cartSendTail.then(run, run);
|
|
6132
|
+
return cartSendTail;
|
|
6133
|
+
}
|
|
6134
|
+
async function postPing(body) {
|
|
6104
6135
|
const config = getConfig();
|
|
6105
|
-
const
|
|
6106
|
-
|
|
6136
|
+
const controller = typeof AbortController === "undefined" ? void 0 : new AbortController();
|
|
6137
|
+
let timer;
|
|
6138
|
+
const timedOut = new Promise((resolve) => {
|
|
6139
|
+
timer = setTimeout(() => {
|
|
6140
|
+
controller?.abort();
|
|
6141
|
+
resolve(false);
|
|
6142
|
+
}, CART_CLAIM_TTL_MS);
|
|
6143
|
+
});
|
|
6107
6144
|
try {
|
|
6108
6145
|
const endpoint = buildEndpoint("/v1/storefront/shops/:storeSlug/ping", {
|
|
6109
6146
|
storeSlug: config.storeSlug
|
|
6110
6147
|
});
|
|
6111
|
-
|
|
6148
|
+
const delivered = fetch(`${config.apiBaseUrl}${endpoint}`, {
|
|
6112
6149
|
method: "POST",
|
|
6113
6150
|
headers: { "Content-Type": "application/json" },
|
|
6114
|
-
body: JSON.stringify(
|
|
6115
|
-
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
connection_id: connectionId ?? void 0,
|
|
6119
|
-
path: resolveStorefrontPagePath(),
|
|
6120
|
-
utm: resolveUtmParameters(config.storeSlug)
|
|
6121
|
-
})
|
|
6122
|
-
});
|
|
6151
|
+
body: JSON.stringify(body),
|
|
6152
|
+
signal: controller?.signal
|
|
6153
|
+
}).then((response) => response.ok);
|
|
6154
|
+
return await Promise.race([delivered, timedOut]);
|
|
6123
6155
|
} catch {
|
|
6156
|
+
return false;
|
|
6157
|
+
} finally {
|
|
6158
|
+
clearTimeout(timer);
|
|
6124
6159
|
}
|
|
6125
6160
|
}
|
|
6161
|
+
async function trackPageView(cartValue, itemCount) {
|
|
6162
|
+
if (!isInitialized()) return;
|
|
6163
|
+
if (typeof document === "undefined") return;
|
|
6164
|
+
const carriesCart = cartValue !== void 0 || itemCount !== void 0;
|
|
6165
|
+
if (isPlatformPageTrackerActive()) {
|
|
6166
|
+
if (carriesCart) await enqueueCartSend(() => sendCartActivity(cartValue, itemCount));
|
|
6167
|
+
return;
|
|
6168
|
+
}
|
|
6169
|
+
const config = getConfig();
|
|
6170
|
+
const sendView = async () => {
|
|
6171
|
+
const settle = carriesCart ? claimCartReport(config.storeSlug, cartValue, itemCount) : void 0;
|
|
6172
|
+
const delivered = await postPing({
|
|
6173
|
+
referer: document.referrer || void 0,
|
|
6174
|
+
cart_value: cartValue,
|
|
6175
|
+
item_count: itemCount,
|
|
6176
|
+
connection_id: getStorefrontConnectionId(config.storeSlug) ?? void 0,
|
|
6177
|
+
path: resolveStorefrontPagePath(),
|
|
6178
|
+
utm: resolveUtmParameters(config.storeSlug)
|
|
6179
|
+
});
|
|
6180
|
+
settle?.(delivered);
|
|
6181
|
+
};
|
|
6182
|
+
await (carriesCart ? enqueueCartSend(sendView) : sendView());
|
|
6183
|
+
}
|
|
6126
6184
|
async function trackCartActivity(cartValue, itemCount) {
|
|
6127
6185
|
if (!isInitialized()) return;
|
|
6128
6186
|
if (typeof document === "undefined") return;
|
|
6129
|
-
|
|
6130
|
-
await
|
|
6187
|
+
const snapshot = cartSnapshot(cartValue, itemCount);
|
|
6188
|
+
await enqueueCartSend(async (isLatest) => {
|
|
6189
|
+
if (!isLatest() || isCartReportedOrInFlight(getConfig().storeSlug, snapshot)) return;
|
|
6190
|
+
await sendCartActivity(cartValue, itemCount);
|
|
6191
|
+
});
|
|
6131
6192
|
}
|
|
6132
6193
|
async function sendCartActivity(cartValue, itemCount) {
|
|
6133
6194
|
const config = getConfig();
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
event_type: "presence",
|
|
6144
|
-
cart_value: cartValue,
|
|
6145
|
-
item_count: itemCount,
|
|
6146
|
-
connection_id: getStorefrontConnectionId(config.storeSlug) ?? void 0,
|
|
6147
|
-
path: resolveStorefrontPagePath()
|
|
6148
|
-
})
|
|
6149
|
-
});
|
|
6150
|
-
} catch {
|
|
6151
|
-
}
|
|
6195
|
+
const settle = claimCartReport(config.storeSlug, cartValue, itemCount);
|
|
6196
|
+
const delivered = await postPing({
|
|
6197
|
+
event_type: "presence",
|
|
6198
|
+
cart_value: cartValue,
|
|
6199
|
+
item_count: itemCount,
|
|
6200
|
+
connection_id: getStorefrontConnectionId(config.storeSlug) ?? void 0,
|
|
6201
|
+
path: resolveStorefrontPagePath()
|
|
6202
|
+
});
|
|
6203
|
+
settle(delivered);
|
|
6152
6204
|
}
|
|
6153
6205
|
|
|
6154
6206
|
// ../sdk/src/modules/presence.ts
|