@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.
Files changed (52) hide show
  1. package/README.md +107 -0
  2. package/dist/astro/{chunk-3UVUDDNY.js → chunk-U7VUQL57.js} +1 -1
  3. package/dist/astro/graphql.cjs +96 -49
  4. package/dist/astro/graphql.d.cts +75 -1
  5. package/dist/astro/graphql.d.ts +75 -1
  6. package/dist/astro/graphql.js +92 -49
  7. package/dist/astro/index.cjs +1 -1
  8. package/dist/astro/index.js +1 -1
  9. package/dist/chunk-3NCEVJJ3.js +10 -0
  10. package/dist/chunk-7HSMUULV.js +452 -0
  11. package/dist/{chunk-BJ2LBLWO.js → chunk-DS3QA3HF.js} +6 -4
  12. package/dist/{chunk-DGZA7KX7.js → chunk-S5RWVMDJ.js} +0 -24
  13. package/dist/{chunk-YR7P4IWE.js → chunk-UYYTYSOD.js} +1 -9
  14. package/dist/chunk-VV4PRH7W.js +26 -0
  15. package/dist/graphql/codegen.cjs +510 -0
  16. package/dist/graphql/codegen.d.cts +23 -0
  17. package/dist/graphql/codegen.d.ts +23 -0
  18. package/dist/graphql/codegen.js +99 -0
  19. package/dist/graphql.cjs +96 -49
  20. package/dist/graphql.d.cts +75 -1
  21. package/dist/graphql.d.ts +75 -1
  22. package/dist/graphql.js +60 -428
  23. package/dist/index.cjs +1 -1
  24. package/dist/index.d.cts +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +10 -6
  27. package/dist/nextjs/{chunk-U4HXENF7.js → chunk-ZIUKEGEN.js} +1 -1
  28. package/dist/nextjs/components.cjs +12 -8
  29. package/dist/nextjs/components.js +14 -9
  30. package/dist/nextjs/graphql.cjs +96 -49
  31. package/dist/nextjs/graphql.d.cts +75 -1
  32. package/dist/nextjs/graphql.d.ts +75 -1
  33. package/dist/nextjs/graphql.js +92 -49
  34. package/dist/nextjs/index.cjs +1 -1
  35. package/dist/nextjs/index.js +1 -1
  36. package/dist/nuxt/{chunk-P6ENNAEE.js → chunk-GMWF6PQ5.js} +1 -1
  37. package/dist/nuxt/graphql.cjs +96 -49
  38. package/dist/nuxt/graphql.d.cts +75 -1
  39. package/dist/nuxt/graphql.d.ts +75 -1
  40. package/dist/nuxt/graphql.js +92 -49
  41. package/dist/nuxt/index.cjs +1 -1
  42. package/dist/nuxt/index.js +1 -1
  43. package/dist/react/components.cjs +1 -1
  44. package/dist/react/components.js +1 -1
  45. package/dist/sveltekit/{chunk-FSARVMG5.js → chunk-5SQUG2L4.js} +1 -1
  46. package/dist/sveltekit/graphql.cjs +96 -49
  47. package/dist/sveltekit/graphql.d.cts +75 -1
  48. package/dist/sveltekit/graphql.d.ts +75 -1
  49. package/dist/sveltekit/graphql.js +92 -49
  50. package/dist/sveltekit/index.cjs +1 -1
  51. package/dist/sveltekit/index.js +1 -1
  52. package/package.json +6 -1
