fontdue-js 2.22.3 → 2.23.0
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/CHANGELOG.md +8 -0
- package/dist/__generated__/CartItemAdditionalLicenses_orderItem.graphql.d.ts +4 -1
- package/dist/__generated__/CartItemAdditionalLicenses_orderItem.graphql.js +34 -22
- package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderCompleteOrderMutation.graphql.js +13 -4
- package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderRemoveDiscountMutation.graphql.js +13 -4
- package/dist/__generated__/CartOrderUpdateMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartOrderUpdateMutation.graphql.js +13 -4
- package/dist/__generated__/CartQuery.graphql.d.ts +1 -1
- package/dist/__generated__/CartQuery.graphql.js +13 -4
- package/dist/__generated__/CartStateUpdateMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CartStateUpdateMutation.graphql.js +13 -4
- package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CheckoutUpdateCustomerMutation.graphql.js +13 -4
- package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.d.ts +1 -1
- package/dist/__generated__/CheckoutUpdateOrderMutation.graphql.js +13 -4
- package/dist/__generated__/FontdueProviderQuery.graphql.d.ts +19 -0
- package/dist/__generated__/FontdueProviderQuery.graphql.js +140 -0
- package/dist/__generated__/PrecartAddToCartMutation.graphql.d.ts +1 -1
- package/dist/__generated__/PrecartAddToCartMutation.graphql.js +34 -25
- package/dist/__generated__/PrecartQuery.graphql.d.ts +1 -1
- package/dist/__generated__/PrecartQuery.graphql.js +17 -7
- package/dist/__generated__/Precart_collection.graphql.d.ts +4 -1
- package/dist/__generated__/Precart_collection.graphql.js +13 -3
- package/dist/__generated__/Precart_license.graphql.d.ts +4 -1
- package/dist/__generated__/Precart_license.graphql.js +19 -9
- package/dist/__generated__/ServerConfigProvider_viewer.graphql.d.ts +23 -0
- package/dist/__generated__/ServerConfigProvider_viewer.graphql.js +57 -0
- package/dist/__generated__/StoreModalCartQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalCartQuery.graphql.js +13 -4
- package/dist/__generated__/StoreModalIndexQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalIndexQuery.graphql.js +5 -5
- package/dist/__generated__/StoreModalProductLicense_license.graphql.d.ts +4 -1
- package/dist/__generated__/StoreModalProductLicense_license.graphql.js +11 -2
- package/dist/__generated__/StoreModalProductQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalProductQuery.graphql.js +12 -3
- package/dist/__generated__/StoreModalProductRefetchQuery.graphql.d.ts +1 -1
- package/dist/__generated__/StoreModalProductRefetchQuery.graphql.js +42 -32
- package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.d.ts +1 -1
- package/dist/__generated__/TestFontsFormUpdateCustomerMutation.graphql.js +13 -4
- package/dist/__generated__/TestModeBanner_viewer.graphql.d.ts +19 -0
- package/dist/__generated__/TestModeBanner_viewer.graphql.js +36 -0
- package/dist/__generated__/ThemeConfig_viewer.graphql.d.ts +19 -0
- package/dist/__generated__/ThemeConfig_viewer.graphql.js +36 -0
- package/dist/__tests__/licenseExclusions.test.js +161 -0
- package/dist/components/BuyingOptions/index.d.ts +9 -0
- package/dist/components/Cart/CartItem/CartItemAdditionalLicenses.js +11 -5
- package/dist/components/CookieNotification/index.d.ts +13 -0
- package/dist/components/FontdueContextProvider/index.d.ts +17 -0
- package/dist/components/FontdueContextProvider/index.js +108 -0
- package/dist/components/FontdueContextProvider/index.server.d.ts +4 -0
- package/dist/components/FontdueContextProvider/index.server.js +7 -0
- package/dist/components/Precart/index.js +12 -7
- package/dist/components/StoreModal/StoreModalIndex.js +1 -1
- package/dist/components/StoreModalProductLicenseSelection/StoreModalProductLicense.js +10 -4
- package/dist/components/TypeTester/TypeTesterStandalone.preload.d.ts +3 -3
- package/dist/components/TypeTester/TypeTesterStandalone.preload.js +10 -9
- package/dist/config.d.ts +2 -1
- package/dist/config.js +17 -6
- package/dist/hooks/useResizeObserver.d.ts +11 -0
- package/dist/hooks/useResizeObserver.js +23 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/loadFontdueProviderQuery.d.ts +3 -0
- package/dist/loadFontdueProviderQuery.js +10 -0
- package/dist/reducer.d.ts +2 -0
- package/dist/reducer.js +3 -1
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +139 -0
- package/package.json +1 -1
- package/types/font-face-set.d.ts +11 -0
- package/.nvmrc +0 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Store } from 'redux';
|
|
3
|
+
import { Config } from '../ConfigContext.js';
|
|
4
|
+
import { FontdueAction, FontdueState } from '../../reducer.js';
|
|
5
|
+
import { Components } from '../ComponentsContext.js';
|
|
6
|
+
export declare function EnsureFontdueContext({ children }: {
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}): React.JSX.Element;
|
|
9
|
+
export interface FontdueContextProvider_props {
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
url?: string;
|
|
12
|
+
stripeIntegration?: 'card-element' | 'dynamic';
|
|
13
|
+
config?: Config;
|
|
14
|
+
components?: Components;
|
|
15
|
+
store?: Store<FontdueState, FontdueAction>;
|
|
16
|
+
}
|
|
17
|
+
export default function FontdueContextProvider({ children, url, stripeIntegration, config, components, store, }: FontdueContextProvider_props): React.JSX.Element;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { Suspense, createContext, useContext, useRef } from 'react';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import { RelayEnvironmentProvider } from 'react-relay';
|
|
6
|
+
import { useCurrentEnvironment } from '../../relay/environment.js';
|
|
7
|
+
import ConfigContext, { makeConfig } from '../ConfigContext.js';
|
|
8
|
+
import { createDefaultStore } from '../../reducer.js';
|
|
9
|
+
import ComponentsContext from '../ComponentsContext.js';
|
|
10
|
+
import UrlContext from '../UrlContext.js';
|
|
11
|
+
import { setCorsModalEnabled } from '../../corsError.js';
|
|
12
|
+
|
|
13
|
+
// Marker context used by self-wrapping components to detect a parent
|
|
14
|
+
// FontdueContextProvider/FontdueProvider. When the marker is `true`, a
|
|
15
|
+
// self-wrapping component skips its inner FontdueContextProvider so the
|
|
16
|
+
// outer config/url/store/relay-env flow through. Internal — do not export
|
|
17
|
+
// from the package.
|
|
18
|
+
const FontdueContextMarker = /*#__PURE__*/createContext(false);
|
|
19
|
+
|
|
20
|
+
// Wraps `children` in `FontdueContextProvider` only when no parent
|
|
21
|
+
// FontdueContextProvider/FontdueProvider is present. Self-wrapping components
|
|
22
|
+
// (`<TypeTester>`, `<StoreModal>`, etc.) use this so they Just Work as
|
|
23
|
+
// standalone islands while staying lightweight inside an outer
|
|
24
|
+
// `<FontdueProvider>` tree.
|
|
25
|
+
export function EnsureFontdueContext(_ref) {
|
|
26
|
+
let {
|
|
27
|
+
children
|
|
28
|
+
} = _ref;
|
|
29
|
+
const isInsideContext = useContext(FontdueContextMarker);
|
|
30
|
+
if (isInsideContext) return /*#__PURE__*/React.createElement(React.Fragment, null, children);
|
|
31
|
+
return /*#__PURE__*/React.createElement(FontdueContextProvider, null, children);
|
|
32
|
+
}
|
|
33
|
+
const IS_SERVER = typeof window === typeof undefined;
|
|
34
|
+
|
|
35
|
+
// === Multi-island state-sharing contract ===
|
|
36
|
+
//
|
|
37
|
+
// Frameworks that hydrate per-island (Astro, Vike, Qwik) mount one
|
|
38
|
+
// `FontdueContextProvider` per fontdue-js component on the page. Each island
|
|
39
|
+
// runs its own React reconciler and gets its own copy of every context, so
|
|
40
|
+
// state that lives inside the component tree is duplicated — adding to the
|
|
41
|
+
// cart in one island wouldn't update the CartButton in a different island.
|
|
42
|
+
//
|
|
43
|
+
// Any stateful client to be shared *across islands* (a Redux store, a Relay
|
|
44
|
+
// Environment, or any future cache) must be a module-level singleton on the
|
|
45
|
+
// client and per-render on the server. SSR has the opposite constraint: a
|
|
46
|
+
// client-shared singleton would leak state between concurrent requests.
|
|
47
|
+
//
|
|
48
|
+
// The pattern (see also `relay/environment.ts → useCurrentEnvironment`):
|
|
49
|
+
//
|
|
50
|
+
// let clientThing: Thing | null = null;
|
|
51
|
+
// function useSharedThing() {
|
|
52
|
+
// if (IS_SERVER) return createThing(); // per-render, no leakage
|
|
53
|
+
// if (clientThing == null) clientThing = createThing();
|
|
54
|
+
// return clientThing; // shared across islands
|
|
55
|
+
// }
|
|
56
|
+
//
|
|
57
|
+
// If you add a new context provider here that holds mutable client state,
|
|
58
|
+
// follow this pattern. If it's purely deriving from props (no state), a
|
|
59
|
+
// vanilla `Context.Provider` is fine — each island will compute the same
|
|
60
|
+
// value.
|
|
61
|
+
let clientStore = null;
|
|
62
|
+
function useSharedStore(providedStore, config) {
|
|
63
|
+
const ref = useRef(null);
|
|
64
|
+
if (providedStore) return providedStore;
|
|
65
|
+
if (IS_SERVER) {
|
|
66
|
+
if (ref.current == null) ref.current = createDefaultStore(config);
|
|
67
|
+
return ref.current;
|
|
68
|
+
}
|
|
69
|
+
if (clientStore == null) clientStore = createDefaultStore(config);
|
|
70
|
+
return clientStore;
|
|
71
|
+
}
|
|
72
|
+
// Lightweight wrapper that sets up Fontdue's React contexts (Relay env,
|
|
73
|
+
// Redux store, config, url, components) without rendering any aux UI.
|
|
74
|
+
// `*Preloaded` self-wrapping components use this so they can stand alone
|
|
75
|
+
// without claiming the page-level aux UI slot. Pages that need aux UI
|
|
76
|
+
// (theme/test-mode/consent/tracking) wrap with `FontdueProvider` instead.
|
|
77
|
+
export default function FontdueContextProvider(_ref2) {
|
|
78
|
+
let {
|
|
79
|
+
children,
|
|
80
|
+
url,
|
|
81
|
+
stripeIntegration,
|
|
82
|
+
config,
|
|
83
|
+
components,
|
|
84
|
+
store
|
|
85
|
+
} = _ref2;
|
|
86
|
+
const environment = useCurrentEnvironment({
|
|
87
|
+
url,
|
|
88
|
+
stripeIntegration
|
|
89
|
+
});
|
|
90
|
+
const configValue = makeConfig(config);
|
|
91
|
+
setCorsModalEnabled(configValue.corsErrorModal);
|
|
92
|
+
const sharedStore = useSharedStore(store, config);
|
|
93
|
+
return /*#__PURE__*/React.createElement(FontdueContextMarker.Provider, {
|
|
94
|
+
value: true
|
|
95
|
+
}, /*#__PURE__*/React.createElement(RelayEnvironmentProvider, {
|
|
96
|
+
environment: environment
|
|
97
|
+
}, /*#__PURE__*/React.createElement(Provider, {
|
|
98
|
+
store: sharedStore
|
|
99
|
+
}, /*#__PURE__*/React.createElement(Suspense, {
|
|
100
|
+
fallback: null
|
|
101
|
+
}, /*#__PURE__*/React.createElement(ConfigContext.Provider, {
|
|
102
|
+
value: configValue
|
|
103
|
+
}, /*#__PURE__*/React.createElement(UrlContext.Provider, {
|
|
104
|
+
value: url ?? (typeof process !== 'undefined' ? process.env.NEXT_PUBLIC_FONTDUE_URL : undefined) ?? ''
|
|
105
|
+
}, /*#__PURE__*/React.createElement(ComponentsContext.Provider, {
|
|
106
|
+
value: components ?? {}
|
|
107
|
+
}, children)))))));
|
|
108
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FontdueContextProvider_props } from './index.js';
|
|
3
|
+
export type { FontdueContextProvider_props } from './index.js';
|
|
4
|
+
export default function FontdueContextProviderServer(props: FontdueContextProvider_props): Promise<React.JSX.Element>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import FontdueContextProvider from './index.js';
|
|
3
|
+
// RSC entry. The client component does the work; this exists so the
|
|
4
|
+
// `react-server` export condition resolves to a server-renderable file.
|
|
5
|
+
export default async function FontdueContextProviderServer(props) {
|
|
6
|
+
return /*#__PURE__*/React.createElement(FontdueContextProvider, props);
|
|
7
|
+
}
|
|
@@ -81,7 +81,7 @@ const specFromLicense = license => {
|
|
|
81
81
|
}
|
|
82
82
|
return licenseOptionSpec;
|
|
83
83
|
};
|
|
84
|
-
_Precart_license2.default.hash && _Precart_license2.default.hash !== "
|
|
84
|
+
_Precart_license2.default.hash && _Precart_license2.default.hash !== "db49280bb01f8bbef6283c0d3fba99e1" && console.error("The definition of 'Precart_license' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _Precart_license2.default;
|
|
85
85
|
function Precart(_ref3) {
|
|
86
86
|
var _viewer$precart2, _collection$licenses3;
|
|
87
87
|
let {
|
|
@@ -120,7 +120,7 @@ function Precart(_ref3) {
|
|
|
120
120
|
});
|
|
121
121
|
}, [environment]);
|
|
122
122
|
const onSelectLicense = (id, checked) => {
|
|
123
|
-
var _collection$licenses;
|
|
123
|
+
var _collection$licenses, _license$excludedLice;
|
|
124
124
|
const license = collection === null || collection === void 0 ? void 0 : (_collection$licenses = collection.licenses) === null || _collection$licenses === void 0 ? void 0 : _collection$licenses.find(node => node.id === id);
|
|
125
125
|
if (!license) return;
|
|
126
126
|
const licenseOptionSpec = specFromLicense(license);
|
|
@@ -128,7 +128,8 @@ function Precart(_ref3) {
|
|
|
128
128
|
type: 'PRECART_TOGGLE_LICENSE',
|
|
129
129
|
licenseId: id,
|
|
130
130
|
checked,
|
|
131
|
-
licenseOptionSpec
|
|
131
|
+
licenseOptionSpec,
|
|
132
|
+
excludedLicenseIds: (_license$excludedLice = license.excludedLicenses) === null || _license$excludedLice === void 0 ? void 0 : _license$excludedLice.map(l => l.id)
|
|
132
133
|
});
|
|
133
134
|
};
|
|
134
135
|
const onSelectLicenseOption = (licenseId, variableId, optionId) => {
|
|
@@ -217,10 +218,14 @@ function Precart(_ref3) {
|
|
|
217
218
|
}, [precartOpen]);
|
|
218
219
|
(0, _react.useEffect)(() => {
|
|
219
220
|
var _collection$licenses2;
|
|
220
|
-
collection === null || collection === void 0 ? void 0 : (_collection$licenses2 = collection.licenses) === null || _collection$licenses2 === void 0 ? void 0 : _collection$licenses2.filter(license => license.defaultSelected).
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
221
|
+
collection === null || collection === void 0 ? void 0 : (_collection$licenses2 = collection.licenses) === null || _collection$licenses2 === void 0 ? void 0 : _collection$licenses2.filter(license => license.defaultSelected).forEach(license => {
|
|
222
|
+
var _license$excludedLice2;
|
|
223
|
+
return dispatch({
|
|
224
|
+
type: 'PRECART_SELECT_LICENSE',
|
|
225
|
+
licenseOptionSpec: specFromLicense(license),
|
|
226
|
+
excludedLicenseIds: (_license$excludedLice2 = license.excludedLicenses) === null || _license$excludedLice2 === void 0 ? void 0 : _license$excludedLice2.map(l => l.id)
|
|
227
|
+
});
|
|
228
|
+
});
|
|
224
229
|
}, []);
|
|
225
230
|
function renderConfirmingModal(subtotal) {
|
|
226
231
|
var _viewer$precart3, _viewer$precart3$skus;
|
|
@@ -15,7 +15,7 @@ const StoreModalIndex = _ref => {
|
|
|
15
15
|
let {
|
|
16
16
|
prepared
|
|
17
17
|
} = _ref;
|
|
18
|
-
const data = (0, _reactRelay.usePreloadedQuery)((_StoreModalIndexQuery2.default.hash && _StoreModalIndexQuery2.default.hash !== "
|
|
18
|
+
const data = (0, _reactRelay.usePreloadedQuery)((_StoreModalIndexQuery2.default.hash && _StoreModalIndexQuery2.default.hash !== "099c77808b41054885365ebe3eda03c8" && console.error("The definition of 'StoreModalIndexQuery' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalIndexQuery2.default), prepared.indexQuery);
|
|
19
19
|
const viewer = data.viewer;
|
|
20
20
|
const edges = (viewer === null || viewer === void 0 ? void 0 : (_viewer$rootCollectio = viewer.rootCollections) === null || _viewer$rootCollectio === void 0 ? void 0 : _viewer$rootCollectio.edges) ?? [];
|
|
21
21
|
return /*#__PURE__*/_react.default.createElement(_StoreModalPageContainer.default, null, {
|
|
@@ -42,7 +42,7 @@ function StoreModalProduceLicense(_ref) {
|
|
|
42
42
|
let {
|
|
43
43
|
license: licenseKey
|
|
44
44
|
} = _ref;
|
|
45
|
-
const license = (0, _reactRelay.useFragment)((_StoreModalProductLicense_license2.default.hash && _StoreModalProductLicense_license2.default.hash !== "
|
|
45
|
+
const license = (0, _reactRelay.useFragment)((_StoreModalProductLicense_license2.default.hash && _StoreModalProductLicense_license2.default.hash !== "87cd41e76dcd8952d7096940a383b9f3" && console.error("The definition of 'StoreModalProductLicense_license' appears to have changed. Run `relay-compiler` to update the generated files to receive the expected data."), _StoreModalProductLicense_license2.default), licenseKey);
|
|
46
46
|
const licenseOptions = (0, _reactRedux.useSelector)(state => state.licenseOptions);
|
|
47
47
|
const selectedOptions = licenseOptions.find(_ref2 => {
|
|
48
48
|
let {
|
|
@@ -53,11 +53,13 @@ function StoreModalProduceLicense(_ref) {
|
|
|
53
53
|
const isSelected = Boolean(selectedOptions);
|
|
54
54
|
const dispatch = (0, _reactRedux.useDispatch)();
|
|
55
55
|
const handleSelectLicense = (0, _react.useCallback)(() => {
|
|
56
|
+
var _license$excludedLice;
|
|
56
57
|
dispatch({
|
|
57
58
|
type: 'PRECART_TOGGLE_LICENSE',
|
|
58
59
|
licenseId: license.id,
|
|
59
60
|
checked: !isSelected,
|
|
60
|
-
licenseOptionSpec: specFromLicense(license)
|
|
61
|
+
licenseOptionSpec: specFromLicense(license),
|
|
62
|
+
excludedLicenseIds: (_license$excludedLice = license.excludedLicenses) === null || _license$excludedLice === void 0 ? void 0 : _license$excludedLice.map(l => l.id)
|
|
61
63
|
});
|
|
62
64
|
}, [dispatch, license, isSelected]);
|
|
63
65
|
const handleLicenseOptionChange = (0, _react.useCallback)(_ref3 => {
|
|
@@ -66,9 +68,11 @@ function StoreModalProduceLicense(_ref) {
|
|
|
66
68
|
optionId
|
|
67
69
|
} = _ref3;
|
|
68
70
|
if (!isSelected) {
|
|
71
|
+
var _license$excludedLice2;
|
|
69
72
|
dispatch({
|
|
70
73
|
type: 'PRECART_SELECT_LICENSE',
|
|
71
|
-
licenseOptionSpec: specFromLicense(license)
|
|
74
|
+
licenseOptionSpec: specFromLicense(license),
|
|
75
|
+
excludedLicenseIds: (_license$excludedLice2 = license.excludedLicenses) === null || _license$excludedLice2 === void 0 ? void 0 : _license$excludedLice2.map(l => l.id)
|
|
72
76
|
});
|
|
73
77
|
}
|
|
74
78
|
dispatch({
|
|
@@ -80,9 +84,11 @@ function StoreModalProduceLicense(_ref) {
|
|
|
80
84
|
}, [dispatch, license, isSelected]);
|
|
81
85
|
(0, _react.useEffect)(() => {
|
|
82
86
|
if (license.defaultSelected) {
|
|
87
|
+
var _license$excludedLice3;
|
|
83
88
|
dispatch({
|
|
84
89
|
type: 'PRECART_SELECT_LICENSE',
|
|
85
|
-
licenseOptionSpec: specFromLicense(license)
|
|
90
|
+
licenseOptionSpec: specFromLicense(license),
|
|
91
|
+
excludedLicenseIds: (_license$excludedLice3 = license.excludedLicenses) === null || _license$excludedLice3 === void 0 ? void 0 : _license$excludedLice3.map(l => l.id)
|
|
86
92
|
});
|
|
87
93
|
}
|
|
88
94
|
}, []);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { LoadSerializableQueryOptions, SerializablePreloadedQuery } from '../../relay/loadSerializableQuery';
|
|
3
|
-
import { TypeTesterStandaloneQuery } from '../../__generated__/TypeTesterStandaloneQuery.graphql';
|
|
4
|
-
import { TypeTesterStandalonePreloadedQueryRenderer } from './TypeTesterStandalone';
|
|
2
|
+
import { LoadSerializableQueryOptions, SerializablePreloadedQuery } from '../../relay/loadSerializableQuery.js';
|
|
3
|
+
import { TypeTesterStandaloneQuery } from '../../__generated__/TypeTesterStandaloneQuery.graphql.js';
|
|
4
|
+
import { TypeTesterStandalonePreloadedQueryRenderer } from './TypeTesterStandalone.js';
|
|
5
5
|
export type TypeTesterPreloadedQuery = SerializablePreloadedQuery<TypeTesterStandaloneQuery>;
|
|
6
6
|
export interface LoadTypeTesterQueryVariables {
|
|
7
7
|
familyName: string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import loadSerializableQuery from '../../relay/loadSerializableQuery';
|
|
3
|
-
import TypeTesterStandaloneQueryNode from '../../__generated__/TypeTesterStandaloneQuery.graphql';
|
|
4
|
-
import
|
|
5
|
-
import { TypeTesterStandalonePreloadedQueryRenderer } from './TypeTesterStandalone';
|
|
2
|
+
import loadSerializableQuery from '../../relay/loadSerializableQuery.js';
|
|
3
|
+
import TypeTesterStandaloneQueryNode from '../../__generated__/TypeTesterStandaloneQuery.graphql.js';
|
|
4
|
+
import FontdueContextProvider from '../FontdueContextProvider/index.js';
|
|
5
|
+
import { TypeTesterStandalonePreloadedQueryRenderer } from './TypeTesterStandalone.js';
|
|
6
6
|
export async function loadTypeTesterQuery(variables, options) {
|
|
7
7
|
return loadSerializableQuery(TypeTesterStandaloneQueryNode, {
|
|
8
8
|
familyName: variables.familyName,
|
|
@@ -10,10 +10,11 @@ export async function loadTypeTesterQuery(variables, options) {
|
|
|
10
10
|
selectable: variables.selectable ?? true
|
|
11
11
|
}, options);
|
|
12
12
|
}
|
|
13
|
-
// Self-wraps with
|
|
14
|
-
//
|
|
15
|
-
//
|
|
16
|
-
//
|
|
13
|
+
// Self-wraps with FontdueContextProvider so consumers don't need to wire up
|
|
14
|
+
// Relay env / Redux store / contexts at the call site. Aux UI (theme,
|
|
15
|
+
// test-mode banner, consent, tracking) is NOT rendered here — that belongs
|
|
16
|
+
// to a single layout-level `<FontdueProvider>` per page. State is shared
|
|
17
|
+
// across multiple preloaded components on a page via module-level singletons.
|
|
17
18
|
export function TypeTesterPreloaded(props) {
|
|
18
|
-
return /*#__PURE__*/React.createElement(
|
|
19
|
+
return /*#__PURE__*/React.createElement(FontdueContextProvider, null, /*#__PURE__*/React.createElement(TypeTesterStandalonePreloadedQueryRenderer, props));
|
|
19
20
|
}
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
// Module-level global configuration. Consumers call `configure()` once at
|
|
2
|
-
// app startup (
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// app startup (Astro layout, Next layout, Vite entry) and every fontdue-js
|
|
3
|
+
// entry point reads defaults from here.
|
|
4
|
+
//
|
|
5
|
+
// Precedence (low to high):
|
|
6
|
+
// 1. Server admin config (from the tenant dashboard, fetched via Relay)
|
|
7
|
+
// 2. configure({...}) — module-level code defaults
|
|
8
|
+
// 3. <FontdueProvider config={...}> — per-instance prop override
|
|
5
9
|
//
|
|
6
10
|
// Per-request isolation note: `configure` sets module-level state. That's
|
|
7
|
-
// fine for single-tenant apps
|
|
8
|
-
//
|
|
9
|
-
//
|
|
11
|
+
// fine for single-tenant apps. Multi-tenant servers that switch URL per
|
|
12
|
+
// request should pass `url` explicitly to loadSerializableQuery rather than
|
|
13
|
+
// rely on configure().
|
|
14
|
+
|
|
15
|
+
// Network-layer + UI config in one bag. UI fields come from `Config` (the
|
|
16
|
+
// shape passed to ConfigContext); URL + stripeIntegration are network-layer.
|
|
10
17
|
|
|
11
18
|
let current = {};
|
|
19
|
+
|
|
20
|
+
// Shallow-merges with prior values. Calling `configure({tracking: {...}})`
|
|
21
|
+
// replaces the whole `tracking` subtree; pass nested fields fully populated
|
|
22
|
+
// when partial-updating.
|
|
12
23
|
export function configure(opts) {
|
|
13
24
|
current = {
|
|
14
25
|
...current,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type ResizeObserverCtor = new (callback: ResizeObserverCallback) => {
|
|
2
|
+
observe: (target: Element) => void;
|
|
3
|
+
unobserve?: (target: Element) => void;
|
|
4
|
+
disconnect?: () => void;
|
|
5
|
+
};
|
|
6
|
+
export type UseResizeObserverOptions = {
|
|
7
|
+
polyfill?: ResizeObserverCtor | null;
|
|
8
|
+
};
|
|
9
|
+
export type UseResizeObserverCallback = (entry: ResizeObserverEntry, observer: ResizeObserver) => void;
|
|
10
|
+
export default function useResizeObserver<T extends Element>(target: React.RefObject<T | null> | T | null, callback: UseResizeObserverCallback, options?: UseResizeObserverOptions): void;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
// Loose constructor type so the SSR no-op polyfills used as fallbacks (which
|
|
4
|
+
// don't implement `disconnect`) still type-check.
|
|
5
|
+
|
|
6
|
+
export default function useResizeObserver(target, callback) {
|
|
7
|
+
let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
8
|
+
const callbackRef = useRef(callback);
|
|
9
|
+
callbackRef.current = callback;
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const element = target && 'current' in target ? target.current : target;
|
|
12
|
+
if (!element) return;
|
|
13
|
+
const Ctor = options.polyfill ?? (typeof ResizeObserver !== 'undefined' ? ResizeObserver : null);
|
|
14
|
+
if (!Ctor) return;
|
|
15
|
+
const observer = new Ctor(entries => {
|
|
16
|
+
for (const entry of entries) callbackRef.current(entry, observer);
|
|
17
|
+
});
|
|
18
|
+
observer.observe(element);
|
|
19
|
+
return () => {
|
|
20
|
+
if (observer.disconnect) observer.disconnect();else if (observer.unobserve) observer.unobserve(element);
|
|
21
|
+
};
|
|
22
|
+
}, [target, options.polyfill]);
|
|
23
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export type {
|
|
1
|
+
export { default as loadFontdueProviderQuery } from './loadFontdueProviderQuery.js';
|
|
2
|
+
export type { FontdueProviderPreloadedQuery } from './loadFontdueProviderQuery.js';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { default as loadFontdueProviderQuery } from './loadFontdueProviderQuery.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import loadSerializableQuery from './relay/loadSerializableQuery.js';
|
|
2
|
+
import FontdueProviderQueryNode from './__generated__/FontdueProviderQuery.graphql.js';
|
|
3
|
+
// Fetches the data aux UI (theme custom properties, test-mode flag) needs to
|
|
4
|
+
// render synchronously on the server and on hydration. Pass the result to
|
|
5
|
+
// `<FontdueProvider preloadedQuery={…}>` in your layout. Without it, aux UI
|
|
6
|
+
// falls back to lazy-fetching on first client render — which causes a visible
|
|
7
|
+
// theming flash because `ThemeConfig` injects CSS variables.
|
|
8
|
+
export default async function loadFontdueProviderQuery() {
|
|
9
|
+
return loadSerializableQuery(FontdueProviderQueryNode, {});
|
|
10
|
+
}
|
package/dist/reducer.d.ts
CHANGED
|
@@ -57,10 +57,12 @@ export type FontdueAction = {
|
|
|
57
57
|
type: 'PRECART_TOGGLE_LICENSE';
|
|
58
58
|
licenseId: string;
|
|
59
59
|
licenseOptionSpec: LicenseOptionSpec;
|
|
60
|
+
excludedLicenseIds?: readonly string[];
|
|
60
61
|
checked: boolean;
|
|
61
62
|
} | {
|
|
62
63
|
type: 'PRECART_SELECT_LICENSE';
|
|
63
64
|
licenseOptionSpec: LicenseOptionSpec;
|
|
65
|
+
excludedLicenseIds?: readonly string[];
|
|
64
66
|
} | {
|
|
65
67
|
type: 'PRECART_SELECT_LICENSE_OPTION';
|
|
66
68
|
licenseId: string;
|
package/dist/reducer.js
CHANGED
|
@@ -34,9 +34,11 @@ const selectLicense = (state, action) => {
|
|
|
34
34
|
if (!(action.type === 'PRECART_SELECT_LICENSE' || action.type === 'PRECART_TOGGLE_LICENSE')) return state;
|
|
35
35
|
const existingLicenseOption = state.licenseOptions.findIndex(option => option.licenseId === action.licenseOptionSpec.licenseId);
|
|
36
36
|
if (existingLicenseOption >= 0) return state;
|
|
37
|
+
const excludedIds = action.excludedLicenseIds ?? [];
|
|
38
|
+
const filtered = excludedIds.length > 0 ? state.licenseOptions.filter(option => !excludedIds.includes(option.licenseId)) : state.licenseOptions;
|
|
37
39
|
return {
|
|
38
40
|
...state,
|
|
39
|
-
licenseOptions:
|
|
41
|
+
licenseOptions: filtered.concat(action.licenseOptionSpec)
|
|
40
42
|
};
|
|
41
43
|
};
|
|
42
44
|
const toggleLicense = (state, action) => {
|
package/dist/vite.d.ts
ADDED
package/dist/vite.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Vite plugin that fixes the SSR-side CJS interop fontdue-js's deps need.
|
|
2
|
+
//
|
|
3
|
+
// fontdue-js itself is published as transpiled (not bundled) ESM. Its Relay
|
|
4
|
+
// + draft-js + fbjs deps still ship as CJS using `module.exports = require(…)`
|
|
5
|
+
// re-export shapes that Node's strict ESM-CJS interop (and Vite's dev SSR
|
|
6
|
+
// module-runner) can't named-import from. Without help, `import { graphql }
|
|
7
|
+
// from 'react-relay'` blows up at SSR time with `Named export 'graphql' not
|
|
8
|
+
// found` or `module is not defined`.
|
|
9
|
+
//
|
|
10
|
+
// `vite-plugin-cjs-interop` is the canonical fix for this — referenced by the
|
|
11
|
+
// Relay maintainers in https://github.com/facebook/relay/issues/4548. It
|
|
12
|
+
// rewrites named imports of the listed packages to read from `.default` after
|
|
13
|
+
// CJS load, which is what Node + Vite actually expose.
|
|
14
|
+
//
|
|
15
|
+
// Consumers wire it up like:
|
|
16
|
+
//
|
|
17
|
+
// // vite.config.ts
|
|
18
|
+
// import fontdueJs from 'fontdue-js/vite';
|
|
19
|
+
// export default defineConfig({ plugins: [fontdueJs()] });
|
|
20
|
+
//
|
|
21
|
+
// Returned shape is structurally a Vite Plugin (or array of plugins).
|
|
22
|
+
//
|
|
23
|
+
// @ts-ignore — vite-plugin-cjs-interop has no bundled types but exports
|
|
24
|
+
// cjsInterop at runtime.
|
|
25
|
+
import { cjsInterop } from 'vite-plugin-cjs-interop';
|
|
26
|
+
import { createRequire } from 'node:module';
|
|
27
|
+
|
|
28
|
+
// Packages whose imports cjsInterop should rewrite to default-import +
|
|
29
|
+
// destructure shape. Limit this to packages that genuinely ship as CJS-only
|
|
30
|
+
// with `module.exports = require('./lib')` shapes that defeat named-import
|
|
31
|
+
// resolution. React-redux is real ESM and must NOT be in this list — its
|
|
32
|
+
// ESM build has true named exports.
|
|
33
|
+
const CJS_DEPS = ['react-relay', 'relay-runtime', 'draft-js', 'fbjs'];
|
|
34
|
+
|
|
35
|
+
// Packages to pre-bundle for the browser via Vite's optimizer. Pre-bundling
|
|
36
|
+
// pulls a package's transitive deps into one esbuild output, which sidesteps
|
|
37
|
+
// the cjs-module-lexer trap when an ESM package (react-redux) imports a CJS
|
|
38
|
+
// transitive (use-sync-external-store). Without this, the browser dev path
|
|
39
|
+
// fails with "does not provide an export named useSyncExternalStoreWithSelector".
|
|
40
|
+
//
|
|
41
|
+
// `react-google-recaptcha` and `@stripe/react-stripe-js` are pulled into the
|
|
42
|
+
// StoreModal subtree (checkout flow). Both transitively import `prop-types`,
|
|
43
|
+
// whose `module.exports = require('./factoryWithTypeCheckers')(...)` shape
|
|
44
|
+
// hides exports behind a runtime call — cjs-module-lexer can't see them, so
|
|
45
|
+
// the optimizer's auto-generated wrapper omits a `default` export. Including
|
|
46
|
+
// the consumers + setting `needsInterop` on `prop-types` forces Vite to
|
|
47
|
+
// synthesize a default export so `import PropTypes from 'prop-types'` resolves.
|
|
48
|
+
const CLIENT_OPTIMIZE = [...CJS_DEPS, 'react-redux', 'react-google-recaptcha', '@stripe/react-stripe-js', 'prop-types',
|
|
49
|
+
// Transitive deps that Vite would otherwise discover late, after fontdue-js
|
|
50
|
+
// subpaths are first imported. Each late discovery triggers a re-optimize
|
|
51
|
+
// and a new browserHash for `react`, which produces the dual-React bug
|
|
52
|
+
// described above `getFontdueJsSubpaths`. Pinning them here keeps the
|
|
53
|
+
// initial scan complete.
|
|
54
|
+
'@sentry/react', '@stripe/stripe-js', 'react-error-boundary', 'redux'];
|
|
55
|
+
const NEEDS_INTEROP = ['prop-types'];
|
|
56
|
+
|
|
57
|
+
// Every public `fontdue-js/*` entry from package.json `exports`. Pre-including
|
|
58
|
+
// them in `optimizeDeps` forces Vite to scan them on the first dev startup
|
|
59
|
+
// instead of discovering them later when a route lazy-loads.
|
|
60
|
+
//
|
|
61
|
+
// Why this matters: when Vite finds a new dep mid-session it re-runs the
|
|
62
|
+
// optimizer, which mints a new `?v=` browserHash for every dep chunk. Chunks
|
|
63
|
+
// already loaded in the page keep their old `?v=` baked into their imports,
|
|
64
|
+
// so a freshly-fetched chunk that imports `react?v=NEW` ends up coexisting
|
|
65
|
+
// with the previously-loaded `react?v=OLD`. Two physical React modules in
|
|
66
|
+
// the same page → two `ReactCurrentDispatcher`s → `useContext` returns null
|
|
67
|
+
// → "Invalid hook call" on first navigation to an uncached route.
|
|
68
|
+
//
|
|
69
|
+
// Frameworks that lazy-load modules (RR7's route splitter, Astro's per-island
|
|
70
|
+
// hydration) make this near-certain unless the optimizer sees the full set
|
|
71
|
+
// up front. Vite's glob form (`fontdue-js/*`) walks the filesystem and gets
|
|
72
|
+
// confused by our `exports`-mapped layout (the dist files don't sit at the
|
|
73
|
+
// subpath names), so we read `exports` directly — that's the authoritative
|
|
74
|
+
// list.
|
|
75
|
+
function getFontdueJsSubpaths() {
|
|
76
|
+
const require = createRequire(import.meta.url);
|
|
77
|
+
const pkg = require('../package.json');
|
|
78
|
+
const out = [];
|
|
79
|
+
for (const key of Object.keys(pkg.exports ?? {})) {
|
|
80
|
+
if (!key.startsWith('./')) continue;
|
|
81
|
+
if (key.endsWith('.css')) continue;
|
|
82
|
+
if (key === './vite') continue;
|
|
83
|
+
out.push(`fontdue-js/${key.slice(2)}`);
|
|
84
|
+
}
|
|
85
|
+
return out;
|
|
86
|
+
}
|
|
87
|
+
export default function fontdueJs() {
|
|
88
|
+
const fontdueSubpaths = getFontdueJsSubpaths();
|
|
89
|
+
return [cjsInterop({
|
|
90
|
+
dependencies: CJS_DEPS
|
|
91
|
+
}), {
|
|
92
|
+
name: 'fontdue-js',
|
|
93
|
+
config() {
|
|
94
|
+
return {
|
|
95
|
+
// Pre-bundle the CJS-shaped deps via esbuild for the client
|
|
96
|
+
// bundle. Without this, Astro dev's browser pass tries to
|
|
97
|
+
// ESM-import `Environment` from `relay-runtime` and fails —
|
|
98
|
+
// its `module.exports = require('./lib/index.js')` shape can't
|
|
99
|
+
// be statically analyzed for named exports.
|
|
100
|
+
optimizeDeps: {
|
|
101
|
+
include: [...fontdueSubpaths, ...CLIENT_OPTIMIZE],
|
|
102
|
+
needsInterop: [...NEEDS_INTEROP]
|
|
103
|
+
},
|
|
104
|
+
// fbjs (transitive via draft-js) references Node's `global` at
|
|
105
|
+
// module init. Browsers don't define it, so the pre-bundled chunk
|
|
106
|
+
// throws `ReferenceError: global is not defined`. Aliasing
|
|
107
|
+
// `global` to `globalThis` at compile time covers both browser
|
|
108
|
+
// and SSR paths.
|
|
109
|
+
define: {
|
|
110
|
+
global: 'globalThis'
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
// Apply `noExternal` to every server-side Vite environment so
|
|
115
|
+
// fontdue-js source flows through Vite's transform pipeline and
|
|
116
|
+
// cjsInterop can rewrite its imports of CJS-shaped Relay/draft-js/
|
|
117
|
+
// fbjs. The legacy `ssr.noExternal` only covered the default `ssr`
|
|
118
|
+
// environment, so Astro 6's separate `prerender` build externalized
|
|
119
|
+
// fontdue-js and `import { graphql } from 'react-relay'` ran against
|
|
120
|
+
// unrewritten CJS at prerender time.
|
|
121
|
+
//
|
|
122
|
+
// `config.consumer` would be the principled check, but at
|
|
123
|
+
// `configEnvironment` time Vite hasn't populated it yet (undefined
|
|
124
|
+
// for ssr/prerender/client alike). Match by name instead:
|
|
125
|
+
// - 'ssr': default Vite SSR env (plain Vite SSR, RR7)
|
|
126
|
+
// - 'prerender': Astro 6's static-prerender env
|
|
127
|
+
// The `consumer` fallback is kept as future-proofing if a framework
|
|
128
|
+
// ever names its server env something else but does populate consumer.
|
|
129
|
+
configEnvironment(name, config) {
|
|
130
|
+
if (name === 'ssr' || name === 'prerender' || config.consumer === 'server') {
|
|
131
|
+
return {
|
|
132
|
+
resolve: {
|
|
133
|
+
noExternal: ['fontdue-js']
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}];
|
|
139
|
+
}
|
package/package.json
CHANGED
package/.nvmrc
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
v14.13.1
|