@blotout/qinto-cli 0.1.31 → 0.1.32
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/index.js +2667 -2659
- package/dist/index.js.map +1 -1
- package/dist/worker-artifact/app-runtime/index.js +81 -23
- package/dist/worker-artifact/main/73ef5f028ec35836560c0489d1abdeea83eceede-q.js.txt +1 -0
- package/dist/worker-artifact/main/index.js +1131 -1040
- package/dist/worker-artifact/version.json +8 -8
- package/package.json +1 -1
- package/dist/worker-artifact/main/8809017061697bf9b90fa4d72f7eb2e0f0e00ad4-q.js.txt +0 -1
|
@@ -20105,7 +20105,7 @@ var userGeoSchema = external_exports.object({
|
|
|
20105
20105
|
|
|
20106
20106
|
// ../../../libs/app-envelope/src/envelope.ts
|
|
20107
20107
|
var ENVELOPE_VERSION = 3;
|
|
20108
|
-
var ENVELOPE_ERROR_CODES = ["invalid_arguments"];
|
|
20108
|
+
var ENVELOPE_ERROR_CODES = ["invalid_arguments", "result_too_large", "callee_timeout", "rpc_error"];
|
|
20109
20109
|
var MAX_INSTALLS_PER_APP = 15;
|
|
20110
20110
|
var MAX_APPS_PER_DOMAIN = 50;
|
|
20111
20111
|
var MAX_EMITS_PER_INSTALL = 10;
|
|
@@ -20119,6 +20119,7 @@ var MAX_SHARED_CONTEXT_ENTRY_BYTES = 4 * 1024;
|
|
|
20119
20119
|
var MAX_PUSH_BYTES = 16 * 1024;
|
|
20120
20120
|
var MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
20121
20121
|
var MAX_RPC_BYTES = 128 * 1024;
|
|
20122
|
+
var TRAFFIC_CLASSES = ["hot", "cold"];
|
|
20122
20123
|
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();
|
|
20123
20124
|
var installRuleSchema = external_exports.object({
|
|
20124
20125
|
mode: external_exports.enum(["except", "only"]),
|
|
@@ -20203,7 +20204,15 @@ var envelopeRequestSchema = external_exports.object({
|
|
|
20203
20204
|
context: external_exports.object({ private: contextEntrySchema.optional(), shared: external_exports.record(external_exports.string().min(1).max(30), contextEntrySchema).optional() }).strict().optional(),
|
|
20204
20205
|
// RPC depth is capped at 3 by the broker; hook depth at 2 by the emit path.
|
|
20205
20206
|
depth: external_exports.number().int().min(0).max(3),
|
|
20206
|
-
rpc: external_exports.object({
|
|
20207
|
+
rpc: external_exports.object({
|
|
20208
|
+
caller: external_exports.string().min(1).max(30).nullable(),
|
|
20209
|
+
fn: external_exports.string().min(1).max(64),
|
|
20210
|
+
args: external_exports.unknown(),
|
|
20211
|
+
// Optional on the wire: a site worker predating traffic classes sends none, which means hot.
|
|
20212
|
+
traffic: external_exports.enum(TRAFFIC_CLASSES).optional(),
|
|
20213
|
+
// Cold calls only: the broker mints it so the callee can query its own catalog.
|
|
20214
|
+
queryTicket: external_exports.string().min(1).max(2048).optional()
|
|
20215
|
+
}).strict().refine((rpc) => {
|
|
20207
20216
|
return new TextEncoder().encode(JSON.stringify(rpc.args ?? null)).length <= MAX_RPC_BYTES;
|
|
20208
20217
|
}, "RPC args exceed the size cap").optional(),
|
|
20209
20218
|
action: external_exports.object({
|
|
@@ -21286,7 +21295,7 @@ var brokerActive = async (env, input2) => {
|
|
|
21286
21295
|
}
|
|
21287
21296
|
return response.status >= 400 && response.status < 500 ? { kind: "refused" } : { kind: "unknown" };
|
|
21288
21297
|
};
|
|
21289
|
-
var buildAppsClient = (env, envelope) => {
|
|
21298
|
+
var buildAppsClient = (env, envelope, traffic) => {
|
|
21290
21299
|
const caller = callerSlug(env);
|
|
21291
21300
|
const subject = envelope.user?.anonId;
|
|
21292
21301
|
return {
|
|
@@ -21303,7 +21312,8 @@ var buildAppsClient = (env, envelope) => {
|
|
|
21303
21312
|
fn,
|
|
21304
21313
|
args,
|
|
21305
21314
|
...options?.installId === void 0 ? {} : { installId: options.installId },
|
|
21306
|
-
depth: envelope.depth + 1
|
|
21315
|
+
depth: envelope.depth + 1,
|
|
21316
|
+
traffic
|
|
21307
21317
|
});
|
|
21308
21318
|
return answer.result;
|
|
21309
21319
|
},
|
|
@@ -21812,10 +21822,14 @@ var buildWorkflowContext = (env, stamp) => {
|
|
|
21812
21822
|
const { variables, secrets } = projectInstallValues(parseVariableMaps(env), variableKinds, stamp.ord);
|
|
21813
21823
|
const { appVariables, appSecrets } = projectAppValues(env, appVariableKinds);
|
|
21814
21824
|
const install = { id: stamp.installId, label: stamp.installLabel };
|
|
21815
|
-
const apps = buildAppsClient(
|
|
21816
|
-
|
|
21817
|
-
|
|
21818
|
-
|
|
21825
|
+
const apps = buildAppsClient(
|
|
21826
|
+
env,
|
|
21827
|
+
{
|
|
21828
|
+
...stamp.anonId === null ? {} : { user: { anonId: stamp.anonId, globalId: null, properties: {} } },
|
|
21829
|
+
depth: 0
|
|
21830
|
+
},
|
|
21831
|
+
"cold"
|
|
21832
|
+
);
|
|
21819
21833
|
return {
|
|
21820
21834
|
env: appEnv(env),
|
|
21821
21835
|
install,
|
|
@@ -21890,7 +21904,8 @@ var buildContext = ({
|
|
|
21890
21904
|
pushes,
|
|
21891
21905
|
captures,
|
|
21892
21906
|
context,
|
|
21893
|
-
currency
|
|
21907
|
+
currency,
|
|
21908
|
+
traffic
|
|
21894
21909
|
}) => {
|
|
21895
21910
|
const { variables, secrets } = projectInstallValues(maps, kinds, install.ord);
|
|
21896
21911
|
const subject = envelope.user?.anonId ?? null;
|
|
@@ -21960,7 +21975,7 @@ var buildContext = ({
|
|
|
21960
21975
|
observability: buildObservability(install.ord),
|
|
21961
21976
|
identity: buildIdentity(env),
|
|
21962
21977
|
currency,
|
|
21963
|
-
apps: buildAppsClient(env, envelope)
|
|
21978
|
+
apps: buildAppsClient(env, envelope, traffic)
|
|
21964
21979
|
};
|
|
21965
21980
|
};
|
|
21966
21981
|
|
|
@@ -22081,7 +22096,7 @@ var dispatchSchedule = async (envelope, bundle, env) => {
|
|
|
22081
22096
|
observability: buildObservability(install.ord),
|
|
22082
22097
|
identity: buildIdentity(env),
|
|
22083
22098
|
currency,
|
|
22084
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22099
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold"),
|
|
22085
22100
|
query: buildQuery({ env, ticket: install.queryTicket, installId: install.id }),
|
|
22086
22101
|
push: async (userId, message) => {
|
|
22087
22102
|
await brokerPush(env, {
|
|
@@ -22210,7 +22225,7 @@ var buildContext2 = (envelope, env) => {
|
|
|
22210
22225
|
observability: buildObservability(install.ord),
|
|
22211
22226
|
identity: buildIdentity(env),
|
|
22212
22227
|
currency: buildCurrency(env),
|
|
22213
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22228
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold"),
|
|
22214
22229
|
query: buildQuery({ env, ticket: envelope.tool.queryTicket, installId: install.id }),
|
|
22215
22230
|
track: buildTrack(env, "tool", install.id),
|
|
22216
22231
|
fail: (message) => {
|
|
@@ -22492,7 +22507,7 @@ var buildContext3 = ({
|
|
|
22492
22507
|
observability: buildObservability(install.ord),
|
|
22493
22508
|
identity: buildIdentity(env),
|
|
22494
22509
|
currency,
|
|
22495
|
-
apps: buildAppsClient(env, { depth: 0 }),
|
|
22510
|
+
apps: buildAppsClient(env, { depth: 0 }, "hot"),
|
|
22496
22511
|
push: async (userId, message) => {
|
|
22497
22512
|
await brokerPush(env, {
|
|
22498
22513
|
userId,
|
|
@@ -22741,6 +22756,17 @@ var checkAgainst = async (schema, value) => {
|
|
|
22741
22756
|
};
|
|
22742
22757
|
|
|
22743
22758
|
// src/rpc.ts
|
|
22759
|
+
var MAX_RPC_ERROR_MESSAGE_LENGTH = 1024;
|
|
22760
|
+
var rpcQuery = (env, rpc, installId) => {
|
|
22761
|
+
if (rpc.queryTicket !== void 0) {
|
|
22762
|
+
return buildQuery({ env, ticket: rpc.queryTicket, installId });
|
|
22763
|
+
}
|
|
22764
|
+
const reason = (rpc.traffic ?? "hot") === "hot" ? "catalog queries are not available on hot traffic" : "catalog queries are not available on this site until its next deploy";
|
|
22765
|
+
const refuse = async () => {
|
|
22766
|
+
throw new Error(reason);
|
|
22767
|
+
};
|
|
22768
|
+
return { catalog: refuse, analytics: refuse };
|
|
22769
|
+
};
|
|
22744
22770
|
var dispatchRpc = async (envelope, bundle, env) => {
|
|
22745
22771
|
if (envelope.installs.length > 1) {
|
|
22746
22772
|
return jsonError(400, "rpc envelope carries more than one install");
|
|
@@ -22768,14 +22794,29 @@ var dispatchRpc = async (envelope, bundle, env) => {
|
|
|
22768
22794
|
const currency = buildCurrency(env);
|
|
22769
22795
|
const subject = envelope.user?.anonId ?? null;
|
|
22770
22796
|
const ctx = {
|
|
22771
|
-
...buildContext({
|
|
22797
|
+
...buildContext({
|
|
22798
|
+
env,
|
|
22799
|
+
envelope,
|
|
22800
|
+
site,
|
|
22801
|
+
install,
|
|
22802
|
+
maps,
|
|
22803
|
+
kinds,
|
|
22804
|
+
appScope,
|
|
22805
|
+
emits,
|
|
22806
|
+
pushes,
|
|
22807
|
+
captures,
|
|
22808
|
+
context,
|
|
22809
|
+
currency,
|
|
22810
|
+
traffic: rpc.traffic ?? "hot"
|
|
22811
|
+
}),
|
|
22772
22812
|
context: fetchedContext(
|
|
22773
22813
|
env,
|
|
22774
22814
|
(what) => {
|
|
22775
22815
|
return requireSubject(subject, what);
|
|
22776
22816
|
},
|
|
22777
22817
|
context
|
|
22778
|
-
)
|
|
22818
|
+
),
|
|
22819
|
+
query: rpcQuery(env, rpc, install.id)
|
|
22779
22820
|
};
|
|
22780
22821
|
let value;
|
|
22781
22822
|
try {
|
|
@@ -22785,17 +22826,19 @@ var dispatchRpc = async (envelope, bundle, env) => {
|
|
|
22785
22826
|
} catch (error61) {
|
|
22786
22827
|
const message = failureMessage(error61);
|
|
22787
22828
|
console.warn(`rpc failed for install ${install.id}: ${message}`);
|
|
22829
|
+
if (error61?.__qintoRpcError === true) {
|
|
22830
|
+
return json2(200, { v: ENVELOPE_VERSION, error: { code: "rpc_error", message: message.slice(0, MAX_RPC_ERROR_MESSAGE_LENGTH) } });
|
|
22831
|
+
}
|
|
22788
22832
|
return json2(200, { v: ENVELOPE_VERSION, error: { message } });
|
|
22789
22833
|
}
|
|
22790
22834
|
const checked = await checkAgainst(definition.output, value);
|
|
22791
22835
|
if (!checked.ok) {
|
|
22792
22836
|
return jsonError(200, failureMessage(`rpc result does not match the output schema: ${checked.message}`));
|
|
22793
22837
|
}
|
|
22794
|
-
const
|
|
22795
|
-
|
|
22796
|
-
|
|
22797
|
-
}
|
|
22798
|
-
const body = { v: ENVELOPE_VERSION, rpc: { result } };
|
|
22838
|
+
const body = {
|
|
22839
|
+
v: ENVELOPE_VERSION,
|
|
22840
|
+
rpc: { result: checked.value === void 0 ? null : checked.value }
|
|
22841
|
+
};
|
|
22799
22842
|
const contextWrites = context.writes();
|
|
22800
22843
|
if (emits.length > 0 || pushes.length > 0 || captures.length > 0 || contextWrites.length > 0) {
|
|
22801
22844
|
body.effects = [{ ord: install.ord, emits, pushes, captures, context: contextWrites }];
|
|
@@ -22977,7 +23020,7 @@ var dispatchUi = async ({ request, env, versions }) => {
|
|
|
22977
23020
|
observability: buildObservability(context.install.ord),
|
|
22978
23021
|
identity: buildIdentity(env),
|
|
22979
23022
|
currency: buildCurrency(env),
|
|
22980
|
-
apps: buildAppsClient(env, { depth: 0 })
|
|
23023
|
+
apps: buildAppsClient(env, { depth: 0 }, "cold")
|
|
22981
23024
|
};
|
|
22982
23025
|
let response;
|
|
22983
23026
|
try {
|
|
@@ -23048,7 +23091,21 @@ var runInstalls = async (envelope, env, invoke) => {
|
|
|
23048
23091
|
const pushes = [];
|
|
23049
23092
|
const captures = [];
|
|
23050
23093
|
const context = contextCollector();
|
|
23051
|
-
const ctx = buildContext({
|
|
23094
|
+
const ctx = buildContext({
|
|
23095
|
+
env,
|
|
23096
|
+
envelope,
|
|
23097
|
+
site,
|
|
23098
|
+
install,
|
|
23099
|
+
maps,
|
|
23100
|
+
kinds,
|
|
23101
|
+
appScope,
|
|
23102
|
+
emits,
|
|
23103
|
+
pushes,
|
|
23104
|
+
captures,
|
|
23105
|
+
context,
|
|
23106
|
+
currency,
|
|
23107
|
+
traffic: "hot"
|
|
23108
|
+
});
|
|
23052
23109
|
try {
|
|
23053
23110
|
await installSpan(install, () => {
|
|
23054
23111
|
return invoke(ctx, install);
|
|
@@ -23113,7 +23170,8 @@ var runTransform = async (envelope, env, action, handler) => {
|
|
|
23113
23170
|
pushes,
|
|
23114
23171
|
captures,
|
|
23115
23172
|
context,
|
|
23116
|
-
currency: buildCurrency(env)
|
|
23173
|
+
currency: buildCurrency(env),
|
|
23174
|
+
traffic: "hot"
|
|
23117
23175
|
});
|
|
23118
23176
|
const ctx = {
|
|
23119
23177
|
...withoutApps,
|
|
@@ -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))},ee=e=>()=>Promise.reject(e),h=(e,t)=>{let[n,r,i,a]=t;e(n,r).then(i,a)},g=e=>{let t=[];return t.push=(...t)=>{for(let n of t)h(e,n);return 0},t},_=(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=g(e);for(let n of t)h(e,n)},o=t().then(e=>{a(m(e,n))},e=>{throw a(ee(e)),e});return o.catch(c),i.ready=o,o},v=(e,t,n)=>n===void 0||!o.some(e=>e===n)?!1:n===`necessary`||e!==null&&e.categories[n]===!0&&e.apps[t]!==!1,y=(e,t)=>e.config?.gpc===!0&&navigator.globalPrivacyControl===!0&&(t===`marketing`||t===`salesOfData`),b=(e,t,n)=>{let r=e.config?.apps?.[t]?.category;return y(e,r)?!1:e.config?.consentConfiguration?.enabled!==!0||v(n,t,r)},x=e=>Object.values(e.config?.apps??{}).some(e=>e.category!==`necessary`||e.capture!==void 0),te=(e,t,n,r)=>b(e,t,n)?r===void 0||b(e,t,r):!1,ne=e=>{let{categories:t,apps:n}=e;if(typeof t==`object`&&t&&typeof n==`object`&&n)return{categories:t,apps:n}},re=()=>{},S=(e,t)=>{console.error(`[Qinto] A handler of app "${e.slug}" (install "${e.installId}") failed.`,t)},C=(e,t,n)=>{for(let r of t)try{let t=r(n);t instanceof Promise&&t.catch(t=>{S(e,t)})}catch(t){S(e,t)}},w=(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(re)},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&&te(e.target,t,e.consent,e.sharedContextConsent)&&C(i,[n],e.sharedContext)}};try{n(a)}catch(e){console.error(`[Qinto] App "${t}" failed to activate install "${r.id}".`,e)}},T=100,E=1024,D=32768,ie=e=>{let t;try{t=JSON.stringify(e)}catch{return}if(!(t===void 0||new TextEncoder().encode(t).length>E))return JSON.parse(t)},ae=e=>{let t={};for(let n of e){if(n.settled!==n.total||n.values.length!==1)continue;let e=ie(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<=D&&(t[n.source.slug]=r)}return Object.keys(t).length===0?void 0:t},oe=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,T)});await Promise.race([Promise.all(o),t]),clearTimeout(e)}return ae(a)},se=(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`))}},ce=(e,t,n,r)=>{let i;try{i=t(n,r)}catch(t){S(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;S(e,TypeError(`A transform hook returned neither nothing, false, nor { installs }.`))},le=(e,t,n,r)=>{let i=r;for(let r of e)for(let e of r.transformHooks){let a=ce(r,e,t,n);if(a===!1)return!1;a!==void 0&&(i=i===void 0?a:se(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)w(e,t,i,n)},M=(e,t)=>{let n=e;n.consent=t,n.sharedContextConsent=void 0;for(let n of e.instances)C(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 oe(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=>{C(e,e.eventHandlers,t)},report:S})},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=le(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=ne(e),a=r??n.consent;n.sharedContextConsent=r;for(let e of n.instances)b(n.target,e.slug,a)&&C(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)&&C(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{}},ue=e=>{try{return decodeURIComponent(e)}catch{return e}},de=()=>{let e={};for(let t of document.cookie.split(`;`)){let n=t.indexOf(`=`);n>0&&(e[t.slice(0,n).trim()]=ue(t.slice(n+1)))}return e},fe=(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},pe=(e,t)=>{let n={params:new URLSearchParams(window.location.search),cookies:de()},r={};for(let[i,a]of Object.entries(e.config?.apps??{})){if(a.capture===void 0||y(e,a.category)||!v(t,i,a.category))continue;let o=fe(a.capture,n);Object.keys(o).length>0&&(r[i]=o)}return r},me=(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},G=(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=me(pe(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=()=>{},he=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`}},ge=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},_e=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},ve=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(_e(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}}},ye=e=>new WebSocket(e),be=500,xe=3e4,Se=1e4,X=4096,Ce=8192,we=(e,t,n)=>{let r=n?`${e}?reconnect=1`:e;if(t.url.length>X)return r;let i=new URLSearchParams({url:t.url});t.referrer!==void 0&&t.referrer.length<=X&&i.set(`referrer`,t.referrer),n&&i.set(`reconnect`,`1`);let a=`${e}?${i}`;return a.length<=Ce?a:r},Te=`session not initialized`,Ee=1e3,De=`erased`,Oe=(e,t)=>{let n=Math.min(be*2**e,xe);return Math.round(n/2+n/2*t)},ke=(e,t)=>e.t===`appPush`?(t.onAppPush?.(e),!0):e.t===`sharedContext`&&(t.onSharedContext?.(e),!0),Ae=e=>{let t=`${e.destination.replace(/\/+$/,``)}/open`,n=null,r=null,i=0,a=!1,o=!1,s=null,c=ve({send:e=>n===null||n.readyState!==1?!1:(n.send(JSON.stringify(e)),!0),requestTimeoutMs:e.requestTimeoutMs}),l=t=>{e.onError?.(t)},u=()=>{if(o=!0,document.removeEventListener(`visibilitychange`,p),r!==null&&(clearTimeout(r),r=null),n!==null){let e=n;n=null,e.close()}c.rejectAll(new J(`connection closed`))},d=()=>{document.visibilityState!==`hidden`&&(r=setTimeout(()=>{r=null,f()},Oe(i,Math.random())),i+=1)},f=()=>{let r=ye(we(t,Y(),a));a=!0,n=r;let o;r.onopen=()=>{o=Date.now();let e=s;s=null,c.flush(),e?.resolve()},r.onmessage=t=>{let n=ge(t.data);if(n===null){l(new J(`invalid message`));return}ke(n,e)||(`anonId`in n&&typeof n.anonId==`string`&&e.onAnonId?.(n.anonId),c.deliver(n),n.t===`error`&&n.message===Te&&r.close())},r.onerror=()=>{l(new J(`connection closed`))},r.onclose=e=>{if(n!==r)return;n=null;let t=s;if(t!==null){s=null,u(),t.reject(new J(`connection closed`));return}if(e.code===Ee&&e.reason===De){u();return}o!==void 0&&Date.now()-o>=Se&&(i=0),c.rejectAll(new J(`connection closed`)),d()}},p=()=>{if(document.visibilityState===`hidden`){r!==null&&(clearTimeout(r),r=null);return}n===null&&r===null&&f()};return{connect:()=>new Promise((e,t)=>{s={resolve:e,reject:t},document.addEventListener(`visibilitychange`,p),f()}),submit:e=>o?Promise.reject(new J(`connection closed`)):(n===null&&r===null&&f(),c.submit(e)),close:()=>{u()}}},je=1e4,Me=()=>{let e=0;return()=>(e+=1,`q${e}`)},Ne=(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()}}},Pe=async e=>{let t=Ae({destination:e.destination,requestTimeoutMs:e.requestTimeoutMs??je,onError:e.onError,onAppPush:e.onAppPush,onSharedContext:e.onSharedContext,onAnonId:e.onAnonId});await he(()=>t.connect());let n=Me();return{client:Ne(t,n,e.destination),submitCapture:async e=>await t.submit({t:`capture`,ref:n(),apps:e})}},Fe=(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 Pe({...i,onAppPush:r.push,onSharedContext:r.sharedContext,onAnonId:e=>{n?.observedAnon(e)}});n=G(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=Fe(Q,Z);t(Q),_(Q,async()=>{let t=Q.config?.destination;if(typeof t!=`string`||t===``)throw Error(`[Qinto] ${$}.config.destination is missing.`);return e.connect({destination:t})},$)}})();
|