@schematichq/schematic-react 1.2.8 → 1.2.9

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.
@@ -799,7 +799,7 @@ function contextString(context) {
799
799
  }, {});
800
800
  return JSON.stringify(sortedContext);
801
801
  }
802
- var version = "1.2.8";
802
+ var version = "1.2.9";
803
803
  var anonymousIdKey = "schematicId";
804
804
  var Schematic = class {
805
805
  additionalHeaders = {};
@@ -838,6 +838,8 @@ var Schematic = class {
838
838
  eventRetryMaxDelay = 3e4;
839
839
  // Maximum retry delay in ms
840
840
  retryTimer = null;
841
+ flagValueDefaults = {};
842
+ flagCheckDefaults = {};
841
843
  constructor(apiKey, options) {
842
844
  this.apiKey = apiKey;
843
845
  this.eventQueue = [];
@@ -908,6 +910,12 @@ var Schematic = class {
908
910
  if (options?.eventRetryMaxDelay !== void 0) {
909
911
  this.eventRetryMaxDelay = options.eventRetryMaxDelay;
910
912
  }
913
+ if (options?.flagValueDefaults !== void 0) {
914
+ this.flagValueDefaults = options.flagValueDefaults;
915
+ }
916
+ if (options?.flagCheckDefaults !== void 0) {
917
+ this.flagCheckDefaults = options.flagCheckDefaults;
918
+ }
911
919
  if (typeof window !== "undefined" && window?.addEventListener) {
912
920
  window.addEventListener("beforeunload", () => {
913
921
  this.flushEventQueue();
@@ -932,6 +940,62 @@ var Schematic = class {
932
940
  this.debug("Initialized with debug mode enabled");
933
941
  }
934
942
  }
943
+ /**
944
+ * Resolve fallback value according to priority order:
945
+ * 1. Callsite fallback value (if provided)
946
+ * 2. Initialization fallback value (flagValueDefaults)
947
+ * 3. Default to false
948
+ */
949
+ resolveFallbackValue(key, callsiteFallback) {
950
+ if (callsiteFallback !== void 0) {
951
+ return callsiteFallback;
952
+ }
953
+ if (key in this.flagValueDefaults) {
954
+ return this.flagValueDefaults[key];
955
+ }
956
+ return false;
957
+ }
958
+ /**
959
+ * Resolve complete CheckFlagReturn object according to priority order:
960
+ * 1. Use callsite fallback for boolean value, construct CheckFlagReturn
961
+ * 2. Use flagCheckDefaults if available for this flag
962
+ * 3. Use flagValueDefaults if available for this flag, construct CheckFlagReturn
963
+ * 4. Default CheckFlagReturn with value: false
964
+ */
965
+ resolveFallbackCheckFlagReturn(key, callsiteFallback, reason = "Fallback value used", error) {
966
+ if (callsiteFallback !== void 0) {
967
+ return {
968
+ flag: key,
969
+ value: callsiteFallback,
970
+ reason,
971
+ error
972
+ };
973
+ }
974
+ if (key in this.flagCheckDefaults) {
975
+ const defaultReturn = this.flagCheckDefaults[key];
976
+ return {
977
+ ...defaultReturn,
978
+ flag: key,
979
+ // Ensure flag matches the requested key
980
+ reason: error !== void 0 ? reason : defaultReturn.reason,
981
+ error
982
+ };
983
+ }
984
+ if (key in this.flagValueDefaults) {
985
+ return {
986
+ flag: key,
987
+ value: this.flagValueDefaults[key],
988
+ reason,
989
+ error
990
+ };
991
+ }
992
+ return {
993
+ flag: key,
994
+ value: false,
995
+ reason,
996
+ error
997
+ };
998
+ }
935
999
  /**
936
1000
  * Get value for a single flag.
937
1001
  * In WebSocket mode, returns cached values if connection is active, otherwise establishes
@@ -940,16 +1004,21 @@ var Schematic = class {
940
1004
  * In REST mode, makes an API call for each check.
941
1005
  */
942
1006
  async checkFlag(options) {
943
- const { fallback = false, key } = options;
1007
+ const { fallback, key } = options;
944
1008
  const context = options.context || this.context;
945
1009
  const contextStr = contextString(context);
946
1010
  this.debug(`checkFlag: ${key}`, { context, fallback });
947
1011
  if (this.isOffline()) {
1012
+ const resolvedFallbackResult = this.resolveFallbackCheckFlagReturn(
1013
+ key,
1014
+ fallback,
1015
+ "Offline mode - using initialization defaults"
1016
+ );
948
1017
  this.debug(`checkFlag offline result: ${key}`, {
949
- value: fallback,
1018
+ value: resolvedFallbackResult.value,
950
1019
  offlineMode: true
951
1020
  });
952
- return fallback;
1021
+ return resolvedFallbackResult.value;
953
1022
  }
954
1023
  if (!this.useWebSocket) {
955
1024
  const requestUrl = `${this.apiUrl}/flags/${key}/check`;
@@ -977,14 +1046,14 @@ var Schematic = class {
977
1046
  return result.value;
978
1047
  }).catch((error) => {
979
1048
  console.error("There was a problem with the fetch operation:", error);
980
- const errorResult = {
981
- flag: key,
982
- value: fallback,
983
- reason: "API request failed",
984
- error: error instanceof Error ? error.message : String(error)
985
- };
1049
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1050
+ key,
1051
+ fallback,
1052
+ "API request failed",
1053
+ error instanceof Error ? error.message : String(error)
1054
+ );
986
1055
  this.submitFlagCheckEvent(key, errorResult, context);
987
- return fallback;
1056
+ return errorResult.value;
988
1057
  });
989
1058
  }
990
1059
  try {
@@ -994,7 +1063,7 @@ var Schematic = class {
994
1063
  return existingVals[key].value;
995
1064
  }
996
1065
  if (this.isOffline()) {
997
- return fallback;
1066
+ return this.resolveFallbackValue(key, fallback);
998
1067
  }
999
1068
  try {
1000
1069
  await this.setContext(context);
@@ -1007,10 +1076,10 @@ var Schematic = class {
1007
1076
  }
1008
1077
  const contextVals = this.checks[contextStr] ?? {};
1009
1078
  const flagCheck = contextVals[key];
1010
- const result = flagCheck?.value ?? fallback;
1079
+ const result = flagCheck?.value ?? this.resolveFallbackValue(key, fallback);
1011
1080
  this.debug(
1012
1081
  `checkFlag WebSocket result: ${key}`,
1013
- typeof flagCheck !== "undefined" ? flagCheck : { value: fallback, fallbackUsed: true }
1082
+ typeof flagCheck !== "undefined" ? flagCheck : { value: result, fallbackUsed: true }
1014
1083
  );
1015
1084
  if (typeof flagCheck !== "undefined") {
1016
1085
  this.submitFlagCheckEvent(key, flagCheck, context);
@@ -1018,14 +1087,14 @@ var Schematic = class {
1018
1087
  return result;
1019
1088
  } catch (error) {
1020
1089
  console.error("Unexpected error in checkFlag:", error);
1021
- const errorResult = {
1022
- flag: key,
1023
- value: fallback,
1024
- reason: "Unexpected error in flag check",
1025
- error: error instanceof Error ? error.message : String(error)
1026
- };
1090
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1091
+ key,
1092
+ fallback,
1093
+ "Unexpected error in flag check",
1094
+ error instanceof Error ? error.message : String(error)
1095
+ );
1027
1096
  this.submitFlagCheckEvent(key, errorResult, context);
1028
- return fallback;
1097
+ return errorResult.value;
1029
1098
  }
1030
1099
  }
1031
1100
  /**
@@ -1068,11 +1137,12 @@ var Schematic = class {
1068
1137
  */
1069
1138
  async fallbackToRest(key, context, fallback) {
1070
1139
  if (this.isOffline()) {
1140
+ const resolvedFallback = this.resolveFallbackValue(key, fallback);
1071
1141
  this.debug(`fallbackToRest offline result: ${key}`, {
1072
- value: fallback,
1142
+ value: resolvedFallback,
1073
1143
  offlineMode: true
1074
1144
  });
1075
- return fallback;
1145
+ return resolvedFallback;
1076
1146
  }
1077
1147
  try {
1078
1148
  const requestUrl = `${this.apiUrl}/flags/${key}/check`;
@@ -1099,14 +1169,14 @@ var Schematic = class {
1099
1169
  return result.value;
1100
1170
  } catch (error) {
1101
1171
  console.error("REST API call failed, using fallback value:", error);
1102
- const errorResult = {
1103
- flag: key,
1104
- value: fallback,
1105
- reason: "API request failed (fallback)",
1106
- error: error instanceof Error ? error.message : String(error)
1107
- };
1172
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1173
+ key,
1174
+ fallback,
1175
+ "API request failed (fallback)",
1176
+ error instanceof Error ? error.message : String(error)
1177
+ );
1108
1178
  this.submitFlagCheckEvent(key, errorResult, context);
1109
- return fallback;
1179
+ return errorResult.value;
1110
1180
  }
1111
1181
  }
1112
1182
  /**
@@ -1875,7 +1945,7 @@ var notifyFlagValueListener = (listener, value) => {
1875
1945
  var import_react = __toESM(require("react"));
1876
1946
 
1877
1947
  // src/version.ts
1878
- var version2 = "1.2.8";
1948
+ var version2 = "1.2.9";
1879
1949
 
1880
1950
  // src/context/schematic.tsx
1881
1951
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -754,7 +754,7 @@ function contextString(context) {
754
754
  }, {});
755
755
  return JSON.stringify(sortedContext);
756
756
  }
757
- var version = "1.2.8";
757
+ var version = "1.2.9";
758
758
  var anonymousIdKey = "schematicId";
759
759
  var Schematic = class {
760
760
  additionalHeaders = {};
@@ -793,6 +793,8 @@ var Schematic = class {
793
793
  eventRetryMaxDelay = 3e4;
794
794
  // Maximum retry delay in ms
795
795
  retryTimer = null;
796
+ flagValueDefaults = {};
797
+ flagCheckDefaults = {};
796
798
  constructor(apiKey, options) {
797
799
  this.apiKey = apiKey;
798
800
  this.eventQueue = [];
@@ -863,6 +865,12 @@ var Schematic = class {
863
865
  if (options?.eventRetryMaxDelay !== void 0) {
864
866
  this.eventRetryMaxDelay = options.eventRetryMaxDelay;
865
867
  }
868
+ if (options?.flagValueDefaults !== void 0) {
869
+ this.flagValueDefaults = options.flagValueDefaults;
870
+ }
871
+ if (options?.flagCheckDefaults !== void 0) {
872
+ this.flagCheckDefaults = options.flagCheckDefaults;
873
+ }
866
874
  if (typeof window !== "undefined" && window?.addEventListener) {
867
875
  window.addEventListener("beforeunload", () => {
868
876
  this.flushEventQueue();
@@ -887,6 +895,62 @@ var Schematic = class {
887
895
  this.debug("Initialized with debug mode enabled");
888
896
  }
889
897
  }
898
+ /**
899
+ * Resolve fallback value according to priority order:
900
+ * 1. Callsite fallback value (if provided)
901
+ * 2. Initialization fallback value (flagValueDefaults)
902
+ * 3. Default to false
903
+ */
904
+ resolveFallbackValue(key, callsiteFallback) {
905
+ if (callsiteFallback !== void 0) {
906
+ return callsiteFallback;
907
+ }
908
+ if (key in this.flagValueDefaults) {
909
+ return this.flagValueDefaults[key];
910
+ }
911
+ return false;
912
+ }
913
+ /**
914
+ * Resolve complete CheckFlagReturn object according to priority order:
915
+ * 1. Use callsite fallback for boolean value, construct CheckFlagReturn
916
+ * 2. Use flagCheckDefaults if available for this flag
917
+ * 3. Use flagValueDefaults if available for this flag, construct CheckFlagReturn
918
+ * 4. Default CheckFlagReturn with value: false
919
+ */
920
+ resolveFallbackCheckFlagReturn(key, callsiteFallback, reason = "Fallback value used", error) {
921
+ if (callsiteFallback !== void 0) {
922
+ return {
923
+ flag: key,
924
+ value: callsiteFallback,
925
+ reason,
926
+ error
927
+ };
928
+ }
929
+ if (key in this.flagCheckDefaults) {
930
+ const defaultReturn = this.flagCheckDefaults[key];
931
+ return {
932
+ ...defaultReturn,
933
+ flag: key,
934
+ // Ensure flag matches the requested key
935
+ reason: error !== void 0 ? reason : defaultReturn.reason,
936
+ error
937
+ };
938
+ }
939
+ if (key in this.flagValueDefaults) {
940
+ return {
941
+ flag: key,
942
+ value: this.flagValueDefaults[key],
943
+ reason,
944
+ error
945
+ };
946
+ }
947
+ return {
948
+ flag: key,
949
+ value: false,
950
+ reason,
951
+ error
952
+ };
953
+ }
890
954
  /**
891
955
  * Get value for a single flag.
892
956
  * In WebSocket mode, returns cached values if connection is active, otherwise establishes
@@ -895,16 +959,21 @@ var Schematic = class {
895
959
  * In REST mode, makes an API call for each check.
896
960
  */
897
961
  async checkFlag(options) {
898
- const { fallback = false, key } = options;
962
+ const { fallback, key } = options;
899
963
  const context = options.context || this.context;
900
964
  const contextStr = contextString(context);
901
965
  this.debug(`checkFlag: ${key}`, { context, fallback });
902
966
  if (this.isOffline()) {
967
+ const resolvedFallbackResult = this.resolveFallbackCheckFlagReturn(
968
+ key,
969
+ fallback,
970
+ "Offline mode - using initialization defaults"
971
+ );
903
972
  this.debug(`checkFlag offline result: ${key}`, {
904
- value: fallback,
973
+ value: resolvedFallbackResult.value,
905
974
  offlineMode: true
906
975
  });
907
- return fallback;
976
+ return resolvedFallbackResult.value;
908
977
  }
909
978
  if (!this.useWebSocket) {
910
979
  const requestUrl = `${this.apiUrl}/flags/${key}/check`;
@@ -932,14 +1001,14 @@ var Schematic = class {
932
1001
  return result.value;
933
1002
  }).catch((error) => {
934
1003
  console.error("There was a problem with the fetch operation:", error);
935
- const errorResult = {
936
- flag: key,
937
- value: fallback,
938
- reason: "API request failed",
939
- error: error instanceof Error ? error.message : String(error)
940
- };
1004
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1005
+ key,
1006
+ fallback,
1007
+ "API request failed",
1008
+ error instanceof Error ? error.message : String(error)
1009
+ );
941
1010
  this.submitFlagCheckEvent(key, errorResult, context);
942
- return fallback;
1011
+ return errorResult.value;
943
1012
  });
944
1013
  }
945
1014
  try {
@@ -949,7 +1018,7 @@ var Schematic = class {
949
1018
  return existingVals[key].value;
950
1019
  }
951
1020
  if (this.isOffline()) {
952
- return fallback;
1021
+ return this.resolveFallbackValue(key, fallback);
953
1022
  }
954
1023
  try {
955
1024
  await this.setContext(context);
@@ -962,10 +1031,10 @@ var Schematic = class {
962
1031
  }
963
1032
  const contextVals = this.checks[contextStr] ?? {};
964
1033
  const flagCheck = contextVals[key];
965
- const result = flagCheck?.value ?? fallback;
1034
+ const result = flagCheck?.value ?? this.resolveFallbackValue(key, fallback);
966
1035
  this.debug(
967
1036
  `checkFlag WebSocket result: ${key}`,
968
- typeof flagCheck !== "undefined" ? flagCheck : { value: fallback, fallbackUsed: true }
1037
+ typeof flagCheck !== "undefined" ? flagCheck : { value: result, fallbackUsed: true }
969
1038
  );
970
1039
  if (typeof flagCheck !== "undefined") {
971
1040
  this.submitFlagCheckEvent(key, flagCheck, context);
@@ -973,14 +1042,14 @@ var Schematic = class {
973
1042
  return result;
974
1043
  } catch (error) {
975
1044
  console.error("Unexpected error in checkFlag:", error);
976
- const errorResult = {
977
- flag: key,
978
- value: fallback,
979
- reason: "Unexpected error in flag check",
980
- error: error instanceof Error ? error.message : String(error)
981
- };
1045
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1046
+ key,
1047
+ fallback,
1048
+ "Unexpected error in flag check",
1049
+ error instanceof Error ? error.message : String(error)
1050
+ );
982
1051
  this.submitFlagCheckEvent(key, errorResult, context);
983
- return fallback;
1052
+ return errorResult.value;
984
1053
  }
985
1054
  }
986
1055
  /**
@@ -1023,11 +1092,12 @@ var Schematic = class {
1023
1092
  */
1024
1093
  async fallbackToRest(key, context, fallback) {
1025
1094
  if (this.isOffline()) {
1095
+ const resolvedFallback = this.resolveFallbackValue(key, fallback);
1026
1096
  this.debug(`fallbackToRest offline result: ${key}`, {
1027
- value: fallback,
1097
+ value: resolvedFallback,
1028
1098
  offlineMode: true
1029
1099
  });
1030
- return fallback;
1100
+ return resolvedFallback;
1031
1101
  }
1032
1102
  try {
1033
1103
  const requestUrl = `${this.apiUrl}/flags/${key}/check`;
@@ -1054,14 +1124,14 @@ var Schematic = class {
1054
1124
  return result.value;
1055
1125
  } catch (error) {
1056
1126
  console.error("REST API call failed, using fallback value:", error);
1057
- const errorResult = {
1058
- flag: key,
1059
- value: fallback,
1060
- reason: "API request failed (fallback)",
1061
- error: error instanceof Error ? error.message : String(error)
1062
- };
1127
+ const errorResult = this.resolveFallbackCheckFlagReturn(
1128
+ key,
1129
+ fallback,
1130
+ "API request failed (fallback)",
1131
+ error instanceof Error ? error.message : String(error)
1132
+ );
1063
1133
  this.submitFlagCheckEvent(key, errorResult, context);
1064
- return fallback;
1134
+ return errorResult.value;
1065
1135
  }
1066
1136
  }
1067
1137
  /**
@@ -1830,7 +1900,7 @@ var notifyFlagValueListener = (listener, value) => {
1830
1900
  import React, { createContext, useEffect, useMemo, useRef } from "react";
1831
1901
 
1832
1902
  // src/version.ts
1833
- var version2 = "1.2.8";
1903
+ var version2 = "1.2.9";
1834
1904
 
1835
1905
  // src/context/schematic.tsx
1836
1906
  import { jsx } from "react/jsx-runtime";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-react",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "main": "dist/schematic-react.cjs.js",
5
5
  "module": "dist/schematic-react.esm.js",
6
6
  "types": "dist/schematic-react.d.ts",
@@ -31,7 +31,7 @@
31
31
  "prepare": "husky"
32
32
  },
33
33
  "dependencies": {
34
- "@schematichq/schematic-js": "^1.2.8"
34
+ "@schematichq/schematic-js": "^1.2.9"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@eslint/js": "^9.39.1",