From 3f0f342a6dfb524370e718be0ce937ad39e2a91d Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 13:25:05 +0300 Subject: [PATCH 01/16] feat(url): add url tools --- .size-limit.json | 4 ++ README.md | 3 +- packages/url/README.md | 15 +++++ packages/url/index.test.ts | 130 +++++++++++++++++++++++++++++++++++++ packages/url/index.ts | 130 +++++++++++++++++++++++++++++++++++++ packages/url/package.json | 12 ++++ packages/url/tsconfig.json | 9 +++ packages/url/typedoc.json | 5 ++ 8 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 packages/url/README.md create mode 100644 packages/url/index.test.ts create mode 100644 packages/url/index.ts create mode 100644 packages/url/package.json create mode 100644 packages/url/tsconfig.json create mode 100644 packages/url/typedoc.json diff --git a/.size-limit.json b/.size-limit.json index d6bf74a..27fabe8 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -10,5 +10,9 @@ { "path": "packages/session-storage/dist/index.js", "limit": "290 B" + }, + { + "path": "packages/url/dist/index.js", + "limit": "675 B" } ] diff --git a/README.md b/README.md index 6357652..b7962c5 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,10 @@ Common utils used by Rambler team ## Packages - [@rambler-tech/cookie-storage](packages/cookie-storage) +- [@rambler-tech/lhci-report](packages/lhci-report) - [@rambler-tech/local-storage](packages/local-storage) - [@rambler-tech/session-storage](packages/session-storage) -- [@rambler-tech/lhci-report](packages/lhci-report) +- [@rambler-tech/url](packages/url) ## Contributing diff --git a/packages/url/README.md b/packages/url/README.md new file mode 100644 index 0000000..79356d1 --- /dev/null +++ b/packages/url/README.md @@ -0,0 +1,15 @@ +# URL tools + +Enhanced tools for URL conversion + +## Install + +``` +npm install -D @rambler-tech/url +``` + +or + +``` +yarn add -D @rambler-tech/url +``` diff --git a/packages/url/index.test.ts b/packages/url/index.test.ts new file mode 100644 index 0000000..b501652 --- /dev/null +++ b/packages/url/index.test.ts @@ -0,0 +1,130 @@ +import { + getUrlParams, + getUrlHashParams, + addUrlParams, + removeUrlHash, + removeUrlNullableParams, + formatUrl, + encodeURIComponentRFC3986 +} from '.' + +test('getUrlParams: valid url', () => { + const href = 'https://foo.bar?action=login&provider=provider' + + expect(getUrlParams(href)).toEqual({ + action: 'login', + provider: 'provider' + }) +}) + +test('getUrlParams: valid url with empty search params', () => { + const href = 'https://foo.bar' + + expect(getUrlParams(href)).toEqual({}) +}) + +test('getUrlHashParams: valid url', () => { + const href = 'https://foo.bar#action=login&provider=provider' + + expect(getUrlHashParams(href)).toEqual({ + action: 'login', + provider: 'provider' + }) +}) + +test('getUrlHashParams: valid url with empty hash', () => { + const href = 'https://foo.baz' + + expect(getUrlHashParams(href)).toEqual({}) +}) + +test('addUrlParams with search params', () => { + expect( + addUrlParams('https://foo.bar/', { + logged: false, + action: 'login', + provider: 'provider' + }) + ).toEqual('https://foo.bar/?logged=false&action=login&provider=provider') +}) + +test('addUrlParams with cleaned search params', () => { + expect( + addUrlParams('https://foo.bar/', { + logged: false, + action: 'login', + provider: 'provider', + test: undefined, + foobar: null + }) + ).toEqual('https://foo.bar/?logged=false&action=login&provider=provider') +}) + +test('addUrlParams with hash', () => { + expect( + addUrlParams( + 'https://foo.bar/?test=test#bar=baz', + { + logged: false, + action: 'login', + provider: 'provider' + }, + {foo: 'bar'} + ) + ).toEqual( + 'https://foo.bar/?test=test&logged=false&action=login&provider=provider#bar=baz&foo=bar' + ) +}) + +test('removeUrlHash', () => { + const href = 'https://foo.bar/baz/?foo=bar' + + expect(removeUrlHash(href)).toEqual(href) + expect(removeUrlHash('https://foo.bar/baz/?foo=bar#foo=bar')).toEqual(href) +}) + +test('should clean query', () => { + expect( + removeUrlNullableParams({test: undefined, foo: 'bar', bar: undefined}) + ).toEqual({ + foo: 'bar' + }) +}) + +test('should format url', () => { + expect( + formatUrl({ + pathname: '/login', + query: { + email: 'testbar.ru', + rname: undefined, + src: null, + type: 'test', + back: 'back.ru' + } + }) + ).toBe('/login?email=testbar.ru&type=test&back=back.ru') +}) + +test('should format full url', () => { + expect( + formatUrl({ + protocol: 'https:', + host: 'somehost.com', + pathname: '/login', + query: { + email: 'testbar.ru', + rname: undefined, + src: null, + type: 'test', + back: 'back.ru' + } + }) + ).toBe('https://somehost.com/login?email=testbar.ru&type=test&back=back.ru') +}) + +test('should encode with RFC 3986 standard', () => { + expect(encodeURIComponentRFC3986('my file(2).txt')).toBe( + 'my%20file%282%29.txt' + ) +}) diff --git a/packages/url/index.ts b/packages/url/index.ts new file mode 100644 index 0000000..6bea03d --- /dev/null +++ b/packages/url/index.ts @@ -0,0 +1,130 @@ +/* eslint-disable import/no-unused-modules */ + +export type ParsedQuery = Record + +export type Query = Record + +interface UrlObject { + protocol?: string | null + host?: string | null + pathname?: string | null + query?: string | Query | null +} + +/** Format URL to string */ +export function formatUrl(urlObject: UrlObject): string { + const {protocol, host, pathname, query} = urlObject + + let cleanedQueryString + + if (query && typeof query === 'object') { + // NOTE: remove undefined or null values from query + const cleanedQuery = removeUrlNullableParams(query) + + cleanedQueryString = new URLSearchParams(cleanedQuery).toString() + } else { + cleanedQueryString = query + } + + return ( + (protocol ? `${protocol}//` : '') + + (host ?? '') + + pathname + + (cleanedQueryString ? `?${cleanedQueryString}` : '') + ) +} + +/** Get URL query params */ +export function getUrlParams(url: string): ParsedQuery { + const searchParams: ParsedQuery = {} + + const {searchParams: iterableSearchParams} = new URL(url) + + iterableSearchParams.forEach((value, key) => { + searchParams[key] = value + }) + + return searchParams +} + +/** Get URL hash params */ +export function getUrlHashParams(url: string): ParsedQuery { + const hashParams: ParsedQuery = {} + + const {hash} = new URL(url) + const iterableHashParams = new URLSearchParams(hash.substring(1)) + + iterableHashParams.forEach((value, key) => { + hashParams[key] = value + }) + + return hashParams +} + +/** Add URL query params */ +export function addUrlParams( + url: string, + searchParams: Query, + hashParams?: Query +): string { + if ( + !Object.keys(searchParams).length && + (!hashParams || !Object.keys(hashParams).length) + ) + return url + + const {protocol, host, pathname} = new URL(url) + + const initialSearchParams = getUrlParams(url) + const mergedSearchParams = removeUrlNullableParams({ + ...initialSearchParams, + ...searchParams + }) + + const search = new URLSearchParams(mergedSearchParams).toString() + const urlSearch = search ? `?${search}` : '' + + const initialHashParams = getUrlHashParams(url) + const mergedHashParams = removeUrlNullableParams({ + ...initialHashParams, + ...hashParams + }) + + const hash = new URLSearchParams(mergedHashParams).toString() + const urlHash = hash ? `#${hash}` : '' + + return `${protocol}//${host}${pathname}${urlSearch}${urlHash}` +} + +/** Remove URL nullable query params (`null` or `undefined`) */ +export function removeUrlNullableParams(query: T): T { + const resultQuery: Query = {} + + Object.keys(query).forEach((key) => { + if (query[key] != null) { + resultQuery[key] = query[key] + } + }) + + return resultQuery as T +} + +/** Remove URL hash */ +export function removeUrlHash(url: string): string { + const {protocol, host, pathname, search} = new URL(url) + + return `${protocol}//${host}${pathname}${search}` +} + +/** + * Encode URI for RFC3986 + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent + */ +export function encodeURIComponentRFC3986(value: string): string { + return encodeURIComponent(value).replace( + /[!'()*]/g, + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + (c) => `%${c.charCodeAt(0).toString(16)}` + ) +} diff --git a/packages/url/package.json b/packages/url/package.json new file mode 100644 index 0000000..b92fa95 --- /dev/null +++ b/packages/url/package.json @@ -0,0 +1,12 @@ +{ + "name": "@rambler-tech/url", + "version": "0.0.0", + "main": "dist", + "module": "dist", + "types": "dist/index.d.ts", + "license": "MIT", + "sideEffects": false, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/url/tsconfig.json b/packages/url/tsconfig.json new file mode 100644 index 0000000..b81d8e5 --- /dev/null +++ b/packages/url/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "outDir": "dist" + }, + "include": [".", "../../types"] +} diff --git a/packages/url/typedoc.json b/packages/url/typedoc.json new file mode 100644 index 0000000..fd9d16b --- /dev/null +++ b/packages/url/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": "@rambler-tech/typedoc-config", + "readme": "../../README.md", + "entryPoints": ["./index.ts"] +} From 4403ec3f6c6b49749818ff0bae6a20b033c0cd04 Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 10:59:56 +0000 Subject: [PATCH 02/16] chore(release): publish - @rambler-tech/url@0.1.0 --- packages/url/CHANGELOG.md | 10 ++++++++++ packages/url/package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/url/CHANGELOG.md diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md new file mode 100644 index 0000000..8b8b9f5 --- /dev/null +++ b/packages/url/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2024-08-14) + +### Features + +- **url:** add url tools ([3f0f342](https://github.com/rambler-digital-solutions/rambler-common/commit/3f0f342a6dfb524370e718be0ce937ad39e2a91d)) diff --git a/packages/url/package.json b/packages/url/package.json index b92fa95..cba39b0 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/url", - "version": "0.0.0", + "version": "0.1.0", "main": "dist", "module": "dist", "types": "dist/index.d.ts", From 946d5baf89b77fa07f9845ef68e3d8f5b6d7dd5f Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 14:29:52 +0300 Subject: [PATCH 03/16] feat(async): add async tools --- .size-limit.json | 4 ++ README.md | 1 + packages/async/README.md | 15 ++++++ packages/async/index.test.ts | 88 ++++++++++++++++++++++++++++++++++++ packages/async/index.ts | 58 ++++++++++++++++++++++++ packages/async/package.json | 12 +++++ packages/async/tsconfig.json | 9 ++++ packages/async/typedoc.json | 5 ++ 8 files changed, 192 insertions(+) create mode 100644 packages/async/README.md create mode 100644 packages/async/index.test.ts create mode 100644 packages/async/index.ts create mode 100644 packages/async/package.json create mode 100644 packages/async/tsconfig.json create mode 100644 packages/async/typedoc.json diff --git a/.size-limit.json b/.size-limit.json index 27fabe8..447411b 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -1,4 +1,8 @@ [ + { + "path": "packages/async/dist/index.js", + "limit": "400 B" + }, { "path": "packages/cookie-storage/dist/index.js", "limit": "990 B" diff --git a/README.md b/README.md index b7962c5..8d34b48 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Common utils used by Rambler team ## Packages +- [@rambler-tech/async](packages/async) - [@rambler-tech/cookie-storage](packages/cookie-storage) - [@rambler-tech/lhci-report](packages/lhci-report) - [@rambler-tech/local-storage](packages/local-storage) diff --git a/packages/async/README.md b/packages/async/README.md new file mode 100644 index 0000000..67c016e --- /dev/null +++ b/packages/async/README.md @@ -0,0 +1,15 @@ +# Async + +Async tools + +## Install + +``` +npm install -D @rambler-tech/async +``` + +or + +``` +yarn add -D @rambler-tech/async +``` diff --git a/packages/async/index.test.ts b/packages/async/index.test.ts new file mode 100644 index 0000000..1510b7c --- /dev/null +++ b/packages/async/index.test.ts @@ -0,0 +1,88 @@ +import {retry, wait} from '.' + +test('retry resolved promise', async () => { + const fn = jest.fn((...args) => Promise.resolve(args)) + const args = [1, 2, 3] + const result = await retry(fn)(...args) + + expect(result).toEqual(args) + expect(fn).toHaveBeenCalledTimes(1) +}) + +test('retry rejected and last resolved promise', async () => { + let counter = 0 + const fn = jest.fn((...args) => + counter++ > 1 ? Promise.resolve(args) : Promise.reject(new Error('error')) + ) + const args = [1, 2, 3] + const result = await retry(fn, {retries: 3, timeout: 10})(...args) + + expect(result).toEqual(args) + expect(fn).toHaveBeenCalledTimes(3) +}) + +test('retry rejected and ignore rejected with specific error', async () => { + let counter = 0 + const fn = jest.fn(() => + Promise.reject( + new Error(counter++ > 0 ? 'aborted by timeout' : 'yet another error') + ) + ) + + const error = await retry(fn, { + retries: 3, + timeout: 10, + shouldRetry: (error) => !error.toString().match(/aborted/) + })().catch((error) => error) + + expect(error.message).toBe('aborted by timeout') + expect(fn).toHaveBeenCalledTimes(2) +}) + +test('retry rejected promise', async () => { + const fn = jest.fn(() => Promise.reject(new Error('failed'))) + const error = await retry(fn, {retries: 3, timeout: 10})().catch( + (error) => error + ) + + expect(error.message).toBe('failed') + expect(fn).toHaveBeenCalledTimes(3) +}) + +test('abort retry', async () => { + const abortController = new AbortController() + const fn = jest.fn(() => Promise.reject(new Error('failed'))) + const promise = retry(fn, { + retries: 3, + timeout: 10, + signal: abortController.signal + })() + + // NOTE: simulate microtask to abort wait after first attempt + await Promise.resolve().then(() => abortController.abort()) + + const error = await promise.catch((error) => error) + + expect(error.message).toBe('The user aborted a timeout.') + expect(fn).toHaveBeenCalledTimes(1) +}) + +test('wait timeout', () => { + jest.useFakeTimers() + jest.spyOn(global, 'setTimeout') + + const promise = wait(1000) + + jest.advanceTimersByTime(1000) + + expect(promise).resolves.toBeUndefined() +}) + +test('aborted wait timeout', () => { + const abortController = new AbortController() + const promise = wait(1000, abortController.signal) + + abortController.abort() + + expect(promise).rejects.toThrow('The user aborted a timeout.') +}) diff --git a/packages/async/index.ts b/packages/async/index.ts new file mode 100644 index 0000000..942aae1 --- /dev/null +++ b/packages/async/index.ts @@ -0,0 +1,58 @@ +/* eslint-disable import/no-unused-modules */ + +const RETRIES_LEFT = 3 +const INTERVAL = 500 + +export type PromiseFactory = (...args: any[]) => Promise + +/** Retry options */ +export interface RetryOptions { + /** Maximum amount of times to retry the operation, default is 3 */ + retries?: number + /** Number of milliseconds before starting the retry, default is 500 */ + timeout?: number + /** Check an error to need retry, by default retry on every error */ + shouldRetry?: (error: Error) => boolean + /** AbortSignal instance to abort retry via an AbortController */ + signal?: AbortSignal +} + +/** Retry function call */ +export function retry( + factory: PromiseFactory, + options: RetryOptions = {} +): PromiseFactory { + let {retries = RETRIES_LEFT} = options + const {timeout = INTERVAL, shouldRetry = () => true, signal} = options + + async function call(...args: any[]): Promise { + try { + return await factory(...args) + } catch (error: any) { + if (--retries < 1 || !shouldRetry(error)) { + throw error + } + + await wait(timeout, signal) + + return call(...args) + } + } + + return (...args: any[]): Promise => call(...args) +} + +/** Wait function call */ +export function wait(timeout: number, signal?: AbortSignal): Promise { + return new Promise((resolve, reject) => { + const timeoutId = window.setTimeout(resolve, timeout) + + signal?.addEventListener('abort', () => { + if (timeoutId) { + clearTimeout(timeoutId) + } + + reject(new DOMException('The user aborted a timeout.', 'AbortError')) + }) + }) +} diff --git a/packages/async/package.json b/packages/async/package.json new file mode 100644 index 0000000..3933ede --- /dev/null +++ b/packages/async/package.json @@ -0,0 +1,12 @@ +{ + "name": "@rambler-tech/async", + "version": "0.0.0", + "main": "dist", + "module": "dist", + "types": "dist/index.d.ts", + "license": "MIT", + "sideEffects": false, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/async/tsconfig.json b/packages/async/tsconfig.json new file mode 100644 index 0000000..b81d8e5 --- /dev/null +++ b/packages/async/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "outDir": "dist" + }, + "include": [".", "../../types"] +} diff --git a/packages/async/typedoc.json b/packages/async/typedoc.json new file mode 100644 index 0000000..fd9d16b --- /dev/null +++ b/packages/async/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": "@rambler-tech/typedoc-config", + "readme": "../../README.md", + "entryPoints": ["./index.ts"] +} From 1558e3e2f31cbb2539ca6ff10f92d08fa44b139c Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 15:00:37 +0300 Subject: [PATCH 04/16] feat(dom): add dom utils --- .size-limit.json | 4 +++ README.md | 1 + packages/dom/README.md | 15 ++++++++ packages/dom/index.test.ts | 32 +++++++++++++++++ packages/dom/index.ts | 73 ++++++++++++++++++++++++++++++++++++++ packages/dom/package.json | 12 +++++++ packages/dom/tsconfig.json | 9 +++++ packages/dom/typedoc.json | 5 +++ 8 files changed, 151 insertions(+) create mode 100644 packages/dom/README.md create mode 100644 packages/dom/index.test.ts create mode 100644 packages/dom/index.ts create mode 100644 packages/dom/package.json create mode 100644 packages/dom/tsconfig.json create mode 100644 packages/dom/typedoc.json diff --git a/.size-limit.json b/.size-limit.json index 27fabe8..436fbb7 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -3,6 +3,10 @@ "path": "packages/cookie-storage/dist/index.js", "limit": "990 B" }, + { + "path": "packages/dom/dist/index.js", + "limit": "500 B" + }, { "path": "packages/local-storage/dist/index.js", "limit": "290 B" diff --git a/README.md b/README.md index b7962c5..fbb052c 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Common utils used by Rambler team ## Packages - [@rambler-tech/cookie-storage](packages/cookie-storage) +- [@rambler-tech/dom](packages/dom) - [@rambler-tech/lhci-report](packages/lhci-report) - [@rambler-tech/local-storage](packages/local-storage) - [@rambler-tech/session-storage](packages/session-storage) diff --git a/packages/dom/README.md b/packages/dom/README.md new file mode 100644 index 0000000..f53c629 --- /dev/null +++ b/packages/dom/README.md @@ -0,0 +1,15 @@ +# DOM + +DOM utils + +## Install + +``` +npm install -D @rambler-tech/dom +``` + +or + +``` +yarn add -D @rambler-tech/dom +``` diff --git a/packages/dom/index.test.ts b/packages/dom/index.test.ts new file mode 100644 index 0000000..f2ca4a6 --- /dev/null +++ b/packages/dom/index.test.ts @@ -0,0 +1,32 @@ +import {injectStyleSheet} from '.' + +test('inject style', () => { + const button = document.createElement('button') + + button.className = 'test-button' + + document.body.appendChild(button) + + expect(window.getComputedStyle(button).display).toBe('inline-block') + + injectStyleSheet('.test-button {display: flex;}') + + expect(window.getComputedStyle(button).display).toBe('flex') +}) + +test('inject style with attributes', () => { + const button = document.createElement('button') + + button.className = 'test-button-2' + + document.body.appendChild(button) + + expect(window.getComputedStyle(button).display).toBe('inline-block') + + const style = injectStyleSheet('.test-button-2 {display: flex;}', { + 'data-scope': 'button' + }) + + expect(window.getComputedStyle(button).display).toBe('flex') + expect(style.getAttribute('data-scope')).toBe('button') +}) diff --git a/packages/dom/index.ts b/packages/dom/index.ts new file mode 100644 index 0000000..b0067eb --- /dev/null +++ b/packages/dom/index.ts @@ -0,0 +1,73 @@ +/* eslint-disable import/no-unused-modules */ + +/** Inject style sheet to DOM */ +export function injectStyleSheet( + cssText: string, + attributes: Record = {} +): HTMLStyleElement { + const style = document.createElement('style') + + style.textContent = cssText + + if (attributes) { + Object.entries(attributes).forEach(([name, value]) => { + style.setAttribute(name, value) + }) + } + + return document.head.appendChild(style) +} + +const REGISTRY = '__ASSETS_REGISTRY__' + +declare const globalThis: any +globalThis[REGISTRY] = {} + +/** Load style sheet */ +export function loadStyleSheet(source: string): Promise { + globalThis[REGISTRY][source] ??= new Promise( + (resolve, reject) => { + const link = document.createElement('link') + + link.rel = 'stylesheet' + link.href = source + + link.onload = () => { + resolve(link) + } + + link.onerror = () => { + reject(new Error(`stylesheet not loaded: ${source}`)) + } + + document.head.appendChild(link) + } + ) + + return globalThis[REGISTRY][source] +} + +/** Load script */ +export function loadScript(source: string): Promise { + globalThis[REGISTRY][source] ??= new Promise( + (resolve, reject) => { + const script = document.createElement('script') + + script.src = source + script.async = true + script.type = 'text/javascript' + + script.onload = () => { + resolve(script) + } + + script.onerror = () => { + reject(new Error(`script not loaded: ${source}`)) + } + + document.body.appendChild(script) + } + ) + + return globalThis[REGISTRY][source] +} diff --git a/packages/dom/package.json b/packages/dom/package.json new file mode 100644 index 0000000..5ac09dd --- /dev/null +++ b/packages/dom/package.json @@ -0,0 +1,12 @@ +{ + "name": "@rambler-tech/dom", + "version": "0.0.0", + "main": "dist", + "module": "dist", + "types": "dist/index.d.ts", + "license": "MIT", + "sideEffects": false, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/dom/tsconfig.json b/packages/dom/tsconfig.json new file mode 100644 index 0000000..b81d8e5 --- /dev/null +++ b/packages/dom/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "outDir": "dist" + }, + "include": [".", "../../types"] +} diff --git a/packages/dom/typedoc.json b/packages/dom/typedoc.json new file mode 100644 index 0000000..fd9d16b --- /dev/null +++ b/packages/dom/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": "@rambler-tech/typedoc-config", + "readme": "../../README.md", + "entryPoints": ["./index.ts"] +} From 2a41f6f40a5ed7bb2d8eff9d1301d99b025b9251 Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 15:35:07 +0300 Subject: [PATCH 05/16] feat(react): add react tools --- .size-limit.json | 4 ++ README.md | 1 + packages/react/README.md | 15 ++++++++ packages/react/error-boundary.tsx | 46 +++++++++++++++++++++++ packages/react/index.ts | 9 +++++ packages/react/package.json | 21 +++++++++++ packages/react/ssr.ts | 2 + packages/react/tsconfig.json | 9 +++++ packages/react/typedoc.json | 5 +++ packages/react/use-click-outside.ts | 37 ++++++++++++++++++ packages/react/use-countdown-timer.ts | 54 +++++++++++++++++++++++++++ packages/react/use-interval.ts | 17 +++++++++ packages/react/use-scroll-position.ts | 33 ++++++++++++++++ packages/react/use-timeout.ts | 17 +++++++++ packages/react/use-viewport.ts | 51 +++++++++++++++++++++++++ yarn.lock | 23 ++++++++++++ 16 files changed, 344 insertions(+) create mode 100644 packages/react/README.md create mode 100644 packages/react/error-boundary.tsx create mode 100644 packages/react/index.ts create mode 100644 packages/react/package.json create mode 100644 packages/react/ssr.ts create mode 100644 packages/react/tsconfig.json create mode 100644 packages/react/typedoc.json create mode 100644 packages/react/use-click-outside.ts create mode 100644 packages/react/use-countdown-timer.ts create mode 100644 packages/react/use-interval.ts create mode 100644 packages/react/use-scroll-position.ts create mode 100644 packages/react/use-timeout.ts create mode 100644 packages/react/use-viewport.ts diff --git a/.size-limit.json b/.size-limit.json index 27fabe8..053aff3 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -7,6 +7,10 @@ "path": "packages/local-storage/dist/index.js", "limit": "290 B" }, + { + "path": "packages/react/dist/index.js", + "limit": "4.25 KB" + }, { "path": "packages/session-storage/dist/index.js", "limit": "290 B" diff --git a/README.md b/README.md index b7962c5..74d36bd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Common utils used by Rambler team - [@rambler-tech/cookie-storage](packages/cookie-storage) - [@rambler-tech/lhci-report](packages/lhci-report) - [@rambler-tech/local-storage](packages/local-storage) +- [@rambler-tech/react](packages/react) - [@rambler-tech/session-storage](packages/session-storage) - [@rambler-tech/url](packages/url) diff --git a/packages/react/README.md b/packages/react/README.md new file mode 100644 index 0000000..ef91ca7 --- /dev/null +++ b/packages/react/README.md @@ -0,0 +1,15 @@ +# React + +React hooks and utils + +## Install + +``` +npm install -D @rambler-tech/react +``` + +or + +``` +yarn add -D @rambler-tech/react +``` diff --git a/packages/react/error-boundary.tsx b/packages/react/error-boundary.tsx new file mode 100644 index 0000000..824cd3c --- /dev/null +++ b/packages/react/error-boundary.tsx @@ -0,0 +1,46 @@ +import {ErrorInfo, PureComponent} from 'react' + +/** Error boundary props */ +export interface ErrorBoundaryProps { + /** Error callback */ + onError: (error: Error, errorInfo: Record) => void + /** Fallback that shows on error */ + fallback: JSX.Element + /** Children to follow errors */ + children: JSX.Element +} + +interface ErrorBoundaryState { + isError: boolean +} + +/** Error boundary */ +export class ErrorBoundary extends PureComponent< + ErrorBoundaryProps, + ErrorBoundaryState +> { + state = { + isError: false + } + + static getDerivedStateFromError(): ErrorBoundaryState { + return {isError: true} + } + + componentDidCatch(error: Error, errorInfo: ErrorInfo): void { + const {onError} = this.props + + onError(error, errorInfo) + } + + render(): JSX.Element { + const {isError} = this.state + const {fallback, children} = this.props + + if (isError) { + return fallback + } + + return children + } +} diff --git a/packages/react/index.ts b/packages/react/index.ts new file mode 100644 index 0000000..30894c6 --- /dev/null +++ b/packages/react/index.ts @@ -0,0 +1,9 @@ +/* eslint-disable import/no-unused-modules */ +export {ErrorBoundary, type ErrorBoundaryProps} from './error-boundary' +export {isSSR} from './ssr' +export {useClickOutside} from './use-click-outside' +export {useCountdownTimer, type Timer} from './use-countdown-timer' +export {useInterval} from './use-interval' +export {useScrollPosition} from './use-scroll-position' +export {useTimeout} from './use-timeout' +export {useViewport, type Viewport} from './use-viewport' diff --git a/packages/react/package.json b/packages/react/package.json new file mode 100644 index 0000000..cc61d74 --- /dev/null +++ b/packages/react/package.json @@ -0,0 +1,21 @@ +{ + "name": "@rambler-tech/react", + "version": "0.0.0", + "main": "dist", + "module": "dist", + "types": "dist/index.d.ts", + "license": "MIT", + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "dependencies": { + "raf-throttle": "^2.0.5" + }, + "devDependencies": { + "@types/react": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } +} diff --git a/packages/react/ssr.ts b/packages/react/ssr.ts new file mode 100644 index 0000000..e1809ef --- /dev/null +++ b/packages/react/ssr.ts @@ -0,0 +1,2 @@ +/** Check is server-side render */ +export const isSSR = typeof window === 'undefined' diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json new file mode 100644 index 0000000..b81d8e5 --- /dev/null +++ b/packages/react/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "outDir": "dist" + }, + "include": [".", "../../types"] +} diff --git a/packages/react/typedoc.json b/packages/react/typedoc.json new file mode 100644 index 0000000..fd9d16b --- /dev/null +++ b/packages/react/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": "@rambler-tech/typedoc-config", + "readme": "../../README.md", + "entryPoints": ["./index.ts"] +} diff --git a/packages/react/use-click-outside.ts b/packages/react/use-click-outside.ts new file mode 100644 index 0000000..3d4f8e6 --- /dev/null +++ b/packages/react/use-click-outside.ts @@ -0,0 +1,37 @@ +import {useEffect, RefObject} from 'react' + +/** Listen click outside */ +export function useClickOutside( + ref: RefObject, + callback: (...args: any[]) => any +) { + useEffect(() => { + let startedInside = false + let startedWhenMounted = false + + const listener = (event: MouseEvent): void => { + // Игнорировать событие если `mousedown` или `touchstart` внутри элемента + if (startedInside || !startedWhenMounted) return + // Игнорировать если клик по элементу ref или дочерним + if (!ref.current || ref.current.contains(event.target as HTMLElement)) + return + + callback(event) + } + + const validateEventStart = (event: any): void => { + startedWhenMounted = !!ref.current + startedInside = !!(ref.current && ref.current.contains(event.target)) + } + + document.addEventListener('mousedown', validateEventStart) + document.addEventListener('touchstart', validateEventStart) + document.addEventListener('click', listener) + + return () => { + document.removeEventListener('mousedown', validateEventStart) + document.removeEventListener('touchstart', validateEventStart) + document.removeEventListener('click', listener) + } + }, [ref, callback]) +} diff --git a/packages/react/use-countdown-timer.ts b/packages/react/use-countdown-timer.ts new file mode 100644 index 0000000..551f92e --- /dev/null +++ b/packages/react/use-countdown-timer.ts @@ -0,0 +1,54 @@ +import {useState, useRef, useEffect} from 'react' + +/** Countdown timer instance */ +export interface Timer { + /** Remaining time */ + remainingTime: number | null + /** Start timer */ + startTimer(time: number): void + /** Stop timer */ + stopTimer(): void +} + +/** Countdown timer */ +export function useCountdownTimer(): Timer { + const [remainingTime, setRemainingTime] = useState(null) + const timerId = useRef() + + const clear = (): void => { + if (timerId.current) { + window.clearInterval(timerId.current) + } + } + + useEffect(() => { + return () => clear() + }, []) + + useEffect(() => { + if (remainingTime === 0) { + clear() + } + }, [remainingTime]) + + const stopTimer = (): void => { + clear() + setRemainingTime(0) + } + + const tick = (): void => { + setRemainingTime((prevTime) => prevTime && prevTime - 1) + } + + const startTimer = (time: number): void => { + clear() + timerId.current = window.setInterval(tick, 1000) + setRemainingTime(time) + } + + return { + remainingTime, + stopTimer, + startTimer + } +} diff --git a/packages/react/use-interval.ts b/packages/react/use-interval.ts new file mode 100644 index 0000000..22c7530 --- /dev/null +++ b/packages/react/use-interval.ts @@ -0,0 +1,17 @@ +import {useEffect, useRef} from 'react' + +/** Start interval */ +export function useInterval(callback: () => void, delay: number) { + const savedCallback = useRef<() => void>() + + useEffect(() => { + savedCallback.current = callback + }, [callback]) + + useEffect(() => { + const tick = (): void => savedCallback.current?.() + const id = window.setInterval(tick, delay) + + return () => window.clearInterval(id) + }, [delay]) +} diff --git a/packages/react/use-scroll-position.ts b/packages/react/use-scroll-position.ts new file mode 100644 index 0000000..701b6ed --- /dev/null +++ b/packages/react/use-scroll-position.ts @@ -0,0 +1,33 @@ +import {useRef, useEffect, DependencyList} from 'react' +import throttle from 'raf-throttle' +import {isSSR} from './ssr' + +function getScrollPosition() { + return isSSR ? 0 : window.pageYOffset +} + +/** Listen scroll position */ +export function useScrollPosition( + callback: (current: number, prev: number) => void, + deps: DependencyList = [] +) { + const scrollPosition = useRef(getScrollPosition()) + + useEffect(() => { + if (isSSR) return + + const handleScroll = throttle((): void => { + const currentScrollPosition = getScrollPosition() + + callback(currentScrollPosition, scrollPosition.current) + + scrollPosition.current = currentScrollPosition + }) + + window.addEventListener('scroll', handleScroll, {passive: true}) + + return () => { + window.removeEventListener('scroll', handleScroll) + } + }, deps) +} diff --git a/packages/react/use-timeout.ts b/packages/react/use-timeout.ts new file mode 100644 index 0000000..ad8e3b0 --- /dev/null +++ b/packages/react/use-timeout.ts @@ -0,0 +1,17 @@ +import {useEffect, useRef} from 'react' + +/** Start timeout */ +export function useTimeout(callback: () => void, delay: number) { + const savedCallback = useRef<() => void>() + + useEffect(() => { + savedCallback.current = callback + }, [callback]) + + useEffect(() => { + const tick = (): void => savedCallback.current?.() + const timerId = window.setTimeout(tick, delay) + + return () => window.clearTimeout(timerId) + }, [delay]) +} diff --git a/packages/react/use-viewport.ts b/packages/react/use-viewport.ts new file mode 100644 index 0000000..bd63c78 --- /dev/null +++ b/packages/react/use-viewport.ts @@ -0,0 +1,51 @@ +import {useState, useEffect} from 'react' +import throttle from 'raf-throttle' +import {isSSR} from './ssr' + +/** Viewport info */ +export interface Viewport { + width: number + isMobile: boolean + isTablet: boolean + isDesktop: boolean +} + +const BREAKPOINT = 768 + +export function useViewport(breakpoints?: [number, number]): Viewport +export function useViewport(breakpoints?: [number]): Omit + +/** Listen viewport change */ +export function useViewport( + breakpoints: [number, number] | [number] = [BREAKPOINT] +): Viewport | Omit { + const [mobile, desktop] = breakpoints + const [width, setWidth] = useState(isSSR ? 0 : window.innerWidth) + + useEffect(() => { + const updateWidth = throttle(() => { + setWidth(window.innerWidth) + }) + + window.addEventListener('resize', updateWidth) + + return () => { + window.removeEventListener('resize', updateWidth) + } + }, []) + + if (typeof desktop === 'number') { + return { + width, + isMobile: width < mobile, + isTablet: width >= mobile && width < desktop, + isDesktop: width >= desktop + } + } + + return { + width, + isMobile: width < mobile, + isDesktop: width >= mobile + } +} diff --git a/yarn.lock b/yarn.lock index dc335a9..b1c23e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1775,6 +1775,19 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== +"@types/prop-types@*": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react@^18.2.0": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" + integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + "@types/semver@^7.3.12": version "7.5.7" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.7.tgz#326f5fdda70d13580777bcaa1bc6fa772a5aef0e" @@ -3131,6 +3144,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" @@ -7368,6 +7386,11 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +raf-throttle@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/raf-throttle/-/raf-throttle-2.0.6.tgz#5f1c273d1630fff421df31fe01551faa04b86700" + integrity sha512-C7W6hy78A+vMmk5a/B6C5szjBHrUzWJkVyakjKCK59Uy2CcA7KhO1JUvvH32IXYFIcyJ3FMKP3ZzCc2/71I6Vg== + react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" From 93c27f6ac7083b6609d762c5decbc02c7006773a Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 14:09:58 +0300 Subject: [PATCH 06/16] feat(debug): add debug --- .size-limit.json | 4 +++ README.md | 1 + packages/debug/README.md | 15 ++++++++++ packages/debug/index.test.ts | 56 ++++++++++++++++++++++++++++++++++++ packages/debug/index.ts | 43 +++++++++++++++++++++++++++ packages/debug/package.json | 18 ++++++++++++ packages/debug/tsconfig.json | 9 ++++++ packages/debug/typedoc.json | 5 ++++ yarn.lock | 14 ++++++++- 9 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 packages/debug/README.md create mode 100644 packages/debug/index.test.ts create mode 100644 packages/debug/index.ts create mode 100644 packages/debug/package.json create mode 100644 packages/debug/tsconfig.json create mode 100644 packages/debug/typedoc.json diff --git a/.size-limit.json b/.size-limit.json index 27fabe8..d68bbdd 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -3,6 +3,10 @@ "path": "packages/cookie-storage/dist/index.js", "limit": "990 B" }, + { + "path": "packages/debug/dist/index.js", + "limit": "3.4 KB" + }, { "path": "packages/local-storage/dist/index.js", "limit": "290 B" diff --git a/README.md b/README.md index b7962c5..c74b522 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ Common utils used by Rambler team ## Packages - [@rambler-tech/cookie-storage](packages/cookie-storage) +- [@rambler-tech/debug](packages/debug) - [@rambler-tech/lhci-report](packages/lhci-report) - [@rambler-tech/local-storage](packages/local-storage) - [@rambler-tech/session-storage](packages/session-storage) diff --git a/packages/debug/README.md b/packages/debug/README.md new file mode 100644 index 0000000..40c27aa --- /dev/null +++ b/packages/debug/README.md @@ -0,0 +1,15 @@ +# Debug + +Debug management based on [debug](https://github.com/debug-js/debug). + +## Install + +``` +npm install -D @rambler-tech/debug +``` + +or + +``` +yarn add -D @rambler-tech/debug +``` diff --git a/packages/debug/index.test.ts b/packages/debug/index.test.ts new file mode 100644 index 0000000..cc51c96 --- /dev/null +++ b/packages/debug/index.test.ts @@ -0,0 +1,56 @@ +import {getItem, setItem} from '@rambler-tech/local-storage' +import {initDebug} from '.' + +class LocalStorage implements LocalStorage { + map: {[key: string]: any} = {} + getItem(key: string): void { + return this.map[key] + } + setItem(key: string, value: any): void { + this.map[key] = value + } + removeItem(key: string): void { + delete this.map[key] + } +} + +Object.defineProperty(window, 'localStorage', { + value: new LocalStorage() +}) + +test('reset local storage debug value', () => { + setItem('debug', 'test', {raw: true}) + + expect(getItem('debug', {raw: true})).toBe('test') + + initDebug('https://foobar.ru?debug=unset') + + expect(getItem('debug', {raw: true})).toBeNull() +}) + +test('use window.location.href value', () => { + Object.defineProperty(window, 'location', { + value: { + href: 'https://test.ru?debug=bar' + }, + writable: true + }) + + setItem('debug', 'foo', {raw: true}) + + expect(getItem('debug', {raw: true})).toBe('foo') + + initDebug() + + expect(getItem('debug', {raw: true})).toBe('bar') +}) + +test('use debug value from initDebug arg', () => { + setItem('debug', 'test', {raw: true}) + + expect(getItem('debug', {raw: true})).toBe('test') + + initDebug('https://foobar.ru?debug=foo') + + expect(getItem('debug', {raw: true})).toBe('foo') +}) diff --git a/packages/debug/index.ts b/packages/debug/index.ts new file mode 100644 index 0000000..af7d53b --- /dev/null +++ b/packages/debug/index.ts @@ -0,0 +1,43 @@ +/* eslint-disable import/no-unused-modules */ +import {getUrlParams} from '@rambler-tech/url' +import {removeItem, setItem, getItem} from '@rambler-tech/local-storage' + +const RESET_DEBUG_LOCAL_STORAGE_VALUE = 'unset' + +/** + * Init debug mode from URL + * + * ```ts + * initDebug('https://example.com?debug=value') + * ``` + * + * Possible value: + * * `*` - Include all debug namespaces + * * `unset` - Reset debug value from local storage + * * `value` - Write debug value into local storage + */ +export function initDebug(href?: string) { + if (typeof window === 'undefined') { + return + } + + const {debug: queryParam} = getUrlParams(href ?? window.location.href) + const storageParam = getItem('debug', {raw: true}) + + if ( + !queryParam || + typeof queryParam !== 'string' || + storageParam === queryParam || + (!storageParam && queryParam === RESET_DEBUG_LOCAL_STORAGE_VALUE) + ) { + return + } + + if (queryParam === RESET_DEBUG_LOCAL_STORAGE_VALUE) { + removeItem('debug') + } else { + setItem('debug', queryParam, {raw: true}) + } +} + +export {default as createDebug} from 'debug' diff --git a/packages/debug/package.json b/packages/debug/package.json new file mode 100644 index 0000000..b56a748 --- /dev/null +++ b/packages/debug/package.json @@ -0,0 +1,18 @@ +{ + "name": "@rambler-tech/debug", + "version": "0.0.0", + "main": "dist", + "module": "dist", + "types": "dist/index.d.ts", + "license": "MIT", + "sideEffects": false, + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@rambler-tech/local-storage": "*", + "@rambler-tech/url": "*", + "@types/debug": "^4.1.7", + "debug": "^3" + } +} diff --git a/packages/debug/tsconfig.json b/packages/debug/tsconfig.json new file mode 100644 index 0000000..b81d8e5 --- /dev/null +++ b/packages/debug/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "baseUrl": ".", + "outDir": "dist" + }, + "include": [".", "../../types"] +} diff --git a/packages/debug/typedoc.json b/packages/debug/typedoc.json new file mode 100644 index 0000000..fd9d16b --- /dev/null +++ b/packages/debug/typedoc.json @@ -0,0 +1,5 @@ +{ + "extends": "@rambler-tech/typedoc-config", + "readme": "../../README.md", + "entryPoints": ["./index.ts"] +} diff --git a/yarn.lock b/yarn.lock index dc335a9..21bea1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1685,6 +1685,13 @@ resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-0.4.31.tgz#a31d74241a6b1edbb973cf36d97a2896834a51f9" integrity sha512-nF0fisEPYMIyfrFgabFimsz9Lnuu9MwkNrrlATm2E4E46afKDyeelT+8bXfw1VSc7sLBxMxRgT7PxTC2JcqN4Q== +"@types/debug@^4.1.7": + version "4.1.12" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== + dependencies: + "@types/ms" "*" + "@types/graceful-fs@^4.1.3": version "4.1.7" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.7.tgz#30443a2e64fd51113bc3e2ba0914d47109695e2a" @@ -1753,6 +1760,11 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== +"@types/ms@*": + version "0.7.34" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== + "@types/node@*": version "20.6.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.3.tgz#5b763b321cd3b80f6b8dde7a37e1a77ff9358dd9" @@ -3162,7 +3174,7 @@ debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, de dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.7: +debug@^3, debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== From 2e5378889bab0610293a5c7545a2ff8abc255ee0 Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 13:59:05 +0000 Subject: [PATCH 07/16] chore(release): publish - @rambler-tech/debug@0.1.0 --- packages/debug/CHANGELOG.md | 10 ++++++++++ packages/debug/package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/debug/CHANGELOG.md diff --git a/packages/debug/CHANGELOG.md b/packages/debug/CHANGELOG.md new file mode 100644 index 0000000..bfd7d5c --- /dev/null +++ b/packages/debug/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2024-08-14) + +### Features + +- **debug:** add debug ([93c27f6](https://github.com/rambler-digital-solutions/rambler-common/commit/93c27f6ac7083b6609d762c5decbc02c7006773a)) diff --git a/packages/debug/package.json b/packages/debug/package.json index b56a748..851eff8 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/debug", - "version": "0.0.0", + "version": "0.1.0", "main": "dist", "module": "dist", "types": "dist/index.d.ts", From 0e153eef963738c66d0a6ff0f1696f1ea775fd2c Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 18:10:34 +0300 Subject: [PATCH 08/16] fix(debug): lock deps --- packages/debug/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/debug/package.json b/packages/debug/package.json index 851eff8..4bfde62 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -10,8 +10,8 @@ "access": "public" }, "dependencies": { - "@rambler-tech/local-storage": "*", - "@rambler-tech/url": "*", + "@rambler-tech/local-storage": "^0.1.4", + "@rambler-tech/url": "^0.1.0", "@types/debug": "^4.1.7", "debug": "^3" } From bd6c8d6a342973ba6d2929a8630024f0f2785f35 Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 15:11:22 +0000 Subject: [PATCH 09/16] chore(release): publish - @rambler-tech/debug@0.1.1 --- packages/debug/CHANGELOG.md | 6 ++++++ packages/debug/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/debug/CHANGELOG.md b/packages/debug/CHANGELOG.md index bfd7d5c..42fed4e 100644 --- a/packages/debug/CHANGELOG.md +++ b/packages/debug/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.1](https://github.com/rambler-digital-solutions/rambler-common/compare/@rambler-tech/debug@0.1.0...@rambler-tech/debug@0.1.1) (2024-08-14) + +### Bug Fixes + +- **debug:** lock deps ([0e153ee](https://github.com/rambler-digital-solutions/rambler-common/commit/0e153eef963738c66d0a6ff0f1696f1ea775fd2c)) + # 0.1.0 (2024-08-14) ### Features diff --git a/packages/debug/package.json b/packages/debug/package.json index 4bfde62..e0cfeeb 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/debug", - "version": "0.1.0", + "version": "0.1.1", "main": "dist", "module": "dist", "types": "dist/index.d.ts", From 560466ebc0b231330bb7a2db7ec333c3c5c4155e Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 18:35:08 +0300 Subject: [PATCH 10/16] docs: fix docs readme --- packages/debug/tsconfig.json | 10 +--------- packages/debug/typedoc.json | 6 +----- packages/url/tsconfig.json | 10 +--------- packages/url/typedoc.json | 6 +----- typedoc.package.json | 2 +- 5 files changed, 5 insertions(+), 29 deletions(-) mode change 100644 => 120000 packages/debug/tsconfig.json mode change 100644 => 120000 packages/debug/typedoc.json mode change 100644 => 120000 packages/url/tsconfig.json mode change 100644 => 120000 packages/url/typedoc.json diff --git a/packages/debug/tsconfig.json b/packages/debug/tsconfig.json deleted file mode 100644 index b81d8e5..0000000 --- a/packages/debug/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "baseUrl": ".", - "outDir": "dist" - }, - "include": [".", "../../types"] -} diff --git a/packages/debug/tsconfig.json b/packages/debug/tsconfig.json new file mode 120000 index 0000000..238bf1b --- /dev/null +++ b/packages/debug/tsconfig.json @@ -0,0 +1 @@ +../../tsconfig.package.json \ No newline at end of file diff --git a/packages/debug/typedoc.json b/packages/debug/typedoc.json deleted file mode 100644 index fd9d16b..0000000 --- a/packages/debug/typedoc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", - "entryPoints": ["./index.ts"] -} diff --git a/packages/debug/typedoc.json b/packages/debug/typedoc.json new file mode 120000 index 0000000..213b456 --- /dev/null +++ b/packages/debug/typedoc.json @@ -0,0 +1 @@ +../../typedoc.package.json \ No newline at end of file diff --git a/packages/url/tsconfig.json b/packages/url/tsconfig.json deleted file mode 100644 index b81d8e5..0000000 --- a/packages/url/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "baseUrl": ".", - "outDir": "dist" - }, - "include": [".", "../../types"] -} diff --git a/packages/url/tsconfig.json b/packages/url/tsconfig.json new file mode 120000 index 0000000..238bf1b --- /dev/null +++ b/packages/url/tsconfig.json @@ -0,0 +1 @@ +../../tsconfig.package.json \ No newline at end of file diff --git a/packages/url/typedoc.json b/packages/url/typedoc.json deleted file mode 100644 index fd9d16b..0000000 --- a/packages/url/typedoc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", - "entryPoints": ["./index.ts"] -} diff --git a/packages/url/typedoc.json b/packages/url/typedoc.json new file mode 120000 index 0000000..213b456 --- /dev/null +++ b/packages/url/typedoc.json @@ -0,0 +1 @@ +../../typedoc.package.json \ No newline at end of file diff --git a/typedoc.package.json b/typedoc.package.json index fd9d16b..1cdc737 100644 --- a/typedoc.package.json +++ b/typedoc.package.json @@ -1,5 +1,5 @@ { "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", + "readme": "./README.md", "entryPoints": ["./index.ts"] } From 4668557fc42854e6c9ecca2df745ca34f2ba8b8e Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 15:35:53 +0000 Subject: [PATCH 11/16] chore(release): publish - @rambler-tech/debug@0.1.2 - @rambler-tech/url@0.1.1 --- packages/debug/CHANGELOG.md | 4 ++++ packages/debug/package.json | 4 ++-- packages/url/CHANGELOG.md | 4 ++++ packages/url/package.json | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/debug/CHANGELOG.md b/packages/debug/CHANGELOG.md index 42fed4e..cb93d63 100644 --- a/packages/debug/CHANGELOG.md +++ b/packages/debug/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.2](https://github.com/rambler-digital-solutions/rambler-common/compare/@rambler-tech/debug@0.1.1...@rambler-tech/debug@0.1.2) (2024-08-14) + +**Note:** Version bump only for package @rambler-tech/debug + ## [0.1.1](https://github.com/rambler-digital-solutions/rambler-common/compare/@rambler-tech/debug@0.1.0...@rambler-tech/debug@0.1.1) (2024-08-14) ### Bug Fixes diff --git a/packages/debug/package.json b/packages/debug/package.json index e0cfeeb..af8da9d 100644 --- a/packages/debug/package.json +++ b/packages/debug/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/debug", - "version": "0.1.1", + "version": "0.1.2", "main": "dist", "module": "dist", "types": "dist/index.d.ts", @@ -11,7 +11,7 @@ }, "dependencies": { "@rambler-tech/local-storage": "^0.1.4", - "@rambler-tech/url": "^0.1.0", + "@rambler-tech/url": "^0.1.1", "@types/debug": "^4.1.7", "debug": "^3" } diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md index 8b8b9f5..004fce0 100644 --- a/packages/url/CHANGELOG.md +++ b/packages/url/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.1.1](https://github.com/rambler-digital-solutions/rambler-common/compare/@rambler-tech/url@0.1.0...@rambler-tech/url@0.1.1) (2024-08-14) + +**Note:** Version bump only for package @rambler-tech/url + # 0.1.0 (2024-08-14) ### Features diff --git a/packages/url/package.json b/packages/url/package.json index cba39b0..ac510de 100644 --- a/packages/url/package.json +++ b/packages/url/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/url", - "version": "0.1.0", + "version": "0.1.1", "main": "dist", "module": "dist", "types": "dist/index.d.ts", From 22c807e0cd8d056db5f319f5d8f4d70d601edd89 Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 18:40:23 +0300 Subject: [PATCH 12/16] docs: fix docs --- packages/async/tsconfig.json | 10 +--------- packages/async/typedoc.json | 6 +----- 2 files changed, 2 insertions(+), 14 deletions(-) mode change 100644 => 120000 packages/async/tsconfig.json mode change 100644 => 120000 packages/async/typedoc.json diff --git a/packages/async/tsconfig.json b/packages/async/tsconfig.json deleted file mode 100644 index b81d8e5..0000000 --- a/packages/async/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "baseUrl": ".", - "outDir": "dist" - }, - "include": [".", "../../types"] -} diff --git a/packages/async/tsconfig.json b/packages/async/tsconfig.json new file mode 120000 index 0000000..238bf1b --- /dev/null +++ b/packages/async/tsconfig.json @@ -0,0 +1 @@ +../../tsconfig.package.json \ No newline at end of file diff --git a/packages/async/typedoc.json b/packages/async/typedoc.json deleted file mode 100644 index fd9d16b..0000000 --- a/packages/async/typedoc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", - "entryPoints": ["./index.ts"] -} diff --git a/packages/async/typedoc.json b/packages/async/typedoc.json new file mode 120000 index 0000000..213b456 --- /dev/null +++ b/packages/async/typedoc.json @@ -0,0 +1 @@ +../../typedoc.package.json \ No newline at end of file From d3b78c3e7fbf5692a01bb457df98a9852a4643d2 Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 18:41:00 +0300 Subject: [PATCH 13/16] docs: fix docs --- packages/dom/tsconfig.json | 10 +--------- packages/dom/typedoc.json | 6 +----- 2 files changed, 2 insertions(+), 14 deletions(-) mode change 100644 => 120000 packages/dom/tsconfig.json mode change 100644 => 120000 packages/dom/typedoc.json diff --git a/packages/dom/tsconfig.json b/packages/dom/tsconfig.json deleted file mode 100644 index b81d8e5..0000000 --- a/packages/dom/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "baseUrl": ".", - "outDir": "dist" - }, - "include": [".", "../../types"] -} diff --git a/packages/dom/tsconfig.json b/packages/dom/tsconfig.json new file mode 120000 index 0000000..238bf1b --- /dev/null +++ b/packages/dom/tsconfig.json @@ -0,0 +1 @@ +../../tsconfig.package.json \ No newline at end of file diff --git a/packages/dom/typedoc.json b/packages/dom/typedoc.json deleted file mode 100644 index fd9d16b..0000000 --- a/packages/dom/typedoc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", - "entryPoints": ["./index.ts"] -} diff --git a/packages/dom/typedoc.json b/packages/dom/typedoc.json new file mode 120000 index 0000000..213b456 --- /dev/null +++ b/packages/dom/typedoc.json @@ -0,0 +1 @@ +../../typedoc.package.json \ No newline at end of file From e205ec423fe5dd346527bc2d2b7321fed16606e7 Mon Sep 17 00:00:00 2001 From: Andrey Polischuk Date: Wed, 14 Aug 2024 18:41:20 +0300 Subject: [PATCH 14/16] docs: fix docs --- packages/react/tsconfig.json | 10 +--------- packages/react/typedoc.json | 6 +----- 2 files changed, 2 insertions(+), 14 deletions(-) mode change 100644 => 120000 packages/react/tsconfig.json mode change 100644 => 120000 packages/react/typedoc.json diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json deleted file mode 100644 index b81d8e5..0000000 --- a/packages/react/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "baseUrl": ".", - "outDir": "dist" - }, - "include": [".", "../../types"] -} diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json new file mode 120000 index 0000000..238bf1b --- /dev/null +++ b/packages/react/tsconfig.json @@ -0,0 +1 @@ +../../tsconfig.package.json \ No newline at end of file diff --git a/packages/react/typedoc.json b/packages/react/typedoc.json deleted file mode 100644 index fd9d16b..0000000 --- a/packages/react/typedoc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "@rambler-tech/typedoc-config", - "readme": "../../README.md", - "entryPoints": ["./index.ts"] -} diff --git a/packages/react/typedoc.json b/packages/react/typedoc.json new file mode 120000 index 0000000..213b456 --- /dev/null +++ b/packages/react/typedoc.json @@ -0,0 +1 @@ +../../typedoc.package.json \ No newline at end of file From 32cac295eb8339809e97200a17eee87db3661be7 Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 15:44:19 +0000 Subject: [PATCH 15/16] chore(release): publish - @rambler-tech/async@0.1.0 --- packages/async/CHANGELOG.md | 10 ++++++++++ packages/async/package.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 packages/async/CHANGELOG.md diff --git a/packages/async/CHANGELOG.md b/packages/async/CHANGELOG.md new file mode 100644 index 0000000..196474b --- /dev/null +++ b/packages/async/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2024-08-14) + +### Features + +- **async:** add async tools ([946d5ba](https://github.com/rambler-digital-solutions/rambler-common/commit/946d5baf89b77fa07f9845ef68e3d8f5b6d7dd5f)) diff --git a/packages/async/package.json b/packages/async/package.json index 3933ede..44f7dc9 100644 --- a/packages/async/package.json +++ b/packages/async/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/async", - "version": "0.0.0", + "version": "0.1.0", "main": "dist", "module": "dist", "types": "dist/index.d.ts", From 8b8eb517e9edf82feccc321c25cc4296370c7d1d Mon Sep 17 00:00:00 2001 From: rambler-ui-bot Date: Wed, 14 Aug 2024 15:47:22 +0000 Subject: [PATCH 16/16] chore(release): publish - @rambler-tech/dom@0.1.0 - @rambler-tech/react@0.1.0 --- packages/dom/CHANGELOG.md | 10 ++++++++++ packages/dom/package.json | 2 +- packages/react/CHANGELOG.md | 10 ++++++++++ packages/react/package.json | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 packages/dom/CHANGELOG.md create mode 100644 packages/react/CHANGELOG.md diff --git a/packages/dom/CHANGELOG.md b/packages/dom/CHANGELOG.md new file mode 100644 index 0000000..699bd10 --- /dev/null +++ b/packages/dom/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2024-08-14) + +### Features + +- **dom:** add dom utils ([1558e3e](https://github.com/rambler-digital-solutions/rambler-common/commit/1558e3e2f31cbb2539ca6ff10f92d08fa44b139c)) diff --git a/packages/dom/package.json b/packages/dom/package.json index 5ac09dd..56a0e9f 100644 --- a/packages/dom/package.json +++ b/packages/dom/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/dom", - "version": "0.0.0", + "version": "0.1.0", "main": "dist", "module": "dist", "types": "dist/index.d.ts", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md new file mode 100644 index 0000000..629b0bb --- /dev/null +++ b/packages/react/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +# 0.1.0 (2024-08-14) + +### Features + +- **react:** add react tools ([2a41f6f](https://github.com/rambler-digital-solutions/rambler-common/commit/2a41f6f40a5ed7bb2d8eff9d1301d99b025b9251)) diff --git a/packages/react/package.json b/packages/react/package.json index cc61d74..37a96df 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@rambler-tech/react", - "version": "0.0.0", + "version": "0.1.0", "main": "dist", "module": "dist", "types": "dist/index.d.ts",