@schematichq/schematic-react 1.2.21 → 1.3.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023-2025 Schematic, Inc.
3
+ Copyright (c) 2023-2026 Schematic, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -33,13 +33,15 @@ __export(index_exports, {
33
33
  RuleType: () => RuleType,
34
34
  Schematic: () => Schematic,
35
35
  SchematicProvider: () => SchematicProvider,
36
+ TrialStatus: () => TrialStatus,
36
37
  UsagePeriod: () => UsagePeriod,
37
38
  useSchematic: () => useSchematic,
38
39
  useSchematicContext: () => useSchematicContext,
39
40
  useSchematicEntitlement: () => useSchematicEntitlement,
40
41
  useSchematicEvents: () => useSchematicEvents,
41
42
  useSchematicFlag: () => useSchematicFlag,
42
- useSchematicIsPending: () => useSchematicIsPending
43
+ useSchematicIsPending: () => useSchematicIsPending,
44
+ useSchematicPlan: () => useSchematicPlan
43
45
  });
44
46
  module.exports = __toCommonJS(index_exports);
45
47
 
@@ -706,26 +708,6 @@ function CheckFlagResponseDataFromJSONTyped(json, ignoreDiscriminator) {
706
708
  value: json["value"]
707
709
  };
708
710
  }
709
- function EventBodyFlagCheckToJSON(json) {
710
- return EventBodyFlagCheckToJSONTyped(json, false);
711
- }
712
- function EventBodyFlagCheckToJSONTyped(value, ignoreDiscriminator = false) {
713
- if (value == null) {
714
- return value;
715
- }
716
- return {
717
- company_id: value["companyId"],
718
- error: value["error"],
719
- flag_id: value["flagId"],
720
- flag_key: value["flagKey"],
721
- reason: value["reason"],
722
- req_company: value["reqCompany"],
723
- req_user: value["reqUser"],
724
- rule_id: value["ruleId"],
725
- user_id: value["userId"],
726
- value: value["value"]
727
- };
728
- }
729
711
  function CheckFlagResponseFromJSON(json) {
730
712
  return CheckFlagResponseFromJSONTyped(json, false);
731
713
  }
@@ -738,6 +720,31 @@ function CheckFlagResponseFromJSONTyped(json, ignoreDiscriminator) {
738
720
  params: json["params"]
739
721
  };
740
722
  }
723
+ var TrialStatus = {
724
+ Active: "active",
725
+ Converted: "converted",
726
+ Expired: "expired"
727
+ };
728
+ function TrialStatusFromJSON(json) {
729
+ return TrialStatusFromJSONTyped(json, false);
730
+ }
731
+ function TrialStatusFromJSONTyped(json, ignoreDiscriminator) {
732
+ return json;
733
+ }
734
+ function DatastreamCompanyPlanFromJSON(json) {
735
+ return DatastreamCompanyPlanFromJSONTyped(json, false);
736
+ }
737
+ function DatastreamCompanyPlanFromJSONTyped(json, ignoreDiscriminator) {
738
+ if (json == null) {
739
+ return json;
740
+ }
741
+ return {
742
+ id: json["id"],
743
+ name: json["name"],
744
+ trialEndDate: json["trial_end_date"] == null ? void 0 : new Date(json["trial_end_date"]),
745
+ trialStatus: json["trial_status"] == null ? void 0 : TrialStatusFromJSON(json["trial_status"])
746
+ };
747
+ }
741
748
  function CheckFlagsResponseDataFromJSON(json) {
742
749
  return CheckFlagsResponseDataFromJSONTyped(json, false);
743
750
  }
@@ -746,7 +753,8 @@ function CheckFlagsResponseDataFromJSONTyped(json, ignoreDiscriminator) {
746
753
  return json;
747
754
  }
