fontdue-js 2.22.0 → 2.22.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 (35) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/components/ConfigContext.d.ts +3 -0
  3. package/dist/components/ConfigContext.js +2 -1
  4. package/dist/components/FontdueProvider/FontdueProviderClientComponent.js +2 -0
  5. package/dist/components/elements/StoreModalUnifiedCheckout.js +7 -3
  6. package/dist/corsError.d.ts +1 -0
  7. package/dist/corsError.js +16 -9
  8. package/dist/global-shim.d.ts +1 -0
  9. package/dist/global-shim.js +8 -0
  10. package/dist/relay/environment.js +51 -42
  11. package/package.json +1 -1
  12. package/dist-bundle/FontdueProvider.js +0 -6
  13. package/dist-bundle/FontdueProvider.js.map +0 -1
  14. package/dist-bundle/TypeTester.js +0 -7
  15. package/dist-bundle/TypeTester.js.map +0 -1
  16. package/dist-bundle/TypeTester.preload.js +0 -75
  17. package/dist-bundle/TypeTester.preload.js.map +0 -1
  18. package/dist-bundle/chunks/ComponentsContext-CmkN9J4X.js +0 -20843
  19. package/dist-bundle/chunks/ComponentsContext-CmkN9J4X.js.map +0 -1
  20. package/dist-bundle/chunks/CorsErrorModal-C1g_-3Re.js +0 -95
  21. package/dist-bundle/chunks/CorsErrorModal-C1g_-3Re.js.map +0 -1
  22. package/dist-bundle/chunks/TypeTesterStandalone-BMWuv8Ca.js +0 -27486
  23. package/dist-bundle/chunks/TypeTesterStandalone-BMWuv8Ca.js.map +0 -1
  24. package/dist-bundle/chunks/consent-DMvR5rEh.js +0 -84
  25. package/dist-bundle/chunks/consent-DMvR5rEh.js.map +0 -1
  26. package/dist-bundle/chunks/index-BNSbxp7B.js +0 -78
  27. package/dist-bundle/chunks/index-BNSbxp7B.js.map +0 -1
  28. package/dist-bundle/chunks/index-C4ak9qTL.js +0 -423
  29. package/dist-bundle/chunks/index-C4ak9qTL.js.map +0 -1
  30. package/dist-bundle/chunks/index-DsvF5W13.js +0 -159
  31. package/dist-bundle/chunks/index-DsvF5W13.js.map +0 -1
  32. package/dist-bundle/chunks/index-o29NNufd.js +0 -131
  33. package/dist-bundle/chunks/index-o29NNufd.js.map +0 -1
  34. package/dist-bundle/index.js +0 -23
  35. package/dist-bundle/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 2.22.2
2
+
3
+ - Fixed country order variables (e.g. *Fair Price Adjustment*) not updating when the licensee country changed at checkout. The unified checkout now clears the option id when syncing the licensee country to a country-type variable, so the server can re-evaluate the multiplier against the new country.
4
+
5
+ ## 2.22.1
6
+
7
+ - Added `corsErrorModal` config option (default `true`). Set to `false` on `<FontdueProvider>` or the script-tag config to suppress the CORS error modal entirely while keeping console warnings and auto-reload polling.
8
+ - GraphQL requests now retry up to 2 times (with a 1s delay) before falling through to CORS error detection. Transient network failures no longer trigger a false-positive CORS modal.
9
+
1
10
  ## 2.22.0
2
11
 
3
12
  - **`features="*"` wildcard on `<TypeTester>` and `<TypeTesters>`** to expose every OpenType feature each font supports without curating a list. Custom *stylistic set* names defined by the foundry are picked up automatically. Works on both the standalone `<fontdue-type-tester>` HTML element and the React `<TypeTester>` / `<TypeTesters>` components.
@@ -29,6 +29,7 @@ export interface Config {
29
29
  typeTester?: TypeTesterConfig;
30
30
  stripe?: StripeConfig;
31
31
  tracking?: TrackingConfig;
32
+ corsErrorModal?: boolean;
32
33
  }
