foreslash 0.1.0 → 0.1.1

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/lib/index.cmn.cjs CHANGED
@@ -123,7 +123,7 @@ function isWeakMap(value) {
123
123
  }
124
124
 
125
125
  function isNil(value) {
126
- return value == null;
126
+ return value === null || value === void 0;
127
127
  }
128
128
  function isNull(value) {
129
129
  return value === null;
@@ -140,6 +140,10 @@ function isObject(value) {
140
140
  return typeof value === 'object' && value !== null;
141
141
  }
142
142
 
143
+ function isPrimitive(value) {
144
+ return value == null || (typeof value !== 'object' && typeof value !== 'function');
145
+ }
146
+
143
147
  function isPromise(value) {
144
148
  return isObject(value) && isFunction(value.then) && getTag(value) === 'Promise';
145
149
  }
@@ -197,8 +201,36 @@ function randomIntFloor(min, max) {
197
201
  return Math.floor(Math.random() * (max - min)) + min;
198
202
  }
199
203
 
200
- function randomChoice(arr) {
201
- return arr[randomIntFloor(0, arr.length)];
204
+ function randomChoice(arr, weights) {
205
+ if (!weights || !weights.length)
206
+ return arr[randomIntFloor(0, arr.length)];
207
+ let sum = 0;
208
+ const cumulativeWeights = [];
209
+ for (let i = 0; i < weights.length; i++) {
210
+ sum += weights[i] ? weights[i] : 0;
211
+ cumulativeWeights.push(sum);
212
+ }
213
+ const randomWeight = Math.random() * sum;
214
+ const index = cumulativeWeights.findIndex(weight => weight > randomWeight);
215
+ return arr[index];
216
+ }
217
+
218
+ const radix32 = '0123456789abcdefghijklmnopqrstuv';
219
+ const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
220
+ const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
221
+ const base32CharsMap = new Map(radix32.split('').map((c, i) => [c, base32Chars[i]]));
222
+ const base32CrockfordMap = new Map(radix32.split('').map((c, i) => [c, base32Crockford[i]]));
223
+ function toBase32(str, mapping) {
224
+ return str
225
+ .split('')
226
+ .map((c) => mapping.get(c))
227
+ .join('');
228
+ }
229
+ function numberToBase32(num, length, mapping) {
230
+ let res = num.toString(32);
231
+ while (res.length < length)
232
+ res = '0' + res;
233
+ return toBase32(res, mapping);
202
234
  }
203
235
 
204
236
  function randomString(length, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
@@ -231,6 +263,71 @@ function _randomHexString(length) {
231
263
  res = '0' + res;
232
264
  return res;
233
265
  }
266
+ function randomBase32String(length, isCrockford = false) {
267
+ if (!Number.isInteger(length) || length <= 0) {
268
+ throw new Error('Invalid length parameter');
269
+ }
270
+ const map = isCrockford ? base32CrockfordMap : base32CharsMap;
271
+ if (length > 13) {
272
+ const count = Math.floor(length / 10);
273
+ let res = _randomBase32String(length % 10, map);
274
+ for (let i = 0; i < count; i++)
275
+ res += _randomBase32String(10, map);
276
+ return res;
277
+ }
278
+ else {
279
+ return _randomBase32String(length, map);
280
+ }
281
+ }
282
+ function _randomBase32String(length, mapping) {
283
+ return numberToBase32(Math.floor(Math.random() * 32 ** length), length, mapping);
284
+ }
285
+
286
+ function shuffle(arr) {
287
+ const array = Array.from(arr);
288
+ if (array.length <= 1)
289
+ return array;
290
+ for (let i = array.length - 1; i > 0; i--) {
291
+ const j = Math.floor(Math.random() * (i + 1));
292
+ [array[i], array[j]] = [array[j], array[i]];
293
+ }
294
+ return array;
295
+ }
296
+
297
+ let lastTime = 0;
298
+ let lastNum1 = 0;
299
+ let lastNum2 = 0;
300
+ function ulid(monotonic = true, time = NaN) {
301
+ const now = isInteger(time) ? time : Date.now();
302
+ if (!monotonic)
303
+ return (_encodeTime(now) + randomBase32String(16)).toUpperCase();
304
+ if (lastTime !== now) {
305
+ lastTime = now;
306
+ lastNum1 = randomIntFloor(0, 32 ** 6);
307
+ lastNum2 = randomIntFloor(0, 32 ** 10);
308
+ }
309
+ else {
310
+ lastNum2++;
311
+ if (lastNum2 >= 32 ** 10) {
312
+ lastNum1++;
313
+ lastNum2 = 0;
314
+ }
315
+ if (lastNum1 >= 32 ** 6) {
316
+ lastNum1 = 0;
317
+ }
318
+ }
319
+ return (_encodeTime(now) +
320
+ numberToBase32(lastNum1, 6, base32CrockfordMap) +
321
+ numberToBase32(lastNum2, 10, base32CrockfordMap)).toUpperCase();
322
+ }
323
+ function _encodeTime(time) {
324
+ let str = '';
325
+ while (str.length < 10) {
326
+ str = base32Crockford[time % 32] + str;
327
+ time = Math.floor(time / 32);
328
+ }
329
+ return str;
330
+ }
234
331
 
235
332
  function compose(...composeFunc) {
236
333
  if (composeFunc.length === 0) {
@@ -398,6 +495,28 @@ function fastClone(obj, map) {
398
495
  return res;
399
496
  }
400
497
 
498
+ function isEmpty(value) {
499
+ if (value == null)
500
+ return true;
501
+ if (typeof value !== 'object') {
502
+ if (value === '' || value === 0)
503
+ return true;
504
+ if (typeof value === 'function')
505
+ return false;
506
+ return false;
507
+ }
508
+ else {
509
+ if (isArrayLike(value)) {
510
+ return !value.length;
511
+ }
512
+ if (isBuffer(value) || isArrayBuffer(value))
513
+ return !value.byteLength;
514
+ if (isSet(value) || isMap(value))
515
+ return !value.size;
516
+ return !Object.getOwnPropertyNames(value).length;
517
+ }
518
+ }
519
+
401
520
  const noop = function noop() { };
402
521
  function pass(value) {
403
522
  return value;
@@ -444,6 +563,7 @@ exports.isArrayLike = isArrayLike;
444
563
  exports.isBigInt = isBigInt;
445
564
  exports.isBoolean = isBoolean;
446
565
  exports.isBuffer = isBuffer;
566
+ exports.isEmpty = isEmpty;
447
567
  exports.isFunction = isFunction;
448
568
  exports.isInteger = isInteger;
449
569
  exports.isMap = isMap;
@@ -452,6 +572,7 @@ exports.isNull = isNull;
452
572
  exports.isNumber = isNumber;
453
573
  exports.isObject = isObject;
454
574
  exports.isPlaceholder = isPlaceholder;
575
+ exports.isPrimitive = isPrimitive;
455
576
  exports.isPromise = isPromise;
456
577
  exports.isPromiseLike = isPromiseLike;
457
578
  exports.isSet = isSet;
@@ -471,8 +592,11 @@ exports.not = not;
471
592
  exports.pass = pass;
472
593
  exports.passWith = passWith;
473
594
  exports.pipe = pipe;
595
+ exports.randomBase32String = randomBase32String;
474
596
  exports.randomChoice = randomChoice;
475
597
  exports.randomHexString = randomHexString;
476
598
  exports.randomInt = randomInt;
477
599
  exports.randomIntFloor = randomIntFloor;
478
600
  exports.randomString = randomString;
601
+ exports.shuffle = shuffle;
602
+ exports.ulid = ulid;
package/lib/index.d.ts CHANGED
@@ -119,6 +119,7 @@ declare function isWeakMap(value: unknown): value is WeakMap<any, any>;
119
119
  * isNil(0) // false
120
120
  * isNil("") // false
121
121
  * isNil(false) // false
122
+ * isNil(document.all) // false
122
123
  * ```
123
124
  */
124
125
  declare function isNil(value: unknown): value is null | undefined;
@@ -177,6 +178,23 @@ declare function isNumber(value: unknown): value is number;
177
178
  */
178
179
  declare function isObject(value: unknown): value is object;
179
180
 
181
+ /**
182
+ * 类型守卫,判断给定的值是否为原始类型(如字符串数字等 JS 内置的类型)
183
+ * - 包括 `undefined` 和 `null`
184
+ * @param value 要判断的值
185
+ * @example
186
+ * ```js
187
+ * isPrimitive(123) // true
188
+ * isPrimitive(false) // true
189
+ * isPrimitive('123') // true
190
+ * isPrimitive({}) // false
191
+ * isPrimitive([]) // false
192
+ * isPrimitive(() => 1) // false
193
+ * isPrimitive(Object(123)) // false
194
+ * ```
195
+ */
196
+ declare function isPrimitive(value: unknown): value is object;
197
+
180
198
  /**
181
199
  * 类型守卫,判断给定的值是否为 `Promise`
182
200
  * @param value 要判断的值
@@ -313,14 +331,16 @@ declare function isWrapperBigInt(value: unknown): value is BigInt;
313
331
  /**
314
332
  * 从给定的数组中返回随机一个元素
315
333
  * @param arr 可以是数组或类数组对象
334
+ * @param weights 可选, 指定数组中每一项的权重, 若短于数组则缺失的部分视为 0
316
335
  * @returns 从数组中随机选择的元素
317
336
  * @example
318
337
  * ```js
319
338
  * randomChoice([1, 2, 3]) // 1 2 3
320
339
  * randomChoice("abc") // "a" "b" "c"
340
+ * randomChoice("abc", [1, 2, 3]) // "b" "a" "c" "c" "b" "c" ...
321
341
  * ```
322
342
  */
323
- declare function randomChoice<T>(arr: ArrayLike<T>): T;
343
+ declare function randomChoice<T>(arr: ArrayLike<T>, weights?: ArrayLike<number>): T;
324
344
 
325
345
  /**
326
346
  * 生成指定范围内的随机整数
@@ -358,7 +378,7 @@ declare function randomIntFloor(min: number, max: number): number;
358
378
  */
359
379
  declare function randomString(length: number, chars?: string): string;
360
380
  /**
361
- * 生成指定长度的随机十六进制字符串(小写),`randomString`也能实现此功能但是性能更差
381
+ * 生成指定长度的随机十六进制字符串(小写),`randomString` 也能实现此功能但是性能更差
362
382
  * @param length 字符串的长度
363
383
  * @returns 返回一个长度为`length`的随机十六进制字符串
364
384
  * @example
@@ -367,6 +387,36 @@ declare function randomString(length: number, chars?: string): string;
367
387
  * ```
368
388
  */
369
389
  declare function randomHexString(length: number): string;
390
+ /**
391
+ * 生成指定长度的随机 Base32 字符串(小写),`randomString` 也能实现此功能但是性能更差
392
+ * @param length 字符串的长度
393
+ * @returns 返回一个长度为`length`的随机 Base32 字符串
394
+ * @example
395
+ * ```js
396
+ * randomHexString(16) // "a491bfd3701ace39"
397
+ * ```
398
+ */
399
+ declare function randomBase32String(length: number, isCrockford?: boolean): string;
400
+
401
+ /**
402
+ * 使用 Fisher-Yates 算法打乱一个数组, 返回打乱后的新数组
403
+ * @param arr 可以是一个数组或类数组对象
404
+ * @returns 打乱后的新数组
405
+ * @example
406
+ * ```js
407
+ * shuffle('abcdefg') // ['d', 'e', 'a', 'c', 'g', 'f', 'b']
408
+ * shuffle([1, 2, 3, 4, 5, 6, 7, 8]) // [3, 2, 6, 5, 8, 1, 7, 4]
409
+ * ```
410
+ */
411
+ declare function shuffle<T>(arr: ArrayLike<T> | Iterable<T>): Array<T>;
412
+
413
+ /**
414
+ * 生成 [ULID 字符串(大写)](https://github.com/ulid/spec), 默认为单调递增
415
+ * @param monotonic 是否为单调递增, 默认为 `true`, 设为 `false` 则为随机生成
416
+ * @param time 时间戳, 默认为当前时间
417
+ * @returns 一个标准的 ULID 字符串
418
+ */
419
+ declare function ulid(monotonic?: boolean, time?: number): string;
370
420
 
371
421
  /**
372
422
  * 快速深拷贝内部实现
@@ -569,6 +619,34 @@ declare function _curryMore<Args extends Array<any>, Res>(fn: (...args: Args) =>
569
619
  */
570
620
  declare function fastClone<T>(obj: T, map?: Map<any, any>): T;
571
621
 
622
+ /**
623
+ * 功能性函数, 检查输入的参数是否为空
624
+ * 1. 若值为 `undefined` 和 `null` 返回 `true`
625
+ * 2. 若值为 `""` 或 `0` 返回 `true`
626
+ * 3. 若值为 函数 返回 `false`
627
+ * 4. 若值为 类数组对象: `length` 为 `0` 返回 `true` 否则返回 `false`
628
+ * 5. 若值为 `Buffer` 或 `ArrayBuffer`: `byteLength` 为 `0` 返回 `true` 否则返回 `false`
629
+ * 6. 若值为 `Set` 或 `Map`: `size` 为 `0` 返回 `true` 否则返回 `false`
630
+ * 7. 若值不为 原始类型: 根据 `Object.getOwnPropertyNames` 判断是否存在自身键, 若没有返回 `true` 否则返回 `false`
631
+ * 8. 返回 `false`
632
+ * @param value 要判断的值
633
+ * @example
634
+ * ```js
635
+ * isEmpty({}) // true
636
+ * isEmpty([]) // true
637
+ * isEmpty(0) // true
638
+ * isEmpty('') // true
639
+ * isEmpty(null) // true
640
+ * isEmpty(undefined) // true
641
+ * isEmpty(123) // false
642
+ * isEmpty('123') // false
643
+ * isEmpty(() => 0) // false
644
+ * isEmpty([1]) // false
645
+ * isEmpty({ a: 1 }) // false
646
+ * ```
647
+ */
648
+ declare function isEmpty(value: unknown): boolean;
649
+
572
650
  /**
573
651
  * 不做任何操作,返回`void`,一般用于函数式编程
574
652
  * @example
@@ -733,4 +811,4 @@ declare function pipe<PipeArgs extends any[], PipeResult, Mid1, Mid2, Mid3, Mid4
733
811
  declare function pipe<PipeArgs extends any[], PipeResult, Mid1, Mid2, Mid3, Mid4, Mid5, Mid6, Mid7>(...pipeFunc: PipeFuncList8<PipeArgs, PipeResult, Mid1, Mid2, Mid3, Mid4, Mid5, Mid6, Mid7>): (...args: PipeArgs) => PipeResult;
734
812
  declare function pipe<PipeArgs extends any[], PipeResult, Mid1, Mid2, Mid3, Mid4, Mid5, Mid6, Mid7>(...pipeFunc: PipeFuncListMore<PipeArgs, PipeResult, Mid1, Mid2, Mid3, Mid4, Mid5, Mid6, Mid7>): (...args: PipeArgs) => PipeResult;
735
813
 
736
- export { _, _fastClone, compose, _curryMore as curry, fastClone, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBoolean, isBuffer, isFunction, isInteger, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPromise, isPromiseLike, isSet, isString, isSymbol, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, noop, not, pass, passWith, pipe, randomChoice, randomHexString, randomInt, randomIntFloor, randomString };
814
+ export { _, _fastClone, compose, _curryMore as curry, fastClone, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBoolean, isBuffer, isEmpty, isFunction, isInteger, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isSet, isString, isSymbol, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, noop, not, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, shuffle, ulid };
package/lib/index.mjs CHANGED
@@ -121,7 +121,7 @@ function isWeakMap(value) {
121
121
  }
122
122
 
123
123
  function isNil(value) {
124
- return value == null;
124
+ return value === null || value === void 0;
125
125
  }
126
126
  function isNull(value) {
127
127
  return value === null;
@@ -138,6 +138,10 @@ function isObject(value) {
138
138
  return typeof value === 'object' && value !== null;
139
139
  }
140
140
 
141
+ function isPrimitive(value) {
142
+ return value == null || (typeof value !== 'object' && typeof value !== 'function');
143
+ }
144
+
141
145
  function isPromise(value) {
142
146
  return isObject(value) && isFunction(value.then) && getTag(value) === 'Promise';
143
147
  }
@@ -195,8 +199,36 @@ function randomIntFloor(min, max) {
195
199
  return Math.floor(Math.random() * (max - min)) + min;
196
200
  }
197
201
 
198
- function randomChoice(arr) {
199
- return arr[randomIntFloor(0, arr.length)];
202
+ function randomChoice(arr, weights) {
203
+ if (!weights || !weights.length)
204
+ return arr[randomIntFloor(0, arr.length)];
205
+ let sum = 0;
206
+ const cumulativeWeights = [];
207
+ for (let i = 0; i < weights.length; i++) {
208
+ sum += weights[i] ? weights[i] : 0;
209
+ cumulativeWeights.push(sum);
210
+ }
211
+ const randomWeight = Math.random() * sum;
212
+ const index = cumulativeWeights.findIndex(weight => weight > randomWeight);
213
+ return arr[index];
214
+ }
215
+
216
+ const radix32 = '0123456789abcdefghijklmnopqrstuv';
217
+ const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
218
+ const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
219
+ const base32CharsMap = new Map(radix32.split('').map((c, i) => [c, base32Chars[i]]));
220
+ const base32CrockfordMap = new Map(radix32.split('').map((c, i) => [c, base32Crockford[i]]));
221
+ function toBase32(str, mapping) {
222
+ return str
223
+ .split('')
224
+ .map((c) => mapping.get(c))
225
+ .join('');
226
+ }
227
+ function numberToBase32(num, length, mapping) {
228
+ let res = num.toString(32);
229
+ while (res.length < length)
230
+ res = '0' + res;
231
+ return toBase32(res, mapping);
200
232
  }
201
233
 
202
234
  function randomString(length, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
@@ -229,6 +261,71 @@ function _randomHexString(length) {
229
261
  res = '0' + res;
230
262
  return res;
231
263
  }
264
+ function randomBase32String(length, isCrockford = false) {
265
+ if (!Number.isInteger(length) || length <= 0) {
266
+ throw new Error('Invalid length parameter');
267
+ }
268
+ const map = isCrockford ? base32CrockfordMap : base32CharsMap;
269
+ if (length > 13) {
270
+ const count = Math.floor(length / 10);
271
+ let res = _randomBase32String(length % 10, map);
272
+ for (let i = 0; i < count; i++)
273
+ res += _randomBase32String(10, map);
274
+ return res;
275
+ }
276
+ else {
277
+ return _randomBase32String(length, map);
278
+ }
279
+ }
280
+ function _randomBase32String(length, mapping) {
281
+ return numberToBase32(Math.floor(Math.random() * 32 ** length), length, mapping);
282
+ }
283
+
284
+ function shuffle(arr) {
285
+ const array = Array.from(arr);
286
+ if (array.length <= 1)
287
+ return array;
288
+ for (let i = array.length - 1; i > 0; i--) {
289
+ const j = Math.floor(Math.random() * (i + 1));
290
+ [array[i], array[j]] = [array[j], array[i]];
291
+ }
292
+ return array;
293
+ }
294
+
295
+ let lastTime = 0;
296
+ let lastNum1 = 0;
297
+ let lastNum2 = 0;
298
+ function ulid(monotonic = true, time = NaN) {
299
+ const now = isInteger(time) ? time : Date.now();
300
+ if (!monotonic)
301
+ return (_encodeTime(now) + randomBase32String(16)).toUpperCase();
302
+ if (lastTime !== now) {
303
+ lastTime = now;
304
+ lastNum1 = randomIntFloor(0, 32 ** 6);
305
+ lastNum2 = randomIntFloor(0, 32 ** 10);
306
+ }
307
+ else {
308
+ lastNum2++;
309
+ if (lastNum2 >= 32 ** 10) {
310
+ lastNum1++;
311
+ lastNum2 = 0;
312
+ }
313
+ if (lastNum1 >= 32 ** 6) {
314
+ lastNum1 = 0;
315
+ }
316
+ }
317
+ return (_encodeTime(now) +
318
+ numberToBase32(lastNum1, 6, base32CrockfordMap) +
319
+ numberToBase32(lastNum2, 10, base32CrockfordMap)).toUpperCase();
320
+ }
321
+ function _encodeTime(time) {
322
+ let str = '';
323
+ while (str.length < 10) {
324
+ str = base32Crockford[time % 32] + str;
325
+ time = Math.floor(time / 32);
326
+ }
327
+ return str;
328
+ }
232
329
 
233
330
  function compose(...composeFunc) {
234
331
  if (composeFunc.length === 0) {
@@ -396,6 +493,28 @@ function fastClone(obj, map) {
396
493
  return res;
397
494
  }
398
495
 
496
+ function isEmpty(value) {
497
+ if (value == null)
498
+ return true;
499
+ if (typeof value !== 'object') {
500
+ if (value === '' || value === 0)
501
+ return true;
502
+ if (typeof value === 'function')
503
+ return false;
504
+ return false;
505
+ }
506
+ else {
507
+ if (isArrayLike(value)) {
508
+ return !value.length;
509
+ }
510
+ if (isBuffer(value) || isArrayBuffer(value))
511
+ return !value.byteLength;
512
+ if (isSet(value) || isMap(value))
513
+ return !value.size;
514
+ return !Object.getOwnPropertyNames(value).length;
515
+ }
516
+ }
517
+
399
518
  const noop = function noop() { };
400
519
  function pass(value) {
401
520
  return value;
@@ -429,4 +548,4 @@ function pipe(...pipeFunc) {
429
548
  };
430
549
  }
431
550
 
432
- export { _, _fastClone, compose, _curryMore as curry, fastClone, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBoolean, isBuffer, isFunction, isInteger, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPromise, isPromiseLike, isSet, isString, isSymbol, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, noop, not, pass, passWith, pipe, randomChoice, randomHexString, randomInt, randomIntFloor, randomString };
551
+ export { _, _fastClone, compose, _curryMore as curry, fastClone, getGlobalThis, getTag, isArray, isArrayBuffer, isArrayLike, isBigInt, isBoolean, isBuffer, isEmpty, isFunction, isInteger, isMap, isNil, isNull, isNumber, isObject, isPlaceholder, isPrimitive, isPromise, isPromiseLike, isSet, isString, isSymbol, isUndefined, isWeakMap, isWeakSet, isWrapperBigInt, isWrapperBoolean, isWrapperNumber, isWrapperObject, isWrapperString, isWrapperSymbol, noop, not, pass, passWith, pipe, randomBase32String, randomChoice, randomHexString, randomInt, randomIntFloor, randomString, shuffle, ulid };
package/lib/index.umd.js CHANGED
@@ -127,7 +127,7 @@ See the Mulan PSL v2 for more details.
127
127
  }
128
128
 
129
129
  function isNil(value) {
130
- return value == null;
130
+ return value === null || value === void 0;
131
131
  }
132
132
  function isNull(value) {
133
133
  return value === null;
@@ -144,6 +144,10 @@ See the Mulan PSL v2 for more details.
144
144
  return typeof value === 'object' && value !== null;
145
145
  }
146
146
 
147
+ function isPrimitive(value) {
148
+ return value == null || (typeof value !== 'object' && typeof value !== 'function');
149
+ }
150
+
147
151
  function isPromise(value) {
148
152
  return isObject(value) && isFunction(value.then) && getTag(value) === 'Promise';
149
153
  }
@@ -201,8 +205,36 @@ See the Mulan PSL v2 for more details.
201
205
  return Math.floor(Math.random() * (max - min)) + min;
202
206
  }
203
207
 
204
- function randomChoice(arr) {
205
- return arr[randomIntFloor(0, arr.length)];
208
+ function randomChoice(arr, weights) {
209
+ if (!weights || !weights.length)
210
+ return arr[randomIntFloor(0, arr.length)];
211
+ let sum = 0;
212
+ const cumulativeWeights = [];
213
+ for (let i = 0; i < weights.length; i++) {
214
+ sum += weights[i] ? weights[i] : 0;
215
+ cumulativeWeights.push(sum);
216
+ }
217
+ const randomWeight = Math.random() * sum;
218
+ const index = cumulativeWeights.findIndex(weight => weight > randomWeight);
219
+ return arr[index];
220
+ }
221
+
222
+ const radix32 = '0123456789abcdefghijklmnopqrstuv';
223
+ const base32Chars = 'abcdefghijklmnopqrstuvwxyz234567';
224
+ const base32Crockford = '0123456789abcdefghjkmnpqrstvwxyz';
225
+ const base32CharsMap = new Map(radix32.split('').map((c, i) => [c, base32Chars[i]]));
226
+ const base32CrockfordMap = new Map(radix32.split('').map((c, i) => [c, base32Crockford[i]]));
227
+ function toBase32(str, mapping) {
228
+ return str
229
+ .split('')
230
+ .map((c) => mapping.get(c))
231
+ .join('');
232
+ }
233
+ function numberToBase32(num, length, mapping) {
234
+ let res = num.toString(32);
235
+ while (res.length < length)
236
+ res = '0' + res;
237
+ return toBase32(res, mapping);
206
238
  }
207
239
 
208
240
  function randomString(length, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
@@ -235,6 +267,71 @@ See the Mulan PSL v2 for more details.
235
267
  res = '0' + res;
236
268
  return res;
237
269
  }
270
+ function randomBase32String(length, isCrockford = false) {
271
+ if (!Number.isInteger(length) || length <= 0) {
272
+ throw new Error('Invalid length parameter');
273
+ }
274
+ const map = isCrockford ? base32CrockfordMap : base32CharsMap;
275
+ if (length > 13) {
276
+ const count = Math.floor(length / 10);
277
+ let res = _randomBase32String(length % 10, map);
278
+ for (let i = 0; i < count; i++)
279
+ res += _randomBase32String(10, map);
280
+ return res;
281
+ }
282
+ else {
283
+ return _randomBase32String(length, map);
284
+ }
285
+ }
286
+ function _randomBase32String(length, mapping) {
287
+ return numberToBase32(Math.floor(Math.random() * 32 ** length), length, mapping);
288
+ }
289
+
290
+ function shuffle(arr) {
291
+ const array = Array.from(arr);
292
+ if (array.length <= 1)
293
+ return array;
294
+ for (let i = array.length - 1; i > 0; i--) {
295
+ const j = Math.floor(Math.random() * (i + 1));
296
+ [array[i], array[j]] = [array[j], array[i]];
297
+ }
298
+ return array;
299
+ }
300
+
301
+ let lastTime = 0;
302
+ let lastNum1 = 0;
303
+ let lastNum2 = 0;
304
+ function ulid(monotonic = true, time = NaN) {
305
+ const now = isInteger(time) ? time : Date.now();
306
+ if (!monotonic)
307
+ return (_encodeTime(now) + randomBase32String(16)).toUpperCase();
308
+ if (lastTime !== now) {
309
+ lastTime = now;
310
+ lastNum1 = randomIntFloor(0, 32 ** 6);
311
+ lastNum2 = randomIntFloor(0, 32 ** 10);
312
+ }
313
+ else {
314
+ lastNum2++;
315
+ if (lastNum2 >= 32 ** 10) {
316
+ lastNum1++;
317
+ lastNum2 = 0;
318
+ }
319
+ if (lastNum1 >= 32 ** 6) {
320
+ lastNum1 = 0;
321
+ }
322
+ }
323
+ return (_encodeTime(now) +
324
+ numberToBase32(lastNum1, 6, base32CrockfordMap) +
325
+ numberToBase32(lastNum2, 10, base32CrockfordMap)).toUpperCase();
326
+ }
327
+ function _encodeTime(time) {
328
+ let str = '';
329
+ while (str.length < 10) {
330
+ str = base32Crockford[time % 32] + str;
331
+ time = Math.floor(time / 32);
332
+ }
333
+ return str;
334
+ }
238
335
 
239
336
  function compose(...composeFunc) {
240
337
  if (composeFunc.length === 0) {
@@ -402,6 +499,28 @@ See the Mulan PSL v2 for more details.
402
499
  return res;
403
500
  }
404
501
 
502
+ function isEmpty(value) {
503
+ if (value == null)
504
+ return true;
505
+ if (typeof value !== 'object') {
506
+ if (value === '' || value === 0)
507
+ return true;
508
+ if (typeof value === 'function')
509
+ return false;
510
+ return false;
511
+ }
512
+ else {
513
+ if (isArrayLike(value)) {
514
+ return !value.length;
515
+ }
516
+ if (isBuffer(value) || isArrayBuffer(value))
517
+ return !value.byteLength;
518
+ if (isSet(value) || isMap(value))
519
+ return !value.size;
520
+ return !Object.getOwnPropertyNames(value).length;
521
+ }
522
+ }
523
+
405
524
  const noop = function noop() { };
406
525
  function pass(value) {
407
526
  return value;
@@ -448,6 +567,7 @@ See the Mulan PSL v2 for more details.
448
567
  exports.isBigInt = isBigInt;
449
568
  exports.isBoolean = isBoolean;
450
569
  exports.isBuffer = isBuffer;
570
+ exports.isEmpty = isEmpty;
451
571
  exports.isFunction = isFunction;
452
572
  exports.isInteger = isInteger;
453
573
  exports.isMap = isMap;
@@ -456,6 +576,7 @@ See the Mulan PSL v2 for more details.
456
576
  exports.isNumber = isNumber;
457
577
  exports.isObject = isObject;
458
578
  exports.isPlaceholder = isPlaceholder;
579
+ exports.isPrimitive = isPrimitive;
459
580
  exports.isPromise = isPromise;
460
581
  exports.isPromiseLike = isPromiseLike;
461
582
  exports.isSet = isSet;
@@ -475,10 +596,13 @@ See the Mulan PSL v2 for more details.
475
596
  exports.pass = pass;
476
597
  exports.passWith = passWith;
477
598
  exports.pipe = pipe;
599
+ exports.randomBase32String = randomBase32String;
478
600
  exports.randomChoice = randomChoice;
479
601
  exports.randomHexString = randomHexString;
480
602
  exports.randomInt = randomInt;
481
603
  exports.randomIntFloor = randomIntFloor;
482
604
  exports.randomString = randomString;
605
+ exports.shuffle = shuffle;
606
+ exports.ulid = ulid;
483
607
 
484
608
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foreslash",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Foreslash is a Javascript utilities lib which contains plenty of practical functions.",
5
5
  "author": "moushu",
6
6
  "license": "Mulan PSL v2",