@tsingroc/tsingroc-components 5.0.0-alpha.21 → 5.0.0-alpha.22

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 (41) hide show
  1. package/dist/components/Calendar.js +8 -4
  2. package/dist/components/ECharts.d.ts +1 -1
  3. package/dist/components/Header.d.ts +1 -1
  4. package/dist/components/Header.js +3 -1
  5. package/dist/components/LineChartEditor.js +3 -3
  6. package/dist/components/LineChartTable.js +319 -123
  7. package/dist/components/LinkedLineChart.js +3 -3
  8. package/dist/components/QuickDateRangePicker.d.ts +1 -1
  9. package/dist/components/QuickDateRangePicker.js +2 -3
  10. package/dist/components/Sidebar.d.ts +1 -1
  11. package/dist/components/Sidebar.js +4 -5
  12. package/dist/components/TsingrocDatePicker.d.ts +2 -2
  13. package/dist/components/TsingrocDatePicker.js +6 -7
  14. package/dist/components/UserButton.d.ts +1 -1
  15. package/dist/components/UserButton.js +24 -18
  16. package/dist/components/WeatherMap.js +1 -1
  17. package/dist/components/auth/AuthProvider.d.ts +29 -0
  18. package/dist/components/auth/AuthProvider.js +138 -0
  19. package/dist/components/auth/AuthService.d.ts +30 -0
  20. package/dist/components/auth/AuthService.js +1 -0
  21. package/dist/components/auth/CasdoorAuth.d.ts +135 -0
  22. package/dist/components/auth/CasdoorAuth.js +156 -0
  23. package/dist/components/auth/EmbeddedAuth.d.ts +16 -0
  24. package/dist/components/auth/EmbeddedAuth.js +53 -0
  25. package/dist/components/auth/Fetcher.d.ts +30 -0
  26. package/dist/components/auth/Fetcher.js +132 -0
  27. package/dist/components/auth/LocalAuth.d.ts +70 -0
  28. package/dist/components/auth/LocalAuth.js +84 -0
  29. package/dist/components/auth/LoginCheck.d.ts +13 -0
  30. package/dist/components/auth/LoginCheck.js +54 -0
  31. package/dist/components/auth/SessionStore.d.ts +68 -0
  32. package/dist/components/auth/SessionStore.js +193 -0
  33. package/dist/deckgl/TiandituLayer.d.ts +1 -1
  34. package/dist/deckgl/TiandituLayer.js +1 -1
  35. package/dist/deckgl/WeatherData.d.ts +1 -1
  36. package/dist/echarts/series/maxBarSeries.d.ts +1 -1
  37. package/dist/index.d.ts +8 -1
  38. package/dist/index.js +7 -1
  39. package/package.json +34 -50
  40. package/dist/components/Auth.d.ts +0 -314
  41. package/dist/components/Auth.js +0 -296
