@shipeasy/sdk 2.0.0 → 2.0.1
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 +17 -8
- package/dist/client/index.d.ts +17 -8
- package/dist/client/index.js +49 -31
- package/dist/client/index.mjs +49 -31
- package/package.json +1 -1
package/dist/client/index.d.mts
CHANGED
|
@@ -126,12 +126,21 @@ declare function _resetShipeasyForTests(): void;
|
|
|
126
126
|
declare const flags: {
|
|
127
127
|
configure(opts: FlagsClientBrowserOptions): void;
|
|
128
128
|
identify(user: User): Promise<void>;
|
|
129
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Read a feature gate. Returns false until FlagsBoundary mounts (SSR-safe).
|
|
131
|
+
* After mount, URL overrides (?se_ks_*) apply even without a configured client.
|
|
132
|
+
*/
|
|
130
133
|
get(name: string): boolean;
|
|
131
134
|
getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
|
|
132
135
|
getExperiment<P extends Record<string, unknown>>(name: string, defaultParams: P, decode?: (raw: unknown) => P, variants?: Record<string, Partial<P>>): ExperimentResult<P>;
|
|
133
136
|
track(eventName: string, props?: Record<string, unknown>): void;
|
|
134
137
|
flush(): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Called by FlagsBoundary after React hydration to unlock flag reads.
|
|
140
|
+
* Dispatches se:override:change so subscribers (FlagsBoundary) re-render
|
|
141
|
+
* once with real values — URL overrides and server-evaluated flags.
|
|
142
|
+
*/
|
|
143
|
+
notifyMounted(): void;
|
|
135
144
|
/** Subscribe for change notifications (identify/override). Used by framework adapters. */
|
|
136
145
|
subscribe(listener: () => void): () => void;
|
|
137
146
|
/** True once identify() has completed and flags are available. */
|
|
@@ -148,14 +157,14 @@ interface LabelAttrs {
|
|
|
148
157
|
"data-label-desc"?: string;
|
|
149
158
|
}
|
|
150
159
|
declare function labelAttrs(key: string, variables?: Record<string, string | number>, desc?: string): LabelAttrs;
|
|
160
|
+
/**
|
|
161
|
+
* Universal i18n facade. Backed by the `window.i18n` global the loader
|
|
162
|
+
* script installs. Returns the key itself when the loader hasn't run
|
|
163
|
+
* (SSR, missing script tag, before profile fetch completes), so call
|
|
164
|
+
* sites never need to null-check.
|
|
165
|
+
*/
|
|
151
166
|
declare const i18n: {
|
|
152
|
-
|
|
153
|
-
* Look up `key` in the active translation profile. When the profile
|
|
154
|
-
* hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
|
|
155
|
-
* `fallback` instead — `fallback` is the source-of-truth English copy
|
|
156
|
-
* and is mandatory so the page never renders a raw key.
|
|
157
|
-
*/
|
|
158
|
-
t(key: string, fallback: string, variables?: Record<string, string | number>): string;
|
|
167
|
+
t(key: string, variables?: Record<string, string | number>): string;
|
|
159
168
|
/**
|
|
160
169
|
* Translate a key and return a framework element (e.g. React <span>)
|
|
161
170
|
* carrying `data-label` / `data-variables` attributes so the ShipEasy
|
package/dist/client/index.d.ts
CHANGED
|
@@ -126,12 +126,21 @@ declare function _resetShipeasyForTests(): void;
|
|
|
126
126
|
declare const flags: {
|
|
127
127
|
configure(opts: FlagsClientBrowserOptions): void;
|
|
128
128
|
identify(user: User): Promise<void>;
|
|
129
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Read a feature gate. Returns false until FlagsBoundary mounts (SSR-safe).
|
|
131
|
+
* After mount, URL overrides (?se_ks_*) apply even without a configured client.
|
|
132
|
+
*/
|
|
130
133
|
get(name: string): boolean;
|
|
131
134
|
getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
|
|
132
135
|
getExperiment<P extends Record<string, unknown>>(name: string, defaultParams: P, decode?: (raw: unknown) => P, variants?: Record<string, Partial<P>>): ExperimentResult<P>;
|
|
133
136
|
track(eventName: string, props?: Record<string, unknown>): void;
|
|
134
137
|
flush(): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Called by FlagsBoundary after React hydration to unlock flag reads.
|
|
140
|
+
* Dispatches se:override:change so subscribers (FlagsBoundary) re-render
|
|
141
|
+
* once with real values — URL overrides and server-evaluated flags.
|
|
142
|
+
*/
|
|
143
|
+
notifyMounted(): void;
|
|
135
144
|
/** Subscribe for change notifications (identify/override). Used by framework adapters. */
|
|
136
145
|
subscribe(listener: () => void): () => void;
|
|
137
146
|
/** True once identify() has completed and flags are available. */
|
|
@@ -148,14 +157,14 @@ interface LabelAttrs {
|
|
|
148
157
|
"data-label-desc"?: string;
|
|
149
158
|
}
|
|
150
159
|
declare function labelAttrs(key: string, variables?: Record<string, string | number>, desc?: string): LabelAttrs;
|
|
160
|
+
/**
|
|
161
|
+
* Universal i18n facade. Backed by the `window.i18n` global the loader
|
|
162
|
+
* script installs. Returns the key itself when the loader hasn't run
|
|
163
|
+
* (SSR, missing script tag, before profile fetch completes), so call
|
|
164
|
+
* sites never need to null-check.
|
|
165
|
+
*/
|
|
151
166
|
declare const i18n: {
|
|
152
|
-
|
|
153
|
-
* Look up `key` in the active translation profile. When the profile
|
|
154
|
-
* hasn't been fetched yet (SSR, CDN downtime, missing key), interpolate
|
|
155
|
-
* `fallback` instead — `fallback` is the source-of-truth English copy
|
|
156
|
-
* and is mandatory so the page never renders a raw key.
|
|
157
|
-
*/
|
|
158
|
-
t(key: string, fallback: string, variables?: Record<string, string | number>): string;
|
|
167
|
+
t(key: string, variables?: Record<string, string | number>): string;
|
|
159
168
|
/**
|
|
160
169
|
* Translate a key and return a framework element (e.g. React <span>)
|
|
161
170
|
* carrying `data-label` / `data-variables` attributes so the ShipEasy
|
package/dist/client/index.js
CHANGED
|
@@ -454,15 +454,13 @@ var FlagsClientBrowser = class {
|
|
|
454
454
|
this.evalResult = data;
|
|
455
455
|
}
|
|
456
456
|
getFlag(name) {
|
|
457
|
-
if (this.evalResult === null) return false;
|
|
458
457
|
const ov = readGateOverride(name);
|
|
459
458
|
if (ov !== null) return ov;
|
|
460
|
-
return this.evalResult
|
|
459
|
+
return this.evalResult?.flags[name] ?? false;
|
|
461
460
|
}
|
|
462
461
|
getConfig(name, decode) {
|
|
463
|
-
if (this.evalResult === null) return void 0;
|
|
464
462
|
const ov = readConfigOverride(name);
|
|
465
|
-
const raw = ov !== void 0 ? ov : this.evalResult
|
|
463
|
+
const raw = ov !== void 0 ? ov : this.evalResult?.configs?.[name];
|
|
466
464
|
if (raw === void 0) return void 0;
|
|
467
465
|
if (!decode) return raw;
|
|
468
466
|
try {
|
|
@@ -661,6 +659,16 @@ function _resetShipeasyForTests() {
|
|
|
661
659
|
_client?.destroy();
|
|
662
660
|
_client = null;
|
|
663
661
|
}
|
|
662
|
+
var _mountedAndReady = false;
|
|
663
|
+
var _standaloneListeners = /* @__PURE__ */ new Set();
|
|
664
|
+
var _standaloneOverrideWired = false;
|
|
665
|
+
function wireStandaloneOverride() {
|
|
666
|
+
if (_standaloneOverrideWired || typeof window === "undefined") return;
|
|
667
|
+
_standaloneOverrideWired = true;
|
|
668
|
+
window.addEventListener("se:override:change", () => {
|
|
669
|
+
for (const cb of _standaloneListeners) cb();
|
|
670
|
+
});
|
|
671
|
+
}
|
|
664
672
|
var flags = {
|
|
665
673
|
configure(opts) {
|
|
666
674
|
configureShipeasy(opts);
|
|
@@ -672,12 +680,26 @@ var flags = {
|
|
|
672
680
|
}
|
|
673
681
|
return _client.identify(user);
|
|
674
682
|
},
|
|
675
|
-
/**
|
|
683
|
+
/**
|
|
684
|
+
* Read a feature gate. Returns false until FlagsBoundary mounts (SSR-safe).
|
|
685
|
+
* After mount, URL overrides (?se_ks_*) apply even without a configured client.
|
|
686
|
+
*/
|
|
676
687
|
get(name) {
|
|
677
|
-
|
|
688
|
+
if (!_mountedAndReady) return false;
|
|
689
|
+
if (_client) return _client.getFlag(name);
|
|
690
|
+
return readGateOverride(name) ?? false;
|
|
678
691
|
},
|
|
679
692
|
getConfig(name, decode) {
|
|
680
|
-
|
|
693
|
+
if (!_mountedAndReady) return void 0;
|
|
694
|
+
if (_client) return _client.getConfig(name, decode);
|
|
695
|
+
const ov = readConfigOverride(name);
|
|
696
|
+
if (ov === void 0) return void 0;
|
|
697
|
+
if (!decode) return ov;
|
|
698
|
+
try {
|
|
699
|
+
return decode(ov);
|
|
700
|
+
} catch {
|
|
701
|
+
return void 0;
|
|
702
|
+
}
|
|
681
703
|
},
|
|
682
704
|
getExperiment(name, defaultParams, decode, variants) {
|
|
683
705
|
return _client?.getExperiment(name, defaultParams, decode, variants) ?? {
|
|
@@ -692,11 +714,24 @@ var flags = {
|
|
|
692
714
|
flush() {
|
|
693
715
|
return _client?.flush() ?? Promise.resolve();
|
|
694
716
|
},
|
|
717
|
+
/**
|
|
718
|
+
* Called by FlagsBoundary after React hydration to unlock flag reads.
|
|
719
|
+
* Dispatches se:override:change so subscribers (FlagsBoundary) re-render
|
|
720
|
+
* once with real values — URL overrides and server-evaluated flags.
|
|
721
|
+
*/
|
|
722
|
+
notifyMounted() {
|
|
723
|
+
if (_mountedAndReady) return;
|
|
724
|
+
_mountedAndReady = true;
|
|
725
|
+
if (typeof window !== "undefined") {
|
|
726
|
+
window.dispatchEvent(new CustomEvent("se:override:change"));
|
|
727
|
+
}
|
|
728
|
+
},
|
|
695
729
|
/** Subscribe for change notifications (identify/override). Used by framework adapters. */
|
|
696
730
|
subscribe(listener) {
|
|
697
|
-
if (
|
|
698
|
-
|
|
699
|
-
|
|
731
|
+
if (_client) return _client.subscribe(listener);
|
|
732
|
+
_standaloneListeners.add(listener);
|
|
733
|
+
wireStandaloneOverride();
|
|
734
|
+
return () => _standaloneListeners.delete(listener);
|
|
700
735
|
},
|
|
701
736
|
/** True once identify() has completed and flags are available. */
|
|
702
737
|
get ready() {
|
|
@@ -717,27 +752,10 @@ function labelAttrs(key, variables, desc) {
|
|
|
717
752
|
return attrs;
|
|
718
753
|
}
|
|
719
754
|
var _createElement = null;
|
|
720
|
-
function interpolate(template, variables) {
|
|
721
|
-
if (!variables) return template;
|
|
722
|
-
let out = template;
|
|
723
|
-
for (const name of Object.keys(variables)) {
|
|
724
|
-
out = out.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), String(variables[name]));
|
|
725
|
-
}
|
|
726
|
-
return out;
|
|
727
|
-
}
|
|
728
755
|
var i18n = {
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
* `fallback` instead — `fallback` is the source-of-truth English copy
|
|
733
|
-
* and is mandatory so the page never renders a raw key.
|
|
734
|
-
*/
|
|
735
|
-
t(key, fallback, variables) {
|
|
736
|
-
if (typeof window !== "undefined" && window.i18n) {
|
|
737
|
-
const v = window.i18n.t(key, variables);
|
|
738
|
-
if (v !== key) return v;
|
|
739
|
-
}
|
|
740
|
-
return interpolate(fallback, variables);
|
|
756
|
+
t(key, variables) {
|
|
757
|
+
if (typeof window !== "undefined" && window.i18n) return window.i18n.t(key, variables);
|
|
758
|
+
return key;
|
|
741
759
|
},
|
|
742
760
|
/**
|
|
743
761
|
* Translate a key and return a framework element (e.g. React <span>)
|
|
@@ -752,7 +770,7 @@ var i18n = {
|
|
|
752
770
|
* configured (e.g. server-side or in non-JSX contexts).
|
|
753
771
|
*/
|
|
754
772
|
tEl(key, fallback, variables, desc) {
|
|
755
|
-
const text = this.t(key,
|
|
773
|
+
const text = this.t(key, variables) || fallback;
|
|
756
774
|
if (!_createElement) return text;
|
|
757
775
|
return _createElement("span", labelAttrs(key, variables, desc), text);
|
|
758
776
|
},
|
package/dist/client/index.mjs
CHANGED
|
@@ -412,15 +412,13 @@ var FlagsClientBrowser = class {
|
|
|
412
412
|
this.evalResult = data;
|
|
413
413
|
}
|
|
414
414
|
getFlag(name) {
|
|
415
|
-
if (this.evalResult === null) return false;
|
|
416
415
|
const ov = readGateOverride(name);
|
|
417
416
|
if (ov !== null) return ov;
|
|
418
|
-
return this.evalResult
|
|
417
|
+
return this.evalResult?.flags[name] ?? false;
|
|
419
418
|
}
|
|
420
419
|
getConfig(name, decode) {
|
|
421
|
-
if (this.evalResult === null) return void 0;
|
|
422
420
|
const ov = readConfigOverride(name);
|
|
423
|
-
const raw = ov !== void 0 ? ov : this.evalResult
|
|
421
|
+
const raw = ov !== void 0 ? ov : this.evalResult?.configs?.[name];
|
|
424
422
|
if (raw === void 0) return void 0;
|
|
425
423
|
if (!decode) return raw;
|
|
426
424
|
try {
|
|
@@ -619,6 +617,16 @@ function _resetShipeasyForTests() {
|
|
|
619
617
|
_client?.destroy();
|
|
620
618
|
_client = null;
|
|
621
619
|
}
|
|
620
|
+
var _mountedAndReady = false;
|
|
621
|
+
var _standaloneListeners = /* @__PURE__ */ new Set();
|
|
622
|
+
var _standaloneOverrideWired = false;
|
|
623
|
+
function wireStandaloneOverride() {
|
|
624
|
+
if (_standaloneOverrideWired || typeof window === "undefined") return;
|
|
625
|
+
_standaloneOverrideWired = true;
|
|
626
|
+
window.addEventListener("se:override:change", () => {
|
|
627
|
+
for (const cb of _standaloneListeners) cb();
|
|
628
|
+
});
|
|
629
|
+
}
|
|
622
630
|
var flags = {
|
|
623
631
|
configure(opts) {
|
|
624
632
|
configureShipeasy(opts);
|
|
@@ -630,12 +638,26 @@ var flags = {
|
|
|
630
638
|
}
|
|
631
639
|
return _client.identify(user);
|
|
632
640
|
},
|
|
633
|
-
/**
|
|
641
|
+
/**
|
|
642
|
+
* Read a feature gate. Returns false until FlagsBoundary mounts (SSR-safe).
|
|
643
|
+
* After mount, URL overrides (?se_ks_*) apply even without a configured client.
|
|
644
|
+
*/
|
|
634
645
|
get(name) {
|
|
635
|
-
|
|
646
|
+
if (!_mountedAndReady) return false;
|
|
647
|
+
if (_client) return _client.getFlag(name);
|
|
648
|
+
return readGateOverride(name) ?? false;
|
|
636
649
|
},
|
|
637
650
|
getConfig(name, decode) {
|
|
638
|
-
|
|
651
|
+
if (!_mountedAndReady) return void 0;
|
|
652
|
+
if (_client) return _client.getConfig(name, decode);
|
|
653
|
+
const ov = readConfigOverride(name);
|
|
654
|
+
if (ov === void 0) return void 0;
|
|
655
|
+
if (!decode) return ov;
|
|
656
|
+
try {
|
|
657
|
+
return decode(ov);
|
|
658
|
+
} catch {
|
|
659
|
+
return void 0;
|
|
660
|
+
}
|
|
639
661
|
},
|
|
640
662
|
getExperiment(name, defaultParams, decode, variants) {
|
|
641
663
|
return _client?.getExperiment(name, defaultParams, decode, variants) ?? {
|
|
@@ -650,11 +672,24 @@ var flags = {
|
|
|
650
672
|
flush() {
|
|
651
673
|
return _client?.flush() ?? Promise.resolve();
|
|
652
674
|
},
|
|
675
|
+
/**
|
|
676
|
+
* Called by FlagsBoundary after React hydration to unlock flag reads.
|
|
677
|
+
* Dispatches se:override:change so subscribers (FlagsBoundary) re-render
|
|
678
|
+
* once with real values — URL overrides and server-evaluated flags.
|
|
679
|
+
*/
|
|
680
|
+
notifyMounted() {
|
|
681
|
+
if (_mountedAndReady) return;
|
|
682
|
+
_mountedAndReady = true;
|
|
683
|
+
if (typeof window !== "undefined") {
|
|
684
|
+
window.dispatchEvent(new CustomEvent("se:override:change"));
|
|
685
|
+
}
|
|
686
|
+
},
|
|
653
687
|
/** Subscribe for change notifications (identify/override). Used by framework adapters. */
|
|
654
688
|
subscribe(listener) {
|
|
655
|
-
if (
|
|
656
|
-
|
|
657
|
-
|
|
689
|
+
if (_client) return _client.subscribe(listener);
|
|
690
|
+
_standaloneListeners.add(listener);
|
|
691
|
+
wireStandaloneOverride();
|
|
692
|
+
return () => _standaloneListeners.delete(listener);
|
|
658
693
|
},
|
|
659
694
|
/** True once identify() has completed and flags are available. */
|
|
660
695
|
get ready() {
|
|
@@ -675,27 +710,10 @@ function labelAttrs(key, variables, desc) {
|
|
|
675
710
|
return attrs;
|
|
676
711
|
}
|
|
677
712
|
var _createElement = null;
|
|
678
|
-
function interpolate(template, variables) {
|
|
679
|
-
if (!variables) return template;
|
|
680
|
-
let out = template;
|
|
681
|
-
for (const name of Object.keys(variables)) {
|
|
682
|
-
out = out.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), String(variables[name]));
|
|
683
|
-
}
|
|
684
|
-
return out;
|
|
685
|
-
}
|
|
686
713
|
var i18n = {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
* `fallback` instead — `fallback` is the source-of-truth English copy
|
|
691
|
-
* and is mandatory so the page never renders a raw key.
|
|
692
|
-
*/
|
|
693
|
-
t(key, fallback, variables) {
|
|
694
|
-
if (typeof window !== "undefined" && window.i18n) {
|
|
695
|
-
const v = window.i18n.t(key, variables);
|
|
696
|
-
if (v !== key) return v;
|
|
697
|
-
}
|
|
698
|
-
return interpolate(fallback, variables);
|
|
714
|
+
t(key, variables) {
|
|
715
|
+
if (typeof window !== "undefined" && window.i18n) return window.i18n.t(key, variables);
|
|
716
|
+
return key;
|
|
699
717
|
},
|
|
700
718
|
/**
|
|
701
719
|
* Translate a key and return a framework element (e.g. React <span>)
|
|
@@ -710,7 +728,7 @@ var i18n = {
|
|
|
710
728
|
* configured (e.g. server-side or in non-JSX contexts).
|
|
711
729
|
*/
|
|
712
730
|
tEl(key, fallback, variables, desc) {
|
|
713
|
-
const text = this.t(key,
|
|
731
|
+
const text = this.t(key, variables) || fallback;
|
|
714
732
|
if (!_createElement) return text;
|
|
715
733
|
return _createElement("span", labelAttrs(key, variables, desc), text);
|
|
716
734
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shipeasy/sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
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",
|