import base64


def numpy_to_json(np_arr):
    """Encodes a numpy array to a json-serializable dict"""
    # TFJS only has types float32, int32, bool, string and complex64
    dtype_map = {
        'b': 'bool',
        'i': 'int32',
        'u': 'int32',
        'S': 'string',
        'O': 'string',
        'U': 'string',
        'c': 'complex64',
        'f': 'float32',
    }
    dtype = dtype_map[np_arr.dtype.kind]
    result = {
        'shape': list(np_arr.shape),
        'dtype': dtype,
    }
    if dtype == 'string':
        result['data'] = np_arr.flatten().tolist()
    else:
        # This is faster for JSON to parse and can represent inf/nan values
        result['dataEnc'] = base64.encodebytes(np_arr.astype(dtype).tobytes()).decode()
    return result