@@ -23,10 +23,14 @@ __export(graphql_exports, {
23
23
  PREPR_DEFAULT_VARIANT: () => PREPR_DEFAULT_VARIANT,
24
24
  PreprError: () => PreprError,
25
25
  createPreprClient: () => createPreprClient2,
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
 
@@ -564,6 +568,63 @@ function toVariantsDocument(document2, schema) {
564
568
  };
565
569
  }
566
570
 
571
+ // src/core/graphql/document.ts
572
+ var import_printer = require("graphql/language/printer.js");
573
+ var import_stripIgnoredCharacters = require("graphql/utilities/stripIgnoredCharacters.js");
574
+ var printed = /* @__PURE__ */ new WeakMap();
575
+ function isDocumentNode(value) {
576
+ return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
577
+ }
578
+ function invalidDocument(originalError) {
579
+ return new PreprError(
580
+ "Expected a GraphQL query string, TypedDocumentString or DocumentNode",
581
+ "INVALID_DOCUMENT",
582
+ "createPreprClient",
583
+ originalError
584
+ );
585
+ }
586
+ var minified = /* @__PURE__ */ new Map();
587
+ var MINIFIED_CACHE_LIMIT = 500;
588
+ function minify(query) {
589
+ const cached = minified.get(query);
590
+ if (cached !== void 0) return cached;
591
+ let result = query;
592
+ try {
593
+ result = (0, import_stripIgnoredCharacters.stripIgnoredCharacters)(query);
594
+ } catch {
595
+ }
596
+ if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
597
+ return result;
598
+ }
599
+ function resolveQuery(document2) {
600
+ if (typeof document2 === "string") return minify(document2);
601
+ if (document2 instanceof String) return minify(document2.toString());
602
+ if (!isDocumentNode(document2)) throw invalidDocument();
603
+ let query = printed.get(document2);
604
+ if (query === void 0) {
605
+ try {
606
+ query = minify((0, import_printer.print)(document2));
607
+ } catch (error) {
608
+ throw invalidDocument(error instanceof Error ? error : void 0);
609
+ }
610
+ printed.set(document2, query);
611
+ }
612
+ return query;
613
+ }
614
+
615
+ // src/core/variants/queries.ts
616
+ function toVariantsQuery(document2, schema) {
617
+ return resolveQuery(toVariantsDocument(document2, schema));
618
+ }
619
+ function toDecisionQuery(document2, schema, options = {}) {
620
+ const paths = options.from === void 0 ? void 0 : personalizationPaths(options.from);
621
+ if (paths && paths.size === 0) return null;
622
+ const decision = toDecisionDocument(document2, schema, paths, {
623
+ topLevelOnly: !paths && options.topLevelOnly
624
+ });
625
+ return decision ? resolveQuery(decision) : null;
626
+ }
627
+
567
628
  // src/core/graphql/transport.ts
568
629
  var import_stega2 = require("@vercel/stega");
569
630
 
@@ -623,50 +684,6 @@ function stegaClean(text) {
623
684
  return (0, import_stega.vercelStegaClean)(text);
624
685
  }
625
686
 
626
- // src/core/graphql/document.ts
627
- var import_printer = require("graphql/language/printer.js");
628
- var import_stripIgnoredCharacters = require("graphql/utilities/stripIgnoredCharacters.js");
629
- var printed = /* @__PURE__ */ new WeakMap();
630
- function isDocumentNode(value) {
631
- return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
632
- }
633
- function invalidDocument(originalError) {
634
- return new PreprError(
635
- "Expected a GraphQL query string, TypedDocumentString or DocumentNode",
636
- "INVALID_DOCUMENT",
637
- "createPreprClient",
638
- originalError
639
- );
640
- }
641
- var minified = /* @__PURE__ */ new Map();
642
- var MINIFIED_CACHE_LIMIT = 500;
643
- function minify(query) {
644
- const cached = minified.get(query);
645
- if (cached !== void 0) return cached;
646
- let result = query;
647
- try {
648
- result = (0, import_stripIgnoredCharacters.stripIgnoredCharacters)(query);
649
- } catch {
650
- }
651
- if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
652
- return result;
653
- }
654
- function resolveQuery(document2) {
655
- if (typeof document2 === "string") return minify(document2);
656
- if (document2 instanceof String) return minify(document2.toString());
657
- if (!isDocumentNode(document2)) throw invalidDocument();
658
- let query = printed.get(document2);
659
- if (query === void 0) {
660
- try {
661
- query = minify((0, import_printer.print)(document2));
662
- } catch (error) {
663
- throw invalidDocument(error instanceof Error ? error : void 0);
664
- }
665
- printed.set(document2, query);
666
- }
667
- return query;
668
- }
669
-
670
687
  // src/core/graphql/transport.ts
671
688
  var OPERATION_NAME = /\b(?:query|mutation|subscription)\s+([_A-Za-z][_0-9A-Za-z]*)/;
672
689
  var STEGA_RAW = new RegExp(
@@ -853,16 +870,18 @@ function isParseableUrl(url) {
853
870
  return false;
854
871
  }
855
872
  }
856
- function createPreprClient(options) {
857
- const { url } = options;
873
+ function assertPreprUrl(url, source) {
858
874
  validatePreprToken(url);
859
875
  if (!isParseableUrl(url)) {
860
876
  throw new PreprError(
861
877
  "Prepr GraphQL URL is not a valid URL",
862
878
  "INVALID_TOKEN",
863
- "createPreprClient"
879
+ source
864
880
  );
865
881
  }
882
+ }
883
+ function createPreprClient(options) {
884
+ assertPreprUrl(options.url, "createPreprClient");
866
885
  const run = createTransport(options);
867
886
  const probeVary = createVaryProbe(run, options);
868
887
  let schema;
@@ -965,6 +984,30 @@ function createEventClient(options, adapter) {
965
984
  };
966
985
  }
967
986
 
987
+ // src/core/graphql/schema-loader.ts
988
+ var schemas = /* @__PURE__ */ new Map();
989
+ async function loadPreprSchema(url, options = {}) {
990
+ assertPreprUrl(url, "loadPreprSchema");
991
+ let schema = schemas.get(url);
992
+ if (!schema) {
993
+ const run = createTransport({ url, fetch: options.fetch, stega: "none" });
994
+ schema = run(
995
+ PREPR_SCHEMA_QUERY
996
+ ).then((result) => toSchemaInfo(result.data)).catch((error) => {
997
+ schemas.delete(url);
998
+ if (error instanceof PreprError) throw error;
999
+ throw new PreprError(
1000
+ "Prepr schema response is not an introspection result",
1001
+ "INVALID_RESPONSE",
1002
+ "loadPreprSchema",
1003
+ error instanceof Error ? error : void 0
1004
+ );
1005
+ });
1006
+ schemas.set(url, schema);
1007
+ }
1008
+ return schema;
1009
+ }
1010
+
968
1011
  // src/nuxt/middleware.ts
969
1012
  var PREPR_CONTEXT_KEY = "prepr";
970
1013
  function getPreprHeadersFromEvent(event) {
@@ -983,8 +1026,12 @@ function createPreprClient2(options) {
983
1026
  PREPR_DEFAULT_VARIANT,
984
1027
  PreprError,
985
1028
  createPreprClient,
1029
+ decisionsFrom,
986
1030
  isPersonalizedResponse,
1031
+ loadPreprSchema,
987
1032
  preprVariantProps,
988
1033
  resolveVariants,
989
- splitStack
1034
+ splitStack,
1035
+ toDecisionQuery,
1036
+ toVariantsQuery
990
1037
  });
@@ -7,6 +7,12 @@ declare const PREPR_DEFAULT_VARIANT = "ALL_OTHER_USERS";
7
7
 
8
8
  /** The variant ids Prepr chose for one visitor, per personalization group. */
9
9
  type PreprDecisions = ReadonlyMap<string, readonly string[]>;
10
+ /**
11
+ * Variant ids per group from a decision response, de-duplicated and in
12
+ * Prepr's order. A visitor in several segments can get more than one variant
13
+ * of the same group, so each entry is a list.
14
+ */
15
+ declare function decisionsFrom(data: unknown): PreprDecisions;
10
16
  interface ResolveVariantsOptions {
11
17
  /**
12
18
  * The visitor's per-group variants (from a decision query). Without it,
@@ -23,6 +29,24 @@ interface ResolveVariantsOptions {
23
29
  */
24
30
  declare function resolveVariants<T>(data: T, options?: ResolveVariantsOptions): T;
25
31
 
32
+ interface FieldInfo {
33
+ /** Named type of the field, without list/non-null wrappers. */
34
+ type: string;
35
+ /** The field accepts Prepr's `personalize` argument (a stack). */
36
+ personalizable: boolean;
37
+ }
38
+ interface TypeInfo {
39
+ fields: Record<string, FieldInfo>;
40
+ /** Members of a union or implementations of an interface. */
41
+ possibleTypes: string[];
42
+ hasContext: boolean;
43
+ }
44
+ /** The slice of the schema the variant transforms need. */
45
+ interface PreprSchemaInfo {
46
+ queryType: string;
47
+ types: Record<string, TypeInfo>;
48
+ }
49
+
26
50
  /** A run of stack items that renders the same way: see {@link splitStack}. */
27
51
  interface PreprStackBlock<T> {
28
52
  key: string;
@@ -71,6 +95,39 @@ interface PreprVariantProps {
71
95
  */
72
96
  declare function preprVariantProps(item: unknown): PreprVariantProps;
73
97
 
98
+ /**
99
+ * The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
100
+ * along; its shape is not part of the public API.
101
+ */
102
+ type PreprSchema = PreprSchemaInfo;
103
+ /**
104
+ * Your query, asking for every personalization and A/B variant: what
105
+ * `query(..., { variants: true })` sends, as a string for your own GraphQL
106
+ * client. The result is the same for every visitor, so cache it like any
107
+ * other content query, and render it with `resolveVariants` or `PreprStack`.
108
+ *
109
+ * A query without personalizable fields comes back unchanged (minified).
110
+ */
111
+ declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
112
+ /**
113
+ * The per-visitor decision query for the same query: send it with the
114
+ * visitor's Prepr headers, never cached, and pass the response's `data` to
115
+ * `decisionsFrom`.
116
+ *
117
+ * Pass the variants result as `from` whenever you have it: the query then
118
+ * asks only about the lists that hold segment groups on this page, which is
119
+ * a few hundred bytes instead of the whole page and markedly faster for a
120
+ * visitor Prepr has not seen before. Without `from` it asks about every
121
+ * personalizable list. `topLevelOnly` stops at the first personalizable list
122
+ * on each path, for middleware that decides only the top of a stack.
123
+ *
124
+ * Null when there is nothing to decide: send no request then.
125
+ */
126
+ declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
127
+ from?: unknown;
128
+ topLevelOnly?: boolean;
129
+ }): string | null;
130
+
74
131
  /**
75
132
  * A GraphQL document accepted by `query`: a plain string, graphql-codegen's
76
133
  * `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
@@ -211,6 +268,23 @@ interface PreprEventClient<TEvent> {
211
268
  }): Promise<PreprDecisions>;
212
269
  }
213
270
 
271
+ /**
272
+ * Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
273
+ * Prepr schema (which fields take `personalize`, which types can hold
274
+ * variants) with one introspection request, kept in memory per URL. For a
275
+ * site that uses its own GraphQL client; `createPreprClient` does this
276
+ * itself.
277
+ *
278
+ * Load it once at startup or lazily before the first rewrite. Schema changes
279
+ * in Prepr take effect after a restart or redeploy.
280
+ *
281
+ * @throws PreprError when the URL is invalid or the request fails; the URL,
282
+ * which holds your access token, is never part of the message.
283
+ */
284
+ declare function loadPreprSchema(url: string, options?: {
285
+ fetch?: typeof fetch;
286
+ }): Promise<PreprSchemaInfo>;
287
+
214
288
  /** The part of an h3 event the client reads. */
215
289
  type PreprNuxtEvent = Pick<H3EventLike, 'context'>;
216
290
  /**
@@ -225,4 +299,4 @@ type PreprNuxtEvent = Pick<H3EventLike, 'context'>;
225
299
  */
226
300
  declare function createPreprClient(options: PreprClientOptions): PreprEventClient<PreprNuxtEvent>;
227
301
 
228
- export { PREPR_DEFAULT_VARIANT, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, type PreprEventClient, type PreprEventQueryOptions, type PreprNuxtEvent, type PreprQueryResult, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, preprVariantProps, resolveVariants, splitStack };
302
+ export { PREPR_DEFAULT_VARIANT, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, type PreprEventClient, type PreprEventQueryOptions, type PreprNuxtEvent, type PreprQueryResult, type PreprSchema, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, decisionsFrom, loadPreprSchema, preprVariantProps, resolveVariants, splitStack, toDecisionQuery, toVariantsQuery };
@@ -7,6 +7,12 @@ declare const PREPR_DEFAULT_VARIANT = "ALL_OTHER_USERS";
7
7
 
8
8
  /** The variant ids Prepr chose for one visitor, per personalization group. */
9
9
  type PreprDecisions = ReadonlyMap<string, readonly string[]>;
10
+ /**
11
+ * Variant ids per group from a decision response, de-duplicated and in
12
+ * Prepr's order. A visitor in several segments can get more than one variant
13
+ * of the same group, so each entry is a list.
14
+ */
15
+ declare function decisionsFrom(data: unknown): PreprDecisions;
10
16
  interface ResolveVariantsOptions {
11
17
  /**
12
18
  * The visitor's per-group variants (from a decision query). Without it,
@@ -23,6 +29,24 @@ interface ResolveVariantsOptions {
23
29
  */
24
30
  declare function resolveVariants<T>(data: T, options?: ResolveVariantsOptions): T;
25
31
 
32
+ interface FieldInfo {
33
+ /** Named type of the field, without list/non-null wrappers. */
34
+ type: string;
35
+ /** The field accepts Prepr's `personalize` argument (a stack). */
36
+ personalizable: boolean;
37
+ }
38
+ interface TypeInfo {
39
+ fields: Record<string, FieldInfo>;
40
+ /** Members of a union or implementations of an interface. */
41
+ possibleTypes: string[];
42
+ hasContext: boolean;
43
+ }
44
+ /** The slice of the schema the variant transforms need. */
45
+ interface PreprSchemaInfo {
46
+ queryType: string;
47
+ types: Record<string, TypeInfo>;
48
+ }
49
+
26
50
  /** A run of stack items that renders the same way: see {@link splitStack}. */
27
51
  interface PreprStackBlock<T> {
28
52
  key: string;
@@ -71,6 +95,39 @@ interface PreprVariantProps {
71
95
  */
72
96
  declare function preprVariantProps(item: unknown): PreprVariantProps;
73
97
 
98
+ /**
99
+ * The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
100
+ * along; its shape is not part of the public API.
101
+ */
102
+ type PreprSchema = PreprSchemaInfo;
103
+ /**
104
+ * Your query, asking for every personalization and A/B variant: what
105
+ * `query(..., { variants: true })` sends, as a string for your own GraphQL
106
+ * client. The result is the same for every visitor, so cache it like any
107
+ * other content query, and render it with `resolveVariants` or `PreprStack`.
108
+ *
109
+ * A query without personalizable fields comes back unchanged (minified).
110
+ */
111
+ declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
112
+ /**
113
+ * The per-visitor decision query for the same query: send it with the
114
+ * visitor's Prepr headers, never cached, and pass the response's `data` to
115
+ * `decisionsFrom`.
116
+ *
117
+ * Pass the variants result as `from` whenever you have it: the query then
118
+ * asks only about the lists that hold segment groups on this page, which is
119
+ * a few hundred bytes instead of the whole page and markedly faster for a
120
+ * visitor Prepr has not seen before. Without `from` it asks about every
121
+ * personalizable list. `topLevelOnly` stops at the first personalizable list
122
+ * on each path, for middleware that decides only the top of a stack.
123
+ *
124
+ * Null when there is nothing to decide: send no request then.
125
+ */
126
+ declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
127
+ from?: unknown;
128
+ topLevelOnly?: boolean;
129
+ }): string | null;
130
+
74
131
  /**
75
132
  * A GraphQL document accepted by `query`: a plain string, graphql-codegen's
76
133
  * `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
@@ -211,6 +268,23 @@ interface PreprEventClient<TEvent> {
211
268
  }): Promise<PreprDecisions>;
212
269
  }
213
270
 
271
+ /**
272
+ * Loads what `toVariantsQuery` and `toDecisionQuery` need to know about your
273
+ * Prepr schema (which fields take `personalize`, which types can hold
274
+ * variants) with one introspection request, kept in memory per URL. For a
275
+ * site that uses its own GraphQL client; `createPreprClient` does this
276
+ * itself.
277
+ *
278
+ * Load it once at startup or lazily before the first rewrite. Schema changes
279
+ * in Prepr take effect after a restart or redeploy.
280
+ *
281
+ * @throws PreprError when the URL is invalid or the request fails; the URL,
282
+ * which holds your access token, is never part of the message.
283
+ */
284
+ declare function loadPreprSchema(url: string, options?: {
285
+ fetch?: typeof fetch;
286
+ }): Promise<PreprSchemaInfo>;
287
+
214
288
  /** The part of an h3 event the client reads. */
215
289
  type PreprNuxtEvent = Pick<H3EventLike, 'context'>;
216
290
  /**
@@ -225,4 +299,4 @@ type PreprNuxtEvent = Pick<H3EventLike, 'context'>;
225
299
  */
226
300
  declare function createPreprClient(options: PreprClientOptions): PreprEventClient<PreprNuxtEvent>;
227
301
 
228
- export { PREPR_DEFAULT_VARIANT, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, type PreprEventClient, type PreprEventQueryOptions, type PreprNuxtEvent, type PreprQueryResult, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, preprVariantProps, resolveVariants, splitStack };
302
+ export { PREPR_DEFAULT_VARIANT, type PreprClientOptions, type PreprDecideOptions, type PreprDecisions, type PreprDocument, type PreprEventClient, type PreprEventQueryOptions, type PreprNuxtEvent, type PreprQueryResult, type PreprSchema, type PreprStackBlock, type PreprStegaMode, type PreprVariantProps, type ResolveVariantsOptions, createPreprClient, decisionsFrom, loadPreprSchema, preprVariantProps, resolveVariants, splitStack, toDecisionQuery, toVariantsQuery };
@@ -4,7 +4,7 @@ import {
4
4
  getPreprHeadersFromHeaders,
5
5
  isPersonalizedResponse,
6
6
  validatePreprToken
7
- } from "./chunk-P6ENNAEE.js";
7
+ } from "./chunk-GMWF6PQ5.js";
8
8
 
9
9
  // src/core/variants/constants.ts
10
10
  var PREPR_CONTEXT_ALIAS = "_preprContext";
@@ -483,6 +483,63 @@ function toVariantsDocument(document2, schema) {
483
483
  };
484
484
  }
485
485
 
486
+ // src/core/graphql/document.ts
487
+ import { print } from "graphql/language/printer.js";
488
+ import { stripIgnoredCharacters } from "graphql/utilities/stripIgnoredCharacters.js";
489
+ var printed = /* @__PURE__ */ new WeakMap();
490
+ function isDocumentNode(value) {
491
+ return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
492
+ }
493
+ function invalidDocument(originalError) {
494
+ return new PreprError(
495
+ "Expected a GraphQL query string, TypedDocumentString or DocumentNode",
496
+ "INVALID_DOCUMENT",
497
+ "createPreprClient",
498
+ originalError
499
+ );
500
+ }
501
+ var minified = /* @__PURE__ */ new Map();
502
+ var MINIFIED_CACHE_LIMIT = 500;
503
+ function minify(query) {
504
+ const cached = minified.get(query);
505
+ if (cached !== void 0) return cached;
506
+ let result = query;
507
+ try {
508
+ result = stripIgnoredCharacters(query);
509
+ } catch {
510
+ }
511
+ if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
512
+ return result;
513
+ }
514
+ function resolveQuery(document2) {
515
+ if (typeof document2 === "string") return minify(document2);
516
+ if (document2 instanceof String) return minify(document2.toString());
517
+ if (!isDocumentNode(document2)) throw invalidDocument();
518
+ let query = printed.get(document2);
519
+ if (query === void 0) {
520
+ try {
521
+ query = minify(print(document2));
522
+ } catch (error) {
523
+ throw invalidDocument(error instanceof Error ? error : void 0);
524
+ }
525
+ printed.set(document2, query);
526
+ }
527
+ return query;
528
+ }
529
+
530
+ // src/core/variants/queries.ts
531
+ function toVariantsQuery(document2, schema) {
532
+ return resolveQuery(toVariantsDocument(document2, schema));
533
+ }
534
+ function toDecisionQuery(document2, schema, options = {}) {
535
+ const paths = options.from === void 0 ? void 0 : personalizationPaths(options.from);
536
+ if (paths && paths.size === 0) return null;
537
+ const decision = toDecisionDocument(document2, schema, paths, {
538
+ topLevelOnly: !paths && options.topLevelOnly
539
+ });
540
+ return decision ? resolveQuery(decision) : null;
541
+ }
542
+
486
543
  // src/core/graphql/transport.ts
487
544
  import { VERCEL_STEGA_REGEX } from "@vercel/stega";
488
545
 
@@ -535,50 +592,6 @@ function stegaClean(text) {
535
592
  return vercelStegaClean(text);
536
593
  }
537
594
 
538
- // src/core/graphql/document.ts
539
- import { print } from "graphql/language/printer.js";
540
- import { stripIgnoredCharacters } from "graphql/utilities/stripIgnoredCharacters.js";
541
- var printed = /* @__PURE__ */ new WeakMap();
542
- function isDocumentNode(value) {
543
- return typeof value === "object" && value !== null && value.kind === "Document" && Array.isArray(value.definitions);
544
- }
545
- function invalidDocument(originalError) {
546
- return new PreprError(
547
- "Expected a GraphQL query string, TypedDocumentString or DocumentNode",
548
- "INVALID_DOCUMENT",
549
- "createPreprClient",
550
- originalError
551
- );
552
- }
553
- var minified = /* @__PURE__ */ new Map();
554
- var MINIFIED_CACHE_LIMIT = 500;
555
- function minify(query) {
556
- const cached = minified.get(query);
557
- if (cached !== void 0) return cached;
558
- let result = query;
559
- try {
560
- result = stripIgnoredCharacters(query);
561
- } catch {
562
- }
563
- if (minified.size < MINIFIED_CACHE_LIMIT) minified.set(query, result);
564
- return result;
565
- }
566
- function resolveQuery(document2) {
567
- if (typeof document2 === "string") return minify(document2);
568
- if (document2 instanceof String) return minify(document2.toString());
569
- if (!isDocumentNode(document2)) throw invalidDocument();
570
- let query = printed.get(document2);
571
- if (query === void 0) {
572
- try {
573
- query = minify(print(document2));
574
- } catch (error) {
575
- throw invalidDocument(error instanceof Error ? error : void 0);
576
- }
577
- printed.set(document2, query);
578
- }
579
- return query;
580
- }
581
-
582
595
  // src/core/graphql/transport.ts
583
596
  var OPERATION_NAME = /\b(?:query|mutation|subscription)\s+([_A-Za-z][_0-9A-Za-z]*)/;
584
597
  var STEGA_RAW = new RegExp(
@@ -765,16 +778,18 @@ function isParseableUrl(url) {
765
778
  return false;
766
779
  }
767
780
  }
768
- function createPreprClient(options) {
769
- const { url } = options;
781
+ function assertPreprUrl(url, source) {
770
782
  validatePreprToken(url);
771
783
  if (!isParseableUrl(url)) {
772
784
  throw new PreprError(
773
785
  "Prepr GraphQL URL is not a valid URL",
774
786
  "INVALID_TOKEN",
775
- "createPreprClient"
787
+ source
776
788
  );
777
789
  }
790
+ }
791
+ function createPreprClient(options) {
792
+ assertPreprUrl(options.url, "createPreprClient");
778
793
  const run = createTransport(options);
779
794
  const probeVary = createVaryProbe(run, options);
780
795
  let schema;
@@ -877,6 +892,30 @@ function createEventClient(options, adapter) {
877
892
  };
878
893
  }
879
894
 
895
+ // src/core/graphql/schema-loader.ts
896
+ var schemas = /* @__PURE__ */ new Map();
897
+ async function loadPreprSchema(url, options = {}) {
898
+ assertPreprUrl(url, "loadPreprSchema");
899
+ let schema = schemas.get(url);
900
+ if (!schema) {
901
+ const run = createTransport({ url, fetch: options.fetch, stega: "none" });
902
+ schema = run(
903
+ PREPR_SCHEMA_QUERY
904
+ ).then((result) => toSchemaInfo(result.data)).catch((error) => {
905
+ schemas.delete(url);
906
+ if (error instanceof PreprError) throw error;
907
+ throw new PreprError(
908
+ "Prepr schema response is not an introspection result",
909
+ "INVALID_RESPONSE",
910
+ "loadPreprSchema",
911
+ error instanceof Error ? error : void 0
912
+ );
913
+ });
914
+ schemas.set(url, schema);
915
+ }
916
+ return schema;
917
+ }
918
+
880
919
  // src/nuxt/graphql.ts
881
920
  function createPreprClient2(options) {
882
921
  return createEventClient(options, {
@@ -887,8 +926,12 @@ export {
887
926
  PREPR_DEFAULT_VARIANT,
888
927
  PreprError,
889
928
  createPreprClient2 as createPreprClient,
929
+ decisionsFrom,
890
930
  isPersonalizedResponse,
931
+ loadPreprSchema,
891
932
  preprVariantProps,
892
933
  resolveVariants,
893
- splitStack
934
+ splitStack,
935
+ toDecisionQuery,
936
+ toVariantsQuery
894
937
  };
@@ -36,7 +36,7 @@ __export(nuxt_exports, {
36
36
  module.exports = __toCommonJS(nuxt_exports);
37
37
 
38
38
  // src/version.ts
39
- var VERSION = "0.6.0-alpha.0";
39
+ var VERSION = "0.6.0-alpha.2";
40
40
 
41
41
  // src/core/constants.ts
42
42
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";
@@ -11,7 +11,7 @@ import {
11
11
  handlePreprRequest,
12
12
  isPersonalizedResponse,
13
13
  validatePreprToken
14
- } from "./chunk-P6ENNAEE.js";
14
+ } from "./chunk-GMWF6PQ5.js";
15
15
 
16
16
  // src/nuxt/server.ts
17
17
  function getPreprUUID(headers) {
@@ -2313,7 +2313,7 @@ function isReactHydrated(text) {
2313
2313
  }
2314
2314
 
2315
2315
  // src/version.ts
2316
- var VERSION = "0.6.0-alpha.0";
2316
+ var VERSION = "0.6.0-alpha.2";
2317
2317
 
2318
2318
  // src/core/pixel.ts
2319
2319
  var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
@@ -2289,7 +2289,7 @@ function isReactHydrated(text) {
2289
2289
  }
2290
2290
 
2291
2291
  // src/version.ts
2292
- var VERSION = "0.6.0-alpha.0";
2292
+ var VERSION = "0.6.0-alpha.2";
2293
2293
 
2294
2294
  // src/core/pixel.ts
2295
2295
  var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var VERSION = "0.6.0-alpha.0";
2
+ var VERSION = "0.6.0-alpha.2";
3
3
 
4
4
  // src/core/constants.ts
5
5
  var COOKIE_PREVIEW_MODE = "Prepr-Preview-Mode";