launchdarkly-js-sdk-common
Advanced tools
Comparing version
{ | ||
"name": "launchdarkly-js-sdk-common", | ||
"version": "5.7.0-beta.1", | ||
"version": "5.7.0-beta.2", | ||
"description": "LaunchDarkly SDK for JavaScript - common code", | ||
@@ -5,0 +5,0 @@ "author": "LaunchDarkly <team@launchdarkly.com>", |
@@ -528,3 +528,133 @@ import EventProcessor from '../EventProcessor'; | ||
}); | ||
it('uses EventSummarizer when platform has no hasherFactory', async () => { | ||
const event = { | ||
kind: 'feature', | ||
creationDate: 1000, | ||
context: eventContext, | ||
key: 'flagkey', | ||
version: 11, | ||
variation: 1, | ||
value: 'value', | ||
default: 'default', | ||
trackEvents: true, | ||
}; | ||
const platformWithoutHasher = { ...platform }; | ||
delete platformWithoutHasher.hasherFactory; | ||
const sender = MockEventSender(); | ||
const ep = EventProcessor(platformWithoutHasher, defaultConfig, envId, null, null, sender); | ||
try { | ||
ep.enqueue(event); | ||
await ep.flush(); | ||
expect(sender.calls.length()).toEqual(1); | ||
const output = (await sender.calls.take()).events; | ||
expect(output.length).toEqual(2); | ||
checkFeatureEvent(output[0], event, false, eventContext); | ||
checkSummaryEvent(output[1]); | ||
// Verify the summary event doesn't have a context field when there's no hasherFactory | ||
const summaryEvent = output[1]; | ||
expect(summaryEvent.context).toBeUndefined(); | ||
expect(summaryEvent.features).toEqual({ | ||
flagkey: { | ||
contextKinds: ['user'], | ||
default: 'default', | ||
counters: [{ version: 11, variation: 1, value: 'value', count: 1 }], | ||
}, | ||
}); | ||
} finally { | ||
ep.stop(); | ||
} | ||
}); | ||
it('uses MultiEventSummarizer when platform has hasherFactory', async () => { | ||
const event = { | ||
kind: 'feature', | ||
creationDate: 1000, | ||
context: eventContext, | ||
key: 'flagkey', | ||
version: 11, | ||
variation: 1, | ||
value: 'value', | ||
default: 'default', | ||
trackEvents: true, | ||
}; | ||
// Stub platform hash a hasher factory. | ||
const sender = MockEventSender(); | ||
const ep = EventProcessor(platform, defaultConfig, envId, null, null, sender); | ||
try { | ||
ep.enqueue(event); | ||
await ep.flush(); | ||
expect(sender.calls.length()).toEqual(1); | ||
const output = (await sender.calls.take()).events; | ||
expect(output.length).toEqual(2); | ||
checkFeatureEvent(output[0], event, false, eventContext); | ||
checkSummaryEvent(output[1]); | ||
// Verify that when MultiEventSummarizer is used, context is included in the summary | ||
const summaryEvent = output[1]; | ||
expect(summaryEvent.context).toEqual(eventContext); | ||
expect(summaryEvent.features).toEqual({ | ||
flagkey: { | ||
contextKinds: ['user'], | ||
default: 'default', | ||
counters: [{ version: 11, variation: 1, value: 'value', count: 1 }], | ||
}, | ||
}); | ||
} finally { | ||
ep.stop(); | ||
} | ||
}); | ||
it('filters context in summary events when using MultiEventSummarizer', async () => { | ||
const event = { | ||
kind: 'feature', | ||
creationDate: 1000, | ||
context: eventContext, | ||
key: 'flagkey', | ||
version: 11, | ||
variation: 1, | ||
value: 'value', | ||
default: 'default', | ||
trackEvents: true, | ||
}; | ||
// Configure with allAttributesPrivate set to true | ||
const config = { ...defaultConfig, allAttributesPrivate: true }; | ||
const sender = MockEventSender(); | ||
const ep = EventProcessor(platform, config, envId, null, null, sender); | ||
try { | ||
ep.enqueue(event); | ||
await ep.flush(); | ||
expect(sender.calls.length()).toEqual(1); | ||
const output = (await sender.calls.take()).events; | ||
expect(output.length).toEqual(2); | ||
// Verify the feature event has filtered context | ||
checkFeatureEvent(output[0], event, false, filteredContext); | ||
// Verify the summary event has filtered context | ||
const summaryEvent = output[1]; | ||
checkSummaryEvent(summaryEvent); | ||
expect(summaryEvent.context).toEqual(filteredContext); | ||
expect(summaryEvent.features).toEqual({ | ||
flagkey: { | ||
contextKinds: ['user'], | ||
default: 'default', | ||
counters: [{ version: 11, variation: 1, value: 'value', count: 1 }], | ||
}, | ||
}); | ||
} finally { | ||
ep.stop(); | ||
} | ||
}); | ||
}); | ||
}); |
@@ -36,2 +36,34 @@ import EventSummarizer from '../EventSummarizer'; | ||
it('returns summaries for feature events', () => { | ||
// getSummaries returns the single summary from getSummary(), but wrapped in an array. | ||
const es = EventSummarizer(); | ||
const event1 = { kind: 'feature', creationDate: 2000, key: 'key', user: user }; | ||
const event2 = { kind: 'feature', creationDate: 1000, key: 'key', user: user }; | ||
const event3 = { kind: 'feature', creationDate: 1500, key: 'key', user: user }; | ||
es.summarizeEvent(event1); | ||
es.summarizeEvent(event2); | ||
es.summarizeEvent(event3); | ||
const summaries = es.getSummaries(); | ||
expect(summaries[0].startDate).toEqual(1000); | ||
expect(summaries[0].endDate).toEqual(2000); | ||
}); | ||
it('clears summaries when getSummaries is called', () => { | ||
const es = EventSummarizer(); | ||
const event1 = { kind: 'feature', creationDate: 2000, key: 'key', user: user }; | ||
const event2 = { kind: 'feature', creationDate: 1000, key: 'key', user: user }; | ||
es.summarizeEvent(event1); | ||
es.summarizeEvent(event2); | ||
const summaries = es.getSummaries(); | ||
expect(summaries[0].startDate).toEqual(1000); | ||
expect(summaries[0].endDate).toEqual(2000); | ||
expect(es.getSummaries()).toEqual([]); | ||
}); | ||
it('returns empty array if no summaries are available', () => { | ||
const es = EventSummarizer(); | ||
expect(es.getSummaries()).toEqual([]); | ||
}); | ||
function makeEvent(key, version, variation, value, defaultVal) { | ||
@@ -38,0 +70,0 @@ return { |
@@ -8,2 +8,3 @@ const EventSender = require('./EventSender'); | ||
const { getContextKeys } = require('./context'); | ||
const EventSummarizer = require('./EventSummarizer'); | ||
@@ -22,3 +23,8 @@ function EventProcessor( | ||
const contextFilter = ContextFilter(options); | ||
const summarizer = MultiEventSummarizer(contextFilter, () => platform.hasherFactory('sha256')); | ||
// If the platform has a hasherFactory, use the MultiEventSummarizer, otherwise use the EventSummarizer. | ||
// Generally packages should be pinning a specific version of the common SDK, but this will handle them potentially | ||
// being mis-matched. | ||
const summarizer = platform.hasherFactory | ||
? MultiEventSummarizer(contextFilter, () => platform.hasherFactory('sha256')) | ||
: new EventSummarizer(); | ||
const samplingInterval = options.samplingInterval; | ||
@@ -134,8 +140,3 @@ const eventCapacity = options.eventCapacity; | ||
}); | ||
// const summary = summarizer.getSummary(); | ||
// summarizer.clearSummary(); | ||
// if (summary) { | ||
// summary.kind = 'summary'; | ||
// eventsToSend.push(summary); | ||
// } | ||
if (diagnosticsAccumulator) { | ||
@@ -142,0 +143,0 @@ // For diagnostic events, we record how many events were in the queue at the last flush (since "how |
@@ -96,2 +96,9 @@ const { getContextKinds } = require('./context'); | ||
es.getSummaries = () => { | ||
const summary = es.getSummary(); | ||
const summaries = summary ? [summary] : []; | ||
es.clearSummary(); | ||
return summaries; | ||
}; | ||
es.clearSummary = () => { | ||
@@ -98,0 +105,0 @@ startDate = 0; |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
550921
1.07%13216
1.13%