@schematichq/schematic-react 1.0.3 → 1.1.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.
@@ -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)(