function evaluate(): AtomicPromise<Either<Error, HTMLScriptElement>> { if (script.matches('[type="module"][src]')) { return AtomicPromise.resolve(import(script.src)) .catch((reason: Error) => reason.message.startsWith('Failed to load ') && script.matches('[src][async]') ? retry(script).catch(() => AtomicPromise.reject(reason)) : AtomicPromise.reject(reason)) .then( () => ( void script.dispatchEvent(new Event('load')), Right(script)), reason => ( void script.dispatchEvent(new Event('error')), Left(new FatalError(reason instanceof Error ? reason.message : reason + '')))); } else { try { if (new URL(standardize(window.location.href)).path !== new URL(standardize(window.location.href)).path) throw new FatalError('Expired.'); if (skip.has(new URL(standardize(window.location.href)).reference)) throw new FatalError('Expired.'); void (0, eval)(code); script.hasAttribute('src') && void script.dispatchEvent(new Event('load')); return AtomicPromise.resolve(Right(script)); } catch (reason) { script.hasAttribute('src') && void script.dispatchEvent(new Event('error')); return AtomicPromise.resolve(Left(new FatalError(reason instanceof Error ? reason.message : reason + ''))); } } }
it('extend', () => { assert.deepStrictEqual( JSON.stringify(scope(new Config({ scope: { '/': { fetch: { wait: 100 } } } }), { orig: new URL(standardize('/')).pathname, dest: new URL(standardize('/')).pathname }).extract()), JSON.stringify(new Config({ fetch: { wait: 100 }, scope: { '/': { fetch: { wait: 100 } } } }))); });
it('enable', () => { assert.deepStrictEqual( JSON.stringify(scope(new Config({ scope: { '/': undefined, '/a': {} } }), { orig: new URL(standardize('/a')).pathname, dest: new URL(standardize('/a')).pathname }).extract()), JSON.stringify(new Config({ scope: { '/': undefined, '/a': {} } }))); });
function retry(script: HTMLScriptElement): AtomicPromise<undefined> { if (new URL(standardize(script.src)).origin === new URL(standardize(window.location.href)).origin) return AtomicPromise.reject(new Error()); script = html('script', Object.values(script.attributes).reduce((o, { name, value }) => (o[name] = value, o), {}), [...script.childNodes]); return new AtomicPromise((resolve, reject) => ( void script.addEventListener('load', () => void resolve()), void script.addEventListener('error', reject), void document.body.appendChild(script), void script.remove())); }
it('mismatch', () => { assert.deepStrictEqual( JSON.stringify(scope(new Config({ scope: { '/a': {} } }), { orig: new URL(standardize('/')).pathname, dest: new URL(standardize('/a')).pathname }).extract(() => [])), JSON.stringify([])); assert.deepStrictEqual( JSON.stringify(scope(new Config({ scope: { '/a': {} } }), { orig: new URL(standardize('/a')).pathname, dest: new URL(standardize('/')).pathname }).extract(() => [])), JSON.stringify([])); });
.fmap(xhr => { const responseURL: URL<StandardURL> = new URL(standardize(xhr.responseURL)); assert(responseURL.origin === new URL(window.location.origin).origin); if (method === 'GET') { const cc = new Map<string, string>( xhr.getResponseHeader('Cache-Control') ? xhr.getResponseHeader('Cache-Control')!.trim().split(/\s*,\s*/) .filter(v => v.length > 0) .map(v => v.split('=').concat('') as [string, string]) : []); for (const path of new Set([requestURL.path, responseURL.path])) { if (xhr.getResponseHeader('ETag') && !cc.has('no-store')) { void caches.set(path, { etag: xhr.getResponseHeader('ETag')!, expiry: cc.has('max-age') && !cc.has('no-cache') ? Date.now() + +cc.get('max-age')! * 1000 || 0 : 0, xhr, }); } else { void caches.delete(path); } } } return (overriddenDisplayURL: URL<StandardURL>, overriddenRequestURL: URL<StandardURL>) => new FetchResponse( responseURL.path === overriddenRequestURL.path ? overriddenDisplayURL : overriddenRequestURL.path === requestURL.path || !key ? responseURL : overriddenDisplayURL, xhr); })
it('submit post', () => { const req = new RouterEventRequest(html('form', { method: 'POST', action: './send' }, [ html('input', { name: 'test', type: 'text', value: 'abc' }) ])); assert(req.url.reference === standardize('./send')); assert(req.method === RouterEventMethod.POST); assert(req.body instanceof FormData); });
it('submit get', () => { const req = new RouterEventRequest(html('form', { method: 'GET', action: './search' }, [ html('input', { name: 'test', type: 'text', value: 'abc' }) ])); assert(req.url.reference === standardize('./search?test=abc')); assert(req.method === RouterEventMethod.GET); assert(req.body === null); });
return (url: string) => { const { path, pathname } = new URL(standardize(url)); return Sequence.from(Object.keys(config).filter(([c]) => c === '/').sort().reverse()) .filter(flip(compare)(pathname)) .map(pattern => config[pattern]) .take(1) .extract() .pop()! .call(config, path); };
it('dir', () => { assert(!compare('/abc', new URL(standardize('/')).pathname)); assert(compare('/abc', new URL(standardize('/abc')).pathname)); assert(compare('/abc', new URL(standardize('/abc/')).pathname)); assert(!compare('/abc/', new URL(standardize('/abc')).pathname)); assert(compare('/abc/', new URL(standardize('/abc/')).pathname)); assert(!compare('/abc', new URL(standardize('/ab')).pathname)); assert(!compare('/ab', new URL(standardize('/abc')).pathname)); });