@pubinfo/core 2.0.0-rc.4 → 2.0.0-rc.5

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.
Files changed (75) hide show
  1. package/dist/{AppSetting-BI-oNc4e.js → AppSetting-DqVYDIHj.js} +15 -15
  2. package/dist/{HCheckList.vue_vue_type_script_setup_true_lang-BdLpkcoh.js → HCheckList.vue_vue_type_script_setup_true_lang-SrNklW3P.js} +1 -1
  3. package/dist/{HToggle-DxdWLgp-.js → HToggle-DGTP9jYA.js} +1 -1
  4. package/dist/{PreferencesContent-CCYkZeCT.js → PreferencesContent-5NtwK9RQ.js} +4 -4
  5. package/dist/{SettingBreadcrumb-BTyfiy4k.js → SettingBreadcrumb-BudqQsuJ.js} +3 -3
  6. package/dist/{SettingCopyright-g6UHi8pZ.js → SettingCopyright-VUberG4R.js} +2 -2
  7. package/dist/{SettingEnableTransition-Ci-5bhbR.js → SettingEnableTransition-C6NYf021.js} +2 -2
  8. package/dist/SettingHome-BTaeKgwN.js +46 -0
  9. package/dist/{SettingMenu-BYLWzA5i.js → SettingMenu-D9Aon2LP.js} +3 -3
  10. package/dist/{SettingMode-tRisyKtg.js → SettingMode-DaqVd9Mq.js} +1 -1
  11. package/dist/{SettingNavSearch-CSM6mPf8.js → SettingNavSearch-N4JIheIk.js} +2 -2
  12. package/dist/{SettingOther-Bj5KF_vC.js → SettingOther-tLulcors.js} +2 -2
  13. package/dist/{SettingPage-CFjmrVI7.js → SettingPage-CEjWB45R.js} +2 -2
  14. package/dist/{SettingTabbar-uFYiaZhK.js → SettingTabbar-DyeLhcCT.js} +3 -3
  15. package/dist/{SettingThemes-C-tMq9o5.js → SettingThemes-C2M3tsVl.js} +1 -1
  16. package/dist/{SettingToolbar-BfDzijNU.js → SettingToolbar-DI7de6i0.js} +24 -31
  17. package/dist/{SettingTopbar-DTDv4NXD.js → SettingTopbar-BgIoXeAq.js} +3 -3
  18. package/dist/{SettingWidthMode-PkiwrHe3.js → SettingWidthMode-DIAU4s5e.js} +1 -1
  19. package/dist/{TopThinMode-BrvA8pV0.js → TopThinMode-JNUHrJI2.js} +1 -1
  20. package/dist/built-in/index.d.ts +1 -0
  21. package/dist/built-in/layout-component/components/Tools/SearchPanel.vue.d.ts +7 -2
  22. package/dist/built-in/layout-component/composables/useGlobalSearch.d.ts +7 -0
  23. package/dist/built-in/system-info/components/SystemInfo.vue.d.ts +2 -0
  24. package/dist/built-in/system-info/index.d.ts +5 -0
  25. package/dist/{colors-VoaDbOhe.js → colors-DxWfHM_v.js} +1 -1
  26. package/dist/features/components/PubinfoIcon/PrismBox.vue.d.ts +21 -0
  27. package/dist/features/components/PubinfoIcon/SquareBox.vue.d.ts +17 -0
  28. package/dist/features/components/PubinfoIcon/index.vue.d.ts +13 -9
  29. package/dist/features/components/PubinfoIcon/props.d.ts +58 -0
  30. package/dist/features/components/index.d.ts +2 -0
  31. package/dist/{index-BfGqLWFB.js → index-5fRpGyLW.js} +4 -4
  32. package/dist/{index-ConeY38N.js → index-BFRIv97x.js} +2 -2
  33. package/dist/{index-Dv9ndBoi.js → index-BH-vHGvk.js} +1 -1
  34. package/dist/{index-BSevJVD5.js → index-C7xIGcDc.js} +2 -2
  35. package/dist/{index-CYoFRwvw.js → index-CNVn3Ubv.js} +2 -2
  36. package/dist/{index-DV3hkzKA.js → index-Cf-u1Zqh.js} +1 -1
  37. package/dist/{index-Ddw98rJ5.js → index-D4v4g8FJ.js} +112 -98
  38. package/dist/{index-DrC787X_.js → index-DQGnbEGS.js} +2 -2
  39. package/dist/{index-IAYhIBQH.js → index-Dv7UUFkD.js} +23446 -23082
  40. package/dist/index.d.ts +1 -1
  41. package/dist/index.js +55 -48
  42. package/dist/{pick-vpv9EEvu.js → pick-VFuUwFn-.js} +1 -1
  43. package/dist/style.css +1 -1
  44. package/dist/utils/global.d.ts +33 -0
  45. package/dist/utils/index.d.ts +2 -1
  46. package/package.json +8 -5
  47. package/src/built-in/index.ts +1 -0
  48. package/src/built-in/layout-component/components/Header/TopMode/index.vue +27 -6
  49. package/src/built-in/layout-component/components/Menu/item.vue +41 -6
  50. package/src/built-in/layout-component/components/SettingBar/components/SettingHome.vue +1 -4
  51. package/src/built-in/layout-component/components/SettingBar/components/SettingToolbar.vue +0 -6
  52. package/src/built-in/layout-component/components/Tools/SearchPanel.vue +113 -37
  53. package/src/built-in/layout-component/components/Tools/index.vue +1 -1
  54. package/src/built-in/layout-component/components/Topbar/Tabbar/MoreAction.vue +58 -2
  55. package/src/built-in/layout-component/components/Topbar/Tabbar/index.vue +64 -6
  56. package/src/built-in/layout-component/composables/useGlobalSearch.ts +40 -1
  57. package/src/built-in/system-info/components/SystemInfo.vue +53 -0
  58. package/src/built-in/system-info/index.ts +16 -0
  59. package/src/core/ctx.ts +7 -1
  60. package/src/core/resolver/icon.ts +9 -5
  61. package/src/features/components/PubinfoIcon/PrismBox.vue +203 -0
  62. package/src/features/components/PubinfoIcon/SquareBox.vue +59 -0
  63. package/src/features/components/PubinfoIcon/index.vue +128 -37
  64. package/src/features/components/PubinfoIcon/props.ts +54 -0
  65. package/src/features/components/index.ts +4 -1
  66. package/src/features/context/index.ts +1 -16
  67. package/src/features/settings/index.ts +0 -1
  68. package/src/index.ts +7 -0
  69. package/src/utils/global.ts +161 -0
  70. package/src/utils/index.ts +2 -1
  71. package/src/utils/proxy.ts +7 -8
  72. package/types/global.d.ts +7 -0
  73. package/types/menu.d.ts +10 -0
  74. package/types/settings.d.ts +0 -7
  75. package/dist/SettingHome-K4Iel0Hr.js +0 -55
