vwo-fme-react-sdk 0.1.0

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +18 -0
  4. package/README.md +352 -0
  5. package/dist/VWOContext.d.ts +24 -0
  6. package/dist/VWOProvider.d.ts +35 -0
  7. package/dist/index.d.ts +23 -0
  8. package/dist/index.js +8 -0
  9. package/dist/logger/LogMessageBuilder.d.ts +63 -0
  10. package/dist/logger/Logger.d.ts +46 -0
  11. package/dist/logger/core/LogManager.d.ts +100 -0
  12. package/dist/logger/core/TransportManager.d.ts +80 -0
  13. package/dist/logger/enums/LogLevelEnum.d.ts +22 -0
  14. package/dist/logger/index.d.ts +17 -0
  15. package/dist/logger/transports/ConsoleTransport.d.ts +60 -0
  16. package/dist/services/loggerService.d.ts +35 -0
  17. package/dist/types/Common.d.ts +36 -0
  18. package/dist/useGetFlag.d.ts +21 -0
  19. package/dist/useGetFlagVariable.d.ts +29 -0
  20. package/dist/useSetAttribute.d.ts +20 -0
  21. package/dist/useTrackEvent.d.ts +21 -0
  22. package/dist/useVWOClient.d.ts +20 -0
  23. package/dist/utils/DataTypeUtil.d.ts +38 -0
  24. package/dist/vwo-fme-react-sdk.cjs.development.js +904 -0
  25. package/dist/vwo-fme-react-sdk.cjs.development.js.map +1 -0
  26. package/dist/vwo-fme-react-sdk.cjs.production.min.js +904 -0
  27. package/dist/vwo-fme-react-sdk.cjs.production.min.js.map +1 -0
  28. package/dist/vwo-fme-react-sdk.esm.js +886 -0
  29. package/dist/vwo-fme-react-sdk.esm.js.map +1 -0
  30. package/lib/VWOContext.ts +47 -0
  31. package/lib/VWOProvider.tsx +103 -0
  32. package/lib/index.ts +29 -0
  33. package/lib/logger/LogMessageBuilder.ts +99 -0
  34. package/lib/logger/Logger.ts +51 -0
  35. package/lib/logger/core/LogManager.ts +164 -0
  36. package/lib/logger/core/TransportManager.ts +142 -0
  37. package/lib/logger/enums/LogLevelEnum.ts +23 -0
  38. package/lib/logger/index.ts +18 -0
  39. package/lib/logger/transports/ConsoleTransport.ts +85 -0
  40. package/lib/services/LoggerService.ts +49 -0
  41. package/lib/types/Common.ts +42 -0
  42. package/lib/useGetFlag.ts +81 -0
  43. package/lib/useGetFlagVariable.ts +65 -0
  44. package/lib/useSetAttribute.ts +48 -0
  45. package/lib/useTrackEvent.ts +52 -0
  46. package/lib/useVWOClient.ts +41 -0
  47. package/lib/utils/DataTypeUtil.ts +48 -0
  48. package/package.json +84 -0