748
755
  return {
749
- flags: json["flags"].map(CheckFlagResponseDataFromJSON)
756
+ flags: json["flags"].map(CheckFlagResponseDataFromJSON),
757
+ plan: json["plan"] == null ? void 0 : DatastreamCompanyPlanFromJSON(json["plan"])
750
758
  };
751
759
  }
752
760
  function CheckFlagsResponseFromJSON(json) {
@@ -761,6 +769,26 @@ function CheckFlagsResponseFromJSONTyped(json, ignoreDiscriminator) {
761
769
  params: json["params"]
762
770
  };
763
771
  }
772
+ function EventBodyFlagCheckToJSON(json) {
773
+ return EventBodyFlagCheckToJSONTyped(json, false);
774
+ }
775
+ function EventBodyFlagCheckToJSONTyped(value, ignoreDiscriminator = false) {
776
+ if (value == null) {
777
+ return value;
778
+ }
779
+ return {
780
+ company_id: value["companyId"],
781
+ error: value["error"],
782
+ flag_id: value["flagId"],
783
+ flag_key: value["flagKey"],
784
+ reason: value["reason"],
785
+ req_company: value["reqCompany"],
786
+ req_user: value["reqUser"],
787
+ rule_id: value["ruleId"],
788
+ user_id: value["userId"],
789
+ value: value["value"]
790
+ };
791
+ }
764
792
  var RuleType = /* @__PURE__ */ ((RuleType2) => {
765
793
  RuleType2["GLOBAL_OVERRIDE"] = "global_override";
766
794
  RuleType2["COMPANY_OVERRIDE"] = "company_override";
@@ -816,6 +844,15 @@ var CheckFlagReturnFromJSON = (json) => {
816
844
  value
817
845
  };
818
846
  };
847
+ var CheckPlanReturnFromJSON = (json) => {
848
+ const { id, name, trialEndDate, trialStatus } = DatastreamCompanyPlanFromJSON(json);
849
+ return {
850
+ id,
851
+ name,
852
+ trialEndDate: trialEndDate == null ? void 0 : trialEndDate,
853
+ trialStatus: trialStatus == null ? void 0 : trialStatus
854
+ };
855
+ };
819
856
  function contextString(context) {
820
857
  const sortedContext = Object.keys(context).reduce((acc, key) => {
821
858
  const sortedKeys = Object.keys(
@@ -830,7 +867,7 @@ function contextString(context) {
830
867
  }, {});
831
868
  return JSON.stringify(sortedContext);
832
869
  }
833
- var version = "1.2.21";
870
+ var version = "1.3.1";
834
871
  var anonymousIdKey = "schematicId";
835
872
  var Schematic = class {
836
873
  additionalHeaders = {};
@@ -847,10 +884,12 @@ var Schematic = class {
847
884
  flagValueListeners = {};
848
885
  isPending = true;
849
886
  isPendingListeners = /* @__PURE__ */ new Set();
887
+ planListeners = /* @__PURE__ */ new Set();
850
888
  storage;
851
889
  useWebSocket = false;
852
890
  checks = {};
853
891
  featureUsageEventMap = {};
892
+ planChecks = {};
854
893
  webSocketUrl = "wss://api.schematichq.com";
855
894
  webSocketConnectionTimeout = 1e4;
856
895
  webSocketReconnect = true;
@@ -1183,28 +1222,32 @@ var Schematic = class {
1183
1222
  this.checks[contextStr] = {};
1184
1223
  }
1185
1224
  this.checks[contextStr][flagCheck.flag] = flagCheck;
1186
- this.debug(`WebSocket flag update:`, {
1187
- flag: flagCheck.flag,
1188
- value: flagCheck.value,
1189
- flagCheck
1190
- });
1191
1225
  if (typeof flagCheck.featureUsageEvent === "string") {
1192
1226
  this.updateFeatureUsageEventMap(flagCheck);
1193
1227
  }
1194
1228
  if ((this.flagCheckListeners[flag.flag]?.size ?? 0) > 0 || (this.flagValueListeners[flag.flag]?.size ?? 0) > 0) {
1195
1229
  this.submitFlagCheckEvent(flagCheck.flag, flagCheck, context);
1196
1230
  }
1197
- this.debug(`About to notify listeners for flag ${flag.flag}`, {
1198
- flag: flag.flag,
1199
- value: flagCheck.value
1200
- });
1231
+ this.debug(
1232
+ `WebSocket flag update received. Notifying listeners for ${flag.flag}`,
1233
+ {
1234
+ flag: flag.flag,
1235
+ value: flagCheck.value,
1236
+ flagCheck
1237
+ }
1238
+ );
1201
1239
  this.notifyFlagCheckListeners(flag.flag, flagCheck);
1202
1240
  this.notifyFlagValueListeners(flag.flag, flagCheck.value);
1203
- this.debug(`Finished notifying listeners for flag ${flag.flag}`, {
1204
- flag: flag.flag,
1205
- value: flagCheck.value
1206
- });
1207
1241
  });
1242
+ if (message.plan !== void 0 && message.plan !== null) {
1243
+ const plan = CheckPlanReturnFromJSON(message.plan);
1244
+ const contextStr = contextString(context);
1245
+ this.planChecks[contextStr] = plan;
1246
+ this.debug(`WebSocket plan update received. Notifying listeners`, {
1247
+ plan
1248
+ });
1249
+ this.notifyPlanListeners(plan);
1250
+ }
1208
1251
  this.flushContextDependentEventQueue();
1209
1252
  this.setIsPending(false);
1210
1253
  };
@@ -2100,6 +2143,11 @@ var Schematic = class {
2100
2143
  (listener) => notifyPendingListener(listener, isPending)
2101
2144
  );
2102
2145
  };
2146
+ getPlan = () => {
2147
+ const contextStr = contextString(this.context);
2148
+ const plan = this.planChecks[contextStr];
2149
+ return plan;
2150
+ };
2103
2151
  // flag checks state
2104
2152
  getFlagCheck = (flagKey) => {
2105
2153
  const contextStr = contextString(this.context);
@@ -2153,6 +2201,12 @@ var Schematic = class {
2153
2201
  this.flagCheckListeners[flagKey].delete(listener);
2154
2202
  };
2155
2203
  };
2204
+ addPlanListener = (listener) => {
2205
+ this.planListeners.add(listener);
2206
+ return () => {
2207
+ this.planListeners.delete(listener);
2208
+ };
2209
+ };
2156
2210
  notifyFlagCheckListeners = (flagKey, check) => {
2157
2211
  const listeners = this.flagCheckListeners?.[flagKey] ?? [];
2158
2212
  if (listeners.size > 0) {
@@ -2201,6 +2255,21 @@ var Schematic = class {
2201
2255
  });
2202
2256
  });
