@exyconn/common 1.0.0 → 2.0.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/README.md +121 -36
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +2330 -176
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +2284 -178
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/utils/index.d.mts +123 -1
- package/dist/client/utils/index.d.ts +123 -1
- package/dist/client/utils/index.js +207 -0
- package/dist/client/utils/index.js.map +1 -1
- package/dist/client/utils/index.mjs +204 -1
- package/dist/client/utils/index.mjs.map +1 -1
- package/dist/index-BLltj-zN.d.ts +1236 -0
- package/dist/index-CIUdLBjA.d.mts +1236 -0
- package/dist/{index-iTKxFa78.d.ts → index-DEzgM15j.d.ts} +10 -2
- package/dist/{index-ClWtDfwk.d.ts → index-DNFVgQx8.d.ts} +544 -2
- package/dist/{index-CcrANHAQ.d.mts → index-DbV04Dx8.d.mts} +10 -2
- package/dist/{index-DSW6JfD-.d.mts → index-DfqEP6Oe.d.mts} +544 -2
- package/dist/index.d.mts +582 -7
- package/dist/index.d.ts +582 -7
- package/dist/index.js +3428 -221
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3430 -223
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +197 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +194 -2
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/utils/index.d.mts +73 -1
- package/dist/server/utils/index.d.ts +73 -1
- package/dist/server/utils/index.js +199 -0
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs +195 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +1 -1
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +296 -0
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +274 -1
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +9 -2
- package/dist/index-BNdT-2X4.d.ts +0 -229
- package/dist/index-Du0LLt9f.d.mts +0 -229
package/dist/client/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import {
|
|
2
|
+
import { useState, useCallback, useMemo, useRef, useEffect } from 'react';
|
|
3
3
|
|
|
4
4
|
// src/client/http/axios-instance.ts
|
|
5
5
|
var createHttpClient = (options) => {
|
|
@@ -576,6 +576,1795 @@ var createErrorResponse = (message, statusCode = 400, error) => ({
|
|
|
576
576
|
error,
|
|
577
577
|
statusCode
|
|
578
578
|
});
|
|
579
|
+
|
|
580
|
+
// src/client/utils/packageCheck.ts
|
|
581
|
+
function parseVersion(version) {
|
|
582
|
+
return version.replace(/[\^~>=<|*x\s]/g, "").split(" ")[0] || "0.0.0";
|
|
583
|
+
}
|
|
584
|
+
function compareVersions(current, latest) {
|
|
585
|
+
const currentClean = parseVersion(current);
|
|
586
|
+
const latestClean = parseVersion(latest);
|
|
587
|
+
if (currentClean === latestClean) return "none";
|
|
588
|
+
const [curMajor, curMinor, curPatch] = currentClean.split(".").map(Number);
|
|
589
|
+
const [latMajor, latMinor, latPatch] = latestClean.split(".").map(Number);
|
|
590
|
+
if (latest.includes("-")) return "prerelease";
|
|
591
|
+
if (latMajor > curMajor) return "major";
|
|
592
|
+
if (latMinor > curMinor) return "minor";
|
|
593
|
+
if (latPatch > curPatch) return "patch";
|
|
594
|
+
return "none";
|
|
595
|
+
}
|
|
596
|
+
async function fetchLatestVersion(packageName) {
|
|
597
|
+
try {
|
|
598
|
+
const encodedName = packageName.startsWith("@") ? `@${encodeURIComponent(packageName.slice(1))}` : encodeURIComponent(packageName);
|
|
599
|
+
const response = await fetch(`https://registry.npmjs.org/${encodedName}`);
|
|
600
|
+
if (!response.ok) {
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
const data = await response.json();
|
|
604
|
+
return data["dist-tags"]?.latest || null;
|
|
605
|
+
} catch {
|
|
606
|
+
return null;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async function fetchPackageJson(source) {
|
|
610
|
+
if (typeof source === "object") {
|
|
611
|
+
return source;
|
|
612
|
+
}
|
|
613
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
614
|
+
const response = await fetch(source);
|
|
615
|
+
if (!response.ok) {
|
|
616
|
+
throw new Error(`Failed to fetch package.json from ${source}: ${response.status}`);
|
|
617
|
+
}
|
|
618
|
+
return response.json();
|
|
619
|
+
}
|
|
620
|
+
throw new Error(
|
|
621
|
+
"File path support requires Node.js environment. Use URL or pass package.json object directly."
|
|
622
|
+
);
|
|
623
|
+
}
|
|
624
|
+
async function checkDependencyType(deps, type, errors) {
|
|
625
|
+
if (!deps) return [];
|
|
626
|
+
const results = [];
|
|
627
|
+
const entries = Object.entries(deps);
|
|
628
|
+
const concurrencyLimit = 10;
|
|
629
|
+
for (let i = 0; i < entries.length; i += concurrencyLimit) {
|
|
630
|
+
const batch = entries.slice(i, i + concurrencyLimit);
|
|
631
|
+
const batchResults = await Promise.all(
|
|
632
|
+
batch.map(async ([name, currentVersion]) => {
|
|
633
|
+
try {
|
|
634
|
+
const latest = await fetchLatestVersion(name);
|
|
635
|
+
if (!latest) {
|
|
636
|
+
errors.push(`Could not fetch latest version for ${name}`);
|
|
637
|
+
return {
|
|
638
|
+
name,
|
|
639
|
+
current: currentVersion,
|
|
640
|
+
latest: "unknown",
|
|
641
|
+
hasUpdate: false,
|
|
642
|
+
updateType: "none",
|
|
643
|
+
dependencyType: type
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
const updateType = compareVersions(currentVersion, latest);
|
|
647
|
+
return {
|
|
648
|
+
name,
|
|
649
|
+
current: currentVersion,
|
|
650
|
+
latest,
|
|
651
|
+
hasUpdate: updateType !== "none",
|
|
652
|
+
updateType,
|
|
653
|
+
dependencyType: type
|
|
654
|
+
};
|
|
655
|
+
} catch (err) {
|
|
656
|
+
errors.push(`Error checking ${name}: ${err}`);
|
|
657
|
+
return {
|
|
658
|
+
name,
|
|
659
|
+
current: currentVersion,
|
|
660
|
+
latest: "error",
|
|
661
|
+
hasUpdate: false,
|
|
662
|
+
updateType: "none",
|
|
663
|
+
dependencyType: type
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
})
|
|
667
|
+
);
|
|
668
|
+
results.push(...batchResults);
|
|
669
|
+
}
|
|
670
|
+
return results;
|
|
671
|
+
}
|
|
672
|
+
async function checkPackage(source) {
|
|
673
|
+
const errors = [];
|
|
674
|
+
let pkg;
|
|
675
|
+
try {
|
|
676
|
+
pkg = await fetchPackageJson(source);
|
|
677
|
+
} catch (err) {
|
|
678
|
+
throw new Error(`Failed to load package.json: ${err}`);
|
|
679
|
+
}
|
|
680
|
+
const [dependencies, devDependencies, peerDependencies, optionalDependencies] = await Promise.all([
|
|
681
|
+
checkDependencyType(pkg.dependencies, "dependencies", errors),
|
|
682
|
+
checkDependencyType(pkg.devDependencies, "devDependencies", errors),
|
|
683
|
+
checkDependencyType(pkg.peerDependencies, "peerDependencies", errors),
|
|
684
|
+
checkDependencyType(pkg.optionalDependencies, "optionalDependencies", errors)
|
|
685
|
+
]);
|
|
686
|
+
const allDeps = [...dependencies, ...devDependencies, ...peerDependencies, ...optionalDependencies];
|
|
687
|
+
return {
|
|
688
|
+
packageName: pkg.name || "unknown",
|
|
689
|
+
packageVersion: pkg.version || "0.0.0",
|
|
690
|
+
totalDependencies: allDeps.length,
|
|
691
|
+
outdatedCount: allDeps.filter((d) => d.hasUpdate).length,
|
|
692
|
+
dependencies: allDeps,
|
|
693
|
+
byType: {
|
|
694
|
+
dependencies,
|
|
695
|
+
devDependencies,
|
|
696
|
+
peerDependencies,
|
|
697
|
+
optionalDependencies
|
|
698
|
+
},
|
|
699
|
+
byUpdateType: {
|
|
700
|
+
major: allDeps.filter((d) => d.updateType === "major"),
|
|
701
|
+
minor: allDeps.filter((d) => d.updateType === "minor"),
|
|
702
|
+
patch: allDeps.filter((d) => d.updateType === "patch"),
|
|
703
|
+
prerelease: allDeps.filter((d) => d.updateType === "prerelease")
|
|
704
|
+
},
|
|
705
|
+
checkedAt: /* @__PURE__ */ new Date(),
|
|
706
|
+
errors
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
function formatPackageCheckResult(result) {
|
|
710
|
+
const lines = [];
|
|
711
|
+
lines.push(`\u{1F4E6} Package: ${result.packageName}@${result.packageVersion}`);
|
|
712
|
+
lines.push(`\u{1F4C5} Checked: ${result.checkedAt.toISOString()}`);
|
|
713
|
+
lines.push(`\u{1F4CA} Total: ${result.totalDependencies} | Outdated: ${result.outdatedCount}`);
|
|
714
|
+
lines.push("");
|
|
715
|
+
if (result.byUpdateType.major.length > 0) {
|
|
716
|
+
lines.push("\u{1F534} MAJOR Updates:");
|
|
717
|
+
result.byUpdateType.major.forEach((d) => {
|
|
718
|
+
lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
|
|
719
|
+
});
|
|
720
|
+
lines.push("");
|
|
721
|
+
}
|
|
722
|
+
if (result.byUpdateType.minor.length > 0) {
|
|
723
|
+
lines.push("\u{1F7E1} MINOR Updates:");
|
|
724
|
+
result.byUpdateType.minor.forEach((d) => {
|
|
725
|
+
lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
|
|
726
|
+
});
|
|
727
|
+
lines.push("");
|
|
728
|
+
}
|
|
729
|
+
if (result.byUpdateType.patch.length > 0) {
|
|
730
|
+
lines.push("\u{1F7E2} PATCH Updates:");
|
|
731
|
+
result.byUpdateType.patch.forEach((d) => {
|
|
732
|
+
lines.push(` ${d.name}: ${d.current} \u2192 ${d.latest}`);
|
|
733
|
+
});
|
|
734
|
+
lines.push("");
|
|
735
|
+
}
|
|
736
|
+
if (result.errors.length > 0) {
|
|
737
|
+
lines.push("\u26A0\uFE0F Errors:");
|
|
738
|
+
result.errors.forEach((e) => {
|
|
739
|
+
lines.push(` ${e}`);
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
return lines.join("\n");
|
|
743
|
+
}
|
|
744
|
+
function generateNcuCommand(result, options = {}) {
|
|
745
|
+
const { updateType = "all", interactive = false, upgrade = false } = options;
|
|
746
|
+
let packages = [];
|
|
747
|
+
switch (updateType) {
|
|
748
|
+
case "major":
|
|
749
|
+
packages = result.byUpdateType.major.map((d) => d.name);
|
|
750
|
+
break;
|
|
751
|
+
case "minor":
|
|
752
|
+
packages = result.byUpdateType.minor.map((d) => d.name);
|
|
753
|
+
break;
|
|
754
|
+
case "patch":
|
|
755
|
+
packages = result.byUpdateType.patch.map((d) => d.name);
|
|
756
|
+
break;
|
|
757
|
+
default:
|
|
758
|
+
packages = result.dependencies.filter((d) => d.hasUpdate).map((d) => d.name);
|
|
759
|
+
}
|
|
760
|
+
if (packages.length === 0) {
|
|
761
|
+
return "# No updates available";
|
|
762
|
+
}
|
|
763
|
+
let cmd = "npx npm-check-updates";
|
|
764
|
+
if (packages.length > 0 && packages.length < result.dependencies.length) {
|
|
765
|
+
cmd += ` --filter "${packages.join(",")}"`;
|
|
766
|
+
}
|
|
767
|
+
if (interactive) {
|
|
768
|
+
cmd += " --interactive";
|
|
769
|
+
}
|
|
770
|
+
if (upgrade) {
|
|
771
|
+
cmd += " --upgrade";
|
|
772
|
+
}
|
|
773
|
+
return cmd;
|
|
774
|
+
}
|
|
775
|
+
var packageCheck = {
|
|
776
|
+
check: checkPackage,
|
|
777
|
+
format: formatPackageCheckResult,
|
|
778
|
+
generateNcuCommand,
|
|
779
|
+
parseVersion,
|
|
780
|
+
compareVersions
|
|
781
|
+
};
|
|
782
|
+
function useToggle(initialValue = false) {
|
|
783
|
+
const [value, setValue] = useState(initialValue);
|
|
784
|
+
const toggle = useCallback(() => setValue((v) => !v), []);
|
|
785
|
+
const setTrue = useCallback(() => setValue(true), []);
|
|
786
|
+
const setFalse = useCallback(() => setValue(false), []);
|
|
787
|
+
return {
|
|
788
|
+
value,
|
|
789
|
+
toggle,
|
|
790
|
+
setTrue,
|
|
791
|
+
setFalse,
|
|
792
|
+
setValue
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
var useToggle_default = useToggle;
|
|
796
|
+
function useCounter(initialValue = 0, options = {}) {
|
|
797
|
+
const { min = -Infinity, max = Infinity, step = 1 } = options;
|
|
798
|
+
const clamp = useCallback(
|
|
799
|
+
(value) => Math.min(Math.max(value, min), max),
|
|
800
|
+
[min, max]
|
|
801
|
+
);
|
|
802
|
+
const [count, setCount] = useState(clamp(initialValue));
|
|
803
|
+
const increment = useCallback(() => {
|
|
804
|
+
setCount((c) => clamp(c + step));
|
|
805
|
+
}, [clamp, step]);
|
|
806
|
+
const decrement = useCallback(() => {
|
|
807
|
+
setCount((c) => clamp(c - step));
|
|
808
|
+
}, [clamp, step]);
|
|
809
|
+
const set = useCallback(
|
|
810
|
+
(value) => {
|
|
811
|
+
setCount(clamp(value));
|
|
812
|
+
},
|
|
813
|
+
[clamp]
|
|
814
|
+
);
|
|
815
|
+
const reset = useCallback(() => {
|
|
816
|
+
setCount(clamp(initialValue));
|
|
817
|
+
}, [clamp, initialValue]);
|
|
818
|
+
return { count, increment, decrement, set, reset };
|
|
819
|
+
}
|
|
820
|
+
var useCounter_default = useCounter;
|
|
821
|
+
function useDefault(initialValue, defaultValue) {
|
|
822
|
+
const [state, setState] = useState(initialValue);
|
|
823
|
+
const value = useMemo(() => {
|
|
824
|
+
return state === null || state === void 0 ? defaultValue : state;
|
|
825
|
+
}, [state, defaultValue]);
|
|
826
|
+
const setValue = useCallback((newValue) => {
|
|
827
|
+
setState(newValue);
|
|
828
|
+
}, []);
|
|
829
|
+
return [value, setValue];
|
|
830
|
+
}
|
|
831
|
+
var useDefault_default = useDefault;
|
|
832
|
+
function usePrevious(value, initialValue) {
|
|
833
|
+
const ref = useRef(initialValue);
|
|
834
|
+
useEffect(() => {
|
|
835
|
+
ref.current = value;
|
|
836
|
+
}, [value]);
|
|
837
|
+
return ref.current;
|
|
838
|
+
}
|
|
839
|
+
var usePrevious_default = usePrevious;
|
|
840
|
+
function useObjectState(initialState) {
|
|
841
|
+
const [state, setStateInternal] = useState(initialState);
|
|
842
|
+
const setState = useCallback((update) => {
|
|
843
|
+
setStateInternal((prev) => {
|
|
844
|
+
const newState = typeof update === "function" ? update(prev) : update;
|
|
845
|
+
return { ...prev, ...newState };
|
|
846
|
+
});
|
|
847
|
+
}, []);
|
|
848
|
+
const resetState = useCallback(() => {
|
|
849
|
+
setStateInternal(initialState);
|
|
850
|
+
}, [initialState]);
|
|
851
|
+
const setProperty = useCallback((key, value) => {
|
|
852
|
+
setStateInternal((prev) => ({ ...prev, [key]: value }));
|
|
853
|
+
}, []);
|
|
854
|
+
const removeProperty = useCallback((key) => {
|
|
855
|
+
setStateInternal((prev) => {
|
|
856
|
+
const newState = { ...prev };
|
|
857
|
+
delete newState[key];
|
|
858
|
+
return newState;
|
|
859
|
+
});
|
|
860
|
+
}, []);
|
|
861
|
+
return { state, setState, resetState, setProperty, removeProperty };
|
|
862
|
+
}
|
|
863
|
+
var useObjectState_default = useObjectState;
|
|
864
|
+
function useHistoryState(initialValue, options = {}) {
|
|
865
|
+
const { maxLength = 100 } = options;
|
|
866
|
+
const [history, setHistory] = useState([initialValue]);
|
|
867
|
+
const [pointer, setPointer] = useState(0);
|
|
868
|
+
const state = useMemo(() => history[pointer], [history, pointer]);
|
|
869
|
+
const setState = useCallback(
|
|
870
|
+
(value) => {
|
|
871
|
+
setHistory((prev) => {
|
|
872
|
+
const currentValue = prev[pointer];
|
|
873
|
+
const newValue = typeof value === "function" ? value(currentValue) : value;
|
|
874
|
+
const newHistory = prev.slice(0, pointer + 1);
|
|
875
|
+
newHistory.push(newValue);
|
|
876
|
+
if (newHistory.length > maxLength) {
|
|
877
|
+
newHistory.shift();
|
|
878
|
+
return newHistory;
|
|
879
|
+
}
|
|
880
|
+
return newHistory;
|
|
881
|
+
});
|
|
882
|
+
setPointer((prev) => Math.min(prev + 1, maxLength - 1));
|
|
883
|
+
},
|
|
884
|
+
[pointer, maxLength]
|
|
885
|
+
);
|
|
886
|
+
const undo = useCallback(() => {
|
|
887
|
+
setPointer((prev) => Math.max(0, prev - 1));
|
|
888
|
+
}, []);
|
|
889
|
+
const redo = useCallback(() => {
|
|
890
|
+
setPointer((prev) => Math.min(history.length - 1, prev + 1));
|
|
891
|
+
}, [history.length]);
|
|
892
|
+
const go = useCallback(
|
|
893
|
+
(index) => {
|
|
894
|
+
const targetIndex = Math.max(0, Math.min(history.length - 1, index));
|
|
895
|
+
setPointer(targetIndex);
|
|
896
|
+
},
|
|
897
|
+
[history.length]
|
|
898
|
+
);
|
|
899
|
+
const clear = useCallback(
|
|
900
|
+
(value) => {
|
|
901
|
+
const resetValue = value ?? initialValue;
|
|
902
|
+
setHistory([resetValue]);
|
|
903
|
+
setPointer(0);
|
|
904
|
+
},
|
|
905
|
+
[initialValue]
|
|
906
|
+
);
|
|
907
|
+
const canUndo = pointer > 0;
|
|
908
|
+
const canRedo = pointer < history.length - 1;
|
|
909
|
+
return {
|
|
910
|
+
state,
|
|
911
|
+
setState,
|
|
912
|
+
undo,
|
|
913
|
+
redo,
|
|
914
|
+
clear,
|
|
915
|
+
canUndo,
|
|
916
|
+
canRedo,
|
|
917
|
+
history,
|
|
918
|
+
pointer,
|
|
919
|
+
go
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
var useHistoryState_default = useHistoryState;
|
|
923
|
+
function useQueue(initialValue = []) {
|
|
924
|
+
const [queue, setQueue] = useState(initialValue);
|
|
925
|
+
const enqueue = useCallback((item) => {
|
|
926
|
+
setQueue((prev) => [...prev, item]);
|
|
927
|
+
}, []);
|
|
928
|
+
const enqueueAll = useCallback((items) => {
|
|
929
|
+
setQueue((prev) => [...prev, ...items]);
|
|
930
|
+
}, []);
|
|
931
|
+
const dequeue = useCallback(() => {
|
|
932
|
+
let dequeuedItem;
|
|
933
|
+
setQueue((prev) => {
|
|
934
|
+
if (prev.length === 0) return prev;
|
|
935
|
+
dequeuedItem = prev[0];
|
|
936
|
+
return prev.slice(1);
|
|
937
|
+
});
|
|
938
|
+
return dequeuedItem;
|
|
939
|
+
}, []);
|
|
940
|
+
const peek = useCallback(() => {
|
|
941
|
+
return queue[0];
|
|
942
|
+
}, [queue]);
|
|
943
|
+
const clear = useCallback(() => {
|
|
944
|
+
setQueue([]);
|
|
945
|
+
}, []);
|
|
946
|
+
const size = queue.length;
|
|
947
|
+
const isEmpty = size === 0;
|
|
948
|
+
const first = queue[0];
|
|
949
|
+
const last = queue[queue.length - 1];
|
|
950
|
+
return {
|
|
951
|
+
queue,
|
|
952
|
+
enqueue,
|
|
953
|
+
enqueueAll,
|
|
954
|
+
dequeue,
|
|
955
|
+
peek,
|
|
956
|
+
clear,
|
|
957
|
+
size,
|
|
958
|
+
isEmpty,
|
|
959
|
+
first,
|
|
960
|
+
last
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
var useQueue_default = useQueue;
|
|
964
|
+
function useList(initialValue = []) {
|
|
965
|
+
const [list, setList] = useState(initialValue);
|
|
966
|
+
const set = useCallback((newList) => {
|
|
967
|
+
setList(newList);
|
|
968
|
+
}, []);
|
|
969
|
+
const push = useCallback((item) => {
|
|
970
|
+
setList((prev) => [...prev, item]);
|
|
971
|
+
}, []);
|
|
972
|
+
const unshift = useCallback((item) => {
|
|
973
|
+
setList((prev) => [item, ...prev]);
|
|
974
|
+
}, []);
|
|
975
|
+
const removeAt = useCallback((index) => {
|
|
976
|
+
setList((prev) => prev.filter((_, i) => i !== index));
|
|
977
|
+
}, []);
|
|
978
|
+
const remove = useCallback((item) => {
|
|
979
|
+
setList((prev) => {
|
|
980
|
+
const index = prev.indexOf(item);
|
|
981
|
+
if (index === -1) return prev;
|
|
982
|
+
return prev.filter((_, i) => i !== index);
|
|
983
|
+
});
|
|
984
|
+
}, []);
|
|
985
|
+
const removeWhere = useCallback((predicate) => {
|
|
986
|
+
setList((prev) => prev.filter((item) => !predicate(item)));
|
|
987
|
+
}, []);
|
|
988
|
+
const updateAt = useCallback((index, item) => {
|
|
989
|
+
setList((prev) => prev.map((v, i) => i === index ? item : v));
|
|
990
|
+
}, []);
|
|
991
|
+
const updateWhere = useCallback(
|
|
992
|
+
(predicate, updater) => {
|
|
993
|
+
setList((prev) => prev.map((item) => predicate(item) ? updater(item) : item));
|
|
994
|
+
},
|
|
995
|
+
[]
|
|
996
|
+
);
|
|
997
|
+
const insertAt = useCallback((index, item) => {
|
|
998
|
+
setList((prev) => [...prev.slice(0, index), item, ...prev.slice(index)]);
|
|
999
|
+
}, []);
|
|
1000
|
+
const move = useCallback((fromIndex, toIndex) => {
|
|
1001
|
+
setList((prev) => {
|
|
1002
|
+
const newList = [...prev];
|
|
1003
|
+
const [item] = newList.splice(fromIndex, 1);
|
|
1004
|
+
newList.splice(toIndex, 0, item);
|
|
1005
|
+
return newList;
|
|
1006
|
+
});
|
|
1007
|
+
}, []);
|
|
1008
|
+
const clear = useCallback(() => {
|
|
1009
|
+
setList([]);
|
|
1010
|
+
}, []);
|
|
1011
|
+
const reset = useCallback(() => {
|
|
1012
|
+
setList(initialValue);
|
|
1013
|
+
}, [initialValue]);
|
|
1014
|
+
const filter = useCallback((predicate) => {
|
|
1015
|
+
setList((prev) => prev.filter(predicate));
|
|
1016
|
+
}, []);
|
|
1017
|
+
const sort = useCallback((compareFn) => {
|
|
1018
|
+
setList((prev) => [...prev].sort(compareFn));
|
|
1019
|
+
}, []);
|
|
1020
|
+
const reverse = useCallback(() => {
|
|
1021
|
+
setList((prev) => [...prev].reverse());
|
|
1022
|
+
}, []);
|
|
1023
|
+
const size = list.length;
|
|
1024
|
+
const isEmpty = size === 0;
|
|
1025
|
+
const first = list[0];
|
|
1026
|
+
const last = list[list.length - 1];
|
|
1027
|
+
return {
|
|
1028
|
+
list,
|
|
1029
|
+
set,
|
|
1030
|
+
push,
|
|
1031
|
+
unshift,
|
|
1032
|
+
removeAt,
|
|
1033
|
+
remove,
|
|
1034
|
+
removeWhere,
|
|
1035
|
+
updateAt,
|
|
1036
|
+
updateWhere,
|
|
1037
|
+
insertAt,
|
|
1038
|
+
move,
|
|
1039
|
+
clear,
|
|
1040
|
+
reset,
|
|
1041
|
+
filter,
|
|
1042
|
+
sort,
|
|
1043
|
+
reverse,
|
|
1044
|
+
size,
|
|
1045
|
+
isEmpty,
|
|
1046
|
+
first,
|
|
1047
|
+
last
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
var useList_default = useList;
|
|
1051
|
+
function useMap(initialValue = []) {
|
|
1052
|
+
const [map, setMap] = useState(() => new Map(initialValue));
|
|
1053
|
+
const get = useCallback((key) => {
|
|
1054
|
+
return map.get(key);
|
|
1055
|
+
}, [map]);
|
|
1056
|
+
const set = useCallback((key, value) => {
|
|
1057
|
+
setMap((prev) => {
|
|
1058
|
+
const newMap = new Map(prev);
|
|
1059
|
+
newMap.set(key, value);
|
|
1060
|
+
return newMap;
|
|
1061
|
+
});
|
|
1062
|
+
}, []);
|
|
1063
|
+
const setAll = useCallback((entries2) => {
|
|
1064
|
+
setMap((prev) => {
|
|
1065
|
+
const newMap = new Map(prev);
|
|
1066
|
+
for (const [key, value] of entries2) {
|
|
1067
|
+
newMap.set(key, value);
|
|
1068
|
+
}
|
|
1069
|
+
return newMap;
|
|
1070
|
+
});
|
|
1071
|
+
}, []);
|
|
1072
|
+
const has = useCallback((key) => {
|
|
1073
|
+
return map.has(key);
|
|
1074
|
+
}, [map]);
|
|
1075
|
+
const remove = useCallback((key) => {
|
|
1076
|
+
setMap((prev) => {
|
|
1077
|
+
const newMap = new Map(prev);
|
|
1078
|
+
newMap.delete(key);
|
|
1079
|
+
return newMap;
|
|
1080
|
+
});
|
|
1081
|
+
}, []);
|
|
1082
|
+
const removeAll = useCallback((keys2) => {
|
|
1083
|
+
setMap((prev) => {
|
|
1084
|
+
const newMap = new Map(prev);
|
|
1085
|
+
keys2.forEach((key) => newMap.delete(key));
|
|
1086
|
+
return newMap;
|
|
1087
|
+
});
|
|
1088
|
+
}, []);
|
|
1089
|
+
const clear = useCallback(() => {
|
|
1090
|
+
setMap(/* @__PURE__ */ new Map());
|
|
1091
|
+
}, []);
|
|
1092
|
+
const reset = useCallback(() => {
|
|
1093
|
+
setMap(new Map(initialValue));
|
|
1094
|
+
}, [initialValue]);
|
|
1095
|
+
const size = map.size;
|
|
1096
|
+
const keys = useMemo(() => Array.from(map.keys()), [map]);
|
|
1097
|
+
const values = useMemo(() => Array.from(map.values()), [map]);
|
|
1098
|
+
const entries = useMemo(() => Array.from(map.entries()), [map]);
|
|
1099
|
+
const isEmpty = size === 0;
|
|
1100
|
+
return {
|
|
1101
|
+
map,
|
|
1102
|
+
get,
|
|
1103
|
+
set,
|
|
1104
|
+
setAll,
|
|
1105
|
+
has,
|
|
1106
|
+
remove,
|
|
1107
|
+
removeAll,
|
|
1108
|
+
clear,
|
|
1109
|
+
reset,
|
|
1110
|
+
size,
|
|
1111
|
+
keys,
|
|
1112
|
+
values,
|
|
1113
|
+
entries,
|
|
1114
|
+
isEmpty
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
var useMap_default = useMap;
|
|
1118
|
+
function useSet(initialValue = []) {
|
|
1119
|
+
const [set, setSet] = useState(() => new Set(initialValue));
|
|
1120
|
+
const add = useCallback((item) => {
|
|
1121
|
+
setSet((prev) => /* @__PURE__ */ new Set([...prev, item]));
|
|
1122
|
+
}, []);
|
|
1123
|
+
const addAll = useCallback((items) => {
|
|
1124
|
+
setSet((prev) => /* @__PURE__ */ new Set([...prev, ...items]));
|
|
1125
|
+
}, []);
|
|
1126
|
+
const has = useCallback((item) => {
|
|
1127
|
+
return set.has(item);
|
|
1128
|
+
}, [set]);
|
|
1129
|
+
const remove = useCallback((item) => {
|
|
1130
|
+
setSet((prev) => {
|
|
1131
|
+
const newSet = new Set(prev);
|
|
1132
|
+
newSet.delete(item);
|
|
1133
|
+
return newSet;
|
|
1134
|
+
});
|
|
1135
|
+
}, []);
|
|
1136
|
+
const removeAll = useCallback((items) => {
|
|
1137
|
+
setSet((prev) => {
|
|
1138
|
+
const newSet = new Set(prev);
|
|
1139
|
+
for (const item of items) {
|
|
1140
|
+
newSet.delete(item);
|
|
1141
|
+
}
|
|
1142
|
+
return newSet;
|
|
1143
|
+
});
|
|
1144
|
+
}, []);
|
|
1145
|
+
const toggle = useCallback((item) => {
|
|
1146
|
+
setSet((prev) => {
|
|
1147
|
+
const newSet = new Set(prev);
|
|
1148
|
+
if (newSet.has(item)) {
|
|
1149
|
+
newSet.delete(item);
|
|
1150
|
+
} else {
|
|
1151
|
+
newSet.add(item);
|
|
1152
|
+
}
|
|
1153
|
+
return newSet;
|
|
1154
|
+
});
|
|
1155
|
+
}, []);
|
|
1156
|
+
const clear = useCallback(() => {
|
|
1157
|
+
setSet(/* @__PURE__ */ new Set());
|
|
1158
|
+
}, []);
|
|
1159
|
+
const reset = useCallback(() => {
|
|
1160
|
+
setSet(new Set(initialValue));
|
|
1161
|
+
}, [initialValue]);
|
|
1162
|
+
const size = set.size;
|
|
1163
|
+
const values = useMemo(() => Array.from(set), [set]);
|
|
1164
|
+
const isEmpty = size === 0;
|
|
1165
|
+
return {
|
|
1166
|
+
set,
|
|
1167
|
+
add,
|
|
1168
|
+
addAll,
|
|
1169
|
+
has,
|
|
1170
|
+
remove,
|
|
1171
|
+
removeAll,
|
|
1172
|
+
toggle,
|
|
1173
|
+
clear,
|
|
1174
|
+
reset,
|
|
1175
|
+
size,
|
|
1176
|
+
values,
|
|
1177
|
+
isEmpty
|
|
1178
|
+
};
|
|
1179
|
+
}
|
|
1180
|
+
var useSet_default = useSet;
|
|
1181
|
+
function useDebounce(value, delay = 500) {
|
|
1182
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
1183
|
+
useEffect(() => {
|
|
1184
|
+
const timer = setTimeout(() => {
|
|
1185
|
+
setDebouncedValue(value);
|
|
1186
|
+
}, delay);
|
|
1187
|
+
return () => {
|
|
1188
|
+
clearTimeout(timer);
|
|
1189
|
+
};
|
|
1190
|
+
}, [value, delay]);
|
|
1191
|
+
return debouncedValue;
|
|
1192
|
+
}
|
|
1193
|
+
var useDebounce_default = useDebounce;
|
|
1194
|
+
function useThrottle(value, interval = 500) {
|
|
1195
|
+
const [throttledValue, setThrottledValue] = useState(value);
|
|
1196
|
+
const lastUpdated = useRef(Date.now());
|
|
1197
|
+
useEffect(() => {
|
|
1198
|
+
const now = Date.now();
|
|
1199
|
+
const timeSinceLastUpdate = now - lastUpdated.current;
|
|
1200
|
+
if (timeSinceLastUpdate >= interval) {
|
|
1201
|
+
lastUpdated.current = now;
|
|
1202
|
+
setThrottledValue(value);
|
|
1203
|
+
return;
|
|
1204
|
+
} else {
|
|
1205
|
+
const timeoutId = setTimeout(() => {
|
|
1206
|
+
lastUpdated.current = Date.now();
|
|
1207
|
+
setThrottledValue(value);
|
|
1208
|
+
}, interval - timeSinceLastUpdate);
|
|
1209
|
+
return () => clearTimeout(timeoutId);
|
|
1210
|
+
}
|
|
1211
|
+
}, [value, interval]);
|
|
1212
|
+
return throttledValue;
|
|
1213
|
+
}
|
|
1214
|
+
var useThrottle_default = useThrottle;
|
|
1215
|
+
function useTimeout(callback, delay) {
|
|
1216
|
+
const savedCallback = useRef(callback);
|
|
1217
|
+
const timeoutId = useRef(null);
|
|
1218
|
+
useEffect(() => {
|
|
1219
|
+
savedCallback.current = callback;
|
|
1220
|
+
}, [callback]);
|
|
1221
|
+
const clear = useCallback(() => {
|
|
1222
|
+
if (timeoutId.current) {
|
|
1223
|
+
clearTimeout(timeoutId.current);
|
|
1224
|
+
timeoutId.current = null;
|
|
1225
|
+
}
|
|
1226
|
+
}, []);
|
|
1227
|
+
const reset = useCallback(() => {
|
|
1228
|
+
clear();
|
|
1229
|
+
if (delay !== null) {
|
|
1230
|
+
timeoutId.current = setTimeout(() => {
|
|
1231
|
+
savedCallback.current();
|
|
1232
|
+
}, delay);
|
|
1233
|
+
}
|
|
1234
|
+
}, [delay, clear]);
|
|
1235
|
+
useEffect(() => {
|
|
1236
|
+
if (delay === null) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
timeoutId.current = setTimeout(() => {
|
|
1240
|
+
savedCallback.current();
|
|
1241
|
+
}, delay);
|
|
1242
|
+
return clear;
|
|
1243
|
+
}, [delay, clear]);
|
|
1244
|
+
return { reset, clear };
|
|
1245
|
+
}
|
|
1246
|
+
var useTimeout_default = useTimeout;
|
|
1247
|
+
function useInterval(callback, delay) {
|
|
1248
|
+
const savedCallback = useRef(callback);
|
|
1249
|
+
useEffect(() => {
|
|
1250
|
+
savedCallback.current = callback;
|
|
1251
|
+
}, [callback]);
|
|
1252
|
+
useEffect(() => {
|
|
1253
|
+
if (delay === null) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
const tick = () => savedCallback.current();
|
|
1257
|
+
const id = setInterval(tick, delay);
|
|
1258
|
+
return () => clearInterval(id);
|
|
1259
|
+
}, [delay]);
|
|
1260
|
+
}
|
|
1261
|
+
var useInterval_default = useInterval;
|
|
1262
|
+
function useIntervalWhen(callback, delay, when, immediate = false) {
|
|
1263
|
+
const savedCallback = useRef(callback);
|
|
1264
|
+
const hasRunImmediate = useRef(false);
|
|
1265
|
+
useEffect(() => {
|
|
1266
|
+
savedCallback.current = callback;
|
|
1267
|
+
}, [callback]);
|
|
1268
|
+
useEffect(() => {
|
|
1269
|
+
if (!when) {
|
|
1270
|
+
hasRunImmediate.current = false;
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
if (immediate && !hasRunImmediate.current) {
|
|
1274
|
+
hasRunImmediate.current = true;
|
|
1275
|
+
savedCallback.current();
|
|
1276
|
+
}
|
|
1277
|
+
const id = setInterval(() => {
|
|
1278
|
+
savedCallback.current();
|
|
1279
|
+
}, delay);
|
|
1280
|
+
return () => clearInterval(id);
|
|
1281
|
+
}, [delay, when, immediate]);
|
|
1282
|
+
}
|
|
1283
|
+
var useIntervalWhen_default = useIntervalWhen;
|
|
1284
|
+
function useRandomInterval(callback, minDelay, maxDelay, enabled = true) {
|
|
1285
|
+
const savedCallback = useRef(callback);
|
|
1286
|
+
const timeoutId = useRef(null);
|
|
1287
|
+
useEffect(() => {
|
|
1288
|
+
savedCallback.current = callback;
|
|
1289
|
+
}, [callback]);
|
|
1290
|
+
const getRandomDelay = useCallback(() => {
|
|
1291
|
+
return Math.floor(Math.random() * (maxDelay - minDelay + 1)) + minDelay;
|
|
1292
|
+
}, [minDelay, maxDelay]);
|
|
1293
|
+
useEffect(() => {
|
|
1294
|
+
if (!enabled) {
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
const tick = () => {
|
|
1298
|
+
savedCallback.current();
|
|
1299
|
+
timeoutId.current = setTimeout(tick, getRandomDelay());
|
|
1300
|
+
};
|
|
1301
|
+
timeoutId.current = setTimeout(tick, getRandomDelay());
|
|
1302
|
+
return () => {
|
|
1303
|
+
if (timeoutId.current) {
|
|
1304
|
+
clearTimeout(timeoutId.current);
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
}, [enabled, getRandomDelay]);
|
|
1308
|
+
}
|
|
1309
|
+
var useRandomInterval_default = useRandomInterval;
|
|
1310
|
+
function useCountdown(initialCount, options = {}) {
|
|
1311
|
+
const { interval = 1e3, onComplete, autoStart = false } = options;
|
|
1312
|
+
const [count, setCount] = useState(initialCount);
|
|
1313
|
+
const [isRunning, setIsRunning] = useState(autoStart);
|
|
1314
|
+
const intervalRef = useRef(null);
|
|
1315
|
+
const onCompleteRef = useRef(onComplete);
|
|
1316
|
+
useEffect(() => {
|
|
1317
|
+
onCompleteRef.current = onComplete;
|
|
1318
|
+
}, [onComplete]);
|
|
1319
|
+
const isComplete = count <= 0;
|
|
1320
|
+
const clear = useCallback(() => {
|
|
1321
|
+
if (intervalRef.current) {
|
|
1322
|
+
clearInterval(intervalRef.current);
|
|
1323
|
+
intervalRef.current = null;
|
|
1324
|
+
}
|
|
1325
|
+
}, []);
|
|
1326
|
+
const start = useCallback(() => {
|
|
1327
|
+
if (count <= 0) return;
|
|
1328
|
+
setIsRunning(true);
|
|
1329
|
+
}, [count]);
|
|
1330
|
+
const pause = useCallback(() => {
|
|
1331
|
+
setIsRunning(false);
|
|
1332
|
+
clear();
|
|
1333
|
+
}, [clear]);
|
|
1334
|
+
const resume = useCallback(() => {
|
|
1335
|
+
if (count > 0) {
|
|
1336
|
+
setIsRunning(true);
|
|
1337
|
+
}
|
|
1338
|
+
}, [count]);
|
|
1339
|
+
const reset = useCallback(
|
|
1340
|
+
(newCount) => {
|
|
1341
|
+
clear();
|
|
1342
|
+
setCount(newCount ?? initialCount);
|
|
1343
|
+
setIsRunning(false);
|
|
1344
|
+
},
|
|
1345
|
+
[clear, initialCount]
|
|
1346
|
+
);
|
|
1347
|
+
useEffect(() => {
|
|
1348
|
+
if (!isRunning || count <= 0) {
|
|
1349
|
+
clear();
|
|
1350
|
+
return;
|
|
1351
|
+
}
|
|
1352
|
+
intervalRef.current = setInterval(() => {
|
|
1353
|
+
setCount((prev) => {
|
|
1354
|
+
const newCount = prev - interval;
|
|
1355
|
+
if (newCount <= 0) {
|
|
1356
|
+
setIsRunning(false);
|
|
1357
|
+
onCompleteRef.current?.();
|
|
1358
|
+
return 0;
|
|
1359
|
+
}
|
|
1360
|
+
return newCount;
|
|
1361
|
+
});
|
|
1362
|
+
}, interval);
|
|
1363
|
+
return clear;
|
|
1364
|
+
}, [isRunning, interval, clear, count]);
|
|
1365
|
+
const formatted = {
|
|
1366
|
+
days: Math.floor(count / (1e3 * 60 * 60 * 24)),
|
|
1367
|
+
hours: Math.floor(count % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60)),
|
|
1368
|
+
minutes: Math.floor(count % (1e3 * 60 * 60) / (1e3 * 60)),
|
|
1369
|
+
seconds: Math.floor(count % (1e3 * 60) / 1e3)
|
|
1370
|
+
};
|
|
1371
|
+
return {
|
|
1372
|
+
count,
|
|
1373
|
+
start,
|
|
1374
|
+
pause,
|
|
1375
|
+
resume,
|
|
1376
|
+
reset,
|
|
1377
|
+
isRunning,
|
|
1378
|
+
isComplete,
|
|
1379
|
+
formatted
|
|
1380
|
+
};
|
|
1381
|
+
}
|
|
1382
|
+
var useCountdown_default = useCountdown;
|
|
1383
|
+
function useContinuousRetry(callback, options = {}) {
|
|
1384
|
+
const {
|
|
1385
|
+
maxAttempts = Infinity,
|
|
1386
|
+
delay = 1e3,
|
|
1387
|
+
exponentialBackoff = false,
|
|
1388
|
+
maxDelay = 3e4,
|
|
1389
|
+
autoStart = true
|
|
1390
|
+
} = options;
|
|
1391
|
+
const [attempts, setAttempts] = useState(0);
|
|
1392
|
+
const [error, setError] = useState(null);
|
|
1393
|
+
const [isRetrying, setIsRetrying] = useState(autoStart);
|
|
1394
|
+
const [isSuccess2, setIsSuccess] = useState(false);
|
|
1395
|
+
const callbackRef = useRef(callback);
|
|
1396
|
+
const timeoutRef = useRef(null);
|
|
1397
|
+
useEffect(() => {
|
|
1398
|
+
callbackRef.current = callback;
|
|
1399
|
+
}, [callback]);
|
|
1400
|
+
const isMaxAttempts = attempts >= maxAttempts;
|
|
1401
|
+
const calculateDelay = useCallback(
|
|
1402
|
+
(attempt) => {
|
|
1403
|
+
if (!exponentialBackoff) return delay;
|
|
1404
|
+
const exponentialDelay = delay * Math.pow(2, attempt);
|
|
1405
|
+
return Math.min(exponentialDelay, maxDelay);
|
|
1406
|
+
},
|
|
1407
|
+
[delay, exponentialBackoff, maxDelay]
|
|
1408
|
+
);
|
|
1409
|
+
const clear = useCallback(() => {
|
|
1410
|
+
if (timeoutRef.current) {
|
|
1411
|
+
clearTimeout(timeoutRef.current);
|
|
1412
|
+
timeoutRef.current = null;
|
|
1413
|
+
}
|
|
1414
|
+
}, []);
|
|
1415
|
+
const stop = useCallback(() => {
|
|
1416
|
+
clear();
|
|
1417
|
+
setIsRetrying(false);
|
|
1418
|
+
}, [clear]);
|
|
1419
|
+
const reset = useCallback(() => {
|
|
1420
|
+
clear();
|
|
1421
|
+
setAttempts(0);
|
|
1422
|
+
setError(null);
|
|
1423
|
+
setIsRetrying(false);
|
|
1424
|
+
setIsSuccess(false);
|
|
1425
|
+
}, [clear]);
|
|
1426
|
+
const start = useCallback(() => {
|
|
1427
|
+
reset();
|
|
1428
|
+
setIsRetrying(true);
|
|
1429
|
+
}, [reset]);
|
|
1430
|
+
useEffect(() => {
|
|
1431
|
+
if (!isRetrying || isSuccess2 || isMaxAttempts) {
|
|
1432
|
+
return;
|
|
1433
|
+
}
|
|
1434
|
+
const attemptCallback = async () => {
|
|
1435
|
+
try {
|
|
1436
|
+
setAttempts((prev) => prev + 1);
|
|
1437
|
+
const result = await callbackRef.current();
|
|
1438
|
+
if (result) {
|
|
1439
|
+
setIsSuccess(true);
|
|
1440
|
+
setIsRetrying(false);
|
|
1441
|
+
} else {
|
|
1442
|
+
const currentDelay = calculateDelay(attempts);
|
|
1443
|
+
timeoutRef.current = setTimeout(attemptCallback, currentDelay);
|
|
1444
|
+
}
|
|
1445
|
+
} catch (err) {
|
|
1446
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1447
|
+
const currentDelay = calculateDelay(attempts);
|
|
1448
|
+
timeoutRef.current = setTimeout(attemptCallback, currentDelay);
|
|
1449
|
+
}
|
|
1450
|
+
};
|
|
1451
|
+
if (attempts === 0) {
|
|
1452
|
+
attemptCallback();
|
|
1453
|
+
}
|
|
1454
|
+
return clear;
|
|
1455
|
+
}, [isRetrying, isSuccess2, isMaxAttempts, attempts, calculateDelay, clear]);
|
|
1456
|
+
return {
|
|
1457
|
+
attempts,
|
|
1458
|
+
error,
|
|
1459
|
+
isRetrying,
|
|
1460
|
+
isSuccess: isSuccess2,
|
|
1461
|
+
isMaxAttempts,
|
|
1462
|
+
start,
|
|
1463
|
+
stop,
|
|
1464
|
+
reset
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
var useContinuousRetry_default = useContinuousRetry;
|
|
1468
|
+
function useWindowSize(debounceMs = 100) {
|
|
1469
|
+
const getSize = () => ({
|
|
1470
|
+
width: typeof window !== "undefined" ? window.innerWidth : 0,
|
|
1471
|
+
height: typeof window !== "undefined" ? window.innerHeight : 0
|
|
1472
|
+
});
|
|
1473
|
+
const [windowSize, setWindowSize] = useState(getSize);
|
|
1474
|
+
useEffect(() => {
|
|
1475
|
+
if (typeof window === "undefined") return;
|
|
1476
|
+
let timeoutId;
|
|
1477
|
+
const handleResize = () => {
|
|
1478
|
+
clearTimeout(timeoutId);
|
|
1479
|
+
timeoutId = setTimeout(() => {
|
|
1480
|
+
setWindowSize(getSize());
|
|
1481
|
+
}, debounceMs);
|
|
1482
|
+
};
|
|
1483
|
+
setWindowSize(getSize());
|
|
1484
|
+
window.addEventListener("resize", handleResize);
|
|
1485
|
+
return () => {
|
|
1486
|
+
clearTimeout(timeoutId);
|
|
1487
|
+
window.removeEventListener("resize", handleResize);
|
|
1488
|
+
};
|
|
1489
|
+
}, [debounceMs]);
|
|
1490
|
+
return windowSize;
|
|
1491
|
+
}
|
|
1492
|
+
var useWindowSize_default = useWindowSize;
|
|
1493
|
+
function useWindowScroll() {
|
|
1494
|
+
const [scroll, setScroll] = useState({
|
|
1495
|
+
x: typeof window !== "undefined" ? window.scrollX : 0,
|
|
1496
|
+
y: typeof window !== "undefined" ? window.scrollY : 0,
|
|
1497
|
+
direction: null,
|
|
1498
|
+
isScrolling: false
|
|
1499
|
+
});
|
|
1500
|
+
useEffect(() => {
|
|
1501
|
+
if (typeof window === "undefined") return;
|
|
1502
|
+
let prevX = window.scrollX;
|
|
1503
|
+
let prevY = window.scrollY;
|
|
1504
|
+
let scrollTimeout;
|
|
1505
|
+
const handleScroll = () => {
|
|
1506
|
+
const x = window.scrollX;
|
|
1507
|
+
const y = window.scrollY;
|
|
1508
|
+
let direction = null;
|
|
1509
|
+
if (y > prevY) direction = "down";
|
|
1510
|
+
else if (y < prevY) direction = "up";
|
|
1511
|
+
else if (x > prevX) direction = "right";
|
|
1512
|
+
else if (x < prevX) direction = "left";
|
|
1513
|
+
prevX = x;
|
|
1514
|
+
prevY = y;
|
|
1515
|
+
setScroll({ x, y, direction, isScrolling: true });
|
|
1516
|
+
clearTimeout(scrollTimeout);
|
|
1517
|
+
scrollTimeout = setTimeout(() => {
|
|
1518
|
+
setScroll((prev) => ({ ...prev, isScrolling: false }));
|
|
1519
|
+
}, 150);
|
|
1520
|
+
};
|
|
1521
|
+
window.addEventListener("scroll", handleScroll, { passive: true });
|
|
1522
|
+
return () => {
|
|
1523
|
+
window.removeEventListener("scroll", handleScroll);
|
|
1524
|
+
clearTimeout(scrollTimeout);
|
|
1525
|
+
};
|
|
1526
|
+
}, []);
|
|
1527
|
+
const scrollTo = useCallback((options) => {
|
|
1528
|
+
if (typeof window !== "undefined") {
|
|
1529
|
+
window.scrollTo(options);
|
|
1530
|
+
}
|
|
1531
|
+
}, []);
|
|
1532
|
+
const scrollToTop = useCallback((behavior = "smooth") => {
|
|
1533
|
+
if (typeof window !== "undefined") {
|
|
1534
|
+
window.scrollTo({ top: 0, behavior });
|
|
1535
|
+
}
|
|
1536
|
+
}, []);
|
|
1537
|
+
const scrollToBottom = useCallback((behavior = "smooth") => {
|
|
1538
|
+
if (typeof window !== "undefined") {
|
|
1539
|
+
window.scrollTo({
|
|
1540
|
+
top: document.documentElement.scrollHeight,
|
|
1541
|
+
behavior
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
}, []);
|
|
1545
|
+
return {
|
|
1546
|
+
...scroll,
|
|
1547
|
+
scrollTo,
|
|
1548
|
+
scrollToTop,
|
|
1549
|
+
scrollToBottom
|
|
1550
|
+
};
|
|
1551
|
+
}
|
|
1552
|
+
var useWindowScroll_default = useWindowScroll;
|
|
1553
|
+
function useDocumentTitle(title, options = {}) {
|
|
1554
|
+
const { restoreOnUnmount = true, template } = options;
|
|
1555
|
+
const previousTitle = useRef(null);
|
|
1556
|
+
useEffect(() => {
|
|
1557
|
+
if (typeof document === "undefined") return;
|
|
1558
|
+
if (previousTitle.current === null) {
|
|
1559
|
+
previousTitle.current = document.title;
|
|
1560
|
+
}
|
|
1561
|
+
const finalTitle = template ? template.replace("%s", title) : title;
|
|
1562
|
+
document.title = finalTitle;
|
|
1563
|
+
return () => {
|
|
1564
|
+
if (restoreOnUnmount && previousTitle.current !== null) {
|
|
1565
|
+
document.title = previousTitle.current;
|
|
1566
|
+
}
|
|
1567
|
+
};
|
|
1568
|
+
}, [title, template, restoreOnUnmount]);
|
|
1569
|
+
}
|
|
1570
|
+
var useDocumentTitle_default = useDocumentTitle;
|
|
1571
|
+
function usePageTitle(title, options = {}) {
|
|
1572
|
+
const { suffix, separator = " | ", restoreOnUnmount = true } = options;
|
|
1573
|
+
useEffect(() => {
|
|
1574
|
+
const originalTitle = document.title;
|
|
1575
|
+
const newTitle = suffix ? `${title}${separator}${suffix}` : title;
|
|
1576
|
+
document.title = newTitle;
|
|
1577
|
+
return () => {
|
|
1578
|
+
if (restoreOnUnmount) {
|
|
1579
|
+
document.title = originalTitle;
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
}, [title, suffix, separator, restoreOnUnmount]);
|
|
1583
|
+
}
|
|
1584
|
+
var usePageTitle_default = usePageTitle;
|
|
1585
|
+
function useFavicon(href, restoreOnUnmount = true) {
|
|
1586
|
+
const originalHref = useRef(null);
|
|
1587
|
+
useEffect(() => {
|
|
1588
|
+
if (typeof document === "undefined") return;
|
|
1589
|
+
const link = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
1590
|
+
if (originalHref.current === null) {
|
|
1591
|
+
originalHref.current = link.href;
|
|
1592
|
+
}
|
|
1593
|
+
link.type = "image/x-icon";
|
|
1594
|
+
link.rel = "shortcut icon";
|
|
1595
|
+
link.href = href;
|
|
1596
|
+
document.head.appendChild(link);
|
|
1597
|
+
return () => {
|
|
1598
|
+
if (restoreOnUnmount && originalHref.current) {
|
|
1599
|
+
link.href = originalHref.current;
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
}, [href, restoreOnUnmount]);
|
|
1603
|
+
}
|
|
1604
|
+
var useFavicon_default = useFavicon;
|
|
1605
|
+
function useVisibilityChange(onVisibilityChange) {
|
|
1606
|
+
const [state, setState] = useState(() => ({
|
|
1607
|
+
isVisible: typeof document !== "undefined" ? !document.hidden : true,
|
|
1608
|
+
visibilityState: typeof document !== "undefined" ? document.visibilityState : "visible",
|
|
1609
|
+
lastChanged: null
|
|
1610
|
+
}));
|
|
1611
|
+
const handleVisibilityChange = useCallback(() => {
|
|
1612
|
+
const isVisible = !document.hidden;
|
|
1613
|
+
const visibilityState = document.visibilityState;
|
|
1614
|
+
setState({
|
|
1615
|
+
isVisible,
|
|
1616
|
+
visibilityState,
|
|
1617
|
+
lastChanged: /* @__PURE__ */ new Date()
|
|
1618
|
+
});
|
|
1619
|
+
onVisibilityChange?.(isVisible);
|
|
1620
|
+
}, [onVisibilityChange]);
|
|
1621
|
+
useEffect(() => {
|
|
1622
|
+
if (typeof document === "undefined") return;
|
|
1623
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
1624
|
+
return () => {
|
|
1625
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1626
|
+
};
|
|
1627
|
+
}, [handleVisibilityChange]);
|
|
1628
|
+
return state;
|
|
1629
|
+
}
|
|
1630
|
+
var useVisibilityChange_default = useVisibilityChange;
|
|
1631
|
+
function usePageLeave(onLeave, options = {}) {
|
|
1632
|
+
const { showConfirmation = false, confirmationMessage = "" } = options;
|
|
1633
|
+
const onLeaveRef = useRef(onLeave);
|
|
1634
|
+
useEffect(() => {
|
|
1635
|
+
onLeaveRef.current = onLeave;
|
|
1636
|
+
}, [onLeave]);
|
|
1637
|
+
const handleMouseLeave = useCallback((e) => {
|
|
1638
|
+
if (e.clientY <= 0) {
|
|
1639
|
+
onLeaveRef.current?.();
|
|
1640
|
+
}
|
|
1641
|
+
}, []);
|
|
1642
|
+
const handleBeforeUnload = useCallback(
|
|
1643
|
+
(e) => {
|
|
1644
|
+
onLeaveRef.current?.();
|
|
1645
|
+
if (showConfirmation) {
|
|
1646
|
+
e.preventDefault();
|
|
1647
|
+
e.returnValue = confirmationMessage;
|
|
1648
|
+
return confirmationMessage;
|
|
1649
|
+
}
|
|
1650
|
+
},
|
|
1651
|
+
[showConfirmation, confirmationMessage]
|
|
1652
|
+
);
|
|
1653
|
+
useEffect(() => {
|
|
1654
|
+
if (typeof window === "undefined") return;
|
|
1655
|
+
document.addEventListener("mouseleave", handleMouseLeave);
|
|
1656
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
1657
|
+
return () => {
|
|
1658
|
+
document.removeEventListener("mouseleave", handleMouseLeave);
|
|
1659
|
+
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
1660
|
+
};
|
|
1661
|
+
}, [handleMouseLeave, handleBeforeUnload]);
|
|
1662
|
+
}
|
|
1663
|
+
var usePageLeave_default = usePageLeave;
|
|
1664
|
+
function useLockBodyScroll(locked = true) {
|
|
1665
|
+
useEffect(() => {
|
|
1666
|
+
if (typeof document === "undefined" || !locked) return;
|
|
1667
|
+
const originalStyle = window.getComputedStyle(document.body).overflow;
|
|
1668
|
+
const originalPaddingRight = window.getComputedStyle(document.body).paddingRight;
|
|
1669
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
1670
|
+
document.body.style.overflow = "hidden";
|
|
1671
|
+
if (scrollbarWidth > 0) {
|
|
1672
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
1673
|
+
}
|
|
1674
|
+
return () => {
|
|
1675
|
+
document.body.style.overflow = originalStyle;
|
|
1676
|
+
document.body.style.paddingRight = originalPaddingRight;
|
|
1677
|
+
};
|
|
1678
|
+
}, [locked]);
|
|
1679
|
+
}
|
|
1680
|
+
var useLockBodyScroll_default = useLockBodyScroll;
|
|
1681
|
+
function useIsClient() {
|
|
1682
|
+
const [isClient, setIsClient] = useState(false);
|
|
1683
|
+
useEffect(() => {
|
|
1684
|
+
setIsClient(true);
|
|
1685
|
+
}, []);
|
|
1686
|
+
return isClient;
|
|
1687
|
+
}
|
|
1688
|
+
var useIsClient_default = useIsClient;
|
|
1689
|
+
function useIsFirstRender() {
|
|
1690
|
+
const isFirst = useRef(true);
|
|
1691
|
+
if (isFirst.current) {
|
|
1692
|
+
isFirst.current = false;
|
|
1693
|
+
return true;
|
|
1694
|
+
}
|
|
1695
|
+
return isFirst.current;
|
|
1696
|
+
}
|
|
1697
|
+
var useIsFirstRender_default = useIsFirstRender;
|
|
1698
|
+
function useEventListener(eventName, handler, element, options) {
|
|
1699
|
+
const savedHandler = useRef(handler);
|
|
1700
|
+
useEffect(() => {
|
|
1701
|
+
savedHandler.current = handler;
|
|
1702
|
+
}, [handler]);
|
|
1703
|
+
useEffect(() => {
|
|
1704
|
+
const targetElement = element ?? (typeof window !== "undefined" ? window : null);
|
|
1705
|
+
if (!targetElement?.addEventListener) {
|
|
1706
|
+
return;
|
|
1707
|
+
}
|
|
1708
|
+
const eventListener = (event) => {
|
|
1709
|
+
savedHandler.current(event);
|
|
1710
|
+
};
|
|
1711
|
+
targetElement.addEventListener(eventName, eventListener, options);
|
|
1712
|
+
return () => {
|
|
1713
|
+
targetElement.removeEventListener(eventName, eventListener, options);
|
|
1714
|
+
};
|
|
1715
|
+
}, [eventName, element, options]);
|
|
1716
|
+
}
|
|
1717
|
+
var useEventListener_default = useEventListener;
|
|
1718
|
+
function useKeyPress(targetKey, callback, options = {}) {
|
|
1719
|
+
const {
|
|
1720
|
+
target,
|
|
1721
|
+
event: eventType = "keydown",
|
|
1722
|
+
preventDefault = false,
|
|
1723
|
+
stopPropagation = false
|
|
1724
|
+
} = options;
|
|
1725
|
+
const [pressed, setPressed] = useState(false);
|
|
1726
|
+
const [event, setEvent] = useState(null);
|
|
1727
|
+
const keys = Array.isArray(targetKey) ? targetKey : [targetKey];
|
|
1728
|
+
const downHandler = useCallback(
|
|
1729
|
+
(e) => {
|
|
1730
|
+
if (keys.includes(e.key)) {
|
|
1731
|
+
if (preventDefault) e.preventDefault();
|
|
1732
|
+
if (stopPropagation) e.stopPropagation();
|
|
1733
|
+
setPressed(true);
|
|
1734
|
+
setEvent(e);
|
|
1735
|
+
callback?.(e);
|
|
1736
|
+
}
|
|
1737
|
+
},
|
|
1738
|
+
[keys, callback, preventDefault, stopPropagation]
|
|
1739
|
+
);
|
|
1740
|
+
const upHandler = useCallback(
|
|
1741
|
+
(e) => {
|
|
1742
|
+
if (keys.includes(e.key)) {
|
|
1743
|
+
setPressed(false);
|
|
1744
|
+
}
|
|
1745
|
+
},
|
|
1746
|
+
[keys]
|
|
1747
|
+
);
|
|
1748
|
+
useEffect(() => {
|
|
1749
|
+
const targetElement = target ?? (typeof document !== "undefined" ? document : null);
|
|
1750
|
+
if (!targetElement) return;
|
|
1751
|
+
targetElement.addEventListener(eventType, downHandler);
|
|
1752
|
+
targetElement.addEventListener("keyup", upHandler);
|
|
1753
|
+
return () => {
|
|
1754
|
+
targetElement.removeEventListener(eventType, downHandler);
|
|
1755
|
+
targetElement.removeEventListener("keyup", upHandler);
|
|
1756
|
+
};
|
|
1757
|
+
}, [target, eventType, downHandler, upHandler]);
|
|
1758
|
+
return { pressed, event };
|
|
1759
|
+
}
|
|
1760
|
+
var useKeyPress_default = useKeyPress;
|
|
1761
|
+
function useHover(onHoverChange) {
|
|
1762
|
+
const [isHovered, setIsHovered] = useState(false);
|
|
1763
|
+
const ref = useRef(null);
|
|
1764
|
+
const onMouseEnter = useCallback(() => {
|
|
1765
|
+
setIsHovered(true);
|
|
1766
|
+
onHoverChange?.(true);
|
|
1767
|
+
}, [onHoverChange]);
|
|
1768
|
+
const onMouseLeave = useCallback(() => {
|
|
1769
|
+
setIsHovered(false);
|
|
1770
|
+
onHoverChange?.(false);
|
|
1771
|
+
}, [onHoverChange]);
|
|
1772
|
+
return {
|
|
1773
|
+
ref,
|
|
1774
|
+
isHovered,
|
|
1775
|
+
bind: {
|
|
1776
|
+
onMouseEnter,
|
|
1777
|
+
onMouseLeave
|
|
1778
|
+
}
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
var useHover_default = useHover;
|
|
1782
|
+
function useClickAway(callback, events = ["mousedown", "touchstart"]) {
|
|
1783
|
+
const ref = useRef(null);
|
|
1784
|
+
const savedCallback = useRef(callback);
|
|
1785
|
+
useEffect(() => {
|
|
1786
|
+
savedCallback.current = callback;
|
|
1787
|
+
}, [callback]);
|
|
1788
|
+
const handleClickAway = useCallback((event) => {
|
|
1789
|
+
const el = ref.current;
|
|
1790
|
+
if (!el || el.contains(event.target)) {
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
savedCallback.current(event);
|
|
1794
|
+
}, []);
|
|
1795
|
+
useEffect(() => {
|
|
1796
|
+
if (typeof document === "undefined") return;
|
|
1797
|
+
events.forEach((eventType) => {
|
|
1798
|
+
document.addEventListener(eventType, handleClickAway);
|
|
1799
|
+
});
|
|
1800
|
+
return () => {
|
|
1801
|
+
events.forEach((eventType) => {
|
|
1802
|
+
document.removeEventListener(eventType, handleClickAway);
|
|
1803
|
+
});
|
|
1804
|
+
};
|
|
1805
|
+
}, [events, handleClickAway]);
|
|
1806
|
+
return ref;
|
|
1807
|
+
}
|
|
1808
|
+
var useClickAway_default = useClickAway;
|
|
1809
|
+
function useOnClickOutside(ref, handler, enabled = true) {
|
|
1810
|
+
useEffect(() => {
|
|
1811
|
+
if (!enabled) return;
|
|
1812
|
+
const listener = (event) => {
|
|
1813
|
+
const el = ref?.current;
|
|
1814
|
+
if (!el || el.contains(event.target)) {
|
|
1815
|
+
return;
|
|
1816
|
+
}
|
|
1817
|
+
handler(event);
|
|
1818
|
+
};
|
|
1819
|
+
document.addEventListener("mousedown", listener);
|
|
1820
|
+
document.addEventListener("touchstart", listener);
|
|
1821
|
+
return () => {
|
|
1822
|
+
document.removeEventListener("mousedown", listener);
|
|
1823
|
+
document.removeEventListener("touchstart", listener);
|
|
1824
|
+
};
|
|
1825
|
+
}, [ref, handler, enabled]);
|
|
1826
|
+
}
|
|
1827
|
+
var useOnClickOutside_default = useOnClickOutside;
|
|
1828
|
+
function useLongPress(options = {}) {
|
|
1829
|
+
const {
|
|
1830
|
+
threshold = 400,
|
|
1831
|
+
onLongPress,
|
|
1832
|
+
onClick,
|
|
1833
|
+
onStart,
|
|
1834
|
+
onFinish,
|
|
1835
|
+
onCancel
|
|
1836
|
+
} = options;
|
|
1837
|
+
const [isPressed, setIsPressed] = useState(false);
|
|
1838
|
+
const [isLongPress, setIsLongPress] = useState(false);
|
|
1839
|
+
const timerRef = useRef(null);
|
|
1840
|
+
const isLongPressRef = useRef(false);
|
|
1841
|
+
const start = useCallback(
|
|
1842
|
+
(event) => {
|
|
1843
|
+
setIsPressed(true);
|
|
1844
|
+
setIsLongPress(false);
|
|
1845
|
+
isLongPressRef.current = false;
|
|
1846
|
+
onStart?.(event);
|
|
1847
|
+
timerRef.current = setTimeout(() => {
|
|
1848
|
+
isLongPressRef.current = true;
|
|
1849
|
+
setIsLongPress(true);
|
|
1850
|
+
onLongPress?.(event);
|
|
1851
|
+
}, threshold);
|
|
1852
|
+
},
|
|
1853
|
+
[threshold, onLongPress, onStart]
|
|
1854
|
+
);
|
|
1855
|
+
const cancel = useCallback(
|
|
1856
|
+
(event) => {
|
|
1857
|
+
setIsPressed(false);
|
|
1858
|
+
if (timerRef.current) {
|
|
1859
|
+
clearTimeout(timerRef.current);
|
|
1860
|
+
timerRef.current = null;
|
|
1861
|
+
}
|
|
1862
|
+
if (!isLongPressRef.current) {
|
|
1863
|
+
onCancel?.(event);
|
|
1864
|
+
}
|
|
1865
|
+
},
|
|
1866
|
+
[onCancel]
|
|
1867
|
+
);
|
|
1868
|
+
const end = useCallback(
|
|
1869
|
+
(event) => {
|
|
1870
|
+
setIsPressed(false);
|
|
1871
|
+
if (timerRef.current) {
|
|
1872
|
+
clearTimeout(timerRef.current);
|
|
1873
|
+
timerRef.current = null;
|
|
1874
|
+
}
|
|
1875
|
+
if (isLongPressRef.current) {
|
|
1876
|
+
onFinish?.(event);
|
|
1877
|
+
} else {
|
|
1878
|
+
onClick?.(event);
|
|
1879
|
+
}
|
|
1880
|
+
},
|
|
1881
|
+
[onClick, onFinish]
|
|
1882
|
+
);
|
|
1883
|
+
return {
|
|
1884
|
+
isPressed,
|
|
1885
|
+
isLongPress,
|
|
1886
|
+
bind: {
|
|
1887
|
+
onMouseDown: start,
|
|
1888
|
+
onMouseUp: end,
|
|
1889
|
+
onMouseLeave: cancel,
|
|
1890
|
+
onTouchStart: start,
|
|
1891
|
+
onTouchEnd: end
|
|
1892
|
+
}
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
var useLongPress_default = useLongPress;
|
|
1896
|
+
function useMouse(options = {}) {
|
|
1897
|
+
const { enabled = true } = options;
|
|
1898
|
+
const ref = useRef(null);
|
|
1899
|
+
const [position, setPosition] = useState({
|
|
1900
|
+
x: 0,
|
|
1901
|
+
y: 0,
|
|
1902
|
+
pageX: 0,
|
|
1903
|
+
pageY: 0,
|
|
1904
|
+
elementX: 0,
|
|
1905
|
+
elementY: 0,
|
|
1906
|
+
isInElement: false
|
|
1907
|
+
});
|
|
1908
|
+
const handleMouseMove = useCallback((event) => {
|
|
1909
|
+
let elementX = 0;
|
|
1910
|
+
let elementY = 0;
|
|
1911
|
+
let isInElement = false;
|
|
1912
|
+
if (ref.current) {
|
|
1913
|
+
const rect = ref.current.getBoundingClientRect();
|
|
1914
|
+
elementX = event.clientX - rect.left;
|
|
1915
|
+
elementY = event.clientY - rect.top;
|
|
1916
|
+
isInElement = elementX >= 0 && elementX <= rect.width && elementY >= 0 && elementY <= rect.height;
|
|
1917
|
+
}
|
|
1918
|
+
setPosition({
|
|
1919
|
+
x: event.clientX,
|
|
1920
|
+
y: event.clientY,
|
|
1921
|
+
pageX: event.pageX,
|
|
1922
|
+
pageY: event.pageY,
|
|
1923
|
+
elementX,
|
|
1924
|
+
elementY,
|
|
1925
|
+
isInElement
|
|
1926
|
+
});
|
|
1927
|
+
}, []);
|
|
1928
|
+
useEffect(() => {
|
|
1929
|
+
if (!enabled || typeof window === "undefined") return;
|
|
1930
|
+
window.addEventListener("mousemove", handleMouseMove);
|
|
1931
|
+
return () => {
|
|
1932
|
+
window.removeEventListener("mousemove", handleMouseMove);
|
|
1933
|
+
};
|
|
1934
|
+
}, [enabled, handleMouseMove]);
|
|
1935
|
+
return {
|
|
1936
|
+
ref,
|
|
1937
|
+
...position
|
|
1938
|
+
};
|
|
1939
|
+
}
|
|
1940
|
+
var useMouse_default = useMouse;
|
|
1941
|
+
function useCopyToClipboard(resetDelay = 2e3) {
|
|
1942
|
+
const [copied, setCopied] = useState(false);
|
|
1943
|
+
const [error, setError] = useState(null);
|
|
1944
|
+
const reset = useCallback(() => {
|
|
1945
|
+
setCopied(false);
|
|
1946
|
+
setError(null);
|
|
1947
|
+
}, []);
|
|
1948
|
+
const copy = useCallback(
|
|
1949
|
+
async (text) => {
|
|
1950
|
+
if (!navigator?.clipboard) {
|
|
1951
|
+
try {
|
|
1952
|
+
const textarea = document.createElement("textarea");
|
|
1953
|
+
textarea.value = text;
|
|
1954
|
+
textarea.style.position = "fixed";
|
|
1955
|
+
textarea.style.left = "-999999px";
|
|
1956
|
+
textarea.style.top = "-999999px";
|
|
1957
|
+
document.body.appendChild(textarea);
|
|
1958
|
+
textarea.focus();
|
|
1959
|
+
textarea.select();
|
|
1960
|
+
const successful = document.execCommand("copy");
|
|
1961
|
+
document.body.removeChild(textarea);
|
|
1962
|
+
if (successful) {
|
|
1963
|
+
setCopied(true);
|
|
1964
|
+
setError(null);
|
|
1965
|
+
setTimeout(reset, resetDelay);
|
|
1966
|
+
return true;
|
|
1967
|
+
} else {
|
|
1968
|
+
throw new Error("execCommand failed");
|
|
1969
|
+
}
|
|
1970
|
+
} catch (err) {
|
|
1971
|
+
const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
|
|
1972
|
+
setError(message);
|
|
1973
|
+
setCopied(false);
|
|
1974
|
+
return false;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
try {
|
|
1978
|
+
await navigator.clipboard.writeText(text);
|
|
1979
|
+
setCopied(true);
|
|
1980
|
+
setError(null);
|
|
1981
|
+
setTimeout(reset, resetDelay);
|
|
1982
|
+
return true;
|
|
1983
|
+
} catch (err) {
|
|
1984
|
+
const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
|
|
1985
|
+
setError(message);
|
|
1986
|
+
setCopied(false);
|
|
1987
|
+
return false;
|
|
1988
|
+
}
|
|
1989
|
+
},
|
|
1990
|
+
[resetDelay, reset]
|
|
1991
|
+
);
|
|
1992
|
+
return { copy, copied, error, reset };
|
|
1993
|
+
}
|
|
1994
|
+
var useCopyToClipboard_default = useCopyToClipboard;
|
|
1995
|
+
function useMediaQuery(query) {
|
|
1996
|
+
const getMatches = (query2) => {
|
|
1997
|
+
if (typeof window === "undefined") return false;
|
|
1998
|
+
return window.matchMedia(query2).matches;
|
|
1999
|
+
};
|
|
2000
|
+
const [matches, setMatches] = useState(getMatches(query));
|
|
2001
|
+
useEffect(() => {
|
|
2002
|
+
if (typeof window === "undefined") return;
|
|
2003
|
+
const mediaQuery = window.matchMedia(query);
|
|
2004
|
+
const handleChange = () => setMatches(mediaQuery.matches);
|
|
2005
|
+
handleChange();
|
|
2006
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
2007
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
2008
|
+
}, [query]);
|
|
2009
|
+
return matches;
|
|
2010
|
+
}
|
|
2011
|
+
var useIsMobile = () => useMediaQuery("(max-width: 767px)");
|
|
2012
|
+
var useIsTablet = () => useMediaQuery("(min-width: 768px) and (max-width: 1023px)");
|
|
2013
|
+
var useIsDesktop = () => useMediaQuery("(min-width: 1024px)");
|
|
2014
|
+
var useIsMobileOrTablet = () => useMediaQuery("(max-width: 1023px)");
|
|
2015
|
+
var useMediaQuery_default = useMediaQuery;
|
|
2016
|
+
function useOrientation() {
|
|
2017
|
+
const getOrientation = () => {
|
|
2018
|
+
if (typeof window === "undefined" || !window.screen?.orientation) {
|
|
2019
|
+
return {
|
|
2020
|
+
angle: 0,
|
|
2021
|
+
type: "portrait-primary",
|
|
2022
|
+
isPortrait: true,
|
|
2023
|
+
isLandscape: false
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
const { angle, type } = window.screen.orientation;
|
|
2027
|
+
const isPortrait = type.includes("portrait");
|
|
2028
|
+
const isLandscape = type.includes("landscape");
|
|
2029
|
+
return { angle, type, isPortrait, isLandscape };
|
|
2030
|
+
};
|
|
2031
|
+
const [orientation, setOrientation] = useState(getOrientation);
|
|
2032
|
+
useEffect(() => {
|
|
2033
|
+
if (typeof window === "undefined") return;
|
|
2034
|
+
const handleOrientationChange = () => {
|
|
2035
|
+
setOrientation(getOrientation());
|
|
2036
|
+
};
|
|
2037
|
+
if (window.screen?.orientation) {
|
|
2038
|
+
window.screen.orientation.addEventListener("change", handleOrientationChange);
|
|
2039
|
+
}
|
|
2040
|
+
window.addEventListener("orientationchange", handleOrientationChange);
|
|
2041
|
+
window.addEventListener("resize", handleOrientationChange);
|
|
2042
|
+
return () => {
|
|
2043
|
+
if (window.screen?.orientation) {
|
|
2044
|
+
window.screen.orientation.removeEventListener("change", handleOrientationChange);
|
|
2045
|
+
}
|
|
2046
|
+
window.removeEventListener("orientationchange", handleOrientationChange);
|
|
2047
|
+
window.removeEventListener("resize", handleOrientationChange);
|
|
2048
|
+
};
|
|
2049
|
+
}, []);
|
|
2050
|
+
return orientation;
|
|
2051
|
+
}
|
|
2052
|
+
var useOrientation_default = useOrientation;
|
|
2053
|
+
function useBattery() {
|
|
2054
|
+
const [battery, setBattery] = useState({
|
|
2055
|
+
isSupported: false,
|
|
2056
|
+
charging: false,
|
|
2057
|
+
chargingTime: Infinity,
|
|
2058
|
+
dischargingTime: Infinity,
|
|
2059
|
+
level: 1,
|
|
2060
|
+
percentage: 100
|
|
2061
|
+
});
|
|
2062
|
+
useEffect(() => {
|
|
2063
|
+
if (typeof navigator === "undefined") return;
|
|
2064
|
+
const nav = navigator;
|
|
2065
|
+
if (!nav.getBattery) {
|
|
2066
|
+
setBattery((prev) => ({ ...prev, isSupported: false }));
|
|
2067
|
+
return;
|
|
2068
|
+
}
|
|
2069
|
+
let batteryManager = null;
|
|
2070
|
+
const updateBattery = (battery2) => {
|
|
2071
|
+
setBattery({
|
|
2072
|
+
isSupported: true,
|
|
2073
|
+
charging: battery2.charging,
|
|
2074
|
+
chargingTime: battery2.chargingTime,
|
|
2075
|
+
dischargingTime: battery2.dischargingTime,
|
|
2076
|
+
level: battery2.level,
|
|
2077
|
+
percentage: Math.round(battery2.level * 100)
|
|
2078
|
+
});
|
|
2079
|
+
};
|
|
2080
|
+
const handleChange = () => {
|
|
2081
|
+
if (batteryManager) {
|
|
2082
|
+
updateBattery(batteryManager);
|
|
2083
|
+
}
|
|
2084
|
+
};
|
|
2085
|
+
nav.getBattery().then((battery2) => {
|
|
2086
|
+
batteryManager = battery2;
|
|
2087
|
+
updateBattery(battery2);
|
|
2088
|
+
battery2.addEventListener("chargingchange", handleChange);
|
|
2089
|
+
battery2.addEventListener("chargingtimechange", handleChange);
|
|
2090
|
+
battery2.addEventListener("dischargingtimechange", handleChange);
|
|
2091
|
+
battery2.addEventListener("levelchange", handleChange);
|
|
2092
|
+
});
|
|
2093
|
+
return () => {
|
|
2094
|
+
if (batteryManager) {
|
|
2095
|
+
batteryManager.removeEventListener("chargingchange", handleChange);
|
|
2096
|
+
batteryManager.removeEventListener("chargingtimechange", handleChange);
|
|
2097
|
+
batteryManager.removeEventListener("dischargingtimechange", handleChange);
|
|
2098
|
+
batteryManager.removeEventListener("levelchange", handleChange);
|
|
2099
|
+
}
|
|
2100
|
+
};
|
|
2101
|
+
}, []);
|
|
2102
|
+
return battery;
|
|
2103
|
+
}
|
|
2104
|
+
var useBattery_default = useBattery;
|
|
2105
|
+
function useNetworkState() {
|
|
2106
|
+
const getConnection = () => {
|
|
2107
|
+
if (typeof navigator === "undefined") return void 0;
|
|
2108
|
+
const nav = navigator;
|
|
2109
|
+
return nav.connection || nav.mozConnection || nav.webkitConnection;
|
|
2110
|
+
};
|
|
2111
|
+
const getNetworkState = () => {
|
|
2112
|
+
const online = typeof navigator !== "undefined" ? navigator.onLine : true;
|
|
2113
|
+
const connection = getConnection();
|
|
2114
|
+
return {
|
|
2115
|
+
online,
|
|
2116
|
+
offline: !online,
|
|
2117
|
+
downlink: connection?.downlink,
|
|
2118
|
+
effectiveType: connection?.effectiveType,
|
|
2119
|
+
rtt: connection?.rtt,
|
|
2120
|
+
saveData: connection?.saveData,
|
|
2121
|
+
type: connection?.type,
|
|
2122
|
+
since: /* @__PURE__ */ new Date()
|
|
2123
|
+
};
|
|
2124
|
+
};
|
|
2125
|
+
const [state, setState] = useState(getNetworkState);
|
|
2126
|
+
useEffect(() => {
|
|
2127
|
+
if (typeof window === "undefined") return;
|
|
2128
|
+
const handleOnline = () => {
|
|
2129
|
+
setState((prev) => ({ ...prev, online: true, offline: false, since: /* @__PURE__ */ new Date() }));
|
|
2130
|
+
};
|
|
2131
|
+
const handleOffline = () => {
|
|
2132
|
+
setState((prev) => ({ ...prev, online: false, offline: true, since: /* @__PURE__ */ new Date() }));
|
|
2133
|
+
};
|
|
2134
|
+
const handleConnectionChange = () => {
|
|
2135
|
+
setState(getNetworkState());
|
|
2136
|
+
};
|
|
2137
|
+
window.addEventListener("online", handleOnline);
|
|
2138
|
+
window.addEventListener("offline", handleOffline);
|
|
2139
|
+
const connection = getConnection();
|
|
2140
|
+
if (connection) {
|
|
2141
|
+
connection.addEventListener("change", handleConnectionChange);
|
|
2142
|
+
}
|
|
2143
|
+
return () => {
|
|
2144
|
+
window.removeEventListener("online", handleOnline);
|
|
2145
|
+
window.removeEventListener("offline", handleOffline);
|
|
2146
|
+
if (connection) {
|
|
2147
|
+
connection.removeEventListener("change", handleConnectionChange);
|
|
2148
|
+
}
|
|
2149
|
+
};
|
|
2150
|
+
}, []);
|
|
2151
|
+
return state;
|
|
2152
|
+
}
|
|
2153
|
+
var useNetworkState_default = useNetworkState;
|
|
2154
|
+
var DEFAULT_EVENTS = [
|
|
2155
|
+
"mousemove",
|
|
2156
|
+
"mousedown",
|
|
2157
|
+
"keydown",
|
|
2158
|
+
"touchstart",
|
|
2159
|
+
"scroll",
|
|
2160
|
+
"wheel"
|
|
2161
|
+
];
|
|
2162
|
+
function useIdle(options = {}) {
|
|
2163
|
+
const {
|
|
2164
|
+
timeout = 6e4,
|
|
2165
|
+
events = DEFAULT_EVENTS,
|
|
2166
|
+
initialState = false,
|
|
2167
|
+
onIdle,
|
|
2168
|
+
onActive
|
|
2169
|
+
} = options;
|
|
2170
|
+
const [isIdle, setIsIdle] = useState(initialState);
|
|
2171
|
+
const [lastActive, setLastActive] = useState(/* @__PURE__ */ new Date());
|
|
2172
|
+
const [isTracking, setIsTracking] = useState(true);
|
|
2173
|
+
const timeoutRef = useRef(null);
|
|
2174
|
+
const onIdleRef = useRef(onIdle);
|
|
2175
|
+
const onActiveRef = useRef(onActive);
|
|
2176
|
+
useEffect(() => {
|
|
2177
|
+
onIdleRef.current = onIdle;
|
|
2178
|
+
onActiveRef.current = onActive;
|
|
2179
|
+
}, [onIdle, onActive]);
|
|
2180
|
+
const handleActivity = useCallback(() => {
|
|
2181
|
+
if (!isTracking) return;
|
|
2182
|
+
setLastActive(/* @__PURE__ */ new Date());
|
|
2183
|
+
if (isIdle) {
|
|
2184
|
+
setIsIdle(false);
|
|
2185
|
+
onActiveRef.current?.();
|
|
2186
|
+
}
|
|
2187
|
+
if (timeoutRef.current) {
|
|
2188
|
+
clearTimeout(timeoutRef.current);
|
|
2189
|
+
}
|
|
2190
|
+
timeoutRef.current = setTimeout(() => {
|
|
2191
|
+
setIsIdle(true);
|
|
2192
|
+
onIdleRef.current?.();
|
|
2193
|
+
}, timeout);
|
|
2194
|
+
}, [isIdle, isTracking, timeout]);
|
|
2195
|
+
const reset = useCallback(() => {
|
|
2196
|
+
handleActivity();
|
|
2197
|
+
}, [handleActivity]);
|
|
2198
|
+
const start = useCallback(() => {
|
|
2199
|
+
setIsTracking(true);
|
|
2200
|
+
handleActivity();
|
|
2201
|
+
}, [handleActivity]);
|
|
2202
|
+
const stop = useCallback(() => {
|
|
2203
|
+
setIsTracking(false);
|
|
2204
|
+
if (timeoutRef.current) {
|
|
2205
|
+
clearTimeout(timeoutRef.current);
|
|
2206
|
+
timeoutRef.current = null;
|
|
2207
|
+
}
|
|
2208
|
+
}, []);
|
|
2209
|
+
useEffect(() => {
|
|
2210
|
+
if (typeof window === "undefined" || !isTracking) return;
|
|
2211
|
+
timeoutRef.current = setTimeout(() => {
|
|
2212
|
+
setIsIdle(true);
|
|
2213
|
+
onIdleRef.current?.();
|
|
2214
|
+
}, timeout);
|
|
2215
|
+
events.forEach((event) => {
|
|
2216
|
+
window.addEventListener(event, handleActivity, { passive: true });
|
|
2217
|
+
});
|
|
2218
|
+
return () => {
|
|
2219
|
+
if (timeoutRef.current) {
|
|
2220
|
+
clearTimeout(timeoutRef.current);
|
|
2221
|
+
}
|
|
2222
|
+
events.forEach((event) => {
|
|
2223
|
+
window.removeEventListener(event, handleActivity);
|
|
2224
|
+
});
|
|
2225
|
+
};
|
|
2226
|
+
}, [events, handleActivity, isTracking, timeout]);
|
|
2227
|
+
return {
|
|
2228
|
+
isIdle,
|
|
2229
|
+
lastActive,
|
|
2230
|
+
reset,
|
|
2231
|
+
start,
|
|
2232
|
+
stop
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
var useIdle_default = useIdle;
|
|
2236
|
+
function useGeolocation(options = {}) {
|
|
2237
|
+
const {
|
|
2238
|
+
enableHighAccuracy = false,
|
|
2239
|
+
maximumAge = 0,
|
|
2240
|
+
timeout = Infinity,
|
|
2241
|
+
watch = false
|
|
2242
|
+
} = options;
|
|
2243
|
+
const isSupported = typeof navigator !== "undefined" && "geolocation" in navigator;
|
|
2244
|
+
const [state, setState] = useState({
|
|
2245
|
+
loading: true,
|
|
2246
|
+
error: null,
|
|
2247
|
+
latitude: null,
|
|
2248
|
+
longitude: null,
|
|
2249
|
+
accuracy: null,
|
|
2250
|
+
altitude: null,
|
|
2251
|
+
altitudeAccuracy: null,
|
|
2252
|
+
heading: null,
|
|
2253
|
+
speed: null,
|
|
2254
|
+
timestamp: null
|
|
2255
|
+
});
|
|
2256
|
+
const handleSuccess = useCallback((position) => {
|
|
2257
|
+
setState({
|
|
2258
|
+
loading: false,
|
|
2259
|
+
error: null,
|
|
2260
|
+
latitude: position.coords.latitude,
|
|
2261
|
+
longitude: position.coords.longitude,
|
|
2262
|
+
accuracy: position.coords.accuracy,
|
|
2263
|
+
altitude: position.coords.altitude,
|
|
2264
|
+
altitudeAccuracy: position.coords.altitudeAccuracy,
|
|
2265
|
+
heading: position.coords.heading,
|
|
2266
|
+
speed: position.coords.speed,
|
|
2267
|
+
timestamp: position.timestamp
|
|
2268
|
+
});
|
|
2269
|
+
}, []);
|
|
2270
|
+
const handleError = useCallback((error) => {
|
|
2271
|
+
setState((prev) => ({
|
|
2272
|
+
...prev,
|
|
2273
|
+
loading: false,
|
|
2274
|
+
error: error.message
|
|
2275
|
+
}));
|
|
2276
|
+
}, []);
|
|
2277
|
+
const refresh = useCallback(() => {
|
|
2278
|
+
if (!isSupported) return;
|
|
2279
|
+
setState((prev) => ({ ...prev, loading: true }));
|
|
2280
|
+
navigator.geolocation.getCurrentPosition(handleSuccess, handleError, {
|
|
2281
|
+
enableHighAccuracy,
|
|
2282
|
+
maximumAge,
|
|
2283
|
+
timeout
|
|
2284
|
+
});
|
|
2285
|
+
}, [isSupported, enableHighAccuracy, maximumAge, timeout, handleSuccess, handleError]);
|
|
2286
|
+
useEffect(() => {
|
|
2287
|
+
if (!isSupported) {
|
|
2288
|
+
setState((prev) => ({
|
|
2289
|
+
...prev,
|
|
2290
|
+
loading: false,
|
|
2291
|
+
error: "Geolocation is not supported"
|
|
2292
|
+
}));
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
const positionOptions = {
|
|
2296
|
+
enableHighAccuracy,
|
|
2297
|
+
maximumAge,
|
|
2298
|
+
timeout
|
|
2299
|
+
};
|
|
2300
|
+
navigator.geolocation.getCurrentPosition(
|
|
2301
|
+
handleSuccess,
|
|
2302
|
+
handleError,
|
|
2303
|
+
positionOptions
|
|
2304
|
+
);
|
|
2305
|
+
let watchId = null;
|
|
2306
|
+
if (watch) {
|
|
2307
|
+
watchId = navigator.geolocation.watchPosition(
|
|
2308
|
+
handleSuccess,
|
|
2309
|
+
handleError,
|
|
2310
|
+
positionOptions
|
|
2311
|
+
);
|
|
2312
|
+
}
|
|
2313
|
+
return () => {
|
|
2314
|
+
if (watchId !== null) {
|
|
2315
|
+
navigator.geolocation.clearWatch(watchId);
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
}, [isSupported, enableHighAccuracy, maximumAge, timeout, watch, handleSuccess, handleError]);
|
|
2319
|
+
return {
|
|
2320
|
+
...state,
|
|
2321
|
+
refresh,
|
|
2322
|
+
isSupported
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
var useGeolocation_default = useGeolocation;
|
|
2326
|
+
function usePreferredLanguage() {
|
|
2327
|
+
const getLanguageState = () => {
|
|
2328
|
+
if (typeof navigator === "undefined") {
|
|
2329
|
+
return { language: "en", languages: ["en"] };
|
|
2330
|
+
}
|
|
2331
|
+
return {
|
|
2332
|
+
language: navigator.language || "en",
|
|
2333
|
+
languages: navigator.languages || [navigator.language || "en"]
|
|
2334
|
+
};
|
|
2335
|
+
};
|
|
2336
|
+
const [state, setState] = useState(getLanguageState);
|
|
2337
|
+
useEffect(() => {
|
|
2338
|
+
if (typeof window === "undefined") return;
|
|
2339
|
+
const handleLanguageChange = () => {
|
|
2340
|
+
setState(getLanguageState());
|
|
2341
|
+
};
|
|
2342
|
+
window.addEventListener("languagechange", handleLanguageChange);
|
|
2343
|
+
return () => {
|
|
2344
|
+
window.removeEventListener("languagechange", handleLanguageChange);
|
|
2345
|
+
};
|
|
2346
|
+
}, []);
|
|
2347
|
+
return state;
|
|
2348
|
+
}
|
|
2349
|
+
var usePreferredLanguage_default = usePreferredLanguage;
|
|
2350
|
+
function useThemeDetector() {
|
|
2351
|
+
const getCurrentTheme = () => {
|
|
2352
|
+
if (typeof window === "undefined") return "light";
|
|
2353
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
2354
|
+
};
|
|
2355
|
+
const [theme, setTheme] = useState(getCurrentTheme);
|
|
2356
|
+
useEffect(() => {
|
|
2357
|
+
if (typeof window === "undefined") return;
|
|
2358
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
2359
|
+
const handleChange = (e) => {
|
|
2360
|
+
setTheme(e.matches ? "dark" : "light");
|
|
2361
|
+
};
|
|
2362
|
+
mediaQuery.addEventListener("change", handleChange);
|
|
2363
|
+
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
2364
|
+
}, []);
|
|
2365
|
+
return theme;
|
|
2366
|
+
}
|
|
2367
|
+
var useThemeDetector_default = useThemeDetector;
|
|
579
2368
|
function useLocalStorage(key, initialValue, options = {}) {
|
|
580
2369
|
const {
|
|
581
2370
|
serializer = JSON.stringify,
|
|
@@ -633,150 +2422,532 @@ function useLocalStorage(key, initialValue, options = {}) {
|
|
|
633
2422
|
window.localStorage.removeItem(key);
|
|
634
2423
|
setStoredValue(initialValue);
|
|
635
2424
|
log("Removed value");
|
|
636
|
-
window.dispatchEvent(new StorageEvent("storage", { key, newValue: null }));
|
|
2425
|
+
window.dispatchEvent(new StorageEvent("storage", { key, newValue: null }));
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
console.warn(`Error removing localStorage key "${key}":`, error);
|
|
2428
|
+
}
|
|
2429
|
+
}, [key, initialValue, log]);
|
|
2430
|
+
useEffect(() => {
|
|
2431
|
+
if (!syncTabs || typeof window === "undefined") {
|
|
2432
|
+
return;
|
|
2433
|
+
}
|
|
2434
|
+
const handleStorageChange = (event) => {
|
|
2435
|
+
if (event.key !== key) {
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
log("Storage event received:", event.newValue);
|
|
2439
|
+
if (event.newValue === null) {
|
|
2440
|
+
setStoredValue(initialValue);
|
|
2441
|
+
} else {
|
|
2442
|
+
try {
|
|
2443
|
+
setStoredValue(deserializer(event.newValue));
|
|
2444
|
+
} catch {
|
|
2445
|
+
console.warn(`Error parsing localStorage change for key "${key}"`);
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
};
|
|
2449
|
+
window.addEventListener("storage", handleStorageChange);
|
|
2450
|
+
return () => window.removeEventListener("storage", handleStorageChange);
|
|
2451
|
+
}, [key, initialValue, syncTabs, deserializer, log]);
|
|
2452
|
+
return [storedValue, setValue, removeValue];
|
|
2453
|
+
}
|
|
2454
|
+
var useLocalStorage_default = useLocalStorage;
|
|
2455
|
+
function useSessionStorage(key, initialValue, options = {}) {
|
|
2456
|
+
const {
|
|
2457
|
+
serializer = JSON.stringify,
|
|
2458
|
+
deserializer = JSON.parse,
|
|
2459
|
+
debug = false
|
|
2460
|
+
} = options;
|
|
2461
|
+
const log = useCallback(
|
|
2462
|
+
(...args) => {
|
|
2463
|
+
if (debug) console.log(`[useSessionStorage:${key}]`, ...args);
|
|
2464
|
+
},
|
|
2465
|
+
[debug, key]
|
|
2466
|
+
);
|
|
2467
|
+
const readValue = useCallback(() => {
|
|
2468
|
+
if (typeof window === "undefined") {
|
|
2469
|
+
return initialValue;
|
|
2470
|
+
}
|
|
2471
|
+
try {
|
|
2472
|
+
const item = window.sessionStorage.getItem(key);
|
|
2473
|
+
if (item === null) {
|
|
2474
|
+
return initialValue;
|
|
2475
|
+
}
|
|
2476
|
+
const parsed = deserializer(item);
|
|
2477
|
+
log("Read value:", parsed);
|
|
2478
|
+
return parsed;
|
|
2479
|
+
} catch (error) {
|
|
2480
|
+
console.warn(`Error reading sessionStorage key "${key}":`, error);
|
|
2481
|
+
return initialValue;
|
|
2482
|
+
}
|
|
2483
|
+
}, [key, initialValue, deserializer, log]);
|
|
2484
|
+
const [storedValue, setStoredValue] = useState(readValue);
|
|
2485
|
+
const setValue = useCallback(
|
|
2486
|
+
(value) => {
|
|
2487
|
+
if (typeof window === "undefined") {
|
|
2488
|
+
console.warn(`Cannot set sessionStorage key "${key}" in non-browser environment`);
|
|
2489
|
+
return;
|
|
2490
|
+
}
|
|
2491
|
+
try {
|
|
2492
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
2493
|
+
setStoredValue(valueToStore);
|
|
2494
|
+
window.sessionStorage.setItem(key, serializer(valueToStore));
|
|
2495
|
+
log("Set value:", valueToStore);
|
|
2496
|
+
} catch (error) {
|
|
2497
|
+
console.warn(`Error setting sessionStorage key "${key}":`, error);
|
|
2498
|
+
}
|
|
2499
|
+
},
|
|
2500
|
+
[key, storedValue, serializer, log]
|
|
2501
|
+
);
|
|
2502
|
+
const removeValue = useCallback(() => {
|
|
2503
|
+
if (typeof window === "undefined") {
|
|
2504
|
+
return;
|
|
2505
|
+
}
|
|
2506
|
+
try {
|
|
2507
|
+
window.sessionStorage.removeItem(key);
|
|
2508
|
+
setStoredValue(initialValue);
|
|
2509
|
+
log("Removed value");
|
|
637
2510
|
} catch (error) {
|
|
638
|
-
console.warn(`Error removing
|
|
2511
|
+
console.warn(`Error removing sessionStorage key "${key}":`, error);
|
|
639
2512
|
}
|
|
640
2513
|
}, [key, initialValue, log]);
|
|
641
2514
|
useEffect(() => {
|
|
642
|
-
if (
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const handleStorageChange = (event) => {
|
|
646
|
-
if (event.key !== key) {
|
|
2515
|
+
if (typeof window === "undefined") return;
|
|
2516
|
+
const handleStorageChange = (e) => {
|
|
2517
|
+
if (e.storageArea !== sessionStorage || e.key !== key) {
|
|
647
2518
|
return;
|
|
648
2519
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
setStoredValue(deserializer(event.newValue));
|
|
655
|
-
} catch {
|
|
656
|
-
console.warn(`Error parsing localStorage change for key "${key}"`);
|
|
2520
|
+
try {
|
|
2521
|
+
if (e.newValue === null) {
|
|
2522
|
+
setStoredValue(initialValue);
|
|
2523
|
+
} else {
|
|
2524
|
+
setStoredValue(deserializer(e.newValue));
|
|
657
2525
|
}
|
|
2526
|
+
} catch (error) {
|
|
2527
|
+
console.warn(`Error handling storage event for key "${key}":`, error);
|
|
658
2528
|
}
|
|
659
2529
|
};
|
|
660
2530
|
window.addEventListener("storage", handleStorageChange);
|
|
661
|
-
return () => window.removeEventListener("storage", handleStorageChange);
|
|
662
|
-
}, [key, initialValue, syncTabs, deserializer, log]);
|
|
663
|
-
return [storedValue, setValue, removeValue];
|
|
664
|
-
}
|
|
665
|
-
var useLocalStorage_default = useLocalStorage;
|
|
666
|
-
function useDebounce(value, delay = 500) {
|
|
667
|
-
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
668
|
-
useEffect(() => {
|
|
669
|
-
const timer = setTimeout(() => {
|
|
670
|
-
setDebouncedValue(value);
|
|
671
|
-
}, delay);
|
|
672
2531
|
return () => {
|
|
673
|
-
|
|
2532
|
+
window.removeEventListener("storage", handleStorageChange);
|
|
674
2533
|
};
|
|
675
|
-
}, [
|
|
676
|
-
return
|
|
2534
|
+
}, [key, initialValue, deserializer]);
|
|
2535
|
+
return [storedValue, setValue, removeValue];
|
|
677
2536
|
}
|
|
678
|
-
var
|
|
679
|
-
|
|
680
|
-
|
|
2537
|
+
var useSessionStorage_default = useSessionStorage;
|
|
2538
|
+
var cache = /* @__PURE__ */ new Map();
|
|
2539
|
+
function useFetch(url, options = {}) {
|
|
2540
|
+
const {
|
|
2541
|
+
skip = false,
|
|
2542
|
+
transform,
|
|
2543
|
+
retries = 0,
|
|
2544
|
+
retryDelay = 1e3,
|
|
2545
|
+
cacheKey,
|
|
2546
|
+
cacheTime = 0,
|
|
2547
|
+
onSuccess,
|
|
2548
|
+
onError,
|
|
2549
|
+
body,
|
|
2550
|
+
...fetchOptions
|
|
2551
|
+
} = options;
|
|
2552
|
+
const [data, setData] = useState(null);
|
|
2553
|
+
const [loading, setLoading] = useState(!skip && !!url);
|
|
2554
|
+
const [isFetching, setIsFetching] = useState(!skip && !!url);
|
|
681
2555
|
const [error, setError] = useState(null);
|
|
682
|
-
const
|
|
683
|
-
|
|
2556
|
+
const [status, setStatus] = useState(null);
|
|
2557
|
+
const abortControllerRef = useRef(null);
|
|
2558
|
+
const retriesRef = useRef(0);
|
|
2559
|
+
const fetchData = useCallback(async () => {
|
|
2560
|
+
if (!url) return null;
|
|
2561
|
+
const key = cacheKey || url;
|
|
2562
|
+
if (cacheTime > 0) {
|
|
2563
|
+
const cached = cache.get(key);
|
|
2564
|
+
if (cached && Date.now() - cached.timestamp < cacheTime) {
|
|
2565
|
+
const cachedData = cached.data;
|
|
2566
|
+
setData(cachedData);
|
|
2567
|
+
setLoading(false);
|
|
2568
|
+
setIsFetching(false);
|
|
2569
|
+
return cachedData;
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
if (abortControllerRef.current) {
|
|
2573
|
+
abortControllerRef.current.abort();
|
|
2574
|
+
}
|
|
2575
|
+
abortControllerRef.current = new AbortController();
|
|
2576
|
+
setIsFetching(true);
|
|
684
2577
|
setError(null);
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
textarea.focus();
|
|
697
|
-
textarea.select();
|
|
698
|
-
const successful = document.execCommand("copy");
|
|
699
|
-
document.body.removeChild(textarea);
|
|
700
|
-
if (successful) {
|
|
701
|
-
setCopied(true);
|
|
702
|
-
setError(null);
|
|
703
|
-
setTimeout(reset, resetDelay);
|
|
704
|
-
return true;
|
|
705
|
-
} else {
|
|
706
|
-
throw new Error("execCommand failed");
|
|
707
|
-
}
|
|
708
|
-
} catch (err) {
|
|
709
|
-
const message = err instanceof Error ? err.message : "Failed to copy to clipboard";
|
|
710
|
-
setError(message);
|
|
711
|
-
setCopied(false);
|
|
712
|
-
return false;
|
|
2578
|
+
try {
|
|
2579
|
+
let processedBody;
|
|
2580
|
+
if (body !== null && body !== void 0) {
|
|
2581
|
+
if (typeof body === "object" && !(body instanceof FormData) && !(body instanceof Blob)) {
|
|
2582
|
+
processedBody = JSON.stringify(body);
|
|
2583
|
+
fetchOptions.headers = {
|
|
2584
|
+
"Content-Type": "application/json",
|
|
2585
|
+
...fetchOptions.headers
|
|
2586
|
+
};
|
|
2587
|
+
} else {
|
|
2588
|
+
processedBody = body;
|
|
713
2589
|
}
|
|
714
2590
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
setError(message);
|
|
724
|
-
setCopied(false);
|
|
725
|
-
return false;
|
|
2591
|
+
const response = await fetch(url, {
|
|
2592
|
+
...fetchOptions,
|
|
2593
|
+
body: processedBody,
|
|
2594
|
+
signal: abortControllerRef.current.signal
|
|
2595
|
+
});
|
|
2596
|
+
setStatus(response.status);
|
|
2597
|
+
if (!response.ok) {
|
|
2598
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
726
2599
|
}
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
2600
|
+
const responseData = await response.json();
|
|
2601
|
+
const transformedData = transform ? transform(responseData) : responseData;
|
|
2602
|
+
if (cacheTime > 0) {
|
|
2603
|
+
cache.set(key, { data: transformedData, timestamp: Date.now() });
|
|
2604
|
+
}
|
|
2605
|
+
setData(transformedData);
|
|
2606
|
+
setError(null);
|
|
2607
|
+
setLoading(false);
|
|
2608
|
+
setIsFetching(false);
|
|
2609
|
+
retriesRef.current = 0;
|
|
2610
|
+
onSuccess?.(transformedData);
|
|
2611
|
+
return transformedData;
|
|
2612
|
+
} catch (err) {
|
|
2613
|
+
if (err.name === "AbortError") {
|
|
2614
|
+
return null;
|
|
2615
|
+
}
|
|
2616
|
+
const fetchError = err instanceof Error ? err : new Error(String(err));
|
|
2617
|
+
if (retriesRef.current < retries) {
|
|
2618
|
+
retriesRef.current++;
|
|
2619
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
2620
|
+
return fetchData();
|
|
2621
|
+
}
|
|
2622
|
+
setError(fetchError);
|
|
2623
|
+
setLoading(false);
|
|
2624
|
+
setIsFetching(false);
|
|
2625
|
+
retriesRef.current = 0;
|
|
2626
|
+
onError?.(fetchError);
|
|
2627
|
+
return null;
|
|
2628
|
+
}
|
|
2629
|
+
}, [url, cacheKey, cacheTime, transform, retries, retryDelay, body, fetchOptions, onSuccess, onError]);
|
|
2630
|
+
const abort = useCallback(() => {
|
|
2631
|
+
if (abortControllerRef.current) {
|
|
2632
|
+
abortControllerRef.current.abort();
|
|
2633
|
+
}
|
|
2634
|
+
}, []);
|
|
2635
|
+
const refetch = useCallback(async () => {
|
|
2636
|
+
const key = cacheKey || url || "";
|
|
2637
|
+
cache.delete(key);
|
|
2638
|
+
setLoading(true);
|
|
2639
|
+
return fetchData();
|
|
2640
|
+
}, [fetchData, cacheKey, url]);
|
|
2641
|
+
useEffect(() => {
|
|
2642
|
+
if (skip || !url) {
|
|
2643
|
+
setLoading(false);
|
|
2644
|
+
setIsFetching(false);
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
fetchData();
|
|
2648
|
+
return () => {
|
|
2649
|
+
abort();
|
|
2650
|
+
};
|
|
2651
|
+
}, [url, skip]);
|
|
2652
|
+
return {
|
|
2653
|
+
data,
|
|
2654
|
+
loading,
|
|
2655
|
+
error,
|
|
2656
|
+
refetch,
|
|
2657
|
+
abort,
|
|
2658
|
+
isFetching,
|
|
2659
|
+
status
|
|
2660
|
+
};
|
|
731
2661
|
}
|
|
732
|
-
var
|
|
733
|
-
|
|
734
|
-
|
|
2662
|
+
var useFetch_default = useFetch;
|
|
2663
|
+
var scriptCache = /* @__PURE__ */ new Map();
|
|
2664
|
+
function useScript(src, options = {}) {
|
|
2665
|
+
const { shouldLoad = true, removeOnUnmount = false, attributes = {} } = options;
|
|
2666
|
+
const [status, setStatus] = useState(() => {
|
|
2667
|
+
if (!src) return "idle";
|
|
2668
|
+
if (typeof window === "undefined") return "idle";
|
|
2669
|
+
const existingScript = document.querySelector(`script[src="${src}"]`);
|
|
2670
|
+
if (existingScript) {
|
|
2671
|
+
return scriptCache.get(src) || "ready";
|
|
2672
|
+
}
|
|
2673
|
+
return "idle";
|
|
2674
|
+
});
|
|
2675
|
+
const load = useCallback(() => {
|
|
2676
|
+
if (!src || typeof document === "undefined") return;
|
|
2677
|
+
const existingScript = document.querySelector(`script[src="${src}"]`);
|
|
2678
|
+
if (existingScript) {
|
|
2679
|
+
const cachedStatus = scriptCache.get(src);
|
|
2680
|
+
if (cachedStatus) {
|
|
2681
|
+
setStatus(cachedStatus);
|
|
2682
|
+
}
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
setStatus("loading");
|
|
2686
|
+
scriptCache.set(src, "loading");
|
|
2687
|
+
const script = document.createElement("script");
|
|
2688
|
+
script.src = src;
|
|
2689
|
+
script.async = true;
|
|
2690
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
2691
|
+
script.setAttribute(key, value);
|
|
2692
|
+
});
|
|
2693
|
+
const handleLoad = () => {
|
|
2694
|
+
setStatus("ready");
|
|
2695
|
+
scriptCache.set(src, "ready");
|
|
2696
|
+
};
|
|
2697
|
+
const handleError = () => {
|
|
2698
|
+
setStatus("error");
|
|
2699
|
+
scriptCache.set(src, "error");
|
|
2700
|
+
};
|
|
2701
|
+
script.addEventListener("load", handleLoad);
|
|
2702
|
+
script.addEventListener("error", handleError);
|
|
2703
|
+
document.body.appendChild(script);
|
|
2704
|
+
}, [src, attributes]);
|
|
2705
|
+
const remove = useCallback(() => {
|
|
2706
|
+
if (!src || typeof document === "undefined") return;
|
|
2707
|
+
const existingScript = document.querySelector(`script[src="${src}"]`);
|
|
2708
|
+
if (existingScript) {
|
|
2709
|
+
document.body.removeChild(existingScript);
|
|
2710
|
+
scriptCache.delete(src);
|
|
2711
|
+
setStatus("idle");
|
|
2712
|
+
}
|
|
2713
|
+
}, [src]);
|
|
2714
|
+
useEffect(() => {
|
|
2715
|
+
if (shouldLoad && status === "idle") {
|
|
2716
|
+
load();
|
|
2717
|
+
}
|
|
2718
|
+
}, [shouldLoad, status, load]);
|
|
735
2719
|
useEffect(() => {
|
|
736
|
-
const originalTitle = document.title;
|
|
737
|
-
const newTitle = suffix ? `${title}${separator}${suffix}` : title;
|
|
738
|
-
document.title = newTitle;
|
|
739
2720
|
return () => {
|
|
740
|
-
if (
|
|
741
|
-
|
|
2721
|
+
if (removeOnUnmount) {
|
|
2722
|
+
remove();
|
|
742
2723
|
}
|
|
743
2724
|
};
|
|
744
|
-
}, [
|
|
2725
|
+
}, [removeOnUnmount, remove]);
|
|
2726
|
+
return {
|
|
2727
|
+
status,
|
|
2728
|
+
ready: status === "ready",
|
|
2729
|
+
loading: status === "loading",
|
|
2730
|
+
error: status === "error",
|
|
2731
|
+
load,
|
|
2732
|
+
remove
|
|
2733
|
+
};
|
|
745
2734
|
}
|
|
746
|
-
var
|
|
747
|
-
function
|
|
748
|
-
const
|
|
2735
|
+
var useScript_default = useScript;
|
|
2736
|
+
function useRenderInfo(componentName = "Component") {
|
|
2737
|
+
const renderCount = useRef(0);
|
|
2738
|
+
const lastRenderTime = useRef(Date.now());
|
|
2739
|
+
const currentTime = Date.now();
|
|
2740
|
+
const sinceLastRender = currentTime - lastRenderTime.current;
|
|
2741
|
+
renderCount.current++;
|
|
2742
|
+
const renders = renderCount.current;
|
|
749
2743
|
useEffect(() => {
|
|
750
|
-
|
|
751
|
-
}
|
|
2744
|
+
lastRenderTime.current = currentTime;
|
|
2745
|
+
});
|
|
2746
|
+
const info = {
|
|
2747
|
+
name: componentName,
|
|
2748
|
+
renders,
|
|
2749
|
+
sinceLastRender,
|
|
2750
|
+
timestamp: currentTime
|
|
2751
|
+
};
|
|
2752
|
+
if (process.env.NODE_ENV === "development") {
|
|
2753
|
+
console.log(`[${componentName}] Render #${renders} (${sinceLastRender}ms since last)`);
|
|
2754
|
+
}
|
|
2755
|
+
return info;
|
|
2756
|
+
}
|
|
2757
|
+
var useRenderInfo_default = useRenderInfo;
|
|
2758
|
+
function useRenderCount() {
|
|
2759
|
+
const renderCount = useRef(0);
|
|
2760
|
+
renderCount.current++;
|
|
2761
|
+
return renderCount.current;
|
|
2762
|
+
}
|
|
2763
|
+
var useRenderCount_default = useRenderCount;
|
|
2764
|
+
function useLogger(componentName, props, options = {}) {
|
|
2765
|
+
const {
|
|
2766
|
+
logProps = true,
|
|
2767
|
+
logLifecycle = true,
|
|
2768
|
+
logger = console.log
|
|
2769
|
+
} = options;
|
|
2770
|
+
const previousProps = useRef(props);
|
|
2771
|
+
const renderCount = useRef(0);
|
|
2772
|
+
renderCount.current++;
|
|
752
2773
|
useEffect(() => {
|
|
753
|
-
if (
|
|
2774
|
+
if (logLifecycle) {
|
|
2775
|
+
logger(`[${componentName}] Mounted`);
|
|
2776
|
+
}
|
|
2777
|
+
return () => {
|
|
2778
|
+
if (logLifecycle) {
|
|
2779
|
+
logger(`[${componentName}] Unmounted (rendered ${renderCount.current} times)`);
|
|
2780
|
+
}
|
|
2781
|
+
};
|
|
2782
|
+
}, []);
|
|
2783
|
+
useEffect(() => {
|
|
2784
|
+
if (!logProps || !props || !previousProps.current) {
|
|
2785
|
+
previousProps.current = props;
|
|
754
2786
|
return;
|
|
755
2787
|
}
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
2788
|
+
const changedProps = {};
|
|
2789
|
+
let hasChanges = false;
|
|
2790
|
+
Object.keys(props).forEach((key) => {
|
|
2791
|
+
if (previousProps.current?.[key] !== props[key]) {
|
|
2792
|
+
changedProps[key] = {
|
|
2793
|
+
from: previousProps.current?.[key],
|
|
2794
|
+
to: props[key]
|
|
2795
|
+
};
|
|
2796
|
+
hasChanges = true;
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
if (previousProps.current) {
|
|
2800
|
+
Object.keys(previousProps.current).forEach((key) => {
|
|
2801
|
+
if (!(key in props)) {
|
|
2802
|
+
changedProps[key] = {
|
|
2803
|
+
from: previousProps.current?.[key],
|
|
2804
|
+
to: void 0
|
|
2805
|
+
};
|
|
2806
|
+
hasChanges = true;
|
|
2807
|
+
}
|
|
2808
|
+
});
|
|
2809
|
+
}
|
|
2810
|
+
if (hasChanges) {
|
|
2811
|
+
logger(`[${componentName}] Props changed:`, changedProps);
|
|
2812
|
+
}
|
|
2813
|
+
previousProps.current = props;
|
|
2814
|
+
}, [componentName, props, logProps, logger]);
|
|
2815
|
+
if (process.env.NODE_ENV === "development") {
|
|
2816
|
+
logger(`[${componentName}] Render #${renderCount.current}`);
|
|
2817
|
+
}
|
|
760
2818
|
}
|
|
761
|
-
var
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
2819
|
+
var useLogger_default = useLogger;
|
|
2820
|
+
var defaultDimensions = {
|
|
2821
|
+
width: 0,
|
|
2822
|
+
height: 0,
|
|
2823
|
+
top: 0,
|
|
2824
|
+
left: 0,
|
|
2825
|
+
bottom: 0,
|
|
2826
|
+
right: 0,
|
|
2827
|
+
x: 0,
|
|
2828
|
+
y: 0
|
|
2829
|
+
};
|
|
2830
|
+
function useMeasure() {
|
|
2831
|
+
const [dimensions, setDimensions] = useState(defaultDimensions);
|
|
2832
|
+
const elementRef = useRef(null);
|
|
2833
|
+
const observerRef = useRef(null);
|
|
2834
|
+
const measure = useCallback(() => {
|
|
2835
|
+
if (!elementRef.current) return;
|
|
2836
|
+
const rect = elementRef.current.getBoundingClientRect();
|
|
2837
|
+
setDimensions({
|
|
2838
|
+
width: rect.width,
|
|
2839
|
+
height: rect.height,
|
|
2840
|
+
top: rect.top,
|
|
2841
|
+
left: rect.left,
|
|
2842
|
+
bottom: rect.bottom,
|
|
2843
|
+
right: rect.right,
|
|
2844
|
+
x: rect.x,
|
|
2845
|
+
y: rect.y
|
|
2846
|
+
});
|
|
2847
|
+
}, []);
|
|
2848
|
+
const ref = useCallback((node) => {
|
|
2849
|
+
if (observerRef.current) {
|
|
2850
|
+
observerRef.current.disconnect();
|
|
2851
|
+
observerRef.current = null;
|
|
2852
|
+
}
|
|
2853
|
+
if (node) {
|
|
2854
|
+
elementRef.current = node;
|
|
2855
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2856
|
+
observerRef.current = new ResizeObserver((entries) => {
|
|
2857
|
+
if (entries[0]) {
|
|
2858
|
+
const rect2 = entries[0].target.getBoundingClientRect();
|
|
2859
|
+
setDimensions({
|
|
2860
|
+
width: rect2.width,
|
|
2861
|
+
height: rect2.height,
|
|
2862
|
+
top: rect2.top,
|
|
2863
|
+
left: rect2.left,
|
|
2864
|
+
bottom: rect2.bottom,
|
|
2865
|
+
right: rect2.right,
|
|
2866
|
+
x: rect2.x,
|
|
2867
|
+
y: rect2.y
|
|
2868
|
+
});
|
|
2869
|
+
}
|
|
2870
|
+
});
|
|
2871
|
+
observerRef.current.observe(node);
|
|
2872
|
+
}
|
|
2873
|
+
const rect = node.getBoundingClientRect();
|
|
2874
|
+
setDimensions({
|
|
2875
|
+
width: rect.width,
|
|
2876
|
+
height: rect.height,
|
|
2877
|
+
top: rect.top,
|
|
2878
|
+
left: rect.left,
|
|
2879
|
+
bottom: rect.bottom,
|
|
2880
|
+
right: rect.right,
|
|
2881
|
+
x: rect.x,
|
|
2882
|
+
y: rect.y
|
|
2883
|
+
});
|
|
2884
|
+
} else {
|
|
2885
|
+
elementRef.current = null;
|
|
2886
|
+
}
|
|
2887
|
+
}, []);
|
|
768
2888
|
useEffect(() => {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
2889
|
+
return () => {
|
|
2890
|
+
if (observerRef.current) {
|
|
2891
|
+
observerRef.current.disconnect();
|
|
2892
|
+
}
|
|
773
2893
|
};
|
|
774
|
-
mediaQuery.addEventListener("change", handleChange);
|
|
775
|
-
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
776
2894
|
}, []);
|
|
777
|
-
return
|
|
2895
|
+
return { ref, dimensions, measure };
|
|
778
2896
|
}
|
|
779
|
-
var
|
|
2897
|
+
var useMeasure_default = useMeasure;
|
|
2898
|
+
function useIntersectionObserver(options = {}) {
|
|
2899
|
+
const {
|
|
2900
|
+
root = null,
|
|
2901
|
+
rootMargin = "0px",
|
|
2902
|
+
threshold = 0,
|
|
2903
|
+
freezeOnceVisible = false,
|
|
2904
|
+
initialIsIntersecting = false,
|
|
2905
|
+
onChange
|
|
2906
|
+
} = options;
|
|
2907
|
+
const [entry, setEntry] = useState(null);
|
|
2908
|
+
const [isIntersecting, setIsIntersecting] = useState(initialIsIntersecting);
|
|
2909
|
+
const elementRef = useRef(null);
|
|
2910
|
+
const observerRef = useRef(null);
|
|
2911
|
+
const frozen = useRef(false);
|
|
2912
|
+
const ref = useCallback(
|
|
2913
|
+
(node) => {
|
|
2914
|
+
if (observerRef.current) {
|
|
2915
|
+
observerRef.current.disconnect();
|
|
2916
|
+
observerRef.current = null;
|
|
2917
|
+
}
|
|
2918
|
+
if (frozen.current) return;
|
|
2919
|
+
if (node && typeof IntersectionObserver !== "undefined") {
|
|
2920
|
+
elementRef.current = node;
|
|
2921
|
+
observerRef.current = new IntersectionObserver(
|
|
2922
|
+
([observerEntry]) => {
|
|
2923
|
+
const newIsIntersecting = observerEntry.isIntersecting;
|
|
2924
|
+
setEntry(observerEntry);
|
|
2925
|
+
setIsIntersecting(newIsIntersecting);
|
|
2926
|
+
onChange?.(newIsIntersecting, observerEntry);
|
|
2927
|
+
if (freezeOnceVisible && newIsIntersecting) {
|
|
2928
|
+
frozen.current = true;
|
|
2929
|
+
observerRef.current?.disconnect();
|
|
2930
|
+
}
|
|
2931
|
+
},
|
|
2932
|
+
{ root, rootMargin, threshold }
|
|
2933
|
+
);
|
|
2934
|
+
observerRef.current.observe(node);
|
|
2935
|
+
} else {
|
|
2936
|
+
elementRef.current = null;
|
|
2937
|
+
}
|
|
2938
|
+
},
|
|
2939
|
+
[root, rootMargin, threshold, freezeOnceVisible, onChange]
|
|
2940
|
+
);
|
|
2941
|
+
useEffect(() => {
|
|
2942
|
+
return () => {
|
|
2943
|
+
if (observerRef.current) {
|
|
2944
|
+
observerRef.current.disconnect();
|
|
2945
|
+
}
|
|
2946
|
+
};
|
|
2947
|
+
}, []);
|
|
2948
|
+
return { ref, isIntersecting, entry };
|
|
2949
|
+
}
|
|
2950
|
+
var useIntersectionObserver_default = useIntersectionObserver;
|
|
780
2951
|
var DEFAULT_DURATION = 4e3;
|
|
781
2952
|
function useSnackbar(defaultDuration = DEFAULT_DURATION) {
|
|
782
2953
|
const [state, setState] = useState({
|
|
@@ -818,72 +2989,7 @@ function useSnackbar(defaultDuration = DEFAULT_DURATION) {
|
|
|
818
2989
|
return { state, show, success, error, warning, info, close };
|
|
819
2990
|
}
|
|
820
2991
|
var useSnackbar_default = useSnackbar;
|
|
821
|
-
function useMediaQuery(query) {
|
|
822
|
-
const getMatches = (query2) => {
|
|
823
|
-
if (typeof window === "undefined") return false;
|
|
824
|
-
return window.matchMedia(query2).matches;
|
|
825
|
-
};
|
|
826
|
-
const [matches, setMatches] = useState(getMatches(query));
|
|
827
|
-
useEffect(() => {
|
|
828
|
-
if (typeof window === "undefined") return;
|
|
829
|
-
const mediaQuery = window.matchMedia(query);
|
|
830
|
-
const handleChange = () => setMatches(mediaQuery.matches);
|
|
831
|
-
handleChange();
|
|
832
|
-
mediaQuery.addEventListener("change", handleChange);
|
|
833
|
-
return () => mediaQuery.removeEventListener("change", handleChange);
|
|
834
|
-
}, [query]);
|
|
835
|
-
return matches;
|
|
836
|
-
}
|
|
837
|
-
var useIsMobile = () => useMediaQuery("(max-width: 767px)");
|
|
838
|
-
var useIsTablet = () => useMediaQuery("(min-width: 768px) and (max-width: 1023px)");
|
|
839
|
-
var useIsDesktop = () => useMediaQuery("(min-width: 1024px)");
|
|
840
|
-
var useIsMobileOrTablet = () => useMediaQuery("(max-width: 1023px)");
|
|
841
|
-
var useMediaQuery_default = useMediaQuery;
|
|
842
|
-
function useOnClickOutside(ref, handler, enabled = true) {
|
|
843
|
-
useEffect(() => {
|
|
844
|
-
if (!enabled) return;
|
|
845
|
-
const listener = (event) => {
|
|
846
|
-
const el = ref?.current;
|
|
847
|
-
if (!el || el.contains(event.target)) {
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
handler(event);
|
|
851
|
-
};
|
|
852
|
-
document.addEventListener("mousedown", listener);
|
|
853
|
-
document.addEventListener("touchstart", listener);
|
|
854
|
-
return () => {
|
|
855
|
-
document.removeEventListener("mousedown", listener);
|
|
856
|
-
document.removeEventListener("touchstart", listener);
|
|
857
|
-
};
|
|
858
|
-
}, [ref, handler, enabled]);
|
|
859
|
-
}
|
|
860
|
-
var useOnClickOutside_default = useOnClickOutside;
|
|
861
|
-
function useWindowSize(debounceMs = 100) {
|
|
862
|
-
const getSize = () => ({
|
|
863
|
-
width: typeof window !== "undefined" ? window.innerWidth : 0,
|
|
864
|
-
height: typeof window !== "undefined" ? window.innerHeight : 0
|
|
865
|
-
});
|
|
866
|
-
const [windowSize, setWindowSize] = useState(getSize);
|
|
867
|
-
useEffect(() => {
|
|
868
|
-
if (typeof window === "undefined") return;
|
|
869
|
-
let timeoutId;
|
|
870
|
-
const handleResize = () => {
|
|
871
|
-
clearTimeout(timeoutId);
|
|
872
|
-
timeoutId = setTimeout(() => {
|
|
873
|
-
setWindowSize(getSize());
|
|
874
|
-
}, debounceMs);
|
|
875
|
-
};
|
|
876
|
-
setWindowSize(getSize());
|
|
877
|
-
window.addEventListener("resize", handleResize);
|
|
878
|
-
return () => {
|
|
879
|
-
clearTimeout(timeoutId);
|
|
880
|
-
window.removeEventListener("resize", handleResize);
|
|
881
|
-
};
|
|
882
|
-
}, [debounceMs]);
|
|
883
|
-
return windowSize;
|
|
884
|
-
}
|
|
885
|
-
var useWindowSize_default = useWindowSize;
|
|
886
2992
|
|
|
887
|
-
export { ApiUrlBuilder, ClientLogger, EventEmitter, addDays, appEvents, camelToKebab, capitalize, capitalizeWords, clientLogger, copyToClipboard, createApiEndpoints, createApiUrlBuilder, createClientLogger, createEmptyPaginationMeta, createErrorResponse, createEventEmitter, createHttpClient, createSuccessResponse, endOfDay, formatDate, formatDateForInput, formatDateTime, formatDateTimeForInput, formatRelativeTime, getErrorMessage, getNextPage, getPrevPage, getResponseData, hasData, hasMorePages, isClipboardAvailable, isErrorResponse, isForbidden, isFuture, isNotFound, isPast, isServerError, isStatusError, isSuccess, isSuccessResponse, isToday, isUnauthorized, kebabToCamel, parseError, parseFullResponse, parseResponse, readFromClipboard, slugify, slugifyUnique, startOfDay, truncate, truncateWords, unslugify, useCopyToClipboard_default as useCopyToClipboard, useDebounce_default as useDebounce, useInterval_default as useInterval, useIsDesktop, useIsMobile, useIsMobileOrTablet, useIsTablet, useLocalStorage_default as useLocalStorage, useMediaQuery_default as useMediaQuery, useOnClickOutside_default as useOnClickOutside, usePageTitle_default as usePageTitle, useSnackbar_default as useSnackbar, useThemeDetector_default as useThemeDetector, useWindowSize_default as useWindowSize, withAbortSignal, withFormData, withTimeout };
|
|
2993
|
+
export { ApiUrlBuilder, ClientLogger, EventEmitter, addDays, appEvents, camelToKebab, capitalize, capitalizeWords, checkPackage, clientLogger, copyToClipboard, createApiEndpoints, createApiUrlBuilder, createClientLogger, createEmptyPaginationMeta, createErrorResponse, createEventEmitter, createHttpClient, createSuccessResponse, endOfDay, formatDate, formatDateForInput, formatDateTime, formatDateTimeForInput, formatPackageCheckResult, formatRelativeTime, generateNcuCommand, getErrorMessage, getNextPage, getPrevPage, getResponseData, hasData, hasMorePages, isClipboardAvailable, isErrorResponse, isForbidden, isFuture, isNotFound, isPast, isServerError, isStatusError, isSuccess, isSuccessResponse, isToday, isUnauthorized, kebabToCamel, packageCheck, parseError, parseFullResponse, parseResponse, readFromClipboard, slugify, slugifyUnique, startOfDay, truncate, truncateWords, unslugify, useBattery_default as useBattery, useClickAway_default as useClickAway, useContinuousRetry_default as useContinuousRetry, useCopyToClipboard_default as useCopyToClipboard, useCountdown_default as useCountdown, useCounter_default as useCounter, useDebounce_default as useDebounce, useDefault_default as useDefault, useDocumentTitle_default as useDocumentTitle, useEventListener_default as useEventListener, useFavicon_default as useFavicon, useFetch_default as useFetch, useGeolocation_default as useGeolocation, useHistoryState_default as useHistoryState, useHover_default as useHover, useIdle_default as useIdle, useIntersectionObserver_default as useIntersectionObserver, useInterval_default as useInterval, useIntervalWhen_default as useIntervalWhen, useIsClient_default as useIsClient, useIsDesktop, useIsFirstRender_default as useIsFirstRender, useIsMobile, useIsMobileOrTablet, useIsTablet, useKeyPress_default as useKeyPress, useList_default as useList, useLocalStorage_default as useLocalStorage, useLockBodyScroll_default as useLockBodyScroll, useLogger_default as useLogger, useLongPress_default as useLongPress, useMap_default as useMap, useMeasure_default as useMeasure, useMediaQuery_default as useMediaQuery, useMouse_default as useMouse, useNetworkState_default as useNetworkState, useObjectState_default as useObjectState, useOnClickOutside_default as useOnClickOutside, useOrientation_default as useOrientation, usePageLeave_default as usePageLeave, usePageTitle_default as usePageTitle, usePreferredLanguage_default as usePreferredLanguage, usePrevious_default as usePrevious, useQueue_default as useQueue, useRandomInterval_default as useRandomInterval, useRenderCount_default as useRenderCount, useRenderInfo_default as useRenderInfo, useScript_default as useScript, useSessionStorage_default as useSessionStorage, useSet_default as useSet, useSnackbar_default as useSnackbar, useThemeDetector_default as useThemeDetector, useThrottle_default as useThrottle, useTimeout_default as useTimeout, useToggle_default as useToggle, useVisibilityChange_default as useVisibilityChange, useWindowScroll_default as useWindowScroll, useWindowSize_default as useWindowSize, withAbortSignal, withFormData, withTimeout };
|
|
888
2994
|
//# sourceMappingURL=index.mjs.map
|
|
889
2995
|
//# sourceMappingURL=index.mjs.map
|