Skip to content

Commit

Permalink
feat(core): add caching to Moji#find
Browse files Browse the repository at this point in the history
  • Loading branch information
ifiokjr committed Jan 17, 2021
1 parent 9599f2d commit 192504e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/rude-carpets-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@svgmoji/core': minor
---

Add support for passing a flat emoji object to the `url` method of `Moji`. This can lead to a performance boost in some cases.
5 changes: 5 additions & 0 deletions .changeset/soft-trains-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@svgmoji/core': minor
---

Add caching to the `Moji#find` method. Now the second time a search is made for the same code, it will be retrieved from the cache.
31 changes: 24 additions & 7 deletions packages/svgmoji__core/src/base-moji.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { matchSorter, rankings } from 'match-sorter';

import type { SpriteCollectionType } from './constants';
import { SpriteCollection } from './constants';
import { isMinifiedEmojiList } from './core-utils';
import { isFlatEmoji, isMinifiedEmojiList } from './core-utils';
import { populateMinifiedEmoji } from './populate-minified-emoji';
import type { FlatEmoji, MinifiedEmoji } from './types';

Expand Down Expand Up @@ -61,8 +61,13 @@ export abstract class Moji {
*/
fallback: FlatEmoji;

/**
* Cache the results for finding an emoji.
*/
readonly #findCache = new Map<string, FlatEmoji | undefined>();

get cdn(): string {
return `https://cdn.jsdelivr.net/npm/@svgmoji/${this.name}@${this.version}/`;
return `https://cdn.jsdelivr.net/npm/@svgmoji/${this.name}@${this.version}`;
}

get fallbackUrl(): string {
Expand Down Expand Up @@ -90,11 +95,12 @@ export abstract class Moji {
/**
* Get the CDN url from the provided emoji hexcode, emoticon or unicode string.
*/
url(emoji: FlatEmoji): string;
url(code: string, options: { fallback: false }): string | undefined;
url(code: string, options?: { fallback?: true }): string;
url(code: string, options: { fallback?: boolean } = {}): string | undefined {
url(code: string | FlatEmoji, options: { fallback?: boolean } = {}): string | undefined {
const { fallback = true } = options;
const emoji = this.find(code);
const emoji = isFlatEmoji(code) ? code : this.find(code);
const fallbackUrl = fallback ? this.fallbackUrl : undefined;

if (!emoji) {
Expand All @@ -109,12 +115,12 @@ export abstract class Moji {
return `${this.cdn}/svg/${emoji.hexcode}.svg`;
}

if (this.type === SpriteCollection.Group && emoji?.group) {
if (this.type === SpriteCollection.Group && emoji.group != null) {
const name = groups[emoji.group] ?? 'other';
return `${this.cdn}/sprites/group/${name}.svg#${emoji.hexcode}`;
}

if (this.type === SpriteCollection.Subgroup && emoji?.subgroup) {
if (this.type === SpriteCollection.Subgroup && emoji.subgroup != null) {
const name = subgroups[emoji.subgroup] ?? 'other';
return `${this.cdn}/sprites/subgroup/${name}.svg#${emoji.hexcode}`;
}
Expand All @@ -126,6 +132,10 @@ export abstract class Moji {
* Get an the emoji object of a value by it's hexcode, emoticon or unicode string.
*/
find(code: string): FlatEmoji | undefined {
if (this.#findCache.has(code)) {
return this.#findCache.get(code);
}

for (const emoji of this.data) {
if (
// This is a native emoji match
Expand All @@ -141,11 +151,14 @@ export abstract class Moji {
// The provided code matches the emoticon.
(emoji.emoticon && generateEmoticonPermutations(emoji.emoticon).includes(code))
) {
this.#findCache.set(code, emoji);
return emoji;
}
}

// No matches were found in the data.
// eslint-disable-next-line unicorn/no-useless-undefined
this.#findCache.set(code, undefined);
return;
}

Expand All @@ -156,6 +169,10 @@ export abstract class Moji {
const { excludeTone } = { ...DEFAULT_OPTIONS, ...options };
const data = excludeTone ? this.tonelessData : this.data;

if (!query) {
return data;
}

return matchSorter(data, query, {
threshold: rankings.WORD_STARTS_WITH,
keys: [
Expand Down Expand Up @@ -187,7 +204,7 @@ export abstract class Moji {
}

const DEFAULT_OPTIONS: Required<BaseMojiProps> = {
excludeTone: true,
excludeTone: false,
};

interface BaseMojiProps {
Expand Down

0 comments on commit 192504e

Please sign in to comment.