@modern-js/plugin-garfish 2.68.13-alpha.1 → 2.68.13-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,7 +29,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var apps_exports = {};
30
30
  __export(apps_exports, {
31
31
  generateApps: () => generateApps,
32
- pathJoin: () => pathJoin
32
+ pathJoin: () => pathJoin,
33
+ useMicroAppMountStatus: () => useMicroAppMountStatus
33
34
  });
34
35
  module.exports = __toCommonJS(apps_exports);
35
36
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -38,6 +39,13 @@ var import_garfish = __toESM(require("garfish"));
38
39
  var import_react = require("react");
39
40
  var import_util = require("../../util");
40
41
  var import_loadable = require("../loadable");
42
+ const MicroAppMountContext = /* @__PURE__ */ (0, import_react.createContext)({
43
+ isMounted: true
44
+ });
45
+ const useMicroAppMountStatus = () => {
46
+ const { isMounted } = (0, import_react.useContext)(MicroAppMountContext);
47
+ return isMounted;
48
+ };
41
49
  function pathJoin(...args) {
42
50
  const res = args.reduce((res2, path) => {
43
51
  let nPath = path;
@@ -66,6 +74,7 @@ function getAppInstance(options, appInfo, manifest) {
66
74
  });
67
75
  const destroyRef = (0, import_react.useRef)(null);
68
76
  const isMountedRef = (0, import_react.useRef)(true);
77
+ const abortControllerRef = (0, import_react.useRef)(null);
69
78
  const context = (0, import_react.useContext)(import_runtime.RuntimeReactContext);
70
79
  var _props_useRouteMatch;
71
80
  const useRouteMatch = (_props_useRouteMatch = props.useRouteMatch) !== null && _props_useRouteMatch !== void 0 ? _props_useRouteMatch : context === null || context === void 0 ? void 0 : (_context_router = context.router) === null || _context_router === void 0 ? void 0 : _context_router.useRouteMatch;
@@ -129,8 +138,10 @@ or directly pass the "basename":
129
138
  ]);
130
139
  (0, import_react.useEffect)(() => {
131
140
  const { setLoadingState, ...userProps } = props;
141
+ abortControllerRef.current = new AbortController();
132
142
  const safeSetLoadingState = (state) => {
133
- if (isMountedRef.current) {
143
+ var _abortControllerRef_current;
144
+ if (isMountedRef.current && !((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted)) {
134
145
  setLoadingState(state);
135
146
  }
136
147
  };
@@ -174,9 +185,11 @@ or directly pass the "basename":
174
185
  return {
175
186
  mount: (...props2) => {
176
187
  if (componetRenderMode && SubComponent) {
177
- setSubModuleComponent({
178
- component: SubComponent
179
- });
188
+ if (isMountedRef.current) {
189
+ setSubModuleComponent({
190
+ component: SubComponent
191
+ });
192
+ }
180
193
  return void 0;
181
194
  } else {
182
195
  (0, import_util.logger)("MicroApp customer render", props2);
@@ -202,7 +215,14 @@ or directly pass the "basename":
202
215
  });
203
216
  async function renderApp() {
204
217
  try {
218
+ var _abortControllerRef_current, _abortControllerRef_current1;
219
+ if ((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted) {
220
+ return;
221
+ }
205
222
  const appInstance = await import_garfish.default.loadApp(appInfo.name, loadAppOptions);
223
+ if ((_abortControllerRef_current1 = abortControllerRef.current) === null || _abortControllerRef_current1 === void 0 ? void 0 : _abortControllerRef_current1.signal.aborted) {
224
+ return;
225
+ }
206
226
  if (!appInstance) {
207
227
  throw new Error(`MicroApp Garfish.loadApp "${appInfo.name}" result is null`);
208
228
  }
@@ -224,15 +244,21 @@ or directly pass the "basename":
224
244
  await (appInstance === null || appInstance === void 0 ? void 0 : appInstance.mount());
225
245
  }
226
246
  } catch (error) {
227
- safeSetLoadingState({
228
- isLoading: true,
229
- error
230
- });
247
+ var _abortControllerRef_current2;
248
+ if (!((_abortControllerRef_current2 = abortControllerRef.current) === null || _abortControllerRef_current2 === void 0 ? void 0 : _abortControllerRef_current2.signal.aborted)) {
249
+ safeSetLoadingState({
250
+ isLoading: true,
251
+ error
252
+ });
253
+ }
231
254
  }
232
255
  }
233
256
  renderApp();
234
257
  return () => {
235
258
  isMountedRef.current = false;
259
+ if (abortControllerRef.current) {
260
+ abortControllerRef.current.abort();
261
+ }
236
262
  if (appRef.current) {
237
263
  const { appInfo: appInfo2 } = appRef.current;
238
264
  if (appInfo2.cache) {
@@ -261,12 +287,26 @@ or directly pass the "basename":
261
287
  }, [
262
288
  SubModuleComponent
263
289
  ]);
290
+ const SafeSubModuleComponent = (0, import_react.useCallback)(() => {
291
+ if (!SubModuleComponent || !isMountedRef.current) {
292
+ return null;
293
+ }
294
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MicroAppMountContext.Provider, {
295
+ value: {
296
+ isMounted: isMountedRef.current
297
+ },
298
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SubModuleComponent, {
299
+ ...props
300
+ })
301
+ });
302
+ }, [
303
+ SubModuleComponent,
304
+ props
305
+ ]);
264
306
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
265
307
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
266
308
  id: domId,
267
- children: SubModuleComponent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SubModuleComponent, {
268
- ...props
269
- })
309
+ children: SubModuleComponent && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SafeSubModuleComponent, {})
270
310
  })
