Skip to content

Commit

Permalink
fix(hn): don't return uuid if it isn't fully loaded yet
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlangelaan committed Feb 7, 2019
1 parent 4b9cbe1 commit c215734
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 44 deletions.
2 changes: 1 addition & 1 deletion packages/hn-react/src/components/DrupalPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class DrupalPage extends React.Component<
return null;
}

const uuid = this.props.site.getUuid(data.url);
const uuid = this.props.site.getUuid(data.url)!;

const entityMapper = (
<EntityMapper
Expand Down
105 changes: 62 additions & 43 deletions packages/hn/src/Site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Site {

// Not hydrated
private pagesLoading: { [s: string]: Promise<string> } = {};
private pagesLoaded: { [s: string]: string } = {};

constructor(initParams?: SiteInitializeParams) {
this.reset();
Expand All @@ -49,6 +50,7 @@ class Site {
__hn: {},
};
this.pagesLoading = {};
this.pagesLoaded = {};
}

/**
Expand Down Expand Up @@ -97,58 +99,75 @@ class Site {
}

public getPage(path, loadFromServer = false): Promise<string> {
if (!this.pagesLoading[path]) {
const dataMaybeAlreadyLoaded = getNested(
() => this.data.data[this.data.paths[path]],
);
if (
getNested(() =>
dataMaybeAlreadyLoaded.__hn.view_modes.includes('default'),
)
) {
this.pagesLoading[path] = Promise.resolve(this.data.paths[path]);
}
if (!loadFromServer) {
const uuid = this.getUuid(path);

// If we already loaded the page (either directly or via another page),
// we can return it right now.
if (uuid) return Promise.resolve(uuid);

// If we're already loading this page, we should return the promise.
if (this.pagesLoading[path]) return this.pagesLoading[path];
}

if (loadFromServer || !this.pagesLoading[path]) {
// Copy this.tokensToVerify for this single request.
const tokensToVerify = [...this.tokensToVerify];

this.pagesLoading[path] = this.fetch(
'/hn?' +
stringify({
path,
_format: 'hn',
_hn_user: this.user ? this.user : undefined,
_hn_verify: tokensToVerify,
}),
).then((page: HnServerResponse) => {
const hnRequestData =
(page.__hn && page.__hn.request && page.__hn.request) || {};

// Get the user id, to pass to all new requests.
this.user = hnRequestData.user || this.user;

// Remove all sent tokens from the tokensToVerify.
this.tokensToVerify = this.tokensToVerify.filter(
t => tokensToVerify.indexOf(t) === -1,
);
// Copy this.tokensToVerify for this single request.
const tokensToVerify = [...this.tokensToVerify];

this.pagesLoading[path] = this.fetch(
'/hn?' +
stringify({
path,
_format: 'hn',
_hn_user: this.user ? this.user : undefined,
_hn_verify: tokensToVerify,
}),
).then((page: HnServerResponse) => {
const hnRequestData =
(page.__hn && page.__hn.request && page.__hn.request) || {};

// Get the user id, to pass to all new requests.
this.user = hnRequestData.user || this.user;

// Remove all sent tokens from the tokensToVerify.
this.tokensToVerify = this.tokensToVerify.filter(
t => tokensToVerify.indexOf(t) === -1,
);

// Add new token to tokensToVerify.
const newToken = hnRequestData.token;
if (newToken) this.tokensToVerify.push(newToken);
// Add new token to tokensToVerify.
const newToken = hnRequestData.token;
if (newToken) this.tokensToVerify.push(newToken);

// Add all data to the global data storage.
this.addData(page);
// Add all data to the global data storage.
this.addData(page);

// Mark this promise as loaded
const uuid = this.data.paths[path];
this.pagesLoaded[path] = uuid;

// Delete the reference to this promise, because we're not loading anymore.
delete this.pagesLoading[path];

return uuid;
});

return this.data.paths[path];
});
}
return this.pagesLoading[path];
}

public getUuid(path: string) {
return this.data.paths[path];
// If we already loaded the page, we can return it right now.
if (this.pagesLoaded[path]) return this.pagesLoaded[path];

// Maybe we already have the data from another fetch.
try {
// We try to get the data directly. If the data isn't available, that's fine.
const uuid = this.data.paths[path];
if (this.getData(uuid).__hn.view_modes.includes('default')) {
return uuid;
}
}
catch {
// The data probabily doesn't exist yet, so we do nothing.
}
}

private addData(data: HnServerResponse) {
Expand Down

0 comments on commit c215734

Please sign in to comment.