rendezvous-kit 0.0.0-development

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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/dist/engines/graphhopper.d.ts +14 -0
  4. package/dist/engines/graphhopper.d.ts.map +1 -0
  5. package/dist/engines/graphhopper.js +72 -0
  6. package/dist/engines/graphhopper.js.map +1 -0
  7. package/dist/engines/openrouteservice.d.ts +14 -0
  8. package/dist/engines/openrouteservice.d.ts.map +1 -0
  9. package/dist/engines/openrouteservice.js +79 -0
  10. package/dist/engines/openrouteservice.js.map +1 -0
  11. package/dist/engines/osrm.d.ts +11 -0
  12. package/dist/engines/osrm.d.ts.map +1 -0
  13. package/dist/engines/osrm.js +48 -0
  14. package/dist/engines/osrm.js.map +1 -0
  15. package/dist/engines/valhalla.d.ts +11 -0
  16. package/dist/engines/valhalla.d.ts.map +1 -0
  17. package/dist/engines/valhalla.js +72 -0
  18. package/dist/engines/valhalla.js.map +1 -0
  19. package/dist/geo.d.ts +16 -0
  20. package/dist/geo.d.ts.map +1 -0
  21. package/dist/geo.js +142 -0
  22. package/dist/geo.js.map +1 -0
  23. package/dist/index.d.ts +10 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +12 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/rendezvous.d.ts +14 -0
  28. package/dist/rendezvous.d.ts.map +1 -0
  29. package/dist/rendezvous.js +72 -0
  30. package/dist/rendezvous.js.map +1 -0
  31. package/dist/types.d.ts +73 -0
  32. package/dist/types.d.ts.map +1 -0
  33. package/dist/types.js +2 -0
  34. package/dist/types.js.map +1 -0
  35. package/dist/venues.d.ts +7 -0
  36. package/dist/venues.d.ts.map +1 -0
  37. package/dist/venues.js +74 -0
  38. package/dist/venues.js.map +1 -0
  39. package/llms-full.txt +481 -0
  40. package/llms.txt +86 -0
  41. package/package.json +76 -0
