Skip to content

Commit 3803c71

Browse files
committed
feat: recompute values only when dirty
1 parent 66dc793 commit 3803c71

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

index.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ module.exports = function (opts = {}) {
2323
let cliInput = null
2424
let promptInput = {}
2525

26+
// Only recompute values when changed
27+
let isDirty = true
28+
let currentState = {}
29+
2630
// Process options
2731
for (const key of optionKeys) {
2832
let d = options[key]
@@ -60,10 +64,12 @@ module.exports = function (opts = {}) {
6064
prompt,
6165
overrides: (_overrides) => {
6266
overrides = Object.assign({}, overrides, _overrides)
67+
isDirty = true
6368
return instance
6469
},
6570
defaults: (_defaults) => {
6671
defaults = Object.assign({}, defaults, _defaults)
72+
isDirty = true
6773
return instance
6874
},
6975
values
@@ -126,6 +132,7 @@ module.exports = function (opts = {}) {
126132

127133
return (argv) => {
128134
cliInput = cli.parse(argv)
135+
isDirty = true
129136
return instance
130137
}
131138
}
@@ -234,12 +241,20 @@ module.exports = function (opts = {}) {
234241

235242
return async () => {
236243
promptInput = Object.assign(promptInput, await promptor(prompts))
244+
isDirty = true
237245
return instance
238246
}
239247
}
240248

241249
function values (_overrides) {
242-
return Object.assign({}, defaults, cliInput, promptInput, overrides, _overrides)
250+
if (isDirty) {
251+
currentState = Object.assign({}, defaults, cliInput, promptInput, overrides)
252+
isDirty = false
253+
}
254+
if (_overrides) {
255+
return Object.assign({}, currentState, _overrides)
256+
}
257+
return currentState
243258
}
244259

245260
return instance

test/index.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,41 @@ suite(pkg.name, () => {
249249

250250
await opts.prompt(['FooBar'])()
251251
})
252+
253+
test('recompute only on dirty state', async () => {
254+
const opts = opta({
255+
options: {
256+
foo: true,
257+
bar: true
258+
},
259+
promptModule: () => {
260+
return async (prompts) => {
261+
return {
262+
bar: 'bar'
263+
}
264+
}
265+
}
266+
})
267+
const obj1 = opts.values()
268+
opts.cli()(['--foo=foo'])
269+
const obj2 = opts.values()
270+
await opts.prompt()()
271+
const obj3 = opts.values()
272+
opts.overrides({ baz: 'baz' })
273+
const obj4 = opts.values()
274+
const obj5 = opts.values()
275+
276+
assert(obj1 !== obj2)
277+
assert(obj2 !== obj3)
278+
assert(obj3 !== obj4)
279+
assert(obj4 === obj5)
280+
assert.deepStrictEqual(obj5, {
281+
// yargs adds these top two
282+
$0: process.argv[1],
283+
_: [],
284+
foo: 'foo',
285+
bar: 'bar',
286+
baz: 'baz'
287+
})
288+
})
252289
})

0 commit comments

Comments
 (0)