@@ -0,0 +1,54 @@
1
+ /**
2
+ * 不带盒子外观的图标配置。
3
+ * 当未显式设置 `box` 时将使用该形状;并且此时不允许传入 `background` / `radius`。
4
+ */
5
+ export interface PubinfoIconNotBoxOptions {
6
+ /** 图标名称 */
7
+ name: string
8
+ /** 是否异步加载 */
9
+ async?: boolean
10
+ /** 翻转方向 */
11
+ flip?: 'horizontal' | 'vertical' | 'both'
12
+ /** 旋转角度 */
13
+ rotate?: number
14
+ /** 颜色 */
15
+ color?: string
16
+ /** 尺寸 */
17
+ size?: string | number
18
+ }
19
+
20
+ /**
21
+ * 带盒子外观的图标配置。判定条件:存在 `box` 字段。
22
+ * 这里将 `box` 设为必填,用作判别式属性。
23
+ */
24
+ export interface PubinfoIconBoxOptions extends PubinfoIconNotBoxOptions {
25
+ /** 盒子类型(存在该字段即可触发 Box 选项) */
26
+ box: 'square' | 'prism'
27
+ /** 背景:纯色或渐变 */
28
+ background?: string | {
29
+ from: string
30
+ to: string
31
+ }
32
+ /** 圆角 */
33
+ radius?: number | string
34
+ /** 背景渐变的角度 */
35
+ angle?: number | string
36
+ /** 是否是小 logo */
37
+ small?: boolean
38
+ }
39
+
40
+ /**
41
+ * 根据是否提供 `box` 自动区分两类配置:
42
+ * - 未提供 `box`:禁止出现 `background` 与 `radius`(否则 TS 报错)
43
+ * - 提供 `box`:允许使用盒子相关属性
44
+ */
45
+ export type PubinfoIconOptions
46
+ = | PubinfoIconBoxOptions
47
+ | (PubinfoIconNotBoxOptions & { box?: undefined, background?: never, radius?: never, angle?: never, small?: false });
48
+
49
+ /**
50
+ * 可用于泛型推断的条件类型:传入的对象类型若含有 `box` 字段,则推断为 Box 版本,否则为普通版本。
51
+ * 一般情况下直接使用 `PubinfoIconOptions` 联合类型即可。
52
+ */
53
+ export type InferPubinfoIconOptions<T extends { box?: any } | undefined>
54
+ = T extends { box: PubinfoIconBoxOptions['box'] } ? PubinfoIconBoxOptions : PubinfoIconNotBoxOptions;
@@ -4,5 +4,8 @@ export { default as PageMain } from './PageMain/index.vue';
4
4
  export { default as PassStrengthValidator } from './PassStrengthValidator/index.vue';