2203
2257
  };
2258
+ notifyPlanListeners = (value) => {
2259
+ const listeners = this.planListeners ?? [];
2260
+ if (listeners.size > 0) {
2261
+ this.debug(`Notifying ${listeners.size} plan listeners`, { value });
2262
+ }
2263
+ listeners.forEach((listener, index) => {
2264
+ this.debug(`Calling listener ${index} for plan`, {
2265
+ value
2266
+ });
2267
+ notifyPlanListener(listener, value);
2268
+ this.debug(`Listener ${index} for plan completed`, {
2269
+ value
2270
+ });
2271
+ });
2272
+ };
2204
2273
  };
2205
2274
  var notifyPendingListener = (listener, value) => {
2206
2275
  if (listener.length > 0) {
@@ -2223,12 +2292,19 @@ var notifyFlagValueListener = (listener, value) => {
2223
2292
  listener();
2224
2293
  }
2225
2294
  };
2295
+ var notifyPlanListener = (listener, value) => {
2296
+ if (listener.length > 0) {
2297
+ listener(value);
2298
+ } else {
2299
+ listener();
2300
+ }
2301
+ };
2226
2302
 
2227
2303
  // src/context/schematic.tsx
2228
2304
  var import_react = __toESM(require("react"));
2229
2305
 
2230
2306
  // src/version.ts
2231
- var version2 = "1.2.21";
2307
+ var version2 = "1.3.1";
2232
2308
 
2233
2309
  // src/context/schematic.tsx
2234
2310
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -2349,6 +2425,28 @@ var useSchematicEntitlement = (key, opts) => {
2349
2425
  }, [client, key, fallbackCheck]);
