@dra2020/baseclient 1.0.13 → 1.0.14
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/LICENSE +21 -0
- package/README.md +37 -0
- package/dist/all/all.d.ts +36 -0
- package/dist/all/allclient.d.ts +18 -0
- package/dist/base.js +33010 -0
- package/dist/base.js.map +1 -0
- package/dist/baseclient.js +8991 -0
- package/dist/baseclient.js.map +1 -0
- package/dist/context/all.d.ts +1 -0
- package/dist/context/context.d.ts +13 -0
- package/dist/dbabstract/all.d.ts +1 -0
- package/dist/dbabstract/db.d.ts +83 -0
- package/dist/dbdynamo/all.d.ts +1 -0
- package/dist/dbdynamo/dbdynamo.d.ts +190 -0
- package/dist/filterexpr/all.d.ts +1 -0
- package/dist/filterexpr/filterexpr.d.ts +64 -0
- package/dist/fsm/all.d.ts +1 -0
- package/dist/fsm/fsm.d.ts +118 -0
- package/dist/fsmfile/all.d.ts +1 -0
- package/dist/fsmfile/fsmfile.d.ts +47 -0
- package/dist/jsonstream/all.d.ts +1 -0
- package/dist/jsonstream/jsonstream.d.ts +130 -0
- package/dist/lambda/all.d.ts +1 -0
- package/dist/lambda/env.d.ts +10 -0
- package/dist/lambda/lambda.d.ts +18 -0
- package/dist/logabstract/all.d.ts +1 -0
- package/dist/logabstract/log.d.ts +26 -0
- package/dist/logclient/all.d.ts +1 -0
- package/dist/logclient/log.d.ts +6 -0
- package/dist/logserver/all.d.ts +5 -0
- package/dist/logserver/log.d.ts +11 -0
- package/dist/logserver/logaccum.d.ts +154 -0
- package/dist/logserver/logblob.d.ts +24 -0
- package/dist/logserver/logconcat.d.ts +55 -0
- package/dist/logserver/logkey.d.ts +28 -0
- package/dist/memsqs/all.d.ts +4 -0
- package/dist/memsqs/client.d.ts +13 -0
- package/dist/memsqs/loopback.d.ts +11 -0
- package/dist/memsqs/orderedlist.d.ts +19 -0
- package/dist/memsqs/queue.d.ts +84 -0
- package/dist/memsqs/server.d.ts +37 -0
- package/dist/ot-editutil/all.d.ts +2 -0
- package/dist/ot-editutil/oteditutil.d.ts +14 -0
- package/dist/ot-editutil/otmaputil.d.ts +21 -0
- package/dist/ot-js/all.d.ts +9 -0
- package/dist/ot-js/otarray.d.ts +111 -0
- package/dist/ot-js/otclientengine.d.ts +38 -0
- package/dist/ot-js/otcomposite.d.ts +37 -0
- package/dist/ot-js/otcounter.d.ts +17 -0
- package/dist/ot-js/otengine.d.ts +22 -0
- package/dist/ot-js/otmap.d.ts +19 -0
- package/dist/ot-js/otserverengine.d.ts +38 -0
- package/dist/ot-js/otsession.d.ts +111 -0
- package/dist/ot-js/ottypes.d.ts +29 -0
- package/dist/poly/all.d.ts +15 -0
- package/dist/poly/blend.d.ts +1 -0
- package/dist/poly/boundbox.d.ts +16 -0
- package/dist/poly/cartesian.d.ts +5 -0
- package/dist/poly/graham-scan.d.ts +8 -0
- package/dist/poly/hash.d.ts +1 -0
- package/dist/poly/matrix.d.ts +24 -0
- package/dist/poly/minbound.d.ts +1 -0
- package/dist/poly/poly.d.ts +52 -0
- package/dist/poly/polybin.d.ts +5 -0
- package/dist/poly/polylabel.d.ts +7 -0
- package/dist/poly/polypack.d.ts +30 -0
- package/dist/poly/polyround.d.ts +1 -0
- package/dist/poly/polysimplify.d.ts +1 -0
- package/dist/poly/quad.d.ts +48 -0
- package/dist/poly/selfintersect.d.ts +1 -0
- package/dist/poly/shamos.d.ts +1 -0
- package/dist/poly/simplify.d.ts +2 -0
- package/dist/poly/topo.d.ts +46 -0
- package/dist/poly/union.d.ts +48 -0
- package/dist/storage/all.d.ts +4 -0
- package/dist/storage/datablob.d.ts +9 -0
- package/dist/storage/env.d.ts +10 -0
- package/dist/storage/splitsblob.d.ts +13 -0
- package/dist/storage/storage.d.ts +166 -0
- package/dist/storages3/all.d.ts +1 -0
- package/dist/storages3/s3.d.ts +62 -0
- package/dist/util/all.d.ts +5 -0
- package/dist/util/bintrie.d.ts +93 -0
- package/dist/util/countedhash.d.ts +19 -0
- package/dist/util/gradient.d.ts +15 -0
- package/dist/util/indexedarray.d.ts +15 -0
- package/dist/util/util.d.ts +68 -0
- package/docs/context.md +2 -0
- package/docs/dbabstract.md +2 -0
- package/docs/dbdynamo.md +2 -0
- package/docs/fsm.md +243 -0
- package/docs/fsmfile.md +2 -0
- package/docs/jsonstream.md +44 -0
- package/docs/lambda.md +2 -0
- package/docs/logabstract.md +2 -0
- package/docs/logclient.md +2 -0
- package/docs/logserver.md +2 -0
- package/docs/ot-editutil.md +2 -0
- package/docs/ot-js.md +95 -0
- package/docs/poly.md +103 -0
- package/docs/storage.md +2 -0
- package/docs/storages3.md +2 -0
- package/docs/util.md +2 -0
- package/lib/all/all.ts +41 -0
- package/lib/all/allclient.ts +19 -0
- package/lib/context/all.ts +1 -0
- package/lib/context/context.ts +82 -0
- package/lib/dbabstract/all.ts +1 -0
- package/lib/dbabstract/db.ts +246 -0
- package/lib/dbdynamo/all.ts +1 -0
- package/lib/dbdynamo/dbdynamo.ts +1551 -0
- package/lib/filterexpr/all.ts +1 -0
- package/lib/filterexpr/filterexpr.ts +625 -0
- package/lib/fsm/all.ts +1 -0
- package/lib/fsm/fsm.ts +549 -0
- package/lib/fsmfile/all.ts +1 -0
- package/lib/fsmfile/fsmfile.ts +236 -0
- package/lib/jsonstream/all.ts +1 -0
- package/lib/jsonstream/jsonstream.ts +940 -0
- package/lib/lambda/all.ts +1 -0
- package/lib/lambda/env.ts +13 -0
- package/lib/lambda/lambda.ts +120 -0
- package/lib/logabstract/all.ts +1 -0
- package/lib/logabstract/log.ts +55 -0
- package/lib/logclient/all.ts +1 -0
- package/lib/logclient/log.ts +105 -0
- package/lib/logserver/all.ts +5 -0
- package/lib/logserver/log.ts +565 -0
- package/lib/logserver/logaccum.ts +1445 -0
- package/lib/logserver/logblob.ts +84 -0
- package/lib/logserver/logconcat.ts +313 -0
- package/lib/logserver/logkey.ts +125 -0
- package/lib/memsqs/all.ts +4 -0
- package/lib/memsqs/client.ts +268 -0
- package/lib/memsqs/loopback.ts +64 -0
- package/lib/memsqs/orderedlist.ts +74 -0
- package/lib/memsqs/queue.ts +395 -0
- package/lib/memsqs/server.ts +262 -0
- package/lib/ot-editutil/all.ts +2 -0
- package/lib/ot-editutil/oteditutil.ts +180 -0
- package/lib/ot-editutil/otmaputil.ts +209 -0
- package/lib/ot-js/all.ts +9 -0
- package/lib/ot-js/otarray.ts +1168 -0
- package/lib/ot-js/otclientengine.ts +327 -0
- package/lib/ot-js/otcomposite.ts +247 -0
- package/lib/ot-js/otcounter.ts +145 -0
- package/lib/ot-js/otengine.ts +71 -0
- package/lib/ot-js/otmap.ts +144 -0
- package/lib/ot-js/otserverengine.ts +329 -0
- package/lib/ot-js/otsession.ts +199 -0
- package/lib/ot-js/ottypes.ts +98 -0
- package/lib/poly/all.ts +15 -0
- package/lib/poly/blend.ts +27 -0
- package/lib/poly/boundbox.ts +102 -0
- package/lib/poly/cartesian.ts +130 -0
- package/lib/poly/graham-scan.ts +401 -0
- package/lib/poly/hash.ts +15 -0
- package/lib/poly/matrix.ts +309 -0
- package/lib/poly/minbound.ts +211 -0
- package/lib/poly/poly.ts +767 -0
- package/lib/poly/polybin.ts +218 -0
- package/lib/poly/polylabel.ts +204 -0
- package/lib/poly/polypack.ts +458 -0
- package/lib/poly/polyround.ts +30 -0
- package/lib/poly/polysimplify.ts +24 -0
- package/lib/poly/quad.ts +272 -0
- package/lib/poly/selfintersect.ts +87 -0
- package/lib/poly/shamos.ts +297 -0
- package/lib/poly/simplify.ts +119 -0
- package/lib/poly/topo.ts +525 -0
- package/lib/poly/union.ts +371 -0
- package/lib/storage/all.ts +4 -0
- package/lib/storage/datablob.ts +36 -0
- package/lib/storage/env.ts +14 -0
- package/lib/storage/splitsblob.ts +63 -0
- package/lib/storage/storage.ts +604 -0
- package/lib/storages3/all.ts +1 -0
- package/lib/storages3/s3.ts +576 -0
- package/lib/util/all.ts +5 -0
- package/lib/util/bintrie.ts +603 -0
- package/lib/util/countedhash.ts +83 -0
- package/lib/util/gradient.ts +108 -0
- package/lib/util/indexedarray.ts +80 -0
- package/lib/util/util.ts +695 -0
- package/package.json +8 -8
package/lib/util/util.ts
ADDED
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
export type DateString = string;
|
|
2
|
+
export function Now(): DateString { return (new Date()).toJSON(); }
|
|
3
|
+
|
|
4
|
+
// polyfill
|
|
5
|
+
let hrtime: any = global && global.process && global.process.hrtime ? global.process.hrtime : null;
|
|
6
|
+
|
|
7
|
+
export class Elapsed
|
|
8
|
+
{
|
|
9
|
+
tStart: any;
|
|
10
|
+
tDur: any;
|
|
11
|
+
|
|
12
|
+
constructor(bStart: boolean = true)
|
|
13
|
+
{
|
|
14
|
+
this.tStart = undefined;
|
|
15
|
+
this.tDur = undefined;
|
|
16
|
+
if (bStart) this.start();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
start(): void
|
|
20
|
+
{
|
|
21
|
+
if (hrtime)
|
|
22
|
+
this.tStart = hrtime();
|
|
23
|
+
else
|
|
24
|
+
this.tStart = performance.now();
|
|
25
|
+
if (this.tDur) this.tDur = undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
end(): void
|
|
29
|
+
{
|
|
30
|
+
if (this.tStart === undefined) this.start();
|
|
31
|
+
if (hrtime)
|
|
32
|
+
this.tDur = hrtime(this.tStart);
|
|
33
|
+
else
|
|
34
|
+
this.tDur = performance.now() - this.tStart;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ms(): number
|
|
38
|
+
{
|
|
39
|
+
if (this.tDur === undefined) this.end();
|
|
40
|
+
if (hrtime)
|
|
41
|
+
return Math.round((this.tDur[0]*1000) + (this.tDur[1]/1000000));
|
|
42
|
+
else
|
|
43
|
+
return this.tDur;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
nano(): number
|
|
47
|
+
{
|
|
48
|
+
if (this.tDur === undefined) this.end();
|
|
49
|
+
if (hrtime)
|
|
50
|
+
return (this.tDur[0]*1000000000) + this.tDur[1];
|
|
51
|
+
else
|
|
52
|
+
return this.tDur * 1000000;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class MultiTimer
|
|
57
|
+
{
|
|
58
|
+
_overall: Elapsed;
|
|
59
|
+
_segment: Elapsed;
|
|
60
|
+
_msAggregate: number;
|
|
61
|
+
|
|
62
|
+
constructor(bStart: boolean = true)
|
|
63
|
+
{
|
|
64
|
+
this._overall = new Elapsed(bStart);
|
|
65
|
+
this._segment = new Elapsed(bStart);
|
|
66
|
+
this._msAggregate = 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
start(): void
|
|
70
|
+
{
|
|
71
|
+
this._overall.start();
|
|
72
|
+
this._segment = new Elapsed();
|
|
73
|
+
this._msAggregate = 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
end(): number
|
|
77
|
+
{
|
|
78
|
+
this._overall.end();
|
|
79
|
+
this.segend();
|
|
80
|
+
return this._overall.ms();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
segstart(): void
|
|
84
|
+
{
|
|
85
|
+
this._segment = new Elapsed();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
segend(): number
|
|
89
|
+
{
|
|
90
|
+
let ms = 0;
|
|
91
|
+
if (this._segment)
|
|
92
|
+
{
|
|
93
|
+
ms = this._segment.ms();
|
|
94
|
+
this._msAggregate += ms;
|
|
95
|
+
this._segment = null;
|
|
96
|
+
}
|
|
97
|
+
return ms;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get overall(): number { return this._overall.ms() }
|
|
101
|
+
get aggregate(): number { return this._msAggregate }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export class Deadline
|
|
105
|
+
{
|
|
106
|
+
msDelta: number;
|
|
107
|
+
elapsed: Elapsed;
|
|
108
|
+
|
|
109
|
+
constructor(msDelta: number)
|
|
110
|
+
{
|
|
111
|
+
this.msDelta = msDelta;
|
|
112
|
+
this.elapsed = new Elapsed();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
start(): void
|
|
116
|
+
{
|
|
117
|
+
this.elapsed.start();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
done(): boolean
|
|
121
|
+
{
|
|
122
|
+
this.elapsed.end();
|
|
123
|
+
return this.elapsed.ms() > this.msDelta;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function createGuid(): string
|
|
128
|
+
{
|
|
129
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
130
|
+
var r = Math.random()*16|0, v = c === 'x' ? r : (r&0x3|0x8);
|
|
131
|
+
return v.toString(16);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
type LoopTest = WeakMap<any,boolean>;
|
|
136
|
+
|
|
137
|
+
function _sizeof(a: any, loops: LoopTest): number
|
|
138
|
+
{
|
|
139
|
+
if (a === null || a === undefined) return 0;
|
|
140
|
+
|
|
141
|
+
switch (typeof a)
|
|
142
|
+
{
|
|
143
|
+
default: return 0;
|
|
144
|
+
case 'number': return 8;
|
|
145
|
+
case 'boolean': return 4;
|
|
146
|
+
case 'string': return a.length * 2;
|
|
147
|
+
|
|
148
|
+
case 'object':
|
|
149
|
+
{
|
|
150
|
+
if (loops.has(a))
|
|
151
|
+
return 0;
|
|
152
|
+
else
|
|
153
|
+
loops.set(a, true);
|
|
154
|
+
|
|
155
|
+
let t: number = 0;
|
|
156
|
+
if (Array.isArray(a))
|
|
157
|
+
{
|
|
158
|
+
for (let i: number = 0; i < a.length; i++)
|
|
159
|
+
t += _sizeof(a[i], loops);
|
|
160
|
+
t += 8; // length
|
|
161
|
+
}
|
|
162
|
+
else if (Buffer && Buffer.isBuffer(a))
|
|
163
|
+
{
|
|
164
|
+
t = a.length;
|
|
165
|
+
}
|
|
166
|
+
else if (a.hasOwnProperty === undefined)
|
|
167
|
+
return t;
|
|
168
|
+
else
|
|
169
|
+
{
|
|
170
|
+
for (var key in a) if (a.hasOwnProperty && a.hasOwnProperty(key))
|
|
171
|
+
{
|
|
172
|
+
t += _sizeof(key, loops); // this is a good estimate of download size, but poor estimate of internal size
|
|
173
|
+
// because of JS object templating vs. naive hashtables
|
|
174
|
+
t += _sizeof(a[key], loops);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return t;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function sizeof(a: any): number
|
|
183
|
+
{
|
|
184
|
+
let loops: LoopTest = new WeakMap();
|
|
185
|
+
let n: number = _sizeof(a, loops);
|
|
186
|
+
return n;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function depthof(a: any): number
|
|
190
|
+
{
|
|
191
|
+
if (a === null || a === undefined) return 1;
|
|
192
|
+
|
|
193
|
+
switch (typeof a)
|
|
194
|
+
{
|
|
195
|
+
default: return 1;
|
|
196
|
+
case 'number': return 1;
|
|
197
|
+
case 'boolean': return 1;
|
|
198
|
+
case 'string': return 1;
|
|
199
|
+
|
|
200
|
+
case 'object':
|
|
201
|
+
{
|
|
202
|
+
let d: number = 0;
|
|
203
|
+
if (Array.isArray(a))
|
|
204
|
+
return a.length > 0 ? (1 + depthof(a[0])) : 2; // still return 2 for empty array
|
|
205
|
+
else if (Buffer && Buffer.isBuffer(a))
|
|
206
|
+
return 2;
|
|
207
|
+
else if (a.hasOwnProperty === undefined)
|
|
208
|
+
return 1;
|
|
209
|
+
else
|
|
210
|
+
{
|
|
211
|
+
for (var key in a) if (a.hasOwnProperty(key))
|
|
212
|
+
return 1 + depthof(a[key]);
|
|
213
|
+
return 2; // or 2 for empty object
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export function isEmpty(o: any): boolean
|
|
219
|
+
{
|
|
220
|
+
if (o === null || o === undefined) return true;
|
|
221
|
+
for (var p in o) if (o.hasOwnProperty(p)) return false;
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export function countKeys(o: any): number
|
|
226
|
+
{
|
|
227
|
+
if (o === undefined || typeof o !== 'object') return -1;
|
|
228
|
+
|
|
229
|
+
let count: number = 0;
|
|
230
|
+
for (let p in o) if (o.hasOwnProperty(p))
|
|
231
|
+
count++;
|
|
232
|
+
return count;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function nthProperty(o: any, n: number = 0): any
|
|
236
|
+
{
|
|
237
|
+
for (let p in o) if (o.hasOwnProperty(p))
|
|
238
|
+
{
|
|
239
|
+
if (n <= 0) return o[p];
|
|
240
|
+
n--;
|
|
241
|
+
}
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function nthKey(o: any, n: number = 0): any
|
|
246
|
+
{
|
|
247
|
+
for (let p in o) if (o.hasOwnProperty(p))
|
|
248
|
+
{
|
|
249
|
+
if (n <= 0) return p;
|
|
250
|
+
n--;
|
|
251
|
+
}
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function partialEqual(o: any, subset: any): boolean
|
|
256
|
+
{
|
|
257
|
+
for (let p in subset) if (subset.hasOwnProperty(p))
|
|
258
|
+
if (o[p] !== subset[p])
|
|
259
|
+
return false;
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export interface EqOptions
|
|
264
|
+
{
|
|
265
|
+
omitKey?: { [key: string]: boolean },
|
|
266
|
+
unorderedArrays?: boolean,
|
|
267
|
+
emptyStringIsNull: boolean,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function exactEqual(o1: any, o2: any, options?: EqOptions): boolean
|
|
271
|
+
{
|
|
272
|
+
if (o1 === o2) return true;
|
|
273
|
+
if (options && options.emptyStringIsNull)
|
|
274
|
+
if ((o1 == null && o2 == '') || (o2 == null && o1 == ''))
|
|
275
|
+
return true;
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function deepEqual(o1: any, o2: any, options?: EqOptions): boolean
|
|
280
|
+
{
|
|
281
|
+
// fast exit
|
|
282
|
+
if (exactEqual(o1, o2, options)) return true;
|
|
283
|
+
|
|
284
|
+
// must be same types
|
|
285
|
+
if (typeof o1 !== typeof o2) return false;
|
|
286
|
+
|
|
287
|
+
// Already tested for exact primitive equality so if not objects, not equal
|
|
288
|
+
if (typeof o1 !== 'object' || o1 == null) return false;
|
|
289
|
+
if (typeof o2 !== 'object' || o2 == null) return false;
|
|
290
|
+
|
|
291
|
+
// Special case array
|
|
292
|
+
if (Array.isArray(o1))
|
|
293
|
+
{
|
|
294
|
+
if (! Array.isArray(o2)) return false;
|
|
295
|
+
if (o1.length != o2.length) return false;
|
|
296
|
+
if (options && options.unorderedArrays)
|
|
297
|
+
{
|
|
298
|
+
o1 = o1.sort();
|
|
299
|
+
o2 = o2.sort();
|
|
300
|
+
}
|
|
301
|
+
for (let i: number = 0; i < o1.length; i++)
|
|
302
|
+
if (! deepEqual(o1[i], o2[i], options))
|
|
303
|
+
return false;
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Special case object
|
|
308
|
+
if (o1.hasOwnProperty === undefined || o2.hasOwnProperty === undefined)
|
|
309
|
+
return exactEqual(o1, o2, options);
|
|
310
|
+
|
|
311
|
+
for (let p in o1) if (o1.hasOwnProperty(p))
|
|
312
|
+
{
|
|
313
|
+
if (options && options.omitKey && options.omitKey[p])
|
|
314
|
+
continue;
|
|
315
|
+
if (o2[p] === undefined)
|
|
316
|
+
return false;
|
|
317
|
+
if (! deepEqual(o1[p], o2[p], options))
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
// If any properties in o2 aren't in o1, not equal
|
|
321
|
+
for (let p in o2) if (o2.hasOwnProperty(p))
|
|
322
|
+
{
|
|
323
|
+
if (options && options.omitKey && options.omitKey[p])
|
|
324
|
+
continue;
|
|
325
|
+
if (o1[p] === undefined)
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const Months = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ];
|
|
333
|
+
|
|
334
|
+
export function prettyDate(d: Date): string
|
|
335
|
+
{
|
|
336
|
+
if (d == null) return 'unknown';
|
|
337
|
+
|
|
338
|
+
let mmm = Months[d.getMonth()];
|
|
339
|
+
let dd = d.getDate();
|
|
340
|
+
let yyyy = d.getFullYear();
|
|
341
|
+
let hh = d.getHours();
|
|
342
|
+
let m = d.getMinutes();
|
|
343
|
+
let mm = m < 10 ? `0${m}` : String(m);
|
|
344
|
+
let ampm = hh >= 12 ? 'PM' : 'AM';
|
|
345
|
+
if (hh > 12) hh -= 12;
|
|
346
|
+
|
|
347
|
+
return `${mmm} ${dd}, ${yyyy} at ${hh}:${mm} ${ampm}`;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function relativeDate(d: Date): string
|
|
351
|
+
{
|
|
352
|
+
if (d == null) return 'unknown';
|
|
353
|
+
let now = new Date();
|
|
354
|
+
let yyyyNow = now.getFullYear();
|
|
355
|
+
let mmmNow = Months[now.getMonth()];
|
|
356
|
+
let ddNow = now.getDate();
|
|
357
|
+
|
|
358
|
+
let mmm = Months[d.getMonth()];
|
|
359
|
+
let dd = d.getDate();
|
|
360
|
+
let yyyy = d.getFullYear();
|
|
361
|
+
let hh = d.getHours();
|
|
362
|
+
let m = d.getMinutes();
|
|
363
|
+
let mm = m < 10 ? `0${m}` : String(m);
|
|
364
|
+
let ampm = hh >= 12 ? 'PM' : 'AM';
|
|
365
|
+
if (hh > 12) hh -= 12;
|
|
366
|
+
|
|
367
|
+
if (yyyyNow === yyyy && mmmNow === mmm && ddNow === dd)
|
|
368
|
+
return `Today at ${hh}:${mm} ${ampm}`;
|
|
369
|
+
else if (yyyyNow === yyyy)
|
|
370
|
+
return `${mmm} ${dd}`;
|
|
371
|
+
else
|
|
372
|
+
return `${mmm} ${dd}, ${yyyy}`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const OneMinute = 1000 * 60;
|
|
376
|
+
const OneHour = OneMinute * 60;
|
|
377
|
+
const OneDay = OneHour * 24;
|
|
378
|
+
|
|
379
|
+
export function recentDate(d: Date): string
|
|
380
|
+
{
|
|
381
|
+
if (d == null) return 'u';
|
|
382
|
+
let now = new Date();
|
|
383
|
+
let msNow = now.getTime();
|
|
384
|
+
let msThen = d.getTime();
|
|
385
|
+
let msDelta = msNow - msThen;
|
|
386
|
+
|
|
387
|
+
// Within the hour, display in minutes
|
|
388
|
+
if (msDelta < OneHour)
|
|
389
|
+
return `${Math.round(msDelta/OneMinute)+1}m`;
|
|
390
|
+
|
|
391
|
+
// Within the day, display in hours
|
|
392
|
+
else if (msDelta < OneDay)
|
|
393
|
+
return `${Math.round(msDelta/OneHour)+1}h`;
|
|
394
|
+
|
|
395
|
+
// Otherwise, display using relativeDate
|
|
396
|
+
else
|
|
397
|
+
return relativeDate(d);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export function textToHtml(sText: string): string
|
|
401
|
+
{
|
|
402
|
+
let lines: string[] = sText.split('\n');
|
|
403
|
+
let aHtml: string[] = [];
|
|
404
|
+
let inTable: boolean = false;
|
|
405
|
+
aHtml.push('<body>');
|
|
406
|
+
for (let i: number = 0; i < lines.length; i++)
|
|
407
|
+
{
|
|
408
|
+
let line = lines[i];
|
|
409
|
+
let isRow: boolean = line.indexOf('|') === 0;
|
|
410
|
+
if (inTable && !isRow)
|
|
411
|
+
{
|
|
412
|
+
aHtml.push('</tbody></table>');
|
|
413
|
+
inTable = false;
|
|
414
|
+
}
|
|
415
|
+
if (isRow && !inTable)
|
|
416
|
+
{
|
|
417
|
+
inTable = true;
|
|
418
|
+
aHtml.push('<table border="1" cellspacing="0" cellpadding="2"><tbody>');
|
|
419
|
+
}
|
|
420
|
+
if (isRow)
|
|
421
|
+
{
|
|
422
|
+
let cells = line.split('|');
|
|
423
|
+
if (cells.length > 2)
|
|
424
|
+
{
|
|
425
|
+
aHtml.push('<tr>');
|
|
426
|
+
for (let j: number = 1; j < cells.length-1; j++)
|
|
427
|
+
aHtml.push(`<td>${cells[j]}</td>`);
|
|
428
|
+
aHtml.push('</tr>');
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else
|
|
432
|
+
aHtml.push(`<div>${line} </div>`);
|
|
433
|
+
}
|
|
434
|
+
if (inTable)
|
|
435
|
+
aHtml.push('</tbody></table>');
|
|
436
|
+
aHtml.push('</body>');
|
|
437
|
+
return aHtml.join('');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export function shallowCopy(src: any): any
|
|
441
|
+
{
|
|
442
|
+
if (src === null || src === undefined) return src;
|
|
443
|
+
|
|
444
|
+
switch (typeof src)
|
|
445
|
+
{
|
|
446
|
+
case 'boolean':
|
|
447
|
+
case 'number':
|
|
448
|
+
case 'string':
|
|
449
|
+
case 'symbol':
|
|
450
|
+
case 'function':
|
|
451
|
+
default:
|
|
452
|
+
return src;
|
|
453
|
+
|
|
454
|
+
case 'object':
|
|
455
|
+
if (Array.isArray(src))
|
|
456
|
+
return src.slice();
|
|
457
|
+
else
|
|
458
|
+
{
|
|
459
|
+
let copy: any = {};
|
|
460
|
+
|
|
461
|
+
for (var p in src) if (src.hasOwnProperty(p))
|
|
462
|
+
copy[p] = src[p];
|
|
463
|
+
return copy;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export function shallowAssign(o1: any, o2: any): any
|
|
469
|
+
{
|
|
470
|
+
if (o1 === null || o1 === undefined) o1 = {};
|
|
471
|
+
if (o2 === null || o2 === undefined) return o1;
|
|
472
|
+
if (typeof o2 !== 'object' || typeof o1 !== 'object') return o1;
|
|
473
|
+
|
|
474
|
+
for (var p in o2) if (o2.hasOwnProperty(p))
|
|
475
|
+
o1[p] = o2[p];
|
|
476
|
+
return o1;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export function shallowDelete(o1: any, o2: any): any
|
|
480
|
+
{
|
|
481
|
+
if (o1 == null || o2 == null) return o1;
|
|
482
|
+
if (typeof o2 !== 'object' || typeof o1 !== 'object') return o1;
|
|
483
|
+
|
|
484
|
+
for (var p in o2) if (o2.hasOwnProperty(p))
|
|
485
|
+
delete o1[p];
|
|
486
|
+
return o1;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
export function shallowAssignImmutable(o1: any, o2: any): any
|
|
490
|
+
{
|
|
491
|
+
if (o1 === null || o1 === undefined) o1 = {};
|
|
492
|
+
if (o2 === null || o2 === undefined) return o1;
|
|
493
|
+
if (typeof o2 !== 'object' || typeof o1 !== 'object') return o1;
|
|
494
|
+
|
|
495
|
+
// First determine whether o2 changes any properties, if it has, make new instance
|
|
496
|
+
let oNew: any = o1;
|
|
497
|
+
for (let p in o2) if (o2.hasOwnProperty(p))
|
|
498
|
+
{
|
|
499
|
+
if (o1[p] != o2[p])
|
|
500
|
+
{
|
|
501
|
+
oNew = shallowCopy(o1);
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (oNew !== o1)
|
|
506
|
+
shallowAssign(oNew, o2);
|
|
507
|
+
return oNew;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export function shallowEqual(o1: any, o2: any): boolean
|
|
511
|
+
{
|
|
512
|
+
if (o1 === undefined || o2 === undefined || typeof o1 !== 'object' || typeof o2 !== 'object')
|
|
513
|
+
return o1 === o2;
|
|
514
|
+
|
|
515
|
+
if (Array.isArray(o1) && Array.isArray(o2))
|
|
516
|
+
{
|
|
517
|
+
if (o1.length != o2.length) return false;
|
|
518
|
+
for (let i: number = 0; i < o1.length; i++)
|
|
519
|
+
if (o1[i] !== o2[i]) return false;
|
|
520
|
+
return true;
|
|
521
|
+
}
|
|
522
|
+
else
|
|
523
|
+
{
|
|
524
|
+
let p: any;
|
|
525
|
+
|
|
526
|
+
for (p in o1) if (o1.hasOwnProperty(p))
|
|
527
|
+
if (o1[p] !== o2[p]) return false;
|
|
528
|
+
for (p in o2) if (o2.hasOwnProperty(p))
|
|
529
|
+
if (o1[p] === undefined) return false;
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export function deepCopy(src: any): any
|
|
535
|
+
{
|
|
536
|
+
// Beware typeof oddities
|
|
537
|
+
if (src === null || src === undefined) return src;
|
|
538
|
+
|
|
539
|
+
if (typeof src === 'object')
|
|
540
|
+
{
|
|
541
|
+
if (Array.isArray(src))
|
|
542
|
+
{
|
|
543
|
+
let dst: any[] = [];
|
|
544
|
+
|
|
545
|
+
for (let i: number = 0; i < src.length; i++)
|
|
546
|
+
dst.push(deepCopy(src[i]));
|
|
547
|
+
return dst;
|
|
548
|
+
}
|
|
549
|
+
else
|
|
550
|
+
{
|
|
551
|
+
if (src.hasOwnProperty === undefined)
|
|
552
|
+
return src;
|
|
553
|
+
|
|
554
|
+
let dst: any = {};
|
|
555
|
+
for (var p in src) if (src.hasOwnProperty(p))
|
|
556
|
+
dst[p] = deepCopy(src[p]);
|
|
557
|
+
return dst;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else
|
|
561
|
+
return src;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
export function deepAccum(accum: any, o: any): any
|
|
565
|
+
{
|
|
566
|
+
if (accum == null) accum = {};
|
|
567
|
+
if (o == null) return accum;
|
|
568
|
+
for (let p in o) if (o.hasOwnProperty(p))
|
|
569
|
+
{
|
|
570
|
+
let vs: any = o[p];
|
|
571
|
+
let vd: any = accum[p];
|
|
572
|
+
let ts = typeof vs;
|
|
573
|
+
if (ts === 'number')
|
|
574
|
+
{
|
|
575
|
+
if (vd !== undefined && typeof vd !== 'number')
|
|
576
|
+
throw 'deepAccum: unexpected type mismatch';
|
|
577
|
+
if (p === 'min')
|
|
578
|
+
accum[p] = vd === undefined ? vs : Math.min(vd, vs);
|
|
579
|
+
else if (p === 'max')
|
|
580
|
+
accum[p] = vd === undefined ? vs : Math.max(vd, vs);
|
|
581
|
+
else
|
|
582
|
+
accum[p] = (vd === undefined ? 0 : vd) + vs;
|
|
583
|
+
}
|
|
584
|
+
else if (vs == null || ts === 'string' || ts === 'boolean')
|
|
585
|
+
accum[p] = vs;
|
|
586
|
+
else if (ts === 'object')
|
|
587
|
+
{
|
|
588
|
+
if (vd === undefined)
|
|
589
|
+
{
|
|
590
|
+
vd = {};
|
|
591
|
+
accum[p] = vd;
|
|
592
|
+
}
|
|
593
|
+
else if (typeof vd !== 'object')
|
|
594
|
+
throw 'deepAccum: unexpected type mismatch';
|
|
595
|
+
deepAccum(vd, vs);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return accum;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
export function precisionRound(n: number, p: number): number
|
|
602
|
+
{
|
|
603
|
+
let f: number = Math.pow(10, p);
|
|
604
|
+
return Math.round(n * f) / f;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
export function percentString(num: number, den: number, precision: number = 0): string
|
|
608
|
+
{
|
|
609
|
+
if (den == 0)
|
|
610
|
+
return '(-)';
|
|
611
|
+
|
|
612
|
+
let p: number = precisionRound((num/den) * 100, precision);
|
|
613
|
+
|
|
614
|
+
return String(p) + '%';
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export function hash(s: string): number
|
|
618
|
+
{
|
|
619
|
+
let hash: number = 5381;
|
|
620
|
+
let i: number = s.length;
|
|
621
|
+
|
|
622
|
+
while (i)
|
|
623
|
+
hash = (hash * 33) ^ s.charCodeAt(--i);
|
|
624
|
+
|
|
625
|
+
/* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
|
|
626
|
+
* integers. Since we want the results to be always positive, convert the
|
|
627
|
+
* signed int to an unsigned by doing an unsigned bitshift. */
|
|
628
|
+
return hash >>> 0;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export function hashObject(o: any): number
|
|
632
|
+
{
|
|
633
|
+
return hash(o ? JSON.stringify(o) : '');
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
const HexTable: string[] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' ];
|
|
637
|
+
export function toHex(n: number): string
|
|
638
|
+
{
|
|
639
|
+
if (n < 0 || n > 255) throw('only 0 to 255 supported now');
|
|
640
|
+
n = Math.floor(n);
|
|
641
|
+
return HexTable[n >> 4] + HexTable[n & 15];
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
export function toRGBA(color: string, alpha: number): string
|
|
645
|
+
{
|
|
646
|
+
// Allow passing rgba in rather than only '#ffffff' form
|
|
647
|
+
if (color.indexOf('rgba') === 0)
|
|
648
|
+
return color;
|
|
649
|
+
|
|
650
|
+
let r: number;
|
|
651
|
+
let g: number;
|
|
652
|
+
let b: number;
|
|
653
|
+
|
|
654
|
+
switch (color)
|
|
655
|
+
{
|
|
656
|
+
case 'white':
|
|
657
|
+
r = 255; g = 255; b = 255;
|
|
658
|
+
break;
|
|
659
|
+
|
|
660
|
+
case 'black':
|
|
661
|
+
r = 0; g = 0; b = 0;
|
|
662
|
+
break;
|
|
663
|
+
|
|
664
|
+
default:
|
|
665
|
+
r = parseInt(color.substr(1, 2), 16);
|
|
666
|
+
g = parseInt(color.substr(3, 2), 16);
|
|
667
|
+
b = parseInt(color.substr(5, 2), 16);
|
|
668
|
+
break;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return `rgba(${String(r)}, ${String(g)}, ${String(b)}, ${String(alpha)})`;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
export function toRGBAIntensity(color: string, intensity: number, alpha: number): string
|
|
675
|
+
{
|
|
676
|
+
// for now assume color is black
|
|
677
|
+
let g: number = precisionRound(255 * intensity, 0);
|
|
678
|
+
return `rgba(${String(g)}, ${String(g)}, ${String(g)}, ${String(alpha)})`;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// Geo functions
|
|
682
|
+
export function distance(x0: number, y0: number, x1: number, y1: number): number
|
|
683
|
+
{
|
|
684
|
+
return Math.hypot(x0 - x1, y0 - y1);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
export function deg2rad(num: number): number { return num * Math.PI / 180; }
|
|
688
|
+
export function rad2deg(num: number): number { return num / Math.PI * 180; }
|
|
689
|
+
|
|
690
|
+
// Restricts lon to range [-180..180]
|
|
691
|
+
export function wrapLon(lon: number): number
|
|
692
|
+
{
|
|
693
|
+
let worlds = Math.floor((lon + 180) / 360);
|
|
694
|
+
return lon - (worlds * 360);
|
|
695
|
+
}
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dra2020/baseclient",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
4
4
|
"description": "Utility functions for Javascript projects.",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "dist/baseclient.js",
|
|
6
|
+
"types": "dist/all/allclient.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "echo \"No test defined.\"",
|
|
9
|
-
"build": "
|
|
10
|
-
"webpack": "
|
|
9
|
+
"build": "webpack",
|
|
10
|
+
"webpack": "node_modules/.bin/webpack"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
13
|
+
"dist/",
|
|
14
|
+
"lib/",
|
|
15
|
+
"docs/"
|
|
16
16
|
],
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|