UNPKG

@ideal-postcodes/address-finder

Version:

Address Finder JS library backed by the Ideal Postcodes UK address search API

68 lines (67 loc) 2.75 kB
import { Client, checkKeyUsability } from "@ideal-postcodes/core-axios"; import { NOOP, defaults } from "./controller"; import { toContextMap } from "./contexts"; import { loaded, toArray, getParent, generateTimer, markLoaded, getScope, } from "@ideal-postcodes/jsutil"; import { setup } from "./setup"; const isTrue = () => true; const getAnchors = (config, marker) => { const scope = getScope(config.scope || null); const matches = scope.querySelectorAll(config.anchor || config.inputField || (config.outputFields || {}).line_1); return toArray(matches).filter((e) => !loaded(e, marker)); }; const DEFAULT_INTERVAL = 1000; const formScope = (anchor) => getParent(anchor, "FORM"); /** * Dynamically apply AddressFinder when relevant fields appear * - Exits if page test is fails * - Check if key usable * - Creates a bind method * - Retrives parent scope * - Marks anchor if completed * - Creates timer tools */ export const watch = (config, options = {}) => { const client = new Client({ ...defaults, ...config, api_key: config.apiKey }); const { pageTest = isTrue } = options; if (!pageTest()) return Promise.resolve(null); return checkKeyUsability({ client }) .then((key) => { if (!key.available) return null; const { getScope = formScope, interval = DEFAULT_INTERVAL, anchor, onBind = NOOP, onAnchorFound = NOOP, onBindAttempt = NOOP, immediate = true, marker = "idpc", } = options; const bind = () => { onBindAttempt({ config, options }); getAnchors({ anchor, ...config }, marker).forEach((anchor) => { const scope = getScope(anchor); if (!scope) return; const contexts = toContextMap(key.contexts); const newConfig = { scope, ...config, checkKey: false, contexts }; onAnchorFound({ anchor, scope, config: newConfig }); const c = setup(newConfig); const details = c.options.contexts[key.context]; if (c.options.detectCountry && details) { c.applyContext(details, false); } else { c.applyContext(c.currentContext(), false); } markLoaded(anchor, marker); onBind(c); }); }; const { start, stop } = generateTimer({ bind, pageTest, interval }); if (immediate) start(); return { start, stop, bind }; }) .catch((e) => { // Swallow promise errors and raise via optionall onError callback if (options.onError) options.onError(e); return null; }); };