2350
2426
  return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, () => fallbackCheck);
2351
2427
  };
2428
+ var useSchematicPlan = (opts) => {
2429
+ const client = useSchematicClient(opts);
2430
+ const fallback = opts?.fallback;
2431
+ const fallbackPlan = (0, import_react2.useMemo)(
2432
+ () => fallback,
2433
+ [
2434
+ fallback?.id,
2435
+ fallback?.name,
2436
+ fallback?.trialEndDate?.getTime(),
2437
+ fallback?.trialStatus
2438
+ ]
2439
+ );
2440
+ const subscribe = (0, import_react2.useCallback)(
2441
+ (callback) => client.addPlanListener(callback),
2442
+ [client]
2443
+ );
2444
+ const getSnapshot = (0, import_react2.useCallback)(() => {
2445
+ const plan = client.getPlan();
2446
+ return plan ?? fallbackPlan;
2447
+ }, [client, fallbackPlan]);
2448
+ return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot, () => fallbackPlan);
2449
+ };
2352
2450
  var useSchematicIsPending = (opts) => {
2353
2451
  const client = useSchematicClient(opts);
2354
2452
  const subscribe = (0, import_react2.useCallback)(
@@ -1,4 +1,5 @@
1
1
  import { CheckFlagReturn } from '@schematichq/schematic-js';
2
+ import { CheckPlanReturn } from '@schematichq/schematic-js';
2
3
  import { Event as Event_2 } from '@schematichq/schematic-js';
3
4
  import { EventBody } from '@schematichq/schematic-js';
4
5
  import { EventBodyIdentify } from '@schematichq/schematic-js';
@@ -13,6 +14,7 @@ import * as SchematicJS from '@schematichq/schematic-js';
13
14
  import { SchematicOptions } from '@schematichq/schematic-js';
14
15
  import { StoragePersister } from '@schematichq/schematic-js';
15
16
  import { Traits } from '@schematichq/schematic-js';
17
+ import { TrialStatus } from '@schematichq/schematic-js';
16
18
  import { UsagePeriod } from '@schematichq/schematic-js';
17
19
 
18
20
  declare type BaseSchematicProviderProps = Omit<SchematicJS.SchematicOptions, "client" | "publishableKey" | "useWebSocket"> & {
@@ -21,6 +23,8 @@ declare type BaseSchematicProviderProps = Omit<SchematicJS.SchematicOptions, "cl
21
23
 
22
24
  export { CheckFlagReturn }
23
25
 
26
+ export { CheckPlanReturn }
27
+
24
28
  export { Event_2 as Event }
25
29
 
26
30
  export { EventBody }
@@ -67,6 +71,8 @@ export { StoragePersister }
67
71
 
68
72
  export { Traits }
69
73
 
74
+ export { TrialStatus }
75
+
70
76
  export { UsagePeriod }
71
77
 
72
78
  export declare const useSchematic: () => SchematicContextProps;
@@ -90,4 +96,10 @@ export declare type UseSchematicFlagOpts = SchematicHookOpts & {
90
96
 
91
97
  export declare const useSchematicIsPending: (opts?: SchematicHookOpts) => boolean;
92
98
 
99
+ export declare const useSchematicPlan: (opts?: UseSchematicPlanOpts) => SchematicJS.CheckPlanReturn | undefined;
100
+
101
+ export declare type UseSchematicPlanOpts = SchematicHookOpts & {
102
+ fallback?: SchematicJS.CheckPlanReturn;
103
+ };
104
+
93
105
  export { }
@@ -661,26 +661,6 @@ function CheckFlagResponseDataFromJSONTyped(json, ignoreDiscriminator) {
661
661
  value: json["value"]
662
662
  };
663
663
  }
664
- function EventBodyFlagCheckToJSON(json) {
665
- return EventBodyFlagCheckToJSONTyped(json, false);
666
- }
667
- function EventBodyFlagCheckToJSONTyped(value, ignoreDiscriminator = false) {
668
- if (value == null) {
669
- return value;
670
- }
671
- return {
672
- company_id: value["companyId"],
673
- error: value["error"],
674
- flag_id: value["flagId"],
675
- flag_key: value["flagKey"],
676
- reason: value["reason"],
677
- req_company: value["reqCompany"],
678
- req_user: value["reqUser"],
679
- rule_id: value["ruleId"],
680
- user_id: value["userId"],
681
- value: value["value"]
682
- };
683
- }
684
664
  function CheckFlagResponseFromJSON(json) {
685
665
  return CheckFlagResponseFromJSONTyped(json, false);
686
666
  }
@@ -693,6 +673,31 @@ function CheckFlagResponseFromJSONTyped(json, ignoreDiscriminator) {
693
673
  params: json["params"]
694
674
  };
695
675
  }
676
+ var TrialStatus = {
677
+ Active: "active",
678
+ Converted: "converted",
679
+ Expired: "expired"
680
+ };
681
+ function TrialStatusFromJSON(json) {
682
+ return TrialStatusFromJSONTyped(json, false);
683
+ }
684
+ function TrialStatusFromJSONTyped(json, ignoreDiscriminator) {
685
+ return json;
686
+ }
687
+ function DatastreamCompanyPlanFromJSON(json) {
688
+ return DatastreamCompanyPlanFromJSONTyped(json, false);
689
+ }
690
+ function DatastreamCompanyPlanFromJSONTyped(json, ignoreDiscriminator) {
691
+ if (json == null) {
692
+ return json;
693
+ }
694
+ return {
695
+ id: json["id"],
696
+ name: json["name"],
697
+ trialEndDate: json["trial_end_date"] == null ? void 0 : new Date(json["trial_end_date"]),
698
+ trialStatus: json["trial_status"] == null ? void 0 : TrialStatusFromJSON(json["trial_status"])
699
+ };
700
+ }
696
701
  function CheckFlagsResponseDataFromJSON(json) {
697
702
  return CheckFlagsResponseDataFromJSONTyped(json, false);
698
703
  }
@@ -701,7 +706,8 @@ function CheckFlagsResponseDataFromJSONTyped(json, ignoreDiscriminator) {
701
706
  return json;
702
707
  }
703
708
  return {
704
- flags: json["flags"].map(CheckFlagResponseDataFromJSON)
709
+ flags: json["flags"].map(CheckFlagResponseDataFromJSON),
710
+ plan: json["plan"] == null ? void 0 : DatastreamCompanyPlanFromJSON(json["plan"])
705
711
  };
706
712
  }
707
713
  function CheckFlagsResponseFromJSON(json) {
@@ -716,6 +722,26 @@ function CheckFlagsResponseFromJSONTyped(json, ignoreDiscriminator) {
716
722
  params: json["params"]
717
723
  };
718
724
  }
725
+ function EventBodyFlagCheckToJSON(json) {
726
+ return EventBodyFlagCheckToJSONTyped(json, false);
727
+ }
728
+ function EventBodyFlagCheckToJSONTyped(value, ignoreDiscriminator = false) {
729
+ if (value == null) {
730
+ return value;
731
+ }
732
+ return {
733
+ company_id: value["companyId"],
734
+ error: value["error"],
735
+ flag_id: value["flagId"],
736
+ flag_key: value["flagKey"],
737
+ reason: value["reason"],
738
+ req_company: value["reqCompany"],
739
+ req_user: value["reqUser"],
740
+ rule_id: value["ruleId"],
741
+ user_id: value["userId"],
742
+ value: value["value"]
743
+ };
744
+ }
719
745
  var RuleType = /* @__PURE__ */ ((RuleType2) => {
720
746
  RuleType2["GLOBAL_OVERRIDE"] = "global_override";
721
747
  RuleType2["COMPANY_OVERRIDE"] = "company_override";
@@ -771,6 +797,15 @@ var CheckFlagReturnFromJSON = (json) => {
771
797
  value
772
798
  };
773
799
  };
800
+ var CheckPlanReturnFromJSON = (json) => {
801
+ const { id, name, trialEndDate, trialStatus } = DatastreamCompanyPlanFromJSON(json);
802
+ return {
803
+ id,
804
+ name,
805
+ trialEndDate: trialEndDate == null ? void 0 : trialEndDate,
806
+ trialStatus: trialStatus == null ? void 0 : trialStatus
807
+ };
808
+ };
774
809
  function contextString(context) {
775
810
  const sortedContext = Object.keys(context).reduce((acc, key) => {
776
811
  const sortedKeys = Object.keys(
@@ -785,7 +820,7 @@ function contextString(context) {
785
820
  }, {});
786
821
  return JSON.stringify(sortedContext);
787
822
  }
788
- var version = "1.2.21";
823
+ var version = "1.3.1";
789
824
  var anonymousIdKey = "schematicId";
790
825
  var Schematic = class {
791
826
  additionalHeaders = {};
@@ -802,10 +837,12 @@ var Schematic = class {
802
837
  flagValueListeners = {};
803
838
  isPending = true;
804
839
  isPendingListeners = /* @__PURE__ */ new Set();
840
+ planListeners = /* @__PURE__ */ new Set();
805
841
  storage;
806
842
  useWebSocket = false;
807
843
  checks = {};
808
844
  featureUsageEventMap = {};
845
+ planChecks = {};
809
846
  webSocketUrl = "wss://api.schematichq.com";
810
847
  webSocketConnectionTimeout = 1e4;
811
848
  webSocketReconnect = true;
@@ -1138,28 +1175,32 @@ var Schematic = class {
1138
1175
  this.checks[contextStr] = {};
1139
1176
  }
1140
1177
  this.checks[contextStr][flagCheck.flag] = flagCheck;
1141
- this.debug(`WebSocket flag update:`, {
1142
- flag: flagCheck.flag,
1143
- value: flagCheck.value,
1144
- flagCheck
1145
- });
1146
1178
  if (typeof flagCheck.featureUsageEvent === "string") {
1147
1179
  this.updateFeatureUsageEventMap(flagCheck);
1148
1180
  }
1149
1181
  if ((this.flagCheckListeners[flag.flag]?.size ?? 0) > 0 || (this.flagValueListeners[flag.flag]?.size ?? 0) > 0) {
1150
1182
  this.submitFlagCheckEvent(flagCheck.flag, flagCheck, context);
1151
1183
  }
1152
- this.debug(`About to notify listeners for flag ${flag.flag}`, {
1153
- flag: flag.flag,
1154
- value: flagCheck.value
1155
- });
1184
+ this.debug(
1185
+ `WebSocket flag update received. Notifying listeners for ${flag.flag}`,
1186
+ {
1187
+ flag: flag.flag,
1188
+ value: flagCheck.value,
1189
+ flagCheck
1190
+ }
1191
+ );
1156
1192
  this.notifyFlagCheckListeners(flag.flag, flagCheck);
1157
1193
  this.notifyFlagValueListeners(flag.flag, flagCheck.value);
1158
- this.debug(`Finished notifying listeners for flag ${flag.flag}`, {
1159
- flag: flag.flag,
1160
- value: flagCheck.value
1161
- });
1162
1194
  });
1195
+ if (message.plan !== void 0 && message.plan !== null) {
1196
+ const plan = CheckPlanReturnFromJSON(message.plan);
1197
+ const contextStr = contextString(context);
1198
+ this.planChecks[contextStr] = plan;
1199
+ this.debug(`WebSocket plan update received. Notifying listeners`, {
1200
+ plan
1201
+ });
1202
+ this.notifyPlanListeners(plan);
1203
+ }
1163
1204
  this.flushContextDependentEventQueue();
1164
1205
  this.setIsPending(false);
1165
1206
  };
@@ -2055,6 +2096,11 @@ var Schematic = class {
2055
2096
  (listener) => notifyPendingListener(listener, isPending)
2056
2097
  );
2057
2098
  };
2099
+ getPlan = () => {
2100
+ const contextStr = contextString(this.context);
2101
+ const plan = this.planChecks[contextStr];
2102
+ return plan;
2103
+ };
2058
2104
  // flag checks state
2059
2105
  getFlagCheck = (flagKey) => {
2060
2106
  const contextStr = contextString(this.context);
@@ -2108,6 +2154,12 @@ var Schematic = class {
2108
2154
  this.flagCheckListeners[flagKey].delete(listener);
2109
2155
  };
2110
2156
  };
2157
+ addPlanListener = (listener) => {
2158
+ this.planListeners.add(listener);
2159
+ return () => {
2160
+ this.planListeners.delete(listener);
2161
+ };
2162
+ };
2111
2163
  notifyFlagCheckListeners = (flagKey, check) => {
2112
2164
  const listeners = this.flagCheckListeners?.[flagKey] ?? [];
2113
2165
  if (listeners.size > 0) {
@@ -2156,6 +2208,21 @@ var Schematic = class {
2156
2208
  });
2157
2209
  });
2158
2210
  };
