@usergist/sdk-core 0.1.0 → 0.1.2

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/dist/mobile.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var zod = require('zod');
4
+
3
5
  // src/types/segment-dsl.ts
4
6
  function emptySegmentDsl() {
5
7
  return { version: 1, root: { combinator: "AND", predicates: [] } };
@@ -16,6 +18,16 @@ function err(code, message, details) {
16
18
  };
17
19
  }
18
20
 
21
+ // src/types/workspace.ts
22
+ function defaultOnboardingMessage(appName) {
23
+ return {
24
+ title: `Welcome to ${appName.trim() || "our app"}`,
25
+ body: "Glad you\u2019re here. Take a look around and make yourself at home.",
26
+ buttonLabel: "Got it",
27
+ format: "modal"
28
+ };
29
+ }
30
+
19
31
  // src/types/survey.ts
20
32
  var SURVEY_END_SENTINEL = "__end__";
21
33
 
@@ -259,8 +271,8 @@ var THEME_PRESETS = [
259
271
  swatches: ["#8B5CF6", "#EC4899", "#E9D5FF"]
260
272
  }
261
273
  ];
262
- function getThemePresetById(id) {
263
- return THEME_PRESETS.find((preset) => preset.id === id);
274
+ function getThemePresetById(id2) {
275
+ return THEME_PRESETS.find((preset) => preset.id === id2);
264
276
  }
265
277
  function defaultThemePreset() {
266
278
  return THEME_PRESETS[0];
@@ -311,7 +323,7 @@ var USER_IDENTIFIED_EVENT_NAME = "$user_identified";
311
323
  function camelize(value) {
312
324
  return value.replace(/_([a-z])/g, (_match, letter) => letter.toUpperCase());
313
325
  }
314
- var ids = (...keys) => Object.fromEntries(keys.map((key) => [key, [key, camelize(key)]]));
326
+ var ids = (...keys) => Object.fromEntries(keys.map((key2) => [key2, [key2, camelize(key2)]]));
315
327
  var pushEvents = [
316
328
  ["$push_sent", "UserGist Push Sent"],
317
329
  ["$push_delivered", "UserGist Push Delivered"],
@@ -368,8 +380,8 @@ var CORE_INTEGRATION_EVENTS = [
368
380
  { key: "$inapp_dismissed", name: "UserGist In-App Message Dismissed", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "dismiss_reason") } },
369
381
  { key: "$inapp_auto_dismissed", name: "UserGist In-App Message Auto-Dismissed", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "dismiss_reason") } },
370
382
  { key: "$inapp_cta_clicked", name: "UserGist In-App Message CTA Clicked", category: "inapp", subjectRole: "actor", properties: { ...ids("message_id", "cta_id", "cta_index"), action: ["action", "cta_action"] } },
