@schematichq/schematic-react 1.0.3 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,17 +28,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ RuleType: () => RuleType,
33
34
  Schematic: () => Schematic,
34
35
  SchematicProvider: () => SchematicProvider,
36
+ UsagePeriod: () => UsagePeriod,
35
37
  useSchematic: () => useSchematic,
36
38
  useSchematicContext: () => useSchematicContext,
39
+ useSchematicEntitlement: () => useSchematicEntitlement,
37
40
  useSchematicEvents: () => useSchematicEvents,
38
41
  useSchematicFlag: () => useSchematicFlag,
39
42
  useSchematicIsPending: () => useSchematicIsPending
40
43
  });
41
- module.exports = __toCommonJS(src_exports);
44
+ module.exports = __toCommonJS(index_exports);
42
45
 
43
46
  // node_modules/@schematichq/schematic-js/dist/schematic.esm.js
44
47
  var __create2 = Object.create;
@@ -70,11 +73,12 @@ var require_browser_polyfill = __commonJS({
70
73
  "node_modules/cross-fetch/dist/browser-polyfill.js"(exports) {
71
74
  (function(self2) {
72
75
  var irrelevant = function(exports2) {
73
- var global = typeof globalThis !== "undefined" && globalThis || typeof self2 !== "undefined" && self2 || typeof global !== "undefined" && global;
76
+ var g = typeof globalThis !== "undefined" && globalThis || typeof self2 !== "undefined" && self2 || // eslint-disable-next-line no-undef
77
+ typeof global !== "undefined" && global || {};
74
78
  var support = {
75
- searchParams: "URLSearchParams" in global,
76
- iterable: "Symbol" in global && "iterator" in Symbol,
77
- blob: "FileReader" in global && "Blob" in global && function() {
79
+ searchParams: "URLSearchParams" in g,
80
+ iterable: "Symbol" in g && "iterator" in Symbol,
81
+ blob: "FileReader" in g && "Blob" in g && function() {
78
82
  try {
79
83
  new Blob();
80
84
  return true;
@@ -82,8 +86,8 @@ var require_browser_polyfill = __commonJS({
82
86
  return false;
83
87
  }
84
88
  }(),
85
- formData: "FormData" in global,
86
- arrayBuffer: "ArrayBuffer" in global
89
+ formData: "FormData" in g,
90
+ arrayBuffer: "ArrayBuffer" in g
87
91
  };
88
92
  function isDataView(obj) {
89
93
  return obj && DataView.prototype.isPrototypeOf(obj);
@@ -141,6 +145,9 @@ var require_browser_polyfill = __commonJS({
141
145
  }, this);
142
146
  } else if (Array.isArray(headers)) {
143
147
  headers.forEach(function(header) {
148
+ if (header.length != 2) {
149
+ throw new TypeError("Headers constructor: expected name/value pair to be length 2, found" + header.length);
150
+ }
144
151
  this.append(header[0], header[1]);
145
152
  }, this);
146
153
  } else if (headers) {
@@ -200,6 +207,7 @@ var require_browser_polyfill = __commonJS({
200
207
  Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
201
208
  }
202
209
  function consumed(body) {
210
+ if (body._noBody) return;
203
211
  if (body.bodyUsed) {
204
212
  return Promise.reject(new TypeError("Already read"));
205
213
  }
@@ -224,14 +232,16 @@ var require_browser_polyfill = __commonJS({
224
232
  function readBlobAsText(blob) {
225
233
  var reader = new FileReader();
226
234
  var promise = fileReaderReady(reader);
227
- reader.readAsText(blob);
235
+ var match = /charset=([A-Za-z0-9_-]+)/.exec(blob.type);
236
+ var encoding = match ? match[1] : "utf-8";
237
+ reader.readAsText(blob, encoding);
228
238
  return promise;
229
239
  }
230
240
  function readArrayBufferAsText(buf) {
231
241
  var view = new Uint8Array(buf);
232
242
  var chars = new Array(view.length);
233
- for (var i2 = 0; i2 < view.length; i2++) {
234
- chars[i2] = String.fromCharCode(view[i2]);
243
+ for (var i = 0; i < view.length; i++) {
244
+ chars[i] = String.fromCharCode(view[i]);
235
245
  }
236
246
  return chars.join("");
237
247
  }
@@ -250,6 +260,7 @@ var require_browser_polyfill = __commonJS({
250
260
  this.bodyUsed = this.bodyUsed;
251
261
  this._bodyInit = body;
252
262
  if (!body) {
263
+ this._noBody = true;
253
264
  this._bodyText = "";
254
265
  } else if (typeof body === "string") {
255
266
  this._bodyText = body;
@@ -293,27 +304,28 @@ var require_browser_polyfill = __commonJS({
293
304
  return Promise.resolve(new Blob([this._bodyText]));
294
305
  }
295
306
  };
296
- this.arrayBuffer = function() {
297
- if (this._bodyArrayBuffer) {
298
- var isConsumed = consumed(this);
299
- if (isConsumed) {
300
- return isConsumed;
301
- }
302
- if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
303
- return Promise.resolve(
304
- this._bodyArrayBuffer.buffer.slice(
305
- this._bodyArrayBuffer.byteOffset,
306
- this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
307
- )
308
- );
309
- } else {
310
- return Promise.resolve(this._bodyArrayBuffer);
311
- }
307
+ }
308
+ this.arrayBuffer = function() {
309
+ if (this._bodyArrayBuffer) {
310
+ var isConsumed = consumed(this);
311
+ if (isConsumed) {
312
+ return isConsumed;
313
+ } else if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
314
+ return Promise.resolve(
315
+ this._bodyArrayBuffer.buffer.slice(
316
+ this._bodyArrayBuffer.byteOffset,
317
+ this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
318
+ )
319
+ );
312
320
  } else {
313
- return this.blob().then(readBlobAsArrayBuffer);
321
+ return Promise.resolve(this._bodyArrayBuffer);
314
322
  }
315
- };
316
- }
323
+ } else if (support.blob) {
324
+ return this.blob().then(readBlobAsArrayBuffer);
325
+ } else {
326
+ throw new Error("could not read as ArrayBuffer");
327
+ }
328
+ };
317
329
  this.text = function() {
318
330
  var rejected = consumed(this);
319
331
  if (rejected) {
@@ -339,7 +351,7 @@ var require_browser_polyfill = __commonJS({
339
351
  };
340
352
  return this;
341
353
  }
342
- var methods = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"];
354
+ var methods = ["CONNECT", "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "TRACE"];
343
355
  function normalizeMethod(method) {
344
356
  var upcased = method.toUpperCase();
345
357
  return methods.indexOf(upcased) > -1 ? upcased : method;
@@ -375,7 +387,12 @@ var require_browser_polyfill = __commonJS({
375
387
  }
376
388
  this.method = normalizeMethod(options.method || this.method || "GET");
377
389
  this.mode = options.mode || this.mode || null;
378
- this.signal = options.signal || this.signal;
390
+ this.signal = options.signal || this.signal || function() {
391
+ if ("AbortController" in g) {
392
+ var ctrl = new AbortController();
393
+ return ctrl.signal;
394
+ }
395
+ }();
379
396
  this.referrer = null;
380
397
  if ((this.method === "GET" || this.method === "HEAD") && body) {
381
398
  throw new TypeError("Body not allowed for GET or HEAD requests");
@@ -418,7 +435,11 @@ var require_browser_polyfill = __commonJS({
418
435
  var key = parts.shift().trim();
419
436
  if (key) {
420
437
  var value = parts.join(":").trim();
421
- headers.append(key, value);
438
+ try {
439
+ headers.append(key, value);
440
+ } catch (error) {
441
+ console.warn("Response " + error.message);
442
+ }
422
443
  }
423
444
  });
424
445
  return headers;
@@ -433,6 +454,9 @@ var require_browser_polyfill = __commonJS({
433
454
  }
434
455
  this.type = "default";
435
456
  this.status = options.status === void 0 ? 200 : options.status;
457
+ if (this.status < 200 || this.status > 599) {
458
+ throw new RangeError("Failed to construct 'Response': The status provided (0) is outside the range [200, 599].");
459
+ }
436
460
  this.ok = this.status >= 200 && this.status < 300;
437
461
  this.statusText = options.statusText === void 0 ? "" : "" + options.statusText;
438
462
  this.headers = new Headers(options.headers);
@@ -449,7 +473,9 @@ var require_browser_polyfill = __commonJS({
449
473
  });
450
474
  };
451
475
  Response.error = function() {
452
- var response = new Response(null, { status: 0, statusText: "" });
476
+ var response = new Response(null, { status: 200, statusText: "" });
477
+ response.ok = false;
478
+ response.status = 0;
453
479
  response.type = "error";
454
480
  return response;
455
481
  };
@@ -460,7 +486,7 @@ var require_browser_polyfill = __commonJS({
460
486
  }
461
487
  return new Response(null, { status, headers: { location: url } });
462
488
  };
463
- exports2.DOMException = global.DOMException;
489
+ exports2.DOMException = g.DOMException;
464
490
  try {
465
491
  new exports2.DOMException();
466
492
  } catch (err) {
@@ -485,10 +511,14 @@ var require_browser_polyfill = __commonJS({
485
511
  }
486
512
  xhr.onload = function() {
487
513
  var options = {
488
- status: xhr.status,
489
514
  statusText: xhr.statusText,
490
515
  headers: parseHeaders(xhr.getAllResponseHeaders() || "")
491
516
  };
517
+ if (request.url.indexOf("file://") === 0 && (xhr.status < 200 || xhr.status > 599)) {
518
+ options.status = 200;
519
+ } else {
520
+ options.status = xhr.status;
521
+ }
492
522
  options.url = "responseURL" in xhr ? xhr.responseURL : options.headers.get("X-Request-URL");
493
523
  var body = "response" in xhr ? xhr.response : xhr.responseText;
494
524
  setTimeout(function() {
@@ -502,7 +532,7 @@ var require_browser_polyfill = __commonJS({
502
532
  };
503
533
  xhr.ontimeout = function() {
504
534
  setTimeout(function() {
505
- reject(new TypeError("Network request failed"));
535
+ reject(new TypeError("Network request timed out"));
506
536
  }, 0);
507
537
  };
508
538
  xhr.onabort = function() {
@@ -512,7 +542,7 @@ var require_browser_polyfill = __commonJS({
512
542
  };
513
543
  function fixUrl(url) {
514
544
  try {
515
- return url === "" && global.location.href ? global.location.href : url;
545
+ return url === "" && g.location.href ? g.location.href : url;
516
546
  } catch (e) {
517
547
  return url;
518
548
  }
@@ -526,14 +556,21 @@ var require_browser_polyfill = __commonJS({
526
556
  if ("responseType" in xhr) {
527
557
  if (support.blob) {
528
558
  xhr.responseType = "blob";
529
- } else if (support.arrayBuffer && request.headers.get("Content-Type") && request.headers.get("Content-Type").indexOf("application/octet-stream") !== -1) {
559
+ } else if (support.arrayBuffer) {
530
560
  xhr.responseType = "arraybuffer";
531
561
  }
532
562
  }
533
- if (init && typeof init.headers === "object" && !(init.headers instanceof Headers)) {
563
+ if (init && typeof init.headers === "object" && !(init.headers instanceof Headers || g.Headers && init.headers instanceof g.Headers)) {
564
+ var names = [];
534
565
  Object.getOwnPropertyNames(init.headers).forEach(function(name) {
566
+ names.push(normalizeName(name));
535
567
  xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
536
568
  });
569
+ request.headers.forEach(function(value, name) {
570
+ if (names.indexOf(name) === -1) {
571
+ xhr.setRequestHeader(name, value);
572
+ }
573
+ });
537
574
  } else {
538
575
  request.headers.forEach(function(value, name) {
539
576
  xhr.setRequestHeader(name, value);
@@ -551,11 +588,11 @@ var require_browser_polyfill = __commonJS({
551
588
  });
552
589
  }
553
590
  fetch2.polyfill = true;
554
- if (!global.fetch) {
555
- global.fetch = fetch2;
556
- global.Headers = Headers;
557
- global.Request = Request;
558
- global.Response = Response;
591
+ if (!g.fetch) {
592
+ g.fetch = fetch2;
593
+ g.Headers = Headers;
594
+ g.Request = Request;
595
+ g.Response = Response;
559
596
  }
560
597
  exports2.Headers = Headers;
561
598
  exports2.Request = Request;
@@ -567,10 +604,9 @@ var require_browser_polyfill = __commonJS({
567
604
  }
568
605
  });
569
606
  var byteToHex = [];
570
- for (i = 0; i < 256; ++i) {
607
+ for (let i = 0; i < 256; ++i) {
571
608
  byteToHex.push((i + 256).toString(16).slice(1));
572
609
  }
573
- var i;
574
610
  function unsafeStringify(arr, offset = 0) {
575
611
  return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
576
612
  }
@@ -578,29 +614,33 @@ var getRandomValues;
578
614
  var rnds8 = new Uint8Array(16);
579
615
  function rng() {
580
616
  if (!getRandomValues) {
581
- getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
582
- if (!getRandomValues) {
617
+ if (typeof crypto === "undefined" || !crypto.getRandomValues) {
583
618
  throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
584
619
  }
620
+ getRandomValues = crypto.getRandomValues.bind(crypto);
585
621
  }
586
622
  return getRandomValues(rnds8);
587
623
  }
588
624
  var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
589
- var native_default = {
590
- randomUUID
591
- };
625
+ var native_default = { randomUUID };
592
626
  function v4(options, buf, offset) {
593
627
  if (native_default.randomUUID && !buf && !options) {
594
628
  return native_default.randomUUID();
595
629
  }
596
630
  options = options || {};
597
- var rnds = options.random || (options.rng || rng)();
631
+ const rnds = options.random ?? options.rng?.() ?? rng();
632
+ if (rnds.length < 16) {
633
+ throw new Error("Random bytes length must be >= 16");
634
+ }
598
635
  rnds[6] = rnds[6] & 15 | 64;
599
636
  rnds[8] = rnds[8] & 63 | 128;
600
637
  if (buf) {
601
638
  offset = offset || 0;
602
- for (var i2 = 0; i2 < 16; ++i2) {
603
- buf[offset + i2] = rnds[i2];
639
+ if (offset < 0 || offset + 16 > buf.length) {
640
+ throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);
641
+ }
642
+ for (let i = 0; i < 16; ++i) {
643
+ buf[offset + i] = rnds[i];
604
644
  }
605
645
  return buf;
606
646
  }
@@ -608,6 +648,117 @@ function v4(options, buf, offset) {
608
648
  }
609
649
  var v4_default = v4;
610
650
  var import_polyfill = __toESM2(require_browser_polyfill());
651
+ function CheckFlagResponseDataFromJSON(json) {
652
+ return CheckFlagResponseDataFromJSONTyped(json, false);
653
+ }
654
+ function CheckFlagResponseDataFromJSONTyped(json, ignoreDiscriminator) {
655
+ if (json == null) {
656
+ return json;
657
+ }
658
+ return {
659
+ companyId: json["company_id"] == null ? void 0 : json["company_id"],
660
+ error: json["error"] == null ? void 0 : json["error"],
661
+ featureAllocation: json["feature_allocation"] == null ? void 0 : json["feature_allocation"],
662
+ featureUsage: json["feature_usage"] == null ? void 0 : json["feature_usage"],
663
+ featureUsagePeriod: json["feature_usage_period"] == null ? void 0 : json["feature_usage_period"],
664
+ featureUsageResetAt: json["feature_usage_reset_at"] == null ? void 0 : new Date(json["feature_usage_reset_at"]),
665
+ flag: json["flag"],
666
+ flagId: json["flag_id"] == null ? void 0 : json["flag_id"],
667
+ reason: json["reason"],
668
+ ruleId: json["rule_id"] == null ? void 0 : json["rule_id"],
669
+ ruleType: json["rule_type"] == null ? void 0 : json["rule_type"],
670
+ userId: json["user_id"] == null ? void 0 : json["user_id"],
671
+ value: json["value"]
672
+ };
673
+ }
674
+ function CheckFlagResponseFromJSON(json) {
675
+ return CheckFlagResponseFromJSONTyped(json, false);
676
+ }
677
+ function CheckFlagResponseFromJSONTyped(json, ignoreDiscriminator) {
678
+ if (json == null) {
679
+ return json;
680
+ }
681
+ return {
682
+ data: CheckFlagResponseDataFromJSON(json["data"]),
683
+ params: json["params"]
684
+ };
685
+ }
686
+ function CheckFlagsResponseDataFromJSON(json) {
687
+ return CheckFlagsResponseDataFromJSONTyped(json, false);
688
+ }
689
+ function CheckFlagsResponseDataFromJSONTyped(json, ignoreDiscriminator) {
690
+ if (json == null) {
691
+ return json;
692
+ }
693
+ return {
694
+ flags: json["flags"].map(CheckFlagResponseDataFromJSON)
695
+ };
696
+ }
697
+ function CheckFlagsResponseFromJSON(json) {
698
+ return CheckFlagsResponseFromJSONTyped(json, false);
699
+ }
700
+ function CheckFlagsResponseFromJSONTyped(json, ignoreDiscriminator) {
701
+ if (json == null) {
702
+ return json;
703
+ }
704
+ return {
705
+ data: CheckFlagsResponseDataFromJSON(json["data"]),
706
+ params: json["params"]
707
+ };
708
+ }
709
+ var RuleType = /* @__PURE__ */ ((RuleType2) => {
710
+ RuleType2["GLOBAL_OVERRIDE"] = "global_override";
711
+ RuleType2["COMPANY_OVERRIDE"] = "company_override";
712
+ RuleType2["COMPANY_OVERRIDE_USAGE_EXCEEDED"] = "company_override_usage_exceeded";
713
+ RuleType2["PLAN_ENTITLEMENT"] = "plan_entitlement";
714
+ RuleType2["PLAN_ENTITLEMENT_USAGE_EXCEEDED"] = "plan_entitlement_usage_exceeded";
715
+ RuleType2["STANDARD"] = "standard";
716
+ RuleType2["DEFAULT"] = "default";
717
+ return RuleType2;
718
+ })(RuleType || {});
719
+ var UsagePeriod = /* @__PURE__ */ ((UsagePeriod2) => {
720
+ UsagePeriod2["ALL_TIME"] = "all_time";
721
+ UsagePeriod2["CURRENT_DAY"] = "current_day";
722
+ UsagePeriod2["CURRENT_MONTH"] = "current_month";
723
+ UsagePeriod2["CURRENT_WEEK"] = "current_week";
724
+ return UsagePeriod2;
725
+ })(UsagePeriod || {});
726
+ var CheckFlagReturnFromJSON = (json) => {
727
+ const {
728
+ companyId,
729
+ error,
730
+ featureAllocation,
731
+ featureUsage,
732
+ featureUsagePeriod,
733
+ featureUsageResetAt,
734
+ flag,
735
+ flagId,
736
+ reason,
737
+ ruleId,
738
+ ruleType,
739
+ userId,
740
+ value
741
+ } = CheckFlagResponseDataFromJSON(json);
742
+ const featureUsageExceeded = !value && // if flag is not false, then we haven't exceeded usage
743
+ (ruleType == "company_override_usage_exceeded" || // if the rule type is one of these, then we have exceeded usage
744
+ ruleType == "plan_entitlement_usage_exceeded");
745
+ return {
746
+ featureUsageExceeded,
747
+ companyId: companyId == null ? void 0 : companyId,
748
+ error: error == null ? void 0 : error,
749
+ featureAllocation: featureAllocation == null ? void 0 : featureAllocation,
750
+ featureUsage: featureUsage == null ? void 0 : featureUsage,
751
+ featureUsagePeriod: featureUsagePeriod == null ? void 0 : featureUsagePeriod,
752
+ featureUsageResetAt: featureUsageResetAt == null ? void 0 : featureUsageResetAt,
753
+ flag,
754
+ flagId: flagId == null ? void 0 : flagId,
755
+ reason,
756
+ ruleId: ruleId == null ? void 0 : ruleId,
757
+ ruleType: ruleType == null ? void 0 : ruleType,
758
+ userId: userId == null ? void 0 : userId,
759
+ value
760
+ };
761
+ };
611
762
  function contextString(context) {
612
763
  const sortedContext = Object.keys(context).reduce((acc, key) => {
613
764
  const sortedKeys = Object.keys(
@@ -631,19 +782,18 @@ var Schematic = class {
631
782
  context = {};
632
783
  eventQueue;
633
784
  eventUrl = "https://c.schematichq.com";
634
- flagListener;
785
+ flagCheckListeners = {};
635
786
  flagValueListeners = {};
636
787
  isPending = true;
637
788
  isPendingListeners = /* @__PURE__ */ new Set();
638
789
  storage;
639
790
  useWebSocket = false;
640
- values = {};
791
+ checks = {};
641
792
  webSocketUrl = "wss://api.schematichq.com";
642
793
  constructor(apiKey, options) {
643
794
  this.apiKey = apiKey;
644
795
  this.eventQueue = [];
645
796
  this.useWebSocket = options?.useWebSocket ?? false;
646
- this.flagListener = options?.flagListener;
647
797
  if (options?.additionalHeaders) {
648
798
  this.additionalHeaders = options.additionalHeaders;
649
799
  }
@@ -693,17 +843,17 @@ var Schematic = class {
693
843
  throw new Error("Network response was not ok");
694
844
  }
695
845
  return response.json();
696
- }).then((data) => {
697
- return data.data.value;
846
+ }).then((response) => {
847
+ return CheckFlagResponseFromJSON(response).data.value;
698
848
  }).catch((error) => {
699
849
  console.error("There was a problem with the fetch operation:", error);
700
850
  return fallback;
701
851
  });
702
852
  }
703
853
  try {
704
- const existingVals = this.values[contextStr];
854
+ const existingVals = this.checks[contextStr];
705
855
  if (this.conn && typeof existingVals !== "undefined" && typeof existingVals[key] !== "undefined") {
706
- return existingVals[key];
856
+ return existingVals[key].value;
707
857
  }
708
858
  try {
709
859
  await this.setContext(context);
@@ -714,8 +864,8 @@ var Schematic = class {
714
864
  );
715
865
  return this.fallbackToRest(key, context, fallback);
716
866
  }
717
- const contextVals = this.values[contextStr] ?? {};
718
- return typeof contextVals[key] === "undefined" ? fallback : contextVals[key];
867
+ const contextVals = this.checks[contextStr] ?? {};
868
+ return contextVals[key]?.value ?? fallback;
719
869
  } catch (error) {
720
870
  console.error("Unexpected error in checkFlag:", error);
721
871
  return fallback;
@@ -739,8 +889,8 @@ var Schematic = class {
739
889
  if (!response.ok) {
740
890
  throw new Error("Network response was not ok");
741
891
  }
742
- const data = await response.json();
743
- return data.data.value;
892
+ const data = CheckFlagResponseFromJSON(await response.json());
893
+ return data?.data?.value ?? false;
744
894
  } catch (error) {
745
895
  console.error("REST API call failed, using fallback value:", error);
746
896
  return fallback;
@@ -767,8 +917,9 @@ var Schematic = class {
767
917
  throw new Error("Network response was not ok");
768
918
  }
769
919
  return response.json();
770
- }).then((data) => {
771
- return (data?.data?.flags ?? []).reduce(
920
+ }).then((responseJson) => {
921
+ const resp = CheckFlagsResponseFromJSON(responseJson);
922
+ return (resp?.data?.flags ?? []).reduce(
772
923
  (accum, flag) => {
773
924
  accum[flag.flag] = flag.value;
774
925
  return accum;
@@ -777,7 +928,7 @@ var Schematic = class {
777
928
  );
778
929
  }).catch((error) => {
779
930
  console.error("There was a problem with the fetch operation:", error);
780
- return false;
931
+ return {};
781
932
  });
782
933
  };
783
934
  /**
@@ -939,18 +1090,15 @@ var Schematic = class {
939
1090
  let resolved = false;
940
1091
  const messageHandler = (event) => {
941
1092
  const message = JSON.parse(event.data);
942
- if (!(contextString(context) in this.values)) {
943
- this.values[contextString(context)] = {};
944
- }
945
- (message.flags ?? []).forEach(
946
- (flag) => {
947
- this.values[contextString(context)][flag.flag] = flag.value;
948
- this.notifyFlagValueListeners(flag.flag, flag.value);
949
- }
950
- );
951
- if (this.flagListener) {
952
- this.flagListener(this.getFlagValues());
1093
+ if (!(contextString(context) in this.checks)) {
1094
+ this.checks[contextString(context)] = {};
953
1095
  }
1096
+ (message.flags ?? []).forEach((flag) => {
1097
+ const flagCheck = CheckFlagReturnFromJSON(flag);
1098
+ this.checks[contextString(context)][flagCheck.flag] = flagCheck;
1099
+ this.notifyFlagCheckListeners(flag.flag, flagCheck);
1100
+ this.notifyFlagValueListeners(flag.flag, flagCheck.value);
1101
+ });
954
1102
  this.setIsPending(false);
955
1103
  if (!resolved) {
956
1104
  resolved = true;
@@ -990,18 +1138,21 @@ var Schematic = class {
990
1138
  setIsPending = (isPending) => {
991
1139
  this.isPending = isPending;
992
1140
  this.isPendingListeners.forEach(
993
- (listener) => notifyListener(listener, isPending)
1141
+ (listener) => notifyPendingListener(listener, isPending)
994
1142
  );
995
1143
  };
1144
+ // flag checks state
1145
+ getFlagCheck = (flagKey) => {
1146
+ const contextStr = contextString(this.context);
1147
+ const checks = this.checks[contextStr] ?? {};
1148
+ return checks[flagKey];
1149
+ };
996
1150
  // flagValues state
997
1151
  getFlagValue = (flagKey) => {
998
- const values = this.getFlagValues();
999
- return values[flagKey];
1000
- };
1001
- getFlagValues = () => {
1002
- const contextStr = contextString(this.context);
1003
- return this.values[contextStr] ?? {};
1152
+ const check = this.getFlagCheck(flagKey);
1153
+ return check?.value;
1004
1154
  };
1155
+ /** Register an event listener that will be notified with the boolean value for a given flag when this value changes */
1005
1156
  addFlagValueListener = (flagKey, listener) => {
1006
1157
  if (!(flagKey in this.flagValueListeners)) {
1007
1158
  this.flagValueListeners[flagKey] = /* @__PURE__ */ new Set();
@@ -1011,12 +1162,40 @@ var Schematic = class {
1011
1162
  this.flagValueListeners[flagKey].delete(listener);
1012
1163
  };
1013
1164
  };
1165
+ /** Register an event listener that will be notified with the full flag check response for a given flag whenever this value changes */
1166
+ addFlagCheckListener = (flagKey, listener) => {
1167
+ if (!(flagKey in this.flagCheckListeners)) {
1168
+ this.flagCheckListeners[flagKey] = /* @__PURE__ */ new Set();
1169
+ }
1170
+ this.flagCheckListeners[flagKey].add(listener);
1171
+ return () => {
1172
+ this.flagCheckListeners[flagKey].delete(listener);
1173
+ };
1174
+ };
1175
+ notifyFlagCheckListeners = (flagKey, check) => {
1176
+ const listeners = this.flagCheckListeners?.[flagKey] ?? [];
1177
+ listeners.forEach((listener) => notifyFlagCheckListener(listener, check));
1178
+ };
1014
1179
  notifyFlagValueListeners = (flagKey, value) => {
1015
1180
  const listeners = this.flagValueListeners?.[flagKey] ?? [];
1016
- listeners.forEach((listener) => notifyListener(listener, value));
1181
+ listeners.forEach((listener) => notifyFlagValueListener(listener, value));
1017
1182
  };
1018
1183
  };
1019
- var notifyListener = (listener, value) => {
1184
+ var notifyPendingListener = (listener, value) => {
1185
+ if (listener.length > 0) {
1186
+ listener(value);
1187
+ } else {
1188
+ listener();
1189
+ }
1190
+ };
1191
+ var notifyFlagCheckListener = (listener, value) => {
1192
+ if (listener.length > 0) {
1193
+ listener(value);
1194
+ } else {
1195
+ listener();
1196
+ }
1197
+ };
1198
+ var notifyFlagValueListener = (listener, value) => {
1020
1199
  if (listener.length > 0) {
1021
1200
  listener(value);
1022
1201
  } else {
@@ -1120,6 +1299,27 @@ var useSchematicFlag = (key, opts) => {
1120
1299
  }, [client, key, fallback]);
1121
1300
  return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot);
1122
1301
  };
1302
+ var useSchematicEntitlement = (key, opts) => {
1303
+ const client = useSchematicClient(opts);
1304
+ const fallback = opts?.fallback ?? false;
1305
+ const fallbackCheck = (0, import_react2.useMemo)(
1306
+ () => ({
1307
+ flag: key,
1308
+ reason: "Fallback",
1309
+ value: fallback
1310
+ }),
1311
+ [key, fallback]
1312
+ );
1313
+ const subscribe = (0, import_react2.useCallback)(
1314
+ (callback) => client.addFlagCheckListener(key, callback),
1315
+ [client, key]
1316
+ );
1317
+ const getSnapshot = (0, import_react2.useCallback)(() => {
1318
+ const check = client.getFlagCheck(key);
1319
+ return check ?? fallbackCheck;
1320
+ }, [client, key, fallbackCheck]);
1321
+ return (0, import_react2.useSyncExternalStore)(subscribe, getSnapshot);
1322
+ };
1123
1323
  var useSchematicIsPending = (opts) => {
1124
1324
  const client = useSchematicClient(opts);
1125
1325
  const subscribe = (0, import_react2.useCallback)(