@shipeasy/sdk 2.1.11 → 2.1.13
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/dist/client/index.d.mts +12 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.js +18 -3
- package/dist/client/index.mjs +18 -3
- package/dist/server/index.js +10 -3
- package/dist/server/index.mjs +10 -3
- package/package.json +1 -1
package/dist/client/index.d.mts
CHANGED
|
@@ -48,6 +48,7 @@ declare class FlagsClientBrowser {
|
|
|
48
48
|
private guardrailsInstalled;
|
|
49
49
|
private listeners;
|
|
50
50
|
private overrideListenerInstalled;
|
|
51
|
+
private identifySeq;
|
|
51
52
|
private onOverrideChange;
|
|
52
53
|
constructor(opts: FlagsClientBrowserOptions);
|
|
53
54
|
identify(user: User): Promise<void>;
|
|
@@ -117,11 +118,22 @@ interface ShipeasyClientConfig {
|
|
|
117
118
|
baseUrl?: string;
|
|
118
119
|
/** Override the admin URL for the devtools overlay (dev use). */
|
|
119
120
|
adminUrl?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Skip the lazy auto-identify({}) at boot. Defaults to true (auto-identify on).
|
|
123
|
+
* Turn off when the host has its own identify orchestration and wants to
|
|
124
|
+
* avoid the initial anon /sdk/evaluate round-trip.
|
|
125
|
+
*/
|
|
126
|
+
autoIdentify?: boolean;
|
|
120
127
|
}
|
|
121
128
|
/**
|
|
122
129
|
* Initialise the ShipEasy client SDK and wire up lazy devtools.
|
|
123
130
|
* Call this once at app startup (e.g. in a useEffect in your root layout).
|
|
124
131
|
* Returns a cleanup function — call it on unmount to remove event listeners.
|
|
132
|
+
*
|
|
133
|
+
* Lazy-identifies the visitor under the hood with a stable anonId + auto-collected
|
|
134
|
+
* browser attrs (locale, timezone, path, screen, referrer, user_agent), so flags
|
|
135
|
+
* and experiments are warm without callers having to wire identify() manually.
|
|
136
|
+
* A later flags.identify({ user_id }) overrides this in place; anonId stays stable.
|
|
125
137
|
*/
|
|
126
138
|
declare function shipeasy(opts: ShipeasyClientConfig): () => void;
|
|
127
139
|
declare function configureShipeasy(opts: FlagsClientBrowserOptions): FlagsClientBrowser;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -48,6 +48,7 @@ declare class FlagsClientBrowser {
|
|
|
48
48
|
private guardrailsInstalled;
|
|
49
49
|
private listeners;
|
|
50
50
|
private overrideListenerInstalled;
|
|
51
|
+
private identifySeq;
|
|
51
52
|
private onOverrideChange;
|
|
52
53
|
constructor(opts: FlagsClientBrowserOptions);
|
|
53
54
|
identify(user: User): Promise<void>;
|
|
@@ -117,11 +118,22 @@ interface ShipeasyClientConfig {
|
|
|
117
118
|
baseUrl?: string;
|
|
118
119
|
/** Override the admin URL for the devtools overlay (dev use). */
|
|
119
120
|
adminUrl?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Skip the lazy auto-identify({}) at boot. Defaults to true (auto-identify on).
|
|
123
|
+
* Turn off when the host has its own identify orchestration and wants to
|
|
124
|
+
* avoid the initial anon /sdk/evaluate round-trip.
|
|
125
|
+
*/
|
|
126
|
+
autoIdentify?: boolean;
|
|
120
127
|
}
|
|
121
128
|
/**
|
|
122
129
|
* Initialise the ShipEasy client SDK and wire up lazy devtools.
|
|
123
130
|
* Call this once at app startup (e.g. in a useEffect in your root layout).
|
|
124
131
|
* Returns a cleanup function — call it on unmount to remove event listeners.
|
|
132
|
+
*
|
|
133
|
+
* Lazy-identifies the visitor under the hood with a stable anonId + auto-collected
|
|
134
|
+
* browser attrs (locale, timezone, path, screen, referrer, user_agent), so flags
|
|
135
|
+
* and experiments are warm without callers having to wire identify() manually.
|
|
136
|
+
* A later flags.identify({ user_id }) overrides this in place; anonId stays stable.
|
|
125
137
|
*/
|
|
126
138
|
declare function shipeasy(opts: ShipeasyClientConfig): () => void;
|
|
127
139
|
declare function configureShipeasy(opts: FlagsClientBrowserOptions): FlagsClientBrowser;
|
package/dist/client/index.js
CHANGED
|
@@ -399,6 +399,9 @@ var FlagsClientBrowser = class {
|
|
|
399
399
|
guardrailsInstalled = false;
|
|
400
400
|
listeners = /* @__PURE__ */ new Set();
|
|
401
401
|
overrideListenerInstalled = false;
|
|
402
|
+
// Monotonic counter so a later identify() always wins even if its /sdk/evaluate
|
|
403
|
+
// response races and lands before an earlier in-flight call's response.
|
|
404
|
+
identifySeq = 0;
|
|
402
405
|
onOverrideChange = () => {
|
|
403
406
|
this.installBridge();
|
|
404
407
|
this.notify();
|
|
@@ -413,8 +416,9 @@ var FlagsClientBrowser = class {
|
|
|
413
416
|
void this.buffer.flushPendingAlias();
|
|
414
417
|
}
|
|
415
418
|
async identify(user) {
|
|
419
|
+
const seq = ++this.identifySeq;
|
|
416
420
|
const prevUserId = this.userId;
|
|
417
|
-
this.userId = user.user_id
|
|
421
|
+
if (user.user_id !== void 0) this.userId = user.user_id;
|
|
418
422
|
if (this.anonId && this.userId && this.userId !== prevUserId) {
|
|
419
423
|
await this.buffer.alias(this.anonId, this.userId);
|
|
420
424
|
}
|
|
@@ -432,7 +436,9 @@ var FlagsClientBrowser = class {
|
|
|
432
436
|
})
|
|
433
437
|
});
|
|
434
438
|
if (!res.ok) throw new Error(`/sdk/evaluate returned ${res.status}`);
|
|
435
|
-
|
|
439
|
+
const data = await res.json();
|
|
440
|
+
if (seq !== this.identifySeq) return;
|
|
441
|
+
this.evalResult = data;
|
|
436
442
|
if (this.autoGuardrails && !this.guardrailsInstalled) {
|
|
437
443
|
this.guardrailsInstalled = true;
|
|
438
444
|
installAutoGuardrails(this.buffer, this.userId, this.anonId);
|
|
@@ -656,6 +662,11 @@ function shipeasy(opts) {
|
|
|
656
662
|
baseUrl: opts.baseUrl ?? "https://cdn.shipeasy.ai"
|
|
657
663
|
});
|
|
658
664
|
flags.notifyMounted();
|
|
665
|
+
if (opts.autoIdentify !== false) {
|
|
666
|
+
void client.identify({}).catch((err) => {
|
|
667
|
+
console.warn("[shipeasy] auto-identify failed:", String(err));
|
|
668
|
+
});
|
|
669
|
+
}
|
|
659
670
|
return attachDevtools(client, { adminUrl: opts.adminUrl });
|
|
660
671
|
}
|
|
661
672
|
function configureShipeasy(opts) {
|
|
@@ -791,12 +802,16 @@ var _EDIT_MODE_SSR_SYM = /* @__PURE__ */ Symbol.for("@shipeasy/sdk:ssr-edit-mode
|
|
|
791
802
|
function getSSRI18nStore() {
|
|
792
803
|
return globalThis[_I18N_SSR_SYM]?.() ?? null;
|
|
793
804
|
}
|
|
805
|
+
var _EDIT_MODE_FALLBACK_SYM = /* @__PURE__ */ Symbol.for("@shipeasy/sdk:ssr-edit-mode-fallback");
|
|
794
806
|
function isEditLabelsMode() {
|
|
795
807
|
if (typeof window !== "undefined") {
|
|
796
808
|
return !!window.__SE_BOOTSTRAP?.editLabels || new URLSearchParams(location.search).has("se_edit_labels");
|
|
797
809
|
}
|
|
798
810
|
const val = globalThis[_EDIT_MODE_SSR_SYM];
|
|
799
|
-
|
|
811
|
+
if (typeof val === "boolean") return val;
|
|
812
|
+
if (typeof val === "function") return val();
|
|
813
|
+
const fb = globalThis[_EDIT_MODE_FALLBACK_SYM];
|
|
814
|
+
return typeof fb === "boolean" ? fb : false;
|
|
800
815
|
}
|
|
801
816
|
function interpolate(raw, variables) {
|
|
802
817
|
if (!variables) return raw;
|
package/dist/client/index.mjs
CHANGED
|
@@ -356,6 +356,9 @@ var FlagsClientBrowser = class {
|
|
|
356
356
|
guardrailsInstalled = false;
|
|
357
357
|
listeners = /* @__PURE__ */ new Set();
|
|
358
358
|
overrideListenerInstalled = false;
|
|
359
|
+
// Monotonic counter so a later identify() always wins even if its /sdk/evaluate
|
|
360
|
+
// response races and lands before an earlier in-flight call's response.
|
|
361
|
+
identifySeq = 0;
|
|
359
362
|
onOverrideChange = () => {
|
|
360
363
|
this.installBridge();
|
|
361
364
|
this.notify();
|
|
@@ -370,8 +373,9 @@ var FlagsClientBrowser = class {
|
|
|
370
373
|
void this.buffer.flushPendingAlias();
|
|
371
374
|
}
|
|
372
375
|
async identify(user) {
|
|
376
|
+
const seq = ++this.identifySeq;
|
|
373
377
|
const prevUserId = this.userId;
|
|
374
|
-
this.userId = user.user_id
|
|
378
|
+
if (user.user_id !== void 0) this.userId = user.user_id;
|
|
375
379
|
if (this.anonId && this.userId && this.userId !== prevUserId) {
|
|
376
380
|
await this.buffer.alias(this.anonId, this.userId);
|
|
377
381
|
}
|
|
@@ -389,7 +393,9 @@ var FlagsClientBrowser = class {
|
|
|
389
393
|
})
|
|
390
394
|
});
|
|
391
395
|
if (!res.ok) throw new Error(`/sdk/evaluate returned ${res.status}`);
|
|
392
|
-
|
|
396
|
+
const data = await res.json();
|
|
397
|
+
if (seq !== this.identifySeq) return;
|
|
398
|
+
this.evalResult = data;
|
|
393
399
|
if (this.autoGuardrails && !this.guardrailsInstalled) {
|
|
394
400
|
this.guardrailsInstalled = true;
|
|
395
401
|
installAutoGuardrails(this.buffer, this.userId, this.anonId);
|
|
@@ -613,6 +619,11 @@ function shipeasy(opts) {
|
|
|
613
619
|
baseUrl: opts.baseUrl ?? "https://cdn.shipeasy.ai"
|
|
614
620
|
});
|
|
615
621
|
flags.notifyMounted();
|
|
622
|
+
if (opts.autoIdentify !== false) {
|
|
623
|
+
void client.identify({}).catch((err) => {
|
|
624
|
+
console.warn("[shipeasy] auto-identify failed:", String(err));
|
|
625
|
+
});
|
|
626
|
+
}
|
|
616
627
|
return attachDevtools(client, { adminUrl: opts.adminUrl });
|
|
617
628
|
}
|
|
618
629
|
function configureShipeasy(opts) {
|
|
@@ -748,12 +759,16 @@ var _EDIT_MODE_SSR_SYM = /* @__PURE__ */ Symbol.for("@shipeasy/sdk:ssr-edit-mode
|
|
|
748
759
|
function getSSRI18nStore() {
|
|
749
760
|
return globalThis[_I18N_SSR_SYM]?.() ?? null;
|
|
750
761
|
}
|
|
762
|
+
var _EDIT_MODE_FALLBACK_SYM = /* @__PURE__ */ Symbol.for("@shipeasy/sdk:ssr-edit-mode-fallback");
|
|
751
763
|
function isEditLabelsMode() {
|
|
752
764
|
if (typeof window !== "undefined") {
|
|
753
765
|
return !!window.__SE_BOOTSTRAP?.editLabels || new URLSearchParams(location.search).has("se_edit_labels");
|
|
754
766
|
}
|
|
755
767
|
const val = globalThis[_EDIT_MODE_SSR_SYM];
|
|
756
|
-
|
|
768
|
+
if (typeof val === "boolean") return val;
|
|
769
|
+
if (typeof val === "function") return val();
|
|
770
|
+
const fb = globalThis[_EDIT_MODE_FALLBACK_SYM];
|
|
771
|
+
return typeof fb === "boolean" ? fb : false;
|
|
757
772
|
}
|
|
758
773
|
function interpolate(raw, variables) {
|
|
759
774
|
if (!variables) return raw;
|
package/dist/server/index.js
CHANGED
|
@@ -493,10 +493,17 @@ async function shipeasy(opts) {
|
|
|
493
493
|
let resolvedUrlOverrides = opts.urlOverrides;
|
|
494
494
|
if (!resolvedUrlOverrides) {
|
|
495
495
|
try {
|
|
496
|
-
const { headers } = await import("next/headers");
|
|
496
|
+
const { headers, cookies } = await import("next/headers");
|
|
497
497
|
const h = await Promise.resolve(headers());
|
|
498
498
|
const search = h.get("x-se-search") ?? "";
|
|
499
|
-
if (search)
|
|
499
|
+
if (search) {
|
|
500
|
+
resolvedUrlOverrides = search;
|
|
501
|
+
} else {
|
|
502
|
+
const c = await Promise.resolve(cookies());
|
|
503
|
+
if (c.get?.("se_edit_labels")?.value === "1") {
|
|
504
|
+
resolvedUrlOverrides = "se_edit_labels=1";
|
|
505
|
+
}
|
|
506
|
+
}
|
|
500
507
|
} catch {
|
|
501
508
|
}
|
|
502
509
|
}
|
|
@@ -532,7 +539,7 @@ function getBootstrapHtml(bootstrap, i18nData, opts) {
|
|
|
532
539
|
if (i18nData) payload.i18n = i18nData;
|
|
533
540
|
if (opts.editLabels) payload.editLabels = true;
|
|
534
541
|
parts.push(
|
|
535
|
-
`(function(){if(!new URLSearchParams(location.search).has('se_edit_labels'))return;var R;function P(v){if(!v||typeof v.t!=='function'||v.__sePatched)return;var O=v.t.bind(v);v.__sePatched=true;window._sei18n_t=O;v.t=function(k,vars){var r=O(k,vars);if(r===k)return k;var V='';try{if(vars&&typeof vars==='object'){var hasKey=false;for(var _k in vars){hasKey=true;break;}if(hasKey)V=JSON.stringify(vars);}}catch(_){V='';}return '\\uFFF9'+k+'\\uFFFA'+V+'\\uFFFA'+r+'\\uFFFB';};}Object.defineProperty(window,'i18n',{configurable:true,get:function(){return R;},set:function(v){P(v);R=v;}});})();`
|
|
542
|
+
`(function(){if(!new URLSearchParams(location.search).has('se_edit_labels'))return;try{document.cookie='se_edit_labels=1;path=/;max-age=86400;samesite=lax';}catch(_){}var R;function P(v){if(!v||typeof v.t!=='function'||v.__sePatched)return;var O=v.t.bind(v);v.__sePatched=true;window._sei18n_t=O;v.t=function(k,vars){var r=O(k,vars);if(r===k)return k;var V='';try{if(vars&&typeof vars==='object'){var hasKey=false;for(var _k in vars){hasKey=true;break;}if(hasKey)V=JSON.stringify(vars);}}catch(_){V='';}return '\\uFFF9'+k+'\\uFFFA'+V+'\\uFFFA'+r+'\\uFFFB';};}Object.defineProperty(window,'i18n',{configurable:true,get:function(){return R;},set:function(v){P(v);R=v;}});})();`
|
|
536
543
|
);
|
|
537
544
|
parts.push(`window.__SE_BOOTSTRAP=${JSON.stringify(payload)};`);
|
|
538
545
|
if (i18nData?.strings && Object.keys(i18nData.strings).length > 0) {
|
package/dist/server/index.mjs
CHANGED
|
@@ -450,10 +450,17 @@ async function shipeasy(opts) {
|
|
|
450
450
|
let resolvedUrlOverrides = opts.urlOverrides;
|
|
451
451
|
if (!resolvedUrlOverrides) {
|
|
452
452
|
try {
|
|
453
|
-
const { headers } = await import("next/headers");
|
|
453
|
+
const { headers, cookies } = await import("next/headers");
|
|
454
454
|
const h = await Promise.resolve(headers());
|
|
455
455
|
const search = h.get("x-se-search") ?? "";
|
|
456
|
-
if (search)
|
|
456
|
+
if (search) {
|
|
457
|
+
resolvedUrlOverrides = search;
|
|
458
|
+
} else {
|
|
459
|
+
const c = await Promise.resolve(cookies());
|
|
460
|
+
if (c.get?.("se_edit_labels")?.value === "1") {
|
|
461
|
+
resolvedUrlOverrides = "se_edit_labels=1";
|
|
462
|
+
}
|
|
463
|
+
}
|
|
457
464
|
} catch {
|
|
458
465
|
}
|
|
459
466
|
}
|
|
@@ -489,7 +496,7 @@ function getBootstrapHtml(bootstrap, i18nData, opts) {
|
|
|
489
496
|
if (i18nData) payload.i18n = i18nData;
|
|
490
497
|
if (opts.editLabels) payload.editLabels = true;
|
|
491
498
|
parts.push(
|
|
492
|
-
`(function(){if(!new URLSearchParams(location.search).has('se_edit_labels'))return;var R;function P(v){if(!v||typeof v.t!=='function'||v.__sePatched)return;var O=v.t.bind(v);v.__sePatched=true;window._sei18n_t=O;v.t=function(k,vars){var r=O(k,vars);if(r===k)return k;var V='';try{if(vars&&typeof vars==='object'){var hasKey=false;for(var _k in vars){hasKey=true;break;}if(hasKey)V=JSON.stringify(vars);}}catch(_){V='';}return '\\uFFF9'+k+'\\uFFFA'+V+'\\uFFFA'+r+'\\uFFFB';};}Object.defineProperty(window,'i18n',{configurable:true,get:function(){return R;},set:function(v){P(v);R=v;}});})();`
|
|
499
|
+
`(function(){if(!new URLSearchParams(location.search).has('se_edit_labels'))return;try{document.cookie='se_edit_labels=1;path=/;max-age=86400;samesite=lax';}catch(_){}var R;function P(v){if(!v||typeof v.t!=='function'||v.__sePatched)return;var O=v.t.bind(v);v.__sePatched=true;window._sei18n_t=O;v.t=function(k,vars){var r=O(k,vars);if(r===k)return k;var V='';try{if(vars&&typeof vars==='object'){var hasKey=false;for(var _k in vars){hasKey=true;break;}if(hasKey)V=JSON.stringify(vars);}}catch(_){V='';}return '\\uFFF9'+k+'\\uFFFA'+V+'\\uFFFA'+r+'\\uFFFB';};}Object.defineProperty(window,'i18n',{configurable:true,get:function(){return R;},set:function(v){P(v);R=v;}});})();`
|
|
493
500
|
);
|
|
494
501
|
parts.push(`window.__SE_BOOTSTRAP=${JSON.stringify(payload)};`);
|
|
495
502
|
if (i18nData?.strings && Object.keys(i18nData.strings).length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipeasy/sdk",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.13",
|
|
4
4
|
"description": "Shipeasy SDK — feature gates, runtime configs, experiments, and metrics for the Shipeasy hosted service.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://shipeasy.ai",
|