5
5
  export { default as PubinfoApp } from './PubinfoApp/index.vue';
6
6
  export { default as PubinfoIcon } from './PubinfoIcon/index.vue';
7
+ export { default as PubinfoIconPrismBox } from './PubinfoIcon/PrismBox.vue';
8
+ export { default as PubinfoIconSquareBox } from './PubinfoIcon/SquareBox.vue';
7
9
  export { default as PubinfoProvider } from './PubinfoProvider';
8
- export { createPubinfoProvider, pubinfoInjectionKey } from './PubinfoProvider';
10
+
11
+ export { createPubinfoProvider, pubinfoInjectionKey } from './PubinfoProvider'; ;
@@ -9,26 +9,11 @@ interface InternalContext {
9
9
  requestBasic: RequestInstance
10
10
  }
11
11
 
12
- // 持久化全局上下文,支持 HMR 后恢复
13
- const g = globalThis as any;
14
- g.__PUBINFO__ = g.__PUBINFO__ || {};
15
- if (!g.__PUBINFO__.ctx) {
16
- g.__PUBINFO__.ctx = createContext<InternalContext>();
17
- }
18
- const ctx = g.__PUBINFO__.ctx as ReturnType<typeof createContext<InternalContext>>;
19
-
20
- // 旧 state 恢复
21
- if (g.__PUBINFO__.state) {
22
- try {
23
- ctx.set(g.__PUBINFO__.state);
24
- }
25
- catch {}
26
- }
12
+ const ctx = createContext<InternalContext>('ctx', { stateKey: 'state' });
27
13
 
28
14
  /** 初始化全局 context */
29
15
  export function createPubinfoContext(newState: InternalContext) {
30
16
  // 缓存用于 wrapProxy 兜底
31
- g.__PUBINFO__.state = newState;
32
17
  ctx.set(newState);
33
18
  // 立即激活 use()
34
19
  ctx.use();
@@ -52,7 +52,6 @@ let globalSettings: RequiredDeep<Settings.all> = {
52
52
  },
53
53
  toolbar: {
54
54
  enableNotification: true,
55
- enableI18n: true,
56
55
  enableFullscreen: true,
57
56
  enablePageReload: true,
58
57
  enableColorScheme: true,
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  PiniaPlugin,
8
8
  PreAccess,
9
9
  Settings,
10
+ SystemInfo,
10
11
  } from './built-in';
11
12
  import { createApp } from './core';
12
13
  import { createPubinfoContext } from './features/context/index.ts';
@@ -71,6 +72,7 @@ export function createPubinfo(options: PubinfoOptions) {
71
72
  LayoutComponent(),
72
73
  Settings(),
73
74
  NProgress(),
75
+ SystemInfo(),
74
76
  ...(options.modules ?? []),
75
77
  ],
76
78
  });