package/llms-full.txt ADDED
@@ -0,0 +1,481 @@
1
+ # rendezvous-kit — Full API Reference
2
+
3
+ > TypeScript library for finding fair meeting points for N people — isochrone intersection, venue search, and fairness scoring.
4
+
5
+ One runtime dependency: geohash-kit. Zero third-party dependencies. ESM-only.
6
+
7
+ Repository: https://github.com/TheCryptoDonkey/rendezvous-kit
8
+ Licence: MIT
9
+
10
+ ## Install
11
+
12
+ ```
13
+ npm install rendezvous-kit
14
+ ```
15
+
16
+ ## Imports
17
+
18
+ ```typescript
19
+ // Barrel (everything)
20
+ import { findRendezvous, ValhallaEngine, intersectPolygons } from 'rendezvous-kit'
21
+
22
+ // Subpath (tree-shakeable)
23
+ import { findRendezvous } from 'rendezvous-kit/rendezvous'
24
+ import { intersectPolygons, boundingBox, centroid, polygonArea } from 'rendezvous-kit/geo'
25
+ import { ValhallaEngine } from 'rendezvous-kit/engines/valhalla'
26
+ import { OpenRouteServiceEngine } from 'rendezvous-kit/engines/openrouteservice'
27
+ import { GraphHopperEngine } from 'rendezvous-kit/engines/graphhopper'
28
+ import { OsrmEngine } from 'rendezvous-kit/engines/osrm'
29
+ import { searchVenues } from 'rendezvous-kit/venues'
30
+ ```
31
+
32
+ ---
33
+
34
+ ## Types
35
+
36
+ ```typescript
37
+ /** A point with coordinates and optional label. */
38
+ interface LatLon {
39
+ lat: number
40
+ lon: number
41
+ label?: string
42
+ }
43
+
44
+ /** Standard GeoJSON polygon geometry. Coordinates are [longitude, latitude] pairs. */
45
+ interface GeoJSONPolygon {
46
+ type: 'Polygon'
47
+ coordinates: number[][][]
48
+ }
49
+
50
+ /** Transport mode for routing calculations. */
51
+ type TransportMode = 'drive' | 'cycle' | 'walk' | 'public_transit'
52
+
53
+ /** Fairness strategy for rendezvous scoring. */
54
+ type FairnessStrategy = 'min_max' | 'min_total' | 'min_variance'
55
+
56
+ /** Venue type for filtering. Custom strings are passed through to Overpass as amenity=<value>. */
57
+ type VenueType =
58
+ | 'park'
59
+ | 'cafe'
60
+ | 'restaurant'
61
+ | 'service_station'
62
+ | 'library'
63
+ | 'pub'
64
+ | 'playground'
65
+ | 'community_centre'
66
+ | string
67
+
68
+ /** Result of an isochrone computation. */
69
+ interface Isochrone {
70
+ origin: LatLon
71
+ mode: TransportMode
72
+ timeMinutes: number
73
+ polygon: GeoJSONPolygon
74
+ }
75
+
76
+ /** A single cell in a route matrix. */
77
+ interface MatrixEntry {
78
+ originIndex: number
79
+ destinationIndex: number
80
+ durationMinutes: number
81
+ distanceKm: number
82
+ }
83
+
84
+ /** Result of a route matrix computation. */
85
+ interface RouteMatrix {
86
+ origins: LatLon[]
87
+ destinations: LatLon[]
88
+ entries: MatrixEntry[]
89
+ }
90
+
91
+ /** A venue found within the rendezvous zone. */
92
+ interface Venue {
93
+ name: string
94
+ lat: number
95
+ lon: number
96
+ venueType: VenueType
97
+ osmId?: string // e.g. 'node/123456'
98
+ }
99
+
100
+ /** Options for rendezvous calculation. */
101
+ interface RendezvousOptions {
102
+ participants: LatLon[] // at least 2 required
103
+ mode: TransportMode
104
+ maxTimeMinutes: number // isochrone time limit
105
+ venueTypes: VenueType[]
106
+ fairness?: FairnessStrategy // default: 'min_max'
107
+ limit?: number // max suggestions to return, default: 5
108
+ }
109
+
110
+ /** A ranked rendezvous suggestion. */
111
+ interface RendezvousSuggestion {
112
+ venue: Venue
113
+ travelTimes: Record<string, number> // keyed by participant label or 'participant_N'
114
+ fairnessScore: number // lower is better
115
+ }
116
+
117
+ /** Engine-agnostic routing interface. Implement this to add a custom engine. */
118
+ interface RoutingEngine {
119
+ readonly name: string
120
+ computeIsochrone(origin: LatLon, mode: TransportMode, timeMinutes: number): Promise<Isochrone>
121
+ computeRouteMatrix(origins: LatLon[], destinations: LatLon[], mode: TransportMode): Promise<RouteMatrix>
122
+ }
123
+
124
+ /** Bounding box (from rendezvous-kit/geo). */
125
+ interface BBox {
126
+ minLon: number
127
+ minLat: number
128
+ maxLon: number
129
+ maxLat: number
130
+ }
131
+ ```
132
+
133
+ ---
134
+
135
+ ## rendezvous-kit/rendezvous
136
+
137
+ ### findRendezvous(engine, options)
138
+
139
+ Run the full rendezvous pipeline and return ranked venue suggestions.
140
+
141
+ **Algorithm:**
142
+ 1. Compute an isochrone polygon for each participant
143
+ 2. Intersect all isochrone polygons (Sutherland–Hodgman)
144
+ 3. Search for venues within the intersection bounding box (Overpass API)
145
+ 4. Compute a route matrix from all participants to all candidate venues
146
+ 5. Score each venue by the selected fairness strategy
147
+ 6. Sort ascending by score and return the top `limit` results
148
+
149
+ Returns an empty array if the isochrones do not overlap. Falls back to the geometric centroid if no venues are found in the intersection.
150
+
151
+ ```typescript
152
+ findRendezvous(engine: RoutingEngine, options: RendezvousOptions): Promise<RendezvousSuggestion[]>
153
+
154
+ // Throws RangeError if participants.length < 2
155
+ ```
156
+
157
+ **Example — three participants, Valhalla, minimise worst case:**
158
+
159
+ ```typescript
160
+ import { findRendezvous } from 'rendezvous-kit'
161
+ import { ValhallaEngine } from 'rendezvous-kit/engines/valhalla'
162
+
163
+ const engine = new ValhallaEngine({ baseUrl: 'http://localhost:8002' })
164
+
165
+ const suggestions = await findRendezvous(engine, {
166
+ participants: [
167
+ { lat: 51.5074, lon: -0.1278, label: 'Alice' }, // London
168
+ { lat: 51.4545, lon: -2.5879, label: 'Bob' }, // Bristol
169
+ { lat: 52.4862, lon: -1.8904, label: 'Carol' }, // Birmingham
170
+ ],
171
+ mode: 'drive',
172
+ maxTimeMinutes: 90,
173
+ venueTypes: ['cafe', 'restaurant'],
174
+ fairness: 'min_max',
175
+ limit: 5,
176
+ })
177
+
178
+ // suggestions[0] is the venue with the lowest worst-case travel time
179
+ console.log(suggestions[0].venue.name)
180
+ console.log(suggestions[0].travelTimes) // { Alice: 72.3, Bob: 81.1, Carol: 68.4 }
181
+ console.log(suggestions[0].fairnessScore) // 81.1 (max of travel times, for min_max)
182
+ ```
183
+
184
+ **Example — two participants, OpenRouteService, equalise travel:**
185
+
186
+ ```typescript
187
+ import { findRendezvous } from 'rendezvous-kit'
188
+ import { OpenRouteServiceEngine } from 'rendezvous-kit/engines/openrouteservice'
189
+
190
+ const engine = new OpenRouteServiceEngine({ apiKey: 'your-api-key' })
191
+
192
+ const suggestions = await findRendezvous(engine, {
193
+ participants: [
194
+ { lat: 48.8566, lon: 2.3522, label: 'Paris' },
195
+ { lat: 50.8503, lon: 4.3517, label: 'Brussels' },
196
+ ],
197
+ mode: 'drive',
198
+ maxTimeMinutes: 120,
199
+ venueTypes: ['restaurant'],
200
+ fairness: 'min_variance',
201
+ })
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Fairness Strategies
207
+
208
+ ### min_max (default)
209
+ Minimises the maximum travel time among all participants.
210
+
211
+ Score = `Math.max(...travelTimes)`
212
+
213
+ Best when you want to guarantee nobody has an excessively long journey. The classic minimax fairness criterion.
214
+
215
+ ### min_total
216
+ Minimises the total travel time across all participants.
217
+
218
+ Score = `sum(travelTimes)`
219
+
220
+ Best when you want the group's combined travel effort to be as low as possible. Can allow one person to travel much further than others.
221
+
222
+ ### min_variance
223
+ Minimises variance in travel times (standard deviation).
224
+
225
+ Score = `sqrt(variance(travelTimes))`
226
+
227
+ Best when you want everyone to travel roughly the same distance. Venues near the geometric centre of the group tend to score well.
228
+
229
+ ---
230
+
231
+ ## rendezvous-kit/geo
232
+
233
+ ### intersectPolygons(polygons)
234
+
235
+ Compute the intersection of N GeoJSON polygons using the Sutherland–Hodgman algorithm. Returns `null` if the intersection is empty or if any input polygon is degenerate.
236
+
237
+ ```typescript
238
+ intersectPolygons(polygons: GeoJSONPolygon[]): GeoJSONPolygon | null
239
+
240
+ // Single polygon — returned unchanged
241
+ intersectPolygons([poly]) // poly
242
+
243
+ // Two overlapping polygons
244
+ intersectPolygons([polyA, polyB]) // intersection polygon
245
+
246
+ // No overlap
247
+ intersectPolygons([polyA, polyFarAway]) // null
248
+ ```
249
+
250
+ ### boundingBox(polygon)
251
+
252
+ Compute the axis-aligned bounding box of a GeoJSON polygon.
253
+
254
+ ```typescript
255
+ boundingBox(polygon: GeoJSONPolygon): BBox
256
+
257
+ boundingBox(poly)
258
+ // { minLon: -0.15, minLat: 51.50, maxLon: -0.10, maxLat: 51.52 }
259
+ ```
260
+
261
+ ### centroid(polygon)
262
+
263
+ Compute the arithmetic centroid of the outer ring of a GeoJSON polygon.
264
+
265
+ ```typescript
266
+ centroid(polygon: GeoJSONPolygon): { lat: number; lon: number }
267
+
268
+ centroid(poly)
269
+ // { lat: 51.51, lon: -0.125 }
270
+ ```
271
+
272
+ ### polygonArea(polygon)
273
+
274
+ Compute the area of a GeoJSON polygon in square metres using the shoelace formula with local metric projection.
275
+
276
+ ```typescript
277
+ polygonArea(polygon: GeoJSONPolygon): number
278
+
279
+ polygonArea(poly) // area in m²
280
+ ```
281
+
282
+ ---
283
+
284
+ ## Engines
285
+
286
+ ### ValhallaEngine
287
+
288
+ Self-hosted [Valhalla](https://github.com/valhalla/valhalla) routing engine. Supports isochrone and route matrix. No authentication required.
289
+
290
+ ```typescript
291
+ class ValhallaEngine implements RoutingEngine {
292
+ readonly name = 'Valhalla'
293
+ constructor(config: { baseUrl: string })
294
+ }
295
+ ```
296
+
297
+ ```typescript
298
+ import { ValhallaEngine } from 'rendezvous-kit/engines/valhalla'
299
+
300
+ const engine = new ValhallaEngine({ baseUrl: 'http://localhost:8002' })
301
+ ```
302
+
303
+ Transport mode mapping: `drive → auto`, `cycle → bicycle`, `walk → pedestrian`, `public_transit → multimodal`
304
+
305
+ ### OpenRouteServiceEngine
306
+
307
+ [OpenRouteService](https://openrouteservice.org/) cloud or self-hosted. Supports isochrone and route matrix. Requires API key for the cloud service.
308
+
309
+ ```typescript
310
+ class OpenRouteServiceEngine implements RoutingEngine {
311
+ readonly name = 'OpenRouteService'
312
+ constructor(options: { apiKey: string; baseUrl?: string })
313
+ // baseUrl defaults to 'https://api.openrouteservice.org'
314
+ }
315
+ ```
316
+
317
+ ```typescript
318
+ import { OpenRouteServiceEngine } from 'rendezvous-kit/engines/openrouteservice'
319
+
320
+ // Cloud (requires free API key from openrouteservice.org)
321
+ const engine = new OpenRouteServiceEngine({ apiKey: 'your-api-key' })
322
+
323
+ // Self-hosted
324
+ const engine = new OpenRouteServiceEngine({
325
+ apiKey: 'local',
326
+ baseUrl: 'http://localhost:8080/ors',
327
+ })
328
+ ```
329
+
330
+ Note: ORS does not support `public_transit`; the engine falls back to `driving-car`.
331
+
332
+ ### GraphHopperEngine
333
+
334
+ [GraphHopper](https://www.graphhopper.com/) cloud or self-hosted. Supports isochrone and route matrix. API key is optional for self-hosted instances.
335
+
336
+ ```typescript
337
+ class GraphHopperEngine implements RoutingEngine {
338
+ readonly name = 'GraphHopper'
339
+ constructor(config: { baseUrl: string; apiKey?: string })
340
+ }
341
+ ```
342
+
343
+ ```typescript
344
+ import { GraphHopperEngine } from 'rendezvous-kit/engines/graphhopper'
345
+
346
+ // Self-hosted (no key needed)
347
+ const engine = new GraphHopperEngine({ baseUrl: 'http://localhost:8989' })
348
+
349
+ // Cloud
350
+ const engine = new GraphHopperEngine({
351
+ baseUrl: 'https://graphhopper.com/api/1',
352
+ apiKey: 'your-api-key',
353
+ })
354
+ ```
355
+
356
+ ### OsrmEngine
357
+
358
+ Self-hosted [OSRM](http://project-osrm.org/). Route matrix only — `computeIsochrone` throws an error. No authentication required.
359
+
360
+ ```typescript
361
+ class OsrmEngine implements RoutingEngine {
362
+ readonly name = 'OSRM'
363
+ constructor(config: { baseUrl: string })
364
+ // computeIsochrone() throws — use Valhalla, ORS, or GraphHopper for isochrones
365
+ }
366
+ ```
367
+
368
+ ```typescript
369
+ import { OsrmEngine } from 'rendezvous-kit/engines/osrm'
370
+
371
+ const engine = new OsrmEngine({ baseUrl: 'http://localhost:5000' })
372
+
373
+ // Use directly for matrix-only workflows
374
+ const matrix = await engine.computeRouteMatrix(origins, destinations, 'drive')
375
+ ```
376
+
377
+ ---
378
+
379
+ ## rendezvous-kit/venues
380
+
381
+ ### searchVenues(polygon, venueTypes, overpassUrl?)
382
+
383
+ Search for venues within a polygon using the [Overpass API](https://overpass-api.de/). Queries the bounding box of the polygon. Named nodes only.
384
+
385
+ ```typescript
386
+ searchVenues(
387
+ polygon: GeoJSONPolygon,
388
+ venueTypes: VenueType[],
389
+ overpassUrl?: string, // defaults to 'https://overpass-api.de/api/interpreter'
390
+ ): Promise<Venue[]>
391
+ ```
392
+
393
+ ```typescript
394
+ import { searchVenues } from 'rendezvous-kit/venues'
395
+ import { intersectPolygons } from 'rendezvous-kit/geo'
396
+
397
+ const intersection = intersectPolygons([isoA.polygon, isoB.polygon])
398
+ if (intersection) {
399
+ const venues = await searchVenues(intersection, ['cafe', 'restaurant'])
400
+ // [{ name: 'The Red Lion', lat: 51.9, lon: -1.4, venueType: 'pub', osmId: 'node/123' }, ...]
401
+ }
402
+ ```
403
+
404
+ Built-in `VenueType` to Overpass tag mapping:
405
+
406
+ | VenueType | Overpass tag |
407
+ |-----------|-------------|
408
+ | `park` | `leisure=park` |
409
+ | `cafe` | `amenity=cafe` |
410
+ | `restaurant` | `amenity=restaurant` |
411
+ | `service_station` | `amenity=fuel` |
412
+ | `library` | `amenity=library` |
413
+ | `pub` | `amenity=pub` |
414
+ | `playground` | `leisure=playground` |
415
+ | `community_centre` | `amenity=community_centre` |
416
+
417
+ Unknown strings are passed through as `amenity=<value>`.
418
+
419
+ ---
420
+
421
+ ## Implementing a Custom Engine
422
+
423
+ ```typescript
424
+ import type { RoutingEngine, LatLon, TransportMode, Isochrone, RouteMatrix } from 'rendezvous-kit'
425
+
426
+ class MyRoutingEngine implements RoutingEngine {
427
+ readonly name = 'MyEngine'
428
+
429
+ async computeIsochrone(
430
+ origin: LatLon,
431
+ mode: TransportMode,
432
+ timeMinutes: number,
433
+ ): Promise<Isochrone> {
434
+ const polygon = await myApi.getIsochrone(origin.lat, origin.lon, timeMinutes)
435
+ return { origin, mode, timeMinutes, polygon }
436
+ }
437
+
438
+ async computeRouteMatrix(
439
+ origins: LatLon[],
440
+ destinations: LatLon[],
441
+ mode: TransportMode,
442
+ ): Promise<RouteMatrix> {
443
+ const raw = await myApi.getMatrix(origins, destinations)
444
+ const entries = []
445
+ for (let oi = 0; oi < origins.length; oi++) {
446
+ for (let di = 0; di < destinations.length; di++) {
447
+ entries.push({
448
+ originIndex: oi,
449
+ destinationIndex: di,
450
+ durationMinutes: raw[oi][di].seconds / 60,
451
+ distanceKm: raw[oi][di].metres / 1000,
452
+ })
453
+ }
454
+ }
455
+ return { origins, destinations, entries }
456
+ }
457
+ }
458
+
459
+ // Use it with findRendezvous
460
+ const suggestions = await findRendezvous(new MyRoutingEngine(), options)
461
+ ```
462
+
463
+ ---
464
+
465
+ ## Engine Comparison
466
+
467
+ | Engine | Isochrone | Matrix | Auth | Notes |
468
+ |--------|:---------:|:------:|------|-------|
469
+ | Valhalla | Yes | Yes | None | Best self-hosted option; supports public transit |
470
+ | OpenRouteService | Yes | Yes | API key | Free tier available; no public transit |
471
+ | GraphHopper | Yes | Yes | Optional | API key only for cloud; optional self-hosted |
472
+ | OSRM | No | Yes | None | Fastest matrix; no isochrone support |
473
+
474
+ ---
475
+
476
+ ## Companion Library
477
+
478
+ **geohash-kit** — spatial primitives used internally by rendezvous-kit.
479
+
480
+ - Repository: https://github.com/TheCryptoDonkey/geohash-kit
481
+ - npm: geohash-kit
package/llms.txt ADDED
@@ -0,0 +1,86 @@
1
+ # rendezvous-kit
2
+
3
+ > TypeScript library for finding fair meeting points for N people — isochrone intersection, venue search, and fairness scoring.
4
+
5
+ One runtime dependency: geohash-kit. Zero third-party dependencies. ESM-only. Five subpath exports.
6
+
7
+ Repository: https://github.com/TheCryptoDonkey/rendezvous-kit
8
+
9
+ ## Install
10
+
11
+ npm install rendezvous-kit
12
+
13
+ ## Subpath Exports
14
+
15
+ ### rendezvous-kit (barrel)
16
+ Re-exports everything below.
17
+
18
+ ### rendezvous-kit/rendezvous
19
+ The main pipeline function.
20
+
21
+ - findRendezvous(engine, options) → Promise<RendezvousSuggestion[]>
22
+
23
+ ### rendezvous-kit/geo
24
+ Pure-TypeScript polygon geometry.
25
+
26
+ - intersectPolygons(polygons: GeoJSONPolygon[]) → GeoJSONPolygon | null
27
+ - boundingBox(polygon: GeoJSONPolygon) → BBox
28
+ - centroid(polygon: GeoJSONPolygon) → { lat, lon }
29
+ - polygonArea(polygon: GeoJSONPolygon) → number (square metres)
30
+
31
+ ### rendezvous-kit/engines/valhalla
32
+ - new ValhallaEngine({ baseUrl: string })
33
+
34
+ ### rendezvous-kit/engines/openrouteservice
35
+ - new OpenRouteServiceEngine({ apiKey: string, baseUrl?: string })
36
+
37
+ ### rendezvous-kit/engines/graphhopper
38
+ - new GraphHopperEngine({ baseUrl: string, apiKey?: string })
39
+
40
+ ### rendezvous-kit/engines/osrm
41
+ - new OsrmEngine({ baseUrl: string }) — matrix only, no isochrone
42
+
43
+ ### rendezvous-kit/venues
44
+ - searchVenues(polygon: GeoJSONPolygon, venueTypes: VenueType[], overpassUrl?: string) → Promise<Venue[]>
45
+
46
+ ## Key Types
47
+
48
+ - LatLon: { lat, lon, label? }
49
+ - GeoJSONPolygon: { type: 'Polygon', coordinates: number[][][] }
50
+ - TransportMode: 'drive' | 'cycle' | 'walk' | 'public_transit'
51
+ - FairnessStrategy: 'min_max' | 'min_total' | 'min_variance'
52
+ - VenueType: 'park' | 'cafe' | 'restaurant' | 'service_station' | 'library' | 'pub' | 'playground' | 'community_centre' | string
53
+ - RendezvousOptions: { participants, mode, maxTimeMinutes, venueTypes, fairness?, limit? }
54
+ - RendezvousSuggestion: { venue, travelTimes: Record<string, number>, fairnessScore }
55
+ - RoutingEngine: interface { name, computeIsochrone, computeRouteMatrix }
56
+
57
+ ## Fairness Strategies
58
+
59
+ - min_max — minimise worst-case travel time (default)
60
+ - min_total — minimise total travel time across all participants
61
+ - min_variance — equalise travel times (minimise standard deviation)
62
+
63
+ ## Quick Example
64
+
65
+ ```typescript
66
+ import { findRendezvous } from 'rendezvous-kit'
67
+ import { ValhallaEngine } from 'rendezvous-kit/engines/valhalla'
68
+
69
+ const engine = new ValhallaEngine({ baseUrl: 'http://localhost:8002' })
70
+
71
+ const suggestions = await findRendezvous(engine, {
72
+ participants: [
73
+ { lat: 51.5074, lon: -0.1278, label: 'Alice' },
74
+ { lat: 51.4545, lon: -2.5879, label: 'Bob' },
75
+ ],
76
+ mode: 'drive',
77
+ maxTimeMinutes: 60,
78
+ venueTypes: ['cafe'],
79
+ fairness: 'min_max',
80
+ limit: 3,
81
+ })
82
+ ```
83
+
84
+ ## Optional
85
+
86
+ - llms-full.txt: Full API reference with all type signatures and examples
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "rendezvous-kit",
3
+ "version": "0.0.0-development",
4
+ "type": "module",
5
+ "description": "Find fair meeting points for N people — isochrone intersection, venue search, and fairness scoring.",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./geo": {
14
+ "types": "./dist/geo.d.ts",
15
+ "default": "./dist/geo.js"
16
+ },
17
+ "./engines/*": {
18
+ "types": "./dist/engines/*.d.ts",
19
+ "default": "./dist/engines/*.js"
20
+ },
21
+ "./venues": {
22
+ "types": "./dist/venues.d.ts",
23
+ "default": "./dist/venues.js"
24
+ },
25
+ "./rendezvous": {
26
+ "types": "./dist/rendezvous.d.ts",
27
+ "default": "./dist/rendezvous.js"
28
+ }
29
+ },
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "typecheck": "tsc --noEmit",
35
+ "bench": "vitest bench"
36
+ },
37
+ "dependencies": {
38
+ "geohash-kit": "^1.1.0"
39
+ },
40
+ "devDependencies": {
41
+ "@semantic-release/changelog": "^6.0.3",
42
+ "@semantic-release/git": "^10.0.1",
43
+ "@semantic-release/github": "^12.0.6",
44
+ "@semantic-release/npm": "^13.1.4",
45
+ "semantic-release": "^25.0.3",
46
+ "typescript": "^5.7.0",
47
+ "vitest": "^3.0.0"
48
+ },
49
+ "files": [
50
+ "dist",
51
+ "LICENSE",
52
+ "llms.txt",
53
+ "llms-full.txt"
54
+ ],
55
+ "keywords": [
56
+ "rendezvous",
57
+ "meeting-point",
58
+ "isochrone",
59
+ "fairness",
60
+ "routing",
61
+ "valhalla",
62
+ "openrouteservice",
63
+ "graphhopper",
64
+ "osrm",
65
+ "geospatial",
66
+ "typescript",
67
+ "esm"
68
+ ],
69
+ "author": "TheCryptoDonkey",
70
+ "license": "MIT",
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "https://github.com/TheCryptoDonkey/rendezvous-kit.git"
74
+ },
75
+ "homepage": "https://github.com/TheCryptoDonkey/rendezvous-kit"
76
+ }