2211
+ notifyPlanListeners = (value) => {
2212
+ const listeners = this.planListeners ?? [];
2213
+ if (listeners.size > 0) {
2214
+ this.debug(`Notifying ${listeners.size} plan listeners`, { value });
2215
+ }
2216
+ listeners.forEach((listener, index) => {
2217
+ this.debug(`Calling listener ${index} for plan`, {
2218
+ value
2219
+ });
2220
+ notifyPlanListener(listener, value);
2221
+ this.debug(`Listener ${index} for plan completed`, {
2222
+ value
2223
+ });
2224
+ });
2225
+ };
2159
2226
  };
2160
2227
  var notifyPendingListener = (listener, value) => {
2161
2228
  if (listener.length > 0) {
@@ -2178,12 +2245,19 @@ var notifyFlagValueListener = (listener, value) => {
2178
2245
  listener();
2179
2246
  }
2180
2247
  };
2248
+ var notifyPlanListener = (listener, value) => {
2249
+ if (listener.length > 0) {
2250
+ listener(value);
2251
+ } else {
2252
+ listener();
2253
+ }
2254
+ };
2181
2255
 
2182
2256
  // src/context/schematic.tsx
2183
2257
  import React, { createContext, useEffect, useMemo, useRef } from "react";
2184
2258
 
2185
2259
  // src/version.ts
2186
- var version2 = "1.2.21";
2260
+ var version2 = "1.3.1";
2187
2261
 
2188
2262
  // src/context/schematic.tsx
2189
2263
  import { jsx } from "react/jsx-runtime";
@@ -2304,6 +2378,28 @@ var useSchematicEntitlement = (key, opts) => {
2304
2378
  }, [client, key, fallbackCheck]);