371
- ...pushEvents.map(([key, name]) => ({
372
- key,
383
+ ...pushEvents.map(([key2, name]) => ({
384
+ key: key2,
373
385
  name,
374
386
  category: "push",
375
387
  subjectRole: "actor",
@@ -378,11 +390,11 @@ var CORE_INTEGRATION_EVENTS = [
378
390
  action_id: ["action_id", "actionId", "action_button", "actionButton"]
379
391
  }
380
392
  })),
381
- ...requestEvents.map(([key, name, subjectRole]) => ({ key, name, category: "requests", subjectRole, properties: { ...ids("request_id", "comment_id", "source", "old_status", "new_status", "deleted_by"), usergist_actor_type: ["usergist_actor_type", "actor_type"] } }))
393
+ ...requestEvents.map(([key2, name, subjectRole]) => ({ key: key2, name, category: "requests", subjectRole, properties: { ...ids("request_id", "comment_id", "source", "old_status", "new_status", "deleted_by"), usergist_actor_type: ["usergist_actor_type", "actor_type"] } }))
382
394
  ];
383
395
  var CORE_EVENT_BY_KEY = new Map(CORE_INTEGRATION_EVENTS.map((event) => [event.key, event]));
384
- function getCoreIntegrationEvent(key) {
385
- return CORE_EVENT_BY_KEY.get(key) ?? null;
396
+ function getCoreIntegrationEvent(key2) {
397
+ return CORE_EVENT_BY_KEY.get(key2) ?? null;
386
398
  }
387
399
  function sanitizeCoreIntegrationProperties(definition, input) {
388
400
  if (!input) return {};
@@ -591,15 +603,15 @@ function reachableQuestions(flow, startId) {
591
603
  const visited = /* @__PURE__ */ new Set();
592
604
  const stack = [start];
593
605
  while (stack.length > 0) {
594
- const id = stack.pop();
595
- if (id === void 0) continue;
596
- if (visited.has(id)) continue;
597
- visited.add(id);
598
- const outgoing = flow.branches.filter((b) => b.fromQuestionId === id);
606
+ const id2 = stack.pop();
607
+ if (id2 === void 0) continue;
608
+ if (visited.has(id2)) continue;
609
+ visited.add(id2);
610
+ const outgoing = flow.branches.filter((b) => b.fromQuestionId === id2);
599
611
  for (const b of outgoing) {
600
612
  if (b.toQuestionId !== SURVEY_END_SENTINEL) stack.push(b.toQuestionId);
601
613
  }
602
- const idx = flow.questions.findIndex((q) => q.id === id);
614
+ const idx = flow.questions.findIndex((q) => q.id === id2);
603
615
  if (idx >= 0 && idx < flow.questions.length - 1) {
604
616
  const next = flow.questions[idx + 1];
605
617
  if (next) stack.push(next.id);
@@ -638,7 +650,7 @@ function tzOffsetMinutes(at, tz) {
638
650
  function startCandidate(schedule, now, tz) {
639
651
  const localNow = wallClock(now, tz);
640
652
  const target = new Date(localNow);
641
- target.setHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
653
+ target.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
642
654
  return localToUtc(target, tz);
643
655
  }
644
656
  function walkForward(candidate, schedule, now, tz) {
@@ -656,30 +668,30 @@ function walkForward(candidate, schedule, now, tz) {
656
668
  function matchesFrequency(local, schedule) {
657
669
  if (schedule.frequency === "daily") return true;
658
670
  if (schedule.frequency === "weekly") {
659
- return schedule.weekday === void 0 || local.getDay() === schedule.weekday;
671
+ return schedule.weekday === void 0 || local.getUTCDay() === schedule.weekday;
660
672
  }
661
- return schedule.dayOfMonth === void 0 || local.getDate() === schedule.dayOfMonth;
673
+ return schedule.dayOfMonth === void 0 || local.getUTCDate() === schedule.dayOfMonth;
662
674
  }
663
675
  function step(cursor, cursorLocal, schedule, tz) {
664
676
  if (schedule.frequency === "daily" || schedule.frequency === "weekly") {
665
677
  return addDays(cursor, 1);
666
678
  }
667
679
  const next = new Date(cursorLocal);
668
- next.setMonth(next.getMonth() + 1);
680
+ next.setUTCMonth(next.getUTCMonth() + 1);
669
681
  if (schedule.dayOfMonth !== void 0) {
670
- const lastDay = lastDayOfMonth(next.getFullYear(), next.getMonth());
671
- next.setDate(Math.min(schedule.dayOfMonth, lastDay));
682
+ const lastDay = lastDayOfMonth(next.getUTCFullYear(), next.getUTCMonth());
683
+ next.setUTCDate(Math.min(schedule.dayOfMonth, lastDay));
672
684
  }
673
- next.setHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
685
+ next.setUTCHours(schedule.hourLocal, schedule.minuteLocal, 0, 0);
674
686
  return localToUtc(next, tz);
675
687
  }
676
688
  function addDays(d, days) {
677
689
  const next = new Date(d.getTime());
678
- next.setDate(next.getDate() + days);
690
+ next.setUTCDate(next.getUTCDate() + days);
679
691
  return next;
680
692
  }
681
693
  function lastDayOfMonth(year, monthIndex) {
682
- return new Date(year, monthIndex + 1, 0).getDate();
694
+ return new Date(Date.UTC(year, monthIndex + 1, 0)).getUTCDate();
683
695
  }
684
696
  function wallClock(d, tz) {
685
697
  const offsetMin = tzOffsetMinutes(d, tz);
@@ -707,11 +719,460 @@ function getFormatter(tz) {
707
719
  return fmt;
708
720
  }
709
721
 
722
+ // src/types/web.ts
723
+ var DELIVERY_PROTOCOL_VERSION = 2;
724
+ function deliveryPlatformsForApp(platforms) {
725
+ const values = /* @__PURE__ */ new Set();
726
+ for (const platform of platforms) {
727
+ if (platform === "web" || platform === "ios" || platform === "android") values.add(platform);
728
+ if (platform === "expo" || platform === "react-native" || platform === "flutter") {
729
+ values.add("ios");
730
+ values.add("android");
731
+ }
732
+ }
733
+ return [...values];
734
+ }
735
+ function resolveWebPresentation(pillar, override) {
736
+ return {
737
+ layout: override?.layout ?? "modal",
738
+ size: override?.size ?? (pillar === "requests" ? "wide" : "standard"),
739
+ position: override?.position ?? "right",
740
+ backdrop: override?.backdrop ?? override?.layout !== "card"
741
+ };
742
+ }
743
+ var id = zod.z.string().regex(/^[A-Za-z][A-Za-z0-9_]{0,63}$/);
744
+ var key = zod.z.string().min(1).max(120).refine(
745
+ (v) => !["__proto__", "prototype", "constructor"].includes(v),
746
+ "Reserved property key"
747
+ );
748
+ var scalar = zod.z.union([
749
+ zod.z.string().max(8192),
750
+ zod.z.number().finite(),
751
+ zod.z.boolean(),
752
+ zod.z.null()
753
+ ]);
754
+ var baseSource = { id, label: zod.z.string().min(1).max(120) };
755
+ var filterSchema = zod.z.object({
756
+ key,
757
+ op: zod.z.enum([
758
+ "eq",
759
+ "neq",
760
+ "gt",
761
+ "gte",
762
+ "lt",
763
+ "lte",
764
+ "in",
765
+ "nin",
766
+ "contains",
767
+ "starts_with",
768
+ "exists",
769
+ "not_exists"
770
+ ]),
771
+ value: zod.z.union([
772
+ zod.z.string(),
773
+ zod.z.number().finite(),
774
+ zod.z.boolean(),
775
+ zod.z.array(zod.z.union([zod.z.string(), zod.z.number().finite()])).max(100)
776
+ ]).optional()
777
+ });
778
+ var personalizationSpecSchema = zod.z.object({
779
+ version: zod.z.literal(1),
780
+ sources: zod.z.array(
781
+ zod.z.discriminatedUnion("kind", [
782
+ zod.z.object({ ...baseSource, kind: zod.z.literal("user_property") }),
783
+ zod.z.object({ ...baseSource, kind: zod.z.literal("trigger_event") }),
784
+ zod.z.object({ ...baseSource, kind: zod.z.literal("send_data") }),
785
+ zod.z.object({ ...baseSource, kind: zod.z.literal("app") }),
786
+ zod.z.object({ ...baseSource, kind: zod.z.literal("now") }),
787
+ zod.z.object({
788
+ ...baseSource,
789
+ kind: zod.z.literal("latest_event"),
790
+ eventName: zod.z.string().min(1).max(120),
791
+ lookbackDays: zod.z.number().int().min(1).max(90),
792
+ filters: zod.z.array(filterSchema).max(8).optional()
793
+ })
794
+ ])
795
+ ).max(16),
796
+ bindings: zod.z.array(
797
+ zod.z.object({
798
+ id,
799
+ label: zod.z.string().min(1).max(120),
800
+ sourceId: id,
801
+ key,
802
+ type: zod.z.enum(["string", "number", "boolean", "date"]),
803
+ fallback: scalar.optional()
804
+ })
805
+ ).max(64),
806
+ missingData: zod.z.literal("skip")
807
+ }).superRefine((spec, ctx) => {
808
+ const sources = new Set(spec.sources.map((source) => source.id));
809
+ if (sources.size !== spec.sources.length)
810
+ ctx.addIssue({
811
+ code: "custom",
812
+ path: ["sources"],
813
+ message: "Source IDs must be unique"
814
+ });
815
+ if (spec.sources.filter((source) => source.kind === "latest_event").length > 4)
816
+ ctx.addIssue({
817
+ code: "custom",
818
+ path: ["sources"],
819
+ message: "Use at most four activity sources"
820
+ });
821
+ const bindings = /* @__PURE__ */ new Set();
822
+ spec.bindings.forEach((binding, index) => {
823
+ if (bindings.has(binding.id))
824
+ ctx.addIssue({
825
+ code: "custom",
826
+ path: ["bindings", index, "id"],
827
+ message: "Field IDs must be unique"
828
+ });
829
+ bindings.add(binding.id);
830
+ if (!sources.has(binding.sourceId))
831
+ ctx.addIssue({
832
+ code: "custom",
833
+ path: ["bindings", index, "sourceId"],
834
+ message: "Choose an existing source"
835
+ });
836
+ if (binding.fallback !== void 0 && (isMissing(binding.fallback) || !matchesType(binding.fallback, binding.type)))
837
+ ctx.addIssue({
838
+ code: "custom",
839
+ path: ["bindings", index, "fallback"],
840
+ message: "Fallback must be a non-empty value of the selected type"
841
+ });
842
+ });
843
+ });
844
+ var userPropertiesUpdateSchema = zod.z.object({
845
+ mutationId: zod.z.string().uuid(),
846
+ set: zod.z.record(key, scalar).refine(
847
+ (v) => Object.keys(v).length <= 64,
848
+ "Update at most 64 properties"
849
+ ).optional(),
850
+ unset: zod.z.array(key).max(64).optional()
851
+ }).superRefine((update, ctx) => {
852
+ if (!Object.keys(update.set ?? {}).length && !update.unset?.length)
853
+ ctx.addIssue({
854
+ code: "custom",
855
+ message: "Supply properties to set or remove"
856
+ });
857
+ if (update.unset?.some((name) => Object.hasOwn(update.set ?? {}, name)))
858
+ ctx.addIssue({
859
+ code: "custom",
860
+ message: "A property cannot be set and removed in the same update"
861
+ });
862
+ });
863
+ function isMissing(value) {
864
+ return value == null || typeof value === "string" && !value.trim();
865
+ }
866
+ function matchesType(value, type) {
867
+ if (type === "date")
868
+ return typeof value === "string" && !Number.isNaN(Date.parse(value));
869
+ return typeof value === type && (typeof value !== "number" || Number.isFinite(value));
870
+ }
871
+ function resolvePersonalizationBindings(spec, sources) {
872
+ const values = /* @__PURE__ */ Object.create(null);
873
+ const issues = [];
874
+ const fallbackBindingIds = [];
875
+ for (const binding of spec.bindings) {
876
+ const source = sources[binding.sourceId]?.values;
877
+ const value = source && Object.hasOwn(source, binding.key) ? source[binding.key] : void 0;
878
+ const missing = isMissing(value);
879
+ if (!missing && matchesType(value, binding.type))
880
+ values[binding.id] = value;
881
+ else if (missing && binding.fallback !== void 0) {
882
+ values[binding.id] = binding.fallback;
883
+ fallbackBindingIds.push(binding.id);
884
+ } else
885
+ issues.push({
886
+ code: missing ? "missing" : "type_mismatch",
887
+ bindingId: binding.id,
888
+ message: missing ? `${binding.label} is missing` : `${binding.label} must be ${binding.type}`
889
+ });
890
+ }
891
+ return {
892
+ status: issues.length ? "skipped" : fallbackBindingIds.length ? "using_fallback" : "ready",
893
+ values,
894
+ fallbackBindingIds,
895
+ issues,
896
+ sources
897
+ };
898
+ }
899
+ var TOKEN = /\{\{\s*p\.([A-Za-z][A-Za-z0-9_]*)\s*\}\}/g;
900
+ var WHOLE_TOKEN = /^\{\{\s*p\.([A-Za-z][A-Za-z0-9_]*)\s*\}\}$/;
901
+ function personalizationToken(bindingId) {
902
+ return `{{p.${bindingId}}}`;
903
+ }
904
+ function renderPersonalizedValue(input, values, issues, path = "", mode = "text") {
905
+ if (typeof input === "string") {
906
+ const whole = WHOLE_TOKEN.exec(input);
907
+ const lookup = (bindingId) => {
908
+ if (Object.hasOwn(values, bindingId)) return values[bindingId];
909
+ issues.push({
910
+ code: "unknown_binding",
911
+ bindingId,
912
+ path,
913
+ message: `No value is available for ${bindingId}`
914
+ });
915
+ return null;
916
+ };
917
+ if (mode === "json" && whole) return lookup(whole[1]);
918
+ if (/\{\{|\}\}/.test(input.replace(TOKEN, "")))
919
+ issues.push({
920
+ code: "invalid_template",
921
+ path,
922
+ message: "Insert a valid dynamic field"
923
+ });
924
+ const result = input.replace(TOKEN, (_, bindingId) => {
925
+ const value = lookup(bindingId);
926
+ return mode === "url" && !whole ? encodeURIComponent(String(value ?? "")) : String(value ?? "");
927
+ });
928
+ if (mode === "url" && result) {
929
+ try {
930
+ const url = new URL(result);
931
+ if (["javascript:", "data:", "file:", "vbscript:"].includes(url.protocol))
932
+ throw new Error("unsafe");
933
+ if (!whole && /\{\{/.test(input.split(/:\/\//)[0] ?? ""))
934
+ throw new Error("dynamic scheme");
935
+ if (!whole && /\{\{/.test(
936
+ input.match(/^[a-z][a-z0-9+.-]*:\/\/([^/?#]*)/i)?.[1] ?? ""
937
+ ))
938
+ throw new Error("dynamic authority");
939
+ } catch {
940
+ issues.push({
941
+ code: "invalid_destination",
942
+ path,
943
+ message: "The resolved destination must be a valid app link or web URL"
944
+ });
945
+ }
946
+ }
947
+ return result;
948
+ }
949
+ if (Array.isArray(input))
950
+ return input.map(
951
+ (item, index) => renderPersonalizedValue(item, values, issues, `${path}/${index}`, mode)
952
+ );
953
+ if (input && typeof input === "object") {
954
+ const result = /* @__PURE__ */ Object.create(null);
955
+ for (const [name, value] of Object.entries(input)) {
956
+ if (["__proto__", "constructor", "prototype"].includes(name)) {
957
+ issues.push({
958
+ code: "invalid_template",
959
+ path,
960
+ message: "Reserved object key"
961
+ });
962
+ continue;
963
+ }
964
+ result[name] = renderPersonalizedValue(
965
+ value,
966
+ values,
967
+ issues,
968
+ `${path}/${name}`,
969
+ mode
970
+ );
971
+ }
972
+ return result;
973
+ }
974
+ return input;
975
+ }
976
+ var TEXT_KEYS = /* @__PURE__ */ new Set([
977
+ "title",
978
+ "body",
979
+ "subtitle",
980
+ "headline",
981
+ "label",
982
+ "placeholder",
983
+ "followUp",
984
+ "lowLabel",
985
+ "highLabel",
986
+ "description",
987
+ "buttonText",
988
+ "submitLabel",
989
+ "nextLabel",
990
+ "backLabel",
991
+ "text"
992
+ ]);
993
+ var URL_KEYS = /* @__PURE__ */ new Set(["imageUrl", "deepLink", "target"]);
994
+ var CONTENT_KEYS = /* @__PURE__ */ new Set([
995
+ "questions",
996
+ "options",
997
+ "ctas",
998
+ "cta",
999
+ "actionButtons",
1000
+ "flow",
1001
+ "welcome",
1002
+ "thankYou",
1003
+ "completion",
1004
+ "endScreen",
1005
+ "openAction"
1006
+ ]);
1007
+ function personalizationUsage(content) {
1008
+ const usage = /* @__PURE__ */ new Map();
1009
+ const scan = (value, field) => {
1010
+ if (typeof value === "string") {
1011
+ for (const match of value.matchAll(TOKEN)) {
1012
+ const fields = usage.get(match[1]) ?? /* @__PURE__ */ new Set();
1013
+ fields.add(field);
1014
+ usage.set(match[1], fields);
1015
+ }
1016
+ } else if (Array.isArray(value)) value.forEach((item) => scan(item, field));
1017
+ else if (value && typeof value === "object")
1018
+ Object.values(value).forEach((item) => scan(item, field));
1019
+ };
1020
+ const walk = (value) => {
1021
+ if (Array.isArray(value)) {
1022
+ value.forEach(walk);
1023
+ return;
1024
+ }
1025
+ if (!value || typeof value !== "object") return;
1026
+ for (const [key2, item] of Object.entries(value)) {
1027
+ if (TEXT_KEYS.has(key2) || URL_KEYS.has(key2) || key2 === "actionJson" || key2 === "payloadExtras")
1028
+ scan(item, key2);
1029
+ else if (CONTENT_KEYS.has(key2)) walk(item);
1030
+ }
1031
+ };
1032
+ walk(content);
1033
+ return usage;
1034
+ }
1035
+ function renderPersonalizedContent(content, resolution) {
1036
+ const usage = personalizationUsage(content);
1037
+ const onlyOptionalImage = (id2) => usage.get(id2)?.size === 1 && usage.get(id2)?.has("imageUrl");
1038
+ const issues = resolution.issues.filter(
1039
+ (issue) => !issue.bindingId || usage.has(issue.bindingId) && !(issue.code === "missing" && onlyOptionalImage(issue.bindingId))
1040
+ );
1041
+ const fallbacks = resolution.fallbackBindingIds.filter((id2) => usage.has(id2));
1042
+ const walk = (value, path = "") => {
1043
+ if (Array.isArray(value))
1044
+ return value.map((item, index) => walk(item, `${path}/${index}`));
1045
+ if (!value || typeof value !== "object") return value;
1046
+ return Object.fromEntries(
1047
+ Object.entries(value).map(([name, item]) => {
1048
+ const childPath = `${path}/${name}`;
1049
+ if (TEXT_KEYS.has(name) && typeof item === "string")
1050
+ return [
1051
+ name,
1052
+ renderPersonalizedValue(item, resolution.values, issues, childPath)
1053
+ ];
1054
+ if (URL_KEYS.has(name) && typeof item === "string") {
1055
+ if (name === "imageUrl" && [...item.matchAll(TOKEN)].some(
1056
+ (match) => resolution.issues.some(
1057
+ (issue) => issue.bindingId === match[1] && issue.code === "missing"
1058
+ )
1059
+ ))
1060
+ return [name, null];
1061
+ const isEvent = name === "target" && value.action === "custom_event";
1062
+ const rendered2 = renderPersonalizedValue(
1063
+ item,
1064
+ resolution.values,
1065
+ issues,
1066
+ childPath,
1067
+ isEvent ? "text" : "url"
1068
+ );
1069
+ if (name === "imageUrl" && rendered2 && !String(rendered2).startsWith("https://"))
1070
+ issues.push({
1071
+ code: "invalid_destination",
1072
+ path: childPath,
1073
+ message: "Image URLs must use HTTPS"
1074
+ });
1075
+ return [name, rendered2];
1076
+ }
1077
+ if (name === "actionJson" || name === "payloadExtras")
1078
+ return [
1079
+ name,
1080
+ renderPersonalizedValue(
1081
+ item,
1082
+ resolution.values,
1083
+ issues,
1084
+ childPath,
1085
+ "json"
1086
+ )
1087
+ ];
1088
+ if (CONTENT_KEYS.has(name)) return [name, walk(item, childPath)];
1089
+ return [name, item];
1090
+ })
1091
+ );
1092
+ };
1093
+ const rendered = walk(content);
1094
+ return {
1095
+ content: rendered,
1096
+ resolution: {
1097
+ ...resolution,
1098
+ fallbackBindingIds: fallbacks,
1099
+ status: issues.length ? "skipped" : fallbacks.length ? "using_fallback" : "ready",
1100
+ issues
1101
+ }
1102
+ };
1103
+ }
1104
+
1105
+ // src/presentation.ts
1106
+ var PresentationGate = class {
1107
+ paused;
1108
+ identity = 0;
1109
+ revisions = { feedback: 0, survey: 0 };
1110
+ listeners = /* @__PURE__ */ new Set();
1111
+ constructor(paused = false) {
1112
+ this.paused = paused;
1113
+ }
1114
+ get isPaused() {
1115
+ return this.paused;
1116
+ }
1117
+ setPaused(paused) {
1118
+ this.paused = paused;
1119
+ this.notify();
1120
+ }
1121
+ invalidate(purpose) {
1122
+ if (purpose) this.revisions[purpose]++;
1123
+ else this.identity++;
1124
+ this.notify();
1125
+ }
1126
+ validator(purpose) {
1127
+ const identity = this.identity;
1128
+ const revision = this.revisions[purpose];
1129
+ return () => identity === this.identity && revision === this.revisions[purpose];
1130
+ }
1131
+ subscribe(listener) {
1132
+ this.listeners.add(listener);
1133
+ return () => {
1134
+ this.listeners.delete(listener);
1135
+ };
1136
+ }
1137
+ runWhenReady(run, valid, cancel = () => {
1138
+ }) {
1139
+ if (!valid()) {
1140
+ cancel();
1141
+ return;
1142
+ }
1143
+ if (!this.paused) {
1144
+ run();
1145
+ return;
1146
+ }
1147
+ const stop = this.subscribe(() => {
1148
+ if (valid() && this.paused) return;
1149
+ stop();
1150
+ if (valid()) run();
1151
+ else cancel();
1152
+ });
1153
+ }
1154
+ waitUntilReady(valid) {
1155
+ if (!valid()) return Promise.resolve(false);
1156
+ if (!this.paused) return Promise.resolve(true);
1157
+ return new Promise((resolve) => {
1158
+ const stop = this.subscribe(() => {
1159
+ if (valid() && this.paused) return;
1160
+ stop();
1161
+ resolve(valid());
1162
+ });
1163
+ });
1164
+ }
1165
+ notify() {
1166
+ for (const listener of [...this.listeners]) listener();
1167
+ }
1168
+ };
1169
+
710
1170
  exports.APP_OPEN_EVENT_NAME = APP_OPEN_EVENT_NAME;
711
1171
  exports.APP_VERSION_CHANGED_EVENT_NAME = APP_VERSION_CHANGED_EVENT_NAME;
712
1172
  exports.AUDIENCE_JOIN_EVENT_NAME = AUDIENCE_JOIN_EVENT_NAME;
713
1173
  exports.AUDIENCE_JOIN_TRIGGER_KIND = AUDIENCE_JOIN_TRIGGER_KIND;
714
1174
  exports.CORE_INTEGRATION_EVENTS = CORE_INTEGRATION_EVENTS;
1175
+ exports.DELIVERY_PROTOCOL_VERSION = DELIVERY_PROTOCOL_VERSION;
715
1176
  exports.INAPP_AUTO_DISMISSED_EVENT_NAME = INAPP_AUTO_DISMISSED_EVENT_NAME;
716
1177
  exports.INAPP_CTA_CLICKED_EVENT_NAME = INAPP_CTA_CLICKED_EVENT_NAME;
717
1178
  exports.INAPP_DISMISSED_EVENT_NAME = INAPP_DISMISSED_EVENT_NAME;
@@ -719,6 +1180,7 @@ exports.INAPP_SHOWN_EVENT_NAME = INAPP_SHOWN_EVENT_NAME;
719
1180
  exports.INTEGRATION_CATEGORIES = INTEGRATION_CATEGORIES;
720
1181
  exports.INTEGRATION_PROVIDERS = INTEGRATION_PROVIDERS;
721
1182
  exports.PUSH_EVENTS = PUSH_EVENTS;
1183
+ exports.PresentationGate = PresentationGate;
722
1184
  exports.RADIUS_PRESETS = RADIUS_PRESETS;
723
1185
  exports.REQUEST_COMMENTED_EVENT_NAME = REQUEST_COMMENTED_EVENT_NAME;
724
1186
  exports.REQUEST_COMMENT_DELETED_EVENT_NAME = REQUEST_COMMENT_DELETED_EVENT_NAME;
@@ -735,8 +1197,10 @@ exports.THEME_PRESETS = THEME_PRESETS;
735
1197
  exports.USER_IDENTIFIED_EVENT_NAME = USER_IDENTIFIED_EVENT_NAME;
736
1198
  exports.brandTokensFromPreset = brandTokensFromPreset;
737
1199
  exports.defaultEventTrigger = defaultEventTrigger;
1200
+ exports.defaultOnboardingMessage = defaultOnboardingMessage;
738
1201
  exports.defaultThemePreset = defaultThemePreset;
739
1202
  exports.defaultTriggerSpec = defaultTriggerSpec;
1203
+ exports.deliveryPlatformsForApp = deliveryPlatformsForApp;
740
1204
  exports.emptyAudienceSpec = emptyAudienceSpec;
741
1205
  exports.emptySegmentDsl = emptySegmentDsl;
742
1206
  exports.err = err;
@@ -753,11 +1217,19 @@ exports.isSilentPushPayload = isSilentPushPayload;
753
1217
  exports.nextPeriodicFire = nextPeriodicFire;
754
1218
  exports.nextQuestionId = nextQuestionId;
755
1219
  exports.ok = ok;
1220
+ exports.personalizationSpecSchema = personalizationSpecSchema;
1221
+ exports.personalizationToken = personalizationToken;
1222
+ exports.personalizationUsage = personalizationUsage;
756
1223
  exports.promptThemeFromBrandTokens = promptThemeFromBrandTokens;
757
1224
  exports.reachableQuestions = reachableQuestions;
1225
+ exports.renderPersonalizedContent = renderPersonalizedContent;
1226
+ exports.renderPersonalizedValue = renderPersonalizedValue;
758
1227
  exports.requestAccentFromBrandTokens = requestAccentFromBrandTokens;
1228
+ exports.resolvePersonalizationBindings = resolvePersonalizationBindings;
1229
+ exports.resolveWebPresentation = resolveWebPresentation;
759
1230
  exports.sanitizeCoreIntegrationProperties = sanitizeCoreIntegrationProperties;
760
1231
  exports.serializedRulesToDsl = serializedRulesToDsl;
761
1232
  exports.tzOffsetMinutes = tzOffsetMinutes;
1233
+ exports.userPropertiesUpdateSchema = userPropertiesUpdateSchema;
762
1234
  //# sourceMappingURL=mobile.cjs.map
763
1235
  //# sourceMappingURL=mobile.cjs.map