Skip to content

Release v2.0.3 #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2.0.3 (January 9, 2025)
- Bugfixing - Properly handle rejected promises when using targeting rules with segment matchers in consumer modes (e.g., Redis and Pluggable storages).

2.0.2 (December 3, 2024)
- Updated the factory `init` and `destroy` methods to support re-initialization after destruction. This update ensures compatibility of the React SDK with React Strict Mode, where the factory's `init` and `destroy` effects are executed an extra time to validate proper resource cleanup.
- Bugfixing - Sanitize the `SplitSDKMachineName` header value to avoid exceptions on HTTP/S requests when it contains non ISO-8859-1 characters (Related to issue https://github.com/splitio/javascript-client/issues/847).
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright © 2024 Split Software, Inc.
Copyright © 2025 Split Software, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This library is compatible with JavaScript ES5 and above.
Please see [Contributors Guide](CONTRIBUTORS-GUIDE.md) to find all you need to submit a Pull Request (PR).

## License
Licensed under the Apache License, Version 2.0. See: [Apache License](http://www.apache.org/licenses/).
Licensed under the Apache License, Version 2.0. See: [Apache License](https://www.apache.org/licenses/).

## About Split

Expand Down Expand Up @@ -46,4 +46,4 @@ For a comprehensive list of open source projects visit our [Github page](https:/

**Learn more about Split:**

Visit [split.io/product](https://www.split.io/product) for an overview of Split, or visit our documentation at [help.split.io](http://help.split.io) for more detailed information.
Visit [split.io/product](https://www.split.io/product) for an overview of Split, or visit our documentation at [help.split.io](https://help.split.io) for more detailed information.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-commons",
"version": "2.0.2",
"version": "2.0.3",
"description": "Split JavaScript SDK common components",
"main": "cjs/index.js",
"module": "esm/index.js",
Expand Down
7 changes: 0 additions & 7 deletions src/evaluator/matchers/large_segment.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { MaybeThenable } from '../../dtos/types';
import { ISegmentsCacheBase } from '../../storages/types';
import { thenable } from '../../utils/promise/thenable';

export function largeSegmentMatcherContext(largeSegmentName: string, storage: { largeSegments?: ISegmentsCacheBase }) {

return function largeSegmentMatcher(key: string): MaybeThenable<boolean> {
const isInLargeSegment = storage.largeSegments ? storage.largeSegments.isInSegment(largeSegmentName, key) : false;

if (thenable(isInLargeSegment)) {
isInLargeSegment.then(result => {
return result;
});
}

return isInLargeSegment;
};
}
7 changes: 0 additions & 7 deletions src/evaluator/matchers/segment.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import { MaybeThenable } from '../../dtos/types';
import { ISegmentsCacheBase } from '../../storages/types';
import { thenable } from '../../utils/promise/thenable';

export function segmentMatcherContext(segmentName: string, storage: { segments: ISegmentsCacheBase }) {

return function segmentMatcher(key: string): MaybeThenable<boolean> {
const isInSegment = storage.segments.isInSegment(segmentName, key);

if (thenable(isInSegment)) {
isInSegment.then(result => {
return result;
});
}

return isInSegment;
};
}
4 changes: 2 additions & 2 deletions src/listeners/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class NodeSignalListener implements ISignalListener {
// Cleaned up, remove handlers.
this.stop();

// This handler prevented the default behaviour, start again.
// This handler prevented the default behavior, start again.
// eslint-disable-next-line no-undef
process.kill(process.pid, SIGTERM);
};
Expand All @@ -72,7 +72,7 @@ export class NodeSignalListener implements ISignalListener {
}

if (thenable(handlerResult)) {
// Always exit, even with errors. The promise is returned for UT purposses.
// Always exit, even with errors. The promise is returned for UT purposes.
return handlerResult.then(wrapUp).catch(wrapUp);
} else {
wrapUp();
Expand Down
8 changes: 4 additions & 4 deletions src/logger/__tests__/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,22 @@ function testLogLevels(levelToTest: SplitIO.LogLevel) {

}

test('SPLIT LOGGER / Logger class public methods behaviour - instance.debug', () => {
test('SPLIT LOGGER / Logger class public methods behavior - instance.debug', () => {
testLogLevels(LogLevels.DEBUG);

});

test('SPLIT LOGGER / Logger class public methods behaviour - instance.info', () => {
test('SPLIT LOGGER / Logger class public methods behavior - instance.info', () => {
testLogLevels(LogLevels.INFO);

});

test('SPLIT LOGGER / Logger class public methods behaviour - instance.warn', () => {
test('SPLIT LOGGER / Logger class public methods behavior - instance.warn', () => {
testLogLevels(LogLevels.WARN);

});

test('SPLIT LOGGER / Logger class public methods behaviour - instance.error', () => {
test('SPLIT LOGGER / Logger class public methods behavior - instance.error', () => {
testLogLevels(LogLevels.ERROR);

});
Expand Down
2 changes: 2 additions & 0 deletions src/readiness/__tests__/readinessManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ test('READINESS MANAGER / Cancel timeout if ready fired', (done) => {

const readinessManager = readinessManagerFactory(EventEmitter, settingsWithTimeout);
readinessManager.init(); // Start the timeout
readinessManager.destroy(); // Should cancel the timeout
readinessManager.init(); // Start the timeout again

readinessManager.gate.on(SDK_READY_TIMED_OUT, () => { sdkReadyTimedoutCalled = true; });
readinessManager.gate.once(SDK_READY, () => { sdkReadyCalled = true; });
Expand Down
2 changes: 1 addition & 1 deletion src/readiness/__tests__/sdkReadinessManager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ describe('SDK Readiness Manager - Event emitter', () => {

describe('SDK Readiness Manager - Ready promise', () => {

test('.ready() promise behaviour for clients', async () => {
test('.ready() promise behavior for clients', async () => {
const sdkReadinessManager = sdkReadinessManagerFactory(EventEmitterMock, fullSettings);

const ready = sdkReadinessManager.sdkStatus.ready();
Expand Down
2 changes: 1 addition & 1 deletion src/storages/inRedis/SplitsCacheInRedis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,10 @@ export class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
return Promise.reject(this.redisError);
}

const splits: Record<string, ISplit | null> = {};
const keys = names.map(name => this.keys.buildSplitKey(name));
return this.redis.mget(...keys)
.then(splitDefinitions => {
const splits: Record<string, ISplit | null> = {};
names.forEach((name, idx) => {
const split = splitDefinitions[idx];
splits[name] = split && JSON.parse(split);
Expand Down
2 changes: 1 addition & 1 deletion src/storages/inRedis/__tests__/RedisAdapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ describe('STORAGE Redis Adapter', () => {

expect(ioredisMock.once).toBeCalledTimes(2); // If the method was called, it should have called the `once` function twice. If that it the case we can assume that the method was called on creation.

// Reset stubs again, we'll check the behaviour calling the method directly.
// Reset stubs again, we'll check the behavior calling the method directly.
clearAllMocks();
expect(ioredisMock.once).not.toBeCalled(); // Control assertion
expect(ioredisMock[METHODS_TO_PROMISE_WRAP[METHODS_TO_PROMISE_WRAP.length - 1]]).not.toBeCalled(); // Control assertion
Expand Down
14 changes: 8 additions & 6 deletions src/sync/streaming/pushManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,12 +349,14 @@ export function pushManagerFactory(
// Reconnects in case of a new client.
// Run in next event-loop cycle to save authentication calls
// in case multiple clients are created in the current cycle.
setTimeout(function checkForReconnect() {
if (connectForNewClient) {
connectForNewClient = false;
connectPush();
}
}, 0);
if (this.isRunning()) {
setTimeout(function checkForReconnect() {
if (connectForNewClient) {
connectForNewClient = false;
connectPush();
}
}, 0);
}
}
},
// [Only for client-side]
Expand Down
4 changes: 2 additions & 2 deletions src/sync/syncManagerOnline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,19 @@ export function syncManagerOnlineFactory(
if (!pollingManager) return;

const mySegmentsSyncTask = (pollingManager as IPollingManagerCS).add(matchingKey, readinessManager, storage);
if (syncEnabled && pushManager) pushManager.add(matchingKey, mySegmentsSyncTask);

if (running) {
if (syncEnabled) {
if (pushManager) {
if (pollingManager!.isRunning()) {
if (pollingManager.isRunning()) {
// if doing polling, we must start the periodic fetch of data
if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
} else {
// if not polling, we must execute the sync task for the initial fetch
// of segments since `syncAll` was already executed when starting the main client
mySegmentsSyncTask.execute();
}
pushManager.add(matchingKey, mySegmentsSyncTask);
} else {
if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
}
Expand Down
2 changes: 1 addition & 1 deletion src/trackers/eventTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function eventTrackerFactory(
whenInit(() => {
// Wrap in a timeout because we don't want it to be blocking.
setTimeout(() => {
// copy of event, to avoid unexpected behaviour if modified by integrations
// copy of event, to avoid unexpected behavior if modified by integrations
const eventDataCopy = objectAssign({}, eventData);
if (properties) eventDataCopy.properties = objectAssign({}, properties);
// integrationsManager does not throw errors (they are internally handled by each integration module)
Expand Down
2 changes: 1 addition & 1 deletion src/trackers/impressionsTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function impressionsTrackerFactory(
if (impressionListener || integrationsManager) {
for (let i = 0; i < impressionsToListenerCount; i++) {
const impressionData: SplitIO.ImpressionData = {
// copy of impression, to avoid unexpected behaviour if modified by integrations or impressionListener
// copy of impression, to avoid unexpected behavior if modified by integrations or impressionListener
impression: objectAssign({}, impressionsToListener[i]),
attributes,
ip,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/settingsValidation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
if (withDefaults.mode === LOCALHOST_MODE && maybeKey === undefined) {
withDefaults.core.key = 'localhost_key';
} else {
// Keeping same behaviour than JS SDK: if settings key or TT are invalid,
// Keeping same behavior than JS SDK: if settings key or TT are invalid,
// `false` value is used as bound key/TT of the default client, which leads to some issues.
// @ts-ignore, @TODO handle invalid keys as a non-recoverable error?
withDefaults.core.key = validateKey(log, maybeKey, LOG_PREFIX_CLIENT_INSTANTIATION);
Expand Down
2 changes: 1 addition & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Declaration file for JavaScript Browser Split Software SDK
// Project: http://www.split.io/
// Project: https://www.split.io/
// Definitions by: Nico Zelaya <https://github.com/NicoZelaya/>

/// <reference path="./splitio.d.ts" />
2 changes: 1 addition & 1 deletion types/splitio.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Type definitions for Split Software SDKs
// Project: http://www.split.io/
// Project: https://www.split.io/

import { RedisOptions } from 'ioredis';
import { RequestOptions } from 'http';
Expand Down
Loading