@luckystack/core 0.14.0 → 0.15.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 (35) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/bootUuid.d.ts +16 -0
  3. package/dist/{chunk-PN2FPJXI.js → chunk-55YXIACQ.js} +1 -1
  4. package/dist/chunk-55YXIACQ.js.map +1 -0
  5. package/dist/{chunk-RC7ZQBO6.js → chunk-EZIBIQXO.js} +3 -3
  6. package/dist/{chunk-C4AK6P5D.js → chunk-NJULJZ3N.js} +29 -17
  7. package/dist/chunk-NJULJZ3N.js.map +1 -0
  8. package/dist/{chunk-6UPWMV6L.js → chunk-YKVBUWB6.js} +2 -2
  9. package/dist/chunk-YKVBUWB6.js.map +1 -0
  10. package/dist/client.d.ts +1 -1
  11. package/dist/client.js +74 -12
  12. package/dist/client.js.map +1 -1
  13. package/dist/config.js +2 -2
  14. package/dist/deployConfigRegistry.d.ts +3 -1
  15. package/dist/emailRegistry.d.ts +2 -1
  16. package/dist/errorTrackerIdentity.d.ts +2 -0
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +134 -31
  19. package/dist/index.js.map +1 -1
  20. package/dist/localSocketEnumerationGuard.d.ts +2 -1
  21. package/dist/middlewareRegistry.d.ts +13 -1
  22. package/dist/{projectConfig-EOJRMH36.js → projectConfig-6QNMG5GZ.js} +2 -2
  23. package/dist/projectConfig.d.ts +13 -9
  24. package/dist/react/languageOverride.d.ts +8 -0
  25. package/dist/redactedLogKeys.d.ts +2 -0
  26. package/dist/roomNameFormatterRegistry.d.ts +7 -5
  27. package/dist/{sentrySetup-T7535RYZ.js → sentrySetup-MZTUOMHL.js} +3 -3
  28. package/dist/sessionProviderRegistry.d.ts +14 -6
  29. package/package.json +1 -1
  30. package/dist/chunk-6UPWMV6L.js.map +0 -1
  31. package/dist/chunk-C4AK6P5D.js.map +0 -1
  32. package/dist/chunk-PN2FPJXI.js.map +0 -1
  33. /package/dist/{chunk-RC7ZQBO6.js.map → chunk-EZIBIQXO.js.map} +0 -0
  34. /package/dist/{projectConfig-EOJRMH36.js.map → projectConfig-6QNMG5GZ.js.map} +0 -0
  35. /package/dist/{sentrySetup-T7535RYZ.js.map → sentrySetup-MZTUOMHL.js.map} +0 -0
package/dist/client.js CHANGED
@@ -43,16 +43,16 @@ import {
43
43
  tryCatchSync,
44
44
  validatePagePath,
45
45
  waitForSocket
46
- } from "./chunk-RC7ZQBO6.js";
46
+ } from "./chunk-EZIBIQXO.js";
47
47
  import {
48
48
  getLogger,
49
49
  registerLogger
50
- } from "./chunk-C4AK6P5D.js";
50
+ } from "./chunk-NJULJZ3N.js";
51
51
  import {
52
52
  getProjectConfig,
53
53
  isProjectConfigRegistered,
54
54
  registerProjectConfig
55
- } from "./chunk-PN2FPJXI.js";
55
+ } from "./chunk-55YXIACQ.js";
56
56
 
57
57
  // src/apiInterceptors.ts
58
58
  var requestInterceptors = /* @__PURE__ */ new Set();
@@ -103,7 +103,7 @@ async function tryCatch(func, params, context) {
103
103
  const response = await func(params);
104
104
  return [null, response];
105
105
  } catch (error) {
106
- const { captureException } = await import("./sentrySetup-T7535RYZ.js");
106
+ const { captureException } = await import("./sentrySetup-MZTUOMHL.js");
107
107
  captureException(error, context);
108
108
  return [error instanceof Error ? error : new Error(String(error)), null];
109
109
  }