@@ -107,7 +109,12 @@ export * from './features';
107
109
  export {
108
110
  cleanup,
109
111
  cleanupWithoutUser,
112
+ clearPersistedState,
110
113
  createContext,
114
+ createRawContext,
115
+ getPersistedState,
116
+ getPubinfoNamespace,
117
+ setPersistedState,
111
118
  storage,
112
119
  wrapProxy,
113
120
  } from './utils';
@@ -0,0 +1,161 @@
1
+ import type { UseContext } from 'unctx';
2
+ import { createContext as createRawContext } from 'unctx';
3
+
4
+ type PubinfoNamespace = Record<string, unknown>;
5
+
6
+ function ensureNamespace(): PubinfoNamespace {
7
+ const g = globalThis as typeof globalThis & { __PUBINFO__?: PubinfoNamespace };
8
+ if (!g.__PUBINFO__) {
9
+ g.__PUBINFO__ = {};
10
+ }
11
+ return g.__PUBINFO__;
12
+ }
13
+
14
+ /**
15
+ * Return the shared __PUBINFO__ namespace, creating it if necessary.
16
+ */
17
+ export function getPubinfoNamespace(): PubinfoNamespace {
18
+ return ensureNamespace();
19
+ }
20
+
21
+ interface PersistedContextOptions {
22
+ /**
23
+ * Optional key used to hydrate persisted state.
24
+ * Defaults to transforming `FooCtx` into `FooState`.
25
+ */
26
+ stateKey?: string
27
+ /**
28
+ * Toggle hydration behaviour. Enabled by default.
29
+ */
30
+ hydrate?: boolean
31
+ /**
32
+ * Automatically persist whenever ctx.set() is called.
33
+ */
34
+ persistOnSet?: boolean
35
+ }
36
+
37
+ /**
38
+ * Create (or reuse) a context stored on the global namespace and
39
+ * hydrate it from a persisted state if available.
40
+ */
41
+ export function createContext<T>(
42
+ contextKey: string,
43
+ options: PersistedContextOptions = {},
44
+ ): UseContext<T> {
45
+ const namespace = ensureNamespace();
46
+
47
+ const normalized = normalizeKeys(contextKey, options.stateKey);
48
+
49
+ if (!namespace[normalized.contextKey]) {
50
+ const existing = normalized.aliasKey ? namespace[normalized.aliasKey] : undefined;
51
+ namespace[normalized.contextKey] = (existing as UseContext<T> | undefined) ?? createRawContext<T>();
52
+ }
53
+
54
+ const ctx = namespace[normalized.contextKey] as UseContext<T> & { __pubinfo_persisted?: boolean };
55
+
56
+ if (normalized.aliasKey) {
57
+ namespace[normalized.aliasKey] = ctx;
58
+ }
59
+
60
+ const { hydrate = true, persistOnSet = true } = options;
61
+ const hydrateKey = normalized.stateKey;
62
+
63
+ if (hydrateKey && persistOnSet && !ctx.__pubinfo_persisted) {
64
+ const originalSet = ctx.set.bind(ctx);
65
+ const originalUnset = ctx.unset.bind(ctx);
66
+
67
+ ctx.set = (instance?: T, replace?: boolean) => {
68
+ originalSet(instance, replace);
69
+ if (instance !== undefined) {
70
+ setPersistedState(hydrateKey, instance);
71
+ }
72
+ else {
73
+ clearPersistedState(hydrateKey);
74
+ }
75
+ };
76
+
77
+ ctx.unset = () => {
78
+ clearPersistedState(hydrateKey);
79
+ originalUnset();
80
+ };
81
+
82
+ ctx.__pubinfo_persisted = true;
83
+ }
84
+
85
+ if (hydrate && hydrateKey) {
86
+ const savedState = namespace[hydrateKey];
87
+ if (savedState !== undefined) {
88
+ try {
89
+ ctx.set(savedState as T);
90
+ }
91
+ catch {
92
+ // ignore hydration failures; callers can recover manually
93
+ }
94
+ }
95
+ }
96
+
97
+ return ctx;
98
+ }
99
+
100
+ /** Persist a value inside the __PUBINFO__ namespace. */
101
+ export function setPersistedState<T>(stateKey: string, state: T) {
102
+ const namespace = ensureNamespace();
103
+ namespace[stateKey] = state;
104
+ }
105
+
106
+ /** Retrieve a value from the __PUBINFO__ namespace. */
107
+ export function getPersistedState<T>(stateKey: string): T | undefined {
108
+ const namespace = ensureNamespace();
109
+ return namespace[stateKey] as T | undefined;
110
+ }
111
+
112
+ /** Remove a value from the __PUBINFO__ namespace. */
113
+ export function clearPersistedState(stateKey: string) {
114
+ const namespace = ensureNamespace();
115
+ if (stateKey in namespace) {
116
+ delete namespace[stateKey];
117
+ }
118
+ }
119
+
120
+ interface NormalizedKeys {
121
+ contextKey: string
122
+ stateKey?: string
123
+ aliasKey?: string
124
+ }
125
+
126
+ function normalizeKeys(contextKey: string, explicitStateKey?: string): NormalizedKeys {
127
+ if (explicitStateKey) {
128
+ return { contextKey, stateKey: explicitStateKey };
129
+ }
130
+
131
+ if (contextKey.endsWith('Ctx')) {
132
+ const base = contextKey.slice(0, -3);
133
+ return {
134
+ contextKey,
135
+ stateKey: base ? `${base}State` : undefined,
136
+ };
137
+ }
138
+
139
+ if (contextKey.endsWith('Context')) {
140
+ const base = contextKey.slice(0, -7);
141
+ if (base) {
142
+ return {
143
+ contextKey: `${base}Ctx`,
144
+ stateKey: `${base}State`,
145
+ aliasKey: contextKey,
146
+ };
147
+ }
148
+ }
149
+
150
+ const base = contextKey;
151
+ if (!base) {
152
+ return { contextKey, stateKey: undefined };
153
+ }
154
+
155
+ const normalizedContextKey = `${base}Ctx`;
156
+ return {
157
+ contextKey: normalizedContextKey,
158
+ stateKey: `${base}State`,
159
+ aliasKey: normalizedContextKey !== contextKey ? contextKey : undefined,
160
+ };
161
+ }
@@ -1,5 +1,6 @@
1
1
  export * from './cleanup';
