yummies 7.12.0 → 7.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -87
- package/async.cjs +17 -0
- package/async.cjs.map +1 -1
- package/async.d.ts +17 -0
- package/async.js +17 -0
- package/async.js.map +1 -1
- package/common.cjs.map +1 -1
- package/common.d.ts +18 -0
- package/common.js.map +1 -1
- package/complex.cjs.map +1 -1
- package/complex.d.ts +66 -0
- package/complex.js.map +1 -1
- package/cookie.cjs.map +1 -1
- package/cookie.d.ts +18 -0
- package/cookie.js.map +1 -1
- package/css.cjs +16 -0
- package/css.cjs.map +1 -1
- package/css.d.ts +17 -0
- package/css.js +16 -0
- package/css.js.map +1 -1
- package/data.cjs.map +1 -1
- package/data.d.ts +18 -0
- package/data.js.map +1 -1
- package/date-time.cjs +16 -0
- package/date-time.cjs.map +1 -1
- package/date-time.d.ts +17 -0
- package/date-time.js +16 -0
- package/date-time.js.map +1 -1
- package/device.cjs +17 -0
- package/device.cjs.map +1 -1
- package/device.d.ts +17 -0
- package/device.js +17 -0
- package/device.js.map +1 -1
- package/encodings.cjs.map +1 -1
- package/encodings.d.ts +17 -0
- package/encodings.js.map +1 -1
- package/errors.cjs +16 -0
- package/errors.cjs.map +1 -1
- package/errors.d.ts +17 -0
- package/errors.js +16 -0
- package/errors.js.map +1 -1
- package/file.cjs +16 -0
- package/file.cjs.map +1 -1
- package/file.d.ts +16 -0
- package/file.js +16 -0
- package/file.js.map +1 -1
- package/format.cjs.map +1 -1
- package/format.d.ts +18 -0
- package/format.js.map +1 -1
- package/html.cjs +16 -0
- package/html.cjs.map +1 -1
- package/html.d.ts +17 -0
- package/html.js +16 -0
- package/html.js.map +1 -1
- package/id.cjs +16 -0
- package/id.cjs.map +1 -1
- package/id.d.ts +16 -0
- package/id.js +16 -0
- package/id.js.map +1 -1
- package/imports.cjs +16 -0
- package/imports.cjs.map +1 -1
- package/imports.d.ts +16 -0
- package/imports.js +16 -0
- package/imports.js.map +1 -1
- package/math.cjs.map +1 -1
- package/math.d.ts +17 -0
- package/math.js.map +1 -1
- package/media.cjs +16 -0
- package/media.cjs.map +1 -1
- package/media.d.ts +16 -0
- package/media.js +16 -0
- package/media.js.map +1 -1
- package/mobx.cjs +96 -0
- package/mobx.cjs.map +1 -1
- package/mobx.d.ts +101 -0
- package/mobx.js +96 -0
- package/mobx.js.map +1 -1
- package/ms.cjs +16 -0
- package/ms.cjs.map +1 -1
- package/ms.d.ts +16 -0
- package/ms.js +16 -0
- package/ms.js.map +1 -1
- package/number.cjs +16 -0
- package/number.cjs.map +1 -1
- package/number.d.ts +16 -0
- package/number.js +16 -0
- package/number.js.map +1 -1
- package/package.json +2 -2
- package/parser.cjs.map +1 -1
- package/parser.d.ts +17 -0
- package/parser.js.map +1 -1
- package/price.cjs.map +1 -1
- package/price.d.ts +16 -0
- package/price.js.map +1 -1
- package/random.cjs +16 -0
- package/random.cjs.map +1 -1
- package/random.d.ts +16 -0
- package/random.js +16 -0
- package/random.js.map +1 -1
- package/sound.cjs +16 -0
- package/sound.cjs.map +1 -1
- package/sound.d.ts +16 -0
- package/sound.js +16 -0
- package/sound.js.map +1 -1
- package/storage.cjs.map +1 -1
- package/storage.d.ts +16 -0
- package/storage.js.map +1 -1
- package/text.cjs +16 -0
- package/text.cjs.map +1 -1
- package/text.d.ts +16 -0
- package/text.js +16 -0
- package/text.js.map +1 -1
- package/type-guard.cjs.map +1 -1
- package/type-guard.d.ts +18 -0
- package/type-guard.js.map +1 -1
- package/types.d.ts +41 -0
- package/types.global.d.ts +41 -0
- package/vibrate.cjs +16 -0
- package/vibrate.cjs.map +1 -1
- package/vibrate.d.ts +16 -0
- package/vibrate.js +16 -0
- package/vibrate.js.map +1 -1
package/storage.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.cjs","names":[],"sources":["../src/storage.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"storage.cjs","names":[],"sources":["../src/storage.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/storage\n *\n * ## Description\n *\n * Typed helpers around **`sessionStorage`** and **`localStorage`**: key namespacing, JSON parse\n * safety, and small wrappers that avoid repeating `try/catch` around `getItem`/`setItem`. Use it when\n * you need durable client state with predictable serialization, not a full offline database.\n *\n * ## Usage\n *\n * ```ts\n * import { createKey } from \"yummies/storage\";\n * ```\n */\n\nexport type StorageType = 'session' | 'local';\n\nconst storages: Record<StorageType, Storage> = {\n session: sessionStorage,\n local: localStorage,\n};\n\n/**\n * Builds a storage key from a prefix, optional namespace and key.\n *\n * @example\n * ```ts\n * createKey('app', 'token', 'auth'); // 'app/auth/token'\n * ```\n */\nexport const createKey = (prefix: string, key: string, namespace?: string) =>\n `${prefix}${namespace ? `/${namespace}` : ''}/${key}`;\n\nconst parseStorageValue = <V>(value: unknown): V | null => {\n if (typeof value !== 'string') {\n return value as V;\n }\n\n try {\n const parsed = JSON.parse(value);\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst formatValueToStorage = (value: unknown): string => {\n return JSON.stringify(value);\n};\n\nexport interface SetToStorageConfig<V>\n extends Omit<GetFromStorageConfig<V>, 'fallback'> {\n value: V;\n}\n\nexport interface UnsetFromStorageConfig\n extends Omit<GetFromStorageConfig<any>, 'fallback'> {}\n\nexport interface GetFromStorageConfig<V> {\n /**\n * Storage key used to retrieve the value.\n * The full key is extended with the project namespace.\n */\n key: string;\n /**\n * Storage type.\n */\n type: StorageType;\n /**\n * Default value used when there is no value in storage.\n */\n fallback?: V;\n /**\n * Optional namespace segment used in the generated key.\n */\n namespace?: string;\n /**\n * Optional key prefix.\n */\n prefix?: string;\n}\n\nexport type SetToStorageWrappedConfig<\n V,\n BaseConfig extends StorageConfigBase,\n> = Omit<\n SetToStorageConfig<V>,\n Extract<keyof SetToStorageConfig<V>, keyof BaseConfig>\n> &\n Partial<\n Pick<\n SetToStorageConfig<V>,\n Extract<keyof SetToStorageConfig<V>, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof SetToStorageConfig<V>>>;\n\nexport type UnsetFromStorageWrappedConfig<\n BaseConfig extends StorageConfigBase,\n> = Omit<\n UnsetFromStorageConfig,\n Extract<keyof UnsetFromStorageConfig, keyof BaseConfig>\n> &\n Partial<\n Pick<\n UnsetFromStorageConfig,\n Extract<keyof UnsetFromStorageConfig, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof UnsetFromStorageConfig>>;\n\nexport type GetFromStorageWrappedConfig<\n V,\n BaseConfig extends StorageConfigBase,\n> = Omit<\n GetFromStorageConfig<V>,\n Extract<keyof GetFromStorageConfig<V>, keyof BaseConfig>\n> &\n Partial<\n Pick<\n GetFromStorageConfig<V>,\n Extract<keyof GetFromStorageConfig<V>, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof GetFromStorageConfig<V>>>;\n\nexport type StorageConfigBase = Partial<\n Pick<GetFromStorageConfig<any>, 'prefix' | 'type'>\n>;\n\nexport interface StorageApi<BaseConfig extends StorageConfigBase> {\n set<Value>(config: SetToStorageWrappedConfig<Value, BaseConfig>): void;\n unset(config: UnsetFromStorageWrappedConfig<BaseConfig>): void;\n get<Value>(\n config: GetFromStorageWrappedConfig<Value, BaseConfig>,\n ): Value | null;\n}\n\n/**\n * Creates an interface for working with storage (`localStorage`, `sessionStorage`).\n */\nexport function createStorage<BaseConfig extends StorageConfigBase>(\n storageConfig: BaseConfig,\n): StorageApi<BaseConfig> {\n return {\n set: <Value>(cfg: SetToStorageWrappedConfig<Value, BaseConfig>) => {\n const config = cfg as unknown as SetToStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n\n const storage = storages[storageType];\n\n storage.setItem(\n createKey(storagePrefix, config.key, config.namespace),\n formatValueToStorage(config.value),\n );\n },\n unset: <Value>(cfg: UnsetFromStorageWrappedConfig<BaseConfig>) => {\n const config = cfg as unknown as SetToStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n const storage = storages[storageType];\n\n storage.removeItem(\n createKey(storagePrefix, config.key, config.namespace),\n );\n },\n get: <Value>(cfg: GetFromStorageWrappedConfig<Value, BaseConfig>) => {\n const config = cfg as unknown as GetFromStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n\n const storage = storages[storageType];\n\n return (\n parseStorageValue<Value>(\n storage.getItem(\n createKey(storagePrefix, config.key, config.namespace),\n ),\n ) ??\n config.fallback ??\n null\n );\n },\n } as const;\n}\n"],"mappings":";;AAmBA,IAAM,WAAyC;CAC7C,SAAS;CACT,OAAO;CACR;;;;;;;;;AAUD,IAAa,aAAa,QAAgB,KAAa,cACrD,GAAG,SAAS,YAAY,IAAI,cAAc,GAAG,GAAG;AAElD,IAAM,qBAAwB,UAA6B;AACzD,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI;AAEF,SADe,KAAK,MAAM,MAAM;SAE1B;AACN,SAAO;;;AAIX,IAAM,wBAAwB,UAA2B;AACvD,QAAO,KAAK,UAAU,MAAM;;;;;AA8F9B,SAAgB,cACd,eACwB;AACxB,QAAO;EACL,MAAa,QAAsD;GACjE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;AAEtC,YAAS,aAEjB,QACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,EACtD,qBAAqB,OAAO,MAAM,CACnC;;EAEH,QAAe,QAAmD;GAChE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;AACtC,YAAS,aAEjB,WACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,CACvD;;EAEH,MAAa,QAAwD;GACnE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;GAEtD,MAAM,UAAU,SAAS;AAEzB,UACE,kBACE,QAAQ,QACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,CACvD,CACF,IACD,OAAO,YACP;;EAGL"}
|
package/storage.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ---header-docs-section---
|
|
3
|
+
* # yummies/storage
|
|
4
|
+
*
|
|
5
|
+
* ## Description
|
|
6
|
+
*
|
|
7
|
+
* Typed helpers around **`sessionStorage`** and **`localStorage`**: key namespacing, JSON parse
|
|
8
|
+
* safety, and small wrappers that avoid repeating `try/catch` around `getItem`/`setItem`. Use it when
|
|
9
|
+
* you need durable client state with predictable serialization, not a full offline database.
|
|
10
|
+
*
|
|
11
|
+
* ## Usage
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createKey } from "yummies/storage";
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
1
17
|
type StorageType = 'session' | 'local';
|
|
2
18
|
/**
|
|
3
19
|
* Builds a storage key from a prefix, optional namespace and key.
|
package/storage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","names":[],"sources":["../src/storage.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"storage.js","names":[],"sources":["../src/storage.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/storage\n *\n * ## Description\n *\n * Typed helpers around **`sessionStorage`** and **`localStorage`**: key namespacing, JSON parse\n * safety, and small wrappers that avoid repeating `try/catch` around `getItem`/`setItem`. Use it when\n * you need durable client state with predictable serialization, not a full offline database.\n *\n * ## Usage\n *\n * ```ts\n * import { createKey } from \"yummies/storage\";\n * ```\n */\n\nexport type StorageType = 'session' | 'local';\n\nconst storages: Record<StorageType, Storage> = {\n session: sessionStorage,\n local: localStorage,\n};\n\n/**\n * Builds a storage key from a prefix, optional namespace and key.\n *\n * @example\n * ```ts\n * createKey('app', 'token', 'auth'); // 'app/auth/token'\n * ```\n */\nexport const createKey = (prefix: string, key: string, namespace?: string) =>\n `${prefix}${namespace ? `/${namespace}` : ''}/${key}`;\n\nconst parseStorageValue = <V>(value: unknown): V | null => {\n if (typeof value !== 'string') {\n return value as V;\n }\n\n try {\n const parsed = JSON.parse(value);\n return parsed;\n } catch {\n return null;\n }\n};\n\nconst formatValueToStorage = (value: unknown): string => {\n return JSON.stringify(value);\n};\n\nexport interface SetToStorageConfig<V>\n extends Omit<GetFromStorageConfig<V>, 'fallback'> {\n value: V;\n}\n\nexport interface UnsetFromStorageConfig\n extends Omit<GetFromStorageConfig<any>, 'fallback'> {}\n\nexport interface GetFromStorageConfig<V> {\n /**\n * Storage key used to retrieve the value.\n * The full key is extended with the project namespace.\n */\n key: string;\n /**\n * Storage type.\n */\n type: StorageType;\n /**\n * Default value used when there is no value in storage.\n */\n fallback?: V;\n /**\n * Optional namespace segment used in the generated key.\n */\n namespace?: string;\n /**\n * Optional key prefix.\n */\n prefix?: string;\n}\n\nexport type SetToStorageWrappedConfig<\n V,\n BaseConfig extends StorageConfigBase,\n> = Omit<\n SetToStorageConfig<V>,\n Extract<keyof SetToStorageConfig<V>, keyof BaseConfig>\n> &\n Partial<\n Pick<\n SetToStorageConfig<V>,\n Extract<keyof SetToStorageConfig<V>, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof SetToStorageConfig<V>>>;\n\nexport type UnsetFromStorageWrappedConfig<\n BaseConfig extends StorageConfigBase,\n> = Omit<\n UnsetFromStorageConfig,\n Extract<keyof UnsetFromStorageConfig, keyof BaseConfig>\n> &\n Partial<\n Pick<\n UnsetFromStorageConfig,\n Extract<keyof UnsetFromStorageConfig, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof UnsetFromStorageConfig>>;\n\nexport type GetFromStorageWrappedConfig<\n V,\n BaseConfig extends StorageConfigBase,\n> = Omit<\n GetFromStorageConfig<V>,\n Extract<keyof GetFromStorageConfig<V>, keyof BaseConfig>\n> &\n Partial<\n Pick<\n GetFromStorageConfig<V>,\n Extract<keyof GetFromStorageConfig<V>, keyof BaseConfig>\n >\n > &\n Pick<BaseConfig, Exclude<keyof BaseConfig, keyof GetFromStorageConfig<V>>>;\n\nexport type StorageConfigBase = Partial<\n Pick<GetFromStorageConfig<any>, 'prefix' | 'type'>\n>;\n\nexport interface StorageApi<BaseConfig extends StorageConfigBase> {\n set<Value>(config: SetToStorageWrappedConfig<Value, BaseConfig>): void;\n unset(config: UnsetFromStorageWrappedConfig<BaseConfig>): void;\n get<Value>(\n config: GetFromStorageWrappedConfig<Value, BaseConfig>,\n ): Value | null;\n}\n\n/**\n * Creates an interface for working with storage (`localStorage`, `sessionStorage`).\n */\nexport function createStorage<BaseConfig extends StorageConfigBase>(\n storageConfig: BaseConfig,\n): StorageApi<BaseConfig> {\n return {\n set: <Value>(cfg: SetToStorageWrappedConfig<Value, BaseConfig>) => {\n const config = cfg as unknown as SetToStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n\n const storage = storages[storageType];\n\n storage.setItem(\n createKey(storagePrefix, config.key, config.namespace),\n formatValueToStorage(config.value),\n );\n },\n unset: <Value>(cfg: UnsetFromStorageWrappedConfig<BaseConfig>) => {\n const config = cfg as unknown as SetToStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n const storage = storages[storageType];\n\n storage.removeItem(\n createKey(storagePrefix, config.key, config.namespace),\n );\n },\n get: <Value>(cfg: GetFromStorageWrappedConfig<Value, BaseConfig>) => {\n const config = cfg as unknown as GetFromStorageConfig<Value>;\n const storageType = (config.type ?? storageConfig.type!) as StorageType;\n const storagePrefix = (config.prefix ?? storageConfig.prefix!) as string;\n\n const storage = storages[storageType];\n\n return (\n parseStorageValue<Value>(\n storage.getItem(\n createKey(storagePrefix, config.key, config.namespace),\n ),\n ) ??\n config.fallback ??\n null\n );\n },\n } as const;\n}\n"],"mappings":";AAmBA,IAAM,WAAyC;CAC7C,SAAS;CACT,OAAO;CACR;;;;;;;;;AAUD,IAAa,aAAa,QAAgB,KAAa,cACrD,GAAG,SAAS,YAAY,IAAI,cAAc,GAAG,GAAG;AAElD,IAAM,qBAAwB,UAA6B;AACzD,KAAI,OAAO,UAAU,SACnB,QAAO;AAGT,KAAI;AAEF,SADe,KAAK,MAAM,MAAM;SAE1B;AACN,SAAO;;;AAIX,IAAM,wBAAwB,UAA2B;AACvD,QAAO,KAAK,UAAU,MAAM;;;;;AA8F9B,SAAgB,cACd,eACwB;AACxB,QAAO;EACL,MAAa,QAAsD;GACjE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;AAEtC,YAAS,aAEjB,QACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,EACtD,qBAAqB,OAAO,MAAM,CACnC;;EAEH,QAAe,QAAmD;GAChE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;AACtC,YAAS,aAEjB,WACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,CACvD;;EAEH,MAAa,QAAwD;GACnE,MAAM,SAAS;GACf,MAAM,cAAe,OAAO,QAAQ,cAAc;GAClD,MAAM,gBAAiB,OAAO,UAAU,cAAc;GAEtD,MAAM,UAAU,SAAS;AAEzB,UACE,kBACE,QAAQ,QACN,UAAU,eAAe,OAAO,KAAK,OAAO,UAAU,CACvD,CACF,IACD,OAAO,YACP;;EAGL"}
|
package/text.cjs
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region src/text.ts
|
|
3
3
|
/**
|
|
4
|
+
* ---header-docs-section---
|
|
5
|
+
* # yummies/text
|
|
6
|
+
*
|
|
7
|
+
* ## Description
|
|
8
|
+
*
|
|
9
|
+
* Russian-centric text helpers: **declension** by count (одно слово / два слова / пять слов) and
|
|
10
|
+
* utilities for splitting long strings into wrapped lines. Pair with `yummies/date-time` for
|
|
11
|
+
* natural language timestamps and labels in Slavic locales.
|
|
12
|
+
*
|
|
13
|
+
* ## Usage
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { declension } from "yummies/text";
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
4
20
|
* Returns the correct word form based on the provided count.
|
|
5
21
|
* @example
|
|
6
22
|
* declension(1, ['slovo', 'slova', 'slov']) // 'slovo'
|
package/text.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.cjs","names":[],"sources":["../src/text.ts"],"sourcesContent":["/**\n * Returns the correct word form based on the provided count.\n * @example\n * declension(1, ['slovo', 'slova', 'slov']) // 'slovo'\n * @example\n * declension(2, ['slovo', 'slova', 'slov']) // 'slova'\n * @example\n * declension(5, ['slovo', 'slova', 'slov']) // 'slov'\n */\nexport const declension = (\n count: number,\n txt: readonly [one: string, two: string, five: string],\n cases = [2, 0, 1, 1, 1, 2],\n) =>\n txt[count % 100 > 4 && count % 100 < 20 ? 2 : cases[Math.min(count % 10, 5)]];\n\n/**\n * Splits text into lines with a maximum line length.\n */\nexport const splitTextByLines = (\n text: string,\n lineLingth: number = 60,\n): string[] => {\n const words = text.split(/\\s+/).filter((word) => word !== '');\n const lines = [];\n let currentLine = '';\n\n for (const word of words) {\n if (word.length > lineLingth) {\n if (currentLine !== '') {\n lines.push(currentLine);\n currentLine = '';\n }\n\n let start = 0;\n while (start < word.length) {\n const chunk = word.slice(start, start + lineLingth);\n lines.push(chunk);\n start += lineLingth;\n }\n continue;\n }\n\n // Проверка возможности добавления слова в текущую строку\n if (currentLine === '') {\n currentLine = word;\n } else if (currentLine.length + 1 + word.length <= lineLingth) {\n currentLine += ` ${word}`;\n } else {\n lines.push(currentLine);\n currentLine = word;\n }\n }\n\n if (currentLine !== '' || lines.length === 0) {\n lines.push(currentLine);\n }\n\n return lines;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"text.cjs","names":[],"sources":["../src/text.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/text\n *\n * ## Description\n *\n * Russian-centric text helpers: **declension** by count (одно слово / два слова / пять слов) and\n * utilities for splitting long strings into wrapped lines. Pair with `yummies/date-time` for\n * natural language timestamps and labels in Slavic locales.\n *\n * ## Usage\n *\n * ```ts\n * import { declension } from \"yummies/text\";\n * ```\n */\n\n/**\n * Returns the correct word form based on the provided count.\n * @example\n * declension(1, ['slovo', 'slova', 'slov']) // 'slovo'\n * @example\n * declension(2, ['slovo', 'slova', 'slov']) // 'slova'\n * @example\n * declension(5, ['slovo', 'slova', 'slov']) // 'slov'\n */\nexport const declension = (\n count: number,\n txt: readonly [one: string, two: string, five: string],\n cases = [2, 0, 1, 1, 1, 2],\n) =>\n txt[count % 100 > 4 && count % 100 < 20 ? 2 : cases[Math.min(count % 10, 5)]];\n\n/**\n * Splits text into lines with a maximum line length.\n */\nexport const splitTextByLines = (\n text: string,\n lineLingth: number = 60,\n): string[] => {\n const words = text.split(/\\s+/).filter((word) => word !== '');\n const lines = [];\n let currentLine = '';\n\n for (const word of words) {\n if (word.length > lineLingth) {\n if (currentLine !== '') {\n lines.push(currentLine);\n currentLine = '';\n }\n\n let start = 0;\n while (start < word.length) {\n const chunk = word.slice(start, start + lineLingth);\n lines.push(chunk);\n start += lineLingth;\n }\n continue;\n }\n\n // Проверка возможности добавления слова в текущую строку\n if (currentLine === '') {\n currentLine = word;\n } else if (currentLine.length + 1 + word.length <= lineLingth) {\n currentLine += ` ${word}`;\n } else {\n lines.push(currentLine);\n currentLine = word;\n }\n }\n\n if (currentLine !== '' || lines.length === 0) {\n lines.push(currentLine);\n }\n\n return lines;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAa,cACX,OACA,KACA,QAAQ;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE,KAE1B,IAAI,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,QAAQ,IAAI,EAAE;;;;AAK7E,IAAa,oBACX,MACA,aAAqB,OACR;CACb,MAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,QAAQ,SAAS,SAAS,GAAG;CAC7D,MAAM,QAAQ,EAAE;CAChB,IAAI,cAAc;AAElB,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,YAAY;AAC5B,OAAI,gBAAgB,IAAI;AACtB,UAAM,KAAK,YAAY;AACvB,kBAAc;;GAGhB,IAAI,QAAQ;AACZ,UAAO,QAAQ,KAAK,QAAQ;IAC1B,MAAM,QAAQ,KAAK,MAAM,OAAO,QAAQ,WAAW;AACnD,UAAM,KAAK,MAAM;AACjB,aAAS;;AAEX;;AAIF,MAAI,gBAAgB,GAClB,eAAc;WACL,YAAY,SAAS,IAAI,KAAK,UAAU,WACjD,gBAAe,IAAI;OACd;AACL,SAAM,KAAK,YAAY;AACvB,iBAAc;;;AAIlB,KAAI,gBAAgB,MAAM,MAAM,WAAW,EACzC,OAAM,KAAK,YAAY;AAGzB,QAAO"}
|
package/text.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ---header-docs-section---
|
|
3
|
+
* # yummies/text
|
|
4
|
+
*
|
|
5
|
+
* ## Description
|
|
6
|
+
*
|
|
7
|
+
* Russian-centric text helpers: **declension** by count (одно слово / два слова / пять слов) and
|
|
8
|
+
* utilities for splitting long strings into wrapped lines. Pair with `yummies/date-time` for
|
|
9
|
+
* natural language timestamps and labels in Slavic locales.
|
|
10
|
+
*
|
|
11
|
+
* ## Usage
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { declension } from "yummies/text";
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
1
17
|
/**
|
|
2
18
|
* Returns the correct word form based on the provided count.
|
|
3
19
|
* @example
|
package/text.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
//#region src/text.ts
|
|
2
2
|
/**
|
|
3
|
+
* ---header-docs-section---
|
|
4
|
+
* # yummies/text
|
|
5
|
+
*
|
|
6
|
+
* ## Description
|
|
7
|
+
*
|
|
8
|
+
* Russian-centric text helpers: **declension** by count (одно слово / два слова / пять слов) and
|
|
9
|
+
* utilities for splitting long strings into wrapped lines. Pair with `yummies/date-time` for
|
|
10
|
+
* natural language timestamps and labels in Slavic locales.
|
|
11
|
+
*
|
|
12
|
+
* ## Usage
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { declension } from "yummies/text";
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
3
19
|
* Returns the correct word form based on the provided count.
|
|
4
20
|
* @example
|
|
5
21
|
* declension(1, ['slovo', 'slova', 'slov']) // 'slovo'
|
package/text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../src/text.ts"],"sourcesContent":["/**\n * Returns the correct word form based on the provided count.\n * @example\n * declension(1, ['slovo', 'slova', 'slov']) // 'slovo'\n * @example\n * declension(2, ['slovo', 'slova', 'slov']) // 'slova'\n * @example\n * declension(5, ['slovo', 'slova', 'slov']) // 'slov'\n */\nexport const declension = (\n count: number,\n txt: readonly [one: string, two: string, five: string],\n cases = [2, 0, 1, 1, 1, 2],\n) =>\n txt[count % 100 > 4 && count % 100 < 20 ? 2 : cases[Math.min(count % 10, 5)]];\n\n/**\n * Splits text into lines with a maximum line length.\n */\nexport const splitTextByLines = (\n text: string,\n lineLingth: number = 60,\n): string[] => {\n const words = text.split(/\\s+/).filter((word) => word !== '');\n const lines = [];\n let currentLine = '';\n\n for (const word of words) {\n if (word.length > lineLingth) {\n if (currentLine !== '') {\n lines.push(currentLine);\n currentLine = '';\n }\n\n let start = 0;\n while (start < word.length) {\n const chunk = word.slice(start, start + lineLingth);\n lines.push(chunk);\n start += lineLingth;\n }\n continue;\n }\n\n // Проверка возможности добавления слова в текущую строку\n if (currentLine === '') {\n currentLine = word;\n } else if (currentLine.length + 1 + word.length <= lineLingth) {\n currentLine += ` ${word}`;\n } else {\n lines.push(currentLine);\n currentLine = word;\n }\n }\n\n if (currentLine !== '' || lines.length === 0) {\n lines.push(currentLine);\n }\n\n return lines;\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"text.js","names":[],"sources":["../src/text.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/text\n *\n * ## Description\n *\n * Russian-centric text helpers: **declension** by count (одно слово / два слова / пять слов) and\n * utilities for splitting long strings into wrapped lines. Pair with `yummies/date-time` for\n * natural language timestamps and labels in Slavic locales.\n *\n * ## Usage\n *\n * ```ts\n * import { declension } from \"yummies/text\";\n * ```\n */\n\n/**\n * Returns the correct word form based on the provided count.\n * @example\n * declension(1, ['slovo', 'slova', 'slov']) // 'slovo'\n * @example\n * declension(2, ['slovo', 'slova', 'slov']) // 'slova'\n * @example\n * declension(5, ['slovo', 'slova', 'slov']) // 'slov'\n */\nexport const declension = (\n count: number,\n txt: readonly [one: string, two: string, five: string],\n cases = [2, 0, 1, 1, 1, 2],\n) =>\n txt[count % 100 > 4 && count % 100 < 20 ? 2 : cases[Math.min(count % 10, 5)]];\n\n/**\n * Splits text into lines with a maximum line length.\n */\nexport const splitTextByLines = (\n text: string,\n lineLingth: number = 60,\n): string[] => {\n const words = text.split(/\\s+/).filter((word) => word !== '');\n const lines = [];\n let currentLine = '';\n\n for (const word of words) {\n if (word.length > lineLingth) {\n if (currentLine !== '') {\n lines.push(currentLine);\n currentLine = '';\n }\n\n let start = 0;\n while (start < word.length) {\n const chunk = word.slice(start, start + lineLingth);\n lines.push(chunk);\n start += lineLingth;\n }\n continue;\n }\n\n // Проверка возможности добавления слова в текущую строку\n if (currentLine === '') {\n currentLine = word;\n } else if (currentLine.length + 1 + word.length <= lineLingth) {\n currentLine += ` ${word}`;\n } else {\n lines.push(currentLine);\n currentLine = word;\n }\n }\n\n if (currentLine !== '' || lines.length === 0) {\n lines.push(currentLine);\n }\n\n return lines;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAa,cACX,OACA,KACA,QAAQ;CAAC;CAAG;CAAG;CAAG;CAAG;CAAG;CAAE,KAE1B,IAAI,QAAQ,MAAM,KAAK,QAAQ,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,QAAQ,IAAI,EAAE;;;;AAK7E,IAAa,oBACX,MACA,aAAqB,OACR;CACb,MAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,QAAQ,SAAS,SAAS,GAAG;CAC7D,MAAM,QAAQ,EAAE;CAChB,IAAI,cAAc;AAElB,MAAK,MAAM,QAAQ,OAAO;AACxB,MAAI,KAAK,SAAS,YAAY;AAC5B,OAAI,gBAAgB,IAAI;AACtB,UAAM,KAAK,YAAY;AACvB,kBAAc;;GAGhB,IAAI,QAAQ;AACZ,UAAO,QAAQ,KAAK,QAAQ;IAC1B,MAAM,QAAQ,KAAK,MAAM,OAAO,QAAQ,WAAW;AACnD,UAAM,KAAK,MAAM;AACjB,aAAS;;AAEX;;AAIF,MAAI,gBAAgB,GAClB,eAAc;WACL,YAAY,SAAS,IAAI,KAAK,UAAU,WACjD,gBAAe,IAAI;OACd;AACL,SAAM,KAAK,YAAY;AACvB,iBAAc;;;AAIlB,KAAI,gBAAgB,MAAM,MAAM,WAAW,EACzC,OAAM,KAAK,YAAY;AAGzB,QAAO"}
|
package/type-guard.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-guard.cjs","names":[],"sources":["../src/type-guard/_exports.ts"],"sourcesContent":["import type { AnyFunction, AnyObject, ValueOf } from 'yummies/types';\n\nconst TYPE = {\n Null: 'null',\n Undefined: 'undefined',\n NaN: 'nan',\n Object: '[object Object]',\n Array: '[object Array]',\n String: '[object String]',\n Number: '[object Number]',\n Boolean: '[object Boolean]',\n Function: '[object Function]',\n AsyncFunction: '[object AsyncFunction]',\n RegExp: '[object RegExp]',\n Symbol: '[object Symbol]',\n Infinite: 'infinite',\n Element: 'element',\n};\n\ntype Type = ValueOf<typeof TYPE>;\n\nfunction getType(value: unknown): Type {\n if (value === undefined) {\n return TYPE.Undefined;\n }\n if (value === null) {\n return TYPE.Null;\n }\n\n // handle DOM elements\n // @ts-expect-error\n if (value && (value.nodeType === 1 || value.nodeType === 9)) {\n return TYPE.Element;\n }\n\n const stringifiedValue = Object.prototype.toString.call(value);\n\n // handle NaN and Infinity\n if (stringifiedValue === TYPE.Number) {\n if (Number.isNaN(value as number)) {\n return TYPE.NaN;\n }\n if (!Number.isFinite(value as number)) {\n return TYPE.Infinite;\n }\n }\n\n return stringifiedValue as Type;\n}\n\nconst createTypeGuard =\n <T>(...types: Type[]) =>\n (value: unknown): value is T =>\n types.includes(getType(value));\n\n/**\n * Checks that a value is neither `null` nor `undefined`.\n *\n * @template T Value type without nullish branches.\n * @param value Value to test.\n * @returns `true` when the value is defined.\n *\n * @example\n * ```ts\n * isDefined(0); // true\n * ```\n *\n * @example\n * ```ts\n * isDefined(null); // false\n * ```\n */\nexport const isDefined = <T>(value: T | undefined | null): value is T =>\n value != null;\n\n/**\n * Checks whether a value is exactly `null`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `null`.\n *\n * @example\n * ```ts\n * isNull(null); // true\n * ```\n *\n * @example\n * ```ts\n * isNull(undefined); // false\n * ```\n */\nexport const isNull = createTypeGuard<null>(TYPE.Null);\n\n/**\n * Checks whether a value is exactly `undefined`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `undefined`.\n *\n * @example\n * ```ts\n * isUndefined(undefined); // true\n * ```\n *\n * @example\n * ```ts\n * isUndefined('value'); // false\n * ```\n */\nexport const isUndefined = createTypeGuard<undefined>(TYPE.Undefined);\n\n/**\n * Checks whether a value is a plain object.\n *\n * @param value Value to test.\n * @returns `true` when the value matches `[object Object]`.\n *\n * @example\n * ```ts\n * isObject({ id: 1 }); // true\n * ```\n *\n * @example\n * ```ts\n * isObject([]); // false\n * ```\n */\nexport const isObject = createTypeGuard<AnyObject>(TYPE.Object);\n\n/**\n * Checks whether a value is an array.\n *\n * @param value Value to test.\n * @returns `true` when the value is an array.\n *\n * @example\n * ```ts\n * isArray([1, 2, 3]); // true\n * ```\n *\n * @example\n * ```ts\n * isArray({ length: 1 }); // false\n * ```\n */\nexport const isArray = createTypeGuard<unknown[]>(TYPE.Array);\n\n/**\n * Checks whether a value is a string object or primitive string.\n *\n * @param value Value to test.\n * @returns `true` when the value is a string.\n *\n * @example\n * ```ts\n * isString('hello'); // true\n * ```\n *\n * @example\n * ```ts\n * isString(123); // false\n * ```\n */\nexport const isString = createTypeGuard<string>(TYPE.String);\n\n/**\n * Checks whether a value is a finite number.\n *\n * Unlike `isNaN` and `isInfinite`, this guard only matches regular numeric values.\n *\n * @param value Value to test.\n * @returns `true` when the value is a non-NaN finite number.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * ```\n *\n * @example\n * ```ts\n * isNumber(Number.NaN); // false\n * ```\n */\nexport const isNumber = createTypeGuard<number>(TYPE.Number);\n\n/**\n * Checks whether a value is a boolean.\n *\n * @param value Value to test.\n * @returns `true` when the value is a boolean.\n *\n * @example\n * ```ts\n * isBoolean(true); // true\n * ```\n *\n * @example\n * ```ts\n * isBoolean('true'); // false\n * ```\n */\nexport const isBoolean = createTypeGuard<boolean>(TYPE.Boolean);\n\n/**\n * Checks whether a value is a synchronous or asynchronous function.\n *\n * @param value Value to test.\n * @returns `true` when the value is a function.\n *\n * @example\n * ```ts\n * isFunction(() => {}); // true\n * ```\n *\n * @example\n * ```ts\n * isFunction(async () => {}); // true\n * ```\n */\nexport const isFunction = createTypeGuard<AnyFunction>(\n TYPE.Function,\n TYPE.AsyncFunction,\n);\n\n/**\n * Checks whether a value is a regular expression.\n *\n * @param value Value to test.\n * @returns `true` when the value is a `RegExp`.\n *\n * @example\n * ```ts\n * isRegExp(/foo/); // true\n * ```\n *\n * @example\n * ```ts\n * isRegExp('foo'); // false\n * ```\n */\nexport const isRegExp = createTypeGuard<RegExp>(TYPE.RegExp);\n\n/**\n * Checks whether a value looks like a DOM element or document node.\n *\n * @param value Value to test.\n * @returns `true` when the value has an element-like node type.\n *\n * @example\n * ```ts\n * isElement(document.body); // true\n * ```\n *\n * @example\n * ```ts\n * isElement({ nodeType: 3 }); // false\n * ```\n */\nexport const isElement = createTypeGuard<HTMLElement>(TYPE.Element);\n\n/**\n * Checks whether a value is `NaN`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `NaN`.\n *\n * @example\n * ```ts\n * isNaN(Number.NaN); // true\n * ```\n *\n * @example\n * ```ts\n * isNaN(5); // false\n * ```\n */\nexport const isNaN = createTypeGuard<number>(TYPE.NaN) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is positive or negative infinity.\n *\n * @param value Value to test.\n * @returns `true` when the value is not finite.\n *\n * @example\n * ```ts\n * isInfinite(Infinity); // true\n * ```\n *\n * @example\n * ```ts\n * isInfinite(10); // false\n * ```\n */\nexport const isInfinite = createTypeGuard<number>(TYPE.Infinite) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is a symbol.\n *\n * @param value Value to test.\n * @returns `true` when the value is a symbol.\n *\n * @example\n * ```ts\n * isSymbol(Symbol('id')); // true\n * ```\n *\n * @example\n * ```ts\n * isSymbol('id'); // false\n * ```\n */\nexport const isSymbol = createTypeGuard<symbol>(TYPE.Symbol);\n"],"mappings":";;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"type-guard.cjs","names":[],"sources":["../src/type-guard/_exports.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/type-guard\n *\n * ## Description\n *\n * Runtime **type guards** and narrowers for primitives, DOM nodes, `NaN`, and common app values.\n * Each helper is implemented once with consistent `typeof` / `Object.prototype.toString` logic so\n * `unknown` from JSON, events, or third-party scripts becomes safe typed branches without ad-hoc\n * checks scattered through the codebase.\n *\n * ## Usage\n *\n * ```ts\n * import { typeGuard } from \"yummies/type-guard\";\n * ```\n */\n\nimport type { AnyFunction, AnyObject, ValueOf } from 'yummies/types';\n\nconst TYPE = {\n Null: 'null',\n Undefined: 'undefined',\n NaN: 'nan',\n Object: '[object Object]',\n Array: '[object Array]',\n String: '[object String]',\n Number: '[object Number]',\n Boolean: '[object Boolean]',\n Function: '[object Function]',\n AsyncFunction: '[object AsyncFunction]',\n RegExp: '[object RegExp]',\n Symbol: '[object Symbol]',\n Infinite: 'infinite',\n Element: 'element',\n};\n\ntype Type = ValueOf<typeof TYPE>;\n\nfunction getType(value: unknown): Type {\n if (value === undefined) {\n return TYPE.Undefined;\n }\n if (value === null) {\n return TYPE.Null;\n }\n\n // handle DOM elements\n // @ts-expect-error\n if (value && (value.nodeType === 1 || value.nodeType === 9)) {\n return TYPE.Element;\n }\n\n const stringifiedValue = Object.prototype.toString.call(value);\n\n // handle NaN and Infinity\n if (stringifiedValue === TYPE.Number) {\n if (Number.isNaN(value as number)) {\n return TYPE.NaN;\n }\n if (!Number.isFinite(value as number)) {\n return TYPE.Infinite;\n }\n }\n\n return stringifiedValue as Type;\n}\n\nconst createTypeGuard =\n <T>(...types: Type[]) =>\n (value: unknown): value is T =>\n types.includes(getType(value));\n\n/**\n * Checks that a value is neither `null` nor `undefined`.\n *\n * @template T Value type without nullish branches.\n * @param value Value to test.\n * @returns `true` when the value is defined.\n *\n * @example\n * ```ts\n * isDefined(0); // true\n * ```\n *\n * @example\n * ```ts\n * isDefined(null); // false\n * ```\n */\nexport const isDefined = <T>(value: T | undefined | null): value is T =>\n value != null;\n\n/**\n * Checks whether a value is exactly `null`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `null`.\n *\n * @example\n * ```ts\n * isNull(null); // true\n * ```\n *\n * @example\n * ```ts\n * isNull(undefined); // false\n * ```\n */\nexport const isNull = createTypeGuard<null>(TYPE.Null);\n\n/**\n * Checks whether a value is exactly `undefined`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `undefined`.\n *\n * @example\n * ```ts\n * isUndefined(undefined); // true\n * ```\n *\n * @example\n * ```ts\n * isUndefined('value'); // false\n * ```\n */\nexport const isUndefined = createTypeGuard<undefined>(TYPE.Undefined);\n\n/**\n * Checks whether a value is a plain object.\n *\n * @param value Value to test.\n * @returns `true` when the value matches `[object Object]`.\n *\n * @example\n * ```ts\n * isObject({ id: 1 }); // true\n * ```\n *\n * @example\n * ```ts\n * isObject([]); // false\n * ```\n */\nexport const isObject = createTypeGuard<AnyObject>(TYPE.Object);\n\n/**\n * Checks whether a value is an array.\n *\n * @param value Value to test.\n * @returns `true` when the value is an array.\n *\n * @example\n * ```ts\n * isArray([1, 2, 3]); // true\n * ```\n *\n * @example\n * ```ts\n * isArray({ length: 1 }); // false\n * ```\n */\nexport const isArray = createTypeGuard<unknown[]>(TYPE.Array);\n\n/**\n * Checks whether a value is a string object or primitive string.\n *\n * @param value Value to test.\n * @returns `true` when the value is a string.\n *\n * @example\n * ```ts\n * isString('hello'); // true\n * ```\n *\n * @example\n * ```ts\n * isString(123); // false\n * ```\n */\nexport const isString = createTypeGuard<string>(TYPE.String);\n\n/**\n * Checks whether a value is a finite number.\n *\n * Unlike `isNaN` and `isInfinite`, this guard only matches regular numeric values.\n *\n * @param value Value to test.\n * @returns `true` when the value is a non-NaN finite number.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * ```\n *\n * @example\n * ```ts\n * isNumber(Number.NaN); // false\n * ```\n */\nexport const isNumber = createTypeGuard<number>(TYPE.Number);\n\n/**\n * Checks whether a value is a boolean.\n *\n * @param value Value to test.\n * @returns `true` when the value is a boolean.\n *\n * @example\n * ```ts\n * isBoolean(true); // true\n * ```\n *\n * @example\n * ```ts\n * isBoolean('true'); // false\n * ```\n */\nexport const isBoolean = createTypeGuard<boolean>(TYPE.Boolean);\n\n/**\n * Checks whether a value is a synchronous or asynchronous function.\n *\n * @param value Value to test.\n * @returns `true` when the value is a function.\n *\n * @example\n * ```ts\n * isFunction(() => {}); // true\n * ```\n *\n * @example\n * ```ts\n * isFunction(async () => {}); // true\n * ```\n */\nexport const isFunction = createTypeGuard<AnyFunction>(\n TYPE.Function,\n TYPE.AsyncFunction,\n);\n\n/**\n * Checks whether a value is a regular expression.\n *\n * @param value Value to test.\n * @returns `true` when the value is a `RegExp`.\n *\n * @example\n * ```ts\n * isRegExp(/foo/); // true\n * ```\n *\n * @example\n * ```ts\n * isRegExp('foo'); // false\n * ```\n */\nexport const isRegExp = createTypeGuard<RegExp>(TYPE.RegExp);\n\n/**\n * Checks whether a value looks like a DOM element or document node.\n *\n * @param value Value to test.\n * @returns `true` when the value has an element-like node type.\n *\n * @example\n * ```ts\n * isElement(document.body); // true\n * ```\n *\n * @example\n * ```ts\n * isElement({ nodeType: 3 }); // false\n * ```\n */\nexport const isElement = createTypeGuard<HTMLElement>(TYPE.Element);\n\n/**\n * Checks whether a value is `NaN`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `NaN`.\n *\n * @example\n * ```ts\n * isNaN(Number.NaN); // true\n * ```\n *\n * @example\n * ```ts\n * isNaN(5); // false\n * ```\n */\nexport const isNaN = createTypeGuard<number>(TYPE.NaN) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is positive or negative infinity.\n *\n * @param value Value to test.\n * @returns `true` when the value is not finite.\n *\n * @example\n * ```ts\n * isInfinite(Infinity); // true\n * ```\n *\n * @example\n * ```ts\n * isInfinite(10); // false\n * ```\n */\nexport const isInfinite = createTypeGuard<number>(TYPE.Infinite) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is a symbol.\n *\n * @param value Value to test.\n * @returns `true` when the value is a symbol.\n *\n * @example\n * ```ts\n * isSymbol(Symbol('id')); // true\n * ```\n *\n * @example\n * ```ts\n * isSymbol('id'); // false\n * ```\n */\nexport const isSymbol = createTypeGuard<symbol>(TYPE.Symbol);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,IAAM,OAAO;CACX,MAAM;CACN,WAAW;CACX,KAAK;CACL,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,UAAU;CACV,eAAe;CACf,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACV;AAID,SAAS,QAAQ,OAAsB;AACrC,KAAI,UAAU,KAAA,EACZ,QAAO,KAAK;AAEd,KAAI,UAAU,KACZ,QAAO,KAAK;AAKd,KAAI,UAAU,MAAM,aAAa,KAAK,MAAM,aAAa,GACvD,QAAO,KAAK;CAGd,MAAM,mBAAmB,OAAO,UAAU,SAAS,KAAK,MAAM;AAG9D,KAAI,qBAAqB,KAAK,QAAQ;AACpC,MAAI,OAAO,MAAM,MAAgB,CAC/B,QAAO,KAAK;AAEd,MAAI,CAAC,OAAO,SAAS,MAAgB,CACnC,QAAO,KAAK;;AAIhB,QAAO;;AAGT,IAAM,mBACA,GAAG,WACN,UACC,MAAM,SAAS,QAAQ,MAAM,CAAC;;;;;;;;;;;;;;;;;;AAmBlC,IAAa,aAAgB,UAC3B,SAAS;;;;;;;;;;;;;;;;;AAkBX,IAAa,SAAS,gBAAsB,KAAK,KAAK;;;;;;;;;;;;;;;;;AAkBtD,IAAa,cAAc,gBAA2B,KAAK,UAAU;;;;;;;;;;;;;;;;;AAkBrE,IAAa,WAAW,gBAA2B,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB/D,IAAa,UAAU,gBAA2B,KAAK,MAAM;;;;;;;;;;;;;;;;;AAkB7D,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;;;AAoB5D,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB5D,IAAa,YAAY,gBAAyB,KAAK,QAAQ;;;;;;;;;;;;;;;;;AAkB/D,IAAa,aAAa,gBACxB,KAAK,UACL,KAAK,cACN;;;;;;;;;;;;;;;;;AAkBD,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB5D,IAAa,YAAY,gBAA6B,KAAK,QAAQ;;;;;;;;;;;;;;;;;AAkBnE,IAAa,QAAQ,gBAAwB,KAAK,IAAI;;;;;;;;;;;;;;;;;AAoBtD,IAAa,aAAa,gBAAwB,KAAK,SAAS;;;;;;;;;;;;;;;;;AAoBhE,IAAa,WAAW,gBAAwB,KAAK,OAAO"}
|
package/type-guard.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
import { AnyFunction, AnyObject } from 'yummies/types';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* ---header-docs-section---
|
|
5
|
+
* # yummies/type-guard
|
|
6
|
+
*
|
|
7
|
+
* ## Description
|
|
8
|
+
*
|
|
9
|
+
* Runtime **type guards** and narrowers for primitives, DOM nodes, `NaN`, and common app values.
|
|
10
|
+
* Each helper is implemented once with consistent `typeof` / `Object.prototype.toString` logic so
|
|
11
|
+
* `unknown` from JSON, events, or third-party scripts becomes safe typed branches without ad-hoc
|
|
12
|
+
* checks scattered through the codebase.
|
|
13
|
+
*
|
|
14
|
+
* ## Usage
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { typeGuard } from "yummies/type-guard";
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
3
21
|
/**
|
|
4
22
|
* Checks that a value is neither `null` nor `undefined`.
|
|
5
23
|
*
|
package/type-guard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-guard.js","names":[],"sources":["../src/type-guard/_exports.ts"],"sourcesContent":["import type { AnyFunction, AnyObject, ValueOf } from 'yummies/types';\n\nconst TYPE = {\n Null: 'null',\n Undefined: 'undefined',\n NaN: 'nan',\n Object: '[object Object]',\n Array: '[object Array]',\n String: '[object String]',\n Number: '[object Number]',\n Boolean: '[object Boolean]',\n Function: '[object Function]',\n AsyncFunction: '[object AsyncFunction]',\n RegExp: '[object RegExp]',\n Symbol: '[object Symbol]',\n Infinite: 'infinite',\n Element: 'element',\n};\n\ntype Type = ValueOf<typeof TYPE>;\n\nfunction getType(value: unknown): Type {\n if (value === undefined) {\n return TYPE.Undefined;\n }\n if (value === null) {\n return TYPE.Null;\n }\n\n // handle DOM elements\n // @ts-expect-error\n if (value && (value.nodeType === 1 || value.nodeType === 9)) {\n return TYPE.Element;\n }\n\n const stringifiedValue = Object.prototype.toString.call(value);\n\n // handle NaN and Infinity\n if (stringifiedValue === TYPE.Number) {\n if (Number.isNaN(value as number)) {\n return TYPE.NaN;\n }\n if (!Number.isFinite(value as number)) {\n return TYPE.Infinite;\n }\n }\n\n return stringifiedValue as Type;\n}\n\nconst createTypeGuard =\n <T>(...types: Type[]) =>\n (value: unknown): value is T =>\n types.includes(getType(value));\n\n/**\n * Checks that a value is neither `null` nor `undefined`.\n *\n * @template T Value type without nullish branches.\n * @param value Value to test.\n * @returns `true` when the value is defined.\n *\n * @example\n * ```ts\n * isDefined(0); // true\n * ```\n *\n * @example\n * ```ts\n * isDefined(null); // false\n * ```\n */\nexport const isDefined = <T>(value: T | undefined | null): value is T =>\n value != null;\n\n/**\n * Checks whether a value is exactly `null`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `null`.\n *\n * @example\n * ```ts\n * isNull(null); // true\n * ```\n *\n * @example\n * ```ts\n * isNull(undefined); // false\n * ```\n */\nexport const isNull = createTypeGuard<null>(TYPE.Null);\n\n/**\n * Checks whether a value is exactly `undefined`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `undefined`.\n *\n * @example\n * ```ts\n * isUndefined(undefined); // true\n * ```\n *\n * @example\n * ```ts\n * isUndefined('value'); // false\n * ```\n */\nexport const isUndefined = createTypeGuard<undefined>(TYPE.Undefined);\n\n/**\n * Checks whether a value is a plain object.\n *\n * @param value Value to test.\n * @returns `true` when the value matches `[object Object]`.\n *\n * @example\n * ```ts\n * isObject({ id: 1 }); // true\n * ```\n *\n * @example\n * ```ts\n * isObject([]); // false\n * ```\n */\nexport const isObject = createTypeGuard<AnyObject>(TYPE.Object);\n\n/**\n * Checks whether a value is an array.\n *\n * @param value Value to test.\n * @returns `true` when the value is an array.\n *\n * @example\n * ```ts\n * isArray([1, 2, 3]); // true\n * ```\n *\n * @example\n * ```ts\n * isArray({ length: 1 }); // false\n * ```\n */\nexport const isArray = createTypeGuard<unknown[]>(TYPE.Array);\n\n/**\n * Checks whether a value is a string object or primitive string.\n *\n * @param value Value to test.\n * @returns `true` when the value is a string.\n *\n * @example\n * ```ts\n * isString('hello'); // true\n * ```\n *\n * @example\n * ```ts\n * isString(123); // false\n * ```\n */\nexport const isString = createTypeGuard<string>(TYPE.String);\n\n/**\n * Checks whether a value is a finite number.\n *\n * Unlike `isNaN` and `isInfinite`, this guard only matches regular numeric values.\n *\n * @param value Value to test.\n * @returns `true` when the value is a non-NaN finite number.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * ```\n *\n * @example\n * ```ts\n * isNumber(Number.NaN); // false\n * ```\n */\nexport const isNumber = createTypeGuard<number>(TYPE.Number);\n\n/**\n * Checks whether a value is a boolean.\n *\n * @param value Value to test.\n * @returns `true` when the value is a boolean.\n *\n * @example\n * ```ts\n * isBoolean(true); // true\n * ```\n *\n * @example\n * ```ts\n * isBoolean('true'); // false\n * ```\n */\nexport const isBoolean = createTypeGuard<boolean>(TYPE.Boolean);\n\n/**\n * Checks whether a value is a synchronous or asynchronous function.\n *\n * @param value Value to test.\n * @returns `true` when the value is a function.\n *\n * @example\n * ```ts\n * isFunction(() => {}); // true\n * ```\n *\n * @example\n * ```ts\n * isFunction(async () => {}); // true\n * ```\n */\nexport const isFunction = createTypeGuard<AnyFunction>(\n TYPE.Function,\n TYPE.AsyncFunction,\n);\n\n/**\n * Checks whether a value is a regular expression.\n *\n * @param value Value to test.\n * @returns `true` when the value is a `RegExp`.\n *\n * @example\n * ```ts\n * isRegExp(/foo/); // true\n * ```\n *\n * @example\n * ```ts\n * isRegExp('foo'); // false\n * ```\n */\nexport const isRegExp = createTypeGuard<RegExp>(TYPE.RegExp);\n\n/**\n * Checks whether a value looks like a DOM element or document node.\n *\n * @param value Value to test.\n * @returns `true` when the value has an element-like node type.\n *\n * @example\n * ```ts\n * isElement(document.body); // true\n * ```\n *\n * @example\n * ```ts\n * isElement({ nodeType: 3 }); // false\n * ```\n */\nexport const isElement = createTypeGuard<HTMLElement>(TYPE.Element);\n\n/**\n * Checks whether a value is `NaN`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `NaN`.\n *\n * @example\n * ```ts\n * isNaN(Number.NaN); // true\n * ```\n *\n * @example\n * ```ts\n * isNaN(5); // false\n * ```\n */\nexport const isNaN = createTypeGuard<number>(TYPE.NaN) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is positive or negative infinity.\n *\n * @param value Value to test.\n * @returns `true` when the value is not finite.\n *\n * @example\n * ```ts\n * isInfinite(Infinity); // true\n * ```\n *\n * @example\n * ```ts\n * isInfinite(10); // false\n * ```\n */\nexport const isInfinite = createTypeGuard<number>(TYPE.Infinite) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is a symbol.\n *\n * @param value Value to test.\n * @returns `true` when the value is a symbol.\n *\n * @example\n * ```ts\n * isSymbol(Symbol('id')); // true\n * ```\n *\n * @example\n * ```ts\n * isSymbol('id'); // false\n * ```\n */\nexport const isSymbol = createTypeGuard<symbol>(TYPE.Symbol);\n"],"mappings":";;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"type-guard.js","names":[],"sources":["../src/type-guard/_exports.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/type-guard\n *\n * ## Description\n *\n * Runtime **type guards** and narrowers for primitives, DOM nodes, `NaN`, and common app values.\n * Each helper is implemented once with consistent `typeof` / `Object.prototype.toString` logic so\n * `unknown` from JSON, events, or third-party scripts becomes safe typed branches without ad-hoc\n * checks scattered through the codebase.\n *\n * ## Usage\n *\n * ```ts\n * import { typeGuard } from \"yummies/type-guard\";\n * ```\n */\n\nimport type { AnyFunction, AnyObject, ValueOf } from 'yummies/types';\n\nconst TYPE = {\n Null: 'null',\n Undefined: 'undefined',\n NaN: 'nan',\n Object: '[object Object]',\n Array: '[object Array]',\n String: '[object String]',\n Number: '[object Number]',\n Boolean: '[object Boolean]',\n Function: '[object Function]',\n AsyncFunction: '[object AsyncFunction]',\n RegExp: '[object RegExp]',\n Symbol: '[object Symbol]',\n Infinite: 'infinite',\n Element: 'element',\n};\n\ntype Type = ValueOf<typeof TYPE>;\n\nfunction getType(value: unknown): Type {\n if (value === undefined) {\n return TYPE.Undefined;\n }\n if (value === null) {\n return TYPE.Null;\n }\n\n // handle DOM elements\n // @ts-expect-error\n if (value && (value.nodeType === 1 || value.nodeType === 9)) {\n return TYPE.Element;\n }\n\n const stringifiedValue = Object.prototype.toString.call(value);\n\n // handle NaN and Infinity\n if (stringifiedValue === TYPE.Number) {\n if (Number.isNaN(value as number)) {\n return TYPE.NaN;\n }\n if (!Number.isFinite(value as number)) {\n return TYPE.Infinite;\n }\n }\n\n return stringifiedValue as Type;\n}\n\nconst createTypeGuard =\n <T>(...types: Type[]) =>\n (value: unknown): value is T =>\n types.includes(getType(value));\n\n/**\n * Checks that a value is neither `null` nor `undefined`.\n *\n * @template T Value type without nullish branches.\n * @param value Value to test.\n * @returns `true` when the value is defined.\n *\n * @example\n * ```ts\n * isDefined(0); // true\n * ```\n *\n * @example\n * ```ts\n * isDefined(null); // false\n * ```\n */\nexport const isDefined = <T>(value: T | undefined | null): value is T =>\n value != null;\n\n/**\n * Checks whether a value is exactly `null`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `null`.\n *\n * @example\n * ```ts\n * isNull(null); // true\n * ```\n *\n * @example\n * ```ts\n * isNull(undefined); // false\n * ```\n */\nexport const isNull = createTypeGuard<null>(TYPE.Null);\n\n/**\n * Checks whether a value is exactly `undefined`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `undefined`.\n *\n * @example\n * ```ts\n * isUndefined(undefined); // true\n * ```\n *\n * @example\n * ```ts\n * isUndefined('value'); // false\n * ```\n */\nexport const isUndefined = createTypeGuard<undefined>(TYPE.Undefined);\n\n/**\n * Checks whether a value is a plain object.\n *\n * @param value Value to test.\n * @returns `true` when the value matches `[object Object]`.\n *\n * @example\n * ```ts\n * isObject({ id: 1 }); // true\n * ```\n *\n * @example\n * ```ts\n * isObject([]); // false\n * ```\n */\nexport const isObject = createTypeGuard<AnyObject>(TYPE.Object);\n\n/**\n * Checks whether a value is an array.\n *\n * @param value Value to test.\n * @returns `true` when the value is an array.\n *\n * @example\n * ```ts\n * isArray([1, 2, 3]); // true\n * ```\n *\n * @example\n * ```ts\n * isArray({ length: 1 }); // false\n * ```\n */\nexport const isArray = createTypeGuard<unknown[]>(TYPE.Array);\n\n/**\n * Checks whether a value is a string object or primitive string.\n *\n * @param value Value to test.\n * @returns `true` when the value is a string.\n *\n * @example\n * ```ts\n * isString('hello'); // true\n * ```\n *\n * @example\n * ```ts\n * isString(123); // false\n * ```\n */\nexport const isString = createTypeGuard<string>(TYPE.String);\n\n/**\n * Checks whether a value is a finite number.\n *\n * Unlike `isNaN` and `isInfinite`, this guard only matches regular numeric values.\n *\n * @param value Value to test.\n * @returns `true` when the value is a non-NaN finite number.\n *\n * @example\n * ```ts\n * isNumber(123); // true\n * ```\n *\n * @example\n * ```ts\n * isNumber(Number.NaN); // false\n * ```\n */\nexport const isNumber = createTypeGuard<number>(TYPE.Number);\n\n/**\n * Checks whether a value is a boolean.\n *\n * @param value Value to test.\n * @returns `true` when the value is a boolean.\n *\n * @example\n * ```ts\n * isBoolean(true); // true\n * ```\n *\n * @example\n * ```ts\n * isBoolean('true'); // false\n * ```\n */\nexport const isBoolean = createTypeGuard<boolean>(TYPE.Boolean);\n\n/**\n * Checks whether a value is a synchronous or asynchronous function.\n *\n * @param value Value to test.\n * @returns `true` when the value is a function.\n *\n * @example\n * ```ts\n * isFunction(() => {}); // true\n * ```\n *\n * @example\n * ```ts\n * isFunction(async () => {}); // true\n * ```\n */\nexport const isFunction = createTypeGuard<AnyFunction>(\n TYPE.Function,\n TYPE.AsyncFunction,\n);\n\n/**\n * Checks whether a value is a regular expression.\n *\n * @param value Value to test.\n * @returns `true` when the value is a `RegExp`.\n *\n * @example\n * ```ts\n * isRegExp(/foo/); // true\n * ```\n *\n * @example\n * ```ts\n * isRegExp('foo'); // false\n * ```\n */\nexport const isRegExp = createTypeGuard<RegExp>(TYPE.RegExp);\n\n/**\n * Checks whether a value looks like a DOM element or document node.\n *\n * @param value Value to test.\n * @returns `true` when the value has an element-like node type.\n *\n * @example\n * ```ts\n * isElement(document.body); // true\n * ```\n *\n * @example\n * ```ts\n * isElement({ nodeType: 3 }); // false\n * ```\n */\nexport const isElement = createTypeGuard<HTMLElement>(TYPE.Element);\n\n/**\n * Checks whether a value is `NaN`.\n *\n * @param value Value to test.\n * @returns `true` when the value is `NaN`.\n *\n * @example\n * ```ts\n * isNaN(Number.NaN); // true\n * ```\n *\n * @example\n * ```ts\n * isNaN(5); // false\n * ```\n */\nexport const isNaN = createTypeGuard<number>(TYPE.NaN) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is positive or negative infinity.\n *\n * @param value Value to test.\n * @returns `true` when the value is not finite.\n *\n * @example\n * ```ts\n * isInfinite(Infinity); // true\n * ```\n *\n * @example\n * ```ts\n * isInfinite(10); // false\n * ```\n */\nexport const isInfinite = createTypeGuard<number>(TYPE.Infinite) as (\n value: unknown,\n) => boolean;\n\n/**\n * Checks whether a value is a symbol.\n *\n * @param value Value to test.\n * @returns `true` when the value is a symbol.\n *\n * @example\n * ```ts\n * isSymbol(Symbol('id')); // true\n * ```\n *\n * @example\n * ```ts\n * isSymbol('id'); // false\n * ```\n */\nexport const isSymbol = createTypeGuard<symbol>(TYPE.Symbol);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoBA,IAAM,OAAO;CACX,MAAM;CACN,WAAW;CACX,KAAK;CACL,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,UAAU;CACV,eAAe;CACf,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,SAAS;CACV;AAID,SAAS,QAAQ,OAAsB;AACrC,KAAI,UAAU,KAAA,EACZ,QAAO,KAAK;AAEd,KAAI,UAAU,KACZ,QAAO,KAAK;AAKd,KAAI,UAAU,MAAM,aAAa,KAAK,MAAM,aAAa,GACvD,QAAO,KAAK;CAGd,MAAM,mBAAmB,OAAO,UAAU,SAAS,KAAK,MAAM;AAG9D,KAAI,qBAAqB,KAAK,QAAQ;AACpC,MAAI,OAAO,MAAM,MAAgB,CAC/B,QAAO,KAAK;AAEd,MAAI,CAAC,OAAO,SAAS,MAAgB,CACnC,QAAO,KAAK;;AAIhB,QAAO;;AAGT,IAAM,mBACA,GAAG,WACN,UACC,MAAM,SAAS,QAAQ,MAAM,CAAC;;;;;;;;;;;;;;;;;;AAmBlC,IAAa,aAAgB,UAC3B,SAAS;;;;;;;;;;;;;;;;;AAkBX,IAAa,SAAS,gBAAsB,KAAK,KAAK;;;;;;;;;;;;;;;;;AAkBtD,IAAa,cAAc,gBAA2B,KAAK,UAAU;;;;;;;;;;;;;;;;;AAkBrE,IAAa,WAAW,gBAA2B,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB/D,IAAa,UAAU,gBAA2B,KAAK,MAAM;;;;;;;;;;;;;;;;;AAkB7D,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;;;AAoB5D,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB5D,IAAa,YAAY,gBAAyB,KAAK,QAAQ;;;;;;;;;;;;;;;;;AAkB/D,IAAa,aAAa,gBACxB,KAAK,UACL,KAAK,cACN;;;;;;;;;;;;;;;;;AAkBD,IAAa,WAAW,gBAAwB,KAAK,OAAO;;;;;;;;;;;;;;;;;AAkB5D,IAAa,YAAY,gBAA6B,KAAK,QAAQ;;;;;;;;;;;;;;;;;AAkBnE,IAAa,QAAQ,gBAAwB,KAAK,IAAI;;;;;;;;;;;;;;;;;AAoBtD,IAAa,aAAa,gBAAwB,KAAK,SAAS;;;;;;;;;;;;;;;;;AAoBhE,IAAa,WAAW,gBAAwB,KAAK,OAAO"}
|
package/types.d.ts
CHANGED
|
@@ -1,3 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ---header-docs-section---
|
|
3
|
+
* # yummies/types
|
|
4
|
+
*
|
|
5
|
+
* ## Description
|
|
6
|
+
*
|
|
7
|
+
* This module collects **TypeScript-only** helpers: `ValueOf`, nullable aliases, branded types, and
|
|
8
|
+
* patterns for props and generics. Nothing here exists at runtime — use `import type` so bundlers
|
|
9
|
+
* drop the imports entirely. The same ideas are also published as **ambient** globals under a
|
|
10
|
+
* separate entry (see below) when you want types in scope without repeating imports in every file.
|
|
11
|
+
*
|
|
12
|
+
* ## `yummies/types.global`
|
|
13
|
+
*
|
|
14
|
+
* Use this subpath when you prefer **global** declarations (no per-file imports). After installing
|
|
15
|
+
* the package, reference the built `.d.ts` bundle — typically via a side-effect import that pulls
|
|
16
|
+
* ambient types into the compilation unit:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* import "yummies/types.global";
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* Or list it under `compilerOptions.types` in **`tsconfig.json`** so `tsc` loads it for the project:
|
|
23
|
+
*
|
|
24
|
+
* ```json
|
|
25
|
+
* {
|
|
26
|
+
* "compilerOptions": {
|
|
27
|
+
* "types": ["yummies/types.global"]
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* ## `yummies/types` (library)
|
|
33
|
+
*
|
|
34
|
+
* Prefer this entry when you want **explicit**, traceable imports at each call site (tree-shaking
|
|
35
|
+
* friendly and clearer in reviews). The root package may re-export some symbols, but
|
|
36
|
+
* **`yummies/types`** is the dedicated surface for type-only utilities.
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* import type { AnyObject, Maybe } from "yummies/types";
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
1
42
|
/**
|
|
2
43
|
* Extracts all values from an object or array type.
|
|
3
44
|
*
|
package/types.global.d.ts
CHANGED
|
@@ -1,4 +1,45 @@
|
|
|
1
1
|
/** THIS IS AUTOGENERATED FILE FROM "utils/types.ts" */
|
|
2
|
+
/**
|
|
3
|
+
* ---header-docs-section---
|
|
4
|
+
* # yummies/types
|
|
5
|
+
*
|
|
6
|
+
* ## Description
|
|
7
|
+
*
|
|
8
|
+
* This module collects **TypeScript-only** helpers: `ValueOf`, nullable aliases, branded types, and
|
|
9
|
+
* patterns for props and generics. Nothing here exists at runtime — use `import type` so bundlers
|
|
10
|
+
* drop the imports entirely. The same ideas are also published as **ambient** globals under a
|
|
11
|
+
* separate entry (see below) when you want types in scope without repeating imports in every file.
|
|
12
|
+
*
|
|
13
|
+
* ## `yummies/types.global`
|
|
14
|
+
*
|
|
15
|
+
* Use this subpath when you prefer **global** declarations (no per-file imports). After installing
|
|
16
|
+
* the package, reference the built `.d.ts` bundle — typically via a side-effect import that pulls
|
|
17
|
+
* ambient types into the compilation unit:
|
|
18
|
+
*
|
|
19
|
+
* ```ts
|
|
20
|
+
* import "yummies/types.global";
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Or list it under `compilerOptions.types` in **`tsconfig.json`** so `tsc` loads it for the project:
|
|
24
|
+
*
|
|
25
|
+
* ```json
|
|
26
|
+
* {
|
|
27
|
+
* "compilerOptions": {
|
|
28
|
+
* "types": ["yummies/types.global"]
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* ## `yummies/types` (library)
|
|
34
|
+
*
|
|
35
|
+
* Prefer this entry when you want **explicit**, traceable imports at each call site (tree-shaking
|
|
36
|
+
* friendly and clearer in reviews). The root package may re-export some symbols, but
|
|
37
|
+
* **`yummies/types`** is the dedicated surface for type-only utilities.
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* import type { AnyObject, Maybe } from "yummies/types";
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
2
43
|
/**
|
|
3
44
|
* Extracts all values from an object or array type.
|
|
4
45
|
*
|
package/vibrate.cjs
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region src/vibrate.ts
|
|
3
3
|
/**
|
|
4
|
+
* ---header-docs-section---
|
|
5
|
+
* # yummies/vibrate
|
|
6
|
+
*
|
|
7
|
+
* ## Description
|
|
8
|
+
*
|
|
9
|
+
* Thin wrapper around **`navigator.vibrate`** for mobile-style haptics: single pulses or patterned
|
|
10
|
+
* on/off sequences. It no-ops when the API is missing or disabled, so UI code stays simple. Do not
|
|
11
|
+
* rely on vibration for critical feedback because iOS and many desktops omit the API entirely.
|
|
12
|
+
*
|
|
13
|
+
* ## Usage
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { vibrate } from "yummies/vibrate";
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
4
20
|
* Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}
|
|
5
21
|
* when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).
|
|
6
22
|
*
|
package/vibrate.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vibrate.cjs","names":[],"sources":["../src/vibrate.ts"],"sourcesContent":["/**\n * Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}\n * when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).\n *\n * - **Single number** — vibrate for that many milliseconds, then stop.\n * - **Array of numbers** — alternating vibration and pause lengths in ms: `[vibrate, pause, vibrate, ...]`.\n * Per the spec, values are clamped; odd-length arrays imply a trailing vibrate segment.\n *\n * If the API is unavailable or the user has disabled vibration, this function **does nothing**\n * (no throw). Call sites should not rely on vibration for critical UX.\n *\n * @param pattern - Duration in ms, or a pattern array as described above.\n *\n * @example\n * Short confirmation buzz (200 ms):\n * ```ts\n * vibrate(200);\n * ```\n *\n * @example\n * Double-pulse pattern: 100 ms on, 50 ms off, 100 ms on:\n * ```ts\n * vibrate([100, 50, 100]);\n * ```\n */\nexport const vibrate = (pattern: number | number[]) => {\n if ('vibrate' in navigator) {\n navigator.vibrate(pattern);\n }\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"vibrate.cjs","names":[],"sources":["../src/vibrate.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/vibrate\n *\n * ## Description\n *\n * Thin wrapper around **`navigator.vibrate`** for mobile-style haptics: single pulses or patterned\n * on/off sequences. It no-ops when the API is missing or disabled, so UI code stays simple. Do not\n * rely on vibration for critical feedback because iOS and many desktops omit the API entirely.\n *\n * ## Usage\n *\n * ```ts\n * import { vibrate } from \"yummies/vibrate\";\n * ```\n */\n\n/**\n * Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}\n * when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).\n *\n * - **Single number** — vibrate for that many milliseconds, then stop.\n * - **Array of numbers** — alternating vibration and pause lengths in ms: `[vibrate, pause, vibrate, ...]`.\n * Per the spec, values are clamped; odd-length arrays imply a trailing vibrate segment.\n *\n * If the API is unavailable or the user has disabled vibration, this function **does nothing**\n * (no throw). Call sites should not rely on vibration for critical UX.\n *\n * @param pattern - Duration in ms, or a pattern array as described above.\n *\n * @example\n * Short confirmation buzz (200 ms):\n * ```ts\n * vibrate(200);\n * ```\n *\n * @example\n * Double-pulse pattern: 100 ms on, 50 ms off, 100 ms on:\n * ```ts\n * vibrate([100, 50, 100]);\n * ```\n */\nexport const vibrate = (pattern: number | number[]) => {\n if ('vibrate' in navigator) {\n navigator.vibrate(pattern);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,WAAW,YAA+B;AACrD,KAAI,aAAa,UACf,WAAU,QAAQ,QAAQ"}
|
package/vibrate.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ---header-docs-section---
|
|
3
|
+
* # yummies/vibrate
|
|
4
|
+
*
|
|
5
|
+
* ## Description
|
|
6
|
+
*
|
|
7
|
+
* Thin wrapper around **`navigator.vibrate`** for mobile-style haptics: single pulses or patterned
|
|
8
|
+
* on/off sequences. It no-ops when the API is missing or disabled, so UI code stays simple. Do not
|
|
9
|
+
* rely on vibration for critical feedback because iOS and many desktops omit the API entirely.
|
|
10
|
+
*
|
|
11
|
+
* ## Usage
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { vibrate } from "yummies/vibrate";
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
1
17
|
/**
|
|
2
18
|
* Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}
|
|
3
19
|
* when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).
|
package/vibrate.js
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
//#region src/vibrate.ts
|
|
2
2
|
/**
|
|
3
|
+
* ---header-docs-section---
|
|
4
|
+
* # yummies/vibrate
|
|
5
|
+
*
|
|
6
|
+
* ## Description
|
|
7
|
+
*
|
|
8
|
+
* Thin wrapper around **`navigator.vibrate`** for mobile-style haptics: single pulses or patterned
|
|
9
|
+
* on/off sequences. It no-ops when the API is missing or disabled, so UI code stays simple. Do not
|
|
10
|
+
* rely on vibration for critical feedback because iOS and many desktops omit the API entirely.
|
|
11
|
+
*
|
|
12
|
+
* ## Usage
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { vibrate } from "yummies/vibrate";
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
3
19
|
* Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}
|
|
4
20
|
* when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).
|
|
5
21
|
*
|
package/vibrate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vibrate.js","names":[],"sources":["../src/vibrate.ts"],"sourcesContent":["/**\n * Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}\n * when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).\n *\n * - **Single number** — vibrate for that many milliseconds, then stop.\n * - **Array of numbers** — alternating vibration and pause lengths in ms: `[vibrate, pause, vibrate, ...]`.\n * Per the spec, values are clamped; odd-length arrays imply a trailing vibrate segment.\n *\n * If the API is unavailable or the user has disabled vibration, this function **does nothing**\n * (no throw). Call sites should not rely on vibration for critical UX.\n *\n * @param pattern - Duration in ms, or a pattern array as described above.\n *\n * @example\n * Short confirmation buzz (200 ms):\n * ```ts\n * vibrate(200);\n * ```\n *\n * @example\n * Double-pulse pattern: 100 ms on, 50 ms off, 100 ms on:\n * ```ts\n * vibrate([100, 50, 100]);\n * ```\n */\nexport const vibrate = (pattern: number | number[]) => {\n if ('vibrate' in navigator) {\n navigator.vibrate(pattern);\n }\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"vibrate.js","names":[],"sources":["../src/vibrate.ts"],"sourcesContent":["/**\n * ---header-docs-section---\n * # yummies/vibrate\n *\n * ## Description\n *\n * Thin wrapper around **`navigator.vibrate`** for mobile-style haptics: single pulses or patterned\n * on/off sequences. It no-ops when the API is missing or disabled, so UI code stays simple. Do not\n * rely on vibration for critical feedback because iOS and many desktops omit the API entirely.\n *\n * ## Usage\n *\n * ```ts\n * import { vibrate } from \"yummies/vibrate\";\n * ```\n */\n\n/**\n * Triggers haptic feedback via the {@link https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API | Vibration API}\n * when `navigator.vibrate` exists (common on Android Chrome; often missing on iOS Safari / desktop).\n *\n * - **Single number** — vibrate for that many milliseconds, then stop.\n * - **Array of numbers** — alternating vibration and pause lengths in ms: `[vibrate, pause, vibrate, ...]`.\n * Per the spec, values are clamped; odd-length arrays imply a trailing vibrate segment.\n *\n * If the API is unavailable or the user has disabled vibration, this function **does nothing**\n * (no throw). Call sites should not rely on vibration for critical UX.\n *\n * @param pattern - Duration in ms, or a pattern array as described above.\n *\n * @example\n * Short confirmation buzz (200 ms):\n * ```ts\n * vibrate(200);\n * ```\n *\n * @example\n * Double-pulse pattern: 100 ms on, 50 ms off, 100 ms on:\n * ```ts\n * vibrate([100, 50, 100]);\n * ```\n */\nexport const vibrate = (pattern: number | number[]) => {\n if ('vibrate' in navigator) {\n navigator.vibrate(pattern);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,IAAa,WAAW,YAA+B;AACrD,KAAI,aAAa,UACf,WAAU,QAAQ,QAAQ"}
|