271
311
  });
272
312
  }
@@ -288,5 +328,6 @@ function generateApps(options, manifest) {
288
328
  // Annotate the CommonJS export names for ESM import in node:
289
329
  0 && (module.exports = {
290
330
  generateApps,
291
- pathJoin
331
+ pathJoin,
332
+ useMicroAppMountStatus
292
333
  });
@@ -8,9 +8,16 @@ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
8
8
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
9
9
  import { RuntimeReactContext } from "@meta/runtime";
10
10
  import Garfish from "garfish";
11
- import { useContext, useEffect, useRef, useState } from "react";
11
+ import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
12
12
  import { generateSubAppContainerKey, logger } from "../../util";
13
13
  import { Loadable } from "../loadable";
14
+ var MicroAppMountContext = /* @__PURE__ */ createContext({
15
+ isMounted: true
16
+ });
17
+ var useMicroAppMountStatus = function() {
18
+ var isMounted = useContext(MicroAppMountContext).isMounted;
19
+ return isMounted;
20
+ };
14
21
  function pathJoin() {
15
22
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
16
23
  args[_key] = arguments[_key];
@@ -42,6 +49,7 @@ function getAppInstance(options, appInfo, manifest) {
42
49
  }), 2), _useState_ = _useState[0], SubModuleComponent = _useState_.component, setSubModuleComponent = _useState[1];
43
50
  var destroyRef = useRef(null);
44
51
  var isMountedRef = useRef(true);
52
+ var abortControllerRef = useRef(null);
45
53
  var context = useContext(RuntimeReactContext);
46
54
  var _props_useRouteMatch;
47
55
  var useRouteMatch = (_props_useRouteMatch = props.useRouteMatch) !== null && _props_useRouteMatch !== void 0 ? _props_useRouteMatch : context === null || context === void 0 ? void 0 : (_context_router = context.router) === null || _context_router === void 0 ? void 0 : _context_router.useRouteMatch;
@@ -108,8 +116,10 @@ or directly pass the "basename":
108
116
  var setLoadingState = props.setLoadingState, userProps = _object_without_properties(props, [
109
117
  "setLoadingState"
110
118
  ]);
