@blotout/qinto-cli 0.1.25 → 0.1.26

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.
@@ -19354,6 +19354,7 @@ var APP_FLOWS = ["transform", "destination"];
19354
19354
  var TRANSFORM_ACTION_TYPES = ["track", "identify"];
19355
19355
  var EVENT_ACTION_TYPES = ["track", "identify", "consent"];
19356
19356
  var BROWSER_RESULT_ACTION_TYPES = ["track", "identify"];
19357
+ var BROWSER_HOOKS = ["transform"];
19357
19358
  var APP_LIFECYCLE_TYPES = ["installed", "configurationChanged", "enabled", "disabled", "versionChanged", "uninstalled"];
19358
19359
  var API_CAPABILITIES = ["track", "identify", "alias", "consentWrite", "consentRead", "propertiesRead", "sessionRead"];
19359
19360
  var DATA_CAPABILITIES = [
@@ -19364,7 +19365,8 @@ var DATA_CAPABILITIES = [
19364
19365
  "eventContext",
19365
19366
  "sharedContext",
19366
19367
  "facts",
19367
- "identity"
19368
+ "identity",
19369
+ "siteInstalls"
19368
19370
  ];
19369
19371
  var MAX_APP_VARIABLES = 32;
19370
19372
  var MAX_APP_SCOPE_VARIABLES = 16;
@@ -19642,7 +19644,8 @@ var baseSchema = external_exports.object({
19642
19644
  browser: external_exports.object({
19643
19645
  entry: external_exports.string().min(1).max(255).optional(),
19644
19646
  capture: captureSchema.optional(),
19645
- eventResults: external_exports.array(external_exports.enum(BROWSER_RESULT_ACTION_TYPES)).max(BROWSER_RESULT_ACTION_TYPES.length).optional()
19647
+ eventResults: external_exports.array(external_exports.enum(BROWSER_RESULT_ACTION_TYPES)).max(BROWSER_RESULT_ACTION_TYPES.length).optional(),
19648
+ hooks: external_exports.array(external_exports.enum(BROWSER_HOOKS)).max(BROWSER_HOOKS.length).optional()
19646
19649
  }).strict().optional().meta({
19647
19650
  description: "The app's browser surface: an optional entry for the bundle that ships inside the site's q.js, and the query params and cookies it declares for capture."
19648
19651
  }),
@@ -19946,6 +19949,15 @@ var validateCapture = (manifest, ctx) => {
19946
19949
  }
19947
19950
  }
19948
19951
  };
19952
+ var validateBrowserHooks = (manifest, ctx) => {
19953
+ const hooks = manifest.browser?.hooks ?? [];
19954
+ if (hooks.length > 0 && manifest.browser?.entry === void 0) {
19955
+ ctx.addIssue({ code: "custom", path: ["browser", "hooks"], message: "hooks needs a browser entry" });
19956
+ }
19957
+ if (hooks.includes("transform") && !manifest.flows.includes("transform")) {
19958
+ ctx.addIssue({ code: "custom", path: ["browser", "hooks"], message: "The browser transform hook needs the transform flow" });
19959
+ }
19960
+ };
19949
19961
  var validateRpc = (manifest, ctx) => {
19950
19962
  const exposes = manifest.rpc?.exposes ?? [];
19951
19963
  uniqueOrIssue(
@@ -20006,6 +20018,7 @@ var appManifestSchema = baseSchema.superRefine((manifest, ctx) => {
20006
20018
  validatePipelines(manifest, ctx);
20007
20019
  validateEndpoints(manifest, ctx);
20008
20020
  validateCapture(manifest, ctx);
20021
+ validateBrowserHooks(manifest, ctx);
20009
20022
  validateRpc(manifest, ctx);
20010
20023
  validateEvents(manifest, ctx);
20011
20024
  validateOauth(manifest, ctx);
@@ -20030,6 +20043,7 @@ var appRpcContractSchema = external_exports.record(external_exports.string().reg
20030
20043
  var ENVELOPE_VERSION = 3;
20031
20044
  var ENVELOPE_ERROR_CODES = ["invalid_arguments"];
20032
20045
  var MAX_INSTALLS_PER_APP = 15;
20046
+ var MAX_APPS_PER_DOMAIN = 50;
20033
20047
  var MAX_EMITS_PER_INSTALL = 10;
20034
20048
  var MAX_PUSHES_PER_INSTALL = 10;
20035
20049
  var MAX_CAPTURE_WRITES_PER_INSTALL = 10;
@@ -20043,6 +20057,10 @@ var MAX_RESPONSE_BYTES = 1024 * 1024;
20043
20057
  var MAX_RPC_BYTES = 128 * 1024;
20044
20058
  var installSchema = external_exports.object({ id: external_exports.string().min(1).max(64), ord: external_exports.number().int().min(1), label: external_exports.string().max(100) }).strict();
20045
20059
  var emitSchema = external_exports.object({ type: external_exports.literal("track"), occurredAt: external_exports.number().int().nonnegative().safe(), payload: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict();
20060
+ var installRuleSchema = external_exports.object({
20061
+ mode: external_exports.enum(["except", "only"]),
20062
+ installIds: external_exports.array(external_exports.string().min(1).max(64)).max(MAX_APPS_PER_DOMAIN * MAX_INSTALLS_PER_APP)
20063
+ }).strict();
20046
20064
  var pushSchema = external_exports.object({ topic: external_exports.string().min(1).max(64), data: external_exports.unknown(), broadcast: external_exports.enum(PUSH_BROADCASTS).optional() }).strict().refine((push) => {
20047
20065
  return new TextEncoder().encode(JSON.stringify(push.data ?? null)).length <= MAX_PUSH_BYTES;
20048
20066
  }, "Push data exceeds the per-message size cap");
@@ -20129,7 +20147,11 @@ var envelopeRequestSchema = external_exports.object({
20129
20147
  var envelopeResponseSchema = external_exports.object({
20130
20148
  v: external_exports.literal(ENVELOPE_VERSION),
20131
20149
  // Transform invocations only: pass the action through, drop it, or replace its payload (§5.4).
20132
- result: external_exports.union([external_exports.literal("pass"), external_exports.literal("drop"), external_exports.object({ payload: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict()]).optional(),
20150
+ result: external_exports.union([
20151
+ external_exports.literal("pass"),
20152
+ external_exports.literal("drop"),
20153
+ external_exports.object({ payload: external_exports.record(external_exports.string(), external_exports.unknown()).optional(), installs: installRuleSchema.optional() }).strict()
20154
+ ]).optional(),
20133
20155
  effects: external_exports.array(effectGroupSchema).optional(),
20134
20156
  rpc: external_exports.object({ result: external_exports.unknown() }).strict().refine((rpc) => {
20135
20157
  return new TextEncoder().encode(JSON.stringify(rpc.result ?? null)).length <= MAX_RPC_BYTES;
@@ -20471,6 +20493,12 @@ var appUiAnalyticsQueryPath = (domainId, appSlug2, resourceIdentifier) => {
20471
20493
  return `/app-ui/sites/${domainId}/apps/${appSlug2}/analytics/${resourceIdentifier}/query`;
20472
20494
  };
20473
20495
  var uiInstallSchema = external_exports.object({ id: external_exports.string().min(1).max(64), ord: external_exports.number().int().min(1), label: external_exports.string().max(100), enabled: external_exports.boolean() }).strict();
20496
+ var siteInstallSchema = external_exports.object({
20497
+ id: external_exports.string().min(1).max(64),
20498
+ appSlug: external_exports.string().min(1).max(30),
20499
+ appName: external_exports.string().min(1).max(100),
20500
+ label: external_exports.string().max(100)
20501
+ }).strict();
20474
20502
  var uiContextSchema = external_exports.object({
20475
20503
  version: external_exports.string().min(1).max(32),
20476
20504
  viewer: external_exports.object({
@@ -20481,8 +20509,10 @@ var uiContextSchema = external_exports.object({
20481
20509
  }).strict(),
20482
20510
  install: uiInstallSchema,
20483
20511
  installs: external_exports.array(uiInstallSchema).min(1).max(MAX_INSTALLS_PER_APP),
20512
+ siteInstalls: external_exports.array(siteInstallSchema).max(MAX_APPS_PER_DOMAIN * MAX_INSTALLS_PER_APP).optional(),
20484
20513
  writeTicket: external_exports.string().min(1).max(2048).optional()
20485
20514
  }).strict();
20515
+ var MAX_UI_SITE_INSTALLS_BYTES = 64 * 1024;
20486
20516
  var parseUiContext = (raw) => {
20487
20517
  if (raw === null) {
20488
20518
  return null;
@@ -20946,6 +20976,18 @@ var addSpanEvent = (name, options = {}) => {
20946
20976
  span.events = [...span.events ?? [], event];
20947
20977
  };
20948
20978
 
20979
+ // src/emitted-event.ts
20980
+ var checkEmittedEvent = (event) => {
20981
+ if (event.type !== "track") {
20982
+ throw new Error("only track events may be emitted");
20983
+ }
20984
+ const occurredAt = event.occurredAt ?? Date.now();
20985
+ if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) {
20986
+ throw new Error("an emitted event occurredAt must be non-negative Unix milliseconds");
20987
+ }
20988
+ return { ...event, occurredAt };
20989
+ };
20990
+
20949
20991
  // src/read-body.ts
20950
20992
  var MAX_ENVELOPE_BYTES = 1024 * 1024;
20951
20993
  var readBody = async (request, maxBytes = MAX_ENVELOPE_BYTES) => {
@@ -21038,17 +21080,21 @@ var brokerPush = async (env, input2) => {
21038
21080
  data: input2.data
21039
21081
  });
21040
21082
  };
21041
- var brokerTrack = async (env, input2) => {
21042
- await askBroker(env, `apps.track ${input2.event.payload["event"]}`, {
21043
- v: ENVELOPE_VERSION,
21044
- kind: "track",
21045
- slug: callerSlug(env),
21046
- key: env.QINTO_INTERNAL_KEY,
21047
- source: input2.source,
21048
- userId: input2.userId,
21049
- installId: input2.installId,
21050
- event: input2.event
21051
- });
21083
+ var buildTrack = (env, source, installId) => {
21084
+ return async (userId, event, options) => {
21085
+ const checked = checkEmittedEvent(event);
21086
+ await askBroker(env, `apps.track ${checked.payload["event"]}`, {
21087
+ v: ENVELOPE_VERSION,
21088
+ kind: "track",
21089
+ slug: callerSlug(env),
21090
+ key: env.QINTO_INTERNAL_KEY,
21091
+ source,
21092
+ userId,
21093
+ installId,
21094
+ installs: options?.installs,
21095
+ event: checked
21096
+ });
21097
+ };
21052
21098
  };
21053
21099
  var brokerContextRead = async (env, userId) => {
21054
21100
  const answer = await askBroker(env, "apps.context read", {
@@ -21113,6 +21159,16 @@ var buildIdentity = (env) => {
21113
21159
  return {
21114
21160
  resolve: (identifier, options) => {
21115
21161
  return brokerIdentityRead(env, identifier, options);
21162
+ },
21163
+ upsert: async (person) => {
21164
+ const answer = await askBroker(env, "apps.identity upsert", {
21165
+ v: ENVELOPE_VERSION,
21166
+ kind: "identityUpsert",
21167
+ slug: callerSlug(env),
21168
+ key: env.QINTO_INTERNAL_KEY,
21169
+ person
21170
+ });
21171
+ return { anonId: answer.anonId, created: answer.created };
21116
21172
  }
21117
21173
  };
21118
21174
  };
@@ -21173,18 +21229,6 @@ var buildAppsClient = (env, envelope) => {
21173
21229
  };
21174
21230
  };
21175
21231
 
21176
- // src/emitted-event.ts
21177
- var checkEmittedEvent = (event) => {
21178
- if (event.type !== "track") {
21179
- throw new Error("only track events may be emitted");
21180
- }
21181
- const occurredAt = event.occurredAt ?? Date.now();
21182
- if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) {
21183
- throw new Error("an emitted event occurredAt must be non-negative Unix milliseconds");
21184
- }
21185
- return { ...event, occurredAt };
21186
- };
21187
-
21188
21232
  // src/oauth.ts
21189
21233
  var EXPIRY_FLOOR_MS = 1e3;
21190
21234
  var read = (env, id, ord, now) => {
@@ -21670,9 +21714,7 @@ var buildWorkflowContext = (env, stamp) => {
21670
21714
  broadcast: message.broadcast
21671
21715
  });
21672
21716
  },
21673
- track: async (userId, event) => {
21674
- await brokerTrack(env, { source: "workflow", userId, installId: install.id, event: checkEmittedEvent(event) });
21675
- },
21717
+ track: buildTrack(env, "workflow", install.id),
21676
21718
  apps
21677
21719
  };
21678
21720
  };
@@ -21957,9 +21999,7 @@ var dispatchSchedule = async (envelope, bundle, env) => {
21957
21999
  broadcast: message.broadcast
21958
22000
  });
21959
22001
  },
21960
- track: async (userId, event2) => {
21961
- await brokerTrack(env, { source: "scheduled", userId, installId: install.id, event: checkEmittedEvent(event2) });
21962
- },
22002
+ track: buildTrack(env, "scheduled", install.id),
21963
22003
  context: (userId) => {
21964
22004
  return asyncContext(env, () => {
21965
22005
  return userId;
@@ -22079,9 +22119,7 @@ var buildContext2 = (envelope, env) => {
22079
22119
  currency: buildCurrency(env),
22080
22120
  apps: buildAppsClient(env, { depth: 0 }),
22081
22121
  query: buildQuery({ env, ticket: envelope.tool.queryTicket, installId: install.id }),
22082
- track: async (userId, event) => {
22083
- await brokerTrack(env, { source: "tool", userId, installId: install.id, event: checkEmittedEvent(event) });
22084
- },
22122
+ track: buildTrack(env, "tool", install.id),
22085
22123
  fail: (message) => {
22086
22124
  return { kind: "tool_error", message: truncate(message) };
22087
22125
  }
@@ -22371,9 +22409,7 @@ var buildContext3 = ({
22371
22409
  broadcast: message.broadcast
22372
22410
  });
22373
22411
  },
22374
- track: async (userId, event) => {
22375
- await brokerTrack(env, { source: "webhook", userId, installId: install.id, event: checkEmittedEvent(event) });
22376
- },
22412
+ track: buildTrack(env, "webhook", install.id),
22377
22413
  context: (userId) => {
22378
22414
  return asyncContext(env, () => {
22379
22415
  return userId;
@@ -22829,6 +22865,7 @@ var dispatchUi = async ({ request, env, versions }) => {
22829
22865
  site,
22830
22866
  install: { id: context.install.id, label: context.install.label },
22831
22867
  installs: projectAllInstallValues(maps, variableKinds, context.installs),
22868
+ ...context.siteInstalls === void 0 ? {} : { siteInstalls: context.siteInstalls },
22832
22869
  // The install is named rather than inherited: one panel serves every install, and reading the
22833
22870
  // subject install's token while showing another account's UI would be silently wrong.
22834
22871
  oauth: buildUiOauth(env, context.installs),
@@ -22947,14 +22984,17 @@ var toTransformResult = (value) => {
22947
22984
  if (typeof value !== "object" || value === null) {
22948
22985
  return null;
22949
22986
  }
22950
- const { kind } = value;
22951
- if (kind === "pass" || kind === "drop") {
22987
+ const { kind, installs } = value;
22988
+ if (kind === "drop") {
22952
22989
  return kind;
22953
22990
  }
22991
+ if (kind === "pass") {
22992
+ return installs === void 0 ? kind : { installs };
22993
+ }
22954
22994
  if (kind === "replace") {
22955
22995
  const { payload } = value;
22956
22996
  if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
22957
- return { payload };
22997
+ return { payload, installs };
22958
22998
  }
22959
22999
  }
22960
23000
  return null;
@@ -22984,14 +23024,14 @@ var runTransform = async (envelope, env, action, handler) => {
22984
23024
  });
22985
23025
  const ctx = {
22986
23026
  ...withoutApps,
22987
- pass: () => {
22988
- return { kind: "pass" };
23027
+ pass: (options) => {
23028
+ return { kind: "pass", installs: options?.installs };
22989
23029
  },
22990
23030
  drop: () => {
22991
23031
  return { kind: "drop" };
22992
23032
  },
22993
- replace: (payload) => {
22994
- return { kind: "replace", payload };
23033
+ replace: (payload, options) => {
23034
+ return { kind: "replace", payload, installs: options?.installs };
22995
23035
  }
22996
23036
  };
22997
23037
  let value;
@@ -0,0 +1 @@
1
+ (function(){var e=()=>{},t=t=>{t.config?.autoCapture?.pageLoad===!0&&t.q.push([`track`,[`PageView`],e,e])},n=class extends Error{constructor(e){super(e),this.name=`QintoError`}},r=class extends n{constructor(e){super(e),this.name=`QintoTimeoutError`}},i=(e=Date.now())=>`evt_${globalThis.crypto.randomUUID()}_${e}`,a=(e,t)=>{if(e!==void 0)return e;let n=t?.orderId;return typeof n==`string`&&n!==``?n:i()},o=[`necessary`,`functional`,`analytics`,`marketing`,`salesOfData`],s=[`then`,`ready`,`config`],c=()=>{},l=(e,t)=>(...n)=>{let r=new Promise((r,i)=>{e.q.push([t,n,r,i])});return r.catch(c),r},u=e=>{let t=e;return t._q=1,t.q=[],new Proxy(t,{get:(e,n)=>typeof n!=`string`||s.includes(n)||n in t?Reflect.get(t,n):(t[n]=l(t,n),t[n])})},d=()=>{let e=document.currentScript?.dataset.qintoGlobal;return typeof e==`string`&&e!==``?e:`qinto`},f=e=>typeof e==`object`&&!!e&&e._q===1,p=(e=`qinto`)=>{let t=globalThis;if(e in t){let n=t[e];if(!f(n))return null;let r=Array.isArray(n.q)?n:u(n);return r!==n&&Object.defineProperty(t,e,{value:r,writable:!0,enumerable:!0,configurable:!0}),r}let n=u({});return Object.defineProperty(t,e,{value:n,writable:!0,enumerable:!0,configurable:!0}),n},m=(e,t)=>async(r,i)=>{let a=Reflect.get(e,r);if(typeof a!=`function`)throw new n(`[Qinto] ${t}.${r} is not a method of this tag.`);return a.apply(e,Array.from(i))},h=e=>()=>Promise.reject(e),g=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},_=e=>{let t=[];return t.push=(...t)=>{for(let n of t)g(e,n);return 0},t},v=(e,t,n=`window.qinto`)=>{let r=e.ready;if(r!==void 0)return r;let i=e,a=e=>{let t=i.q;i.q=_(e);for(let n of t)g(e,n)},o=t().then(e=>{a(m(e,n))},e=>{throw a(h(e)),e});return o.catch(c),i.ready=o,o},y=(e,t,n)=>n===void 0||!o.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,b=(e,t,n)=>e.config?.consentConfiguration?.enabled!==!0||y(n,t,e.config?.apps?.[t]?.category),x=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),ee=(e,t,n,r)=>b(e,t,n)?r===void 0||b(e,t,r):!1,te=e=>{let{categories:t,apps:n}=e;if(typeof t==`object`&&t&&typeof n==`object`&&n)return{categories:t,apps:n}},S=()=>{},C=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},w=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{C(e,t)})}catch(t){C(e,t)}},T=(e,t,n,r)=>{e.activated.add(r.id);let i={slug:t,installId:r.id,eventHandlers:[],transformHooks:[],consentHandlers:[],pushHandlers:[],sharedContextHandlers:[]};e.instances.push(i);let a={variables:r.variables,install:{id:r.id,label:r.label},getSession:async()=>{let n=await e.client.getSession();return e.target.config?.apps?.[t]?.geo===!0?n:{...n,ip:null,geo:null}},track:(t,n)=>{e.client.track(t,n).catch(S)},onEvent:e=>{i.eventHandlers.push(e)},onTransform:e=>{if(r.transform!==!0){console.error(`[Qinto] App "${t}" registers a transform hook without declaring browser.hooks: ["transform"].`);return}i.transformHooks.push(e)},onConsent:e=>{i.consentHandlers.push(e)},onPush:e=>{i.pushHandlers.push(e)},fetch:async(n,i)=>{let a=new URL(`${e.client.destination}/app/${t}${n}`);if(!n.startsWith(`/`)||!a.pathname.startsWith(`/app/${t}/`))throw TypeError(`[Qinto] App "${t}" fetched "${n}"; the path must be absolute and stay inside the app.`);let o=new Headers(i?.headers);return o.set(`x-qinto-install`,r.id),fetch(a,{...i,headers:o,credentials:`include`})},onSharedContext:n=>{if(e.target.config?.apps?.[t]?.sharedContext!==!0){console.error(`[Qinto] App "${t}" reads shared context without declaring the sharedContext capability.`);return}i.sharedContextHandlers.push(n),e.sharedContext!==null&&ee(e.target,t,e.consent,e.sharedContextConsent)&&w(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},E=100,D=1024,ne=32768,re=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>D))return JSON.parse(t)},ie=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=re(n.values[0]);if(e===void 0)continue;let r={...t[n.source.slug]??{},[n.source.installId]:e},i={...t,[n.source.slug]:r};new TextEncoder().encode(JSON.stringify(i)).length<=ne&&(t[n.source.slug]=r)}return Object.keys(t).length===0?void 0:t},ae=async(e,t,{declares:n,notify:r,report:i})=>{let a=[],o=[];for(let s of e){if(!n(s)){r(s);continue}let e={source:s,total:s.eventHandlers.length,settled:0,values:[]};a.push(e);for(let n of s.eventHandlers){let r;try{r=n(t)}catch(t){e.settled+=1,i(s,t);continue}o.push(Promise.resolve(r).then(t=>{e.settled+=1,t!==void 0&&e.values.push(t)},t=>{e.settled+=1,i(s,t)}))}}if(o.length>0){let e,t=new Promise(t=>{e=setTimeout(t,E)});await Promise.race([Promise.all(o),t]),clearTimeout(e)}return ie(a)},oe=(e,t)=>{if(e.mode===`except`&&t.mode===`except`)return{mode:`except`,installIds:[...new Set([...e.installIds,...t.installIds])]};let[n,r]=e.mode===`only`?[e,t]:[t,e],i=new Set(r.installIds);return{mode:`only`,installIds:n.installIds.filter(e=>i.has(e)===(r.mode===`only`))}},se=(e,t,n,r)=>{let i;try{i=t(n,r)}catch(t){C(e,t);return}if(i===void 0||i===!1)return i;let a=i?.installs;if((a?.mode===`except`||a?.mode===`only`)&&Array.isArray(a.installIds))return a;C(e,TypeError(`A transform hook returned neither nothing, false, nor { installs }.`))},ce=(e,t,n,r)=>{let i=r;for(let r of e)for(let e of r.transformHooks){let a=se(r,e,t,n);if(a===!1)return!1;a!==void 0&&(i=i===void 0?a:oe(i,a))}return i},O=(e,t)=>{let{app:n,install:r,topic:i,to:a}=e;return typeof n!=`string`||typeof i!=`string`||r!==void 0&&typeof r!=`string`||t&&!(Array.isArray(a)&&a.every(e=>typeof e==`string`))},k=(e,t,n,r)=>r===null?e.slug===t&&(n===void 0||n===e.installId):r.has(e.slug),A=e=>`_appInstalls`in e?e._appInstalls:void 0,j=(e,t,n)=>{if(!b(e.target,t,e.consent))return;let r=(A(e.target)?.[t]??[]).filter(t=>!e.activated.has(t.id)&&(t.geoFilter!==!0||e.geoAllowed.has(t.id)));if(r.length===0)return;let i=n.factory;if(i===void 0){try{i=n.loader()}catch(e){i=null,console.error(`[Qinto] App "${t}" failed to load.`,e)}e.apps.set(t,{...n,factory:i})}if(i!==null)for(let n of r)T(e,t,i,n)},M=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)w(n,n.consentHandlers,t);e.onConsentSettled?.(t);for(let[t,n]of e.apps)j(e,t,n)},N=async e=>{try{M(e,await e.client.getConsent())}catch(e){console.error(`[Qinto] The apps consent read failed.`,e)}},P=async e=>{if(e.geoRequested||!Object.values(A(e.target)??{}).some(e=>e.some(e=>e.geoFilter===!0)))return;let t=e;t.geoRequested=!0;try{t.geoAllowed=new Set(await e.client.getGeoInstalls())}catch(e){console.error(`[Qinto] The geo filter read failed; geo-filtered installs stay off on this page.`,e);return}for(let[t,n]of e.apps)j(e,t,n)},F=async(e,t,n)=>{e.onPageEvent?.(e.consent);let r=new Set(n?.installIds);return ae(e.instances.filter(t=>b(e.target,t.slug,e.consent)&&(n===void 0||r.has(t.installId)===(n.mode===`only`))),t,{declares:n=>e.target.config?.apps?.[n.slug]?.eventResults?.includes(t.type)===!0,notify:e=>{w(e,e.eventHandlers,t)},report:C})},I=e=>{let{client:t}=e;return{track:async(n,r,i)=>{let o=a(i?.eventId,r),s=t.actionContext(),c={type:`track`,event:n,eventId:o,properties:r??{}},l=i?.installs,u=ce(e.instances,c,s.page.url,l);if(u===!1)return{eventId:o};let d=await F(e,c,u);return await t.submitTrack({event:n,eventId:o,properties:r,context:s,appResults:d,installs:l}),{eventId:o}},identify:async(n,r)=>{let i=t.actionContext(),a=await F(e,{type:`identify`,event:`identify`,properties:n??{}});return t.submitIdentify({traits:n,id:r,context:i,appResults:a})},alias:t.alias,consent:async n=>{if(await t.submitConsent(n,t.actionContext()),e.onConsentMutation?.(),x(e.target)){let t=e;t.consent=null,await N(e)}},getAnonId:t.getAnonId,getConsent:t.getConsent,getSession:t.getSession,close:t.close}},L=(e,t)=>{let n=new Map,r=null,i=null,a=e=>{let[t,i]=e;if(n.has(t))return;let a={loader:i};n.set(t,a),r?.(t,a)},o=e,s=`_apps`in o?o._apps:void 0,c=Array.isArray(s)?s:[];c.push=(...e)=>{for(let t of e)a(t);return 0},o._apps=c;for(let e of c.splice(0))a(e);return{sharedContext:e=>{let{context:t}=e;if(typeof t!=`object`||!t||Array.isArray(t)){console.error(`[Qinto] The server sent a malformed shared context.`,e);return}let n=i;if(n===null)return;n.sharedContext=t;let r=te(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)b(n.target,e.slug,a)&&w(e,e.sharedContextHandlers,n.sharedContext)},push:e=>{let{app:t,install:n,topic:r,scope:a,to:o}=e,s=a===`site`;if(O(e,s)){console.error(`[Qinto] The server sent a malformed app push.`,e);return}let c=i;if(c===null)return;let l=s?new Set(o):null,u={topic:r,data:e.data,from:t};for(let e of c.instances)k(e,t,n,l)&&b(c.target,e.slug,c.consent)&&w(e,e.pushHandlers,u)},connect:async a=>{let o={target:e,client:a,apps:n,instances:[],activated:new Set,consent:null,geoAllowed:new Set,geoRequested:!1,sharedContext:i?.sharedContext??null,sharedContextConsent:i?.sharedContextConsent,onConsentSettled:t?.onConsentSettled,onConsentMutation:t?.onConsentMutation,onPageEvent:t?.onPageEvent};i=o,r=(e,t)=>{j(o,e,t),o.consent===null&&o.target.config?.consentConfiguration?.enabled===!0&&o.target.config?.apps?.[e]?.category!==`necessary`&&N(o),P(o)};for(let[e,t]of n)j(o,e,t);let s=P(o);return e.config?.consentConfiguration?.enabled===!0&&x(e)?await N(o):o.onConsentSettled?.(o.consent),await s,I(o)}}},R=512,z=864e5,B=e=>Object.fromEntries(Object.entries(e).map(([e,t])=>[e,Object.fromEntries(Object.entries(t).map(([e,t])=>[e,t.value]))])),V=(e,t)=>`qinto:cap:${encodeURIComponent(e)}:${encodeURIComponent(t)}`,H=e=>{try{let t=window.sessionStorage.getItem(e);if(t===null)return null;let n=JSON.parse(t);return typeof n.at!=`number`||typeof n.anonId!=`string`||typeof n.apps!=`object`||n.apps===null||Date.now()-n.at>z?null:{at:n.at,anonId:n.anonId,apps:n.apps}}catch{return null}},U=(e,t)=>{try{window.sessionStorage.setItem(e,JSON.stringify(t))}catch{}},W=e=>{try{window.sessionStorage.removeItem(e)}catch{}},G=e=>{try{return decodeURIComponent(e)}catch{return e}},le=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=G(t.slice(n+1)))}return e},ue=(e,t)=>{let n={};for(let r of e.queryParams){let e=t.params.get(r);e!==null&&e.length<=R&&(n[r]={value:e,source:`query`})}for(let r of e.cookies){let e=t.cookies[r];e!==void 0&&e.length<=R&&(n[r]={value:e,source:`cookie`})}return n},de=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:le()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||!y(t,i,a.category))continue;let e=ue(a.capture,n);Object.keys(e).length>0&&(r[i]=e)}return r},fe=(e,t)=>{let n={};for(let[r,i]of Object.entries(e)){let e=t[r]??{},a={};for(let[t,n]of Object.entries(i))(e[t]?.value!==n.value||e[t]?.source!==n.source)&&(a[t]=n);Object.keys(a).length>0&&(n[r]=a)}return n},pe=(e,t,n,r)=>{let i=V(r,n),a=H(i),o=a?.apps??{},s=a?.anonId??null,c=a===null,l={},u=0,d=(e,t)=>{s!==null&&s!==e.anonId&&(o={}),s=e.anonId;let n=new Set(Object.entries(e.accepted).flatMap(([e,t])=>t.map(t=>`${e}\u0000${t}`)));for(let[e,r]of Object.entries(t))for(let[t,i]of Object.entries(r))n.has(`${e}\u0000${t}`)&&(o[e]={...o[e],[t]:i});U(i,{at:Date.now(),anonId:s,apps:o})},f=null,p=()=>{u+=1,o={},l={},W(i)},m=n=>{if(f=n,!c)return;let r=fe(de(e,n),{...o,...l});if(Object.keys(r).length===0)return;let i=u;l={...l,...r},t(B(r)).then(e=>{i===u&&d(e,r)}).catch(()=>{}).finally(()=>{l={}})};return{settled:e=>{m(e)},needsAnon:()=>!c,observedAnon:e=>{(e===null||s!==null&&s!==e)&&p(),s=e,c=!0,m(f)},clear:p}},K=Symbol.for(`qinto.connectGate`),q=()=>{},me=e=>{let t=globalThis,n=(t[K]??Promise.resolve()).then(e);return t[K]=n.then(q,q),n},J=class extends n{constructor(e){super(e),this.name=`QintoProtocolError`}},he=e=>{if(typeof e!=`string`)return null;let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t)return null;let n=t;return n.t===`ack`||n.t===`error`||n.t===`consentState`||n.t===`session`||n.t===`captureAck`||n.t===`geoInstalls`||n.t===`appPush`||n.t===`sharedContext`?t:null},ge=e=>{if(e.t===`consentState`)return{categories:e.categories,apps:e.apps};if(e.t===`session`)return{anonId:e.anonId,globalId:e.globalId,ip:e.ip,geo:e.geo};if(e.t===`captureAck`)return{anonId:e.anonId,accepted:e.accepted};if(e.t===`geoInstalls`)return e.installs},_e=e=>{let t=new Map,n=e=>{let n=t.get(e);if(n!==void 0)return clearTimeout(n.timer),t.delete(e),n};return{submit:n=>new Promise((i,a)=>{let o={frame:n,sent:e.send(n),resolve:i,reject:a,timer:setTimeout(()=>{t.delete(n.ref),a(new r(`The Qinto request timed out.`))},e.requestTimeoutMs)};t.set(n.ref,o)}),flush:()=>{for(let n of t.values())n.sent||=e.send(n.frame)},deliver:e=>{let t=e.ref===void 0?void 0:n(e.ref);if(t!==void 0){if(e.t===`error`){t.reject(new J(e.message));return}t.resolve(ge(e))}},rejectAll:e=>{let n=[...t.values()];t.clear();for(let t of n)clearTimeout(t.timer),t.reject(e)}}},Y=()=>{let e=document.referrer;return{url:window.location.href,...e===``?{}:{referrer:e}}},ve=e=>new WebSocket(e),ye=500,be=3e4,X=4096,xe=8192,Se=(e,t)=>{if(t.url.length>X)return e;let n=new URLSearchParams({url:t.url});t.referrer!==void 0&&t.referrer.length<=X&&n.set(`referrer`,t.referrer);let r=`${e}?${n}`;return r.length<=xe?r:e},Ce=`session not initialized`,we=(e,t)=>{let n=Math.min(ye*2**e,be);return Math.round(n/2+n/2*t)},Te=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`&&(t.onSharedContext?.(e),!0),Ee=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=null,o=_e({send:e=>n===null||n.readyState!==1?!1:(n.send(JSON.stringify(e)),!0),requestTimeoutMs:e.requestTimeoutMs}),s=t=>{e.onError?.(t)},c=()=>{if(r!==null&&(clearTimeout(r),r=null),n!==null){let e=n;n=null,e.close()}o.rejectAll(new J(`connection closed`))},l=()=>{let u=ve(Se(t,Y()));n=u,u.onopen=()=>{i=0;let e=a;a=null,o.flush(),e?.resolve()},u.onmessage=t=>{let n=he(t.data);if(n===null){s(new J(`invalid message`));return}Te(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),o.deliver(n),n.t===`error`&&n.message===Ce&&u.close())},u.onerror=()=>{s(new J(`connection closed`))},u.onclose=()=>{if(n!==u)return;n=null;let e=a;if(e!==null){a=null,c(),e.reject(new J(`connection closed`));return}o.rejectAll(new J(`connection closed`)),r=setTimeout(()=>{r=null,l()},we(i,Math.random())),i+=1}};return{connect:()=>new Promise((e,t)=>{a={resolve:e,reject:t},l()}),submit:e=>o.submit(e),close:()=>{c()}}},De=1e4,Oe=()=>{let e=0;return()=>(e+=1,`q${e}`)},ke=(e,t,n)=>{let r=null,i=()=>({occurredAt:Date.now(),page:Y()}),o=async()=>{let n=await e.submit({t:`getSession`,ref:t()});return r=n.anonId,n};return{destination:n.replace(/\/+$/,``),actionContext:i,submitIdentify:async({traits:n,id:r,context:i,appResults:a})=>{await e.submit({t:`identify`,ref:t(),traits:n,id:r,context:i,appResults:a})},submitTrack:async({event:n,eventId:r,properties:i,context:a,appResults:o,installs:s})=>{await e.submit({t:`track`,ref:t(),event:n,eventId:r,properties:i,context:a,appResults:o,installs:s})},submitConsent:async(n,r)=>{await e.submit({t:`consent`,ref:t(),categories:n.categories,apps:n.apps,context:r})},track:async(n,r,o)=>{let s=a(o?.eventId,r);return await e.submit({t:`track`,ref:t(),event:n,eventId:s,properties:r,context:i(),installs:o?.installs}),{eventId:s}},alias:async n=>{await e.submit({t:`alias`,ref:t(),alias:n})},getConsent:async()=>await e.submit({t:`getConsent`,ref:t()}),getGeoInstalls:async()=>await e.submit({t:`getGeoInstalls`,ref:t()}),getSession:o,getAnonId:async()=>(r===null&&await o(),r),close:async()=>{e.close()}}},Ae=async e=>{let t=Ee({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??De,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await me(()=>t.connect());let n=Oe();return{client:ke(t,n,e.destination),submitCapture:async e=>await t.submit({t:`capture`,ref:n(),apps:e})}},je=(e,t)=>{let n=null,r=L(e,{onConsentSettled:e=>{n?.settled(e)},onConsentMutation:()=>{n?.clear()},onPageEvent:e=>{n?.settled(e)}});return{connect:async i=>{let a=await Ae({...i,onAppPush:r.push,onSharedContext:r.sharedContext,onAnonId:e=>{n?.observedAnon(e)}});n=pe(e,a.submitCapture,i.destination,t);let o=await r.connect(a.client);return n.needsAnon()&&n.observedAnon((await a.client.getSession()).anonId),o}}},Z=d(),Q=p(Z),$=`window.${Z}`;if(Q!==null&&Q.ready===void 0){let e=je(Q,Z);t(Q),v(Q,async()=>{let t=Q.config?.destination;if(typeof t!=`string`||t===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);return e.connect({destination:t})},$)}})();