or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-pouchdb-collate

Collation functions for PouchDB map/reduce to maintain consistent CouchDB collation ordering

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/pouchdb-collate@7.0.x

To install, run

npx @tessl/cli install tessl/npm-pouchdb-collate@7.0.0

0

# PouchDB Collate

1

2

PouchDB Collate provides collation functions for PouchDB map/reduce operations to maintain consistent CouchDB collation ordering. It offers four key functions for converting objects to serialized strings that maintain proper sort order, parsing those strings back to objects, comparing objects with proper ordering semantics, and normalizing objects to match CouchDB expectations.

3

4

## Package Information

5

6

- **Package Name**: pouchdb-collate

7

- **Package Type**: npm

8

- **Language**: JavaScript (ES6 modules)

9

- **Installation**: `npm install pouchdb-collate`

10

11

## Core Imports

12

13

```javascript

14

import { collate, normalizeKey, toIndexableString, parseIndexableString } from "pouchdb-collate";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const { collate, normalizeKey, toIndexableString, parseIndexableString } = require("pouchdb-collate");

21

```

22

23

## Basic Usage

24

25

```javascript

26

import { collate, toIndexableString, parseIndexableString, normalizeKey } from "pouchdb-collate";

27

28

// Compare objects with proper CouchDB ordering

29

const comparison = collate("apple", "banana"); // -1 (apple < banana)

30

const sameComparison = collate([1, 2], [1, 2]); // 0 (equal)

31

32

// Convert objects to sortable strings

33

const sortableId = toIndexableString([67, true, "McDuck", "Scrooge"]);

34

// Result: '5323256.70000000000000017764\u000021\u00004McDuck\u00004Scrooge\u0000\u0000'

35

36

// Parse strings back to original objects

37

const originalData = parseIndexableString(sortableId);

38

// Result: [67, true, "McDuck", "Scrooge"]

39

40

// Normalize keys for CouchDB compatibility

41

const normalized = normalizeKey(undefined); // null

42

const dateNormalized = normalizeKey(new Date("2023-01-01")); // "2023-01-01T00:00:00.000Z"

43

```

44

45

## Capabilities

46

47

### Object Comparison

48

49

Compares two objects using CouchDB collation ordering rules.

50

51

```javascript { .api }

52

/**

53

* Compares two objects using CouchDB collation ordering

54

* @param {any} a - First object to compare

55

* @param {any} b - Second object to compare

56

* @returns {number} Number indicating comparison result (-1, 0, 1)

57

*/

58

function collate(a, b);

59

```

60

61

CouchDB collation order: null < boolean < number < string < array < object

62

63

**Usage Examples:**

64

65

```javascript

66

// Basic comparisons

67

collate(null, false); // -1 (null comes before boolean)

68

collate(42, "hello"); // -1 (number comes before string)

69

collate([1, 2], {a: 1}); // -1 (array comes before object)

70

71

// String comparison

72

collate("apple", "banana"); // -1

73

collate("banana", "apple"); // 1

74

collate("same", "same"); // 0

75

76

// Array comparison (element by element)

77

collate([1, 2, 3], [1, 2, 4]); // -1

78

collate([1, 2], [1, 2, 3]); // -1 (shorter array comes first)

79

80

// Object comparison (by keys and values)

81

collate({a: 1, b: 2}, {a: 1, b: 3}); // -1

82

collate({a: 1}, {a: 1, b: 2}); // -1 (fewer keys comes first)

83

```

84

85

### String Serialization

86

87

Converts any object to a serialized string that maintains proper CouchDB collation ordering for lexical sorting.

88

89

```javascript { .api }

90

/**

91

* Converts any object to a serialized string maintaining CouchDB collation ordering

92

* @param {any} key - Object to convert to indexable string

93

* @returns {string} String representation suitable for lexical sorting

94

*/

95

function toIndexableString(key);

96

```

97

98

**Usage Examples:**

99

100

```javascript

101

// Create sortable document IDs

102

const docId1 = toIndexableString([25, true, "Smith", "John"]);

103

const docId2 = toIndexableString([30, false, "Doe", "Jane"]);

104

105

// These strings will sort lexically in the same order as collate() would sort the original objects

106

console.log(docId1 < docId2); // true (matches collate([25, true, "Smith", "John"], [30, false, "Doe", "Jane"]) < 0)

107

108

// Handle different data types

109

toIndexableString(null); // "1\u0000"

110

toIndexableString(true); // "21\u0000"

111

toIndexableString(42); // "532342.00000000000000000000\u0000"

112

toIndexableString("hello"); // "4hello\u0000"

113

toIndexableString([1, 2]); // "5532141.00000000000000000000532242.00000000000000000000\u0000"

114

115

// For CouchDB compatibility, replace null bytes with another separator

116

const couchDbSafeId = toIndexableString([1, 2, 3]).replace(/\u0000/g, '\u0001');

117

```