@@ -0,0 +1,886 @@
1
+ import React, { createContext, useContext, useState, useRef, useEffect, useMemo } from 'react';
2
+ import { init } from 'vwo-fme-node-sdk';
3
+ export { init } from 'vwo-fme-node-sdk';
4
+
5
+ /**
6
+ * Copyright 2025 Wingify Software Pvt. Ltd.
7
+ *
8
+ * Licensed under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License.
10
+ * You may obtain a copy of the License at
11
+ *
12
+ * http://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * Unless required by applicable law or agreed to in writing, software
15
+ * distributed under the License is distributed on an "AS IS" BASIS,
16
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
+ * See the License for the specific language governing permissions and
18
+ * limitations under the License.
19
+ */
20
+ /**
21
+ * Abstract class representing a logger.
22
+ * This class provides the structure for logging mechanisms and should be extended by specific logger implementations.
23
+ */
24
+ class Logger {}
25
+
26
+ /**
27
+ * Copyright 2025 Wingify Software Pvt. Ltd.
28
+ *
29
+ * Licensed under the Apache License, Version 2.0 (the "License");
30
+ * you may not use this file except in compliance with the License.
31
+ * You may obtain a copy of the License at
32
+ *
33
+ * http://www.apache.org/licenses/LICENSE-2.0
34
+ *
35
+ * Unless required by applicable law or agreed to in writing, software
36
+ * distributed under the License is distributed on an "AS IS" BASIS,
37
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38
+ * See the License for the specific language governing permissions and
39
+ * limitations under the License.
40
+ */
41
+ var LogLevelEnum;
42
+ (function (LogLevelEnum) {
43
+ LogLevelEnum["TRACE"] = "trace";
44
+ LogLevelEnum["DEBUG"] = "debug";
45
+ LogLevelEnum["INFO"] = "info";
46
+ LogLevelEnum["WARN"] = "warn";
47
+ LogLevelEnum["ERROR"] = "error";
48
+ })(LogLevelEnum || (LogLevelEnum = {}));
49
+
50
+ /**
51
+ * Copyright 2025 Wingify Software Pvt. Ltd.
52
+ *
53
+ * Licensed under the Apache License, Version 2.0 (the "License");
54
+ * you may not use this file except in compliance with the License.
55
+ * You may obtain a copy of the License at
56
+ *
57
+ * http://www.apache.org/licenses/LICENSE-2.0
58
+ *
59
+ * Unless required by applicable law or agreed to in writing, software
60
+ * distributed under the License is distributed on an "AS IS" BASIS,
61
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
62
+ * See the License for the specific language governing permissions and
63
+ * limitations under the License.
64
+ */
65
+ /**
66
+ * ConsoleTransport class implements the Logger interface to provide logging functionality.
67
+ * It outputs logs to the console based on the log level set in the configuration.
68
+ */
69
+ class ConsoleTransport {
70
+ /**
71
+ * Constructor initializes the ConsoleTransport with a configuration object.
72
+ * @param {Record<string, any>} config - Configuration settings for the logger, including 'level'.
73
+ */
74
+ constructor(config = {}) {
75
+ this.config = config; // Store the configuration
76
+ this.level = this.config.level; // Set the logging level from the configuration
77
+ }
78
+ /**
79
+ * Logs a trace message.
80
+ * @param {string} message - The message to log.
81
+ */
82
+ trace(message) {
83
+ this.consoleLog(LogLevelEnum.TRACE, message);
84
+ }
85
+ /**
86
+ * Logs a debug message.
87
+ * @param {string} message - The message to log.
88
+ */
89
+ debug(message) {
90
+ this.consoleLog(LogLevelEnum.DEBUG, message);
91
+ }
92
+ /**
93
+ * Logs an informational message.
94
+ * @param {string} message - The message to log.
95
+ */
96
+ info(message) {
97
+ this.consoleLog(LogLevelEnum.INFO, message);
98
+ }
99
+ /**
100
+ * Logs a warning message.
101
+ * @param {string} message - The message to log.
102
+ */
103
+ warn(message) {
104
+ this.consoleLog(LogLevelEnum.WARN, message);
105
+ }
106
+ /**
107
+ * Logs an error message.
108
+ * @param {string} message - The message to log.
109
+ */
110
+ error(message) {
111
+ this.consoleLog(LogLevelEnum.ERROR, message);
112
+ }
113
+ /**
114
+ * Generic log function that logs messages to the console based on the log level.
115
+ * @param {string} level - The log level under which the message should be logged.
116
+ * @param {string} message - The message to log.
117
+ */
118
+ consoleLog(level, message) {
119
+ console[level](message); // Use console's logging function dynamically based on the level
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Copyright 2025 Wingify Software Pvt. Ltd.
125
+ *
126
+ * Licensed under the Apache License, Version 2.0 (the "License");
127
+ * you may not use this file except in compliance with the License.
128
+ * You may obtain a copy of the License at
129
+ *
130
+ * http://www.apache.org/licenses/LICENSE-2.0
131
+ *
132
+ * Unless required by applicable law or agreed to in writing, software
133
+ * distributed under the License is distributed on an "AS IS" BASIS,
134
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135
+ * See the License for the specific language governing permissions and
136
+ * limitations under the License.
137
+ */
138
+ /**
139
+ * Implements the ILogMessageBuilder interface to provide a concrete log message builder.
140
+ */
141
+ class LogMessageBuilder {
142
+ /**
143
+ * Constructs a new LogMessageBuilder instance.
144
+ * @param {Record<string, any>} loggerConfig - Configuration for the logger.
145
+ * @param {Record<string, any>} transportConfig - Configuration for the transport mechanism.
146
+ */
147
+ constructor(loggerConfig, transportConfig) {
148
+ this.loggerConfig = loggerConfig;
149
+ this.transportConfig = transportConfig;
150
+ // Set the prefix, defaulting to an empty string if not provided.
151
+ this.prefix = this.transportConfig.prefix || this.loggerConfig.prefix || '';
152
+ // Set the date and time format, defaulting to the logger's format if the transport's format is not provided.
153
+ this.dateTimeFormat = this.transportConfig.dateTimeFormat || this.loggerConfig.dateTimeFormat;
154
+ }
155
+ /**
156
+ * Formats a log message combining level, prefix, date/time, and the actual message.
157
+ * @param {string} level - The log level.
158
+ * @param {string} message - The message to log.
159
+ * @returns {string} The formatted log message.
160
+ */
161
+ formatMessage(level, message) {
162
+ return `[${this.getFormattedLevel(level)}]: ${this.getFormattedPrefix(this.prefix)} ${this.getFormattedDateTime()} ${message}`;
163
+ }
164
+ getFormattedPrefix(prefix) {
165
+ return `${prefix}`;
166
+ }
167
+ /**
168
+ * Returns the formatted log level with appropriate coloring based on the log level.
169
+ * @param {string} level - The log level.
170
+ * @returns {string} The formatted log level.
171
+ */
172
+ getFormattedLevel(level) {
173
+ const upperCaseLevel = level.toUpperCase();
174
+ let LogLevelColorInfoEnum;
175
+ LogLevelColorInfoEnum = {
176
+ [LogLevelEnum.TRACE]: upperCaseLevel,
177
+ [LogLevelEnum.DEBUG]: upperCaseLevel,
178
+ [LogLevelEnum.INFO]: upperCaseLevel,
179
+ [LogLevelEnum.WARN]: upperCaseLevel,
180
+ [LogLevelEnum.ERROR]: upperCaseLevel
181
+ };
182
+ return LogLevelColorInfoEnum[level];
183
+ }
184
+ /**
185
+ * Retrieves the current date and time formatted according to the specified format.
186
+ * @returns {string} The formatted date and time.
187
+ */
188
+ getFormattedDateTime() {
189
+ return this.dateTimeFormat();
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Copyright 2025 Wingify Software Pvt. Ltd.
195
+ *
196
+ * Licensed under the Apache License, Version 2.0 (the "License");
197
+ * you may not use this file except in compliance with the License.
198
+ * You may obtain a copy of the License at
199
+ *
200
+ * http://www.apache.org/licenses/LICENSE-2.0
201
+ *
202
+ * Unless required by applicable law or agreed to in writing, software
203
+ * distributed under the License is distributed on an "AS IS" BASIS,
204
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205
+ * See the License for the specific language governing permissions and
206
+ * limitations under the License.
207
+ */
208
+ /**
209
+ * Checks if a value is a function.
210
+ * @param val The value to check.
211
+ * @returns True if the value is a function, false otherwise.
212
+ */
213
+ function isFunction(val) {
214
+ return Object.prototype.toString.call(val) === '[object Function]';
215
+ }
216
+ /**
217
+ * Checks if a value is an object (excluding arrays, functions, regex, promises, and dates).
218
+ * @param val The value to check.
219
+ * @returns True if the value is a valid object, false otherwise.
220
+ */
221
+ function isObject(val) {
222
+ return Object.prototype.toString.call(val) === '[object Object]';
223
+ }
224
+ /**
225
+ * Checks if a value is a string.
226
+ * @param val The value to check.
227
+ * @returns True if the value is a string, false otherwise.
228
+ */
229
+ function isString(val) {
230
+ return typeof val === 'string' || Object.prototype.toString.call(val) === '[object String]';
231
+ }
232
+
233
+ /**
234
+ * Copyright 2025 Wingify Software Pvt. Ltd.
235
+ *
236
+ * Licensed under the Apache License, Version 2.0 (the "License");
237
+ * you may not use this file except in compliance with the License.
238
+ * You may obtain a copy of the License at
239
+ *
240
+ * http://www.apache.org/licenses/LICENSE-2.0
241
+ *
242
+ * Unless required by applicable law or agreed to in writing, software
243
+ * distributed under the License is distributed on an "AS IS" BASIS,
244
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
245
+ * See the License for the specific language governing permissions and
246
+ * limitations under the License.
247
+ */
248
+ var LogLevelNumberEnum;
249
+ (function (LogLevelNumberEnum) {
250
+ LogLevelNumberEnum[LogLevelNumberEnum["TRACE"] = 0] = "TRACE";
251
+ LogLevelNumberEnum[LogLevelNumberEnum["DEBUG"] = 1] = "DEBUG";
252
+ LogLevelNumberEnum[LogLevelNumberEnum["INFO"] = 2] = "INFO";
253
+ LogLevelNumberEnum[LogLevelNumberEnum["WARN"] = 3] = "WARN";
254
+ LogLevelNumberEnum[LogLevelNumberEnum["ERROR"] = 4] = "ERROR";
255
+ })(LogLevelNumberEnum || (LogLevelNumberEnum = {}));
256
+ /**
257
+ * Manages logging transports and delegates logging messages to them based on configuration.
258
+ * Implements the IlogTransport interface.
259
+ */
260
+ class LogTransportManager {
261
+ /**
262
+ * Initializes the manager with a configuration object.
263
+ * @param {Record<string, any>} config - Configuration settings for the log manager.
264
+ */
265
+ constructor(config) {
266
+ this.transports = [];
267
+ this.config = config;
268
+ }
269
+ /**
270
+ * Adds a new transport to the manager.
271
+ * @param {Record<string, any>} transport - The transport object to be added.
272
+ */
273
+ addTransport(transport) {
274
+ this.transports.push(transport);
275
+ }
276
+ /**
277
+ * Determines if the log should be processed based on the transport and configuration levels.
278
+ * @param {string} transportLevel - The log level set for the transport.
279
+ * @param {string} configLevel - The log level set in the configuration.
280
+ * @returns {boolean} - Returns true if the log level is appropriate for logging, false otherwise.
281
+ */
282
+ shouldLog(transportLevel, configLevel) {
283
+ // Default to the most specific level available
284
+ // transportLevel = transportLevel || configLevel || this.config.level;
285
+ const targetLevel = LogLevelNumberEnum[transportLevel.toUpperCase()];
286
+ const desiredLevel = LogLevelNumberEnum[(configLevel || this.config.level).toUpperCase()];
287
+ return targetLevel >= desiredLevel;
288
+ }
289
+ /**
290
+ * Logs a message at TRACE level.
291
+ * @param {string} message - The message to log.
292
+ */
293
+ trace(message) {
294
+ this.log(LogLevelEnum.TRACE, message);
295
+ }
296
+ /**
297
+ * Logs a message at DEBUG level.
298
+ * @param {string} message - The message to log.
299
+ */
300
+ debug(message) {
301
+ this.log(LogLevelEnum.DEBUG, message);
302
+ }
303
+ /**
304
+ * Logs a message at INFO level.
305
+ * @param {string} message - The message to log.
306
+ */
307
+ info(message) {
308
+ this.log(LogLevelEnum.INFO, message);
309
+ }
310
+ /**
311
+ * Logs a message at WARN level.
312
+ * @param {string} message - The message to log.
313
+ */
314
+ warn(message) {
315
+ this.log(LogLevelEnum.WARN, message);
316
+ }
317
+ /**
318
+ * Logs a message at ERROR level.
319
+ * @param {string} message - The message to log.
320
+ */
321
+ error(message) {
322
+ this.log(LogLevelEnum.ERROR, message);
323
+ }
324
+ /**
325
+ * Delegates the logging of messages to the appropriate transports.
326
+ * @param {string} level - The level at which to log the message.
327
+ * @param {string} message - The message to log.
328
+ */
329
+ log(level, message) {
330
+ for (let i = 0; i < this.transports.length; i++) {
331
+ const logMessageBuilder = new LogMessageBuilder(this.config, this.transports[i]);
332
+ const formattedMessage = logMessageBuilder.formatMessage(level, message);
333
+ if (this.shouldLog(level, this.transports[i].level)) {
334
+ if (this.transports[i].log && isFunction(this.transports[i].log)) {
335
+ // Use custom log handler if available
336
+ this.transports[i].log(level, message);
337
+ } else {
338
+ // Otherwise, use the default log method
339
+ this.transports[i][level](formattedMessage);
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Copyright 2025 Wingify Software Pvt. Ltd.
348
+ *
349
+ * Licensed under the Apache License, Version 2.0 (the "License");
350
+ * you may not use this file except in compliance with the License.
351
+ * You may obtain a copy of the License at
352
+ *
353
+ * http://www.apache.org/licenses/LICENSE-2.0
354
+ *
355
+ * Unless required by applicable law or agreed to in writing, software
356
+ * distributed under the License is distributed on an "AS IS" BASIS,
357
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
358
+ * See the License for the specific language governing permissions and
359
+ * limitations under the License.
360
+ */
361
+ /**
362
+ * LogManager class provides logging functionality with support for multiple transports.
363
+ * It is designed as a singleton to ensure a single instance throughout the application.
364
+ */
365
+ class LogManager extends Logger {
366
+ /**
367
+ * Constructor for LogManager.
368
+ * @param {Record<string, any>} config - Configuration object for LogManager.
369
+ */
370
+ constructor(config) {
371
+ super();
372
+ this.name = 'VWO Logger'; // Default logger name
373
+ this.requestId = new Date().getTime().toString(); // current timestamp in milliseconds
374
+ this.level = LogLevelEnum.ERROR; // Default logging level
375
+ this.prefix = 'VWO-SDK'; // Default prefix for log messages
376
+ this.config = config;
377
+ if (config.isAlwaysNewInstance || !LogManager.instance) {
378
+ LogManager.instance = this;
379
+ // Initialize configuration with defaults or provided values
380
+ this.config.name = config.name || this.name;
381
+ this.config.requestId = config.requestId || this.requestId;
382
+ this.config.level = config.level || this.level;
383
+ this.config.prefix = config.prefix || this.prefix;
384
+ this.config.dateTimeFormat = config.dateTimeFormat || this.dateTimeFormat;
385
+ this.transportManager = new LogTransportManager(this.config);
386
+ this.handleTransports();
387
+ }
388
+ return LogManager.instance;
389
+ }
390
+ dateTimeFormat() {
391
+ return new Date().toISOString(); // Default date-time format for log messages
392
+ }
393
+ /**
394
+ * Provides access to the singleton instance of LogManager.
395
+ * @returns {LogManager} The singleton instance.
396
+ */
397
+ static get Instance() {
398
+ return LogManager.instance;
399
+ }
400
+ /**
401
+ * Handles the initialization and setup of transports based on configuration.
402
+ */
403
+ handleTransports() {
404
+ this.addTransport(new ConsoleTransport({
405
+ level: this.config.level
406
+ }));
407
+ }
408
+ /**
409
+ * Adds a single transport to the LogManager.
410
+ * @param {Record<any, any>} transport - The transport object to add.
411
+ */
412
+ addTransport(transport) {
413
+ this.transportManager.addTransport(transport);
414
+ }
415
+ /**
416
+ * Adds multiple transports to the LogManager.
417
+ * @param {Array<Record<any, any>>} transports - The list of transport objects to add.
418
+ */
419
+ addTransports(transports) {
420
+ for (let i = 0; i < transports.length; i++) {
421
+ this.addTransport(transports[i]);
422
+ }
423
+ }
424
+ /**
425
+ * Logs a trace message.
426
+ * @param {string} message - The message to log at trace level.
427
+ */
428
+ trace(message) {
429
+ this.transportManager.log(LogLevelEnum.TRACE, message);
430
+ }
431
+ /**
432
+ * Logs a debug message.
433
+ * @param {string} message - The message to log at debug level.
434
+ */
435
+ debug(message) {
436
+ this.transportManager.log(LogLevelEnum.DEBUG, message);
437
+ }
438
+ /**
439
+ * Logs an informational message.
440
+ * @param {string} message - The message to log at info level.
441
+ */
442
+ info(message) {
443
+ this.transportManager.log(LogLevelEnum.INFO, message);
444
+ }
445
+ /**
446
+ * Logs a warning message.
447
+ * @param {string} message - The message to log at warn level.
448
+ */
449
+ warn(message) {
450
+ this.transportManager.log(LogLevelEnum.WARN, message);
451
+ }
452
+ /**
453
+ * Logs an error message.
454
+ * @param {string} message - The message to log at error level.
455
+ */
456
+ error(message) {
457
+ this.transportManager.log(LogLevelEnum.ERROR, message);
458
+ }
459
+ }
460
+
461
+ /**
462
+ * Copyright 2025 Wingify Software Pvt. Ltd.
463
+ *
464
+ * Licensed under the Apache License, Version 2.0 (the "License");
465
+ * you may not use this file except in compliance with the License.
466
+ * You may obtain a copy of the License at
467
+ *
468
+ * http://www.apache.org/licenses/LICENSE-2.0
469
+ *
470
+ * Unless required by applicable law or agreed to in writing, software
471
+ * distributed under the License is distributed on an "AS IS" BASIS,
472
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
473
+ * See the License for the specific language governing permissions and
474
+ * limitations under the License.
475
+ */
476
+ let logger = null;
477
+ /**
478
+ * Initializes the global logger instance.
479
+ * This function should be called inside `VWOProvider` before logging is used anywhere in the application.
480
+ *
481
+ * @param {object} config - The logger configuration object.
482
+ * @param {object} config.logger - Optional logging configuration (e.g., log level, transports).
483
+ * @returns {void} No return value; initializes the logger instance.
484
+ */
485
+ function initLogger(config) {
486
+ if (!logger) {
487
+ logger = new LogManager(config.logger || {});
488
+ }
489
+ }
490
+ /**
491
+ * Retrieves the global logger instance.
492
+ * Ensures that `initLogger` has been called before attempting to use logging.
493
+ *
494
+ * @returns {LogManager} The global logger instance.
495
+ */
496
+ function getLogger() {
497
+ if (!logger) {
498
+ logger = new LogManager({
499
+ level: 'error'
500
+ });
501
+ }
502
+ return logger;
503
+ }
504
+
505
+ /**
506
+ * Copyright 2025 Wingify Software Pvt. Ltd.
507
+ *
508
+ * Licensed under the Apache License, Version 2.0 (the "License");
509
+ * you may not use this file except in compliance with the License.
510
+ * You may obtain a copy of the License at
511
+ *
512
+ * http://www.apache.org/licenses/LICENSE-2.0
513
+ *
514
+ * Unless required by applicable law or agreed to in writing, software
515
+ * distributed under the License is distributed on an "AS IS" BASIS,
516
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
517
+ * See the License for the specific language governing permissions and
518
+ * limitations under the License.
519
+ */
520
+ /**
521
+ * Context for VWO SDK
522
+ */
523
+ const VWOContext = /*#__PURE__*/createContext({
524
+ vwoClient: null,
525
+ userContext: {}
526
+ });
527
+ /**
528
+ * Hook to use the VWO context
529
+ * @returns VWO context
530
+ */
531
+ const useVWOContext = () => {
532
+ const logger = getLogger();
533
+ try {
534
+ // Fetch the context
535
+ const context = useContext(VWOContext);
536
+ // If the context is not found, throw an error
537
+ if (!context) {
538
+ logger.error('useVWOContext must be used within a VWOProvider');
539
+ return null;
540
+ }
541
+ return context;
542
+ } catch (error) {
543
+ logger.error(`Error in useVWOContext hook: ${error}`);
544
+ return null;
545
+ }
546
+ };
547
+
548
+ /**
549
+ * Copyright 2025 Wingify Software Pvt. Ltd.
550
+ *
551
+ * Licensed under the Apache License, Version 2.0 (the "License");
552
+ * you may not use this file except in compliance with the License.
553
+ * You may obtain a copy of the License at
554
+ *
555
+ * http://www.apache.org/licenses/LICENSE-2.0
556
+ *
557
+ * Unless required by applicable law or agreed to in writing, software
558
+ * distributed under the License is distributed on an "AS IS" BASIS,
559
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
560
+ * See the License for the specific language governing permissions and
561
+ * limitations under the License.
562
+ */
563
+ /**
564
+ * VWOProvider component to provide the VWO SDK instance and context to the app
565
+ * @param client - VWO SDK instance
566
+ * @param config - VWO SDK config (initialization config)
567
+ * @param context - VWO SDK context (userContext)
568
+ * @param children - React children (ReactNode)
569
+ * @returns VWOProvider component
570
+ */
571
+ const VWOProvider = ({
572
+ client,
573
+ config,
574
+ context,
575
+ children
576
+ }) => {
577
+ const [vwoClient, setVwoClient] = useState(client || null);
578
+ const vwoClientRef = useRef(vwoClient);
579
+ const isMounted = useRef(true);
580
+ // Initialize logger globally before using it
581
+ useEffect(() => {
582
+ if (config?.logger) {
583
+ initLogger(config);
584
+ }
585
+ }, [config]);
586
+ const logger = getLogger();
587
+ // Initialize the VWO SDK instance when the component mounts
588
+ useEffect(() => {
589
+ if (!vwoClient && !config) {
590
+ logger.error("VWOProvider Error: Either `client` or `config` must be provided.");
591
+ return;
592
+ }
593
+ if (!context || !isObject(context)) {
594
+ logger.error("VWOProvider Error: `context` is required and must be a valid object.");
595
+ return;
596
+ }
597
+ isMounted.current = true;
598
+ async function initializeVWO() {
599
+ if (!vwoClient && config) {
600
+ try {
601
+ // Initialize the VWO SDK instance
602
+ const instance = await init(config);
603
+ if (isMounted.current) {
604
+ // Update the VWO SDK instance
605
+ setVwoClient(instance);
606
+ // Update the ref with the new instance
607
+ vwoClientRef.current = instance;
608
+ }
609
+ } catch (error) {
610
+ logger.error("VWO-SDK Initialization failed:");
611
+ }
612
+ }
613
+ }
614
+ // Initialize the VWO SDK instance
615
+ initializeVWO();
616
+ // Cleanup the VWO SDK instance when the component unmounts
617
+ return () => {
618
+ isMounted.current = false;
619
+ if (vwoClientRef.current?.destroy) vwoClientRef.current.destroy();
620
+ };
621
+ }, [vwoClient, config]);
622
+ // Provide the VWO SDK instance and context to the app
623
+ return React.createElement(VWOContext.Provider, {
624
+ value: {
625
+ vwoClient,
626
+ userContext: context
627
+ }
628
+ }, children);
629
+ };
630
+
631
+ /**
632
+ * Copyright 2025 Wingify Software Pvt. Ltd.
633
+ *
634
+ * Licensed under the Apache License, Version 2.0 (the "License");
635
+ * you may not use this file except in compliance with the License.
636
+ * You may obtain a copy of the License at
637
+ *
638
+ * http://www.apache.org/licenses/LICENSE-2.0
639
+ *
640
+ * Unless required by applicable law or agreed to in writing, software
641
+ * distributed under the License is distributed on an "AS IS" BASIS,
642
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
643
+ * See the License for the specific language governing permissions and
644
+ * limitations under the License.
645
+ */
646
+ /**
647
+ * Returns the VWO SDK client instance
648
+ * @returns VWO SDK client instance
649
+ */
650
+ const useVWOClient = () => {
651
+ const logger = getLogger();
652
+ try {
653
+ const context = useVWOContext();
654
+ // If the VWO SDK client is not found, throw an error
655
+ if (!context || !context.vwoClient) {
656
+ logger.error('useVWOClient must be used within a VWOProvider !!');
657
+ return null;
658
+ }
659
+ // Return the VWO SDK client
660
+ return context.vwoClient;
661
+ } catch (error) {
662
+ logger.error(`Error in useVWOClient hook: ${error}`);
663
+ return null;
664
+ }
665
+ };
666
+
667
+ /**
668
+ * Copyright 2025 Wingify Software Pvt. Ltd.
669
+ *
670
+ * Licensed under the Apache License, Version 2.0 (the "License");
671
+ * you may not use this file except in compliance with the License.
672
+ * You may obtain a copy of the License at
673
+ *
674
+ * http://www.apache.org/licenses/LICENSE-2.0
675
+ *
676
+ * Unless required by applicable law or agreed to in writing, software
677
+ * distributed under the License is distributed on an "AS IS" BASIS,
678
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
679
+ * See the License for the specific language governing permissions and
680
+ * limitations under the License.
681
+ */
682
+ /**
683
+ * Hook to get a feature flag value
684
+ * @param featureKey - The key of the feature flag to get
685
+ * @returns The feature flag value
686
+ */
687
+ const useGetFlag = featureKey => {
688
+ // This is the return schema for the flag if the feature key is not found or the flag is not enabled
689
+ const errorReturnSchema = {
690
+ isEnabled: () => false,
691
+ getVariables: () => [],
692
+ getVariable: (_key, defaultValue) => defaultValue
693
+ };
694
+ const logger = getLogger();
695
+ try {
696
+ if (!featureKey) {
697
+ logger.error('Feature key is required for useGetFlag hook');
698
+ return errorReturnSchema;
699
+ }
700
+ const [flag, setFlag] = useState(null);
701
+ const {
702
+ vwoClient,
703
+ userContext
704
+ } = useVWOContext();
705
+ if (!vwoClient) {
706
+ logger.error('VWO Client is missing in useGetFlag hook. Ensure VWOProvider is correctly initialized.');
707
+ return errorReturnSchema;
708
+ }
709
+ if (!userContext || !isObject(userContext)) {
710
+ logger.error('Invalid user context in useGetFlag hook. Ensure a valid userContext is provided.');
711
+ return errorReturnSchema;
712
+ }
713
+ // Memoize the userContext to avoid unnecessary re-fetching
714
+ const stableUserContext = useMemo(() => userContext, [userContext]);
715
+ // Memoize the getFlag function to avoid re-creation
716
+ const getFlag = useMemo(() => {
717
+ return async () => {
718
+ try {
719
+ const result = await vwoClient.getFlag(featureKey, stableUserContext);
720
+ setFlag(result);
721
+ } catch (error) {
722
+ logger.error(`Error fetching feature flag "${featureKey}": ${error}`);
723
+ setFlag({});
724
+ }
725
+ };
726
+ }, [featureKey, vwoClient, stableUserContext]);
727
+ // Runs only when `getFlag` reference changes
728
+ useEffect(() => {
729
+ getFlag();
730
+ }, [getFlag]);
731
+ return flag;
732
+ } catch (error) {
733
+ logger.error(`Error getting feature flag: ${error}`);
734
+ return errorReturnSchema;
735
+ }
736
+ };
737
+
738
+ /**
739
+ * Copyright 2025 Wingify Software Pvt. Ltd.
740
+ *
741
+ * Licensed under the Apache License, Version 2.0 (the "License");
742
+ * you may not use this file except in compliance with the License.
743
+ * You may obtain a copy of the License at
744
+ *
745
+ * http://www.apache.org/licenses/LICENSE-2.0
746
+ *
747
+ * Unless required by applicable law or agreed to in writing, software
748
+ * distributed under the License is distributed on an "AS IS" BASIS,
749
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
750
+ * See the License for the specific language governing permissions and
751
+ * limitations under the License.
752
+ */
753
+ /**
754
+ * Hook to get all variables from a flag
755
+ * @param flag - The flag to get the variables from
756
+ * @returns The variables from the flag
757
+ */
758
+ const useGetFlagVariables = flag => {
759
+ const logger = getLogger();
760
+ try {
761
+ if (!flag || !isObject(flag)) {
762
+ logger.error('Flag is required for useGetFlagVariables hook and should be an object');
763
+ return [];
764
+ }
765
+ return flag.getVariables();
766
+ } catch (error) {
767
+ logger.error(`Error getting flag variables: ${error}`);
768
+ return [];
769
+ }
770
+ };
771
+ /**
772
+ * Hook to get a flag variable
773
+ * @param flag - The flag to get the variable from
774
+ * @param variableKey - The key of the variable to get
775
+ * @param defaultValue - The default value to return if the variable is not found
776
+ * @returns The value of the variable
777
+ */
778
+ const useGetFlagVariable = (flag, variableKey, defaultValue) => {
779
+ const logger = getLogger();
780
+ try {
781
+ if (!flag || !isObject(flag)) {
782
+ logger.error('Flag is required for useGetFlagVariable hook and should be an object');
783
+ return [];
784
+ }
785
+ if (!flag || !variableKey) {
786
+ logger.error('Flag and variable key are required for useGetFlagVariable hook');
787
+ return defaultValue;
788
+ }
789
+ return flag.getVariable(variableKey, defaultValue);
790
+ } catch (error) {
791
+ logger.error(`Error getting flag variable: ${error}`);
792
+ return defaultValue;
793
+ }
794
+ };
795
+
796
+ /**
797
+ * Copyright 2025 Wingify Software Pvt. Ltd.
798
+ *
799
+ * Licensed under the Apache License, Version 2.0 (the "License");
800
+ * you may not use this file except in compliance with the License.
801
+ * You may obtain a copy of the License at
802
+ *
803
+ * http://www.apache.org/licenses/LICENSE-2.0
804
+ *
805
+ * Unless required by applicable law or agreed to in writing, software
806
+ * distributed under the License is distributed on an "AS IS" BASIS,
807
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
808
+ * See the License for the specific language governing permissions and
809
+ * limitations under the License.
810
+ */
811
+ /**
812
+ * Hook to track an event
813
+ * @param eventName - The name of the event to track
814
+ * @param eventProperties - The properties of the event to track (optional)
815
+ */
816
+ const useTrackEvent = (eventName, eventProperties = {}) => {
817
+ const logger = getLogger();
818
+ try {
819
+ if (!eventName && !isString(eventName)) {
820
+ logger.error('Event name is required for useTrackEvent hook and it should be a string');
821
+ return;
822
+ }
823
+ // Fetch the vwoClient and userContext from the context
824
+ const {
825
+ vwoClient,
826
+ userContext
827
+ } = useVWOContext();
828
+ if (!vwoClient) {
829
+ logger.error('VWO Client is missing in useTrackEvent hook. Ensure VWOProvider is correctly initialized.');
830
+ return {};
831
+ }
832
+ if (!userContext || !isObject(userContext)) {
833
+ logger.error('Invalid user context in useTrackEvent hook. Ensure a valid userContext is provided.');
834
+ return {};
835
+ }
836
+ // Track the event
837
+ vwoClient.trackEvent(eventName, userContext, eventProperties);
838
+ } catch (error) {
839
+ logger.error(`Error tracking event: ${error}`);
840
+ }
841
+ };
842
+
843
+ /**
844
+ * Copyright 2025 Wingify Software Pvt. Ltd.
845
+ *
846
+ * Licensed under the Apache License, Version 2.0 (the "License");
847
+ * you may not use this file except in compliance with the License.
848
+ * You may obtain a copy of the License at
849
+ *
850
+ * http://www.apache.org/licenses/LICENSE-2.0
851
+ *
852
+ * Unless required by applicable law or agreed to in writing, software
853
+ * distributed under the License is distributed on an "AS IS" BASIS,
854
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
855
+ * See the License for the specific language governing permissions and
856
+ * limitations under the License.
857
+ */
858
+ /**
859
+ * Hook to set attributes for the user
860
+ * @param attributeMap - The map of attributes to set
861
+ */
862
+ const useSetAttribute = attributeMap => {
863
+ const logger = getLogger();
864
+ try {
865
+ if (!attributeMap || !isObject(attributeMap) || Object.keys(attributeMap).length === 0) {
866
+ logger.error('attributeMap(object having key-value pairs of user attributes) is required for useSetAttribute hook');
867
+ return;
868
+ }
869
+ // Fetch the vwoClient and userContext from the context
870
+ const {
871
+ vwoClient,
872
+ userContext
873
+ } = useVWOContext();
874
+ if (!userContext || !isObject(userContext)) {
875
+ logger.error('Invalid user context in useSetAttribute hook. Ensure a valid userContext is provided.');
876
+ return {};
877
+ }
878
+ // Set the attributes
879
+ vwoClient.setAttribute(attributeMap, userContext);
880
+ } catch (error) {
881
+ logger.error(`Error setting attributes: ${error}`);
882
+ }
883
+ };
884
+
885
+ export { VWOProvider, useGetFlag, useGetFlagVariable, useGetFlagVariables, useSetAttribute, useTrackEvent, useVWOClient };
886
+ //# sourceMappingURL=vwo-fme-react-sdk.esm.js.map