@schematichq/schematic-react 1.3.1 → 1.4.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/README.md +39 -0
- package/dist/schematic-react.cjs.js +15 -7
- package/dist/schematic-react.d.ts +880 -32
- package/dist/schematic-react.esm.js +15 -7
- package/package.json +12 -14
package/README.md
CHANGED
|
@@ -136,6 +136,45 @@ const MyComponent = () => {
|
|
|
136
136
|
|
|
137
137
|
*Note: `useSchematicIsPending` is checking if entitlement data has been loaded, typically via `identify`. It should, therefore, be used to wrap flag and entitlement checks, but never the initial call to `identify`.*
|
|
138
138
|
|
|
139
|
+
### Company plan information
|
|
140
|
+
|
|
141
|
+
To access the current company's plan and trial status, you can use the `useSchematicPlan` hook:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { useSchematicPlan } from "@schematichq/schematic-react";
|
|
145
|
+
|
|
146
|
+
const MyComponent = () => {
|
|
147
|
+
const plan = useSchematicPlan();
|
|
148
|
+
|
|
149
|
+
if (!plan) {
|
|
150
|
+
return <div>No plan assigned</div>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div>
|
|
155
|
+
<p>Current plan: {plan.name}</p>
|
|
156
|
+
|
|
157
|
+
{plan.trialStatus === "active" && (
|
|
158
|
+
<p>Trial ends: {plan.trialEndDate?.toLocaleDateString()}</p>
|
|
159
|
+
)}
|
|
160
|
+
|
|
161
|
+
{plan.trialStatus === "expired" && (
|
|
162
|
+
<p>Your trial has ended. <a href="/upgrade">Upgrade now</a></p>
|
|
163
|
+
)}
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The hook returns an object with the following properties:
|
|
170
|
+
|
|
171
|
+
| Property | Type | Description |
|
|
172
|
+
| --- | --- | --- |
|
|
173
|
+
| `id` | `string` | The plan ID |
|
|
174
|
+
| `name` | `string` | The plan name |
|
|
175
|
+
| `trialEndDate` | `Date \| undefined` | The trial end date, if the company has or had a trial |
|
|
176
|
+
| `trialStatus` | `"active" \| "expired" \| "converted" \| undefined` | The company's trial status: `active` if the trial is ongoing, `expired` if the trial ended without conversion, `converted` if the company converted to a paid plan, or `undefined` if the company has never trialed |
|
|
177
|
+
|
|
139
178
|
## Fallback Behavior
|
|
140
179
|
|
|
141
180
|
The SDK includes built-in fallback behavior you can use to ensure your application continues to function even when unable to reach Schematic (e.g., during service disruptions or network issues).
|
|
@@ -809,6 +809,7 @@ var UsagePeriod = /* @__PURE__ */ ((UsagePeriod2) => {
|
|
|
809
809
|
var CheckFlagReturnFromJSON = (json) => {
|
|
810
810
|
const {
|
|
811
811
|
companyId,
|
|
812
|
+
entitlement,
|
|
812
813
|
error,
|
|
813
814
|
featureAllocation,
|
|
814
815
|
featureUsage,
|
|
@@ -826,20 +827,27 @@ var CheckFlagReturnFromJSON = (json) => {
|
|
|
826
827
|
const featureUsageExceeded = !value && // if flag is not false, then we haven't exceeded usage
|
|
827
828
|
(ruleType == "company_override_usage_exceeded" || // if the rule type is one of these, then we have exceeded usage
|
|
828
829
|
ruleType == "plan_entitlement_usage_exceeded");
|
|
830
|
+
const resolvedAllocation = entitlement?.allocation ?? featureAllocation;
|
|
831
|
+
const resolvedUsage = entitlement?.usage ?? featureUsage;
|
|
832
|
+
const resolvedEvent = entitlement?.eventName ?? featureUsageEvent;
|
|
833
|
+
const resolvedPeriod = entitlement?.metricPeriod ?? featureUsagePeriod;
|
|
834
|
+
const resolvedResetAt = entitlement?.metricResetAt ?? featureUsageResetAt;
|
|
829
835
|
return {
|
|
830
836
|
featureUsageExceeded,
|
|
831
837
|
companyId: companyId == null ? void 0 : companyId,
|
|
838
|
+
creditRemaining: entitlement?.creditRemaining == null ? void 0 : entitlement.creditRemaining,
|
|
832
839
|
error: error == null ? void 0 : error,
|
|
833
|
-
featureAllocation:
|
|
834
|
-
featureUsage:
|
|
835
|
-
featureUsageEvent:
|
|
836
|
-
featureUsagePeriod:
|
|
837
|
-
featureUsageResetAt:
|
|
840
|
+
featureAllocation: resolvedAllocation == null ? void 0 : resolvedAllocation,
|
|
841
|
+
featureUsage: resolvedUsage == null ? void 0 : resolvedUsage,
|
|
842
|
+
featureUsageEvent: resolvedEvent == null ? void 0 : resolvedEvent,
|
|
843
|
+
featureUsagePeriod: resolvedPeriod == null ? void 0 : resolvedPeriod,
|
|
844
|
+
featureUsageResetAt: resolvedResetAt == null ? void 0 : resolvedResetAt,
|
|
838
845
|
flag,
|
|
839
846
|
flagId: flagId == null ? void 0 : flagId,
|
|
840
847
|
reason,
|
|
841
848
|
ruleId: ruleId == null ? void 0 : ruleId,
|
|
842
849
|
ruleType: ruleType == null ? void 0 : ruleType,
|
|
850
|
+
softLimit: entitlement?.softLimit == null ? void 0 : entitlement.softLimit,
|
|
843
851
|
userId: userId == null ? void 0 : userId,
|
|
844
852
|
value
|
|
845
853
|
};
|
|
@@ -867,7 +875,7 @@ function contextString(context) {
|
|
|
867
875
|
}, {});
|
|
868
876
|
return JSON.stringify(sortedContext);
|
|
869
877
|
}
|
|
870
|
-
var version = "1.
|
|
878
|
+
var version = "1.4.0";
|
|
871
879
|
var anonymousIdKey = "schematicId";
|
|
872
880
|
var Schematic = class {
|
|
873
881
|
additionalHeaders = {};
|
|
@@ -2304,7 +2312,7 @@ var notifyPlanListener = (listener, value) => {
|
|
|
2304
2312
|
var import_react = __toESM(require("react"));
|
|
2305
2313
|
|
|
2306
2314
|
// src/version.ts
|
|
2307
|
-
var version2 = "1.
|
|
2315
|
+
var version2 = "1.4.1";
|
|
2308
2316
|
|
|
2309
2317
|
// src/context/schematic.tsx
|
|
2310
2318
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -1,47 +1,792 @@
|
|
|
1
|
-
import { CheckFlagReturn } from '@schematichq/schematic-js';
|
|
2
|
-
import { CheckPlanReturn } from '@schematichq/schematic-js';
|
|
3
|
-
import { Event as Event_2 } from '@schematichq/schematic-js';
|
|
4
|
-
import { EventBody } from '@schematichq/schematic-js';
|
|
5
|
-
import { EventBodyIdentify } from '@schematichq/schematic-js';
|
|
6
|
-
import { EventBodyTrack } from '@schematichq/schematic-js';
|
|
7
|
-
import { EventType } from '@schematichq/schematic-js';
|
|
8
|
-
import { Keys } from '@schematichq/schematic-js';
|
|
9
1
|
import { default as React_2 } from 'react';
|
|
10
|
-
import { RuleType } from '@schematichq/schematic-js';
|
|
11
|
-
import { Schematic } from '@schematichq/schematic-js';
|
|
12
|
-
import { SchematicContext } from '@schematichq/schematic-js';
|
|
13
|
-
import * as SchematicJS from '@schematichq/schematic-js';
|
|
14
|
-
import { SchematicOptions } from '@schematichq/schematic-js';
|
|
15
|
-
import { StoragePersister } from '@schematichq/schematic-js';
|
|
16
|
-
import { Traits } from '@schematichq/schematic-js';
|
|
17
|
-
import { TrialStatus } from '@schematichq/schematic-js';
|
|
18
|
-
import { UsagePeriod } from '@schematichq/schematic-js';
|
|
19
2
|
|
|
20
3
|
declare type BaseSchematicProviderProps = Omit<SchematicJS.SchematicOptions, "client" | "publishableKey" | "useWebSocket"> & {
|
|
21
4
|
children: React_2.ReactNode;
|
|
22
5
|
};
|
|
23
6
|
|
|
24
|
-
|
|
7
|
+
declare type BooleanListenerFn = (value: boolean) => void;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @export
|
|
12
|
+
* @interface CheckFlagResponse
|
|
13
|
+
*/
|
|
14
|
+
declare interface CheckFlagResponse {
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @type {CheckFlagResponseData}
|
|
18
|
+
* @memberof CheckFlagResponse
|
|
19
|
+
*/
|
|
20
|
+
data: CheckFlagResponseData;
|
|
21
|
+
/**
|
|
22
|
+
* Input parameters
|
|
23
|
+
* @type {object}
|
|
24
|
+
* @memberof CheckFlagResponse
|
|
25
|
+
*/
|
|
26
|
+
params: object;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
*
|
|
31
|
+
* @export
|
|
32
|
+
* @interface CheckFlagResponseData
|
|
33
|
+
*/
|
|
34
|
+
declare interface CheckFlagResponseData {
|
|
35
|
+
/**
|
|
36
|
+
* If company keys were provided and matched a company, its ID
|
|
37
|
+
* @type {string}
|
|
38
|
+
* @memberof CheckFlagResponseData
|
|
39
|
+
*/
|
|
40
|
+
companyId?: string | null;
|
|
41
|
+
/**
|
|
42
|
+
* If a feature entitlement rule was matched, its entitlement details
|
|
43
|
+
* @type {FeatureEntitlement}
|
|
44
|
+
* @memberof CheckFlagResponseData
|
|
45
|
+
*/
|
|
46
|
+
entitlement?: FeatureEntitlement;
|
|
47
|
+
/**
|
|
48
|
+
* If an error occurred while checking the flag, the error message
|
|
49
|
+
* @type {string}
|
|
50
|
+
* @memberof CheckFlagResponseData
|
|
51
|
+
*/
|
|
52
|
+
error?: string | null;
|
|
53
|
+
/**
|
|
54
|
+
* Deprecated: Use Entitlement.Allocation instead.
|
|
55
|
+
* @type {number}
|
|
56
|
+
* @memberof CheckFlagResponseData
|
|
57
|
+
* @deprecated
|
|
58
|
+
*/
|
|
59
|
+
featureAllocation?: number | null;
|
|
60
|
+
/**
|
|
61
|
+
* Deprecated: Use Entitlement.Usage instead.
|
|
62
|
+
* @type {number}
|
|
63
|
+
* @memberof CheckFlagResponseData
|
|
64
|
+
* @deprecated
|
|
65
|
+
*/
|
|
66
|
+
featureUsage?: number | null;
|
|
67
|
+
/**
|
|
68
|
+
* Deprecated: Use Entitlement.EventName instead.
|
|
69
|
+
* @type {string}
|
|
70
|
+
* @memberof CheckFlagResponseData
|
|
71
|
+
* @deprecated
|
|
72
|
+
*/
|
|
73
|
+
featureUsageEvent?: string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Deprecated: Use Entitlement.MetricPeriod instead.
|
|
76
|
+
* @type {string}
|
|
77
|
+
* @memberof CheckFlagResponseData
|
|
78
|
+
* @deprecated
|
|
79
|
+
*/
|
|
80
|
+
featureUsagePeriod?: string | null;
|
|
81
|
+
/**
|
|
82
|
+
* Deprecated: Use Entitlement.MetricResetAt instead.
|
|
83
|
+
* @type {Date}
|
|
84
|
+
* @memberof CheckFlagResponseData
|
|
85
|
+
* @deprecated
|
|
86
|
+
*/
|
|
87
|
+
featureUsageResetAt?: Date | null;
|
|
88
|
+
/**
|
|
89
|
+
* The key used to check the flag
|
|
90
|
+
* @type {string}
|
|
91
|
+
* @memberof CheckFlagResponseData
|
|
92
|
+
*/
|
|
93
|
+
flag: string;
|
|
94
|
+
/**
|
|
95
|
+
* If a flag was found, its ID
|
|
96
|
+
* @type {string}
|
|
97
|
+
* @memberof CheckFlagResponseData
|
|
98
|
+
*/
|
|
99
|
+
flagId?: string | null;
|
|
100
|
+
/**
|
|
101
|
+
* A human-readable explanation of the result
|
|
102
|
+
* @type {string}
|
|
103
|
+
* @memberof CheckFlagResponseData
|
|
104
|
+
*/
|
|
105
|
+
reason: string;
|
|
106
|
+
/**
|
|
107
|
+
* If a rule was found, its ID
|
|
108
|
+
* @type {string}
|
|
109
|
+
* @memberof CheckFlagResponseData
|
|
110
|
+
*/
|
|
111
|
+
ruleId?: string | null;
|
|
112
|
+
/**
|
|
113
|
+
* If a rule was found, its type
|
|
114
|
+
* @type {string}
|
|
115
|
+
* @memberof CheckFlagResponseData
|
|
116
|
+
*/
|
|
117
|
+
ruleType?: string | null;
|
|
118
|
+
/**
|
|
119
|
+
* If user keys were provided and matched a user, its ID
|
|
120
|
+
* @type {string}
|
|
121
|
+
* @memberof CheckFlagResponseData
|
|
122
|
+
*/
|
|
123
|
+
userId?: string | null;
|
|
124
|
+
/**
|
|
125
|
+
* A boolean flag check result; for feature entitlements, this represents whether further consumption of the feature is permitted
|
|
126
|
+
* @type {boolean}
|
|
127
|
+
* @memberof CheckFlagResponseData
|
|
128
|
+
*/
|
|
129
|
+
value: boolean;
|
|
130
|
+
}
|
|
25
131
|
|
|
26
|
-
|
|
132
|
+
declare function CheckFlagResponseFromJSON(json: any): CheckFlagResponse;
|
|
133
|
+
|
|
134
|
+
export declare type CheckFlagReturn = {
|
|
135
|
+
/** The company has access to the feature, but has exceeded the usage limit */
|
|
136
|
+
featureUsageExceeded?: boolean;
|
|
137
|
+
/** If company keys were provided and matched a company, its ID */
|
|
138
|
+
companyId?: string;
|
|
139
|
+
/** If the company has a credit-based entitlement for this feature, the remaining credit amount */
|
|
140
|
+
creditRemaining?: number;
|
|
141
|
+
/** If an error occurred while checking the flag, the error message */
|
|
142
|
+
error?: string;
|
|
143
|
+
/** If a numeric feature entitlement rule was matched, its allocation */
|
|
144
|
+
featureAllocation?: number;
|
|
145
|
+
/** If a numeric feature entitlement rule was matched, the company's usage */
|
|
146
|
+
featureUsage?: number;
|
|
147
|
+
/** Event representing the feature usage */
|
|
148
|
+
featureUsageEvent?: string;
|
|
149
|
+
/** For event-based feature entitlement rules, the period over which usage is tracked (current_month, current_day, current_week, all_time) */
|
|
150
|
+
featureUsagePeriod?: UsagePeriod;
|
|
151
|
+
/** For event-based feature entitlement rules, when the usage period will reset */
|
|
152
|
+
featureUsageResetAt?: Date;
|
|
153
|
+
/** The key used to check the flag */
|
|
154
|
+
flag: string;
|
|
155
|
+
/** If a flag was found, its ID */
|
|
156
|
+
flagId?: string;
|
|
157
|
+
/** A human-readable explanation of the result */
|
|
158
|
+
reason: string;
|
|
159
|
+
/** If a rule was found, its ID */
|
|
160
|
+
ruleId?: string;
|
|
161
|
+
/** If a rule was found, its type */
|
|
162
|
+
ruleType?: RuleType;
|
|
163
|
+
/** For usage-based pricing, the soft limit for overage charges or the next tier boundary */
|
|
164
|
+
softLimit?: number;
|
|
165
|
+
/** If user keys were provided and matched a user, its ID */
|
|
166
|
+
userId?: string;
|
|
167
|
+
/** A boolean flag check result; for feature entitlements, this represents whether further consumption of the feature is permitted */
|
|
168
|
+
value: boolean;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
declare const CheckFlagReturnFromJSON: (json: any) => CheckFlagReturn;
|
|
172
|
+
|
|
173
|
+
declare type CheckFlagReturnListenerFn = (value: CheckFlagReturn) => void;
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
*
|
|
177
|
+
* @export
|
|
178
|
+
* @interface CheckFlagsResponse
|
|
179
|
+
*/
|
|
180
|
+
declare interface CheckFlagsResponse {
|
|
181
|
+
/**
|
|
182
|
+
*
|
|
183
|
+
* @type {CheckFlagsResponseData}
|
|
184
|
+
* @memberof CheckFlagsResponse
|
|
185
|
+
*/
|
|
186
|
+
data: CheckFlagsResponseData;
|
|
187
|
+
/**
|
|
188
|
+
* Input parameters
|
|
189
|
+
* @type {object}
|
|
190
|
+
* @memberof CheckFlagsResponse
|
|
191
|
+
*/
|
|
192
|
+
params: object;
|
|
193
|
+
}
|
|
27
194
|
|
|
195
|
+
/**
|
|
196
|
+
*
|
|
197
|
+
* @export
|
|
198
|
+
* @interface CheckFlagsResponseData
|
|
199
|
+
*/
|
|
200
|
+
declare interface CheckFlagsResponseData {
|
|
201
|
+
/**
|
|
202
|
+
*
|
|
203
|
+
* @type {Array<CheckFlagResponseData>}
|
|
204
|
+
* @memberof CheckFlagsResponseData
|
|
205
|
+
*/
|
|
206
|
+
flags: Array<CheckFlagResponseData>;
|
|
207
|
+
/**
|
|
208
|
+
*
|
|
209
|
+
* @type {DatastreamCompanyPlan}
|
|
210
|
+
* @memberof CheckFlagsResponseData
|
|
211
|
+
*/
|
|
212
|
+
plan?: DatastreamCompanyPlan;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
declare function CheckFlagsResponseFromJSON(json: any): CheckFlagsResponse;
|
|
216
|
+
|
|
217
|
+
declare type CheckOptions = {
|
|
218
|
+
context?: SchematicContext;
|
|
219
|
+
fallback?: boolean;
|
|
220
|
+
key: string;
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
export declare type CheckPlanReturn = {
|
|
224
|
+
id: string;
|
|
225
|
+
name: string;
|
|
226
|
+
trialEndDate?: Date;
|
|
227
|
+
trialStatus?: TrialStatus;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
declare const CheckPlanReturnFromJSON: (json: any) => CheckPlanReturn;
|
|
231
|
+
|
|
232
|
+
declare type CheckPlanReturnListenerFn = (value: CheckPlanReturn) => void;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
*
|
|
236
|
+
* @export
|
|
237
|
+
* @interface DatastreamCompanyPlan
|
|
238
|
+
*/
|
|
239
|
+
declare interface DatastreamCompanyPlan {
|
|
240
|
+
/**
|
|
241
|
+
*
|
|
242
|
+
* @type {string}
|
|
243
|
+
* @memberof DatastreamCompanyPlan
|
|
244
|
+
*/
|
|
245
|
+
id: string;
|
|
246
|
+
/**
|
|
247
|
+
*
|
|
248
|
+
* @type {string}
|
|
249
|
+
* @memberof DatastreamCompanyPlan
|
|
250
|
+
*/
|
|
251
|
+
name: string;
|
|
252
|
+
/**
|
|
253
|
+
*
|
|
254
|
+
* @type {Date}
|
|
255
|
+
* @memberof DatastreamCompanyPlan
|
|
256
|
+
*/
|
|
257
|
+
trialEndDate?: Date | null;
|
|
258
|
+
/**
|
|
259
|
+
*
|
|
260
|
+
* @type {TrialStatus}
|
|
261
|
+
* @memberof DatastreamCompanyPlan
|
|
262
|
+
*/
|
|
263
|
+
trialStatus?: TrialStatus | null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
declare function DatastreamCompanyPlanFromJSON(json: any): DatastreamCompanyPlan;
|
|
267
|
+
|
|
268
|
+
declare type EmptyListenerFn = () => void;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
*
|
|
272
|
+
* @export
|
|
273
|
+
*/
|
|
274
|
+
declare const EntitlementValueType: {
|
|
275
|
+
readonly Boolean: "boolean";
|
|
276
|
+
readonly Credit: "credit";
|
|
277
|
+
readonly Numeric: "numeric";
|
|
278
|
+
readonly Trait: "trait";
|
|
279
|
+
readonly Unknown: "unknown";
|
|
280
|
+
readonly Unlimited: "unlimited";
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
declare type EntitlementValueType = (typeof EntitlementValueType)[keyof typeof EntitlementValueType];
|
|
284
|
+
|
|
285
|
+
declare type Event_2 = {
|
|
286
|
+
api_key: string;
|
|
287
|
+
body: EventBody;
|
|
288
|
+
sent_at: string;
|
|
289
|
+
tracker_event_id: string;
|
|
290
|
+
tracker_user_id: string;
|
|
291
|
+
type: EventType;
|
|
292
|
+
retry_count?: number;
|
|
293
|
+
next_retry_at?: number;
|
|
294
|
+
};
|
|
28
295
|
export { Event_2 as Event }
|
|
29
296
|
|
|
30
|
-
export
|
|
297
|
+
export declare type EventBody = EventBodyIdentify | EventBodyTrack | EventBodyFlagCheck;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Schematic API
|
|
301
|
+
* Schematic API
|
|
302
|
+
*
|
|
303
|
+
* The version of the OpenAPI document: 0.1
|
|
304
|
+
*
|
|
305
|
+
*
|
|
306
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
307
|
+
* https://openapi-generator.tech
|
|
308
|
+
* Do not edit the class manually.
|
|
309
|
+
*/
|
|
310
|
+
/**
|
|
311
|
+
*
|
|
312
|
+
* @export
|
|
313
|
+
* @interface EventBodyFlagCheck
|
|
314
|
+
*/
|
|
315
|
+
declare interface EventBodyFlagCheck {
|
|
316
|
+
/**
|
|
317
|
+
* Schematic company ID (starting with 'comp_') of the company evaluated, if any
|
|
318
|
+
* @type {string}
|
|
319
|
+
* @memberof EventBodyFlagCheck
|
|
320
|
+
*/
|
|
321
|
+
companyId?: string | null;
|
|
322
|
+
/**
|
|
323
|
+
* Report an error that occurred during the flag check
|
|
324
|
+
* @type {string}
|
|
325
|
+
* @memberof EventBodyFlagCheck
|
|
326
|
+
*/
|
|
327
|
+
error?: string | null;
|
|
328
|
+
/**
|
|
329
|
+
* Schematic flag ID (starting with 'flag_') for the flag matching the key, if any
|
|
330
|
+
* @type {string}
|
|
331
|
+
* @memberof EventBodyFlagCheck
|
|
332
|
+
*/
|
|
333
|
+
flagId?: string | null;
|
|
334
|
+
/**
|
|
335
|
+
* The key of the flag being checked
|
|
336
|
+
* @type {string}
|
|
337
|
+
* @memberof EventBodyFlagCheck
|
|
338
|
+
*/
|
|
339
|
+
flagKey: string;
|
|
340
|
+
/**
|
|
341
|
+
* The reason why the value was returned
|
|
342
|
+
* @type {string}
|
|
343
|
+
* @memberof EventBodyFlagCheck
|
|
344
|
+
*/
|
|
345
|
+
reason: string;
|
|
346
|
+
/**
|
|
347
|
+
* Key-value pairs used to to identify company for which the flag was checked
|
|
348
|
+
* @type {{ [key: string]: string; }}
|
|
349
|
+
* @memberof EventBodyFlagCheck
|
|
350
|
+
*/
|
|
351
|
+
reqCompany?: {
|
|
352
|
+
[key: string]: string;
|
|
353
|
+
} | null;
|
|
354
|
+
/**
|
|
355
|
+
* Key-value pairs used to to identify user for which the flag was checked
|
|
356
|
+
* @type {{ [key: string]: string; }}
|
|
357
|
+
* @memberof EventBodyFlagCheck
|
|
358
|
+
*/
|
|
359
|
+
reqUser?: {
|
|
360
|
+
[key: string]: string;
|
|
361
|
+
} | null;
|
|
362
|
+
/**
|
|
363
|
+
* Schematic rule ID (starting with 'rule_') of the rule that matched for the flag, if any
|
|
364
|
+
* @type {string}
|
|
365
|
+
* @memberof EventBodyFlagCheck
|
|
366
|
+
*/
|
|
367
|
+
ruleId?: string | null;
|
|
368
|
+
/**
|
|
369
|
+
* Schematic user ID (starting with 'user_') of the user evaluated, if any
|
|
370
|
+
* @type {string}
|
|
371
|
+
* @memberof EventBodyFlagCheck
|
|
372
|
+
*/
|
|
373
|
+
userId?: string | null;
|
|
374
|
+
/**
|
|
375
|
+
* The value of the flag for the given company and/or user
|
|
376
|
+
* @type {boolean}
|
|
377
|
+
* @memberof EventBodyFlagCheck
|
|
378
|
+
*/
|
|
379
|
+
value: boolean;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
declare function EventBodyFlagCheckToJSON(json: any): EventBodyFlagCheck;
|
|
383
|
+
|
|
384
|
+
export declare type EventBodyIdentify = {
|
|
385
|
+
company?: {
|
|
386
|
+
keys?: Keys;
|
|
387
|
+
name?: string;
|
|
388
|
+
traits?: Traits;
|
|
389
|
+
};
|
|
390
|
+
keys?: Keys;
|
|
391
|
+
name?: string;
|
|
392
|
+
traits?: Traits;
|
|
393
|
+
};
|
|
394
|
+
|
|
395
|
+
export declare type EventBodyTrack = SchematicContext & {
|
|
396
|
+
event: string;
|
|
397
|
+
quantity?: number;
|
|
398
|
+
traits?: Traits;
|
|
399
|
+
};
|
|
31
400
|
|
|
32
|
-
export
|
|
401
|
+
export declare type EventType = "identify" | "track" | "flag_check";
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
*
|
|
405
|
+
* @export
|
|
406
|
+
* @interface FeatureEntitlement
|
|
407
|
+
*/
|
|
408
|
+
declare interface FeatureEntitlement {
|
|
409
|
+
/**
|
|
410
|
+
* If the company has a numeric entitlement for this feature, the allocated amount
|
|
411
|
+
* @type {number}
|
|
412
|
+
* @memberof FeatureEntitlement
|
|
413
|
+
*/
|
|
414
|
+
allocation?: number | null;
|
|
415
|
+
/**
|
|
416
|
+
* If the company has a credit-based entitlement for this feature, the ID of the credit
|
|
417
|
+
* @type {string}
|
|
418
|
+
* @memberof FeatureEntitlement
|
|
419
|
+
*/
|
|
420
|
+
creditId?: string | null;
|
|
421
|
+
/**
|
|
422
|
+
* If the company has a credit-based entitlement for this feature, the remaining credit amount
|
|
423
|
+
* @type {number}
|
|
424
|
+
* @memberof FeatureEntitlement
|
|
425
|
+
*/
|
|
426
|
+
creditRemaining?: number | null;
|
|
427
|
+
/**
|
|
428
|
+
* If the company has a credit-based entitlement for this feature, the total credit amount
|
|
429
|
+
* @type {number}
|
|
430
|
+
* @memberof FeatureEntitlement
|
|
431
|
+
*/
|
|
432
|
+
creditTotal?: number | null;
|
|
433
|
+
/**
|
|
434
|
+
* If the company has a credit-based entitlement for this feature, the amount of credit used
|
|
435
|
+
* @type {number}
|
|
436
|
+
* @memberof FeatureEntitlement
|
|
437
|
+
*/
|
|
438
|
+
creditUsed?: number | null;
|
|
439
|
+
/**
|
|
440
|
+
* If the feature is event-based, the name of the event tracked for usage
|
|
441
|
+
* @type {string}
|
|
442
|
+
* @memberof FeatureEntitlement
|
|
443
|
+
*/
|
|
444
|
+
eventName?: string | null;
|
|
445
|
+
/**
|
|
446
|
+
* The ID of the feature
|
|
447
|
+
* @type {string}
|
|
448
|
+
* @memberof FeatureEntitlement
|
|
449
|
+
*/
|
|
450
|
+
featureId: string;
|
|
451
|
+
/**
|
|
452
|
+
* The key of the flag associated with the feature
|
|
453
|
+
* @type {string}
|
|
454
|
+
* @memberof FeatureEntitlement
|
|
455
|
+
*/
|
|
456
|
+
featureKey: string;
|
|
457
|
+
/**
|
|
458
|
+
* For event-based feature entitlements, the period over which usage is tracked
|
|
459
|
+
* @type {string}
|
|
460
|
+
* @memberof FeatureEntitlement
|
|
461
|
+
*/
|
|
462
|
+
metricPeriod?: FeatureEntitlementMetricPeriodEnum | null;
|
|
463
|
+
/**
|
|
464
|
+
* For event-based feature entitlements, when the usage period will reset
|
|
465
|
+
* @type {Date}
|
|
466
|
+
* @memberof FeatureEntitlement
|
|
467
|
+
*/
|
|
468
|
+
metricResetAt?: Date | null;
|
|
469
|
+
/**
|
|
470
|
+
* For event-based feature entitlements that have a monthly period, whether that monthly reset is based on the calendar month or a billing cycle
|
|
471
|
+
* @type {string}
|
|
472
|
+
* @memberof FeatureEntitlement
|
|
473
|
+
*/
|
|
474
|
+
monthReset?: FeatureEntitlementMonthResetEnum | null;
|
|
475
|
+
/**
|
|
476
|
+
* For usage-based pricing, the soft limit for overage charges or the next tier boundary
|
|
477
|
+
* @type {number}
|
|
478
|
+
* @memberof FeatureEntitlement
|
|
479
|
+
*/
|
|
480
|
+
softLimit?: number | null;
|
|
481
|
+
/**
|
|
482
|
+
* If the company has a numeric entitlement for this feature, the current usage amount
|
|
483
|
+
* @type {number}
|
|
484
|
+
* @memberof FeatureEntitlement
|
|
485
|
+
*/
|
|
486
|
+
usage?: number | null;
|
|
487
|
+
/**
|
|
488
|
+
* The type of the entitlement value
|
|
489
|
+
* @type {EntitlementValueType}
|
|
490
|
+
* @memberof FeatureEntitlement
|
|
491
|
+
*/
|
|
492
|
+
valueType: EntitlementValueType;
|
|
493
|
+
}
|
|
33
494
|
|
|
34
|
-
|
|
495
|
+
/**
|
|
496
|
+
* @export
|
|
497
|
+
*/
|
|
498
|
+
declare const FeatureEntitlementMetricPeriodEnum: {
|
|
499
|
+
readonly AllTime: "all_time";
|
|
500
|
+
readonly CurrentDay: "current_day";
|
|
501
|
+
readonly CurrentMonth: "current_month";
|
|
502
|
+
readonly CurrentWeek: "current_week";
|
|
503
|
+
};
|
|
35
504
|
|
|
36
|
-
|
|
505
|
+
declare type FeatureEntitlementMetricPeriodEnum = (typeof FeatureEntitlementMetricPeriodEnum)[keyof typeof FeatureEntitlementMetricPeriodEnum];
|
|
37
506
|
|
|
38
|
-
|
|
507
|
+
/**
|
|
508
|
+
* @export
|
|
509
|
+
*/
|
|
510
|
+
declare const FeatureEntitlementMonthResetEnum: {
|
|
511
|
+
readonly FirstOfMonth: "first_of_month";
|
|
512
|
+
readonly BillingCycle: "billing_cycle";
|
|
513
|
+
};
|
|
39
514
|
|
|
40
|
-
|
|
515
|
+
declare type FeatureEntitlementMonthResetEnum = (typeof FeatureEntitlementMonthResetEnum)[keyof typeof FeatureEntitlementMonthResetEnum];
|
|
41
516
|
|
|
42
|
-
|
|
517
|
+
declare type FlagCheckListenerFn = CheckFlagReturnListenerFn | EmptyListenerFn;
|
|
43
518
|
|
|
44
|
-
|
|
519
|
+
declare type FlagValueListenerFn = BooleanListenerFn | EmptyListenerFn;
|
|
520
|
+
|
|
521
|
+
/** A record of unique key-value pairs used for identifying a company or user */
|
|
522
|
+
export declare type Keys = Record<string, string>;
|
|
523
|
+
|
|
524
|
+
declare type PendingListenerFn = BooleanListenerFn | EmptyListenerFn;
|
|
525
|
+
|
|
526
|
+
declare type PlanListenerFn = CheckPlanReturnListenerFn | EmptyListenerFn;
|
|
527
|
+
|
|
528
|
+
export declare enum RuleType {
|
|
529
|
+
/** A global rule that, if present, will override all other rules for a flag */
|
|
530
|
+
GLOBAL_OVERRIDE = "global_override",
|
|
531
|
+
/** Rule type indicating feature access provisioned to a company via an override */
|
|
532
|
+
COMPANY_OVERRIDE = "company_override",
|
|
533
|
+
/** Rule type indicating that feature access has been provisione to a company via an override, but the usage limit has been reached or exceeded */
|
|
534
|
+
COMPANY_OVERRIDE_USAGE_EXCEEDED = "company_override_usage_exceeded",
|
|
535
|
+
/** Rule type indicating feature access provisioned to a company via its base plan or add-ons */
|
|
536
|
+
PLAN_ENTITLEMENT = "plan_entitlement",
|
|
537
|
+
/** Rule type indicating that feature access has been provisione to a company via base plan or add-ons, but the usage limit has been reached or exceeded */
|
|
538
|
+
PLAN_ENTITLEMENT_USAGE_EXCEEDED = "plan_entitlement_usage_exceeded",
|
|
539
|
+
/** General-purpose targeting rule */
|
|
540
|
+
STANDARD = "standard",
|
|
541
|
+
/** Default rule type that will be used if no other rules are matched */
|
|
542
|
+
DEFAULT = "default"
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
export declare class Schematic {
|
|
546
|
+
private additionalHeaders;
|
|
547
|
+
private apiKey;
|
|
548
|
+
private apiUrl;
|
|
549
|
+
private conn;
|
|
550
|
+
private context;
|
|
551
|
+
private debugEnabled;
|
|
552
|
+
private offlineEnabled;
|
|
553
|
+
private eventQueue;
|
|
554
|
+
private contextDependentEventQueue;
|
|
555
|
+
private eventUrl;
|
|
556
|
+
private flagCheckListeners;
|
|
557
|
+
private flagValueListeners;
|
|
558
|
+
private isPending;
|
|
559
|
+
private isPendingListeners;
|
|
560
|
+
private planListeners;
|
|
561
|
+
private storage;
|
|
562
|
+
private useWebSocket;
|
|
563
|
+
private checks;
|
|
564
|
+
private featureUsageEventMap;
|
|
565
|
+
private planChecks;
|
|
566
|
+
private webSocketUrl;
|
|
567
|
+
private webSocketConnectionTimeout;
|
|
568
|
+
private webSocketReconnect;
|
|
569
|
+
private webSocketMaxReconnectAttempts;
|
|
570
|
+
private webSocketMaxConnectionAttempts;
|
|
571
|
+
private webSocketInitialRetryDelay;
|
|
572
|
+
private webSocketMaxRetryDelay;
|
|
573
|
+
private wsReconnectAttempts;
|
|
574
|
+
private wsReconnectTimer;
|
|
575
|
+
private wsIntentionalDisconnect;
|
|
576
|
+
private currentWebSocket;
|
|
577
|
+
private isConnecting;
|
|
578
|
+
private maxEventQueueSize;
|
|
579
|
+
private maxEventRetries;
|
|
580
|
+
private eventRetryInitialDelay;
|
|
581
|
+
private eventRetryMaxDelay;
|
|
582
|
+
private retryTimer;
|
|
583
|
+
private flagValueDefaults;
|
|
584
|
+
private flagCheckDefaults;
|
|
585
|
+
private fallbackCheckCache;
|
|
586
|
+
constructor(apiKey: string, options?: SchematicOptions);
|
|
587
|
+
/**
|
|
588
|
+
* Resolve fallback value according to priority order:
|
|
589
|
+
* 1. Callsite fallback value (if provided)
|
|
590
|
+
* 2. Boolean value from flagCheckDefaults initialization option
|
|
591
|
+
* 3. Boolean value from flagValueDefaults initialization option
|
|
592
|
+
* 4. Default to false
|
|
593
|
+
*/
|
|
594
|
+
private resolveFallbackValue;
|
|
595
|
+
/**
|
|
596
|
+
* Resolve complete CheckFlagReturn object according to priority order:
|
|
597
|
+
* 1. Use callsite fallback for boolean value, construct CheckFlagReturn
|
|
598
|
+
* 2. Use flagCheckDefaults if available for this flag
|
|
599
|
+
* 3. Use flagValueDefaults if available for this flag, construct CheckFlagReturn
|
|
600
|
+
* 4. Default CheckFlagReturn with value: false
|
|
601
|
+
*/
|
|
602
|
+
private resolveFallbackCheckFlagReturn;
|
|
603
|
+
/**
|
|
604
|
+
* Get value for a single flag.
|
|
605
|
+
* In WebSocket mode, returns cached values if connection is active, otherwise establishes
|
|
606
|
+
* new connection and then returns the requested value. Falls back to preconfigured fallback
|
|
607
|
+
* values if WebSocket connection fails.
|
|
608
|
+
* In REST mode, makes an API call for each check.
|
|
609
|
+
*/
|
|
610
|
+
checkFlag(options: CheckOptions): Promise<boolean>;
|
|
611
|
+
/**
|
|
612
|
+
* Helper function to log debug messages
|
|
613
|
+
* Only logs if debug mode is enabled
|
|
614
|
+
*/
|
|
615
|
+
debug(message: string, ...args: unknown[]): void;
|
|
616
|
+
/**
|
|
617
|
+
* Create a persistent message handler for websocket flag updates
|
|
618
|
+
*/
|
|
619
|
+
private createPersistentMessageHandler;
|
|
620
|
+
/**
|
|
621
|
+
* Helper function to check if client is in offline mode
|
|
622
|
+
*/
|
|
623
|
+
private isOffline;
|
|
624
|
+
/**
|
|
625
|
+
* Submit a flag check event
|
|
626
|
+
* Records data about a flag check for analytics
|
|
627
|
+
*/
|
|
628
|
+
private submitFlagCheckEvent;
|
|
629
|
+
/**
|
|
630
|
+
* Make an API call to fetch all flag values for a given context.
|
|
631
|
+
* Recommended for use in REST mode only.
|
|
632
|
+
* In offline mode, returns an empty object.
|
|
633
|
+
*/
|
|
634
|
+
checkFlags: (context?: SchematicContext) => Promise<Record<string, boolean>>;
|
|
635
|
+
/**
|
|
636
|
+
* Send an identify event.
|
|
637
|
+
* This will set the context for subsequent flag evaluation and events, and will also
|
|
638
|
+
* send an identify event to the Schematic API which will upsert a user and company.
|
|
639
|
+
*/
|
|
640
|
+
identify: (body: EventBodyIdentify) => Promise<void>;
|
|
641
|
+
/**
|
|
642
|
+
* Set the flag evaluation context.
|
|
643
|
+
* In WebSocket mode, this will:
|
|
644
|
+
* 1. Open a websocket connection if not already open
|
|
645
|
+
* 2. Send the context to the server
|
|
646
|
+
* 3. Wait for initial flag values to be returned
|
|
647
|
+
* The promise resolves when initial flag values are received.
|
|
648
|
+
* In offline mode, this will just set the context locally without connecting.
|
|
649
|
+
*/
|
|
650
|
+
setContext: (context: SchematicContext) => Promise<void>;
|
|
651
|
+
/**
|
|
652
|
+
* Send a track event
|
|
653
|
+
* Track usage for a company and/or user.
|
|
654
|
+
* Optimistically updates feature usage flags if tracking a featureUsageEvent.
|
|
655
|
+
*/
|
|
656
|
+
track: (body: EventBodyTrack) => Promise<void>;
|
|
657
|
+
/**
|
|
658
|
+
* Optimistically update feature usage flags associated with a tracked event
|
|
659
|
+
* This updates flags in memory with updated usage counts and value/featureUsageExceeded flags
|
|
660
|
+
* before the network request completes
|
|
661
|
+
*/
|
|
662
|
+
private optimisticallyUpdateFeatureUsage;
|
|
663
|
+
/**
|
|
664
|
+
* Event processing
|
|
665
|
+
*/
|
|
666
|
+
private hasContext;
|
|
667
|
+
private flushContextDependentEventQueue;
|
|
668
|
+
private startRetryTimer;
|
|
669
|
+
private stopRetryTimer;
|
|
670
|
+
private flushEventQueue;
|
|
671
|
+
private getAnonymousId;
|
|
672
|
+
private handleEvent;
|
|
673
|
+
private sendEvent;
|
|
674
|
+
private storeEvent;
|
|
675
|
+
/**
|
|
676
|
+
* Websocket management
|
|
677
|
+
*/
|
|
678
|
+
/**
|
|
679
|
+
* Force an immediate WebSocket reconnection.
|
|
680
|
+
* This is useful when the application returns from a background state (e.g., mobile app
|
|
681
|
+
* coming back to foreground) and wants to immediately re-establish the connection
|
|
682
|
+
* rather than waiting for the exponential backoff timer.
|
|
683
|
+
*
|
|
684
|
+
* This method will:
|
|
685
|
+
* - Cancel any pending reconnection timer
|
|
686
|
+
* - Reset the reconnection attempt counter
|
|
687
|
+
* - Close any existing connection
|
|
688
|
+
* - Immediately attempt to reconnect
|
|
689
|
+
* - Re-send the current context to get fresh flag values
|
|
690
|
+
*
|
|
691
|
+
* Use this when you need guaranteed fresh values (e.g., after an in-app purchase).
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```typescript
|
|
695
|
+
* // React Native example: reconnect when app comes to foreground
|
|
696
|
+
* useEffect(() => {
|
|
697
|
+
* const subscription = AppState.addEventListener("change", (state) => {
|
|
698
|
+
* if (state === "active") {
|
|
699
|
+
* client.forceReconnect();
|
|
700
|
+
* }
|
|
701
|
+
* });
|
|
702
|
+
* return () => subscription.remove();
|
|
703
|
+
* }, [client]);
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
706
|
+
forceReconnect: () => Promise<void>;
|
|
707
|
+
/**
|
|
708
|
+
* Reconnect the WebSocket connection only if the current connection is unhealthy.
|
|
709
|
+
* This is useful when the application returns from a background state and wants to
|
|
710
|
+
* ensure a healthy connection exists, but doesn't need to force a reconnection if
|
|
711
|
+
* the connection is still active.
|
|
712
|
+
*
|
|
713
|
+
* This method will:
|
|
714
|
+
* - Check if an existing connection is healthy (readyState === OPEN)
|
|
715
|
+
* - If healthy, return immediately without reconnecting
|
|
716
|
+
* - If unhealthy, perform the same reconnection logic as forceReconnect()
|
|
717
|
+
*
|
|
718
|
+
* Use this when you want efficient reconnection that avoids unnecessary disconnects.
|
|
719
|
+
*
|
|
720
|
+
* @example
|
|
721
|
+
* ```typescript
|
|
722
|
+
* // React Native example: reconnect only if needed when app comes to foreground
|
|
723
|
+
* useEffect(() => {
|
|
724
|
+
* const subscription = AppState.addEventListener("change", (state) => {
|
|
725
|
+
* if (state === "active") {
|
|
726
|
+
* client.reconnectIfNeeded();
|
|
727
|
+
* }
|
|
728
|
+
* });
|
|
729
|
+
* return () => subscription.remove();
|
|
730
|
+
* }, [client]);
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
reconnectIfNeeded: () => Promise<void>;
|
|
734
|
+
/**
|
|
735
|
+
* Internal method to handle reconnection logic for both forceReconnect and reconnectIfNeeded.
|
|
736
|
+
*/
|
|
737
|
+
private reconnect;
|
|
738
|
+
/**
|
|
739
|
+
* If using websocket mode, close the connection when done.
|
|
740
|
+
* In offline mode, this is a no-op.
|
|
741
|
+
*/
|
|
742
|
+
cleanup: () => Promise<void>;
|
|
743
|
+
/**
|
|
744
|
+
* Calculate the delay for the next reconnection attempt using exponential backoff with jitter.
|
|
745
|
+
* This helps prevent dogpiling when the server recovers from an outage.
|
|
746
|
+
*/
|
|
747
|
+
private calculateReconnectDelay;
|
|
748
|
+
/**
|
|
749
|
+
* Handle browser going offline
|
|
750
|
+
*/
|
|
751
|
+
private handleNetworkOffline;
|
|
752
|
+
/**
|
|
753
|
+
* Handle browser coming back online
|
|
754
|
+
*/
|
|
755
|
+
private handleNetworkOnline;
|
|
756
|
+
/**
|
|
757
|
+
* Attempt to reconnect the WebSocket connection with exponential backoff.
|
|
758
|
+
* Called automatically when the connection closes unexpectedly.
|
|
759
|
+
*/
|
|
760
|
+
private attemptReconnect;
|
|
761
|
+
private wsConnect;
|
|
762
|
+
private wsConnectOnce;
|
|
763
|
+
private wsSendMessage;
|
|
764
|
+
/**
|
|
765
|
+
* State management
|
|
766
|
+
*/
|
|
767
|
+
getIsPending: () => boolean;
|
|
768
|
+
addIsPendingListener: (listener: PendingListenerFn) => () => void;
|
|
769
|
+
private setIsPending;
|
|
770
|
+
getPlan: () => CheckPlanReturn | undefined;
|
|
771
|
+
getFlagCheck: (flagKey: string) => CheckFlagReturn | undefined;
|
|
772
|
+
getFlagValue: (flagKey: string) => boolean | undefined;
|
|
773
|
+
/** Register an event listener that will be notified with the boolean value for a given flag when this value changes */
|
|
774
|
+
addFlagValueListener: (flagKey: string, listener: FlagValueListenerFn) => () => void;
|
|
775
|
+
/** Register an event listener that will be notified with the full flag check response for a given flag whenever this value changes */
|
|
776
|
+
addFlagCheckListener: (flagKey: string, listener: FlagCheckListenerFn) => () => void;
|
|
777
|
+
addPlanListener: (listener: PlanListenerFn) => () => void;
|
|
778
|
+
private notifyFlagCheckListeners;
|
|
779
|
+
/** Add or update a CheckFlagReturn in the featureUsageEventMap */
|
|
780
|
+
private updateFeatureUsageEventMap;
|
|
781
|
+
private notifyFlagValueListeners;
|
|
782
|
+
private notifyPlanListeners;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/** Context for checking flags and sending events */
|
|
786
|
+
export declare type SchematicContext = {
|
|
787
|
+
company?: Keys;
|
|
788
|
+
user?: Keys;
|
|
789
|
+
};
|
|
45
790
|
|
|
46
791
|
declare interface SchematicContextProps {
|
|
47
792
|
client: SchematicJS.Schematic;
|
|
@@ -51,7 +796,87 @@ export declare interface SchematicHookOpts {
|
|
|
51
796
|
client?: SchematicJS.Schematic;
|
|
52
797
|
}
|
|
53
798
|
|
|
54
|
-
|
|
799
|
+
declare namespace SchematicJS {
|
|
800
|
+
export {
|
|
801
|
+
CheckFlagResponseFromJSON,
|
|
802
|
+
CheckFlagsResponseFromJSON,
|
|
803
|
+
DatastreamCompanyPlanFromJSON,
|
|
804
|
+
EventBodyFlagCheckToJSON,
|
|
805
|
+
BooleanListenerFn,
|
|
806
|
+
CheckFlagResponseData,
|
|
807
|
+
CheckFlagReturn,
|
|
808
|
+
CheckFlagReturnFromJSON,
|
|
809
|
+
CheckFlagReturnListenerFn,
|
|
810
|
+
CheckOptions,
|
|
811
|
+
CheckPlanReturn,
|
|
812
|
+
CheckPlanReturnFromJSON,
|
|
813
|
+
CheckPlanReturnListenerFn,
|
|
814
|
+
EmptyListenerFn,
|
|
815
|
+
Event_2 as Event,
|
|
816
|
+
EventBody,
|
|
817
|
+
EventBodyFlagCheck,
|
|
818
|
+
EventBodyIdentify,
|
|
819
|
+
EventBodyTrack,
|
|
820
|
+
EventType,
|
|
821
|
+
FlagCheckListenerFn,
|
|
822
|
+
FlagValueListenerFn,
|
|
823
|
+
Keys,
|
|
824
|
+
PendingListenerFn,
|
|
825
|
+
PlanListenerFn,
|
|
826
|
+
RuleType,
|
|
827
|
+
Schematic,
|
|
828
|
+
SchematicContext,
|
|
829
|
+
SchematicOptions,
|
|
830
|
+
StoragePersister,
|
|
831
|
+
Traits,
|
|
832
|
+
TrialStatus,
|
|
833
|
+
UsagePeriod
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
export declare type SchematicOptions = {
|
|
838
|
+
/** Optionally provide any additional headers to include in the request */
|
|
839
|
+
additionalHeaders?: Record<string, string>;
|
|
840
|
+
/** Optionally provide a custom API URL */
|
|
841
|
+
apiUrl?: string;
|
|
842
|
+
/** Enable debug mode to log flag check results and events to the console.
|
|
843
|
+
* Can also be enabled at runtime via URL query parameter "schematic_debug=true" */
|
|
844
|
+
debug?: boolean;
|
|
845
|
+
/** Optionally provide a custom event URL */
|
|
846
|
+
eventUrl?: string;
|
|
847
|
+
/** Enable offline mode to prevent all network requests.
|
|
848
|
+
* When enabled, events are only logged not sent, and flag checks return fallback values.
|
|
849
|
+
* Can also be enabled at runtime via URL query parameter "schematic_offline=true" */
|
|
850
|
+
offline?: boolean;
|
|
851
|
+
/** Optionally provide a custom storage persister for client-side storage */
|
|
852
|
+
storage?: StoragePersister;
|
|
853
|
+
/** Use a WebSocket connection for real-time flag checks; if using this, run the cleanup function to close the connection */
|
|
854
|
+
useWebSocket?: boolean;
|
|
855
|
+
/** Optionally provide a custom WebSocket URL */
|
|
856
|
+
webSocketUrl?: string;
|
|
857
|
+
/** WebSocket connection timeout in milliseconds (default: 10000) */
|
|
858
|
+
webSocketConnectionTimeout?: number;
|
|
859
|
+
/** Enable automatic reconnection on WebSocket disconnect (default: true) */
|
|
860
|
+
webSocketReconnect?: boolean;
|
|
861
|
+
/** Maximum number of reconnection attempts (default: 7, set to Infinity for unlimited) */
|
|
862
|
+
webSocketMaxReconnectAttempts?: number;
|
|
863
|
+
/** Initial retry delay in milliseconds for exponential backoff (default: 1000) */
|
|
864
|
+
webSocketInitialRetryDelay?: number;
|
|
865
|
+
/** Maximum retry delay in milliseconds for exponential backoff (default: 30000) */
|
|
866
|
+
webSocketMaxRetryDelay?: number;
|
|
867
|
+
/** Maximum number of events to queue for retry when network is down (default: 100) */
|
|
868
|
+
maxEventQueueSize?: number;
|
|
869
|
+
/** Maximum number of retry attempts for failed events (default: 5) */
|
|
870
|
+
maxEventRetries?: number;
|
|
871
|
+
/** Initial retry delay in milliseconds for failed events (default: 1000) */
|
|
872
|
+
eventRetryInitialDelay?: number;
|
|
873
|
+
/** Maximum retry delay in milliseconds for failed events (default: 30000) */
|
|
874
|
+
eventRetryMaxDelay?: number;
|
|
875
|
+
/** Default boolean values for flags when Schematic API cannot be reached and no callsite fallback is provided */
|
|
876
|
+
flagValueDefaults?: Record<string, boolean>;
|
|
877
|
+
/** Default CheckFlagReturn objects for flags when Schematic API cannot be reached and no callsite fallback is provided */
|
|
878
|
+
flagCheckDefaults?: Record<string, CheckFlagReturn>;
|
|
879
|
+
};
|
|
55
880
|
|
|
56
881
|
export declare const SchematicProvider: React_2.FC<SchematicProviderProps>;
|
|
57
882
|
|
|
@@ -67,13 +892,36 @@ declare type SchematicProviderPropsWithPublishableKey = BaseSchematicProviderPro
|
|
|
67
892
|
publishableKey: string;
|
|
68
893
|
};
|
|
69
894
|
|
|
70
|
-
|
|
895
|
+
/** Optional type for implementing custom client-side storage */
|
|
896
|
+
export declare type StoragePersister = {
|
|
897
|
+
setItem(key: string, value: any): void;
|
|
898
|
+
getItem(key: string): any;
|
|
899
|
+
removeItem(key: string): void;
|
|
900
|
+
};
|
|
71
901
|
|
|
72
|
-
|
|
902
|
+
/**
|
|
903
|
+
* A flexible key/value type that can store any type of value on a company or user.
|
|
904
|
+
*/
|
|
905
|
+
export declare type Traits = Record<string, any>;
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
*
|
|
909
|
+
* @export
|
|
910
|
+
*/
|
|
911
|
+
export declare const TrialStatus: {
|
|
912
|
+
readonly Active: "active";
|
|
913
|
+
readonly Converted: "converted";
|
|
914
|
+
readonly Expired: "expired";
|
|
915
|
+
};
|
|
73
916
|
|
|
74
|
-
export
|
|
917
|
+
export declare type TrialStatus = (typeof TrialStatus)[keyof typeof TrialStatus];
|
|
75
918
|
|
|
76
|
-
export
|
|
919
|
+
export declare enum UsagePeriod {
|
|
920
|
+
ALL_TIME = "all_time",
|
|
921
|
+
CURRENT_DAY = "current_day",
|
|
922
|
+
CURRENT_MONTH = "current_month",
|
|
923
|
+
CURRENT_WEEK = "current_week"
|
|
924
|
+
}
|
|
77
925
|
|
|
78
926
|
export declare const useSchematic: () => SchematicContextProps;
|
|
79
927
|
|
|
@@ -762,6 +762,7 @@ var UsagePeriod = /* @__PURE__ */ ((UsagePeriod2) => {
|
|
|
762
762
|
var CheckFlagReturnFromJSON = (json) => {
|
|
763
763
|
const {
|
|
764
764
|
companyId,
|
|
765
|
+
entitlement,
|
|
765
766
|
error,
|
|
766
767
|
featureAllocation,
|
|
767
768
|
featureUsage,
|
|
@@ -779,20 +780,27 @@ var CheckFlagReturnFromJSON = (json) => {
|
|
|
779
780
|
const featureUsageExceeded = !value && // if flag is not false, then we haven't exceeded usage
|
|
780
781
|
(ruleType == "company_override_usage_exceeded" || // if the rule type is one of these, then we have exceeded usage
|
|
781
782
|
ruleType == "plan_entitlement_usage_exceeded");
|
|
783
|
+
const resolvedAllocation = entitlement?.allocation ?? featureAllocation;
|
|
784
|
+
const resolvedUsage = entitlement?.usage ?? featureUsage;
|
|
785
|
+
const resolvedEvent = entitlement?.eventName ?? featureUsageEvent;
|
|
786
|
+
const resolvedPeriod = entitlement?.metricPeriod ?? featureUsagePeriod;
|
|
787
|
+
const resolvedResetAt = entitlement?.metricResetAt ?? featureUsageResetAt;
|
|
782
788
|
return {
|
|
783
789
|
featureUsageExceeded,
|
|
784
790
|
companyId: companyId == null ? void 0 : companyId,
|
|
791
|
+
creditRemaining: entitlement?.creditRemaining == null ? void 0 : entitlement.creditRemaining,
|
|
785
792
|
error: error == null ? void 0 : error,
|
|
786
|
-
featureAllocation:
|
|
787
|
-
featureUsage:
|
|
788
|
-
featureUsageEvent:
|
|
789
|
-
featureUsagePeriod:
|
|
790
|
-
featureUsageResetAt:
|
|
793
|
+
featureAllocation: resolvedAllocation == null ? void 0 : resolvedAllocation,
|
|
794
|
+
featureUsage: resolvedUsage == null ? void 0 : resolvedUsage,
|
|
795
|
+
featureUsageEvent: resolvedEvent == null ? void 0 : resolvedEvent,
|
|
796
|
+
featureUsagePeriod: resolvedPeriod == null ? void 0 : resolvedPeriod,
|
|
797
|
+
featureUsageResetAt: resolvedResetAt == null ? void 0 : resolvedResetAt,
|
|
791
798
|
flag,
|
|
792
799
|
flagId: flagId == null ? void 0 : flagId,
|
|
793
800
|
reason,
|
|
794
801
|
ruleId: ruleId == null ? void 0 : ruleId,
|
|
795
802
|
ruleType: ruleType == null ? void 0 : ruleType,
|
|
803
|
+
softLimit: entitlement?.softLimit == null ? void 0 : entitlement.softLimit,
|
|
796
804
|
userId: userId == null ? void 0 : userId,
|
|
797
805
|
value
|
|
798
806
|
};
|
|
@@ -820,7 +828,7 @@ function contextString(context) {
|
|
|
820
828
|
}, {});
|
|
821
829
|
return JSON.stringify(sortedContext);
|
|
822
830
|
}
|
|
823
|
-
var version = "1.
|
|
831
|
+
var version = "1.4.0";
|
|
824
832
|
var anonymousIdKey = "schematicId";
|
|
825
833
|
var Schematic = class {
|
|
826
834
|
additionalHeaders = {};
|
|
@@ -2257,7 +2265,7 @@ var notifyPlanListener = (listener, value) => {
|
|
|
2257
2265
|
import React, { createContext, useEffect, useMemo, useRef } from "react";
|
|
2258
2266
|
|
|
2259
2267
|
// src/version.ts
|
|
2260
|
-
var version2 = "1.
|
|
2268
|
+
var version2 = "1.4.1";
|
|
2261
2269
|
|
|
2262
2270
|
// src/context/schematic.tsx
|
|
2263
2271
|
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.
|
|
3
|
+
"version": "1.4.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",
|
|
@@ -30,12 +30,10 @@
|
|
|
30
30
|
"tsc": "npx tsc",
|
|
31
31
|
"prepare": "husky"
|
|
32
32
|
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"@schematichq/schematic-js": "^1.3.1"
|
|
35
|
-
},
|
|
36
33
|
"devDependencies": {
|
|
37
34
|
"@eslint/js": "^10.0.1",
|
|
38
|
-
"@microsoft/api-extractor": "^7.58.
|
|
35
|
+
"@microsoft/api-extractor": "^7.58.2",
|
|
36
|
+
"@schematichq/schematic-js": "^1.4.0",
|
|
39
37
|
"@testing-library/dom": "^10.4.1",
|
|
40
38
|
"@testing-library/jest-dom": "^6.9.1",
|
|
41
39
|
"@testing-library/react": "^16.3.2",
|
|
@@ -45,16 +43,16 @@
|
|
|
45
43
|
"eslint": "^10.2.0",
|
|
46
44
|
"eslint-plugin-import": "^2.32.0",
|
|
47
45
|
"eslint-plugin-react": "^7.37.5",
|
|
48
|
-
"eslint-plugin-react-hooks": "^7.0
|
|
49
|
-
"globals": "^17.
|
|
50
|
-
"happy-dom": "^20.
|
|
46
|
+
"eslint-plugin-react-hooks": "^7.1.0",
|
|
47
|
+
"globals": "^17.5.0",
|
|
48
|
+
"happy-dom": "^20.9.0",
|
|
51
49
|
"husky": "^9.1.7",
|
|
52
|
-
"jsdom": "^29.0.
|
|
53
|
-
"prettier": "^3.8.
|
|
54
|
-
"react": "^19.2.
|
|
55
|
-
"react-dom": "^19.2.
|
|
56
|
-
"typescript": "^6.0.
|
|
57
|
-
"typescript-eslint": "^8.58.
|
|
50
|
+
"jsdom": "^29.0.2",
|
|
51
|
+
"prettier": "^3.8.3",
|
|
52
|
+
"react": "^19.2.5",
|
|
53
|
+
"react-dom": "^19.2.5",
|
|
54
|
+
"typescript": "^6.0.3",
|
|
55
|
+
"typescript-eslint": "^8.58.2",
|
|
58
56
|
"vitest": "^4.0.18"
|
|
59
57
|
},
|
|
60
58
|
"peerDependencies": {
|