@preprio/toolkit 0.6.0-alpha.1 → 0.6.0-alpha.10
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/README.md +163 -61
- package/dist/astro/{chunk-O7N6GPAH.js → chunk-CG2QBHNU.js} +1 -1
- package/dist/astro/graphql.cjs +58 -10
- package/dist/astro/graphql.d.cts +33 -38
- package/dist/astro/graphql.d.ts +33 -38
- package/dist/astro/graphql.js +59 -11
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/{chunk-VI6QZTBM.js → chunk-LIDUJWWJ.js} +1 -1
- package/dist/{chunk-TBKSBXGH.js → chunk-M3RBYJ5J.js} +52 -5
- package/dist/{chunk-3JLWZQ37.js → chunk-SF6TN4JR.js} +1 -1
- package/dist/{chunk-YWIKKWBR.js → chunk-TN6SNAR2.js} +1 -1
- package/dist/graphql/codegen.cjs +51 -4
- package/dist/graphql/codegen.js +3 -3
- package/dist/graphql.cjs +89 -10
- package/dist/graphql.d.cts +69 -39
- package/dist/graphql.d.ts +69 -39
- package/dist/graphql.js +38 -9
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/nextjs/chunk-B4GVZEOL.js +549 -0
- package/dist/nextjs/components.cjs +297 -81
- package/dist/nextjs/components.d.cts +26 -11
- package/dist/nextjs/components.d.ts +26 -11
- package/dist/nextjs/components.js +288 -73
- package/dist/nextjs/graphql.cjs +856 -266
- package/dist/nextjs/graphql.d.cts +184 -116
- package/dist/nextjs/graphql.d.ts +184 -116
- package/dist/nextjs/graphql.js +543 -266
- package/dist/nextjs/index.cjs +116 -54
- package/dist/nextjs/index.d.cts +61 -23
- package/dist/nextjs/index.d.ts +61 -23
- package/dist/nextjs/index.js +97 -299
- package/dist/nextjs/{server-CjpELYvq.d.ts → server-BL-sqZvu.d.cts} +1 -1
- package/dist/nextjs/{server-CjpELYvq.d.cts → server-BL-sqZvu.d.ts} +1 -1
- package/dist/nuxt/{chunk-IQDSBPDN.js → chunk-FMC3DP7N.js} +1 -1
- package/dist/nuxt/graphql.cjs +58 -10
- package/dist/nuxt/graphql.d.cts +33 -38
- package/dist/nuxt/graphql.d.ts +33 -38
- package/dist/nuxt/graphql.js +59 -11
- package/dist/nuxt/index.cjs +1 -1
- package/dist/nuxt/index.js +1 -1
- package/dist/react/components.cjs +1 -1
- package/dist/react/components.js +1 -1
- package/dist/sveltekit/{chunk-OKYZ6HPH.js → chunk-AJPKBAHO.js} +1 -1
- package/dist/sveltekit/graphql.cjs +58 -10
- package/dist/sveltekit/graphql.d.cts +33 -38
- package/dist/sveltekit/graphql.d.ts +33 -38
- package/dist/sveltekit/graphql.js +59 -11
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +1 -1
- package/dist/nextjs/chunk-BQ6IGSH6.js +0 -231
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createPreprPreview,
|
|
4
4
|
loadTrackingPixel
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-LIDUJWWJ.js";
|
|
6
6
|
import "../chunk-S5RWVMDJ.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-TN6SNAR2.js";
|
|
8
8
|
|
|
9
9
|
// src/nextjs/components.ts
|
|
10
10
|
import { usePathname, useRouter } from "next/navigation";
|
|
@@ -34,68 +34,149 @@ function isReactHydrated(text) {
|
|
|
34
34
|
return true;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
// src/nextjs/
|
|
38
|
-
function
|
|
39
|
-
const match = document.cookie.match(/(?:^|; )prepr_ab_bucket=([AB])(?:;|$)/);
|
|
40
|
-
const bucket = match ? match[1] : "A";
|
|
37
|
+
// src/nextjs/decision-switch.ts
|
|
38
|
+
function applyPreprDecisions(decision, options = {}) {
|
|
41
39
|
const state = window;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
raw = "";
|
|
40
|
+
const key = location.pathname + location.search;
|
|
41
|
+
const previous = state.__preprDecision;
|
|
42
|
+
let value = decision;
|
|
43
|
+
if (value !== void 0 && value !== "*" && options.refresh && previous && previous.key === key && previous.value !== "*") {
|
|
44
|
+
const pairs = (from) => {
|
|
45
|
+
const out = {};
|
|
46
|
+
from.split("~").forEach((pair) => {
|
|
47
|
+
const colon = pair.indexOf(":");
|
|
48
|
+
if (colon > 0) out[pair.slice(0, colon)] = pair;
|
|
49
|
+
});
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
52
|
+
const before = pairs(previous.value);
|
|
53
|
+
const after = pairs(value);
|
|
54
|
+
document.querySelectorAll("[data-prepr-v][data-prepr-show]").forEach((element) => {
|
|
55
|
+
const range = document.createRange();
|
|
56
|
+
range.selectNodeContents(element);
|
|
57
|
+
if (range.getBoundingClientRect().top >= window.innerHeight) return;
|
|
58
|
+
(element.getAttribute("data-prepr-v") || "").split(" ").forEach((token) => {
|
|
59
|
+
const group = token.slice(0, token.indexOf(":"));
|
|
60
|
+
if (before[group]) after[group] = before[group];
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
value = Object.keys(after).map((group) => after[group]).join("~");
|
|
67
64
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
65
|
+
if (value !== void 0) state.__preprDecision = { key, value };
|
|
66
|
+
const current = state.__preprDecision;
|
|
67
|
+
if (!current || current.key !== key) return false;
|
|
68
|
+
document.querySelectorAll("[data-prepr-decision]").forEach((marker) => {
|
|
69
|
+
marker.setAttribute("data-prepr-decided", "");
|
|
70
|
+
});
|
|
71
|
+
const defaults = current.value === "*";
|
|
72
|
+
const chosen = {};
|
|
73
|
+
current.value.split("~").forEach((pair) => {
|
|
74
|
+
const colon = pair.indexOf(":");
|
|
75
|
+
if (colon > 0)
|
|
76
|
+
chosen[pair.slice(0, colon)] = pair.slice(colon + 1).split("|");
|
|
77
|
+
});
|
|
78
|
+
document.querySelectorAll("[data-prepr-v]").forEach((element) => {
|
|
79
|
+
const nested = element.hasAttribute("data-prepr-nested");
|
|
80
|
+
const show = defaults ? element.hasAttribute("data-prepr-default") : (element.getAttribute("data-prepr-v") || "").split(" ").every((token) => {
|
|
81
|
+
const colon = token.indexOf(":");
|
|
82
|
+
const variant = token.slice(colon + 1);
|
|
83
|
+
const variants = chosen[token.slice(0, colon)];
|
|
84
|
+
return !!variants && (nested ? variants[0] === variant : variants.indexOf(variant) >= 0);
|
|
83
85
|
});
|
|
86
|
+
if (show) element.setAttribute("data-prepr-show", "");
|
|
87
|
+
else element.removeAttribute("data-prepr-show");
|
|
84
88
|
});
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
function requestPreprDecision(key, options = {}) {
|
|
92
|
+
const fresh = 1e4;
|
|
93
|
+
const keep = 18e5;
|
|
94
|
+
const keepStatic = 36e5;
|
|
95
|
+
const state = window;
|
|
96
|
+
const asking = state.__preprAsking = state.__preprAsking || {};
|
|
97
|
+
const read = () => {
|
|
98
|
+
const all = {};
|
|
99
|
+
try {
|
|
100
|
+
const match = document.cookie.match(/(?:^|; )prepr_decisions=([^;]*)/);
|
|
101
|
+
const parsed = match ? JSON.parse(decodeURIComponent(match[1])) : null;
|
|
102
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed))
|
|
103
|
+
Object.keys(parsed).forEach((stored) => {
|
|
104
|
+
const entry = parsed[stored];
|
|
105
|
+
if (stored.charAt(0) === "/" && Array.isArray(entry) && typeof entry[0] === "string" && typeof entry[1] === "number")
|
|
106
|
+
all[stored] = [entry[0], entry[1]];
|
|
107
|
+
});
|
|
108
|
+
} catch {
|
|
90
109
|
}
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
110
|
+
return all;
|
|
111
|
+
};
|
|
112
|
+
const usable = (entry, now) => {
|
|
113
|
+
if (!entry) return false;
|
|
114
|
+
const age = now - entry[1];
|
|
115
|
+
return age >= 0 && age < (entry[0] === "*" ? fresh : entry[0] === "" ? keepStatic : keep);
|
|
116
|
+
};
|
|
117
|
+
const store = (answer) => {
|
|
118
|
+
const all = read();
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
const kept = all[key];
|
|
121
|
+
const entries = Object.keys(all).filter((stored) => stored !== key && usable(all[stored], now)).map((stored) => [stored, all[stored]]);
|
|
122
|
+
entries.push([
|
|
123
|
+
key,
|
|
124
|
+
answer === "*" && kept && usable(kept, now) && kept[0] !== "*" ? kept : [answer, now]
|
|
125
|
+
]);
|
|
126
|
+
entries.sort((a, b) => b[1][1] - a[1][1]);
|
|
127
|
+
entries.length = Math.min(entries.length, 20);
|
|
128
|
+
const encode = () => {
|
|
129
|
+
const out = {};
|
|
130
|
+
entries.forEach((entry) => {
|
|
131
|
+
out[entry[0]] = entry[1];
|
|
132
|
+
});
|
|
133
|
+
return encodeURIComponent(JSON.stringify(out));
|
|
134
|
+
};
|
|
135
|
+
let value = encode();
|
|
136
|
+
while (entries.length > 1 && value.length > 3e3) {
|
|
137
|
+
entries.pop();
|
|
138
|
+
value = encode();
|
|
139
|
+
}
|
|
140
|
+
document.cookie = "prepr_decisions=" + value + "; path=/; max-age=3600; samesite=lax" + (location.protocol === "https:" ? "; secure" : "");
|
|
141
|
+
};
|
|
142
|
+
const ask = () => {
|
|
143
|
+
if (!asking[key]) {
|
|
144
|
+
asking[key] = fetch(key, {
|
|
145
|
+
headers: { "Prepr-Decide": "1" },
|
|
146
|
+
cache: "no-store",
|
|
147
|
+
credentials: "same-origin",
|
|
148
|
+
// The proxy gives up on Prepr after its own `timeoutMs`; this only
|
|
149
|
+
// covers a proxy that never answers.
|
|
150
|
+
signal: AbortSignal.timeout ? AbortSignal.timeout(6e3) : void 0
|
|
151
|
+
}).then((response) => response.ok ? response.text() : "*").catch(() => "*").then((answer) => {
|
|
152
|
+
delete asking[key];
|
|
153
|
+
try {
|
|
154
|
+
store(answer);
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
return answer;
|
|
158
|
+
});
|
|
96
159
|
}
|
|
97
|
-
|
|
160
|
+
return asking[key];
|
|
161
|
+
};
|
|
162
|
+
const last = read()[key];
|
|
163
|
+
if (last && !(last[0] === "" && options.personalized) && usable(last, Date.now())) {
|
|
164
|
+
const value = last[0];
|
|
165
|
+
if (value !== "" && Date.now() - last[1] >= fresh) {
|
|
166
|
+
ask().then((answer) => {
|
|
167
|
+
if (answer !== "*" && answer !== value && options.onChange)
|
|
168
|
+
options.onChange(answer);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return { result: value, value: Promise.resolve(value) };
|
|
98
172
|
}
|
|
173
|
+
const pending = {
|
|
174
|
+
value: ask()
|
|
175
|
+
};
|
|
176
|
+
pending.value.then((answer) => {
|
|
177
|
+
pending.result = answer;
|
|
178
|
+
});
|
|
179
|
+
return pending;
|
|
99
180
|
}
|
|
100
181
|
|
|
101
182
|
// src/react/components.ts
|
|
@@ -133,44 +214,178 @@ function PreprToolbar({
|
|
|
133
214
|
}, []);
|
|
134
215
|
return null;
|
|
135
216
|
}
|
|
136
|
-
|
|
217
|
+
var shown = /* @__PURE__ */ new Map();
|
|
218
|
+
var historyStep = false;
|
|
219
|
+
var onPopState = () => {
|
|
220
|
+
historyStep = true;
|
|
221
|
+
};
|
|
222
|
+
function requestDecision(key, personalized = false) {
|
|
223
|
+
return requestPreprDecision(key, {
|
|
224
|
+
personalized,
|
|
225
|
+
onChange: (value) => {
|
|
226
|
+
if (location.pathname + location.search !== key) return;
|
|
227
|
+
applyPreprDecisions(value, { refresh: true });
|
|
228
|
+
const state = window.__preprDecision;
|
|
229
|
+
if (state) shown.set(key, state.value);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function linkTarget(event) {
|
|
234
|
+
const anchor = event.target?.closest?.("a[href]");
|
|
235
|
+
if (!(anchor instanceof HTMLAnchorElement)) return null;
|
|
236
|
+
if (anchor.target && anchor.target !== "_self" || anchor.hasAttribute("download")) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
const url = new URL(anchor.href, location.href);
|
|
240
|
+
const key = url.pathname + url.search;
|
|
241
|
+
if (url.origin !== location.origin || key === location.pathname + location.search) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return key;
|
|
245
|
+
}
|
|
246
|
+
var HOVER_DELAY_MS = 65;
|
|
247
|
+
var hovering = null;
|
|
248
|
+
function onPointerOver(event) {
|
|
249
|
+
if (event.pointerType !== "mouse") return;
|
|
250
|
+
const key = linkTarget(event);
|
|
251
|
+
if (hovering?.key === key) return;
|
|
252
|
+
if (hovering) clearTimeout(hovering.timer);
|
|
253
|
+
hovering = key ? { key, timer: setTimeout(() => requestDecision(key), HOVER_DELAY_MS) } : null;
|
|
254
|
+
}
|
|
255
|
+
function onPointerDown(event) {
|
|
256
|
+
if (event.button !== 0) return;
|
|
257
|
+
const key = linkTarget(event);
|
|
258
|
+
if (key) requestDecision(key);
|
|
259
|
+
}
|
|
260
|
+
var replaying = null;
|
|
261
|
+
function onClick(event) {
|
|
262
|
+
const key = linkTarget(event);
|
|
263
|
+
if (!key) return;
|
|
264
|
+
const anchor = event.target.closest("a[href]");
|
|
265
|
+
if (replaying === anchor) {
|
|
266
|
+
replaying = null;
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const pending = requestDecision(key);
|
|
273
|
+
if (pending.result !== void 0) return;
|
|
274
|
+
event.preventDefault();
|
|
275
|
+
event.stopImmediatePropagation();
|
|
276
|
+
void pending.value.then(() => {
|
|
277
|
+
replaying = anchor;
|
|
278
|
+
anchor.click();
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
var listeners = 0;
|
|
282
|
+
function useDecisionRequests() {
|
|
283
|
+
useEffect2(() => {
|
|
284
|
+
if (listeners++ === 0) {
|
|
285
|
+
window.addEventListener("pointerover", onPointerOver, { passive: true });
|
|
286
|
+
window.addEventListener("pointerdown", onPointerDown, {
|
|
287
|
+
capture: true,
|
|
288
|
+
passive: true
|
|
289
|
+
});
|
|
290
|
+
window.addEventListener("click", onClick, true);
|
|
291
|
+
window.addEventListener("popstate", onPopState);
|
|
292
|
+
}
|
|
293
|
+
return () => {
|
|
294
|
+
if (--listeners === 0) {
|
|
295
|
+
window.removeEventListener("pointerover", onPointerOver);
|
|
296
|
+
window.removeEventListener("pointerdown", onPointerDown, true);
|
|
297
|
+
window.removeEventListener("click", onClick, true);
|
|
298
|
+
window.removeEventListener("popstate", onPopState);
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}, []);
|
|
302
|
+
}
|
|
303
|
+
function PreprPersonalizationSwitch() {
|
|
304
|
+
useDecisionRequests();
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
function PreprDecisionApplier() {
|
|
308
|
+
useDecisionRequests();
|
|
137
309
|
useLayoutEffect(() => {
|
|
138
|
-
|
|
139
|
-
|
|
310
|
+
const key = location.pathname + location.search;
|
|
311
|
+
const remember = () => {
|
|
312
|
+
const state = window.__preprDecision;
|
|
313
|
+
if (state) shown.set(key, state.value);
|
|
314
|
+
};
|
|
315
|
+
const previous = historyStep ? shown.get(key) : void 0;
|
|
316
|
+
historyStep = false;
|
|
317
|
+
if (applyPreprDecisions(previous)) {
|
|
318
|
+
remember();
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const pending = requestDecision(key, true);
|
|
322
|
+
if (pending.result !== void 0) {
|
|
323
|
+
applyPreprDecisions(pending.result);
|
|
324
|
+
remember();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
let live = true;
|
|
328
|
+
void pending.value.then((value) => {
|
|
329
|
+
if (live && location.pathname + location.search === key) {
|
|
330
|
+
applyPreprDecisions(value);
|
|
331
|
+
remember();
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
return () => {
|
|
335
|
+
live = false;
|
|
336
|
+
};
|
|
140
337
|
});
|
|
141
338
|
return null;
|
|
142
339
|
}
|
|
143
340
|
var VARIANT_KEY_ATTRIBUTE = "data-prepr-variant-key";
|
|
144
341
|
function PreprVariantTracking({
|
|
145
342
|
variantKeys,
|
|
146
|
-
ab,
|
|
147
343
|
children
|
|
148
344
|
}) {
|
|
149
345
|
const ref = useRef(null);
|
|
150
346
|
const keys = variantKeys.join(" ");
|
|
151
347
|
useLayoutEffect(() => {
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
348
|
+
let tagged = [];
|
|
349
|
+
const wrapper = ref.current?.closest("[data-prepr-v]");
|
|
350
|
+
const shown2 = () => !wrapper || wrapper.hasAttribute("data-prepr-show");
|
|
351
|
+
const untag = () => {
|
|
352
|
+
for (const [element] of tagged)
|
|
353
|
+
element.removeAttribute(VARIANT_KEY_ATTRIBUTE);
|
|
354
|
+
tagged = [];
|
|
355
|
+
};
|
|
356
|
+
const tag = () => {
|
|
357
|
+
if (!shown2()) return untag();
|
|
358
|
+
if (tagged.length > 0) return;
|
|
359
|
+
const elements = [...ref.current?.children ?? []];
|
|
360
|
+
const list = keys.split(" ");
|
|
361
|
+
const pairs = elements.length === list.length ? elements.map((element, i) => [element, list[i]]) : elements.slice(0, 1).map((element) => [element, list[0]]);
|
|
362
|
+
tagged = pairs.filter(([element, key]) => {
|
|
363
|
+
if (element.hasAttribute(VARIANT_KEY_ATTRIBUTE)) return false;
|
|
364
|
+
element.setAttribute(VARIANT_KEY_ATTRIBUTE, key);
|
|
365
|
+
return true;
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
const timer = setTimeout(tag);
|
|
369
|
+
const observer = wrapper && new MutationObserver(tag);
|
|
370
|
+
observer?.observe(wrapper, {
|
|
371
|
+
attributes: true,
|
|
372
|
+
attributeFilter: ["data-prepr-show"]
|
|
159
373
|
});
|
|
160
374
|
return () => {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
375
|
+
clearTimeout(timer);
|
|
376
|
+
observer?.disconnect();
|
|
377
|
+
untag();
|
|
164
378
|
};
|
|
165
379
|
}, [keys]);
|
|
166
380
|
return createElement(
|
|
167
381
|
"div",
|
|
168
|
-
|
|
382
|
+
{ ref, style: { display: "contents" } },
|
|
169
383
|
children
|
|
170
384
|
);
|
|
171
385
|
}
|
|
172
386
|
export {
|
|
173
|
-
|
|
387
|
+
PreprDecisionApplier,
|
|
388
|
+
PreprPersonalizationSwitch,
|
|
174
389
|
PreprToolbar,
|
|
175
390
|
PreprTrackingPixel,
|
|
176
391
|
PreprVariantTracking
|