2
+ export * from './global';
2
3
  export * from './path';
3
4
  export * from './proxy';
4
5
  export * from './storage';
5
- export { createContext } from 'unctx';
6
+ export { createContext as createRawContext } from 'unctx';
@@ -1,3 +1,5 @@
1
+ import { getPersistedState } from './global';
2
+
1
3
  export function wrapProxy<T extends Record<K, any>, K extends keyof T>(
2
4
  fn: () => T,
3
5
  key: K,
@@ -10,14 +12,11 @@ export function wrapProxy<T extends Record<K, any>, K extends keyof T>(
10
12
  }
11
13
  catch (e) {
12
14
  // 1. 从全局缓存读取
13
- const g: any = globalThis as any;
14
- if (g.__PUBINFO__?.state) {
15
- const cached = g.__PUBINFO__.state as T;
16
- if (cached && cached[key]) {
17
- const inst = cached[key];
18
- const val = (inst as any)[prop];
19
- return typeof val === 'function' ? val.bind(inst) : val;
20
- }
15
+ const cached = getPersistedState<T>('state');
16
+ if (cached && cached[key]) {
17
+ const inst = cached[key];
18
+ const val = (inst as any)[prop];
19
+ return typeof val === 'function' ? val.bind(inst) : val;
21
20
  }
22
21
  throw e;
23
22
  }
@@ -0,0 +1,7 @@
1
+ declare const __SYSTEM_INFO__: {
2
+ pkg: {
3
+ dependencies: Record<string, string>
4
+ devDependencies: Record<string, string>
5
+ }
6
+ buildTime: string
7
+ };
package/types/menu.d.ts CHANGED
@@ -24,6 +24,16 @@ export declare namespace Menu {
24
24
  icon?: string
25
25
  activeIcon?: string
26
26
  auth?: string | string[]
27
+ iconOptions?: {
28
+ angle?: number | string
29
+ background?: string | {
30
+ from: string
31
+ to: string
32
+ }
33
+ boxType?: 'square' | 'prism'
34
+ iconColor?: string
35
+ radius?: number | string
36
+ }
27
37
  sidebar?: boolean
28
38
  isDev?: boolean
29
39
  devText?: string
@@ -314,13 +314,6 @@ declare namespace Settings {
314
314
  */
315
315
  enableNotification?: boolean
316
316
 
317
- /**
318
- * 是否开启国际化
319
- *
320
- * @默认值 `true`
321
- */
322
- enableI18n?: boolean
323
-
324
317
  /**
325
318
  * 是否开启全屏
326
319
  *
@@ -1,55 +0,0 @@
1
- import { _ as f } from "./HDivider.vue_vue_type_script_setup_true_lang-DIHR-9Yv.js";
2
- import { _ as b } from "./HInput.vue_vue_type_script_setup_true_lang-DBqCXRnn.js";
3
- import { _ as g } from "./HToggle-DxdWLgp-.js";
4
- import { bL as V, bN as x } from "./index-IAYhIBQH.js";
5
- import { defineComponent as H, toRefs as v, createBlock as N, openBlock as C, withCtx as i, createElementVNode as s, createVNode as o, createTextVNode as a, unref as t } from "vue";
6
- import { R as _ } from "./question-line-CfkciTFq.js";
7
- const R = { class: "setting-item" }, S = { class: "label" }, T = { class: "setting-item" }, $ = { class: "label" }, Q = /* @__PURE__ */ H({
8
- name: "SettingHome",
9
- __name: "SettingHome",
10
- setup(k) {
11
- const { settingsStore: d } = V(), { home: n, toolbar: r } = v(d.settings);
12
- return (B, e) => {
13
- const m = x, p = g, u = b, c = f;
14
- return C(), N(c, { title: "主页" }, {
15
- default: i(() => [
16
- s("div", R, [
17
- s("div", S, [
18
- e[2] || (e[2] = a(" 是否启用 ")),
19
- o(m, { text: "该功能开启时,登录成功默认进入主页,反之则默认进入导航栏里第一个导航页面" }, {
20
- default: i(() => [
21
- o(t(_))
22
- ]),
23
- _: 1
24
- })
25
- ]),
26
- o(p, {
27
- modelValue: t(n).enable,
28
- "onUpdate:modelValue": e[0] || (e[0] = (l) => t(n).enable = l)
29
- }, null, 8, ["modelValue"])
30
- ]),
31
- s("div", T, [
32
- s("div", $, [
33
- e[3] || (e[3] = a(" 主页名称 ")),
34
- o(m, { text: "开启国际化时,该设置无效" }, {
35
- default: i(() => [
36
- o(t(_))
37
- ]),
38
- _: 1
39
- })
40
- ]),
41
- o(u, {
42
- modelValue: t(n).title,
43
- "onUpdate:modelValue": e[1] || (e[1] = (l) => t(n).title = l),
44
- disabled: t(r).enableI18n
45
- }, null, 8, ["modelValue", "disabled"])
46
- ])
47
- ]),
48
- _: 1
49
- });
50
- };
51
- }
52
- });
53
- export {
54
- Q as default
55
- };