Resource retries and fallback URLs
Use a development SDK and WASM built from the same core commit. resourcePolicy is a SqsMap host extension; transformRequest keeps MapLibre-style naming. The policy runs in browser main-thread, strict render Worker and desktop map HTTP adapters. Native libraries expose configuration/planning while external hosts execute HTTP. The mobile application script host remains pending; see native resources.
Automatic imagery connectivity recovery
The code below tries an explicitly configured fallback after a network failure, attempt timeout, or HTTP 408/429/5xx. It does not infer visitor geography from browser language. Neither the website nor imagery-provider URL is embedded in the map engine. Unrelated providers retain the default deadline. Create a sized #map container, display Esri and provider credits, and ensure the provider and proxy allow CORS.
import { MapView, ResourceType } from '@sqsmap/core';
const map = await MapView.create(document.querySelector('#map'), {
resourceTimeoutMs: 20000,
resourcePolicy: {
maxConcurrentRequests: 8,
retries: 1,
retryDelayMs: 100,
cache: 'default',
fallbacks: [{
prefix: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/',
replacements: ['https://www.sqsmap.com/api/imagery/arcgis/'],
resourceTypes: [ResourceType.Tile],
attemptTimeoutMs: 4000,
}],
},
});
map.setProjection('mercator');
map.addRasterTiles(
'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
{ name: 'World Imagery', scheme: 'mercator', tileSize: 256, maxZoom: 18,
attribution: 'Powered by Esri · Source: Esri, Vantor, Earthstar Geographics, and the GIS User Community' },
);
await map.flush({ render: true });
// Show map.getAttributions() in your own UI and destroy the map on page teardown.
The example proxy is the website's current forwarding service. For your own deployment, replace it with a proxy for your fixed provider and retain the required credits and provider usage conditions. flush confirms a frame submission while tile loading remains asynchronous; the attribution API exposes the current credits.
Policy boundaries
| Setting | Range and default |
|---|---|
resourceTimeoutMs | Entire logical request: 1–120000 ms, default 30000; includes candidates, waits and reads |
maxConcurrentRequests | 1–32, default 32; a retry wait keeps its slot |
attemptTimeoutMs | Per attempt: 1–120000 ms; a rule overrides the global setting, otherwise the total deadline applies |
retries | Extra attempts per endpoint: 0–2, default zero |
retryDelayMs | Fixed retry wait for the same endpoint: 0–2000 ms, default zero |
cache | Fetch default / no-store / reload / no-cache / force-cache; browser default when omitted |
fallbacks | At most 16 rules; the first match wins; at most three replacements per rule |
Prefixes must be normalized absolute HTTP(S) URLs ending in /, without query, fragment or embedded credentials. Each fallback combines its prefix with the original path suffix. resourceTypes restricts matching resource kinds. Query parameters are discarded unless forwardQuery: true explicitly enables forwarding. Creation deeply captures the policy; subsequent caller mutations do not change the map.
Only GET/HEAD requests repeat. POST, invalid settings, byte-limit violations, cancellation and other 4xx responses never repeat or forward. Stream-read and decoding failures are not classified as retryable connection failures. Retries currently use a fixed delay, without exponential backoff or Retry-After processing.
Each candidate evaluates transformRequest independently. Automatic authorization applies only to the final exact origin https://api.suanjinshan.com. Fallback requests do not inherit previous headers; user-supplied authorization must still be scoped to the target origin. Live sources force no-store, overriding policy caching. Cache behavior is delegated to the browser; there is no new persistent cache store.
Replacing a source, removing a layer, destroying the map or caller cancellation stops requests and waits. Late data cannot populate obsolete instances. No fallback starts after the total deadline. Explicit resource calls return RESOURCE_LIMIT when slots are exhausted; map download loops wait for an available slot.
Actual verification
A controlled service returns 503 from primary endpoints and styles and imagery from fallbacks. Main-thread and strict-Worker maps both retry the primary once, then switch to the fallback. Two actual software-GL screenshots contain the fallback imagery. Forty-seven transport checks also cover deadlines, cancellation, byte budgets and credential isolation. WebGL submits external-image uploads before the host closes the bitmap, preventing empty imagery from premature disposal. This is not public-provider or other-device acceptance.
Browser planning now reuses shared Rust. See native resource policies for configuration/plans. Common script configuration and desktop execution are connected. Mobile application adapters, protocol extensions and unified cache management remain pending.
Reconfigure and observe at runtime
await map.sqs.resources.configure(configuration) replaces all settings, restoring omitted fields to defaults. It captures bounded plain JSON at call time, rejecting functions and implicit toJSON. getConfiguration() returns a deeply immutable snapshot; plan(query) computes a plan without downloading.
const subscription = map.on('sqs.resourceschange', event => {
console.log(event.context, event.resourceConfiguration);
});
await map.sqs.resources.configure({ resourcePolicy: { retries: 1 } });
const plan = await map.sqs.resources.plan({
url: 'https://primary.example/tiles/1/2/3', resourceType: 'Tile', maxBytes: 8388608,
});
await map.sqs.resources.configure({});
subscription.unsubscribe();
The console example targets the browser SDK. Complete copyable HTML includes every button, style, listener and teardown; add ?worker=1 for a strict render Worker. See the shared facade for portable debugger scripts. Events retain historical configuration; rejected writes emit no event. Future dispatches use new settings, while existing jobs keep their candidate URLs, retries, cache mode and deadlines. Reducing capacity does not cancel in-flight jobs, and retry waits retain slots.
Desktop execution and disk cache
Desktop source HTTP, images, styles/fonts/sprites and online imagery tiles share map capacity. Cancellation and map destruction terminate HTTP waits, and late responses are rejected after the total deadline. Existing generation/view-epoch guards remain. Offline-pack reads bypass HTTP policy. WebSocket, local data, offline-pack creation and separate 3D downloaders are managed independently.
| Mode | Desktop behavior |
|---|---|
default | Read fresh cache; validate stale entries with ETag/Last-Modified |
force-cache | Read available cache, or download and cache on a miss |
no-cache | Validate with the server; 304 reads a bounded cached body |
reload | Skip existing bodies and validator headers; download and replace cache |
no-store | Never read/write cache; send no-store; live HTTP forces this mode |
Cached file sizes are checked before bounded reads. The decoder invalidates corrupt content without treating it as a fallback condition. This reuses the existing disk cache and capacity management; it does not introduce cross-platform cache CRUD APIs. Desktop JSON configuration does not accept tokens or function-valued transformRequest.
Capability fields resourcePolicyPlanning, resourcePolicyExecution and resourcePolicyEvents distinguish planning, current-host execution and notification. Browser/desktop expose all three; C native-library execution is false, and its host executes requestPlan. Local evidence uses the same scripts in native one-shot/persistent, desktop and browser main-thread/strict Worker routes. Actual HTTP, imagery decoding and event checks do not replace external-machine, mobile or formal-release acceptance.
Browser custom protocols describes standalone browser download callbacks and platform boundaries.
13.6b connects shared custom-protocol planning and tile templates with original URI/response identities; see custom planning for host registration, budgets and scope.