Skip to content

Commit 8cdfd62

Browse files
committed
fix: ensure proper cache invalidation
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent d5a7391 commit 8cdfd62

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

lib/node_modules/@stdlib/array/base/nested2views/lib/main.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
// MODULES //
2424

2525
var setNonEnumerableReadOnly = require( '@stdlib/utils/define-nonenumerable-read-only-property' );
26+
var setNonEnumerable = require( '@stdlib/utils/define-nonenumerable-property' );
2627
var setReadWriteAccessor = require( '@stdlib/utils/define-read-write-accessor' );
2728
var resolveGetter = require( '@stdlib/array/base/resolve-getter' );
2829
var accessors = require( '@stdlib/array/base/accessors' );
@@ -99,13 +100,15 @@ function nested2views( arr, fields ) {
99100
* @private
100101
* @constructor
101102
* @param {Collection} arr - nested array
103+
* @param {NonNegativeInteger} i - element index
102104
* @returns {Datum} datum instance
103105
*/
104-
function Datum( arr ) {
106+
function Datum( arr, i ) {
105107
var acc = accessors( arr ).accessors;
106-
setNonEnumerableReadOnly( this, '_arr', arr );
107-
setNonEnumerableReadOnly( this, '_get', acc[ 0 ] );
108-
setNonEnumerableReadOnly( this, '_set', acc[ 1 ] );
108+
setNonEnumerable( this, '_arr', arr );
109+
setNonEnumerable( this, '_get', acc[ 0 ] );
110+
setNonEnumerable( this, '_set', acc[ 1 ] );
111+
setNonEnumerableReadOnly( this, '_i', i );
109112
return this;
110113
}
111114

@@ -114,16 +117,37 @@ function nested2views( arr, fields ) {
114117
setReadWriteAccessor( Datum.prototype, keys[ i ], getValue( i ), setValue( i ) ); // eslint-disable-line max-len
115118
}
116119

120+
// Define a method for ensuring that cached references are up-to-date:
121+
setNonEnumerableReadOnly( Datum.prototype, '_updateCache', updateCache );
122+
117123
// Ensure that the returned array correctly serializes to JSON:
118124
setNonEnumerableReadOnly( Datum.prototype, 'toJSON', toJSON );
119125

120126
// Create a list of composite views...
121127
out = [];
122128
for ( i = 0; i < M; i++ ) {
123-
out.push( new Datum( oget( arr, i ) ) );
129+
out.push( new Datum( oget( arr, i ), i ) );
124130
}
125131
return out;
126132

133+
/**
134+
* Updates cached references, if necessary.
135+
*
136+
* @private
137+
*/
138+
function updateCache() {
139+
var acc;
140+
var ref;
141+
142+
ref = oget( arr, this._i );
143+
if ( ref !== this._arr ) {
144+
acc = accessors( ref ).accessors;
145+
this._arr = ref;
146+
this._get = acc[ 0 ];
147+
this._set = acc[ 1 ];
148+
}
149+
}
150+
127151
/**
128152
* Returns an accessor for returning the value associated with a field.
129153
*
@@ -141,6 +165,7 @@ function nested2views( arr, fields ) {
141165
* @returns {*} result
142166
*/
143167
function get() {
168+
this._updateCache();
144169
return this._get( this._arr, idx );
145170
}
146171
}
@@ -162,6 +187,7 @@ function nested2views( arr, fields ) {
162187
* @param {*} value - value to set
163188
*/
164189
function set( value ) {
190+
this._updateCache();
165191
this._set( this._arr, idx, value );
166192
}
167193
}

lib/node_modules/@stdlib/array/base/nested2views/test/test.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,65 @@ tape( 'the function returns views on the input arrays (accessors)', function tes
227227

228228
t.end();
229229
});
230+
231+
tape( 'the function supports outer array mutation (indexed)', function test( t ) {
232+
var actual;
233+
var fields;
234+
var tmp;
235+
var x;
236+
237+
fields = [ 'x', 'y' ];
238+
239+
x = [ [ 1, 2 ], [ 3, 4 ] ];
240+
241+
actual = nested2views( x, fields );
242+
243+
t.strictEqual( actual[ 0 ].x, 1, 'returns expected value' );
244+
t.strictEqual( actual[ 0 ].y, 2, 'returns expected value' );
245+
246+
t.strictEqual( actual[ 1 ].x, 3, 'returns expected value' );
247+
t.strictEqual( actual[ 1 ].y, 4, 'returns expected value' );
248+
249+
tmp = x[ 0 ];
250+
x[ 0 ] = x[ 1 ];
251+
x[ 1 ] = tmp;
252+
253+
t.strictEqual( actual[ 0 ].x, 3, 'returns expected value' );
254+
t.strictEqual( actual[ 0 ].y, 4, 'returns expected value' );
255+
256+
t.strictEqual( actual[ 1 ].x, 1, 'returns expected value' );
257+
t.strictEqual( actual[ 1 ].y, 2, 'returns expected value' );
258+
259+
t.end();
260+
});
261+
262+
tape( 'the function supports outer array mutation (accessors)', function test( t ) {
263+
var actual;
264+
var fields;
265+
var tmp;
266+
var x;
267+
268+
fields = [ 'x', 'y' ];
269+
270+
x = [ [ 1, 2 ], [ 3, 4 ] ];
271+
272+
actual = nested2views( toAccessorArray( x ), fields );
273+
274+
t.strictEqual( actual[ 0 ].x, 1, 'returns expected value' );
275+
t.strictEqual( actual[ 0 ].y, 2, 'returns expected value' );
276+
277+
t.strictEqual( actual[ 1 ].x, 3, 'returns expected value' );
278+
t.strictEqual( actual[ 1 ].y, 4, 'returns expected value' );
279+
280+
tmp = x[ 0 ];
281+
x[ 0 ] = x[ 1 ];
282+
x[ 1 ] = tmp;
283+
284+
t.strictEqual( actual[ 0 ].x, 3, 'returns expected value' );
285+
t.strictEqual( actual[ 0 ].y, 4, 'returns expected value' );
286+
287+
t.strictEqual( actual[ 1 ].x, 1, 'returns expected value' );
288+
t.strictEqual( actual[ 1 ].y, 2, 'returns expected value' );
289+
290+
t.end();
291+
});

0 commit comments

Comments
 (0)