0
# Instance API
1
2
The OboeInstance provides an event-driven API for listening to JSON parsing events, including pattern-based node matching, lifecycle events, and error handling. All methods return the instance for method chaining.
3
4
## Capabilities
5
6
### Event Listener Methods
7
8
#### Standard Event Listeners
9
10
Add and remove event listeners using EventEmitter-style methods.
11
12
```javascript { .api }
13
/**
14
* Add event listener
15
* @param {string} event - Event name
16
* @param {Function} callback - Event handler function
17
* @returns {OboeInstance} The instance for chaining
18
*/
19
on(event: string, callback: Function): OboeInstance;
20
21
/**
22
* Add event listener (alias for on)
23
* @param {string} event - Event name
24
* @param {Function} callback - Event handler function
25
* @returns {OboeInstance} The instance for chaining
26
*/
27
addListener(event: string, callback: Function): OboeInstance;
28
29
/**
30
* Remove event listener
31
* @param {string} event - Event name
32
* @param {Function} callback - Event handler function to remove
33
* @returns {OboeInstance} The instance for chaining
34
*/
35
removeListener(event: string, callback?: Function): OboeInstance;
36
37
/**
38
* Manually emit events
39
* @param {string} event - Event to emit
40
* @param {...any} args - Arguments to pass to listeners
41
*/
42
emit(event: string, ...args: any[]): void;
43
```
44
45
**Standard Events:**
46
- `'start'` - HTTP request has started
47
- `'done'` - JSON parsing completed successfully
48
- `'fail'` - Error occurred during request or parsing
49
- `'node:pattern'` - Node matching pattern found
50
- `'path:pattern'` - Path matching pattern found
51
52
**Usage Examples:**
53
54
```javascript
55
const request = oboe('https://api.example.com/data.json');
56
57
// Standard event listeners
58
request
59
.on('start', function(statusCode, headers) {
60
console.log('Request started:', statusCode);
61
})
62
.on('done', function(json) {
63
console.log('Parsing complete:', json);
64
})
65
.on('fail', function(error) {
66
console.error('Failed:', error);
67
});
68
69
// Fully-qualified pattern events
70
request.on('node:!.users.*', function(user, path, ancestors) {
71
console.log('User found:', user);
72
});
73
74
// Remove specific listener
75
const userHandler = function(user) { console.log(user); };
76
request.on('node:!.users.*', userHandler);
77
request.removeListener('node:!.users.*', userHandler);
78
```
79
80
### Pattern Matching Methods
81
82
#### Node Pattern Matching
83
84
Listen for JSON nodes that match specific JSONPath patterns.
85
86
```javascript { .api }
87
/**
88
* Listen for nodes matching JSONPath pattern
89
* @param {string|object} pattern - JSONPath pattern or pattern map
90
* @param {NodeCallback} callback - Called when pattern matches (optional if using pattern map)
91
* @returns {OboeInstance} The instance for chaining
92
*/
93
node(pattern: string | PatternMap, callback?: NodeCallback): OboeInstance;
94
95
type NodeCallback = (node: any, path: string[], ancestors: any[]) => void;
96
97
interface PatternMap {
98
[pattern: string]: NodeCallback;
99
}
100
```
101
102
**Usage Examples:**
103
104
```javascript
105
// Single pattern with callback
106
oboe('https://api.example.com/users.json')
107
.node('!.users.*', function(user, path, ancestors) {
108
console.log('User:', user);
109
console.log('Path:', path); // ['users', '0'], ['users', '1'], etc.
110
console.log('Ancestors:', ancestors); // [rootObject, usersArray]
111
});
112
113
// Multiple patterns using pattern map
114
oboe('https://api.example.com/data.json')
115
.node({
116
'!.users.*': function(user) {
117
console.log('User found:', user.name);
118
},
119
'!.posts.*': function(post) {
120
console.log('Post found:', post.title);
121
},
122
'!.comments.*': function(comment) {
123
console.log('Comment found:', comment.text);
124
}
125
});
126
127
// Pattern with field selection
128
oboe('https://api.example.com/users.json')
129
.node('!.users.*{name email}', function(user) {
130
// Only name and email fields are included
131
console.log(user); // { name: "John", email: "john@example.com" }
132
});
133
```
134
135
#### Path Pattern Matching
136
137
Listen for JSON paths that match specific JSONPath patterns.
138
139
```javascript { .api }
140
/**
141
* Listen for paths matching JSONPath pattern
142
* @param {string|object} pattern - JSONPath pattern or pattern map
143
* @param {PathCallback} callback - Called when pattern matches (optional if using pattern map)
144
* @returns {OboeInstance} The instance for chaining
145
*/
146
path(pattern: string | PatternMap, callback?: PathCallback): OboeInstance;
147
148
type PathCallback = (path: string[], ancestors: any[]) => void;
149
```
150
151
**Usage Examples:**
152
153
```javascript
154
// Listen for array paths
155
oboe('https://api.example.com/data.json')
156
.path('!.items', function(path, ancestors) {
157
console.log('Found items array at path:', path); // ['items']
158
console.log('Root object:', ancestors[0]);
159
});
160
161
// Multiple path patterns
162
oboe('https://api.example.com/nested.json')
163
.path({
164
'!.data': function(path) {
165
console.log('Data section found');
166
},
167
'!.data.users': function(path) {
168
console.log('Users array found');
169
},
170
'!.data.users.*': function(path) {
171
console.log('User path:', path); // ['data', 'users', '0'], etc.
172
}
173
});
174
```
175
176
### Lifecycle Event Methods
177
178
#### Start Event
179
180
Listen for HTTP request initiation.
181
182
```javascript { .api }
183
/**
184
* Listen for HTTP request start
185
* @param {StartCallback} callback - Called when request starts
186
* @returns {OboeInstance} The instance for chaining
187
*/
188
start(callback: StartCallback): OboeInstance;
189
190
type StartCallback = (statusCode: number, headers: Record<string, string>) => void;
191
```
192
193
**Usage Example:**
194
195
```javascript
196
oboe('https://api.example.com/data.json')
197
.start(function(statusCode, headers) {
198
console.log('Request started with status:', statusCode);
199
console.log('Content-Type:', headers['content-type']);
200
console.log('Content-Length:', headers['content-length']);
201
});
202
```
203
204
#### Done Event
205
206
Listen for successful completion of JSON parsing.
207
208
```javascript { .api }
209
/**
210
* Listen for parsing completion
211
* @param {DoneCallback} callback - Called when parsing completes successfully
212
* @returns {OboeInstance} The instance for chaining
213
*/
214
done(callback: DoneCallback): OboeInstance;
215
216
type DoneCallback = (json: any) => void;
217
```
218
219
**Usage Example:**
220
221
```javascript
222
oboe('https://api.example.com/data.json')
223
.done(function(completeJson) {
224
console.log('Parsing complete. Full JSON:', completeJson);
225
console.log('Total items:', completeJson.items.length);
226
});
227
```
228
229
#### Fail Event
230
231
Listen for errors during request or parsing.
232
233
```javascript { .api }
234
/**
235
* Listen for errors
236
* @param {FailCallback} callback - Called when errors occur
237
* @returns {OboeInstance} The instance for chaining
238
*/
239
fail(callback: FailCallback): OboeInstance;
240
241
type FailCallback = (error: OboeError) => void;
242
243
interface OboeError {
244
/** Original thrown error (if applicable) */
245
thrown?: Error;
246
/** HTTP status code (if HTTP error) */
247
statusCode?: number;
248
/** Response body (if available) */
249
body?: string;
250
/** Parsed JSON response body (if applicable) */
251
jsonBody?: any;
252
}
253
```
254
255
**Usage Example:**
256
257
```javascript
258
oboe('https://api.example.com/data.json')
259
.fail(function(error) {
260
if (error.statusCode) {
261
console.error('HTTP Error:', error.statusCode);
262
console.error('Response:', error.body);
263
} else if (error.thrown) {
264
console.error('Parsing Error:', error.thrown.message);
265
} else {
266
console.error('Unknown Error:', error);
267
}
268
});
269
```
270
271
### Control Methods
272
273
#### Abort Request
274
275
Cancel the HTTP request and stop JSON parsing.
276
277
```javascript { .api }
278
/**
279
* Abort the HTTP request and JSON parsing
280
*/
281
abort(): void;
282
```
283
284
**Usage Example:**
285
286
```javascript
287
const request = oboe('https://api.example.com/large-data.json');
288
289
// Abort after 5 seconds
290
setTimeout(function() {
291
request.abort();
292
console.log('Request aborted');
293
}, 5000);
294
```
295
296
#### Forget Callback
297
298
Available within callbacks to unregister the current callback. Only callable from within node/path callbacks.
299
300
```javascript { .api }
301
/**
302
* Unregister the current callback (only available within callbacks)
303
*/
304
forget(): void;
305
```
306
307
**Usage Example:**
308
309
```javascript
310
oboe('https://api.example.com/stream.json')
311
.node('!.items.*', function(item) {
312
console.log('Processing item:', item.id);
313
314
if (item.id === 'stop-processing') {
315
this.forget(); // Stop receiving more items
316
console.log('Stopped processing items');
317
}
318
});
319
```
320
321
### Access Methods
322
323
#### Header Access
324
325
Access HTTP response headers once the request has started.
326
327
```javascript { .api }
328
/**
329
* Access HTTP response headers
330
* @param {string} name - Optional specific header name
331
* @returns {any} Header value (if name provided) or headers object (if no name)
332
*/
333
header(name?: string): any;
334
```
335
336
**Usage Examples:**
337
338
```javascript
339
const request = oboe('https://api.example.com/data.json');
340
341
request.start(function() {
342
// Get all headers
343
const headers = request.header();
344
console.log('All headers:', headers);
345
346
// Get specific header
347
const contentType = request.header('content-type');
348
console.log('Content-Type:', contentType);
349
350
// Case-insensitive header access
351
const length = request.header('Content-Length');
352
console.log('Content Length:', length);
353
});
354
```
355
356
#### Root Access
357
358
Access the root JSON object once parsing is complete.
359
360
```javascript { .api }
361
/**
362
* Access the root JSON object
363
* @returns {any} The complete parsed JSON object (undefined until parsing completes)
364
*/
365
root(): any;
366
```
367
368
**Usage Example:**
369
370
```javascript
371
const request = oboe('https://api.example.com/data.json');
372
373
request.done(function() {
374
const rootObject = request.root();
375
console.log('Root object:', rootObject);
376
console.log('Total users:', rootObject.users.length);
377
});
378
```
379
380
#### Source Access
381
382
Access the URL or source identifier for this oboe instance.
383
384
```javascript { .api }
385
/**
386
* The URL or source identifier for this instance
387
*/
388
source: string;
389
```
390
391
**Usage Example:**
392
393
```javascript
394
const request = oboe('https://api.example.com/data.json');
395
396
console.log('Requesting:', request.source);
397
// Output: "Requesting: https://api.example.com/data.json"
398
399
// Available in callbacks too
400
request.done(function() {
401
console.log('Completed request to:', this.source);
402
});
403
```
404
405
## Method Chaining
406
407
All methods except `abort()`, `emit()`, `header()`, `root()`, and `source` return the instance for fluent chaining:
408
409
```javascript
410
oboe('https://api.example.com/data.json')
411
.start(logStart)
412
.node('!.users.*', processUser)
413
.node('!.posts.*', processPost)
414
.path('!.metadata', processMetadata)
415
.done(handleComplete)
416
.fail(handleError);
417
```
418
419
## Callback Context
420
421
Within all callbacks, `this` refers to the oboe instance, providing access to all instance methods and properties:
422
423
```javascript
424
oboe('https://api.example.com/data.json')
425
.node('!.users.*', function(user) {
426
console.log('Processing user from:', this.source);
427
428
if (user.premium) {
429
// Access other methods via 'this'
430
this.node('!.premium-features.*', handlePremiumFeature);
431
}
432
});
433
```