gemi 0.54.0 → 0.54.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 (30) hide show
  1. package/dist/{chunk-26r8dcxd.js → chunk-05edp1zf.js} +2 -2
  2. package/dist/{chunk-26r8dcxd.js.map → chunk-05edp1zf.js.map} +1 -1
  3. package/dist/{chunk-ywr2vd5r.js → chunk-3xa807p3.js} +1 -1
  4. package/dist/{chunk-2zmz3pjk.js → chunk-efp54183.js} +1 -1
  5. package/dist/{chunk-kkkqyvwv.js → chunk-n382ygnp.js} +12 -12
  6. package/dist/{chunk-kkkqyvwv.js.map → chunk-n382ygnp.js.map} +3 -3
  7. package/dist/{chunk-c2pv3ah8.js → chunk-qq2yhtpp.js} +1 -1
  8. package/dist/chunks/{ThemeProvider-Bk1eZymb.js → ThemeProvider-li1J_igh.js} +26 -2
  9. package/dist/chunks/ThemeProvider-li1J_igh.js.map +1 -0
  10. package/dist/client/QueryManagerContext.d.ts +10 -0
  11. package/dist/client/QueryManagerContext.d.ts.map +1 -1
  12. package/dist/client/QueryResource.d.ts +12 -0
  13. package/dist/client/QueryResource.d.ts.map +1 -1
  14. package/dist/client/index.js +85 -13
  15. package/dist/client/index.js.map +1 -1
  16. package/dist/client/useLocale.d.ts.map +1 -1
  17. package/dist/client/useQuery.d.ts +15 -0
  18. package/dist/client/useQuery.d.ts.map +1 -1
  19. package/dist/facades/index.js +1 -1
  20. package/dist/i18n/I18nRouter.d.ts.map +1 -1
  21. package/dist/i18n/index.js +1 -1
  22. package/dist/kernel/index.js +1 -1
  23. package/dist/server/index.js +1 -1
  24. package/dist/services/index.js +1 -1
  25. package/dist/testing/index.js +1 -1
  26. package/package.json +1 -1
  27. package/dist/chunks/ThemeProvider-Bk1eZymb.js.map +0 -1
  28. /package/dist/{chunk-ywr2vd5r.js.map → chunk-3xa807p3.js.map} +0 -0
  29. /package/dist/{chunk-2zmz3pjk.js.map → chunk-efp54183.js.map} +0 -0
  30. /package/dist/{chunk-c2pv3ah8.js.map → chunk-qq2yhtpp.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"QueryResource.d.ts","sourceRoot":"","sources":["../../client/QueryResource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;IACV;;;;;;OAMG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,qBAAa,aAAa;IACxB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACnC,aAAa,cAAqB;IAClC,eAAe,sBAA6B;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAqB;IACrC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,CAA+B;gBAElC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAM1D;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS;IAsC5D,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,OAAO;IAQf;;;;;;;;;;OAUG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM;IAIvB;;;;;;;;OAQG;IACH,IAAI,CACF,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAA2B,GACrC;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE;IA+B7C,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B;IA2BrE;;;;OAIG;IACH,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM;IAe9B,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAoB;IAwClE,OAAO,CAAC,UAAU,EAAE,MAAM;YAIZ,cAAc;CA6E7B"}
1
+ {"version":3,"file":"QueryResource.d.ts","sourceRoot":"","sources":["../../client/QueryResource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,GAAG,CAAC;IACV;;;;;;OAMG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,qBAAa,aAAa;IACxB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IACnC,aAAa,cAAqB;IAClC,eAAe,sBAA6B;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAqB;IACrC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,CAA+B;gBAElC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAM1D;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS;IAsC5D,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,OAAO;IAQf;;;;;;;;;;OAUG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM;IAIvB;;;;;;;;OAQG;IACH,IAAI,CACF,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAA2B,GACrC;QAAE,KAAK,CAAC,EAAE,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE;IA+B7C,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B;IA2BrE;;;;;;;;;;OAUG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAA2B;IAcrE;;;;OAIG;IACH,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM;IAe9B,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,GAAE,CAAC,IAAI,EAAE,GAAG,KAAK,GAAoB;IAwClE,OAAO,CAAC,UAAU,EAAE,MAAM;YAIZ,cAAc;CA6E7B"}
@@ -1,4 +1,4 @@
1
- import { B as QueryError, C as I18nContext, D as useLocation, E as ServerDataProvider, F as applyParams$1, I as QueryConfigContext, L as QueryManagerContext, M as RouteStateContext, N as RouteStateProvider, P as toVariantKey, R as QueryManagerProvider, S as useNavigate, T as ServerDataContext, V as Subject, _ as setActiveLocale, a as m, b as useRoute, c as ClientRouterContext, d as ComponentsProvider, f as loadViewModule, g as registerDictionary, h as loadDictionaryForRender, i as WebSocketContextProvider, j as useParams, k as Action, l as ClientRouterProvider, m as loadDictionary, n as useTheme, o as RouteTransitionProvider, p as subscribeViewModules, r as WebSocketContext, s as useRouteTransition, t as ThemeProvider, u as ComponentsContext, v as readRoutePayload, w as I18nProvider, x as useSearchParams, y as routeDataUrl, z as DEFAULT_STALE_TIME } from "../chunks/ThemeProvider-Bk1eZymb.js";
1
+ import { B as QueryError, C as I18nContext, D as useLocation, E as ServerDataProvider, F as applyParams$1, I as QueryConfigContext, L as QueryManagerContext, M as RouteStateContext, N as RouteStateProvider, P as toVariantKey, R as QueryManagerProvider, S as useNavigate, T as ServerDataContext, V as Subject, _ as setActiveLocale, a as m, b as useRoute, c as ClientRouterContext, d as ComponentsProvider, f as loadViewModule, g as registerDictionary, h as loadDictionaryForRender, i as WebSocketContextProvider, j as useParams, k as Action, l as ClientRouterProvider, m as loadDictionary, n as useTheme, o as RouteTransitionProvider, p as subscribeViewModules, r as WebSocketContext, s as useRouteTransition, t as ThemeProvider, u as ComponentsContext, v as readRoutePayload, w as I18nProvider, x as useSearchParams, y as routeDataUrl, z as DEFAULT_STALE_TIME } from "../chunks/ThemeProvider-li1J_igh.js";
2
2
  import { Fragment, StrictMode, Suspense, createContext, createElement, isValidElement, memo, use, useCallback, useContext, useDeferredValue, useEffect, useMemo, useRef, useState, useSyncExternalStore, useTransition } from "react";
3
3
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { createRoot as createRoot$1, hydrateRoot } from "react-dom/client";
@@ -32,6 +32,8 @@ var defaultConfig = {
32
32
  keepPreviousData: true,
33
33
  retryIntervalOnError: 1e4,
34
34
  refreshInterval: 999999,
35
+ revalidateOnFocus: false,
36
+ focusThrottleInterval: 5e3,
35
37
  staleTime: DEFAULT_STALE_TIME,
36
38
  debug: false,
37
39
  lazy: false,
@@ -95,6 +97,9 @@ function useFrameworkQuery(url, ...args) {
95
97
  const refetchUntilTimerRef = useRef(null);
96
98
  const refetchUntilDurationRef = useRef(0);
97
99
  const prefetchedRef = useRef(false);
100
+ const focusEligibleRef = useRef(!lazy);
101
+ const wasAwayRef = useRef(false);
102
+ const lastFocusRevalidationRef = useRef(0);
98
103
  const subscribe = useCallback((onStoreChange) => resource.store.subscribe(onStoreChange), [resource]);
99
104
  const getSnapshot = useCallback(() => resource.peek(variantKey), [resource, variantKey]);
100
105
  const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
@@ -188,6 +193,38 @@ function useFrameworkQuery(url, ...args) {
188
193
  if (refreshIntervalRef.current) clearInterval(refreshIntervalRef.current);
189
194
  };
190
195
  }, [config.refreshInterval, handleReload]);
196
+ useEffect(() => {
197
+ if (!config.revalidateOnFocus) return;
198
+ const markAway = () => {
199
+ wasAwayRef.current = true;
200
+ };
201
+ const revalidate = () => {
202
+ if (!focusEligibleRef.current) return;
203
+ if (document.visibilityState === "hidden") return;
204
+ if (!wasAwayRef.current) return;
205
+ const now = Date.now();
206
+ if (now - lastFocusRevalidationRef.current < configRef.current.focusThrottleInterval) return;
207
+ wasAwayRef.current = false;
208
+ lastFocusRevalidationRef.current = now;
209
+ resource.revalidate(variantKey, configRef.current.staleTime);
210
+ };
211
+ const onVisibilityChange = () => {
212
+ if (document.visibilityState === "hidden") markAway();
213
+ else revalidate();
214
+ };
215
+ window.addEventListener("blur", markAway);
216
+ window.addEventListener("focus", revalidate);
217
+ document.addEventListener("visibilitychange", onVisibilityChange);
218
+ return () => {
219
+ window.removeEventListener("blur", markAway);
220
+ window.removeEventListener("focus", revalidate);
221
+ document.removeEventListener("visibilitychange", onVisibilityChange);
222
+ };
223
+ }, [
224
+ config.revalidateOnFocus,
225
+ resource,
226
+ variantKey
227
+ ]);
191
228
  useEffect(() => {
192
229
  if (typeof import.meta.hot?.on === "function") import.meta.hot.on("http-reload", handleReload);
193
230
  return () => {
@@ -196,6 +233,7 @@ function useFrameworkQuery(url, ...args) {
196
233
  }, [handleReload]);
197
234
  const trigger = useCallback(() => {
198
235
  fetchedRef.current = true;
236
+ focusEligibleRef.current = true;
199
237
  const variant = resource.store.getValue().get(variantKey);
200
238
  if (!variant || !variant.loading && !variant.hasData) resource.refetch(variantKey);
201
239
  }, [resource, variantKey]);
@@ -207,9 +245,11 @@ function useFrameworkQuery(url, ...args) {
207
245
  }, [resource, variantKey]);
208
246
  const refetch = useCallback(() => {
209
247
  fetchedRef.current = true;
248
+ focusEligibleRef.current = true;
210
249
  resource.refetch(variantKey);
211
250
  }, [resource, variantKey]);
212
251
  function mutate(fn) {
252
+ focusEligibleRef.current = true;
213
253
  if (!fn) {
214
254
  fetchedRef.current = true;
215
255
  resource.refetch(variantKey);
@@ -1699,26 +1739,58 @@ function createHandle(id, locales, load) {
1699
1739
  }
1700
1740
  //#endregion
1701
1741
  //#region client/useLocale.ts
1702
- var setCookie = async (locale) => {
1742
+ var LOCALE_COOKIE = "i18n-locale";
1743
+ var LOCALE_COOKIE_MAX_AGE = 3600 * 24 * 365;
1744
+ /**
1745
+ * The active locale lives in two places: the URL segment `setLocale` navigates
1746
+ * to, and the `i18n-locale` cookie the server falls back to when the URL has no
1747
+ * segment — which is exactly the case for the default locale. Both have to be in
1748
+ * place *before* the navigation asks for route data, or `Translator.detectLocale`
1749
+ * answers the request with a redirect back to the locale the cookie still names.
1750
+ *
1751
+ * Hence a synchronous `document.cookie` write rather than an awaited one. The
1752
+ * previous implementation awaited `cookieStore.set()` and hung the navigation off
1753
+ * its `.then()`; that promise is reported to never settle on iOS Safari, so the
1754
+ * `.then()` never ran and changing the language became a silent no-op — no
1755
+ * rejection, nothing for an error reporter to pick up. A synchronous write cannot
1756
+ * hang and cannot fail asynchronously, so nothing is left to gate navigation on.
1757
+ */
1758
+ function persistLocale(locale) {
1759
+ if (typeof document === "undefined") return;
1703
1760
  try {
1704
- return await globalThis.cookieStore.set("i18n-locale", locale);
1705
- } catch (err) {
1706
- return await fetch(`/api/__gemi__/services/i18n/set-locale/${locale}`);
1707
- }
1708
- };
1761
+ document.cookie = [
1762
+ `${LOCALE_COOKIE}=${encodeURIComponent(locale)}`,
1763
+ `Max-Age=${LOCALE_COOKIE_MAX_AGE}`,
1764
+ "SameSite=Strict",
1765
+ "Path=/"
1766
+ ].join("; ");
1767
+ } catch {}
1768
+ }
1769
+ /**
1770
+ * `onLocaleChange` is a server-side hook, so it takes a request to fire it. The
1771
+ * switch must not wait on that round trip, nor be cancelled by one that fails —
1772
+ * including one that fails *synchronously*: `fetch` is absent in some old
1773
+ * WebViews, and an unguarded call would throw before the navigation ran, which
1774
+ * is the same silent no-op this hook exists to prevent through another door.
1775
+ */
1776
+ function notifyLocaleChange(locale) {
1777
+ try {
1778
+ fetch(`/api/__gemi__/services/i18n/set-locale/${encodeURIComponent(locale)}`).catch(() => {});
1779
+ } catch {}
1780
+ }
1709
1781
  function useLocale() {
1710
1782
  const { i18n } = useRouteData();
1711
1783
  const { pathname, search } = useLocation();
1712
1784
  const { replace } = useNavigate();
1713
1785
  const params = useParams();
1714
1786
  const setLocale = async (locale) => {
1787
+ persistLocale(locale);
1788
+ notifyLocaleChange(locale);
1715
1789
  const urlSearchParams = new URLSearchParams(search);
1716
- setCookie(locale).then(() => {
1717
- replace(pathname, {
1718
- locale,
1719
- search: Object.fromEntries(urlSearchParams.entries()),
1720
- params
1721
- });
1790
+ await replace(pathname, {
1791
+ locale,
1792
+ search: Object.fromEntries(urlSearchParams.entries()),
1793
+ params
1722
1794
  });
1723
1795
  };
1724
1796
  return [i18n.currentLocale, setLocale];