@preprio/toolkit 0.6.0-alpha.5 → 0.6.0-alpha.7
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 +138 -52
- package/dist/astro/{chunk-CD4LXNR3.js → chunk-3EXK2LHI.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-5O7RGYHX.js → chunk-3QGWCYTL.js} +1 -1
- package/dist/{chunk-ZWKHACNA.js → chunk-PFJO4TYL.js} +52 -5
- package/dist/{chunk-HPWTLDLR.js → chunk-U7TRFVK7.js} +1 -1
- package/dist/{chunk-OH2PPC76.js → chunk-VQIPTUN4.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-L4L6X3JJ.js → chunk-CZK7SMBD.js} +58 -53
- package/dist/nextjs/components.cjs +175 -242
- package/dist/nextjs/components.d.cts +25 -21
- package/dist/nextjs/components.d.ts +25 -21
- package/dist/nextjs/components.js +167 -236
- package/dist/nextjs/graphql.cjs +374 -510
- package/dist/nextjs/graphql.d.cts +131 -135
- package/dist/nextjs/graphql.d.ts +131 -135
- package/dist/nextjs/graphql.js +309 -457
- package/dist/nextjs/index.cjs +114 -54
- package/dist/nextjs/index.d.cts +57 -33
- package/dist/nextjs/index.d.ts +57 -33
- package/dist/nextjs/index.js +108 -5
- package/dist/nuxt/{chunk-PJZMLKJ2.js → chunk-JL33ENCM.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-SKBW7RBD.js → chunk-S7S276V7.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/nuxt/graphql.cjs
CHANGED
|
@@ -178,7 +178,10 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
178
178
|
path,
|
|
179
179
|
ctx
|
|
180
180
|
);
|
|
181
|
-
if (pruned)
|
|
181
|
+
if (!pruned) continue;
|
|
182
|
+
if (fragment.typeCondition.name.value === typeName) {
|
|
183
|
+
selections.push(...pruned.selections);
|
|
184
|
+
} else {
|
|
182
185
|
selections.push(
|
|
183
186
|
inlineFragment(fragment.typeCondition.name.value, [
|
|
184
187
|
...pruned.selections
|
|
@@ -188,13 +191,19 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
188
191
|
continue;
|
|
189
192
|
}
|
|
190
193
|
if (selection.kind === "InlineFragment") {
|
|
194
|
+
const condition = selection.typeCondition?.name.value ?? typeName;
|
|
191
195
|
const pruned = decisionSelectionSet(
|
|
192
196
|
selection.selectionSet,
|
|
193
|
-
|
|
197
|
+
condition,
|
|
194
198
|
path,
|
|
195
199
|
ctx
|
|
196
200
|
);
|
|
197
|
-
if (pruned)
|
|
201
|
+
if (!pruned) continue;
|
|
202
|
+
if (condition === typeName && !selection.directives?.length) {
|
|
203
|
+
selections.push(...pruned.selections);
|
|
204
|
+
} else {
|
|
205
|
+
selections.push({ ...selection, selectionSet: pruned });
|
|
206
|
+
}
|
|
198
207
|
continue;
|
|
199
208
|
}
|
|
200
209
|
if (!selection.selectionSet) continue;
|
|
@@ -268,20 +277,58 @@ function toDecisionDocument(document2, schema, groupPaths, options) {
|
|
|
268
277
|
const used = /* @__PURE__ */ new Set();
|
|
269
278
|
collectVariables(pruned, used);
|
|
270
279
|
collectVariables(operation.directives, used);
|
|
280
|
+
const shared = sharedContextFragment(schema);
|
|
271
281
|
return {
|
|
272
282
|
kind: "Document",
|
|
273
283
|
definitions: [
|
|
284
|
+
...shared ? [shared.definition] : [],
|
|
274
285
|
{
|
|
275
286
|
...operation,
|
|
276
287
|
name: operation.name && name(`${operation.name.value}Decision`),
|
|
277
288
|
variableDefinitions: (operation.variableDefinitions ?? []).filter(
|
|
278
289
|
(definition) => used.has(definition.variable.name.value)
|
|
279
290
|
),
|
|
280
|
-
selectionSet: pruned
|
|
291
|
+
selectionSet: shared ? shared.apply(pruned) : pruned
|
|
281
292
|
}
|
|
282
293
|
]
|
|
283
294
|
};
|
|
284
295
|
}
|
|
296
|
+
function sharedContextFragment(schema) {
|
|
297
|
+
const contextTypes = new Set(
|
|
298
|
+
Object.values(schema.types).flatMap(
|
|
299
|
+
(type) => type.hasContext ? [type.fields._context.type] : []
|
|
300
|
+
)
|
|
301
|
+
);
|
|
302
|
+
if (contextTypes.size !== 1) return null;
|
|
303
|
+
const [contextType] = contextTypes;
|
|
304
|
+
const fragmentName = "c";
|
|
305
|
+
const definition = {
|
|
306
|
+
kind: "FragmentDefinition",
|
|
307
|
+
name: name(fragmentName),
|
|
308
|
+
typeCondition: { kind: "NamedType", name: name(contextType) },
|
|
309
|
+
selectionSet: selectionSet(
|
|
310
|
+
["kind", "group_id", "variant_id"].map(
|
|
311
|
+
(field) => ({ kind: "Field", name: name(field) })
|
|
312
|
+
)
|
|
313
|
+
)
|
|
314
|
+
};
|
|
315
|
+
const spread = {
|
|
316
|
+
kind: "FragmentSpread",
|
|
317
|
+
name: name(fragmentName)
|
|
318
|
+
};
|
|
319
|
+
const apply = (set) => selectionSet(
|
|
320
|
+
set.selections.map((selection) => {
|
|
321
|
+
if (selection.kind === "Field" && selection.alias?.value === PREPR_CONTEXT_ALIAS) {
|
|
322
|
+
return { ...selection, selectionSet: selectionSet([spread]) };
|
|
323
|
+
}
|
|
324
|
+
return "selectionSet" in selection && selection.selectionSet ? {
|
|
325
|
+
...selection,
|
|
326
|
+
selectionSet: apply(selection.selectionSet)
|
|
327
|
+
} : selection;
|
|
328
|
+
})
|
|
329
|
+
);
|
|
330
|
+
return { definition, apply };
|
|
331
|
+
}
|
|
285
332
|
|
|
286
333
|
// src/core/variants/probe-document.ts
|
|
287
334
|
function probeSelectionSet(set, fragments) {
|
|
@@ -862,6 +909,7 @@ function createVaryProbe(run, options) {
|
|
|
862
909
|
}
|
|
863
910
|
|
|
864
911
|
// src/core/graphql/client.ts
|
|
912
|
+
var clientSchemas = /* @__PURE__ */ new WeakMap();
|
|
865
913
|
function isParseableUrl(url) {
|
|
866
914
|
try {
|
|
867
915
|
new URL(url);
|
|
@@ -898,7 +946,7 @@ function createPreprClient(options) {
|
|
|
898
946
|
));
|
|
899
947
|
const variantsDocuments = /* @__PURE__ */ new Map();
|
|
900
948
|
const decisionDocuments = /* @__PURE__ */ new Map();
|
|
901
|
-
|
|
949
|
+
const client = {
|
|
902
950
|
async query(document2, variables, queryOptions = {}) {
|
|
903
951
|
const { variants, ...rest } = queryOptions;
|
|
904
952
|
if (!variants) return run(document2, variables, rest);
|
|
@@ -910,10 +958,10 @@ function createPreprClient(options) {
|
|
|
910
958
|
return run(derived, variables, rest);
|
|
911
959
|
},
|
|
912
960
|
async decide(document2, variables, queryOptions = {}) {
|
|
913
|
-
const { from,
|
|
961
|
+
const { from, ...rest } = queryOptions;
|
|
914
962
|
const paths = from === void 0 ? void 0 : personalizationPaths(from);
|
|
915
963
|
if (paths && paths.size === 0) return /* @__PURE__ */ new Map();
|
|
916
|
-
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") :
|
|
964
|
+
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") : "*";
|
|
917
965
|
let byPaths = decisionDocuments.get(document2);
|
|
918
966
|
if (!byPaths) {
|
|
919
967
|
byPaths = /* @__PURE__ */ new Map();
|
|
@@ -921,9 +969,7 @@ function createPreprClient(options) {
|
|
|
921
969
|
}
|
|
922
970
|
let derived = byPaths.get(signature);
|
|
923
971
|
if (derived === void 0) {
|
|
924
|
-
derived = toDecisionDocument(document2, await loadSchema(), paths
|
|
925
|
-
topLevelOnly: !paths && topLevelOnly
|
|
926
|
-
});
|
|
972
|
+
derived = toDecisionDocument(document2, await loadSchema(), paths);
|
|
927
973
|
byPaths.set(signature, derived);
|
|
928
974
|
}
|
|
929
975
|
if (!derived) return /* @__PURE__ */ new Map();
|
|
@@ -937,6 +983,8 @@ function createPreprClient(options) {
|
|
|
937
983
|
(vary) => vary === null || SEGMENTS_VARY.test(vary)
|
|
938
984
|
)
|
|
939
985
|
};
|
|
986
|
+
clientSchemas.set(client, loadSchema);
|
|
987
|
+
return client;
|
|
940
988
|
}
|
|
941
989
|
|
|
942
990
|
// src/core/graphql/event-client.ts
|
package/dist/nuxt/graphql.d.cts
CHANGED
|
@@ -95,39 +95,6 @@ interface PreprVariantProps {
|
|
|
95
95
|
*/
|
|
96
96
|
declare function preprVariantProps(item: unknown): PreprVariantProps;
|
|
97
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
|
-
|
|
131
98
|
/**
|
|
132
99
|
* A GraphQL document accepted by `query`: a plain string, graphql-codegen's
|
|
133
100
|
* `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
|
|
@@ -221,11 +188,6 @@ interface PreprDecideOptions extends Omit<PreprQueryOptions, 'variants'> {
|
|
|
221
188
|
* none, e.g. on pages with only A/B tests or no personalization.
|
|
222
189
|
*/
|
|
223
190
|
from?: unknown;
|
|
224
|
-
/**
|
|
225
|
-
* @internal Ask only about the first personalizable list on each path,
|
|
226
|
-
* without `from`: what middleware needs for groups at the top of a stack.
|
|
227
|
-
*/
|
|
228
|
-
topLevelOnly?: boolean;
|
|
229
191
|
}
|
|
230
192
|
interface PreprQueryResult<TResult> {
|
|
231
193
|
data: TResult;
|
|
@@ -236,6 +198,39 @@ interface PreprQueryResult<TResult> {
|
|
|
236
198
|
personalized: boolean;
|
|
237
199
|
}
|
|
238
200
|
|
|
201
|
+
/**
|
|
202
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
203
|
+
* along; its shape is not part of the public API.
|
|
204
|
+
*/
|
|
205
|
+
type PreprSchema = PreprSchemaInfo;
|
|
206
|
+
/**
|
|
207
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
208
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
209
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
210
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
211
|
+
*
|
|
212
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
213
|
+
*/
|
|
214
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
215
|
+
/**
|
|
216
|
+
* The per-visitor decision query for the same query: send it with the
|
|
217
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
218
|
+
* `decisionsFrom`.
|
|
219
|
+
*
|
|
220
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
221
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
222
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
223
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
224
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
225
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
226
|
+
*
|
|
227
|
+
* Null when there is nothing to decide: send no request then.
|
|
228
|
+
*/
|
|
229
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
230
|
+
from?: unknown;
|
|
231
|
+
topLevelOnly?: boolean;
|
|
232
|
+
}): string | null;
|
|
233
|
+
|
|
239
234
|
/**
|
|
240
235
|
* Query options for frameworks without an implicit request scope.
|
|
241
236
|
* `personalize: true` requires the request `event`; the compiler enforces it.
|
package/dist/nuxt/graphql.d.ts
CHANGED
|
@@ -95,39 +95,6 @@ interface PreprVariantProps {
|
|
|
95
95
|
*/
|
|
96
96
|
declare function preprVariantProps(item: unknown): PreprVariantProps;
|
|
97
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
|
-
|
|
131
98
|
/**
|
|
132
99
|
* A GraphQL document accepted by `query`: a plain string, graphql-codegen's
|
|
133
100
|
* `TypedDocumentString` (`documentMode: 'string'`), or any `DocumentNode`,
|
|
@@ -221,11 +188,6 @@ interface PreprDecideOptions extends Omit<PreprQueryOptions, 'variants'> {
|
|
|
221
188
|
* none, e.g. on pages with only A/B tests or no personalization.
|
|
222
189
|
*/
|
|
223
190
|
from?: unknown;
|
|
224
|
-
/**
|
|
225
|
-
* @internal Ask only about the first personalizable list on each path,
|
|
226
|
-
* without `from`: what middleware needs for groups at the top of a stack.
|
|
227
|
-
*/
|
|
228
|
-
topLevelOnly?: boolean;
|
|
229
191
|
}
|
|
230
192
|
interface PreprQueryResult<TResult> {
|
|
231
193
|
data: TResult;
|
|
@@ -236,6 +198,39 @@ interface PreprQueryResult<TResult> {
|
|
|
236
198
|
personalized: boolean;
|
|
237
199
|
}
|
|
238
200
|
|
|
201
|
+
/**
|
|
202
|
+
* The schema facts the query rewrites need, from `loadPreprSchema`. Pass it
|
|
203
|
+
* along; its shape is not part of the public API.
|
|
204
|
+
*/
|
|
205
|
+
type PreprSchema = PreprSchemaInfo;
|
|
206
|
+
/**
|
|
207
|
+
* Your query, asking for every personalization and A/B variant: what
|
|
208
|
+
* `query(..., { variants: true })` sends, as a string for your own GraphQL
|
|
209
|
+
* client. The result is the same for every visitor, so cache it like any
|
|
210
|
+
* other content query, and render it with `resolveVariants` or `PreprStack`.
|
|
211
|
+
*
|
|
212
|
+
* A query without personalizable fields comes back unchanged (minified).
|
|
213
|
+
*/
|
|
214
|
+
declare function toVariantsQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema): string;
|
|
215
|
+
/**
|
|
216
|
+
* The per-visitor decision query for the same query: send it with the
|
|
217
|
+
* visitor's Prepr headers, never cached, and pass the response's `data` to
|
|
218
|
+
* `decisionsFrom`.
|
|
219
|
+
*
|
|
220
|
+
* Pass the variants result as `from` whenever you have it: the query then
|
|
221
|
+
* asks only about the lists that hold segment groups on this page, which is
|
|
222
|
+
* a few hundred bytes instead of the whole page and markedly faster for a
|
|
223
|
+
* visitor Prepr has not seen before. Without `from` it asks about every
|
|
224
|
+
* personalizable list. `topLevelOnly` stops at the first personalizable list
|
|
225
|
+
* on each path, for middleware that decides only the top of a stack.
|
|
226
|
+
*
|
|
227
|
+
* Null when there is nothing to decide: send no request then.
|
|
228
|
+
*/
|
|
229
|
+
declare function toDecisionQuery(document: PreprDocument<unknown, unknown> | string, schema: PreprSchema, options?: {
|
|
230
|
+
from?: unknown;
|
|
231
|
+
topLevelOnly?: boolean;
|
|
232
|
+
}): string | null;
|
|
233
|
+
|
|
239
234
|
/**
|
|
240
235
|
* Query options for frameworks without an implicit request scope.
|
|
241
236
|
* `personalize: true` requires the request `event`; the compiler enforces it.
|
package/dist/nuxt/graphql.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getPreprHeadersFromHeaders,
|
|
5
5
|
isPersonalizedResponse,
|
|
6
6
|
validatePreprToken
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JL33ENCM.js";
|
|
8
8
|
|
|
9
9
|
// src/core/variants/constants.ts
|
|
10
10
|
var PREPR_CONTEXT_ALIAS = "_preprContext";
|
|
@@ -93,7 +93,10 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
93
93
|
path,
|
|
94
94
|
ctx
|
|
95
95
|
);
|
|
96
|
-
if (pruned)
|
|
96
|
+
if (!pruned) continue;
|
|
97
|
+
if (fragment.typeCondition.name.value === typeName) {
|
|
98
|
+
selections.push(...pruned.selections);
|
|
99
|
+
} else {
|
|
97
100
|
selections.push(
|
|
98
101
|
inlineFragment(fragment.typeCondition.name.value, [
|
|
99
102
|
...pruned.selections
|
|
@@ -103,13 +106,19 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
103
106
|
continue;
|
|
104
107
|
}
|
|
105
108
|
if (selection.kind === "InlineFragment") {
|
|
109
|
+
const condition = selection.typeCondition?.name.value ?? typeName;
|
|
106
110
|
const pruned = decisionSelectionSet(
|
|
107
111
|
selection.selectionSet,
|
|
108
|
-
|
|
112
|
+
condition,
|
|
109
113
|
path,
|
|
110
114
|
ctx
|
|
111
115
|
);
|
|
112
|
-
if (pruned)
|
|
116
|
+
if (!pruned) continue;
|
|
117
|
+
if (condition === typeName && !selection.directives?.length) {
|
|
118
|
+
selections.push(...pruned.selections);
|
|
119
|
+
} else {
|
|
120
|
+
selections.push({ ...selection, selectionSet: pruned });
|
|
121
|
+
}
|
|
113
122
|
continue;
|
|
114
123
|
}
|
|
115
124
|
if (!selection.selectionSet) continue;
|
|
@@ -183,20 +192,58 @@ function toDecisionDocument(document2, schema, groupPaths, options) {
|
|
|
183
192
|
const used = /* @__PURE__ */ new Set();
|
|
184
193
|
collectVariables(pruned, used);
|
|
185
194
|
collectVariables(operation.directives, used);
|
|
195
|
+
const shared = sharedContextFragment(schema);
|
|
186
196
|
return {
|
|
187
197
|
kind: "Document",
|
|
188
198
|
definitions: [
|
|
199
|
+
...shared ? [shared.definition] : [],
|
|
189
200
|
{
|
|
190
201
|
...operation,
|
|
191
202
|
name: operation.name && name(`${operation.name.value}Decision`),
|
|
192
203
|
variableDefinitions: (operation.variableDefinitions ?? []).filter(
|
|
193
204
|
(definition) => used.has(definition.variable.name.value)
|
|
194
205
|
),
|
|
195
|
-
selectionSet: pruned
|
|
206
|
+
selectionSet: shared ? shared.apply(pruned) : pruned
|
|
196
207
|
}
|
|
197
208
|
]
|
|
198
209
|
};
|
|
199
210
|
}
|
|
211
|
+
function sharedContextFragment(schema) {
|
|
212
|
+
const contextTypes = new Set(
|
|
213
|
+
Object.values(schema.types).flatMap(
|
|
214
|
+
(type) => type.hasContext ? [type.fields._context.type] : []
|
|
215
|
+
)
|
|
216
|
+
);
|
|
217
|
+
if (contextTypes.size !== 1) return null;
|
|
218
|
+
const [contextType] = contextTypes;
|
|
219
|
+
const fragmentName = "c";
|
|
220
|
+
const definition = {
|
|
221
|
+
kind: "FragmentDefinition",
|
|
222
|
+
name: name(fragmentName),
|
|
223
|
+
typeCondition: { kind: "NamedType", name: name(contextType) },
|
|
224
|
+
selectionSet: selectionSet(
|
|
225
|
+
["kind", "group_id", "variant_id"].map(
|
|
226
|
+
(field) => ({ kind: "Field", name: name(field) })
|
|
227
|
+
)
|
|
228
|
+
)
|
|
229
|
+
};
|
|
230
|
+
const spread = {
|
|
231
|
+
kind: "FragmentSpread",
|
|
232
|
+
name: name(fragmentName)
|
|
233
|
+
};
|
|
234
|
+
const apply = (set) => selectionSet(
|
|
235
|
+
set.selections.map((selection) => {
|
|
236
|
+
if (selection.kind === "Field" && selection.alias?.value === PREPR_CONTEXT_ALIAS) {
|
|
237
|
+
return { ...selection, selectionSet: selectionSet([spread]) };
|
|
238
|
+
}
|
|
239
|
+
return "selectionSet" in selection && selection.selectionSet ? {
|
|
240
|
+
...selection,
|
|
241
|
+
selectionSet: apply(selection.selectionSet)
|
|
242
|
+
} : selection;
|
|
243
|
+
})
|
|
244
|
+
);
|
|
245
|
+
return { definition, apply };
|
|
246
|
+
}
|
|
200
247
|
|
|
201
248
|
// src/core/variants/probe-document.ts
|
|
202
249
|
function probeSelectionSet(set, fragments) {
|
|
@@ -770,6 +817,7 @@ function createVaryProbe(run, options) {
|
|
|
770
817
|
}
|
|
771
818
|
|
|
772
819
|
// src/core/graphql/client.ts
|
|
820
|
+
var clientSchemas = /* @__PURE__ */ new WeakMap();
|
|
773
821
|
function isParseableUrl(url) {
|
|
774
822
|
try {
|
|
775
823
|
new URL(url);
|
|
@@ -806,7 +854,7 @@ function createPreprClient(options) {
|
|
|
806
854
|
));
|
|
807
855
|
const variantsDocuments = /* @__PURE__ */ new Map();
|
|
808
856
|
const decisionDocuments = /* @__PURE__ */ new Map();
|
|
809
|
-
|
|
857
|
+
const client = {
|
|
810
858
|
async query(document2, variables, queryOptions = {}) {
|
|
811
859
|
const { variants, ...rest } = queryOptions;
|
|
812
860
|
if (!variants) return run(document2, variables, rest);
|
|
@@ -818,10 +866,10 @@ function createPreprClient(options) {
|
|
|
818
866
|
return run(derived, variables, rest);
|
|
819
867
|
},
|
|
820
868
|
async decide(document2, variables, queryOptions = {}) {
|
|
821
|
-
const { from,
|
|
869
|
+
const { from, ...rest } = queryOptions;
|
|
822
870
|
const paths = from === void 0 ? void 0 : personalizationPaths(from);
|
|
823
871
|
if (paths && paths.size === 0) return /* @__PURE__ */ new Map();
|
|
824
|
-
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") :
|
|
872
|
+
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") : "*";
|
|
825
873
|
let byPaths = decisionDocuments.get(document2);
|
|
826
874
|
if (!byPaths) {
|
|
827
875
|
byPaths = /* @__PURE__ */ new Map();
|
|
@@ -829,9 +877,7 @@ function createPreprClient(options) {
|
|
|
829
877
|
}
|
|
830
878
|
let derived = byPaths.get(signature);
|
|
831
879
|
if (derived === void 0) {
|
|
832
|
-
derived = toDecisionDocument(document2, await loadSchema(), paths
|
|
833
|
-
topLevelOnly: !paths && topLevelOnly
|
|
834
|
-
});
|
|
880
|
+
derived = toDecisionDocument(document2, await loadSchema(), paths);
|
|
835
881
|
byPaths.set(signature, derived);
|
|
836
882
|
}
|
|
837
883
|
if (!derived) return /* @__PURE__ */ new Map();
|
|
@@ -845,6 +891,8 @@ function createPreprClient(options) {
|
|
|
845
891
|
(vary) => vary === null || SEGMENTS_VARY.test(vary)
|
|
846
892
|
)
|
|
847
893
|
};
|
|
894
|
+
clientSchemas.set(client, loadSchema);
|
|
895
|
+
return client;
|
|
848
896
|
}
|
|
849
897
|
|
|
850
898
|
// src/core/graphql/event-client.ts
|
package/dist/nuxt/index.cjs
CHANGED
package/dist/nuxt/index.js
CHANGED
|
@@ -2313,7 +2313,7 @@ function isReactHydrated(text) {
|
|
|
2313
2313
|
}
|
|
2314
2314
|
|
|
2315
2315
|
// src/version.ts
|
|
2316
|
-
var VERSION = "0.6.0-alpha.
|
|
2316
|
+
var VERSION = "0.6.0-alpha.7";
|
|
2317
2317
|
|
|
2318
2318
|
// src/core/pixel.ts
|
|
2319
2319
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
package/dist/react/components.js
CHANGED
|
@@ -2289,7 +2289,7 @@ function isReactHydrated(text) {
|
|
|
2289
2289
|
}
|
|
2290
2290
|
|
|
2291
2291
|
// src/version.ts
|
|
2292
|
-
var VERSION = "0.6.0-alpha.
|
|
2292
|
+
var VERSION = "0.6.0-alpha.7";
|
|
2293
2293
|
|
|
2294
2294
|
// src/core/pixel.ts
|
|
2295
2295
|
var PIXEL_SCRIPT_URL = "https://cdn.tracking.prepr.io/js/prepr.min.js";
|
|
@@ -178,7 +178,10 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
178
178
|
path,
|
|
179
179
|
ctx
|
|
180
180
|
);
|
|
181
|
-
if (pruned)
|
|
181
|
+
if (!pruned) continue;
|
|
182
|
+
if (fragment.typeCondition.name.value === typeName) {
|
|
183
|
+
selections.push(...pruned.selections);
|
|
184
|
+
} else {
|
|
182
185
|
selections.push(
|
|
183
186
|
inlineFragment(fragment.typeCondition.name.value, [
|
|
184
187
|
...pruned.selections
|
|
@@ -188,13 +191,19 @@ function decisionSelectionSet(set, typeName, path, ctx) {
|
|
|
188
191
|
continue;
|
|
189
192
|
}
|
|
190
193
|
if (selection.kind === "InlineFragment") {
|
|
194
|
+
const condition = selection.typeCondition?.name.value ?? typeName;
|
|
191
195
|
const pruned = decisionSelectionSet(
|
|
192
196
|
selection.selectionSet,
|
|
193
|
-
|
|
197
|
+
condition,
|
|
194
198
|
path,
|
|
195
199
|
ctx
|
|
196
200
|
);
|
|
197
|
-
if (pruned)
|
|
201
|
+
if (!pruned) continue;
|
|
202
|
+
if (condition === typeName && !selection.directives?.length) {
|
|
203
|
+
selections.push(...pruned.selections);
|
|
204
|
+
} else {
|
|
205
|
+
selections.push({ ...selection, selectionSet: pruned });
|
|
206
|
+
}
|
|
198
207
|
continue;
|
|
199
208
|
}
|
|
200
209
|
if (!selection.selectionSet) continue;
|
|
@@ -268,20 +277,58 @@ function toDecisionDocument(document2, schema, groupPaths, options) {
|
|
|
268
277
|
const used = /* @__PURE__ */ new Set();
|
|
269
278
|
collectVariables(pruned, used);
|
|
270
279
|
collectVariables(operation.directives, used);
|
|
280
|
+
const shared = sharedContextFragment(schema);
|
|
271
281
|
return {
|
|
272
282
|
kind: "Document",
|
|
273
283
|
definitions: [
|
|
284
|
+
...shared ? [shared.definition] : [],
|
|
274
285
|
{
|
|
275
286
|
...operation,
|
|
276
287
|
name: operation.name && name(`${operation.name.value}Decision`),
|
|
277
288
|
variableDefinitions: (operation.variableDefinitions ?? []).filter(
|
|
278
289
|
(definition) => used.has(definition.variable.name.value)
|
|
279
290
|
),
|
|
280
|
-
selectionSet: pruned
|
|
291
|
+
selectionSet: shared ? shared.apply(pruned) : pruned
|
|
281
292
|
}
|
|
282
293
|
]
|
|
283
294
|
};
|
|
284
295
|
}
|
|
296
|
+
function sharedContextFragment(schema) {
|
|
297
|
+
const contextTypes = new Set(
|
|
298
|
+
Object.values(schema.types).flatMap(
|
|
299
|
+
(type) => type.hasContext ? [type.fields._context.type] : []
|
|
300
|
+
)
|
|
301
|
+
);
|
|
302
|
+
if (contextTypes.size !== 1) return null;
|
|
303
|
+
const [contextType] = contextTypes;
|
|
304
|
+
const fragmentName = "c";
|
|
305
|
+
const definition = {
|
|
306
|
+
kind: "FragmentDefinition",
|
|
307
|
+
name: name(fragmentName),
|
|
308
|
+
typeCondition: { kind: "NamedType", name: name(contextType) },
|
|
309
|
+
selectionSet: selectionSet(
|
|
310
|
+
["kind", "group_id", "variant_id"].map(
|
|
311
|
+
(field) => ({ kind: "Field", name: name(field) })
|
|
312
|
+
)
|
|
313
|
+
)
|
|
314
|
+
};
|
|
315
|
+
const spread = {
|
|
316
|
+
kind: "FragmentSpread",
|
|
317
|
+
name: name(fragmentName)
|
|
318
|
+
};
|
|
319
|
+
const apply = (set) => selectionSet(
|
|
320
|
+
set.selections.map((selection) => {
|
|
321
|
+
if (selection.kind === "Field" && selection.alias?.value === PREPR_CONTEXT_ALIAS) {
|
|
322
|
+
return { ...selection, selectionSet: selectionSet([spread]) };
|
|
323
|
+
}
|
|
324
|
+
return "selectionSet" in selection && selection.selectionSet ? {
|
|
325
|
+
...selection,
|
|
326
|
+
selectionSet: apply(selection.selectionSet)
|
|
327
|
+
} : selection;
|
|
328
|
+
})
|
|
329
|
+
);
|
|
330
|
+
return { definition, apply };
|
|
331
|
+
}
|
|
285
332
|
|
|
286
333
|
// src/core/variants/probe-document.ts
|
|
287
334
|
function probeSelectionSet(set, fragments) {
|
|
@@ -862,6 +909,7 @@ function createVaryProbe(run, options) {
|
|
|
862
909
|
}
|
|
863
910
|
|
|
864
911
|
// src/core/graphql/client.ts
|
|
912
|
+
var clientSchemas = /* @__PURE__ */ new WeakMap();
|
|
865
913
|
function isParseableUrl(url) {
|
|
866
914
|
try {
|
|
867
915
|
new URL(url);
|
|
@@ -898,7 +946,7 @@ function createPreprClient(options) {
|
|
|
898
946
|
));
|
|
899
947
|
const variantsDocuments = /* @__PURE__ */ new Map();
|
|
900
948
|
const decisionDocuments = /* @__PURE__ */ new Map();
|
|
901
|
-
|
|
949
|
+
const client = {
|
|
902
950
|
async query(document2, variables, queryOptions = {}) {
|
|
903
951
|
const { variants, ...rest } = queryOptions;
|
|
904
952
|
if (!variants) return run(document2, variables, rest);
|
|
@@ -910,10 +958,10 @@ function createPreprClient(options) {
|
|
|
910
958
|
return run(derived, variables, rest);
|
|
911
959
|
},
|
|
912
960
|
async decide(document2, variables, queryOptions = {}) {
|
|
913
|
-
const { from,
|
|
961
|
+
const { from, ...rest } = queryOptions;
|
|
914
962
|
const paths = from === void 0 ? void 0 : personalizationPaths(from);
|
|
915
963
|
if (paths && paths.size === 0) return /* @__PURE__ */ new Map();
|
|
916
|
-
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") :
|
|
964
|
+
const signature = paths ? [...paths].map(([path, types]) => `${path}:${[...types].sort().join(",")}`).sort().join("|") : "*";
|
|
917
965
|
let byPaths = decisionDocuments.get(document2);
|
|
918
966
|
if (!byPaths) {
|
|
919
967
|
byPaths = /* @__PURE__ */ new Map();
|
|
@@ -921,9 +969,7 @@ function createPreprClient(options) {
|
|
|
921
969
|
}
|
|
922
970
|
let derived = byPaths.get(signature);
|
|
923
971
|
if (derived === void 0) {
|
|
924
|
-
derived = toDecisionDocument(document2, await loadSchema(), paths
|
|
925
|
-
topLevelOnly: !paths && topLevelOnly
|
|
926
|
-
});
|
|
972
|
+
derived = toDecisionDocument(document2, await loadSchema(), paths);
|
|
927
973
|
byPaths.set(signature, derived);
|
|
928
974
|
}
|
|
929
975
|
if (!derived) return /* @__PURE__ */ new Map();
|
|
@@ -937,6 +983,8 @@ function createPreprClient(options) {
|
|
|
937
983
|
(vary) => vary === null || SEGMENTS_VARY.test(vary)
|
|
938
984
|
)
|
|
939
985
|
};
|
|
986
|
+
clientSchemas.set(client, loadSchema);
|
|
987
|
+
return client;
|
|
940
988
|
}
|
|
941
989
|
|
|
942
990
|
// src/core/graphql/event-client.ts
|