@cross-deck/web 1.7.0 → 1.8.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 +29 -0
- package/dist/crossdeck.umd.min.js +2 -2
- package/dist/crossdeck.umd.min.js.map +1 -1
- package/dist/error-codes.json +8 -1
- package/dist/index.cjs +84 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +15 -5
- package/dist/index.d.ts +15 -5
- package/dist/index.mjs +84 -14
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +73 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +73 -3
- package/dist/react.mjs.map +1 -1
- package/dist/vue.cjs +73 -3
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.mjs +73 -3
- package/dist/vue.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/contracts.json +0 -546
package/dist/vue.cjs
CHANGED
|
@@ -36,6 +36,8 @@ var CrossdeckError = class _CrossdeckError extends Error {
|
|
|
36
36
|
this.requestId = payload.requestId;
|
|
37
37
|
this.status = payload.status;
|
|
38
38
|
this.retryAfterMs = payload.retryAfterMs;
|
|
39
|
+
this.minVersion = payload.minVersion;
|
|
40
|
+
this.surface = payload.surface;
|
|
39
41
|
Object.setPrototypeOf(this, _CrossdeckError.prototype);
|
|
40
42
|
}
|
|
41
43
|
};
|
|
@@ -56,7 +58,10 @@ async function crossdeckErrorFromResponse(res) {
|
|
|
56
58
|
message: envelope.message ?? `HTTP ${res.status}`,
|
|
57
59
|
requestId: envelope.request_id ?? requestId,
|
|
58
60
|
status: res.status,
|
|
59
|
-
retryAfterMs
|
|
61
|
+
retryAfterMs,
|
|
62
|
+
// PARK metadata, present only on a 426 / sdk_version_unsupported body.
|
|
63
|
+
minVersion: typeof envelope.minVersion === "string" ? envelope.minVersion : void 0,
|
|
64
|
+
surface: typeof envelope.surface === "string" ? envelope.surface : void 0
|
|
60
65
|
});
|
|
61
66
|
}
|
|
62
67
|
return new CrossdeckError({
|
|
@@ -92,7 +97,7 @@ function typeMapForStatus(status) {
|
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
// src/_version.ts
|
|
95
|
-
var SDK_VERSION = "1.
|
|
100
|
+
var SDK_VERSION = "1.8.0";
|
|
96
101
|
var SDK_NAME = "@cross-deck/web";
|
|
97
102
|
|
|
98
103
|
// src/http.ts
|
|
@@ -932,6 +937,18 @@ var EventQueue = class {
|
|
|
932
937
|
this.cancelTimer = null;
|
|
933
938
|
this.firstFlushFired = false;
|
|
934
939
|
this.nextRetryAt = null;
|
|
940
|
+
/**
|
|
941
|
+
* PARK state (HTTP 426 / `sdk_version_unsupported`). Once parked, the
|
|
942
|
+
* queue stops flushing — the server has told us our wire dialect is too
|
|
943
|
+
* old, and retrying the same payload only burns the user's battery and
|
|
944
|
+
* bandwidth and drips pointless rejects into the server logs until the
|
|
945
|
+
* app ships an upgraded SDK. The held events stay durable (persisted)
|
|
946
|
+
* and are delivered by the next boot's rehydrate, post-upgrade. Parked
|
|
947
|
+
* is per-instance: a fresh boot (the upgraded build) starts unparked.
|
|
948
|
+
*/
|
|
949
|
+
this.parked = false;
|
|
950
|
+
/** One developer-facing console warning per instance — never per-event spam. */
|
|
951
|
+
this.parkWarned = false;
|
|
935
952
|
this.retry = new RetryPolicy(cfg.retry ?? {});
|
|
936
953
|
this.persistent = cfg.persistentStore ?? null;
|
|
937
954
|
if (this.persistent) {
|
|
@@ -987,6 +1004,7 @@ var EventQueue = class {
|
|
|
987
1004
|
* flushes (pagehide / visibilitychange→hidden / beforeunload).
|
|
988
1005
|
*/
|
|
989
1006
|
async flush(options = {}) {
|
|
1007
|
+
if (this.parked) return null;
|
|
990
1008
|
let batch;
|
|
991
1009
|
let batchId;
|
|
992
1010
|
if (this.pendingBatch !== null && this.pendingBatchId !== null) {
|
|
@@ -1038,6 +1056,29 @@ var EventQueue = class {
|
|
|
1038
1056
|
} catch (err) {
|
|
1039
1057
|
const message = err instanceof Error ? err.message : String(err);
|
|
1040
1058
|
this.lastError = message;
|
|
1059
|
+
if (isVersionRejected(err)) {
|
|
1060
|
+
this.parked = true;
|
|
1061
|
+
this.buffer = [...batch, ...this.buffer];
|
|
1062
|
+
if (this.buffer.length > HARD_BUFFER_CAP) {
|
|
1063
|
+
const overflow = this.buffer.length - HARD_BUFFER_CAP;
|
|
1064
|
+
this.buffer.splice(0, overflow);
|
|
1065
|
+
this.dropped += overflow;
|
|
1066
|
+
}
|
|
1067
|
+
this.pendingBatch = null;
|
|
1068
|
+
this.pendingBatchId = null;
|
|
1069
|
+
this.inFlight -= batch.length;
|
|
1070
|
+
this.persistAll();
|
|
1071
|
+
this.cfg.onBufferChange?.(this.buffer.length);
|
|
1072
|
+
const minVersion = versionRejectionFloor(err);
|
|
1073
|
+
if (!this.parkWarned) {
|
|
1074
|
+
this.parkWarned = true;
|
|
1075
|
+
console.warn(
|
|
1076
|
+
`[Crossdeck] SDK outdated \u2014 the server is no longer accepting this version's event format. Your events are PARKED on-device (held, not lost) and will deliver automatically once you update @cross-deck/web${minVersion ? ` to >= ${minVersion}` : ""} and redeploy.`
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1079
|
+
this.cfg.onParked?.({ minVersion, surface: versionRejectionSurface(err) });
|
|
1080
|
+
return null;
|
|
1081
|
+
}
|
|
1041
1082
|
if (isPermanent4xx(err)) {
|
|
1042
1083
|
const droppedCount = batch.length;
|
|
1043
1084
|
this.pendingBatch = null;
|
|
@@ -1156,8 +1197,22 @@ function isPermanent4xx(err) {
|
|
|
1156
1197
|
if (typeof status !== "number" || !Number.isFinite(status)) return false;
|
|
1157
1198
|
if (status < 400 || status >= 500) return false;
|
|
1158
1199
|
if (status === 408 || status === 429) return false;
|
|
1200
|
+
if (status === 426) return false;
|
|
1159
1201
|
return true;
|
|
1160
1202
|
}
|
|
1203
|
+
function isVersionRejected(err) {
|
|
1204
|
+
if (!err || typeof err !== "object") return false;
|
|
1205
|
+
if (err.status === 426) return true;
|
|
1206
|
+
return err.code === "sdk_version_unsupported";
|
|
1207
|
+
}
|
|
1208
|
+
function versionRejectionFloor(err) {
|
|
1209
|
+
const v = err?.minVersion;
|
|
1210
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
1211
|
+
}
|
|
1212
|
+
function versionRejectionSurface(err) {
|
|
1213
|
+
const v = err?.surface;
|
|
1214
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
1215
|
+
}
|
|
1161
1216
|
function defaultScheduler(fn, ms) {
|
|
1162
1217
|
const id = setTimeout(fn, ms);
|
|
1163
1218
|
if (typeof id.unref === "function") {
|
|
@@ -2898,6 +2953,13 @@ var CROSSDECK_ERROR_CODES = Object.freeze([
|
|
|
2898
2953
|
description: "A field is present but the value failed validation (wrong shape, wrong length, wrong enum value).",
|
|
2899
2954
|
resolution: "Read error.message for the specific field + reason. SDK-managed call sites should never emit this \u2014 file a bug if you do.",
|
|
2900
2955
|
retryable: false
|
|
2956
|
+
},
|
|
2957
|
+
{
|
|
2958
|
+
code: "sdk_version_unsupported",
|
|
2959
|
+
type: "version_error",
|
|
2960
|
+
description: "HTTP 426 \u2014 your installed SDK sends an event format the server no longer accepts. The data is good; only the wire dialect is too old. The SDK PARKS automatically: events are held on-device (paused, not lost) and deliver on the next launch after you upgrade.",
|
|
2961
|
+
resolution: "Update @cross-deck/web to at least the version in error.minVersion and redeploy \u2014 the parked queue backfills automatically. See https://cross-deck.com/docs/sdk-event-durability/.",
|
|
2962
|
+
retryable: false
|
|
2901
2963
|
}
|
|
2902
2964
|
]);
|
|
2903
2965
|
function getErrorCode(code) {
|
|
@@ -3443,7 +3505,8 @@ var BACKEND_WIRE_CODES = Object.freeze([
|
|
|
3443
3505
|
"google_not_supported",
|
|
3444
3506
|
"stripe_not_supported",
|
|
3445
3507
|
"missing_required_param",
|
|
3446
|
-
"invalid_param_value"
|
|
3508
|
+
"invalid_param_value",
|
|
3509
|
+
"sdk_version_unsupported"
|
|
3447
3510
|
]);
|
|
3448
3511
|
var VERIFIER_SDK_ERROR_CODES_CATALOGUE = {
|
|
3449
3512
|
contractId: "sdk-error-codes-catalogue",
|
|
@@ -4600,6 +4663,13 @@ var CrossdeckClient = class {
|
|
|
4600
4663
|
headline,
|
|
4601
4664
|
{ ...info }
|
|
4602
4665
|
);
|
|
4666
|
+
},
|
|
4667
|
+
onParked: (info) => {
|
|
4668
|
+
debug.emit(
|
|
4669
|
+
"sdk.parked",
|
|
4670
|
+
`[crossdeck] SDK parked \u2014 server no longer accepts this version's event format. Events held on-device (paused, not lost); update @cross-deck/web${info.minVersion ? ` to >= ${info.minVersion}` : ""} to resume.`,
|
|
4671
|
+
{ ...info }
|
|
4672
|
+
);
|
|
4603
4673
|
}
|
|
4604
4674
|
});
|
|
4605
4675
|
const deviceInfo = autoTrack.deviceInfo ? collectDeviceInfo({ appVersion: opts.appVersion ?? void 0 }) : opts.appVersion ? { appVersion: opts.appVersion } : {};
|