Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
491 commits
Select commit Hold shift + click to select a range
817df99
fix ruleIndex in rule match reason
eli-darkly Oct 10, 2019
7190f23
Merge pull request #143 from launchdarkly/eb/ch52234/rule-index
eli-darkly Oct 10, 2019
7a96e72
merge from public after release
LaunchDarklyCI Oct 10, 2019
b7f1426
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Oct 11, 2019
6654243
reimplement flag change events to use dependency graph
eli-darkly Oct 17, 2019
ffd16f0
rm unused
eli-darkly Oct 17, 2019
597527c
fix setting of empty dependencies
eli-darkly Oct 17, 2019
55d5f7e
misc cleanup
eli-darkly Oct 17, 2019
de09377
typo
eli-darkly Oct 17, 2019
fa629a4
update syntax: const, let, arrow functions
eli-darkly Oct 18, 2019
38e308a
more syntax fixes, linting
eli-darkly Oct 18, 2019
51dc73d
more syntax fixes, linting
eli-darkly Oct 18, 2019
46e960a
more syntax fixes, linting
eli-darkly Oct 18, 2019
5633da7
downgrade ESLint because we must support Node 6
eli-darkly Oct 18, 2019
07827df
Merge pull request #145 from launchdarkly/eb/ch35417/es2015
eli-darkly Oct 18, 2019
9a69099
Merge branch 'master' into eb/ch52363/change-events
eli-darkly Oct 18, 2019
8361f7b
skip update event logic if there are no update event listeners
eli-darkly Oct 19, 2019
7ac9ab8
consequence of passing an empty object was correct but non-self-evident
eli-darkly Oct 19, 2019
aa48dc1
rm meaningless "arguments"
eli-darkly Oct 19, 2019
d0fdff1
avoid unnecessary deferral of internal callbacks
eli-darkly Oct 19, 2019
d268893
better handling of invalid data types
eli-darkly Oct 20, 2019
81b41ea
Merge pull request #144 from launchdarkly/eb/ch52363/change-events
eli-darkly Oct 22, 2019
9590571
Merge pull request #146 from launchdarkly/eb/ch53164/efficient-callbacks
eli-darkly Oct 22, 2019
f874713
fix regex, add comment
eli-darkly Oct 22, 2019
18c8d6d
don't signal init failure & don't fire an error unless it's unrecover…
eli-darkly Oct 22, 2019
1bb0cfc
fix tests
eli-darkly Oct 22, 2019
483e24c
remove unused "hoek" dependency
eli-darkly Oct 22, 2019
102b595
Merge pull request #149 from launchdarkly/eb/ch48460/dependencies
eli-darkly Oct 22, 2019
e5ce416
remove typedoc dependency
eli-darkly Oct 23, 2019
3b043e2
use semver 6.x
eli-darkly Oct 23, 2019
1e849f8
update eslint to 6.x
eli-darkly Oct 23, 2019
587b777
update async package (removes old lodash dependency)
eli-darkly Oct 23, 2019
7d8d074
update node-cache package (removes old lodash dependency)
eli-darkly Oct 23, 2019
04a80af
add audit script
eli-darkly Oct 23, 2019
81c3aad
Revert "update node-cache package (removes old lodash dependency)"
eli-darkly Oct 23, 2019
6af73a8
Revert "update async package (removes old lodash dependency)"
eli-darkly Oct 23, 2019
159924f
fix dependency path parsing
eli-darkly Oct 23, 2019
ee0c889
Revert "Revert "update async package (removes old lodash dependency)""
eli-darkly Oct 23, 2019
9de1e85
Revert "Revert "update node-cache package (removes old lodash depende…
eli-darkly Oct 23, 2019
5373bda
run "npm audit fix" for dev dependencies
eli-darkly Oct 23, 2019
bd06c68
Merge pull request #148 from launchdarkly/eb/ch46962/init-error
eli-darkly Oct 23, 2019
214b68e
Merge pull request #150 from launchdarkly/eb/ch53632/no-typedoc
eli-darkly Oct 23, 2019
025145d
Merge pull request #151 from launchdarkly/eb/ch53633/semver-update
eli-darkly Oct 23, 2019
83562a8
update eslint to 6.x (#152)
eli-darkly Oct 23, 2019
42ef9a5
Merge branch 'master' into eb/ch53542/npm-audit-fix
eli-darkly Oct 23, 2019
c2cde3b
Merge pull request #153 from launchdarkly/eb/ch53542/npm-audit-fix
eli-darkly Oct 23, 2019
41167dc
Merge pull request #147 from launchdarkly/eb/ch10795/bad-data
eli-darkly Oct 23, 2019
5693928
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Oct 23, 2019
ea5e463
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Oct 23, 2019
752b6d7
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Oct 25, 2019
91c7b82
add TS decl for new Redis parameter
eli-darkly Oct 25, 2019
1d21356
add TS syntax check code
eli-darkly Oct 25, 2019
ab838aa
Merge pull request #154 from launchdarkly/eb/ch53636/redis-intf
eli-darkly Oct 29, 2019
1fe1826
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
bwoskow-ld Nov 7, 2019
291c8bc
better config validation
eli-darkly Nov 19, 2019
07ba97e
rm unused
eli-darkly Nov 19, 2019
a78398a
new config options and headers for diagnostic events
eli-darkly Nov 19, 2019
43db5af
fix tests
eli-darkly Nov 19, 2019
a9335cf
object shorthand
eli-darkly Nov 19, 2019
862a491
Merge pull request #155 from launchdarkly/eb/ch56521/validate-config
eli-darkly Nov 19, 2019
e0505d6
Merge pull request #156 from launchdarkly/eb/ch56381/diag-events-1-co…
eli-darkly Nov 19, 2019
272a603
Merge branch 'master' into diagnostic-events
eli-darkly Nov 19, 2019
fb42a33
add more end-to-end tests, improve HTTP test helpers, general cleanup
eli-darkly Nov 20, 2019
7ca8250
rm nock
eli-darkly Nov 20, 2019
60222a2
Node 6 compatibility
eli-darkly Nov 20, 2019
96f0352
remove redundant helper, misc cleanup
eli-darkly Nov 20, 2019
a351318
Node 6 compatibility
eli-darkly Nov 20, 2019
e9c869e
fix comment
eli-darkly Nov 20, 2019
a556934
change asyncify to promisifySingle
eli-darkly Nov 20, 2019
ea227eb
misc fixes
eli-darkly Nov 20, 2019
42603da
add Windows CircleCI job
eli-darkly Nov 20, 2019
382ee93
fix config
eli-darkly Nov 20, 2019
193f2d4
syntax
eli-darkly Nov 20, 2019
dc2755a
Merge pull request #159 from launchdarkly/eb/ch56746/windows-ci
eli-darkly Nov 21, 2019
c6d3079
Merge branch 'master' into diag-events-merged
eli-darkly Nov 21, 2019
4cce49e
Merge branch 'eb/ch56656/better-async-helper' into diag-events-merged
eli-darkly Nov 21, 2019
3d8bd18
diagnostic events, part 2: initial event and stats, except for stream…
eli-darkly Nov 21, 2019
9b6fe96
comments
eli-darkly Nov 21, 2019
638d011
add test for stats event
eli-darkly Nov 21, 2019
5dd0195
capture stream connection stats in diagnostic events
eli-darkly Nov 21, 2019
a5338c2
fix test
eli-darkly Nov 21, 2019
b187af3
remove eventReportingDisabled from diagnostic event; only create diag…
eli-darkly Nov 22, 2019
cdefc53
Merge branch 'eb/ch56381/diag-events-2-initial' into eb/ch56381/diag-…
eli-darkly Nov 22, 2019
3da81f7
Merge pull request #157 from launchdarkly/eb/ch56656/http-test-cleanup
eli-darkly Nov 23, 2019
14f5f61
Merge pull request #158 from launchdarkly/eb/ch56656/better-async-helper
eli-darkly Nov 23, 2019
4f16b1d
revise tests to use new helper package
eli-darkly Nov 23, 2019
79db3e0
Merge branch 'master' into diag-events-merged
eli-darkly Nov 23, 2019
af8e51e
Merge branch 'diagnostic-events' into eb/ch56381/diag-events-2-initial
eli-darkly Nov 23, 2019
9630ddb
misc cleanup
eli-darkly Nov 23, 2019
31a9b41
Merge pull request #160 from launchdarkly/eb/ch56381/diag-events-2-in…
eli-darkly Nov 23, 2019
75a9cd2
Merge branch 'diagnostic-events' into eb/ch56381/diag-events-3-stream
eli-darkly Nov 23, 2019
81d5249
Merge pull request #161 from launchdarkly/eb/ch56381/diag-events-3-st…
eli-darkly Nov 23, 2019
90ef205
Merge branch 'master' into eb/ch57131/new-test-package
eli-darkly Nov 23, 2019
677e1b2
use launchdarkly-js-test-helpers 1.0.0
eli-darkly Nov 26, 2019
438cf91
fix package reference
eli-darkly Nov 26, 2019
d7208df
minor fixes to config validation messages + add comment
eli-darkly Dec 4, 2019
cc9dbed
Merge pull request #163 from launchdarkly/eb/ch56521/config-validatio…
eli-darkly Dec 4, 2019
c015310
Merge branch 'master' into diagnostic-events
eli-darkly Dec 5, 2019
1f75d71
Merge pull request #162 from launchdarkly/eb/ch57131/new-test-package
eli-darkly Dec 6, 2019
1eea22e
Merge branch 'master' into diagnostic-events
eli-darkly Dec 9, 2019
aace735
diagnostic eventsInQueue counter should be # of events at last flush
eli-darkly Dec 9, 2019
1fb38d1
rename eventsInQueue to eventsInLastBatch
eli-darkly Dec 10, 2019
d270a35
Merge pull request #164 from launchdarkly/eb/ch56381-ch58405/diagnost…
eli-darkly Dec 11, 2019
f866ab4
merge from public after release
LaunchDarklyCI Dec 11, 2019
24b85c3
don't let user fall outside of last bucket in rollout
bwoskow-ld Dec 24, 2019
561ed34
add unit tests for basic bucketing logic and edge case
eli-darkly Dec 30, 2019
359678e
avoid redundant property lookups
eli-darkly Dec 30, 2019
787c9e3
Merge pull request #165 from launchdarkly/bw/ch43307/bucket-issue
eli-darkly Jan 3, 2020
cea2d8a
merge from public after release
LaunchDarklyCI Jan 6, 2020
e9d2cfd
fix Redis client parameter to match TS declaration (but still support…
eli-darkly Jan 13, 2020
cc98785
Merge pull request #166 from launchdarkly/eb/ch61188/redis-params
eli-darkly Jan 13, 2020
cc96ab8
merge from public after release
LaunchDarklyCI Jan 13, 2020
b099acf
add event payload ID
eli-darkly Jan 14, 2020
68fc8f8
remove mistakenly checked-in test code (note, this SDK key was only v…
eli-darkly Jan 14, 2020
603d788
Merge pull request #167 from launchdarkly/eb/ch61092/payload-id
eli-darkly Jan 14, 2020
b0f4e0b
merge from public after release
LaunchDarklyCI Jan 15, 2020
8bad3d5
add mention of singleton usage
eli-darkly Feb 11, 2020
50c3497
Merge pull request #168 from launchdarkly/eb/ch65200/singleton-comment
eli-darkly Feb 11, 2020
47e13c8
Merge branch 'master' into diagnostic-events
eli-darkly Feb 11, 2020
315e9ba
update diagnostic event info for OS name, data store type, Node version
eli-darkly Feb 11, 2020
e012522
standardize linting
eli-darkly Feb 11, 2020
6af8688
disallow window and document
eli-darkly Feb 11, 2020
d600230
fix null/undef checks
eli-darkly Feb 11, 2020
c80f85e
misc linting fixes
eli-darkly Feb 12, 2020
5feaef6
Merge pull request #170 from launchdarkly/eb/ch65303/linting
eli-darkly Feb 12, 2020
3d1a4dd
Merge pull request #169 from launchdarkly/eb/ch62088/spec-updates
eli-darkly Feb 12, 2020
62304d2
inlineUsersInEvents is not an unknown option
eli-darkly Feb 12, 2020
d008bc6
drop node-sha1 dependency
eli-darkly Feb 12, 2020
2965a25
Merge pull request #171 from launchdarkly/eb/ch65544/unknown-option
eli-darkly Feb 12, 2020
9a8bc0f
Merge pull request #172 from launchdarkly/eb/ch65523/sha1-module
eli-darkly Feb 12, 2020
e4849e0
Merge branch 'master' into diagnostic-events
eli-darkly Feb 12, 2020
d80cb60
merge from public after release
LaunchDarklyCI Feb 12, 2020
66b65f0
don't omit streamInits.failed when it's false
eli-darkly Feb 14, 2020
0387358
Merge pull request #173 from launchdarkly/eb/ch65817/diagnostic-expli…
eli-darkly Feb 14, 2020
9913d25
merge from public after release
LaunchDarklyCI Feb 14, 2020
59c9687
bump request dependency to get security patch; loosen some exact depe…
eli-darkly Feb 20, 2020
aff36e4
remove request package; improve polling cache logic + add test
eli-darkly Feb 20, 2020
f2e68a4
bump typescript version to fix build error in Node 6
eli-darkly Feb 20, 2020
e754252
update @types/node to fix TypeScript check step
eli-darkly Feb 20, 2020
23e02c0
Merge pull request #174 from launchdarkly/eb/ch66555/request-dep
eli-darkly Feb 20, 2020
a99c572
Merge branch 'master' into eb/ch66553/drop-request-package
eli-darkly Feb 20, 2020
9b30917
lint
eli-darkly Feb 20, 2020
8cc01d2
merge from public after release
LaunchDarklyCI Feb 20, 2020
37196b9
make sure we keep polling regardless of whether we got new data
eli-darkly Mar 9, 2020
12c8594
Merge pull request #175 from launchdarkly/eb/ch66553/drop-request-pac…
eli-darkly Mar 9, 2020
5ef755f
merge from public after release
LaunchDarklyCI Mar 9, 2020
4aaaf65
use launchdarkly-eventsource, make stream retry behavior consistent
eli-darkly Apr 3, 2020
e213d02
Merge pull request #176 from launchdarkly/eb/ch69693/stream-retry
eli-darkly Apr 3, 2020
ef5de0b
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Apr 3, 2020
b626468
stream retry delay option should be in seconds & should be included i…
eli-darkly Apr 3, 2020
9dd0e9c
Merge pull request #177 from launchdarkly/eb/ch72241/stream-retry-option
eli-darkly Apr 7, 2020
7d143b6
minor test fix
eli-darkly Apr 7, 2020
b2a8a1d
merge from public after release
LaunchDarklyCI Apr 7, 2020
2e084b2
fix: Throw an error on malformed user-supplied logger
maxwellgerber Apr 22, 2020
c666c0f
don't call unref() on Redis client; ensure that database integration …
eli-darkly Apr 22, 2020
40f9754
Merge pull request #178 from launchdarkly/eb/ch25282/redis-unref
eli-darkly Apr 22, 2020
3d558cf
update Redis driver to major version 3
eli-darkly Apr 22, 2020
00c6da8
add test case
maxwellgerber Apr 22, 2020
bfcd711
allow redisOpts parameter to be omitted
eli-darkly Apr 23, 2020
66353c2
add logger adapter shim + tests
maxwellgerber Apr 23, 2020
cf98f97
Merge pull request #179 from launchdarkly/eb/ch74036/redis3
eli-darkly Apr 23, 2020
ac46536
Merge pull request #185 from maxwellgerber/fix/throw-err-on-malformed…
eli-darkly Apr 23, 2020
7c08df2
Merge branch 'contrib' of github.com:launchdarkly/node-server-sdk
eli-darkly Apr 23, 2020
1b94b45
minor cleanup and comments for ch74741 fix (logger wrapper)
eli-darkly Apr 23, 2020
194fc9e
fix proxy tunnel configuration and make sure it's used in streaming
eli-darkly Apr 24, 2020
11210de
Merge pull request #181 from launchdarkly/eb/ch74739/streaming-proxy
eli-darkly Apr 24, 2020
10ab5ab
merge from public after release
LaunchDarklyCI Apr 25, 2020
12949a2
change some string concatenation expressions to use interpolation
eli-darkly May 4, 2020
9f16efb
Merge branch 'master' into eb/ch74741/logger-wrapper-followup
eli-darkly May 4, 2020
a3b70cc
Merge pull request #180 from launchdarkly/eb/ch74741/logger-wrapper-f…
eli-darkly May 4, 2020
a1762e2
feat: upgrade winston (#189)
FauxFaux Jun 23, 2020
02e90a3
Merge branch 'contrib' of github.com:launchdarkly/node-server-sdk
eli-darkly Jun 23, 2020
3fbcf83
fix merge
eli-darkly Jun 24, 2020
a4ae3ad
remove support for indirect/patch and indirect/put (#182)
eli-darkly Jun 25, 2020
2780797
reuse same Promise and same event listeners for all waitForInitializa…
eli-darkly Jun 26, 2020
b73ca82
Merge pull request #183 from launchdarkly/eb/ch80833/wait-for-init-li…
eli-darkly Jun 26, 2020
64b8869
better docs for waitForInitialization + misc doc cleanup (#184)
eli-darkly Jun 30, 2020
2f0c4c0
update js-eventsource to 1.3.1 for stream parsing bugfix (#185)
eli-darkly Jun 30, 2020
179d838
merge from public after release
LaunchDarklyCI Jun 30, 2020
5c52e9e
fix broken logger format (#186)
eli-darkly Jun 30, 2020
804c424
merge from public after release
LaunchDarklyCI Jun 30, 2020
09d03b6
retroactively update changelog for bugfix in 5.13.2 release
eli-darkly Jul 8, 2020
a16805c
Merge pull request #187 from launchdarkly/eb/ch80833/bugfix-changelog
eli-darkly Jul 8, 2020
b858395
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Aug 5, 2020
0a28e52
allow get/getAll Redis queries to be queued if Redis client hasn't ye…
eli-darkly Aug 27, 2020
9bedee0
Merge pull request #188 from launchdarkly/eb/ch87993/redis-connect-state
eli-darkly Aug 27, 2020
1e90630
merge from public after release
LaunchDarklyCI Aug 28, 2020
abfcf7f
set stream read timeout
eli-darkly Jan 26, 2021
4f8774e
Merge pull request #189 from launchdarkly/eb/ch73764/stream-read-timeout
eli-darkly Jan 26, 2021
0882774
merge from public after release
LaunchDarklyCI Jan 26, 2021
c4b9f3a
adding the alias functionality (#190)
bwoskow-ld Jan 29, 2021
0e24961
merge from public after release
LaunchDarklyCI Jan 29, 2021
26ebc52
Removed the guides link
bwoskow-ld Feb 3, 2021
4307257
remove monkey-patching of setImmediate
eli-darkly Feb 8, 2021
ad3e106
Merge pull request #191 from launchdarkly/eb/ch100514/no-monkey-patch
eli-darkly Feb 8, 2021
43eee0e
merge from public after release
LaunchDarklyCI Feb 9, 2021
4b3ad52
Persist contextKind property during feature and custom event transfor…
bwoskow-ld Feb 11, 2021
5210f46
merge from public after release
LaunchDarklyCI Feb 11, 2021
d9b7597
add inlineUsersInEvents option in TypeScript
eli-darkly Mar 30, 2021
8e425a0
Merge pull request #197 from launchdarkly/eb/ch103585/inline-property
eli-darkly Apr 1, 2021
3e3db9c
merge from public after release
LaunchDarklyCI Apr 1, 2021
05d80fc
Add support for seed to bucketUser
Apr 16, 2021
70277ce
Add note for incorporating seed into evaluation
Apr 21, 2021
94a1016
Send events when the evaluation is from an experiment
Apr 22, 2021
8da6541
Use seed to evaluate.
Apr 22, 2021
db5c28c
Clean up test descriptions
Apr 22, 2021
520da38
Rename variable to be less confusing
Apr 23, 2021
48af02d
Use ternary to eliminate mutation
Apr 23, 2021
10a2377
Make return signature more consistent
Apr 23, 2021
8707999
Un-prettier the tests
Apr 23, 2021
d8e7cbb
Add traffic allocation support (#198)
Apr 26, 2021
293c6a5
redis lower bounds bump (#199)
bwoskow-ld Apr 28, 2021
6330aef
merge from public after release
LaunchDarklyCI Apr 29, 2021
7b450e3
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
bwoskow-ld May 11, 2021
8bfea5f
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
bwoskow-ld May 24, 2021
c1a91f8
Merge branch 'master' into exp-alloc
robertjneal Jun 4, 2021
71b3579
update launchdarkly-js-test-helpers to fix TLS tests (#200)
eli-darkly Jun 9, 2021
473a1c1
update js-eventsource to remove vulnerability warning (#201)
eli-darkly Jun 10, 2021
ae3a860
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Jun 10, 2021
d937730
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
bwoskow-ld Jun 11, 2021
3e55ee1
add CI jobs for all compatible Node versions
eli-darkly Jun 12, 2021
895a7b7
CI fixes
eli-darkly Jun 12, 2021
b42ac5d
more CI fixes
eli-darkly Jun 12, 2021
da29df1
comment
eli-darkly Jun 12, 2021
439c16b
use default value to simplify config
eli-darkly Jun 12, 2021
6aed521
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
bwoskow-ld Jun 14, 2021
7520d6c
Merge branch 'master' into 6.0
eli-darkly Jun 14, 2021
9b534c7
(6.0 - #1) stop saying we're compatible with Node <12 (#203)
eli-darkly Jun 14, 2021
b6da495
add CI jobs for all compatible Node versions (#202)
eli-darkly Jun 14, 2021
23eda3b
Merge branch 'master' into 6.0
eli-darkly Jun 14, 2021
847a903
(6.0 - #2) remove Redis integration (#204)
eli-darkly Jun 14, 2021
679f879
allow feature store to be specified as a factory (so it can get our l…
eli-darkly Jun 14, 2021
ecf5135
(6.0 - #3) remove Winston (#205)
eli-darkly Jun 14, 2021
19cc663
remove deprecated things for 6.0 (#206)
eli-darkly Jun 14, 2021
2381b91
Merge pull request #207 from launchdarkly/eb/ch111387/data-store-factory
eli-darkly Jun 14, 2021
868128b
update node-cache to 5.x (drops old Node compat)
eli-darkly Jun 15, 2021
1191c2e
update semver to 7.x (drops old Node compat)
eli-darkly Jun 15, 2021
38ead49
update uuid to 8.x (Node compat, perf improvements, bugfixes)
eli-darkly Jun 15, 2021
4930fc7
update dev dependencies
eli-darkly Jun 15, 2021
2ad6d55
linter
eli-darkly Jun 15, 2021
010a1a5
Merge pull request #208 from launchdarkly/eb/ch111699/update-deps
eli-darkly Jun 15, 2021
3ae053a
replace lrucache package with lru-cache (#209)
eli-darkly Jun 15, 2021
59e2f82
make yaml dependency optional (#210)
eli-darkly Jun 15, 2021
d292f74
update release metadata to include maintenance branch
eli-darkly Jun 15, 2021
4a5dc99
Merge branch '6.0'
eli-darkly Jun 15, 2021
6a1c746
remove package-lock.json (#211)
eli-darkly Jun 17, 2021
a95ddfe
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Jun 17, 2021
e74c640
rm prerelease changelog
eli-darkly Jun 17, 2021
4237116
Merge branch 'master' of github.com:launchdarkly/node-server-sdk
eli-darkly Jun 17, 2021
bb0a957
Merge branch 'exp-alloc'
eli-darkly Jun 17, 2021
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
29 changes: 18 additions & 11 deletions evaluate_flag.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,15 @@ function getResultForVariationOrRollout(r, user, flag, reason, cb) {
if (!r) {
cb(new Error('Fallthrough variation undefined'), errorResult('MALFORMED_FLAG'));
} else {
const index = variationForUser(r, user, flag);
const [index, inExperiment] = variationForUser(r, user, flag);
if (index === null || index === undefined) {
cb(new Error('Variation/rollout object with no variation or rollout'), errorResult('MALFORMED_FLAG'));
} else {
getVariation(flag, index, reason, cb);
const transformedReason = reason;
if (inExperiment) {
transformedReason.inExperiment = true;
}
getVariation(flag, index, transformedReason, cb);
}
}
}
Expand All @@ -301,27 +305,28 @@ function errorResult(errorKind) {
return { value: null, variationIndex: null, reason: { kind: 'ERROR', errorKind: errorKind } };
}

// Given a variation or rollout 'r', select
// the variation for the given user
// Given a variation or rollout 'r', select the variation for the given user.
// Returns an array of the form [variationIndex, inExperiment].
function variationForUser(r, user, flag) {
if (r.variation !== null && r.variation !== undefined) {
// This represets a fixed variation; return it
return r.variation;
return [r.variation, false];
}
const rollout = r.rollout;
if (rollout) {
const isExperiment = rollout.kind === 'experiment';
const variations = rollout.variations;
if (variations && variations.length > 0) {
// This represents a percentage rollout. Assume
// we're rolling out by key
const bucketBy = rollout.bucketBy || 'key';
const bucket = bucketUser(user, flag.key, bucketBy, flag.salt);
const bucket = bucketUser(user, flag.key, bucketBy, flag.salt, rollout.seed);
let sum = 0;
for (let i = 0; i < variations.length; i++) {
const variate = variations[i];
sum += variate.weight / 100000.0;
if (bucket < sum) {
return variate.variation;
return [variate.variation, isExperiment && !variate.untracked];
}
}

Expand All @@ -330,11 +335,12 @@ function variationForUser(r, user, flag) {
// data could contain buckets that don't actually add up to 100000. Rather than returning an error in
// this case (or changing the scaling, which would potentially change the results for *all* users), we
// will simply put the user in the last bucket.
return variations[variations.length - 1].variation;
const lastVariate = variations[variations.length - 1];
return [lastVariate.variation, isExperiment && !lastVariate.untracked];
}
}

return null;
return [null, false];
}

// Fetch an attribute value from a user object. Automatically
Expand All @@ -350,7 +356,7 @@ function userValue(user, attr) {
}

// Compute a percentile for a user
function bucketUser(user, key, attr, salt) {
function bucketUser(user, key, attr, salt, seed) {
let idHash = bucketableStringValue(userValue(user, attr));

if (idHash === null) {
Expand All @@ -361,7 +367,8 @@ function bucketUser(user, key, attr, salt) {
idHash += '.' + user.secondary;
}

const hashKey = util.format('%s.%s.%s', key, salt, idHash);
const prefix = seed ? util.format('%d.', seed) : util.format('%s.%s.', key, salt);
const hashKey = prefix + idHash;
const hashVal = parseInt(sha1Hex(hashKey).substring(0, 15), 16);

return hashVal / 0xfffffffffffffff;
Expand Down
5 changes: 5 additions & 0 deletions event_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ function EventFactory(withReasons) {

function isExperiment(flag, reason) {
if (reason) {
// If the reason says we're in an experiment, we are. Otherwise, apply
// the legacy rule exclusion logic.
if (reason.inExperiment) {
return true;
}
switch (reason.kind) {
case 'RULE_MATCH': {
const index = reason.ruleIndex;
Expand Down
82 changes: 81 additions & 1 deletion test/LDClient-events-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,87 @@ describe('LDClient - analytics events', () => {
value: 'b',
default: 'c',
trackEvents: true,
reason: { kind: 'FALLTHROUGH' }
reason: { kind: 'FALLTHROUGH' },
});
});

it('forces tracking when an evaluation is in the tracked portion of an experiment rollout', async () => {
var flag = {
key: 'flagkey',
version: 1,
on: true,
targets: [],
rules: [],
fallthrough: {
rollout: {
kind: 'experiment',
variations: [
{
weight: 100000,
variation: 1,
},
],
},
},
variations: ['a', 'b'],
};
var client = stubs.createClient({ eventProcessor: eventProcessor }, { flagkey: flag });
await client.waitForInitialization();
await client.variation(flag.key, defaultUser, 'c');

expect(eventProcessor.events).toHaveLength(1);
var e = eventProcessor.events[0];
expect(e).toEqual({
kind: 'feature',
creationDate: e.creationDate,
key: 'flagkey',
version: 1,
user: defaultUser,
variation: 1,
value: 'b',
default: 'c',
trackEvents: true,
reason: { kind: 'FALLTHROUGH', inExperiment: true },
});
});

it('does not force tracking when an evaluation is in the untracked portion of an experiment rollout', async () => {
var flag = {
key: 'flagkey',
version: 1,
on: true,
targets: [],
rules: [],
fallthrough: {
rollout: {
kind: 'experiment',
variations: [
{
weight: 100000,
variation: 1,
untracked: true,
},
],
},
},
variations: ['a', 'b'],
};
var client = stubs.createClient({ eventProcessor: eventProcessor }, { flagkey: flag });
await client.waitForInitialization();
debugger;
await client.variation(flag.key, defaultUser, 'c');

expect(eventProcessor.events).toHaveLength(1);
var e = eventProcessor.events[0];
expect(e).toEqual({
kind: 'feature',
creationDate: e.creationDate,
key: 'flagkey',
version: 1,
user: defaultUser,
variation: 1,
value: 'b',
default: 'c',
});
});

Expand Down
86 changes: 86 additions & 0 deletions test/evaluate_flag-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,58 @@ describe('rollout', () => {
done();
});
});

describe('with seed', () => {
const seed = 61;
const flagKey = 'flagkey';
const salt = 'salt';
const rollout = {
kind: 'experiment',
seed,
variations: [
{ variation: 0, weight: 10000 },
{ variation: 1, weight: 20000 },
{ variation: 0, weight: 70000, untracked: true },
],
};
const flag = {
key: flagKey,
salt: salt,
on: true,
fallthrough: { rollout: rollout },
variations: [null, null, null],
};

it('buckets user into first variant of the experiment', done => {
var user = { key: 'userKeyA' };
evaluate.evaluate(flag, user, featureStore, eventFactory, (err, detail) => {
expect(err).toEqual(null);
expect(detail.variationIndex).toEqual(0);
expect(detail.reason.inExperiment).toBe(true);
done();
});
});

it('uses seed to bucket user into second variant of the experiment', done => {
var user = { key: 'userKeyB' };
evaluate.evaluate(flag, user, featureStore, eventFactory, (err, detail) => {
expect(err).toEqual(null);
expect(detail.variationIndex).toEqual(1);
expect(detail.reason.inExperiment).toBe(true);
done();
});
});

it('buckets user outside of the experiment', done => {
var user = { key: 'userKeyC' };
evaluate.evaluate(flag, user, featureStore, eventFactory, (err, detail) => {
expect(err).toEqual(null);
expect(detail.variationIndex).toEqual(0);
expect(detail.reason.inExperiment).toBe(undefined);
done();
});
});
});
});

describe('bucketUser', () => {
Expand Down Expand Up @@ -795,4 +847,38 @@ describe('bucketUser', () => {
var bucket = evaluate.bucketUser(user, 'hashKey', 'floatAttr', 'saltyA');
expect(bucket).toBe(0);
});

describe('when seed is present', () => {
const seed = 61;
it('gets expected bucket values for specific keys', () => {
var user = { key: 'userKeyA' };
var bucket = evaluate.bucketUser(user, 'hashKey', 'key', 'saltyA', seed);
expect(bucket).toBeCloseTo(0.09801207, 7);

user = { key: 'userKeyB' };
bucket = evaluate.bucketUser(user, 'hashKey', 'key', 'saltyA', seed);
expect(bucket).toBeCloseTo(0.14483777, 7);

user = { key: 'userKeyC' };
bucket = evaluate.bucketUser(user, 'hashKey', 'key', 'saltyA', seed);
expect(bucket).toBeCloseTo(0.9242641, 7);
});

it('should not generate a different bucket when hashKey or salt are changed', () => {
let user = { key: 'userKeyA' };
let bucket = evaluate.bucketUser(user, 'hashKey', 'key', 'saltyA', seed);
let bucketDifferentHashKey = evaluate.bucketUser(user, 'otherHashKey', 'key', 'saltyA', seed);
let bucketDifferentSalt = evaluate.bucketUser(user, 'hashKey', 'key', 'otherSaltyA', seed);

expect(bucketDifferentHashKey).toBeCloseTo(bucket, 7);
expect(bucketDifferentSalt).toBeCloseTo(bucket, 7);
});

it('should generate a new bucket if the seed changes', () => {
const otherSeed = 60;
var user = { key: 'userKeyA' };
var bucket = evaluate.bucketUser(user, 'hashKey', 'key', 'saltyA', otherSeed);
expect(bucket).toBeCloseTo(0.7008816, 7);
});
});
});