Skip to content

Commit

Permalink
Merge pull request #454 from storyblok/fix-int-687-fix-memory-leaks
Browse files Browse the repository at this point in the history
fix(int 687): fix memory leaks on resolve relations
  • Loading branch information
Thiago Saife authored Mar 1, 2023
2 parents 6b9dc94 + c1b4f50 commit 8cac77e
Showing 1 changed file with 58 additions and 26 deletions.
84 changes: 58 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class Storyblok {
private accessToken: string
private cache: ISbCache
private helpers: SbHelpers

private resolveCounter: number
public relations: RelationsType
public links: LinksType
public richTextResolver: any
Expand Down Expand Up @@ -131,6 +131,7 @@ class Storyblok {
this.links = {} as LinksType
this.cache = config.cache || { clear: 'manual' }
this.helpers = new SbHelpers()
this.resolveCounter = 0
this.resolveNestedRelations = false

this.client = new SbFetch({
Expand Down Expand Up @@ -281,7 +282,8 @@ class Storyblok {

private _insertLinks(
jtree: ISbStoriesParams,
treeItem: keyof ISbStoriesParams
treeItem: keyof ISbStoriesParams,
resolveId: string
): void {
const node = jtree[treeItem]

Expand All @@ -290,34 +292,37 @@ class Storyblok {
node.fieldtype == 'multilink' &&
node.linktype == 'story' &&
typeof node.id === 'string' &&
this.links[node.id]
this.links[resolveId][node.id]
) {
node.story = this._cleanCopy(this.links[node.id])
node.story = this._cleanCopy(this.links[resolveId][node.id])
} else if (
node &&
node.linktype === 'story' &&
typeof node.uuid === 'string' &&
this.links[node.uuid]
this.links[resolveId][node.uuid]
) {
node.story = this._cleanCopy(this.links[node.uuid])
node.story = this._cleanCopy(this.links[resolveId][node.uuid])
}
}

private _insertRelations(
jtree: ISbStoriesParams,
treeItem: keyof ISbStoriesParams,
fields: string | Array<string>
fields: string | Array<string>,
resolveId: string
): void {
if (fields.indexOf(`${jtree.component}.${treeItem}`) > -1) {
if (typeof jtree[treeItem] === 'string') {
if (this.relations[jtree[treeItem]]) {
jtree[treeItem] = this._cleanCopy(this.relations[jtree[treeItem]])
if (this.relations[resolveId][jtree[treeItem]]) {
jtree[treeItem] = this._cleanCopy(
this.relations[resolveId][jtree[treeItem]]
)
}
} else if (jtree[treeItem] && jtree[treeItem].constructor === Array) {
const stories: JSON[] = []
jtree[treeItem].forEach((uuid: string) => {
if (this.relations[uuid]) {
stories.push(this._cleanCopy(this.relations[uuid]))
if (this.relations[resolveId][uuid]) {
stories.push(this._cleanCopy(this.relations[resolveId][uuid]))
}
})
jtree[treeItem] = stories
Expand All @@ -327,7 +332,8 @@ class Storyblok {

private iterateTree(
story: ISbStoryData,
fields: string | Array<string>
fields: string | Array<string>,
resolveId: string
): void {
const enrich = (jtree: ISbStoriesParams | any) => {
if (jtree == null) {
Expand All @@ -346,9 +352,14 @@ class Storyblok {
this._insertRelations(
jtree,
treeItem as keyof ISbStoriesParams,
fields
fields,
resolveId
)
this._insertLinks(
jtree,
treeItem as keyof ISbStoriesParams,
resolveId
)
this._insertLinks(jtree, treeItem as keyof ISbStoriesParams)
}
enrich(jtree[treeItem])
}
Expand All @@ -360,7 +371,8 @@ class Storyblok {

private async resolveLinks(
responseData: ISbResponseData,
params: ISbStoriesParams
params: ISbStoriesParams,
resolveId: string
): Promise<void> {
let links: (ISbStoryData | ISbLinkURLObject | string)[] = []

Expand Down Expand Up @@ -393,13 +405,17 @@ class Storyblok {
}

links.forEach((story: ISbStoryData | any) => {
this.links[story.uuid] = { ...story, ...{ _stopResolving: true } }
this.links[resolveId][story.uuid] = {
...story,
...{ _stopResolving: true },
}
})
}

private async resolveRelations(
responseData: ISbResponseData,
params: ISbStoriesParams
params: ISbStoriesParams,
resolveId: string
): Promise<void> {
let relations = []

Expand Down Expand Up @@ -431,48 +447,62 @@ class Storyblok {

if (relations && relations.length > 0) {
relations.forEach((story: ISbStoryData) => {
this.relations[story.uuid] = { ...story, ...{ _stopResolving: true } }
this.relations[resolveId][story.uuid] = {
...story,
...{ _stopResolving: true },
}
})
}
}

private async resolveStories(
responseData: ISbResponseData,
params: ISbStoriesParams
params: ISbStoriesParams,
resolveId: string
): Promise<void> {
let relationParams: string[] = []

this.links[resolveId] = {}
this.relations[resolveId] = {}

if (
typeof params.resolve_relations !== 'undefined' &&
params.resolve_relations.length > 0
) {
if (typeof params.resolve_relations === 'string') {
relationParams = params.resolve_relations.split(',')
}
await this.resolveRelations(responseData, params)
await this.resolveRelations(responseData, params, resolveId)
}

if (
params.resolve_links &&
['1', 'story', 'url'].indexOf(params.resolve_links) > -1 &&
(responseData.links?.length || responseData.link_uuids?.length)
) {
await this.resolveLinks(responseData, params)
await this.resolveLinks(responseData, params, resolveId)
}

if (this.resolveNestedRelations) {
for (const relUuid in this.relations) {
this.iterateTree(this.relations[relUuid], relationParams)
for (const relUuid in this.relations[resolveId]) {
this.iterateTree(
this.relations[resolveId][relUuid],
relationParams,
resolveId
)
}
}

if (responseData.story) {
this.iterateTree(responseData.story, relationParams)
this.iterateTree(responseData.story, relationParams, resolveId)
} else {
responseData.stories.forEach((story: ISbStoryData) => {
this.iterateTree(story, relationParams)
this.iterateTree(story, relationParams, resolveId)
})
}

delete this.links[resolveId]
delete this.relations[resolveId]
}

private async cacheResponse(
Expand Down Expand Up @@ -522,7 +552,9 @@ class Storyblok {
}

if (response.data.story || response.data.stories) {
await this.resolveStories(response.data, params)
const resolveId = (this.resolveCounter =
++this.resolveCounter % 1000)
await this.resolveStories(response.data, params, `${resolveId}`)
}

if (params.version === 'published' && url != '/cdn/spaces/me') {
Expand Down

0 comments on commit 8cac77e

Please sign in to comment.