@jsm-mit/map-routes-replicated-shards-package
v0.4.0
Published
The package of map-routes: the fastest route by car through 2–5 points, with the line of each leg, from a replicated-shards group of IC canisters (a coordinator and worker copies) that hold OpenStreetMap road graphs.
Readme
@jsm-mit/map-routes-replicated-shards-package
The package of map-routes: the fastest route by car through 2–5 points, with the line of each
leg, from a group of Internet Computer canisters (replicated shards): a coordinator and copies
of workers, each holding an OpenStreetMap road graph of one area (© OpenStreetMap
contributors, ODbL). Queries cost the caller nothing. It replaces the deprecated
@jsm-mit/tigi-map-package.
The group (0.2): MapRoutesClient
import { coordinatorTicketProvider, errorKeyOf, isTimeoutError, MapRoutesClient } from "@jsm-mit/map-routes-replicated-shards-package";
const map = new MapRoutesClient({
coordinatorId, // the coordinator of the group
identity: user, // the caller of the queries (a ticket names it)
ticketProvider, // where tickets come from (below)
});
const route = await map.routeAsyncUnsafe([me, pickup, destination], { line: true, timeoutMs: 5_000 });
// route.legs[i]: { meters, seconds, line? } line = encoded polyline, precision 5 (as ORS)
// route.snapMeters, route.osmDate, route.graphSha256, route.copy (the copy that answered)- The client reads the areas and their live copies from the coordinator and keeps them
ttlSeconds; it picks the area that holds every point. - A ticket (
replicated-shards.md) names the user, the area, a bbox, a time and one copy. The client keeps it per area, asks for the next one in the background in the last quarter of its life, and at once (with one retry of the call) when the worker refuses it (TicketExpired,TicketInvalid,TicketMissing,OutsideBbox). - Ticket providers:
- a system registered at the coordinator signs
issueTicketitself at the ticket core of the user (the coordinator names it,issuerFor):coordinatorTicketProvider({ coordinatorId, system: identity, user })(often the user is the system itself); - a front asks its own backend canister (a registered system), which asks the coordinator
for the front's user:
ticketProvider: (request) => backend.mapTicket(request).
- a system registered at the coordinator signs
- Without a provider the client draws a live copy and sends no ticket — only while the copies do not require tickets.
- A copy that does not answer: the list is read again and the call is tried once more.
Errors: CanisterError with errorKeyOf(error) = OutsideArea (no area holds every point,
or a point farther than 1 km from a road), NoRoute, NotReady (no live copy, no graph),
InvalidData, the ticket refusals above (after the renewal), and the refusals of the provider:
Blocked (the user — a clear reason; show it), RateLimited, Waiting, NotAuthorized.
Timeout (isTimeoutError; renewals and retries count) and CriticalCanisterError
(transport; also a system the coordinator does not know).
Without a ticket
MapRoutesClient without ticketProvider asks a live copy without a ticket: a group with
ticketRequired off (local tests). 0.3 has no MapRoutesActor and no MAP_ROUTES_CANISTER_ID
(the single copy 6aigz is gone); before 0.3 the package was @jsm-mit/map-routes-package.
Local replica: host: "http://127.0.0.1:4943".
Scripts
npm run test-unit— no canister (the client on a fake transport).npm run test-smoke— one copy (map-routes-worker) on the LOCAL replica with the newestdata/*.tmc.npm run test-group— the group on the LOCAL replica: the coordinator, two copies of Iraq, tickets required (../scripts/check/local-coordinator-check.sh iraq, local test identitymrc-systemas the system).npm run sync-declarations—declarations/from../map-routes-worker.didand../map-routes-coordinator.did.npm run publish-public— human-run; see the script for its refusals.