@@ -442,11 +442,14 @@ function apiRequest(params) {
442
442
  responseTimeout = null;
443
443
  }
444
444
  };
445
+ let ownAbortController = null;
445
446
  const cleanupAbortController = () => {
446
447
  if (signal && abortHandler) {
447
448
  signal.removeEventListener("abort", abortHandler);
448
449
  }
449
- abortControllers.delete(abortKey);
450
+ if (ownAbortController && abortControllers.get(abortKey) === ownAbortController) {
451
+ abortControllers.delete(abortKey);
452
+ }
450
453
  };
451
454
  if (useAbortController) {
452
455
  if (abortControllers.has(abortKey)) {
@@ -458,6 +461,7 @@ function apiRequest(params) {
458
461
  if (oldest !== void 0) abortControllers.delete(oldest);
459
462
  }
460
463
  const abortController = new AbortController();
464
+ ownAbortController = abortController;
461
465
  abortControllers.set(abortKey, abortController);
462
466
  signal = abortController.signal;
463
467
  abortHandler = () => {
@@ -755,11 +759,49 @@ var registerMiddlewareHandler = (handler) => {
755
759
  };
756
760
  var getMiddlewareHandler = () => activeHandler;
757
761
  var pageMiddlewares = /* @__PURE__ */ new Map();
762
+ var pageRoutes = /* @__PURE__ */ new Set();
763
+ var registerPageRoute = (path) => {
764
+ pageRoutes.add(path);
765
+ };
758
766
  var registerPageMiddleware = (path, middleware) => {
767
+ pageRoutes.add(path);
759
768
  pageMiddlewares.set(path, middleware);
760
769
  };
761
770
  var getPageMiddleware = (path) => pageMiddlewares.get(path);
762
771
  var hasPageMiddleware = (path) => pageMiddlewares.has(path);
772
+ var splitPath = (path) => {
773
+ const withoutSuffix = path.split(/[?#]/, 1)[0] ?? "";
774
+ return withoutSuffix.split("/").filter((segment) => segment.length > 0);
775
+ };
776
+ var decodeSegment = (segment) => {
777
+ const [error, decoded] = tryCatchSync(() => decodeURIComponent(segment));
778
+ return error || decoded === null ? segment : decoded;
779
+ };
780
+ var matchScore = (patternSegments, pathSegments) => {
781
+ let score = 0;
782
+ for (const [index, patternSegment] of patternSegments.entries()) {
783
+ if (patternSegment === "*" && index === patternSegments.length - 1) return score + 1;
784
+ const pathSegment = pathSegments[index];
785
+ if (pathSegment === void 0) return null;
786
+ if (patternSegment.startsWith(":")) {
787
+ score += 2;
788
+ } else if (patternSegment.toLowerCase() === pathSegment.toLowerCase()) {
789
+ score += 3;
790
+ } else {
791
+ return null;
792
+ }
793
+ }
794
+ return patternSegments.length === pathSegments.length ? score : null;
795
+ };
796
+ var resolvePageMiddleware = (path) => {
797
+ const pathSegments = splitPath(path).map((segment) => decodeSegment(segment));
798
+ let best = null;
799
+ for (const pattern of pageRoutes) {
800
+ const score = matchScore(splitPath(pattern), pathSegments);
801
+ if (score !== null && (best === null || score > best.score)) best = { score, pattern };
802
+ }
803
+ return best ? pageMiddlewares.get(best.pattern) : void 0;
804
+ };
763
805
 
764
806
  // src/react/sessionContext.ts
765
807
  import { createContext, use } from "react";
@@ -783,6 +825,10 @@ var setLatestSession = (session) => {
783
825
  };
784
826
  var getCurrentSession = () => latestSession;
785
827
  var proposeLogin = async (session) => {
828
+ if (latestSession?.id === session.id) {
829
+ setLatestSession(session);
830
+ return { stopped: false, committed: true };
831
+ }
786
832
  const veto = await dispatchVetoableClientHook("preLogin", { candidateSession: session });
787
833
  if (veto.stopped) return { stopped: true, signal: veto.signal, committed: false };
788
834
  setLatestSession(session);
@@ -827,7 +873,17 @@ var useTheme = () => {
827
873
  };
828
874
 
829
875
  // src/react/TranslationProvider.tsx
830
- import { createContext as createContext3, use as use3, useEffect, useMemo as useMemo2, useState as useState3 } from "react";
876
+ import { createContext as createContext3, use as use3, useCallback as useCallback3, useEffect, useMemo as useMemo2, useState as useState3 } from "react";
877
+
878
+ // src/react/languageOverride.ts
879
+ var activeLanguage = (state) => state.override ?? state.source;
880
+ var applyLanguageSource = (state, next) => next === state.source ? state : { source: next, override: null };
881
+ var applyLanguageOverride = (state, value) => ({
882
+ ...state,
883
+ override: typeof value === "function" ? value(activeLanguage(state)) : value
884
+ });
885
+
886
+ // src/react/TranslationProvider.tsx
831
887
  import { jsx as jsx2 } from "react/jsx-runtime";
832
888
  var TranslationContext = createContext3(null);
833
889
  var resolveTranslations = (code) => {
@@ -836,18 +892,22 @@ var resolveTranslations = (code) => {
836
892
  return {};
837
893
  };
838
894
  function TranslationProvider({ children }) {
839
- const [language, setLanguage] = useState3(() => getActiveLanguage());
895
+ const [languageState, setLanguageState] = useState3(() => ({ source: getActiveLanguage(), override: null }));
896
+ const language = activeLanguage(languageState);
840
897
  const translations = useMemo2(() => resolveTranslations(language), [language]);
841
898
  useEffect(() => {
842
899
  const handle = window.setInterval(() => {
843
900
  const next = getActiveLanguage();
844
- if (next !== language) setLanguage(next);
901
+ setLanguageState((state) => applyLanguageSource(state, next));
845
902
  }, 250);
846
903
  return () => {
847
904
  window.clearInterval(handle);
848
905
  };
849
- }, [language]);
850
- const contextValue = useMemo2(() => ({ translations, setLanguage }), [translations]);
906
+ }, []);
907
+ const setLanguage = useCallback3((value) => {
908
+ setLanguageState((state) => applyLanguageOverride(state, value));
909
+ }, []);
910
+ const contextValue = useMemo2(() => ({ translations, setLanguage }), [translations, setLanguage]);
851
911
  return /* @__PURE__ */ jsx2(TranslationContext, { value: contextValue, children });
852
912
  }
853
913
  function useTranslation() {
@@ -980,7 +1040,7 @@ function Middleware({
980
1040
  count++;
981
1041
  if (count > 500) break;
982
1042
  }
983
- const pageMw = getPageMiddleware(location.pathname);
1043
+ const pageMw = resolvePageMiddleware(location.pathname);
984
1044
  const handler = pageMw ?? getMiddlewareHandler();
985
1045
  const result = await handler({
986
1046
  location: location.pathname,
@@ -1030,7 +1090,7 @@ function useRouter() {
1030
1090
  const { session } = useSession();
1031
1091
  const navigate = async (path) => {
1032
1092
  const queryObject = getParams(location.search);
1033
- const pageMw = getPageMiddleware(path);
1093
+ const pageMw = resolvePageMiddleware(path);
1034
1094
  const handler = pageMw ?? getMiddlewareHandler();
1035
1095
  const result = await handler({ location: path, searchParams: queryObject, session });
1036
1096
  const outcome = resolveMiddlewareOutcome(result);
@@ -1103,10 +1163,12 @@ export {
1103
1163
  registerMiddlewareHandler,
1104
1164
  registerNotifier,
1105
1165
  registerPageMiddleware,
1166
+ registerPageRoute,
1106
1167
  registerProjectConfig,
1107
1168
  removeApiQueueItem,
1108
1169
  removeApiQueueItemsByKey,
1109
1170
  removeSyncQueueItem,
1171
+ resolvePageMiddleware,
1110
1172
  setLatestSession,
1111
1173
  setSocket,
1112
1174
  sleep,