@ahnseungchan/webviewkit 2.0.0 → 2.2.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 +13 -9
- package/dist/index.d.mts +37 -7
- package/dist/index.d.ts +37 -7
- package/dist/index.js +500 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +486 -110
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
FLUTTER_READY_EVENT: () => FLUTTER_READY_EVENT,
|
|
45
45
|
FLUTTER_UNIFIED_HANDLER: () => FLUTTER_UNIFIED_HANDLER,
|
|
46
46
|
HistoryAction: () => HistoryAction,
|
|
47
|
+
KEEP_ALIVE_LIMIT: () => KEEP_ALIVE_LIMIT,
|
|
47
48
|
RN_BRIDGE_HANDLER: () => RN_BRIDGE_HANDLER,
|
|
48
49
|
STACK_BRIDGE_METHODS: () => STACK_BRIDGE_METHODS,
|
|
49
50
|
STACK_TRANSITION_MS: () => STACK_TRANSITION_MS,
|
|
@@ -77,6 +78,7 @@ __export(index_exports, {
|
|
|
77
78
|
serializeBridgeMessage: () => serializeBridgeMessage,
|
|
78
79
|
toStackPath: () => toStackPath,
|
|
79
80
|
useActivity: () => useActivity,
|
|
81
|
+
useOnRevive: () => useOnRevive,
|
|
80
82
|
useParams: () => useParams,
|
|
81
83
|
useStackRouter: () => useStackRouter,
|
|
82
84
|
waitForBridgeHost: () => waitForBridgeHost
|
|
@@ -84,12 +86,14 @@ __export(index_exports, {
|
|
|
84
86
|
module.exports = __toCommonJS(index_exports);
|
|
85
87
|
|
|
86
88
|
// src/constants.ts
|
|
87
|
-
var STACK_TRANSITION_MS =
|
|
89
|
+
var STACK_TRANSITION_MS = 500;
|
|
88
90
|
var TRANSITION_END_GRACE_MS = 50;
|
|
89
91
|
var BACK_TIMEOUT_MS = 1e3;
|
|
90
92
|
var BRIDGE_TIMEOUT_MS = 5e3;
|
|
91
93
|
var BRIDGE_HOST_WAIT_MS = 3e3;
|
|
92
94
|
var BRIDGE_HOST_POLL_MS = 100;
|
|
95
|
+
var KEEP_ALIVE_LIMIT = 5;
|
|
96
|
+
var DEV_MOUNTED_PAGES_WARN = 15;
|
|
93
97
|
|
|
94
98
|
// src/bridge/detect-host.ts
|
|
95
99
|
var FLUTTER_READY_EVENT = "flutterInAppWebViewPlatformReady";
|
|
@@ -864,19 +868,55 @@ var import_styled4 = __toESM(require("@emotion/styled"));
|
|
|
864
868
|
|
|
865
869
|
// src/stack-router/stack-router-provider.tsx
|
|
866
870
|
var import_styled3 = __toESM(require("@emotion/styled"));
|
|
867
|
-
var
|
|
871
|
+
var import_react10 = require("react");
|
|
868
872
|
|
|
869
873
|
// src/stack-router/_components/header.tsx
|
|
870
874
|
var import_styled = __toESM(require("@emotion/styled"));
|
|
875
|
+
var import_react4 = require("react");
|
|
876
|
+
|
|
877
|
+
// src/stack-router/activity-context.tsx
|
|
878
|
+
var import_react3 = require("react");
|
|
879
|
+
var ActivityContext = (0, import_react3.createContext)(null);
|
|
880
|
+
function useActivity() {
|
|
881
|
+
const context = (0, import_react3.useContext)(ActivityContext);
|
|
882
|
+
if (!context) {
|
|
883
|
+
throw new Error(
|
|
884
|
+
"useActivity must be used inside a StackRouterProvider page"
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
return context;
|
|
888
|
+
}
|
|
889
|
+
function useParams() {
|
|
890
|
+
return useActivity().params;
|
|
891
|
+
}
|
|
892
|
+
function useOnRevive(callback) {
|
|
893
|
+
const { revision, data } = useActivity();
|
|
894
|
+
const callbackRef = (0, import_react3.useRef)(callback);
|
|
895
|
+
callbackRef.current = callback;
|
|
896
|
+
const lastRevisionRef = (0, import_react3.useRef)(revision);
|
|
897
|
+
(0, import_react3.useEffect)(() => {
|
|
898
|
+
if (revision > lastRevisionRef.current) callbackRef.current(data);
|
|
899
|
+
lastRevisionRef.current = revision;
|
|
900
|
+
}, [revision, data]);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// src/stack-router/_components/header.tsx
|
|
871
904
|
var import_jsx_runtime3 = require("@emotion/react/jsx-runtime");
|
|
872
905
|
var Header = ({ title }) => {
|
|
906
|
+
var _a;
|
|
907
|
+
const activity = (0, import_react4.useContext)(ActivityContext);
|
|
873
908
|
const { currentPath: currentPath2, canGoBack } = useStackRouter();
|
|
909
|
+
const path = (_a = activity == null ? void 0 : activity.path) != null ? _a : currentPath2;
|
|
910
|
+
const showBack = activity ? activity.index > 0 : canGoBack;
|
|
874
911
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(StyledHeader, { children: [
|
|
875
|
-
|
|
876
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledTitle, { children: title != null ? title :
|
|
912
|
+
showBack && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(back_router_default, {}),
|
|
913
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(StyledTitle, { children: title != null ? title : path })
|
|
877
914
|
] });
|
|
878
915
|
};
|
|
879
916
|
var StyledHeader = import_styled.default.header`
|
|
917
|
+
position: sticky;
|
|
918
|
+
top: 0;
|
|
919
|
+
z-index: 1;
|
|
880
920
|
width: 100%;
|
|
881
921
|
height: 64px;
|
|
882
922
|
flex-shrink: 0;
|
|
@@ -889,49 +929,77 @@ var StyledHeader = import_styled.default.header`
|
|
|
889
929
|
`;
|
|
890
930
|
var StyledTitle = import_styled.default.h1`
|
|
891
931
|
margin: 0;
|
|
932
|
+
min-width: 0;
|
|
892
933
|
font-size: 1.25rem;
|
|
893
934
|
font-weight: 600;
|
|
894
935
|
color: var(--wvk-header-color, #111827);
|
|
936
|
+
white-space: nowrap;
|
|
937
|
+
overflow: hidden;
|
|
938
|
+
text-overflow: ellipsis;
|
|
895
939
|
`;
|
|
896
940
|
var header_default = Header;
|
|
897
941
|
|
|
898
942
|
// src/stack-router/_components/stack-page.tsx
|
|
899
|
-
var
|
|
943
|
+
var import_react5 = require("@emotion/react");
|
|
900
944
|
var import_styled2 = __toESM(require("@emotion/styled"));
|
|
901
|
-
var
|
|
945
|
+
var import_react6 = require("react");
|
|
902
946
|
var import_jsx_runtime4 = require("@emotion/react/jsx-runtime");
|
|
903
|
-
var
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
var
|
|
908
|
-
from { transform: translate3d(
|
|
909
|
-
to { transform: translate3d(
|
|
947
|
+
var IOS_EASING = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
948
|
+
var FADE_EASING = "ease";
|
|
949
|
+
var PARALLAX_OFFSET = "-30%";
|
|
950
|
+
var EDGE_SHADOW = "var(--wvk-edge-shadow, -6px 0 24px rgba(0, 0, 0, 0.12))";
|
|
951
|
+
var coverIn = import_react5.keyframes`
|
|
952
|
+
from { transform: translate3d(100%, 0, 0); box-shadow: none; }
|
|
953
|
+
to { transform: translate3d(0, 0, 0); box-shadow: ${EDGE_SHADOW}; }
|
|
910
954
|
`;
|
|
911
|
-
var
|
|
912
|
-
from { transform: translate3d(
|
|
913
|
-
to { transform: translate3d(
|
|
955
|
+
var coverOut = import_react5.keyframes`
|
|
956
|
+
from { transform: translate3d(0, 0, 0); box-shadow: ${EDGE_SHADOW}; }
|
|
957
|
+
to { transform: translate3d(100%, 0, 0); box-shadow: none; }
|
|
914
958
|
`;
|
|
915
|
-
var
|
|
959
|
+
var parallaxOut = import_react5.keyframes`
|
|
916
960
|
from { transform: translate3d(0, 0, 0); }
|
|
917
|
-
to { transform: translate3d(
|
|
961
|
+
to { transform: translate3d(${PARALLAX_OFFSET}, 0, 0); }
|
|
962
|
+
`;
|
|
963
|
+
var parallaxIn = import_react5.keyframes`
|
|
964
|
+
from { transform: translate3d(${PARALLAX_OFFSET}, 0, 0); }
|
|
965
|
+
to { transform: translate3d(0, 0, 0); }
|
|
918
966
|
`;
|
|
919
|
-
var
|
|
967
|
+
var dimIn = import_react5.keyframes`
|
|
920
968
|
from { opacity: 0; }
|
|
921
969
|
to { opacity: 1; }
|
|
922
970
|
`;
|
|
923
|
-
var
|
|
971
|
+
var dimOut = import_react5.keyframes`
|
|
924
972
|
from { opacity: 1; }
|
|
925
973
|
to { opacity: 0; }
|
|
926
974
|
`;
|
|
927
|
-
var
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
var
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
975
|
+
var fadeIn = import_react5.keyframes`
|
|
976
|
+
from { opacity: 0; }
|
|
977
|
+
to { opacity: 1; }
|
|
978
|
+
`;
|
|
979
|
+
var fadeOut = import_react5.keyframes`
|
|
980
|
+
from { opacity: 1; }
|
|
981
|
+
to { opacity: 0; }
|
|
982
|
+
`;
|
|
983
|
+
var layerOf = (direction, pageState) => direction === "push" === (pageState === "enter") ? "upper" : "lower";
|
|
984
|
+
function slideStyles(direction, pageState, duration) {
|
|
985
|
+
const timing = `${duration}ms ${IOS_EASING} forwards`;
|
|
986
|
+
if (layerOf(direction, pageState) === "upper") {
|
|
987
|
+
return import_react5.css`
|
|
988
|
+
animation: ${direction === "push" ? coverIn : coverOut} ${timing};
|
|
989
|
+
`;
|
|
990
|
+
}
|
|
991
|
+
return import_react5.css`
|
|
992
|
+
animation: ${direction === "push" ? parallaxOut : parallaxIn} ${timing};
|
|
993
|
+
&::after {
|
|
994
|
+
content: "";
|
|
995
|
+
/* transform 중인 페이지 기준 fixed = 스크롤과 무관하게 페이지 전체를 덮음 */
|
|
996
|
+
position: fixed;
|
|
997
|
+
inset: 0;
|
|
998
|
+
pointer-events: none;
|
|
999
|
+
background: var(--wvk-dim-color, rgba(0, 0, 0, 0.12));
|
|
1000
|
+
animation: ${direction === "push" ? dimIn : dimOut} ${timing};
|
|
1001
|
+
}
|
|
1002
|
+
`;
|
|
935
1003
|
}
|
|
936
1004
|
var PageWrapper = import_styled2.default.div`
|
|
937
1005
|
position: absolute;
|
|
@@ -940,14 +1008,20 @@ var PageWrapper = import_styled2.default.div`
|
|
|
940
1008
|
-webkit-overflow-scrolling: touch;
|
|
941
1009
|
background: var(--wvk-page-bg, #ffffff);
|
|
942
1010
|
z-index: ${({ zIndex }) => zIndex};
|
|
943
|
-
visibility: ${({ pageState }) => pageState === "covered" ? "hidden" : "visible"};
|
|
1011
|
+
visibility: ${({ pageState }) => pageState === "covered" || pageState === "cached" ? "hidden" : "visible"};
|
|
944
1012
|
${({ pageState, direction, transitionType, duration }) => {
|
|
945
1013
|
if (pageState !== "enter" && pageState !== "exit") return "";
|
|
946
1014
|
if (transitionType === "none" || duration === 0) return "";
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
${duration}ms
|
|
1015
|
+
if (transitionType === "fade") {
|
|
1016
|
+
return import_react5.css`
|
|
1017
|
+
will-change: opacity;
|
|
1018
|
+
animation: ${pageState === "enter" ? fadeIn : fadeOut} ${duration}ms
|
|
1019
|
+
${FADE_EASING} forwards;
|
|
1020
|
+
`;
|
|
1021
|
+
}
|
|
1022
|
+
return import_react5.css`
|
|
1023
|
+
will-change: transform;
|
|
1024
|
+
${slideStyles(direction, pageState, duration)}
|
|
951
1025
|
`;
|
|
952
1026
|
}}
|
|
953
1027
|
`;
|
|
@@ -957,8 +1031,8 @@ function StackPage({
|
|
|
957
1031
|
children,
|
|
958
1032
|
...wrapperProps
|
|
959
1033
|
}) {
|
|
960
|
-
const ref = (0,
|
|
961
|
-
(0,
|
|
1034
|
+
const ref = (0, import_react6.useRef)(null);
|
|
1035
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
962
1036
|
var _a;
|
|
963
1037
|
(_a = ref.current) == null ? void 0 : _a.toggleAttribute("inert", !isTop);
|
|
964
1038
|
}, [isTop]);
|
|
@@ -970,39 +1044,126 @@ function StackPage({
|
|
|
970
1044
|
"data-state": wrapperProps.pageState,
|
|
971
1045
|
"aria-hidden": isTop ? void 0 : true,
|
|
972
1046
|
onAnimationEnd: (event) => {
|
|
973
|
-
if (event.target === event.currentTarget
|
|
1047
|
+
if (event.target === event.currentTarget && !event.pseudoElement) {
|
|
1048
|
+
onAnimationEnd == null ? void 0 : onAnimationEnd();
|
|
1049
|
+
}
|
|
974
1050
|
},
|
|
975
1051
|
children
|
|
976
1052
|
}
|
|
977
1053
|
);
|
|
978
1054
|
}
|
|
979
1055
|
|
|
980
|
-
// src/stack-router/activity-context.tsx
|
|
981
|
-
var import_react5 = require("react");
|
|
982
|
-
var ActivityContext = (0, import_react5.createContext)(null);
|
|
983
|
-
function useActivity() {
|
|
984
|
-
const context = (0, import_react5.useContext)(ActivityContext);
|
|
985
|
-
if (!context) {
|
|
986
|
-
throw new Error(
|
|
987
|
-
"useActivity must be used inside a StackRouterProvider page"
|
|
988
|
-
);
|
|
989
|
-
}
|
|
990
|
-
return context;
|
|
991
|
-
}
|
|
992
|
-
function useParams() {
|
|
993
|
-
return useActivity().params;
|
|
994
|
-
}
|
|
995
|
-
|
|
996
1056
|
// src/stack-router/stack-reducer.ts
|
|
997
1057
|
var topOf = (entries) => entries[entries.length - 1];
|
|
998
|
-
|
|
999
|
-
|
|
1058
|
+
var bumpRevision = (entry) => {
|
|
1059
|
+
var _a;
|
|
1060
|
+
return {
|
|
1061
|
+
...entry,
|
|
1062
|
+
revision: ((_a = entry.revision) != null ? _a : 0) + 1
|
|
1063
|
+
};
|
|
1064
|
+
};
|
|
1065
|
+
function createStackState(entry, cacheLimit = 0) {
|
|
1066
|
+
return {
|
|
1067
|
+
entries: [entry],
|
|
1068
|
+
leaving: [],
|
|
1069
|
+
transition: null,
|
|
1070
|
+
cached: [],
|
|
1071
|
+
cacheLimit
|
|
1072
|
+
};
|
|
1000
1073
|
}
|
|
1074
|
+
function cacheEntries(state, removed) {
|
|
1075
|
+
const { entries, cached, cacheLimit } = state;
|
|
1076
|
+
const incoming = removed.filter((entry) => entry.keepAlive);
|
|
1077
|
+
if (cacheLimit <= 0 || incoming.length === 0) return cached;
|
|
1078
|
+
const incomingPaths = new Set(incoming.map((entry) => entry.path));
|
|
1079
|
+
const merged = [
|
|
1080
|
+
...cached.filter((entry) => !incomingPaths.has(entry.path)),
|
|
1081
|
+
...incoming
|
|
1082
|
+
];
|
|
1083
|
+
const capacity = cacheLimit - entries.filter((e) => e.keepAlive).length;
|
|
1084
|
+
return capacity > 0 ? merged.slice(-capacity) : [];
|
|
1085
|
+
}
|
|
1086
|
+
function withoutPath(list, path) {
|
|
1087
|
+
return list.filter((entry) => entry.path !== path);
|
|
1088
|
+
}
|
|
1089
|
+
function flushLeaving(state, nextEntries) {
|
|
1090
|
+
const alive = new Set(nextEntries.map((entry) => entry.key));
|
|
1091
|
+
const removed = state.leaving.filter((entry) => !alive.has(entry.key));
|
|
1092
|
+
return cacheEntries({ ...state, entries: nextEntries }, removed);
|
|
1093
|
+
}
|
|
1094
|
+
function revive(state, action) {
|
|
1095
|
+
const { direction, index, animate } = action;
|
|
1096
|
+
const entry = bumpRevision(action.entry);
|
|
1097
|
+
const previousTop = topOf(state.entries);
|
|
1098
|
+
const entries = [...state.entries.slice(0, index), entry];
|
|
1099
|
+
const removed = state.entries.slice(index);
|
|
1100
|
+
const cached = state.cached.filter((item) => item.key !== entry.key);
|
|
1101
|
+
const base = { ...state, entries, cached };
|
|
1102
|
+
if (!animate || direction === "pop" && removed.length === 0) {
|
|
1103
|
+
return {
|
|
1104
|
+
...base,
|
|
1105
|
+
cached: cacheEntries(base, removed),
|
|
1106
|
+
leaving: [],
|
|
1107
|
+
transition: null
|
|
1108
|
+
};
|
|
1109
|
+
}
|
|
1110
|
+
if (direction === "push") {
|
|
1111
|
+
const stillInStack = !removed.includes(previousTop);
|
|
1112
|
+
return {
|
|
1113
|
+
...base,
|
|
1114
|
+
cached: cacheEntries(
|
|
1115
|
+
base,
|
|
1116
|
+
removed.filter((item) => item !== previousTop)
|
|
1117
|
+
),
|
|
1118
|
+
leaving: stillInStack ? [] : [previousTop],
|
|
1119
|
+
transition: {
|
|
1120
|
+
type: "push",
|
|
1121
|
+
enterKey: entry.key,
|
|
1122
|
+
exitKey: previousTop.key
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
return {
|
|
1127
|
+
...base,
|
|
1128
|
+
leaving: removed,
|
|
1129
|
+
transition: {
|
|
1130
|
+
type: "pop",
|
|
1131
|
+
enterKey: entry.key,
|
|
1132
|
+
exitKeys: removed.map((item) => item.key)
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
function findRevivable(state, path, opts = {}) {
|
|
1137
|
+
const matches = (entry) => entry.path === path;
|
|
1138
|
+
const fromStack = opts.includeRemovable ? [...state.entries.slice(1)].reverse().find((entry) => entry.keepAlive && matches(entry)) : void 0;
|
|
1139
|
+
return fromStack != null ? fromStack : [...state.cached].reverse().find((entry) => matches(entry));
|
|
1140
|
+
}
|
|
1141
|
+
var OVERWRITES_LEAVING = /* @__PURE__ */ new Set([
|
|
1142
|
+
"PUSH",
|
|
1143
|
+
"POP_TO",
|
|
1144
|
+
"RESET",
|
|
1145
|
+
"RESET_PUSH",
|
|
1146
|
+
"RESTORE",
|
|
1147
|
+
"REVIVE"
|
|
1148
|
+
]);
|
|
1001
1149
|
function stackReducer(state, action) {
|
|
1150
|
+
if (!OVERWRITES_LEAVING.has(action.type) || state.leaving.length === 0) {
|
|
1151
|
+
return reduce(state, action);
|
|
1152
|
+
}
|
|
1153
|
+
const settled = { ...state, leaving: [] };
|
|
1154
|
+
const next = reduce(settled, action);
|
|
1155
|
+
if (next === settled) return state;
|
|
1156
|
+
return reduce(
|
|
1157
|
+
{ ...settled, cached: flushLeaving(state, next.entries) },
|
|
1158
|
+
action
|
|
1159
|
+
);
|
|
1160
|
+
}
|
|
1161
|
+
function reduce(state, action) {
|
|
1002
1162
|
switch (action.type) {
|
|
1003
1163
|
case "PUSH": {
|
|
1004
1164
|
const previousTop = topOf(state.entries);
|
|
1005
1165
|
return {
|
|
1166
|
+
...state,
|
|
1006
1167
|
entries: [...state.entries, action.entry],
|
|
1007
1168
|
leaving: [],
|
|
1008
1169
|
transition: action.animate ? {
|
|
@@ -1012,20 +1173,34 @@ function stackReducer(state, action) {
|
|
|
1012
1173
|
} : null
|
|
1013
1174
|
};
|
|
1014
1175
|
}
|
|
1015
|
-
case "REPLACE":
|
|
1176
|
+
case "REPLACE": {
|
|
1177
|
+
const entries = [...state.entries.slice(0, -1), action.entry];
|
|
1178
|
+
const { path } = action.entry;
|
|
1016
1179
|
return {
|
|
1017
1180
|
...state,
|
|
1018
|
-
entries
|
|
1181
|
+
entries,
|
|
1182
|
+
cached: cacheEntries(
|
|
1183
|
+
{ ...state, entries, cached: withoutPath(state.cached, path) },
|
|
1184
|
+
withoutPath([topOf(state.entries)], path)
|
|
1185
|
+
)
|
|
1019
1186
|
};
|
|
1187
|
+
}
|
|
1020
1188
|
case "POP_TO": {
|
|
1021
1189
|
const index = Math.max(0, action.index);
|
|
1022
1190
|
if (index >= state.entries.length - 1) return state;
|
|
1023
1191
|
const entries = state.entries.slice(0, index + 1);
|
|
1024
1192
|
const leaving = state.entries.slice(index + 1);
|
|
1025
1193
|
if (!action.animate) {
|
|
1026
|
-
return {
|
|
1194
|
+
return {
|
|
1195
|
+
...state,
|
|
1196
|
+
entries,
|
|
1197
|
+
leaving: [],
|
|
1198
|
+
transition: null,
|
|
1199
|
+
cached: cacheEntries({ ...state, entries }, leaving)
|
|
1200
|
+
};
|
|
1027
1201
|
}
|
|
1028
1202
|
return {
|
|
1203
|
+
...state,
|
|
1029
1204
|
entries,
|
|
1030
1205
|
leaving,
|
|
1031
1206
|
transition: {
|
|
@@ -1035,21 +1210,80 @@ function stackReducer(state, action) {
|
|
|
1035
1210
|
}
|
|
1036
1211
|
};
|
|
1037
1212
|
}
|
|
1038
|
-
case "RESET":
|
|
1039
|
-
|
|
1213
|
+
case "RESET": {
|
|
1214
|
+
const next = createStackState(action.entry, state.cacheLimit);
|
|
1215
|
+
const { path } = action.entry;
|
|
1216
|
+
return {
|
|
1217
|
+
...next,
|
|
1218
|
+
cached: cacheEntries(
|
|
1219
|
+
{
|
|
1220
|
+
...state,
|
|
1221
|
+
entries: next.entries,
|
|
1222
|
+
cached: withoutPath(state.cached, path)
|
|
1223
|
+
},
|
|
1224
|
+
withoutPath(state.entries, path)
|
|
1225
|
+
)
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
case "REVIVE":
|
|
1229
|
+
return revive(state, action);
|
|
1230
|
+
case "RESET_PUSH": {
|
|
1231
|
+
const [root] = state.entries;
|
|
1232
|
+
const previousTop = topOf(state.entries);
|
|
1233
|
+
const reusedKey = action.entry.key;
|
|
1234
|
+
const isReused = [...state.entries, ...state.cached].some(
|
|
1235
|
+
(entry) => entry.key === reusedKey
|
|
1236
|
+
);
|
|
1237
|
+
const entries = [
|
|
1238
|
+
root,
|
|
1239
|
+
isReused ? bumpRevision(action.entry) : action.entry
|
|
1240
|
+
];
|
|
1241
|
+
const sameTop = previousTop.key === reusedKey;
|
|
1242
|
+
const dropped = (action.animate ? state.entries.slice(1, -1) : state.entries.slice(1)).filter((entry) => entry.key !== reusedKey);
|
|
1243
|
+
const cached = state.cached.filter((entry) => entry.key !== reusedKey);
|
|
1244
|
+
const exiting = action.animate && !sameTop;
|
|
1245
|
+
return {
|
|
1246
|
+
...state,
|
|
1247
|
+
entries,
|
|
1248
|
+
cached: cacheEntries({ ...state, entries, cached }, dropped),
|
|
1249
|
+
leaving: exiting ? [previousTop] : [],
|
|
1250
|
+
transition: exiting ? {
|
|
1251
|
+
type: "push",
|
|
1252
|
+
enterKey: action.entry.key,
|
|
1253
|
+
exitKey: previousTop.key
|
|
1254
|
+
} : null
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1040
1257
|
case "RESTORE":
|
|
1041
|
-
return {
|
|
1042
|
-
|
|
1258
|
+
return {
|
|
1259
|
+
...state,
|
|
1260
|
+
entries: action.entries,
|
|
1261
|
+
leaving: [],
|
|
1262
|
+
transition: null
|
|
1263
|
+
};
|
|
1264
|
+
case "END_TRANSITION": {
|
|
1043
1265
|
if (!state.transition && state.leaving.length === 0) return state;
|
|
1044
|
-
return {
|
|
1266
|
+
return {
|
|
1267
|
+
...state,
|
|
1268
|
+
leaving: [],
|
|
1269
|
+
transition: null,
|
|
1270
|
+
cached: flushLeaving(state, state.entries)
|
|
1271
|
+
};
|
|
1272
|
+
}
|
|
1045
1273
|
default:
|
|
1046
1274
|
return state;
|
|
1047
1275
|
}
|
|
1048
1276
|
}
|
|
1049
1277
|
function getRenderedPages(state) {
|
|
1050
|
-
const { entries, leaving, transition } = state;
|
|
1278
|
+
const { entries, leaving, transition, cached } = state;
|
|
1051
1279
|
const top = topOf(entries);
|
|
1052
|
-
|
|
1280
|
+
const ordered = (transition == null ? void 0 : transition.type) === "push" ? [...entries.slice(0, -1), ...leaving, top] : [...entries, ...leaving];
|
|
1281
|
+
const cachedPages = cached.map((entry) => ({
|
|
1282
|
+
entry,
|
|
1283
|
+
pageState: "cached",
|
|
1284
|
+
isTop: false
|
|
1285
|
+
}));
|
|
1286
|
+
const stackPages = ordered.map((entry) => {
|
|
1053
1287
|
const isTop = entry.key === top.key;
|
|
1054
1288
|
let pageState = isTop ? "idle" : "covered";
|
|
1055
1289
|
if ((transition == null ? void 0 : transition.type) === "push") {
|
|
@@ -1062,20 +1296,21 @@ function getRenderedPages(state) {
|
|
|
1062
1296
|
}
|
|
1063
1297
|
return { entry, pageState, isTop };
|
|
1064
1298
|
});
|
|
1299
|
+
return [...cachedPages, ...stackPages];
|
|
1065
1300
|
}
|
|
1066
1301
|
|
|
1067
1302
|
// src/stack-router/use-prefers-reduced-motion.ts
|
|
1068
|
-
var
|
|
1303
|
+
var import_react7 = require("react");
|
|
1069
1304
|
var QUERY = "(prefers-reduced-motion: reduce)";
|
|
1070
1305
|
var getMediaQuery = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(QUERY) : null;
|
|
1071
1306
|
function usePrefersReducedMotion() {
|
|
1072
|
-
const [reduced, setReduced] = (0,
|
|
1307
|
+
const [reduced, setReduced] = (0, import_react7.useState)(
|
|
1073
1308
|
() => {
|
|
1074
1309
|
var _a, _b;
|
|
1075
1310
|
return (_b = (_a = getMediaQuery()) == null ? void 0 : _a.matches) != null ? _b : false;
|
|
1076
1311
|
}
|
|
1077
1312
|
);
|
|
1078
|
-
(0,
|
|
1313
|
+
(0, import_react7.useEffect)(() => {
|
|
1079
1314
|
var _a;
|
|
1080
1315
|
const mediaQuery = getMediaQuery();
|
|
1081
1316
|
if (!mediaQuery) return;
|
|
@@ -1090,13 +1325,13 @@ function usePrefersReducedMotion() {
|
|
|
1090
1325
|
}
|
|
1091
1326
|
|
|
1092
1327
|
// src/stack-router/use-stack-bridge-sync.ts
|
|
1093
|
-
var
|
|
1328
|
+
var import_react8 = require("react");
|
|
1094
1329
|
function useStackBridgeSync(bridge, router, onBackAtRoot) {
|
|
1095
1330
|
const enabled = Boolean(bridge);
|
|
1096
1331
|
const options = typeof bridge === "object" ? bridge : {};
|
|
1097
|
-
const latest = (0,
|
|
1332
|
+
const latest = (0, import_react8.useRef)({ router, options, onBackAtRoot });
|
|
1098
1333
|
latest.current = { router, options, onBackAtRoot };
|
|
1099
|
-
(0,
|
|
1334
|
+
(0, import_react8.useEffect)(() => {
|
|
1100
1335
|
if (!enabled) return;
|
|
1101
1336
|
return installBridgeHost({
|
|
1102
1337
|
allowUrl: latest.current.options.allowUrl,
|
|
@@ -1121,7 +1356,7 @@ function useStackBridgeSync(bridge, router, onBackAtRoot) {
|
|
|
1121
1356
|
}, [enabled]);
|
|
1122
1357
|
const { depth, currentPath: currentPath2 } = router;
|
|
1123
1358
|
const emit = enabled && options.emitStackChanged !== false;
|
|
1124
|
-
(0,
|
|
1359
|
+
(0, import_react8.useEffect)(() => {
|
|
1125
1360
|
if (!emit || !isNativeBridgeHost(detectBridgeHost())) return;
|
|
1126
1361
|
createWebViewBridgeClient().notifyStackChanged({ depth, path: currentPath2 }).catch((error) => {
|
|
1127
1362
|
var _a, _b;
|
|
@@ -1131,7 +1366,7 @@ function useStackBridgeSync(bridge, router, onBackAtRoot) {
|
|
|
1131
1366
|
}
|
|
1132
1367
|
|
|
1133
1368
|
// src/stack-router/use-stack-navigation.ts
|
|
1134
|
-
var
|
|
1369
|
+
var import_react9 = require("react");
|
|
1135
1370
|
|
|
1136
1371
|
// src/stack-router/match-path.ts
|
|
1137
1372
|
var splitSegments = (pathname) => pathname.split("/").filter((segment) => segment.length > 0);
|
|
@@ -1182,37 +1417,57 @@ var isDev2 = () => {
|
|
|
1182
1417
|
var _a;
|
|
1183
1418
|
return typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NODE_ENV) !== "production";
|
|
1184
1419
|
};
|
|
1185
|
-
function createEntry(hit, path, data, key = createBridgeId()) {
|
|
1420
|
+
function createEntry(hit, path, cacheLimit, data, key = createBridgeId()) {
|
|
1186
1421
|
return {
|
|
1187
1422
|
key,
|
|
1188
1423
|
path,
|
|
1189
1424
|
pattern: hit.activity.path,
|
|
1190
1425
|
params: hit.match.params,
|
|
1191
1426
|
query: hit.match.query,
|
|
1192
|
-
data
|
|
1427
|
+
data,
|
|
1428
|
+
keepAlive: hit.activity.keepAlive === true && cacheLimit > 0
|
|
1193
1429
|
};
|
|
1194
1430
|
}
|
|
1195
1431
|
var currentUrl = () => window.location.pathname + window.location.search;
|
|
1196
1432
|
function useStackNavigation(options) {
|
|
1197
|
-
const optionsRef = (0,
|
|
1433
|
+
const optionsRef = (0, import_react9.useRef)(options);
|
|
1198
1434
|
optionsRef.current = options;
|
|
1199
|
-
const [state, dispatch] = (0,
|
|
1435
|
+
const [state, dispatch] = (0, import_react9.useReducer)(stackReducer, void 0, () => {
|
|
1436
|
+
var _a;
|
|
1200
1437
|
const { initialActivity } = options;
|
|
1438
|
+
const cacheLimit = (_a = options.keepAliveLimit) != null ? _a : KEEP_ALIVE_LIMIT;
|
|
1201
1439
|
return createStackState(
|
|
1202
1440
|
createEntry(
|
|
1203
1441
|
{ activity: initialActivity, match: { params: {}, query: {} } },
|
|
1204
|
-
initialActivity.path
|
|
1205
|
-
|
|
1442
|
+
initialActivity.path,
|
|
1443
|
+
cacheLimit
|
|
1444
|
+
),
|
|
1445
|
+
cacheLimit
|
|
1206
1446
|
);
|
|
1207
1447
|
});
|
|
1208
|
-
const stateRef = (0,
|
|
1448
|
+
const stateRef = (0, import_react9.useRef)(state);
|
|
1209
1449
|
stateRef.current = state;
|
|
1210
|
-
const
|
|
1211
|
-
const
|
|
1450
|
+
const newEntry = (hit, path, data, key) => createEntry(hit, path, stateRef.current.cacheLimit, data, key);
|
|
1451
|
+
const busyRef = (0, import_react9.useRef)(false);
|
|
1452
|
+
const ignorePopRef = (0, import_react9.useRef)(0);
|
|
1453
|
+
const pendingTravelRef = (0, import_react9.useRef)(0);
|
|
1454
|
+
const isLocked = () => busyRef.current || pendingTravelRef.current > 0;
|
|
1455
|
+
const travel = (delta, ignorePop) => {
|
|
1456
|
+
pendingTravelRef.current += 1;
|
|
1457
|
+
if (ignorePop) ignorePopRef.current += 1;
|
|
1458
|
+
return history.travel(delta).then((popped) => {
|
|
1459
|
+
pendingTravelRef.current -= 1;
|
|
1460
|
+
if (!popped && ignorePop) {
|
|
1461
|
+
ignorePopRef.current = Math.max(0, ignorePopRef.current - 1);
|
|
1462
|
+
}
|
|
1463
|
+
return popped;
|
|
1464
|
+
});
|
|
1465
|
+
};
|
|
1466
|
+
const resolve = (0, import_react9.useCallback)((path) => {
|
|
1212
1467
|
const { activities, initialActivity } = optionsRef.current;
|
|
1213
1468
|
return findActivity([...activities, initialActivity], path);
|
|
1214
1469
|
}, []);
|
|
1215
|
-
const resolveOrNotify = (0,
|
|
1470
|
+
const resolveOrNotify = (0, import_react9.useCallback)(
|
|
1216
1471
|
(path) => {
|
|
1217
1472
|
var _a, _b;
|
|
1218
1473
|
const hit = resolve(path);
|
|
@@ -1227,29 +1482,35 @@ function useStackNavigation(options) {
|
|
|
1227
1482
|
[resolve]
|
|
1228
1483
|
);
|
|
1229
1484
|
const animate = () => optionsRef.current.duration > 0;
|
|
1230
|
-
const push = (0,
|
|
1485
|
+
const push = (0, import_react9.useCallback)(
|
|
1231
1486
|
(path, data) => {
|
|
1232
|
-
if (
|
|
1487
|
+
if (isLocked()) return false;
|
|
1233
1488
|
const hit = resolveOrNotify(path);
|
|
1234
1489
|
if (!hit) return false;
|
|
1235
|
-
const
|
|
1490
|
+
const { entries } = stateRef.current;
|
|
1491
|
+
const revived = findRevivable(stateRef.current, path);
|
|
1492
|
+
const entry = revived ? { ...revived, data } : newEntry(hit, path, data);
|
|
1236
1493
|
busyRef.current = true;
|
|
1237
|
-
history.push(path, {
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1494
|
+
history.push(path, { key: entry.key, index: entries.length, data });
|
|
1495
|
+
dispatch(
|
|
1496
|
+
revived ? {
|
|
1497
|
+
type: "REVIVE",
|
|
1498
|
+
entry,
|
|
1499
|
+
direction: "push",
|
|
1500
|
+
index: entries.length,
|
|
1501
|
+
animate: animate()
|
|
1502
|
+
} : { type: "PUSH", entry, animate: animate() }
|
|
1503
|
+
);
|
|
1243
1504
|
return true;
|
|
1244
1505
|
},
|
|
1245
1506
|
[resolveOrNotify]
|
|
1246
1507
|
);
|
|
1247
|
-
const replace = (0,
|
|
1508
|
+
const replace = (0, import_react9.useCallback)(
|
|
1248
1509
|
(path, data) => {
|
|
1249
|
-
if (
|
|
1510
|
+
if (isLocked()) return false;
|
|
1250
1511
|
const hit = resolveOrNotify(path);
|
|
1251
1512
|
if (!hit) return false;
|
|
1252
|
-
const entry =
|
|
1513
|
+
const entry = newEntry(hit, path, data);
|
|
1253
1514
|
history.replace(path, {
|
|
1254
1515
|
key: entry.key,
|
|
1255
1516
|
index: stateRef.current.entries.length - 1,
|
|
@@ -1260,21 +1521,46 @@ function useStackNavigation(options) {
|
|
|
1260
1521
|
},
|
|
1261
1522
|
[resolveOrNotify]
|
|
1262
1523
|
);
|
|
1263
|
-
const reset = (0,
|
|
1524
|
+
const reset = (0, import_react9.useCallback)(
|
|
1264
1525
|
(path, data) => {
|
|
1265
|
-
if (
|
|
1526
|
+
if (isLocked()) return false;
|
|
1266
1527
|
const hit = resolveOrNotify(path);
|
|
1267
1528
|
if (!hit) return false;
|
|
1268
|
-
const entry =
|
|
1269
|
-
|
|
1529
|
+
const entry = newEntry(hit, path, data);
|
|
1530
|
+
const depth = stateRef.current.entries.length;
|
|
1270
1531
|
dispatch({ type: "RESET", entry });
|
|
1532
|
+
const commit = () => {
|
|
1533
|
+
history.replace(path, { key: entry.key, index: 0, data });
|
|
1534
|
+
};
|
|
1535
|
+
if (depth === 1) commit();
|
|
1536
|
+
else void travel(-(depth - 1), true).then(commit);
|
|
1271
1537
|
return true;
|
|
1272
1538
|
},
|
|
1273
1539
|
[resolveOrNotify]
|
|
1274
1540
|
);
|
|
1275
|
-
const
|
|
1541
|
+
const resetPush = (0, import_react9.useCallback)(
|
|
1542
|
+
(path, data) => {
|
|
1543
|
+
const { entries } = stateRef.current;
|
|
1544
|
+
if (entries.length === 1) return push(path, data);
|
|
1545
|
+
if (isLocked()) return false;
|
|
1546
|
+
const hit = resolveOrNotify(path);
|
|
1547
|
+
if (!hit) return false;
|
|
1548
|
+
const revivable = findRevivable(stateRef.current, path, {
|
|
1549
|
+
includeRemovable: true
|
|
1550
|
+
});
|
|
1551
|
+
const entry = revivable ? { ...revivable, data } : newEntry(hit, path, data);
|
|
1552
|
+
busyRef.current = true;
|
|
1553
|
+
dispatch({ type: "RESET_PUSH", entry, animate: animate() });
|
|
1554
|
+
void travel(-(entries.length - 1), true).then(() => {
|
|
1555
|
+
history.push(path, { key: entry.key, index: 1, data });
|
|
1556
|
+
});
|
|
1557
|
+
return true;
|
|
1558
|
+
},
|
|
1559
|
+
[push, resolveOrNotify]
|
|
1560
|
+
);
|
|
1561
|
+
const pop = (0, import_react9.useCallback)((count = 1) => {
|
|
1276
1562
|
var _a, _b;
|
|
1277
|
-
if (
|
|
1563
|
+
if (isLocked()) return false;
|
|
1278
1564
|
const { entries } = stateRef.current;
|
|
1279
1565
|
if (entries.length <= 1) {
|
|
1280
1566
|
(_b = (_a = optionsRef.current).onBackAtRoot) == null ? void 0 : _b.call(_a);
|
|
@@ -1283,16 +1569,12 @@ function useStackNavigation(options) {
|
|
|
1283
1569
|
const delta = Math.min(Math.max(1, count), entries.length - 1);
|
|
1284
1570
|
const targetIndex = entries.length - 1 - delta;
|
|
1285
1571
|
busyRef.current = true;
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
busyRef.current = false;
|
|
1289
|
-
dispatch({ type: "POP_TO", index: targetIndex, animate: false });
|
|
1290
|
-
}
|
|
1291
|
-
});
|
|
1572
|
+
dispatch({ type: "POP_TO", index: targetIndex, animate: animate() });
|
|
1573
|
+
void travel(-delta, false);
|
|
1292
1574
|
return true;
|
|
1293
1575
|
}, []);
|
|
1294
|
-
const back = (0,
|
|
1295
|
-
const popTo = (0,
|
|
1576
|
+
const back = (0, import_react9.useCallback)(() => pop(1), [pop]);
|
|
1577
|
+
const popTo = (0, import_react9.useCallback)(
|
|
1296
1578
|
(path) => {
|
|
1297
1579
|
const { entries } = stateRef.current;
|
|
1298
1580
|
for (let i = entries.length - 2; i >= 0; i -= 1) {
|
|
@@ -1304,11 +1586,15 @@ function useStackNavigation(options) {
|
|
|
1304
1586
|
},
|
|
1305
1587
|
[pop]
|
|
1306
1588
|
);
|
|
1307
|
-
const endTransition = (0,
|
|
1589
|
+
const endTransition = (0, import_react9.useCallback)(() => {
|
|
1308
1590
|
dispatch({ type: "END_TRANSITION" });
|
|
1309
1591
|
}, []);
|
|
1310
|
-
(0,
|
|
1592
|
+
(0, import_react9.useEffect)(() => {
|
|
1311
1593
|
const onPop = (historyState) => {
|
|
1594
|
+
if (ignorePopRef.current > 0) {
|
|
1595
|
+
ignorePopRef.current -= 1;
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1312
1598
|
const { entries } = stateRef.current;
|
|
1313
1599
|
const index = historyState.key ? entries.findIndex((entry2) => entry2.key === historyState.key) : -1;
|
|
1314
1600
|
if (index !== -1) {
|
|
@@ -1318,12 +1604,26 @@ function useStackNavigation(options) {
|
|
|
1318
1604
|
}
|
|
1319
1605
|
return;
|
|
1320
1606
|
}
|
|
1607
|
+
const cachedEntry = historyState.key ? stateRef.current.cached.find((item) => item.key === historyState.key) : void 0;
|
|
1608
|
+
const targetIndex = historyState.index;
|
|
1609
|
+
if (cachedEntry && typeof targetIndex === "number" && // 루트 자리(0)는 되살리지 않는다. 아래 일반 처리(reset)로 넘긴다
|
|
1610
|
+
targetIndex >= 1 && targetIndex <= entries.length) {
|
|
1611
|
+
busyRef.current = true;
|
|
1612
|
+
dispatch({
|
|
1613
|
+
type: "REVIVE",
|
|
1614
|
+
entry: { ...cachedEntry, data: historyState.data },
|
|
1615
|
+
direction: targetIndex === entries.length ? "push" : "pop",
|
|
1616
|
+
index: targetIndex,
|
|
1617
|
+
animate: animate()
|
|
1618
|
+
});
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1321
1621
|
const hit = resolveOrNotify(historyState.path);
|
|
1322
1622
|
if (!hit) {
|
|
1323
1623
|
busyRef.current = false;
|
|
1324
1624
|
return;
|
|
1325
1625
|
}
|
|
1326
|
-
const entry =
|
|
1626
|
+
const entry = newEntry(
|
|
1327
1627
|
hit,
|
|
1328
1628
|
historyState.path,
|
|
1329
1629
|
historyState.data,
|
|
@@ -1341,8 +1641,8 @@ function useStackNavigation(options) {
|
|
|
1341
1641
|
removeListener();
|
|
1342
1642
|
};
|
|
1343
1643
|
}, [resolveOrNotify]);
|
|
1344
|
-
const restoredRef = (0,
|
|
1345
|
-
(0,
|
|
1644
|
+
const restoredRef = (0, import_react9.useRef)(false);
|
|
1645
|
+
(0, import_react9.useEffect)(() => {
|
|
1346
1646
|
if (restoredRef.current) return;
|
|
1347
1647
|
restoredRef.current = true;
|
|
1348
1648
|
const root = stateRef.current.entries[0];
|
|
@@ -1353,7 +1653,7 @@ function useStackNavigation(options) {
|
|
|
1353
1653
|
return;
|
|
1354
1654
|
}
|
|
1355
1655
|
const savedData = history.getCurrentState().data;
|
|
1356
|
-
const top =
|
|
1656
|
+
const top = newEntry(hit, url, savedData);
|
|
1357
1657
|
if (optionsRef.current.restoreStack === "top-only") {
|
|
1358
1658
|
history.replace(url, { key: top.key, index: 0, data: savedData });
|
|
1359
1659
|
dispatch({ type: "RESTORE", entries: [top] });
|
|
@@ -1363,7 +1663,7 @@ function useStackNavigation(options) {
|
|
|
1363
1663
|
history.push(url, { key: top.key, index: 1, data: savedData });
|
|
1364
1664
|
dispatch({ type: "RESTORE", entries: [root, top] });
|
|
1365
1665
|
}, [resolve]);
|
|
1366
|
-
(0,
|
|
1666
|
+
(0, import_react9.useEffect)(() => {
|
|
1367
1667
|
if (!state.transition) {
|
|
1368
1668
|
busyRef.current = false;
|
|
1369
1669
|
return;
|
|
@@ -1374,14 +1674,24 @@ function useStackNavigation(options) {
|
|
|
1374
1674
|
);
|
|
1375
1675
|
return () => clearTimeout(timer);
|
|
1376
1676
|
}, [state, endTransition]);
|
|
1377
|
-
return {
|
|
1677
|
+
return {
|
|
1678
|
+
state,
|
|
1679
|
+
push,
|
|
1680
|
+
replace,
|
|
1681
|
+
reset,
|
|
1682
|
+
resetPush,
|
|
1683
|
+
back,
|
|
1684
|
+
pop,
|
|
1685
|
+
popTo,
|
|
1686
|
+
endTransition
|
|
1687
|
+
};
|
|
1378
1688
|
}
|
|
1379
1689
|
|
|
1380
1690
|
// src/stack-router/stack-router-provider.tsx
|
|
1381
1691
|
var import_jsx_runtime5 = require("@emotion/react/jsx-runtime");
|
|
1382
|
-
var StackRouterContext = (0,
|
|
1692
|
+
var StackRouterContext = (0, import_react10.createContext)(null);
|
|
1383
1693
|
var useStackRouter = () => {
|
|
1384
|
-
const context = (0,
|
|
1694
|
+
const context = (0, import_react10.useContext)(StackRouterContext);
|
|
1385
1695
|
if (!context) {
|
|
1386
1696
|
throw new Error("useStackRouter must be used within a StackRouterProvider");
|
|
1387
1697
|
}
|
|
@@ -1391,6 +1701,8 @@ var isDevEnv = () => {
|
|
|
1391
1701
|
var _a;
|
|
1392
1702
|
return typeof process !== "undefined" && ((_a = process.env) == null ? void 0 : _a.NODE_ENV) === "development";
|
|
1393
1703
|
};
|
|
1704
|
+
var MIN_MOUNTED_PAGES = 1;
|
|
1705
|
+
var CACHED_ACTIVITY_INDEX = -1;
|
|
1394
1706
|
var StackRouterProvider = ({
|
|
1395
1707
|
initialActivity,
|
|
1396
1708
|
Activities = [],
|
|
@@ -1400,6 +1712,8 @@ var StackRouterProvider = ({
|
|
|
1400
1712
|
transition = "slide",
|
|
1401
1713
|
duration = STACK_TRANSITION_MS,
|
|
1402
1714
|
restoreStack = "with-root",
|
|
1715
|
+
keepAliveLimit = KEEP_ALIVE_LIMIT,
|
|
1716
|
+
maxMountedPages,
|
|
1403
1717
|
safeArea = false,
|
|
1404
1718
|
onBackAtRoot,
|
|
1405
1719
|
onNotFound,
|
|
@@ -1413,6 +1727,7 @@ var StackRouterProvider = ({
|
|
|
1413
1727
|
activities: Activities,
|
|
1414
1728
|
duration: effectiveDuration,
|
|
1415
1729
|
restoreStack,
|
|
1730
|
+
keepAliveLimit,
|
|
1416
1731
|
onBackAtRoot,
|
|
1417
1732
|
onNotFound
|
|
1418
1733
|
});
|
|
@@ -1422,7 +1737,7 @@ var StackRouterProvider = ({
|
|
|
1422
1737
|
return (_b2 = (_a2 = Activities.find((activity) => activity.path === pattern)) == null ? void 0 : _a2.element) != null ? _b2 : initialActivity.path === pattern ? initialActivity.element : null;
|
|
1423
1738
|
};
|
|
1424
1739
|
const top = state.entries[state.entries.length - 1];
|
|
1425
|
-
const value = (0,
|
|
1740
|
+
const value = (0, import_react10.useMemo)(
|
|
1426
1741
|
() => ({
|
|
1427
1742
|
currentPath: top.path,
|
|
1428
1743
|
currentState: {
|
|
@@ -1444,6 +1759,7 @@ var StackRouterProvider = ({
|
|
|
1444
1759
|
push: navigation.push,
|
|
1445
1760
|
replace: navigation.replace,
|
|
1446
1761
|
reset: navigation.reset,
|
|
1762
|
+
resetPush: navigation.resetPush,
|
|
1447
1763
|
back: navigation.back,
|
|
1448
1764
|
pop: navigation.pop,
|
|
1449
1765
|
popTo: navigation.popTo,
|
|
@@ -1454,11 +1770,60 @@ var StackRouterProvider = ({
|
|
|
1454
1770
|
useStackBridgeSync(bridge, value, onBackAtRoot);
|
|
1455
1771
|
const direction = (_b = (_a = state.transition) == null ? void 0 : _a.type) != null ? _b : "push";
|
|
1456
1772
|
const pages = getRenderedPages(state);
|
|
1773
|
+
const stackIndexByKey = new Map(
|
|
1774
|
+
state.entries.map((entry, index) => [entry.key, index])
|
|
1775
|
+
);
|
|
1776
|
+
const activityIndexOf = (entry) => {
|
|
1777
|
+
const stackIndex = stackIndexByKey.get(entry.key);
|
|
1778
|
+
if (stackIndex !== void 0) return stackIndex;
|
|
1779
|
+
const leavingIndex = state.leaving.findIndex(
|
|
1780
|
+
(item) => item.key === entry.key
|
|
1781
|
+
);
|
|
1782
|
+
return leavingIndex === -1 ? CACHED_ACTIVITY_INDEX : state.entries.length + leavingIndex;
|
|
1783
|
+
};
|
|
1784
|
+
const mountLimit = maxMountedPages === void 0 || !Number.isFinite(maxMountedPages) ? Infinity : Math.max(MIN_MOUNTED_PAGES, maxMountedPages);
|
|
1785
|
+
const mountedKeysRef = (0, import_react10.useRef)(/* @__PURE__ */ new Set());
|
|
1786
|
+
const wasMounted = mountedKeysRef.current;
|
|
1787
|
+
const shouldMount = (page) => {
|
|
1788
|
+
const { entry, pageState } = page;
|
|
1789
|
+
if (pageState === "cached" || entry.keepAlive) return true;
|
|
1790
|
+
const stackIndex = stackIndexByKey.get(entry.key);
|
|
1791
|
+
if (stackIndex === void 0) return wasMounted.has(entry.key);
|
|
1792
|
+
if (pageState === "enter" || pageState === "exit") return true;
|
|
1793
|
+
return state.entries.length - stackIndex <= mountLimit;
|
|
1794
|
+
};
|
|
1795
|
+
const mountedKeys = new Set(
|
|
1796
|
+
pages.filter(shouldMount).map((page) => page.entry.key)
|
|
1797
|
+
);
|
|
1798
|
+
mountedKeysRef.current = mountedKeys;
|
|
1799
|
+
const mountedCount = mountedKeys.size;
|
|
1800
|
+
const domOrderRef = (0, import_react10.useRef)([]);
|
|
1801
|
+
const currentKeys = new Set(pages.map((page) => page.entry.key));
|
|
1802
|
+
const knownKeys = new Set(domOrderRef.current);
|
|
1803
|
+
domOrderRef.current = [
|
|
1804
|
+
...domOrderRef.current.filter((key) => currentKeys.has(key)),
|
|
1805
|
+
...pages.map((page) => page.entry.key).filter((key) => !knownKeys.has(key))
|
|
1806
|
+
];
|
|
1807
|
+
const domOrder = domOrderRef.current;
|
|
1808
|
+
const domPages = pages.map((page, index) => ({ page, index })).sort(
|
|
1809
|
+
(a, b) => domOrder.indexOf(a.page.entry.key) - domOrder.indexOf(b.page.entry.key)
|
|
1810
|
+
);
|
|
1811
|
+
const hasWarnedRef = (0, import_react10.useRef)(false);
|
|
1812
|
+
(0, import_react10.useEffect)(() => {
|
|
1813
|
+
if (hasWarnedRef.current || !isDevEnv() || mountedCount <= DEV_MOUNTED_PAGES_WARN) {
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
hasWarnedRef.current = true;
|
|
1817
|
+
console.warn(
|
|
1818
|
+
`[webviewkit] \uB9C8\uC6B4\uD2B8\uB41C \uD398\uC774\uC9C0\uAC00 ${mountedCount}\uAC1C\uC785\uB2C8\uB2E4. \uBA54\uBAA8\uB9AC \uC0AC\uC6A9\uC774 \uCEE4\uC9C8 \uC218 \uC788\uC73C\uB2C8 maxMountedPages \uB85C \uC0C1\uD55C\uC744 \uB450\uC138\uC694.`
|
|
1819
|
+
);
|
|
1820
|
+
}, [mountedCount]);
|
|
1457
1821
|
const showDevTools = enableDevTools != null ? enableDevTools : isDevEnv();
|
|
1458
1822
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(StackRouterContext.Provider, { value, children: [
|
|
1459
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LayoutContainer, { safeArea, children: /* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1460
|
-
|
|
1461
|
-
|
|
1823
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LayoutContainer, { safeArea, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Layout, { maxWidth, "data-testid": "layout", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageContainer, { children: domPages.map(({ page, index }) => {
|
|
1824
|
+
var _a2;
|
|
1825
|
+
const { entry, pageState, isTop } = page;
|
|
1826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1462
1827
|
ActivityContext.Provider,
|
|
1463
1828
|
{
|
|
1464
1829
|
value: {
|
|
@@ -1468,10 +1833,12 @@ var StackRouterProvider = ({
|
|
|
1468
1833
|
params: entry.params,
|
|
1469
1834
|
query: entry.query,
|
|
1470
1835
|
data: entry.data,
|
|
1471
|
-
index,
|
|
1472
|
-
isTop
|
|
1836
|
+
index: activityIndexOf(entry),
|
|
1837
|
+
isTop,
|
|
1838
|
+
isCached: pageState === "cached",
|
|
1839
|
+
revision: (_a2 = entry.revision) != null ? _a2 : 0
|
|
1473
1840
|
},
|
|
1474
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.
|
|
1841
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
1475
1842
|
StackPage,
|
|
1476
1843
|
{
|
|
1477
1844
|
pageState,
|
|
@@ -1481,13 +1848,16 @@ var StackRouterProvider = ({
|
|
|
1481
1848
|
zIndex: index,
|
|
1482
1849
|
isTop,
|
|
1483
1850
|
onAnimationEnd: pageState === "enter" ? endTransition : void 0,
|
|
1484
|
-
children:
|
|
1851
|
+
children: [
|
|
1852
|
+
mountedKeys.has(entry.key) && isShowHeader && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(header_default, {}),
|
|
1853
|
+
mountedKeys.has(entry.key) ? elementFor(entry.pattern) : null
|
|
1854
|
+
]
|
|
1485
1855
|
}
|
|
1486
1856
|
)
|
|
1487
1857
|
},
|
|
1488
1858
|
entry.key
|
|
1489
|
-
)
|
|
1490
|
-
|
|
1859
|
+
);
|
|
1860
|
+
}) }) }) }),
|
|
1491
1861
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1492
1862
|
StackDevRoadmap,
|
|
1493
1863
|
{
|
|
@@ -1592,6 +1962,7 @@ var BackIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
|
1592
1962
|
FLUTTER_READY_EVENT,
|
|
1593
1963
|
FLUTTER_UNIFIED_HANDLER,
|
|
1594
1964
|
HistoryAction,
|
|
1965
|
+
KEEP_ALIVE_LIMIT,
|
|
1595
1966
|
RN_BRIDGE_HANDLER,
|
|
1596
1967
|
STACK_BRIDGE_METHODS,
|
|
1597
1968
|
STACK_TRANSITION_MS,
|
|
@@ -1625,6 +1996,7 @@ var BackIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
|
1625
1996
|
serializeBridgeMessage,
|
|
1626
1997
|
toStackPath,
|
|
1627
1998
|
useActivity,
|
|
1999
|
+
useOnRevive,
|
|
1628
2000
|
useParams,
|
|
1629
2001
|
useStackRouter,
|
|
1630
2002
|
waitForBridgeHost
|