mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
Recent community wildlife observations, as a new Wildlife group in the layer panel. - Server: keyless iNaturalist proxy (v2 observations with only the projected fields; undocumented v1 UTFGrid density tiles, decoded on the server) sharing one paced queue (burst 4, ~1/s, 60/min, 8,000/day budget, up to four in flight), in-memory caches and upstream-only cooldowns; Acartia Salish Sea marine-mammal feed rounded to 0.01 degrees with comments dropped. - Layer: grid counts drawn as a soft view-ranked density glow; real sampled sightings as taxon badges at their true positions with ambient photo thumbnails and labels; obscured records stay privacy cells; a clicked sighting stays pinned through camera moves and refreshes. - Anchored photo card per selection with the single iNaturalist link; attribution in the layer row and the Data attribution popover. - Filters (CONFIRMED, taxa presets) round-trip in share links with token 9. Co-Authored-By: Claude Opus 5.5 <[email protected]>
71 lines
1.8 KiB
JavaScript
71 lines
1.8 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { EventEmitter } from 'node:events';
|
|
import { inaturalistProxy } from './observations.js';
|
|
|
|
export const NOW = Date.parse('2026-11-04T18:05:00Z');
|
|
|
|
/** Mount the proxy over synthetic HTTP objects, without opening a socket. */
|
|
export function installInatProxy(
|
|
defaultUrl,
|
|
options = {},
|
|
hook = 'configureServer',
|
|
) {
|
|
let handler;
|
|
const plugin = inaturalistProxy({
|
|
now: () => NOW,
|
|
cacheDir: null,
|
|
queueOptions: { intervalMs: 0, windowMs: 0 },
|
|
warn() {},
|
|
...options,
|
|
});
|
|
assert.equal(plugin.name, 'inaturalist');
|
|
assert.equal(typeof plugin.configureServer, 'function');
|
|
assert.equal(typeof plugin.configurePreviewServer, 'function');
|
|
plugin[hook]({
|
|
middlewares: {
|
|
use(mount, callback) {
|
|
assert.equal(mount, '/api/inaturalist');
|
|
handler = callback;
|
|
},
|
|
},
|
|
});
|
|
return async (
|
|
url = defaultUrl,
|
|
{ method = 'GET', peer = 'local', headers = {}, signal } = {},
|
|
) => {
|
|
const res = Object.assign(new EventEmitter(), {
|
|
headers: {},
|
|
writeHead(status, headers) {
|
|
this.status = status;
|
|
Object.assign(this.headers, headers);
|
|
},
|
|
setHeader(key, value) {
|
|
this.headers[key] = value;
|
|
},
|
|
end(value) {
|
|
this.status ??= this.statusCode;
|
|
this.body = JSON.parse(value);
|
|
},
|
|
});
|
|
const abort = () => {
|
|
res.destroyed = true;
|
|
res.emit('close');
|
|
};
|
|
signal?.addEventListener('abort', abort, { once: true });
|
|
try {
|
|
await handler(
|
|
Object.assign(new EventEmitter(), {
|
|
url,
|
|
method,
|
|
headers,
|
|
socket: { remoteAddress: peer },
|
|
}),
|
|
res,
|
|
);
|
|
} finally {
|
|
signal?.removeEventListener('abort', abort);
|
|
}
|
|
return res;
|
|
};
|
|
}
|