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 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
@@ -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.201",
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": "2b70f52fbccc90c61d200cb237244e762a7b106e",
21
+ "gitHead": "6cab20969ce73935cf78b48ddecfab0adca48174",
22
22
  "devDependencies": {
23
23
  "del": "^5.1.0",
24
24
  "eslint": "^8.42.0",