@shipeasy/sdk 2.0.2 → 2.0.3

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.
@@ -137,10 +137,10 @@ declare const flags: {
137
137
  identify(user: User): Promise<void>;
138
138
  /**
139
139
  * Read a feature gate.
140
- * Priority: URL override → server bootstrap (window.__SE_BOOTSTRAP) → CDN-fetched (post-mount) → false.
141
- * The _mountedAndReady gate still applies for the CDN path to prevent hydration
142
- * mismatches on force-static pages; bootstrap data is safe to read immediately
143
- * because the server rendered with the same values.
140
+ * Priority: bootstrap → CDN/URL-override (post-mount) → false.
141
+ * Bootstrap is safe before mount because the server rendered with the same values.
142
+ * Everything else gates on _mountedAndReady to prevent hydration mismatches on
143
+ * force-static pages where SSR has no flag data.
144
144
  */
145
145
  get(name: string): boolean;
146
146
  getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
@@ -150,7 +150,11 @@ declare const flags: {
150
150
  /**
151
151
  * Called by FlagsBoundary after React hydration to unlock flag reads.
152
152
  * Dispatches se:override:change so subscribers (FlagsBoundary) re-render
153
- * once with real values — URL overrides and server-evaluated flags.
153
+ * once with real values — URL overrides and CDN-loaded flags.
154
+ *
155
+ * Always dispatches even if already mounted: in React hydration-recovery
156
+ * renders the latch is already true so the early-return guard would swallow
157
+ * the event, leaving the re-mounted subtree stuck with stale (empty) values.
154
158
  */
155
159
  notifyMounted(): void;
156
160
  /** Subscribe for change notifications (identify/override). Used by framework adapters. */
@@ -137,10 +137,10 @@ declare const flags: {
137
137
  identify(user: User): Promise<void>;
138
138
  /**
139
139
  * Read a feature gate.
140
- * Priority: URL override → server bootstrap (window.__SE_BOOTSTRAP) → CDN-fetched (post-mount) → false.
141
- * The _mountedAndReady gate still applies for the CDN path to prevent hydration
142
- * mismatches on force-static pages; bootstrap data is safe to read immediately
143
- * because the server rendered with the same values.
140
+ * Priority: bootstrap → CDN/URL-override (post-mount) → false.
141
+ * Bootstrap is safe before mount because the server rendered with the same values.
142
+ * Everything else gates on _mountedAndReady to prevent hydration mismatches on
143
+ * force-static pages where SSR has no flag data.
144
144
  */
145
145
  get(name: string): boolean;
146
146
  getConfig<T = unknown>(name: string, decode?: (raw: unknown) => T): T | undefined;
@@ -150,7 +150,11 @@ declare const flags: {
150
150
  /**
151
151
  * Called by FlagsBoundary after React hydration to unlock flag reads.
152
152
  * Dispatches se:override:change so subscribers (FlagsBoundary) re-render
153
- * once with real values — URL overrides and server-evaluated flags.
153
+ * once with real values — URL overrides and CDN-loaded flags.
154
+ *
155
+ * Always dispatches even if already mounted: in React hydration-recovery
156
+ * renders the latch is already true so the early-return guard would swallow
157
+ * the event, leaving the re-mounted subtree stuck with stale (empty) values.
154
158
  */
155
159
  notifyMounted(): void;
156
160
  /** Subscribe for change notifications (identify/override). Used by framework adapters. */
@@ -686,30 +686,19 @@ var flags = {
686
686
  },
687
687
  /**
688
688
  * Read a feature gate.
689
- * Priority: URL override → server bootstrap (window.__SE_BOOTSTRAP) → CDN-fetched (post-mount) → false.
690
- * The _mountedAndReady gate still applies for the CDN path to prevent hydration
691
- * mismatches on force-static pages; bootstrap data is safe to read immediately
692
- * because the server rendered with the same values.
689
+ * Priority: bootstrap → CDN/URL-override (post-mount) → false.
690
+ * Bootstrap is safe before mount because the server rendered with the same values.
691
+ * Everything else gates on _mountedAndReady to prevent hydration mismatches on
692
+ * force-static pages where SSR has no flag data.
693
693
  */
694
694
  get(name) {
695
- const ov = readGateOverride(name);
696
- if (ov !== null) return ov;
697
695
  const bs = getBootstrap();
698
696
  if (bs !== null && name in bs.flags) return bs.flags[name];
699
697
  if (!_mountedAndReady) return false;
700
698
  if (_client) return _client.getFlag(name);
701
- return false;
699
+ return readGateOverride(name) ?? false;
702
700
  },
703
701
  getConfig(name, decode) {
704
- const ov = readConfigOverride(name);
705
- if (ov !== void 0) {
706
- if (!decode) return ov;
707
- try {
708
- return decode(ov);
709
- } catch {
710
- return void 0;
711
- }
712
- }
713
702
  const bs = getBootstrap();
714
703
  if (bs !== null && name in bs.configs) {
715
704
  const raw = bs.configs[name];
@@ -722,7 +711,14 @@ var flags = {
722
711
  }
723
712
  if (!_mountedAndReady) return void 0;
724
713
  if (_client) return _client.getConfig(name, decode);
725
- return void 0;
714
+ const ov = readConfigOverride(name);
715
+ if (ov === void 0) return void 0;
716
+ if (!decode) return ov;
717
+ try {
718
+ return decode(ov);
719
+ } catch {
720
+ return void 0;
721
+ }
726
722
  },
727
723
  getExperiment(name, defaultParams, decode, variants) {
728
724
  return _client?.getExperiment(name, defaultParams, decode, variants) ?? {
@@ -740,10 +736,13 @@ var flags = {
740
736
  /**
741
737
  * Called by FlagsBoundary after React hydration to unlock flag reads.
742
738
  * Dispatches se:override:change so subscribers (FlagsBoundary) re-render
743
- * once with real values — URL overrides and server-evaluated flags.
739
+ * once with real values — URL overrides and CDN-loaded flags.
740
+ *
741
+ * Always dispatches even if already mounted: in React hydration-recovery
742
+ * renders the latch is already true so the early-return guard would swallow
743
+ * the event, leaving the re-mounted subtree stuck with stale (empty) values.
744
744
  */
745
745
  notifyMounted() {
746
- if (_mountedAndReady) return;
747
746
  _mountedAndReady = true;
748
747
  if (typeof window !== "undefined") {
749
748
  window.dispatchEvent(new CustomEvent("se:override:change"));
@@ -644,30 +644,19 @@ var flags = {
644
644
  },
645
645
  /**
646
646
  * Read a feature gate.
647
- * Priority: URL override → server bootstrap (window.__SE_BOOTSTRAP) → CDN-fetched (post-mount) → false.
648
- * The _mountedAndReady gate still applies for the CDN path to prevent hydration
649
- * mismatches on force-static pages; bootstrap data is safe to read immediately
650
- * because the server rendered with the same values.
647
+ * Priority: bootstrap → CDN/URL-override (post-mount) → false.
648
+ * Bootstrap is safe before mount because the server rendered with the same values.
649
+ * Everything else gates on _mountedAndReady to prevent hydration mismatches on
650
+ * force-static pages where SSR has no flag data.
651
651
  */
652
652
  get(name) {
653
- const ov = readGateOverride(name);
654
- if (ov !== null) return ov;
655
653
  const bs = getBootstrap();
656
654
  if (bs !== null && name in bs.flags) return bs.flags[name];
657
655
  if (!_mountedAndReady) return false;
658
656
  if (_client) return _client.getFlag(name);
659
- return false;
657
+ return readGateOverride(name) ?? false;
660
658
  },
661
659
  getConfig(name, decode) {
662
- const ov = readConfigOverride(name);
663
- if (ov !== void 0) {
664
- if (!decode) return ov;
665
- try {
666
- return decode(ov);
667
- } catch {
668
- return void 0;
669
- }
670
- }
671
660
  const bs = getBootstrap();
672
661
  if (bs !== null && name in bs.configs) {
673
662
  const raw = bs.configs[name];
@@ -680,7 +669,14 @@ var flags = {
680
669
  }
681
670
  if (!_mountedAndReady) return void 0;
682
671
  if (_client) return _client.getConfig(name, decode);
683
- return void 0;
672
+ const ov = readConfigOverride(name);
673
+ if (ov === void 0) return void 0;
674
+ if (!decode) return ov;
675
+ try {
676
+ return decode(ov);
677
+ } catch {
678
+ return void 0;
679
+ }
684
680
  },
685
681
  getExperiment(name, defaultParams, decode, variants) {
686
682
  return _client?.getExperiment(name, defaultParams, decode, variants) ?? {
@@ -698,10 +694,13 @@ var flags = {
698
694
  /**
699
695
  * Called by FlagsBoundary after React hydration to unlock flag reads.
700
696
  * Dispatches se:override:change so subscribers (FlagsBoundary) re-render
701
- * once with real values — URL overrides and server-evaluated flags.
697
+ * once with real values — URL overrides and CDN-loaded flags.
698
+ *
699
+ * Always dispatches even if already mounted: in React hydration-recovery
700
+ * renders the latch is already true so the early-return guard would swallow
701
+ * the event, leaving the re-mounted subtree stuck with stale (empty) values.
702
702
  */
703
703
  notifyMounted() {
704
- if (_mountedAndReady) return;
705
704
  _mountedAndReady = true;
706
705
  if (typeof window !== "undefined") {
707
706
  window.dispatchEvent(new CustomEvent("se:override:change"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shipeasy/sdk",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
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",