@zk-tech/base-ui-configuration-service 0.0.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,984 @@
1
+ 'use strict';
2
+
3
+ var dispose = require('@zk-tech/bedrock/dispose');
4
+ var di = require('@zk-tech/bedrock/di');
5
+ var event = require('@zk-tech/bedrock/event');
6
+ var assert = require('@zk-tech/bedrock/assert');
7
+ var valtio = require('valtio');
8
+ var lodashEs = require('lodash-es');
9
+ var React3 = require('react');
10
+ var lock = require('@zk-tech/bedrock/lock');
11
+ var reactRouterDom = require('react-router-dom');
12
+ var pathToRegexp = require('path-to-regexp');
13
+ var reactErrorBoundary = require('react-error-boundary');
14
+ var ahooks = require('ahooks');
15
+ var cs = require('classnames');
16
+
17
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
18
+
19
+ var React3__default = /*#__PURE__*/_interopDefault(React3);
20
+ var cs__default = /*#__PURE__*/_interopDefault(cs);
21
+
22
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
23
+ var __decorateClass = (decorators, target, key, kind) => {
24
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
25
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
26
+ if (decorator = decorators[i])
27
+ result = (decorator(result)) || result;
28
+ return result;
29
+ };
30
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
31
+
32
+ // src/base/middleware/action-point-runner.ts
33
+ var ActionPointRunner = class extends Function {
34
+ constructor(middlewares, point, _uiConfig) {
35
+ super();
36
+ this.middlewares = middlewares;
37
+ this.point = point;
38
+ this._uiConfig = _uiConfig;
39
+ this._isStop = false;
40
+ this.index = 0;
41
+ const closure = (...args) => closure.run(...args);
42
+ closure.middlewares = middlewares;
43
+ closure.point = point ?? {
44
+ name: "",
45
+ from: "",
46
+ trigger: "",
47
+ path: []
48
+ };
49
+ closure._uiConfig = _uiConfig;
50
+ return Object.setPrototypeOf(closure, new.target.prototype);
51
+ }
52
+ get isStop() {
53
+ return this._isStop;
54
+ }
55
+ run(...args) {
56
+ this._rawArguments = args;
57
+ this.index = -1;
58
+ let data;
59
+ while (this.hasNext() && !this._isStop) {
60
+ data = this.getNext()();
61
+ }
62
+ return data;
63
+ }
64
+ hasNext() {
65
+ return this.index < this.middlewares.length - 1;
66
+ }
67
+ getNext(skip = false) {
68
+ let next = () => {
69
+ };
70
+ if (this.hasNext()) {
71
+ this.index += 1;
72
+ const handler = this.middlewares[this.index];
73
+ next = () => {
74
+ return handler({
75
+ stop: () => {
76
+ this._isStop = true;
77
+ },
78
+ uiConfig: this._uiConfig,
79
+ actionInfo: this.point,
80
+ triggerArgs: this._rawArguments
81
+ });
82
+ };
83
+ }
84
+ return next;
85
+ }
86
+ };
87
+
88
+ // src/base/middleware/middleware.ts
89
+ var MiddlewareManager = class {
90
+ constructor() {
91
+ this._registerById = /* @__PURE__ */ new Map();
92
+ /** caller <-> middleware handler 的映射表 */
93
+ this._registerByCaller = /* @__PURE__ */ new Map();
94
+ this._onMiddlewareChange = new event.Emitter();
95
+ this._disposeMap = /* @__PURE__ */ new Map();
96
+ this.onMiddlewareChange = this._onMiddlewareChange.event;
97
+ }
98
+ buildRunner(options) {
99
+ const caller = this._getCaller(options);
100
+ const handlers = (this._registerByCaller.get(caller) ?? []).map((id) => this._registerById.get(id)?.handler).filter((item) => item);
101
+ if (options.handler) {
102
+ handlers.push(options.handler);
103
+ }
104
+ return new ActionPointRunner(
105
+ // @ts-ignore type error
106
+ handlers,
107
+ {
108
+ from: options.trigger,
109
+ name: options.uiConfig.id,
110
+ trigger: options.method
111
+ },
112
+ options.uiConfig
113
+ );
114
+ }
115
+ use(props) {
116
+ const existed = this._registerById.get(props.id);
117
+ if (existed) {
118
+ assert.lvAssertNotHere("config had been existed");
119
+ }
120
+ this._registerById.set(props.id, props);
121
+ props.triggerMethod.forEach((item) => {
122
+ const caller = this._getCaller({ trigger: props.trigger, method: item });
123
+ if (!this._registerByCaller.has(caller)) {
124
+ this._registerByCaller.set(caller, []);
125
+ }
126
+ const target = this._registerByCaller.get(caller);
127
+ target.push(props.id);
128
+ });
129
+ this._onMiddlewareChange.fire({
130
+ trigger: props.trigger,
131
+ method: props.triggerMethod
132
+ });
133
+ const dispose = props.freshTrigger(() => {
134
+ this._onMiddlewareChange.fire({
135
+ trigger: props.trigger,
136
+ method: props.triggerMethod
137
+ });
138
+ });
139
+ this._disposeMap.set(props.id, dispose);
140
+ }
141
+ unUse(id) {
142
+ const target = this._registerById.get(id);
143
+ if (!target) {
144
+ return;
145
+ }
146
+ target.triggerMethod.forEach((item) => {
147
+ const caller = this._getCaller({ trigger: target.trigger, method: item });
148
+ if (!this._registerByCaller.has(caller)) {
149
+ return;
150
+ }
151
+ const triggers = this._registerByCaller.get(caller);
152
+ this._registerByCaller.set(
153
+ caller,
154
+ triggers.filter((_item) => _item === target.id)
155
+ );
156
+ });
157
+ this._onMiddlewareChange.fire({
158
+ trigger: target.trigger,
159
+ method: target.triggerMethod
160
+ });
161
+ const dispose = this._disposeMap.get(id);
162
+ dispose?.dispose();
163
+ this._disposeMap.delete(id);
164
+ }
165
+ _getCaller({ trigger, method }) {
166
+ return `${trigger}-${method.toString()}`;
167
+ }
168
+ };
169
+
170
+ // src/base/base-ui-configuration-service.tsx
171
+ exports.BaseUiConfigurationService = class BaseUiConfigurationService extends dispose.Disposable {
172
+ constructor(_setting, _containerService) {
173
+ super();
174
+ this._setting = _setting;
175
+ this._containerService = _containerService;
176
+ }
177
+ get setting() {
178
+ return this._setting;
179
+ }
180
+ registerConfig(config) {
181
+ for (const key of Object.keys(config)) {
182
+ this.uiManager[key].registerConfig(config[key]);
183
+ }
184
+ }
185
+ useMiddleware(props) {
186
+ return this.middleware.use(props);
187
+ }
188
+ _bootstrap() {
189
+ this.middleware = this._containerService.createInstance(MiddlewareManager);
190
+ this._initAllManager();
191
+ }
192
+ };
193
+ exports.BaseUiConfigurationService = __decorateClass([
194
+ __decorateParam(1, di.IContainerService)
195
+ ], exports.BaseUiConfigurationService);
196
+ var BaseSetting = class {
197
+ constructor(options) {
198
+ const defaultConfig = {
199
+ namespace: "base",
200
+ visible: true,
201
+ debugMode: false
202
+ };
203
+ this.observableData = valtio.proxy(lodashEs.merge(defaultConfig, options.setting));
204
+ }
205
+ get namespace() {
206
+ return this.observableData.namespace;
207
+ }
208
+ get debugMode() {
209
+ return this.observableData.debugMode;
210
+ }
211
+ get visible() {
212
+ return this.observableData.visible;
213
+ }
214
+ };
215
+ var GlobalContext = React3.createContext();
216
+ var BaseUiManager = class {
217
+ // feat: 修复旧框架跳转新框架闪动
218
+ constructor(_middlewareManager) {
219
+ this._middlewareManager = _middlewareManager;
220
+ this._listenerMiddlewareChange();
221
+ }
222
+ unRegisterConfig(id) {
223
+ assert.lvAssertNotHere(
224
+ "There is no such scenario yet, and no support capability is provided for the time being. If necessary, please contact infrastructure support"
225
+ );
226
+ }
227
+ _listenerMiddlewareChange() {
228
+ this._middlewareManager.onMiddlewareChange((props) => {
229
+ this._middlewareChange(props);
230
+ });
231
+ }
232
+ };
233
+
234
+ // src/utils/sort.ts
235
+ var OrderLevel = /* @__PURE__ */ ((OrderLevel2) => {
236
+ OrderLevel2["high"] = "high";
237
+ OrderLevel2["default"] = "default";
238
+ OrderLevel2["low"] = "low";
239
+ return OrderLevel2;
240
+ })(OrderLevel || {});
241
+ function sortListBySettings({
242
+ list,
243
+ filter = (item) => item
244
+ }) {
245
+ return list.sort((a, b) => {
246
+ const typeSort = { high: 2, default: 1, low: 0 };
247
+ const { orderLevel: aType = "default", order: aPriority = 0 } = a;
248
+ const { orderLevel: bType = "default", order: bPriority = 0 } = b;
249
+ if (aType !== bType) {
250
+ return typeSort[bType] - typeSort[aType];
251
+ }
252
+ return bPriority - aPriority;
253
+ }).map(filter);
254
+ }
255
+
256
+ // src/utils/merged-array.ts
257
+ var mergeUiConfigs = (configs) => {
258
+ const uiConfigs = {};
259
+ configs.map((configObj) => {
260
+ for (const [key, config] of Object.entries(configObj)) {
261
+ if (!Array.isArray(config)) {
262
+ continue;
263
+ }
264
+ if (key in uiConfigs) {
265
+ uiConfigs[key]?.push(...config);
266
+ } else {
267
+ Object.assign(uiConfigs, {
268
+ [key]: config
269
+ });
270
+ }
271
+ }
272
+ });
273
+ return uiConfigs;
274
+ };
275
+
276
+ // src/utils/runner-builder.ts
277
+ function runnerBuilder({
278
+ middleware,
279
+ trigger,
280
+ method,
281
+ handler,
282
+ uiConfig
283
+ }) {
284
+ const runner = middleware.buildRunner({
285
+ trigger,
286
+ method,
287
+ handler,
288
+ uiConfig
289
+ });
290
+ return runner;
291
+ }
292
+
293
+ // src/utils/evaluate.ts
294
+ function evaluate(config, defaultValue, ...args) {
295
+ if (typeof config === "function") {
296
+ return config(...args) ?? defaultValue;
297
+ }
298
+ return config ?? defaultValue;
299
+ }
300
+ var PageRouteManagerSymbol = "PageRoute";
301
+ var KeepAliveStatus = /* @__PURE__ */ ((KeepAliveStatus2) => {
302
+ KeepAliveStatus2["Activated"] = "Activated";
303
+ KeepAliveStatus2["InActivated"] = "InActivated";
304
+ return KeepAliveStatus2;
305
+ })(KeepAliveStatus || {});
306
+ var InitAwaitLock = class {
307
+ constructor() {
308
+ this._mutex = new lock.SharedMutex();
309
+ void this._mutex.lock();
310
+ }
311
+ /**
312
+ * @description 是否已经完成初始化
313
+ */
314
+ get hasBeenDone() {
315
+ return !this._mutex.isLocked();
316
+ }
317
+ /**
318
+ * @description 标记初始化完成并放行
319
+ */
320
+ initDone() {
321
+ if (this.hasBeenDone) {
322
+ return;
323
+ }
324
+ this._mutex.unLock();
325
+ }
326
+ };
327
+
328
+ // src/utils/is-equal.ts
329
+ var isEqualStr = (val, otherVal) => val === otherVal;
330
+ var queryStringify = (parseObj) => {
331
+ if (typeof parseObj !== "object") {
332
+ assert.lvAssertNever(parseObj);
333
+ }
334
+ return Object.entries(parseObj).map((item) => `${item[0]}=${item[1]}`).join("&");
335
+ };
336
+ var ErrorBoundary = ({ children, fallback, onError }) => {
337
+ return /* @__PURE__ */ React.createElement(reactErrorBoundary.ErrorBoundary, { fallback: fallback ?? /* @__PURE__ */ React.createElement("div", null), onError }, children);
338
+ };
339
+ function useObserverSelector(selectionTarget, selector, options = {}) {
340
+ const { deps } = options;
341
+ if (!selectionTarget) {
342
+ return void 0;
343
+ }
344
+ const snapshot2 = valtio.useSnapshot(selectionTarget);
345
+ const selectedValue = React3.useMemo(() => {
346
+ return selector(snapshot2);
347
+ }, [snapshot2, ...deps ?? []]);
348
+ return selectedValue;
349
+ }
350
+
351
+ // src/feature/page-route/component/page-route.module.scss
352
+ var page_route_module_default = {};
353
+
354
+ // src/feature/page-route/component/page-route.tsx
355
+ var PageRoute = ({ layout }) => {
356
+ const navigate2 = reactRouterDom.useNavigate();
357
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
358
+ const baseRoute = useObserverSelector(uiConfigurationService.setting, (manager) => {
359
+ return {
360
+ namespace: manager.namespace,
361
+ baseRoute: manager.baseRoute,
362
+ redirectRouteIdWhen404: manager.redirectRouteIdWhen404
363
+ };
364
+ });
365
+ const routeConfig = useObserverSelector(
366
+ uiConfigurationService.uiManager[PageRouteManagerSymbol],
367
+ (manager) => {
368
+ return manager.observableData.configs;
369
+ }
370
+ );
371
+ const redirectRouteId = useObserverSelector(uiConfigurationService.setting, (setting) => {
372
+ return setting?.observableData?.redirectRouteIdWhen404;
373
+ });
374
+ const redirectRoute = React3.useMemo(() => {
375
+ if (!redirectRouteId) return void 0;
376
+ return routeConfig.find(({ id }) => id === redirectRouteId);
377
+ }, [redirectRouteId, routeConfig]);
378
+ React3.useEffect(() => {
379
+ const routeManager = uiConfigurationService.uiManager[PageRouteManagerSymbol];
380
+ const { pendingNavigateOptions } = routeManager;
381
+ if (pendingNavigateOptions) {
382
+ navigate2(pendingNavigateOptions.path, pendingNavigateOptions.options);
383
+ }
384
+ const dispose = routeManager.onWouldRouteChange((to, options) => {
385
+ if (typeof to === "string") {
386
+ navigate2(to, options);
387
+ } else {
388
+ navigate2(to);
389
+ }
390
+ });
391
+ routeManager.initDone();
392
+ return () => {
393
+ dispose.dispose();
394
+ };
395
+ }, []);
396
+ const config = React3.useMemo(
397
+ () => routeConfig.map((item) => /* @__PURE__ */ React.createElement(
398
+ reactRouterDom.Route,
399
+ {
400
+ key: `${item.id}-${item._updateTime}`,
401
+ path: item.path,
402
+ index: item.index,
403
+ element: /* @__PURE__ */ React.createElement(ErrorBoundary, { fallback: item.errorElement ?? /* @__PURE__ */ React.createElement("div", null) }, item.content ? item.content() : item.skeleton?.() ?? null)
404
+ }
405
+ )),
406
+ [routeConfig]
407
+ );
408
+ return /* @__PURE__ */ React.createElement("div", { id: baseRoute.namespace, className: page_route_module_default.root }, /* @__PURE__ */ React.createElement(reactRouterDom.Routes, null, /* @__PURE__ */ React.createElement(reactRouterDom.Route, { element: layout }, config), redirectRoute ? /* @__PURE__ */ React.createElement(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ React.createElement(reactRouterDom.Navigate, { to: redirectRoute.path, replace: true }) }) : null));
409
+ };
410
+ var Repeater = React3.memo((props) => {
411
+ const { mode, children } = props;
412
+ const resolveRef = React3.useRef();
413
+ if (mode === "hidden") {
414
+ React3.startTransition(() => {
415
+ throw new Promise((resolve) => resolveRef.current = resolve);
416
+ });
417
+ }
418
+ if (resolveRef.current) {
419
+ React3.startTransition(() => {
420
+ resolveRef.current?.();
421
+ resolveRef.current = void 0;
422
+ });
423
+ }
424
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
425
+ });
426
+
427
+ // src/feature/page-route/component/keep-alive-outlet/components/offscreen/index.tsx
428
+ var Offscreen = React3.memo((props) => {
429
+ const { mode, children, fallback } = props;
430
+ return /* @__PURE__ */ React.createElement(React3.Suspense, { fallback }, /* @__PURE__ */ React.createElement(Repeater, { mode }, children));
431
+ });
432
+ var isNeedCache = (routesConfig, pathName, updateTime) => {
433
+ for (const route of routesConfig) {
434
+ const isMatch = reactRouterDom.matchPath(route.path, pathName);
435
+ if (isMatch) {
436
+ const needCache = evaluate(route.isNeedCache, false);
437
+ const hasContentRendered = Boolean(evaluate(route.content, null));
438
+ const updated = !updateTime ? true : updateTime === route._updateTime;
439
+ return needCache && hasContentRendered && updated;
440
+ }
441
+ }
442
+ return false;
443
+ };
444
+
445
+ // src/feature/page-route/component/keep-alive-outlet/utils/outlets.ts
446
+ var getValidOutlets = (routesConfig, pathname, outlets) => {
447
+ outlets.forEach((outletData) => {
448
+ const needRefresh = !(outletData.isCacheItem && isNeedCache(routesConfig, outletData.pathname, outletData?.updateTime));
449
+ if (needRefresh) {
450
+ outletData.outlet = null;
451
+ }
452
+ });
453
+ const newOutlets = outlets.filter((item) => item.outlet);
454
+ return newOutlets;
455
+ };
456
+
457
+ // src/feature/page-route/component/keep-alive-outlet/index.tsx
458
+ var OutletWrapper = ({ visible, updateTime, path, children }) => {
459
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
460
+ React3.useEffect(() => {
461
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].notifyPageRendered(path);
462
+ }, [path, visible, updateTime]);
463
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
464
+ };
465
+ function KeepAliveOutlet({ fallback, routesConfig }) {
466
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
467
+ const location = reactRouterDom.useLocation();
468
+ const outlet = reactRouterDom.useOutlet();
469
+ const initRef = React3.useRef(true);
470
+ const handleNotifyActivateRoute = (pathName) => {
471
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].activateKeepAliveRoute(pathName, location.state);
472
+ };
473
+ const calcOutlets = (tempOutlets) => {
474
+ handleNotifyActivateRoute(location.pathname);
475
+ const validTempOutlets = getValidOutlets(routesConfig, location.pathname, tempOutlets);
476
+ let result = validTempOutlets.find((o) => isEqualStr(o.pathname, location.pathname));
477
+ const isCacheItem = isNeedCache(routesConfig, location.pathname);
478
+ const notUpdated = routesConfig.reduce((bool, _config) => {
479
+ if (!bool) {
480
+ return false;
481
+ }
482
+ if (!_config._updateTime) {
483
+ return true;
484
+ }
485
+ return tempOutlets.find((item) => item.pathname === location.pathname)?.updateTime === _config._updateTime;
486
+ }, true);
487
+ if (result && isCacheItem && notUpdated) {
488
+ return validTempOutlets;
489
+ }
490
+ if (!result) {
491
+ const route = uiConfigurationService.uiManager[PageRouteManagerSymbol].getRouteConfigByPath(
492
+ location.pathname
493
+ );
494
+ result = {
495
+ key: location.key,
496
+ pathname: location.pathname,
497
+ updateTime: route?._updateTime,
498
+ isCacheItem,
499
+ outlet
500
+ };
501
+ validTempOutlets.push(result);
502
+ }
503
+ return validTempOutlets;
504
+ };
505
+ const [outlets, setOutlets] = React3.useState(
506
+ // eslint-disable-next-line no-nested-ternary
507
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].pendingNavigateOptions ? [] : initRef.current ? calcOutlets([]) : []
508
+ );
509
+ initRef.current = false;
510
+ React3.useEffect(() => {
511
+ setOutlets(calcOutlets);
512
+ }, [location.pathname, routesConfig]);
513
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, outlets.map((o) => {
514
+ const visibilityMode = isEqualStr(o.pathname, location.pathname) ? "visible" : "hidden";
515
+ return /* @__PURE__ */ React.createElement(Offscreen, { key: o.key, mode: visibilityMode, fallback: fallback || null }, /* @__PURE__ */ React.createElement(
516
+ OutletWrapper,
517
+ {
518
+ updateTime: o.updateTime,
519
+ path: location.pathname,
520
+ visible: visibilityMode === "visible"
521
+ },
522
+ o.outlet
523
+ ));
524
+ }));
525
+ }
526
+ var OutletWrapper2 = ({ visible, updateTime, path, children }) => {
527
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
528
+ React3.useEffect(() => {
529
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].notifyPageRendered(path);
530
+ }, [path, visible, updateTime]);
531
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
532
+ };
533
+ function KeepAliveSingleOutlet({ fallback, routesConfig }) {
534
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
535
+ const location = reactRouterDom.useLocation();
536
+ const outlet = reactRouterDom.useOutlet();
537
+ const handleNotifyActivateRoute = (pathName) => {
538
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].activateKeepAliveRoute(pathName, location.state);
539
+ };
540
+ const calcOutlets = ahooks.useMemoizedFn((tempOutlets) => {
541
+ handleNotifyActivateRoute(location.pathname);
542
+ const validTempOutlets = getValidOutlets(routesConfig, location.pathname, tempOutlets);
543
+ let result = validTempOutlets.find((o) => isEqualStr(o.pathname, location.pathname));
544
+ const isCacheItem = isNeedCache(routesConfig, location.pathname);
545
+ const notUpdated = routesConfig.reduce((bool, _config) => {
546
+ if (!bool) {
547
+ return false;
548
+ }
549
+ if (!_config._updateTime) {
550
+ return true;
551
+ }
552
+ return tempOutlets.find((item) => item.pathname === location.pathname)?.updateTime === _config._updateTime;
553
+ }, true);
554
+ if (result && isCacheItem && notUpdated) {
555
+ return validTempOutlets;
556
+ }
557
+ if (!result) {
558
+ const route = uiConfigurationService.uiManager[PageRouteManagerSymbol].getRouteConfigByPath(
559
+ location.pathname
560
+ );
561
+ result = {
562
+ key: location.key,
563
+ pathname: location.pathname,
564
+ updateTime: route?._updateTime,
565
+ isCacheItem,
566
+ outlet
567
+ };
568
+ validTempOutlets.push(result);
569
+ }
570
+ return validTempOutlets;
571
+ });
572
+ const outlets = React3.useMemo(() => {
573
+ if (uiConfigurationService.uiManager[PageRouteManagerSymbol].pendingNavigateOptions) {
574
+ return [];
575
+ }
576
+ return calcOutlets([]);
577
+ }, [
578
+ uiConfigurationService.uiManager[PageRouteManagerSymbol].pendingNavigateOptions,
579
+ location.pathname,
580
+ routesConfig,
581
+ calcOutlets
582
+ ]);
583
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, outlets.map((o) => {
584
+ const visibilityMode = isEqualStr(o.pathname, location.pathname) ? "visible" : "hidden";
585
+ return /* @__PURE__ */ React.createElement(Offscreen, { key: o.key, mode: visibilityMode, fallback: fallback || null }, /* @__PURE__ */ React.createElement(
586
+ OutletWrapper2,
587
+ {
588
+ updateTime: o.updateTime,
589
+ path: location.pathname,
590
+ visible: visibilityMode === "visible"
591
+ },
592
+ o.outlet
593
+ ));
594
+ }));
595
+ }
596
+
597
+ // src/feature/page-route/page-route-manager.tsx
598
+ var PageRouteManager = class extends BaseUiManager {
599
+ constructor() {
600
+ super(...arguments);
601
+ this.observableData = valtio.proxy({
602
+ currentRoute: void 0,
603
+ configs: [],
604
+ keepAliveStatusMap: {},
605
+ historyRoutes: [],
606
+ containerWidth: 0
607
+ });
608
+ this._locker = new InitAwaitLock();
609
+ this._onWouldRouteChange = new event.Emitter();
610
+ this.onWouldRouteChange = this._onWouldRouteChange.event;
611
+ this._onKeepAliveChange = new event.Emitter();
612
+ this.onKeepAliveChange = this._onKeepAliveChange.event;
613
+ this._onPageRendered = new event.Emitter();
614
+ this.onPageRendered = this._onPageRendered.event;
615
+ this._onPageContainerWidthChange = new event.Emitter();
616
+ this.onPageContainerWidthChange = this._onPageContainerWidthChange.event;
617
+ // fix: 修复个人页刷新打开埋点参数上报错误
618
+ this._onRouteConfigChange = new event.Emitter();
619
+ this.onRouteConfigChange = this._onRouteConfigChange.event;
620
+ }
621
+ get pendingNavigateOptions() {
622
+ return this._pendingNavigateOptions;
623
+ }
624
+ get currentRoute() {
625
+ return this.getRouteConfigByPath(this.observableData.currentRoute);
626
+ }
627
+ registerConfig(configs) {
628
+ configs.forEach((config) => {
629
+ const idx = this.observableData.configs.findIndex((item) => item.id === config.id);
630
+ if (idx !== -1) {
631
+ this.observableData.configs[idx] = lodashEs.merge(this.observableData.configs[idx], config, {
632
+ _updateTime: Date.now()
633
+ });
634
+ } else {
635
+ this.observableData.configs.push(
636
+ lodashEs.merge({}, config, {
637
+ _updateTime: 0
638
+ })
639
+ );
640
+ }
641
+ });
642
+ this._onRouteConfigChange.fire(valtio.snapshot(this.observableData.configs));
643
+ }
644
+ updatePageRoute(path) {
645
+ const routesLength = this.observableData.historyRoutes.length;
646
+ if (this.observableData.historyRoutes[routesLength - 1] !== path) {
647
+ this.observableData.historyRoutes.push(path);
648
+ }
649
+ const preRoute = this.getRouteConfigByPath(this.observableData.currentRoute);
650
+ const setRoute = this.getRouteConfigByPath(path);
651
+ if (preRoute?.id !== setRoute?.id) {
652
+ if (preRoute) {
653
+ preRoute?.onActiveChange?.({ active: false });
654
+ }
655
+ setRoute?.onActiveChange?.({ active: true });
656
+ }
657
+ this.observableData.currentRoute = path;
658
+ }
659
+ navigate(id, options) {
660
+ const path = this.generatePath(id, options);
661
+ if (!path) {
662
+ assert.lvAssert(path);
663
+ }
664
+ const runner = runnerBuilder({
665
+ middleware: this._middlewareManager,
666
+ trigger: PageRouteManagerSymbol,
667
+ method: "shouldInterceptNavigate",
668
+ uiConfig: { id, path }
669
+ });
670
+ const interceptRes = runner.run();
671
+ if (runner.isStop || interceptRes) {
672
+ return;
673
+ }
674
+ this._navigateByPath(path, options);
675
+ }
676
+ _navigateByPath(path, options) {
677
+ if (!this._locker.hasBeenDone) {
678
+ this._pendingNavigateOptions = {
679
+ path,
680
+ options
681
+ };
682
+ } else {
683
+ this._onWouldRouteChange.fire(path, options);
684
+ }
685
+ }
686
+ updateContainerWidth(width) {
687
+ this.observableData.containerWidth = width;
688
+ }
689
+ initDone() {
690
+ if (this._locker.hasBeenDone) {
691
+ return;
692
+ }
693
+ this._pendingNavigateOptions = void 0;
694
+ this._locker.initDone();
695
+ }
696
+ navigateBack(to = -1) {
697
+ this._onWouldRouteChange.fire(to);
698
+ }
699
+ generatePath(id, options) {
700
+ const target = this.observableData.configs.find((item) => item.id === id);
701
+ if (!target) {
702
+ assert.lvAssert(target);
703
+ }
704
+ const compiler = pathToRegexp.compile(target.path);
705
+ let result = compiler(options?.params ?? {});
706
+ const query = typeof options?.query === "string" ? options.query : queryStringify(options?.query ?? {});
707
+ if (query.length !== 0) {
708
+ result += query.includes("?") ? query : `?${query}`;
709
+ }
710
+ return result;
711
+ }
712
+ activateKeepAliveRoute(activatePathName, locationState) {
713
+ if (activatePathName === this.currentKeepAliveData?.pathName && Object.values(this.observableData.keepAliveStatusMap).length > 0) {
714
+ return;
715
+ }
716
+ const allAlivePathName = Object.keys(this.observableData.keepAliveStatusMap);
717
+ for (const alivePathName of allAlivePathName) {
718
+ if (isEqualStr(alivePathName, activatePathName)) {
719
+ continue;
720
+ }
721
+ this._updateKeepAliveStatus(alivePathName, "InActivated" /* InActivated */);
722
+ }
723
+ this._updateKeepAliveStatus(activatePathName, "Activated" /* Activated */, locationState);
724
+ }
725
+ _updateKeepAliveStatus(pathName, status, locationState) {
726
+ const lastStatusVal = this.observableData.keepAliveStatusMap[pathName];
727
+ const lastStatus = lastStatusVal?.status;
728
+ const matchRoteConfig = this.observableData.configs.find((item) => reactRouterDom.matchPath(item.path, pathName));
729
+ const newStatusVal = {
730
+ pathName,
731
+ status,
732
+ routeId: matchRoteConfig?.id ?? "NOT_FOUND",
733
+ locationState
734
+ };
735
+ this.observableData.keepAliveStatusMap[pathName] = newStatusVal;
736
+ if (status !== lastStatus) {
737
+ this._onKeepAliveChange.fire(newStatusVal);
738
+ }
739
+ }
740
+ get currentKeepAliveData() {
741
+ const { keepAliveStatusMap, currentRoute = "" } = this.observableData;
742
+ return Object.values(keepAliveStatusMap).find((item) => item.status === "Activated" /* Activated */);
743
+ }
744
+ notifyPageRendered(config) {
745
+ if (typeof config === "string") {
746
+ const routeConfig = this.getRouteConfigByPath(config);
747
+ this._onPageRendered.fire(routeConfig ? valtio.snapshot(routeConfig) : routeConfig);
748
+ } else {
749
+ this._onPageRendered.fire(config);
750
+ }
751
+ }
752
+ getRouteConfigByPath(path) {
753
+ if (!path) {
754
+ return void 0;
755
+ }
756
+ return this.observableData.configs.find((item) => reactRouterDom.matchPath(item.path, path));
757
+ }
758
+ render(options) {
759
+ return /* @__PURE__ */ React.createElement(PageRoute, { layout: options.layout });
760
+ }
761
+ renderOutlet(options) {
762
+ return /* @__PURE__ */ React.createElement(KeepAliveOutlet, { ...options });
763
+ }
764
+ renderSingleOutlet(options) {
765
+ return /* @__PURE__ */ React.createElement(KeepAliveSingleOutlet, { ...options });
766
+ }
767
+ _middlewareChange(props) {
768
+ }
769
+ };
770
+ var useKeepAliveEffect = (cb) => {
771
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
772
+ const location = reactRouterDom.useLocation();
773
+ const initedLocationPathName = React3.useRef(location.pathname);
774
+ const disposeCb = React3.useRef(null);
775
+ const handleTrggerEffect = (data) => {
776
+ if (!data) {
777
+ return;
778
+ }
779
+ if (data.pathName !== initedLocationPathName.current) {
780
+ return;
781
+ }
782
+ if (data.status === "Activated" /* Activated */) {
783
+ disposeCb.current = cb?.();
784
+ } else {
785
+ disposeCb.current?.();
786
+ }
787
+ };
788
+ React3.useEffect(() => {
789
+ const pageRouteManager = uiConfigurationService.uiManager[PageRouteManagerSymbol];
790
+ handleTrggerEffect(pageRouteManager.currentKeepAliveData);
791
+ const diposeEvent = pageRouteManager.onKeepAliveChange((data) => {
792
+ handleTrggerEffect(data);
793
+ });
794
+ return () => {
795
+ diposeEvent.dispose();
796
+ disposeCb.current?.();
797
+ };
798
+ }, []);
799
+ };
800
+ var useKeepAliveLayoutEffect = (cb) => {
801
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
802
+ const location = reactRouterDom.useLocation();
803
+ const initedLocationPathName = React3.useRef(location.pathname);
804
+ const disposeCb = React3.useRef(null);
805
+ const handleTrggerEffect = (data) => {
806
+ if (!data) {
807
+ return;
808
+ }
809
+ if (data.pathName !== initedLocationPathName.current) {
810
+ return;
811
+ }
812
+ if (data.status === "Activated" /* Activated */) {
813
+ disposeCb.current = cb?.();
814
+ } else {
815
+ disposeCb.current?.();
816
+ }
817
+ };
818
+ React3.useLayoutEffect(() => {
819
+ const pageRouteManager = uiConfigurationService.uiManager[PageRouteManagerSymbol];
820
+ handleTrggerEffect(pageRouteManager.currentKeepAliveData);
821
+ const diposeEvent = pageRouteManager.onKeepAliveChange((data) => {
822
+ handleTrggerEffect(data);
823
+ });
824
+ return () => {
825
+ diposeEvent.dispose();
826
+ disposeCb.current?.();
827
+ };
828
+ }, []);
829
+ };
830
+ var usePageContainerWidth = () => {
831
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
832
+ return useObserverSelector(uiConfigurationService.uiManager[PageRouteManagerSymbol], (manager) => {
833
+ return manager.observableData.containerWidth;
834
+ });
835
+ };
836
+ function navigate(platformUiConfiguration, to, options) {
837
+ const pageRouteManager = platformUiConfiguration.uiManager[PageRouteManagerSymbol];
838
+ switch (true) {
839
+ case (typeof to === "string" || typeof to === "object"):
840
+ if (typeof to === "object") {
841
+ to = reactRouterDom.createPath(to);
842
+ }
843
+ const path = reactRouterDom.parsePath(to);
844
+ const routesConfig = pageRouteManager.observableData.configs;
845
+ const matchItem = routesConfig.find((item) => reactRouterDom.matchPath(item.path, path?.pathname ?? ""));
846
+ if (!matchItem) {
847
+ return;
848
+ }
849
+ const matchRes = Object.entries(reactRouterDom.matchPath(matchItem.path, path?.pathname ?? "")?.params ?? {}).reduce((pre, cur) => {
850
+ const [key, value] = cur;
851
+ if (!key || !value) {
852
+ return pre;
853
+ }
854
+ pre[key] = value;
855
+ return pre;
856
+ }, {});
857
+ pageRouteManager.navigate(matchItem.id, {
858
+ query: path.search,
859
+ params: matchRes,
860
+ ...options
861
+ });
862
+ break;
863
+ case typeof to === "number":
864
+ pageRouteManager.navigateBack(to);
865
+ break;
866
+ }
867
+ }
868
+ var useNavigateFactory = (uiConfigurationService) => {
869
+ const useNavigate2 = ahooks.useMemoizedFn((to, options) => {
870
+ navigate(uiConfigurationService, to, options);
871
+ });
872
+ return useNavigate2;
873
+ };
874
+
875
+ // src/feature/block-content/block-content-manager.interface.ts
876
+ var BlockContentManagerSymbol = "BlockContent";
877
+
878
+ // src/feature/block-content/component/block-content.module.scss
879
+ var block_content_module_default = {};
880
+
881
+ // src/feature/block-content/component/block-content.tsx
882
+ var BlockContentComponent = React3__default.default.memo(() => {
883
+ const { uiConfigurationService } = React3.useContext(GlobalContext);
884
+ const activeBlockContentConfig = useObserverSelector(
885
+ uiConfigurationService.uiManager[BlockContentManagerSymbol],
886
+ (manager) => {
887
+ const { activeId, configs } = manager.observableData;
888
+ return configs.find((item) => item.id === activeId);
889
+ }
890
+ );
891
+ const containerRef = React3.useRef(null);
892
+ return /* @__PURE__ */ React3__default.default.createElement(
893
+ "div",
894
+ {
895
+ ref: containerRef,
896
+ className: cs__default.default(block_content_module_default.container, evaluate(activeBlockContentConfig?.className, ""))
897
+ },
898
+ evaluate(activeBlockContentConfig?.content, null)
899
+ );
900
+ });
901
+ var BlockContent = BlockContentComponent;
902
+
903
+ // src/feature/block-content/block-content-manager.tsx
904
+ var BlockContentManager = class extends BaseUiManager {
905
+ constructor() {
906
+ super(...arguments);
907
+ this.observableData = valtio.proxy({
908
+ forceUpdate: 0,
909
+ activeId: void 0,
910
+ configs: []
911
+ });
912
+ }
913
+ registerConfig(configs) {
914
+ configs.forEach((config) => {
915
+ const idx = this.observableData.configs.findIndex((item) => item.id === config.id);
916
+ if (idx !== -1) {
917
+ this.observableData.configs[idx] = lodashEs.merge(this.observableData.configs[idx], config);
918
+ } else {
919
+ assert.lvAssertNotNil(
920
+ config.id,
921
+ `The "id" attribute is required when registering "UiManagerName.BlockContent"`
922
+ );
923
+ this.observableData.configs.push(config);
924
+ }
925
+ });
926
+ if (!(this.observableData.activeId && this.observableData.configs.find((item) => item.id === this.observableData.activeId))) {
927
+ this.observableData.activeId = this.observableData.configs[0]?.id;
928
+ }
929
+ }
930
+ changeActiveId(activeId) {
931
+ this.observableData.activeId = activeId;
932
+ }
933
+ render() {
934
+ return /* @__PURE__ */ React.createElement(BlockContent, null);
935
+ }
936
+ _middlewareChange() {
937
+ this.observableData.forceUpdate++;
938
+ }
939
+ };
940
+
941
+ Object.defineProperty(exports, "Navigate", {
942
+ enumerable: true,
943
+ get: function () { return reactRouterDom.Navigate; }
944
+ });
945
+ Object.defineProperty(exports, "matchPath", {
946
+ enumerable: true,
947
+ get: function () { return reactRouterDom.matchPath; }
948
+ });
949
+ Object.defineProperty(exports, "parsePath", {
950
+ enumerable: true,
951
+ get: function () { return reactRouterDom.parsePath; }
952
+ });
953
+ Object.defineProperty(exports, "resolvePath", {
954
+ enumerable: true,
955
+ get: function () { return reactRouterDom.resolvePath; }
956
+ });
957
+ Object.defineProperty(exports, "useLocation", {
958
+ enumerable: true,
959
+ get: function () { return reactRouterDom.useLocation; }
960
+ });
961
+ Object.defineProperty(exports, "useSearchParams", {
962
+ enumerable: true,
963
+ get: function () { return reactRouterDom.useSearchParams; }
964
+ });
965
+ exports.BaseSetting = BaseSetting;
966
+ exports.BaseUiManager = BaseUiManager;
967
+ exports.BlockContentManager = BlockContentManager;
968
+ exports.BlockContentManagerSymbol = BlockContentManagerSymbol;
969
+ exports.GlobalContext = GlobalContext;
970
+ exports.KeepAliveStatus = KeepAliveStatus;
971
+ exports.MiddlewareManager = MiddlewareManager;
972
+ exports.OrderLevel = OrderLevel;
973
+ exports.PageRouteManager = PageRouteManager;
974
+ exports.PageRouteManagerSymbol = PageRouteManagerSymbol;
975
+ exports.evaluate = evaluate;
976
+ exports.mergeUiConfigs = mergeUiConfigs;
977
+ exports.runnerBuilder = runnerBuilder;
978
+ exports.sortListBySettings = sortListBySettings;
979
+ exports.useKeepAliveEffect = useKeepAliveEffect;
980
+ exports.useKeepAliveLayoutEffect = useKeepAliveLayoutEffect;
981
+ exports.useNavigateFactory = useNavigateFactory;
982
+ exports.usePageContainerWidth = usePageContainerWidth;
983
+ //# sourceMappingURL=index.cjs.map
984
+ //# sourceMappingURL=index.cjs.map