@formo/analytics 1.17.3 → 1.17.5
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/package.json +4 -1
- package/.env.example +0 -1
- package/.github/workflows/ci.yml +0 -50
- package/.github/workflows/release.yml +0 -54
- package/.husky/post-commit +0 -7
- package/.husky/pre-commit +0 -11
- package/.releaserc.js +0 -35
- package/CONTRIBUTING.md +0 -83
- package/scripts/generate-sri.sh +0 -52
- package/src/FormoAnalytics.ts +0 -1031
- package/src/FormoAnalyticsProvider.tsx +0 -84
- package/src/constants/base.ts +0 -6
- package/src/constants/config.ts +0 -660
- package/src/constants/events.ts +0 -21
- package/src/constants/index.ts +0 -3
- package/src/global.d.ts +0 -12
- package/src/index.ts +0 -3
- package/src/lib/event/EventFactory.ts +0 -519
- package/src/lib/event/EventManager.ts +0 -39
- package/src/lib/event/constants.ts +0 -4
- package/src/lib/event/index.ts +0 -3
- package/src/lib/event/type.ts +0 -9
- package/src/lib/event/utils.ts +0 -33
- package/src/lib/fetch.ts +0 -3
- package/src/lib/index.ts +0 -5
- package/src/lib/logger/Logger.ts +0 -115
- package/src/lib/logger/index.ts +0 -2
- package/src/lib/logger/type.ts +0 -14
- package/src/lib/queue/EventQueue.ts +0 -306
- package/src/lib/queue/index.ts +0 -2
- package/src/lib/queue/type.ts +0 -6
- package/src/lib/ramda/internal/_curry1.ts +0 -19
- package/src/lib/ramda/internal/_curry2.ts +0 -37
- package/src/lib/ramda/internal/_curry3.ts +0 -68
- package/src/lib/ramda/internal/_has.ts +0 -3
- package/src/lib/ramda/internal/_isObject.ts +0 -3
- package/src/lib/ramda/internal/_isPlaceholder.ts +0 -5
- package/src/lib/ramda/mergeDeepRight.ts +0 -13
- package/src/lib/ramda/mergeDeepWithKey.ts +0 -22
- package/src/lib/ramda/mergeWithKey.ts +0 -28
- package/src/lib/storage/StorageManager.ts +0 -51
- package/src/lib/storage/built-in/blueprint.ts +0 -17
- package/src/lib/storage/built-in/cookie.ts +0 -60
- package/src/lib/storage/built-in/memory.ts +0 -23
- package/src/lib/storage/built-in/web.ts +0 -57
- package/src/lib/storage/constant.ts +0 -2
- package/src/lib/storage/index.ts +0 -25
- package/src/lib/storage/type.ts +0 -21
- package/src/lib/version.ts +0 -2
- package/src/types/base.ts +0 -120
- package/src/types/events.ts +0 -126
- package/src/types/index.ts +0 -3
- package/src/types/provider.ts +0 -17
- package/src/utils/address.ts +0 -43
- package/src/utils/base.ts +0 -3
- package/src/utils/converter.ts +0 -44
- package/src/utils/generate.ts +0 -16
- package/src/utils/index.ts +0 -4
- package/src/utils/timestamp.ts +0 -9
- package/src/validators/address.ts +0 -69
- package/src/validators/agent.ts +0 -4
- package/src/validators/checks.ts +0 -160
- package/src/validators/index.ts +0 -7
- package/src/validators/network.ts +0 -34
- package/src/validators/object.ts +0 -4
- package/src/validators/string.ts +0 -4
- package/src/validators/uint8array.ts +0 -17
- package/test/lib/events.spec.ts +0 -12
- package/test/utils/address.spec.ts +0 -14
- package/test/utils/converter.spec.ts +0 -31
- package/test/validators/address.spec.ts +0 -15
- package/tsconfig.json +0 -28
- package/webpack.config.ts +0 -23
package/src/lib/logger/Logger.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { ILogger, LogLevel } from "./type";
|
|
2
|
-
|
|
3
|
-
export class Logger implements ILogger {
|
|
4
|
-
private static instance: ILogger;
|
|
5
|
-
private enabledLevels: Set<LogLevel>;
|
|
6
|
-
private enabled: boolean;
|
|
7
|
-
|
|
8
|
-
private constructor(
|
|
9
|
-
enabled: boolean = false,
|
|
10
|
-
enabledLevels: LogLevel[] = []
|
|
11
|
-
) {
|
|
12
|
-
this.enabled = enabled;
|
|
13
|
-
this.enabledLevels = new Set(enabledLevels);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
public static init(config: {
|
|
17
|
-
enabled?: boolean;
|
|
18
|
-
enabledLevels?: LogLevel[];
|
|
19
|
-
}): void {
|
|
20
|
-
// Get or create instance
|
|
21
|
-
const instance = Logger.getInstance();
|
|
22
|
-
|
|
23
|
-
// Update configuration
|
|
24
|
-
if (config.enabled !== undefined) {
|
|
25
|
-
instance.setEnabled(config.enabled);
|
|
26
|
-
}
|
|
27
|
-
if (config.enabledLevels !== undefined) {
|
|
28
|
-
instance.setEnabledLevels(config.enabledLevels);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public static getInstance(config?: {
|
|
33
|
-
enabled?: boolean;
|
|
34
|
-
enabledLevels?: LogLevel[];
|
|
35
|
-
}): ILogger {
|
|
36
|
-
if (!Logger.instance) {
|
|
37
|
-
Logger.instance = new Logger(
|
|
38
|
-
config?.enabled ?? false,
|
|
39
|
-
config?.enabledLevels ?? []
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
return Logger.instance;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public setEnabled(enabled: boolean): void {
|
|
46
|
-
this.enabled = enabled;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public isLoggingEnabled(): boolean {
|
|
50
|
-
return this.enabled;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public setEnabledLevels(levels: LogLevel[]): void {
|
|
54
|
-
this.enabledLevels = new Set(levels);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public getEnabledLevels(): LogLevel[] {
|
|
58
|
-
return Array.from(this.enabledLevels);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private shouldLog(level: LogLevel): boolean {
|
|
62
|
-
if (!this.enabled) return false;
|
|
63
|
-
return this.enabledLevels.has(level);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private formatMessage(message: string): string {
|
|
67
|
-
const timestamp = new Date().toLocaleString("en-US", {
|
|
68
|
-
year: "numeric",
|
|
69
|
-
month: "2-digit",
|
|
70
|
-
day: "2-digit",
|
|
71
|
-
hour: "2-digit",
|
|
72
|
-
minute: "2-digit",
|
|
73
|
-
second: "2-digit",
|
|
74
|
-
hour12: false,
|
|
75
|
-
});
|
|
76
|
-
return `[Formo Analytics][${timestamp}] ${message}`;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
public debug(message: string, ...args: any[]): void {
|
|
80
|
-
if (this.shouldLog("debug")) {
|
|
81
|
-
console.debug(this.formatMessage(message), ...args);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public info(message: string, ...args: any[]): void {
|
|
86
|
-
if (this.shouldLog("info")) {
|
|
87
|
-
console.info(this.formatMessage(message), ...args);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public warn(message: string, ...args: any[]): void {
|
|
92
|
-
if (this.shouldLog("warn")) {
|
|
93
|
-
console.warn(this.formatMessage(message), ...args);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
public error(message: string, ...args: any[]): void {
|
|
98
|
-
if (this.shouldLog("error")) {
|
|
99
|
-
console.error(this.formatMessage(message), ...args);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
public trace(message: string, ...args: any[]): void {
|
|
104
|
-
if (this.shouldLog("trace")) {
|
|
105
|
-
console.trace(this.formatMessage(message), ...args);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
public log(message: string, ...args: any[]): void {
|
|
110
|
-
this.info(message, ...args);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Export a default instance for easy use
|
|
115
|
-
export const logger = Logger.getInstance();
|
package/src/lib/logger/index.ts
DELETED
package/src/lib/logger/type.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export interface ILogger {
|
|
2
|
-
setEnabledLevels(levels: LogLevel[]): void;
|
|
3
|
-
getEnabledLevels(): LogLevel[];
|
|
4
|
-
setEnabled(enabled: boolean): void;
|
|
5
|
-
isLoggingEnabled(): boolean;
|
|
6
|
-
log(...data: any[]): void;
|
|
7
|
-
info(...data: any[]): void;
|
|
8
|
-
debug(...data: any[]): void;
|
|
9
|
-
warn(...data: any[]): void;
|
|
10
|
-
error(...data: any[]): void;
|
|
11
|
-
trace(...data: any[]): void;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type LogLevel = "debug" | "info" | "warn" | "error" | "trace";
|
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import { isNetworkError } from "../../validators";
|
|
2
|
-
import { IFormoEvent, IFormoEventPayload } from "../../types";
|
|
3
|
-
import {
|
|
4
|
-
clampNumber,
|
|
5
|
-
getActionDescriptor,
|
|
6
|
-
hash,
|
|
7
|
-
millisecondsToSecond,
|
|
8
|
-
toDateHourMinute,
|
|
9
|
-
} from "../../utils";
|
|
10
|
-
import { logger } from "../logger";
|
|
11
|
-
import { EVENTS_API_REQUEST_HEADER } from "../../constants";
|
|
12
|
-
import fetch from "../fetch";
|
|
13
|
-
import { IEventQueue } from "./type";
|
|
14
|
-
const noop = () => {};
|
|
15
|
-
|
|
16
|
-
type QueueItem = {
|
|
17
|
-
message: IFormoEventPayload;
|
|
18
|
-
callback: (...args: any) => any;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
type IFormoEventFlushPayload = IFormoEventPayload & {
|
|
22
|
-
sent_at: string;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
type Options = {
|
|
26
|
-
url: string;
|
|
27
|
-
flushAt?: number;
|
|
28
|
-
flushInterval?: number;
|
|
29
|
-
host?: string;
|
|
30
|
-
retryCount?: number;
|
|
31
|
-
errorHandler?: any;
|
|
32
|
-
maxQueueSize?: number;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const DEFAULT_RETRY = 3;
|
|
36
|
-
const MAX_RETRY = 5;
|
|
37
|
-
const MIN_RETRY = 1;
|
|
38
|
-
|
|
39
|
-
const DEFAULT_FLUSH_AT = 20;
|
|
40
|
-
const MAX_FLUSH_AT = 20;
|
|
41
|
-
const MIN_FLUSH_AT = 1;
|
|
42
|
-
|
|
43
|
-
const DEFAULT_QUEUE_SIZE = 1_024 * 500; // 500kB
|
|
44
|
-
const MAX_QUEUE_SIZE = 1_024 * 500; // 500kB
|
|
45
|
-
const MIN_QUEUE_SIZE = 200; // 200 bytes
|
|
46
|
-
|
|
47
|
-
const DEFAULT_FLUSH_INTERVAL = 1_000 * 30; // 1 MINUTE
|
|
48
|
-
const MAX_FLUSH_INTERVAL = 1_000 * 300; // 5 MINUTES
|
|
49
|
-
const MIN_FLUSH_INTERVAL = 1_000 * 10; // 10 SECONDS
|
|
50
|
-
|
|
51
|
-
export class EventQueue implements IEventQueue {
|
|
52
|
-
private writeKey: string;
|
|
53
|
-
private url: string;
|
|
54
|
-
private queue: QueueItem[] = [];
|
|
55
|
-
private timer: null | NodeJS.Timeout;
|
|
56
|
-
private flushAt: number;
|
|
57
|
-
private flushIntervalMs: number;
|
|
58
|
-
private flushed: boolean;
|
|
59
|
-
private maxQueueSize: number; // min 200 bytes, max 500kB
|
|
60
|
-
private errorHandler: any;
|
|
61
|
-
private retryCount: number;
|
|
62
|
-
private pendingFlush: Promise<any> | null;
|
|
63
|
-
private payloadHashes: Set<string> = new Set();
|
|
64
|
-
|
|
65
|
-
constructor(writeKey: string, options: Options) {
|
|
66
|
-
options = options || {};
|
|
67
|
-
|
|
68
|
-
this.queue = [];
|
|
69
|
-
this.writeKey = writeKey;
|
|
70
|
-
this.url = options.url;
|
|
71
|
-
this.retryCount = clampNumber(
|
|
72
|
-
options.retryCount || DEFAULT_RETRY,
|
|
73
|
-
MAX_RETRY,
|
|
74
|
-
MIN_RETRY
|
|
75
|
-
);
|
|
76
|
-
this.flushAt = clampNumber(
|
|
77
|
-
options.flushAt || DEFAULT_FLUSH_AT,
|
|
78
|
-
MAX_FLUSH_AT,
|
|
79
|
-
MIN_FLUSH_AT
|
|
80
|
-
);
|
|
81
|
-
this.maxQueueSize = clampNumber(
|
|
82
|
-
options.maxQueueSize || DEFAULT_QUEUE_SIZE,
|
|
83
|
-
MAX_QUEUE_SIZE,
|
|
84
|
-
MIN_QUEUE_SIZE
|
|
85
|
-
);
|
|
86
|
-
this.flushIntervalMs = clampNumber(
|
|
87
|
-
options.flushInterval || DEFAULT_FLUSH_INTERVAL,
|
|
88
|
-
MAX_FLUSH_INTERVAL,
|
|
89
|
-
MIN_FLUSH_INTERVAL
|
|
90
|
-
);
|
|
91
|
-
this.flushed = true;
|
|
92
|
-
this.errorHandler = options.errorHandler;
|
|
93
|
-
this.pendingFlush = null;
|
|
94
|
-
this.timer = null;
|
|
95
|
-
|
|
96
|
-
this.onPageLeave(async (isAccessible: boolean) => {
|
|
97
|
-
if (isAccessible === false) {
|
|
98
|
-
await this.flush();
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
//#region Public functions
|
|
104
|
-
private async generateMessageId(event: IFormoEvent): Promise<string> {
|
|
105
|
-
const formattedTimestamp = toDateHourMinute(new Date(event.original_timestamp));
|
|
106
|
-
const eventForHashing = { ...event, original_timestamp: formattedTimestamp };
|
|
107
|
-
const eventString = JSON.stringify(eventForHashing);
|
|
108
|
-
return hash(eventString);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
async enqueue(event: IFormoEvent, callback?: (...args: any) => void) {
|
|
112
|
-
callback = callback || noop;
|
|
113
|
-
|
|
114
|
-
const message_id = await this.generateMessageId(event);
|
|
115
|
-
// check if the message already exists
|
|
116
|
-
if (await this.isDuplicate(message_id)) {
|
|
117
|
-
logger.warn(
|
|
118
|
-
`Event already enqueued, try again after ${millisecondsToSecond(
|
|
119
|
-
this.flushIntervalMs
|
|
120
|
-
)} seconds.`
|
|
121
|
-
);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
this.queue.push({
|
|
126
|
-
message: { ...event, message_id },
|
|
127
|
-
callback,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
logger.log(
|
|
131
|
-
`Event enqueued: ${getActionDescriptor(event.type, event.properties)}`
|
|
132
|
-
);
|
|
133
|
-
|
|
134
|
-
if (!this.flushed) {
|
|
135
|
-
this.flushed = true;
|
|
136
|
-
this.flush();
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const hasReachedFlushAt = this.queue.length >= this.flushAt;
|
|
141
|
-
const hasReachedQueueSize =
|
|
142
|
-
this.queue.reduce((acc, item) => acc + JSON.stringify(item).length, 0) >=
|
|
143
|
-
this.maxQueueSize;
|
|
144
|
-
|
|
145
|
-
if (hasReachedFlushAt || hasReachedQueueSize) {
|
|
146
|
-
this.flush();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (this.flushIntervalMs && !this.timer) {
|
|
151
|
-
this.timer = setTimeout(this.flush.bind(this), this.flushIntervalMs);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
async flush(callback?: (...args: any) => void) {
|
|
156
|
-
callback = callback || noop;
|
|
157
|
-
|
|
158
|
-
if (this.timer) {
|
|
159
|
-
clearTimeout(this.timer);
|
|
160
|
-
this.timer = null;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (!this.queue.length) {
|
|
164
|
-
callback();
|
|
165
|
-
return Promise.resolve();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
try {
|
|
169
|
-
if (this.pendingFlush) {
|
|
170
|
-
await this.pendingFlush;
|
|
171
|
-
}
|
|
172
|
-
} catch (err) {
|
|
173
|
-
this.pendingFlush = null;
|
|
174
|
-
throw err;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const items = this.queue.splice(0, this.flushAt);
|
|
178
|
-
this.payloadHashes.clear();
|
|
179
|
-
|
|
180
|
-
// Generate sent_at once for the entire batch
|
|
181
|
-
const sentAt = new Date().toISOString();
|
|
182
|
-
const data: IFormoEventFlushPayload[] = items.map((item) => ({
|
|
183
|
-
...item.message,
|
|
184
|
-
sent_at: sentAt
|
|
185
|
-
}));
|
|
186
|
-
|
|
187
|
-
const done = (err?: Error) => {
|
|
188
|
-
items.forEach(({ message, callback }) => callback(err, message, data));
|
|
189
|
-
callback(err, data);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
return (this.pendingFlush = fetch(`${this.url}`, {
|
|
193
|
-
headers: EVENTS_API_REQUEST_HEADER(this.writeKey),
|
|
194
|
-
method: "POST",
|
|
195
|
-
body: JSON.stringify(data),
|
|
196
|
-
keepalive: true,
|
|
197
|
-
retries: this.retryCount,
|
|
198
|
-
retryDelay: (attempt) => Math.pow(2, attempt) * 1_000, // exponential backoff
|
|
199
|
-
retryOn: (_, error) => this.isErrorRetryable(error),
|
|
200
|
-
})
|
|
201
|
-
.then(() => {
|
|
202
|
-
done();
|
|
203
|
-
return Promise.resolve(data);
|
|
204
|
-
})
|
|
205
|
-
.catch((err) => {
|
|
206
|
-
if (typeof this.errorHandler === "function") {
|
|
207
|
-
done(err);
|
|
208
|
-
return this.errorHandler(err);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (err.response) {
|
|
212
|
-
const error = new Error(err.response.statusText);
|
|
213
|
-
done(error);
|
|
214
|
-
throw error;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
done(err);
|
|
218
|
-
throw err;
|
|
219
|
-
}));
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
//#region Utility functions
|
|
223
|
-
private isErrorRetryable(error: any) {
|
|
224
|
-
// Retry Network Errors.
|
|
225
|
-
if (isNetworkError(error)) return true;
|
|
226
|
-
|
|
227
|
-
// Cannot determine if the request can be retried
|
|
228
|
-
if (!error?.response) return false;
|
|
229
|
-
|
|
230
|
-
// Retry Server Errors (5xx).
|
|
231
|
-
if (error?.response?.status >= 500 && error?.response?.status <= 599)
|
|
232
|
-
return true;
|
|
233
|
-
|
|
234
|
-
// Retry if rate limited.
|
|
235
|
-
if (error?.response?.status === 429) return true;
|
|
236
|
-
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
private async isDuplicate(eventId: string) {
|
|
241
|
-
// check if exists a message with identical payload within 1 minute
|
|
242
|
-
if (this.payloadHashes.has(eventId)) return true;
|
|
243
|
-
|
|
244
|
-
this.payloadHashes.add(eventId);
|
|
245
|
-
return false;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
private onPageLeave = (callback: (isAccessible: boolean) => void) => {
|
|
249
|
-
// To ensure the callback is only called once even if more than one events
|
|
250
|
-
// are fired at once.
|
|
251
|
-
let pageLeft = false;
|
|
252
|
-
let isAccessible = false;
|
|
253
|
-
|
|
254
|
-
function handleOnLeave() {
|
|
255
|
-
if (pageLeft) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
pageLeft = true;
|
|
260
|
-
|
|
261
|
-
callback(isAccessible);
|
|
262
|
-
|
|
263
|
-
// Reset pageLeft on the next tick
|
|
264
|
-
// to ensure callback executes for other listeners
|
|
265
|
-
// when closing an inactive browser tab.
|
|
266
|
-
setTimeout(() => {
|
|
267
|
-
pageLeft = false;
|
|
268
|
-
}, 0);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Catches the unloading of the page (e.g., closing the tab or navigating away).
|
|
272
|
-
// Includes user actions like clicking a link, entering a new URL,
|
|
273
|
-
// refreshing the page, or closing the browser tab
|
|
274
|
-
// Note that 'pagehide' is not supported in IE.
|
|
275
|
-
// So, this is a fallback.
|
|
276
|
-
(globalThis as typeof window).addEventListener("beforeunload", () => {
|
|
277
|
-
isAccessible = false;
|
|
278
|
-
handleOnLeave();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
(globalThis as typeof window).addEventListener("blur", () => {
|
|
282
|
-
isAccessible = true;
|
|
283
|
-
handleOnLeave();
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
(globalThis as typeof window).addEventListener("focus", () => {
|
|
287
|
-
pageLeft = false;
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
// Catches the page being hidden, including scenarios like closing the tab.
|
|
291
|
-
document.addEventListener("pagehide", () => {
|
|
292
|
-
isAccessible = document.visibilityState === "hidden";
|
|
293
|
-
handleOnLeave();
|
|
294
|
-
});
|
|
295
|
-
|
|
296
|
-
// Catches visibility changes, such as switching tabs or minimizing the browser.
|
|
297
|
-
document.addEventListener("visibilitychange", () => {
|
|
298
|
-
isAccessible = true;
|
|
299
|
-
if (document.visibilityState === "hidden") {
|
|
300
|
-
handleOnLeave();
|
|
301
|
-
} else {
|
|
302
|
-
pageLeft = false;
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
};
|
|
306
|
-
}
|
package/src/lib/queue/index.ts
DELETED
package/src/lib/queue/type.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import _isPlaceholder from "./_isPlaceholder";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Optimized internal one-arity curry function.
|
|
5
|
-
*
|
|
6
|
-
* @private
|
|
7
|
-
* @category Function
|
|
8
|
-
* @param {Function} fn The function to curry.
|
|
9
|
-
* @return {Function} The curried function.
|
|
10
|
-
*/
|
|
11
|
-
export default function _curry1(fn: Function) {
|
|
12
|
-
return function f1(a: any) {
|
|
13
|
-
if (arguments.length === 0 || _isPlaceholder(a)) {
|
|
14
|
-
return f1;
|
|
15
|
-
} else {
|
|
16
|
-
return fn.apply(this, arguments);
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import _curry1 from "./_curry1";
|
|
2
|
-
import _isPlaceholder from "./_isPlaceholder";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Optimized internal two-arity curry function.
|
|
6
|
-
*
|
|
7
|
-
* @private
|
|
8
|
-
* @category Function
|
|
9
|
-
* @param {Function} fn The function to curry.
|
|
10
|
-
* @return {Function} The curried function.
|
|
11
|
-
*/
|
|
12
|
-
export default function _curry2(fn: Function) {
|
|
13
|
-
return function f2(a: any, b: any) {
|
|
14
|
-
switch (arguments.length) {
|
|
15
|
-
case 0:
|
|
16
|
-
return f2;
|
|
17
|
-
case 1:
|
|
18
|
-
return _isPlaceholder(a)
|
|
19
|
-
? f2
|
|
20
|
-
: _curry1(function (_b: any) {
|
|
21
|
-
return fn(a, _b);
|
|
22
|
-
});
|
|
23
|
-
default:
|
|
24
|
-
return _isPlaceholder(a) && _isPlaceholder(b)
|
|
25
|
-
? f2
|
|
26
|
-
: _isPlaceholder(a)
|
|
27
|
-
? _curry1(function (_a: any) {
|
|
28
|
-
return fn(_a, b);
|
|
29
|
-
})
|
|
30
|
-
: _isPlaceholder(b)
|
|
31
|
-
? _curry1(function (_b: any) {
|
|
32
|
-
return fn(a, _b);
|
|
33
|
-
})
|
|
34
|
-
: fn(a, b);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import _curry1 from "./_curry1";
|
|
2
|
-
import _curry2 from "./_curry2";
|
|
3
|
-
import _isPlaceholder from "./_isPlaceholder";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Optimized internal three-arity curry function.
|
|
7
|
-
*
|
|
8
|
-
* @private
|
|
9
|
-
* @category Function
|
|
10
|
-
* @param {Function} fn The function to curry.
|
|
11
|
-
* @return {Function} The curried function.
|
|
12
|
-
*/
|
|
13
|
-
export default function _curry3(fn: Function) {
|
|
14
|
-
return function f3(a: any, b: any, c: any) {
|
|
15
|
-
switch (arguments.length) {
|
|
16
|
-
case 0:
|
|
17
|
-
return f3;
|
|
18
|
-
case 1:
|
|
19
|
-
return _isPlaceholder(a)
|
|
20
|
-
? f3
|
|
21
|
-
: _curry2(function (_b: any, _c: any) {
|
|
22
|
-
return fn(a, _b, _c);
|
|
23
|
-
});
|
|
24
|
-
case 2:
|
|
25
|
-
return _isPlaceholder(a) && _isPlaceholder(b)
|
|
26
|
-
? f3
|
|
27
|
-
: _isPlaceholder(a)
|
|
28
|
-
? _curry2(function (_a: any, _c: any) {
|
|
29
|
-
return fn(_a, b, _c);
|
|
30
|
-
})
|
|
31
|
-
: _isPlaceholder(b)
|
|
32
|
-
? _curry2(function (_b: any, _c: any) {
|
|
33
|
-
return fn(a, _b, _c);
|
|
34
|
-
})
|
|
35
|
-
: _curry1(function (_c: any) {
|
|
36
|
-
return fn(a, b, _c);
|
|
37
|
-
});
|
|
38
|
-
default:
|
|
39
|
-
return _isPlaceholder(a) && _isPlaceholder(b) && _isPlaceholder(c)
|
|
40
|
-
? f3
|
|
41
|
-
: _isPlaceholder(a) && _isPlaceholder(b)
|
|
42
|
-
? _curry2(function (_a: any, _b: any) {
|
|
43
|
-
return fn(_a, _b, c);
|
|
44
|
-
})
|
|
45
|
-
: _isPlaceholder(a) && _isPlaceholder(c)
|
|
46
|
-
? _curry2(function (_a: any, _c: any) {
|
|
47
|
-
return fn(_a, b, _c);
|
|
48
|
-
})
|
|
49
|
-
: _isPlaceholder(b) && _isPlaceholder(c)
|
|
50
|
-
? _curry2(function (_b: any, _c: any) {
|
|
51
|
-
return fn(a, _b, _c);
|
|
52
|
-
})
|
|
53
|
-
: _isPlaceholder(a)
|
|
54
|
-
? _curry1(function (_a: any) {
|
|
55
|
-
return fn(_a, b, c);
|
|
56
|
-
})
|
|
57
|
-
: _isPlaceholder(b)
|
|
58
|
-
? _curry1(function (_b: any) {
|
|
59
|
-
return fn(a, _b, c);
|
|
60
|
-
})
|
|
61
|
-
: _isPlaceholder(c)
|
|
62
|
-
? _curry1(function (_c: any) {
|
|
63
|
-
return fn(a, b, _c);
|
|
64
|
-
})
|
|
65
|
-
: fn(a, b, c);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import _curry2 from "./internal/_curry2";
|
|
2
|
-
import mergeDeepWithKey from "./mergeDeepWithKey";
|
|
3
|
-
|
|
4
|
-
const mergeDeepRight = _curry2(function mergeDeepRight(lObj: any, rObj: any) {
|
|
5
|
-
return mergeDeepWithKey(
|
|
6
|
-
function (_: Function, __: any, rVal: any) {
|
|
7
|
-
return rVal;
|
|
8
|
-
},
|
|
9
|
-
lObj,
|
|
10
|
-
rObj
|
|
11
|
-
);
|
|
12
|
-
});
|
|
13
|
-
export default mergeDeepRight;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import _curry3 from "./internal/_curry3";
|
|
2
|
-
import _isObject from "./internal/_isObject";
|
|
3
|
-
import mergeWithKey from "./mergeWithKey";
|
|
4
|
-
|
|
5
|
-
const mergeDeepWithKey = _curry3(function mergeDeepWithKey(
|
|
6
|
-
fn: Function,
|
|
7
|
-
lObj: any,
|
|
8
|
-
rObj: any
|
|
9
|
-
) {
|
|
10
|
-
return mergeWithKey(
|
|
11
|
-
function (k: Function, lVal: any, rVal: any) {
|
|
12
|
-
if (_isObject(lVal) && _isObject(rVal)) {
|
|
13
|
-
return mergeDeepWithKey(fn, lVal, rVal);
|
|
14
|
-
} else {
|
|
15
|
-
return fn(k, lVal, rVal);
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
lObj,
|
|
19
|
-
rObj
|
|
20
|
-
);
|
|
21
|
-
});
|
|
22
|
-
export default mergeDeepWithKey;
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import _curry3 from "./internal/_curry3";
|
|
2
|
-
import _has from "./internal/_has";
|
|
3
|
-
|
|
4
|
-
const mergeWithKey = _curry3(function mergeWithKey(
|
|
5
|
-
fn: Function,
|
|
6
|
-
l: any,
|
|
7
|
-
r: any
|
|
8
|
-
) {
|
|
9
|
-
const result: any = {};
|
|
10
|
-
let k;
|
|
11
|
-
l = l || {};
|
|
12
|
-
r = r || {};
|
|
13
|
-
|
|
14
|
-
for (k in l) {
|
|
15
|
-
if (_has(k, l)) {
|
|
16
|
-
result[k] = _has(k, r) ? fn(k, l[k], r[k]) : l[k];
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
for (k in r) {
|
|
21
|
-
if (_has(k, r) && !_has(k, result)) {
|
|
22
|
-
result[k] = r[k];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return result;
|
|
27
|
-
});
|
|
28
|
-
export default mergeWithKey;
|