33 defineProperties , concat , getBytesCopy , getNumber , hexlify ,
44 toBeArray , toBigInt , toNumber ,
55 assert , assertArgument
6+ /*, isError*/
67} from "../../utils/index.js" ;
78
89import type { BigNumberish , BytesLike } from "../../utils/index.js" ;
@@ -19,12 +20,44 @@ const passProperties = [ "then" ];
1920
2021const _guard = { } ;
2122
23+ const resultNames : WeakMap < Result , ReadonlyArray < null | string > > = new WeakMap ( ) ;
24+
25+ function getNames ( result : Result ) : ReadonlyArray < null | string > {
26+ return resultNames . get ( result ) ! ;
27+ }
28+ function setNames ( result : Result , names : ReadonlyArray < null | string > ) : void {
29+ resultNames . set ( result , names ) ;
30+ }
31+
2232function throwError ( name : string , error : Error ) : never {
2333 const wrapped = new Error ( `deferred error during ABI decoding triggered accessing ${ name } ` ) ;
2434 ( < any > wrapped ) . error = error ;
2535 throw wrapped ;
2636}
2737
38+ function toObject ( names : ReadonlyArray < null | string > , items : Result , deep ?: boolean ) : Record < string , any > | Array < any > {
39+ if ( names . indexOf ( null ) >= 0 ) {
40+ return items . map ( ( item , index ) => {
41+ if ( item instanceof Result ) {
42+ return toObject ( getNames ( item ) , item , deep ) ;
43+ }
44+ return item ;
45+ } ) ;
46+ }
47+
48+ return ( < Array < string > > names ) . reduce ( ( accum , name , index ) => {
49+ let item = items . getValue ( name ) ;
50+ if ( ! ( name in accum ) ) {
51+ if ( deep && item instanceof Result ) {
52+ item = toObject ( getNames ( item ) , item , deep ) ;
53+ }
54+ accum [ name ] = item ;
55+ }
56+ return accum ;
57+ } , < Record < string , any > > { } ) ;
58+ }
59+
60+
2861/**
2962 * A [[Result]] is a sub-class of Array, which allows accessing any
3063 * of its values either positionally by its index or, if keys are
@@ -33,6 +66,9 @@ function throwError(name: string, error: Error): never {
3366 * @_docloc : api/abi
3467 */
3568export class Result extends Array < any > {
69+ // No longer used; but cannot be removed as it will remove the
70+ // #private field from the .d.ts which may break backwards
71+ // compatibility
3672 readonly #names: ReadonlyArray < null | string > ;
3773
3874 [ K : string | number ] : any
@@ -73,21 +109,25 @@ export class Result extends Array<any> {
73109 } , < Map < string , number > > ( new Map ( ) ) ) ;
74110
75111 // Remove any key thats not unique
76- this . #names = Object . freeze ( items . map ( ( item , index ) => {
112+ setNames ( this , Object . freeze ( items . map ( ( item , index ) => {
77113 const name = names [ index ] ;
78114 if ( name != null && nameCounts . get ( name ) === 1 ) {
79115 return name ;
80116 }
81117 return null ;
82- } ) ) ;
118+ } ) ) ) ;
119+
120+ // Dummy operations to prevent TypeScript from complaining
121+ this . #names = [ ] ;
122+ if ( this . #names == null ) { void ( this . #names) ; }
83123
84124 if ( ! wrap ) { return ; }
85125
86126 // A wrapped Result is immutable
87127 Object . freeze ( this ) ;
88128
89129 // Proxy indices and names so we can trap deferred errors
90- return new Proxy ( this , {
130+ const proxy = new Proxy ( this , {
91131 get : ( target , prop , receiver ) => {
92132 if ( typeof ( prop ) === "string" ) {
93133
@@ -127,6 +167,7 @@ export class Result extends Array<any> {
127167 return Reflect . get ( target , prop , receiver ) ;
128168 }
129169 } ) ;
170+ setNames ( proxy , getNames ( this ) ) ;
130171 }
131172
132173 /**
@@ -157,21 +198,14 @@ export class Result extends Array<any> {
157198 * any outstanding deferred errors.
158199 */
159200 toObject ( deep ?: boolean ) : Record < string , any > {
160- return this . #names. reduce ( ( accum , name , index ) => {
161- assert ( name != null , "value at index ${ index } unnamed" , "UNSUPPORTED_OPERATION" , {
201+ const names = getNames ( this ) ;
202+ return names . reduce ( ( accum , name , index ) => {
203+
204+ assert ( name != null , `value at index ${ index } unnamed` , "UNSUPPORTED_OPERATION" , {
162205 operation : "toObject()"
163206 } ) ;
164207
165- // Add values for names that don't conflict
166- if ( ! ( name in accum ) ) {
167- let child = this . getValue ( name ) ;
168- if ( deep && child instanceof Result ) {
169- child = child . toObject ( deep ) ;
170- }
171- accum [ name ] = child ;
172- }
173-
174- return accum ;
208+ return toObject ( names , this , deep ) ;
175209 } , < Record < string , any > > { } ) ;
176210 }
177211
@@ -192,10 +226,12 @@ export class Result extends Array<any> {
192226 }
193227 if ( end > this . length ) { end = this . length ; }
194228
229+ const _names = getNames ( this ) ;
230+
195231 const result : Array < any > = [ ] , names : Array < null | string > = [ ] ;
196232 for ( let i = start ; i < end ; i ++ ) {
197233 result . push ( this [ i ] ) ;
198- names . push ( this . #names [ i ] ) ;
234+ names . push ( _names [ i ] ) ;
199235 }
200236
201237 return new Result ( _guard , result , names ) ;
@@ -205,6 +241,8 @@ export class Result extends Array<any> {
205241 * @_ignore
206242 */
207243 filter ( callback : ( el : any , index : number , array : Result ) => boolean , thisArg ?: any ) : Result {
244+ const _names = getNames ( this ) ;
245+
208246 const result : Array < any > = [ ] , names : Array < null | string > = [ ] ;
209247 for ( let i = 0 ; i < this . length ; i ++ ) {
210248 const item = this [ i ] ;
@@ -214,7 +252,7 @@ export class Result extends Array<any> {
214252
215253 if ( callback . call ( thisArg , item , i , this ) ) {
216254 result . push ( item ) ;
217- names . push ( this . #names [ i ] ) ;
255+ names . push ( _names [ i ] ) ;
218256 }
219257 }
220258
@@ -248,7 +286,7 @@ export class Result extends Array<any> {
248286 * accessible by name.
249287 */
250288 getValue ( name : string ) : any {
251- const index = this . #names . indexOf ( name ) ;
289+ const index = getNames ( this ) . indexOf ( name ) ;
252290 if ( index === - 1 ) { return undefined ; }
253291
254292 const value = this [ index ] ;
0 commit comments