33
34
  export declare const makeConfig: (config?: Config) => {
34
35
  typeTester: {
@@ -99,6 +100,7 @@ export declare const makeConfig: (config?: Config) => {
99
100
  consentMessage: string | undefined;
100
101
  segment: SegmentConfig | undefined;
101
102
  };
103
+ corsErrorModal: boolean;
102
104
  };
103
105
  declare const _default: React.Context<{
104
106
  typeTester: {
@@ -169,5 +171,6 @@ declare const _default: React.Context<{
169
171
  consentMessage: string | undefined;
170
172
  segment: SegmentConfig | undefined;
171
173
  };
174
+ corsErrorModal: boolean;
172
175
  }>;
173
176
  export default _default;
@@ -79,7 +79,8 @@ const makeConfig = config => {
79
79
  consentRequired: (config === null || config === void 0 ? void 0 : (_config$tracking2 = config.tracking) === null || _config$tracking2 === void 0 ? void 0 : _config$tracking2.consentRequired) ?? false,
80
80
  consentMessage: config === null || config === void 0 ? void 0 : (_config$tracking3 = config.tracking) === null || _config$tracking3 === void 0 ? void 0 : _config$tracking3.consentMessage,
81
81
  segment: config === null || config === void 0 ? void 0 : (_config$tracking4 = config.tracking) === null || _config$tracking4 === void 0 ? void 0 : _config$tracking4.segment
82
- }
82
+ },
83
+ corsErrorModal: (config === null || config === void 0 ? void 0 : config.corsErrorModal) ?? true
83
84
  };
84
85
  };
85
86
  exports.makeConfig = makeConfig;
@@ -15,6 +15,7 @@ var _reducer = require("../../reducer");
15
15
  var _ComponentsContext = _interopRequireDefault(require("../ComponentsContext"));
16
16
  var _UrlContext = _interopRequireDefault(require("../UrlContext"));
17
17
  var _retryImport = _interopRequireDefault(require("../../retryImport"));
18
+ var _corsError = require("../../corsError");
18
19
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
20
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
20
21
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -35,6 +36,7 @@ function FontdueProviderClientComponent(_ref) {
35
36
  stripeIntegration
36
37
  });
37
38
  const configValue = (0, _ConfigContext.makeConfig)(config);
39
+ (0, _corsError.setCorsModalEnabled)(configValue.corsErrorModal);
38
40
  const storeRef = (0, _react.useRef)(store ?? (0, _reducer.createDefaultStore)(config));