119
+ abortControllerRef.current = new AbortController();
111
120
  var safeSetLoadingState = function(state) {
112
- if (isMountedRef.current) {
121
+ var _abortControllerRef_current;
122
+ if (isMountedRef.current && !((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted)) {
113
123
  setLoadingState(state);
114
124
  }
115
125
  };
@@ -149,9 +159,11 @@ or directly pass the "basename":
149
159
  _$props[_key] = arguments[_key];
150
160
  }
151
161
  if (componetRenderMode && SubComponent) {
152
- setSubModuleComponent({
153
- component: SubComponent
154
- });
162
+ if (isMountedRef.current) {
163
+ setSubModuleComponent({
164
+ component: SubComponent
165
+ });
166
+ }
155
167
  return void 0;
156
168
  } else {
157
169
  logger("MicroApp customer render", _$props);
@@ -180,7 +192,7 @@ or directly pass the "basename":
180
192
  });
181
193
  function _renderApp() {
182
194
  _renderApp = _async_to_generator(function() {
183
- var appInstance, error;
195
+ var _abortControllerRef_current, _abortControllerRef_current1, appInstance, error, _abortControllerRef_current2;
184
196
  return _ts_generator(this, function(_state) {
185
197
  switch (_state.label) {
186
198
  case 0:
@@ -190,12 +202,22 @@ or directly pass the "basename":
190
202
  ,
191
203
  7
192
204
  ]);
205
+ if ((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted) {
206
+ return [
207
+ 2
208
+ ];
209
+ }
193
210
  return [
194
211
  4,
195
212
  Garfish.loadApp(appInfo.name, loadAppOptions)
196
213
  ];
197
214
  case 1:
198
215
  appInstance = _state.sent();
216
+ if ((_abortControllerRef_current1 = abortControllerRef.current) === null || _abortControllerRef_current1 === void 0 ? void 0 : _abortControllerRef_current1.signal.aborted) {
217
+ return [
218
+ 2
219
+ ];
220
+ }
199
221
  if (!appInstance) {
200
222
  throw new Error('MicroApp Garfish.loadApp "'.concat(appInfo.name, '" result is null'));
201
223
  }
@@ -241,10 +263,12 @@ or directly pass the "basename":
241
263
  ];
242
264
  case 6:
243
265
  error = _state.sent();
244
- safeSetLoadingState({
245
- isLoading: true,
246
- error
247
- });
266
+ if (!((_abortControllerRef_current2 = abortControllerRef.current) === null || _abortControllerRef_current2 === void 0 ? void 0 : _abortControllerRef_current2.signal.aborted)) {
267
+ safeSetLoadingState({
268
+ isLoading: true,
269
+ error
270
+ });
271
+ }
248
272
  return [
249
273
  3,
250
274
  7
@@ -261,6 +285,9 @@ or directly pass the "basename":
261
285
  renderApp();
262
286
  return function() {
263
287
  isMountedRef.current = false;
288
+ if (abortControllerRef.current) {
289
+ abortControllerRef.current.abort();
290
+ }
264
291
  if (appRef.current) {
265
292
  var _$appInfo = appRef.current.appInfo;
266
293
  if (_$appInfo.cache) {
@@ -289,10 +316,24 @@ or directly pass the "basename":
289
316
  }, [
290
317
  SubModuleComponent
291
318
  ]);
319
+ var SafeSubModuleComponent = useCallback(function() {
320
+ if (!SubModuleComponent || !isMountedRef.current) {
321
+ return null;
322
+ }
323
+ return /* @__PURE__ */ _jsx(MicroAppMountContext.Provider, {
324
+ value: {
325
+ isMounted: isMountedRef.current
326
+ },
327
+ children: /* @__PURE__ */ _jsx(SubModuleComponent, _object_spread({}, props))
328
+ });
329
+ }, [
330
+ SubModuleComponent,
331
+ props
332
+ ]);
292
333
  return /* @__PURE__ */ _jsx(_Fragment, {
293
334
  children: /* @__PURE__ */ _jsx("div", {
294
335
  id: domId,
295
- children: SubModuleComponent && /* @__PURE__ */ _jsx(SubModuleComponent, _object_spread({}, props))
336
+ children: SubModuleComponent && /* @__PURE__ */ _jsx(SafeSubModuleComponent, {})
296
337
  })
297
338
  });
298
339
  }
@@ -313,5 +354,6 @@ function generateApps(options, manifest) {
313
354
  }
314
355
  export {
315
356
  generateApps,
316
- pathJoin
357
+ pathJoin,
358
+ useMicroAppMountStatus
317
359
  };
@@ -1,9 +1,16 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { RuntimeReactContext } from "@meta/runtime";
3
3
  import Garfish from "garfish";
4
- import { useContext, useEffect, useRef, useState } from "react";
4
+ import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
5
5
  import { generateSubAppContainerKey, logger } from "../../util";
6
6
  import { Loadable } from "../loadable";
7
+ const MicroAppMountContext = /* @__PURE__ */ createContext({
8
+ isMounted: true
9
+ });
10
+ const useMicroAppMountStatus = () => {
11
+ const { isMounted } = useContext(MicroAppMountContext);
12
+ return isMounted;
13
+ };
7
14
  function pathJoin(...args) {
8
15
  const res = args.reduce((res2, path) => {
9
16
  let nPath = path;
@@ -32,6 +39,7 @@ function getAppInstance(options, appInfo, manifest) {
32
39
  });
33
40
  const destroyRef = useRef(null);
34
41
  const isMountedRef = useRef(true);
42
+ const abortControllerRef = useRef(null);
35
43
  const context = useContext(RuntimeReactContext);
36
44
  var _props_useRouteMatch;
37
45
  const useRouteMatch = (_props_useRouteMatch = props.useRouteMatch) !== null && _props_useRouteMatch !== void 0 ? _props_useRouteMatch : context === null || context === void 0 ? void 0 : (_context_router = context.router) === null || _context_router === void 0 ? void 0 : _context_router.useRouteMatch;
@@ -95,8 +103,10 @@ or directly pass the "basename":
95
103
  ]);
96
104
  useEffect(() => {
97
105
  const { setLoadingState, ...userProps } = props;
106
+ abortControllerRef.current = new AbortController();
98
107
  const safeSetLoadingState = (state) => {
99
- if (isMountedRef.current) {
108
+ var _abortControllerRef_current;
109
+ if (isMountedRef.current && !((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted)) {
100
110
  setLoadingState(state);
101
111
  }
102
112
  };
@@ -140,9 +150,11 @@ or directly pass the "basename":
140
150
  return {
141
151
  mount: (...props2) => {
142
152
  if (componetRenderMode && SubComponent) {
143
- setSubModuleComponent({
144
- component: SubComponent
145
- });
153
+ if (isMountedRef.current) {
154
+ setSubModuleComponent({
155
+ component: SubComponent
156
+ });
157
+ }
146
158
  return void 0;
147
159
  } else {
148
160
  logger("MicroApp customer render", props2);
@@ -168,7 +180,14 @@ or directly pass the "basename":
168
180
  });
169
181
  async function renderApp() {
170
182
  try {
183
+ var _abortControllerRef_current, _abortControllerRef_current1;
184
+ if ((_abortControllerRef_current = abortControllerRef.current) === null || _abortControllerRef_current === void 0 ? void 0 : _abortControllerRef_current.signal.aborted) {
185
+ return;
186
+ }
171
187
  const appInstance = await Garfish.loadApp(appInfo.name, loadAppOptions);
188
+ if ((_abortControllerRef_current1 = abortControllerRef.current) === null || _abortControllerRef_current1 === void 0 ? void 0 : _abortControllerRef_current1.signal.aborted) {
189
+ return;
190
+ }
172
191
  if (!appInstance) {
173
192
  throw new Error(`MicroApp Garfish.loadApp "${appInfo.name}" result is null`);
174
193
  }
@@ -190,15 +209,21 @@ or directly pass the "basename":
190
209
  await (appInstance === null || appInstance === void 0 ? void 0 : appInstance.mount());
191
210
  }
192
211
  } catch (error) {
193
- safeSetLoadingState({
194
- isLoading: true,
195
- error
196
- });
212
+ var _abortControllerRef_current2;
213
+ if (!((_abortControllerRef_current2 = abortControllerRef.current) === null || _abortControllerRef_current2 === void 0 ? void 0 : _abortControllerRef_current2.signal.aborted)) {
214
+ safeSetLoadingState({
215
+ isLoading: true,
216
+ error
217
+ });
218
+ }
197
219
  }
198
220
  }
199
221
  renderApp();
200
222
  return () => {
201
223
  isMountedRef.current = false;
224
+ if (abortControllerRef.current) {
225
+ abortControllerRef.current.abort();
226
+ }
202
227
  if (appRef.current) {
203
228
  const { appInfo: appInfo2 } = appRef.current;
204
229
  if (appInfo2.cache) {
@@ -227,12 +252,26 @@ or directly pass the "basename":
227
252
  }, [
228
253
  SubModuleComponent
229
254
  ]);
255
+ const SafeSubModuleComponent = useCallback(() => {
256
+ if (!SubModuleComponent || !isMountedRef.current) {
257
+ return null;
258
+ }
259
+ return /* @__PURE__ */ _jsx(MicroAppMountContext.Provider, {
260
+ value: {
261
+ isMounted: isMountedRef.current
262
+ },
263
+ children: /* @__PURE__ */ _jsx(SubModuleComponent, {
264
+ ...props
265
+ })
266
+ });
267
+ }, [
268
+ SubModuleComponent,
269
+ props
270
+ ]);
230
271
  return /* @__PURE__ */ _jsx(_Fragment, {
231
272
  children: /* @__PURE__ */ _jsx("div", {
232
273
  id: domId,
233
- children: SubModuleComponent && /* @__PURE__ */ _jsx(SubModuleComponent, {
234
- ...props
235
- })
274
+ children: SubModuleComponent && /* @__PURE__ */ _jsx(SafeSubModuleComponent, {})
236
275
  })
237
276
  });
238
277
  }
@@ -253,5 +292,6 @@ function generateApps(options, manifest) {
253
292
  }
254
293
  export {
255
294
  generateApps,
256
- pathJoin
295
+ pathJoin,
296
+ useMicroAppMountStatus
257
297
  };
@@ -5,6 +5,7 @@ export interface Provider extends interfaces.Provider {
5
5
  SubModuleComponent?: React.ComponentType<any>;
6
6
  jupiter_submodule_app_key?: React.ComponentType<any>;
7
7
  }
8
+ export declare const useMicroAppMountStatus: () => boolean;
8
9
  export interface AppMap {
9
10
  [key: string]: React.FC<MicroComponentProps>;
10
11
  }
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.68.13-alpha.1",
18
+ "version": "2.68.13-alpha.2",
19
19
  "jsnext:source": "./src/cli/index.ts",
20
20
  "types": "./dist/types/cli/index.d.ts",
21
21
  "typesVersions": {
@@ -69,8 +69,8 @@
69
69
  "debug": "4.3.7",
70
70
  "garfish": "^1.8.1",
71
71
  "react-loadable": "^5.5.0",
72
- "@modern-js/plugin-v2": "2.68.12",
73
72
  "@modern-js/runtime-utils": "2.68.12",
73
+ "@modern-js/plugin-v2": "2.68.12",
74
74
  "@modern-js/utils": "2.68.12"
75
75
  },
76
76
  "peerDependencies": {
@@ -93,13 +93,13 @@
93
93
  "react-dom": "^18.3.1",
94
94
  "react-router-dom": "6.27.0",
95
95
  "typescript": "^5",
96
- "@modern-js/runtime": "2.68.12",
97
- "@scripts/build": "2.66.0",
98
- "@modern-js/types": "2.68.12",
99
96
  "@modern-js/app-tools": "2.68.12",
100
- "@scripts/jest-config": "2.66.0",
97
+ "@scripts/build": "2.66.0",
98
+ "@modern-js/core": "2.68.12",
101
99
  "@modern-js/plugin-router-v5": "2.68.12",
102
- "@modern-js/core": "2.68.12"
100
+ "@modern-js/types": "2.68.12",
101
+ "@modern-js/runtime": "2.68.12",
102
+ "@scripts/jest-config": "2.66.0"
103
103
  },
104
104
  "sideEffects": false,
105
105
  "publishConfig": {