@superrouteca/smap 1.1.6 → 1.1.7
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/CHANGELOG.md +9 -0
- package/README.md +10 -0
- package/dist/SOURCE.json +7 -7
- package/dist/smap-client.cjs +2 -2
- package/dist/smap-client.js +2 -2
- package/dist/smap-client.mjs +2 -2
- package/dist/smap.cjs +186 -37
- package/dist/smap.js +185 -36
- package/dist/smap.mjs +186 -37
- package/package.json +1 -1
- package/types/smap.d.cts +24 -1
- package/types/smap.d.mts +24 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.7 — 2026-10-28
|
|
4
|
+
|
|
5
|
+
- Plan editor: faster edits through sMap's fast path, with no code change. When your plan editor token answer names a
|
|
6
|
+
fast path, or your map key's configuration on sMap does, every edit goes there and falls back to the Open Platform
|
|
7
|
+
by itself when the fast path asks for it, fails, or does not answer within 2 seconds (5 seconds for a refine). Quota
|
|
8
|
+
and rate-limit refusals stay final. The editor's state and `change` events say which path answered (`path`);
|
|
9
|
+
`fastPath: false` keeps every edit on the Open Platform, and `smapUrl` names the sMap service a map key's
|
|
10
|
+
configuration is read from (the map's own with `map.planEditor`).
|
|
11
|
+
|
|
3
12
|
## 1.1.6 — 2026-10-28
|
|
4
13
|
|
|
5
14
|
- Plan editor: `map.planEditor` lets a person edit a plan of routes on the map — drag a stop within its route or onto
|
package/README.md
CHANGED
|
@@ -322,6 +322,16 @@ editor.destroy();
|
|
|
322
322
|
`plan_editing_off`, `key_off`, `plan_routes_only`). A map key needs *Allow plan editing* switched on and the page's
|
|
323
323
|
origin on its allowlist. In an app shell (macOS, Windows) pass `app: 'apple:<bundle id>'` or `'windows:<id>'`: it
|
|
324
324
|
is sent as `X-SMap-App`.
|
|
325
|
+
- **Fast path** (no code change): when the plan editor token answer carries `fast_path.url`, or the map key's
|
|
326
|
+
configuration on sMap names one (`GET <smapUrl>/plan/v1/config`, read once and kept 10 minutes; `smapUrl` is the
|
|
327
|
+
map's own sMap service with `map.planEditor`, `https://tile.srsr.ca` otherwise), every call goes there
|
|
328
|
+
(`<url>/<same path>`, with the same credential, headers and body) instead of `<baseUrl>/v1/plan/…`. A
|
|
329
|
+
`409 USE_STANDARD_PATH` (or `X-Plan-Path: standard`), any 5xx, a network error or no answer within 2 seconds
|
|
330
|
+
(`fastPathTimeout`; 5 seconds for refine, `fastPathRefineTimeout`) repeats the same call once on the standard path; the next call tries the fast path again.
|
|
331
|
+
`402`, `429` and every other 4xx are final, as on the standard path. A renewed token follows its own answer (the
|
|
332
|
+
fast path may appear or go). `state().path` and the `change` event's `path` say where the last answer came from
|
|
333
|
+
(`'fast'` or `'standard'`); `fastPath: false` keeps every call on the standard path. The snapshot works on both
|
|
334
|
+
paths with the same id.
|
|
325
335
|
- **Distance snapshot**: the editor opens one (`POST /v1/plan/matrix`) and names it in every call, so legs measured
|
|
326
336
|
once are not measured again. When an answer says the snapshot expired (`X-Plan-Matrix: expired`, or a `410`), it
|
|
327
337
|
opens a new one and carries on; a snapshot that cannot be opened never stops an edit. `destroy()` closes it.
|
package/dist/SOURCE.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sdkVersion": "1.1.
|
|
2
|
+
"sdkVersion": "1.1.7",
|
|
3
3
|
"engine": "maplibre-gl 6.16.0",
|
|
4
4
|
"files": {
|
|
5
|
-
"smap.js": "
|
|
5
|
+
"smap.js": "1e7ba1266c67f860e74a2956521d55f49ea5771e0b1cfa832014433ea0554d25",
|
|
6
6
|
"smap.css": "d82adcd1b8e2b5d1a6ebe0ee648bc24eb84471bc956e3c8ac3cc7dc1f447d96f",
|
|
7
|
-
"smap-client.js": "
|
|
7
|
+
"smap-client.js": "f845c1d52a6f13bfb7f85cf8690e70320b09278b203b9e6a2cc874eed734eb10",
|
|
8
8
|
"smap-client.d.ts": "5f0df11bf60c5a9ced34522a284de81260c27871678ab772f16da9ccf6883f58",
|
|
9
|
-
"smap.mjs": "
|
|
10
|
-
"smap.cjs": "
|
|
11
|
-
"smap-client.cjs": "
|
|
12
|
-
"smap-client.mjs": "
|
|
9
|
+
"smap.mjs": "ff3859691bfaf62d672ec6991eeda530be3316b22413d85c09a4adb7e11529cb",
|
|
10
|
+
"smap.cjs": "74c72a1504a0023d1b3d2613aac1527bc20676a7002c909715e60f798182b5c8",
|
|
11
|
+
"smap-client.cjs": "c1d143a0a9ac8a4cf1abdc7c2c82aec0d063bc51188e3eeb572dc48497475ef3",
|
|
12
|
+
"smap-client.mjs": "69d3e44f0d3fd39c3edbd8be6e66d4ddb625795f356a583dfeea610025cb7bd5",
|
|
13
13
|
"smap-client.d.cts": "e0fe4eb54cd66b831116082f42bd2f7de260f9f12a2741f4004f8cf10c252116",
|
|
14
14
|
"smap-client.d.mts": "96830d316ddb33b4ff8edb8b6f810337479636114f75c4170d95038ffda74103",
|
|
15
15
|
"vendor-licenses.txt": "ee5fc05a0677eaf69601d2c7db0d9ecd6cc27c3abc1d0733bc9ed34707cf8ef2"
|
package/dist/smap-client.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* Generated by js/build.mjs from js/src (see SOURCE.json). Do not edit. */
|
|
2
|
-
/*! sMap JS client 1.1.
|
|
2
|
+
/*! sMap JS client 1.1.7 — tokens, the nearest node, styles, tiles and raw reads, without a map view. */
|
|
3
3
|
/*
|
|
4
4
|
* Runs wherever `fetch` exists: browsers, Node.js 18+, workers; elsewhere (mini programs, older runtimes) pass your
|
|
5
5
|
* own `fetch`. UMD: `window.SMapClient`, `require('smap-client')`, or an AMD module.
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}(typeof self !== 'undefined' ? self : this, function () {
|
|
20
20
|
'use strict';
|
|
21
21
|
|
|
22
|
-
var VERSION = '1.1.
|
|
22
|
+
var VERSION = '1.1.7';
|
|
23
23
|
var NODE_TTL = 3600 * 1000; // the measured order
|
|
24
24
|
var KNOWN_TTL = 30 * 86400 * 1000; // the last node list received, used when none can be read
|
|
25
25
|
|
package/dist/smap-client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! sMap JS client 1.1.
|
|
1
|
+
/*! sMap JS client 1.1.7 — tokens, the nearest node, styles, tiles and raw reads, without a map view. */
|
|
2
2
|
/*
|
|
3
3
|
* Runs wherever `fetch` exists: browsers, Node.js 18+, workers; elsewhere (mini programs, older runtimes) pass your
|
|
4
4
|
* own `fetch`. UMD: `window.SMapClient`, `require('smap-client')`, or an AMD module.
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
}(typeof self !== 'undefined' ? self : this, function () {
|
|
19
19
|
'use strict';
|
|
20
20
|
|
|
21
|
-
var VERSION = '1.1.
|
|
21
|
+
var VERSION = '1.1.7';
|
|
22
22
|
var NODE_TTL = 3600 * 1000; // the measured order
|
|
23
23
|
var KNOWN_TTL = 30 * 86400 * 1000; // the last node list received, used when none can be read
|
|
24
24
|
|
package/dist/smap-client.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Generated by js/build.mjs from js/src (see SOURCE.json). Do not edit. */
|
|
2
2
|
var smapClientModule = { exports: {} };
|
|
3
3
|
(function (module, exports, define) {
|
|
4
|
-
/*! sMap JS client 1.1.
|
|
4
|
+
/*! sMap JS client 1.1.7 — tokens, the nearest node, styles, tiles and raw reads, without a map view. */
|
|
5
5
|
/*
|
|
6
6
|
* Runs wherever `fetch` exists: browsers, Node.js 18+, workers; elsewhere (mini programs, older runtimes) pass your
|
|
7
7
|
* own `fetch`. UMD: `window.SMapClient`, `require('smap-client')`, or an AMD module.
|
|
@@ -21,7 +21,7 @@ var smapClientModule = { exports: {} };
|
|
|
21
21
|
}(typeof self !== 'undefined' ? self : this, function () {
|
|
22
22
|
'use strict';
|
|
23
23
|
|
|
24
|
-
var VERSION = '1.1.
|
|
24
|
+
var VERSION = '1.1.7';
|
|
25
25
|
var NODE_TTL = 3600 * 1000; // the measured order
|
|
26
26
|
var KNOWN_TTL = 30 * 86400 * 1000; // the last node list received, used when none can be read
|
|
27
27
|
|
package/dist/smap.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Generated by js/build.mjs from js/src (see SOURCE.json). Do not edit. */
|
|
2
2
|
'use strict';
|
|
3
|
-
/*! sMap Web SDK 1.1.
|
|
3
|
+
/*! sMap Web SDK 1.1.7. Bundles maplibre-gl 6.16.0 (BSD-3-Clause), see vendor-licenses.txt. */
|
|
4
4
|
|
|
5
5
|
var smapCore = null;
|
|
6
6
|
function smapCreateEngine() {
|
|
@@ -28364,6 +28364,24 @@ function smapCreatePlan() {
|
|
|
28364
28364
|
// its Origin; a native app also names itself with X-SMap-App (and X-SMap-App-Cert on Android).
|
|
28365
28365
|
|
|
28366
28366
|
var DEFAULT_BASE = 'https://open.superroute.ca';
|
|
28367
|
+
// The sMap service a map key's configuration is read from (GET <smap>/plan/v1/config), unless the editor is told another.
|
|
28368
|
+
var DEFAULT_SMAP = 'https://tile.srsr.ca';
|
|
28369
|
+
// Fast path (OPEN-ROUTE-EDIT E19, §2f.5): a call there not answered within this long is repeated on the standard path.
|
|
28370
|
+
// Per call, in this one place: every call 2 s, except refine (its search runs up to 2 s inside sRoad, and sMap's own
|
|
28371
|
+
// refine budget is 4 s) 5 s.
|
|
28372
|
+
var FAST_PATH_TIMEOUT_MS = 2000;
|
|
28373
|
+
var FAST_PATH_REFINE_TIMEOUT_MS = 5000;
|
|
28374
|
+
/** The fast-path time limit of a call (`path` after /v1/plan), from the defaults or the options that replace them. */
|
|
28375
|
+
function fastPathTimeoutFor(path, o) {
|
|
28376
|
+
var refine = path === '/refine';
|
|
28377
|
+
var given = refine ? o.fastPathRefineTimeout : o.fastPathTimeout;
|
|
28378
|
+
if (typeof given === 'number' && given > 0) { return given; }
|
|
28379
|
+
return refine ? FAST_PATH_REFINE_TIMEOUT_MS : FAST_PATH_TIMEOUT_MS;
|
|
28380
|
+
}
|
|
28381
|
+
// A map key's configuration is kept this long; one that could not be read is asked for again after RETRY.
|
|
28382
|
+
var KEY_CONFIG_TTL_MS = 600000;
|
|
28383
|
+
var KEY_CONFIG_RETRY_MS = 60000;
|
|
28384
|
+
var PLAN_PREFIX = '/v1/plan';
|
|
28367
28385
|
// A token whose expiry can be read is renewed this many seconds before it ends.
|
|
28368
28386
|
var RENEW_BEFORE = 30;
|
|
28369
28387
|
var TOKEN_PREFIX = 'sr_pet_';
|
|
@@ -28386,19 +28404,27 @@ function smapCreatePlan() {
|
|
|
28386
28404
|
/**
|
|
28387
28405
|
* What a token provider gave: the token string, or the token answer of POST /v1/plan/token
|
|
28388
28406
|
* ({ access_token, token_type, expires_in, expires_at, scopes, origins }, or that answer's `{ data }` envelope).
|
|
28389
|
-
* Returns { token, exp } with exp in Unix seconds (0 when it cannot be told)
|
|
28407
|
+
* Returns { token, exp, fastPath } with exp in Unix seconds (0 when it cannot be told) and fastPath the answer's
|
|
28408
|
+
* `fast_path.url` (null without one: every call goes to the standard path).
|
|
28390
28409
|
*/
|
|
28391
28410
|
function readToken(t) {
|
|
28392
28411
|
if (t && typeof t === 'object' && t.data && typeof t.data === 'object' && !t.access_token) { t = t.data; }
|
|
28393
|
-
if (typeof t === 'string' && t) { return { token: t, exp: tokenExpiry(t) }; }
|
|
28412
|
+
if (typeof t === 'string' && t) { return { token: t, exp: tokenExpiry(t), fastPath: null }; }
|
|
28394
28413
|
if (t && typeof t === 'object' && typeof t.access_token === 'string' && t.access_token) {
|
|
28395
28414
|
var exp = t.expires_at ? Date.parse(t.expires_at) / 1000 : 0;
|
|
28396
28415
|
if (!exp && typeof t.expires_in === 'number') { exp = Date.now() / 1000 + t.expires_in; }
|
|
28397
|
-
return { token: t.access_token, exp: exp || tokenExpiry(t.access_token) };
|
|
28416
|
+
return { token: t.access_token, exp: exp || tokenExpiry(t.access_token), fastPath: fastPathOf(t) };
|
|
28398
28417
|
}
|
|
28399
28418
|
return null;
|
|
28400
28419
|
}
|
|
28401
28420
|
|
|
28421
|
+
/** The fast-path address of a token answer or a map key's configuration (`fast_path.url`), or null. */
|
|
28422
|
+
function fastPathOf(o) {
|
|
28423
|
+
var f = o && typeof o === 'object' ? o.fast_path : null;
|
|
28424
|
+
var url = f && typeof f === 'object' && typeof f.url === 'string' ? f.url.replace(/\/+$/, '') : '';
|
|
28425
|
+
return url ? url : null;
|
|
28426
|
+
}
|
|
28427
|
+
|
|
28402
28428
|
/** The app headers of a native app: options.app is 'android:<package>' / 'apple:<bundle id>' / 'windows:<id>', or { id, cert }. */
|
|
28403
28429
|
function appHeaders(app) {
|
|
28404
28430
|
var h = {};
|
|
@@ -28417,6 +28443,7 @@ function smapCreatePlan() {
|
|
|
28417
28443
|
if (c && typeof c.token === 'function') {
|
|
28418
28444
|
var token = null;
|
|
28419
28445
|
var exp = 0;
|
|
28446
|
+
var fast = null;
|
|
28420
28447
|
var pending = null;
|
|
28421
28448
|
var fetchToken = function () {
|
|
28422
28449
|
if (!pending) {
|
|
@@ -28426,6 +28453,7 @@ function smapCreatePlan() {
|
|
|
28426
28453
|
if (!read) { throw new Error('sMap plan editor: the token provider gave no token'); }
|
|
28427
28454
|
token = read.token;
|
|
28428
28455
|
exp = read.exp;
|
|
28456
|
+
fast = read.fastPath;
|
|
28429
28457
|
return token;
|
|
28430
28458
|
}, function (e) { pending = null; throw e; });
|
|
28431
28459
|
}
|
|
@@ -28439,6 +28467,8 @@ function smapCreatePlan() {
|
|
|
28439
28467
|
},
|
|
28440
28468
|
// After a 401 SESSION_EXPIRED: forget the token so the next call asks the provider again. True when a retry may help.
|
|
28441
28469
|
renew: function () { token = null; exp = 0; return true; },
|
|
28470
|
+
// The fast-path address the latest token answer gave (read after headers()), or null.
|
|
28471
|
+
fastPath: function () { return Promise.resolve(fast); },
|
|
28442
28472
|
};
|
|
28443
28473
|
}
|
|
28444
28474
|
if (c && typeof c.key === 'string' && c.key) {
|
|
@@ -28446,6 +28476,7 @@ function smapCreatePlan() {
|
|
|
28446
28476
|
kind: 'key',
|
|
28447
28477
|
headers: function () { return Promise.resolve({ Authorization: 'Bearer ' + c.key }); },
|
|
28448
28478
|
renew: function () { return false; },
|
|
28479
|
+
fastPath: null, // set by the transport: the key's configuration on sMap
|
|
28449
28480
|
};
|
|
28450
28481
|
}
|
|
28451
28482
|
throw new Error('sMap plan editor: credentials are { token: () => Promise<string | TokenAnswer> } or { key: string }');
|
|
@@ -28468,44 +28499,155 @@ function smapCreatePlan() {
|
|
|
28468
28499
|
function cancelled() { var e = new Error('cancelled'); e.name = 'AbortError'; e.cancelled = true; return e; }
|
|
28469
28500
|
|
|
28470
28501
|
/**
|
|
28471
|
-
* The transport: send(method, path, body, signal) resolves { status, body, data, matrix } (matrix: the
|
|
28472
|
-
* header
|
|
28473
|
-
*
|
|
28502
|
+
* The transport: send(method, path, body, signal) resolves { status, body, data, matrix, path } (matrix: the
|
|
28503
|
+
* X-Plan-Matrix header; path: 'fast' or 'standard', where the answer came from) or rejects with a PlanError. A 401
|
|
28504
|
+
* SESSION_EXPIRED with a token provider asks for a new token and repeats the call once; every other refusal
|
|
28505
|
+
* (SESSION_REVOKED, TOKEN_INVALID, 403 NOT_AUTHORIZED with its reason) is raised.
|
|
28506
|
+
*
|
|
28507
|
+
* Fast path (OPEN-ROUTE-EDIT E19, §2f.5): when the credential names a fast-path address (the token answer's
|
|
28508
|
+
* `fast_path.url`, or a map key's configuration from GET <smapUrl>/plan/v1/config), each call goes to
|
|
28509
|
+
* <url>/<same path> with the same method, credential, headers and body. A 409 USE_STANDARD_PATH (or the header
|
|
28510
|
+
* X-Plan-Path: standard), any 5xx, a network error or no answer within 2 s (refine: 5 s) repeats the same call once on the standard
|
|
28511
|
+
* path (<baseUrl>/v1/plan/<same path>); the next call tries the fast path again. 402, 429 and every other 4xx are final.
|
|
28474
28512
|
*/
|
|
28475
28513
|
function createTransport(o) {
|
|
28476
28514
|
o = o || {};
|
|
28477
28515
|
var base = String(o.baseUrl || DEFAULT_BASE).replace(/\/$/, '');
|
|
28516
|
+
var smap = String(o.smapUrl || DEFAULT_SMAP).replace(/\/$/, '');
|
|
28517
|
+
var fastOn = o.fastPath !== false;
|
|
28518
|
+
var timeoutMs = fastPathTimeoutFor('', o);
|
|
28478
28519
|
var creds = credentialsOf(o.credentials);
|
|
28479
28520
|
var app = appHeaders(o.app);
|
|
28480
28521
|
var fetchFn = o.fetch || (typeof fetch === 'function' ? function (url, init) { return fetch(url, init); } : null);
|
|
28481
28522
|
if (!fetchFn) { throw new Error('sMap plan editor: no fetch; pass options.fetch'); }
|
|
28482
28523
|
|
|
28524
|
+
function headersWith(h, json) {
|
|
28525
|
+
var headers = { Accept: 'application/json' };
|
|
28526
|
+
Object.keys(app).forEach(function (k) { headers[k] = app[k]; });
|
|
28527
|
+
Object.keys(h).forEach(function (k) { headers[k] = h[k]; });
|
|
28528
|
+
if (json) { headers['Content-Type'] = 'application/json'; }
|
|
28529
|
+
return headers;
|
|
28530
|
+
}
|
|
28531
|
+
|
|
28532
|
+
// One request, read to the end. With `limit` it gives up after that many ms ({ timedOut: true }); a network error
|
|
28533
|
+
// resolves { failed: error } unless the caller's own signal ended it (then it rejects, cancelled).
|
|
28534
|
+
function exchange(url, init, signal, limit) {
|
|
28535
|
+
if (!limit) {
|
|
28536
|
+
return fetchFn(url, init).then(read);
|
|
28537
|
+
}
|
|
28538
|
+
var inner = newController();
|
|
28539
|
+
var timedOut = false;
|
|
28540
|
+
var timer = null;
|
|
28541
|
+
var onAbort = function () { if (inner) { inner.abort(); } };
|
|
28542
|
+
if (signal) {
|
|
28543
|
+
if (signal.aborted) { return Promise.reject(cancelled()); }
|
|
28544
|
+
if (signal.addEventListener) { signal.addEventListener('abort', onAbort); }
|
|
28545
|
+
}
|
|
28546
|
+
var own = {};
|
|
28547
|
+
Object.keys(init).forEach(function (k) { own[k] = init[k]; });
|
|
28548
|
+
if (inner) { own.signal = inner.signal; }
|
|
28549
|
+
var done = function () {
|
|
28550
|
+
if (timer) { clearTimeout(timer); }
|
|
28551
|
+
if (signal && signal.removeEventListener) { signal.removeEventListener('abort', onAbort); }
|
|
28552
|
+
};
|
|
28553
|
+
var timeout = new Promise(function (resolve) {
|
|
28554
|
+
timer = setTimeout(function () { timedOut = true; if (inner) { inner.abort(); } resolve({ timedOut: true }); }, limit);
|
|
28555
|
+
});
|
|
28556
|
+
var answer = Promise.resolve().then(function () { return fetchFn(url, own); }).then(read).then(function (r) { return r; }, function (e) {
|
|
28557
|
+
if (signal && signal.aborted) { throw cancelled(); }
|
|
28558
|
+
if (timedOut) { return { timedOut: true }; }
|
|
28559
|
+
return { failed: e };
|
|
28560
|
+
});
|
|
28561
|
+
return Promise.race([answer, timeout]).then(function (r) {
|
|
28562
|
+
done();
|
|
28563
|
+
if (signal && signal.aborted) { throw cancelled(); }
|
|
28564
|
+
return r;
|
|
28565
|
+
}, function (e) { done(); throw e; });
|
|
28566
|
+
}
|
|
28567
|
+
|
|
28568
|
+
function read(res) {
|
|
28569
|
+
return res.text().then(function (text) {
|
|
28570
|
+
var json = null;
|
|
28571
|
+
try { json = text ? JSON.parse(text) : null; } catch (e) { json = null; }
|
|
28572
|
+
var get = function (k) { return res.headers && typeof res.headers.get === 'function' ? res.headers.get(k) : null; };
|
|
28573
|
+
return { status: res.status, ok: res.ok, json: json, matrix: get('X-Plan-Matrix'), planPath: get('X-Plan-Path') };
|
|
28574
|
+
});
|
|
28575
|
+
}
|
|
28576
|
+
|
|
28577
|
+
// A map key's configuration on sMap: GET <smap>/plan/v1/config -> {"fast_path": {"url"}} or {}.
|
|
28578
|
+
var keyConfig = { url: null, until: 0, pending: null };
|
|
28579
|
+
function keyFastPath(h) {
|
|
28580
|
+
if (Date.now() < keyConfig.until) { return Promise.resolve(keyConfig.url); }
|
|
28581
|
+
if (keyConfig.pending) { return keyConfig.pending; }
|
|
28582
|
+
keyConfig.pending = exchange(smap + '/plan/v1/config', { method: 'GET', headers: headersWith(h, false) }, null, timeoutMs).then(function (r) {
|
|
28583
|
+
if (r.status >= 200 && r.status < 300) {
|
|
28584
|
+
keyConfig.url = fastPathOf(r.json);
|
|
28585
|
+
keyConfig.until = Date.now() + KEY_CONFIG_TTL_MS;
|
|
28586
|
+
} else {
|
|
28587
|
+
// A refusal is an answer (no fast path for this key); a failure is asked again after a minute.
|
|
28588
|
+
keyConfig.url = null;
|
|
28589
|
+
keyConfig.until = Date.now() + (r.status >= 400 && r.status < 500 ? KEY_CONFIG_TTL_MS : KEY_CONFIG_RETRY_MS);
|
|
28590
|
+
}
|
|
28591
|
+
return keyConfig.url;
|
|
28592
|
+
}, function () {
|
|
28593
|
+
keyConfig.url = null;
|
|
28594
|
+
keyConfig.until = Date.now() + KEY_CONFIG_RETRY_MS;
|
|
28595
|
+
return null;
|
|
28596
|
+
}).then(function (url) { keyConfig.pending = null; return url; });
|
|
28597
|
+
return keyConfig.pending;
|
|
28598
|
+
}
|
|
28599
|
+
|
|
28600
|
+
function fastPathFor(h) {
|
|
28601
|
+
if (!fastOn) { return Promise.resolve(null); }
|
|
28602
|
+
return creds.fastPath ? creds.fastPath() : keyFastPath(h);
|
|
28603
|
+
}
|
|
28604
|
+
|
|
28605
|
+
// Repeat on the standard path (§2f.5)?
|
|
28606
|
+
function useStandard(r) {
|
|
28607
|
+
if (r.timedOut || r.failed) { return true; }
|
|
28608
|
+
if (r.status >= 500) { return true; }
|
|
28609
|
+
if (r.status !== 409) { return false; }
|
|
28610
|
+
return !!(r.json && r.json.error && r.json.error.code === 'USE_STANDARD_PATH') || String(r.planPath || '').toLowerCase() === 'standard';
|
|
28611
|
+
}
|
|
28612
|
+
|
|
28483
28613
|
function send(method, path, body, signal, retried) {
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
if (
|
|
28490
|
-
|
|
28491
|
-
|
|
28492
|
-
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
|
|
28499
|
-
|
|
28500
|
-
|
|
28501
|
-
|
|
28502
|
-
|
|
28503
|
-
|
|
28504
|
-
return
|
|
28614
|
+
var h = null;
|
|
28615
|
+
return creds.headers().then(function (got) {
|
|
28616
|
+
h = got;
|
|
28617
|
+
return fastPathFor(h);
|
|
28618
|
+
}).then(function (fast) {
|
|
28619
|
+
if (signal && signal.aborted) { throw cancelled(); }
|
|
28620
|
+
var init = { method: method, headers: headersWith(h, body !== undefined) };
|
|
28621
|
+
if (body !== undefined) { init.body = JSON.stringify(body); }
|
|
28622
|
+
var standard = function () {
|
|
28623
|
+
var s = {};
|
|
28624
|
+
Object.keys(init).forEach(function (k) { s[k] = init[k]; });
|
|
28625
|
+
s.headers = headersWith(h, body !== undefined);
|
|
28626
|
+
if (signal) { s.signal = signal; }
|
|
28627
|
+
return exchange(base + path, s, signal, 0).then(function (r) { r.via = 'standard'; return r; });
|
|
28628
|
+
};
|
|
28629
|
+
if (!fast || path.indexOf(PLAN_PREFIX + '/') !== 0) { return standard(); }
|
|
28630
|
+
var rest = path.slice(PLAN_PREFIX.length);
|
|
28631
|
+
return exchange(fast + rest, init, signal, fastPathTimeoutFor(rest, o)).then(function (r) {
|
|
28632
|
+
if (useStandard(r)) { return standard(); }
|
|
28633
|
+
r.via = 'fast';
|
|
28634
|
+
return r;
|
|
28505
28635
|
});
|
|
28636
|
+
}).then(function (r) {
|
|
28637
|
+
if (!r.ok) {
|
|
28638
|
+
var json = r.json;
|
|
28639
|
+
var err = (json && json.error) || {};
|
|
28640
|
+
if (r.status === 401 && err.code === 'SESSION_EXPIRED' && !retried && creds.renew()) { return send(method, path, body, signal, true); }
|
|
28641
|
+
var e = PlanError(err.message || ('HTTP ' + r.status), {
|
|
28642
|
+
status: r.status, code: err.code || null, details: err.details || null, reason: err.reason || (json && json.reason) || null, path: path,
|
|
28643
|
+
});
|
|
28644
|
+
e.via = r.via;
|
|
28645
|
+
throw e;
|
|
28646
|
+
}
|
|
28647
|
+
return { status: r.status, body: r.json, data: r.json && r.json.data, matrix: r.matrix, path: r.via };
|
|
28506
28648
|
});
|
|
28507
28649
|
}
|
|
28508
|
-
return { send: send, kind: creds.kind, baseUrl: base };
|
|
28650
|
+
return { send: send, kind: creds.kind, baseUrl: base, smapUrl: smap };
|
|
28509
28651
|
}
|
|
28510
28652
|
|
|
28511
28653
|
// ------------------------------------------------------------------ plans
|
|
@@ -28658,7 +28800,12 @@ function smapCreatePlan() {
|
|
|
28658
28800
|
* @param {Object} options
|
|
28659
28801
|
* @param {Object} options.credentials { token: () => Promise<string | TokenAnswer> } or { key: string }
|
|
28660
28802
|
* @param {string|Object} [options.app] a native app's identity: 'android:<package>' / 'apple:<bundle id>' / 'windows:<id>', or { id, cert }
|
|
28661
|
-
* @param {string} [options.baseUrl] the Open Platform (default https://open.superroute.ca)
|
|
28803
|
+
* @param {string} [options.baseUrl] the Open Platform (default https://open.superroute.ca): the standard path
|
|
28804
|
+
* @param {string} [options.smapUrl] the sMap service a map key's configuration is read from (default
|
|
28805
|
+
* https://tile.srsr.ca; map.planEditor passes the map's own sMap address)
|
|
28806
|
+
* @param {boolean} [options.fastPath=true] use the fast path when the credential names one (false: standard only)
|
|
28807
|
+
* @param {number} [options.fastPathTimeout=2000] ms a fast-path call may take before it is repeated on the standard path
|
|
28808
|
+
* @param {number} [options.fastPathRefineTimeout=5000] the same for refine (its search takes longer)
|
|
28662
28809
|
* @param {Function} [options.fetch] fetch to use (default the page's)
|
|
28663
28810
|
* @param {Object} [options.plan] the starting plan: { vehicles, jobs, routes, region?, profile?, departed_at? }
|
|
28664
28811
|
* @param {string} [options.region] used when the plan names none
|
|
@@ -28694,6 +28841,7 @@ function smapCreatePlan() {
|
|
|
28694
28841
|
this._opening = null;
|
|
28695
28842
|
this._openingKey = null;
|
|
28696
28843
|
this._matrixRetryAt = 0;
|
|
28844
|
+
this._path = null;
|
|
28697
28845
|
this._destroyed = false;
|
|
28698
28846
|
if (options.plan) { this.setPlan(options.plan).catch(function () {}); }
|
|
28699
28847
|
}
|
|
@@ -28762,7 +28910,7 @@ function smapCreatePlan() {
|
|
|
28762
28910
|
return {
|
|
28763
28911
|
plan: this.getPlan(), result: this.getResult(), busy: this._busy, error: this._error, canUndo: this.canUndo(),
|
|
28764
28912
|
canRedo: this.canRedo(), choices: clone(this._choices), locked: this.locked(), last: clone(this._last),
|
|
28765
|
-
preview: this._previewResult ? clone(this._previewResult) : null,
|
|
28913
|
+
preview: this._previewResult ? clone(this._previewResult) : null, path: this._path,
|
|
28766
28914
|
};
|
|
28767
28915
|
};
|
|
28768
28916
|
|
|
@@ -28972,7 +29120,7 @@ function smapCreatePlan() {
|
|
|
28972
29120
|
var e = this._history[this._at] || {};
|
|
28973
29121
|
this._emit('change', {
|
|
28974
29122
|
kind: kind, plan: this.getPlan(), result: this.getResult(), answer: this._last ? clone(this._last.answer) : null,
|
|
28975
|
-
pending: !e.result, canUndo: this.canUndo(), canRedo: this.canRedo(),
|
|
29123
|
+
pending: !e.result, canUndo: this.canUndo(), canRedo: this.canRedo(), path: this._path,
|
|
28976
29124
|
});
|
|
28977
29125
|
};
|
|
28978
29126
|
|
|
@@ -29072,7 +29220,7 @@ function smapCreatePlan() {
|
|
|
29072
29220
|
self._error = null;
|
|
29073
29221
|
self._setBusy(false);
|
|
29074
29222
|
if (self._history[self._at] === target || kind !== 'recost') { self._changed(kind); }
|
|
29075
|
-
return { kind: kind, plan: self.getPlan(), result: self.getResult(), answer: clone(answer) };
|
|
29223
|
+
return { kind: kind, plan: self.getPlan(), result: self.getResult(), answer: clone(answer), path: self._path };
|
|
29076
29224
|
}, function (err) {
|
|
29077
29225
|
var current = self._inflight === ticket;
|
|
29078
29226
|
if (current) { self._inflight = null; self._setBusy(false); }
|
|
@@ -29103,6 +29251,7 @@ function smapCreatePlan() {
|
|
|
29103
29251
|
if (matrix) { body.matrix = matrix; } else { delete body.matrix; }
|
|
29104
29252
|
return self._transport.send('POST', path, body, signal);
|
|
29105
29253
|
}).then(function (res) {
|
|
29254
|
+
if (!self._destroyed) { self._path = res.path || null; }
|
|
29106
29255
|
if (body.matrix) { self._snapshotSeen(res.matrix, body.matrix); }
|
|
29107
29256
|
return res;
|
|
29108
29257
|
}, function (err) {
|
|
@@ -29154,7 +29303,7 @@ function smapCreatePlan() {
|
|
|
29154
29303
|
}
|
|
29155
29304
|
self._matrixRetryAt = 0;
|
|
29156
29305
|
if (self._openingKey === key) { self._matrix = id; self._matrixKey = key; }
|
|
29157
|
-
self._emit('snapshot', { status: 'opened', matrix: id, expires_at: res.data.expires_at || null, node: res.data.node || null });
|
|
29306
|
+
self._emit('snapshot', { status: 'opened', matrix: id, expires_at: res.data.expires_at || null, node: res.data.node || null, path: res.path || null });
|
|
29158
29307
|
return id;
|
|
29159
29308
|
}, function (err) {
|
|
29160
29309
|
self._matrixRetryAt = Date.now() + SNAPSHOT_RETRY_MS;
|
|
@@ -29890,7 +30039,7 @@ function smapCreatePlan() {
|
|
|
29890
30039
|
*/
|
|
29891
30040
|
function attach(map, options) {
|
|
29892
30041
|
options = options || {};
|
|
29893
|
-
var editor = new PlanEditor(Object.assign({}, options, { plan: null }));
|
|
30042
|
+
var editor = new PlanEditor(Object.assign({}, options, { plan: null, smapUrl: options.smapUrl || map._base }));
|
|
29894
30043
|
var layer = attachToMap(map, editor, options);
|
|
29895
30044
|
var toolId = null;
|
|
29896
30045
|
var destroyed = false;
|
|
@@ -29976,7 +30125,7 @@ function smapCreateSdk(engine, interop, plan) {
|
|
|
29976
30125
|
})(typeof self !== 'undefined' ? self : this, function (engine, interop, plan) {
|
|
29977
30126
|
'use strict';
|
|
29978
30127
|
|
|
29979
|
-
var VERSION = '1.1.
|
|
30128
|
+
var VERSION = '1.1.7';
|
|
29980
30129
|
var FLAVORS = ['light', 'white', 'grayscale', 'dark', 'black'];
|
|
29981
30130
|
var BASEMAP_SOURCE = 'basemap';
|
|
29982
30131
|
var BUILDINGS_LAYER = 'smap-buildings-3d';
|
|
@@ -32294,7 +32443,7 @@ function SMapMap(options) {
|
|
|
32294
32443
|
SMapMap.prototype = core.Map.prototype;
|
|
32295
32444
|
return new core.Map(options);
|
|
32296
32445
|
}
|
|
32297
|
-
var smapVersion = "1.1.
|
|
32446
|
+
var smapVersion = "1.1.7";
|
|
32298
32447
|
var smapStyles = ['light', 'white', 'grayscale', 'dark', 'black'];
|
|
32299
32448
|
/** The bundled rendering engine, for anything the SDK does not wrap (loaded on the first call). */
|
|
32300
32449
|
function smapGetEngine() { return smapLoad().engine; }
|