39
41
  return /*#__PURE__*/_react.default.createElement(_reactRelay.RelayEnvironmentProvider, {
40
42
  environment: environment
@@ -354,13 +354,17 @@ function StoreModalUnifiedCheckout(_ref2) {
354
354
  // Only update if the country has actually changed
355
355
  if (countryVariableSelection.countryCode === licenseeIdentity.country) return;
356
356
 
357
- // Build updated selections array
357
+ // Build updated selections array. For country-type variables, send
358
+ // countryCode and clear orderVariableOptionId — the server derives the
359
+ // option from the country. Carrying forward the previous country's option
360
+ // id conflicts with the new country's option.
358
361
  const updatedSelections = order.orderVariableSelections.map(selection => {
359
362
  var _selection$orderVaria;
363
+ const isCountryVariable = selection.orderVariable.variableType === 'country';
360
364
  return {
361
365
  orderVariableId: selection.orderVariable.id,
362
- orderVariableOptionId: ((_selection$orderVaria = selection.orderVariableOption) === null || _selection$orderVaria === void 0 ? void 0 : _selection$orderVaria.id) ?? null,
363
- countryCode: selection.orderVariable.variableType === 'country' ? licenseeIdentity.country : selection.countryCode ?? null
366
+ orderVariableOptionId: isCountryVariable ? null : ((_selection$orderVaria = selection.orderVariableOption) === null || _selection$orderVaria === void 0 ? void 0 : _selection$orderVaria.id) ?? null,
367
+ countryCode: isCountryVariable ? licenseeIdentity.country : selection.countryCode ?? null
364
368
  };
365
369
  });
366
370
 
@@ -1,3 +1,4 @@
1
+ export declare function setCorsModalEnabled(enabled: boolean): void;
1
2
  export interface CorsError {
2
3
  origin: string;
3
4
  fontdueUrl: string;
package/dist/corsError.js CHANGED
@@ -4,12 +4,17 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.handlePossibleCorsError = handlePossibleCorsError;
7
+ exports.setCorsModalEnabled = setCorsModalEnabled;
7
8
  var _retryImport = _interopRequireDefault(require("./retryImport"));
8
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
9
10
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
10
11
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
11
12
  let detected = false;
12
13
  let navigating = false;
14
+ let modalEnabled = true;
15
+ function setCorsModalEnabled(enabled) {
16
+ modalEnabled = enabled;
17
+ }
13
18
  if (typeof window !== 'undefined') {
14
19
  window.addEventListener('beforeunload', () => {
15
20
  navigating = true;
@@ -52,15 +57,17 @@ async function isCorsBlocked(fetchUrl) {
52
57
  }
53
58
  function showCorsError(origin, fetchUrl) {
54
59
  console.error(`[Fontdue] Cross-origin request to ${fetchUrl} was blocked.\n\n` + `Your website (${origin}) is not listed as an allowed origin ` + `in your Fontdue CORS settings.\n\n` + `To fix this:\n` + `1. Log in to your Fontdue dashboard\n` + `2. Go to Settings \u2192 Security\n` + `3. Add "${origin}" to the "Cross-origin API access" field\n` + `4. Save \u2014 this page will reload automatically`);
55
- (0, _retryImport.default)(() => Promise.resolve().then(() => _interopRequireWildcard(require('./components/CorsErrorModal')))).then(_ref => {
56
- let {
57
- renderCorsErrorModal
58
- } = _ref;
59
- renderCorsErrorModal(origin, fetchUrl);
60
- }).catch(() => {
61
- // Chunk failed to load — the console.error above already
62
- // told the developer what's wrong.
63
- });
60
+ if (modalEnabled) {
61
+ (0, _retryImport.default)(() => Promise.resolve().then(() => _interopRequireWildcard(require('./components/CorsErrorModal')))).then(_ref => {
62
+ let {
63
+ renderCorsErrorModal
64
+ } = _ref;
65
+ renderCorsErrorModal(origin, fetchUrl);
66
+ }).catch(() => {
67
+ // Chunk failed to load — the console.error above already
68
+ // told the developer what's wrong.
69
+ });
70
+ }
64
71
  startPolling(fetchUrl);
65
72
  }
66
73
  function handlePossibleCorsError(error, fetchUrl) {
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ // fbjs (transitive via draft-js) references Node's `global` at module init.
2
+ // Browsers don't define `global`, so hydration blows up with a ReferenceError.
3
+ // ESM evaluates imports in source order, so importing this first ensures the
4
+ // alias is in place before fbjs/setImmediate evaluates.
5
+ if (typeof globalThis.global === 'undefined') {
6
+ globalThis.global = globalThis;
7
+ }
8
+ export {};
@@ -23,52 +23,61 @@ const CACHE_TTL = 10 * 1000; // 10 seconds, to resolve preloaded results
23
23
  function createNetworkFetch(options) {
24
24
  return async function networkFetch(request, variables) {
25
25
  const url = (FONTDUE_URL && `${FONTDUE_URL}/graphql`) ?? ((options === null || options === void 0 ? void 0 : options.url) ?? '') + '/graphql';
26
- let resp;
27
- try {
28
- resp = await fetch(url + `?queryName=${request.name}`, {
29
- method: 'POST',
30
- credentials: 'include',
31
- headers: {
32
- Accept: 'application/json',
33
- 'Content-Type': 'application/json',
34
- 'fontdue-stripe-integration': STRIPE_INTEGRATION ?? ((options === null || options === void 0 ? void 0 : options.stripeIntegration) || 'dynamic'),
35
- 'fontdue-client-version': _package.version
36
- },
37
- body: JSON.stringify({
38
- query: request.text,
39
- variables
40
- }),
41
- // @ts-ignore
42
- next: {
43
- tags: ['graphql', `operation:${request.name}`]
26
+ for (let attempt = 0; attempt <= 2; attempt++) {
27
+ try {
28
+ const resp = await fetch(url + `?queryName=${request.name}`, {
29
+ method: 'POST',
30
+ credentials: 'include',
31
+ headers: {
32
+ Accept: 'application/json',
33
+ 'Content-Type': 'application/json',
34
+ 'fontdue-stripe-integration': STRIPE_INTEGRATION ?? ((options === null || options === void 0 ? void 0 : options.stripeIntegration) || 'dynamic'),
35
+ 'fontdue-client-version': _package.version
36
+ },
37
+ body: JSON.stringify({
38
+ query: request.text,
39
+ variables
40
+ }),
41
+ // @ts-ignore
42
+ next: {
43
+ tags: ['graphql', `operation:${request.name}`]
44
+ }
45
+ });
46
+ const json = await resp.json();
47
+
48
+ // GraphQL returns exceptions (for example, a missing required variable) in the "errors"
49
+ // property of the response. If any exceptions occurred when processing the request,
50
+ // throw an error to indicate to the developer what went wrong.
51
+ if (Array.isArray(json.errors)) {
52
+ var _json$errors, _error$extensions;
53
+ const error = (_json$errors = json.errors) === null || _json$errors === void 0 ? void 0 : _json$errors[0];
54
+ console.error('GraphQL Error:', {
55
+ message: error.message,
56
+ code: (_error$extensions = error.extensions) === null || _error$extensions === void 0 ? void 0 : _error$extensions.code,
57
+ path: error.path
58
+ });
59
+ }
60
+ return json;
61
+ } catch (error) {
62
+ // Retry on network errors (TypeError) before falling through to CORS detection
63
+ if (attempt < 2 && error instanceof TypeError) {
64
+ await new Promise(resolve => setTimeout(resolve, 1000));
65
+ continue;
44
66
  }
45
- });
46
- } catch (error) {
47
- if ((0, _corsError.handlePossibleCorsError)(error, url)) {
48
- return {
49
- data: undefined,
50
- errors: [{
51
- message: 'Cross-origin request blocked'
52
- }]
53
- };
67
+ if ((0, _corsError.handlePossibleCorsError)(error, url)) {
68
+ return {
69
+ data: undefined,
70
+ errors: [{
71
+ message: 'Cross-origin request blocked'
72
+ }]
73
+ };
74
+ }
75
+ throw error;
54
76
  }
55
- throw error;
56
77
  }
57
- const json = await resp.json();
58
78
 
59
- // GraphQL returns exceptions (for example, a missing required variable) in the "errors"
60
- // property of the response. If any exceptions occurred when processing the request,
61
- // throw an error to indicate to the developer what went wrong.
62
- if (Array.isArray(json.errors)) {
63
- var _json$errors, _error$extensions;
64
- const error = (_json$errors = json.errors) === null || _json$errors === void 0 ? void 0 : _json$errors[0];
65
- console.error('GraphQL Error:', {
66
- message: error.message,
67
- code: (_error$extensions = error.extensions) === null || _error$extensions === void 0 ? void 0 : _error$extensions.code,
68
- path: error.path
69
- });
70
- }
71
- return json;
79
+ // Unreachable final iteration either returns or throws
80
+ throw new Error('Unexpected: exhausted retries');
72
81
  };
73
82
  }
74
83
  const networkFetch = createNetworkFetch();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fontdue-js",
3
- "version": "2.22.0",
3
+ "version": "2.22.2",
4
4
  "scripts": {
5
5
  "build": "npm run relay && run-p build-js build-css build-ts",
6
6
  "build-js": "babel src --out-dir dist --extensions .ts,.tsx,.js,.jsx",
@@ -1,6 +0,0 @@
1
- 'use client';
2
- import './chunks/ComponentsContext-CmkN9J4X.js';
3
- import 'react';
4
- export { F as default } from './chunks/index-C4ak9qTL.js';
5
- import './index.js';
6
- //# sourceMappingURL=FontdueProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FontdueProvider.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -1,7 +0,0 @@
1
- 'use client';
2
- import './chunks/ComponentsContext-CmkN9J4X.js';
3
- export { T as TypeTesterStandalonePreloadedQueryRenderer, a as default } from './chunks/TypeTesterStandalone-BMWuv8Ca.js';
4
- import 'react';
5
- import './index.js';
6
- import 'react-dom';
7
- //# sourceMappingURL=TypeTester.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TypeTester.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -1,75 +0,0 @@
1
- import React__default from 'react';
2
- import { c as createNetworkFetch } from './chunks/ComponentsContext-CmkN9J4X.js';
3
- import { T as TypeTesterStandalonePreloadedQueryRenderer, n as node } from './chunks/TypeTesterStandalone-BMWuv8Ca.js';
4
- import { F as FontdueProvider } from './chunks/index-C4ak9qTL.js';
5
- import './index.js';
6
- import 'react-dom';
7
-
8
- /**
9
- * RELAY CACHE KEY NORMALIZATION
10
- *
11
- * This type transformation is required to fix a cache key inconsistency issue in Relay.
12
- *
13
- * THE PROBLEM:
14
- * Relay's `getOperationVariables()` function always includes ALL argumentDefinitions
15
- * from the GraphQL operation, even optional ones, setting them to their defaultValue
16
- * (typically null). This means when Relay generates cache keys, it creates entries like:
17
- *
18
- * Cache Key A: { collectionId: "123", tags: null, excludeTags: null, selectable: true }
19
- * Cache Key B: { collectionId: "123", selectable: true } // when optional vars omitted
20
- *
21
- * Even though these represent the same logical query, they produce different cache keys
22
- * because `JSON.stringify(stableCopy(variables))` serializes them differently.
23
- *
24
- * (This is possibly caused by NextJS RSC data serialization and hydration)
25
- *
26
- * THE ROOT CAUSE:
27
- * - GraphQL schema defines: `$tags: [String!], $excludeTags: [String!]` (optional)
28
- * - TypeScript generates: `tags?: ReadonlyArray<string> | null`
29
- * - Relay's argumentDefinitions include: `{ name: "tags", defaultValue: null }`
30
- * - getOperationVariables() always sets: `operationVariables[def.name] = def.defaultValue`
31
- *
32
- * THE SOLUTION:
33
- * RequireAllWithNull<T> transforms optional properties to required properties with
34
- * explicit null values, forcing callers to be consistent. This ensures server-side
35
- * preloaded queries and client-side cache lookups use identical variable structures.
36
- *
37
- * USAGE:
38
- * Instead of: { tags, excludeTags } // undefined values
39
- * Use: { tags: tags ?? null, excludeTags: excludeTags ?? null } // explicit nulls
40
- *
41
- * This eliminates cache misses caused by variable structure inconsistencies between
42
- * server-side rendering and client-side Relay operations.
43
- */
44
-
45
- // Call into raw network fetch to get serializable GraphQL query response
46
- // This response will be sent to the client to "warm" the QueryResponseCache
47
- // to avoid the client fetches.
48
- async function loadSerializableQuery(query, variables, options) {
49
- if (!('params' in query)) throw new Error('Params not found in query, is it a fragment instead of a query?');
50
- const fetcher = createNetworkFetch(options);
51
- const response = await fetcher(query.params, variables);
52
- return {
53
- params: query.params,
54
- variables,
55
- response
56
- };
57
- }
58
-
59
- async function loadTypeTesterQuery(variables, options) {
60
- return loadSerializableQuery(node, {
61
- familyName: variables.familyName,
62
- styleName: variables.styleName,
63
- selectable: variables.selectable ?? true
64
- }, options);
65
- }
66
- // Self-wraps with FontdueProvider so consumers don't need to. The provider
67
- // state is a module-level singleton under the hood, so multiple
68
- // TypeTesterPreloaded (or other *Preloaded) components on a page all share
69
- // one Relay env + Redux store + auxiliary UI.
70
- function TypeTesterPreloaded(props) {
71
- return /*#__PURE__*/React__default.createElement(FontdueProvider, null, /*#__PURE__*/React__default.createElement(TypeTesterStandalonePreloadedQueryRenderer, props));
72
- }
73
-
74
- export { TypeTesterPreloaded, loadTypeTesterQuery };
75
- //# sourceMappingURL=TypeTester.preload.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TypeTester.preload.js","sources":["../src/relay/loadSerializableQuery.ts","../src/components/TypeTester/TypeTesterStandalone.preload.tsx"],"sourcesContent":["import {\n GraphQLResponse,\n GraphQLTaggedNode,\n OperationType,\n RequestParameters,\n VariablesOf,\n} from 'relay-runtime';\nimport { createNetworkFetch } from './environment';\n\nexport interface SerializablePreloadedQuery<TQuery extends OperationType> {\n params: RequestParameters;\n variables: VariablesOf<TQuery>;\n response: GraphQLResponse;\n}\n\n/**\n * RELAY CACHE KEY NORMALIZATION\n *\n * This type transformation is required to fix a cache key inconsistency issue in Relay.\n *\n * THE PROBLEM:\n * Relay's `getOperationVariables()` function always includes ALL argumentDefinitions\n * from the GraphQL operation, even optional ones, setting them to their defaultValue\n * (typically null). This means when Relay generates cache keys, it creates entries like:\n *\n * Cache Key A: { collectionId: \"123\", tags: null, excludeTags: null, selectable: true }\n * Cache Key B: { collectionId: \"123\", selectable: true } // when optional vars omitted\n *\n * Even though these represent the same logical query, they produce different cache keys\n * because `JSON.stringify(stableCopy(variables))` serializes them differently.\n *\n * (This is possibly caused by NextJS RSC data serialization and hydration)\n *\n * THE ROOT CAUSE:\n * - GraphQL schema defines: `$tags: [String!], $excludeTags: [String!]` (optional)\n * - TypeScript generates: `tags?: ReadonlyArray<string> | null`\n * - Relay's argumentDefinitions include: `{ name: \"tags\", defaultValue: null }`\n * - getOperationVariables() always sets: `operationVariables[def.name] = def.defaultValue`\n *\n * THE SOLUTION:\n * RequireAllWithNull<T> transforms optional properties to required properties with\n * explicit null values, forcing callers to be consistent. This ensures server-side\n * preloaded queries and client-side cache lookups use identical variable structures.\n *\n * USAGE:\n * Instead of: { tags, excludeTags } // undefined values\n * Use: { tags: tags ?? null, excludeTags: excludeTags ?? null } // explicit nulls\n *\n * This eliminates cache misses caused by variable structure inconsistencies between\n * server-side rendering and client-side Relay operations.\n */\ntype RequireAllWithNull<T> = {\n [K in keyof T]-?: T[K] | null;\n};\n\nexport interface LoadSerializableQueryOptions {\n url?: string;\n stripeIntegration?: 'card-element' | 'dynamic';\n}\n\n// Call into raw network fetch to get serializable GraphQL query response\n// This response will be sent to the client to \"warm\" the QueryResponseCache\n// to avoid the client fetches.\nexport default async function loadSerializableQuery<TQuery extends OperationType>(\n query: GraphQLTaggedNode,\n variables: RequireAllWithNull<VariablesOf<TQuery>>,\n options?: LoadSerializableQueryOptions,\n): Promise<SerializablePreloadedQuery<TQuery>> {\n if (!('params' in query))\n throw new Error('Params not found in query, is it a fragment instead of a query?');\n const fetcher = createNetworkFetch(options);\n const response = await fetcher(query.params, variables);\n\n return {\n params: query.params,\n variables,\n response,\n };\n}\n","import React from 'react';\nimport loadSerializableQuery, {\n LoadSerializableQueryOptions,\n SerializablePreloadedQuery,\n} from '../../relay/loadSerializableQuery';\nimport TypeTesterStandaloneQueryNode, {\n TypeTesterStandaloneQuery,\n} from '../../__generated__/TypeTesterStandaloneQuery.graphql';\nimport FontdueProvider from '../FontdueProvider';\nimport { TypeTesterStandalonePreloadedQueryRenderer } from './TypeTesterStandalone';\n\nexport type TypeTesterPreloadedQuery =\n SerializablePreloadedQuery<TypeTesterStandaloneQuery>;\n\nexport interface LoadTypeTesterQueryVariables {\n familyName: string;\n styleName: string;\n selectable?: boolean;\n}\n\nexport async function loadTypeTesterQuery(\n variables: LoadTypeTesterQueryVariables,\n options?: LoadSerializableQueryOptions,\n): Promise<TypeTesterPreloadedQuery> {\n return loadSerializableQuery<TypeTesterStandaloneQuery>(\n TypeTesterStandaloneQueryNode,\n {\n familyName: variables.familyName,\n styleName: variables.styleName,\n selectable: variables.selectable ?? true,\n },\n options,\n );\n}\n\ntype RendererProps = React.ComponentProps<typeof TypeTesterStandalonePreloadedQueryRenderer>;\n\n// Self-wraps with FontdueProvider so consumers don't need to. The provider\n// state is a module-level singleton under the hood, so multiple\n// TypeTesterPreloaded (or other *Preloaded) components on a page all share\n// one Relay env + Redux store + auxiliary UI.\nexport function TypeTesterPreloaded(props: RendererProps) {\n return (\n <FontdueProvider>\n <TypeTesterStandalonePreloadedQueryRenderer {...props} />\n </FontdueProvider>\n );\n}\n"],"names":["loadSerializableQuery","query","variables","options","Error","fetcher","createNetworkFetch","response","params","loadTypeTesterQuery","TypeTesterStandaloneQueryNode","familyName","styleName","selectable","TypeTesterPreloaded","props","React","createElement","FontdueProvider","TypeTesterStandalonePreloadedQueryRenderer"],"mappings":";;;;;;;AAeA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACe,eAAeA,qBAAqBA,CACjDC,KAAwB,EACxBC,SAAkD,EAClDC,OAAsC,EACO;EAC7C,IAAI,EAAE,QAAQ,IAAIF,KAAK,CAAC,EACtB,MAAM,IAAIG,KAAK,CAAC,iEAAiE,CAAC;AACpF,EAAA,MAAMC,OAAO,GAAGC,kBAAkB,CAACH,OAAO,CAAC;EAC3C,MAAMI,QAAQ,GAAG,MAAMF,OAAO,CAACJ,KAAK,CAACO,MAAM,EAAEN,SAAS,CAAC;EAEvD,OAAO;IACLM,MAAM,EAAEP,KAAK,CAACO,MAAM;IACpBN,SAAS;AACTK,IAAAA;GACD;AACH;;AC1DO,eAAeE,mBAAmBA,CACvCP,SAAuC,EACvCC,OAAsC,EACH;EACnC,OAAOH,qBAAqB,CAC1BU,IAA6B,EAC7B;IACEC,UAAU,EAAET,SAAS,CAACS,UAAU;IAChCC,SAAS,EAAEV,SAAS,CAACU,SAAS;AAC9BC,IAAAA,UAAU,EAAEX,SAAS,CAACW,UAAU,IAAI;GACrC,EACDV,OACF,CAAC;AACH;AAIA;AACA;AACA;AACA;AACO,SAASW,mBAAmBA,CAACC,KAAoB,EAAE;AACxD,EAAA,oBACEC,cAAA,CAAAC,aAAA,CAACC,eAAe,EAAA,IAAA,eACdF,cAAA,CAAAC,aAAA,CAACE,0CAA0C,EAAKJ,KAAQ,CACzC,CAAC;AAEtB;;;;"}