@fragmentsx/client-core 0.2.4 → 0.4.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.
Files changed (44) hide show
  1. package/dist/createAreaManager.d.ts +18 -0
  2. package/dist/createAreaManager.d.ts.map +1 -0
  3. package/dist/fragmentsClient.d.ts +0 -2
  4. package/dist/fragmentsClient.d.ts.map +1 -1
  5. package/dist/index.cjs.js +228 -270
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.es.js +228 -270
  9. package/dist/plugins/fetch/areaQueries.test.d.ts +2 -0
  10. package/dist/plugins/fetch/areaQueries.test.d.ts.map +1 -0
  11. package/dist/plugins/fetch/index.d.ts +10 -7
  12. package/dist/plugins/fetch/index.d.ts.map +1 -1
  13. package/dist/plugins/fetch/restFetcher.d.ts +6 -0
  14. package/dist/plugins/fetch/restFetcher.d.ts.map +1 -0
  15. package/dist/plugins/fetch/restFetcher.test.d.ts +2 -0
  16. package/dist/plugins/fetch/restFetcher.test.d.ts.map +1 -0
  17. package/dist/plugins/fonts/index.d.ts.map +1 -1
  18. package/dist/plugins/fonts/index.test.d.ts +2 -0
  19. package/dist/plugins/fonts/index.test.d.ts.map +1 -0
  20. package/dist/plugins/fragments/index.d.ts.map +1 -1
  21. package/dist/plugins/load/index.d.ts +6 -7
  22. package/dist/plugins/load/index.d.ts.map +1 -1
  23. package/dist/plugins/metrics/globalMetrics.d.ts +8 -1
  24. package/dist/plugins/metrics/globalMetrics.d.ts.map +1 -1
  25. package/dist/plugins/metrics/index.d.ts.map +1 -1
  26. package/dist/plugins/properties/index.d.ts +17 -0
  27. package/dist/plugins/properties/index.d.ts.map +1 -0
  28. package/dist/plugins/properties/index.test.d.ts +2 -0
  29. package/dist/plugins/properties/index.test.d.ts.map +1 -0
  30. package/dist/testing/createTestFragmentsClient.d.ts +4 -0
  31. package/dist/testing/createTestFragmentsClient.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/dist/plugins/fetch/fetcher.d.ts +0 -8
  34. package/dist/plugins/fetch/fetcher.d.ts.map +0 -1
  35. package/dist/plugins/fetch/fetcher.test.d.ts +0 -2
  36. package/dist/plugins/fetch/fetcher.test.d.ts.map +0 -1
  37. package/dist/plugins/fetch/queries/AreaListQuery.d.ts +0 -43
  38. package/dist/plugins/fetch/queries/AreaListQuery.d.ts.map +0 -1
  39. package/dist/plugins/fetch/queries/AreaQuery.d.ts +0 -24
  40. package/dist/plugins/fetch/queries/AreaQuery.d.ts.map +0 -1
  41. package/dist/plugins/fetch/queries/FragmentQuery.d.ts +0 -31
  42. package/dist/plugins/fetch/queries/FragmentQuery.d.ts.map +0 -1
  43. package/dist/plugins/fetch/queries/parts.d.ts +0 -5
  44. package/dist/plugins/fetch/queries/parts.d.ts.map +0 -1
