@monterosa/sdk-util 0.17.1-rc.6

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.
@@ -0,0 +1,846 @@
1
+ import mitt from 'mitt';
2
+
3
+ /**
4
+ * @license
5
+ * subscribe.ts
6
+ * util
7
+ *
8
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-02-22
9
+ * Copyright © 2022 Monterosa. All rights reserved.
10
+ *
11
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
12
+ */
13
+ var Emitter = /** @class */ (function () {
14
+ function Emitter() {
15
+ this.handlers = new Map();
16
+ this.emitter = mitt();
17
+ }
18
+ Emitter.prototype.on = function (event, handler) {
19
+ var _this = this;
20
+ var mittHandler = function (args) {
21
+ handler.apply(void 0, (Array.isArray(args) ? args : [args]));
22
+ };
23
+ this.handlers.set(handler, mittHandler);
24
+ this.emitter.on(event, mittHandler);
25
+ return function () { return _this.off(event, handler); };
26
+ };
27
+ Emitter.prototype.off = function (event, handler) {
28
+ if (handler === undefined) {
29
+ this.emitter.off(event);
30
+ return;
31
+ }
32
+ var mittHandler = this.handlers.get(handler);
33
+ if (mittHandler) {
34
+ this.emitter.off(event, mittHandler);
35
+ this.handlers.delete(handler);
36
+ }
37
+ };
38
+ Emitter.prototype.emit = function (event) {
39
+ var args = [];
40
+ for (var _i = 1; _i < arguments.length; _i++) {
41
+ args[_i - 1] = arguments[_i];
42
+ }
43
+ this.emitter.emit(event, args);
44
+ };
45
+ Emitter.prototype.once = function (event, handler) {
46
+ var _this = this;
47
+ var mittHandler = function (args) {
48
+ handler.apply(void 0, (Array.isArray(args) ? args : [args]));
49
+ _this.off(event, handler);
50
+ };
51
+ this.handlers.set(handler, mittHandler);
52
+ this.emitter.on(event, mittHandler);
53
+ return function () { return _this.off(event, handler); };
54
+ };
55
+ return Emitter;
56
+ }());
57
+ /**
58
+ * @internal
59
+ */
60
+ var subscribe = function (emitter, event, callback) {
61
+ emitter.on(event, callback);
62
+ return function () { return emitter.off(event, callback); };
63
+ };
64
+
65
+ /*! *****************************************************************************
66
+ Copyright (c) Microsoft Corporation.
67
+
68
+ Permission to use, copy, modify, and/or distribute this software for any
69
+ purpose with or without fee is hereby granted.
70
+
71
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
72
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
73
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
74
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
75
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
76
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
77
+ PERFORMANCE OF THIS SOFTWARE.
78
+ ***************************************************************************** */
79
+ /* global Reflect, Promise */
80
+
81
+ var extendStatics = function(d, b) {
82
+ extendStatics = Object.setPrototypeOf ||
83
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
84
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
85
+ return extendStatics(d, b);
86
+ };
87
+
88
+ function __extends(d, b) {
89
+ if (typeof b !== "function" && b !== null)
90
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
91
+ extendStatics(d, b);
92
+ function __() { this.constructor = d; }
93
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
94
+ }
95
+
96
+ function __awaiter(thisArg, _arguments, P, generator) {
97
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
98
+ return new (P || (P = Promise))(function (resolve, reject) {
99
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
100
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
101
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
102
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
103
+ });
104
+ }
105
+
106
+ function __generator(thisArg, body) {
107
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
108
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
109
+ function verb(n) { return function (v) { return step([n, v]); }; }
110
+ function step(op) {
111
+ if (f) throw new TypeError("Generator is already executing.");
112
+ while (_) try {
113
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
114
+ if (y = 0, t) op = [op[0] & 2, t.value];
115
+ switch (op[0]) {
116
+ case 0: case 1: t = op; break;
117
+ case 4: _.label++; return { value: op[1], done: false };
118
+ case 5: _.label++; y = op[1]; op = [0]; continue;
119
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
120
+ default:
121
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
122
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
123
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
124
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
125
+ if (t[2]) _.ops.pop();
126
+ _.trys.pop(); continue;
127
+ }
128
+ op = body.call(thisArg, _);
129
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
130
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
131
+ }
132
+ }
133
+
134
+ /**
135
+ * @license
136
+ * delay.ts
137
+ * util
138
+ *
139
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-03-24
140
+ * Copyright © 2022 Monterosa. All rights reserved.
141
+ *
142
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
143
+ */
144
+ /**
145
+ * @internal
146
+ */
147
+ var delay = function (timeout) { return __awaiter(void 0, void 0, void 0, function () {
148
+ return __generator(this, function (_a) {
149
+ switch (_a.label) {
150
+ case 0: return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, timeout); })];
151
+ case 1:
152
+ _a.sent();
153
+ return [2 /*return*/];
154
+ }
155
+ });
156
+ }); };
157
+
158
+ /**
159
+ * @license
160
+ * memoize-promise.ts
161
+ * util
162
+ *
163
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-09-20
164
+ * Copyright © 2022 Monterosa. All rights reserved.
165
+ *
166
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
167
+ */
168
+ /**
169
+ * Creates a function that memoizes the result of `func`.
170
+ *
171
+ * @internal
172
+ *
173
+ * @param func - A function that returns a promise. The results of its work will be memoized.
174
+ * @param resolver - A function that determines the cache key.
175
+ * @param config - A configuration object with the following optional properties:
176
+ * `clearOnResolve` - Deletes memoized result upon promise resolve. Defaults to `false`.
177
+ * `clearOnReject` - Deletes memoized result upon promise reject. Defaults to `true`.
178
+ */
179
+ var memoizePromise = function (func, resolver, config) {
180
+ var _a, _b;
181
+ if (config === void 0) { config = {}; }
182
+ var clearOnResolve = (_a = config.clearOnResolve) !== null && _a !== void 0 ? _a : false;
183
+ var clearOnReject = (_b = config.clearOnReject) !== null && _b !== void 0 ? _b : true;
184
+ var cache = new Map();
185
+ var memoized = function () {
186
+ var args = [];
187
+ for (var _i = 0; _i < arguments.length; _i++) {
188
+ args[_i] = arguments[_i];
189
+ }
190
+ var key = resolver.apply(void 0, args);
191
+ if (cache.has(key)) {
192
+ return cache.get(key);
193
+ }
194
+ var promise = func.apply(void 0, args);
195
+ cache.set(key, promise);
196
+ promise.then(function () { return clearOnResolve && cache.delete(key); });
197
+ promise.catch(function () { return clearOnReject && cache.delete(key); });
198
+ return promise;
199
+ };
200
+ memoized.cache = cache;
201
+ return memoized;
202
+ };
203
+
204
+ /**
205
+ * @license
206
+ * global.ts
207
+ * util
208
+ *
209
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-04-21
210
+ * Copyright © 2022 Monterosa. All rights reserved.
211
+ *
212
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
213
+ */
214
+ /* eslint no-restricted-globals: "off" */
215
+ /**
216
+ * Global object polyfill.
217
+ * Based on MDN article: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
218
+ *
219
+ * @internal
220
+ *
221
+ * @returns typeof globalThis
222
+ */
223
+ function getGlobal() {
224
+ if (typeof self !== 'undefined') {
225
+ return self;
226
+ }
227
+ if (typeof globalThis !== 'undefined') {
228
+ return globalThis;
229
+ }
230
+ if (typeof window !== 'undefined') {
231
+ return window;
232
+ }
233
+ if (typeof global !== 'undefined') {
234
+ return global;
235
+ }
236
+ throw new Error('Unable to locate global object.');
237
+ }
238
+
239
+ /**
240
+ * @license
241
+ * storage.ts
242
+ * util
243
+ *
244
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-04-21
245
+ * Copyright © 2022 Monterosa. All rights reserved.
246
+ *
247
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
248
+ */
249
+ var PREFIX = 'monterosa_sdk_';
250
+ var BAIT = 'bait';
251
+ var globals = getGlobal();
252
+ /**
253
+ * @internal
254
+ */
255
+ var getKey = function (name) { return "" + PREFIX + name; };
256
+ /**
257
+ * @internal
258
+ */
259
+ function getItem(key) {
260
+ return globals.localStorage.getItem(getKey(key));
261
+ }
262
+ /**
263
+ * @internal
264
+ */
265
+ function setItem(key, value) {
266
+ return globals.localStorage.setItem(getKey(key), value);
267
+ }
268
+ /**
269
+ * @internal
270
+ */
271
+ function removeItem(key) {
272
+ return globals.localStorage.removeItem(getKey(key));
273
+ }
274
+ /**
275
+ * @internal
276
+ */
277
+ function clear() {
278
+ return globals.localStorage.clear();
279
+ }
280
+ /**
281
+ * Checks locastorage availability.
282
+ * Based on MDN article: https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
283
+ * and Paul Irish gists: https://gist.github.com/paulirish/5558557
284
+ *
285
+ * @internal
286
+ *
287
+ * @returns boolean
288
+ */
289
+ function checkAvailability() {
290
+ try {
291
+ setItem(BAIT, BAIT);
292
+ getItem(BAIT);
293
+ removeItem(BAIT);
294
+ return true;
295
+ }
296
+ catch (e) {
297
+ return false;
298
+ }
299
+ }
300
+
301
+ /**
302
+ * @license
303
+ * error.ts
304
+ * util
305
+ *
306
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2022-03-31
307
+ * Copyright © 2022 Monterosa. All rights reserved.
308
+ *
309
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
310
+ */
311
+ /* eslint max-classes-per-file: ["error", 2] */
312
+ /**
313
+ * MonterosaError extends the standard JavaScript `Error` object. It has
314
+ * an error code so that user can identify the error. Also it has it's own
315
+ * specific `name` "MonterosaError"
316
+ */
317
+ var MonterosaError = /** @class */ (function (_super) {
318
+ __extends(MonterosaError, _super);
319
+ /**
320
+ * @param code - Error code string
321
+ * @param message - A descriptive message for the error
322
+ */
323
+ function MonterosaError(code, message) {
324
+ var _this = _super.call(this, message) || this;
325
+ /**
326
+ * The name property represents a name for the type of error.
327
+ */
328
+ _this.name = 'MonterosaError';
329
+ _this.code = code;
330
+ // Fix For ES5
331
+ // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
332
+ Object.setPrototypeOf(_this, MonterosaError.prototype);
333
+ return _this;
334
+ }
335
+ return MonterosaError;
336
+ }(Error));
337
+ /**
338
+ * @internal
339
+ */
340
+ function createError(code, messages) {
341
+ var params = [];
342
+ for (var _i = 2; _i < arguments.length; _i++) {
343
+ params[_i - 2] = arguments[_i];
344
+ }
345
+ var message = messages[code].apply(messages, params);
346
+ return new MonterosaError(code, message);
347
+ }
348
+
349
+ /**
350
+ * @license
351
+ * throttle.ts
352
+ * util
353
+ *
354
+ * Created by Josep Rodriguez <josep.rodriguez@monterosa.co.uk> on 2022-07-13
355
+ * Copyright © 2022 Monterosa. All rights reserved.
356
+ *
357
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
358
+ */
359
+ /* eslint-disable */
360
+ // @ts-nocheck
361
+ /**
362
+ * lodash (Custom Build) <https://lodash.com/>
363
+ * Build: `lodash modularize exports="npm" -o ./`
364
+ * Copyright jQuery Foundation and other contributors <https://jquery.org/>
365
+ * Released under MIT license <https://lodash.com/license>
366
+ * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
367
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
368
+ */
369
+ /** Used as the `TypeError` message for "Functions" methods. */
370
+ var FUNC_ERROR_TEXT = 'Expected a function';
371
+ /** Used as references for various `Number` constants. */
372
+ var NAN = 0 / 0;
373
+ /** `Object#toString` result references. */
374
+ var symbolTag = '[object Symbol]';
375
+ /** Used to match leading and trailing whitespace. */
376
+ var reTrim = /^\s+|\s+$/g;
377
+ /** Used to detect bad signed hexadecimal string values. */
378
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
379
+ /** Used to detect binary string values. */
380
+ var reIsBinary = /^0b[01]+$/i;
381
+ /** Used to detect octal string values. */
382
+ var reIsOctal = /^0o[0-7]+$/i;
383
+ /** Built-in method references without a dependency on `root`. */
384
+ var freeParseInt = parseInt;
385
+ /** Detect free variable `global` from Node.js. */
386
+ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
387
+ /** Detect free variable `self`. */
388
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
389
+ /** Used as a reference to the global object. */
390
+ var root = freeGlobal || freeSelf || Function('return this')();
391
+ /** Used for built-in method references. */
392
+ var objectProto = Object.prototype;
393
+ /**
394
+ * Used to resolve the
395
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
396
+ * of values.
397
+ */
398
+ var objectToString = objectProto.toString;
399
+ /* Built-in method references for those with the same name as other `lodash` methods. */
400
+ var nativeMax = Math.max, nativeMin = Math.min;
401
+ /**
402
+ * Gets the timestamp of the number of milliseconds that have elapsed since
403
+ * the Unix epoch (1 January 1970 00:00:00 UTC).
404
+ *
405
+ * @static
406
+ * @memberOf _
407
+ * @since 2.4.0
408
+ * @category Date
409
+ * @returns {number} Returns the timestamp.
410
+ * @example
411
+ *
412
+ * _.defer(function(stamp) {
413
+ * console.log(_.now() - stamp);
414
+ * }, _.now());
415
+ * // => Logs the number of milliseconds it took for the deferred invocation.
416
+ */
417
+ var now$1 = function () {
418
+ return root.Date.now();
419
+ };
420
+ /**
421
+ * Creates a debounced function that delays invoking `func` until after `wait`
422
+ * milliseconds have elapsed since the last time the debounced function was
423
+ * invoked. The debounced function comes with a `cancel` method to cancel
424
+ * delayed `func` invocations and a `flush` method to immediately invoke them.
425
+ * Provide `options` to indicate whether `func` should be invoked on the
426
+ * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
427
+ * with the last arguments provided to the debounced function. Subsequent
428
+ * calls to the debounced function return the result of the last `func`
429
+ * invocation.
430
+ *
431
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
432
+ * invoked on the trailing edge of the timeout only if the debounced function
433
+ * is invoked more than once during the `wait` timeout.
434
+ *
435
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
436
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
437
+ *
438
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
439
+ * for details over the differences between `_.debounce` and `_.throttle`.
440
+ *
441
+ * @static
442
+ * @memberOf _
443
+ * @since 0.1.0
444
+ * @category Function
445
+ * @param {Function} func The function to debounce.
446
+ * @param {number} [wait=0] The number of milliseconds to delay.
447
+ * @param {Object} [options={}] The options object.
448
+ * @param {boolean} [options.leading=false]
449
+ * Specify invoking on the leading edge of the timeout.
450
+ * @param {number} [options.maxWait]
451
+ * The maximum time `func` is allowed to be delayed before it's invoked.
452
+ * @param {boolean} [options.trailing=true]
453
+ * Specify invoking on the trailing edge of the timeout.
454
+ * @returns {Function} Returns the new debounced function.
455
+ * @example
456
+ *
457
+ * // Avoid costly calculations while the window size is in flux.
458
+ * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
459
+ *
460
+ * // Invoke `sendMail` when clicked, debouncing subsequent calls.
461
+ * jQuery(element).on('click', _.debounce(sendMail, 300, {
462
+ * 'leading': true,
463
+ * 'trailing': false
464
+ * }));
465
+ *
466
+ * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
467
+ * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
468
+ * var source = new EventSource('/stream');
469
+ * jQuery(source).on('message', debounced);
470
+ *
471
+ * // Cancel the trailing debounced invocation.
472
+ * jQuery(window).on('popstate', debounced.cancel);
473
+ */
474
+ function debounce(func, wait, options) {
475
+ var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
476
+ if (typeof func != 'function') {
477
+ throw new TypeError(FUNC_ERROR_TEXT);
478
+ }
479
+ wait = toNumber(wait) || 0;
480
+ if (isObject(options)) {
481
+ leading = !!options.leading;
482
+ maxing = 'maxWait' in options;
483
+ maxWait = maxing
484
+ ? nativeMax(toNumber(options.maxWait) || 0, wait)
485
+ : maxWait;
486
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
487
+ }
488
+ function invokeFunc(time) {
489
+ var args = lastArgs, thisArg = lastThis;
490
+ lastArgs = lastThis = undefined;
491
+ lastInvokeTime = time;
492
+ result = func.apply(thisArg, args);
493
+ return result;
494
+ }
495
+ function leadingEdge(time) {
496
+ // Reset any `maxWait` timer.
497
+ lastInvokeTime = time;
498
+ // Start the timer for the trailing edge.
499
+ timerId = setTimeout(timerExpired, wait);
500
+ // Invoke the leading edge.
501
+ return leading ? invokeFunc(time) : result;
502
+ }
503
+ function remainingWait(time) {
504
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall;
505
+ return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
506
+ }
507
+ function shouldInvoke(time) {
508
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
509
+ // Either this is the first call, activity has stopped and we're at the
510
+ // trailing edge, the system time has gone backwards and we're treating
511
+ // it as the trailing edge, or we've hit the `maxWait` limit.
512
+ return (lastCallTime === undefined ||
513
+ timeSinceLastCall >= wait ||
514
+ timeSinceLastCall < 0 ||
515
+ (maxing && timeSinceLastInvoke >= maxWait));
516
+ }
517
+ function timerExpired() {
518
+ var time = now$1();
519
+ if (shouldInvoke(time)) {
520
+ return trailingEdge(time);
521
+ }
522
+ // Restart the timer.
523
+ timerId = setTimeout(timerExpired, remainingWait(time));
524
+ }
525
+ function trailingEdge(time) {
526
+ timerId = undefined;
527
+ // Only invoke if we have `lastArgs` which means `func` has been
528
+ // debounced at least once.
529
+ if (trailing && lastArgs) {
530
+ return invokeFunc(time);
531
+ }
532
+ lastArgs = lastThis = undefined;
533
+ return result;
534
+ }
535
+ function cancel() {
536
+ if (timerId !== undefined) {
537
+ clearTimeout(timerId);
538
+ }
539
+ lastInvokeTime = 0;
540
+ lastArgs = lastCallTime = lastThis = timerId = undefined;
541
+ }
542
+ function flush() {
543
+ return timerId === undefined ? result : trailingEdge(now$1());
544
+ }
545
+ function debounced() {
546
+ var time = now$1(), isInvoking = shouldInvoke(time);
547
+ lastArgs = arguments;
548
+ lastThis = this;
549
+ lastCallTime = time;
550
+ if (isInvoking) {
551
+ if (timerId === undefined) {
552
+ return leadingEdge(lastCallTime);
553
+ }
554
+ if (maxing) {
555
+ // Handle invocations in a tight loop.
556
+ timerId = setTimeout(timerExpired, wait);
557
+ return invokeFunc(lastCallTime);
558
+ }
559
+ }
560
+ if (timerId === undefined) {
561
+ timerId = setTimeout(timerExpired, wait);
562
+ }
563
+ return result;
564
+ }
565
+ debounced.cancel = cancel;
566
+ debounced.flush = flush;
567
+ return debounced;
568
+ }
569
+ /**
570
+ * Creates a throttled function that only invokes `func` at most once per
571
+ * every `wait` milliseconds. The throttled function comes with a `cancel`
572
+ * method to cancel delayed `func` invocations and a `flush` method to
573
+ * immediately invoke them. Provide `options` to indicate whether `func`
574
+ * should be invoked on the leading and/or trailing edge of the `wait`
575
+ * timeout. The `func` is invoked with the last arguments provided to the
576
+ * throttled function. Subsequent calls to the throttled function return the
577
+ * result of the last `func` invocation.
578
+ *
579
+ * **Note:** If `leading` and `trailing` options are `true`, `func` is
580
+ * invoked on the trailing edge of the timeout only if the throttled function
581
+ * is invoked more than once during the `wait` timeout.
582
+ *
583
+ * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
584
+ * until to the next tick, similar to `setTimeout` with a timeout of `0`.
585
+ *
586
+ * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
587
+ * for details over the differences between `_.throttle` and `_.debounce`.
588
+ *
589
+ * @internal
590
+ *
591
+ * @static
592
+ * @memberOf _
593
+ * @since 0.1.0
594
+ * @category Function
595
+ * @param {Function} func The function to throttle.
596
+ * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
597
+ * @param {Object} [options={}] The options object.
598
+ * @param {boolean} [options.leading=true]
599
+ * Specify invoking on the leading edge of the timeout.
600
+ * @param {boolean} [options.trailing=true]
601
+ * Specify invoking on the trailing edge of the timeout.
602
+ * @returns {Function} Returns the new throttled function.
603
+ * @example
604
+ *
605
+ * // Avoid excessively updating the position while scrolling.
606
+ * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
607
+ *
608
+ * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
609
+ * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
610
+ * jQuery(element).on('click', throttled);
611
+ *
612
+ * // Cancel the trailing throttled invocation.
613
+ * jQuery(window).on('popstate', throttled.cancel);
614
+ */
615
+ function throttle(func, wait, options) {
616
+ var leading = true, trailing = true;
617
+ if (typeof func != 'function') {
618
+ throw new TypeError(FUNC_ERROR_TEXT);
619
+ }
620
+ if (isObject(options)) {
621
+ leading = 'leading' in options ? !!options.leading : leading;
622
+ trailing = 'trailing' in options ? !!options.trailing : trailing;
623
+ }
624
+ return debounce(func, wait, {
625
+ leading: leading,
626
+ maxWait: wait,
627
+ trailing: trailing,
628
+ });
629
+ }
630
+ /**
631
+ * Checks if `value` is the
632
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
633
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
634
+ *
635
+ * @static
636
+ * @memberOf _
637
+ * @since 0.1.0
638
+ * @category Lang
639
+ * @param {*} value The value to check.
640
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
641
+ * @example
642
+ *
643
+ * _.isObject({});
644
+ * // => true
645
+ *
646
+ * _.isObject([1, 2, 3]);
647
+ * // => true
648
+ *
649
+ * _.isObject(_.noop);
650
+ * // => true
651
+ *
652
+ * _.isObject(null);
653
+ * // => false
654
+ */
655
+ function isObject(value) {
656
+ var type = typeof value;
657
+ return !!value && (type == 'object' || type == 'function');
658
+ }
659
+ /**
660
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
661
+ * and has a `typeof` result of "object".
662
+ *
663
+ * @static
664
+ * @memberOf _
665
+ * @since 4.0.0
666
+ * @category Lang
667
+ * @param {*} value The value to check.
668
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
669
+ * @example
670
+ *
671
+ * _.isObjectLike({});
672
+ * // => true
673
+ *
674
+ * _.isObjectLike([1, 2, 3]);
675
+ * // => true
676
+ *
677
+ * _.isObjectLike(_.noop);
678
+ * // => false
679
+ *
680
+ * _.isObjectLike(null);
681
+ * // => false
682
+ */
683
+ function isObjectLike(value) {
684
+ return !!value && typeof value == 'object';
685
+ }
686
+ /**
687
+ * Checks if `value` is classified as a `Symbol` primitive or object.
688
+ *
689
+ * @static
690
+ * @memberOf _
691
+ * @since 4.0.0
692
+ * @category Lang
693
+ * @param {*} value The value to check.
694
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
695
+ * @example
696
+ *
697
+ * _.isSymbol(Symbol.iterator);
698
+ * // => true
699
+ *
700
+ * _.isSymbol('abc');
701
+ * // => false
702
+ */
703
+ function isSymbol(value) {
704
+ return (typeof value == 'symbol' ||
705
+ (isObjectLike(value) && objectToString.call(value) == symbolTag));
706
+ }
707
+ /**
708
+ * Converts `value` to a number.
709
+ *
710
+ * @static
711
+ * @memberOf _
712
+ * @since 4.0.0
713
+ * @category Lang
714
+ * @param {*} value The value to process.
715
+ * @returns {number} Returns the number.
716
+ * @example
717
+ *
718
+ * _.toNumber(3.2);
719
+ * // => 3.2
720
+ *
721
+ * _.toNumber(Number.MIN_VALUE);
722
+ * // => 5e-324
723
+ *
724
+ * _.toNumber(Infinity);
725
+ * // => Infinity
726
+ *
727
+ * _.toNumber('3.2');
728
+ * // => 3.2
729
+ */
730
+ function toNumber(value) {
731
+ if (typeof value == 'number') {
732
+ return value;
733
+ }
734
+ if (isSymbol(value)) {
735
+ return NAN;
736
+ }
737
+ if (isObject(value)) {
738
+ var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
739
+ value = isObject(other) ? other + '' : other;
740
+ }
741
+ if (typeof value != 'string') {
742
+ return value === 0 ? value : +value;
743
+ }
744
+ value = value.replace(reTrim, '');
745
+ var isBinary = reIsBinary.test(value);
746
+ return isBinary || reIsOctal.test(value)
747
+ ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
748
+ : reIsBadHex.test(value)
749
+ ? NAN
750
+ : +value;
751
+ }
752
+
753
+ /**
754
+ * @license
755
+ * time.ts
756
+ * util
757
+ *
758
+ * Created by Rygor Kharytanovich <rygor@monterosa.co.uk> on 2025-03-24
759
+ * Copyright © 2025 Monterosa. All rights reserved.
760
+ *
761
+ * More details on the license can be found at https://www.monterosa.co/sdk/license
762
+ */
763
+ var emitter = new Emitter();
764
+ var serverTimestamp = 0;
765
+ var lastTickTimestamp = 0;
766
+ var tickTimeoutId;
767
+ /**
768
+ * Returns local timestamp in seconds
769
+ */
770
+ function getCurrentTimestamp() {
771
+ return Date.now() / 1000;
772
+ }
773
+ /**
774
+ * Normalizes the timestamp to reduce fluctuations due to `setTimeout` delays.
775
+ * Ensures the fractional part is around 0.5 to avoid skipping a second.
776
+ *
777
+ * Returns half-second timestamp. It is used to be sure that timestamp will not
778
+ * fluctuate more than in 1 second after each tick due to longer delays.
779
+ * https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#reasons_for_delays_longer_than_specified
780
+ *
781
+ * For example if the initial timestamp has a fractional part 0.9999 then with
782
+ * the setTimeout (tick) longer than specified we might jump over a one second.
783
+ * Lets imaging setTimeout took 1.0002 second, then our timestamp will be 2.0001.
784
+ * Thats why we are trying to keep fractional part in the middle of the second.
785
+ */
786
+ function getMiddleTimestamp(timestamp) {
787
+ return Math.floor(timestamp) + 0.5;
788
+ }
789
+ /**
790
+ * Calculates the delay for the next tick to keep timestamps stable.
791
+ */
792
+ function calculateNextTickDelay() {
793
+ var expectedNextTick = getMiddleTimestamp(serverTimestamp) + 1;
794
+ return (expectedNextTick - serverTimestamp) * 1000;
795
+ }
796
+ /**
797
+ * Main function that maintains current timestamp
798
+ */
799
+ function tick() {
800
+ clearTimeout(tickTimeoutId);
801
+ var currentTimestamp = getCurrentTimestamp();
802
+ var timeSinceLastTick = currentTimestamp - lastTickTimestamp;
803
+ serverTimestamp += timeSinceLastTick;
804
+ lastTickTimestamp = currentTimestamp;
805
+ tickTimeoutId = setTimeout(tick, calculateNextTickDelay());
806
+ emitter.emit('tick', serverTimestamp);
807
+ }
808
+ /**
809
+ * @internal
810
+ *
811
+ * Sets or updates current timestamp
812
+ *
813
+ * @param timestamp - Current timestamp in seconds
814
+ */
815
+ function setTimestamp(timestamp) {
816
+ lastTickTimestamp = getCurrentTimestamp();
817
+ serverTimestamp = getMiddleTimestamp(timestamp);
818
+ }
819
+ /**
820
+ * Returns current timestamp that is preserved by `tick()` function
821
+ *
822
+ * @returns Current timestamp in seconds
823
+ */
824
+ function now() {
825
+ return Math.floor(serverTimestamp);
826
+ }
827
+ /**
828
+ * Subscribes listener to the timestamp increment
829
+ *
830
+ * @param callback - A handler that executes when the timestamp is incremented
831
+ *
832
+ * @returns A function that unsubscribes the listener
833
+ */
834
+ function onTick(callback) {
835
+ return subscribe(emitter, 'tick', callback);
836
+ }
837
+ // Initially timestamp is set based on a local date
838
+ // Later on it can be overriden outside at any moment
839
+ // in our case it is populated with the server timestamp
840
+ // which comes from Enmasse session handshake message
841
+ setTimestamp(getCurrentTimestamp());
842
+ // Kicking in timestamp maintaining
843
+ tick();
844
+
845
+ export { Emitter, MonterosaError, checkAvailability, clear, createError, delay, getGlobal, getItem, getKey, memoizePromise, now, onTick, removeItem, setItem, setTimestamp, subscribe, throttle, tick };
846
+ //# sourceMappingURL=index.esm5.js.map