118

119

### String Parsing

120

121

Reverses the toIndexableString operation, converting a serialized string back to its original structured object.

122

123

```javascript { .api }

124

/**

125

* Converts an indexable string back to its original structured object

126

* @param {string} str - Indexable string created by toIndexableString

127

* @returns {any} Original JavaScript value

128

* @throws {Error} If the string format is invalid

129

*/

130

function parseIndexableString(str);

131

```

132

133

**Usage Examples:**

134

135

```javascript

136

// Round-trip conversion

137

const originalData = [67, true, "McDuck", "Scrooge"];

138

const serialized = toIndexableString(originalData);

139

const restored = parseIndexableString(serialized);

140

console.log(restored); // [67, true, "McDuck", "Scrooge"]

141

142

// Parse different data types

143

parseIndexableString("1\u0000"); // null

144

parseIndexableString("21\u0000"); // true

145

parseIndexableString("20\u0000"); // false

146

parseIndexableString("532342.00000000000000000000\u0000"); // 42

147

148

// Error handling

149

try {

150

parseIndexableString("invalid-string");

151

} catch (error) {

152

console.error("Invalid indexable string format");

153

}

154

```

155

156

### Key Normalization

157

158

Normalizes objects to match CouchDB expectations by converting undefined to null, NaN/Infinity to null, and Date objects to JSON strings.

159

160

```javascript { .api }

161

/**

162

* Normalizes objects to match CouchDB expectations

163

* @param {any} key - Object to normalize

164

* @returns {any} Normalized version compatible with CouchDB

165

*/

166

function normalizeKey(key);

167

```

168

169

**Usage Examples:**

170

171

```javascript

172

// Handle undefined and special values

173

normalizeKey(undefined); // null

174

normalizeKey(NaN); // null

175

normalizeKey(Infinity); // null

176

normalizeKey(-Infinity); // null

177

178

// Convert dates to JSON strings

179

normalizeKey(new Date("2023-01-01")); // "2023-01-01T00:00:00.000Z"

180

181

// Recursively normalize arrays and objects

182

normalizeKey([1, undefined, new Date("2023-01-01")]);

183

// [1, null, "2023-01-01T00:00:00.000Z"]

184

185

normalizeKey({

186

name: "John",

187

birthDate: new Date("1990-01-01"),

188

score: undefined

189

});

190

// { name: "John", birthDate: "1990-01-01T00:00:00.000Z" }

191

// Note: undefined properties are omitted

192

193

// Equivalent to JSON.parse(JSON.stringify(obj)) but faster

194

const fastNormalized = normalizeKey(complexObject);

195

const jsonNormalized = JSON.parse(JSON.stringify(complexObject));

196

// Results are equivalent

197

```

198

199

## Types

200

201

```javascript { .api }

202

// All functions accept any JavaScript value including:

203

// null, undefined, boolean, number, string, Date, arrays, and objects

204

205

// Comparison functions return one of: -1, 0, 1

206

// Indexable strings are encoded strings with specific format for sorting

207

```

208

209

## Error Handling

210

211

The package throws errors in the following cases:

212

213

- `parseIndexableString()` throws an Error if given a malformed indexable string

214

- All other functions handle invalid inputs gracefully by normalizing them according to CouchDB rules

215

216

## Advanced Usage

217

218

### Creating Compound Sort Keys

219

220

```javascript

221

// Sort by age (ascending), then by gender (descending), then by name (ascending)

222

function createSortKey(person) {

223

return toIndexableString([

224

person.age,

225

!person.male, // Invert boolean for descending order

226

person.lastName,

227

person.firstName

228

]);

229

}

230

231

const people = [

232

{ age: 25, male: true, lastName: "Smith", firstName: "John" },

233

{ age: 25, male: false, lastName: "Smith", firstName: "Jane" },

234

{ age: 30, male: true, lastName: "Doe", firstName: "Bob" }

235

];

236

237

// Create sortable IDs

238

people.forEach(person => {

239

person._id = createSortKey(person);

240

});

241

242

// Now people can be sorted lexically by _id and maintain proper ordering

243

```

244

245

### Data Type Priority

246

247

Objects are sorted according to CouchDB collation rules:

248

249

1. **null** (includes undefined, NaN, Infinity, -Infinity)

250

2. **boolean** (false < true)

251

3. **number** (numeric comparison)

252

4. **string** (lexicographic comparison)

253

5. **array** (element-by-element comparison, shorter arrays first)

254

6. **object** (key-by-key comparison, fewer keys first)