@ng-native/fabric 0.17.0 → 0.18.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.
@@ -1 +1 @@
1
- {"version":3,"file":"inline-token.js","sourceRoot":"","sources":["../src/inline-token.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A custom property's value set on an element at run time, `[style.--tint]=\"tint()\"` or\n * `style=\"--gap: 4px\"`, as a token the cascade can read.\n *\n * A stylesheet's custom properties are converted when the app is built, where there is a CSS\n * parser (`@ng-native/metro/css/values.cjs`). A bound one only exists here, where there is not,\n * so this takes the shapes a binding actually holds and nothing more: a length in `px`, `%`,\n * `rem`, `em` or a viewport unit, two to four lengths in `px`, a number, a colour as React Native\n * writes one, a colour's three channels, a word, another token, `var(--brand)`, and one made of\n * others, `calc(var(--gap) * 2)`, `calc(10px * 2)` or a `color-mix()` (see\n * inline-derived-token.ts).\n * Anything else is kept as a word, which leaves a use site that wants a length or a colour unset,\n * as a token of the wrong kind does.\n */\nimport { CSS_SPACE, type DeferredDeclaration, type TokenValue } from './css.ts';\nimport { derivedToken } from './inline-derived-token.ts';\nimport { HUE_DEGREES, isNamedColor } from './transition.ts';\n\nconst PX = /^(-?\\d*\\.?\\d+)px$/;\nconst PERCENT = /^-?\\d*\\.?\\d+%$/;\nconst RELATIVE = /^(-?\\d*\\.?\\d+)(rem|em|vw|vh|vmin|vmax)$/i;\nconst NUMBER = /^-?\\d*\\.?\\d+$/;\nconst ANGLE = /^(-?\\d*\\.?\\d+)(deg|grad|rad|turn)$/i;\n/** `#fff`, `rgb()`, `rgba()`, `hsl()`, `hsla()` and `hwb()`: what React Native's `processColor` reads. */\nconst COLOR_FUNCTION = /^(#[\\da-f]{3,8}|(rgba?|hsla?|hwb)\\(.*\\))$/i;\nconst WORD = /^-?[a-z][\\w-]*$/i;\n/** One colour channel: a number, a percentage, or a hue with its unit. */\nconst CHANNEL = /^(-?(?:\\d+\\.?\\d*|\\.\\d+))(%|deg|grad|rad|turn)?$/;\n/** `var(--name)` or `var(--name, <fallback>)`, the whole value. */\nconst VAR = /^var\\([ \\t\\n\\r\\f]*(--[\\w-]+)[ \\t\\n\\r\\f]*(?:,([\\s\\S]*))?\\)$/i;\n/**\n * A value worked out where it is set: one with a `var()` in it, a `calc()`, `min()` or `max()`,\n * a `color-mix()`, or a relative colour, of tokens or of values written out.\n */\nconst DERIVED = /var\\(|^(?:calc|min|max|color-mix)\\(|^[a-z]+\\([ \\t\\n\\r\\f]*from[ \\t\\n\\r\\f]/i;\nconst WEIGHTS: Record<string, string> = { normal: '400', bold: '700' };\n/**\n * CSS whitespace at either end: a space, a tab, a newline, a carriage return or a form feed. A\n * no-break space is part of the value, as it is in a browser, where `trim()` would drop it.\n */\nconst PADDED = new RegExp(`^${CSS_SPACE.source}|${CSS_SPACE.source}$`, 'g');\nexport const cssTrim = (text: string): string => text.replace(PADDED, '');\n/** A family name's parts: a quoted string, which may hold escapes, or a bare word. */\nconst FAMILY_PART = /^(?:'((?:[^'\\\\]|\\\\[\\s\\S])*)'|\"((?:[^\"\\\\]|\\\\[\\s\\S])*)\"|(-?[a-z_][\\w-]*))/i;\nconst LEADING_SPACE = new RegExp(`^${CSS_SPACE.source}`);\n/**\n * A CSS escape: up to six hex digits and one whitespace after them, a newline, which only joins\n * the lines either side, or any other character.\n */\nconst ESCAPE = /\\\\([\\da-f]{1,6})(?:\\r\\n|[ \\t\\n\\r\\f])?|\\\\(\\r\\n|[\\n\\r\\f])|\\\\([\\s\\S])/gi;\n\n/** A quoted string's text with its escapes decoded. One naming no character is U+FFFD. */\nconst decodeEscapes = (text: string): string =>\n text.replace(ESCAPE, (_, hex: string | undefined, newline: string | undefined, char: string) => {\n if (newline !== undefined) return '';\n if (hex === undefined) return char;\n const code = parseInt(hex, 16);\n return code && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff)\n ? String.fromCodePoint(code)\n : '\\ufffd';\n });\n\n/**\n * The first family of a `font-family` stack, as a stylesheet reads it (`firstFamily` in\n * values.cjs): `'Inter Display', sans-serif` is `Inter Display`, and `Segoe UI` is one name of two\n * words. Undefined for anything that is not a stack.\n */\nexport function firstFamily(value: string): string | undefined {\n let rest = cssTrim(value);\n const words: string[] = [];\n while (rest && !rest.startsWith(',')) {\n const part = FAMILY_PART.exec(rest);\n if (!part) return undefined;\n const quoted = part[1] ?? part[2];\n words.push(quoted === undefined ? part[3]! : decodeEscapes(quoted));\n rest = rest.slice(part[0].length).replace(LEADING_SPACE, '');\n }\n return words.length ? words.join(' ') : undefined;\n}\n\n/**\n * A value kept as written, and a family too when it reads as one: `'Inter-Bold'` is the family\n * `Inter-Bold`, and a stack its first. The written word stays the keyword, so a quoted `\"none\"` is\n * still no display.\n */\nfunction fromText(text: string): TokenValue {\n const family = firstFamily(text);\n return family === undefined || family === text ? { keyword: text } : { keyword: text, family };\n}\n\n/**\n * CSS takes a bare 0 wherever it takes a length, and no other bare number. A number from 1 to 1000\n * is a weight as well, at the nearest hundred, which is every weight native draws.\n */\nfunction fromNumber(value: number): TokenValue | undefined {\n if (!Number.isFinite(value)) return undefined;\n const weight =\n value >= 1 && value <= 1000\n ? { weight: String(Math.min(900, Math.max(100, Math.round(value / 100) * 100))) }\n : {};\n // And a line height, as a multiple of the font size, as the stylesheet's own reads it.\n const lineHeight = {\n lineHeight: { __defer: { unit: 'em' as const, factor: value, multiple: true as const } },\n };\n return value === 0\n ? { number: 0, length: 0, ...lineHeight }\n : { number: value, ...weight, ...lineHeight };\n}\n\n/**\n * A word is a keyword, `row`, and may be a colour, `red`, or a weight, `bold`, as well: every form\n * it can take, as the build-time conversion gives, and a use site reads the one it needs.\n */\nfunction fromWord(text: string): TokenValue {\n const weight = WEIGHTS[text.toLowerCase()];\n return {\n keyword: text,\n ...(isNamedColor(text) ? { color: text } : {}),\n ...(weight ? { weight } : {}),\n };\n}\n\nconst clamp = (value: number, low: number, high: number) => Math.min(high, Math.max(low, value));\n\n/**\n * `13 110 253`, `13, 110, 253`, `100% 0% 0%` or `0 100% 50%`, in the forms `rgb()` and `hsl()` read\n * channels in, by the same rules the build-time conversion uses (`channelForms` in values.cjs).\n */\nfunction fromChannels(text: string): TokenValue | undefined {\n const commas = text.split(',');\n const spaced = commas.length === 1;\n const words = spaced ? text.split(CSS_SPACE) : commas.map(cssTrim);\n const parsed = words.map((word) => CHANNEL.exec(word));\n if (parsed.length !== 3 || parsed.some((match) => !match)) return undefined;\n const values = parsed.map((match) => ({ n: Number(match![1]), unit: match![2] ?? '' }));\n const channels = rgbChannels(values);\n const hslChannels = hslOf(values, spaced);\n if (!channels && !hslChannels) return undefined;\n return { ...(channels ? { channels } : {}), ...(hslChannels ? { hslChannels } : {}) };\n}\n\ninterface Channel {\n readonly n: number;\n readonly unit: string;\n}\n\n/** As `rgb()` reads them: three numbers, or three percentages of 255. */\nfunction rgbChannels(values: readonly Channel[]): number[] | undefined {\n const scale = values.every((v) => v.unit === '')\n ? 1\n : values.every((v) => v.unit === '%')\n ? 255 / 100\n : 0;\n if (!scale) return undefined;\n return values.map((v) => Math.round(clamp(v.n * scale, 0, 255) * 1000) / 1000);\n}\n\n/** As `hsl()` reads them: a hue, then two percentages, which the space syntax may write bare. */\nfunction hslOf([hue, ...rest]: readonly Channel[], spaced: boolean): number[] | undefined {\n const degrees = hue!.n * (hue!.unit === '' ? 1 : (HUE_DEGREES[hue!.unit] ?? NaN));\n const fractions = rest.map((v) =>\n v.unit === '%' || (spaced && v.unit === '') ? clamp(v.n / 100, 0, 1) : NaN,\n );\n const hsl = [degrees, ...fractions];\n return hsl.every(Number.isFinite) ? hsl : undefined;\n}\n\n/**\n * Another token, kept as an alias and resolved where it is set, as a stylesheet's `--x: var(--y)`\n * is. Undefined when the parentheses do not close where the value ends: `var(--a, 1px) var(--b)`.\n */\nfunction fromVar(text: string): TokenValue | undefined {\n const match = VAR.exec(text);\n if (!match) return undefined;\n const alias = match[1]!;\n const rest = match[2];\n if (rest === undefined) return { alias };\n if (!balanced(rest)) return undefined;\n const fallback = tokenFromValue(rest);\n return fallback ? { alias, fallback } : { alias };\n}\n\nfunction balanced(text: string): boolean {\n let depth = 0;\n for (const char of text) {\n if (char === '(') depth++;\n else if (char === ')' && --depth < 0) return false;\n }\n return depth === 0;\n}\n\n/** Two to four lengths in `px`, a padding or a margin's sides, as the stylesheet's own reads them. */\nfunction fromLengths(text: string): TokenValue | undefined {\n const parts = text.split(/[ \\t\\n\\r\\f]+/);\n if (parts.length < 2 || parts.length > 4) return undefined;\n const lengths = parts.map((part) => (part === '0' ? 0 : Number(PX.exec(part)?.[1] ?? NaN)));\n return lengths.every(Number.isFinite) ? { lengths } : undefined;\n}\n\n/** A time as CSS writes one: a number of seconds or milliseconds. */\nconst TIME = /^([+-]?(?:\\d+\\.?\\d*|\\.\\d+))(ms|s)$/i;\n\n/** A number with a unit, as the token each is: a length, a percentage, an angle or a time. */\nfunction withUnit(text: string): TokenValue | undefined {\n const px = PX.exec(text);\n if (px) return { length: Number(px[1]) };\n // A `rem` is 16 points, and the others are measured where they are used, as in a stylesheet.\n const relative = RELATIVE.exec(text);\n if (relative) {\n const [, factor, unit] = relative;\n const lower = unit!.toLowerCase();\n if (lower === 'rem') return { length: Number(factor) * 16 };\n const measured = lower as NonNullable<DeferredDeclaration['compute']>['unit'];\n // The shape the stylesheet compiles one to, which `TokenValue` does not spell out.\n const deferred = { __defer: { unit: measured, factor: Number(factor) } };\n return { length: deferred } as unknown as TokenValue;\n }\n // A percentage is a fraction as well, and an angle its degrees, as the build-time conversion\n // reads them: an hsl() of tokens takes its saturation and its hue so.\n if (PERCENT.test(text)) return { length: text, number: Number(text.slice(0, -1)) / 100 };\n const angle = ANGLE.exec(text);\n if (angle) {\n const [, value, unit] = angle;\n return { angle: Number(value) * HUE_DEGREES[unit!.toLowerCase()]!, number: Number(value) };\n }\n const time = TIME.exec(text);\n // In milliseconds, as the build reads a time: what a transition or an animation takes.\n if (time) return { time: Number(time[1]) * (time[2]!.toLowerCase() === 's' ? 1000 : 1) };\n return undefined;\n}\n\n/**\n * A value with a token in it: another token, or one made of others, worked out where it is set.\n * Any other shape is a word no use site reads, as a colour function with a `var()` left in it is\n * not a colour native can draw.\n */\nfunction withTokens(text: string): TokenValue {\n return fromVar(text) ?? derivedToken(text) ?? { keyword: text };\n}\n\nexport function tokenFromValue(value: unknown): TokenValue | undefined {\n if (typeof value === 'number') return fromNumber(value);\n if (typeof value !== 'string') return undefined;\n const text = cssTrim(value);\n if (!text) return undefined;\n const measure = withUnit(text);\n if (measure) return measure;\n if (NUMBER.test(text)) return fromNumber(Number(text));\n if (DERIVED.test(text)) return withTokens(text);\n if (COLOR_FUNCTION.test(text)) return { color: text };\n // `0 0 0` is both, so it is kept as both, as the stylesheet's own token is.\n const lengths = fromLengths(text);\n const channels = fromChannels(text);\n if (lengths) return { ...channels, ...lengths };\n return channels ?? (WORD.test(text) ? fromWord(text) : fromText(text));\n}\n"]}
1
+ {"version":3,"file":"inline-token.js","sourceRoot":"","sources":["../src/inline-token.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * A custom property's value set on an element at run time, `[style.--tint]=\"tint()\"` or\n * `style=\"--gap: 4px\"`, as a token the cascade can read.\n *\n * A stylesheet's custom properties are converted when the app is built, where there is a CSS\n * parser (`@ng-native/metro/css/values.cjs`). A bound one only exists here, where there is not,\n * so this takes the shapes a binding actually holds and nothing more: a length in `px`, `%`,\n * `rem`, `em` or a viewport unit, two to four lengths in `px`, a number, a colour as React Native\n * writes one, a `platform-color()`, a colour's three channels, a word, another token,\n * `var(--brand)`, and one made of others, `calc(var(--gap) * 2)`, `calc(10px * 2)` or a\n * `color-mix()` (see inline-derived-token.ts).\n * Anything else is kept as a word, which leaves a use site that wants a length or a colour unset,\n * as a token of the wrong kind does.\n */\nimport {\n CSS_SPACE,\n type DeferredDeclaration,\n type PlatformColour,\n type TokenValue,\n} from './css.ts';\nimport { derivedToken } from './inline-derived-token.ts';\nimport { HUE_DEGREES, isNamedColor } from './transition.ts';\n\nconst PX = /^(-?\\d*\\.?\\d+)px$/;\nconst PERCENT = /^-?\\d*\\.?\\d+%$/;\nconst RELATIVE = /^(-?\\d*\\.?\\d+)(rem|em|vw|vh|vmin|vmax)$/i;\nconst NUMBER = /^-?\\d*\\.?\\d+$/;\nconst ANGLE = /^(-?\\d*\\.?\\d+)(deg|grad|rad|turn)$/i;\n/** `#fff`, `rgb()`, `rgba()`, `hsl()`, `hsla()` and `hwb()`: what React Native's `processColor` reads. */\nconst COLOR_FUNCTION = /^(#[\\da-f]{3,8}|(rgba?|hsla?|hwb)\\(.*\\))$/i;\nconst WORD = /^-?[a-z][\\w-]*$/i;\n/** One colour channel: a number, a percentage, or a hue with its unit. */\nconst CHANNEL = /^(-?(?:\\d+\\.?\\d*|\\.\\d+))(%|deg|grad|rad|turn)?$/;\n/** `var(--name)` or `var(--name, <fallback>)`, the whole value. */\nconst VAR = /^var\\([ \\t\\n\\r\\f]*(--[\\w-]+)[ \\t\\n\\r\\f]*(?:,([\\s\\S]*))?\\)$/i;\n/**\n * A value worked out where it is set: one with a `var()` in it, a `calc()`, `min()` or `max()`,\n * a `color-mix()`, or a relative colour, of tokens or of values written out.\n */\nconst DERIVED = /var\\(|^(?:calc|min|max|color-mix)\\(|^[a-z]+\\([ \\t\\n\\r\\f]*from[ \\t\\n\\r\\f]/i;\nconst WEIGHTS: Record<string, string> = { normal: '400', bold: '700' };\n/**\n * CSS whitespace at either end: a space, a tab, a newline, a carriage return or a form feed. A\n * no-break space is part of the value, as it is in a browser, where `trim()` would drop it.\n */\nconst PADDED = new RegExp(`^${CSS_SPACE.source}|${CSS_SPACE.source}$`, 'g');\nexport const cssTrim = (text: string): string => text.replace(PADDED, '');\n/** A family name's parts: a quoted string, which may hold escapes, or a bare word. */\nconst FAMILY_PART = /^(?:'((?:[^'\\\\]|\\\\[\\s\\S])*)'|\"((?:[^\"\\\\]|\\\\[\\s\\S])*)\"|(-?[a-z_][\\w-]*))/i;\nconst LEADING_SPACE = new RegExp(`^${CSS_SPACE.source}`);\n/**\n * A CSS escape: up to six hex digits and one whitespace after them, a newline, which only joins\n * the lines either side, or any other character.\n */\nconst ESCAPE = /\\\\([\\da-f]{1,6})(?:\\r\\n|[ \\t\\n\\r\\f])?|\\\\(\\r\\n|[\\n\\r\\f])|\\\\([\\s\\S])/gi;\n\n/** A quoted string's text with its escapes decoded. One naming no character is U+FFFD. */\nconst decodeEscapes = (text: string): string =>\n text.replace(ESCAPE, (_, hex: string | undefined, newline: string | undefined, char: string) => {\n if (newline !== undefined) return '';\n if (hex === undefined) return char;\n const code = parseInt(hex, 16);\n return code && code <= 0x10ffff && (code < 0xd800 || code > 0xdfff)\n ? String.fromCodePoint(code)\n : '\\ufffd';\n });\n\n/**\n * The first family of a `font-family` stack, as a stylesheet reads it (`firstFamily` in\n * values.cjs): `'Inter Display', sans-serif` is `Inter Display`, and `Segoe UI` is one name of two\n * words. Undefined for anything that is not a stack.\n */\nexport function firstFamily(value: string): string | undefined {\n let rest = cssTrim(value);\n const words: string[] = [];\n while (rest && !rest.startsWith(',')) {\n const part = FAMILY_PART.exec(rest);\n if (!part) return undefined;\n const quoted = part[1] ?? part[2];\n words.push(quoted === undefined ? part[3]! : decodeEscapes(quoted));\n rest = rest.slice(part[0].length).replace(LEADING_SPACE, '');\n }\n return words.length ? words.join(' ') : undefined;\n}\n\n/**\n * A value kept as written, and a family too when it reads as one: `'Inter-Bold'` is the family\n * `Inter-Bold`, and a stack its first. The written word stays the keyword, so a quoted `\"none\"` is\n * still no display.\n */\nfunction fromText(text: string): TokenValue {\n const family = firstFamily(text);\n return family === undefined || family === text ? { keyword: text } : { keyword: text, family };\n}\n\n/**\n * CSS takes a bare 0 wherever it takes a length, and no other bare number. A number from 1 to 1000\n * is a weight as well, at the nearest hundred, which is every weight native draws.\n */\nfunction fromNumber(value: number): TokenValue | undefined {\n if (!Number.isFinite(value)) return undefined;\n const weight =\n value >= 1 && value <= 1000\n ? { weight: String(Math.min(900, Math.max(100, Math.round(value / 100) * 100))) }\n : {};\n // And a line height, as a multiple of the font size, as the stylesheet's own reads it.\n const lineHeight = {\n lineHeight: { __defer: { unit: 'em' as const, factor: value, multiple: true as const } },\n };\n return value === 0\n ? { number: 0, length: 0, ...lineHeight }\n : { number: value, ...weight, ...lineHeight };\n}\n\n/**\n * A word is a keyword, `row`, and may be a colour, `red`, or a weight, `bold`, as well: every form\n * it can take, as the build-time conversion gives, and a use site reads the one it needs.\n */\nfunction fromWord(text: string): TokenValue {\n const lower = text.toLowerCase();\n const weight = Object.hasOwn(WEIGHTS, lower) ? WEIGHTS[lower] : undefined;\n return {\n keyword: text,\n ...(isNamedColor(text) ? { color: text } : {}),\n ...(weight ? { weight } : {}),\n };\n}\n\nconst clamp = (value: number, low: number, high: number) => Math.min(high, Math.max(low, value));\n\n/**\n * `13 110 253`, `13, 110, 253`, `100% 0% 0%` or `0 100% 50%`, in the forms `rgb()` and `hsl()` read\n * channels in, by the same rules the build-time conversion uses (`channelForms` in values.cjs).\n */\nfunction fromChannels(text: string): TokenValue | undefined {\n const commas = text.split(',');\n const spaced = commas.length === 1;\n const words = spaced ? text.split(CSS_SPACE) : commas.map(cssTrim);\n const parsed = words.map((word) => CHANNEL.exec(word));\n if (parsed.length !== 3 || parsed.some((match) => !match)) return undefined;\n const values = parsed.map((match) => ({ n: Number(match![1]), unit: match![2] ?? '' }));\n const channels = rgbChannels(values);\n const hslChannels = hslOf(values, spaced);\n if (!channels && !hslChannels) return undefined;\n return { ...(channels ? { channels } : {}), ...(hslChannels ? { hslChannels } : {}) };\n}\n\ninterface Channel {\n readonly n: number;\n readonly unit: string;\n}\n\n/** As `rgb()` reads them: three numbers, or three percentages of 255. */\nfunction rgbChannels(values: readonly Channel[]): number[] | undefined {\n const scale = values.every((v) => v.unit === '')\n ? 1\n : values.every((v) => v.unit === '%')\n ? 255 / 100\n : 0;\n if (!scale) return undefined;\n return values.map((v) => Math.round(clamp(v.n * scale, 0, 255) * 1000) / 1000);\n}\n\n/** As `hsl()` reads them: a hue, then two percentages, which the space syntax may write bare. */\nfunction hslOf([hue, ...rest]: readonly Channel[], spaced: boolean): number[] | undefined {\n const degrees = hue!.n * (hue!.unit === '' ? 1 : (HUE_DEGREES[hue!.unit] ?? NaN));\n const fractions = rest.map((v) =>\n v.unit === '%' || (spaced && v.unit === '') ? clamp(v.n / 100, 0, 1) : NaN,\n );\n const hsl = [degrees, ...fractions];\n return hsl.every(Number.isFinite) ? hsl : undefined;\n}\n\n/**\n * Another token, kept as an alias and resolved where it is set, as a stylesheet's `--x: var(--y)`\n * is. Undefined when the parentheses do not close where the value ends: `var(--a, 1px) var(--b)`.\n */\nfunction fromVar(text: string): TokenValue | undefined {\n const match = VAR.exec(text);\n if (!match) return undefined;\n const alias = match[1]!;\n const rest = match[2];\n if (rest === undefined) return { alias };\n if (!balanced(rest)) return undefined;\n const fallback = tokenFromValue(rest);\n return fallback ? { alias, fallback } : { alias };\n}\n\nfunction balanced(text: string): boolean {\n let depth = 0;\n for (const char of text) {\n if (char === '(') depth++;\n else if (char === ')' && --depth < 0) return false;\n }\n return depth === 0;\n}\n\n/** Two to four lengths in `px`, a padding or a margin's sides, as the stylesheet's own reads them. */\nfunction fromLengths(text: string): TokenValue | undefined {\n const parts = text.split(/[ \\t\\n\\r\\f]+/);\n if (parts.length < 2 || parts.length > 4) return undefined;\n const lengths = parts.map((part) => (part === '0' ? 0 : Number(PX.exec(part)?.[1] ?? NaN)));\n return lengths.every(Number.isFinite) ? { lengths } : undefined;\n}\n\n/** A time as CSS writes one: a number of seconds or milliseconds. */\nconst TIME = /^([+-]?(?:\\d+\\.?\\d*|\\.\\d+))(ms|s)$/i;\n\n/** A number with a unit, as the token each is: a length, a percentage, an angle or a time. */\nfunction withUnit(text: string): TokenValue | undefined {\n const px = PX.exec(text);\n if (px) return { length: Number(px[1]) };\n // A `rem` is 16 points, and the others are measured where they are used, as in a stylesheet.\n const relative = RELATIVE.exec(text);\n if (relative) {\n const [, factor, unit] = relative;\n const lower = unit!.toLowerCase();\n if (lower === 'rem') return { length: Number(factor) * 16 };\n const measured = lower as NonNullable<DeferredDeclaration['compute']>['unit'];\n // The shape the stylesheet compiles one to, which `TokenValue` does not spell out.\n const deferred = { __defer: { unit: measured, factor: Number(factor) } };\n return { length: deferred } as unknown as TokenValue;\n }\n // A percentage is a fraction as well, and an angle its degrees, as the build-time conversion\n // reads them: an hsl() of tokens takes its saturation and its hue so.\n if (PERCENT.test(text)) return { length: text, number: Number(text.slice(0, -1)) / 100 };\n const angle = ANGLE.exec(text);\n if (angle) {\n const [, value, unit] = angle;\n return { angle: Number(value) * HUE_DEGREES[unit!.toLowerCase()]!, number: Number(value) };\n }\n const time = TIME.exec(text);\n // In milliseconds, as the build reads a time: what a transition or an animation takes.\n if (time) return { time: Number(time[1]) * (time[2]!.toLowerCase() === 's' ? 1000 : 1) };\n return undefined;\n}\n\n/**\n * A value with a token in it: another token, or one made of others, worked out where it is set.\n * Any other shape is a word no use site reads, as a colour function with a `var()` left in it is\n * not a colour native can draw.\n */\nfunction withTokens(text: string): TokenValue {\n if (nestsTooDeep(text)) return { keyword: text };\n return fromVar(text) ?? derivedToken(text) ?? { keyword: text };\n}\n\n/**\n * How deep a value's brackets may nest for its tokens to be read. Each level is a call deeper in\n * the reading, and in working the value out after, so a few thousand, in text from a server,\n * would overflow the stack in the middle of a binding. A stylesheet's deepest is a handful.\n */\nconst MAX_NESTING = 32;\n\nfunction nestsTooDeep(text: string): boolean {\n let depth = 0;\n for (const char of text) {\n if (char === '(' && ++depth > MAX_NESTING) return true;\n if (char === ')') depth--;\n }\n return false;\n}\n\nconst PLATFORM_COLOR = /^platform-color\\(([\\s\\S]*)\\)$/i;\n/** A platform colour's name: a word, or a quoted string, as Android's `?attr/...` has to be. */\nconst PLATFORM_NAME = /^(?:'([^'\\\\]*)'|\"([^\"\\\\]*)\"|([a-z_][\\w-]*))$/i;\n\n/**\n * `platform-color(link, \"?attr/colorAccent\")`, as the stylesheet holds one (`platformColor` in\n * compile.cjs): its names, which the platform resolves. Undefined for anything else, a call with\n * no name in it included.\n */\nexport function platformColourOf(text: string): PlatformColour | undefined {\n const inside = PLATFORM_COLOR.exec(text)?.[1];\n if (inside === undefined) return undefined;\n const names: string[] = [];\n for (const written of inside.split(',')) {\n const name = PLATFORM_NAME.exec(cssTrim(written));\n if (!name) return undefined;\n names.push(name[1] ?? name[2] ?? name[3]!);\n }\n return { platformColor: names };\n}\n\nexport function tokenFromValue(value: unknown): TokenValue | undefined {\n if (typeof value === 'number') return fromNumber(value);\n if (typeof value !== 'string') return undefined;\n const text = cssTrim(value);\n if (!text) return undefined;\n const measure = withUnit(text);\n if (measure) return measure;\n if (NUMBER.test(text)) return fromNumber(Number(text));\n const platform = platformColourOf(text);\n if (platform) return { color: platform };\n if (DERIVED.test(text)) return withTokens(text);\n if (COLOR_FUNCTION.test(text)) return { color: text };\n // `0 0 0` is both, so it is kept as both, as the stylesheet's own token is.\n const lengths = fromLengths(text);\n const channels = fromChannels(text);\n if (lengths) return { ...channels, ...lengths };\n return channels ?? (WORD.test(text) ? fromWord(text) : fromText(text));\n}\n"]}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * What a view paints, set on native with no commit: its opacity, transform and colours, through
3
+ * React Native's animated nodes, as `Animated` with the native driver sets them.
4
+ *
5
+ * A commit for a change of paint alone costs the whole round: the path from the root cloned,
6
+ * native's diff, and a layout of every view on the screen, for a progress bar stepped every 50ms
7
+ * twenty times a second. A value set on a native animated node reaches the view directly, by
8
+ * `synchronouslyUpdateViewOnUIThread`, with none of that. Each view has one graph: a value node
9
+ * for every number it paints, the transform and colour nodes over them, a style node and a props
10
+ * node connected to the view. A change of a number is a value set; a change of what the view
11
+ * paints, another key or a transform of another shape, builds the graph again.
12
+ *
13
+ * Only what native can change without a layout goes this way: React Native's props node updates
14
+ * the view's props and not the shadow tree, so the engine commits the values the views hold
15
+ * once they are left alone, or before anything reads where they are drawn.
16
+ */
17
+ import type { NativeAnimated, Touched } from './native-drive.ts';
18
+ export type NumericTransform = readonly {
19
+ readonly property: string;
20
+ readonly value: number;
21
+ }[];
22
+ /** A colour as native's colour node takes it: red, green and blue to 255, alpha to 1. */
23
+ export type Rgba = readonly [number, number, number, number];
24
+ /** What a view paints, as numbers native's nodes take. */
25
+ export interface PaintValues {
26
+ opacity?: number;
27
+ /**
28
+ * Each entry's property and its amount: points, a factor, or an angle in radians. Or a list
29
+ * as a commit carries it, for one a transform node cannot take, a matrix: native is given it
30
+ * whole, as an object node, and each change of it builds the graph again.
31
+ */
32
+ transform?: NumericTransform | {
33
+ readonly literal: readonly unknown[];
34
+ };
35
+ colors?: Readonly<Record<string, Rgba>>;
36
+ }
37
+ export declare class NativePainter {
38
+ private readonly native;
39
+ private readonly touched;
40
+ private readonly graphs;
41
+ constructor(native: NativeAnimated, touched?: Touched);
42
+ /** Whether native can ease a value as well as set it. */
43
+ get eases(): boolean;
44
+ /** Have native paint these values on a view, setting only what changed. */
45
+ paint(view: object, tag: number, values: PaintValues): void;
46
+ /**
47
+ * Ease what a view paints from where native has it to `to`, over the frames given, as eased
48
+ * progress from nothing to one. A view with no graph of this shape starts at `from`. `ended`
49
+ * is told once every value has got there; `stop` leaves each where it has got to.
50
+ */
51
+ ease(view: object, tag: number, from: PaintValues, to: PaintValues, frames: readonly number[], ended: () => void): {
52
+ stop(): void;
53
+ };
54
+ /** Whether native paints a view, with a graph connected to it. */
55
+ paints(view: object): boolean;
56
+ /** Let a view go: native no longer paints anything on it. */
57
+ release(view: object): void;
58
+ /** The view's graph for values of this shape, built again where it was of another. */
59
+ private graphFor;
60
+ /** The style keys a graph for these values sets. */
61
+ private styleOf;
62
+ private build;
63
+ private stopLeaf;
64
+ private tearDown;
65
+ private flush;
66
+ }
@@ -0,0 +1,246 @@
1
+ const PARTS = ['r', 'g', 'b', 'a'];
2
+ /** Every number a view paints, by its path in the graph. */
3
+ function leavesOf(values) {
4
+ const leaves = new Map();
5
+ if (values.opacity !== undefined)
6
+ leaves.set('opacity', values.opacity);
7
+ for (const [key, rgba] of Object.entries(values.colors ?? {})) {
8
+ rgba.forEach((part, at) => leaves.set(`${key}.${PARTS[at]}`, part));
9
+ }
10
+ const transform = values.transform;
11
+ if (Array.isArray(transform)) {
12
+ transform.forEach((entry, at) => {
13
+ leaves.set(`transform.${at}`, entry.value);
14
+ });
15
+ }
16
+ return leaves;
17
+ }
18
+ /** What makes two sets of values the same graph: which keys, and the transform's properties. */
19
+ function shapeOf(values) {
20
+ const colours = Object.keys(values.colors ?? {}).sort();
21
+ const list = values.transform;
22
+ const transform = !list
23
+ ? undefined
24
+ : Array.isArray(list)
25
+ ? list.map((entry) => entry.property).join(',')
26
+ : JSON.stringify(list.literal);
27
+ return `${values.opacity === undefined ? '' : 'o'}|${colours.join(',')}|${transform ?? '-'}`;
28
+ }
29
+ /** What an entry of a transform is where it moves the view nowhere: a scale is 1, the rest 0. */
30
+ const restingAmount = (property) => (property.startsWith('scale') ? 1 : 0);
31
+ /**
32
+ * Values in the shape of `to`, each at where `from` has it: an opacity or a colour `from` has
33
+ * none of is where `to` is, and a transform entry it has none of rests the view as it is. A
34
+ * transform painted whole, a matrix, cannot be eased from somewhere else, and starts at `to`.
35
+ */
36
+ function startIn(from, to) {
37
+ const colors = {};
38
+ for (const [key, rgba] of Object.entries(to.colors ?? {}))
39
+ colors[key] = from.colors?.[key] ?? rgba;
40
+ const ends = to.transform;
41
+ const starts = Array.isArray(from.transform) ? from.transform : [];
42
+ const transform = Array.isArray(ends)
43
+ ? ends.map((entry, at) => ({
44
+ property: entry.property,
45
+ value: starts[at]?.property === entry.property
46
+ ? starts[at].value
47
+ : restingAmount(entry.property),
48
+ }))
49
+ : ends;
50
+ return {
51
+ opacity: to.opacity === undefined ? undefined : (from.opacity ?? to.opacity),
52
+ transform,
53
+ colors,
54
+ };
55
+ }
56
+ export class NativePainter {
57
+ native;
58
+ touched;
59
+ graphs = new WeakMap();
60
+ constructor(native, touched) {
61
+ this.native = native;
62
+ this.touched = touched;
63
+ }
64
+ /** Whether native can ease a value as well as set it. */
65
+ get eases() {
66
+ const { API } = this.native;
67
+ return !!(API.startAnimatingNode && API.stopAnimation && this.native.generateNewAnimationId);
68
+ }
69
+ /** Have native paint these values on a view, setting only what changed. */
70
+ paint(view, tag, values) {
71
+ const graph = this.graphFor(view, tag, values);
72
+ for (const [path, value] of leavesOf(values)) {
73
+ if (graph.values.get(path) === value)
74
+ continue;
75
+ this.stopLeaf(graph, path);
76
+ this.native.API.setAnimatedNodeValue(graph.leaves.get(path), value);
77
+ graph.values.set(path, value);
78
+ }
79
+ this.flush();
80
+ }
81
+ /**
82
+ * Ease what a view paints from where native has it to `to`, over the frames given, as eased
83
+ * progress from nothing to one. A view with no graph of this shape starts at `from`. `ended`
84
+ * is told once every value has got there; `stop` leaves each where it has got to.
85
+ */
86
+ ease(view, tag, from, to, frames, ended) {
87
+ const { API } = this.native;
88
+ // Built in the shape it ends in, each value at where it starts: an entry the start has none
89
+ // of, as a first transform, is at what leaves the view as it is.
90
+ const start = shapeOf(from) === shapeOf(to) ? from : startIn(from, to);
91
+ const graph = this.graphFor(view, tag, start);
92
+ const mine = new Map();
93
+ const stop = () => {
94
+ for (const [path, id] of mine) {
95
+ if (graph.easing.get(path) !== id)
96
+ continue;
97
+ API.stopAnimation(id);
98
+ graph.easing.delete(path);
99
+ // Somewhere between the two: the next value set is set, whatever it is.
100
+ graph.values.delete(path);
101
+ }
102
+ mine.clear();
103
+ this.flush();
104
+ };
105
+ if (!this.eases) {
106
+ this.paint(view, tag, to);
107
+ ended();
108
+ return { stop };
109
+ }
110
+ for (const [path, value] of leavesOf(to)) {
111
+ if (graph.values.get(path) === value)
112
+ continue;
113
+ this.stopLeaf(graph, path);
114
+ const id = this.native.generateNewAnimationId();
115
+ mine.set(path, id);
116
+ graph.easing.set(path, id);
117
+ graph.values.set(path, value);
118
+ const config = { type: 'frames', frames: [...frames], toValue: value, iterations: 1 };
119
+ API.startAnimatingNode(id, graph.leaves.get(path), config, (result) => {
120
+ if (graph.easing.get(path) === id)
121
+ graph.easing.delete(path);
122
+ if (!mine.delete(path) || !result.finished)
123
+ return;
124
+ if (mine.size === 0)
125
+ ended();
126
+ });
127
+ }
128
+ this.flush();
129
+ if (mine.size === 0)
130
+ ended();
131
+ return { stop };
132
+ }
133
+ /** Whether native paints a view, with a graph connected to it. */
134
+ paints(view) {
135
+ return this.graphs.has(view);
136
+ }
137
+ /** Let a view go: native no longer paints anything on it. */
138
+ release(view) {
139
+ const graph = this.graphs.get(view);
140
+ if (!graph)
141
+ return;
142
+ this.graphs.delete(view);
143
+ this.tearDown(graph);
144
+ this.flush();
145
+ }
146
+ /** The view's graph for values of this shape, built again where it was of another. */
147
+ graphFor(view, tag, values) {
148
+ const shape = shapeOf(values);
149
+ const graph = this.graphs.get(view);
150
+ if (graph?.tag === tag && graph.shape === shape)
151
+ return graph;
152
+ if (graph)
153
+ this.tearDown(graph);
154
+ const built = this.build(tag, shape, values);
155
+ this.graphs.set(view, built);
156
+ this.touched?.(view, tag, Object.keys(this.styleOf(values)));
157
+ return built;
158
+ }
159
+ /** The style keys a graph for these values sets. */
160
+ styleOf(values) {
161
+ const keys = {};
162
+ if (values.opacity !== undefined)
163
+ keys['opacity'] = true;
164
+ for (const key of Object.keys(values.colors ?? {}))
165
+ keys[key] = true;
166
+ if (values.transform)
167
+ keys['transform'] = true;
168
+ return keys;
169
+ }
170
+ build(tag, shape, values) {
171
+ const { API } = this.native;
172
+ const nodes = [];
173
+ const leaves = new Map();
174
+ const made = (config) => {
175
+ const node = this.native.generateNewNodeTag();
176
+ API.createAnimatedNode(node, config);
177
+ nodes.push(node);
178
+ return node;
179
+ };
180
+ const leaf = (path, value) => {
181
+ const node = made({ type: 'value', value, offset: 0 });
182
+ leaves.set(path, node);
183
+ return node;
184
+ };
185
+ const style = {};
186
+ if (values.opacity !== undefined)
187
+ style['opacity'] = leaf('opacity', values.opacity);
188
+ for (const [key, rgba] of Object.entries(values.colors ?? {})) {
189
+ const [r, g, b, a] = rgba.map((part, at) => leaf(`${key}.${PARTS[at]}`, part));
190
+ const colour = made({ type: 'color', r, g, b, a });
191
+ for (const part of [r, g, b, a])
192
+ API.connectAnimatedNodes(part, colour);
193
+ style[key] = colour;
194
+ }
195
+ const list = values.transform;
196
+ if (list && !Array.isArray(list)) {
197
+ style['transform'] = made({ type: 'object', value: list.literal });
198
+ }
199
+ else if (list) {
200
+ const transforms = list.map((entry, at) => ({
201
+ type: 'animated',
202
+ property: entry.property,
203
+ nodeTag: leaf(`transform.${at}`, entry.value),
204
+ }));
205
+ const transform = made({ type: 'transform', transforms });
206
+ for (const entry of transforms)
207
+ API.connectAnimatedNodes(entry.nodeTag, transform);
208
+ style['transform'] = transform;
209
+ }
210
+ const styleNode = made({ type: 'style', style });
211
+ for (const node of Object.values(style))
212
+ API.connectAnimatedNodes(node, styleNode);
213
+ const props = made({ type: 'props', props: { style: styleNode } });
214
+ API.connectAnimatedNodes(styleNode, props);
215
+ API.connectAnimatedNodeToView(props, tag);
216
+ return {
217
+ tag,
218
+ shape,
219
+ props,
220
+ nodes: [props, ...nodes.filter((node) => node !== props).reverse()],
221
+ leaves,
222
+ values: leavesOf(values),
223
+ easing: new Map(),
224
+ };
225
+ }
226
+ stopLeaf(graph, path) {
227
+ const id = graph.easing.get(path);
228
+ if (id === undefined)
229
+ return;
230
+ graph.easing.delete(path);
231
+ this.native.API.stopAnimation?.(id);
232
+ }
233
+ tearDown(graph) {
234
+ const { API } = this.native;
235
+ for (const id of graph.easing.values())
236
+ API.stopAnimation?.(id);
237
+ graph.easing.clear();
238
+ API.disconnectAnimatedNodeFromView(graph.props, graph.tag);
239
+ for (const node of graph.nodes)
240
+ API.dropAnimatedNode(node);
241
+ }
242
+ flush() {
243
+ this.native.API.flushQueue?.();
244
+ }
245
+ }
246
+ //# sourceMappingURL=native-paint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-paint.js","sourceRoot":"","sources":["../src/native-paint.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * What a view paints, set on native with no commit: its opacity, transform and colours, through\n * React Native's animated nodes, as `Animated` with the native driver sets them.\n *\n * A commit for a change of paint alone costs the whole round: the path from the root cloned,\n * native's diff, and a layout of every view on the screen, for a progress bar stepped every 50ms\n * twenty times a second. A value set on a native animated node reaches the view directly, by\n * `synchronouslyUpdateViewOnUIThread`, with none of that. Each view has one graph: a value node\n * for every number it paints, the transform and colour nodes over them, a style node and a props\n * node connected to the view. A change of a number is a value set; a change of what the view\n * paints, another key or a transform of another shape, builds the graph again.\n *\n * Only what native can change without a layout goes this way: React Native's props node updates\n * the view's props and not the shadow tree, so the engine commits the values the views hold\n * once they are left alone, or before anything reads where they are drawn.\n */\nimport type { NativeAnimated, Touched } from './native-drive.ts';\n\nexport type NumericTransform = readonly { readonly property: string; readonly value: number }[];\n\n/** A colour as native's colour node takes it: red, green and blue to 255, alpha to 1. */\nexport type Rgba = readonly [number, number, number, number];\n\n/** What a view paints, as numbers native's nodes take. */\nexport interface PaintValues {\n opacity?: number;\n /**\n * Each entry's property and its amount: points, a factor, or an angle in radians. Or a list\n * as a commit carries it, for one a transform node cannot take, a matrix: native is given it\n * whole, as an object node, and each change of it builds the graph again.\n */\n transform?: NumericTransform | { readonly literal: readonly unknown[] };\n colors?: Readonly<Record<string, Rgba>>;\n}\n\ninterface Graph {\n tag: number;\n shape: string;\n props: number;\n /** Every node made, the props node first, for dropping them. */\n nodes: number[];\n /** The value node for each number painted, by its path: `opacity`, `transform.0`, `color.r`. */\n leaves: Map<string, number>;\n /** The last value each leaf was set or eased to. Absent where an ease was stopped part way. */\n values: Map<string, number>;\n /** The animation easing each leaf, by its id, while one does. */\n easing: Map<string, number>;\n}\n\nconst PARTS = ['r', 'g', 'b', 'a'] as const;\n\n/** Every number a view paints, by its path in the graph. */\nfunction leavesOf(values: PaintValues): Map<string, number> {\n const leaves = new Map<string, number>();\n if (values.opacity !== undefined) leaves.set('opacity', values.opacity);\n for (const [key, rgba] of Object.entries(values.colors ?? {})) {\n rgba.forEach((part, at) => leaves.set(`${key}.${PARTS[at]}`, part));\n }\n const transform = values.transform;\n if (Array.isArray(transform)) {\n (transform as NumericTransform).forEach((entry, at) => {\n leaves.set(`transform.${at}`, entry.value);\n });\n }\n return leaves;\n}\n\n/** What makes two sets of values the same graph: which keys, and the transform's properties. */\nfunction shapeOf(values: PaintValues): string {\n const colours = Object.keys(values.colors ?? {}).sort();\n const list = values.transform;\n const transform = !list\n ? undefined\n : Array.isArray(list)\n ? (list as NumericTransform).map((entry) => entry.property).join(',')\n : JSON.stringify((list as { literal: unknown }).literal);\n return `${values.opacity === undefined ? '' : 'o'}|${colours.join(',')}|${transform ?? '-'}`;\n}\n\n/** What an entry of a transform is where it moves the view nowhere: a scale is 1, the rest 0. */\nconst restingAmount = (property: string): number => (property.startsWith('scale') ? 1 : 0);\n\n/**\n * Values in the shape of `to`, each at where `from` has it: an opacity or a colour `from` has\n * none of is where `to` is, and a transform entry it has none of rests the view as it is. A\n * transform painted whole, a matrix, cannot be eased from somewhere else, and starts at `to`.\n */\nfunction startIn(from: PaintValues, to: PaintValues): PaintValues {\n const colors: Record<string, Rgba> = {};\n for (const [key, rgba] of Object.entries(to.colors ?? {}))\n colors[key] = from.colors?.[key] ?? rgba;\n const ends = to.transform;\n const starts = Array.isArray(from.transform) ? (from.transform as NumericTransform) : [];\n const transform = Array.isArray(ends)\n ? (ends as NumericTransform).map((entry, at) => ({\n property: entry.property,\n value:\n starts[at]?.property === entry.property\n ? starts[at].value\n : restingAmount(entry.property),\n }))\n : ends;\n return {\n opacity: to.opacity === undefined ? undefined : (from.opacity ?? to.opacity),\n transform,\n colors,\n };\n}\n\nexport class NativePainter {\n private readonly native: NativeAnimated;\n private readonly touched: Touched | undefined;\n private readonly graphs = new WeakMap<object, Graph>();\n\n constructor(native: NativeAnimated, touched?: Touched) {\n this.native = native;\n this.touched = touched;\n }\n\n /** Whether native can ease a value as well as set it. */\n get eases(): boolean {\n const { API } = this.native;\n return !!(API.startAnimatingNode && API.stopAnimation && this.native.generateNewAnimationId);\n }\n\n /** Have native paint these values on a view, setting only what changed. */\n paint(view: object, tag: number, values: PaintValues): void {\n const graph = this.graphFor(view, tag, values);\n for (const [path, value] of leavesOf(values)) {\n if (graph.values.get(path) === value) continue;\n this.stopLeaf(graph, path);\n this.native.API.setAnimatedNodeValue(graph.leaves.get(path)!, value);\n graph.values.set(path, value);\n }\n this.flush();\n }\n\n /**\n * Ease what a view paints from where native has it to `to`, over the frames given, as eased\n * progress from nothing to one. A view with no graph of this shape starts at `from`. `ended`\n * is told once every value has got there; `stop` leaves each where it has got to.\n */\n ease(\n view: object,\n tag: number,\n from: PaintValues,\n to: PaintValues,\n frames: readonly number[],\n ended: () => void,\n ): { stop(): void } {\n const { API } = this.native;\n // Built in the shape it ends in, each value at where it starts: an entry the start has none\n // of, as a first transform, is at what leaves the view as it is.\n const start = shapeOf(from) === shapeOf(to) ? from : startIn(from, to);\n const graph = this.graphFor(view, tag, start);\n const mine = new Map<string, number>();\n const stop = () => {\n for (const [path, id] of mine) {\n if (graph.easing.get(path) !== id) continue;\n API.stopAnimation!(id);\n graph.easing.delete(path);\n // Somewhere between the two: the next value set is set, whatever it is.\n graph.values.delete(path);\n }\n mine.clear();\n this.flush();\n };\n if (!this.eases) {\n this.paint(view, tag, to);\n ended();\n return { stop };\n }\n for (const [path, value] of leavesOf(to)) {\n if (graph.values.get(path) === value) continue;\n this.stopLeaf(graph, path);\n const id = this.native.generateNewAnimationId!();\n mine.set(path, id);\n graph.easing.set(path, id);\n graph.values.set(path, value);\n const config = { type: 'frames', frames: [...frames], toValue: value, iterations: 1 };\n API.startAnimatingNode!(id, graph.leaves.get(path)!, config, (result) => {\n if (graph.easing.get(path) === id) graph.easing.delete(path);\n if (!mine.delete(path) || !result.finished) return;\n if (mine.size === 0) ended();\n });\n }\n this.flush();\n if (mine.size === 0) ended();\n return { stop };\n }\n\n /** Whether native paints a view, with a graph connected to it. */\n paints(view: object): boolean {\n return this.graphs.has(view);\n }\n\n /** Let a view go: native no longer paints anything on it. */\n release(view: object): void {\n const graph = this.graphs.get(view);\n if (!graph) return;\n this.graphs.delete(view);\n this.tearDown(graph);\n this.flush();\n }\n\n /** The view's graph for values of this shape, built again where it was of another. */\n private graphFor(view: object, tag: number, values: PaintValues): Graph {\n const shape = shapeOf(values);\n const graph = this.graphs.get(view);\n if (graph?.tag === tag && graph.shape === shape) return graph;\n if (graph) this.tearDown(graph);\n const built = this.build(tag, shape, values);\n this.graphs.set(view, built);\n this.touched?.(view, tag, Object.keys(this.styleOf(values)));\n return built;\n }\n\n /** The style keys a graph for these values sets. */\n private styleOf(values: PaintValues): Record<string, true> {\n const keys: Record<string, true> = {};\n if (values.opacity !== undefined) keys['opacity'] = true;\n for (const key of Object.keys(values.colors ?? {})) keys[key] = true;\n if (values.transform) keys['transform'] = true;\n return keys;\n }\n\n private build(tag: number, shape: string, values: PaintValues): Graph {\n const { API } = this.native;\n const nodes: number[] = [];\n const leaves = new Map<string, number>();\n const made = (config: object): number => {\n const node = this.native.generateNewNodeTag();\n API.createAnimatedNode(node, config);\n nodes.push(node);\n return node;\n };\n const leaf = (path: string, value: number): number => {\n const node = made({ type: 'value', value, offset: 0 });\n leaves.set(path, node);\n return node;\n };\n const style: Record<string, number> = {};\n if (values.opacity !== undefined) style['opacity'] = leaf('opacity', values.opacity);\n for (const [key, rgba] of Object.entries(values.colors ?? {})) {\n const [r, g, b, a] = rgba.map((part, at) => leaf(`${key}.${PARTS[at]}`, part));\n const colour = made({ type: 'color', r, g, b, a });\n for (const part of [r, g, b, a]) API.connectAnimatedNodes(part!, colour);\n style[key] = colour;\n }\n const list = values.transform;\n if (list && !Array.isArray(list)) {\n style['transform'] = made({ type: 'object', value: (list as { literal: unknown }).literal });\n } else if (list) {\n const transforms = (list as NumericTransform).map((entry, at) => ({\n type: 'animated',\n property: entry.property,\n nodeTag: leaf(`transform.${at}`, entry.value),\n }));\n const transform = made({ type: 'transform', transforms });\n for (const entry of transforms) API.connectAnimatedNodes(entry.nodeTag, transform);\n style['transform'] = transform;\n }\n const styleNode = made({ type: 'style', style });\n for (const node of Object.values(style)) API.connectAnimatedNodes(node, styleNode);\n const props = made({ type: 'props', props: { style: styleNode } });\n API.connectAnimatedNodes(styleNode, props);\n API.connectAnimatedNodeToView(props, tag);\n return {\n tag,\n shape,\n props,\n nodes: [props, ...nodes.filter((node) => node !== props).reverse()],\n leaves,\n values: leavesOf(values),\n easing: new Map(),\n };\n }\n\n private stopLeaf(graph: Graph, path: string): void {\n const id = graph.easing.get(path);\n if (id === undefined) return;\n graph.easing.delete(path);\n this.native.API.stopAnimation?.(id);\n }\n\n private tearDown(graph: Graph): void {\n const { API } = this.native;\n for (const id of graph.easing.values()) API.stopAnimation?.(id);\n graph.easing.clear();\n API.disconnectAnimatedNodeFromView(graph.props, graph.tag);\n for (const node of graph.nodes) API.dropAnimatedNode(node);\n }\n\n private flush(): void {\n this.native.API.flushQueue?.();\n }\n}\n"]}
@@ -84,6 +84,11 @@ export declare function sharesAsPoints<T extends Track>(tracks: ReadonlyMap<stri
84
84
  tracks: Map<string, T>;
85
85
  resting: Record<string, unknown>;
86
86
  };
87
+ /**
88
+ * A transform entry's amount as native's transform node takes it: points, a factor, or an angle
89
+ * in radians. Null for what it cannot take, a percentage translate.
90
+ */
91
+ export declare function amount(key: string, value: unknown): number | null;
87
92
  /** The values a scroll-driven animation commits: its frame at the offset the view starts at. */
88
93
  export declare function firstFrame(tracks: ReadonlyMap<string, Track>, spec: AnimationSpec, range: readonly [number, number]): Record<string, unknown>;
89
94
  export {};
@@ -278,7 +278,7 @@ export function sharesAsPoints(tracks, resting, size) {
278
278
  * A transform entry's amount as native's transform node takes it: points, a factor, or an angle
279
279
  * in radians. Null for what it cannot take, a percentage translate.
280
280
  */
281
- function amount(key, value) {
281
+ export function amount(key, value) {
282
282
  if (typeof value === 'number')
283
283
  return value;
284
284
  if (typeof value !== 'string')