@preprio/toolkit 0.6.0-alpha.0 → 0.6.0-alpha.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/README.md +107 -0
- package/dist/astro/{chunk-3UVUDDNY.js → chunk-U7VUQL57.js} +1 -1
- package/dist/astro/graphql.cjs +96 -49
- package/dist/astro/graphql.d.cts +75 -1
- package/dist/astro/graphql.d.ts +75 -1
- package/dist/astro/graphql.js +92 -49
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/chunk-3NCEVJJ3.js +10 -0
- package/dist/chunk-7HSMUULV.js +452 -0
- package/dist/{chunk-BJ2LBLWO.js → chunk-DS3QA3HF.js} +6 -4
- package/dist/{chunk-DGZA7KX7.js → chunk-S5RWVMDJ.js} +0 -24
- package/dist/{chunk-YR7P4IWE.js → chunk-UYYTYSOD.js} +1 -9
- package/dist/chunk-VV4PRH7W.js +26 -0
- package/dist/graphql/codegen.cjs +510 -0
- package/dist/graphql/codegen.d.cts +23 -0
- package/dist/graphql/codegen.d.ts +23 -0
- package/dist/graphql/codegen.js +99 -0
- package/dist/graphql.cjs +96 -49
- package/dist/graphql.d.cts +75 -1
- package/dist/graphql.d.ts +75 -1
- package/dist/graphql.js +60 -428
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -6
- package/dist/nextjs/{chunk-U4HXENF7.js → chunk-ZIUKEGEN.js} +1 -1
- package/dist/nextjs/components.cjs +12 -8
- package/dist/nextjs/components.js +14 -9
- package/dist/nextjs/graphql.cjs +96 -49
- package/dist/nextjs/graphql.d.cts +75 -1
- package/dist/nextjs/graphql.d.ts +75 -1
- package/dist/nextjs/graphql.js +92 -49
- package/dist/nextjs/index.cjs +1 -1
- package/dist/nextjs/index.js +1 -1
- package/dist/nuxt/{chunk-P6ENNAEE.js → chunk-GMWF6PQ5.js} +1 -1
- package/dist/nuxt/graphql.cjs +96 -49
- package/dist/nuxt/graphql.d.cts +75 -1
- package/dist/nuxt/graphql.d.ts +75 -1
- package/dist/nuxt/graphql.js +92 -49
- 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-FSARVMG5.js → chunk-5SQUG2L4.js} +1 -1
- package/dist/sveltekit/graphql.cjs +96 -49
- package/dist/sveltekit/graphql.d.cts +75 -1
- package/dist/sveltekit/graphql.d.ts +75 -1
- package/dist/sveltekit/graphql.js +92 -49
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
toDecisionQuery,
|
|
3
|
+
toSchemaInfo,
|
|
4
|
+
toVariantsQuery
|
|
5
|
+
} from "../chunk-7HSMUULV.js";
|
|
6
|
+
import "../chunk-UYYTYSOD.js";
|
|
7
|
+
import "../chunk-VV4PRH7W.js";
|
|
8
|
+
|
|
9
|
+
// src/codegen/index.ts
|
|
10
|
+
function typeRef(type) {
|
|
11
|
+
const value = type;
|
|
12
|
+
return value.ofType ? { name: null, ofType: typeRef(value.ofType) } : { name: value.name ?? null };
|
|
13
|
+
}
|
|
14
|
+
function introspect(schema) {
|
|
15
|
+
const types = Object.values(
|
|
16
|
+
schema.getTypeMap()
|
|
17
|
+
).map((type) => {
|
|
18
|
+
const possible = "getTypes" in type || "getInterfaces" in type ? schema.getPossibleTypes(type) : [];
|
|
19
|
+
return {
|
|
20
|
+
name: type.name,
|
|
21
|
+
possibleTypes: possible.length ? possible.map((member) => ({ name: member.name })) : null,
|
|
22
|
+
fields: type.getFields ? Object.values(type.getFields()).map((field) => ({
|
|
23
|
+
name: field.name,
|
|
24
|
+
args: (field.args ?? []).map((arg) => ({ name: arg.name })),
|
|
25
|
+
type: typeRef(field.type)
|
|
26
|
+
})) : null
|
|
27
|
+
};
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
__schema: {
|
|
31
|
+
queryType: { name: schema.getQueryType()?.name ?? "Query" },
|
|
32
|
+
types
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function spreadNames(node, into) {
|
|
37
|
+
if (Array.isArray(node)) {
|
|
38
|
+
for (const child of node) spreadNames(child, into);
|
|
39
|
+
} else if (node && typeof node === "object") {
|
|
40
|
+
const value = node;
|
|
41
|
+
if (value.kind === "FragmentSpread" && value.name) {
|
|
42
|
+
into.add(value.name.value);
|
|
43
|
+
}
|
|
44
|
+
for (const [key, child] of Object.entries(node)) {
|
|
45
|
+
if (key !== "loc") spreadNames(child, into);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return into;
|
|
49
|
+
}
|
|
50
|
+
function plugin(schema, documents, _config) {
|
|
51
|
+
const info = toSchemaInfo(introspect(schema));
|
|
52
|
+
const definitions = documents.flatMap((source) => [
|
|
53
|
+
...source.document?.definitions ?? []
|
|
54
|
+
]);
|
|
55
|
+
const fragments = /* @__PURE__ */ new Map();
|
|
56
|
+
for (const definition of definitions) {
|
|
57
|
+
if (definition.kind === "FragmentDefinition") {
|
|
58
|
+
fragments.set(definition.name.value, definition);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const lines = [
|
|
62
|
+
"// Generated by @preprio/toolkit/graphql/codegen. Do not edit."
|
|
63
|
+
];
|
|
64
|
+
const seen = /* @__PURE__ */ new Set();
|
|
65
|
+
for (const definition of definitions) {
|
|
66
|
+
if (definition.kind !== "OperationDefinition") continue;
|
|
67
|
+
const operation = definition;
|
|
68
|
+
if (operation.operation !== "query" || !operation.name) continue;
|
|
69
|
+
const name = operation.name.value;
|
|
70
|
+
if (seen.has(name)) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`@preprio/toolkit codegen: two queries are named "${name}"; rename one so their exports do not collide.`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
seen.add(name);
|
|
76
|
+
const used = /* @__PURE__ */ new Set();
|
|
77
|
+
const queue = [...spreadNames(operation, /* @__PURE__ */ new Set())];
|
|
78
|
+
while (queue.length) {
|
|
79
|
+
const next = queue.pop();
|
|
80
|
+
if (used.has(next) || !fragments.has(next)) continue;
|
|
81
|
+
used.add(next);
|
|
82
|
+
queue.push(...spreadNames(fragments.get(next), /* @__PURE__ */ new Set()));
|
|
83
|
+
}
|
|
84
|
+
const document = {
|
|
85
|
+
kind: "Document",
|
|
86
|
+
definitions: [operation, ...[...used].map((n) => fragments.get(n))]
|
|
87
|
+
};
|
|
88
|
+
const decision = toDecisionQuery(document, info);
|
|
89
|
+
if (!decision) continue;
|
|
90
|
+
lines.push(
|
|
91
|
+
`export const ${name}VariantsQuery = ${JSON.stringify(toVariantsQuery(document, info))};`,
|
|
92
|
+
`export const ${name}DecisionQuery = ${JSON.stringify(decision)};`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return lines.join("\n") + "\n";
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
plugin
|
|
99
|
+
};
|
package/dist/graphql.cjs
CHANGED
|
@@ -23,10 +23,14 @@ __export(graphql_exports, {
|
|
|
23
23
|
PREPR_DEFAULT_VARIANT: () => PREPR_DEFAULT_VARIANT,
|
|
24
24
|
PreprError: () => PreprError,
|
|
25
25
|
createPreprClient: () => createPreprClient,
|
|
26
|
+
decisionsFrom: () => decisionsFrom,
|
|
26
27
|
isPersonalizedResponse: () => isPersonalizedResponse,
|
|
28
|
+
loadPreprSchema: () => loadPreprSchema,
|
|
27
29
|
preprVariantProps: () => preprVariantProps,
|
|
28
30
|
resolveVariants: () => resolveVariants,
|
|
29
|
-
splitStack: () => splitStack
|
|
31
|
+
splitStack: () => splitStack,
|
|
32
|
+
toDecisionQuery: () => toDecisionQuery,
|
|
33
|
+
toVariantsQuery: () => toVariantsQuery
|
|
30
34
|
});
|
|
31
35
|
module.exports = __toCommonJS(graphql_exports);
|
|
32
36
|
|
|
@@ -534,6 +538,63 @@ function toVariantsDocument(document2, schema) {
|
|
|
534
538
|
};
|
|
535
539
|
}
|
|
536
540
|
|
|
541
|
+
// src/core/graphql/document.ts
|
|
542
|
+
var import_printer = require("graphql/language/printer.js");
|
|
543
|
+
var import_stripIgnoredCharacters = require("graphql/utilities/stripIgnoredCharacters.js");
|
|
544
|
+
var printed = /* @__PURE__ */ new WeakMap();
|
|
545
|
+
function isDocumentNode(value) {
|
|
546
|
+
return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
|
|
547
|
+
}
|
|
548
|
+
function invalidDocument(originalError) {
|
|
549
|
+
return new PreprError(
|
|
550
|
+
"Expected a GraphQL query string, TypedDocumentString or DocumentNode",
|
|
551
|
+
"INVALID_DOCUMENT",
|
|
552
|
+
"createPreprClient",
|
|
553
|
+
originalError
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
var minified = /* @__PURE__ */ new Map();
|
|
557
|
+
var MINIFIED_CACHE_LIMIT = 500;
|
|
558
|
+
function minify(query) {
|
|
559
|
+
const cached = minified.get(query);
|
|
560
|
+
if (cached !== void 0) return cached;
|
|
561
|
+
let result = query;
|
|
562
|
+
try {
|
|
563
|
+
result = (0, import_stripIgnoredCharacters.stripIgnoredCharacters)(query);
|
|
564
|
+
} catch {
|
|
565
|
+
}
|
|
566
|
+
if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
|
|
567
|
+
return result;
|
|
568
|
+
}
|
|
569
|
+
function resolveQuery(document2) {
|
|
570
|
+
if (typeof document2 === "string") return minify(document2);
|
|
571
|
+
if (document2 instanceof String) return minify(document2.toString());
|
|
572
|
+
if (!isDocumentNode(document2)) throw invalidDocument();
|
|
573
|
+
let query = printed.get(document2);
|
|
574
|
+
if (query === void 0) {
|
|
575
|
+
try {
|
|
576
|
+
query = minify((0, import_printer.print)(document2));
|
|
577
|
+
} catch (error) {
|
|
578
|
+
throw invalidDocument(error instanceof Error ? error : void 0);
|
|
579
|
+
}
|
|
580
|
+
printed.set(document2, query);
|
|
581
|
+
}
|
|
582
|
+
return query;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// src/core/variants/queries.ts
|
|
586
|
+
function toVariantsQuery(document2, schema) {
|
|
587
|
+
return resolveQuery(toVariantsDocument(document2, schema));
|
|
588
|
+
}
|
|
589
|
+
function toDecisionQuery(document2, schema, options = {}) {
|
|
590
|
+
const paths = options.from === void 0 ? void 0 : personalizationPaths(options.from);
|
|
591
|
+
if (paths && paths.size === 0) return null;
|
|
592
|
+
const decision = toDecisionDocument(document2, schema, paths, {
|
|
593
|
+
topLevelOnly: !paths && options.topLevelOnly
|
|
594
|
+
});
|
|
595
|
+
return decision ? resolveQuery(decision) : null;
|
|
596
|
+
}
|
|
597
|
+
|
|
537
598
|
// src/core/graphql/transport.ts
|
|
538
599
|
var import_stega2 = require("@vercel/stega");
|
|
539
600
|
|
|
@@ -593,50 +654,6 @@ function stegaClean(text) {
|
|
|
593
654
|
return (0, import_stega.vercelStegaClean)(text);
|
|
594
655
|
}
|
|
595
656
|
|
|
596
|
-
// src/core/graphql/document.ts
|
|
597
|
-
var import_printer = require("graphql/language/printer.js");
|
|
598
|
-
var import_stripIgnoredCharacters = require("graphql/utilities/stripIgnoredCharacters.js");
|
|
599
|
-
var printed = /* @__PURE__ */ new WeakMap();
|
|
600
|
-
function isDocumentNode(value) {
|
|
601
|
-
return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
|
|
602
|
-
}
|
|
603
|
-
function invalidDocument(originalError) {
|
|
604
|
-
return new PreprError(
|
|
605
|
-
"Expected a GraphQL query string, TypedDocumentString or DocumentNode",
|
|
606
|
-
"INVALID_DOCUMENT",
|
|
607
|
-
"createPreprClient",
|
|
608
|
-
originalError
|
|
609
|
-
);
|
|
610
|
-
}
|
|
611
|
-
var minified = /* @__PURE__ */ new Map();
|
|
612
|
-
var MINIFIED_CACHE_LIMIT = 500;
|
|
613
|
-
function minify(query) {
|
|
614
|
-
const cached = minified.get(query);
|
|
615
|
-
if (cached !== void 0) return cached;
|
|
616
|
-
let result = query;
|
|
617
|
-
try {
|
|
618
|
-
result = (0, import_stripIgnoredCharacters.stripIgnoredCharacters)(query);
|
|
619
|
-
} catch {
|
|
620
|
-
}
|
|
621
|
-
if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
|
|
622
|
-
return result;
|
|
623
|
-
}
|
|
624
|
-
function resolveQuery(document2) {
|
|
625
|
-
if (typeof document2 === "string") return minify(document2);
|
|
626
|
-
if (document2 instanceof String) return minify(document2.toString());
|
|
627
|
-
if (!isDocumentNode(document2)) throw invalidDocument();
|
|
628
|
-
let query = printed.get(document2);
|
|
629
|
-
if (query === void 0) {
|
|
630
|
-
try {
|
|
631
|
-
query = minify((0, import_printer.print)(document2));
|
|
632
|
-
} catch (error) {
|
|
633
|
-
throw invalidDocument(error instanceof Error ? error : void 0);
|
|
634
|
-
}
|
|
635
|
-
printed.set(document2, query);
|
|
636
|
-
}
|
|
637
|
-
return query;
|
|
638
|
-
}
|
|
639
|
-
|
|
640
657
|
// src/core/graphql/transport.ts
|
|
641
658
|
var OPERATION_NAME = /\b(?:query|mutation|subscription)\s+([_A-Za-z][_0-9A-Za-z]*)/;
|
|
642
659
|
var STEGA_RAW = new RegExp(
|
|
@@ -816,16 +833,18 @@ function isParseableUrl(url) {
|
|
|
816
833
|
return false;
|
|
817
834
|
}
|
|
818
835
|
}
|
|
819
|
-
function
|
|
820
|
-
const { url } = options;
|
|
836
|
+
function assertPreprUrl(url, source) {
|
|
821
837
|
validatePreprToken(url);
|
|
822
838
|
if (!isParseableUrl(url)) {
|
|
823
839
|
throw new PreprError(
|
|
824
840
|
"Prepr GraphQL URL is not a valid URL",
|
|
825
841
|
"INVALID_TOKEN",
|
|
826
|
-
|
|
842
|
+
source
|
|
827
843
|
);
|
|
828
844
|
}
|
|
845
|
+
}
|
|
846
|
+
function createPreprClient(options) {
|
|
847
|
+
assertPreprUrl(options.url, "createPreprClient");
|
|
829
848
|
const run = createTransport(options);
|
|
830
849
|
const probeVary = createVaryProbe(run, options);
|
|
831
850
|
let schema;
|
|
@@ -882,13 +901,41 @@ function createPreprClient(options) {
|
|
|
882
901
|
)
|
|
883
902
|
};
|
|
884
903
|
}
|
|
904
|
+
|
|
905
|
+
// src/core/graphql/schema-loader.ts
|
|
906
|
+
var schemas = /* @__PURE__ */ new Map();
|
|
907
|
+
async function loadPreprSchema(url, options = {}) {
|
|
908
|
+
assertPreprUrl(url, "loadPreprSchema");
|
|
909
|
+
let schema = schemas.get(url);
|
|
910
|
+
if (!schema) {
|
|
911
|
+
const run = createTransport({ url, fetch: options.fetch, stega: "none" });
|
|
912
|
+
schema = run(
|
|
913
|
+
PREPR_SCHEMA_QUERY
|
|
914
|
+
).then((result) => toSchemaInfo(result.data)).catch((error) => {
|
|
915
|
+
schemas.delete(url);
|
|
916
|
+
if (error instanceof PreprError) throw error;
|
|
917
|
+
throw new PreprError(
|
|
918
|
+
"Prepr schema response is not an introspection result",
|
|
919
|
+
"INVALID_RESPONSE",
|
|
920
|
+
"loadPreprSchema",
|
|
921
|
+
error instanceof Error ? error : void 0
|
|
922
|
+
);
|
|
923
|
+
});
|
|
924
|
+
schemas.set(url, schema);
|
|
925
|
+
}
|
|
926
|
+
return schema;
|
|
927
|
+
}
|
|
885
928
|
// Annotate the CommonJS export names for ESM import in node:
|
|
886
929
|
0 && (module.exports = {
|
|
887
930
|
PREPR_DEFAULT_VARIANT,
|
|
888
931
|
PreprError,
|
|
889
932
|
createPreprClient,
|
|
933
|
+
decisionsFrom,
|
|
890
934
|
isPersonalizedResponse,
|
|
935
|
+
loadPreprSchema,
|
|
891
936
|
preprVariantProps,
|
|
892
937
|
resolveVariants,
|
|
893
|
-
splitStack
|
|
938
|
+
splitStack,
|
|
939
|
+
toDecisionQuery,
|
|
940
|
+
toVariantsQuery
|
|
894
941
|
});
|
package/dist/graphql.d.cts
CHANGED
|
@@ -8,6 +8,12 @@ declare const PREPR_DEFAULT_VARIANT = "ALL_OTHER_USERS";
|
|
|
8
8
|
|
|
9
9
|
/** The variant ids Prepr chose for one visitor, per personalization group. */
|
|
10
10
|
type PreprDecisions = ReadonlyMap<string, readonly string[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Variant ids per group from a decision response, de-duplicated and in
|
|
13
|
+
* Prepr's order. A visitor in several segments can get more than one variant
|
|
14
|
+
* of the same group, so each entry is a list.
|
|
15
|
+
*/
|
|
16
|
+
declare function decisionsFrom(data: unknown): PreprDecisions;
|
|
11
17
|
interface ResolveVariantsOptions {
|
|
12
18
|
/**
|
|
13
19
|
* The visitor's per-group variants (from a decision query). Without it,
|
|
@@ -24,6 +30,24 @@ interface ResolveVariantsOptions {
|
|
|
24
30
|
*/
|
|
25
31
|
declare function resolveVariants<T>(data: T, options?: ResolveVariantsOptions): T;
|
|
26
32
|
|
|
33
|
+
interface FieldInfo {
|
|
34
|
+
/** Named type of the field, without list/non-null wrappers. */
|
|
35
|
+
type: string;
|
|
36
|
+
/** The field accepts Prepr's `personalize` argument (a stack). */
|
|
37
|
+
personalizable: boolean;
|
|
38
|
+
}
|
|
39
|
+
interface TypeInfo {
|
|
40
|
+
fields: Record<string, FieldInfo>;
|
|
41
|
+
/** Members of a union or implementations of an interface. */
|
|
42
|
+
possibleTypes: string[];
|
|
43
|
+
hasContext: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** The slice of the schema the variant transforms need. */
|
|
46
|
+
interface PreprSchemaInfo {
|
|
47
|
+
queryType: string;
|
|
48
|
+
types: Record<string, TypeInfo>;
|
|
49
|
+
}
|
|
50
|
+
|
|
27
51
|
/** A run of stack items that renders the same way: see {@link splitStack}. */
|
|
28
52
|
interface PreprStackBlock<T> {
|
|
29
53
|
key: string;
|
|
@@ -72,6 +96,39 @@ interface PreprVariantProps {
|
|
|
72
96
|
*/
|
|
73
97
|
declare function preprVariantProps(item: unknown): PreprVariantProps;
|
|
74
98
|
|
|
99
|
+
/**
|
|
100
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
101
|
+
* along; its shape is not part of the public API.
|
|
102
|
+
*/
|
|
103
|
+
type PreprSchema = PreprSchemaInfo;
|
|
104
|
+
/**
|
|
105
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
106
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
107
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
108
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
109
|
+
*
|
|
110
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
111
|
+
*/
|
|
112
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
113
|
+
/**
|
|
114
|
+
* The per-visitor decision query for the same query: send it with the
|
|
115
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
116
|
+
* `decisionsFrom`.
|
|
117
|
+
*
|
|
118
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
119
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
120
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
121
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
122
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
123
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
124
|
+
*
|
|
125
|
+
* Null when there is nothing to decide: send no request then.
|
|
126
|
+
*/
|
|
127
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
128
|
+
from?: unknown;
|
|
129
|
+
topLevelOnly?: boolean;
|
|
130
|
+
}): string | null;
|
|
131
|
+
|
|
75
132
|
/**
|
|
76
133
|
* A GraphQL document accepted by `query`: a plain string, graphql-codegen's
|
|
77
134
|
* `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
|
|
@@ -228,4 +285,21 @@ interface PreprClient {
|
|
|
228
285
|
*/
|
|
229
286
|
declare function createPreprClient(options: PreprClientOptions): PreprClient;
|
|
230
287
|
|
|
231
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
|
|
290
|
+
* Prepr schema (which fields take `personalize`, which types can hold
|
|
291
|
+
* variants) with one introspection request, kept in memory per URL. For a
|
|
292
|
+
* site that uses its own GraphQL client; `createPreprClient` does this
|
|
293
|
+
* itself.
|
|
294
|
+
*
|
|
295
|
+
* Load it once at startup or lazily before the first rewrite. Schema changes
|
|
296
|
+
* in Prepr take effect after a restart or redeploy.
|
|
297
|
+
*
|
|
298
|
+
* @throws PreprError when the URL is invalid or the request fails; the URL,
|
|
299
|
+
* which holds your access token, is never part of the message.
|
|
300
|
+
*/
|
|
301
|
+
declare function loadPreprSchema(url: string, options?: {
|
|
302
|
+
fetch?: typeof fetch;
|
|
303
|
+
}): Promise<PreprSchemaInfo>;
|
|
304
|
+
|
|
305
|
+
export { PREPR_DEFAULT_VARIANT, type PreprClient, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, PreprHeaders, type PreprQueryOptions, type PreprQueryResult, type PreprSchema, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, decisionsFrom, loadPreprSchema, preprVariantProps, resolveVariants, splitStack, toDecisionQuery, toVariantsQuery };
|
package/dist/graphql.d.ts
CHANGED
|
@@ -8,6 +8,12 @@ declare const PREPR_DEFAULT_VARIANT = "ALL_OTHER_USERS";
|
|
|
8
8
|
|
|
9
9
|
/** The variant ids Prepr chose for one visitor, per personalization group. */
|
|
10
10
|
type PreprDecisions = ReadonlyMap<string, readonly string[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Variant ids per group from a decision response, de-duplicated and in
|
|
13
|
+
* Prepr's order. A visitor in several segments can get more than one variant
|
|
14
|
+
* of the same group, so each entry is a list.
|
|
15
|
+
*/
|
|
16
|
+
declare function decisionsFrom(data: unknown): PreprDecisions;
|
|
11
17
|
interface ResolveVariantsOptions {
|
|
12
18
|
/**
|
|
13
19
|
* The visitor's per-group variants (from a decision query). Without it,
|
|
@@ -24,6 +30,24 @@ interface ResolveVariantsOptions {
|
|
|
24
30
|
*/
|
|
25
31
|
declare function resolveVariants<T>(data: T, options?: ResolveVariantsOptions): T;
|
|
26
32
|
|
|
33
|
+
interface FieldInfo {
|
|
34
|
+
/** Named type of the field, without list/non-null wrappers. */
|
|
35
|
+
type: string;
|
|
36
|
+
/** The field accepts Prepr's `personalize` argument (a stack). */
|
|
37
|
+
personalizable: boolean;
|
|
38
|
+
}
|
|
39
|
+
interface TypeInfo {
|
|
40
|
+
fields: Record<string, FieldInfo>;
|
|
41
|
+
/** Members of a union or implementations of an interface. */
|
|
42
|
+
possibleTypes: string[];
|
|
43
|
+
hasContext: boolean;
|
|
44
|
+
}
|
|
45
|
+
/** The slice of the schema the variant transforms need. */
|
|
46
|
+
interface PreprSchemaInfo {
|
|
47
|
+
queryType: string;
|
|
48
|
+
types: Record<string, TypeInfo>;
|
|
49
|
+
}
|
|
50
|
+
|
|
27
51
|
/** A run of stack items that renders the same way: see {@link splitStack}. */
|
|
28
52
|
interface PreprStackBlock<T> {
|
|
29
53
|
key: string;
|
|
@@ -72,6 +96,39 @@ interface PreprVariantProps {
|
|
|
72
96
|
*/
|
|
73
97
|
declare function preprVariantProps(item: unknown): PreprVariantProps;
|
|
74
98
|
|
|
99
|
+
/**
|
|
100
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
101
|
+
* along; its shape is not part of the public API.
|
|
102
|
+
*/
|
|
103
|
+
type PreprSchema = PreprSchemaInfo;
|
|
104
|
+
/**
|
|
105
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
106
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
107
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
108
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
109
|
+
*
|
|
110
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
111
|
+
*/
|
|
112
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
113
|
+
/**
|
|
114
|
+
* The per-visitor decision query for the same query: send it with the
|
|
115
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
116
|
+
* `decisionsFrom`.
|
|
117
|
+
*
|
|
118
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
119
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
120
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
121
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
122
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
123
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
124
|
+
*
|
|
125
|
+
* Null when there is nothing to decide: send no request then.
|
|
126
|
+
*/
|
|
127
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
128
|
+
from?: unknown;
|
|
129
|
+
topLevelOnly?: boolean;
|
|
130
|
+
}): string | null;
|
|
131
|
+
|
|
75
132
|
/**
|
|
76
133
|
* A GraphQL document accepted by `query`: a plain string, graphql-codegen's
|
|
77
134
|
* `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
|
|
@@ -228,4 +285,21 @@ interface PreprClient {
|
|
|
228
285
|
*/
|
|
229
286
|
declare function createPreprClient(options: PreprClientOptions): PreprClient;
|
|
230
287
|
|
|
231
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
|
|
290
|
+
* Prepr schema (which fields take `personalize`, which types can hold
|
|
291
|
+
* variants) with one introspection request, kept in memory per URL. For a
|
|
292
|
+
* site that uses its own GraphQL client; `createPreprClient` does this
|
|
293
|
+
* itself.
|
|
294
|
+
*
|
|
295
|
+
* Load it once at startup or lazily before the first rewrite. Schema changes
|
|
296
|
+
* in Prepr take effect after a restart or redeploy.
|
|
297
|
+
*
|
|
298
|
+
* @throws PreprError when the URL is invalid or the request fails; the URL,
|
|
299
|
+
* which holds your access token, is never part of the message.
|
|
300
|
+
*/
|
|
301
|
+
declare function loadPreprSchema(url: string, options?: {
|
|
302
|
+
fetch?: typeof fetch;
|
|
303
|
+
}): Promise<PreprSchemaInfo>;
|
|
304
|
+
|
|
305
|
+
export { PREPR_DEFAULT_VARIANT, type PreprClient, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, PreprHeaders, type PreprQueryOptions, type PreprQueryResult, type PreprSchema, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, decisionsFrom, loadPreprSchema, preprVariantProps, resolveVariants, splitStack, toDecisionQuery, toVariantsQuery };
|