bmlt-query-client 1.0.2 โ 1.0.3
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 +1 -3
- package/.prettierignore +32 -0
- package/.prettierrc +14 -0
- package/PROJECT_SUMMARY.md +12 -2
- package/README.md +85 -51
- package/dist/app.d.ts +24 -0
- package/dist/app.js +113 -69
- package/dist/app.js.map +1 -1
- package/eslint.config.mjs +42 -0
- package/package.json +11 -5
- package/vite.config.ts +6 -6
- package/README.old.md +0 -490
package/.eslintrc.json
CHANGED
package/.prettierignore
ADDED
|
@@ -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
|
+
}
|
package/PROJECT_SUMMARY.md
CHANGED
|
@@ -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
|
+
[](https://badge.fury.io/js/bmlt-query-client)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
[](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
|
|
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
|
-
- ๐ฆ **
|
|
23
|
+
- ๐ฆ **ES Module format** - Single optimized browser-compatible build
|
|
15
24
|
|
|
16
25
|
## Quick Start
|
|
17
26
|
|
|
18
|
-
### For Browser (ES Modules
|
|
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://
|
|
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/
|
|
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'
|
|
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)
|
|
79
|
-
.startingAfter(17, 0)
|
|
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
|
|
94
|
+
## Bundle Size
|
|
86
95
|
|
|
87
96
|
The client has been optimized for minimal bundle size:
|
|
88
97
|
|
|
89
|
-
- **ES Module**: ~55KB (15KB gzipped) -
|
|
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)
|
|
153
|
-
.endingBefore(20, 0)
|
|
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)
|
|
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)
|
|
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
|
-
- **[
|
|
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
|
|
221
|
-
npm run build
|
|
226
|
+
# Build the ES module bundle
|
|
227
|
+
npm run build
|
|
228
|
+
|
|
229
|
+
# Clean build directory
|
|
230
|
+
npm run clean
|
|
222
231
|
|
|
223
|
-
#
|
|
224
|
-
npm run
|
|
225
|
-
npm run
|
|
226
|
-
|
|
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,
|
|
237
|
-
timeout: 30000,
|
|
238
|
-
userAgent: 'my-app/1.0.0',
|
|
239
|
-
enableGeocoding: true,
|
|
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',
|
|
242
|
-
retryCount: 3,
|
|
243
|
-
timeout: 10000
|
|
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',
|
|
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,
|
|
257
|
-
retryCount: 3,
|
|
258
|
-
timeout: 10000,
|
|
259
|
-
intervalCap: 1,
|
|
260
|
-
interval: 1000,
|
|
261
|
-
concurrency: 1
|
|
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 {
|