@@ -0,0 +1,193 @@
1
+ export class SessionStore {
2
+ #service;
3
+ #persistent;
4
+ #persistentKey;
5
+ #revalidateInterval;
6
+ #session = null;
7
+ #operation = null;
8
+ get service() {
9
+ return this.#service;
10
+ }
11
+ get session() {
12
+ return this.#session;
13
+ }
14
+ constructor(service, options = {}) {
15
+ this.#service = service;
16
+ const {
17
+ persistent = true,
18
+ persistentKey = "access_token",
19
+ revalidateInterval = 0
20
+ } = options;
21
+ this.#persistent = persistent;
22
+ this.#persistentKey = persistentKey;
23
+ this.#revalidateInterval = revalidateInterval;
24
+ if (persistent) {
25
+ const token = localStorage.getItem(persistentKey);
26
+ if (token !== null) {
27
+ void this.load(token).catch(() => localStorage.removeItem(persistentKey));
28
+ }
29
+ }
30
+ const revalidate = this.revalidate.bind(this);
31
+ if (options.revalidateOnFocus) {
32
+ window.addEventListener("focus", revalidate);
33
+ }
34
+ if (options.revalidateOnReconnect) {
35
+ window.addEventListener("online", revalidate);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * 获取会话。
41
+ *
42
+ * 如果当前已经有会话,那么直接返回会话。
43
+ * 如果当前没有会话,那么获取一个新的会话(通常是登录),失败时抛出异常。
44
+ * 返回的 Promise 可能永远不会 resolve,也可能立即 resolve。
45
+ */
46
+ get() {
47
+ if (this.#session) return Promise.resolve(this.#session);
48
+ if (this.#operation) return this.#operation.promise;
49
+ let cancelled = false;
50
+ const promise = this.#service.getSession().catch(err => {
51
+ this.#updateAndNotify(null, {
52
+ type: "failed",
53
+ reason: err
54
+ });
55
+ throw err;
56
+ }).then(state => {
57
+ if (cancelled) throw new Error("操作被新操作取消");
58
+ return this.load(state);
59
+ });
60
+ const cancel = () => cancelled = true;
61
+ this.#operation = {
62
+ promise,
63
+ cancel
64
+ };
65
+ return promise;
66
+ }
67
+
68
+ /** 加载并验证一个外部的会话状态。有效时更新并返回 Session,无效时抛出异常。 */
69
+ load(state) {
70
+ if (this.#operation) this.#operation.cancel();
71
+ let cancelled = false;
72
+ const promise = this.#validate(state).catch(err => {
73
+ this.#updateAndNotify(null, {
74
+ type: "failed",
75
+ reason: err
76
+ });
77
+ throw err;
78
+ }).then(session => {
79
+ if (cancelled) throw new Error("操作被新操作取消");
80
+ this.#updateAndNotify(session, {
81
+ type: "validated",
82
+ session
83
+ });
84
+ return session;
85
+ });
86
+ const cancel = () => cancelled = true;
87
+ this.#operation = {
88
+ promise,
89
+ cancel
90
+ };
91
+ return promise;
92
+ }
93
+
94
+ /** 在线验证当前保存的会话是否有效。有效时返回 Session,无效或无会话时清除状态并抛出异常。 */
95
+ validate() {
96
+ if (this.#operation) return this.#operation.promise;
97
+ if (!this.#session) return Promise.reject(new Error("当前无会话!"));
98
+ clearTimeout(this.#revalidateTask);
99
+ const session = this.#session;
100
+ let cancelled = false;
101
+ const promise = this.#validate(session.state).catch(err => {
102
+ this.#updateAndNotify(null, {
103
+ type: "invalidated",
104
+ reason: err
105
+ });
106
+ throw err;
107
+ }).then(session => {
108
+ if (cancelled) throw new Error("操作被新操作取消");
109
+ this.#updateAndNotify(session, {
110
+ type: "revalidated",
111
+ session
112
+ });
113
+ this.#updateRevalidateTask();
114
+ return session;
115
+ });
116
+ const cancel = () => cancelled = true;
117
+ this.#operation = {
118
+ promise,
119
+ cancel
120
+ };
121
+ return promise;
122
+ }
123
+
124
+ /** 在线验证当前保存的会话是否有效。无效时清除状态,有效或无会话时不做任何操作。返回会话是否有效。 */
125
+ async revalidate() {
126
+ try {
127
+ void (await this.validate());
128
+ return true;
129
+ } catch {
130
+ return false;
131
+ }
132
+ }
133
+
134
+ /** 立即结束会话并清除状态。如果当前无会话则不做任何操作。 */
135
+ async clear() {
136
+ if (this.#operation) this.#operation.cancel();
137
+ if (this.#session) {
138
+ await this.#service.endSession?.(this.#session.state);
139
+ this.#updateAndNotify(null, {
140
+ type: "invalidated",
141
+ reason: "用户已登出"
142
+ });
143
+ }
144
+ }
145
+ addEventListener(listener) {
146
+ this.#listeners = [...this.#listeners, listener];
147
+ }
148
+ removeEventListener(listener) {
149
+ this.#listeners = this.#listeners.filter(l => l !== listener);
150
+ }
151
+ async #validate(state) {
152
+ const rawUserInfo = await this.#service.validate(state);
153
+ const userInfo = this.#service.parseUserInfo(rawUserInfo);
154
+ return {
155
+ state,
156
+ rawUserInfo,
157
+ userInfo
158
+ };
159
+ }
160
+ #listeners = [];
161
+ #updateAndNotify(session, event) {
162
+ this.#session = session;
163
+ this.#operation = null;
164
+ if (this.#persistent) {
165
+ if (session) {
166
+ localStorage.setItem(this.#persistentKey, session.state);
167
+ } else {
168
+ localStorage.removeItem(this.#persistentKey);
169
+ }
170
+ }
171
+ for (const listener of this.#listeners) {
172
+ listener(event);
173
+ }
174
+ }
175
+ #revalidateTask = undefined;
176
+ #updateRevalidateTask() {
177
+ if (this.#revalidateInterval && this.#session) {
178
+ this.#revalidateTask = setTimeout(async () => {
179
+ await this.revalidate();
180
+ this.#updateRevalidateTask();
181
+ }, this.#revalidateInterval);
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * SessionStore 发出的事件类型。
188
+ *
189
+ * - validated:会话首次验证成功。
190
+ * - revalidated:会话重新验证成功。
191
+ * - failed: 会话创建或首次验证失败。
192
+ * - invalidated:会话失效。
193
+ */
@@ -1,6 +1,6 @@
1
- import { CompositeLayer } from "deck.gl";
2
1
  import type { DefaultProps } from "@deck.gl/core";
3
2
  import { TileLayer } from "@deck.gl/geo-layers";
3
+ import { CompositeLayer } from "deck.gl";
4
4
  export interface TiandituLayerProps {
5
5
  tiandituTk: string;
6
6
  type: "vec" | "img" | "ter";
@@ -1,5 +1,5 @@
1
- import { BitmapLayer, CompositeLayer } from "deck.gl";
2
1
  import { TileLayer } from "@deck.gl/geo-layers";
2
+ import { BitmapLayer, CompositeLayer } from "deck.gl";
3
3
  export default class TiandituLayer extends CompositeLayer {
4
4
  static layerName = "TiandituLayer";
5
5
  static defaultProps = {
@@ -1,5 +1,5 @@
1
- import type * as wl from "weatherlayers-gl";
2
1
  import type { BitmapBoundingBox } from "@deck.gl/layers";
2
+ import type * as wl from "weatherlayers-gl";
3
3
  export interface WeatherData {
4
4
  dims: {
5
5
  longitude: number;
@@ -1,4 +1,4 @@
1
- import type { Color, BarSeriesOption as OrigBarSeriesOption } from "echarts";
1
+ import type { BarSeriesOption as OrigBarSeriesOption, Color } from "echarts";
2
2
  import type { EChartsSeries } from "..";
3
3
  export interface MaxBarSeriesOption {
4
4
  /** 系列名称,不可与其他系列重名。*/
package/dist/index.d.ts CHANGED
@@ -1,4 +1,11 @@
1
- export { AuthProvider, type AuthProviderProps, AuthCheck, type AuthCheckProps, AuthCallback, type AuthCallbackProps, useAuth, type Auth, type CasdoorAuth, type LocalAuth, } from "./components/Auth";
1
+ export { AuthProvider, useSessionStore, useSession, type AuthProviderProps, type TokenBasedAuthProviderProps, type GenericAuthProviderProps, type UseSessionOptions, type UseSessionNonNullableOptions, } from "./components/auth/AuthProvider";
2
+ export type { AuthService, UserInfo } from "./components/auth/AuthService";
3
+ export { CasdoorAuthService, CasdoorCallback, CasdoorRoleCheck, type CasdoorAuthServiceOptions, type CasdoorTokenPayload, type CasdoorUserInfo, type CasdoorCallbackProps, type CasdoorRoleCheckProps, } from "./components/auth/CasdoorAuth";
4
+ export { EmbeddedAuthService, type EmbeddedAuthServiceOptions, } from "./components/auth/EmbeddedAuth";
5
+ export { fetcherWithBearerToken, fetcherWithLoginOn401, useFetcher, FetcherMiddleware, FetcherWithAuth, type Fetcher, type FetcherExtraOptions, type FetcherMiddlewareProps, type FetcherWithAuthProps, } from "./components/auth/Fetcher";
6
+ export { LocalAuthService, useLocalLogin, type LocalAuthServiceOptions, type LocalTokenPayload, type LocalUserInfo, } from "./components/auth/LocalAuth";
7
+ export { LoginCheck, type LoginCheckProps } from "./components/auth/LoginCheck";
8
+ export { SessionStore, type SessionStoreOptions, type SessionStoreEvent, type SessionStoreEventListener, type Session, } from "./components/auth/SessionStore";
2
9
  export { default as AutoResizedECharts, withAutoResize, } from "./components/AutoResizedECharts";
3
10
  export { default as Calendar, type CalendarProps } from "./components/Calendar";
4
11
  export { default as CircularProgress, type CircularProgressProps, } from "./components/CircularProgress";
package/dist/index.js CHANGED
@@ -1,4 +1,10 @@
1
- export { AuthProvider, AuthCheck, AuthCallback, useAuth } from "./components/Auth";
1
+ export { AuthProvider, useSessionStore, useSession } from "./components/auth/AuthProvider";
2
+ export { CasdoorAuthService, CasdoorCallback, CasdoorRoleCheck } from "./components/auth/CasdoorAuth";
3
+ export { EmbeddedAuthService } from "./components/auth/EmbeddedAuth";
4
+ export { fetcherWithBearerToken, fetcherWithLoginOn401, useFetcher, FetcherMiddleware, FetcherWithAuth } from "./components/auth/Fetcher";
5
+ export { LocalAuthService, useLocalLogin } from "./components/auth/LocalAuth";
6
+ export { LoginCheck } from "./components/auth/LoginCheck";
7
+ export { SessionStore } from "./components/auth/SessionStore";
2
8
  export { default as AutoResizedECharts, withAutoResize } from "./components/AutoResizedECharts";
3
9
  export { default as Calendar } from "./components/Calendar";
4
10
  export { default as CircularProgress } from "./components/CircularProgress";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsingroc/tsingroc-components",
3
- "version": "5.0.0-alpha.21",
3
+ "version": "5.0.0-alpha.22",
4
4
  "author": "",
5
5
  "license": "ISC",
6
6
  "description": "",
@@ -29,85 +29,69 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "test": "echo \"Error: no test specified\" && exit 1",
32
- "dev": "rspress",
33
- "lint": "eslint .",
34
- "format": "prettier . -w && eslint . --fix",
32
+ "dev": "vite",
33
+ "lint": "oxlint --type-aware",
34
+ "format": "dprint fmt && oxlint --type-aware --fix",
35
35
  "build": "rm -rf dist && (npx babel src --out-dir dist --extensions .ts,.tsx & tsc -p tsconfig.lib.json & copyfiles src/**/*.css dist --up 1 & wait)",
36
36
  "prepublishOnly": "npm run build",
37
- "docs:build": "rspress build",
38
- "docs:preview": "rspress preview"
37
+ "docs:build": "vite build",
38
+ "docs:preview": "vite preview"
39
39
  },
40
40
  "dependencies": {
41
41
  "casdoor-js-sdk": "^0.16.0",
42
- "dayjs": "^1.11.18",
43
- "deck.gl": "^9.2.2",
42
+ "dayjs": "^1.11.19",
43
+ "deck.gl": "^9.2.5",
44
44
  "geotiff": "^2.1.3",
45
45
  "jwt-decode": "^4.0.0",
46
46
  "react-icons": "^5.5.0",
47
47
  "rollup-plugin-worker-factory": "^0.5.7",
48
- "weatherlayers-gl": "^2025.8.0"
48
+ "weatherlayers-gl": "^2025.12.0"
49
49
  },
50
50
  "peerDependencies": {
51
- "@ant-design/icons": "^6.0.0",
52
- "@ant-design/v5-patch-for-react-19": "^1.0.3",
53
- "antd": "^5.27.5",
51
+ "@ant-design/icons": "^6.1.0",
52
+ "antd": "^6.1.4",
54
53
  "antd-style": "^3.7.1",
55
- "echarts": "^5.6.0 || ^6.0.0",
54
+ "echarts": "^6.0.0",
56
55
  "echarts-gl": "^2.0.9",
57
- "react": "^19.2.0",
58
- "react-dom": "^19.2.0"
56
+ "react": "^19.2.3",
57
+ "react-dom": "^19.2.3"
59
58
  },
60
59
  "devDependencies": {
61
60
  "@ant-design/icons": "^6.1.0",
62
61
  "@ant-design/v5-patch-for-react-19": "^1.0.3",
63
62
  "@babel/cli": "^7.28.3",
64
- "@babel/core": "^7.28.4",
65
- "@babel/preset-react": "^7.27.1",
66
- "@babel/preset-typescript": "^7.27.1",
67
- "@eslint/js": "^9.38.0",
68
- "@ianvs/prettier-plugin-sort-imports": "^4.7.0",
69
- "@rspress/core": "^2.0.0-beta.34",
70
- "@rspress/plugin-preview": "^2.0.0-beta.34",
71
- "@types/node": "^22.18.12",
72
- "@types/react": "^19.2.2",
73
- "@types/react-dom": "^19.2.2",
74
- "antd": "^5.27.6",
63
+ "@babel/core": "^7.28.5",
64
+ "@babel/preset-react": "^7.28.5",
65
+ "@babel/preset-typescript": "^7.28.5",
66
+ "@content-collections/core": "^0.12.0",
67
+ "@content-collections/mdx": "^0.2.2",
68
+ "@content-collections/vite": "^0.2.8",
69
+ "@types/node": "^22.19.3",
70
+ "@types/react": "^19.2.7",
71
+ "@types/react-dom": "^19.2.3",
72
+ "@vitejs/plugin-react": "^5.1.2",
73
+ "antd": "^6.1.4",
75
74
  "antd-style": "^3.7.1",
76
75
  "babel-plugin-react-compiler": "^1.0.0",
77
76
  "copyfiles": "^2.4.1",
77
+ "dprint": "^0.50.2",
78
78
  "echarts": "^6.0.0",
79
79
  "echarts-gl": "^2.0.9",
80
- "eslint": "^9.38.0",
81
- "eslint-plugin-react-hooks": "^7.0.0",
82
- "globals": "^16.4.0",
83
- "prettier": "^3.6.2",
84
- "react": "^19.2.0",
85
- "react-dom": "^19.2.0",
80
+ "eslint-plugin-react-hooks": "^7.0.1",
81
+ "oxlint": "^1.38.0",
82
+ "oxlint-tsgolint": "^0.10.1",
83
+ "react": "^19.2.3",
84
+ "react-dom": "^19.2.3",
86
85
  "react-markdown": "^10.1.0",
87
86
  "remark-gfm": "^4.0.1",
88
- "typedoc": "^0.28.14",
87
+ "typedoc": "^0.28.15",
89
88
  "typescript": "^5.9.3",
90
- "typescript-eslint": "^8.46.2"
89
+ "vite": "npm:rolldown-vite@^7.3.0",
90
+ "zod": "^4.3.5"
91
91
  },
92
92
  "overrides": {
93
93
  "echarts-gl": {
94
94
  "echarts": "^6.0.0"
95
95
  }
96
- },
97
- "prettier": {
98
- "trailingComma": "all",
99
- "importOrder": [
100
- "<BUILTIN_MODULES>",
101
- "",
102
- "<THIRD_PARTY_MODULES>",
103
- "^@(?!docs/)",
104
- "",
105
- "^@docs/",
106
- "^[./]"
107
- ],
108
- "importOrderCaseSensitive": true,
109
- "plugins": [
110
- "@ianvs/prettier-plugin-sort-imports"
111
- ]
112
96
  }
113
97
  }