yummies 7.10.0 → 7.11.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/async.cjs +11 -11
- package/async.cjs.map +1 -1
- package/async.d.ts +9 -11
- package/async.js +11 -11
- package/async.js.map +1 -1
- package/complex.cjs +32 -8
- package/complex.cjs.map +1 -1
- package/complex.d.ts +133 -13
- package/complex.js +32 -8
- package/complex.js.map +1 -1
- package/css.cjs.map +1 -1
- package/css.d.ts +3 -3
- package/css.js.map +1 -1
- package/date-time.cjs.map +1 -1
- package/date-time.js.map +1 -1
- package/format.cjs.map +1 -1
- package/format.d.ts +89 -4
- package/format.js.map +1 -1
- package/html.cjs.map +1 -1
- package/html.d.ts +3 -3
- package/html.js.map +1 -1
- package/id.cjs.map +1 -1
- package/id.d.ts +10 -10
- package/id.js.map +1 -1
- package/imports.cjs.map +1 -1
- package/imports.d.ts +5 -4
- package/imports.js.map +1 -1
- package/math.cjs.map +1 -1
- package/math.d.ts +1 -1
- package/math.js.map +1 -1
- package/media.cjs.map +1 -1
- package/media.d.ts +1 -1
- package/media.js.map +1 -1
- package/mobx.cjs.map +1 -1
- package/mobx.d.ts +165 -6
- package/mobx.js.map +1 -1
- package/ms.cjs.map +1 -1
- package/ms.d.ts +1 -1
- package/ms.js.map +1 -1
- package/package.json +5 -5
- package/parser.cjs.map +1 -1
- package/parser.d.ts +63 -0
- package/parser.js.map +1 -1
- package/react.cjs.map +1 -1
- package/react.d.ts +407 -9
- package/react.js.map +1 -1
- package/sound.cjs.map +1 -1
- package/sound.d.ts +1 -1
- package/sound.js.map +1 -1
- package/storage.cjs.map +1 -1
- package/storage.d.ts +7 -6
- package/storage.js.map +1 -1
- package/text.cjs.map +1 -1
- package/text.d.ts +5 -5
- package/text.js.map +1 -1
- package/type-guard.cjs.map +1 -1
- package/type-guard.d.ts +199 -42
- package/type-guard.js.map +1 -1
- package/vibrate.cjs.map +1 -1
- package/vibrate.d.ts +1 -1
- package/vibrate.js.map +1 -1
package/html.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ import { Config } from 'dompurify';
|
|
|
2
2
|
import { Maybe } from 'yummies/types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Extracts an RGB value from any valid CSS color.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* Not recommended for frequent use because it triggers a reflow.
|
|
8
8
|
*/
|
|
9
9
|
declare const getComputedColor: (color?: string) => string | null;
|
|
10
10
|
declare const downloadUsingAnchor: (urlOrBlob: string | Blob, fileName?: string) => void;
|
|
@@ -29,7 +29,7 @@ declare const startViewTransitionSafety: (fn: VoidFunction, params?: {
|
|
|
29
29
|
disabled?: boolean;
|
|
30
30
|
}) => ViewTransition | undefined;
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Calculates the scrollbar width.
|
|
33
33
|
*/
|
|
34
34
|
declare const calcScrollbarWidth: (elementToAppend?: HTMLElement) => number;
|
|
35
35
|
/**
|
package/html.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.js","sources":["../src/html.ts"],"sourcesContent":["import DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';\nimport { blobToUrl } from 'yummies/media';\nimport type { Maybe } from 'yummies/types';\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"html.js","sources":["../src/html.ts"],"sourcesContent":["import DOMPurify, { type Config as DOMPurifyConfig } from 'dompurify';\nimport { blobToUrl } from 'yummies/media';\nimport type { Maybe } from 'yummies/types';\n\n/**\n * Extracts an RGB value from any valid CSS color.\n *\n * Not recommended for frequent use because it triggers a reflow.\n */\nexport const getComputedColor = (color?: string): string | null => {\n if (!color) return null;\n\n const d = document.createElement('div');\n d.style.color = color;\n document.body.append(d);\n const rgbcolor = globalThis.getComputedStyle(d).color;\n const match =\n /rgba?\\((\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*(,\\s*\\d+[.d+]*)*\\)/g.exec(rgbcolor);\n\n d.remove();\n\n if (!match) return null;\n\n return `${match[1]}, ${match[2]}, ${match[3]}`;\n};\n\nexport const downloadUsingAnchor = (\n urlOrBlob: string | Blob,\n fileName?: string,\n) => {\n const url = blobToUrl(urlOrBlob);\n\n const a = document.createElement('a');\n a.href = url;\n\n a.download = fileName ?? 'file';\n\n a.target = '_blank';\n\n document.body.append(a);\n\n a.click();\n\n a.remove();\n};\n\n/**\n * Surrounds string in an anchor tag\n */\nexport function wrapTextToTagLink(link: string) {\n const descr = String(link).replace(/^(https?:\\/{0,2})?(w{3}\\.)?/, 'www.');\n if (!/^https?:\\/{2}/.test(link)) link = `http://${link}`;\n return `<a href=${link} target=\"_blank\">${descr}</a>`;\n}\n\nexport const collectOffsetTop = (element: HTMLElement | null) => {\n let offsetTop = 0;\n let node = element;\n\n while (node != null) {\n offsetTop += node.offsetTop;\n node = node.parentElement;\n }\n\n return offsetTop;\n};\n\nexport const skipEvent = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n\n return false;\n};\n\nexport const globalScrollIntoViewForY = (node: HTMLElement) => {\n const scrollContainer = document.body;\n const pageHeight = window.innerHeight;\n const nodeBounding = node.getBoundingClientRect();\n const scrollPagesCount = scrollContainer.scrollHeight / pageHeight;\n\n const scrollPageNumber = Math.min(\n Math.max(nodeBounding.top / pageHeight, 1),\n scrollPagesCount,\n );\n\n window.scroll({\n top: scrollPageNumber * pageHeight,\n behavior: 'smooth',\n });\n};\n\nconst sanitizeDefaults: DOMPurifyConfig = {\n ALLOWED_TAGS: [\n 'a',\n 'article',\n 'b',\n 'blockquote',\n 'br',\n 'caption',\n 'code',\n 'del',\n 'details',\n 'div',\n 'em',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'hr',\n 'i',\n 'img',\n 'ins',\n 'kbd',\n 'li',\n 'main',\n 'ol',\n 'p',\n 'pre',\n 'section',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'th',\n 'thead',\n 'tr',\n 'u',\n 'ul',\n ],\n ALLOWED_ATTR: ['href', 'target', 'name', 'src', 'class'],\n};\n\nexport const sanitizeHtml = (html: Maybe<string>, config?: DOMPurifyConfig) => {\n return DOMPurify.sanitize(html || '', {\n ...sanitizeDefaults,\n ...config,\n });\n};\n\nexport const checkElementHasParent = (\n element: HTMLElement | null,\n parent: Maybe<HTMLElement>,\n) => {\n let node = element;\n\n if (!parent) return false;\n\n while (node != null) {\n if (node === parent) {\n return true;\n } else {\n node = node.parentElement;\n }\n }\n\n return false;\n};\n\n/**\n * Executes a function within a view transition if supported by the browser.\n *\n * @param {VoidFunction} fn - The function to be executed.\n * @returns {ViewTransition} - The result of the executed function.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition | MDN: Document.startViewTransition}\n */\nexport const startViewTransitionSafety = (\n fn: VoidFunction,\n params?: { disabled?: boolean },\n) => {\n if (\n typeof document !== 'undefined' &&\n document.startViewTransition &&\n !params?.disabled\n ) {\n return document.startViewTransition(fn);\n }\n fn();\n};\n\n/**\n * Calculates the scrollbar width.\n */\nexport const calcScrollbarWidth = (elementToAppend = document.body) => {\n const outer = document.createElement('div');\n\n outer.style.visibility = 'hidden';\n outer.style.width = '100px';\n outer.style.overflow = 'scroll';\n\n elementToAppend.append(outer);\n\n const inner = document.createElement('div');\n inner.style.width = '100%';\n\n outer.append(inner);\n\n const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;\n\n outer.parentNode?.removeChild(outer);\n\n return scrollbarWidth;\n};\n\n/**\n * Calculates the inner height of an HTML element, accounting for padding.\n */\nexport function getElementInnerHeight(element: HTMLElement) {\n const { clientHeight } = element;\n const { paddingTop, paddingBottom } = getComputedStyle(element);\n return (\n clientHeight -\n Number.parseFloat(paddingTop) -\n Number.parseFloat(paddingBottom)\n );\n}\n\n/**\n * Calculates the inner width of an HTML element, accounting for padding.\n */\nexport function getElementInnerWidth(el: HTMLElement) {\n const { clientWidth } = el;\n const { paddingLeft, paddingRight } = getComputedStyle(el);\n return (\n clientWidth -\n Number.parseFloat(paddingLeft) -\n Number.parseFloat(paddingRight)\n );\n}\n\nexport const isPrefersDarkTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: dark)')?.matches;\n\nexport const isPrefersLightTheme = () =>\n !!globalThis.matchMedia?.('(prefers-color-scheme: light)')?.matches;\n"],"names":[],"mappings":"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"}
|
package/id.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.cjs","sources":["../src/id.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"id.cjs","sources":["../src/id.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n\n/**\n * Creates a function that generates unique strings based on call order.\n *\n * @example\n * ```ts\n * generateLinearNumericId = createLinearNumericIdGenerator(6);\n * generateLinearNumericId() // '000000'\n * generateLinearNumericId() // '000001'\n * ...\n * generateLinearNumericId() // '999999'\n * generateLinearNumericId() // '1000000'\n * ...\n * generateLinearNumericId() // '9999999'\n * generateLinearNumericId() // '10000000'\n * ```\n *\n * @param size Minimum string length.\n * @returns {()=>string}\n */\nexport const createLinearNumericIdGenerator = (size: number = 9) => {\n let lastCount = 0;\n return () => {\n return (lastCount++).toString().padStart(size, '0');\n };\n};\n\n/**\n *\n * @example\n * ```ts\n * generateLinearNumericId() // '000000000'\n * generateLinearNumericId() // '000000001'\n * ...\n * generateLinearNumericId() // '999999999'\n * generateLinearNumericId() // '1000000000'\n * ...\n * generateLinearNumericId() // '9999999999'\n * generateLinearNumericId() // '10000000000'\n * ```\n *\n */\nexport const generateLinearNumericId = createLinearNumericIdGenerator();\n\n/**\n * Is not recommended to use.\n *\n * Generates execution stack based pseudo-id (just sliced string from error stack)\n */\nexport const generateStackBasedId = () =>\n new Error().stack!.split('\\n').slice(1, 4).join('');\n"],"names":["customAlphabet"],"mappings":";;;AAEA,MAAM,SAAS;AACf,MAAM,cAAc;AAEpB,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM;AAMjC,MAAM,aAAaA,OAAAA,eAAe,UAAU,CAAC;AAM7C,MAAM,kBAAkBA,OAAAA,eAAe,UAAU,CAAC;AAMlD,MAAM,oBAAoBA,OAAAA,eAAe,QAAQ,CAAC;AAMlD,MAAM,yBAAyBA,OAAAA,eAAe,QAAQ,CAAC;AAqBvD,MAAM,iCAAiC,CAAC,OAAe,MAAM;AAClE,MAAI,YAAY;AAChB,SAAO,MAAM;AACX,YAAQ,aAAa,SAAA,EAAW,SAAS,MAAM,GAAG;AAAA,EACpD;AACF;AAiBO,MAAM,0BAA0B,+BAAA;AAOhC,MAAM,uBAAuB,MAClC,IAAI,MAAA,EAAQ,MAAO,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE;;;;;;;;"}
|
package/id.d.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
3
|
+
* Length: 6.
|
|
4
4
|
*/
|
|
5
5
|
declare const generateId: (size?: number) => string;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.
|
|
8
|
+
* Length: 4.
|
|
9
9
|
*/
|
|
10
10
|
declare const generateShortId: (size?: number) => string;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Uses the alphabet `0123456789`.
|
|
13
|
+
* Length: 6.
|
|
14
14
|
*/
|
|
15
15
|
declare const generateNumericId: (size?: number) => string;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Uses the alphabet `0123456789`.
|
|
18
|
+
* Length: 4.
|
|
19
19
|
*/
|
|
20
20
|
declare const generateNumericShortId: (size?: number) => string;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Creates a function that generates unique strings based on call order.
|
|
23
23
|
*
|
|
24
24
|
* @example
|
|
25
25
|
* ```ts
|
|
@@ -34,7 +34,7 @@ declare const generateNumericShortId: (size?: number) => string;
|
|
|
34
34
|
* generateLinearNumericId() // '10000000'
|
|
35
35
|
* ```
|
|
36
36
|
*
|
|
37
|
-
* @param size
|
|
37
|
+
* @param size Minimum string length.
|
|
38
38
|
* @returns {()=>string}
|
|
39
39
|
*/
|
|
40
40
|
declare const createLinearNumericIdGenerator: (size?: number) => () => string;
|
package/id.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.js","sources":["../src/id.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"id.js","sources":["../src/id.ts"],"sourcesContent":["import { customAlphabet } from 'nanoid';\n\nconst DIGITS = '0123456789';\nconst LATIN_CHARS = 'abcdefghijklmnopqrstuvwxyz';\n\nconst ALPHABET = `${LATIN_CHARS}${DIGITS}`;\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 6.\n */\nexport const generateId = customAlphabet(ALPHABET, 6);\n\n/**\n * Uses the alphabet `abcdefghijklmnopqrstuvwxyz0123456789`.\n * Length: 4.\n */\nexport const generateShortId = customAlphabet(ALPHABET, 4);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 6.\n */\nexport const generateNumericId = customAlphabet(DIGITS, 6);\n\n/**\n * Uses the alphabet `0123456789`.\n * Length: 4.\n */\nexport const generateNumericShortId = customAlphabet(DIGITS, 4);\n\n/**\n * Creates a function that generates unique strings based on call order.\n *\n * @example\n * ```ts\n * generateLinearNumericId = createLinearNumericIdGenerator(6);\n * generateLinearNumericId() // '000000'\n * generateLinearNumericId() // '000001'\n * ...\n * generateLinearNumericId() // '999999'\n * generateLinearNumericId() // '1000000'\n * ...\n * generateLinearNumericId() // '9999999'\n * generateLinearNumericId() // '10000000'\n * ```\n *\n * @param size Minimum string length.\n * @returns {()=>string}\n */\nexport const createLinearNumericIdGenerator = (size: number = 9) => {\n let lastCount = 0;\n return () => {\n return (lastCount++).toString().padStart(size, '0');\n };\n};\n\n/**\n *\n * @example\n * ```ts\n * generateLinearNumericId() // '000000000'\n * generateLinearNumericId() // '000000001'\n * ...\n * generateLinearNumericId() // '999999999'\n * generateLinearNumericId() // '1000000000'\n * ...\n * generateLinearNumericId() // '9999999999'\n * generateLinearNumericId() // '10000000000'\n * ```\n *\n */\nexport const generateLinearNumericId = createLinearNumericIdGenerator();\n\n/**\n * Is not recommended to use.\n *\n * Generates execution stack based pseudo-id (just sliced string from error stack)\n */\nexport const generateStackBasedId = () =>\n new Error().stack!.split('\\n').slice(1, 4).join('');\n"],"names":[],"mappings":";AAEA,MAAM,SAAS;AACf,MAAM,cAAc;AAEpB,MAAM,WAAW,GAAG,WAAW,GAAG,MAAM;AAMjC,MAAM,aAAa,eAAe,UAAU,CAAC;AAM7C,MAAM,kBAAkB,eAAe,UAAU,CAAC;AAMlD,MAAM,oBAAoB,eAAe,QAAQ,CAAC;AAMlD,MAAM,yBAAyB,eAAe,QAAQ,CAAC;AAqBvD,MAAM,iCAAiC,CAAC,OAAe,MAAM;AAClE,MAAI,YAAY;AAChB,SAAO,MAAM;AACX,YAAQ,aAAa,SAAA,EAAW,SAAS,MAAM,GAAG;AAAA,EACpD;AACF;AAiBO,MAAM,0BAA0B,+BAAA;AAOhC,MAAM,uBAAuB,MAClC,IAAI,MAAA,EAAQ,MAAO,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,EAAE;"}
|
package/imports.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imports.cjs","sources":["../src/imports.ts"],"sourcesContent":["import { sleep } from 'yummies/async';\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"imports.cjs","sources":["../src/imports.ts"],"sourcesContent":["import { sleep } from 'yummies/async';\n\n/**\n * Lazily loads a module with retry support.\n *\n * @example\n * ```ts\n * fetchLazyModule(() => import('./test.ts'), 3) // starts loading test.ts\n * // If loading test.ts fails, fetchLazyModule retries by calling fetchModule() again\n * // It retries as many times as specified by attempts (3 by default)\n * ```\n */\nexport const fetchLazyModule = async <T>(\n fetchModule: () => Promise<T>,\n attempts = 3,\n delay = 1000,\n): Promise<T> => {\n const attemptsArray = Array.from<typeof fetchModule>({\n length: attempts,\n }).fill(fetchModule);\n\n let lastError: null | Error = null;\n\n for await (const attempt of attemptsArray) {\n try {\n if (lastError !== null) {\n await sleep(delay);\n }\n return await attempt();\n } catch (error) {\n lastError = error as Error;\n }\n }\n throw lastError;\n};\n\nexport type PackedAsyncModule<T> = Promise<T | { default: T }>;\n\nexport const unpackAsyncModule = async <T>(\n maybeModule: T | PackedAsyncModule<T>,\n): Promise<T> => {\n if (maybeModule instanceof Promise) {\n const data = (await maybeModule) as any;\n\n if ((data as any).default) {\n return (data as any).default;\n } else {\n return data;\n }\n }\n\n return maybeModule;\n};\n"],"names":["sleep"],"mappings":";;;AAYO,MAAM,kBAAkB,OAC7B,aACA,WAAW,GACX,QAAQ,QACO;AACf,QAAM,gBAAgB,MAAM,KAAyB;AAAA,IACnD,QAAQ;AAAA,EAAA,CACT,EAAE,KAAK,WAAW;AAEnB,MAAI,YAA0B;AAE9B,mBAAiB,WAAW,eAAe;AACzC,QAAI;AACF,UAAI,cAAc,MAAM;AACtB,cAAMA,MAAAA,MAAM,KAAK;AAAA,MACnB;AACA,aAAO,MAAM,QAAA;AAAA,IACf,SAAS,OAAO;AACd,kBAAY;AAAA,IACd;AAAA,EACF;AACA,QAAM;AACR;AAIO,MAAM,oBAAoB,OAC/B,gBACe;AACf,MAAI,uBAAuB,SAAS;AAClC,UAAM,OAAQ,MAAM;AAEpB,QAAK,KAAa,SAAS;AACzB,aAAQ,KAAa;AAAA,IACvB,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;;;"}
|
package/imports.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Lazily loads a module with retry support.
|
|
3
|
+
*
|
|
3
4
|
* @example
|
|
4
5
|
* ```ts
|
|
5
|
-
* fetchLazyModule(() => import(
|
|
6
|
-
* //
|
|
7
|
-
* //
|
|
6
|
+
* fetchLazyModule(() => import('./test.ts'), 3) // starts loading test.ts
|
|
7
|
+
* // If loading test.ts fails, fetchLazyModule retries by calling fetchModule() again
|
|
8
|
+
* // It retries as many times as specified by attempts (3 by default)
|
|
8
9
|
* ```
|
|
9
10
|
*/
|
|
10
11
|
declare const fetchLazyModule: <T>(fetchModule: () => Promise<T>, attempts?: number, delay?: number) => Promise<T>;
|
package/imports.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imports.js","sources":["../src/imports.ts"],"sourcesContent":["import { sleep } from 'yummies/async';\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"imports.js","sources":["../src/imports.ts"],"sourcesContent":["import { sleep } from 'yummies/async';\n\n/**\n * Lazily loads a module with retry support.\n *\n * @example\n * ```ts\n * fetchLazyModule(() => import('./test.ts'), 3) // starts loading test.ts\n * // If loading test.ts fails, fetchLazyModule retries by calling fetchModule() again\n * // It retries as many times as specified by attempts (3 by default)\n * ```\n */\nexport const fetchLazyModule = async <T>(\n fetchModule: () => Promise<T>,\n attempts = 3,\n delay = 1000,\n): Promise<T> => {\n const attemptsArray = Array.from<typeof fetchModule>({\n length: attempts,\n }).fill(fetchModule);\n\n let lastError: null | Error = null;\n\n for await (const attempt of attemptsArray) {\n try {\n if (lastError !== null) {\n await sleep(delay);\n }\n return await attempt();\n } catch (error) {\n lastError = error as Error;\n }\n }\n throw lastError;\n};\n\nexport type PackedAsyncModule<T> = Promise<T | { default: T }>;\n\nexport const unpackAsyncModule = async <T>(\n maybeModule: T | PackedAsyncModule<T>,\n): Promise<T> => {\n if (maybeModule instanceof Promise) {\n const data = (await maybeModule) as any;\n\n if ((data as any).default) {\n return (data as any).default;\n } else {\n return data;\n }\n }\n\n return maybeModule;\n};\n"],"names":[],"mappings":";AAYO,MAAM,kBAAkB,OAC7B,aACA,WAAW,GACX,QAAQ,QACO;AACf,QAAM,gBAAgB,MAAM,KAAyB;AAAA,IACnD,QAAQ;AAAA,EAAA,CACT,EAAE,KAAK,WAAW;AAEnB,MAAI,YAA0B;AAE9B,mBAAiB,WAAW,eAAe;AACzC,QAAI;AACF,UAAI,cAAc,MAAM;AACtB,cAAM,MAAM,KAAK;AAAA,MACnB;AACA,aAAO,MAAM,QAAA;AAAA,IACf,SAAS,OAAO;AACd,kBAAY;AAAA,IACd;AAAA,EACF;AACA,QAAM;AACR;AAIO,MAAM,oBAAoB,OAC/B,gBACe;AACf,MAAI,uBAAuB,SAAS;AAClC,UAAM,OAAQ,MAAM;AAEpB,QAAK,KAAa,SAAS;AACzB,aAAQ,KAAa;AAAA,IACvB,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;"}
|
package/math.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.cjs","sources":["../src/math.ts"],"sourcesContent":["import type { Maybe } from 'yummies/types';\n\nexport function degToRad(deg: number) {\n return deg * (Math.PI / 180);\n}\nexport function radToDeg(rad: number) {\n return rad * (180 / Math.PI);\n}\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"math.cjs","sources":["../src/math.ts"],"sourcesContent":["import type { Maybe } from 'yummies/types';\n\nexport function degToRad(deg: number) {\n return deg * (Math.PI / 180);\n}\nexport function radToDeg(rad: number) {\n return rad * (180 / Math.PI);\n}\n\n/**\n * Returns what percentage `value` is of `from`.\n * @example\n * ```ts\n * percentFrom(500, 2000) // 25\n * percentFrom(1000, 2000) // 50\n * ```\n */\nexport const percentFrom = (value: Maybe<number>, from: Maybe<number>) => {\n return ((value ?? 0) / (from ?? 0)) * 100 || 0;\n};\n"],"names":[],"mappings":";;AAEO,SAAS,SAAS,KAAa;AACpC,SAAO,OAAO,KAAK,KAAK;AAC1B;AACO,SAAS,SAAS,KAAa;AACpC,SAAO,OAAO,MAAM,KAAK;AAC3B;AAUO,MAAM,cAAc,CAAC,OAAsB,SAAwB;AACxE,UAAS,SAAS,MAAM,QAAQ,KAAM,OAAO;AAC/C;;;;"}
|
package/math.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Maybe } from 'yummies/types';
|
|
|
3
3
|
declare function degToRad(deg: number): number;
|
|
4
4
|
declare function radToDeg(rad: number): number;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Returns what percentage `value` is of `from`.
|
|
7
7
|
* @example
|
|
8
8
|
* ```ts
|
|
9
9
|
* percentFrom(500, 2000) // 25
|
package/math.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.js","sources":["../src/math.ts"],"sourcesContent":["import type { Maybe } from 'yummies/types';\n\nexport function degToRad(deg: number) {\n return deg * (Math.PI / 180);\n}\nexport function radToDeg(rad: number) {\n return rad * (180 / Math.PI);\n}\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"math.js","sources":["../src/math.ts"],"sourcesContent":["import type { Maybe } from 'yummies/types';\n\nexport function degToRad(deg: number) {\n return deg * (Math.PI / 180);\n}\nexport function radToDeg(rad: number) {\n return rad * (180 / Math.PI);\n}\n\n/**\n * Returns what percentage `value` is of `from`.\n * @example\n * ```ts\n * percentFrom(500, 2000) // 25\n * percentFrom(1000, 2000) // 50\n * ```\n */\nexport const percentFrom = (value: Maybe<number>, from: Maybe<number>) => {\n return ((value ?? 0) / (from ?? 0)) * 100 || 0;\n};\n"],"names":[],"mappings":"AAEO,SAAS,SAAS,KAAa;AACpC,SAAO,OAAO,KAAK,KAAK;AAC1B;AACO,SAAS,SAAS,KAAa;AACpC,SAAO,OAAO,MAAM,KAAK;AAC3B;AAUO,MAAM,cAAc,CAAC,OAAsB,SAAwB;AACxE,UAAS,SAAS,MAAM,QAAQ,KAAM,OAAO;AAC/C;"}
|
package/media.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.cjs","sources":["../src/media.ts"],"sourcesContent":["import { degToRad } from 'yummies/math';\n\nexport function blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport const blobToUrl = (urlOrBlob: string | Blob) =>\n urlOrBlob instanceof Blob ? URL.createObjectURL(urlOrBlob) : urlOrBlob;\n\nexport const fileToBlob = (file: File) => {\n return new Blob([file], { type: file.type });\n};\n\nexport const imageToBlob = (\n imageElement: HTMLImageElement,\n mimeType: string = 'image/png',\n) => {\n const canvas = document.createElement('canvas');\n\n canvas.width = imageElement.naturalWidth || 300;\n canvas.height = imageElement.naturalHeight || 300;\n\n canvas.getContext('2d')!.drawImage(imageElement, 0, 0);\n\n const dataUri = canvas.toDataURL(mimeType, 1);\n const base64data = dataUri.split(',')[1];\n const base64MimeType = dataUri.split(';')[0].slice(5);\n\n const bytes = globalThis.atob(base64data);\n const buf = new ArrayBuffer(bytes.length);\n const array = new Uint8Array(buf);\n\n for (let index = 0; index < bytes.length; index++) {\n array[index] = bytes.charCodeAt(index);\n }\n\n const blob = new Blob([array], { type: base64MimeType });\n\n return blob;\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"media.cjs","sources":["../src/media.ts"],"sourcesContent":["import { degToRad } from 'yummies/math';\n\nexport function blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport const blobToUrl = (urlOrBlob: string | Blob) =>\n urlOrBlob instanceof Blob ? URL.createObjectURL(urlOrBlob) : urlOrBlob;\n\nexport const fileToBlob = (file: File) => {\n return new Blob([file], { type: file.type });\n};\n\nexport const imageToBlob = (\n imageElement: HTMLImageElement,\n mimeType: string = 'image/png',\n) => {\n const canvas = document.createElement('canvas');\n\n canvas.width = imageElement.naturalWidth || 300;\n canvas.height = imageElement.naturalHeight || 300;\n\n canvas.getContext('2d')!.drawImage(imageElement, 0, 0);\n\n const dataUri = canvas.toDataURL(mimeType, 1);\n const base64data = dataUri.split(',')[1];\n const base64MimeType = dataUri.split(';')[0].slice(5);\n\n const bytes = globalThis.atob(base64data);\n const buf = new ArrayBuffer(bytes.length);\n const array = new Uint8Array(buf);\n\n for (let index = 0; index < bytes.length; index++) {\n array[index] = bytes.charCodeAt(index);\n }\n\n const blob = new Blob([array], { type: base64MimeType });\n\n return blob;\n};\n\n/**\n * Loads and renders an image using `Image`.\n *\n * @returns {Promise<HTMLImageElement>}\n */\nexport const renderImage = (urlOrBlob: Blob | string) =>\n new Promise<HTMLImageElement>((resolve, reject) => {\n const image = new Image();\n image.src = blobToUrl(urlOrBlob);\n image.onload = () => resolve(image);\n image.onerror = () => reject();\n });\n\nfunction cropImageFromCanvas(context: CanvasRenderingContext2D) {\n const canvas = context.canvas;\n let w = canvas.width;\n let h = canvas.height;\n const pix: { x: number[]; y: number[] } = { x: [], y: [] };\n const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\n let x: number;\n let y: number;\n let index: number;\n\n for (y = 0; y < h; y++) {\n for (x = 0; x < w; x++) {\n index = (y * w + x) * 4;\n if (imageData.data[index + 3] > 0) {\n pix.x.push(x);\n pix.y.push(y);\n }\n }\n }\n pix.x.sort((a, b) => a - b);\n pix.y.sort((a, b) => a - b);\n const n = pix.x.length - 1;\n\n w = 1 + pix.x[n] - pix.x[0];\n h = 1 + pix.y[n] - pix.y[0];\n const cut = context.getImageData(pix.x[0], pix.y[0], w, h);\n\n canvas.width = w;\n canvas.height = h;\n context.putImageData(cut, 0, 0);\n return canvas;\n}\n\n// TODO: ломает iphone с огромными изображениями\nexport const rotateImage = (image: HTMLImageElement, angle: number) => {\n const maxSize = Math.max(image.width, image.height);\n const canvas = document.createElement('canvas');\n canvas.width = maxSize;\n canvas.height = maxSize;\n const context = canvas.getContext('2d')!;\n context.save();\n context.translate(canvas.width / 2, canvas.height / 2);\n context.rotate(degToRad(angle));\n context.drawImage(image, -image.width / 2, -image.height / 2);\n context.restore();\n cropImageFromCanvas(context);\n return renderImage(canvas.toDataURL('image/png'));\n};\n\ninterface DecodedDataUrl {\n mimeType?: string;\n data?: string;\n}\n\n/*\n * Returning object which contains base64 data and mime type of passed data url string.\n * */\nexport function decodeDataUrl(url: string): DecodedDataUrl {\n const regex = /^data:(.*);base64,\\s?(.*)$/;\n const matches = new RegExp(regex).exec(url);\n\n return {\n mimeType: matches?.[1],\n data: matches?.[2],\n };\n}\n\nexport const isHttpUrl = (url: string): boolean => {\n return url.startsWith('https://') || url.startsWith('http://');\n};\n\nexport const isBase64Image = (str: string): boolean => {\n const { mimeType, data } = decodeDataUrl(str);\n return !!(data && mimeType?.startsWith('image/'));\n};\n"],"names":["degToRad"],"mappings":"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"}
|
package/media.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ declare const blobToUrl: (urlOrBlob: string | Blob) => string;
|
|
|
3
3
|
declare const fileToBlob: (file: File) => Blob;
|
|
4
4
|
declare const imageToBlob: (imageElement: HTMLImageElement, mimeType?: string) => Blob;
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Loads and renders an image using `Image`.
|
|
7
7
|
*
|
|
8
8
|
* @returns {Promise<HTMLImageElement>}
|
|
9
9
|
*/
|
package/media.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.js","sources":["../src/media.ts"],"sourcesContent":["import { degToRad } from 'yummies/math';\n\nexport function blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport const blobToUrl = (urlOrBlob: string | Blob) =>\n urlOrBlob instanceof Blob ? URL.createObjectURL(urlOrBlob) : urlOrBlob;\n\nexport const fileToBlob = (file: File) => {\n return new Blob([file], { type: file.type });\n};\n\nexport const imageToBlob = (\n imageElement: HTMLImageElement,\n mimeType: string = 'image/png',\n) => {\n const canvas = document.createElement('canvas');\n\n canvas.width = imageElement.naturalWidth || 300;\n canvas.height = imageElement.naturalHeight || 300;\n\n canvas.getContext('2d')!.drawImage(imageElement, 0, 0);\n\n const dataUri = canvas.toDataURL(mimeType, 1);\n const base64data = dataUri.split(',')[1];\n const base64MimeType = dataUri.split(';')[0].slice(5);\n\n const bytes = globalThis.atob(base64data);\n const buf = new ArrayBuffer(bytes.length);\n const array = new Uint8Array(buf);\n\n for (let index = 0; index < bytes.length; index++) {\n array[index] = bytes.charCodeAt(index);\n }\n\n const blob = new Blob([array], { type: base64MimeType });\n\n return blob;\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"media.js","sources":["../src/media.ts"],"sourcesContent":["import { degToRad } from 'yummies/math';\n\nexport function blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\nexport const blobToUrl = (urlOrBlob: string | Blob) =>\n urlOrBlob instanceof Blob ? URL.createObjectURL(urlOrBlob) : urlOrBlob;\n\nexport const fileToBlob = (file: File) => {\n return new Blob([file], { type: file.type });\n};\n\nexport const imageToBlob = (\n imageElement: HTMLImageElement,\n mimeType: string = 'image/png',\n) => {\n const canvas = document.createElement('canvas');\n\n canvas.width = imageElement.naturalWidth || 300;\n canvas.height = imageElement.naturalHeight || 300;\n\n canvas.getContext('2d')!.drawImage(imageElement, 0, 0);\n\n const dataUri = canvas.toDataURL(mimeType, 1);\n const base64data = dataUri.split(',')[1];\n const base64MimeType = dataUri.split(';')[0].slice(5);\n\n const bytes = globalThis.atob(base64data);\n const buf = new ArrayBuffer(bytes.length);\n const array = new Uint8Array(buf);\n\n for (let index = 0; index < bytes.length; index++) {\n array[index] = bytes.charCodeAt(index);\n }\n\n const blob = new Blob([array], { type: base64MimeType });\n\n return blob;\n};\n\n/**\n * Loads and renders an image using `Image`.\n *\n * @returns {Promise<HTMLImageElement>}\n */\nexport const renderImage = (urlOrBlob: Blob | string) =>\n new Promise<HTMLImageElement>((resolve, reject) => {\n const image = new Image();\n image.src = blobToUrl(urlOrBlob);\n image.onload = () => resolve(image);\n image.onerror = () => reject();\n });\n\nfunction cropImageFromCanvas(context: CanvasRenderingContext2D) {\n const canvas = context.canvas;\n let w = canvas.width;\n let h = canvas.height;\n const pix: { x: number[]; y: number[] } = { x: [], y: [] };\n const imageData = context.getImageData(0, 0, canvas.width, canvas.height);\n let x: number;\n let y: number;\n let index: number;\n\n for (y = 0; y < h; y++) {\n for (x = 0; x < w; x++) {\n index = (y * w + x) * 4;\n if (imageData.data[index + 3] > 0) {\n pix.x.push(x);\n pix.y.push(y);\n }\n }\n }\n pix.x.sort((a, b) => a - b);\n pix.y.sort((a, b) => a - b);\n const n = pix.x.length - 1;\n\n w = 1 + pix.x[n] - pix.x[0];\n h = 1 + pix.y[n] - pix.y[0];\n const cut = context.getImageData(pix.x[0], pix.y[0], w, h);\n\n canvas.width = w;\n canvas.height = h;\n context.putImageData(cut, 0, 0);\n return canvas;\n}\n\n// TODO: ломает iphone с огромными изображениями\nexport const rotateImage = (image: HTMLImageElement, angle: number) => {\n const maxSize = Math.max(image.width, image.height);\n const canvas = document.createElement('canvas');\n canvas.width = maxSize;\n canvas.height = maxSize;\n const context = canvas.getContext('2d')!;\n context.save();\n context.translate(canvas.width / 2, canvas.height / 2);\n context.rotate(degToRad(angle));\n context.drawImage(image, -image.width / 2, -image.height / 2);\n context.restore();\n cropImageFromCanvas(context);\n return renderImage(canvas.toDataURL('image/png'));\n};\n\ninterface DecodedDataUrl {\n mimeType?: string;\n data?: string;\n}\n\n/*\n * Returning object which contains base64 data and mime type of passed data url string.\n * */\nexport function decodeDataUrl(url: string): DecodedDataUrl {\n const regex = /^data:(.*);base64,\\s?(.*)$/;\n const matches = new RegExp(regex).exec(url);\n\n return {\n mimeType: matches?.[1],\n data: matches?.[2],\n };\n}\n\nexport const isHttpUrl = (url: string): boolean => {\n return url.startsWith('https://') || url.startsWith('http://');\n};\n\nexport const isBase64Image = (str: string): boolean => {\n const { mimeType, data } = decodeDataUrl(str);\n return !!(data && mimeType?.startsWith('image/'));\n};\n"],"names":[],"mappings":"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"}
|
package/mobx.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mobx.cjs","sources":["../src/mobx/apply-observable.ts","../src/mobx/create-enhanced-atom.ts","../src/mobx/create-ref.ts","../src/mobx/deep-observable-struct.ts","../src/mobx/get-mobx-administration.ts","../src/mobx/lazy-observe.ts"],"sourcesContent":["import { type AnnotationMapEntry, makeObservable } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\nexport type ObservableAnnotationsArray<T extends AnyObject = AnyObject> = [\n AnnotationMapEntry,\n ...(keyof T | (string & {}))[],\n][];\n\nexport const applyObservable = <T extends AnyObject>(\n context: T,\n annotationsArray: ObservableAnnotationsArray<T>,\n useDecorators?: boolean,\n) => {\n if (useDecorators) {\n annotationsArray.forEach(([annotation, ...fields]) => {\n fields.forEach((field) => {\n // @ts-expect-error\n annotation(context, field);\n });\n });\n\n makeObservable(context);\n } else {\n const annotationsObject: AnyObject = {};\n\n annotationsArray.forEach(([annotation, ...fields]) => {\n fields.forEach((field) => {\n annotationsObject[field] = annotation;\n });\n });\n\n makeObservable(context, annotationsObject);\n }\n};\n","import { createAtom, type IAtom } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\nexport interface IEnhancedAtom<TMeta extends AnyObject = AnyObject>\n extends IAtom {\n meta: TMeta;\n}\n\n/**\n * Creates an enhanced atom with meta data\n * And bind `reportChanged` and `reportObserved` method to the atom\n */\nexport const createEnhancedAtom = <TMeta extends AnyObject>(\n name: string,\n onBecomeObservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,\n onBecomeUnobservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,\n meta?: TMeta,\n): IEnhancedAtom<TMeta> => {\n const atom = createAtom(\n name,\n onBecomeObservedHandler && (() => onBecomeObservedHandler(atom)),\n onBecomeUnobservedHandler && (() => onBecomeUnobservedHandler(atom)),\n ) as IEnhancedAtom<TMeta>;\n atom.meta = meta ?? ({} as TMeta);\n atom.reportChanged = atom.reportChanged.bind(atom);\n atom.reportObserved = atom.reportObserved.bind(atom);\n return atom;\n};\n","import {\n type IEqualsComparer,\n makeObservable,\n comparer as mobxComparer,\n observable,\n runInAction,\n} from 'mobx';\nimport type { AnyObject, Maybe } from 'yummies/types';\n\n/**\n * You can return `false` if you don't want to change the value in this ref\n */\nexport type RefChangeListener<T> = (\n value: T | null,\n prevValue: T | undefined,\n) => void | false;\n\n/**\n * Alternative to React.createRef but works in MobX world.\n * Typically it the should be the same React.LegacyRef (fn style)\n */\nexport interface Ref<T = any, TMeta = AnyObject> {\n /**\n * Setter function\n */\n (value: Maybe<T>): void;\n\n set(value: Maybe<T>): void;\n listeners: Set<RefChangeListener<NoInfer<T>>>;\n current: NoInfer<T> | null;\n meta: TMeta;\n}\n\nexport interface CreateRefConfig<T = any, TMeta = AnyObject> {\n onSet?: (node: T, prevValue: T | undefined) => void;\n onUnset?: (lastValue: T | undefined) => void;\n onChange?: RefChangeListener<T>;\n meta?: TMeta;\n initial?: Maybe<T>;\n comparer?: IEqualsComparer<T | null>;\n}\n\n/**\n * Creates ref thing to attach HTMLElements in React and all other\n */\nexport const createRef = <T = any, TMeta = AnyObject>(\n cfg?: CreateRefConfig<T, TMeta>,\n): Ref<T, TMeta> => {\n let lastValue: T | undefined;\n const comparer = cfg?.comparer ?? mobxComparer.default;\n\n const setValue: Ref<T, TMeta>['set'] = (value) => {\n const nextValue = value ?? null;\n\n if (comparer(ref.current, nextValue)) {\n return;\n }\n\n runInAction(() => {\n const prevLastValue = lastValue;\n lastValue = ref.current ?? undefined;\n ref.current = nextValue;\n\n let isNextValueIgnored = false;\n\n ref.listeners.forEach((listener) => {\n const listenerResult = listener(ref.current, lastValue);\n\n if (listenerResult === false) {\n isNextValueIgnored = true;\n }\n });\n\n if (isNextValueIgnored) {\n lastValue = prevLastValue;\n ref.current = lastValue ?? null;\n } else if (ref.current === null && lastValue !== undefined) {\n lastValue = undefined;\n }\n });\n };\n\n const ref = setValue as Ref<T, TMeta>;\n\n ref.set = setValue;\n\n ref.listeners = new Set(cfg?.onChange ? [cfg.onChange] : []);\n\n if (cfg?.onSet || cfg?.onUnset) {\n ref.listeners.add((value, prevValue) => {\n if (value) {\n cfg.onSet?.(value, prevValue);\n } else {\n cfg.onUnset?.(prevValue);\n }\n });\n }\n\n ref.current = cfg?.initial ?? null;\n ref.meta = cfg?.meta ?? ({} as TMeta);\n\n makeObservable(ref, {\n current: observable.ref,\n meta: observable,\n });\n\n return ref;\n};\n\nexport const isRef = <T, TMeta = any>(\n value: T | Ref<T, TMeta>,\n): value is Ref<T, TMeta> => {\n return typeof value === 'function' && 'current' in value;\n};\n\nexport const toRef = <T, TMeta = any>(\n value: T | Ref<T, TMeta>,\n cfg?: Omit<CreateRefConfig<T, TMeta>, 'initial'>,\n): Ref<T, TMeta> => {\n return isRef(value) ? value : createRef({ initial: value, ...cfg });\n};\n","import { action, makeObservable, observable } from 'mobx';\nimport { typeGuard } from 'yummies/type-guard';\nimport type { AnyObject } from 'yummies/types';\n\nexport class DeepObservableStruct<TData extends AnyObject> {\n data: TData;\n\n constructor(data: TData) {\n this.data = data;\n\n makeObservable(this, {\n data: observable.deep,\n set: action,\n });\n }\n\n set(newData: Partial<TData>) {\n type StackItem = [key: string, currObservable: AnyObject, new: AnyObject];\n\n const stack: StackItem[] = Object.keys(this.data).map((key) => [\n key,\n this.data,\n newData,\n ]);\n\n let currentIndex = 0;\n let stackLength = stack.length;\n\n while (currentIndex < stackLength) {\n const [key, currObservableData, newData] = stack[currentIndex];\n const newValue = newData[key];\n const currValue = currObservableData[key];\n\n currentIndex++;\n\n if (key in newData) {\n if (typeGuard.isObject(newValue) && typeGuard.isObject(currValue)) {\n const newValueKeys = Object.keys(newValue);\n\n Object.keys(currValue).forEach((childKey) => {\n if (!(childKey in newValue)) {\n delete currObservableData[key][childKey];\n }\n });\n\n newValueKeys.forEach((childKey) => {\n const length = stack.push([\n childKey,\n currObservableData[key],\n newValue,\n ]);\n stackLength = length;\n });\n } else if (newValue !== currValue) {\n currObservableData[key] = newValue;\n }\n } else {\n delete currObservableData[key];\n }\n }\n\n Object.keys(newData).forEach((newDataKey) => {\n if (!this.data[newDataKey]) {\n // @ts-expect-error\n this.data[newDataKey] = newData[newDataKey];\n }\n });\n }\n}\n","import { $mobx, type AnnotationMapEntry } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\ntype ObservableObjectAdministration = Parameters<\n Exclude<AnnotationMapEntry, boolean>['make_']\n>[0];\n\nexport const getMobxAdministration = (\n context: AnyObject,\n): ObservableObjectAdministration => context[$mobx];\n","import { onBecomeObserved, onBecomeUnobserved } from 'mobx';\n\n/**\n * When ONE OF the properties is becomes observed then `onStart` function is called.\n * WHen ALL properties are unobserved then `onEnd` function is called with the `metaData` that was returned by `onStart`.\n *\n * It uses `onBecomeObserved` and `onBecomeUnobserved` mobx hooks to perform lazy observation.\n */\nexport const lazyObserve = <TMetaData = void>({\n context,\n property,\n onStart,\n onEnd,\n endDelay = false,\n}: {\n context?: any;\n property: any | any[];\n onStart?: () => TMetaData;\n onEnd?: (metaData: TMetaData, cleanupFn: VoidFunction) => void;\n endDelay?: number | false;\n}) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let metaData: TMetaData | undefined;\n const observingProps = new Set<string>();\n const properties = Array.isArray(property) ? property : [property];\n\n const cleanup = () => {\n observingProps.clear();\n\n if (endDelay === false) {\n onEnd?.(metaData!, cleanup);\n metaData = undefined;\n return;\n }\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n timeoutId = setTimeout(() => {\n onEnd?.(metaData!, cleanup);\n timeoutId = undefined;\n metaData = undefined;\n }, endDelay);\n };\n\n const start = (property: string) => {\n const isAlreadyObserving = observingProps.size > 0;\n observingProps.add(property);\n\n if (isAlreadyObserving) {\n return;\n }\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n metaData = onStart?.();\n };\n\n const stop = (property: string) => {\n const isAlreadyNotObserving = !observingProps.size;\n\n observingProps.delete(property);\n\n const isObserving = observingProps.size > 0;\n\n if (isAlreadyNotObserving || isObserving) {\n return;\n }\n\n cleanup();\n };\n\n properties.forEach((property) => {\n if (context) {\n onBecomeObserved(context, property, () => start(property));\n onBecomeUnobserved(context, property, () => stop(property));\n } else {\n onBecomeObserved(property, () => start(property));\n onBecomeUnobserved(property, () => stop(property));\n }\n });\n\n return cleanup;\n};\n"],"names":["makeObservable","createAtom","mobxComparer","runInAction","observable","action","newData","typeGuard","$mobx","property","onBecomeObserved","onBecomeUnobserved"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mobx.cjs","sources":["../src/mobx/apply-observable.ts","../src/mobx/create-enhanced-atom.ts","../src/mobx/create-ref.ts","../src/mobx/deep-observable-struct.ts","../src/mobx/get-mobx-administration.ts","../src/mobx/lazy-observe.ts"],"sourcesContent":["import { type AnnotationMapEntry, makeObservable } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\nexport type ObservableAnnotationsArray<T extends AnyObject = AnyObject> = [\n AnnotationMapEntry,\n ...(keyof T | (string & {}))[],\n][];\n\n/**\n * Applies a compact list of MobX annotations to an object using either\n * decorator-style invocation or the annotation map form accepted by `makeObservable`.\n *\n * @template T Target object type.\n * @param context Object that should become observable.\n * @param annotationsArray Tuples of annotation followed by annotated field names.\n * @param useDecorators Enables decorator-style application before calling `makeObservable`.\n *\n * @example\n * ```ts\n * applyObservable(store, [[observable, 'items'], [action, 'setItems']]);\n * ```\n *\n * @example\n * ```ts\n * applyObservable(viewModel, [[computed, 'fullName']], true);\n * ```\n */\nexport const applyObservable = <T extends AnyObject>(\n context: T,\n annotationsArray: ObservableAnnotationsArray<T>,\n useDecorators?: boolean,\n) => {\n if (useDecorators) {\n annotationsArray.forEach(([annotation, ...fields]) => {\n fields.forEach((field) => {\n // @ts-expect-error\n annotation(context, field);\n });\n });\n\n makeObservable(context);\n } else {\n const annotationsObject: AnyObject = {};\n\n annotationsArray.forEach(([annotation, ...fields]) => {\n fields.forEach((field) => {\n annotationsObject[field] = annotation;\n });\n });\n\n makeObservable(context, annotationsObject);\n }\n};\n","import { createAtom, type IAtom } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\nexport interface IEnhancedAtom<TMeta extends AnyObject = AnyObject>\n extends IAtom {\n meta: TMeta;\n}\n\n/**\n * Creates a MobX atom extended with metadata and bound reporting methods.\n *\n * @template TMeta Metadata object stored on the atom.\n * @param name Atom name used by MobX for debugging.\n * @param onBecomeObservedHandler Callback fired when the atom becomes observed.\n * @param onBecomeUnobservedHandler Callback fired when the atom is no longer observed.\n * @param meta Optional metadata attached to the atom.\n * @returns Atom instance with `meta`, `reportChanged` and `reportObserved`.\n *\n * @example\n * ```ts\n * const atom = createEnhancedAtom('user-status');\n * atom.reportChanged();\n * ```\n *\n * @example\n * ```ts\n * const atom = createEnhancedAtom('cache', undefined, undefined, { scope: 'users' });\n * atom.meta.scope;\n * ```\n */\nexport const createEnhancedAtom = <TMeta extends AnyObject>(\n name: string,\n onBecomeObservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,\n onBecomeUnobservedHandler?: (atom: IEnhancedAtom<TMeta>) => void,\n meta?: TMeta,\n): IEnhancedAtom<TMeta> => {\n const atom = createAtom(\n name,\n onBecomeObservedHandler && (() => onBecomeObservedHandler(atom)),\n onBecomeUnobservedHandler && (() => onBecomeUnobservedHandler(atom)),\n ) as IEnhancedAtom<TMeta>;\n atom.meta = meta ?? ({} as TMeta);\n atom.reportChanged = atom.reportChanged.bind(atom);\n atom.reportObserved = atom.reportObserved.bind(atom);\n return atom;\n};\n","import {\n type IEqualsComparer,\n makeObservable,\n comparer as mobxComparer,\n observable,\n runInAction,\n} from 'mobx';\nimport type { AnyObject, Maybe } from 'yummies/types';\n\n/**\n * You can return `false` if you don't want to change the value in this ref\n */\nexport type RefChangeListener<T> = (\n value: T | null,\n prevValue: T | undefined,\n) => void | false;\n\n/**\n * Alternative to React.createRef but works in MobX world.\n * Typically it the should be the same React.LegacyRef (fn style)\n */\nexport interface Ref<T = any, TMeta = AnyObject> {\n /**\n * Setter function\n */\n (value: Maybe<T>): void;\n\n set(value: Maybe<T>): void;\n listeners: Set<RefChangeListener<NoInfer<T>>>;\n current: NoInfer<T> | null;\n meta: TMeta;\n}\n\nexport interface CreateRefConfig<T = any, TMeta = AnyObject> {\n onSet?: (node: T, prevValue: T | undefined) => void;\n onUnset?: (lastValue: T | undefined) => void;\n onChange?: RefChangeListener<T>;\n meta?: TMeta;\n initial?: Maybe<T>;\n comparer?: IEqualsComparer<T | null>;\n}\n\n/**\n * Creates a MobX-aware ref that behaves like a callback ref and exposes\n * observable `current` and `meta` fields.\n *\n * @template T Referenced value type.\n * @template TMeta Additional observable metadata stored on the ref.\n * @param cfg Optional callbacks, initial value and comparer configuration.\n * @returns Observable ref function object.\n *\n * @example\n * ```ts\n * const inputRef = createRef<HTMLInputElement>();\n * inputRef.set(document.createElement('input'));\n * ```\n *\n * @example\n * ```ts\n * const nodeRef = createRef({\n * onUnset: () => console.log('detached'),\n * meta: { mounted: false },\n * });\n * ```\n */\nexport const createRef = <T = any, TMeta = AnyObject>(\n cfg?: CreateRefConfig<T, TMeta>,\n): Ref<T, TMeta> => {\n let lastValue: T | undefined;\n const comparer = cfg?.comparer ?? mobxComparer.default;\n\n const setValue: Ref<T, TMeta>['set'] = (value) => {\n const nextValue = value ?? null;\n\n if (comparer(ref.current, nextValue)) {\n return;\n }\n\n runInAction(() => {\n const prevLastValue = lastValue;\n lastValue = ref.current ?? undefined;\n ref.current = nextValue;\n\n let isNextValueIgnored = false;\n\n ref.listeners.forEach((listener) => {\n const listenerResult = listener(ref.current, lastValue);\n\n if (listenerResult === false) {\n isNextValueIgnored = true;\n }\n });\n\n if (isNextValueIgnored) {\n lastValue = prevLastValue;\n ref.current = lastValue ?? null;\n } else if (ref.current === null && lastValue !== undefined) {\n lastValue = undefined;\n }\n });\n };\n\n const ref = setValue as Ref<T, TMeta>;\n\n ref.set = setValue;\n\n ref.listeners = new Set(cfg?.onChange ? [cfg.onChange] : []);\n\n if (cfg?.onSet || cfg?.onUnset) {\n ref.listeners.add((value, prevValue) => {\n if (value) {\n cfg.onSet?.(value, prevValue);\n } else {\n cfg.onUnset?.(prevValue);\n }\n });\n }\n\n ref.current = cfg?.initial ?? null;\n ref.meta = cfg?.meta ?? ({} as TMeta);\n\n makeObservable(ref, {\n current: observable.ref,\n meta: observable,\n });\n\n return ref;\n};\n\n/**\n * Checks whether the provided value is a ref created by `createRef`.\n *\n * @template T Referenced value type.\n * @template TMeta Ref metadata type.\n * @param value Value to inspect.\n * @returns `true` when the value is a ref-like function with `current`.\n *\n * @example\n * ```ts\n * const ref = createRef<number>();\n * isRef(ref); // true\n * ```\n *\n * @example\n * ```ts\n * isRef({ current: 1 }); // false\n * ```\n */\nexport const isRef = <T, TMeta = any>(\n value: T | Ref<T, TMeta>,\n): value is Ref<T, TMeta> => {\n return typeof value === 'function' && 'current' in value;\n};\n\n/**\n * Normalizes a plain value or an existing ref into a `Ref` instance.\n *\n * @template T Referenced value type.\n * @template TMeta Ref metadata type.\n * @param value Existing ref or initial plain value.\n * @param cfg Optional ref configuration applied when a new ref is created.\n * @returns Existing ref or a newly created ref initialized with `value`.\n *\n * @example\n * ```ts\n * const ref = toRef(document.body);\n * ref.current === document.body;\n * ```\n *\n * @example\n * ```ts\n * const existingRef = createRef<number>();\n * const sameRef = toRef(existingRef);\n * ```\n */\nexport const toRef = <T, TMeta = any>(\n value: T | Ref<T, TMeta>,\n cfg?: Omit<CreateRefConfig<T, TMeta>, 'initial'>,\n): Ref<T, TMeta> => {\n return isRef(value) ? value : createRef({ initial: value, ...cfg });\n};\n","import { action, makeObservable, observable } from 'mobx';\nimport { typeGuard } from 'yummies/type-guard';\nimport type { AnyObject } from 'yummies/types';\n\n/**\n * Wraps a plain object into a deeply observable structure and allows\n * patch-like updates while preserving nested observable references where possible.\n *\n * @template TData Observable object shape.\n *\n * @example\n * ```ts\n * const state = new DeepObservableStruct({ user: { name: 'Ann' } });\n * state.set({ user: { name: 'Bob' } });\n * ```\n *\n * @example\n * ```ts\n * const state = new DeepObservableStruct({ filters: { active: true } });\n * state.set({ filters: { active: false, archived: true } });\n * ```\n */\nexport class DeepObservableStruct<TData extends AnyObject> {\n data: TData;\n\n constructor(data: TData) {\n this.data = data;\n\n makeObservable(this, {\n data: observable.deep,\n set: action,\n });\n }\n\n set(newData: Partial<TData>) {\n type StackItem = [key: string, currObservable: AnyObject, new: AnyObject];\n\n const stack: StackItem[] = Object.keys(this.data).map((key) => [\n key,\n this.data,\n newData,\n ]);\n\n let currentIndex = 0;\n let stackLength = stack.length;\n\n while (currentIndex < stackLength) {\n const [key, currObservableData, newData] = stack[currentIndex];\n const newValue = newData[key];\n const currValue = currObservableData[key];\n\n currentIndex++;\n\n if (key in newData) {\n if (typeGuard.isObject(newValue) && typeGuard.isObject(currValue)) {\n const newValueKeys = Object.keys(newValue);\n\n Object.keys(currValue).forEach((childKey) => {\n if (!(childKey in newValue)) {\n delete currObservableData[key][childKey];\n }\n });\n\n newValueKeys.forEach((childKey) => {\n const length = stack.push([\n childKey,\n currObservableData[key],\n newValue,\n ]);\n stackLength = length;\n });\n } else if (newValue !== currValue) {\n currObservableData[key] = newValue;\n }\n } else {\n delete currObservableData[key];\n }\n }\n\n Object.keys(newData).forEach((newDataKey) => {\n if (!this.data[newDataKey]) {\n // @ts-expect-error\n this.data[newDataKey] = newData[newDataKey];\n }\n });\n }\n}\n","import { $mobx, type AnnotationMapEntry } from 'mobx';\nimport type { AnyObject } from 'yummies/types';\n\ntype ObservableObjectAdministration = Parameters<\n Exclude<AnnotationMapEntry, boolean>['make_']\n>[0];\n\n/**\n * Returns the internal MobX administration object associated with an observable target.\n *\n * @param context Observable object instance.\n * @returns MobX administration internals stored under `$mobx`.\n *\n * @example\n * ```ts\n * const admin = getMobxAdministration(store);\n * admin.name_;\n * ```\n *\n * @example\n * ```ts\n * const values = getMobxAdministration(formState).values_;\n * ```\n */\nexport const getMobxAdministration = (\n context: AnyObject,\n): ObservableObjectAdministration => context[$mobx];\n","import { onBecomeObserved, onBecomeUnobserved } from 'mobx';\n\n/**\n * Starts side effects only while one or more MobX observables are being observed.\n *\n * When the first property becomes observed, `onStart` is called. When all tracked\n * properties become unobserved, `onEnd` is called with the value returned by\n * `onStart`. Cleanup can be delayed via `endDelay`.\n *\n * It uses MobX `onBecomeObserved` and `onBecomeUnobserved` hooks to perform\n * lazy subscription management.\n *\n * @template TMetaData Data returned from `onStart` and forwarded to `onEnd`.\n * @param config Configuration for tracked properties and lifecycle callbacks.\n * @returns Cleanup function that clears the tracked state and runs `onEnd`.\n *\n * @example\n * ```ts\n * const stop = lazyObserve({\n * context: store,\n * property: 'items',\n * onStart: () => api.subscribe(),\n * onEnd: (subscription) => subscription.unsubscribe(),\n * });\n * ```\n *\n * @example\n * ```ts\n * lazyObserve({\n * property: [boxA, boxB],\n * onStart: () => console.log('observed'),\n * endDelay: 300,\n * });\n * ```\n */\nexport const lazyObserve = <TMetaData = void>({\n context,\n property,\n onStart,\n onEnd,\n endDelay = false,\n}: {\n context?: any;\n property: any | any[];\n onStart?: () => TMetaData;\n onEnd?: (metaData: TMetaData, cleanupFn: VoidFunction) => void;\n endDelay?: number | false;\n}) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let metaData: TMetaData | undefined;\n const observingProps = new Set<string>();\n const properties = Array.isArray(property) ? property : [property];\n\n const cleanup = () => {\n observingProps.clear();\n\n if (endDelay === false) {\n onEnd?.(metaData!, cleanup);\n metaData = undefined;\n return;\n }\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n timeoutId = setTimeout(() => {\n onEnd?.(metaData!, cleanup);\n timeoutId = undefined;\n metaData = undefined;\n }, endDelay);\n };\n\n const start = (property: string) => {\n const isAlreadyObserving = observingProps.size > 0;\n observingProps.add(property);\n\n if (isAlreadyObserving) {\n return;\n }\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = undefined;\n }\n\n metaData = onStart?.();\n };\n\n const stop = (property: string) => {\n const isAlreadyNotObserving = !observingProps.size;\n\n observingProps.delete(property);\n\n const isObserving = observingProps.size > 0;\n\n if (isAlreadyNotObserving || isObserving) {\n return;\n }\n\n cleanup();\n };\n\n properties.forEach((property) => {\n if (context) {\n onBecomeObserved(context, property, () => start(property));\n onBecomeUnobserved(context, property, () => stop(property));\n } else {\n onBecomeObserved(property, () => start(property));\n onBecomeUnobserved(property, () => stop(property));\n }\n });\n\n return cleanup;\n};\n"],"names":["makeObservable","createAtom","mobxComparer","runInAction","observable","action","newData","typeGuard","$mobx","property","onBecomeObserved","onBecomeUnobserved"],"mappings":"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"}
|
package/mobx.d.ts
CHANGED
|
@@ -5,14 +5,51 @@ type ObservableAnnotationsArray<T extends AnyObject = AnyObject> = [
|
|
|
5
5
|
AnnotationMapEntry,
|
|
6
6
|
...(keyof T | (string & {}))[]
|
|
7
7
|
][];
|
|
8
|
+
/**
|
|
9
|
+
* Applies a compact list of MobX annotations to an object using either
|
|
10
|
+
* decorator-style invocation or the annotation map form accepted by `makeObservable`.
|
|
11
|
+
*
|
|
12
|
+
* @template T Target object type.
|
|
13
|
+
* @param context Object that should become observable.
|
|
14
|
+
* @param annotationsArray Tuples of annotation followed by annotated field names.
|
|
15
|
+
* @param useDecorators Enables decorator-style application before calling `makeObservable`.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* applyObservable(store, [[observable, 'items'], [action, 'setItems']]);
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* applyObservable(viewModel, [[computed, 'fullName']], true);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
8
27
|
declare const applyObservable: <T extends AnyObject>(context: T, annotationsArray: ObservableAnnotationsArray<T>, useDecorators?: boolean) => void;
|
|
9
28
|
|
|
10
29
|
interface IEnhancedAtom<TMeta extends AnyObject = AnyObject> extends IAtom {
|
|
11
30
|
meta: TMeta;
|
|
12
31
|
}
|
|
13
32
|
/**
|
|
14
|
-
* Creates
|
|
15
|
-
*
|
|
33
|
+
* Creates a MobX atom extended with metadata and bound reporting methods.
|
|
34
|
+
*
|
|
35
|
+
* @template TMeta Metadata object stored on the atom.
|
|
36
|
+
* @param name Atom name used by MobX for debugging.
|
|
37
|
+
* @param onBecomeObservedHandler Callback fired when the atom becomes observed.
|
|
38
|
+
* @param onBecomeUnobservedHandler Callback fired when the atom is no longer observed.
|
|
39
|
+
* @param meta Optional metadata attached to the atom.
|
|
40
|
+
* @returns Atom instance with `meta`, `reportChanged` and `reportObserved`.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const atom = createEnhancedAtom('user-status');
|
|
45
|
+
* atom.reportChanged();
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const atom = createEnhancedAtom('cache', undefined, undefined, { scope: 'users' });
|
|
51
|
+
* atom.meta.scope;
|
|
52
|
+
* ```
|
|
16
53
|
*/
|
|
17
54
|
declare const createEnhancedAtom: <TMeta extends AnyObject>(name: string, onBecomeObservedHandler?: (atom: IEnhancedAtom<TMeta>) => void, onBecomeUnobservedHandler?: (atom: IEnhancedAtom<TMeta>) => void, meta?: TMeta) => IEnhancedAtom<TMeta>;
|
|
18
55
|
|
|
@@ -43,12 +80,90 @@ interface CreateRefConfig<T = any, TMeta = AnyObject> {
|
|
|
43
80
|
comparer?: IEqualsComparer<T | null>;
|
|
44
81
|
}
|
|
45
82
|
/**
|
|
46
|
-
* Creates ref
|
|
83
|
+
* Creates a MobX-aware ref that behaves like a callback ref and exposes
|
|
84
|
+
* observable `current` and `meta` fields.
|
|
85
|
+
*
|
|
86
|
+
* @template T Referenced value type.
|
|
87
|
+
* @template TMeta Additional observable metadata stored on the ref.
|
|
88
|
+
* @param cfg Optional callbacks, initial value and comparer configuration.
|
|
89
|
+
* @returns Observable ref function object.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* const inputRef = createRef<HTMLInputElement>();
|
|
94
|
+
* inputRef.set(document.createElement('input'));
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```ts
|
|
99
|
+
* const nodeRef = createRef({
|
|
100
|
+
* onUnset: () => console.log('detached'),
|
|
101
|
+
* meta: { mounted: false },
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
47
104
|
*/
|
|
48
105
|
declare const createRef: <T = any, TMeta = AnyObject>(cfg?: CreateRefConfig<T, TMeta>) => Ref<T, TMeta>;
|
|
106
|
+
/**
|
|
107
|
+
* Checks whether the provided value is a ref created by `createRef`.
|
|
108
|
+
*
|
|
109
|
+
* @template T Referenced value type.
|
|
110
|
+
* @template TMeta Ref metadata type.
|
|
111
|
+
* @param value Value to inspect.
|
|
112
|
+
* @returns `true` when the value is a ref-like function with `current`.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```ts
|
|
116
|
+
* const ref = createRef<number>();
|
|
117
|
+
* isRef(ref); // true
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* isRef({ current: 1 }); // false
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
49
125
|
declare const isRef: <T, TMeta = any>(value: T | Ref<T, TMeta>) => value is Ref<T, TMeta>;
|
|
126
|
+
/**
|
|
127
|
+
* Normalizes a plain value or an existing ref into a `Ref` instance.
|
|
128
|
+
*
|
|
129
|
+
* @template T Referenced value type.
|
|
130
|
+
* @template TMeta Ref metadata type.
|
|
131
|
+
* @param value Existing ref or initial plain value.
|
|
132
|
+
* @param cfg Optional ref configuration applied when a new ref is created.
|
|
133
|
+
* @returns Existing ref or a newly created ref initialized with `value`.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* const ref = toRef(document.body);
|
|
138
|
+
* ref.current === document.body;
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```ts
|
|
143
|
+
* const existingRef = createRef<number>();
|
|
144
|
+
* const sameRef = toRef(existingRef);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
50
147
|
declare const toRef: <T, TMeta = any>(value: T | Ref<T, TMeta>, cfg?: Omit<CreateRefConfig<T, TMeta>, "initial">) => Ref<T, TMeta>;
|
|
51
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Wraps a plain object into a deeply observable structure and allows
|
|
151
|
+
* patch-like updates while preserving nested observable references where possible.
|
|
152
|
+
*
|
|
153
|
+
* @template TData Observable object shape.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const state = new DeepObservableStruct({ user: { name: 'Ann' } });
|
|
158
|
+
* state.set({ user: { name: 'Bob' } });
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* const state = new DeepObservableStruct({ filters: { active: true } });
|
|
164
|
+
* state.set({ filters: { active: false, archived: true } });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
52
167
|
declare class DeepObservableStruct<TData extends AnyObject> {
|
|
53
168
|
data: TData;
|
|
54
169
|
constructor(data: TData);
|
|
@@ -56,13 +171,57 @@ declare class DeepObservableStruct<TData extends AnyObject> {
|
|
|
56
171
|
}
|
|
57
172
|
|
|
58
173
|
type ObservableObjectAdministration = Parameters<Exclude<AnnotationMapEntry, boolean>['make_']>[0];
|
|
174
|
+
/**
|
|
175
|
+
* Returns the internal MobX administration object associated with an observable target.
|
|
176
|
+
*
|
|
177
|
+
* @param context Observable object instance.
|
|
178
|
+
* @returns MobX administration internals stored under `$mobx`.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const admin = getMobxAdministration(store);
|
|
183
|
+
* admin.name_;
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* const values = getMobxAdministration(formState).values_;
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
59
191
|
declare const getMobxAdministration: (context: AnyObject) => ObservableObjectAdministration;
|
|
60
192
|
|
|
61
193
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
194
|
+
* Starts side effects only while one or more MobX observables are being observed.
|
|
195
|
+
*
|
|
196
|
+
* When the first property becomes observed, `onStart` is called. When all tracked
|
|
197
|
+
* properties become unobserved, `onEnd` is called with the value returned by
|
|
198
|
+
* `onStart`. Cleanup can be delayed via `endDelay`.
|
|
199
|
+
*
|
|
200
|
+
* It uses MobX `onBecomeObserved` and `onBecomeUnobserved` hooks to perform
|
|
201
|
+
* lazy subscription management.
|
|
202
|
+
*
|
|
203
|
+
* @template TMetaData Data returned from `onStart` and forwarded to `onEnd`.
|
|
204
|
+
* @param config Configuration for tracked properties and lifecycle callbacks.
|
|
205
|
+
* @returns Cleanup function that clears the tracked state and runs `onEnd`.
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* const stop = lazyObserve({
|
|
210
|
+
* context: store,
|
|
211
|
+
* property: 'items',
|
|
212
|
+
* onStart: () => api.subscribe(),
|
|
213
|
+
* onEnd: (subscription) => subscription.unsubscribe(),
|
|
214
|
+
* });
|
|
215
|
+
* ```
|
|
64
216
|
*
|
|
65
|
-
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```ts
|
|
219
|
+
* lazyObserve({
|
|
220
|
+
* property: [boxA, boxB],
|
|
221
|
+
* onStart: () => console.log('observed'),
|
|
222
|
+
* endDelay: 300,
|
|
223
|
+
* });
|
|
224
|
+
* ```
|
|
66
225
|
*/
|
|
67
226
|
declare const lazyObserve: <TMetaData = void>({ context, property, onStart, onEnd, endDelay, }: {
|
|
68
227
|
context?: any;
|