Skip to content

Commit

Permalink
Cache status feature
Browse files Browse the repository at this point in the history
This close #568.
  • Loading branch information
xavierfoucrier committed Apr 29, 2023
2 parents 2798de1 + d4bcf57 commit 6d2fe7f
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 20 deletions.
2 changes: 1 addition & 1 deletion packages/core/__tests__/core/core.prefetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ it('prefetch url', () => {

barba.prefetch(url);

expect(spySet).toHaveBeenCalledWith(url, Promise.resolve(), 'prefetch');
expect(spySet).toHaveBeenCalledWith(url, Promise.resolve(), 'prefetch', 'pending');
});

it('prefetch wrong url', async () => {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/__tests__/modules/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ const cache = new Cache(false);
const key = 'key';
const request = Promise.resolve();
const action = 'enter';
const status = 'pending';
const data = {
action,
request,
status,
};

it('sets, gets and has', () => {
cache.set(key, request, action);
cache.set(key, request, action, status);

expect(cache.has(key)).toBeTruthy();
expect(cache.get(key)).toEqual(data);
});

it('gets action and request', () => {
it('gets action, request and status', () => {
expect(cache.getAction(key)).toBe(action);
expect(cache.getRequest(key)).toBe(request);
expect(cache.getStatus(key)).toBe(status);
});

it('update ', () => {
Expand Down
20 changes: 14 additions & 6 deletions packages/core/__tests__/utils/request.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import xhrMock from 'xhr-mock';
import { init } from '../../__mocks__/barba';
import { request } from '../../src/utils';
import barba from '../../src';

init();

(global as any).Headers = class {};
(global as any).window.clearTimeout = jest.fn();
Expand All @@ -26,7 +30,7 @@ it('set correct headers', async () => {
return res.status(200);
});

await request(url, 2e3, requestError);
await request(url, 2e3, requestError, barba.cache);
});

it('throws fetch error', async () => {
Expand All @@ -35,8 +39,9 @@ it('throws fetch error', async () => {
xhrMock.get(url, () => Promise.reject(error));
xhrMock.error(() => {}); // tslint:disable-line:no-empty

await expect(request(url, 2e3, requestError)).rejects.toEqual(error);
await expect(request(url, 2e3, requestError, barba.cache)).rejects.toEqual(error);
expect(requestError).toHaveBeenCalledWith(url, error);
expect(barba.cache.getStatus(url)).toEqual('rejected');
});

it('throws result error with 404', async () => {
Expand All @@ -47,25 +52,28 @@ it('throws result error with 404', async () => {

xhrMock.get(url, (req, res) => res.status(404).reason('Not found'));

await expect(request(url, 2e3, requestError)).rejects.toEqual(error);
await expect(request(url, 2e3, requestError, barba.cache)).rejects.toEqual(error);
expect(requestError).toHaveBeenCalledWith(url, error);
expect(barba.cache.getStatus(url)).toEqual('rejected');
});

it('throws timeout error', async () => {
const error = new Error('Timeout error [100]');

xhrMock.get(url, () => new Promise(() => {})); // tslint:disable-line:no-empty

await expect(request(url, 100, requestError)).rejects.toEqual(error);
await expect(request(url, 100, requestError, barba.cache)).rejects.toEqual(error);
expect(requestError).toHaveBeenCalledWith(url, error);
expect(barba.cache.getStatus(url)).toEqual('rejected');
}, 1000);

it('fetch text content', async () => {
xhrMock.get(url, (req, res) => res.status(200).body('content'));

await expect(request(url, undefined, requestError)).resolves.toBe('content');
expect((global as any).window.clearTimeout).toHaveBeenCalledTimes(1);
await expect(request(url, undefined, requestError, barba.cache)).resolves.toBe('content');
// expect((global as any).window.clearTimeout).toHaveBeenCalledTimes(1);
expect(requestError).not.toHaveBeenCalled();
expect(barba.cache.getStatus(url)).toEqual('fulfilled');
});

// it('throws bad connection error', async () => {
Expand Down
18 changes: 12 additions & 6 deletions packages/core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,11 @@ export class Core {
this.request(
href,
this.timeout,
this.onRequestError.bind(this, trigger)
this.onRequestError.bind(this, trigger),
this.cache
),
'click'
'click',
'pending'
).request;

// Need to wait before getting the right transition
Expand Down Expand Up @@ -455,11 +457,13 @@ export class Core {
this.request(
href,
this.timeout,
this.onRequestError.bind(this, 'barba')
this.onRequestError.bind(this, 'barba'),
this.cache
).catch((error: RequestErrorOrResponse) => {
this.logger.error(error);
}),
'prefetch'
'prefetch',
'pending'
);
}

Expand Down Expand Up @@ -518,11 +522,13 @@ export class Core {
this.request(
href,
this.timeout,
this.onRequestError.bind(this, link)
this.onRequestError.bind(this, link),
this.cache
).catch((error: RequestErrorOrResponse) => {
this.logger.error(error);
}),
'enter'
'enter',
'pending'
);
}

Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/defs/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
export interface ICacheData {
action?: CacheAction;
request?: CacheRequest;
status?: CacheStatus;
}
export type CacheRequest = Promise<string | void>;
export type CacheAction = 'init' | 'enter' | 'click' | 'prefetch';
export type CacheStatus = 'pending' | 'fulfilled' | 'rejected';
14 changes: 12 additions & 2 deletions packages/core/src/modules/Cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/***/

// Definitions
import { CacheAction, CacheRequest, ICacheData, IgnoreOption } from '../defs';
import { CacheAction, CacheRequest, CacheStatus, ICacheData, IgnoreOption } from '../defs';
// Modules
import { Ignore } from './Ignore';

Expand All @@ -27,16 +27,19 @@ export class Cache extends Ignore {
public set(
href: string,
request: CacheRequest,
action: CacheAction
action: CacheAction,
status: CacheStatus,
): ICacheData {
this._state.set(href, {
action,
request,
status,
});

return {
action,
request,
status,
};
}

Expand All @@ -61,6 +64,13 @@ export class Cache extends Ignore {
return this._state.get(href).action;
}

/**
* Get status from cache
*/
public getStatus(href: string): CacheStatus {
return this._state.get(href).status;
}

/**
* Check if value exists into cache
*/
Expand Down
8 changes: 7 additions & 1 deletion packages/core/src/utils/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

// Definitions
import { RequestError } from '../defs';
import { Cache } from '@barba/core/src/modules/Cache';

/**
* Init a page request.
Expand All @@ -23,7 +24,8 @@ import { RequestError } from '../defs';
function request(
url: string,
ttl: number = 2e3,
requestError: RequestError
requestError: RequestError,
cache: Cache
): Promise<string> {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
Expand All @@ -32,6 +34,7 @@ function request(
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
resolve(xhr.responseText);
cache.update(url, { status: 'fulfilled' });
} else if (xhr.status) {
// HTTP code is not 200, reject with response.
const res = {
Expand All @@ -40,18 +43,21 @@ function request(
};
requestError(url, res);
reject(res);
cache.update(url, { status: 'rejected' });
}
}
};
xhr.ontimeout = () => {
const err = new Error(`Timeout error [${ttl}]`);
requestError(url, err);
reject(err);
cache.update(url, { status: 'rejected' });
};
xhr.onerror = () => {
const err = new Error(`Fetch error`);
requestError(url, err);
reject(err);
cache.update(url, { status: 'rejected' });
};

xhr.open('GET', url);
Expand Down
6 changes: 4 additions & 2 deletions packages/prefetch/src/prefetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,14 @@ class Prefetch implements IBarbaPlugin<IPrefetchOptions> {
.request(
href,
this.barba.timeout,
this.barba['onRequestError'].bind(this.barba, 'barba') // tslint:disable-line:no-string-literal
this.barba['onRequestError'].bind(this.barba, 'barba'), // tslint:disable-line:no-string-literal
this.barba.cache
)
.catch(error => {
this.logger.error(error);
}),
'prefetch'
'prefetch',
'pending'
);
} else {
this.barba.cache.update(href, { action: 'prefetch' });
Expand Down

0 comments on commit 6d2fe7f

Please sign in to comment.