pubo-utils 1.0.201 → 1.0.202
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/README.md +633 -0
- package/dist/pubo-utils.js +1 -1
- package/es/factory/resource-manager.d.ts +43 -0
- package/es/factory/resource-manager.js +72 -0
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/lib/factory/resource-manager.d.ts +43 -0
- package/lib/factory/resource-manager.js +90 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +13 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
# pubo-utils
|
|
2
|
+
|
|
3
|
+
通用工具库,提供函数式编程、异步控制、数据转换、几何计算等功能。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install pubo-utils
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## API 文档
|
|
12
|
+
|
|
13
|
+
### debounce
|
|
14
|
+
|
|
15
|
+
防抖函数,限制函数执行频率。
|
|
16
|
+
|
|
17
|
+
**函数签名**
|
|
18
|
+
```typescript
|
|
19
|
+
export const debounce = (cb: any, time: number, first = false) => (...args) => void
|
|
20
|
+
```
|
|
21
|
+
- `cb`: 要防抖的回调函数
|
|
22
|
+
- `time`: 防抖时间(毫秒)
|
|
23
|
+
- `first`: 是否立即执行第一次调用,默认 false
|
|
24
|
+
- 返回:一个防抖后的函数
|
|
25
|
+
|
|
26
|
+
### hex2rgb
|
|
27
|
+
|
|
28
|
+
十六进制颜色转 RGB 数组。
|
|
29
|
+
|
|
30
|
+
**函数签名**
|
|
31
|
+
```typescript
|
|
32
|
+
export const hex2rgb = (n: number | string): [number, number, number]
|
|
33
|
+
```
|
|
34
|
+
- `n`: 十六进制颜色值(如 `0xFF0000` 或 `"#FF0000"`)
|
|
35
|
+
- 返回:RGB 数组 `[r, g, b]`
|
|
36
|
+
|
|
37
|
+
### rgb2hex
|
|
38
|
+
|
|
39
|
+
RGB 数组转十六进制颜色字符串。
|
|
40
|
+
|
|
41
|
+
**函数签名**
|
|
42
|
+
```typescript
|
|
43
|
+
export const rgb2hex = (color: [number, number, number] | [number, number, number, number]): string
|
|
44
|
+
```
|
|
45
|
+
- `color`: RGB 或 RGBA 数组
|
|
46
|
+
- 返回:十六进制颜色字符串(如 `"#FF0000"`)
|
|
47
|
+
|
|
48
|
+
### ColorUtils
|
|
49
|
+
|
|
50
|
+
颜色工具类,支持多种颜色格式转换。
|
|
51
|
+
|
|
52
|
+
**构造函数**
|
|
53
|
+
```typescript
|
|
54
|
+
constructor(n: number | string | [number, number, number])
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**属性**
|
|
58
|
+
- `int`: 颜色的整数值
|
|
59
|
+
- `rgb`: 返回 `"rba(r, g, b)"` 格式字符串
|
|
60
|
+
- `hex`: 返回十六进制字符串
|
|
61
|
+
|
|
62
|
+
**方法**
|
|
63
|
+
- `getRgbArray(): [number, number, number]` - 返回 RGB 数组
|
|
64
|
+
- `toString(type: 'hex' | 'rgb' = 'hex'): string` - 转换为指定格式字符串
|
|
65
|
+
|
|
66
|
+
### LinearColor
|
|
67
|
+
|
|
68
|
+
线性颜色生成器,根据数值生成渐变色。
|
|
69
|
+
|
|
70
|
+
**构造函数**
|
|
71
|
+
```typescript
|
|
72
|
+
constructor({ base = [255, 0, 0], intensity = 1 }: { base?: [number, number, number]; intensity?: number } = {})
|
|
73
|
+
```
|
|
74
|
+
- `base`: 基础颜色数组,默认红色 `[255, 0, 0]`
|
|
75
|
+
- `intensity`: 强度系数,默认 1
|
|
76
|
+
|
|
77
|
+
**方法**
|
|
78
|
+
- `getColor(value: number): [number, number, number]` - 根据数值返回 RGB 颜色数组
|
|
79
|
+
|
|
80
|
+
### Emitter
|
|
81
|
+
|
|
82
|
+
事件发射器,支持异步事件处理。
|
|
83
|
+
|
|
84
|
+
**方法**
|
|
85
|
+
- `on(event: string, func: any): string` - 注册事件监听器,返回监听器 ID
|
|
86
|
+
- `cancel(id?: string): void` - 取消指定 ID 的监听器
|
|
87
|
+
- `emit(event: string, payload?: any): void` - 触发事件(同步)
|
|
88
|
+
- `emitSync(event: string, payload?: any): Promise<any>` - 触发事件(异步等待)
|
|
89
|
+
- `clear(): void` - 清除所有监听器
|
|
90
|
+
- `clone(): any` - 克隆当前状态
|
|
91
|
+
- `restore(snapshot: any): void` - 恢复状态
|
|
92
|
+
|
|
93
|
+
### CacheEmitter
|
|
94
|
+
|
|
95
|
+
带缓存的事件发射器,继承自 `Emitter`。
|
|
96
|
+
|
|
97
|
+
**方法**
|
|
98
|
+
- `emit(event: string, payload?: any): void` - 触发事件并缓存 payload
|
|
99
|
+
- `getState(event: string): any` - 获取指定事件的缓存值
|
|
100
|
+
|
|
101
|
+
### superFactory
|
|
102
|
+
|
|
103
|
+
超级工厂函数,用于创建可配置的工厂函数。
|
|
104
|
+
|
|
105
|
+
**类型定义**
|
|
106
|
+
```typescript
|
|
107
|
+
export type SuperFactory = <C, F>(factory: Factory<C>) => CreateFactory<C, F>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**函数签名**
|
|
111
|
+
```typescript
|
|
112
|
+
export const superFactory: SuperFactory = (factory) => (options: any) => any
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### loop
|
|
116
|
+
|
|
117
|
+
循环执行函数,可控制停止。
|
|
118
|
+
|
|
119
|
+
**函数签名**
|
|
120
|
+
```typescript
|
|
121
|
+
export const loop = (cb: () => Promise<void>, time: number) => () => void
|
|
122
|
+
```
|
|
123
|
+
- `cb`: 要循环执行的异步函数
|
|
124
|
+
- `time`: 循环间隔(毫秒)
|
|
125
|
+
- 返回:停止函数
|
|
126
|
+
|
|
127
|
+
### waitFor
|
|
128
|
+
|
|
129
|
+
等待条件成立,支持超时。
|
|
130
|
+
|
|
131
|
+
**函数签名**
|
|
132
|
+
```typescript
|
|
133
|
+
export const waitFor = (bool: () => boolean | Promise<boolean>, { checkTime, timeout }: { checkTime?: number; timeout?: number } = {}) => Promise<any>
|
|
134
|
+
```
|
|
135
|
+
- `bool`: 返回布尔值的函数
|
|
136
|
+
- `checkTime`: 检查间隔(毫秒),默认 100
|
|
137
|
+
- `timeout`: 超时时间(毫秒)
|
|
138
|
+
- 返回:Promise,条件成立时解析
|
|
139
|
+
|
|
140
|
+
### retry
|
|
141
|
+
|
|
142
|
+
重试异步操作。
|
|
143
|
+
|
|
144
|
+
**函数签名**
|
|
145
|
+
```typescript
|
|
146
|
+
export const retry = async (action: any, { times = 5, interval = 1000 }: { times: number; interval: number } = { times: 5, interval: 1000 }) => Promise<any>
|
|
147
|
+
```
|
|
148
|
+
- `action`: 要重试的异步函数
|
|
149
|
+
- `times`: 重试次数,默认 5
|
|
150
|
+
- `interval`: 重试间隔(毫秒),默认 1000
|
|
151
|
+
|
|
152
|
+
### RetryPlus
|
|
153
|
+
|
|
154
|
+
增强版重试类,支持取消和参数传递。
|
|
155
|
+
|
|
156
|
+
**构造函数**
|
|
157
|
+
```typescript
|
|
158
|
+
constructor(action, { times = 5, interval = 1000 }: { times: number; interval: number } = { times: 5, interval: 1000 })
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**方法**
|
|
162
|
+
- `run(...args: any[]): Promise<any>` - 执行重试操作
|
|
163
|
+
- `cancel(): Promise<void>` - 取消重试
|
|
164
|
+
|
|
165
|
+
### RemoteControl
|
|
166
|
+
|
|
167
|
+
远程控制类,用于高频控制信号。
|
|
168
|
+
|
|
169
|
+
**构造函数**
|
|
170
|
+
```typescript
|
|
171
|
+
constructor({ start, stop, fps = 5 }: RemoteControlOptions)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**方法**
|
|
175
|
+
- `control(payload: any): void` - 发送控制信号
|
|
176
|
+
- `stop(): void` - 停止控制
|
|
177
|
+
|
|
178
|
+
### SyncQueue
|
|
179
|
+
|
|
180
|
+
同步队列,确保异步任务顺序执行。
|
|
181
|
+
|
|
182
|
+
**方法**
|
|
183
|
+
- `push(fn: () => Promise<any>): Promise<any>` - 添加任务到队列
|
|
184
|
+
- `length: number` - 当前队列长度
|
|
185
|
+
|
|
186
|
+
### runAsyncTasks
|
|
187
|
+
|
|
188
|
+
并行执行异步任务,控制并发数。
|
|
189
|
+
|
|
190
|
+
**函数签名**
|
|
191
|
+
```typescript
|
|
192
|
+
export const runAsyncTasks = async (list: (() => Promise<any>)[], j = 4) => Promise<void>
|
|
193
|
+
```
|
|
194
|
+
- `list`: 异步函数数组
|
|
195
|
+
- `j`: 并发数,默认 4
|
|
196
|
+
|
|
197
|
+
### random
|
|
198
|
+
|
|
199
|
+
生成随机字符串。
|
|
200
|
+
|
|
201
|
+
**函数签名**
|
|
202
|
+
```typescript
|
|
203
|
+
export const random = (n = 8) => string
|
|
204
|
+
```
|
|
205
|
+
- `n`: 字符串长度,默认 8
|
|
206
|
+
- 返回:随机字符串
|
|
207
|
+
|
|
208
|
+
### randomRangeNum
|
|
209
|
+
|
|
210
|
+
生成指定范围内的随机数。
|
|
211
|
+
|
|
212
|
+
**函数签名**
|
|
213
|
+
```typescript
|
|
214
|
+
export const randomRangeNum = (range: [number, number]) => number
|
|
215
|
+
```
|
|
216
|
+
- `range`: 范围数组 `[min, max]`
|
|
217
|
+
- 返回:范围内的随机数
|
|
218
|
+
|
|
219
|
+
### sleep
|
|
220
|
+
|
|
221
|
+
异步休眠。
|
|
222
|
+
|
|
223
|
+
**函数签名**
|
|
224
|
+
```typescript
|
|
225
|
+
export const sleep = async (time: number) => Promise<void>
|
|
226
|
+
```
|
|
227
|
+
- `time`: 休眠时间(毫秒)
|
|
228
|
+
|
|
229
|
+
### timeout
|
|
230
|
+
|
|
231
|
+
带超时的异步函数执行。
|
|
232
|
+
|
|
233
|
+
**函数签名**
|
|
234
|
+
```typescript
|
|
235
|
+
export const timeout = async (cb: () => Promise<any>, time = 10000): Promise<any>
|
|
236
|
+
```
|
|
237
|
+
- `cb`: 要执行的异步函数
|
|
238
|
+
- `time`: 超时时间(毫秒),默认 10000
|
|
239
|
+
- 返回:cb 的执行结果,超时则抛出错误
|
|
240
|
+
|
|
241
|
+
### throttle
|
|
242
|
+
|
|
243
|
+
节流函数,限制函数执行频率。
|
|
244
|
+
|
|
245
|
+
**函数签名**
|
|
246
|
+
```typescript
|
|
247
|
+
export function throttle(cb: (...args: any[]) => any, time: number) => (...args: any[]) => Promise<any>
|
|
248
|
+
```
|
|
249
|
+
- `cb`: 要节流的函数
|
|
250
|
+
- `time`: 节流时间(毫秒)
|
|
251
|
+
- 返回:节流后的函数
|
|
252
|
+
|
|
253
|
+
### ContinuousTrigger
|
|
254
|
+
|
|
255
|
+
连续触发检测器,用于检测连续操作。
|
|
256
|
+
|
|
257
|
+
**构造函数**
|
|
258
|
+
```typescript
|
|
259
|
+
constructor(props: ContinuousTriggerProps)
|
|
260
|
+
```
|
|
261
|
+
- `props.resetTime`: 重置时间(毫秒)
|
|
262
|
+
- `props.count`: 触发次数阈值
|
|
263
|
+
- `props.cb`: 达到阈值时的回调函数
|
|
264
|
+
|
|
265
|
+
**方法**
|
|
266
|
+
- `increment(): void` - 增加计数
|
|
267
|
+
- `clear(): void` - 清除计数
|
|
268
|
+
- `count: number` - 当前计数
|
|
269
|
+
|
|
270
|
+
### HistoryStack
|
|
271
|
+
|
|
272
|
+
历史记录栈,支持撤销/重做。
|
|
273
|
+
|
|
274
|
+
**构造函数**
|
|
275
|
+
```typescript
|
|
276
|
+
constructor(len = 10)
|
|
277
|
+
```
|
|
278
|
+
- `len`: 最大记录长度,默认 10
|
|
279
|
+
|
|
280
|
+
**方法**
|
|
281
|
+
- `backup(item: T): void` - 备份新项
|
|
282
|
+
- `undo(): T | undefined` - 撤销
|
|
283
|
+
- `redo(): T | undefined` - 重做
|
|
284
|
+
- `clear(): void` - 清空
|
|
285
|
+
|
|
286
|
+
### WatchDog
|
|
287
|
+
|
|
288
|
+
看门狗定时器,用于检测超时。
|
|
289
|
+
|
|
290
|
+
**构造函数**
|
|
291
|
+
```typescript
|
|
292
|
+
constructor({ limit = 10, onTimeout }: WatchDogProps)
|
|
293
|
+
```
|
|
294
|
+
- `limit`: 超时时间(秒),默认 10
|
|
295
|
+
- `onTimeout`: 超时回调
|
|
296
|
+
|
|
297
|
+
**方法**
|
|
298
|
+
- `feed(): void` - 喂狗,重置定时器
|
|
299
|
+
- `init(): void` - 初始化定时器
|
|
300
|
+
- `stop(): void` - 停止定时器
|
|
301
|
+
|
|
302
|
+
### Level
|
|
303
|
+
|
|
304
|
+
等级计算器,根据数值计算等级。
|
|
305
|
+
|
|
306
|
+
**构造函数**
|
|
307
|
+
```typescript
|
|
308
|
+
constructor(props: LevelProps)
|
|
309
|
+
```
|
|
310
|
+
- `props.max`: 最大值
|
|
311
|
+
- `props.min`: 最小值
|
|
312
|
+
- `props.count`: 等级数量
|
|
313
|
+
|
|
314
|
+
**方法**
|
|
315
|
+
- `get(value: number): number` - 计算等级(1 到 count)
|
|
316
|
+
|
|
317
|
+
### callbackToPromise
|
|
318
|
+
|
|
319
|
+
回调函数转 Promise。
|
|
320
|
+
|
|
321
|
+
**函数签名**
|
|
322
|
+
```typescript
|
|
323
|
+
export const callbackToPromise = (fn: (...args: any[], callback: (err: any, ...rest: any[]) => void) => void) => (...args: any[]) => Promise<any>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### 几何函数(Geometry)
|
|
327
|
+
|
|
328
|
+
#### getDistance
|
|
329
|
+
```typescript
|
|
330
|
+
export const getDistance = (a: Point2D, b: Point2D): number
|
|
331
|
+
```
|
|
332
|
+
计算两点间距离。
|
|
333
|
+
|
|
334
|
+
#### degrees
|
|
335
|
+
```typescript
|
|
336
|
+
export const degrees = (rad: number): number
|
|
337
|
+
```
|
|
338
|
+
弧度转角度。
|
|
339
|
+
|
|
340
|
+
#### radians
|
|
341
|
+
```typescript
|
|
342
|
+
export const radians = (deg: number): number
|
|
343
|
+
```
|
|
344
|
+
角度转弧度。
|
|
345
|
+
|
|
346
|
+
#### getAngle
|
|
347
|
+
```typescript
|
|
348
|
+
export const getAngle = ({ w, h }: { w: number; h: number }): number
|
|
349
|
+
```
|
|
350
|
+
根据宽高计算角度。
|
|
351
|
+
|
|
352
|
+
#### filterKeyPoints
|
|
353
|
+
```typescript
|
|
354
|
+
export function filterKeyPoints(list: Point2D[], len = 0.5): Point2D[]
|
|
355
|
+
```
|
|
356
|
+
过滤关键点,去除距离过近的点。
|
|
357
|
+
|
|
358
|
+
#### getCenter
|
|
359
|
+
```typescript
|
|
360
|
+
export function getCenter(list: Point2D[] | [number, number][]): Point2D
|
|
361
|
+
```
|
|
362
|
+
计算点集中心点。
|
|
363
|
+
|
|
364
|
+
#### getRotate
|
|
365
|
+
```typescript
|
|
366
|
+
export function getRotate(data: Vector2D, theta: number, isDeg?: boolean): Vector2D
|
|
367
|
+
```
|
|
368
|
+
2D 向量旋转。
|
|
369
|
+
|
|
370
|
+
#### getPositionTheta
|
|
371
|
+
```typescript
|
|
372
|
+
export const getPositionTheta = (a: Point2D, b: Point2D): number
|
|
373
|
+
```
|
|
374
|
+
计算 A 点到 B 点的方向角(弧度)。
|
|
375
|
+
|
|
376
|
+
#### getBestPointIndex
|
|
377
|
+
```typescript
|
|
378
|
+
export const getBestPointIndex = (points: Point2D[], pose: Point2D & { theta: number }): number
|
|
379
|
+
```
|
|
380
|
+
根据距离和方向找到最佳点索引。
|
|
381
|
+
|
|
382
|
+
#### orderByDistance
|
|
383
|
+
```typescript
|
|
384
|
+
export const orderByDistance = (points: Point2D[], pose: Point2D & { theta: number } = { x: 0, y: 0, theta: 0 }): Point2D[]
|
|
385
|
+
```
|
|
386
|
+
按照距离和方向排序点集。
|
|
387
|
+
|
|
388
|
+
#### getVectorTheta
|
|
389
|
+
```typescript
|
|
390
|
+
export const getVectorTheta = (a: Point2D, b: Point2D): number
|
|
391
|
+
```
|
|
392
|
+
计算向量 a 到向量 b 的夹角(弧度)。
|
|
393
|
+
|
|
394
|
+
### 字符串工具
|
|
395
|
+
|
|
396
|
+
#### lower2camel
|
|
397
|
+
```typescript
|
|
398
|
+
export const lower2camel = (str: string): string
|
|
399
|
+
```
|
|
400
|
+
下划线命名转驼峰命名。
|
|
401
|
+
|
|
402
|
+
#### fixNum
|
|
403
|
+
```typescript
|
|
404
|
+
export const fixNum = (num: number | string | undefined | null, n: number = 2): string
|
|
405
|
+
```
|
|
406
|
+
格式化数字,保留指定位小数,无效值返回 "N/A"。
|
|
407
|
+
|
|
408
|
+
### RegExpList
|
|
409
|
+
|
|
410
|
+
正则表达式列表,用于批量匹配。
|
|
411
|
+
|
|
412
|
+
**构造函数**
|
|
413
|
+
```typescript
|
|
414
|
+
constructor(list: string[])
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
**方法**
|
|
418
|
+
- `include(value: string): boolean` - 检查是否匹配任意正则
|
|
419
|
+
|
|
420
|
+
### SensorDataFilter
|
|
421
|
+
|
|
422
|
+
传感器数据过滤器,过滤跳变数据。
|
|
423
|
+
|
|
424
|
+
**构造函数**
|
|
425
|
+
```typescript
|
|
426
|
+
constructor({ size = 5, step = 5, min = -Infinity, max = Infinity }: { size?: number; step?: number; max?: number; min?: number } = {})
|
|
427
|
+
```
|
|
428
|
+
- `size`: 缓冲区大小,默认 5
|
|
429
|
+
- `step`: 跳变步长,默认 5
|
|
430
|
+
- `min`: 最小值,默认 -Infinity
|
|
431
|
+
- `max`: 最大值,默认 Infinity
|
|
432
|
+
|
|
433
|
+
**方法**
|
|
434
|
+
- `filter(n: number): number` - 过滤输入值
|
|
435
|
+
|
|
436
|
+
### StringSplit
|
|
437
|
+
|
|
438
|
+
字符串分割器,支持缓存。
|
|
439
|
+
|
|
440
|
+
**构造函数**
|
|
441
|
+
```typescript
|
|
442
|
+
constructor(splitSymbol: string)
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**方法**
|
|
446
|
+
- `split(str: string): string[]` - 分割字符串
|
|
447
|
+
|
|
448
|
+
### 对象工具
|
|
449
|
+
|
|
450
|
+
#### cloneDeep
|
|
451
|
+
```typescript
|
|
452
|
+
export function cloneDeep(data: any, hash = new WeakMap()): any
|
|
453
|
+
```
|
|
454
|
+
深拷贝,支持循环引用。
|
|
455
|
+
|
|
456
|
+
#### getTreeItem
|
|
457
|
+
```typescript
|
|
458
|
+
export function getTreeItem(tree: any, indexes: number[]): any
|
|
459
|
+
```
|
|
460
|
+
根据索引路径获取树节点。
|
|
461
|
+
|
|
462
|
+
#### searchTree
|
|
463
|
+
```typescript
|
|
464
|
+
export function searchTree(tree: any, cb: (item: any) => boolean, key: string = 'children'): number[]
|
|
465
|
+
```
|
|
466
|
+
搜索树节点,返回索引路径。
|
|
467
|
+
|
|
468
|
+
#### flatTree
|
|
469
|
+
```typescript
|
|
470
|
+
export const flatTree = (tree: any, key: string = 'children', indexes: number[] = [], tmp: any[] = []): any[]
|
|
471
|
+
```
|
|
472
|
+
扁平化树结构。
|
|
473
|
+
|
|
474
|
+
#### filterTree
|
|
475
|
+
```typescript
|
|
476
|
+
export const filterTree = (tree: any, cb: (item: any) => boolean, key: string = 'children'): any[]
|
|
477
|
+
```
|
|
478
|
+
过滤树节点。
|
|
479
|
+
|
|
480
|
+
#### reflection
|
|
481
|
+
```typescript
|
|
482
|
+
export const reflection = (obj: any): any
|
|
483
|
+
```
|
|
484
|
+
创建对象的反向映射(键值互换)。
|
|
485
|
+
|
|
486
|
+
### BufferSplit
|
|
487
|
+
|
|
488
|
+
缓冲区分割器,按分隔符分割 Buffer。
|
|
489
|
+
|
|
490
|
+
**构造函数**
|
|
491
|
+
```typescript
|
|
492
|
+
constructor(buf: Buffer)
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**方法**
|
|
496
|
+
- `push(buf: Buffer): Buffer[]` - 追加数据并返回分割后的 Buffer 数组
|
|
497
|
+
|
|
498
|
+
### FP(函数式编程工具)
|
|
499
|
+
|
|
500
|
+
#### Success
|
|
501
|
+
```typescript
|
|
502
|
+
export const Success = (value: any) => ({ type: 'Success', value })
|
|
503
|
+
```
|
|
504
|
+
创建成功结果。
|
|
505
|
+
|
|
506
|
+
#### Failure
|
|
507
|
+
```typescript
|
|
508
|
+
export const Failure = (error: any) => ({ type: 'Failure', error })
|
|
509
|
+
```
|
|
510
|
+
创建失败结果。
|
|
511
|
+
|
|
512
|
+
#### Command
|
|
513
|
+
```typescript
|
|
514
|
+
export const Command = (cmd: any, next: any) => ({ type: 'Command', cmd, next })
|
|
515
|
+
```
|
|
516
|
+
创建命令。
|
|
517
|
+
|
|
518
|
+
#### effectPipe
|
|
519
|
+
```typescript
|
|
520
|
+
export const effectPipe = (...fns: any[]) => (start: any) => any
|
|
521
|
+
```
|
|
522
|
+
组合多个效果函数。
|
|
523
|
+
|
|
524
|
+
#### runEffect
|
|
525
|
+
```typescript
|
|
526
|
+
export async function runEffect(effect: any): Promise<any>
|
|
527
|
+
```
|
|
528
|
+
运行效果。
|
|
529
|
+
|
|
530
|
+
### Base64Utils
|
|
531
|
+
|
|
532
|
+
Base64 工具集(命名空间导出)。
|
|
533
|
+
|
|
534
|
+
#### toUnit8Array
|
|
535
|
+
```typescript
|
|
536
|
+
export function toUnit8Array(input: string): Uint8Array
|
|
537
|
+
```
|
|
538
|
+
Base64 字符串转 Uint8Array。
|
|
539
|
+
|
|
540
|
+
### UTM(坐标转换工具)
|
|
541
|
+
|
|
542
|
+
#### toLatLon
|
|
543
|
+
```typescript
|
|
544
|
+
export function toLatLon(options: LatLonOptions): WGS84Position
|
|
545
|
+
```
|
|
546
|
+
UTM 坐标转 WGS84 经纬度。
|
|
547
|
+
|
|
548
|
+
#### fromLatLon
|
|
549
|
+
```typescript
|
|
550
|
+
export function fromLatLon({ latitude, longitude }: WGS84Position, forceZoneNum?: number): UTMPosition
|
|
551
|
+
```
|
|
552
|
+
WGS84 经纬度转 UTM 坐标。
|
|
553
|
+
|
|
554
|
+
#### latitudeToZoneLetter
|
|
555
|
+
```typescript
|
|
556
|
+
export function latitudeToZoneLetter(latitude: number): string | null
|
|
557
|
+
```
|
|
558
|
+
纬度转 UTM 区域字母。
|
|
559
|
+
|
|
560
|
+
#### latLonToZoneNumber
|
|
561
|
+
```typescript
|
|
562
|
+
export function latLonToZoneNumber({ latitude, longitude }: WGS84Position): number
|
|
563
|
+
```
|
|
564
|
+
经纬度转 UTM 区域编号。
|
|
565
|
+
|
|
566
|
+
## 类型定义
|
|
567
|
+
|
|
568
|
+
### Point2D
|
|
569
|
+
```typescript
|
|
570
|
+
interface Point2D {
|
|
571
|
+
x: number;
|
|
572
|
+
y: number;
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Vector2D
|
|
577
|
+
```typescript
|
|
578
|
+
type Vector2D = [number, number]
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### WGS84Position
|
|
582
|
+
```typescript
|
|
583
|
+
interface WGS84Position {
|
|
584
|
+
latitude: number;
|
|
585
|
+
longitude: number;
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### UTMPosition
|
|
590
|
+
```typescript
|
|
591
|
+
interface UTMPosition {
|
|
592
|
+
x: number;
|
|
593
|
+
y: number;
|
|
594
|
+
zoneNum: number;
|
|
595
|
+
zoneLetter: string | null;
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### LatLonOptions
|
|
600
|
+
```typescript
|
|
601
|
+
interface LatLonOptions {
|
|
602
|
+
x: number;
|
|
603
|
+
y: number;
|
|
604
|
+
zoneNum: number;
|
|
605
|
+
zoneLetter?: string;
|
|
606
|
+
northern?: boolean;
|
|
607
|
+
strict?: boolean;
|
|
608
|
+
}
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
## 示例
|
|
612
|
+
|
|
613
|
+
```javascript
|
|
614
|
+
const { debounce, sleep, random, cloneDeep } = require('pubo-utils');
|
|
615
|
+
|
|
616
|
+
// 防抖
|
|
617
|
+
const debouncedFn = debounce(() => console.log('debounced'), 1000);
|
|
618
|
+
debouncedFn();
|
|
619
|
+
|
|
620
|
+
// 休眠
|
|
621
|
+
await sleep(1000);
|
|
622
|
+
|
|
623
|
+
// 随机字符串
|
|
624
|
+
const rand = random(10);
|
|
625
|
+
|
|
626
|
+
// 深拷贝
|
|
627
|
+
const obj = { a: 1, b: { c: 2 } };
|
|
628
|
+
const copied = cloneDeep(obj);
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
## 许可证
|
|
632
|
+
|
|
633
|
+
MIT
|
package/dist/pubo-utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.PuboUtils=e():t.PuboUtils=e()}(this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Base64Utils:()=>s,BufferSplit:()=>St,CacheEmitter:()=>p,ColorUtils:()=>c,ContinuousTrigger:()=>E,Emitter:()=>f,FP:()=>n,HistoryStack:()=>L,Level:()=>N,LinearColor:()=>u,RegExpList:()=>H,RemoteControl:()=>T,RetryPlus:()=>x,SensorDataFilter:()=>K,StringSplit:()=>Q,SyncQueue:()=>_,UTM:()=>i,WatchDog:()=>k,callbackToPromise:()=>R,cloneDeep:()=>V,debounce:()=>r,degrees:()=>O,filterKeyPoints:()=>F,filterTree:()=>Y,fixNum:()=>$,flatTree:()=>J,getAngle:()=>z,getBestPointIndex:()=>B,getCenter:()=>U,getDistance:()=>j,getPositionTheta:()=>D,getRotate:()=>I,getTreeItem:()=>Z,getVectorTheta:()=>X,hex2rgb:()=>a,loop:()=>w,lower2camel:()=>W,orderByDistance:()=>q,radians:()=>C,random:()=>l,randomRangeNum:()=>m,reflection:()=>tt,retry:()=>M,runAsyncTasks:()=>A,searchTree:()=>G,sleep:()=>y,superFactory:()=>g,throttle:()=>v,timeout:()=>d,waitFor:()=>b});var s={};t.r(s),t.d(s,{EncoderMap:()=>S,toUnit8Array:()=>P});var i={};t.r(i),t.d(i,{fromLatLon:()=>_t,latLonToZoneNumber:()=>vt,latitudeToZoneLetter:()=>At,toLatLon:()=>Tt});var n={};t.r(n),t.d(n,{Command:()=>kt,Failure:()=>Lt,Success:()=>Pt,effectPipe:()=>Rt,runEffect:()=>jt});const r=(t,e,s=!1)=>{if(s){let s,i=!0;return(...n)=>{i&&(t(...n),i=!1),s&&clearTimeout(s),s=setTimeout((()=>{clearTimeout(s),i=!0,s=null}),e)}}{let s;return(...i)=>{s&&(clearTimeout(s),s=null),s=setTimeout((()=>{t(...i),clearTimeout(s),i=null,s=null}),e)}}},o=t=>parseInt(t.replace("#",""),16),a=t=>{let e;e="string"==typeof t?o(t):t;const s=e.toString(2).padStart(24,"0");return[parseInt(s.slice(0,8),2),parseInt(s.slice(8,16),2),parseInt(s.slice(16,24),2)]},h=t=>"#"+[0,1,2].map((e=>t[e].toString(16))).join("");class c{int;constructor(t){"number"==typeof t?this.int=t:"string"==typeof t?this.int=o(t):Array.isArray(t)&&(this.int=o(h(t)))}getRgbArray(){return a(this.int)}get rgb(){return`rba(${this.getRgbArray().join(", ")})`}get hex(){return h(this.getRgbArray())}toString(t="hex"){return"rgb"===t?this.rgb:this.hex}}class u{base=[255,0,0];intensity=1;min;max;constructor({base:t=[255,0,0],intensity:e=1}={}){this.base=t,this.intensity=e,this.intensity<1&&(this.intensity=1),this.min=this.base[1],this.max=this.base[0],Math.abs(this.min-this.max)<1&&(this.min=0,this.max=255)}getColor(t){if(t<0)return this.base;let e=this.base[0],s=this.base[1],i=this.base[2],n=t*this.intensity;return s=this.base[1]+n,s<this.max||(n=s-this.max,s=this.max,e=this.base[0]-n,e>this.min||(n=this.min-e,e=this.min,i=this.base[2]+n,i<this.max||(n=i-this.max,i=this.max,s-=n,s>this.min||(n=this.min-s,s=this.min,e+=n,e<this.max||(n=e-this.max,e=this.max,i-=n,i>this.min||(i=this.min)))))),[e,s,i]}}const l=(t=8)=>{const e=t=>Math.random().toString(32).slice(2,2+t);if(t<=8)return e(t);let s="";for(let i=0;i<=t;i+=8)s+=e(t-i>8?8:t-i);return s},m=t=>{const e=Math.abs(t[1]-t[0]);return Math.random()*e+Math.min(...t)};class f{state={};ids={};on(t,e){if(this.state[t]||(this.state[t]={}),"function"!=typeof e)throw new Error("第二个参数必须为function!");const s=`${l(40)}_${(new Date).valueOf()}`;return this.state[t][s]=e,this.ids[s]=t,s}cancel(t){if(!t)return;const e=this.ids[t];e&&this.state[e]&&(delete this.state[e][t],0===Object.keys(this.state[e]).length&&delete this.state[e],delete this.ids[t])}clear(){this.state={},this.ids={}}emit(t,e){if(this.state[t])for(const s of Object.keys(this.state[t])){const i=this.state[t][s];"function"==typeof i&&i(e)}}async emitSync(t,e){if(this.state[t])for(const s of Object.keys(this.state[t])){const i=this.state[t][s];if("function"==typeof i)try{await i(e)}catch(t){console.log(t)}}}clone(){return{state:{...this.state},ids:{...this.ids}}}restore(t){this.state=t.state,this.ids=t.ids}}class p extends f{_cache={};emit(t,e){this._cache[t]=e,super.emit(t,e)}getState(t){return this._cache[t]}}const g=t=>e=>{const s={};for(const i of Object.keys(e))s[i]=t(e[i],i);return s},y=async t=>{await new Promise((e=>{let s=setTimeout((()=>{e(),clearTimeout(s),s=null}),t)}))},d=async(t,e=1e4)=>new Promise((async(s,i)=>{let n=!1;const r=setTimeout((()=>{n=!0,i(new Error("Timeout"))}),e);let o;try{o=await t(),clearTimeout(r)}catch(t){console.log(t),clearTimeout(r),n||i(t)}n||s(o)})),w=(t,e)=>{let s=!0;return(async()=>{for(;s;){try{await t()}catch(t){console.log(t)}await y(e)}})(),()=>s=!1},b=(t,{checkTime:e,timeout:s}={})=>new Promise(((i,n)=>{let r,o=w((async()=>{const e=await t();e&&("function"==typeof o&&o(),r&&(clearTimeout(r),r=null),i(e),o=null,t=null,i=null)}),e||100);s&&(r=setTimeout((()=>{"function"==typeof o&&o(),r&&(clearTimeout(r),r=null),n("timeout"),n=null,o=null,t=null}),s))})),M=async(t,{times:e=5,interval:s=1e3}={times:5,interval:1e3})=>{let i=1;const n=async()=>{let r;if(i>e)throw new Error("retry times exceed");try{return r=await t(),r}catch(t){console.log(`action error, times ${i}`),console.log(t),await y(s),i+=1,await n()}};await n()};class x{times;interval;action;count=1;args=[];result;canceled=!1;constructor(t,{times:e=5,interval:s=1e3}={times:5,interval:1e3}){this.interval=s,this.times=e,this.action=t}async _run(){if(this.canceled)throw new Error("retry canceled");if(this.count>this.times)throw new Error("retry times exceed");try{this.result=await this.action(...this.args)}catch(t){console.log(`action error, times ${this.count}`),console.log(t),await y(this.interval),this.count+=1,await this._run()}}async run(...t){return this.canceled=!1,this.result=null,this.count=1,this.args=t,await this._run(),this.args=[],this.count=1,this.result}async cancel(){this.canceled=!0}}class T{timeout;_start;_stop;fps;payload;constructor({start:t,stop:e,fps:s=5}){this._start=t,this._stop=e,this.fps=s}send(){this.payload&&this._start(this.payload)}control(t){this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.payload=t,this.send(),this.timeout=setTimeout((()=>this.stop()),1e3/this.fps)}stop(){this.payload=null,clearTimeout(this.timeout),this.timeout=null,this._stop()}}class _{cache=[];running=!1;len=0;async _run({fn:t,promise:e}){try{const s=await t();e.resolve(s)}catch(t){e.reject(t)}t=null,e=null}async run(){if(this.cache.length<1)return void(this.running=!1);this.running=!0;const t=this.cache.shift();this.len-=1,"function"==typeof t.fn&&await this._run(t),this.run()}push(t){return this.len+=1,new Promise(((e,s)=>{this.cache.push({fn:t,promise:{resolve:e,reject:s}}),this.running||this.run()}))}get length(){return this.len}}const A=async(t,e=4)=>{let s=-1;const i=[],n=async()=>{if(s+=1,t[s]){try{await t[s]()}catch(t){console.log(t)}await n()}};for(let t=0;t<e;t+=1)i.push(n());await Promise.all(i)};function v(t,e){const s=new _;let i=[];return(...n)=>{if(i=n,!(s.length>0))return s.push((async()=>{await y(e),await t(...i)}))}}class E{timeout;_count=0;props;constructor(t){this.props=t}get count(){return this._count}increment(){clearTimeout(this.timeout),this.timeout=setTimeout((()=>this.clear()),this.props.resetTime),this._count=this._count+1,this._count>this.props.count&&this.props.cb()}clear(){clearTimeout(this.timeout),this._count=0,this.timeout=0}}const S=function(){const t={};for(let e=0;e<64;e++)t["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(e)]=e;return t}();function P(t){const e=new Uint8Array(6*t.length/8);let s=0,i=0,n=0;for(let r=0;r<t.length&&n<e.length;r+=1)if(i=(i<<6)+S[t.charAt(r)],s+=6,s>=8){s-=8;let t=i>>>s;e[n++]=255&t,t<<=s,i-=t}return e}class L{stack=[];len=10;point=0;constructor(t=10){this.len=t}get current(){if(this.point<this.stack.length&&this.point>-1)return this.stack[this.point]}clear(){this.stack.length=0,this.point=0}backup(t){this.point>0&&this.stack.length>0&&(this.stack.splice(0,this.point),this.point=0),this.stack.unshift(t),this.stack.length>this.len&&this.stack.pop()}undo(){return this.point<this.stack.length-1&&(this.point+=1),this.current}redo(){return this.point>0&&(this.point-=1),this.current}}class k{onTimeout;timeout=null;_time;constructor({limit:t=10,onTimeout:e}){this._time=1e3*t,this.onTimeout=()=>{this.timeout&&(clearTimeout(this.timeout),this.timeout=null),e()}}feed(){this.init()}init(){clearTimeout(this.timeout),this.timeout=null,delete this.timeout,this.timeout=setTimeout(this.onTimeout,this._time)}stop(){this.timeout&&clearTimeout(this.timeout),delete this.timeout}}class N{config;step;constructor(t){this.config=t,this.step=(this.config.max-this.config.min)/(this.config.count-2)}get(t){if(t<=this.config.min)return 1;if(t>=this.config.max)return this.config.count;for(let e=2,s=this.config.min+this.step;s<this.config.max+this.step;s+=this.step,e+=1)if(t<s)return e;return this.config.count}}const R=t=>(...e)=>new Promise(((s,i)=>{t(...e,((t,...e)=>{t&&i(t),e.length<2?s(e[0]):s([...e])})),t=null})),j=(t,e)=>Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)),O=t=>180*t/Math.PI,C=t=>t*Math.PI/180,z=({w:t,h:e})=>O(Math.atan2(e,t));function F(t,e=.5){if(t.length<3||e<=0)return t;let s;return t.filter(((i,n)=>!(n>0&&j(s,i)<e||(s=t[n],0))))}function U(t){const e=[0,0];for(const s of t)Array.isArray(s)?(e[0]+=s[0],e[1]+=s[1]):(e[0]+=s.x,e[1]+=s.y);return{x:e[0]/t.length,y:e[1]/t.length}}function I(t,e,s){return s&&(e=C(e)),[Math.cos(e)*t[0]-Math.sin(e)*t[1],Math.sin(e)*t[0]+Math.cos(e)*t[1]]}const D=(t,e)=>{const s={x:e.x-t.x,y:e.y-t.y};return Math.atan2(s.y,s.x)},B=(t,e)=>{if(t.length<2)return 0;const s=[];let i=1/0,n=0;for(const r of t){const t=j(r,e),o=D(e,r)-e.theta;i>t&&(i=t),s.push({...r,index:n,distance:t,theta:o}),n+=1}return s.filter((t=>t.distance-i<.1)).sort(((t,e)=>t.theta-e.theta))[0].index},q=(t,e={x:0,y:0,theta:0})=>{let s=e;const i=[],n=[...t];for(;n.length>0;){const t=B(n,s);i.push(n[t]),s=n[t],n.splice(t,1)}return i},X=(t,e)=>Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x),W=t=>t.split("_").map(((t,e)=>e>0?t.slice(0,1).toUpperCase()+t.slice(1):t)).join(""),$=(t,e=2)=>null==t||"NaN"===t?"N/A":("number"!=typeof t&&(t=parseFloat(t)),isNaN(t)?"N/A":t.toFixed(e));class H{list;_RegExpList=null;constructor(t){this.list=t}getRegEXP(t){const e=t.replace("/","\\/").replace("*",".*");return new RegExp(e)}include(t){return this._RegExpList||(this._RegExpList=this.list.map(this.getRegEXP)),this._RegExpList.some((e=>e.test(t)))}}class K{tmp=[];size;step;min;max;count=0;value=NaN;old;constructor({size:t=5,step:e=5,min:s=-1/0,max:i=1/0}={}){this.size=t,this.step=e,this.min=s,this.max=i,this.old=this.min}filter(t){return t<this.min||t>this.max||(this.tmp.push(t),this.old=this.calc(t)),this.old}calc(t){if(this.tmp.length<1)return t;this.tmp.length>this.size&&this.tmp.shift();const{res:e,dic:s}=this.getMostNumberOfTmp();return e!==t&&Math.abs(e-t)>this.step?(this.value!==t?this.count=1:this.count+=1,this.value=t,this.count>s[e]?(this.tmp.length=0,this.tmp.push(t),this.count=0,this.value=NaN,t):e):(this.count=0,this.value=NaN,t)}getMostNumberOfTmp(){const t={};let e,s=0;for(const i of this.tmp)t[i]?t[i]+=1:t[i]=1,t[i]>=s&&(s=t[i],e=i);return{res:e,dic:t}}}class Q{_splitSymbol;_cache="";constructor(t){this._splitSymbol=t}split(t){const e=(this._cache+t).split(this._splitSymbol);return this._cache=e.splice(e.length-1,1)[0],e}}function V(t,e=new WeakMap){if("object"!=typeof t||null===t)return t;if(e.has(t))return e.get(t);if(Array.isArray(t)){const s=t.map((t=>V(t,e)));return e.set(t,s),s}if(t instanceof Set){const s=new Set([...t].map((t=>V(t,e))));return e.set(t,s),s}if(t instanceof Map){const s=new Map;for(const[i,n]of t.entries())s.set(V(i,e),V(n,e));return e.set(t,s),s}{const s={};e.set(t,s);for(const i in t)Object.prototype.hasOwnProperty.call(t,i)&&(s[i]=V(t[i],e));return s}}function Z(t,e){if(e.length<1)return null;let s;Array.isArray(t)&&(s={children:t});for(const t of e)s=s.children[t];return V(s)}function G(t,e,s="children"){const i=[];let n=!1;const r=t=>{for(let o=0;o<t.length;o+=1){const a=t[o];if(e(a)){n=!0,i.push(o);break}if(Array.isArray(a[s])){if(i.push(o),r(a[s]),n)break;i.pop()}}};return Array.isArray(t)?r(t):Array.isArray(t[s])&&r(t[s]),n?i:[]}const J=(t,e="children",s=[],i=[])=>{let n=[];return Array.isArray(t[e])?n=t[e]:Array.isArray(t)&&(n=t),n.forEach(((t,n)=>{const r={...t};delete r[e],i.push(r),r.__indexes=[...s,n]})),n.forEach(((t,n)=>J(t,e,[...s,n],i))),i},Y=(t,e,s="children")=>{const i=[];let n=[];return Array.isArray(t[s])?n=t[s]:Array.isArray(t)&&(n=t),n.forEach((t=>{var n;t[s]&&(t[s]=Y(t[s],e)),((null===(n=t[s])||void 0===n?void 0:n.length)>0||e(t))&&i.push(t)})),i},tt=t=>{const e={};for(const s of Object.keys(t))e[t[s]]=s;return e},et=.9996,st=.00669438,it=Math.pow(st,2),nt=Math.pow(st,3),rt=st/(1-st),ot=Math.sqrt(1-st),at=(1-ot)/(1+ot),ht=Math.pow(at,2),ct=Math.pow(at,3),ut=Math.pow(at,4),lt=Math.pow(at,5),mt=1-st/4-3*it/64-5*nt/256,ft=3*st/8+3*it/32+45*nt/1024,pt=15*it/256+45*nt/1024,gt=35*nt/3072,yt=1.5*at-27/32*ct+269/512*lt,dt=21/16*ht-55/32*ut,wt=151/96*ct-417/128*lt,bt=1097/512*ut,Mt=6378137,xt="CDEFGHJKLMNPQRSTUVWXX";function Tt(t){const{zoneNum:e,strict:s=!0}=t;let{zoneLetter:i,northern:n}=t;const r=t.x,o=t.y;if(!i&&void 0===n)throw new Error("either zoneLetter or northern needs to be set");if(i&&void 0!==n)throw new Error("set either zoneLetter or northern, but not both");if(s){if(r<1e5||1e6<=r)throw new RangeError("easting out of range (must be between 100 000 m and 999 999 m)");if(o<0||o>1e7)throw new RangeError("northing out of range (must be between 0 m and 10 000 000 m)")}if(e<1||e>60)throw new RangeError("zone number out of range (must be between 1 and 60)");if(i){if(i=i.toUpperCase(),1!==i.length||-1===xt.indexOf(i))throw new RangeError("zone letter out of range (must be between C and X)");n=i>="N"}const a=r-5e5;let h=o;n||(h-=1e7);const c=h/et/(Mt*mt),u=c+yt*Math.sin(2*c)+dt*Math.sin(4*c)+wt*Math.sin(6*c)+bt*Math.sin(8*c),l=Math.sin(u),m=Math.pow(l,2),f=Math.cos(u),p=Math.tan(u),g=Math.pow(p,2),y=Math.pow(p,4),d=1-st*m,w=Math.sqrt(d),b=(1-st)/d,M=at*f*f,x=M*M,T=a/(Mt/w*et),_=Math.pow(T,2),A=Math.pow(T,3),v=Math.pow(T,4),E=Math.pow(T,5),S=Math.pow(T,6),P=(T-A/6*(1+2*g+M)+E/120*(5-2*M+28*g-3*x+8*rt+24*y))/f;return{latitude:O(u-p/b*(_/2-v/24*(5+3*g+10*M-4*x-9*rt))+S/720*(61+90*g+298*M+45*y-252*rt-3*x)),longitude:O(P)+Et(e)}}function _t({latitude:t,longitude:e},s){if(t>84||t<-80)throw new RangeError("latitude out of range (must be between 80 deg S and 84 deg N)");if(e>180||e<-180)throw new RangeError("longitude out of range (must be between 180 deg W and 180 deg E)");const i=C(t),n=Math.sin(i),r=Math.cos(i),o=Math.tan(i),a=Math.pow(o,2),h=Math.pow(o,4);let c;c=void 0===s?vt({latitude:t,longitude:e}):s;const u=At(t),l=C(e),m=Et(c),f=C(m),p=Mt/Math.sqrt(1-st*n*n),g=rt*r*r,y=r*(l-f),d=Math.pow(y,2),w=Math.pow(y,3),b=Math.pow(y,4),M=Math.pow(y,5),x=Math.pow(y,6),T=Mt*(mt*i-ft*Math.sin(2*i)+pt*Math.sin(4*i)-gt*Math.sin(6*i));let _=et*(T+p*o*(d/2+b/24*(5-a+9*g+4*g*g)+x/720*(61-58*a+h+600*g-330*rt)));return t<0&&(_+=1e7),{x:et*p*(y+w/6*(1-a+g)+M/120*(5-18*a+h+72*g-58*rt))+5e5,y:_,zoneNum:c,zoneLetter:u}}function At(t){return-80<=t&&t<=84?xt[Math.floor((t+80)/8)]:null}function vt({latitude:t,longitude:e}){if(56<=t&&t<64&&3<=e&&e<12)return 32;if(72<=t&&t<=84&&e>=0){if(e<9)return 31;if(e<21)return 33;if(e<33)return 35;if(e<42)return 37}return Math.floor((e+180)/6)+1}function Et(t){return 6*(t-1)-180+3}class St{cache=Buffer.alloc(0);c;constructor(t){this.c=t}push(t){const e=Buffer.concat([this.cache,t]),s=[];let i=0;for(let t=this.cache.byteLength;t<=e.byteLength-this.c.byteLength;t+=1)if(this.c.equals(e.subarray(t,this.c.byteLength+t))){const n=e.subarray(i,t);s.push(n),i=this.c.byteLength+t,t=this.c.byteLength+t}return this.cache=e.subarray(i),s}}const Pt=t=>({type:"Success",value:t}),Lt=t=>({type:"Failure",error:t}),kt=(t,e)=>({type:"Command",cmd:t,next:e}),Nt=(t,e)=>{switch(t.type){case"Success":return e(t.value);case"Failure":return t;case"Command":const s=s=>Nt(t.next(s),e);return kt(t.cmd,s)}},Rt=(...t)=>e=>t.reduce(Nt,Pt(e));async function jt(t){for(;"Command"===t.type;)try{t=t.next(await t.cmd())}catch(t){return Lt(t)}return t}return e})()));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.PuboUtils=e():t.PuboUtils=e()}(this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{Base64Utils:()=>s,BufferSplit:()=>vt,CacheEmitter:()=>d,ColorUtils:()=>l,ContinuousTrigger:()=>A,Emitter:()=>f,FP:()=>n,HistoryStack:()=>C,Level:()=>O,LinearColor:()=>u,RegExpList:()=>$,RemoteControl:()=>E,ResourceHandler:()=>r.ResourceHandler,ResourceHandlerParams:()=>r.ResourceHandlerParams,ResourceHandlerState:()=>Lt,ResourceManager:()=>kt,RetryPlus:()=>x,SensorDataFilter:()=>K,StringSplit:()=>Q,SyncQueue:()=>S,UTM:()=>i,WatchDog:()=>P,callbackToPromise:()=>R,cloneDeep:()=>V,debounce:()=>o,degrees:()=>L,filterKeyPoints:()=>F,filterTree:()=>tt,fixNum:()=>X,flatTree:()=>J,getAngle:()=>j,getBestPointIndex:()=>H,getCenter:()=>z,getDistance:()=>D,getPositionTheta:()=>G,getRotate:()=>U,getTreeItem:()=>Y,getVectorTheta:()=>B,hex2rgb:()=>h,loop:()=>b,lower2camel:()=>q,orderByDistance:()=>W,radians:()=>k,random:()=>m,randomRangeNum:()=>p,reflection:()=>et,retry:()=>T,runAsyncTasks:()=>_,searchTree:()=>Z,sleep:()=>y,superFactory:()=>g,throttle:()=>N,timeout:()=>w,waitFor:()=>M});var s={};t.r(s),t.d(s,{EncoderMap:()=>v,toUnit8Array:()=>I});var i={};t.r(i),t.d(i,{fromLatLon:()=>St,latLonToZoneNumber:()=>Nt,latitudeToZoneLetter:()=>_t,toLatLon:()=>Et});var n={};t.r(n),t.d(n,{Command:()=>Pt,Failure:()=>Ct,Success:()=>It,effectPipe:()=>Rt,runEffect:()=>Dt});var r={};t.r(r),t.d(r,{x:()=>Lt,f:()=>kt});const o=(t,e,s=!1)=>{if(s){let s,i=!0;return(...n)=>{i&&(t(...n),i=!1),s&&clearTimeout(s),s=setTimeout((()=>{clearTimeout(s),i=!0,s=null}),e)}}{let s;return(...i)=>{s&&(clearTimeout(s),s=null),s=setTimeout((()=>{t(...i),clearTimeout(s),i=null,s=null}),e)}}},a=t=>parseInt(t.replace("#",""),16),h=t=>{let e;e="string"==typeof t?a(t):t;const s=e.toString(2).padStart(24,"0");return[parseInt(s.slice(0,8),2),parseInt(s.slice(8,16),2),parseInt(s.slice(16,24),2)]},c=t=>"#"+[0,1,2].map((e=>t[e].toString(16))).join("");class l{int;constructor(t){"number"==typeof t?this.int=t:"string"==typeof t?this.int=a(t):Array.isArray(t)&&(this.int=a(c(t)))}getRgbArray(){return h(this.int)}get rgb(){return`rba(${this.getRgbArray().join(", ")})`}get hex(){return c(this.getRgbArray())}toString(t="hex"){return"rgb"===t?this.rgb:this.hex}}class u{base=[255,0,0];intensity=1;min;max;constructor({base:t=[255,0,0],intensity:e=1}={}){this.base=t,this.intensity=e,this.intensity<1&&(this.intensity=1),this.min=this.base[1],this.max=this.base[0],Math.abs(this.min-this.max)<1&&(this.min=0,this.max=255)}getColor(t){if(t<0)return this.base;let e=this.base[0],s=this.base[1],i=this.base[2],n=t*this.intensity;return s=this.base[1]+n,s<this.max||(n=s-this.max,s=this.max,e=this.base[0]-n,e>this.min||(n=this.min-e,e=this.min,i=this.base[2]+n,i<this.max||(n=i-this.max,i=this.max,s-=n,s>this.min||(n=this.min-s,s=this.min,e+=n,e<this.max||(n=e-this.max,e=this.max,i-=n,i>this.min||(i=this.min)))))),[e,s,i]}}const m=(t=8)=>{const e=t=>Math.random().toString(32).slice(2,2+t);if(t<=8)return e(t);let s="";for(let i=0;i<=t;i+=8)s+=e(t-i>8?8:t-i);return s},p=t=>{const e=Math.abs(t[1]-t[0]);return Math.random()*e+Math.min(...t)};class f{state={};ids={};on(t,e){if(this.state[t]||(this.state[t]={}),"function"!=typeof e)throw new Error("第二个参数必须为function!");const s=`${m(40)}_${(new Date).valueOf()}`;return this.state[t][s]=e,this.ids[s]=t,s}cancel(t){if(!t)return;const e=this.ids[t];e&&this.state[e]&&(delete this.state[e][t],0===Object.keys(this.state[e]).length&&delete this.state[e],delete this.ids[t])}clear(){this.state={},this.ids={}}emit(t,e){if(this.state[t])for(const s of Object.keys(this.state[t])){const i=this.state[t][s];"function"==typeof i&&i(e)}}async emitSync(t,e){if(this.state[t])for(const s of Object.keys(this.state[t])){const i=this.state[t][s];if("function"==typeof i)try{await i(e)}catch(t){console.log(t)}}}clone(){return{state:{...this.state},ids:{...this.ids}}}restore(t){this.state=t.state,this.ids=t.ids}}class d extends f{_cache={};emit(t,e){this._cache[t]=e,super.emit(t,e)}getState(t){return this._cache[t]}}const g=t=>e=>{const s={};for(const i of Object.keys(e))s[i]=t(e[i],i);return s},y=async t=>{await new Promise((e=>{let s=setTimeout((()=>{e(),clearTimeout(s),s=null}),t)}))},w=async(t,e=1e4)=>new Promise((async(s,i)=>{let n=!1;const r=setTimeout((()=>{n=!0,i(new Error("Timeout"))}),e);let o;try{o=await t(),clearTimeout(r)}catch(t){console.log(t),clearTimeout(r),n||i(t)}n||s(o)})),b=(t,e)=>{let s=!0;return(async()=>{for(;s;){try{await t()}catch(t){console.log(t)}await y(e)}})(),()=>s=!1},M=(t,{checkTime:e,timeout:s}={})=>new Promise(((i,n)=>{let r,o=b((async()=>{const e=await t();e&&("function"==typeof o&&o(),r&&(clearTimeout(r),r=null),i(e),o=null,t=null,i=null)}),e||100);s&&(r=setTimeout((()=>{"function"==typeof o&&o(),r&&(clearTimeout(r),r=null),n("timeout"),n=null,o=null,t=null}),s))})),T=async(t,{times:e=5,interval:s=1e3}={times:5,interval:1e3})=>{let i=1;const n=async()=>{let r;if(i>e)throw new Error("retry times exceed");try{return r=await t(),r}catch(t){console.log(`action error, times ${i}`),console.log(t),await y(s),i+=1,await n()}};await n()};class x{times;interval;action;count=1;args=[];result;canceled=!1;constructor(t,{times:e=5,interval:s=1e3}={times:5,interval:1e3}){this.interval=s,this.times=e,this.action=t}async _run(){if(this.canceled)throw new Error("retry canceled");if(this.count>this.times)throw new Error("retry times exceed");try{this.result=await this.action(...this.args)}catch(t){console.log(`action error, times ${this.count}`),console.log(t),await y(this.interval),this.count+=1,await this._run()}}async run(...t){return this.canceled=!1,this.result=null,this.count=1,this.args=t,await this._run(),this.args=[],this.count=1,this.result}async cancel(){this.canceled=!0}}class E{timeout;_start;_stop;fps;payload;constructor({start:t,stop:e,fps:s=5}){this._start=t,this._stop=e,this.fps=s}send(){this.payload&&this._start(this.payload)}control(t){this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.payload=t,this.send(),this.timeout=setTimeout((()=>this.stop()),1e3/this.fps)}stop(){this.payload=null,clearTimeout(this.timeout),this.timeout=null,this._stop()}}class S{cache=[];running=!1;len=0;async _run({fn:t,promise:e}){try{const s=await t();e.resolve(s)}catch(t){e.reject(t)}t=null,e=null}async run(){if(this.cache.length<1)return void(this.running=!1);this.running=!0;const t=this.cache.shift();this.len-=1,"function"==typeof t.fn&&await this._run(t),this.run()}push(t){return this.len+=1,new Promise(((e,s)=>{this.cache.push({fn:t,promise:{resolve:e,reject:s}}),this.running||this.run()}))}get length(){return this.len}}const _=async(t,e=4)=>{let s=-1;const i=[],n=async()=>{if(s+=1,t[s]){try{await t[s]()}catch(t){console.log(t)}await n()}};for(let t=0;t<e;t+=1)i.push(n());await Promise.all(i)};function N(t,e){const s=new S;let i=[];return(...n)=>{if(i=n,!(s.length>0))return s.push((async()=>{await y(e),await t(...i)}))}}class A{timeout;_count=0;props;constructor(t){this.props=t}get count(){return this._count}increment(){clearTimeout(this.timeout),this.timeout=setTimeout((()=>this.clear()),this.props.resetTime),this._count=this._count+1,this._count>this.props.count&&this.props.cb()}clear(){clearTimeout(this.timeout),this._count=0,this.timeout=0}}const v=function(){const t={};for(let e=0;e<64;e++)t["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(e)]=e;return t}();function I(t){const e=new Uint8Array(6*t.length/8);let s=0,i=0,n=0;for(let r=0;r<t.length&&n<e.length;r+=1)if(i=(i<<6)+v[t.charAt(r)],s+=6,s>=8){s-=8;let t=i>>>s;e[n++]=255&t,t<<=s,i-=t}return e}class C{stack=[];len=10;point=0;constructor(t=10){this.len=t}get current(){if(this.point<this.stack.length&&this.point>-1)return this.stack[this.point]}clear(){this.stack.length=0,this.point=0}backup(t){this.point>0&&this.stack.length>0&&(this.stack.splice(0,this.point),this.point=0),this.stack.unshift(t),this.stack.length>this.len&&this.stack.pop()}undo(){return this.point<this.stack.length-1&&(this.point+=1),this.current}redo(){return this.point>0&&(this.point-=1),this.current}}class P{onTimeout;timeout=null;_time;constructor({limit:t=10,onTimeout:e}){this._time=1e3*t,this.onTimeout=()=>{this.timeout&&(clearTimeout(this.timeout),this.timeout=null),e()}}feed(){this.init()}init(){clearTimeout(this.timeout),this.timeout=null,delete this.timeout,this.timeout=setTimeout(this.onTimeout,this._time)}stop(){this.timeout&&clearTimeout(this.timeout),delete this.timeout}}class O{config;step;constructor(t){this.config=t,this.step=(this.config.max-this.config.min)/(this.config.count-2)}get(t){if(t<=this.config.min)return 1;if(t>=this.config.max)return this.config.count;for(let e=2,s=this.config.min+this.step;s<this.config.max+this.step;s+=this.step,e+=1)if(t<s)return e;return this.config.count}}const R=t=>(...e)=>new Promise(((s,i)=>{t(...e,((t,...e)=>{t&&i(t),e.length<2?s(e[0]):s([...e])})),t=null})),D=(t,e)=>Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2)),L=t=>180*t/Math.PI,k=t=>t*Math.PI/180,j=({w:t,h:e})=>L(Math.atan2(e,t));function F(t,e=.5){if(t.length<3||e<=0)return t;let s;return t.filter(((i,n)=>!(n>0&&D(s,i)<e||(s=t[n],0))))}function z(t){const e=[0,0];for(const s of t)Array.isArray(s)?(e[0]+=s[0],e[1]+=s[1]):(e[0]+=s.x,e[1]+=s.y);return{x:e[0]/t.length,y:e[1]/t.length}}function U(t,e,s){return s&&(e=k(e)),[Math.cos(e)*t[0]-Math.sin(e)*t[1],Math.sin(e)*t[0]+Math.cos(e)*t[1]]}const G=(t,e)=>{const s={x:e.x-t.x,y:e.y-t.y};return Math.atan2(s.y,s.x)},H=(t,e)=>{if(t.length<2)return 0;const s=[];let i=1/0,n=0;for(const r of t){const t=D(r,e),o=G(e,r)-e.theta;i>t&&(i=t),s.push({...r,index:n,distance:t,theta:o}),n+=1}return s.filter((t=>t.distance-i<.1)).sort(((t,e)=>t.theta-e.theta))[0].index},W=(t,e={x:0,y:0,theta:0})=>{let s=e;const i=[],n=[...t];for(;n.length>0;){const t=H(n,s);i.push(n[t]),s=n[t],n.splice(t,1)}return i},B=(t,e)=>Math.atan2(e.y,e.x)-Math.atan2(t.y,t.x),q=t=>t.split("_").map(((t,e)=>e>0?t.slice(0,1).toUpperCase()+t.slice(1):t)).join(""),X=(t,e=2)=>null==t||"NaN"===t?"N/A":("number"!=typeof t&&(t=parseFloat(t)),isNaN(t)?"N/A":t.toFixed(e));class ${list;_RegExpList=null;constructor(t){this.list=t}getRegEXP(t){const e=t.replace("/","\\/").replace("*",".*");return new RegExp(e)}include(t){return this._RegExpList||(this._RegExpList=this.list.map(this.getRegEXP)),this._RegExpList.some((e=>e.test(t)))}}class K{tmp=[];size;step;min;max;count=0;value=NaN;old;constructor({size:t=5,step:e=5,min:s=-1/0,max:i=1/0}={}){this.size=t,this.step=e,this.min=s,this.max=i,this.old=this.min}filter(t){return t<this.min||t>this.max||(this.tmp.push(t),this.old=this.calc(t)),this.old}calc(t){if(this.tmp.length<1)return t;this.tmp.length>this.size&&this.tmp.shift();const{res:e,dic:s}=this.getMostNumberOfTmp();return e!==t&&Math.abs(e-t)>this.step?(this.value!==t?this.count=1:this.count+=1,this.value=t,this.count>s[e]?(this.tmp.length=0,this.tmp.push(t),this.count=0,this.value=NaN,t):e):(this.count=0,this.value=NaN,t)}getMostNumberOfTmp(){const t={};let e,s=0;for(const i of this.tmp)t[i]?t[i]+=1:t[i]=1,t[i]>=s&&(s=t[i],e=i);return{res:e,dic:t}}}class Q{_splitSymbol;_cache="";constructor(t){this._splitSymbol=t}split(t){const e=(this._cache+t).split(this._splitSymbol);return this._cache=e.splice(e.length-1,1)[0],e}}function V(t,e=new WeakMap){if("object"!=typeof t||null===t)return t;if(e.has(t))return e.get(t);if(Array.isArray(t)){const s=t.map((t=>V(t,e)));return e.set(t,s),s}if(t instanceof Set){const s=new Set([...t].map((t=>V(t,e))));return e.set(t,s),s}if(t instanceof Map){const s=new Map;for(const[i,n]of t.entries())s.set(V(i,e),V(n,e));return e.set(t,s),s}{const s={};e.set(t,s);for(const i in t)Object.prototype.hasOwnProperty.call(t,i)&&(s[i]=V(t[i],e));return s}}function Y(t,e){if(e.length<1)return null;let s;Array.isArray(t)&&(s={children:t});for(const t of e)s=s.children[t];return V(s)}function Z(t,e,s="children"){const i=[];let n=!1;const r=t=>{for(let o=0;o<t.length;o+=1){const a=t[o];if(e(a)){n=!0,i.push(o);break}if(Array.isArray(a[s])){if(i.push(o),r(a[s]),n)break;i.pop()}}};return Array.isArray(t)?r(t):Array.isArray(t[s])&&r(t[s]),n?i:[]}const J=(t,e="children",s=[],i=[])=>{let n=[];return Array.isArray(t[e])?n=t[e]:Array.isArray(t)&&(n=t),n.forEach(((t,n)=>{const r={...t};delete r[e],i.push(r),r.__indexes=[...s,n]})),n.forEach(((t,n)=>J(t,e,[...s,n],i))),i},tt=(t,e,s="children")=>{const i=[];let n=[];return Array.isArray(t[s])?n=t[s]:Array.isArray(t)&&(n=t),n.forEach((t=>{var n;t[s]&&(t[s]=tt(t[s],e)),((null===(n=t[s])||void 0===n?void 0:n.length)>0||e(t))&&i.push(t)})),i},et=t=>{const e={};for(const s of Object.keys(t))e[t[s]]=s;return e},st=.9996,it=.00669438,nt=Math.pow(it,2),rt=Math.pow(it,3),ot=it/(1-it),at=Math.sqrt(1-it),ht=(1-at)/(1+at),ct=Math.pow(ht,2),lt=Math.pow(ht,3),ut=Math.pow(ht,4),mt=Math.pow(ht,5),pt=1-it/4-3*nt/64-5*rt/256,ft=3*it/8+3*nt/32+45*rt/1024,dt=15*nt/256+45*rt/1024,gt=35*rt/3072,yt=1.5*ht-27/32*lt+269/512*mt,wt=21/16*ct-55/32*ut,bt=151/96*lt-417/128*mt,Mt=1097/512*ut,Tt=6378137,xt="CDEFGHJKLMNPQRSTUVWXX";function Et(t){const{zoneNum:e,strict:s=!0}=t;let{zoneLetter:i,northern:n}=t;const r=t.x,o=t.y;if(!i&&void 0===n)throw new Error("either zoneLetter or northern needs to be set");if(i&&void 0!==n)throw new Error("set either zoneLetter or northern, but not both");if(s){if(r<1e5||1e6<=r)throw new RangeError("easting out of range (must be between 100 000 m and 999 999 m)");if(o<0||o>1e7)throw new RangeError("northing out of range (must be between 0 m and 10 000 000 m)")}if(e<1||e>60)throw new RangeError("zone number out of range (must be between 1 and 60)");if(i){if(i=i.toUpperCase(),1!==i.length||-1===xt.indexOf(i))throw new RangeError("zone letter out of range (must be between C and X)");n=i>="N"}const a=r-5e5;let h=o;n||(h-=1e7);const c=h/st/(Tt*pt),l=c+yt*Math.sin(2*c)+wt*Math.sin(4*c)+bt*Math.sin(6*c)+Mt*Math.sin(8*c),u=Math.sin(l),m=Math.pow(u,2),p=Math.cos(l),f=Math.tan(l),d=Math.pow(f,2),g=Math.pow(f,4),y=1-it*m,w=Math.sqrt(y),b=(1-it)/y,M=ht*p*p,T=M*M,x=a/(Tt/w*st),E=Math.pow(x,2),S=Math.pow(x,3),_=Math.pow(x,4),N=Math.pow(x,5),A=Math.pow(x,6),v=(x-S/6*(1+2*d+M)+N/120*(5-2*M+28*d-3*T+8*ot+24*g))/p;return{latitude:L(l-f/b*(E/2-_/24*(5+3*d+10*M-4*T-9*ot))+A/720*(61+90*d+298*M+45*g-252*ot-3*T)),longitude:L(v)+At(e)}}function St({latitude:t,longitude:e},s){if(t>84||t<-80)throw new RangeError("latitude out of range (must be between 80 deg S and 84 deg N)");if(e>180||e<-180)throw new RangeError("longitude out of range (must be between 180 deg W and 180 deg E)");const i=k(t),n=Math.sin(i),r=Math.cos(i),o=Math.tan(i),a=Math.pow(o,2),h=Math.pow(o,4);let c;c=void 0===s?Nt({latitude:t,longitude:e}):s;const l=_t(t),u=k(e),m=At(c),p=k(m),f=Tt/Math.sqrt(1-it*n*n),d=ot*r*r,g=r*(u-p),y=Math.pow(g,2),w=Math.pow(g,3),b=Math.pow(g,4),M=Math.pow(g,5),T=Math.pow(g,6),x=Tt*(pt*i-ft*Math.sin(2*i)+dt*Math.sin(4*i)-gt*Math.sin(6*i));let E=st*(x+f*o*(y/2+b/24*(5-a+9*d+4*d*d)+T/720*(61-58*a+h+600*d-330*ot)));return t<0&&(E+=1e7),{x:st*f*(g+w/6*(1-a+d)+M/120*(5-18*a+h+72*d-58*ot))+5e5,y:E,zoneNum:c,zoneLetter:l}}function _t(t){return-80<=t&&t<=84?xt[Math.floor((t+80)/8)]:null}function Nt({latitude:t,longitude:e}){if(56<=t&&t<64&&3<=e&&e<12)return 32;if(72<=t&&t<=84&&e>=0){if(e<9)return 31;if(e<21)return 33;if(e<33)return 35;if(e<42)return 37}return Math.floor((e+180)/6)+1}function At(t){return 6*(t-1)-180+3}class vt{cache=Buffer.alloc(0);c;constructor(t){this.c=t}push(t){const e=Buffer.concat([this.cache,t]),s=[];let i=0;for(let t=this.cache.byteLength;t<=e.byteLength-this.c.byteLength;t+=1)if(this.c.equals(e.subarray(t,this.c.byteLength+t))){const n=e.subarray(i,t);s.push(n),i=this.c.byteLength+t,t=this.c.byteLength+t}return this.cache=e.subarray(i),s}}const It=t=>({type:"Success",value:t}),Ct=t=>({type:"Failure",error:t}),Pt=(t,e)=>({type:"Command",cmd:t,next:e}),Ot=(t,e)=>{switch(t.type){case"Success":return e(t.value);case"Failure":return t;case"Command":const s=s=>Ot(t.next(s),e);return Pt(t.cmd,s)}},Rt=(...t)=>e=>t.reduce(Ot,It(e));async function Dt(t){for(;"Command"===t.type;)try{t=t.next(await t.cmd())}catch(t){return Ct(t)}return t}var Lt=function(t){return t[t.DISCONNECTED=0]="DISCONNECTED",t[t.CONNECTING=1]="CONNECTING",t[t.CONNECTED=2]="CONNECTED",t[t.DISPOSING=3]="DISPOSING",t[t.DISPOSED=4]="DISPOSED",t}({});class kt{options;handler;handlerInstance=null;connections=0;disposeTimer=null;static WAIT_CONFIG={checkTime:500,timeout:3e4};static DISPOSE_DELAY=6e4;constructor(t,e){this.handler=t,this.options=e}async run(t){this.clearDisposeTimer(),this.connections++;try{return await this.ensureConnected(),await this.handlerInstance.run(t)}finally{this.handleConnectionEnd()}}async ensureConnected(){var t;4===(null===(t=this.handlerInstance)||void 0===t?void 0:t.getState())&&(this.handlerInstance=null),this.handlerInstance?await M((()=>3!==this.handlerInstance.getState()),kt.WAIT_CONFIG):this.handlerInstance=new this.handler(this.options),await M((()=>2===this.handlerInstance.getState()),kt.WAIT_CONFIG)}clearDisposeTimer(){this.disposeTimer&&(clearTimeout(this.disposeTimer),this.disposeTimer=null)}handleConnectionEnd(){this.connections=Math.max(0,this.connections-1),0===this.connections&&(this.clearDisposeTimer(),this.disposeTimer=setTimeout((()=>this.dispose()),kt.DISPOSE_DELAY))}dispose(){this.handlerInstance&&(this.handlerInstance.dispose(),this.handlerInstance=null),this.disposeTimer=null}}return e})()));
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface ResourceHandlerParams {
|
|
2
|
+
service: string;
|
|
3
|
+
payload: unknown;
|
|
4
|
+
}
|
|
5
|
+
export declare enum ResourceHandlerState {
|
|
6
|
+
DISCONNECTED = 0,
|
|
7
|
+
CONNECTING = 1,
|
|
8
|
+
CONNECTED = 2,
|
|
9
|
+
DISPOSING = 3,
|
|
10
|
+
DISPOSED = 4
|
|
11
|
+
}
|
|
12
|
+
/** 资源处理器接口定义 */
|
|
13
|
+
export interface ResourceHandler {
|
|
14
|
+
dispose(): void;
|
|
15
|
+
getState(): ResourceHandlerState;
|
|
16
|
+
run(request: ResourceHandlerParams): Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
/** 资源管理器 - 管理资源处理器的生命周期 */
|
|
19
|
+
export declare class ResourceManager {
|
|
20
|
+
private readonly options;
|
|
21
|
+
private readonly handler;
|
|
22
|
+
private handlerInstance;
|
|
23
|
+
private connections;
|
|
24
|
+
private disposeTimer;
|
|
25
|
+
private static readonly WAIT_CONFIG;
|
|
26
|
+
private static readonly DISPOSE_DELAY;
|
|
27
|
+
constructor(handler: any, options: unknown);
|
|
28
|
+
/**
|
|
29
|
+
* 执行请求
|
|
30
|
+
* @param params - 请求参数
|
|
31
|
+
* @returns 执行结果
|
|
32
|
+
* @throws 连接超时或执行错误
|
|
33
|
+
*/
|
|
34
|
+
run(params: ResourceHandlerParams): Promise<unknown>;
|
|
35
|
+
/** 确保资源处理器实例已连接 */
|
|
36
|
+
private ensureConnected;
|
|
37
|
+
/** 清理释放定时器 */
|
|
38
|
+
private clearDisposeTimer;
|
|
39
|
+
/** 处理连接结束 */
|
|
40
|
+
private handleConnectionEnd;
|
|
41
|
+
/** 释放资源处理器实例 */
|
|
42
|
+
dispose(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { waitFor } from 'pubo-utils';
|
|
2
|
+
export var ResourceHandlerState = /*#__PURE__*/ function(ResourceHandlerState) {
|
|
3
|
+
ResourceHandlerState[ResourceHandlerState["DISCONNECTED"] = 0] = "DISCONNECTED";
|
|
4
|
+
ResourceHandlerState[ResourceHandlerState["CONNECTING"] = 1] = "CONNECTING";
|
|
5
|
+
ResourceHandlerState[ResourceHandlerState["CONNECTED"] = 2] = "CONNECTED";
|
|
6
|
+
ResourceHandlerState[ResourceHandlerState["DISPOSING"] = 3] = "DISPOSING";
|
|
7
|
+
ResourceHandlerState[ResourceHandlerState["DISPOSED"] = 4] = "DISPOSED";
|
|
8
|
+
return ResourceHandlerState;
|
|
9
|
+
}({});
|
|
10
|
+
/** 资源管理器 - 管理资源处理器的生命周期 */ export class ResourceManager {
|
|
11
|
+
options;
|
|
12
|
+
handler;
|
|
13
|
+
handlerInstance = null;
|
|
14
|
+
connections = 0;
|
|
15
|
+
disposeTimer = null;
|
|
16
|
+
static WAIT_CONFIG = {
|
|
17
|
+
checkTime: 500,
|
|
18
|
+
timeout: 30000
|
|
19
|
+
};
|
|
20
|
+
static DISPOSE_DELAY = 60000;
|
|
21
|
+
constructor(handler, options){
|
|
22
|
+
this.handler = handler;
|
|
23
|
+
this.options = options;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 执行请求
|
|
27
|
+
* @param params - 请求参数
|
|
28
|
+
* @returns 执行结果
|
|
29
|
+
* @throws 连接超时或执行错误
|
|
30
|
+
*/ async run(params) {
|
|
31
|
+
this.clearDisposeTimer();
|
|
32
|
+
this.connections++;
|
|
33
|
+
try {
|
|
34
|
+
await this.ensureConnected();
|
|
35
|
+
return await this.handlerInstance.run(params);
|
|
36
|
+
} finally{
|
|
37
|
+
this.handleConnectionEnd();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** 确保资源处理器实例已连接 */ async ensureConnected() {
|
|
41
|
+
var _this_handlerInstance;
|
|
42
|
+
if (((_this_handlerInstance = this.handlerInstance) === null || _this_handlerInstance === void 0 ? void 0 : _this_handlerInstance.getState()) === 4) {
|
|
43
|
+
this.handlerInstance = null;
|
|
44
|
+
}
|
|
45
|
+
if (!this.handlerInstance) {
|
|
46
|
+
this.handlerInstance = new this.handler(this.options);
|
|
47
|
+
} else {
|
|
48
|
+
await waitFor(()=>this.handlerInstance.getState() !== 3, ResourceManager.WAIT_CONFIG);
|
|
49
|
+
}
|
|
50
|
+
await waitFor(()=>this.handlerInstance.getState() === 2, ResourceManager.WAIT_CONFIG);
|
|
51
|
+
}
|
|
52
|
+
/** 清理释放定时器 */ clearDisposeTimer() {
|
|
53
|
+
if (this.disposeTimer) {
|
|
54
|
+
clearTimeout(this.disposeTimer);
|
|
55
|
+
this.disposeTimer = null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** 处理连接结束 */ handleConnectionEnd() {
|
|
59
|
+
this.connections = Math.max(0, this.connections - 1);
|
|
60
|
+
if (this.connections === 0) {
|
|
61
|
+
this.clearDisposeTimer();
|
|
62
|
+
this.disposeTimer = setTimeout(()=>this.dispose(), ResourceManager.DISPOSE_DELAY);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** 释放资源处理器实例 */ dispose() {
|
|
66
|
+
if (this.handlerInstance) {
|
|
67
|
+
this.handlerInstance.dispose();
|
|
68
|
+
this.handlerInstance = null;
|
|
69
|
+
}
|
|
70
|
+
this.disposeTimer = null;
|
|
71
|
+
}
|
|
72
|
+
}
|
package/es/index.d.ts
CHANGED
|
@@ -21,3 +21,4 @@ export { cloneDeep, getTreeItem, searchTree, flatTree, filterTree, reflection }
|
|
|
21
21
|
export * as UTM from './math/utm';
|
|
22
22
|
export { BufferSplit } from './buf';
|
|
23
23
|
export * as FP from './fp';
|
|
24
|
+
export { ResourceHandlerParams, ResourceHandlerState, ResourceHandler, ResourceManager, } from './factory/resource-manager';
|
package/es/index.js
CHANGED
|
@@ -21,3 +21,4 @@ export { cloneDeep, getTreeItem, searchTree, flatTree, filterTree, reflection }
|
|
|
21
21
|
export * as UTM from './math/utm';
|
|
22
22
|
export { BufferSplit } from './buf';
|
|
23
23
|
export * as FP from './fp';
|
|
24
|
+
export { ResourceHandlerParams, ResourceHandlerState, ResourceHandler, ResourceManager } from './factory/resource-manager';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface ResourceHandlerParams {
|
|
2
|
+
service: string;
|
|
3
|
+
payload: unknown;
|
|
4
|
+
}
|
|
5
|
+
export declare enum ResourceHandlerState {
|
|
6
|
+
DISCONNECTED = 0,
|
|
7
|
+
CONNECTING = 1,
|
|
8
|
+
CONNECTED = 2,
|
|
9
|
+
DISPOSING = 3,
|
|
10
|
+
DISPOSED = 4
|
|
11
|
+
}
|
|
12
|
+
/** 资源处理器接口定义 */
|
|
13
|
+
export interface ResourceHandler {
|
|
14
|
+
dispose(): void;
|
|
15
|
+
getState(): ResourceHandlerState;
|
|
16
|
+
run(request: ResourceHandlerParams): Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
/** 资源管理器 - 管理资源处理器的生命周期 */
|
|
19
|
+
export declare class ResourceManager {
|
|
20
|
+
private readonly options;
|
|
21
|
+
private readonly handler;
|
|
22
|
+
private handlerInstance;
|
|
23
|
+
private connections;
|
|
24
|
+
private disposeTimer;
|
|
25
|
+
private static readonly WAIT_CONFIG;
|
|
26
|
+
private static readonly DISPOSE_DELAY;
|
|
27
|
+
constructor(handler: any, options: unknown);
|
|
28
|
+
/**
|
|
29
|
+
* 执行请求
|
|
30
|
+
* @param params - 请求参数
|
|
31
|
+
* @returns 执行结果
|
|
32
|
+
* @throws 连接超时或执行错误
|
|
33
|
+
*/
|
|
34
|
+
run(params: ResourceHandlerParams): Promise<unknown>;
|
|
35
|
+
/** 确保资源处理器实例已连接 */
|
|
36
|
+
private ensureConnected;
|
|
37
|
+
/** 清理释放定时器 */
|
|
38
|
+
private clearDisposeTimer;
|
|
39
|
+
/** 处理连接结束 */
|
|
40
|
+
private handleConnectionEnd;
|
|
41
|
+
/** 释放资源处理器实例 */
|
|
42
|
+
dispose(): void;
|
|
43
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
ResourceHandlerState: function() {
|
|
13
|
+
return ResourceHandlerState;
|
|
14
|
+
},
|
|
15
|
+
ResourceManager: function() {
|
|
16
|
+
return ResourceManager;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _puboutils = require("pubo-utils");
|
|
20
|
+
var ResourceHandlerState = /*#__PURE__*/ function(ResourceHandlerState) {
|
|
21
|
+
ResourceHandlerState[ResourceHandlerState["DISCONNECTED"] = 0] = "DISCONNECTED";
|
|
22
|
+
ResourceHandlerState[ResourceHandlerState["CONNECTING"] = 1] = "CONNECTING";
|
|
23
|
+
ResourceHandlerState[ResourceHandlerState["CONNECTED"] = 2] = "CONNECTED";
|
|
24
|
+
ResourceHandlerState[ResourceHandlerState["DISPOSING"] = 3] = "DISPOSING";
|
|
25
|
+
ResourceHandlerState[ResourceHandlerState["DISPOSED"] = 4] = "DISPOSED";
|
|
26
|
+
return ResourceHandlerState;
|
|
27
|
+
}({});
|
|
28
|
+
class ResourceManager {
|
|
29
|
+
options;
|
|
30
|
+
handler;
|
|
31
|
+
handlerInstance = null;
|
|
32
|
+
connections = 0;
|
|
33
|
+
disposeTimer = null;
|
|
34
|
+
static WAIT_CONFIG = {
|
|
35
|
+
checkTime: 500,
|
|
36
|
+
timeout: 30000
|
|
37
|
+
};
|
|
38
|
+
static DISPOSE_DELAY = 60000;
|
|
39
|
+
constructor(handler, options){
|
|
40
|
+
this.handler = handler;
|
|
41
|
+
this.options = options;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 执行请求
|
|
45
|
+
* @param params - 请求参数
|
|
46
|
+
* @returns 执行结果
|
|
47
|
+
* @throws 连接超时或执行错误
|
|
48
|
+
*/ async run(params) {
|
|
49
|
+
this.clearDisposeTimer();
|
|
50
|
+
this.connections++;
|
|
51
|
+
try {
|
|
52
|
+
await this.ensureConnected();
|
|
53
|
+
return await this.handlerInstance.run(params);
|
|
54
|
+
} finally{
|
|
55
|
+
this.handleConnectionEnd();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** 确保资源处理器实例已连接 */ async ensureConnected() {
|
|
59
|
+
var _this_handlerInstance;
|
|
60
|
+
if (((_this_handlerInstance = this.handlerInstance) === null || _this_handlerInstance === void 0 ? void 0 : _this_handlerInstance.getState()) === 4) {
|
|
61
|
+
this.handlerInstance = null;
|
|
62
|
+
}
|
|
63
|
+
if (!this.handlerInstance) {
|
|
64
|
+
this.handlerInstance = new this.handler(this.options);
|
|
65
|
+
} else {
|
|
66
|
+
await (0, _puboutils.waitFor)(()=>this.handlerInstance.getState() !== 3, ResourceManager.WAIT_CONFIG);
|
|
67
|
+
}
|
|
68
|
+
await (0, _puboutils.waitFor)(()=>this.handlerInstance.getState() === 2, ResourceManager.WAIT_CONFIG);
|
|
69
|
+
}
|
|
70
|
+
/** 清理释放定时器 */ clearDisposeTimer() {
|
|
71
|
+
if (this.disposeTimer) {
|
|
72
|
+
clearTimeout(this.disposeTimer);
|
|
73
|
+
this.disposeTimer = null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** 处理连接结束 */ handleConnectionEnd() {
|
|
77
|
+
this.connections = Math.max(0, this.connections - 1);
|
|
78
|
+
if (this.connections === 0) {
|
|
79
|
+
this.clearDisposeTimer();
|
|
80
|
+
this.disposeTimer = setTimeout(()=>this.dispose(), ResourceManager.DISPOSE_DELAY);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** 释放资源处理器实例 */ dispose() {
|
|
84
|
+
if (this.handlerInstance) {
|
|
85
|
+
this.handlerInstance.dispose();
|
|
86
|
+
this.handlerInstance = null;
|
|
87
|
+
}
|
|
88
|
+
this.disposeTimer = null;
|
|
89
|
+
}
|
|
90
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -21,3 +21,4 @@ export { cloneDeep, getTreeItem, searchTree, flatTree, filterTree, reflection }
|
|
|
21
21
|
export * as UTM from './math/utm';
|
|
22
22
|
export { BufferSplit } from './buf';
|
|
23
23
|
export * as FP from './fp';
|
|
24
|
+
export { ResourceHandlerParams, ResourceHandlerState, ResourceHandler, ResourceManager, } from './factory/resource-manager';
|
package/lib/index.js
CHANGED
|
@@ -45,6 +45,18 @@ _export(exports, {
|
|
|
45
45
|
RemoteControl: function() {
|
|
46
46
|
return _loop.RemoteControl;
|
|
47
47
|
},
|
|
48
|
+
ResourceHandler: function() {
|
|
49
|
+
return _resourcemanager.ResourceHandler;
|
|
50
|
+
},
|
|
51
|
+
ResourceHandlerParams: function() {
|
|
52
|
+
return _resourcemanager.ResourceHandlerParams;
|
|
53
|
+
},
|
|
54
|
+
ResourceHandlerState: function() {
|
|
55
|
+
return _resourcemanager.ResourceHandlerState;
|
|
56
|
+
},
|
|
57
|
+
ResourceManager: function() {
|
|
58
|
+
return _resourcemanager.ResourceManager;
|
|
59
|
+
},
|
|
48
60
|
RetryPlus: function() {
|
|
49
61
|
return _loop.RetryPlus;
|
|
50
62
|
},
|
|
@@ -183,6 +195,7 @@ const _object = require("./object");
|
|
|
183
195
|
const _utm = /*#__PURE__*/ _interop_require_wildcard(require("./math/utm"));
|
|
184
196
|
const _buf = require("./buf");
|
|
185
197
|
const _fp = /*#__PURE__*/ _interop_require_wildcard(require("./fp"));
|
|
198
|
+
const _resourcemanager = require("./factory/resource-manager");
|
|
186
199
|
function _getRequireWildcardCache(nodeInterop) {
|
|
187
200
|
if (typeof WeakMap !== "function") return null;
|
|
188
201
|
var cacheBabelInterop = new WeakMap();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pubo-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.202",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"module": "./es/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">=8.0.0"
|
|
20
20
|
},
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "6cab20969ce73935cf78b48ddecfab0adca48174",
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"del": "^5.1.0",
|
|
24
24
|
"eslint": "^8.42.0",
|