@preprio/toolkit 0.6.0-alpha.0 → 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 +268 -59
- package/dist/astro/{chunk-3UVUDDNY.js → chunk-CG2QBHNU.js} +1 -1
- package/dist/astro/graphql.cjs +154 -59
- package/dist/astro/graphql.d.cts +75 -6
- package/dist/astro/graphql.d.ts +75 -6
- package/dist/astro/graphql.js +150 -59
- package/dist/astro/index.cjs +1 -1
- package/dist/astro/index.js +1 -1
- package/dist/chunk-3NCEVJJ3.js +10 -0
- package/dist/{chunk-BJ2LBLWO.js → chunk-LIDUJWWJ.js} +6 -4
- package/dist/chunk-M3RBYJ5J.js +499 -0
- package/dist/{chunk-DGZA7KX7.js → chunk-S5RWVMDJ.js} +0 -24
- package/dist/{chunk-YR7P4IWE.js → chunk-SF6TN4JR.js} +1 -9
- package/dist/chunk-TN6SNAR2.js +26 -0
- package/dist/graphql/codegen.cjs +557 -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 +185 -59
- package/dist/graphql.d.cts +110 -6
- package/dist/graphql.d.ts +110 -6
- package/dist/graphql.js +91 -430
- 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-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 +289 -73
- package/dist/nextjs/graphql.cjs +952 -315
- package/dist/nextjs/graphql.d.cts +225 -83
- package/dist/nextjs/graphql.d.ts +225 -83
- package/dist/nextjs/graphql.js +634 -314
- 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-P6ENNAEE.js → chunk-FMC3DP7N.js} +1 -1
- package/dist/nuxt/graphql.cjs +154 -59
- package/dist/nuxt/graphql.d.cts +75 -6
- package/dist/nuxt/graphql.d.ts +75 -6
- package/dist/nuxt/graphql.js +150 -59
- 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-AJPKBAHO.js} +1 -1
- package/dist/sveltekit/graphql.cjs +154 -59
- package/dist/sveltekit/graphql.d.cts +75 -6
- package/dist/sveltekit/graphql.d.ts +75 -6
- package/dist/sveltekit/graphql.js +150 -59
- package/dist/sveltekit/index.cjs +1 -1
- package/dist/sveltekit/index.js +1 -1
- package/package.json +6 -1
- package/dist/nextjs/chunk-U4HXENF7.js +0 -231
package/dist/graphql.cjs
CHANGED
|
@@ -20,16 +20,48 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/graphql.ts
|
|
21
21
|
var graphql_exports = {};
|
|
22
22
|
__export(graphql_exports, {
|
|
23
|
+
PREPR_ANY_ITEM_TAG: () => PREPR_ANY_ITEM_TAG,
|
|
23
24
|
PREPR_DEFAULT_VARIANT: () => PREPR_DEFAULT_VARIANT,
|
|
24
25
|
PreprError: () => PreprError,
|
|
25
26
|
createPreprClient: () => createPreprClient,
|
|
27
|
+
decisionsFrom: () => decisionsFrom,
|
|
26
28
|
isPersonalizedResponse: () => isPersonalizedResponse,
|
|
29
|
+
loadPreprSchema: () => loadPreprSchema,
|
|
30
|
+
preprCacheTags: () => preprCacheTags,
|
|
31
|
+
preprModelTag: () => preprModelTag,
|
|
27
32
|
preprVariantProps: () => preprVariantProps,
|
|
28
33
|
resolveVariants: () => resolveVariants,
|
|
29
|
-
splitStack: () => splitStack
|
|
34
|
+
splitStack: () => splitStack,
|
|
35
|
+
toDecisionQuery: () => toDecisionQuery,
|
|
36
|
+
toVariantsQuery: () => toVariantsQuery
|
|
30
37
|
});
|
|
31
38
|
module.exports = __toCommonJS(graphql_exports);
|
|
32
39
|
|
|
40
|
+
// src/core/graphql/cache-tags.ts
|
|
41
|
+
var MAX_TAGS = 128;
|
|
42
|
+
var MAX_TAG_LENGTH = 256;
|
|
43
|
+
var PREPR_ANY_ITEM_TAG = "prepr:any";
|
|
44
|
+
var preprItemTag = (id) => `prepr:${id}`;
|
|
45
|
+
var NOT_ALPHANUMERIC = /[^a-z0-9]/g;
|
|
46
|
+
var preprModelTag = (model) => `prepr:model:${model.toLowerCase().replace(NOT_ALPHANUMERIC, "")}`;
|
|
47
|
+
function preprCacheTags(data) {
|
|
48
|
+
const tags = /* @__PURE__ */ new Set();
|
|
49
|
+
const stack = [data];
|
|
50
|
+
while (stack.length > 0) {
|
|
51
|
+
const value = stack.pop();
|
|
52
|
+
if (typeof value !== "object" || value === null) continue;
|
|
53
|
+
const id = value._id;
|
|
54
|
+
if (typeof id === "string" && id !== "") {
|
|
55
|
+
const tag = preprItemTag(id);
|
|
56
|
+
if (tag.length > MAX_TAG_LENGTH) return [PREPR_ANY_ITEM_TAG];
|
|
57
|
+
tags.add(tag);
|
|
58
|
+
if (tags.size > MAX_TAGS) return [PREPR_ANY_ITEM_TAG];
|
|
59
|
+
}
|
|
60
|
+
for (const child of Object.values(value)) stack.push(child);
|
|
61
|
+
}
|
|
62
|
+
return [...tags];
|
|
63
|
+
}
|
|
64
|
+
|
|
33
65
|
// src/core/server.ts
|
|
34
66
|
var PreprError = class extends Error {
|
|
35
67
|
constructor(message, code, context, originalError) {
|
|
@@ -144,7 +176,10 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
144
176
|
path,
|
|
145
177
|
ctx
|
|
146
178
|
);
|
|
147
|
-
if (pruned)
|
|
179
|
+
if (!pruned) continue;
|
|
180
|
+
if (fragment.typeCondition.name.value === typeName) {
|
|
181
|
+
selections.push(...pruned.selections);
|
|
182
|
+
} else {
|
|
148
183
|
selections.push(
|
|
149
184
|
inlineFragment(fragment.typeCondition.name.value, [
|
|
150
185
|
...pruned.selections
|
|
@@ -154,13 +189,19 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
154
189
|
continue;
|
|
155
190
|
}
|
|
156
191
|
if (selection.kind === "InlineFragment") {
|
|
192
|
+
const condition = selection.typeCondition?.name.value ?? typeName;
|
|
157
193
|
const pruned = decisionSelectionSet(
|
|
158
194
|
selection.selectionSet,
|
|
159
|
-
|
|
195
|
+
condition,
|
|
160
196
|
path,
|
|
161
197
|
ctx
|
|
162
198
|
);
|
|
163
|
-
if (pruned)
|
|
199
|
+
if (!pruned) continue;
|
|
200
|
+
if (condition === typeName && !selection.directives?.length) {
|
|
201
|
+
selections.push(...pruned.selections);
|
|
202
|
+
} else {
|
|
203
|
+
selections.push({ ...selection, selectionSet: pruned });
|
|
204
|
+
}
|
|
164
205
|
continue;
|
|
165
206
|
}
|
|
166
207
|
if (!selection.selectionSet) continue;
|
|
@@ -234,20 +275,58 @@ function toDecisionDocument(document2, schema, groupPaths, options) {
|
|
|
234
275
|
const used = /* @__PURE__ */ new Set();
|
|
235
276
|
collectVariables(pruned, used);
|
|
236
277
|
collectVariables(operation.directives, used);
|
|
278
|
+
const shared = sharedContextFragment(schema);
|
|
237
279
|
return {
|
|
238
280
|
kind: "Document",
|
|
239
281
|
definitions: [
|
|
282
|
+
...shared ? [shared.definition] : [],
|
|
240
283
|
{
|
|
241
284
|
...operation,
|
|
242
285
|
name: operation.name && name(`${operation.name.value}Decision`),
|
|
243
286
|
variableDefinitions: (operation.variableDefinitions ?? []).filter(
|
|
244
287
|
(definition) => used.has(definition.variable.name.value)
|
|
245
288
|
),
|
|
246
|
-
selectionSet: pruned
|
|
289
|
+
selectionSet: shared ? shared.apply(pruned) : pruned
|
|
247
290
|
}
|
|
248
291
|
]
|
|
249
292
|
};
|
|
250
293
|
}
|
|
294
|
+
function sharedContextFragment(schema) {
|
|
295
|
+
const contextTypes = new Set(
|
|
296
|
+
Object.values(schema.types).flatMap(
|
|
297
|
+
(type) => type.hasContext ? [type.fields._context.type] : []
|
|
298
|
+
)
|
|
299
|
+
);
|
|
300
|
+
if (contextTypes.size !== 1) return null;
|
|
301
|
+
const [contextType] = contextTypes;
|
|
302
|
+
const fragmentName = "c";
|
|
303
|
+
const definition = {
|
|
304
|
+
kind: "FragmentDefinition",
|
|
305
|
+
name: name(fragmentName),
|
|
306
|
+
typeCondition: { kind: "NamedType", name: name(contextType) },
|
|
307
|
+
selectionSet: selectionSet(
|
|
308
|
+
["kind", "group_id", "variant_id"].map(
|
|
309
|
+
(field) => ({ kind: "Field", name: name(field) })
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
};
|
|
313
|
+
const spread = {
|
|
314
|
+
kind: "FragmentSpread",
|
|
315
|
+
name: name(fragmentName)
|
|
316
|
+
};
|
|
317
|
+
const apply = (set) => selectionSet(
|
|
318
|
+
set.selections.map((selection) => {
|
|
319
|
+
if (selection.kind === "Field" && selection.alias?.value === PREPR_CONTEXT_ALIAS) {
|
|
320
|
+
return { ...selection, selectionSet: selectionSet([spread]) };
|
|
321
|
+
}
|
|
322
|
+
return "selectionSet" in selection && selection.selectionSet ? {
|
|
323
|
+
...selection,
|
|
324
|
+
selectionSet: apply(selection.selectionSet)
|
|
325
|
+
} : selection;
|
|
326
|
+
})
|
|
327
|
+
);
|
|
328
|
+
return { definition, apply };
|
|
329
|
+
}
|
|
251
330
|
|
|
252
331
|
// src/core/variants/probe-document.ts
|
|
253
332
|
function probeSelectionSet(set, fragments) {
|
|
@@ -534,6 +613,63 @@ function toVariantsDocument(document2, schema) {
|
|
|
534
613
|
};
|
|
535
614
|
}
|
|
536
615
|
|
|
616
|
+
// src/core/graphql/document.ts
|
|
617
|
+
var import_printer = require("graphql/language/printer.js");
|
|
618
|
+
var import_stripIgnoredCharacters = require("graphql/utilities/stripIgnoredCharacters.js");
|
|
619
|
+
var printed = /* @__PURE__ */ new WeakMap();
|
|
620
|
+
function isDocumentNode(value) {
|
|
621
|
+
return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
|
|
622
|
+
}
|
|
623
|
+
function invalidDocument(originalError) {
|
|
624
|
+
return new PreprError(
|
|
625
|
+
"Expected a GraphQL query string, TypedDocumentString or DocumentNode",
|
|
626
|
+
"INVALID_DOCUMENT",
|
|
627
|
+
"createPreprClient",
|
|
628
|
+
originalError
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
var minified = /* @__PURE__ */ new Map();
|
|
632
|
+
var MINIFIED_CACHE_LIMIT = 500;
|
|
633
|
+
function minify(query) {
|
|
634
|
+
const cached = minified.get(query);
|
|
635
|
+
if (cached !== void 0) return cached;
|
|
636
|
+
let result = query;
|
|
637
|
+
try {
|
|
638
|
+
result = (0, import_stripIgnoredCharacters.stripIgnoredCharacters)(query);
|
|
639
|
+
} catch {
|
|
640
|
+
}
|
|
641
|
+
if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
|
|
642
|
+
return result;
|
|
643
|
+
}
|
|
644
|
+
function resolveQuery(document2) {
|
|
645
|
+
if (typeof document2 === "string") return minify(document2);
|
|
646
|
+
if (document2 instanceof String) return minify(document2.toString());
|
|
647
|
+
if (!isDocumentNode(document2)) throw invalidDocument();
|
|
648
|
+
let query = printed.get(document2);
|
|
649
|
+
if (query === void 0) {
|
|
650
|
+
try {
|
|
651
|
+
query = minify((0, import_printer.print)(document2));
|
|
652
|
+
} catch (error) {
|
|
653
|
+
throw invalidDocument(error instanceof Error ? error : void 0);
|
|
654
|
+
}
|
|
655
|
+
printed.set(document2, query);
|
|
656
|
+
}
|
|
657
|
+
return query;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
// src/core/variants/queries.ts
|
|
661
|
+
function toVariantsQuery(document2, schema) {
|
|
662
|
+
return resolveQuery(toVariantsDocument(document2, schema));
|
|
663
|
+
}
|
|
664
|
+
function toDecisionQuery(document2, schema, options = {}) {
|
|
665
|
+
const paths = options.from === void 0 ? void 0 : personalizationPaths(options.from);
|
|
666
|
+
if (paths && paths.size === 0) return null;
|
|
667
|
+
const decision = toDecisionDocument(document2, schema, paths, {
|
|
668
|
+
topLevelOnly: !paths && options.topLevelOnly
|
|
669
|
+
});
|
|
670
|
+
return decision ? resolveQuery(decision) : null;
|
|
671
|
+
}
|
|
672
|
+
|
|
537
673
|
// src/core/graphql/transport.ts
|
|
538
674
|
var import_stega2 = require("@vercel/stega");
|
|
539
675
|
|
|
@@ -593,50 +729,6 @@ function stegaClean(text) {
|
|
|
593
729
|
return (0, import_stega.vercelStegaClean)(text);
|
|
594
730
|
}
|
|
595
731
|
|
|
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
732
|
// src/core/graphql/transport.ts
|
|
641
733
|
var OPERATION_NAME = /\b(?:query|mutation|subscription)\s+([_A-Za-z][_0-9A-Za-z]*)/;
|
|
642
734
|
var STEGA_RAW = new RegExp(
|
|
@@ -808,6 +900,7 @@ function createVaryProbe(run, options) {
|
|
|
808
900
|
}
|
|
809
901
|
|
|
810
902
|
// src/core/graphql/client.ts
|
|
903
|
+
var clientSchemas = /* @__PURE__ */ new WeakMap();
|
|
811
904
|
function isParseableUrl(url) {
|
|
812
905
|
try {
|
|
813
906
|
new URL(url);
|
|
@@ -816,16 +909,18 @@ function isParseableUrl(url) {
|
|
|
816
909
|
return false;
|
|
817
910
|
}
|
|
818
911
|
}
|
|
819
|
-
function
|
|
820
|
-
const { url } = options;
|
|
912
|
+
function assertPreprUrl(url, source) {
|
|
821
913
|
validatePreprToken(url);
|
|
822
914
|
if (!isParseableUrl(url)) {
|
|
823
915
|
throw new PreprError(
|
|
824
916
|
"Prepr GraphQL URL is not a valid URL",
|
|
825
917
|
"INVALID_TOKEN",
|
|
826
|
-
|
|
918
|
+
source
|
|
827
919
|
);
|
|
828
920
|
}
|
|
921
|
+
}
|
|
922
|
+
function createPreprClient(options) {
|
|
923
|
+
assertPreprUrl(options.url, "createPreprClient");
|
|
829
924
|
const run = createTransport(options);
|
|
830
925
|
const probeVary = createVaryProbe(run, options);
|
|
831
926
|
let schema;
|
|
@@ -842,7 +937,7 @@ function createPreprClient(options) {
|
|
|
842
937
|
));
|
|
843
938
|
const variantsDocuments = /* @__PURE__ */ new Map();
|
|
844
939
|
const decisionDocuments = /* @__PURE__ */ new Map();
|
|
845
|
-
|
|
940
|
+
const client = {
|
|
846
941
|
async query(document2, variables, queryOptions = {}) {
|
|
847
942
|
const { variants, ...rest } = queryOptions;
|
|
848
943
|
if (!variants) return run(document2, variables, rest);
|
|
@@ -854,10 +949,10 @@ function createPreprClient(options) {
|
|
|
854
949
|
return run(derived, variables, rest);
|
|
855
950
|
},
|
|
856
951
|
async decide(document2, variables, queryOptions = {}) {
|
|
857
|
-
const { from,
|
|
952
|
+
const { from, ...rest } = queryOptions;
|
|
858
953
|
const paths = from === void 0 ? void 0 : personalizationPaths(from);
|
|
859
954
|
if (paths && paths.size === 0) return /* @__PURE__ */ new Map();
|
|
860
|
-
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") :
|
|
955
|
+
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") : "*";
|
|
861
956
|
let byPaths = decisionDocuments.get(document2);
|
|
862
957
|
if (!byPaths) {
|
|
863
958
|
byPaths = /* @__PURE__ */ new Map();
|
|
@@ -865,9 +960,7 @@ function createPreprClient(options) {
|
|
|
865
960
|
}
|
|
866
961
|
let derived = byPaths.get(signature);
|
|
867
962
|
if (derived === void 0) {
|
|
868
|
-
derived = toDecisionDocument(document2, await loadSchema(), paths
|
|
869
|
-
topLevelOnly: !paths && topLevelOnly
|
|
870
|
-
});
|
|
963
|
+
derived = toDecisionDocument(document2, await loadSchema(), paths);
|
|
871
964
|
byPaths.set(signature, derived);
|
|
872
965
|
}
|
|
873
966
|
if (!derived) return /* @__PURE__ */ new Map();
|
|
@@ -881,14 +974,47 @@ function createPreprClient(options) {
|
|
|
881
974
|
(vary) => vary === null || SEGMENTS_VARY.test(vary)
|
|
882
975
|
)
|
|
883
976
|
};
|
|
977
|
+
clientSchemas.set(client, loadSchema);
|
|
978
|
+
return client;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/core/graphql/schema-loader.ts
|
|
982
|
+
var schemas = /* @__PURE__ */ new Map();
|
|
983
|
+
async function loadPreprSchema(url, options = {}) {
|
|
984
|
+
assertPreprUrl(url, "loadPreprSchema");
|
|
985
|
+
let schema = schemas.get(url);
|
|
986
|
+
if (!schema) {
|
|
987
|
+
const run = createTransport({ url, fetch: options.fetch, stega: "none" });
|
|
988
|
+
schema = run(
|
|
989
|
+
PREPR_SCHEMA_QUERY
|
|
990
|
+
).then((result) => toSchemaInfo(result.data)).catch((error) => {
|
|
991
|
+
schemas.delete(url);
|
|
992
|
+
if (error instanceof PreprError) throw error;
|
|
993
|
+
throw new PreprError(
|
|
994
|
+
"Prepr schema response is not an introspection result",
|
|
995
|
+
"INVALID_RESPONSE",
|
|
996
|
+
"loadPreprSchema",
|
|
997
|
+
error instanceof Error ? error : void 0
|
|
998
|
+
);
|
|
999
|
+
});
|
|
1000
|
+
schemas.set(url, schema);
|
|
1001
|
+
}
|
|
1002
|
+
return schema;
|
|
884
1003
|
}
|
|
885
1004
|
// Annotate the CommonJS export names for ESM import in node:
|
|
886
1005
|
0 && (module.exports = {
|
|
1006
|
+
PREPR_ANY_ITEM_TAG,
|
|
887
1007
|
PREPR_DEFAULT_VARIANT,
|
|
888
1008
|
PreprError,
|
|
889
1009
|
createPreprClient,
|
|
1010
|
+
decisionsFrom,
|
|
890
1011
|
isPersonalizedResponse,
|
|
1012
|
+
loadPreprSchema,
|
|
1013
|
+
preprCacheTags,
|
|
1014
|
+
preprModelTag,
|
|
891
1015
|
preprVariantProps,
|
|
892
1016
|
resolveVariants,
|
|
893
|
-
splitStack
|
|
1017
|
+
splitStack,
|
|
1018
|
+
toDecisionQuery,
|
|
1019
|
+
toVariantsQuery
|
|
894
1020
|
});
|
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;
|
|
@@ -165,11 +189,6 @@ interface PreprDecideOptions extends Omit<PreprQueryOptions, 'variants'> {
|
|
|
165
189
|
* none, e.g. on pages with only A/B tests or no personalization.
|
|
166
190
|
*/
|
|
167
191
|
from?: unknown;
|
|
168
|
-
/**
|
|
169
|
-
* @internal Ask only about the first personalizable list on each path,
|
|
170
|
-
* without `from`: what middleware needs for groups at the top of a stack.
|
|
171
|
-
*/
|
|
172
|
-
topLevelOnly?: boolean;
|
|
173
192
|
}
|
|
174
193
|
interface PreprQueryResult<TResult> {
|
|
175
194
|
data: TResult;
|
|
@@ -214,6 +233,74 @@ interface PreprClient {
|
|
|
214
233
|
hasSegments<TVariables>(document: PreprDocument<unknown, TVariables>, variables?: TVariables): Promise<boolean>;
|
|
215
234
|
}
|
|
216
235
|
|
|
236
|
+
/**
|
|
237
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
238
|
+
* along; its shape is not part of the public API.
|
|
239
|
+
*/
|
|
240
|
+
type PreprSchema = PreprSchemaInfo;
|
|
241
|
+
/**
|
|
242
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
243
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
244
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
245
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
246
|
+
*
|
|
247
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
248
|
+
*/
|
|
249
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
250
|
+
/**
|
|
251
|
+
* The per-visitor decision query for the same query: send it with the
|
|
252
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
253
|
+
* `decisionsFrom`.
|
|
254
|
+
*
|
|
255
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
256
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
257
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
258
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
259
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
260
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
261
|
+
*
|
|
262
|
+
* Null when there is nothing to decide: send no request then.
|
|
263
|
+
*/
|
|
264
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
265
|
+
from?: unknown;
|
|
266
|
+
topLevelOnly?: boolean;
|
|
267
|
+
}): string | null;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Tag for pages showing more items than fit in Next.js's tag limits. Every
|
|
271
|
+
* webhook event revalidates it, so those pages refresh on any change.
|
|
272
|
+
*/
|
|
273
|
+
declare const PREPR_ANY_ITEM_TAG = "prepr:any";
|
|
274
|
+
/**
|
|
275
|
+
* Cache tag for every page listing items of one model. `tagItems` adds it to
|
|
276
|
+
* list queries and to lookups that found nothing; add it yourself with
|
|
277
|
+
* `cacheTag()` for other pages that depend on which items exist.
|
|
278
|
+
* `createPreprWebhookRoute` revalidates it when an item of that model is
|
|
279
|
+
* published, unpublished or deleted.
|
|
280
|
+
*
|
|
281
|
+
* The name is compared case-insensitively and without spaces or
|
|
282
|
+
* punctuation, so the model's name in Prepr (`'Blog post'`, as webhooks send
|
|
283
|
+
* it) and its GraphQL type (`BlogPost`) give the same tag. A model whose API
|
|
284
|
+
* ID was renamed away from its name gets two different tags.
|
|
285
|
+
*
|
|
286
|
+
* @param model The model's singular name in Prepr or its GraphQL type name.
|
|
287
|
+
*/
|
|
288
|
+
declare const preprModelTag: (model: string) => string;
|
|
289
|
+
/**
|
|
290
|
+
* Cache tags for every Prepr item in a query result: `prepr:<_id>` for each
|
|
291
|
+
* object with a string `_id`, at any depth. Pair it with `cacheTag()` inside
|
|
292
|
+
* `'use cache'`, and a publish webhook revalidates only the pages that show
|
|
293
|
+
* the changed item. Run the query with `variants: true` so the tags cover
|
|
294
|
+
* every variant's items, not only those of one visitor.
|
|
295
|
+
*
|
|
296
|
+
* Next.js accepts at most 128 tags of 256 characters per `cacheTag()` call.
|
|
297
|
+
* A result past either limit returns `[PREPR_ANY_ITEM_TAG]` instead, which
|
|
298
|
+
* every webhook event revalidates.
|
|
299
|
+
*
|
|
300
|
+
* @param data A parsed JSON query result, such as `query()`'s `data`.
|
|
301
|
+
*/
|
|
302
|
+
declare function preprCacheTags(data: unknown): string[];
|
|
303
|
+
|
|
217
304
|
/**
|
|
218
305
|
* Create a GraphQL client for the Prepr API.
|
|
219
306
|
*
|
|
@@ -228,4 +315,21 @@ interface PreprClient {
|
|
|
228
315
|
*/
|
|
229
316
|
declare function createPreprClient(options: PreprClientOptions): PreprClient;
|
|
230
317
|
|
|
231
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
|
|
320
|
+
* Prepr schema (which fields take `personalize`, which types can hold
|
|
321
|
+
* variants) with one introspection request, kept in memory per URL. For a
|
|
322
|
+
* site that uses its own GraphQL client; `createPreprClient` does this
|
|
323
|
+
* itself.
|
|
324
|
+
*
|
|
325
|
+
* Load it once at startup or lazily before the first rewrite. Schema changes
|
|
326
|
+
* in Prepr take effect after a restart or redeploy.
|
|
327
|
+
*
|
|
328
|
+
* @throws PreprError when the URL is invalid or the request fails; the URL,
|
|
329
|
+
* which holds your access token, is never part of the message.
|
|
330
|
+
*/
|
|
331
|
+
declare function loadPreprSchema(url: string, options?: {
|
|
332
|
+
fetch?: typeof fetch;
|
|
333
|
+
}): Promise<PreprSchemaInfo>;
|
|
334
|
+
|
|
335
|
+
export { PREPR_ANY_ITEM_TAG, 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, preprCacheTags, preprModelTag, 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;
|
|
@@ -165,11 +189,6 @@ interface PreprDecideOptions extends Omit<PreprQueryOptions, 'variants'> {
|
|
|
165
189
|
* none, e.g. on pages with only A/B tests or no personalization.
|
|
166
190
|
*/
|
|
167
191
|
from?: unknown;
|
|
168
|
-
/**
|
|
169
|
-
* @internal Ask only about the first personalizable list on each path,
|
|
170
|
-
* without `from`: what middleware needs for groups at the top of a stack.
|
|
171
|
-
*/
|
|
172
|
-
topLevelOnly?: boolean;
|
|
173
192
|
}
|
|
174
193
|
interface PreprQueryResult<TResult> {
|
|
175
194
|
data: TResult;
|
|
@@ -214,6 +233,74 @@ interface PreprClient {
|
|
|
214
233
|
hasSegments<TVariables>(document: PreprDocument<unknown, TVariables>, variables?: TVariables): Promise<boolean>;
|
|
215
234
|
}
|
|
216
235
|
|
|
236
|
+
/**
|
|
237
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
238
|
+
* along; its shape is not part of the public API.
|
|
239
|
+
*/
|
|
240
|
+
type PreprSchema = PreprSchemaInfo;
|
|
241
|
+
/**
|
|
242
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
243
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
244
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
245
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
246
|
+
*
|
|
247
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
248
|
+
*/
|
|
249
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
250
|
+
/**
|
|
251
|
+
* The per-visitor decision query for the same query: send it with the
|
|
252
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
253
|
+
* `decisionsFrom`.
|
|
254
|
+
*
|
|
255
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
256
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
257
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
258
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
259
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
260
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
261
|
+
*
|
|
262
|
+
* Null when there is nothing to decide: send no request then.
|
|
263
|
+
*/
|
|
264
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
265
|
+
from?: unknown;
|
|
266
|
+
topLevelOnly?: boolean;
|
|
267
|
+
}): string | null;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Tag for pages showing more items than fit in Next.js's tag limits. Every
|
|
271
|
+
* webhook event revalidates it, so those pages refresh on any change.
|
|
272
|
+
*/
|
|
273
|
+
declare const PREPR_ANY_ITEM_TAG = "prepr:any";
|
|
274
|
+
/**
|
|
275
|
+
* Cache tag for every page listing items of one model. `tagItems` adds it to
|
|
276
|
+
* list queries and to lookups that found nothing; add it yourself with
|
|
277
|
+
* `cacheTag()` for other pages that depend on which items exist.
|
|
278
|
+
* `createPreprWebhookRoute` revalidates it when an item of that model is
|
|
279
|
+
* published, unpublished or deleted.
|
|
280
|
+
*
|
|
281
|
+
* The name is compared case-insensitively and without spaces or
|
|
282
|
+
* punctuation, so the model's name in Prepr (`'Blog post'`, as webhooks send
|
|
283
|
+
* it) and its GraphQL type (`BlogPost`) give the same tag. A model whose API
|
|
284
|
+
* ID was renamed away from its name gets two different tags.
|
|
285
|
+
*
|
|
286
|
+
* @param model The model's singular name in Prepr or its GraphQL type name.
|
|
287
|
+
*/
|
|
288
|
+
declare const preprModelTag: (model: string) => string;
|
|
289
|
+
/**
|
|
290
|
+
* Cache tags for every Prepr item in a query result: `prepr:<_id>` for each
|
|
291
|
+
* object with a string `_id`, at any depth. Pair it with `cacheTag()` inside
|
|
292
|
+
* `'use cache'`, and a publish webhook revalidates only the pages that show
|
|
293
|
+
* the changed item. Run the query with `variants: true` so the tags cover
|
|
294
|
+
* every variant's items, not only those of one visitor.
|
|
295
|
+
*
|
|
296
|
+
* Next.js accepts at most 128 tags of 256 characters per `cacheTag()` call.
|
|
297
|
+
* A result past either limit returns `[PREPR_ANY_ITEM_TAG]` instead, which
|
|
298
|
+
* every webhook event revalidates.
|
|
299
|
+
*
|
|
300
|
+
* @param data A parsed JSON query result, such as `query()`'s `data`.
|
|
301
|
+
*/
|
|
302
|
+
declare function preprCacheTags(data: unknown): string[];
|
|
303
|
+
|
|
217
304
|
/**
|
|
218
305
|
* Create a GraphQL client for the Prepr API.
|
|
219
306
|
*
|
|
@@ -228,4 +315,21 @@ interface PreprClient {
|
|
|
228
315
|
*/
|
|
229
316
|
declare function createPreprClient(options: PreprClientOptions): PreprClient;
|
|
230
317
|
|
|
231
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
|
|
320
|
+
* Prepr schema (which fields take `personalize`, which types can hold
|
|
321
|
+
* variants) with one introspection request, kept in memory per URL. For a
|
|
322
|
+
* site that uses its own GraphQL client; `createPreprClient` does this
|
|
323
|
+
* itself.
|
|
324
|
+
*
|
|
325
|
+
* Load it once at startup or lazily before the first rewrite. Schema changes
|
|
326
|
+
* in Prepr take effect after a restart or redeploy.
|
|
327
|
+
*
|
|
328
|
+
* @throws PreprError when the URL is invalid or the request fails; the URL,
|
|
329
|
+
* which holds your access token, is never part of the message.
|
|
330
|
+
*/
|
|
331
|
+
declare function loadPreprSchema(url: string, options?: {
|
|
332
|
+
fetch?: typeof fetch;
|
|
333
|
+
}): Promise<PreprSchemaInfo>;
|
|
334
|
+
|
|
335
|
+
export { PREPR_ANY_ITEM_TAG, 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, preprCacheTags, preprModelTag, preprVariantProps, resolveVariants, splitStack, toDecisionQuery, toVariantsQuery };
|