2305
2379
  return useSyncExternalStore(subscribe, getSnapshot, () => fallbackCheck);
2306
2380
  };
2381
+ var useSchematicPlan = (opts) => {
2382
+ const client = useSchematicClient(opts);
2383
+ const fallback = opts?.fallback;
2384
+ const fallbackPlan = useMemo2(
2385
+ () => fallback,
2386
+ [
2387
+ fallback?.id,
2388
+ fallback?.name,
2389
+ fallback?.trialEndDate?.getTime(),
2390
+ fallback?.trialStatus
2391
+ ]
2392
+ );
2393
+ const subscribe = useCallback(
2394
+ (callback) => client.addPlanListener(callback),
2395
+ [client]
2396
+ );
2397
+ const getSnapshot = useCallback(() => {
2398
+ const plan = client.getPlan();
2399
+ return plan ?? fallbackPlan;
2400
+ }, [client, fallbackPlan]);
2401
+ return useSyncExternalStore(subscribe, getSnapshot, () => fallbackPlan);
2402
+ };
2307
2403
  var useSchematicIsPending = (opts) => {
2308
2404
  const client = useSchematicClient(opts);
2309
2405
  const subscribe = useCallback(
@@ -2317,13 +2413,15 @@ export {
2317
2413
  RuleType,
2318
2414
  Schematic,
2319
2415
  SchematicProvider,
2416
+ TrialStatus,
2320
2417
  UsagePeriod,
2321
2418
  useSchematic,
2322
2419
  useSchematicContext,
2323
2420
  useSchematicEntitlement,
2324
2421
  useSchematicEvents,
2325
2422
  useSchematicFlag,
2326
- useSchematicIsPending
2423
+ useSchematicIsPending,
2424
+ useSchematicPlan
2327
2425
  };
2328
2426
  /*! Bundled license information:
2329
2427
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schematichq/schematic-react",
3
- "version": "1.2.21",
3
+ "version": "1.3.1",
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,34 +31,39 @@
31
31
  "prepare": "husky"
32
32
  },
33
33
  "dependencies": {
34
- "@schematichq/schematic-js": "^1.2.21"
34
+ "@schematichq/schematic-js": "^1.3.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@eslint/js": "^10.0.1",
38
- "@microsoft/api-extractor": "^7.57.6",
38
+ "@microsoft/api-extractor": "^7.58.1",
39
39
  "@testing-library/dom": "^10.4.1",
40
40
  "@testing-library/jest-dom": "^6.9.1",
41
41
  "@testing-library/react": "^16.3.2",
42
42
  "@types/react": "^19.2.14",
43
43
  "@vitest/browser": "^4.0.18",
44
- "esbuild": "^0.27.3",
45
- "eslint": "^10.0.2",
44
+ "esbuild": "^0.28.0",
45
+ "eslint": "^10.2.0",
46
46
  "eslint-plugin-import": "^2.32.0",
47
47
  "eslint-plugin-react": "^7.37.5",
48
48
  "eslint-plugin-react-hooks": "^7.0.1",
49
49
  "globals": "^17.4.0",
50
- "happy-dom": "^20.8.3",
50
+ "happy-dom": "^20.8.9",
51
51
  "husky": "^9.1.7",
52
- "jsdom": "^28.1.0",
52
+ "jsdom": "^29.0.1",
53
53
  "prettier": "^3.8.1",
54
54
  "react": "^19.2.4",
55
55
  "react-dom": "^19.2.4",
56
- "typescript": "^5.9.3",
57
- "typescript-eslint": "^8.56.1",
56
+ "typescript": "^6.0.2",
57
+ "typescript-eslint": "^8.58.0",
58
58
  "vitest": "^4.0.18"
59
59
  },
60
60
  "peerDependencies": {
61
61
  "react": ">=18"
62
62
  },
63
+ "resolutions": {
64
+ "minimatch": ">=3.1.3",
65
+ "rollup": ">=4.59.0",
66
+ "undici": ">=7.24.0"
67
+ },
63
68
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
64
69
  }