Skip to content

Commit

Permalink
perf: optimize tree shaking with readonly objects
Browse files Browse the repository at this point in the history
  • Loading branch information
standy authored and anmostovoy committed Feb 12, 2020
1 parent 6caf03d commit 84a7671
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 41 deletions.
32 changes: 24 additions & 8 deletions locale/da/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
FormatByTemplateFn,
ParseByTemplateFn,
ParseByTemplateOrThrowFn,
Formatter,
ParserData,
} from '../../src/utils/basic-types';
import {extend} from '../../src/utils/utils';
export * from '../../src/default-exports';
Expand Down Expand Up @@ -59,13 +61,19 @@ export const formatters: FormatterObj = {

// a.m., p.m.
aa: date => meridiemFull[date.getHours() < 12 ? 0 : 1],

Mo: ordinalFormatter('M'),
Do: ordinalFormatter('D'),
DDDo: ordinalFormatter('DDD'),
do: ordinalFormatter('d'),
Qo: ordinalFormatter('Q'),
Wo: ordinalFormatter('W'),
};

// Generate ordinal version of formatters: M -> Mo, D -> Do, etc.
const ordinalFormatters = ['M', 'D', 'DDD', 'd', 'Q', 'W'];
ordinalFormatters.forEach(formatterToken => {
formatters[formatterToken + 'o'] = date => ordinal(defaultFormatters[formatterToken](date) as number);
});
function ordinalFormatter(formatterToken: string): Formatter {
return date => ordinal(defaultFormatters[formatterToken](date) as number);
}

function ordinal(number: number) {
return number + '.';
Expand Down Expand Up @@ -95,16 +103,24 @@ const parsers: ParserObj = {
date.setMonth(index);
},
],

Mo: ordinalParser('M'),
Do: ordinalParser('D'),
DDDo: ordinalParser('DDD'),
do: ordinalParser('d'),
Qo: ordinalParser('Q'),
Wo: ordinalParser('W'),
};

ordinalFormatters.forEach(formatterToken => {
parsers[formatterToken + 'o'] = [
// Generate ordinal version of parsers: M -> Mo, D -> Do, etc.
function ordinalParser(token: string): ParserData {
return [
'\\d+(?:[.])',
(date, value) => {
defaultParsers[formatterToken][1](date, value.slice(0, -1));
defaultParsers[token][1](date, value.slice(0, -1));
},
];
});
}

export const format: FormatByTemplateFn = createFormat(extend(defaultFormatters, formatters));
export const createCustomFormat = createCustomFormatFn(extend(defaultFormatters, formatters));
Expand Down
39 changes: 28 additions & 11 deletions locale/en/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
FormatByTemplateFn,
ParseByTemplateFn,
ParseByTemplateOrThrowFn,
ParserData,
Formatter,
} from '../../src/utils/basic-types';
import {extend} from '../../src/utils/utils';
export * from '../../src/default-exports';
Expand Down Expand Up @@ -62,13 +64,19 @@ export const formatters: FormatterObj = {

// a.m., p.m.
aa: date => meridiemFull[date.getHours() < 12 ? 0 : 1],

Mo: ordinalFormatter('M'),
Do: ordinalFormatter('D'),
DDDo: ordinalFormatter('DDD'),
do: ordinalFormatter('d'),
Qo: ordinalFormatter('Q'),
Wo: ordinalFormatter('W'),
};

// Generate ordinal version of formatters: M -> Mo, D -> Do, etc.
const ordinalFormatters = ['M', 'D', 'DDD', 'd', 'Q', 'W'];
ordinalFormatters.forEach(formatterToken => {
formatters[formatterToken + 'o'] = date => ordinal(defaultFormatters[formatterToken](date) as number);
});
function ordinalFormatter(formatterToken: string): Formatter {
return date => ordinal(defaultFormatters[formatterToken](date) as number);
}

