From 0ee933186729cd63ce35609d3c75fbfca2cdc5bc Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 30 Oct 2024 23:08:38 -0300 Subject: [PATCH] Revert "Remove 'full' subpackage, since there is not significant difference with the default 'slim' subpackage" This reverts commit 23668a9bbd69bfdf569e3e5ae0e551bdf283e522. --- CHANGES.txt | 1 - full/package.json | 6 ++ package-lock.json | 13 +++- package.json | 6 +- rollup.ci.config.js | 2 +- src/__tests__/offline/browser.spec.js | 12 ++-- src/full/index.ts | 7 +++ src/full/splitFactory.ts | 27 ++++++++ src/{umd-full.ts => full/umd.ts} | 0 src/platform/getFetchFull.ts | 6 ++ src/platform/{getFetch.ts => getFetchSlim.ts} | 0 src/settings/__tests__/index.spec.ts | 21 ++++--- src/settings/full.ts | 23 +++++++ src/splitFactory.ts | 5 +- ts-tests/index.ts | 9 +++ types/full/index.d.ts | 62 +++++++++++++++++++ 16 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 full/package.json create mode 100644 src/full/index.ts create mode 100644 src/full/splitFactory.ts rename src/{umd-full.ts => full/umd.ts} (100%) create mode 100644 src/platform/getFetchFull.ts rename src/platform/{getFetch.ts => getFetchSlim.ts} (100%) create mode 100644 src/settings/full.ts create mode 100644 types/full/index.d.ts diff --git a/CHANGES.txt b/CHANGES.txt index deb4281..08b6a6a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,7 +7,6 @@ - Removed internal ponyfills for the `Map` and `Set` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. - Removed the deprecated `GoogleAnalyticsToSplit` and `SplitToGoogleAnalytics` pluggable integration modules, along with the related interfaces in the TypeScript definitions. - Removed the `LocalhostFromObject` export from the default import (`import { LocalhostFromObject } from '@splitsoftware/splitio-browserjs'`). It is no longer necessary to manually import and configure it in the `sync.localhostMode` option to enable localhost mode. - - Removed the "full" import (`import { SplitFactory } from '@splitsoftware/splitio-browserjs/full'`), since with the removal of `LocalhostFromObject` from the default import, the difference between them is minimal. The "full" import differs only by including the `unfetch` ponyfill to support older browsers. 0.15.0 (September 13, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: diff --git a/full/package.json b/full/package.json new file mode 100644 index 0000000..a59cb3f --- /dev/null +++ b/full/package.json @@ -0,0 +1,6 @@ +{ + "main": "../cjs/full/index.js", + "module": "../esm/full/index.js", + "types": "../types/full/index.d.ts", + "sideEffects": false +} diff --git a/package-lock.json b/package-lock.json index 23b7e48..297c4df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "2.0.0-rc.5", - "tslib": "^2.3.1" + "tslib": "^2.3.1", + "unfetch": "^4.2.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^24.0.1", @@ -9165,6 +9166,11 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -16365,6 +16371,11 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" }, + "unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==" + }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/package.json b/package.json index 56a42fc..e5b2ba5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "cjs", "esm", "src", - "types" + "types", + "full" ], "scripts": { "check": "npm run check:lint && npm run check:types && npm run check:version", @@ -59,7 +60,8 @@ "homepage": "https://github.com/splitio/javascript-browser-client#readme", "dependencies": { "@splitsoftware/splitio-commons": "2.0.0-rc.5", - "tslib": "^2.3.1" + "tslib": "^2.3.1", + "unfetch": "^4.2.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^24.0.1", diff --git a/rollup.ci.config.js b/rollup.ci.config.js index 80dcb43..af1d738 100644 --- a/rollup.ci.config.js +++ b/rollup.ci.config.js @@ -35,7 +35,7 @@ export default env => { * * Only https://www.npmjs.com/package/rollup-plugin-ts compiles from node_modules, and is used for tests. */ - createRollupConfig('esm/umd-full.js', 'full'), // umd/split-browser-VERSION.full[.min].js + createRollupConfig('esm/full/umd.js', 'full'), // umd/split-browser-VERSION.full[.min].js createRollupConfig('esm/umd.js') // umd/split-browser-VERSION[.min].js ]; }; diff --git a/src/__tests__/offline/browser.spec.js b/src/__tests__/offline/browser.spec.js index 2c5ee06..6b2d981 100644 --- a/src/__tests__/offline/browser.spec.js +++ b/src/__tests__/offline/browser.spec.js @@ -2,7 +2,8 @@ import tape from 'tape-catch'; import sinon from 'sinon'; import fetchMock from '../testUtils/fetchMock'; import { url } from '../testUtils'; -import { SplitFactory, InLocalStorage } from '../../index'; +import { SplitFactory, InLocalStorage } from '../../full'; +import { SplitFactory as SplitFactorySlim } from '../../'; import { settingsFactory } from '../../settings'; const settings = settingsFactory({ core: { key: 'facundo@split.io' } }); @@ -87,7 +88,10 @@ tape('Browser offline mode', function (assert) { sharedUpdateCount++; }); - const factoryReadyFromCache = SplitFactory({ ...config, storage: InLocalStorage() }); + const factoriesReadyFromCache = [ + SplitFactory({ ...config, storage: InLocalStorage() }), + SplitFactorySlim({ ...config, storage: InLocalStorage() }) + ]; const configs = [ { ...config, features: { ...config.features }, storage: InLocalStorage /* invalid */ }, { ...config }, @@ -95,7 +99,7 @@ tape('Browser offline mode', function (assert) { ]; const factories = [ ...configs.map(config => SplitFactory(config)), - factoryReadyFromCache + ...factoriesReadyFromCache ]; let readyCount = 0, updateCount = 0, readyFromCacheCount = 0; @@ -357,7 +361,7 @@ tape('Browser offline mode', function (assert) { // SDK events on other factory clients assert.equal(readyCount, factories.length, 'Each factory client should have emitted SDK_READY event once'); assert.equal(updateCount, factories.length - 1, 'Each factory client except one should have emitted SDK_UPDATE event once'); - assert.equal(readyFromCacheCount, 2, 'The main and shared client of the factory with LOCALSTORAGE should have emitted SDK_READY_FROM_CACHE event'); + assert.equal(readyFromCacheCount, factoriesReadyFromCache.length * 2, 'The main and shared client of the factories with LOCALSTORAGE should have emitted SDK_READY_FROM_CACHE event'); assert.end(); }); diff --git a/src/full/index.ts b/src/full/index.ts new file mode 100644 index 0000000..be0ed7a --- /dev/null +++ b/src/full/index.ts @@ -0,0 +1,7 @@ +export { SplitFactory } from './splitFactory'; +export { InLocalStorage } from '@splitsoftware/splitio-commons/src/storages/inLocalStorage/index'; +export { ErrorLogger } from '@splitsoftware/splitio-commons/src/logger/browser/ErrorLogger'; +export { WarnLogger } from '@splitsoftware/splitio-commons/src/logger/browser/WarnLogger'; +export { InfoLogger } from '@splitsoftware/splitio-commons/src/logger/browser/InfoLogger'; +export { DebugLogger } from '@splitsoftware/splitio-commons/src/logger/browser/DebugLogger'; +export { PluggableStorage } from '@splitsoftware/splitio-commons/src/storages/pluggable'; diff --git a/src/full/splitFactory.ts b/src/full/splitFactory.ts new file mode 100644 index 0000000..ba1f6fe --- /dev/null +++ b/src/full/splitFactory.ts @@ -0,0 +1,27 @@ +import SplitIO from '@splitsoftware/splitio-commons/types/splitio'; +import { settingsFactory } from '../settings/full'; +import { getModules } from '../platform/getModules'; +import { sdkFactory } from '@splitsoftware/splitio-commons/src/sdkFactory/index'; +import { ISdkFactoryParams } from '@splitsoftware/splitio-commons/src/sdkFactory/types'; +import { getFetch } from '../platform/getFetchFull'; +import { getEventSource } from '../platform/getEventSource'; +import { EventEmitter } from '@splitsoftware/splitio-commons/src/utils/MinEvents'; +import { now } from '@splitsoftware/splitio-commons/src/utils/timeTracker/now/browser'; + +const platform = { getFetch, getEventSource, EventEmitter, now }; + +/** + * SplitFactory with pluggable modules for Browser. + * Includes fetch polyfill out-of-the-box. + * + * @param config - configuration object used to instantiate the SDK + * @param __updateModules - optional function that lets redefine internal SDK modules. Use with + * caution since, unlike `config`, this param is not validated neither considered part of the public API. + * @throws Will throw an error if the provided config is invalid. + */ +export function SplitFactory(config: SplitIO.IClientSideSettings, __updateModules?: (modules: ISdkFactoryParams) => void) { + const settings = settingsFactory(config); + const modules = getModules(settings, platform); + if (__updateModules) __updateModules(modules); + return sdkFactory(modules); +} diff --git a/src/umd-full.ts b/src/full/umd.ts similarity index 100% rename from src/umd-full.ts rename to src/full/umd.ts diff --git a/src/platform/getFetchFull.ts b/src/platform/getFetchFull.ts new file mode 100644 index 0000000..496c07a --- /dev/null +++ b/src/platform/getFetchFull.ts @@ -0,0 +1,6 @@ +import { IFetch } from '@splitsoftware/splitio-commons/src/services/types'; +import unfetch from 'unfetch'; + +export function getFetch() { + return typeof fetch === 'function' ? fetch : unfetch as unknown as IFetch; +} diff --git a/src/platform/getFetch.ts b/src/platform/getFetchSlim.ts similarity index 100% rename from src/platform/getFetch.ts rename to src/platform/getFetchSlim.ts diff --git a/src/settings/__tests__/index.spec.ts b/src/settings/__tests__/index.spec.ts index ab157b6..4b1ad49 100644 --- a/src/settings/__tests__/index.spec.ts +++ b/src/settings/__tests__/index.spec.ts @@ -1,15 +1,18 @@ -import { settingsFactory } from '../index'; +import { settingsFactory as slimSettingsFactory } from '../index'; +import { settingsFactory as fullSettingsFactory } from '../full'; test('SETTINGS / Consent is overwritable and "GRANTED" by default', () => { - let settings = settingsFactory({}); - expect(settings.userConsent).toEqual('GRANTED'); // userConsent defaults to granted if not provided + [slimSettingsFactory, fullSettingsFactory].forEach((settingsFactory) => { + let settings = settingsFactory({}); + expect(settings.userConsent).toEqual('GRANTED'); // userConsent defaults to granted if not provided - settings = settingsFactory({ userConsent: 'INVALID-VALUE' }); - expect(settings.userConsent).toEqual('GRANTED'); // userConsent defaults to granted if a wrong value is provided + settings = settingsFactory({ userConsent: 'INVALID-VALUE' }); + expect(settings.userConsent).toEqual('GRANTED'); // userConsent defaults to granted if a wrong value is provided - settings = settingsFactory({ userConsent: 'UNKNOWN' }); - expect(settings.userConsent).toEqual('UNKNOWN'); // userConsent can be overwritten + settings = settingsFactory({ userConsent: 'UNKNOWN' }); + expect(settings.userConsent).toEqual('UNKNOWN'); // userConsent can be overwritten - settings = settingsFactory({ userConsent: 'declined' }); - expect(settings.userConsent).toEqual('DECLINED'); // userConsent can be overwritten + settings = settingsFactory({ userConsent: 'declined' }); + expect(settings.userConsent).toEqual('DECLINED'); // userConsent can be overwritten + }); }); diff --git a/src/settings/full.ts b/src/settings/full.ts new file mode 100644 index 0000000..8c6f6fb --- /dev/null +++ b/src/settings/full.ts @@ -0,0 +1,23 @@ +import { settingsValidation } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/index'; +import { defaults } from './defaults'; +import { validateRuntime } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/runtime'; +import { validateStorageCS } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/storage/storageCS'; +import { validatePluggableIntegrations } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/integrations/pluggable'; +import { validateLogger } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/logger/pluggableLogger'; +import { validateConsent } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/consent'; + +const params = { + defaults, + acceptKey: true, // Client with bound key + runtime: validateRuntime, + storage: validateStorageCS, + integrations: validatePluggableIntegrations, + logger: validateLogger, + consent: validateConsent, +}; + +export function settingsFactory(config: any) { + const settings = settingsValidation(config, params); + + return settings; +} diff --git a/src/splitFactory.ts b/src/splitFactory.ts index 7a7f81f..b376756 100644 --- a/src/splitFactory.ts +++ b/src/splitFactory.ts @@ -1,9 +1,9 @@ -import type SplitIO from '@splitsoftware/splitio-commons/types/splitio'; +import SplitIO from '@splitsoftware/splitio-commons/types/splitio'; import { settingsFactory } from './settings'; import { getModules } from './platform/getModules'; import { sdkFactory } from '@splitsoftware/splitio-commons/src/sdkFactory/index'; import { ISdkFactoryParams } from '@splitsoftware/splitio-commons/src/sdkFactory/types'; -import { getFetch } from './platform/getFetch'; +import { getFetch } from './platform/getFetchSlim'; import { getEventSource } from './platform/getEventSource'; import { EventEmitter } from '@splitsoftware/splitio-commons/src/utils/MinEvents'; import { now } from '@splitsoftware/splitio-commons/src/utils/timeTracker/now/browser'; @@ -12,6 +12,7 @@ const platform = { getFetch, getEventSource, EventEmitter, now }; /** * SplitFactory with pluggable modules for Browser. + * Doesn't include fetch ponyfill out-of-the-box. * * @param config - configuration object used to instantiate the SDK * @param __updateModules - optional function that lets redefine internal SDK modules. Use with diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 5b40ecf..0a90b87 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -11,8 +11,13 @@ * @author Nico Zelaya */ +import { SplitFactory as SplitFactoryFull, InLocalStorage as InLocalStorageFull, DebugLogger as DebugLoggerFull, InfoLogger as InfoLoggerFull, WarnLogger as WarnLoggerFull, ErrorLogger as ErrorLoggerFull, PluggableStorage as PluggableStorageFull } from '../types/full'; import { SplitFactory, InLocalStorage, DebugLogger, InfoLogger, WarnLogger, ErrorLogger, PluggableStorage } from '../types/index'; +// Entry points must export the same objects +let splitFactory = SplitFactory; splitFactory = SplitFactoryFull; +let inLocalStorage = InLocalStorage; inLocalStorage = InLocalStorageFull; +let pluggableStorage = PluggableStorage; pluggableStorage = PluggableStorageFull; let stringPromise: Promise; let splitNamesPromise: Promise; @@ -619,6 +624,10 @@ fullBrowserSettings.debug = DebugLogger(); fullBrowserSettings.debug = InfoLogger(); fullBrowserSettings.debug = WarnLogger(); fullBrowserSettings.debug = ErrorLogger(); +fullBrowserSettings.debug = DebugLoggerFull(); +fullBrowserSettings.debug = InfoLoggerFull(); +fullBrowserSettings.debug = WarnLoggerFull(); +fullBrowserSettings.debug = ErrorLoggerFull(); // let fullNodeSettings: SplitIO.INodeSettings = { // core: { diff --git a/types/full/index.d.ts b/types/full/index.d.ts new file mode 100644 index 0000000..648e49a --- /dev/null +++ b/types/full/index.d.ts @@ -0,0 +1,62 @@ +// Declaration file for JavaScript Browser Split Software SDK +// Project: http://www.split.io/ +// Definitions by: Nico Zelaya + +import '@splitsoftware/splitio-commons'; + +export = JsSdk; + +declare module JsSdk { + /** + * Full version of the Split.io SDK factory function. + * + * Unlike the default version, it includes a `fetch` polyfill to support old browsers @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#language-support}. + * + * The settings parameter should be an object that complies with the SplitIO.IClientSideSettings or SplitIO.IClientSideAsyncSettings interfaces. + * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#configuration} + */ + export function SplitFactory(settings: SplitIO.IClientSideSettings): SplitIO.ISDK; + export function SplitFactory(settings: SplitIO.IClientSideAsyncSettings): SplitIO.IAsyncSDK; + + /** + * Persistent storage based on the LocalStorage Web API for browsers. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#storage} + */ + export function InLocalStorage(options?: SplitIO.InLocalStorageOptions): SplitIO.StorageSyncFactory; + + /** + * Pluggable storage to use the SDK in consumer mode. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#sharing-state-with-a-pluggable-storage} + */ + export function PluggableStorage(options: SplitIO.PluggableStorageOptions): SplitIO.StorageAsyncFactory; + + /** + * Creates a logger instance that enables descriptive log messages with DEBUG log level when passed in the factory settings. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#logging} + */ + export function DebugLogger(): SplitIO.ILogger; + + /** + * Creates a logger instance that enables descriptive log messages with INFO log level when passed in the factory settings. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#logging} + */ + export function InfoLogger(): SplitIO.ILogger; + + /** + * Creates a logger instance that enables descriptive log messages with WARN log level when passed in the factory settings. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#logging} + */ + export function WarnLogger(): SplitIO.ILogger; + + /** + * Creates a logger instance that enables descriptive log messages with ERROR log level when passed in the factory settings. + * + * @see {@link https://help.split.io/hc/en-us/articles/360058730852-Browser-SDK#logging} + */ + export function ErrorLogger(): SplitIO.ILogger; +}