@cross-deck/web 1.7.0 → 1.9.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 +40 -0
- package/README.md +12 -6
- 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 +113 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +30 -5
- package/dist/index.d.ts +30 -5
- package/dist/index.mjs +113 -14
- package/dist/index.mjs.map +1 -1
- package/dist/react.cjs +102 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.mjs +102 -3
- package/dist/react.mjs.map +1 -1
- package/dist/vue.cjs +102 -3
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.mjs +102 -3
- package/dist/vue.mjs.map +1 -1
- package/package.json +3 -3
- package/dist/contracts.json +0 -546
package/dist/index.d.mts
CHANGED
|
@@ -247,9 +247,9 @@ declare const CrossdeckContracts: {
|
|
|
247
247
|
/** Filter by lifecycle status. */
|
|
248
248
|
readonly withStatus: (status: ContractStatus) => readonly Contract[];
|
|
249
249
|
/** Semver of the SDK release these contracts were bundled with. */
|
|
250
|
-
readonly sdkVersion: "1.
|
|
250
|
+
readonly sdkVersion: "1.8.0";
|
|
251
251
|
/** Fully-qualified bundle identifier — e.g. `@cross-deck/web@1.4.2`. */
|
|
252
|
-
readonly bundledIn: "@cross-deck/web@1.
|
|
252
|
+
readonly bundledIn: "@cross-deck/web@1.8.0";
|
|
253
253
|
/**
|
|
254
254
|
* Resolve a failing test back to the contract it exercises.
|
|
255
255
|
* Used by test-framework hooks (Vitest `afterEach`, XCTest
|
|
@@ -798,6 +798,21 @@ declare class CrossdeckClient {
|
|
|
798
798
|
* and not a per-device anon id.
|
|
799
799
|
*/
|
|
800
800
|
getCheckoutReference(): string;
|
|
801
|
+
/**
|
|
802
|
+
* The device-scoped anonymous id the SDK minted on first boot and persists
|
|
803
|
+
* across launches (stable until reset()). Public accessor so a server-to-
|
|
804
|
+
* server flow or a block/suspension gate can pass the device identity to
|
|
805
|
+
* POST /v1/resolve without reaching into private storage.
|
|
806
|
+
*
|
|
807
|
+
* Returns `null` BEFORE init() — there is no anon id yet, and a gate that
|
|
808
|
+
* fires during early app boot should get a clean falsy, not a throw. (This is
|
|
809
|
+
* deliberately softer than getCheckoutReference(), which requires init.)
|
|
810
|
+
*
|
|
811
|
+
* Note: /v1/resolve also accepts a VERIFIED identity (userId + idToken)
|
|
812
|
+
* without an anonymousId, and that path is higher-trust — prefer it where the
|
|
813
|
+
* user is authenticated.
|
|
814
|
+
*/
|
|
815
|
+
getAnonymousId(): string | null;
|
|
801
816
|
private requireStarted;
|
|
802
817
|
/**
|
|
803
818
|
* Build the identity query for /v1/entitlements. Priority:
|
|
@@ -843,7 +858,7 @@ declare const Crossdeck: CrossdeckClient;
|
|
|
843
858
|
* }
|
|
844
859
|
* }
|
|
845
860
|
*/
|
|
846
|
-
type CrossdeckErrorType = "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "internal_error" | "network_error" | "configuration_error";
|
|
861
|
+
type CrossdeckErrorType = "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "version_error" | "internal_error" | "network_error" | "configuration_error";
|
|
847
862
|
interface CrossdeckErrorPayload {
|
|
848
863
|
type: CrossdeckErrorType;
|
|
849
864
|
code: string;
|
|
@@ -860,6 +875,14 @@ interface CrossdeckErrorPayload {
|
|
|
860
875
|
* server is telling you the safe rate.
|
|
861
876
|
*/
|
|
862
877
|
retryAfterMs?: number;
|
|
878
|
+
/**
|
|
879
|
+
* Required SDK version floor — populated only on a `426 Upgrade Required`
|
|
880
|
+
* / `sdk_version_unsupported` response. The queue surfaces it in the
|
|
881
|
+
* "update to >= X" PARK message so the cure is exact.
|
|
882
|
+
*/
|
|
883
|
+
minVersion?: string;
|
|
884
|
+
/** SDK surface the rejection applies to (web/node/swift/…), on a 426. */
|
|
885
|
+
surface?: string;
|
|
863
886
|
}
|
|
864
887
|
declare class CrossdeckError extends Error {
|
|
865
888
|
readonly type: CrossdeckErrorType;
|
|
@@ -867,6 +890,8 @@ declare class CrossdeckError extends Error {
|
|
|
867
890
|
readonly requestId?: string;
|
|
868
891
|
readonly status?: number;
|
|
869
892
|
readonly retryAfterMs?: number;
|
|
893
|
+
readonly minVersion?: string;
|
|
894
|
+
readonly surface?: string;
|
|
870
895
|
constructor(payload: CrossdeckErrorPayload);
|
|
871
896
|
}
|
|
872
897
|
|
|
@@ -936,7 +961,7 @@ declare class MemoryStorage implements KeyValueStorage {
|
|
|
936
961
|
*
|
|
937
962
|
* Do NOT edit by hand — `node scripts/sync-sdk-versions.mjs`.
|
|
938
963
|
*/
|
|
939
|
-
declare const SDK_VERSION = "1.
|
|
964
|
+
declare const SDK_VERSION = "1.9.0";
|
|
940
965
|
declare const SDK_NAME = "@cross-deck/web";
|
|
941
966
|
|
|
942
967
|
/**
|
|
@@ -974,7 +999,7 @@ interface ErrorCodeEntry {
|
|
|
974
999
|
/** The string thrown as CrossdeckError.code. */
|
|
975
1000
|
code: string;
|
|
976
1001
|
/** CrossdeckError.type — broad category. */
|
|
977
|
-
type: "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "internal_error" | "network_error" | "configuration_error";
|
|
1002
|
+
type: "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "version_error" | "internal_error" | "network_error" | "configuration_error";
|
|
978
1003
|
/** One-sentence description. Surfaced verbatim in dashboards. */
|
|
979
1004
|
description: string;
|
|
980
1005
|
/** What the developer should do. Imperative phrasing. */
|
package/dist/index.d.ts
CHANGED
|
@@ -247,9 +247,9 @@ declare const CrossdeckContracts: {
|
|
|
247
247
|
/** Filter by lifecycle status. */
|
|
248
248
|
readonly withStatus: (status: ContractStatus) => readonly Contract[];
|
|
249
249
|
/** Semver of the SDK release these contracts were bundled with. */
|
|
250
|
-
readonly sdkVersion: "1.
|
|
250
|
+
readonly sdkVersion: "1.8.0";
|
|
251
251
|
/** Fully-qualified bundle identifier — e.g. `@cross-deck/web@1.4.2`. */
|
|
252
|
-
readonly bundledIn: "@cross-deck/web@1.
|
|
252
|
+
readonly bundledIn: "@cross-deck/web@1.8.0";
|
|
253
253
|
/**
|
|
254
254
|
* Resolve a failing test back to the contract it exercises.
|
|
255
255
|
* Used by test-framework hooks (Vitest `afterEach`, XCTest
|
|
@@ -798,6 +798,21 @@ declare class CrossdeckClient {
|
|
|
798
798
|
* and not a per-device anon id.
|
|
799
799
|
*/
|
|
800
800
|
getCheckoutReference(): string;
|
|
801
|
+
/**
|
|
802
|
+
* The device-scoped anonymous id the SDK minted on first boot and persists
|
|
803
|
+
* across launches (stable until reset()). Public accessor so a server-to-
|
|
804
|
+
* server flow or a block/suspension gate can pass the device identity to
|
|
805
|
+
* POST /v1/resolve without reaching into private storage.
|
|
806
|
+
*
|
|
807
|
+
* Returns `null` BEFORE init() — there is no anon id yet, and a gate that
|
|
808
|
+
* fires during early app boot should get a clean falsy, not a throw. (This is
|
|
809
|
+
* deliberately softer than getCheckoutReference(), which requires init.)
|
|
810
|
+
*
|
|
811
|
+
* Note: /v1/resolve also accepts a VERIFIED identity (userId + idToken)
|
|
812
|
+
* without an anonymousId, and that path is higher-trust — prefer it where the
|
|
813
|
+
* user is authenticated.
|
|
814
|
+
*/
|
|
815
|
+
getAnonymousId(): string | null;
|
|
801
816
|
private requireStarted;
|
|
802
817
|
/**
|
|
803
818
|
* Build the identity query for /v1/entitlements. Priority:
|
|
@@ -843,7 +858,7 @@ declare const Crossdeck: CrossdeckClient;
|
|
|
843
858
|
* }
|
|
844
859
|
* }
|
|
845
860
|
*/
|
|
846
|
-
type CrossdeckErrorType = "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "internal_error" | "network_error" | "configuration_error";
|
|
861
|
+
type CrossdeckErrorType = "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "version_error" | "internal_error" | "network_error" | "configuration_error";
|
|
847
862
|
interface CrossdeckErrorPayload {
|
|
848
863
|
type: CrossdeckErrorType;
|
|
849
864
|
code: string;
|
|
@@ -860,6 +875,14 @@ interface CrossdeckErrorPayload {
|
|
|
860
875
|
* server is telling you the safe rate.
|
|
861
876
|
*/
|
|
862
877
|
retryAfterMs?: number;
|
|
878
|
+
/**
|
|
879
|
+
* Required SDK version floor — populated only on a `426 Upgrade Required`
|
|
880
|
+
* / `sdk_version_unsupported` response. The queue surfaces it in the
|
|
881
|
+
* "update to >= X" PARK message so the cure is exact.
|
|
882
|
+
*/
|
|
883
|
+
minVersion?: string;
|
|
884
|
+
/** SDK surface the rejection applies to (web/node/swift/…), on a 426. */
|
|
885
|
+
surface?: string;
|
|
863
886
|
}
|
|
864
887
|
declare class CrossdeckError extends Error {
|
|
865
888
|
readonly type: CrossdeckErrorType;
|
|
@@ -867,6 +890,8 @@ declare class CrossdeckError extends Error {
|
|
|
867
890
|
readonly requestId?: string;
|
|
868
891
|
readonly status?: number;
|
|
869
892
|
readonly retryAfterMs?: number;
|
|
893
|
+
readonly minVersion?: string;
|
|
894
|
+
readonly surface?: string;
|
|
870
895
|
constructor(payload: CrossdeckErrorPayload);
|
|
871
896
|
}
|
|
872
897
|
|
|
@@ -936,7 +961,7 @@ declare class MemoryStorage implements KeyValueStorage {
|
|
|
936
961
|
*
|
|
937
962
|
* Do NOT edit by hand — `node scripts/sync-sdk-versions.mjs`.
|
|
938
963
|
*/
|
|
939
|
-
declare const SDK_VERSION = "1.
|
|
964
|
+
declare const SDK_VERSION = "1.9.0";
|
|
940
965
|
declare const SDK_NAME = "@cross-deck/web";
|
|
941
966
|
|
|
942
967
|
/**
|
|
@@ -974,7 +999,7 @@ interface ErrorCodeEntry {
|
|
|
974
999
|
/** The string thrown as CrossdeckError.code. */
|
|
975
1000
|
code: string;
|
|
976
1001
|
/** CrossdeckError.type — broad category. */
|
|
977
|
-
type: "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "internal_error" | "network_error" | "configuration_error";
|
|
1002
|
+
type: "authentication_error" | "permission_error" | "invalid_request_error" | "rate_limit_error" | "version_error" | "internal_error" | "network_error" | "configuration_error";
|
|
978
1003
|
/** One-sentence description. Surfaced verbatim in dashboards. */
|
|
979
1004
|
description: string;
|
|
980
1005
|
/** What the developer should do. Imperative phrasing. */
|
package/dist/index.mjs
CHANGED
|
@@ -8,6 +8,8 @@ var CrossdeckError = class _CrossdeckError extends Error {
|
|
|
8
8
|
this.requestId = payload.requestId;
|
|
9
9
|
this.status = payload.status;
|
|
10
10
|
this.retryAfterMs = payload.retryAfterMs;
|
|
11
|
+
this.minVersion = payload.minVersion;
|
|
12
|
+
this.surface = payload.surface;
|
|
11
13
|
Object.setPrototypeOf(this, _CrossdeckError.prototype);
|
|
12
14
|
}
|
|
13
15
|
};
|
|
@@ -28,7 +30,10 @@ async function crossdeckErrorFromResponse(res) {
|
|
|
28
30
|
message: envelope.message ?? `HTTP ${res.status}`,
|
|
29
31
|
requestId: envelope.request_id ?? requestId,
|
|
30
32
|
status: res.status,
|
|
31
|
-
retryAfterMs
|
|
33
|
+
retryAfterMs,
|
|
34
|
+
// PARK metadata, present only on a 426 / sdk_version_unsupported body.
|
|
35
|
+
minVersion: typeof envelope.minVersion === "string" ? envelope.minVersion : void 0,
|
|
36
|
+
surface: typeof envelope.surface === "string" ? envelope.surface : void 0
|
|
32
37
|
});
|
|
33
38
|
}
|
|
34
39
|
return new CrossdeckError({
|
|
@@ -64,7 +69,7 @@ function typeMapForStatus(status) {
|
|
|
64
69
|
}
|
|
65
70
|
|
|
66
71
|
// src/_version.ts
|
|
67
|
-
var SDK_VERSION = "1.
|
|
72
|
+
var SDK_VERSION = "1.9.0";
|
|
68
73
|
var SDK_NAME = "@cross-deck/web";
|
|
69
74
|
|
|
70
75
|
// src/http.ts
|
|
@@ -904,6 +909,18 @@ var EventQueue = class {
|
|
|
904
909
|
this.cancelTimer = null;
|
|
905
910
|
this.firstFlushFired = false;
|
|
906
911
|
this.nextRetryAt = null;
|
|
912
|
+
/**
|
|
913
|
+
* PARK state (HTTP 426 / `sdk_version_unsupported`). Once parked, the
|
|
914
|
+
* queue stops flushing — the server has told us our wire dialect is too
|
|
915
|
+
* old, and retrying the same payload only burns the user's battery and
|
|
916
|
+
* bandwidth and drips pointless rejects into the server logs until the
|
|
917
|
+
* app ships an upgraded SDK. The held events stay durable (persisted)
|
|
918
|
+
* and are delivered by the next boot's rehydrate, post-upgrade. Parked
|
|
919
|
+
* is per-instance: a fresh boot (the upgraded build) starts unparked.
|
|
920
|
+
*/
|
|
921
|
+
this.parked = false;
|
|
922
|
+
/** One developer-facing console warning per instance — never per-event spam. */
|
|
923
|
+
this.parkWarned = false;
|
|
907
924
|
this.retry = new RetryPolicy(cfg.retry ?? {});
|
|
908
925
|
this.persistent = cfg.persistentStore ?? null;
|
|
909
926
|
if (this.persistent) {
|
|
@@ -959,6 +976,7 @@ var EventQueue = class {
|
|
|
959
976
|
* flushes (pagehide / visibilitychange→hidden / beforeunload).
|
|
960
977
|
*/
|
|
961
978
|
async flush(options = {}) {
|
|
979
|
+
if (this.parked) return null;
|
|
962
980
|
let batch;
|
|
963
981
|
let batchId;
|
|
964
982
|
if (this.pendingBatch !== null && this.pendingBatchId !== null) {
|
|
@@ -1010,6 +1028,29 @@ var EventQueue = class {
|
|
|
1010
1028
|
} catch (err) {
|
|
1011
1029
|
const message = err instanceof Error ? err.message : String(err);
|
|
1012
1030
|
this.lastError = message;
|
|
1031
|
+
if (isVersionRejected(err)) {
|
|
1032
|
+
this.parked = true;
|
|
1033
|
+
this.buffer = [...batch, ...this.buffer];
|
|
1034
|
+
if (this.buffer.length > HARD_BUFFER_CAP) {
|
|
1035
|
+
const overflow = this.buffer.length - HARD_BUFFER_CAP;
|
|
1036
|
+
this.buffer.splice(0, overflow);
|
|
1037
|
+
this.dropped += overflow;
|
|
1038
|
+
}
|
|
1039
|
+
this.pendingBatch = null;
|
|
1040
|
+
this.pendingBatchId = null;
|
|
1041
|
+
this.inFlight -= batch.length;
|
|
1042
|
+
this.persistAll();
|
|
1043
|
+
this.cfg.onBufferChange?.(this.buffer.length);
|
|
1044
|
+
const minVersion = versionRejectionFloor(err);
|
|
1045
|
+
if (!this.parkWarned) {
|
|
1046
|
+
this.parkWarned = true;
|
|
1047
|
+
console.warn(
|
|
1048
|
+
`[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.`
|
|
1049
|
+
);
|
|
1050
|
+
}
|
|
1051
|
+
this.cfg.onParked?.({ minVersion, surface: versionRejectionSurface(err) });
|
|
1052
|
+
return null;
|
|
1053
|
+
}
|
|
1013
1054
|
if (isPermanent4xx(err)) {
|
|
1014
1055
|
const droppedCount = batch.length;
|
|
1015
1056
|
this.pendingBatch = null;
|
|
@@ -1128,8 +1169,22 @@ function isPermanent4xx(err) {
|
|
|
1128
1169
|
if (typeof status !== "number" || !Number.isFinite(status)) return false;
|
|
1129
1170
|
if (status < 400 || status >= 500) return false;
|
|
1130
1171
|
if (status === 408 || status === 429) return false;
|
|
1172
|
+
if (status === 426) return false;
|
|
1131
1173
|
return true;
|
|
1132
1174
|
}
|
|
1175
|
+
function isVersionRejected(err) {
|
|
1176
|
+
if (!err || typeof err !== "object") return false;
|
|
1177
|
+
if (err.status === 426) return true;
|
|
1178
|
+
return err.code === "sdk_version_unsupported";
|
|
1179
|
+
}
|
|
1180
|
+
function versionRejectionFloor(err) {
|
|
1181
|
+
const v = err?.minVersion;
|
|
1182
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
1183
|
+
}
|
|
1184
|
+
function versionRejectionSurface(err) {
|
|
1185
|
+
const v = err?.surface;
|
|
1186
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
1187
|
+
}
|
|
1133
1188
|
function defaultScheduler(fn, ms) {
|
|
1134
1189
|
const id = setTimeout(fn, ms);
|
|
1135
1190
|
if (typeof id.unref === "function") {
|
|
@@ -1315,6 +1370,16 @@ function hasDocument() {
|
|
|
1315
1370
|
return typeof globalThis.document !== "undefined";
|
|
1316
1371
|
}
|
|
1317
1372
|
|
|
1373
|
+
// src/read-cost-bridge.ts
|
|
1374
|
+
var BUCKETS_BRIDGE_KEY = "__crossdeckBucketsBridge__";
|
|
1375
|
+
function bridgeReadCost(ctx) {
|
|
1376
|
+
try {
|
|
1377
|
+
const setter = globalThis[BUCKETS_BRIDGE_KEY];
|
|
1378
|
+
if (typeof setter === "function") setter(ctx);
|
|
1379
|
+
} catch {
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1318
1383
|
// src/device-info.ts
|
|
1319
1384
|
function isBrowser() {
|
|
1320
1385
|
return typeof globalThis.window !== "undefined" && typeof globalThis.document !== "undefined" && typeof globalThis.navigator !== "undefined";
|
|
@@ -2870,6 +2935,13 @@ var CROSSDECK_ERROR_CODES = Object.freeze([
|
|
|
2870
2935
|
description: "A field is present but the value failed validation (wrong shape, wrong length, wrong enum value).",
|
|
2871
2936
|
resolution: "Read error.message for the specific field + reason. SDK-managed call sites should never emit this \u2014 file a bug if you do.",
|
|
2872
2937
|
retryable: false
|
|
2938
|
+
},
|
|
2939
|
+
{
|
|
2940
|
+
code: "sdk_version_unsupported",
|
|
2941
|
+
type: "version_error",
|
|
2942
|
+
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.",
|
|
2943
|
+
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/.",
|
|
2944
|
+
retryable: false
|
|
2873
2945
|
}
|
|
2874
2946
|
]);
|
|
2875
2947
|
function getErrorCode(code) {
|
|
@@ -3415,7 +3487,8 @@ var BACKEND_WIRE_CODES = Object.freeze([
|
|
|
3415
3487
|
"google_not_supported",
|
|
3416
3488
|
"stripe_not_supported",
|
|
3417
3489
|
"missing_required_param",
|
|
3418
|
-
"invalid_param_value"
|
|
3490
|
+
"invalid_param_value",
|
|
3491
|
+
"sdk_version_unsupported"
|
|
3419
3492
|
]);
|
|
3420
3493
|
var VERIFIER_SDK_ERROR_CODES_CATALOGUE = {
|
|
3421
3494
|
contractId: "sdk-error-codes-catalogue",
|
|
@@ -4572,6 +4645,13 @@ var CrossdeckClient = class {
|
|
|
4572
4645
|
headline,
|
|
4573
4646
|
{ ...info }
|
|
4574
4647
|
);
|
|
4648
|
+
},
|
|
4649
|
+
onParked: (info) => {
|
|
4650
|
+
debug.emit(
|
|
4651
|
+
"sdk.parked",
|
|
4652
|
+
`[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.`,
|
|
4653
|
+
{ ...info }
|
|
4654
|
+
);
|
|
4575
4655
|
}
|
|
4576
4656
|
});
|
|
4577
4657
|
const deviceInfo = autoTrack.deviceInfo ? collectDeviceInfo({ appVersion: opts.appVersion ?? void 0 }) : opts.appVersion ? { appVersion: opts.appVersion } : {};
|
|
@@ -4789,6 +4869,7 @@ var CrossdeckClient = class {
|
|
|
4789
4869
|
message: "identify(userId) requires a non-empty userId."
|
|
4790
4870
|
});
|
|
4791
4871
|
}
|
|
4872
|
+
bridgeReadCost({ actor: userId });
|
|
4792
4873
|
if (!s.consent.analytics) {
|
|
4793
4874
|
s.debug.emit(
|
|
4794
4875
|
"sdk.consent_denied",
|
|
@@ -5441,6 +5522,7 @@ var CrossdeckClient = class {
|
|
|
5441
5522
|
}
|
|
5442
5523
|
this.state.autoTracker?.uninstall();
|
|
5443
5524
|
this.state.identity.reset();
|
|
5525
|
+
bridgeReadCost({ actor: void 0 });
|
|
5444
5526
|
this.state.entitlements.clearAll();
|
|
5445
5527
|
this.state.events.reset();
|
|
5446
5528
|
this.state.superProps.clear();
|
|
@@ -5531,6 +5613,23 @@ var CrossdeckClient = class {
|
|
|
5531
5613
|
const s = this.requireStarted();
|
|
5532
5614
|
return s.identity.crossdeckCustomerId ?? s.developerUserId ?? s.identity.anonymousId;
|
|
5533
5615
|
}
|
|
5616
|
+
/**
|
|
5617
|
+
* The device-scoped anonymous id the SDK minted on first boot and persists
|
|
5618
|
+
* across launches (stable until reset()). Public accessor so a server-to-
|
|
5619
|
+
* server flow or a block/suspension gate can pass the device identity to
|
|
5620
|
+
* POST /v1/resolve without reaching into private storage.
|
|
5621
|
+
*
|
|
5622
|
+
* Returns `null` BEFORE init() — there is no anon id yet, and a gate that
|
|
5623
|
+
* fires during early app boot should get a clean falsy, not a throw. (This is
|
|
5624
|
+
* deliberately softer than getCheckoutReference(), which requires init.)
|
|
5625
|
+
*
|
|
5626
|
+
* Note: /v1/resolve also accepts a VERIFIED identity (userId + idToken)
|
|
5627
|
+
* without an anonymousId, and that path is higher-trust — prefer it where the
|
|
5628
|
+
* user is authenticated.
|
|
5629
|
+
*/
|
|
5630
|
+
getAnonymousId() {
|
|
5631
|
+
return this.state ? this.state.identity.anonymousId : null;
|
|
5632
|
+
}
|
|
5534
5633
|
// ---------- private helpers ----------
|
|
5535
5634
|
requireStarted() {
|
|
5536
5635
|
if (!this.state) {
|
|
@@ -5648,8 +5747,8 @@ function installUnloadFlush(onUnload) {
|
|
|
5648
5747
|
}
|
|
5649
5748
|
|
|
5650
5749
|
// src/_contracts-bundled.ts
|
|
5651
|
-
var BUNDLED_IN = "@cross-deck/web@1.
|
|
5652
|
-
var SDK_VERSION2 = "1.
|
|
5750
|
+
var BUNDLED_IN = "@cross-deck/web@1.8.0";
|
|
5751
|
+
var SDK_VERSION2 = "1.8.0";
|
|
5653
5752
|
var BUNDLED_CONTRACTS = Object.freeze([
|
|
5654
5753
|
{
|
|
5655
5754
|
"id": "contract-failed-payload-schema-lock",
|
|
@@ -5771,7 +5870,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
5771
5870
|
"legal/security/index.html#diagnostic",
|
|
5772
5871
|
"legal/sdk-data/index.html#b-diagnostic"
|
|
5773
5872
|
],
|
|
5774
|
-
"bundledIn": "@cross-deck/web@1.
|
|
5873
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
5775
5874
|
"runtimeVerified": true
|
|
5776
5875
|
},
|
|
5777
5876
|
{
|
|
@@ -5811,7 +5910,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
5811
5910
|
],
|
|
5812
5911
|
"registeredAt": "2026-05-26",
|
|
5813
5912
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 8 (codifies existing contract)",
|
|
5814
|
-
"bundledIn": "@cross-deck/web@1.
|
|
5913
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
5815
5914
|
"runtimeVerified": true
|
|
5816
5915
|
},
|
|
5817
5916
|
{
|
|
@@ -5857,7 +5956,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
5857
5956
|
],
|
|
5858
5957
|
"registeredAt": "2026-05-26",
|
|
5859
5958
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 3.3",
|
|
5860
|
-
"bundledIn": "@cross-deck/web@1.
|
|
5959
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
5861
5960
|
"runtimeVerified": true
|
|
5862
5961
|
},
|
|
5863
5962
|
{
|
|
@@ -5963,7 +6062,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
5963
6062
|
],
|
|
5964
6063
|
"registeredAt": "2026-05-26",
|
|
5965
6064
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 2.2.a + 2.2.b + 2.2.c",
|
|
5966
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6065
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
5967
6066
|
"runtimeVerified": true
|
|
5968
6067
|
},
|
|
5969
6068
|
{
|
|
@@ -5991,7 +6090,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
5991
6090
|
],
|
|
5992
6091
|
"registeredAt": "2026-05-26",
|
|
5993
6092
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 5.5",
|
|
5994
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6093
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
5995
6094
|
"runtimeVerified": false
|
|
5996
6095
|
},
|
|
5997
6096
|
{
|
|
@@ -6071,7 +6170,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
6071
6170
|
],
|
|
6072
6171
|
"registeredAt": "2026-05-26",
|
|
6073
6172
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 1.3 (web/RN) + dogfood-gap fix (swift + android)",
|
|
6074
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6173
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
6075
6174
|
"runtimeVerified": true
|
|
6076
6175
|
},
|
|
6077
6176
|
{
|
|
@@ -6117,7 +6216,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
6117
6216
|
],
|
|
6118
6217
|
"registeredAt": "2026-05-26",
|
|
6119
6218
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 6.2",
|
|
6120
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6219
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
6121
6220
|
"runtimeVerified": true
|
|
6122
6221
|
},
|
|
6123
6222
|
{
|
|
@@ -6159,7 +6258,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
6159
6258
|
],
|
|
6160
6259
|
"registeredAt": "2026-05-26",
|
|
6161
6260
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 3.2",
|
|
6162
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6261
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
6163
6262
|
"runtimeVerified": true
|
|
6164
6263
|
},
|
|
6165
6264
|
{
|
|
@@ -6193,7 +6292,7 @@ var BUNDLED_CONTRACTS = Object.freeze([
|
|
|
6193
6292
|
],
|
|
6194
6293
|
"registeredAt": "2026-05-26",
|
|
6195
6294
|
"firstRegisteredIn": "bank-grade reconciliation v1.4.0 \u2014 phase 3.5",
|
|
6196
|
-
"bundledIn": "@cross-deck/web@1.
|
|
6295
|
+
"bundledIn": "@cross-deck/web@1.8.0",
|
|
6197
6296
|
"runtimeVerified": false
|
|
6198
6297
|
}
|
|
6199
6298
|
]);
|