function ordinal(number: number) {
const rem100 = number % 100;
Expand All @@ -90,6 +98,7 @@ function toLower(s: string) {
}
const months3charLower = months3char.map(toLower);
const monthsFullLower = monthsFull.map(toLower);

const parsers: ParserObj = {
// Month: Jan, Feb, ..., Dec
MMM: [
Expand All @@ -109,18 +118,26 @@ const parsers: ParserObj = {
date.setMonth(index);
},
],

Mo: ordinalParser('M'),
Do: ordinalParser('D'),
DDDo: ordinalParser('DDD'),
do: ordinalParser('d'),
Qo: ordinalParser('Q'),
Wo: ordinalParser('W'),
};

ordinalFormatters.forEach(formatterToken => {
parsers[formatterToken + 'o'] = [
// Generate ordinal version of parsers: M -> Mo, D -> Do, etc.
function ordinalParser(token: string): ParserData {
return [
'\\d+(?:st|nd|rd)',
(date, value) => {
defaultParsers[formatterToken][1](date, value.slice(0, -2));
defaultParsers[token][1](date, value.slice(0, -2));
},
];
});
}

export const format: FormatByTemplateFn = createFormat(extend(defaultFormatters, formatters));
export const createCustomFormat = createCustomFormatFn(extend(defaultFormatters, formatters));
export const parse: ParseByTemplateFn = createParse(extend(defaultParsers, parsers));
export const format: FormatByTemplateFn = createFormat(/*@__PURE__*/ extend(defaultFormatters, formatters));
export const createCustomFormat = createCustomFormatFn(/*@__PURE__*/ extend(defaultFormatters, formatters));
export const parse: ParseByTemplateFn = createParse(/*@__PURE__*/ extend(defaultParsers, parsers));
export const parseOrThrow: ParseByTemplateOrThrowFn = parseOrThrowWrapper(parse);
35 changes: 19 additions & 16 deletions locale/ru/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ParserData,
} from '../../src/utils/basic-types';
import {extend} from '../../src/utils/utils';
import {ValidDate} from '../../src/valid-date';
export * from '../../src/default-exports';

// http://new.gramota.ru/spravka/buro/search-answer?s=242637
Expand Down Expand Up @@ -48,6 +49,19 @@ const weekdays3char = ['вск', 'пнд', 'втр', 'срд', 'чтв', 'птн
const weekdaysFull = ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'];
const meridiem = ['ночи', 'утра', 'дня', 'вечера'];

function timeOfDay(date: ValidDate) {
const hours = date.getHours();
if (hours >= 17) {
return meridiem[3];
} else if (hours >= 12) {
return meridiem[2];
} else if (hours >= 4) {
return meridiem[1];
} else {
return meridiem[0];
}
}

export const formatters: FormatterObj = {
// Month: янв., фев., ..., дек.
MMM: date => monthsShort[date.getMonth()],
Expand Down Expand Up @@ -79,18 +93,9 @@ export const formatters: FormatterObj = {
dddd: date => weekdaysFull[date.getDay()],

// Time of day: ночи, утра, дня, вечера
A: date => {
const hours = date.getHours();
if (hours >= 17) {
return meridiem[3];
} else if (hours >= 12) {
return meridiem[2];
} else if (hours >= 4) {
return meridiem[1];
} else {
return meridiem[0];
}
},
A: timeOfDay,
a: timeOfDay,
aa: timeOfDay,

// Generate ordinal version of formatters: M -> Mo, DDD -> DDDo, etc.
Do: date => defaultFormatters['D'](date) + '-е',
Expand All @@ -103,8 +108,6 @@ export const formatters: FormatterObj = {
'Do MMMM': date => formatters['Do'](date) + ' ' + monthsGenitive[date.getMonth()],
};

formatters['a'] = formatters['aa'] = formatters['A'];

const parsers: ParserObj = {
// Month: янв., фев., ..., дек.
MMM: [
Expand Down Expand Up @@ -136,11 +139,11 @@ const parsers: ParserObj = {
Qo: ordinalParser('Q', '-й'),
};

function ordinalParser(key: string, suffix: string): ParserData {
function ordinalParser(token: string, suffix: string): ParserData {
return [
'\\d+' + suffix,
(date, value) => {
defaultParsers[key][1](date, value.slice(0, -suffix.length));
defaultParsers[token][1](date, value.slice(0, -suffix.length));
},
];
}
Expand Down
2 changes: 1 addition & 1 deletion src/format/create-format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {isValidDate} from '../default-exports';
type Token = string | Formatter;

function splitToTokens(template: string, formatters: FormatterObj): Token[] {
const RX_TOKENS = tokensRx(formatters);
const RX_TOKENS = /*@__PURE__*/tokensRx(formatters);
const tokens = template.match(RX_TOKENS) as string[];
// this regexp cant fail because of "|."

Expand Down
2 changes: 1 addition & 1 deletion src/format/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ export const format: FormatByTemplateFn = createFormat(commonFormatters);
*/
export function extendFormat(formatters: FormatterObj) {
for (const key in formatters) {
commonFormatters[key] = formatters[key];
(commonFormatters as any)[key] = formatters[key];
}
}
2 changes: 1 addition & 1 deletion src/parse/create-parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function escapeRegExp(text: string) {
}

export function createParse(parsers: ParserObj): ParseByTemplateFn {
const RX_TOKENS = tokensRx(parsers);
const RX_TOKENS = /*@__PURE__*/tokensRx(parsers);

return function parse(dateStr: string, template: string): ValidDate | null {
const tokens = template.match(RX_TOKENS) as string[];
Expand Down
6 changes: 3 additions & 3 deletions src/utils/basic-types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ValidDate} from '../valid-date';

export const enum MS {
Milliseconds = 1, // 1000;
Milliseconds = 1, // 1;
Seconds = 1e3, // 1000;
Minutes = 6e4, // 1000 * 60;
Hours = 36e5, // 1000 * 60 * 60;
Expand Down Expand Up @@ -40,8 +40,8 @@ export interface ParseByTemplateOrThrowFn {
}

export type Formatter = (date: ValidDate, index?: number, tokens?: (string | Formatter)[]) => string | number;
export type FormatterObj = {[key: string]: Formatter};
export type FormatterObj = Readonly<Record<string, Formatter>>;

export type Parser = (date: Date, value: string) => void;
export type ParserData = [string, Parser];
export type ParserObj = {[key: string]: ParserData};
export type ParserObj = Readonly<Record<string, ParserData>>;

0 comments on commit 84a7671

Please sign in to comment.