react-native-fxview 1.0.2 → 1.0.3-beta2
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/FXCategoryController.js +24 -20
- package/FXCategoryController.ts +21 -20
- package/FXView.js +9 -5
- package/FXView.tsx +6 -5
- package/FXViewController.js +21 -17
- package/FXViewController.ts +18 -17
- package/FXViewManager.d.ts +10 -0
- package/FXViewManager.js +40 -28
- package/FXViewManager.ts +45 -28
- package/index.d.ts +2 -3
- package/index.js +4 -6
- package/index.ts +2 -3
- package/logger/FXLogger-README.md +248 -0
- package/logger/FXLogger.d.ts +109 -0
- package/logger/FXLogger.js +239 -0
- package/logger/FXLogger.ts +282 -0
- package/package.json +9 -1
- package/queue/PriorityQueue.d.ts +153 -0
- package/queue/PriorityQueue.js +325 -0
- package/queue/PriorityQueue.ts +367 -0
- package/types.ts +1 -1
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
// ========== Logger 类型定义 ==========
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 日志级别枚举
|
|
6
|
+
*/
|
|
7
|
+
export enum FXLogLevel {
|
|
8
|
+
DEBUG = 0, // 调试级别(最详细)
|
|
9
|
+
INFO = 1, // 信息级别
|
|
10
|
+
WARN = 2, // 警告级别
|
|
11
|
+
ERROR = 3, // 错误级别
|
|
12
|
+
SILENT = 4, // 静默模式(不输出任何日志)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Logger 配置接口
|
|
17
|
+
*/
|
|
18
|
+
export interface FXLoggerConfig {
|
|
19
|
+
debug: boolean; // 是否启用调试模式
|
|
20
|
+
level: FXLogLevel; // 日志级别
|
|
21
|
+
showTimestamp: boolean; // 是否显示时间戳
|
|
22
|
+
prefix: string; // 日志前缀
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* FX Logger - 专为 React Native 项目设计的调试日志系统
|
|
27
|
+
* 提供丰富的日志功能和灵活的配置选项
|
|
28
|
+
*/
|
|
29
|
+
export class FXLogger {
|
|
30
|
+
private static instance: FXLogger;
|
|
31
|
+
private config: FXLoggerConfig;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 私有构造函数,实现单例模式
|
|
35
|
+
*/
|
|
36
|
+
private constructor() {
|
|
37
|
+
// 自动检测环境
|
|
38
|
+
const isDevelopment = this.isDevelopmentEnvironment();
|
|
39
|
+
|
|
40
|
+
// 根据环境设置默认配置
|
|
41
|
+
this.config = {
|
|
42
|
+
debug: isDevelopment, // 开发环境启用调试模式,生产环境禁用
|
|
43
|
+
level: isDevelopment ? FXLogLevel.DEBUG : FXLogLevel.ERROR, // 生产环境只显示错误日志
|
|
44
|
+
showTimestamp: true,
|
|
45
|
+
prefix: isDevelopment ? "[FX-DEV]" : "[FX-PROD]", // 不同环境使用不同前缀
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 获取单例实例
|
|
51
|
+
*/
|
|
52
|
+
public static getInstance(): FXLogger {
|
|
53
|
+
if (!FXLogger.instance) {
|
|
54
|
+
FXLogger.instance = new FXLogger();
|
|
55
|
+
}
|
|
56
|
+
return FXLogger.instance;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 检测当前是否为开发环境
|
|
61
|
+
*/
|
|
62
|
+
private isDevelopmentEnvironment(): boolean {
|
|
63
|
+
try {
|
|
64
|
+
// 使用 Function 构造函数来安全地访问全局变量,避免 TypeScript 错误
|
|
65
|
+
const getGlobal = new Function("return this")();
|
|
66
|
+
|
|
67
|
+
// 检测 React Native 的 __DEV__ 变量
|
|
68
|
+
if (typeof getGlobal.__DEV__ !== "undefined" && getGlobal.__DEV__) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// 检测 Node.js 环境变量
|
|
73
|
+
if (
|
|
74
|
+
typeof getGlobal.process !== "undefined" &&
|
|
75
|
+
getGlobal.process.env &&
|
|
76
|
+
getGlobal.process.env.NODE_ENV === "development"
|
|
77
|
+
) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// 检测 window 对象(浏览器环境)
|
|
82
|
+
if (typeof getGlobal.window !== "undefined" && getGlobal.window.__DEV__) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 检测全局对象属性
|
|
87
|
+
if (getGlobal.NODE_ENV === "development") {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
// 如果检测过程中出错,默认返回 false(生产环境)
|
|
92
|
+
this.error("Environment detection failed", error);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 默认返回 false(生产环境)
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* 获取当前配置
|
|
101
|
+
*/
|
|
102
|
+
public getConfig(): FXLoggerConfig {
|
|
103
|
+
return { ...this.config };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 配置 Logger
|
|
108
|
+
*/
|
|
109
|
+
public configure(config: Partial<FXLoggerConfig>): void {
|
|
110
|
+
this.config = { ...this.config, ...config };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 启用调试模式
|
|
115
|
+
*/
|
|
116
|
+
public enableDebug(): void {
|
|
117
|
+
this.config.debug = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* 禁用调试模式
|
|
122
|
+
*/
|
|
123
|
+
public disableDebug(): void {
|
|
124
|
+
this.config.debug = false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 获取时间戳(包含年月日)
|
|
129
|
+
*/
|
|
130
|
+
private getTimestamp(): string {
|
|
131
|
+
const now = new Date();
|
|
132
|
+
const year = now.getFullYear();
|
|
133
|
+
const month = (now.getMonth() + 1).toString().padStart(2, "0");
|
|
134
|
+
const day = now.getDate().toString().padStart(2, "0");
|
|
135
|
+
const hours = now.getHours().toString().padStart(2, "0");
|
|
136
|
+
const minutes = now.getMinutes().toString().padStart(2, "0");
|
|
137
|
+
const seconds = now.getSeconds().toString().padStart(2, "0");
|
|
138
|
+
const milliseconds = now.getMilliseconds().toString().padStart(3, "0");
|
|
139
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 检查是否应该记录日志
|
|
144
|
+
*/
|
|
145
|
+
private shouldLog(level: FXLogLevel): boolean {
|
|
146
|
+
if (!this.config.debug && level < FXLogLevel.ERROR) {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
return level >= this.config.level;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* 获取日志级别的颜色符号
|
|
154
|
+
*/
|
|
155
|
+
private getLevelColor(level: FXLogLevel): string {
|
|
156
|
+
switch (level) {
|
|
157
|
+
case FXLogLevel.DEBUG:
|
|
158
|
+
return "🔵"; // 蓝色 - 调试
|
|
159
|
+
case FXLogLevel.INFO:
|
|
160
|
+
return "🟢"; // 绿色 - 信息
|
|
161
|
+
case FXLogLevel.WARN:
|
|
162
|
+
return "🟡"; // 黄色 - 警告
|
|
163
|
+
case FXLogLevel.ERROR:
|
|
164
|
+
return "🔴"; // 红色 - 错误
|
|
165
|
+
default:
|
|
166
|
+
return "⚪"; // 默认白色
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* 格式化日志消息
|
|
172
|
+
*/
|
|
173
|
+
private formatMessage(level: string, message: string): string {
|
|
174
|
+
const parts: string[] = [];
|
|
175
|
+
|
|
176
|
+
if (this.config.prefix) {
|
|
177
|
+
parts.push(this.config.prefix);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (this.config.showTimestamp) {
|
|
181
|
+
parts.push(`[${this.getTimestamp()}]`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 根据日志级别添加颜色符号
|
|
185
|
+
const levelEnum =
|
|
186
|
+
FXLogLevel[level.toUpperCase() as keyof typeof FXLogLevel];
|
|
187
|
+
const colorSymbol = this.getLevelColor(levelEnum);
|
|
188
|
+
parts.push(`[${colorSymbol}${level.toUpperCase()}]`);
|
|
189
|
+
|
|
190
|
+
return parts.join("") + " " + message;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 调试日志
|
|
195
|
+
*/
|
|
196
|
+
log(message?: any, ...optionalParams: any[]): void {
|
|
197
|
+
if (!this.shouldLog(FXLogLevel.DEBUG)) return;
|
|
198
|
+
|
|
199
|
+
const formattedMessage = this.formatMessage("debug", message);
|
|
200
|
+
console.log(formattedMessage, ...optionalParams);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 信息日志
|
|
205
|
+
*/
|
|
206
|
+
info(message?: any, ...optionalParams: any[]): void {
|
|
207
|
+
if (!this.shouldLog(FXLogLevel.INFO)) return;
|
|
208
|
+
|
|
209
|
+
const formattedMessage = this.formatMessage("info", message);
|
|
210
|
+
console.info(formattedMessage, ...optionalParams);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* 警告日志
|
|
215
|
+
*/
|
|
216
|
+
warn(message?: any, ...optionalParams: any[]): void {
|
|
217
|
+
if (!this.shouldLog(FXLogLevel.WARN)) return;
|
|
218
|
+
|
|
219
|
+
const formattedMessage = this.formatMessage("warn", message);
|
|
220
|
+
console.warn(formattedMessage, ...optionalParams);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* 错误日志
|
|
225
|
+
*/
|
|
226
|
+
error(message?: any, ...optionalParams: any[]): void {
|
|
227
|
+
if (!this.shouldLog(FXLogLevel.ERROR)) return;
|
|
228
|
+
|
|
229
|
+
const formattedMessage = this.formatMessage("error", message);
|
|
230
|
+
console.error(formattedMessage, ...optionalParams);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* 追踪日志
|
|
235
|
+
*/
|
|
236
|
+
trace(message?: any, ...optionalParams: any[]): void {
|
|
237
|
+
if (!this.shouldLog(FXLogLevel.DEBUG)) return;
|
|
238
|
+
|
|
239
|
+
const formattedMessage = this.formatMessage("trace", message);
|
|
240
|
+
console.trace(formattedMessage, ...optionalParams);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* 表格日志
|
|
245
|
+
*/
|
|
246
|
+
table(...data: any[]): void {
|
|
247
|
+
if (!this.shouldLog(FXLogLevel.DEBUG)) return;
|
|
248
|
+
|
|
249
|
+
console.table(...data);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 分组日志
|
|
254
|
+
*/
|
|
255
|
+
group(label?: string): void {
|
|
256
|
+
if (!this.shouldLog(FXLogLevel.DEBUG)) return;
|
|
257
|
+
|
|
258
|
+
console.group(label);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* 结束分组日志
|
|
263
|
+
*/
|
|
264
|
+
groupEnd(): void {
|
|
265
|
+
console.groupEnd();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 折叠分组日志
|
|
270
|
+
*/
|
|
271
|
+
groupCollapsed(label?: string): void {
|
|
272
|
+
if (!this.shouldLog(FXLogLevel.DEBUG)) return;
|
|
273
|
+
|
|
274
|
+
console.groupCollapsed(label);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// 创建全局实例
|
|
279
|
+
const logger = FXLogger.getInstance();
|
|
280
|
+
|
|
281
|
+
// 导出默认实例
|
|
282
|
+
export default logger;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-fxview",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3-beta2",
|
|
4
4
|
"description": "A dynamic view component for React Native that allows runtime UI updates and component management",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
"*.js",
|
|
9
9
|
"*.ts",
|
|
10
10
|
"*.tsx",
|
|
11
|
+
"*.d.ts",
|
|
12
|
+
"queue/**/*.js",
|
|
13
|
+
"queue/**/*.ts",
|
|
14
|
+
"queue/**/*.d.ts",
|
|
15
|
+
"logger/**/*.js",
|
|
16
|
+
"logger/**/*.ts",
|
|
17
|
+
"logger/**/*.d.ts",
|
|
18
|
+
"logger/**/*.md",
|
|
11
19
|
"README.md",
|
|
12
20
|
"LICENSE"
|
|
13
21
|
],
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用的优先级队列 - 支持泛型存储,可切换大顶堆/小顶堆模式
|
|
3
|
+
* 支持优先级相同时的排序策略:先入先出(FIFO)或后入先出(LIFO)
|
|
4
|
+
*/
|
|
5
|
+
export declare enum HeapType {
|
|
6
|
+
MAX_HEAP = "max",// 大顶堆:优先级高的在前
|
|
7
|
+
MIN_HEAP = "min"
|
|
8
|
+
}
|
|
9
|
+
export declare enum PriorityOrder {
|
|
10
|
+
FIFO = "fifo",// 先入先出:优先级相同时,先入队的在前
|
|
11
|
+
LIFO = "lifo"
|
|
12
|
+
}
|
|
13
|
+
export declare class PriorityQueue<T> {
|
|
14
|
+
private items;
|
|
15
|
+
private heapType;
|
|
16
|
+
private priorityOrder;
|
|
17
|
+
constructor(heapType?: HeapType, priorityOrder?: PriorityOrder);
|
|
18
|
+
/**
|
|
19
|
+
* 设置堆类型(可选参数)
|
|
20
|
+
*/
|
|
21
|
+
setHeapType(heapType?: HeapType): void;
|
|
22
|
+
/**
|
|
23
|
+
* 获取当前堆类型
|
|
24
|
+
*/
|
|
25
|
+
getHeapType(): HeapType;
|
|
26
|
+
/**
|
|
27
|
+
* 设置优先级相同时的排序策略(可选参数)
|
|
28
|
+
*/
|
|
29
|
+
setPriorityOrder(order?: PriorityOrder): void;
|
|
30
|
+
/**
|
|
31
|
+
* 获取当前优先级相同时的排序策略
|
|
32
|
+
*/
|
|
33
|
+
getPriorityOrder(): PriorityOrder;
|
|
34
|
+
/**
|
|
35
|
+
* 入队 - 按当前堆类型和排序策略排序
|
|
36
|
+
*/
|
|
37
|
+
enqueue(item: T, priority?: number, timestamp?: number): void;
|
|
38
|
+
/**
|
|
39
|
+
* 批量入队(可选参数)
|
|
40
|
+
*/
|
|
41
|
+
enqueueMultiple(items: T[], priority?: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* 出队 - 返回队首元素(最高或最低优先级)
|
|
44
|
+
*/
|
|
45
|
+
dequeue(): T | null;
|
|
46
|
+
/**
|
|
47
|
+
* 批量出队(可选参数)
|
|
48
|
+
*/
|
|
49
|
+
dequeueMultiple(count?: number): T[];
|
|
50
|
+
/**
|
|
51
|
+
* 查看队首元素(不移除)
|
|
52
|
+
*/
|
|
53
|
+
peek(): T | null;
|
|
54
|
+
/**
|
|
55
|
+
* 查看队首元素的优先级
|
|
56
|
+
*/
|
|
57
|
+
peekPriority(): number | null;
|
|
58
|
+
/**
|
|
59
|
+
* 查看前N个元素(可选参数)
|
|
60
|
+
*/
|
|
61
|
+
peekMultiple(count?: number): T[];
|
|
62
|
+
/**
|
|
63
|
+
* 队列是否为空
|
|
64
|
+
*/
|
|
65
|
+
isEmpty(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* 队列大小
|
|
68
|
+
*/
|
|
69
|
+
size(): number;
|
|
70
|
+
/**
|
|
71
|
+
* 清空队列
|
|
72
|
+
*/
|
|
73
|
+
clear(): void;
|
|
74
|
+
/**
|
|
75
|
+
* 获取所有元素(按当前堆类型排序)
|
|
76
|
+
*/
|
|
77
|
+
getAll(): T[];
|
|
78
|
+
/**
|
|
79
|
+
* 获取所有元素及其优先级
|
|
80
|
+
*/
|
|
81
|
+
getAllWithPriority(): Array<{
|
|
82
|
+
item: T;
|
|
83
|
+
priority: number;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* 获取所有元素及其详细信息
|
|
87
|
+
*/
|
|
88
|
+
getAllWithDetails(): Array<{
|
|
89
|
+
item: T;
|
|
90
|
+
priority: number;
|
|
91
|
+
timestamp: number;
|
|
92
|
+
}>;
|
|
93
|
+
/**
|
|
94
|
+
* 获取指定索引的元素(可选参数)
|
|
95
|
+
*/
|
|
96
|
+
getAt(index?: number): T | null;
|
|
97
|
+
/**
|
|
98
|
+
* 获取指定范��的元素(可选参数)
|
|
99
|
+
*/
|
|
100
|
+
getRange(start?: number, end?: number): T[];
|
|
101
|
+
/**
|
|
102
|
+
* 移除指定元素
|
|
103
|
+
*/
|
|
104
|
+
remove(item: T): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* 移除指定索引的元素(可选参数)
|
|
107
|
+
*/
|
|
108
|
+
removeAt(index?: number): T | null;
|
|
109
|
+
/**
|
|
110
|
+
* 更新元素的优先级
|
|
111
|
+
*/
|
|
112
|
+
updatePriority(item: T, newPriority?: number): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* 查找指定元素
|
|
115
|
+
*/
|
|
116
|
+
find(predicate: (item: T) => boolean): T | null;
|
|
117
|
+
/**
|
|
118
|
+
* 查找所有符合条件的元素
|
|
119
|
+
*/
|
|
120
|
+
findAll(predicate: (item: T) => boolean): T[];
|
|
121
|
+
/**
|
|
122
|
+
* 过滤元素
|
|
123
|
+
*/
|
|
124
|
+
filter(predicate: (item: T) => boolean): T[];
|
|
125
|
+
/**
|
|
126
|
+
* 遍历元素
|
|
127
|
+
*/
|
|
128
|
+
forEach(callback: (item: T, priority: number, index: number) => void): void;
|
|
129
|
+
/**
|
|
130
|
+
* 映射元素
|
|
131
|
+
*/
|
|
132
|
+
map<U>(callback: (item: T, priority: number, index: number) => U): U[];
|
|
133
|
+
/**
|
|
134
|
+
* 判断是否应该插入到指定元素之前
|
|
135
|
+
*/
|
|
136
|
+
private shouldInsertBefore;
|
|
137
|
+
/**
|
|
138
|
+
* 重新排序所有元素
|
|
139
|
+
*/
|
|
140
|
+
private resort;
|
|
141
|
+
/**
|
|
142
|
+
* 转换为数组
|
|
143
|
+
*/
|
|
144
|
+
toArray(): T[];
|
|
145
|
+
/**
|
|
146
|
+
* 转换为JSON字符串
|
|
147
|
+
*/
|
|
148
|
+
toJSON(): string;
|
|
149
|
+
/**
|
|
150
|
+
* 克隆队列
|
|
151
|
+
*/
|
|
152
|
+
clone(): PriorityQueue<T>;
|
|
153
|
+
}
|