@xylex-group/athena 1.4.1 → 1.5.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/dist/react.js CHANGED
@@ -1,4 +1,5 @@
1
- import { useState, useMemo, useCallback } from 'react';
1
+ import { createContext, useState, useMemo, useCallback, createElement, useContext, useRef, useEffect } from 'react';
2
+ import { useSyncExternalStore } from 'use-sync-external-store/shim';
2
3
 
3
4
  // src/gateway/use-athena-gateway.ts
4
5
 
@@ -534,6 +535,963 @@ function useAthenaGateway(config) {
534
535
  };
535
536
  }
536
537
 
537
- export { AthenaGatewayError, isAthenaGatewayError, useAthenaGateway };
538
+ // src/react/utils.ts
539
+ function isRecord2(value) {
540
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
541
+ }
542
+ function isPrimitive(value) {
543
+ return value == null || ["string", "number", "boolean"].includes(typeof value);
544
+ }
545
+ function encodePrimitive(value) {
546
+ if (value === null) return "null:0:";
547
+ if (value === void 0) return "undefined:0:";
548
+ if (typeof value === "string") return `str:${value.length}:${value}`;
549
+ if (typeof value === "number") {
550
+ const serialized2 = Number.isFinite(value) ? String(value) : "nan";
551
+ return `num:${serialized2.length}:${serialized2}`;
552
+ }
553
+ const serialized = value ? "1" : "0";
554
+ return `bool:${serialized.length}:${serialized}`;
555
+ }
556
+ function stableSerialize(value, seen) {
557
+ if (value === null) return "null";
558
+ if (value === void 0) return "undefined";
559
+ const valueType = typeof value;
560
+ if (valueType === "string") return `"${value}"`;
561
+ if (valueType === "number") return Number.isFinite(value) ? String(value) : "null";
562
+ if (valueType === "boolean") return value ? "true" : "false";
563
+ if (valueType === "bigint") return `${String(value)}n`;
564
+ if (valueType === "symbol") return `symbol:${String(value)}`;
565
+ if (valueType === "function") {
566
+ const namedFunction = value;
567
+ return `function:${namedFunction.name || "anonymous"}`;
568
+ }
569
+ if (value instanceof Date) return `date:${value.toISOString()}`;
570
+ if (Array.isArray(value)) {
571
+ return `[${value.map((item) => stableSerialize(item, seen)).join(",")}]`;
572
+ }
573
+ if (valueType === "object") {
574
+ const objectValue = value;
575
+ if (seen.has(objectValue)) return "[circular]";
576
+ seen.add(objectValue);
577
+ const keys = Object.keys(objectValue).sort();
578
+ const serialized = `{${keys.map((key) => `${key}:${stableSerialize(objectValue[key], seen)}`).join(",")}}`;
579
+ seen.delete(objectValue);
580
+ return serialized;
581
+ }
582
+ return String(value);
583
+ }
584
+ function safeSerializeQueryKey(queryKey) {
585
+ try {
586
+ if (typeof queryKey === "string") {
587
+ return `key:${queryKey}`;
588
+ }
589
+ if (Array.isArray(queryKey) && queryKey.every(isPrimitive)) {
590
+ return `arr:${queryKey.map((item) => encodePrimitive(item)).join("|")}`;
591
+ }
592
+ return `ser:${stableSerialize(queryKey, /* @__PURE__ */ new WeakSet())}`;
593
+ } catch {
594
+ try {
595
+ return `fallback:${String(queryKey)}`;
596
+ } catch {
597
+ return "fallback:[unserializable-query-key]";
598
+ }
599
+ }
600
+ }
601
+ function sleep(ms) {
602
+ if (ms <= 0) return Promise.resolve();
603
+ return new Promise((resolve) => {
604
+ setTimeout(resolve, ms);
605
+ });
606
+ }
607
+ function resolveRetryCount(retry) {
608
+ if (retry === false || retry == null) return 0;
609
+ if (!Number.isFinite(retry)) return 0;
610
+ return Math.max(0, Math.trunc(retry));
611
+ }
612
+ function resolveRetryDelay(retryDelay, attempt) {
613
+ if (typeof retryDelay === "function") {
614
+ const resolved = retryDelay(attempt);
615
+ if (!Number.isFinite(resolved)) return 0;
616
+ return Math.max(0, resolved);
617
+ }
618
+ if (typeof retryDelay === "number") {
619
+ if (!Number.isFinite(retryDelay)) return 0;
620
+ return Math.max(0, retryDelay);
621
+ }
622
+ return 0;
623
+ }
624
+ async function runWithRetry(execute, options) {
625
+ const retries = resolveRetryCount(options?.retry);
626
+ let attempt = 0;
627
+ for (; ; ) {
628
+ attempt += 1;
629
+ try {
630
+ return await execute(attempt);
631
+ } catch (error) {
632
+ if (attempt > retries) {
633
+ throw error;
634
+ }
635
+ const delay = resolveRetryDelay(options?.retryDelay, attempt);
636
+ await sleep(delay);
637
+ }
638
+ }
639
+ }
640
+ function errorMessageFromUnknown(error) {
641
+ if (typeof error === "string" && error.trim()) return error.trim();
642
+ if (error instanceof Error && error.message.trim()) return error.message.trim();
643
+ if (isRecord2(error)) {
644
+ const messageCandidate = error.message ?? error.error;
645
+ if (typeof messageCandidate === "string" && messageCandidate.trim()) {
646
+ return messageCandidate.trim();
647
+ }
648
+ }
649
+ return "Athena request failed";
650
+ }
651
+ function normalizeAthenaError(error, source) {
652
+ if (isRecord2(error) && typeof error.message === "string" && (error.status === void 0 || typeof error.status === "number") && (error.code === void 0 || typeof error.code === "string")) {
653
+ return {
654
+ message: error.message,
655
+ status: typeof error.status === "number" ? error.status : void 0,
656
+ code: typeof error.code === "string" ? error.code : void 0,
657
+ details: error.details,
658
+ raw: error.raw ?? source ?? error
659
+ };
660
+ }
661
+ if (isAthenaGatewayError(error)) {
662
+ const details = error.toDetails();
663
+ return {
664
+ message: details.message,
665
+ status: details.status,
666
+ code: details.code,
667
+ details,
668
+ raw: source ?? error
669
+ };
670
+ }
671
+ if (isRecord2(source) && source.errorDetails && isRecord2(source.errorDetails)) {
672
+ const details = source.errorDetails;
673
+ return {
674
+ message: errorMessageFromUnknown(error ?? source.error),
675
+ status: typeof source.status === "number" ? source.status : void 0,
676
+ code: typeof details.code === "string" ? details.code : void 0,
677
+ details,
678
+ raw: source
679
+ };
680
+ }
681
+ if (isRecord2(source) && typeof source.status === "number") {
682
+ return {
683
+ message: errorMessageFromUnknown(error),
684
+ status: source.status,
685
+ details: source,
686
+ raw: source
687
+ };
688
+ }
689
+ return {
690
+ message: errorMessageFromUnknown(error),
691
+ raw: source ?? error
692
+ };
693
+ }
694
+ function isAthenaResponseLike(value) {
695
+ if (!isRecord2(value)) return false;
696
+ if ("error" in value || "errorDetails" in value) return true;
697
+ if ("status" in value && typeof value.status === "number") {
698
+ return "data" in value || "raw" in value;
699
+ }
700
+ return "data" in value && ("raw" in value || "status" in value);
701
+ }
702
+ function normalizeAthenaResult(value, select) {
703
+ if (isAthenaResponseLike(value)) {
704
+ const status = typeof value.status === "number" ? value.status : value.error != null ? 500 : 200;
705
+ if (value.error != null) {
706
+ return {
707
+ data: void 0,
708
+ error: normalizeAthenaError(value.error, value),
709
+ status,
710
+ raw: value.raw ?? value
711
+ };
712
+ }
713
+ const hasData = "data" in value;
714
+ const sourceData2 = hasData ? value.data : void 0;
715
+ const selectedData2 = sourceData2 === void 0 ? void 0 : sourceData2 === null ? null : select ? select(sourceData2) : sourceData2;
716
+ return {
717
+ data: selectedData2,
718
+ error: null,
719
+ status,
720
+ raw: value.raw ?? value
721
+ };
722
+ }
723
+ const sourceData = value;
724
+ const selectedData = select ? select(sourceData) : sourceData;
725
+ return {
726
+ data: selectedData,
727
+ error: null,
728
+ status: 200,
729
+ raw: value
730
+ };
731
+ }
732
+
733
+ // src/react/query-client.ts
734
+ function createInitialQueryState(initialData) {
735
+ return {
736
+ status: initialData === void 0 ? "idle" : "success",
737
+ isFetching: false,
738
+ data: initialData,
739
+ error: null,
740
+ updatedAt: initialData === void 0 ? void 0 : Date.now()
741
+ };
742
+ }
743
+ function createInitialMutationState() {
744
+ return {
745
+ status: "idle",
746
+ data: void 0,
747
+ error: null,
748
+ isLoading: false,
749
+ lastVariables: void 0,
750
+ lastResponse: void 0,
751
+ updatedAt: void 0
752
+ };
753
+ }
754
+ function shouldUseMemoryCache(config) {
755
+ return config.cache?.mode === "memory";
756
+ }
757
+ var AthenaQueryClient = class {
758
+ queryEntries = /* @__PURE__ */ new Map();
759
+ mutationEntries = /* @__PURE__ */ new Map();
760
+ inflightQueries = /* @__PURE__ */ new Map();
761
+ eventSubscribers = /* @__PURE__ */ new Set();
762
+ adapters = /* @__PURE__ */ new Set();
763
+ requestCounter = 0;
764
+ config;
765
+ defaultQueryOptions;
766
+ defaultMutationOptions;
767
+ constructor(config = {}) {
768
+ this.config = {
769
+ cache: {
770
+ mode: config.cache?.mode ?? "none",
771
+ staleTime: config.cache?.staleTime,
772
+ gcTime: config.cache?.gcTime
773
+ },
774
+ defaultQueryOptions: config.defaultQueryOptions,
775
+ defaultMutationOptions: config.defaultMutationOptions
776
+ };
777
+ this.defaultQueryOptions = {
778
+ retry: config.defaultQueryOptions?.retry ?? 0,
779
+ retryDelay: config.defaultQueryOptions?.retryDelay,
780
+ refetchOnMount: config.defaultQueryOptions?.refetchOnMount ?? true,
781
+ refetchOnWindowFocus: config.defaultQueryOptions?.refetchOnWindowFocus ?? false,
782
+ refetchOnReconnect: config.defaultQueryOptions?.refetchOnReconnect ?? false
783
+ };
784
+ this.defaultMutationOptions = {
785
+ retry: config.defaultMutationOptions?.retry ?? 0,
786
+ retryDelay: config.defaultMutationOptions?.retryDelay
787
+ };
788
+ }
789
+ getQueryKeyToken(queryKey) {
790
+ return safeSerializeQueryKey(queryKey);
791
+ }
792
+ getMutationKeyToken(mutationKey) {
793
+ if (mutationKey == null) {
794
+ return "__mutation__default__";
795
+ }
796
+ return safeSerializeQueryKey(mutationKey);
797
+ }
798
+ getQueryState(key) {
799
+ const entry = this.ensureQueryEntry(key);
800
+ return entry.state;
801
+ }
802
+ getMutationState(key) {
803
+ const entry = this.ensureMutationEntry(key);
804
+ return entry.state;
805
+ }
806
+ subscribeQuery(key, listener) {
807
+ const entry = this.ensureQueryEntry(key);
808
+ if (entry.gcTimer) {
809
+ clearTimeout(entry.gcTimer);
810
+ entry.gcTimer = void 0;
811
+ }
812
+ entry.listeners.add(listener);
813
+ return () => {
814
+ const current = this.queryEntries.get(key);
815
+ if (!current) return;
816
+ current.listeners.delete(listener);
817
+ if (current.listeners.size === 0) {
818
+ this.scheduleQueryGc(current);
819
+ }
820
+ };
821
+ }
822
+ subscribeMutation(key, listener) {
823
+ const entry = this.ensureMutationEntry(key);
824
+ if (entry.gcTimer) {
825
+ clearTimeout(entry.gcTimer);
826
+ entry.gcTimer = void 0;
827
+ }
828
+ entry.listeners.add(listener);
829
+ return () => {
830
+ const current = this.mutationEntries.get(key);
831
+ if (!current) return;
832
+ current.listeners.delete(listener);
833
+ if (current.listeners.size === 0) {
834
+ this.scheduleMutationGc(current);
835
+ }
836
+ };
837
+ }
838
+ subscribeEvents(listener) {
839
+ this.eventSubscribers.add(listener);
840
+ return () => {
841
+ this.eventSubscribers.delete(listener);
842
+ };
843
+ }
844
+ attachAdapter(adapter) {
845
+ this.adapters.add(adapter);
846
+ return () => {
847
+ this.adapters.delete(adapter);
848
+ };
849
+ }
850
+ resetQuery(queryKey) {
851
+ const key = this.getQueryKeyToken(queryKey);
852
+ const entry = this.ensureQueryEntry(key);
853
+ entry.activeRequestId = ++this.requestCounter;
854
+ this.setQueryState(entry, createInitialQueryState(), "query_reset");
855
+ this.inflightQueries.delete(key);
856
+ }
857
+ resetMutation(mutationKey) {
858
+ const key = this.getMutationKeyToken(mutationKey);
859
+ const entry = this.ensureMutationEntry(key);
860
+ entry.activeRequestId = ++this.requestCounter;
861
+ this.setMutationState(entry, createInitialMutationState(), "mutation_reset");
862
+ }
863
+ async executeQuery(input) {
864
+ const entry = this.ensureQueryEntry(input.queryKeyToken);
865
+ if (input.dedupe !== false) {
866
+ const existing = this.inflightQueries.get(input.queryKeyToken);
867
+ if (existing) {
868
+ return existing;
869
+ }
870
+ }
871
+ if (!input.force && shouldUseMemoryCache(this.config)) {
872
+ const staleTime = this.config.cache?.staleTime ?? 0;
873
+ const hasFreshData = entry.state.status === "success" && entry.state.data !== void 0 && entry.state.updatedAt !== void 0 && Date.now() - entry.state.updatedAt <= staleTime;
874
+ if (hasFreshData) {
875
+ return {
876
+ data: entry.state.data,
877
+ error: null,
878
+ status: 200,
879
+ raw: entry.state.lastResponse ?? entry.state.data,
880
+ __applied: true
881
+ };
882
+ }
883
+ }
884
+ const requestId = ++this.requestCounter;
885
+ entry.activeRequestId = requestId;
886
+ const startRequestLog = {
887
+ requestId,
888
+ queryKey: input.queryKey,
889
+ queryKeyToken: input.queryKeyToken,
890
+ attempt: 1,
891
+ startedAt: Date.now()
892
+ };
893
+ const loadingStatus = entry.state.data === void 0 ? "loading" : entry.state.status;
894
+ this.setQueryState(
895
+ entry,
896
+ {
897
+ ...entry.state,
898
+ status: loadingStatus,
899
+ isFetching: true,
900
+ error: null,
901
+ lastRequest: startRequestLog
902
+ },
903
+ "query_updated"
904
+ );
905
+ const executionPromise = runWithRetry(
906
+ async (attempt) => {
907
+ const attemptRequestLog = {
908
+ ...startRequestLog,
909
+ attempt
910
+ };
911
+ if (entry.activeRequestId === requestId) {
912
+ this.setQueryState(
913
+ entry,
914
+ {
915
+ ...entry.state,
916
+ lastRequest: attemptRequestLog,
917
+ isFetching: true
918
+ },
919
+ "query_updated"
920
+ );
921
+ }
922
+ const rawResult = await input.queryFn();
923
+ const normalized = normalizeAthenaResult(rawResult, input.select);
924
+ if (normalized.error) {
925
+ throw {
926
+ __athenaNormalizedError: normalized.error,
927
+ __athenaStatus: normalized.status,
928
+ __athenaRaw: normalized.raw,
929
+ __athenaResponse: rawResult
930
+ };
931
+ }
932
+ return {
933
+ normalized,
934
+ response: rawResult,
935
+ attempt
936
+ };
937
+ },
938
+ {
939
+ retry: input.retry,
940
+ retryDelay: input.retryDelay
941
+ }
942
+ ).then((result) => {
943
+ const applied = entry.activeRequestId === requestId;
944
+ if (applied) {
945
+ const finishedAt = Date.now();
946
+ const doneRequestLog = {
947
+ ...startRequestLog,
948
+ attempt: result.attempt,
949
+ endedAt: finishedAt
950
+ };
951
+ this.setQueryState(
952
+ entry,
953
+ {
954
+ ...entry.state,
955
+ status: "success",
956
+ isFetching: false,
957
+ error: null,
958
+ data: result.normalized.data,
959
+ lastRequest: doneRequestLog,
960
+ lastResponse: result.response,
961
+ updatedAt: finishedAt
962
+ },
963
+ "query_updated"
964
+ );
965
+ }
966
+ return {
967
+ ...result.normalized,
968
+ __applied: applied
969
+ };
970
+ }).catch((error) => {
971
+ const wrapped = typeof error === "object" && error !== null ? error : void 0;
972
+ const normalizedError = wrapped?.__athenaNormalizedError ? wrapped.__athenaNormalizedError : normalizeAthenaError(error);
973
+ const status = typeof wrapped?.__athenaStatus === "number" ? wrapped.__athenaStatus : normalizedError.status ?? 500;
974
+ const raw = wrapped?.__athenaRaw ?? normalizedError.raw ?? null;
975
+ const response = wrapped?.__athenaResponse ?? raw;
976
+ const applied = entry.activeRequestId === requestId;
977
+ if (applied) {
978
+ const finishedAt = Date.now();
979
+ const doneRequestLog = {
980
+ ...startRequestLog,
981
+ endedAt: finishedAt,
982
+ attempt: entry.state.lastRequest?.requestId === requestId ? entry.state.lastRequest.attempt : startRequestLog.attempt
983
+ };
984
+ this.setQueryState(
985
+ entry,
986
+ {
987
+ ...entry.state,
988
+ status: "error",
989
+ isFetching: false,
990
+ error: normalizedError,
991
+ lastRequest: doneRequestLog,
992
+ lastResponse: response,
993
+ updatedAt: finishedAt
994
+ },
995
+ "query_updated"
996
+ );
997
+ }
998
+ return {
999
+ data: void 0,
1000
+ error: normalizedError,
1001
+ status,
1002
+ raw,
1003
+ __applied: applied
1004
+ };
1005
+ }).finally(() => {
1006
+ const inflight = this.inflightQueries.get(input.queryKeyToken);
1007
+ if (inflight === executionPromise) {
1008
+ this.inflightQueries.delete(input.queryKeyToken);
1009
+ }
1010
+ });
1011
+ this.inflightQueries.set(input.queryKeyToken, executionPromise);
1012
+ return executionPromise;
1013
+ }
1014
+ async executeMutation(input) {
1015
+ const entry = this.ensureMutationEntry(input.mutationKeyToken);
1016
+ const requestId = ++this.requestCounter;
1017
+ entry.activeRequestId = requestId;
1018
+ const startRequestLog = {
1019
+ requestId,
1020
+ mutationKey: input.mutationKey,
1021
+ mutationKeyToken: input.mutationKeyToken,
1022
+ attempt: 1,
1023
+ startedAt: Date.now(),
1024
+ variables: input.variables
1025
+ };
1026
+ this.setMutationState(
1027
+ entry,
1028
+ {
1029
+ ...entry.state,
1030
+ status: "loading",
1031
+ isLoading: true,
1032
+ error: null,
1033
+ lastVariables: input.variables,
1034
+ lastRequest: startRequestLog
1035
+ },
1036
+ "mutation_updated"
1037
+ );
1038
+ try {
1039
+ const result = await runWithRetry(
1040
+ async (attempt) => {
1041
+ const attemptRequestLog = {
1042
+ ...startRequestLog,
1043
+ attempt
1044
+ };
1045
+ if (entry.activeRequestId === requestId) {
1046
+ this.setMutationState(
1047
+ entry,
1048
+ {
1049
+ ...entry.state,
1050
+ lastRequest: attemptRequestLog,
1051
+ isLoading: true
1052
+ },
1053
+ "mutation_updated"
1054
+ );
1055
+ }
1056
+ const rawResult = await input.mutationFn(input.variables);
1057
+ const normalized = normalizeAthenaResult(rawResult, input.select);
1058
+ if (normalized.error) {
1059
+ throw {
1060
+ __athenaNormalizedError: normalized.error,
1061
+ __athenaStatus: normalized.status,
1062
+ __athenaRaw: normalized.raw,
1063
+ __athenaResponse: rawResult
1064
+ };
1065
+ }
1066
+ return {
1067
+ normalized,
1068
+ response: rawResult,
1069
+ attempt
1070
+ };
1071
+ },
1072
+ {
1073
+ retry: input.retry,
1074
+ retryDelay: input.retryDelay
1075
+ }
1076
+ );
1077
+ if (entry.activeRequestId === requestId) {
1078
+ const finishedAt = Date.now();
1079
+ const doneRequestLog = {
1080
+ ...startRequestLog,
1081
+ attempt: result.attempt,
1082
+ endedAt: finishedAt
1083
+ };
1084
+ this.setMutationState(
1085
+ entry,
1086
+ {
1087
+ ...entry.state,
1088
+ status: "success",
1089
+ isLoading: false,
1090
+ data: result.normalized.data,
1091
+ error: null,
1092
+ lastVariables: input.variables,
1093
+ lastRequest: doneRequestLog,
1094
+ lastResponse: result.response,
1095
+ updatedAt: finishedAt
1096
+ },
1097
+ "mutation_updated"
1098
+ );
1099
+ }
1100
+ return result.normalized;
1101
+ } catch (error) {
1102
+ const wrapped = typeof error === "object" && error !== null ? error : void 0;
1103
+ const normalizedError = wrapped?.__athenaNormalizedError ? wrapped.__athenaNormalizedError : normalizeAthenaError(error);
1104
+ const status = typeof wrapped?.__athenaStatus === "number" ? wrapped.__athenaStatus : normalizedError.status ?? 500;
1105
+ const raw = wrapped?.__athenaRaw ?? normalizedError.raw ?? null;
1106
+ const response = wrapped?.__athenaResponse ?? raw;
1107
+ if (entry.activeRequestId === requestId) {
1108
+ const finishedAt = Date.now();
1109
+ const doneRequestLog = {
1110
+ ...startRequestLog,
1111
+ endedAt: finishedAt,
1112
+ attempt: entry.state.lastRequest?.requestId === requestId ? entry.state.lastRequest.attempt : startRequestLog.attempt
1113
+ };
1114
+ this.setMutationState(
1115
+ entry,
1116
+ {
1117
+ ...entry.state,
1118
+ status: "error",
1119
+ isLoading: false,
1120
+ error: normalizedError,
1121
+ lastVariables: input.variables,
1122
+ lastRequest: doneRequestLog,
1123
+ lastResponse: response,
1124
+ updatedAt: finishedAt
1125
+ },
1126
+ "mutation_updated"
1127
+ );
1128
+ }
1129
+ return {
1130
+ data: void 0,
1131
+ error: normalizedError,
1132
+ status,
1133
+ raw
1134
+ };
1135
+ }
1136
+ }
1137
+ ensureQueryEntry(key) {
1138
+ let entry = this.queryEntries.get(key);
1139
+ if (entry) return entry;
1140
+ entry = {
1141
+ key,
1142
+ state: createInitialQueryState(),
1143
+ listeners: /* @__PURE__ */ new Set(),
1144
+ activeRequestId: 0
1145
+ };
1146
+ this.queryEntries.set(key, entry);
1147
+ return entry;
1148
+ }
1149
+ ensureMutationEntry(key) {
1150
+ let entry = this.mutationEntries.get(key);
1151
+ if (entry) return entry;
1152
+ entry = {
1153
+ key,
1154
+ state: createInitialMutationState(),
1155
+ listeners: /* @__PURE__ */ new Set(),
1156
+ activeRequestId: 0
1157
+ };
1158
+ this.mutationEntries.set(key, entry);
1159
+ return entry;
1160
+ }
1161
+ scheduleQueryGc(entry) {
1162
+ const gcTime = shouldUseMemoryCache(this.config) ? Math.max(0, this.config.cache?.gcTime ?? 3e5) : Math.max(0, this.config.cache?.gcTime ?? 0);
1163
+ entry.gcTimer = setTimeout(() => {
1164
+ const current = this.queryEntries.get(entry.key);
1165
+ if (!current || current.listeners.size > 0) return;
1166
+ this.queryEntries.delete(entry.key);
1167
+ this.inflightQueries.delete(entry.key);
1168
+ this.emitEvent({
1169
+ type: "query_gc",
1170
+ key: entry.key,
1171
+ state: current.state,
1172
+ timestamp: Date.now()
1173
+ });
1174
+ }, gcTime);
1175
+ }
1176
+ scheduleMutationGc(entry) {
1177
+ const gcTime = shouldUseMemoryCache(this.config) ? Math.max(0, this.config.cache?.gcTime ?? 3e5) : Math.max(0, this.config.cache?.gcTime ?? 0);
1178
+ entry.gcTimer = setTimeout(() => {
1179
+ const current = this.mutationEntries.get(entry.key);
1180
+ if (!current || current.listeners.size > 0) return;
1181
+ this.mutationEntries.delete(entry.key);
1182
+ }, gcTime);
1183
+ }
1184
+ setQueryState(entry, state, eventType) {
1185
+ entry.state = state;
1186
+ for (const listener of entry.listeners) {
1187
+ listener();
1188
+ }
1189
+ this.emitEvent({
1190
+ type: eventType,
1191
+ key: entry.key,
1192
+ state,
1193
+ timestamp: Date.now()
1194
+ });
1195
+ }
1196
+ setMutationState(entry, state, eventType) {
1197
+ entry.state = state;
1198
+ for (const listener of entry.listeners) {
1199
+ listener();
1200
+ }
1201
+ this.emitEvent({
1202
+ type: eventType,
1203
+ key: entry.key,
1204
+ state,
1205
+ timestamp: Date.now()
1206
+ });
1207
+ }
1208
+ emitEvent(event) {
1209
+ for (const listener of this.eventSubscribers) {
1210
+ listener(event);
1211
+ }
1212
+ for (const adapter of this.adapters) {
1213
+ adapter.onEvent?.(event);
1214
+ if (event.type === "query_updated" || event.type === "query_reset" || event.type === "query_gc") {
1215
+ adapter.onQueryUpdated?.(event);
1216
+ }
1217
+ if (event.type === "mutation_updated" || event.type === "mutation_reset") {
1218
+ adapter.onMutationUpdated?.(event);
1219
+ }
1220
+ }
1221
+ }
1222
+ };
1223
+ function createAthenaQueryClient(config) {
1224
+ return new AthenaQueryClient(config);
1225
+ }
1226
+ function attachStateAdapter(client, adapter) {
1227
+ return client.attachAdapter(adapter);
1228
+ }
1229
+ var AthenaQueryClientContext = createContext(null);
1230
+ function AthenaQueryClientProvider(props) {
1231
+ const memoizedClient = useMemo(() => {
1232
+ if (props.client) {
1233
+ return props.client;
1234
+ }
1235
+ return createAthenaQueryClient(props.config);
1236
+ }, [props.client, props.config]);
1237
+ return createElement(
1238
+ AthenaQueryClientContext.Provider,
1239
+ { value: memoizedClient },
1240
+ props.children
1241
+ );
1242
+ }
1243
+ function useAthenaQueryClient() {
1244
+ const client = useContext(AthenaQueryClientContext);
1245
+ if (!client) {
1246
+ throw new Error(
1247
+ "No AthenaQueryClient found. Wrap your component tree with AthenaQueryClientProvider."
1248
+ );
1249
+ }
1250
+ return client;
1251
+ }
1252
+ function getBrowserTarget() {
1253
+ const maybeGlobal = globalThis;
1254
+ const hasListeners = (value) => Boolean(value) && typeof value === "object" && typeof value.addEventListener === "function" && typeof value.removeEventListener === "function";
1255
+ if (hasListeners(maybeGlobal.window)) {
1256
+ return maybeGlobal.window;
1257
+ }
1258
+ if (hasListeners(maybeGlobal)) {
1259
+ return maybeGlobal;
1260
+ }
1261
+ return null;
1262
+ }
1263
+ function useQuery(options) {
1264
+ const client = useAthenaQueryClient();
1265
+ const queryKeyRef = useRef(options.queryKey);
1266
+ queryKeyRef.current = options.queryKey;
1267
+ const queryFnRef = useRef(options.queryFn);
1268
+ queryFnRef.current = options.queryFn;
1269
+ const selectRef = useRef(options.select);
1270
+ selectRef.current = options.select;
1271
+ const onSuccessRef = useRef(options.onSuccess);
1272
+ onSuccessRef.current = options.onSuccess;
1273
+ const onErrorRef = useRef(options.onError);
1274
+ onErrorRef.current = options.onError;
1275
+ const onSettledRef = useRef(options.onSettled);
1276
+ onSettledRef.current = options.onSettled;
1277
+ const enabledRef = useRef(options.enabled ?? true);
1278
+ enabledRef.current = options.enabled ?? true;
1279
+ const retryRef = useRef(options.retry);
1280
+ retryRef.current = options.retry;
1281
+ const retryDelayRef = useRef(options.retryDelay);
1282
+ retryDelayRef.current = options.retryDelay;
1283
+ const initialDataRef = useRef(options.initialData);
1284
+ initialDataRef.current = options.initialData;
1285
+ const refetchOnMountRef = useRef(options.refetchOnMount);
1286
+ refetchOnMountRef.current = options.refetchOnMount;
1287
+ const refetchOnWindowFocusRef = useRef(options.refetchOnWindowFocus);
1288
+ refetchOnWindowFocusRef.current = options.refetchOnWindowFocus;
1289
+ const refetchOnReconnectRef = useRef(options.refetchOnReconnect);
1290
+ refetchOnReconnectRef.current = options.refetchOnReconnect;
1291
+ const queryKeyToken = useMemo(
1292
+ () => client.getQueryKeyToken(options.queryKey),
1293
+ [client, options.queryKey]
1294
+ );
1295
+ const activeQueryKeyTokenRef = useRef(queryKeyToken);
1296
+ activeQueryKeyTokenRef.current = queryKeyToken;
1297
+ const subscribe = useCallback(
1298
+ (listener) => client.subscribeQuery(queryKeyToken, listener),
1299
+ [client, queryKeyToken]
1300
+ );
1301
+ const getSnapshot = useCallback(
1302
+ () => client.getQueryState(queryKeyToken),
1303
+ [client, queryKeyToken]
1304
+ );
1305
+ const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1306
+ const effectiveSnapshot = useMemo(() => {
1307
+ if (snapshot.status === "idle" && snapshot.data === void 0 && initialDataRef.current !== void 0) {
1308
+ return {
1309
+ ...snapshot,
1310
+ status: "success",
1311
+ data: initialDataRef.current,
1312
+ error: null
1313
+ };
1314
+ }
1315
+ return snapshot;
1316
+ }, [snapshot]);
1317
+ const runQuery = useCallback(
1318
+ async (force = false) => {
1319
+ const result = await client.executeQuery({
1320
+ queryKey: queryKeyRef.current,
1321
+ queryKeyToken,
1322
+ queryFn: () => queryFnRef.current(),
1323
+ select: selectRef.current,
1324
+ retry: retryRef.current ?? client.defaultQueryOptions.retry ?? 0,
1325
+ retryDelay: retryDelayRef.current ?? client.defaultQueryOptions.retryDelay,
1326
+ dedupe: true,
1327
+ force
1328
+ });
1329
+ const internalResult = result;
1330
+ if (activeQueryKeyTokenRef.current !== queryKeyToken || internalResult.__applied === false) {
1331
+ return result;
1332
+ }
1333
+ if (result.error) {
1334
+ onErrorRef.current?.(result.error);
1335
+ onSettledRef.current?.(result.data, result.error);
1336
+ return result;
1337
+ }
1338
+ onSuccessRef.current?.(result.data);
1339
+ onSettledRef.current?.(result.data, null);
1340
+ return result;
1341
+ },
1342
+ [client, queryKeyToken]
1343
+ );
1344
+ const lastAutoKeyRef = useRef(null);
1345
+ useEffect(() => {
1346
+ const refetchOnMount = refetchOnMountRef.current ?? client.defaultQueryOptions.refetchOnMount ?? true;
1347
+ const isFirstRenderForKey = lastAutoKeyRef.current !== queryKeyToken;
1348
+ lastAutoKeyRef.current = queryKeyToken;
1349
+ if (!enabledRef.current) {
1350
+ return;
1351
+ }
1352
+ const state = client.getQueryState(queryKeyToken);
1353
+ const shouldFetch = state.status === "idle" || isFirstRenderForKey && refetchOnMount;
1354
+ if (shouldFetch) {
1355
+ void runQuery(false);
1356
+ }
1357
+ }, [client, queryKeyToken, runQuery]);
1358
+ useEffect(() => {
1359
+ const browser = getBrowserTarget();
1360
+ if (!browser || !enabledRef.current) {
1361
+ return void 0;
1362
+ }
1363
+ const refetchOnWindowFocus = refetchOnWindowFocusRef.current ?? client.defaultQueryOptions.refetchOnWindowFocus ?? false;
1364
+ if (!refetchOnWindowFocus) {
1365
+ return void 0;
1366
+ }
1367
+ const onFocus = () => {
1368
+ if (!enabledRef.current) return;
1369
+ void runQuery(true);
1370
+ };
1371
+ browser.addEventListener("focus", onFocus);
1372
+ return () => {
1373
+ browser.removeEventListener("focus", onFocus);
1374
+ };
1375
+ }, [client, runQuery]);
1376
+ useEffect(() => {
1377
+ const browser = getBrowserTarget();
1378
+ if (!browser || !enabledRef.current) {
1379
+ return void 0;
1380
+ }
1381
+ const refetchOnReconnect = refetchOnReconnectRef.current ?? client.defaultQueryOptions.refetchOnReconnect ?? false;
1382
+ if (!refetchOnReconnect) {
1383
+ return void 0;
1384
+ }
1385
+ const onReconnect = () => {
1386
+ if (!enabledRef.current) return;
1387
+ void runQuery(true);
1388
+ };
1389
+ browser.addEventListener("online", onReconnect);
1390
+ return () => {
1391
+ browser.removeEventListener("online", onReconnect);
1392
+ };
1393
+ }, [client, runQuery]);
1394
+ const refetch = useCallback(() => runQuery(true), [runQuery]);
1395
+ const reset = useCallback(() => {
1396
+ client.resetQuery(queryKeyRef.current);
1397
+ }, [client]);
1398
+ return {
1399
+ data: effectiveSnapshot.data,
1400
+ error: effectiveSnapshot.error,
1401
+ isLoading: effectiveSnapshot.status === "loading" && effectiveSnapshot.data === void 0,
1402
+ isFetching: effectiveSnapshot.isFetching,
1403
+ isSuccess: effectiveSnapshot.status === "success",
1404
+ isError: effectiveSnapshot.status === "error",
1405
+ status: effectiveSnapshot.status,
1406
+ refetch,
1407
+ reset,
1408
+ lastResponse: effectiveSnapshot.lastResponse,
1409
+ lastRequest: effectiveSnapshot.lastRequest
1410
+ };
1411
+ }
1412
+ function useMutation(options) {
1413
+ const client = useAthenaQueryClient();
1414
+ const mutationKeyRef = useRef(options.mutationKey);
1415
+ mutationKeyRef.current = options.mutationKey;
1416
+ const mutationFnRef = useRef(options.mutationFn);
1417
+ mutationFnRef.current = options.mutationFn;
1418
+ const selectRef = useRef(options.select);
1419
+ selectRef.current = options.select;
1420
+ const retryRef = useRef(options.retry);
1421
+ retryRef.current = options.retry;
1422
+ const retryDelayRef = useRef(options.retryDelay);
1423
+ retryDelayRef.current = options.retryDelay;
1424
+ const onMutateRef = useRef(options.onMutate);
1425
+ onMutateRef.current = options.onMutate;
1426
+ const onSuccessRef = useRef(options.onSuccess);
1427
+ onSuccessRef.current = options.onSuccess;
1428
+ const onErrorRef = useRef(options.onError);
1429
+ onErrorRef.current = options.onError;
1430
+ const onSettledRef = useRef(options.onSettled);
1431
+ onSettledRef.current = options.onSettled;
1432
+ const mutationKeyToken = useMemo(
1433
+ () => client.getMutationKeyToken(options.mutationKey),
1434
+ [client, options.mutationKey]
1435
+ );
1436
+ const subscribe = useCallback(
1437
+ (listener) => client.subscribeMutation(mutationKeyToken, listener),
1438
+ [client, mutationKeyToken]
1439
+ );
1440
+ const getSnapshot = useCallback(
1441
+ () => client.getMutationState(mutationKeyToken),
1442
+ [client, mutationKeyToken]
1443
+ );
1444
+ const snapshot = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
1445
+ const mutateAsync = useCallback(
1446
+ async (variables) => {
1447
+ await onMutateRef.current?.(variables);
1448
+ const result = await client.executeMutation({
1449
+ mutationKey: mutationKeyRef.current,
1450
+ mutationKeyToken,
1451
+ variables,
1452
+ mutationFn: (currentVariables) => mutationFnRef.current(currentVariables),
1453
+ select: selectRef.current,
1454
+ retry: retryRef.current ?? client.defaultMutationOptions.retry ?? 0,
1455
+ retryDelay: retryDelayRef.current ?? client.defaultMutationOptions.retryDelay
1456
+ });
1457
+ if (result.error) {
1458
+ onErrorRef.current?.(result.error, variables);
1459
+ onSettledRef.current?.(result.data, result.error, variables);
1460
+ throw result.error;
1461
+ }
1462
+ const data = result.data;
1463
+ onSuccessRef.current?.(data, variables);
1464
+ onSettledRef.current?.(data, null, variables);
1465
+ return data;
1466
+ },
1467
+ [client, mutationKeyToken]
1468
+ );
1469
+ const mutate = useCallback(
1470
+ (variables) => {
1471
+ void mutateAsync(variables).catch(() => void 0);
1472
+ },
1473
+ [mutateAsync]
1474
+ );
1475
+ const reset = useCallback(() => {
1476
+ client.resetMutation(mutationKeyRef.current);
1477
+ }, [client]);
1478
+ return {
1479
+ mutate,
1480
+ mutateAsync,
1481
+ data: snapshot.data,
1482
+ error: snapshot.error,
1483
+ isIdle: snapshot.status === "idle",
1484
+ isLoading: snapshot.status === "loading",
1485
+ isSuccess: snapshot.status === "success",
1486
+ isError: snapshot.status === "error",
1487
+ status: snapshot.status,
1488
+ reset,
1489
+ lastResponse: snapshot.lastResponse,
1490
+ lastVariables: snapshot.lastVariables,
1491
+ lastRequest: snapshot.lastRequest
1492
+ };
1493
+ }
1494
+
1495
+ export { AthenaGatewayError, AthenaQueryClient, AthenaQueryClientProvider, attachStateAdapter, createAthenaQueryClient, isAthenaGatewayError, useAthenaGateway, useAthenaQueryClient, useMutation, useQuery };
538
1496
  //# sourceMappingURL=react.js.map
539
1497
  //# sourceMappingURL=react.js.map