~cytrogen/masto-fe

3b5e302f7fc1e62cbd075e154ad9415f20fde2ce — たいち ひ 2 years ago a86886b
Rewrite `emoji_mart_data_light` as TS (#25138)

A app/javascript/mastodon/features/emoji/emoji_compressed.d.ts => app/javascript/mastodon/features/emoji/emoji_compressed.d.ts +51 -0
@@ 0,0 1,51 @@
import type { BaseEmoji, EmojiData, NimbleEmojiIndex } from 'emoji-mart';
import type { Category, Data, Emoji } from 'emoji-mart/dist-es/utils/data';

/*
 * The 'search' property, although not defined in the [`Emoji`]{@link node_modules/@types/emoji-mart/dist-es/utils/data.d.ts#Emoji} type,
 * is used in the application.
 * This could be due to an oversight by the library maintainer.
 * The `search` property is defined and used [here]{@link node_modules/emoji-mart/dist/utils/data.js#uncompress}.
 */
export type Search = string;
/*
 * The 'skins' property does not exist in the application data.
 * This could be a potential area of refactoring or error handling.
 * The non-existence of 'skins' property is evident at [this location]{@link app/javascript/mastodon/features/emoji/emoji_compressed.js:121}.
 */
export type Skins = null;

export type FilenameData = string[] | string[][];
export type ShortCodesToEmojiDataKey =
  | EmojiData['id']
  | BaseEmoji['native']
  | keyof NimbleEmojiIndex['emojis'];

export type SearchData = [
  BaseEmoji['native'],
  Emoji['short_names'],
  Search,
  Emoji['unified']
];

export interface ShortCodesToEmojiData {
  [key: ShortCodesToEmojiDataKey]: [FilenameData, SearchData];
}
export type EmojisWithoutShortCodes = FilenameData[];

export type EmojiCompressed = [
  ShortCodesToEmojiData,
  Skins,
  Category[],
  Data['aliases'],
  EmojisWithoutShortCodes
];

/*
 * `emoji_compressed.js` uses `babel-plugin-preval`, which makes it difficult to convert to TypeScript.
 * As a temporary solution, we are allowing a default export here to apply the TypeScript type `EmojiCompressed` to the JS file export.
 * - {@link app/javascript/mastodon/features/emoji/emoji_compressed.js}
 */
declare const emojiCompressed: EmojiCompressed;

export default emojiCompressed; // eslint-disable-line import/no-default-export

M app/javascript/mastodon/features/emoji/emoji_compressed.js => app/javascript/mastodon/features/emoji/emoji_compressed.js +10 -0
@@ 118,6 118,16 @@ Object.keys(emojiIndex.emojis).forEach(key => {
// inconsistent behavior in dev mode
module.exports = JSON.parse(JSON.stringify([
  shortCodesToEmojiData,
  /*
   * The property `skins` is not found in the current context.
   * This could potentially lead to issues when interacting with modules or data structures
   * that expect the presence of `skins` property.
   * Currently, no definitions or references to `skins` property can be found in:
   * - {@link node_modules/emoji-mart/dist/utils/data.js}
   * - {@link node_modules/emoji-mart/data/all.json}
   * - {@link app/javascript/mastodon/features/emoji/emoji_compressed.d.ts#Skins}
   * Future refactorings or updates should consider adding definitions or handling for `skins` property.
   */
  emojiMartData.skins,
  emojiMartData.categories,
  emojiMartData.aliases,

R app/javascript/mastodon/features/emoji/emoji_mart_data_light.js => app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts +28 -19
@@ 1,32 1,46 @@
// The output of this module is designed to mimic emoji-mart's
// "data" object, such that we can use it for a light version of emoji-mart's
// emojiIndex.search functionality.
import type { BaseEmoji } from 'emoji-mart';
import type { Emoji } from 'emoji-mart/dist-es/utils/data';

import type { Search, ShortCodesToEmojiData } from './emoji_compressed';
import emojiCompressed from './emoji_compressed';
import { unicodeToUnifiedName } from './unicode_to_unified_name';

const [ shortCodesToEmojiData, skins, categories, short_names ] = emojiCompressed;
type Emojis = {
  [key in keyof ShortCodesToEmojiData]: {
    native: BaseEmoji['native'];
    search: Search;
    short_names: Emoji['short_names'];
    unified: Emoji['unified'];
  };
};

const [
  shortCodesToEmojiData,
  skins,
  categories,
  short_names,
  _emojisWithoutShortCodes,
] = emojiCompressed;

const emojis = {};
const emojis: Emojis = {};

// decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
  let [
    filenameData, // eslint-disable-line @typescript-eslint/no-unused-vars
    searchData,
  ] = shortCodesToEmojiData[shortCode];
  let [
    native,
    short_names,
    search,
    unified,
  ] = searchData;
  const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
  const native = searchData[0];
  let short_names = searchData[1];
  const search = searchData[2];
  let unified = searchData[3];

  if (!unified) {
    // unified name can be derived from unicodeToUnifiedName
    unified = unicodeToUnifiedName(native);
  }

  short_names = [shortCode].concat(short_names);
  if (short_names) short_names = [shortCode].concat(short_names);
  emojis[shortCode] = {
    native,
    search,


@@ 35,9 49,4 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
  };
});

export {
  emojis,
  skins,
  categories,
  short_names,
};
export { emojis, skins, categories, short_names };