bmlt-query-client 1.0.2 โ†’ 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json CHANGED
@@ -1,9 +1,7 @@
1
1
  {
2
2
  "parser": "@typescript-eslint/parser",
3
3
  "plugins": ["@typescript-eslint"],
4
- "extends": [
5
- "eslint:recommended"
6
- ],
4
+ "extends": ["eslint:recommended"],
7
5
  "env": {
8
6
  "browser": true,
9
7
  "node": true,
@@ -0,0 +1,32 @@
1
+ # Dependencies
2
+ node_modules/
3
+
4
+ # Build outputs
5
+ dist/
6
+ build/
7
+ *.d.ts
8
+
9
+ # Logs
10
+ *.log
11
+ npm-debug.log*
12
+ yarn-debug.log*
13
+ yarn-error.log*
14
+
15
+ # Coverage
16
+ coverage/
17
+
18
+ # Cache
19
+ .cache/
20
+ .parcel-cache/
21
+
22
+ # Misc
23
+ .DS_Store
24
+ .env*
25
+ .vscode/
26
+ .idea/
27
+ *.tsbuildinfo
28
+
29
+ # Package files
30
+ package-lock.json
31
+ yarn.lock
32
+ pnpm-lock.yaml
package/.prettierrc ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": true,
5
+ "printWidth": 100,
6
+ "tabWidth": 2,
7
+ "useTabs": false,
8
+ "bracketSpacing": true,
9
+ "arrowParens": "avoid",
10
+ "endOfLine": "lf",
11
+ "quoteProps": "as-needed",
12
+ "bracketSameLine": false,
13
+ "embeddedLanguageFormatting": "auto"
14
+ }
@@ -1,17 +1,20 @@
1
1
  # BMLT Query Client - Project Complete! ๐ŸŽ‰
2
2
 
3
3
  ## Overview
4
+
4
5
  A comprehensive TypeScript client for querying BMLT (Basic Meeting List Tool) servers with built-in geocoding support using Nominatim. Successfully replaces the broken `StringSearchIsAnAddress` functionality with reliable, rate-limited geocoding.
5
6
 
6
7
  ## โœ… Completed Features
7
8
 
8
9
  ### ๐Ÿš€ Core Functionality
10
+
9
11
  - **Full TypeScript Support** - Complete type definitions for all BMLT API endpoints
10
12
  - **All BMLT Endpoints** - Complete coverage of the BMLT Semantic API
11
13
  - **Fluent Query Builder** - Chainable methods for complex searches
12
14
  - **Geographic Search** - Address-to-coordinate conversion with radius search
13
15
 
14
16
  ### ๐ŸŒ Geocoding Service
17
+
15
18
  - **Nominatim Integration** - OpenStreetMap-based geocoding
16
19
  - **US Region Bias** - Defaults to US (`countryCode: 'us'`)
17
20
  - **Custom Region Support** - Country codes and viewbox restrictions
@@ -20,13 +23,16 @@ A comprehensive TypeScript client for querying BMLT (Basic Meeting List Tool) se
20
23
  - **Retry Logic** - Exponential backoff with configurable retry counts
21
24
 
22
25
  ### ๐Ÿ›ก๏ธ Error Handling
26
+
23
27
  - **Comprehensive Error Types** - Specific error classes for different failures
24
28
  - **User-Friendly Messages** - Clean error messages for end users
25
29
  - **Retry Detection** - Automatic identification of retryable vs non-retryable errors
26
30
  - **Network Resilience** - Handles timeouts, network failures, and rate limits
27
31
 
28
32
  ### ๐Ÿ“ก API Coverage
33
+
29
34
  All BMLT Semantic API endpoints:
35
+
30
36
  - `GetSearchResults` - Meeting searches with extensive filtering
31
37
  - `GetFormats` - Available meeting formats
32
38
  - `GetServiceBodies` - Service body hierarchy
@@ -38,6 +44,7 @@ All BMLT Semantic API endpoints:
38
44
  - `GetCoverageArea` - Geographic coverage
39
45
 
40
46
  ### ๐Ÿงช Testing & Examples
47
+
41
48
  - **Real NYC Demo Server** - All examples use `https://latest.aws.bmlt.app/main_server`
42
49
  - **Integration Tests** - Comprehensive test suite with real API calls
43
50
  - **Working Examples** - Complete usage examples with actual NYC data
@@ -80,14 +87,14 @@ import { BmltClient, Weekday, VenueType } from 'bmlt-query-client';
80
87
 
81
88
  // Initialize client with NYC demo server
82
89
  const client = new BmltClient({
83
- rootServerURL: 'https://latest.aws.bmlt.app/main_server'
90
+ rootServerURL: 'https://latest.aws.bmlt.app/main_server',
84
91
  });
85
92
 
86
93
  // Search by address with automatic geocoding
87
94
  const meetings = await client.searchMeetingsByAddress({
88
95
  address: 'Times Square, New York, NY',
89
96
  radiusMiles: 2,
90
- sortByDistance: true
97
+ sortByDistance: true,
91
98
  });
92
99
 
93
100
  // Use fluent query builder
@@ -119,11 +126,13 @@ const virtualMeetings = await new MeetingQueryBuilder(client)
119
126
  ## ๐Ÿ“‹ Next Steps
120
127
 
121
128
  ### Publishing to NPM
129
+
122
130
  1. Update author information in `package.json`
123
131
  2. Set up GitHub repository
124
132
  3. Run `npm publish` to release to NPM registry
125
133
 
126
134
  ### Optional Enhancements
135
+
127
136
  - Add caching layer for geocoding results
128
137
  - Support for additional geocoding providers
129
138
  - WebSocket support for real-time updates
@@ -152,6 +161,7 @@ npm run clean
152
161
  ## ๐Ÿ“– Documentation
153
162
 
154
163
  Complete documentation is available in `README.md` including:
164
+
155
165
  - Installation and setup instructions
156
166
  - Complete API reference
157
167
  - Working examples with NYC demo server
package/README.md CHANGED
@@ -1,48 +1,57 @@
1
1
  # BMLT Query Client
2
2
 
3
+ [![npm version](https://badge.fury.io/js/bmlt-query-client.svg)](https://badge.fury.io/js/bmlt-query-client)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js](https://img.shields.io/badge/Node.js-18.0%2B-green.svg)](https://nodejs.org/)
6
+ [![npm](https://img.shields.io/npm/v/bmlt-query-client.svg)](https://www.npmjs.com/package/bmlt-query-client)
7
+
3
8
  A modern TypeScript/JavaScript client for querying BMLT (Basic Meeting List Tool) servers with built-in geocoding support using the native fetch API.
4
9
 
10
+ ## Demo
11
+
12
+ [https://bmlt-enabled.github.io/bmlt-query-client/](https://bmlt-enabled.github.io/bmlt-query-client/)
13
+
5
14
  ## Features
6
15
 
7
- - ๐Ÿš€ **Zero dependencies** - Uses native fetch API instead of axios
16
+ - ๐Ÿš€ **Zero dependencies** - Uses native fetch API
8
17
  - ๐Ÿ›๏ธ **Complete BMLT API coverage** - All semantic endpoints supported
9
18
  - ๐ŸŒ **Built-in geocoding** - Uses Nominatim for address-to-coordinates conversion
10
19
  - ๐Ÿ” **Fluent query builder** - Chainable API for complex meeting searches
11
20
  - โšก **Rate limiting & retry logic** - Stable operation with automatic retries
12
21
  - ๐Ÿ“ฑ **Browser ready** - Works in all modern browsers via ES modules
13
22
  - ๐ŸŽฏ **TypeScript support** - Full type definitions included
14
- - ๐Ÿ“ฆ **Multiple formats** - ES modules, CommonJS, and browser bundles
23
+ - ๐Ÿ“ฆ **ES Module format** - Single optimized browser-compatible build
15
24
 
16
25
  ## Quick Start
17
26
 
18
- ### For Browser (ES Modules - Recommended)
27
+ ### For Browser (ES Modules)
19
28
 
20
29
  The easiest way to use the BMLT Query Client in the browser is via ES modules:
21
30
 
22
31
  ```html
23
32
  <script type="module">
24
33
  // Import directly from a CDN (when published)
25
- import { BmltClient, VenueType, QuickSearch } from 'https://unpkg.com/bmlt-query-client/dist/index.esm.js';
26
-
34
+ import { BmltClient, VenueType, QuickSearch } from 'https://cdn.aws.bmlt.app/app.js';
35
+
27
36
  // Or import from your local build
28
- // import { BmltClient, VenueType, QuickSearch } from './dist/index.esm.js';
37
+ // import { BmltClient, VenueType, QuickSearch } from './dist/app.js';
29
38
 
30
39
  // Initialize the client
31
40
  const client = new BmltClient({
32
- rootServerURL: 'https://latest.aws.bmlt.app/main_server' // NYC demo server
41
+ rootServerURL: 'https://latest.aws.bmlt.app/main_server', // NYC demo server
33
42
  });
34
43
 
35
44
  // Search for virtual meetings
36
45
  const virtualMeetings = await client.searchMeetings({
37
46
  venue_types: VenueType.VIRTUAL,
38
- page_size: 10
47
+ page_size: 10,
39
48
  });
40
49
 
41
50
  // Search meetings by address
42
51
  const nearbyMeetings = await client.searchMeetingsByAddress({
43
52
  address: 'Times Square, New York, NY',
44
53
  radiusMiles: 5,
45
- searchParams: { page_size: 10 }
54
+ searchParams: { page_size: 10 },
46
55
  });
47
56
 
48
57
  // Use the fluent query builder
@@ -63,32 +72,30 @@ npm install bmlt-query-client
63
72
  import { BmltClient, VenueType, MeetingQueryBuilder } from 'bmlt-query-client';
64
73
 
65
74
  const client = new BmltClient({
66
- rootServerURL: 'https://your-bmlt-server.org/main_server'
75
+ rootServerURL: 'https://your-bmlt-server.org/main_server',
67
76
  });
68
77
 
69
78
  // Search for meetings
70
79
  const meetings = await client.searchMeetings({
71
80
  weekdays: [1, 2, 3], // Sunday, Monday, Tuesday
72
- venue_types: VenueType.IN_PERSON
81
+ venue_types: VenueType.IN_PERSON,
73
82
  });
74
83
 
75
84
  // Use the query builder for complex searches
76
85
  const builder = new MeetingQueryBuilder(client);
77
86
  const eveningMeetings = await builder
78
- .onWeekdays(1, 2, 3, 4, 5) // Weekdays
79
- .startingAfter(17, 0) // After 5 PM
87
+ .onWeekdays(1, 2, 3, 4, 5) // Weekdays
88
+ .startingAfter(17, 0) // After 5 PM
80
89
  .inPersonOnly()
81
90
  .nearCoordinates({ latitude: 40.7589, longitude: -73.9851 }, 2) // 2 mile radius
82
91
  .execute();
83
92
  ```
84
93
 
85
- ## Bundle Sizes
94
+ ## Bundle Size
86
95
 
87
96
  The client has been optimized for minimal bundle size:
88
97
 
89
- - **ES Module**: ~55KB (15KB gzipped) - All dependencies included
90
- - **IIFE Bundle**: ~35KB (11KB gzipped) - For legacy browser support
91
- - **CommonJS/ESM (Node)**: ~31KB (8KB gzipped) - External dependencies
98
+ - **ES Module**: ~55KB (15KB gzipped) - Zero external dependencies, fully self-contained
92
99
 
93
100
  ## Browser Support
94
101
 
@@ -114,14 +121,14 @@ const formats = await client.getFormats();
114
121
  const serviceBodies = await client.getServiceBodies();
115
122
 
116
123
  // Field values
117
- const fieldValues = await client.getFieldValues({
118
- meeting_key: 'location_municipality'
124
+ const fieldValues = await client.getFieldValues({
125
+ meeting_key: 'location_municipality',
119
126
  });
120
127
 
121
128
  // Changes within date range
122
129
  const changes = await client.getChanges({
123
130
  start_date: '2023-01-01',
124
- end_date: '2023-01-31'
131
+ end_date: '2023-01-31',
125
132
  });
126
133
  ```
127
134
 
@@ -136,7 +143,7 @@ console.log(result.coordinates); // { latitude: 40.758, longitude: -73.985 }
136
143
  const meetings = await client.searchMeetingsByAddress({
137
144
  address: 'Central Park, New York',
138
145
  radiusMiles: 2,
139
- sortByDistance: true
146
+ sortByDistance: true,
140
147
  });
141
148
  ```
142
149
 
@@ -149,11 +156,11 @@ const builder = new MeetingQueryBuilder(client);
149
156
  const meetings = await builder
150
157
  .onWeekdays(Weekday.SATURDAY, Weekday.SUNDAY)
151
158
  .virtualOnly()
152
- .startingAfter(10, 0) // After 10 AM
153
- .endingBefore(20, 0) // Before 8 PM
159
+ .startingAfter(10, 0) // After 10 AM
160
+ .endingBefore(20, 0) // Before 8 PM
154
161
  .searchText('meditation')
155
162
  .sortByDistance()
156
- .paginate(20, 1) // 20 results, page 1
163
+ .paginate(20, 1) // 20 results, page 1
157
164
  .execute();
158
165
  ```
159
166
 
@@ -172,7 +179,7 @@ const weekendMeetings = await quickSearch.weekend().execute();
172
179
  const todaysVirtualMeetings = await quickSearch
173
180
  .today()
174
181
  .virtualOnly()
175
- .startingAfter(18, 0) // After 6 PM
182
+ .startingAfter(18, 0) // After 6 PM
176
183
  .execute();
177
184
  ```
178
185
 
@@ -189,12 +196,12 @@ try {
189
196
  if (error instanceof BmltQueryError) {
190
197
  console.log('Error type:', error.type);
191
198
  console.log('User message:', error.getUserMessage());
192
-
199
+
193
200
  if (error.isRetryable()) {
194
201
  // Handle retryable errors (network, timeout, rate limit)
195
202
  console.log('This error can be retried');
196
203
  }
197
-
204
+
198
205
  if (error.isType(BmltErrorType.GEOCODING_ERROR)) {
199
206
  // Handle geocoding-specific errors
200
207
  console.log('Geocoding failed');
@@ -205,8 +212,7 @@ try {
205
212
 
206
213
  ## Examples
207
214
 
208
- - **[ES Module Demo](./example-esm.html)** - Complete browser example using ES modules
209
- - **[Legacy Demo](./example.html)** - Browser example using IIFE bundle
215
+ - **[Browser Demo](./docs/index.html)** - Complete browser example using ES modules
210
216
 
211
217
  ## Development
212
218
 
@@ -217,31 +223,59 @@ npm install
217
223
  # Run tests
218
224
  npm test
219
225
 
220
- # Build all formats
221
- npm run build:all
226
+ # Build the ES module bundle
227
+ npm run build
228
+
229
+ # Clean build directory
230
+ npm run clean
222
231
 
223
- # Build individual formats
224
- npm run build # Node.js (ESM/CJS)
225
- npm run build:esm # Browser ES module
226
- npm run build:browser # Browser IIFE bundle
232
+ # Code formatting
233
+ npm run format # Format all files
234
+ npm run format:check # Check formatting
235
+
236
+ # Code quality
237
+ npm run lint # Lint code
238
+ npm run type-check # TypeScript checking
227
239
  ```
228
240
 
229
241
  ## Configuration
230
242
 
243
+ ### Runtime Configuration
244
+
245
+ You can update client settings after initialization:
246
+
247
+ ```javascript
248
+ // Update user agent for all requests
249
+ client.setUserAgent('my-updated-app/2.0.0');
250
+ console.log(client.getUserAgent()); // 'my-updated-app/2.0.0'
251
+
252
+ // Update request timeout
253
+ client.setTimeout(60000); // 60 seconds
254
+ console.log(client.getTimeout()); // 60000
255
+
256
+ // Update root server URL
257
+ client.setRootServerURL('https://new-server.org/main_server');
258
+ console.log(client.getRootServerURL());
259
+
260
+ // Update default data format
261
+ client.setDefaultFormat(BmltDataFormat.JSONP);
262
+ console.log(client.getDefaultFormat());
263
+ ```
264
+
231
265
  ### Client Options
232
266
 
233
267
  ```javascript
234
268
  const client = new BmltClient({
235
269
  rootServerURL: 'https://your-server.org/main_server', // Required
236
- defaultFormat: BmltDataFormat.JSON, // Optional
237
- timeout: 30000, // 30 seconds
238
- userAgent: 'my-app/1.0.0', // Custom user agent
239
- enableGeocoding: true, // Enable address search
270
+ defaultFormat: BmltDataFormat.JSON, // Optional
271
+ timeout: 30000, // 30 seconds
272
+ userAgent: 'my-app/1.0.0', // Custom user agent
273
+ enableGeocoding: true, // Enable address search
240
274
  geocodingOptions: {
241
- countryCode: 'us', // Bias results to US
242
- retryCount: 3, // Retry failed requests
243
- timeout: 10000 // Geocoding timeout
244
- }
275
+ countryCode: 'us', // Bias results to US
276
+ retryCount: 3, // Retry failed requests
277
+ timeout: 10000, // Geocoding timeout
278
+ },
245
279
  });
246
280
  ```
247
281
 
@@ -251,15 +285,15 @@ const client = new BmltClient({
251
285
  const client = new BmltClient({
252
286
  rootServerURL: 'https://your-server.org/main_server',
253
287
  geocodingOptions: {
254
- countryCode: 'us', // ISO country code bias
288
+ countryCode: 'us', // ISO country code bias
255
289
  viewbox: [-74.2, 40.4, -73.7, 40.9], // Geographic bounding box [w,s,e,n]
256
- bounded: true, // Restrict to viewbox
257
- retryCount: 3, // Request retry attempts
258
- timeout: 10000, // Request timeout (ms)
259
- intervalCap: 1, // Rate limit: requests per interval
260
- interval: 1000, // Rate limit interval (ms)
261
- concurrency: 1 // Max concurrent requests
262
- }
290
+ bounded: true, // Restrict to viewbox
291
+ retryCount: 3, // Request retry attempts
292
+ timeout: 10000, // Request timeout (ms)
293
+ intervalCap: 1, // Rate limit: requests per interval
294
+ interval: 1000, // Rate limit interval (ms)
295
+ concurrency: 1, // Max concurrent requests
296
+ },
263
297
  });
264
298
  ```
265
299
 
package/dist/app.d.ts CHANGED
@@ -97,6 +97,22 @@ export declare class BmltClient {
97
97
  * Clear the geocoding queue
98
98
  */
99
99
  clearGeocodingQueue(): void;
100
+ /**
101
+ * Get the current user agent string
102
+ */
103
+ getUserAgent(): string;
104
+ /**
105
+ * Set the user agent string for HTTP requests
106
+ */
107
+ setUserAgent(userAgent: string): void;
108
+ /**
109
+ * Get the current timeout setting
110
+ */
111
+ getTimeout(): number;
112
+ /**
113
+ * Set the timeout for HTTP requests
114
+ */
115
+ setTimeout(timeout: number): void;
100
116
  }
101
117
 
102
118
  export declare interface BmltClientOptions {
@@ -448,6 +464,14 @@ export declare class GeocodingService {
448
464
  * Set concurrency limit
449
465
  */
450
466
  setConcurrency(concurrency: number): void;
467
+ /**
468
+ * Get the current user agent string
469
+ */
470
+ getUserAgent(): string;
471
+ /**
472
+ * Set the user agent string for geocoding requests
473
+ */
474
+ setUserAgent(userAgent: string): void;
451
475
  }
452
476
 
453
477
  export declare interface GeographicSearchParams {
@@ -512,6 +536,8 @@ export declare interface Meeting {
512
536
  location_postal_code_1?: string;
513
537
  /** Location province/state */
514
538
  location_province?: string;
539
+ /** Location sub province/county */
540
+ location_sub_province?: string;
515
541
  /** Location nation */
516
542
  location_nation?: string;
517
543
  /** Latitude */
@@ -524,10 +550,10 @@ export declare interface Meeting {
524
550
  email_contact?: string;
525
551
  /** World Committee Code */
526
552
  worldid_mixed?: string;
527
- /** Shared group ID */
528
- shared_group_id_bigint?: string;
529
553
  /** Service body ID */
530
554
  service_body_bigint: string;
555
+ /** Service body Name */
556
+ service_body_name?: string;
531
557
  /** Meeting formats (comma-separated format IDs) */
532
558
  format_shared_id_list?: string;
533
559
  /** Meeting comments */