package/dist/index.cjs.js CHANGED
@@ -1690,94 +1690,48 @@ const CssOverrideSchema = /* @__PURE__ */ object({
1690
1690
  const BASE_HEADERS = {
1691
1691
  "Content-Type": "application/json"
1692
1692
  };
1693
- const createFetcher = (baseUrl, defaultHeaders = {}) => {
1693
+ const createRestFetcher = (baseUrl, defaultHeaders = {}) => {
1694
1694
  const cache = /* @__PURE__ */ new Map();
1695
1695
  const inflightRequests = /* @__PURE__ */ new Map();
1696
- const getCacheKey = (query2, variables, options) => JSON.stringify({ query: query2, variables, options });
1697
- const query = async (query2, variables = {}, options = {}) => {
1698
- const cacheKey = getCacheKey(query2, variables, options);
1699
- if (cache.has(cacheKey)) {
1700
- return cache.get(cacheKey);
1696
+ const get = (url) => {
1697
+ const fullUrl = `${baseUrl}${url}`;
1698
+ if (cache.has(fullUrl)) {
1699
+ return Promise.resolve(cache.get(fullUrl));
1701
1700
  }
1702
- if (inflightRequests.has(cacheKey)) {
1703
- return inflightRequests.get(cacheKey);
1701
+ if (inflightRequests.has(fullUrl)) {
1702
+ return inflightRequests.get(fullUrl);
1704
1703
  }
1705
- const request = fetch(baseUrl, {
1706
- ...options,
1707
- method: "POST",
1708
- body: JSON.stringify({ query: query2, variables }),
1709
- credentials: "include",
1704
+ const request = fetch(fullUrl, {
1705
+ method: "GET",
1710
1706
  headers: {
1711
1707
  ...BASE_HEADERS,
1712
- ...defaultHeaders,
1713
- ...options.headers
1708
+ ...defaultHeaders
1714
1709
  }
1715
1710
  }).then(async (res) => {
1716
- if (!res.ok) throw new Error(`Fetch error: ${res.status}`);
1717
- const data = await res.json();
1718
- if (!query2.includes("mutation")) {
1719
- cache.set(cacheKey, data);
1711
+ if (!res.ok) {
1712
+ throw new Error(`Fetch error: ${res.status} ${res.statusText}`);
1713
+ }
1714
+ let data;
1715
+ try {
1716
+ data = await res.json();
1717
+ } catch {
1718
+ return null;
1720
1719
  }
1720
+ cache.set(fullUrl, data);
1721
1721
  return data;
1722
1722
  }).finally(() => {
1723
- inflightRequests.delete(cacheKey);
1723
+ inflightRequests.delete(fullUrl);
1724
1724
  });
1725
- inflightRequests.set(cacheKey, request);
1725
+ inflightRequests.set(fullUrl, request);
1726
1726
  return request;
1727
1727
  };
1728
- const invalidate = (endpoint, options) => {
1729
- cache.delete(getCacheKey(endpoint, options));
1728
+ const invalidate = (url) => {
1729
+ cache.delete(`${baseUrl}${url}`);
1730
1730
  };
1731
- const clearCache = () => cache.clear();
1732
- return { query, invalidate, clearCache };
1733
- };
1734
- const googleFonts = `googleFonts {
1735
- id
1736
- variants
1737
- subsets
1738
- family
1739
- version
1740
- files {
1741
- url
1742
- variant
1743
- }
1744
- category
1745
- }`;
1746
- const linkedCssChunk = `linkedCssChunk {
1747
- id
1748
- content
1749
- }`;
1750
- const linkedFragments = `{
1751
- id
1752
- document
1753
- ${googleFonts}
1754
- ${linkedCssChunk}
1755
- }`;
1756
- const fragment = `
1757
- {
1758
- id
1759
- document
1760
- linkedFragments ${linkedFragments}
1761
- ${googleFonts}
1762
- ${linkedCssChunk}
1763
- }
1764
- `;
1765
- const getFragmentQuery = (fragmentId, isSelf) => {
1766
- return {
1767
- query: isSelf ? `
1768
- query FragmentDocument($fragmentId: Int!) {
1769
- fragment(fragmentIds: [$fragmentId]) ${fragment}
1770
- }
1771
- ` : `
1772
- query FragmentDocument($fragmentId: Int!) {
1773
- clientFragment(fragmentId: $fragmentId) ${fragment}
1774
- }
1775
- }`,
1776
- variables: {
1777
- fragmentId
1778
- },
1779
- _type: null
1731
+ const clearCache = () => {
1732
+ cache.clear();
1780
1733
  };
1734
+ return { get, invalidate, clearCache };
1781
1735
  };
1782
1736
  var isObject = (input) => {
1783
1737
  return typeof input === "object" && input !== null && !Array.isArray(input);
@@ -1792,6 +1746,7 @@ var createConstants = (...constants) => {
1792
1746
  };
1793
1747
  var noop = () => void 0;
1794
1748
  var isBrowser_default = typeof window !== "undefined";
1749
+ var generateId = () => Math.random().toString(16).slice(2);
1795
1750
  var getKey = (v) => isKey(v) ? v.slice(1) : null;
1796
1751
  var isKey = (v) => typeof v === "string" && v.startsWith("$");
1797
1752
  function hashGenerator(layerKey) {
@@ -1949,159 +1904,88 @@ const fetchBeacon = (baseUrl) => {
1949
1904
  sendBeacon
1950
1905
  };
1951
1906
  };
1952
- const getAreaListQuery = (areaCodes) => {
1953
- return {
1954
- query: `query($areaCodes: [String!]!) {
1955
- clientAreas(areaCodes: $areaCodes) {
1956
- areaId
1957
- campaignId
1958
- areaProperties
1959
- projectProperties
1960
- font {
1961
- id
1962
- variants
1963
- subsets
1964
- family
1965
- version
1966
- files {
1967
- url
1968
- variant
1969
- }
1970
- category
1971
- }
1972
- variant {
1973
- id
1974
- fragment {
1975
- props
1976
- fragment ${fragment}
1977
- }
1978
- }
1979
- }
1980
- }`,
1981
- variables: {
1982
- areaCodes
1983
- }
1984
- };
1985
- };
1986
1907
  const fetchPlugin = (state) => {
1987
- var _a, _b, _c, _d;
1988
- const isSelf = ((_a = state == null ? void 0 : state.env) == null ? void 0 : _a.isSelf) ?? false;
1989
- const url = (_b = state == null ? void 0 : state.env) == null ? void 0 : _b.backendEndpoint;
1990
- const apiToken = (_c = state == null ? void 0 : state.env) == null ? void 0 : _c.apiToken;
1991
- const referer = (_d = state == null ? void 0 : state.env) == null ? void 0 : _d.referer;
1908
+ var _a, _b, _c;
1909
+ const url = (_a = state == null ? void 0 : state.env) == null ? void 0 : _a.backendEndpoint;
1910
+ const apiToken = (_b = state == null ? void 0 : state.env) == null ? void 0 : _b.apiToken;
1911
+ const referer = (_c = state == null ? void 0 : state.env) == null ? void 0 : _c.referer;
1992
1912
  let headers = {
1993
- Authorization: `Bearer ${apiToken}`
1913
+ "X-Api-Key": apiToken
1994
1914
  };
1995
1915
  if (referer) {
1996
1916
  headers.Referer = referer;
1997
1917
  }
1998
- const fetcher = createFetcher(url, headers);
1918
+ const restFetcher = createRestFetcher(url, headers);
1999
1919
  const beaconFetcher = fetchBeacon();
2000
- const registerFragmentDocument = (fragmentId, fragment2) => {
2001
- var _a2, _b2;
2002
- const fragmentDocument = fragment2 == null ? void 0 : fragment2.document;
1920
+ const registerFragmentDocument = (fragmentId, fragment) => {
1921
+ const fragmentDocument = fragment == null ? void 0 : fragment.document;
2003
1922
  if (!fragmentDocument) {
2004
1923
  console.error("Empty document");
2005
1924
  return null;
2006
1925
  }
2007
- if (fragment2) {
2008
- state.$fetch.cacheDocuments.set(fragmentId, fragmentDocument);
2009
- if (Array.isArray(fragment2.linkedFragments)) {
2010
- fragment2.linkedFragments.forEach(
2011
- (linkedFragment) => registerFragmentDocument(linkedFragment.id, linkedFragment)
2012
- );
2013
- }
2014
- if (Array.isArray(fragment2.linkedCssChunk)) {
2015
- fragment2.linkedCssChunk.forEach(
2016
- (linkedChunk) => state.$fetch.cacheCssChunks.set(linkedChunk.id, linkedChunk.content)
2017
- );
2018
- }
2019
- if ("$fonts" in state) {
2020
- (_b2 = fragment2 == null ? void 0 : fragment2.googleFonts) == null ? void 0 : _b2.forEach((_a2 = state.$fonts) == null ? void 0 : _a2.registerFont);
2021
- }
2022
- return fragmentDocument;
2023
- }
2024
- return null;
2025
- };
2026
- const queryFragment = async (fragmentId) => {
2027
- var _a2;
2028
- if (!apiToken || !fragmentId) return null;
2029
- if (state.$fetch.cacheDocuments.has(fragmentId)) {
2030
- return state.$fetch.cacheDocuments.get(fragmentId);
2031
- }
2032
- const fragmentQuery = getFragmentQuery(fragmentId, isSelf);
2033
- const response = await fetcher.query(
2034
- fragmentQuery.query,
2035
- fragmentQuery.variables,
2036
- { referrerPolicy: "unsafe-url" }
2037
- );
2038
- let fragment2 = null;
2039
- if (!!(response == null ? void 0 : response.data) && "clientFragment" in response.data) {
2040
- fragment2 = response.data.clientFragment;
1926
+ state.$fetch.cacheDocuments.set(fragmentId, fragmentDocument);
1927
+ if (fragment.linkedFragments !== void 0) {
1928
+ fragment.linkedFragments.forEach((linked) => {
1929
+ if ((linked == null ? void 0 : linked.id) && (linked == null ? void 0 : linked.document)) {
1930
+ state.$fetch.cacheDocuments.set(linked.id, linked.document);
1931
+ }
1932
+ });
2041
1933
  }
2042
- if (!!(response == null ? void 0 : response.data) && "fragment" in response.data) {
2043
- fragment2 = (_a2 = response.data.fragment) == null ? void 0 : _a2.at(0);
1934
+ if (Array.isArray(fragment.fragmentCssChunks)) {
1935
+ fragment.fragmentCssChunks.forEach(({ cssChunk }) => {
1936
+ if (cssChunk) {
1937
+ state.$fetch.cacheCssChunks.set(cssChunk.id, cssChunk.content);
1938
+ }
1939
+ });
2044
1940
  }
2045
- return registerFragmentDocument(fragmentId, fragment2);
1941
+ return fragmentDocument;
2046
1942
  };
2047
- const queryArea = async (areaCode) => {
2048
- return queryAreaList([areaCode]).then((res) => res == null ? void 0 : res.at(0));
2049
- };
2050
- const queryAreaList = async (areaCodes2) => {
2051
- var _a2;
2052
- if (!apiToken || !areaCodes2) return null;
2053
- const nonLoadedAreas = areaCodes2.filter(
1943
+ const queryAreaList = async (areaCodes) => {
1944
+ if (!apiToken || !(areaCodes == null ? void 0 : areaCodes.length)) return [];
1945
+ const nonLoadedCodes = areaCodes.filter(
2054
1946
  (code) => !state.$fetch.cacheAreaDocuments.has(code)
2055
1947
  );
2056
- if (!nonLoadedAreas.length) {
2057
- return areaCodes2.map(state.$fetch.cacheAreaDocuments.get);
1948
+ if (nonLoadedCodes.length > 0) {
1949
+ await Promise.all(
1950
+ nonLoadedCodes.map(async (code) => {
1951
+ var _a2, _b2, _c2, _d;
1952
+ const dto = await restFetcher.get(`/api/area/${code}`);
1953
+ if (!dto) return;
1954
+ const fragment = (_a2 = dto.variant) == null ? void 0 : _a2.fragment;
1955
+ if (fragment) {
1956
+ registerFragmentDocument(fragment.id, fragment);
1957
+ }
1958
+ if ("$fonts" in state && dto.font) {
1959
+ (_b2 = state.$fonts) == null ? void 0 : _b2.registerFont(dto.font);
1960
+ }
1961
+ const entity = {
1962
+ fragmentId: fragment == null ? void 0 : fragment.id,
1963
+ props: ((_c2 = dto.variant) == null ? void 0 : _c2.props) ?? {},
1964
+ font: dto.font,
1965
+ areaId: dto.areaId,
1966
+ campaignId: dto.campaignId,
1967
+ variantId: (_d = dto.variant) == null ? void 0 : _d.id
1968
+ };
1969
+ state.$fetch.cacheAreaDocuments.set(code, entity);
1970
+ })
1971
+ );
2058
1972
  }
2059
- const areaQuery = getAreaListQuery(areaCodes2);
2060
- const response = await fetcher.query(
2061
- areaQuery.query,
2062
- areaQuery.variables,
2063
- { referrerPolicy: "unsafe-url" }
1973
+ return areaCodes.map(
1974
+ (code) => state.$fetch.cacheAreaDocuments.get(code) ?? null
2064
1975
  );
2065
- const areas = (_a2 = response == null ? void 0 : response.data) == null ? void 0 : _a2.clientAreas;
2066
- if (areas) {
2067
- areas.forEach((area, index2) => {
2068
- var _a3;
2069
- const areaCode = areaCodes2 == null ? void 0 : areaCodes2.at(index2);
2070
- const areaFragment = area.variant.fragment.fragment;
2071
- registerFragmentDocument(areaFragment.id, areaFragment);
2072
- const resultProps = [
2073
- ...area.projectProperties ?? [],
2074
- ...area.areaProperties ?? []
2075
- ].reduce((acc, prop) => {
2076
- acc[prop._id] = prop.defaultValue;
2077
- return acc;
2078
- }, area.variant.fragment.props);
2079
- const entity = {
2080
- areaId: area.areaId,
2081
- campaignId: area.campaignId,
2082
- variantId: area.variant.id,
2083
- fragmentId: area.variant.fragment.fragment.id,
2084
- font: area.font,
2085
- props: resultProps
2086
- };
2087
- if ("$fonts" in state) {
2088
- (_a3 = state.$fonts) == null ? void 0 : _a3.registerFont(area.font);
2089
- }
2090
- state.$fetch.cacheAreaDocuments.set(areaCode, entity);
2091
- });
2092
- return areaCodes2.map((code) => state.$fetch.cacheAreaDocuments.get(code));
2093
- }
2094
- return null;
1976
+ };
1977
+ const queryArea = async (areaCode) => {
1978
+ return queryAreaList([areaCode]).then((res) => (res == null ? void 0 : res.at(0)) ?? null);
2095
1979
  };
2096
1980
  state.$fetch = {
2097
1981
  cacheCssChunks: /* @__PURE__ */ new Map(),
2098
1982
  cacheDocuments: /* @__PURE__ */ new Map(),
2099
1983
  cacheAreaDocuments: /* @__PURE__ */ new Map(),
2100
- queryFragment,
1984
+ registerFragmentDocument,
2101
1985
  queryArea,
2102
1986
  queryAreaList,
2103
- query: fetcher.query,
2104
1987
  sendBeacon: beaconFetcher.sendBeacon,
1988
+ get: restFetcher.get,
2105
1989
  readCssChunk: (id) => state.$fetch.cacheCssChunks.get(id) ?? null,
2106
1990
  readFragment: (fragmentId) => state.$fetch.cacheDocuments.get(fragmentId) ?? null,
2107
1991
  readArea: (areaCode) => state.$fetch.cacheAreaDocuments.get(areaCode) ?? null
@@ -2404,6 +2288,84 @@ const scopesPlugin = (state) => {
2404
2288
  };
2405
2289
  return state;
2406
2290
  };
2291
+ const PROPERTIES_ROOT_KEY = "PropertiesRoot:root";
2292
+ const propertiesPlugin = (state) => {
2293
+ const hydrate = (properties) => {
2294
+ if (!Array.isArray(properties)) return;
2295
+ const keys = [];
2296
+ for (const prop of properties) {
2297
+ if (!prop || !prop._id) continue;
2298
+ const key = `${index.nodes.Variable}:${prop._id}`;
2299
+ state.mutate(
2300
+ { ...prop, _type: index.nodes.Variable, _id: String(prop._id) },
2301
+ { replace: true }
2302
+ );
2303
+ keys.push(key);
2304
+ }
2305
+ state.mutate(
2306
+ PROPERTIES_ROOT_KEY,
2307
+ { propertyKeys: keys },
2308
+ { replace: true }
2309
+ );
2310
+ };
2311
+ const addProperty = (type, initialData) => {
2312
+ const id = (initialData == null ? void 0 : initialData._id) || generateId();
2313
+ const key = `${index.nodes.Variable}:${id}`;
2314
+ state.mutate({
2315
+ _type: index.nodes.Variable,
2316
+ _id: String(id),
2317
+ type,
2318
+ name: `${type} property`,
2319
+ ...initialData
2320
+ });
2321
+ const root = state.resolve(PROPERTIES_ROOT_KEY);
2322
+ const currentKeys = (root == null ? void 0 : root.propertyKeys) ?? [];
2323
+ state.mutate(
2324
+ PROPERTIES_ROOT_KEY,
2325
+ { propertyKeys: [...currentKeys, key] },
2326
+ { replace: true }
2327
+ );
2328
+ return key;
2329
+ };
2330
+ const removeProperty = (key) => {
2331
+ state.invalidate(key);
2332
+ const root = state.resolve(PROPERTIES_ROOT_KEY);
2333
+ const currentKeys = (root == null ? void 0 : root.propertyKeys) ?? [];
2334
+ state.mutate(
2335
+ PROPERTIES_ROOT_KEY,
2336
+ { propertyKeys: currentKeys.filter((k) => k !== key) },
2337
+ { replace: true }
2338
+ );
2339
+ };
2340
+ const extractProperties = () => {
2341
+ const root = state.resolve(PROPERTIES_ROOT_KEY);
2342
+ const keys = (root == null ? void 0 : root.propertyKeys) ?? [];
2343
+ return keys.map((key) => state.resolve(key, { deep: true })).filter(Boolean);
2344
+ };
2345
+ const getPropertyKeys = () => {
2346
+ const root = state.resolve(PROPERTIES_ROOT_KEY);
2347
+ return (root == null ? void 0 : root.propertyKeys) ?? [];
2348
+ };
2349
+ state.addSkip((dataField) => {
2350
+ if (typeof dataField === "object" && dataField !== null && !Array.isArray(dataField)) {
2351
+ return dataField._type === index.nodes.Variable && (dataField._id === "replaceBeforeSave" || !dataField._id);
2352
+ }
2353
+ return false;
2354
+ });
2355
+ state.mutate({
2356
+ _type: "PropertiesRoot",
2357
+ _id: "root",
2358
+ propertyKeys: []
2359
+ });
2360
+ state.$properties = {
2361
+ key: PROPERTIES_ROOT_KEY,
2362
+ hydrate,
2363
+ addProperty,
2364
+ removeProperty,
2365
+ extractProperties,
2366
+ getPropertyKeys
2367
+ };
2368
+ };
2407
2369
  const fragmentsPlugin = (options) => (state) => {
2408
2370
  const plugins = (options == null ? void 0 : options.plugins) ?? [];
2409
2371
  const createFragmentManager = (fragmentId, initialDocument = {}) => {
@@ -2440,6 +2402,7 @@ const fragmentsPlugin = (options) => (state) => {
2440
2402
  // cssPlugin,
2441
2403
  fragmentStylesheetPlugin(state),
2442
2404
  scopesPlugin,
2405
+ propertiesPlugin,
2443
2406
  ...plugins
2444
2407
  ],
2445
2408
  skip: [
@@ -2450,12 +2413,19 @@ const fragmentsPlugin = (options) => (state) => {
2450
2413
  ...Object.keys(index.nodes),
2451
2414
  "Temp",
2452
2415
  "Spring",
2453
- PLUGIN_TYPES.FragmentStylesheet
2416
+ PLUGIN_TYPES.FragmentStylesheet,
2417
+ "PropertiesRoot"
2454
2418
  ])
2455
2419
  ]
2456
2420
  });
2457
2421
  manager.mutate(tempGraph);
2458
2422
  manager.mutate(springGraph);
2423
+ const fragmentRoot = manager.resolve(manager.$fragment.root);
2424
+ const propertyLinks = (fragmentRoot == null ? void 0 : fragmentRoot.properties) ?? [];
2425
+ const propertyEntities = propertyLinks.map((link) => manager.resolve(link)).filter(Boolean);
2426
+ if (propertyEntities.length > 0) {
2427
+ manager.$properties.hydrate(propertyEntities);
2428
+ }
2459
2429
  state.mutate(state.$fragments.key, {
2460
2430
  managers: {
2461
2431
  [fragmentId]: manager
@@ -2484,9 +2454,6 @@ const fragmentsPlugin = (options) => (state) => {
2484
2454
  });
2485
2455
  return state;
2486
2456
  };
2487
- const addClientMetric = `mutation AddClientMetric($type: ClientMetricType!, $value: GoalAchievementPost!) {
2488
- addClientMetric(metric: {metricType: $type, achievement: $value})
2489
- }`;
2490
2457
  const pendingPixels = /* @__PURE__ */ new Set();
2491
2458
  const sendWithImage = (url) => {
2492
2459
  try {
@@ -2560,10 +2527,16 @@ const types = createConstants(
2560
2527
  "REACH_PROJECT_GOAL"
2561
2528
  );
2562
2529
  const globalMetricsPlugin = (state) => {
2563
- const sendMetric = async (type, value) => {
2530
+ const sendMetric = (type, value) => {
2564
2531
  var _a;
2565
- const query = (_a = state == null ? void 0 : state.$fetch) == null ? void 0 : _a.query;
2566
- await query(addClientMetric, { type, value });
2532
+ if (type !== types.REACH_PROJECT_GOAL || !value) return;
2533
+ const params = new URLSearchParams({
2534
+ goal_id: String(value.goalId),
2535
+ variant_id: String(value.variantId),
2536
+ area_id: String(value.areaId),
2537
+ campaign_id: String(value.campaignId)
2538
+ });
2539
+ (_a = state.$fetch) == null ? void 0 : _a.get(`/api/metric/goal?${params}`).catch(() => void 0);
2567
2540
  };
2568
2541
  const reachGoal = (goal) => {
2569
2542
  sendMetric(types.REACH_PROJECT_GOAL, goal);
@@ -2582,76 +2555,24 @@ const loadPlugin = (state) => {
2582
2555
  console.error("LoadFragmentPlugin depends from Fetch and Fragments plugin");
2583
2556
  return state;
2584
2557
  }
2585
- const resourceCache = /* @__PURE__ */ new Map();
2586
- const createSuspenseResource = (key, fetcher) => {
2587
- if (resourceCache.has(key)) return resourceCache.get(key);
2588
- let status = "pending";
2589
- let result;
2590
- const suspender = fetcher().then(
2591
- (r2) => {
2592
- status = "success";
2593
- result = r2;
2594
- },
2595
- (e) => {
2596
- status = "error";
2597
- result = e;
2598
- }
2599
- );
2600
- const resource = {
2601
- read() {
2602
- if (status === "pending") throw suspender;
2603
- if (status === "error") throw result;
2604
- return result;
2605
- }
2606
- };
2607
- resourceCache.set(key, resource);
2608
- return resource;
2609
- };
2610
- const loadFragment = (fragmentId, options) => {
2558
+ const loadFragment = (fragmentId) => {
2611
2559
  var _a, _b;
2612
- const suspense = options == null ? void 0 : options.suspense;
2613
2560
  const readFragment = (_a = state == null ? void 0 : state.$fetch) == null ? void 0 : _a.readFragment(fragmentId);
2614
2561
  const fragmentManager = (_b = state == null ? void 0 : state.$fragments) == null ? void 0 : _b.getManager(fragmentId);
2615
2562
  if (readFragment && !fragmentManager) {
2616
- const fragmentManager2 = state.$fragments.createFragmentManager(
2617
- fragmentId,
2618
- readFragment
2619
- );
2620
- return fragmentManager2;
2563
+ return state.$fragments.createFragmentManager(fragmentId, readFragment);
2621
2564
  }
2622
2565
  if (readFragment && fragmentManager) return fragmentManager;
2623
- const loader = async () => {
2624
- var _a2;
2625
- const fragmentDocument = await ((_a2 = state == null ? void 0 : state.$fetch) == null ? void 0 : _a2.queryFragment(fragmentId));
2626
- return state.$fragments.createFragmentManager(
2627
- fragmentId,
2628
- fragmentDocument
2629
- );
2630
- };
2631
- if (suspense) {
2632
- const resource = createSuspenseResource(fragmentId, loader);
2633
- return resource.read();
2634
- }
2635
- return loader();
2566
+ return null;
2636
2567
  };
2637
- const loadArea = (areaCode, options) => {
2568
+ const loadArea = (areaCode) => {
2638
2569
  var _a;
2639
- const suspense = options == null ? void 0 : options.suspense;
2640
2570
  const readArea2 = (_a = state == null ? void 0 : state.$fetch) == null ? void 0 : _a.readArea(areaCode);
2641
2571
  if (readArea2) return readArea2;
2642
- const loader = async () => {
2643
- var _a2;
2644
- const areaEntity = await ((_a2 = state == null ? void 0 : state.$fetch) == null ? void 0 : _a2.queryArea(areaCode));
2645
- await loadFragment(areaEntity == null ? void 0 : areaEntity.fragmentId, {
2646
- suspense: false
2647
- });
2572
+ return state.$fetch.queryArea(areaCode).then((areaEntity) => {
2573
+ loadFragment(areaEntity == null ? void 0 : areaEntity.fragmentId);
2648
2574
  return areaEntity;
2649
- };
2650
- if (suspense) {
2651
- const resource = createSuspenseResource(areaCode, loader);
2652
- return resource.read();
2653
- }
2654
- return loader();
2575
+ });
2655
2576
  };
2656
2577
  const readArea = () => {
2657
2578
  return state;
@@ -2666,6 +2587,7 @@ const fontsPlugin = (state) => {
2666
2587
  const fonts = /* @__PURE__ */ new Map();
2667
2588
  let defaultFontFamily = null;
2668
2589
  const registerFont = (font) => {
2590
+ if (!font) return;
2669
2591
  const fontFamily = font.family;
2670
2592
  if (!fonts.has(fontFamily)) {
2671
2593
  fonts.set(fontFamily, font);
@@ -2679,7 +2601,8 @@ const fontsPlugin = (state) => {
2679
2601
  const getStyles = () => {
2680
2602
  const styles = [];
2681
2603
  for (const [fontFamily, font] of fonts) {
2682
- const files = font.files ?? [];
2604
+ const rawFiles = font.files ?? [];
2605
+ const files = Array.isArray(rawFiles) ? rawFiles : Object.entries(rawFiles).map(([variant, url]) => ({ variant, url }));
2683
2606
  for (const file of files) {
2684
2607
  const [weightItem] = getFontWeights([file.variant]);
2685
2608
  styles.push(`@font-face {
@@ -2718,27 +2641,27 @@ const PLUGIN_TYPES = createConstants(
2718
2641
  "FragmentStylesheet"
2719
2642
  );
2720
2643
  const createFragmentsClient = (options) => {
2721
- const BACKEND_TARGET = (options == null ? void 0 : options.isSelf) ? "/graphql" : "http://85.192.29.65/graphql";
2722
2644
  return kt({
2723
2645
  _type: "GlobalManager",
2724
2646
  initialState: {},
2725
2647
  skip: [
2726
2648
  u([
2727
2649
  ...Object.keys(index.nodes),
2728
- ...Object.keys(PLUGIN_TYPES)
2650
+ ...Object.keys(PLUGIN_TYPES),
2651
+ "PropertiesRoot"
2729
2652
  ])
2730
2653
  ],
2731
2654
  plugins: [
2732
2655
  (state) => {
2733
2656
  state.env = {
2734
- isSelf: (options == null ? void 0 : options.isSelf) ?? false,
2735
- backendEndpoint: (options == null ? void 0 : options.backendEndpoint) ?? BACKEND_TARGET,
2657
+ backendEndpoint: (options == null ? void 0 : options.backendEndpoint) ?? "https://client-api.fragmentsx.com",
2736
2658
  apiToken: options == null ? void 0 : options.apiToken,
2737
2659
  referer: options == null ? void 0 : options.referer
2738
2660
  };
2739
2661
  },
2740
2662
  fetchPlugin,
2741
2663
  fontsPlugin,
2664
+ propertiesPlugin,
2742
2665
  fragmentsPlugin({
2743
2666
  plugins: options == null ? void 0 : options.fragmentPlugins
2744
2667
  }),
@@ -2749,6 +2672,39 @@ const createFragmentsClient = (options) => {
2749
2672
  ]
2750
2673
  });
2751
2674
  };
2675
+ const areaMetaPlugin = (options) => (state) => {
2676
+ state.$area = {
2677
+ areaId: options.areaId,
2678
+ campaignId: options.campaignId,
2679
+ variantId: options.variantId
2680
+ };
2681
+ };
2682
+ const createAreaManager = (options) => {
2683
+ var _a;
2684
+ const manager = kt({
2685
+ _type: "AreaManager",
2686
+ _id: String(options.areaId),
2687
+ initialState: {},
2688
+ skip: [
2689
+ u([
2690
+ ...Object.keys(index.nodes),
2691
+ "PropertiesRoot"
2692
+ ])
2693
+ ],
2694
+ plugins: [
2695
+ areaMetaPlugin({
2696
+ areaId: options.areaId,
2697
+ campaignId: options.campaignId,
2698
+ variantId: options.variantId
2699
+ }),
2700
+ propertiesPlugin
2701
+ ]
2702
+ });
2703
+ if ((_a = options.areaProperties) == null ? void 0 : _a.length) {
2704
+ manager.$properties.hydrate(options.areaProperties);
2705
+ }
2706
+ return manager;
2707
+ };
2752
2708
  const ssrPlugin = (state) => {
2753
2709
  var _a, _b, _c;
2754
2710
  if (!["$fragments"].every((field) => field in state)) {
@@ -2809,6 +2765,8 @@ function createTestFragmentsClient(options) {
2809
2765
  }
2810
2766
  return client;
2811
2767
  }
2768
+ exports.createAreaManager = createAreaManager;
2812
2769
  exports.createFragmentsClient = createFragmentsClient;
2813
2770
  exports.createTestFragmentsClient = createTestFragmentsClient;
2771
+ exports.propertiesPlugin = propertiesPlugin;
2814
2772
  exports.ssrPlugin = ssrPlugin;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export { createFragmentsClient } from './fragmentsClient';
2
+ export { createAreaManager } from './createAreaManager';
2
3
  export { ssrPlugin } from './plugins/ssr';
4
+ export { propertiesPlugin } from './plugins/properties';
3
5
  export { createTestFragmentsClient, type TestFragmentsClientOptions, type FragmentDocument, type AreaCacheEntity, } from './testing/createTestFragmentsClient';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EACL,yBAAyB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,qCAAqC,CAAC"}