@pixodesk/svg-animator-rn 1.0.41 → 1.0.43
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/dist/index.cjs +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/PixodeskSvgAnimator.tsx +9 -9
- package/src/PxRnErrorBoundary.tsx +3 -3
package/dist/index.cjs
CHANGED
|
@@ -398,7 +398,7 @@ var PxRnErrorBoundary = class extends import_react2.Component {
|
|
|
398
398
|
}
|
|
399
399
|
componentDidCatch(error, info) {
|
|
400
400
|
var _a, _b;
|
|
401
|
-
((_a = this.props.diag) != null ? _a : (0, import_internal4.createDiagnostics)(void 0, "[PixodeskSvgAnimator]")).error(import_svg_animator_core3.PxDiagnosticKind.internal, error,
|
|
401
|
+
((_a = this.props.diag) != null ? _a : (0, import_internal4.createDiagnostics)(void 0, "[PixodeskSvgAnimator]")).error(import_svg_animator_core3.PxDiagnosticKind.internal, import_svg_animator_core3.PxDiagnosticCode.rnBoundaryCaught, error, (_b = info == null ? void 0 : info.componentStack) != null ? _b : void 0);
|
|
402
402
|
}
|
|
403
403
|
componentDidUpdate(prev) {
|
|
404
404
|
if (this.state.error && prev.children !== this.props.children) {
|
|
@@ -560,12 +560,12 @@ var EMPTY_TRACKS = {
|
|
|
560
560
|
function compileDocument(doc, overrides, diag) {
|
|
561
561
|
const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
|
|
562
562
|
const warnings = (0, import_svg_animator_core4.validateNodeEffects)(doc);
|
|
563
|
-
for (const w of warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.document,
|
|
563
|
+
for (const w of warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.document, import_svg_animator_core4.PxDiagnosticCode.effectsShape, w);
|
|
564
564
|
(0, import_internal6.reportDocumentDiagnostics)(doc, "[PixodeskSvgAnimator]");
|
|
565
565
|
const patch = (0, import_svg_animator_core4.foldTimelineOverride)(timeline, { duration, delay, iterations, startOn });
|
|
566
566
|
if (patch !== void 0 || resetTimeline) {
|
|
567
567
|
const applied = (0, import_svg_animator_core4.applyAnimatorConfig)(doc, patch != null ? patch : {}, { resetTimeline: !!resetTimeline });
|
|
568
|
-
for (const w of applied.warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage,
|
|
568
|
+
for (const w of applied.warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.timelineOverrideIgnored, w);
|
|
569
569
|
doc = applied.doc;
|
|
570
570
|
}
|
|
571
571
|
let prepared = (0, import_svg_animator_core4.materializeAllInTree)(doc, import_svg_animator_core4.PxTimelineEngine.native);
|
|
@@ -618,7 +618,7 @@ function PixodeskSvgAnimator({
|
|
|
618
618
|
);
|
|
619
619
|
} catch (e) {
|
|
620
620
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
621
|
-
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal,
|
|
621
|
+
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, import_svg_animator_core4.PxDiagnosticCode.rnCompileFailed, error);
|
|
622
622
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
623
623
|
}
|
|
624
624
|
}, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);
|
|
@@ -707,7 +707,7 @@ function PixodeskSvgAnimator({
|
|
|
707
707
|
},
|
|
708
708
|
setPlaybackRate: (rate) => {
|
|
709
709
|
if (!(0, import_svg_animator_core4.isValidPlaybackRate)(rate)) {
|
|
710
|
-
makeDiag().warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.
|
|
710
|
+
makeDiag().warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.rateRejected);
|
|
711
711
|
return;
|
|
712
712
|
}
|
|
713
713
|
rateRef.current = rate;
|
|
@@ -743,7 +743,7 @@ function PixodeskSvgAnimator({
|
|
|
743
743
|
const { mode: compMode, warnings: modeWarnings } = (0, import_svg_animator_core4.resolveControlMode)({ progress: progressProp, time, play, pause, autoplay });
|
|
744
744
|
(0, import_react3.useEffect)(() => {
|
|
745
745
|
const diag = makeDiag();
|
|
746
|
-
for (const w of modeWarnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, w);
|
|
746
|
+
for (const w of modeWarnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.controlPropsConflict, w);
|
|
747
747
|
}, [modeWarnings.join("|")]);
|
|
748
748
|
(0, import_react3.useEffect)(() => {
|
|
749
749
|
if (compMode === import_svg_animator_core4.PxControlMode.fixedTime) {
|
|
@@ -854,13 +854,13 @@ function PixodeskSvgAnimator({
|
|
|
854
854
|
} catch (e) {
|
|
855
855
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
856
856
|
renderErrorRef.current = error;
|
|
857
|
-
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal,
|
|
857
|
+
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, import_svg_animator_core4.PxDiagnosticCode.rnRenderFailed, error);
|
|
858
858
|
return null;
|
|
859
859
|
}
|
|
860
860
|
}, [compiled, trackById]);
|
|
861
861
|
(0, import_react3.useEffect)(() => {
|
|
862
862
|
const diag = makeDiag();
|
|
863
|
-
for (const w of warningsRef.current) diag.warn(import_svg_animator_core4.PxDiagnosticKind.platform, w);
|
|
863
|
+
for (const w of warningsRef.current) diag.warn(import_svg_animator_core4.PxDiagnosticKind.platform, import_svg_animator_core4.PxDiagnosticCode.rnUnsupported, w);
|
|
864
864
|
}, [root]);
|
|
865
865
|
const failure = (_b = compiled.error) != null ? _b : renderErrorRef.current;
|
|
866
866
|
if (failure) return fallback ? fallback(failure) : null;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/PixodeskSvgAnimator.tsx","../src/PxRnTracks.ts","../src/PxRnPropNames.ts","../src/PxRnMatrix.ts","../src/PxRnRender.tsx","../src/PxRnTypeMap.ts","../src/PxRnErrorBoundary.tsx","../src/PxRnSafety.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nexport { PixodeskSvgAnimator, default } from './PixodeskSvgAnimator';\nexport type { PixodeskSvgAnimatorProps, RnAnimatorApi } from './PixodeskSvgAnimator';\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PX_RATE_REJECTED, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';\nimport React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { Dimensions, Platform, Pressable, View } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedReaction,\n Easing,\n runOnJS,\n useAnimatedProps,\n useSharedValue,\n withDelay,\n withRepeat,\n withTiming,\n type SharedValue,\n} from 'react-native-reanimated';\nimport { compileTracks, sampleProps, type PxCompiledTracks, type PxElementTracks } from './PxRnTracks';\nimport { renderRnNode, type RenderRnNodeOptions } from './PxRnRender';\nimport { PxRnErrorBoundary } from './PxRnErrorBoundary';\nimport { openClosedTextPathTargets } from './PxRnSafety';\n\n\n// -- Public types -----------------------------------------------------------\n\n/**\n * The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's\n * name (review §9). It no longer \"mirrors\" the React one by hand: the local copy had already\n * drifted (its `setPlaybackRate` comment lost \"negative plays backwards\"). One definition.\n * @public\n */\nexport type RnAnimatorApi = PxAnimatorHandle;\n\n/**\n * The component's props. The playback override, the control props and the callbacks are core's\n * shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and\n * `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs\n * on this platform is declared here: `fallback`, which has no web counterpart.\n * @public\n */\nexport interface PixodeskSvgAnimatorProps\n extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {\n\n // -- Source ---------------------------------------------------------------\n\n /** The animation document to render. */\n doc: PxAnimatedSvgDocument;\n\n /**\n * Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.\n *\n * `engine` is accepted but ignored here: React Native always uses the `native` (fully\n * flattened) materialization, because react-native-svg has no `<use>` shadow-tree\n * propagation.\n */\n timeline?: PxTimelinePatch | string;\n\n // -- Imperative control ---------------------------------------------------\n\n /**\n * Ref populated with the imperative playback API. Filled in EVERY mode and never picks one\n * (review §1): `autoplay` next to it still autoplays.\n */\n apiRef?: React.RefObject<RnAnimatorApi | null>;\n\n // -- Failure handling -----------------------------------------------------\n // A document that cannot be compiled or rendered is reported through `onError` — the same\n // `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the\n // thrown Error and, when the error boundary caught it, `diagnostic.detail.componentStack`.\n // The component renders `fallback` instead of throwing, so one broken animation never\n // takes down the screen around it. Only JavaScript failures reach this — a crash inside\n // react-native-svg's native renderer bypasses JavaScript entirely.\n\n /** Rendered in place of the animation after a failure. Default: nothing. */\n fallback?: (error: Error) => ReactElement | null;\n}\n\n\n// -- Animated element wrapper ------------------------------------------------\n\n/**\n * Whether react-native-svg is backed by NATIVE views here, rather than by the\n * DOM through react-native-web.\n *\n * The two want different things from an animated `transform`: a native view\n * declares a `matrix` prop taking six numbers, while the DOM wants a\n * `transform` attribute holding an SVG string. Getting it wrong is silent —\n * the value is dropped and the element simply never moves — so this single\n * constant decides it once and feeds both the track compiler (value form) and\n * the sampler (prop name). Everything else in the package defaults to the\n * DOM-compatible form.\n */\nconst NATIVE_SVG_VIEWS = Platform.OS !== 'web';\n\nconst animatedComponentCache = new Map<ComponentType<any>, ComponentType<any>>();\n\nfunction getAnimatedComponent(Component: ComponentType<any>): ComponentType<any> {\n let cached = animatedComponentCache.get(Component);\n if (!cached) {\n cached = Animated.createAnimatedComponent(Component as any);\n animatedComponentCache.set(Component, cached);\n }\n return cached;\n}\n\n/** One animated element: static props + UI-thread sampled animated props. */\nfunction AnimatedPxElement({\n Component, staticProps, children, tracks, progress, stepMs, sampleCount,\n}: {\n Component: ComponentType<any>;\n staticProps: Record<string, any>;\n children: ReactNode;\n tracks: PxElementTracks;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n}) {\n const AnimatedComponent = useMemo(() => getAnimatedComponent(Component), [Component]);\n\n // Runs on the UI thread every frame; `sampleProps` is a trivial indexed\n // lookup into the precompiled tracks — no interpolation logic on the hot path.\n const animatedProps = useAnimatedProps(() => {\n // On iOS/Android these values bypass react-native-svg's JS prop layer\n // and land on the native view, which declares `matrix`, not\n // `transform`. The web build keeps the DOM-facing `transform` name.\n return sampleProps(tracks, progress.value, stepMs, sampleCount, NATIVE_SVG_VIEWS);\n }, [tracks, stepMs, sampleCount]);\n\n return (\n <AnimatedComponent {...staticProps} animatedProps={animatedProps}>\n {children}\n </AnimatedComponent>\n );\n}\n\n\n/**\n * react-native-svg elements whose `render()` returns `null`. They carry data for\n * their PARENT (a `<Stop>` is read by the gradient that owns it) rather than\n * producing a native view, so reanimated has nothing to attach to — wrapping one\n * in `Animated.createAnimatedComponent` throws\n * \"Cannot find host instance for this component\".\n */\nconst NON_HOST_TAGS = new Set(['stop', 'feMergeNode']);\n\n/**\n * Definition elements — they describe paint/geometry for something else rather\n * than drawing themselves. Their animated attributes (a gradient's `y1`, a\n * stop's `stop-color`) do not reliably flow through reanimated's animated-props\n * path, so an animated def is rendered by re-sampling from JS instead. There\n * are only ever a handful per document and they change slowly, so the cost is\n * negligible — visual elements still animate entirely on the UI thread.\n */\nconst SAMPLED_DEF_TAGS = new Set(['linearGradient', 'radialGradient', ...NON_HOST_TAGS]);\n\n/** True when this subtree must be driven from JS rather than the UI thread:\n * either the node itself is an animated def, or it owns an animated non-host\n * child (an animated `<Stop>` only re-renders via its parent gradient). */\nfunction needsJsSampling(node: PxNode, trackById: Map<string, PxElementTracks>): boolean {\n const id = (node as any).id;\n if (SAMPLED_DEF_TAGS.has(String(node.type)) && id && trackById.has(id)) return true;\n return (node.children ?? []).some(c => needsJsSampling(c, trackById));\n}\n\n/**\n * Renders a subtree whose animation cannot run on the UI thread (see\n * {@link NON_HOST_TAGS}) by re-rendering it from JS with sampled values.\n *\n * Changing a `<Stop>`'s props does not re-render its parent gradient, so the\n * whole subtree is rebuilt — which is why this wraps the gradient rather than\n * the stop. The reaction itself runs on the UI thread and only crosses to JS\n * when the QUANTISED sample index changes, capping these few elements at\n * ~30fps instead of a JS call every frame.\n */\nfunction SampledSubtree({\n node, trackById, progress, stepMs, sampleCount, renderOpts,\n}: {\n node: PxNode;\n trackById: Map<string, PxElementTracks>;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n renderOpts: RenderRnNodeOptions;\n}) {\n const [idx, setIdx] = useState(0);\n\n useAnimatedReaction(\n () => Math.floor(Math.round(progress.value / stepMs) / 2) * 2, // half-rate\n (next, prev) => {\n if (next !== prev) runOnJS(setIdx)(next);\n },\n [stepMs]\n );\n\n const tMs = Math.min(Math.max(idx, 0), sampleCount - 1) * stepMs;\n\n return renderRnNode(node, {\n ...renderOpts,\n // Sampled values are baked in as PLAIN props — nothing reanimated-driven.\n decorate: (n, Component, staticProps, children, key) => {\n const id = (n as any).id;\n const tracks = id ? trackById.get(id) : undefined;\n if (!tracks) return undefined;\n // Wire prop names, NOT the native ones: these go back through\n // react-native-svg's JS prop layer, which does the renaming itself.\n const sampled = sampleProps(tracks, tMs, stepMs, sampleCount);\n return createElement(Component, { ...staticProps, ...sampled, key }, children);\n },\n });\n}\n\n\n\n/** Overrides that shadow the document's own `animator` config. */\n/** The override subset of the props — core's shared shape, not a local copy (review §9). */\ntype ConfigOverrides = PxPlaybackOverride;\n\ninterface Compiled {\n /** Materialized document, or null when compilation failed. */\n doc: PxAnimatedSvgDocument | null;\n tracks: PxCompiledTracks;\n error: Error | null;\n}\n\n/** Playable-but-empty tracks, so a failed compile still satisfies every hook\n * below it — React forbids skipping hooks on an error path. */\nconst EMPTY_TRACKS: PxCompiledTracks = {\n duration: 1, iterations: 1, direction: 'normal', delay: 0,\n fill: 'forwards', resetOnFinish: false, stepMs: 1, sampleCount: 2, elements: [],\n};\n\n/**\n * Materializes + compiles a document. Extracted from the component so the\n * whole thing sits behind one try/catch, and so it can be tested directly.\n */\nfunction compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {\n const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;\n const warnings = validateNodeEffects(doc as PxNode);\n for (const w of warnings) diag.warn(PxDiagnosticKind.document, 'effects shape: ' + w);\n // The whole-document boundary diagnostic — see the note in the web player's entry.\n reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');\n\n // The per-instance override, applied to the WIRE document BEFORE anything reads the\n // config — `materializeAllInTree` samples motion paths against `duration`, so a later\n // patch would be read by none of the pipeline. Same call, same rules, on every surface.\n const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });\n if (patch !== undefined || resetTimeline) {\n const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });\n for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, 'timeline override: ' + w);\n doc = applied.doc;\n }\n\n // `native` = the FULLY-FLATTENED materialization: effects + loops +\n // sampled motion paths + animated `<use>` inlined into real `<g>`\n // clones + orphaned defs pruned. That last part is why RN must not use\n // the `js` flavor: the frame loop keeps `<use href=\"#animatedTarget\">`\n // live references, which only work because the DOM propagates\n // attribute writes through `<use>` shadow trees. react-native-svg has\n // no such live propagation, so an animated `<use>` would render frozen.\n let prepared = materializeAllInTree(doc, PxTimelineEngine.native);\n\n // Sidestep a react-native-svg NATIVE crash (see PxRnSafety). Guarded on\n // the platform because the DOM renders this case correctly and the web\n // document must stay exactly as the core pipeline produced it.\n if (NATIVE_SVG_VIEWS) {\n prepared = openClosedTextPathTargets(prepared as PxNode) as PxAnimatedSvgDocument;\n }\n\n prepared = generateNewIds(prepared);\n const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });\n return { doc: prepared, tracks, error: null };\n}\n\n\n// -- Main component ----------------------------------------------------------\n\n/**\n * React Native component for rendering and controlling Pixodesk SVG animations.\n *\n * The document is materialized once through the shared core pipeline (effects,\n * loops, motion-path sampling, animated-`<use>` inlining — identical to the\n * web's `native` engine, NOT the frame loop, which keeps `<use>` live), compiled\n * into densely sampled per-element tracks, and\n * played back natively: a single reanimated progress value driven by\n * `withTiming`/`withRepeat` on the UI thread, with per-element worklets\n * indexing the precompiled tracks. No JS-thread frame loop.\n * @public\n */\nexport function PixodeskSvgAnimator({\n doc, timeline, resetTimeline, duration, delay, iterations, startOn,\n // (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)\n autoplay, play, pause, apiRef, progress: progressProp, time,\n onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError,\n}: PixodeskSvgAnimatorProps): ReactElement | null {\n\n // -- Compile the document (once per doc/override change) ------------------\n\n // `timeline` is an object prop: a fresh literal every render would otherwise recompile the\n // whole document (materialize + compile tracks), which is the expensive path. Key on its\n // CONTENT instead — the override is small, the document is not.\n const timelineKey = typeof timeline === 'string' ? timeline : JSON.stringify(timeline ?? null);\n\n\n /**\n * The diagnostics channel, built from the CURRENT props each time (API review §5).\n * Deliberately not hoisted into a wrapper closure: `(m, d) => onWarn?.(m, d)` would always\n * be a function, so the channel would believe a handler exists and the console fallback\n * would never fire for anyone who passed nothing.\n */\n const makeDiag = (): PxDiagnostics => createDiagnostics(\n { onWarn, onError, muteWarn, muteError }, '[PixodeskSvgAnimator]');\n\n const compiled = useMemo((): Compiled => {\n try {\n return compileDocument(\n doc,\n { timeline, resetTimeline, duration, delay, iterations, startOn },\n makeDiag(),\n );\n } catch (e) {\n // A malformed document must not take the host screen down with it. This instance\n // will not play — an ERROR, reported once, here (review §25.1).\n const error = e instanceof Error ? e : new Error(String(e));\n makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'compile' });\n return { doc: null, tracks: EMPTY_TRACKS, error };\n }\n // `timeline` is an object prop, so a fresh literal each render would recompile the whole\n // document. Key on its CONTENT — the override is small, unlike the document.\n }, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);\n\n const tracks: PxCompiledTracks = compiled.tracks;\n // The span `progress` 0–1 covers (ONE iteration when endless) — NOT the seek ceiling.\n const totalDuration = progressSpanMs(tracks.duration, tracks.iterations);\n // How far a seek may go: unbounded when endless (review §3).\n const seekCeiling = seekCeilingMs(tracks.duration, tracks.iterations);\n\n // Whole-run time lives on its own clock: `progress` below is deliberately within ONE\n // iteration, and `withRepeat` never reports how many have elapsed, so the run time cannot\n // be read back off it. See `createRunClock`.\n const runClock = useMemo(() => createRunClock(seekCeiling), [seekCeiling]);\n\n // -- Playback state -------------------------------------------------------\n\n // Progress in ms within ONE iteration; iteration repetition/alternation is\n // expressed through withRepeat, so worklets only ever see [0, duration].\n const progress = useSharedValue(0);\n const playingRef = useRef(false);\n const rateRef = useRef(1);\n\n /** True when the current rate plays the timeline backwards. */\n const reversePlayback = () => rateRef.current < 0;\n\n /** Where the playhead rests once playback ends. `resetOnFinish` snaps back\n * to the start; otherwise `fill` decides whether the final frame is held. */\n const restingPosition = () => {\n if (tracks.resetOnFinish) return 0;\n if (tracks.fill === 'none' || tracks.fill === 'backwards') return 0;\n return reversePlayback() ? 0 : tracks.duration;\n };\n\n const notifyFinish = () => {\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n };\n\n const startFrom = (fromMs: number) => {\n const dur = tracks.duration;\n const rate = rateRef.current || 1;\n const backwards = rate < 0;\n const speed = Math.abs(rate);\n // `direction` decides which end a leg runs toward; a negative playback\n // rate flips it again (the two compose, as in the Web Animations API).\n const directionReversed = tracks.direction === 'reverse' || tracks.direction === 'alternate-reverse';\n const reversedStart = backwards ? !directionReversed : directionReversed;\n const alternates = tracks.direction === 'alternate' || tracks.direction === 'alternate-reverse';\n const from = Math.max(0, Math.min(fromMs, dur));\n\n const legTarget = reversedStart ? 0 : dur;\n const legRemaining = Math.abs(legTarget - from) / speed;\n const repeats = tracks.iterations === Infinity ? -1 : tracks.iterations;\n\n cancelAnimation(progress);\n progress.value = reversedStart ? (from <= 0 ? dur : from) : (from >= dur ? 0 : from);\n\n const animation = repeats === 1\n ? withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }, (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n })\n : withRepeat(\n withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }),\n repeats, alternates,\n (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n }\n );\n\n progress.value = tracks.delay > 0 && from === 0\n ? withDelay(tracks.delay / speed, animation)\n : animation;\n\n playingRef.current = true;\n };\n\n const api: RnAnimatorApi = {\n isPlaying: () => playingRef.current,\n play: () => {\n // `startFrom` rewinds to the opposite end when the playhead is\n // already resting at a boundary (mirrors WAAPI, where play() on a\n // finished animation auto-rewinds) — the run clock rewinds with it,\n // or the time would keep counting on from the old end.\n if (Number.isFinite(seekCeiling) && runClock.now() >= seekCeiling) runClock.seek(0);\n runClock.start(rateRef.current);\n startFrom(progress.value);\n onPlay?.();\n },\n pause: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.stop();\n onPause?.();\n onStop?.();\n },\n cancel: () => {\n cancelAnimation(progress);\n progress.value = 0;\n playingRef.current = false;\n runClock.seek(0);\n runClock.stop();\n onCancel?.();\n onStop?.();\n },\n finish: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n },\n setPlaybackRate: (rate: number) => {\n if (!isValidPlaybackRate(rate)) {\n makeDiag().warn(PxDiagnosticKind.usage, PX_RATE_REJECTED);\n return;\n }\n rateRef.current = rate;\n if (playingRef.current) {\n runClock.start(rate); // resume from the current time at the new rate\n startFrom(progress.value);\n }\n },\n\n // Ms from the start of the WHOLE run, like every other engine (review §3). This used\n // to return `progress.value`, which is ms within the current iteration — so a slider\n // built on it jumped back to 0 every time the animation repeated.\n getCurrentTime: () => runClock.now(),\n\n setCurrentTime: (t: number) => {\n const wasPlaying = playingRef.current;\n cancelAnimation(progress);\n playingRef.current = false;\n // Clamp against the SEEK ceiling, not the progress span — the old clamp capped an\n // endless timeline at one iteration.\n const clamped = clampSeekMs(t, seekCeiling);\n runClock.seek(clamped);\n const withinIteration = tracks.duration > 0\n ? (clamped % tracks.duration) || (clamped === 0 ? 0 : tracks.duration)\n : 0;\n progress.value = withinIteration;\n // Seeking mid-playback continues from the new position rather than\n // silently pausing.\n if (wasPlaying) startFrom(withinIteration);\n else runClock.stop();\n },\n\n getCurrentProgress: () => timeToProgress(runClock.now(), tracks.duration, tracks.iterations),\n\n setCurrentProgress: (p: number) => {\n api.setCurrentTime(progressToTimeMs(p, tracks.duration, tracks.iterations));\n },\n };\n\n useImperativeHandle(apiRef, () => api, [compiled]);\n\n // -- Declarative control --------------------------------------------------\n\n // The EFFECTIVE trigger, read back off the COMPILED document — so it already reflects the\n // `timeline` override and the `startOn` shortcut, both merged in before compilation.\n // Resolved through core's one table, so a document means the same here as on the web:\n // no `startOn` = 'load', no `outAction` = 'continue'.\n const trigger = resolveTrigger(compiled.doc ? getAnimatorConfig(compiled.doc)?.trigger : undefined);\n const effectiveStartOn = trigger.startOn;\n const effectiveOutAction = trigger.outAction;\n\n // ONE control-mode rule, decided in core and shared with React and Vue (API review §1/§7).\n // This component always had the right ORDER but no name for it, and never told anyone when\n // two tiers of props were passed together.\n const { mode: compMode, warnings: modeWarnings } =\n resolveControlMode({ progress: progressProp, time, play, pause, autoplay });\n\n useEffect(() => {\n const diag = makeDiag();\n for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modeWarnings.join('|')]);\n\n useEffect(() => {\n if (compMode === PxControlMode.fixedTime) {\n const seekMs = time !== undefined\n ? time\n : progressToTimeMs(progressProp ?? 0, tracks.duration, tracks.iterations);\n api.setCurrentTime(seekMs);\n return;\n }\n if (compMode === PxControlMode.play) {\n if (play && !pause) api.play();\n else if (pause) api.pause();\n else if (play === false) api.pause(); // hold, not finish() — review §8, same as web\n else api.play();\n return;\n }\n // 'click' and 'scrollIntoView' start from their own handlers below.\n if (compMode === PxControlMode.autoplay && effectiveStartOn === 'load') {\n api.play();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, compMode, autoplay, play, pause, progressProp, time]);\n\n // `startOn: 'scrollIntoView'` — react-native has no IntersectionObserver, so\n // visibility is sampled by measuring the view against the window box. The\n // poll is cheap (a native measure every 200ms) and only runs while this\n // trigger is active; `outAction` decides what leaving the viewport does.\n const scrollRef = useRef<View | null>(null);\n const inViewRef = useRef(false);\n useEffect(() => {\n if (!autoplay || effectiveStartOn !== 'scrollIntoView') return;\n const threshold = trigger.scrollIntoViewThreshold;\n inViewRef.current = false;\n\n const check = () => {\n const node = scrollRef.current;\n if (!node) return;\n node.measureInWindow((_x, y, _w, h) => {\n if (!h) return;\n const screen = Dimensions.get('window').height;\n const visible = Math.max(0, Math.min(y + h, screen) - Math.max(y, 0));\n const ratio = visible / h;\n const isIn = ratio > 0 && ratio >= threshold;\n if (isIn === inViewRef.current) return;\n inViewRef.current = isIn;\n if (isIn) {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n } else if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n });\n };\n\n check();\n const id = setInterval(check, 200);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);\n\n // Stop cleanly on unmount / doc swap — and say so, the way the web's destroy() does (§18):\n // both are \"the animator was thrown away\", so `onRemove` fires, and `onStop` with it.\n useEffect(() => {\n return () => {\n cancelAnimation(progress);\n playingRef.current = false;\n onRemove?.();\n onStop?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled]);\n\n // -- Render ---------------------------------------------------------------\n\n const trackById = useMemo(() => {\n const map = new Map<string, PxElementTracks>();\n for (const el of tracks.elements) map.set(el.id, el);\n return map;\n }, [tracks]);\n\n const warningsRef = useRef<Array<string>>([]);\n const renderErrorRef = useRef<Error | null>(null);\n const root = useMemo(() => {\n warningsRef.current = [];\n renderErrorRef.current = null;\n if (!compiled.doc) return null;\n\n const renderOpts: RenderRnNodeOptions = {\n warnings: warningsRef.current,\n defs: getDefinitions(compiled.doc),\n };\n try {\n return renderRnNode(compiled.doc as PxNode, {\n ...renderOpts,\n decorate: (node, Component, staticProps, children, key) => {\n // An animated definition subtree (gradient / its stops) cannot be\n // driven on the UI thread — hand the WHOLE subtree to the\n // JS-sampled renderer and stop descending here.\n if (needsJsSampling(node, trackById)) {\n return (\n <SampledSubtree\n key={key}\n node={node}\n trackById={trackById}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n renderOpts={renderOpts}\n />\n );\n }\n\n const id = (node as any).id;\n const elTracks = id ? trackById.get(id) : undefined;\n if (!elTracks) return undefined;\n return (\n <AnimatedPxElement\n key={key}\n Component={Component}\n staticProps={staticProps}\n tracks={elTracks}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n >\n {children}\n </AnimatedPxElement>\n );\n },\n });\n } catch (e) {\n // Building the element tree threw — this instance will not play: report it once\n // (an ERROR, review §25.1) and render nothing rather than unmount the host screen.\n const error = e instanceof Error ? e : new Error(String(e));\n renderErrorRef.current = error;\n makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'render' });\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, trackById]);\n\n useEffect(() => {\n const diag = makeDiag();\n // `platform`: these come from the react-native-svg prop mapper — shapes this renderer\n // cannot express, rather than anything wrong with the file.\n for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [root]);\n\n // A compile/render failure was reported where it was caught (once, as an error); here it\n // only decides what to show.\n const failure = compiled.error ?? renderErrorRef.current;\n if (failure) return fallback ? fallback(failure) : null;\n\n // `startOn: 'click'` — the touch analogue of the web player's click trigger:\n // tap to start, tap again to apply `outAction`. Hover (`mouseOver`) has no\n // touch equivalent and `scrollIntoView` needs the surrounding scroll view,\n // so both are left to the host app.\n let content: ReactElement | null = root;\n\n if (autoplay && effectiveStartOn === 'scrollIntoView' && root) {\n // `collapsable={false}` keeps the view in the native tree so it can be measured.\n content = <View ref={scrollRef} collapsable={false}>{root}</View>;\n } else if (autoplay && effectiveStartOn === 'click' && root) {\n content = (\n <Pressable\n onPress={() => {\n if (playingRef.current) {\n if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n } else {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n }\n }}\n >\n {root}\n </Pressable>\n );\n }\n\n // Catches what the try/catch above cannot: throws during React's own render\n // and commit of the tree — react-native-svg internals, reanimated failing\n // to attach to a component that turns out not to be a host view, and so on.\n return (\n <PxRnErrorBoundary fallback={fallback} diag={makeDiag()}>\n {content}\n </PxRnErrorBoundary>\n );\n}\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';\nimport { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/**\n * Sampled animation tracks for ONE element: prop name → per-sample values.\n *\n * The compiler densely samples every animated property through core's\n * `calcAnimationValues` — the exact function the web frames engine renders\n * with — so RN playback is value-identical to the web player. Easing, loops,\n * transform composition, color interpolation and path morphing are all baked\n * into the samples at compile time; the UI-thread worklet only indexes arrays.\n * @internal\n */\nexport interface PxElementTracks {\n /** Element id (after id regeneration). */\n id: string;\n /** react-native-svg prop name → one value per sample. */\n props: Record<string, Array<string | number | Array<number>>>;\n}\n\n/** @internal */\nexport interface PxCompiledTracks {\n /** Per-iteration duration, ms. */\n duration: number;\n /** Iteration count (Infinity for 'infinite'). */\n iterations: number;\n /** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */\n direction: string;\n /** Delay before start, ms (positive = wait). */\n delay: number;\n /** WAAPI-style fill mode (default 'forwards'). */\n fill: string;\n /** When true, snap back to the start after a natural finish. */\n resetOnFinish: boolean;\n /** Sample step, ms. */\n stepMs: number;\n /** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */\n sampleCount: number;\n /** Tracks for every animated element. */\n elements: Array<PxElementTracks>;\n}\n\n/** @internal */\nexport interface CompileTracksOptions {\n /** Target sample rate, samples/second. Default 60 (one per frame). */\n sampleRate?: number;\n /** Hard cap on samples per iteration (memory guard). Default 600. */\n maxSamples?: number;\n /**\n * Sample values in the form the NATIVE react-native-svg views expect\n * (currently: `transform` as a 6-number matrix rather than an SVG string).\n *\n * Defaults to `false` — the plain SVG form, which is what react-native-web\n * hands straight to the DOM. Only the component knows the platform, so it\n * decides; every consumer that does not opt in keeps DOM-compatible values.\n */\n native?: boolean;\n}\n\n\n\n/**\n * Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`\n * + `generateNewIds` first) into densely sampled per-element tracks.\n * @internal\n */\nexport function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {\n const config = getAnimatorConfig(doc) || {};\n\n const duration = +(config.duration || PX_DEFAULT_DURATION_MS);\n const _iterations = config.iterations;\n let iterations = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const native = opts?.native ?? false;\n const sampleRate = opts?.sampleRate ?? 60;\n const maxSamples = opts?.maxSamples ?? 600;\n let sampleCount = Math.max(2, Math.round((duration / 1000) * sampleRate) + 1);\n if (sampleCount > maxSamples) sampleCount = maxSamples;\n const stepMs = duration / (sampleCount - 1);\n\n // Element tag per id — `toRnPropValue` needs it to leave the root `<Svg>`'s\n // transform as a string (see its `tag` parameter).\n const tagById = new Map<string, string>();\n const indexTags = (n: any): void => {\n if (n && typeof n.id === 'string') tagById.set(n.id, String(n.type));\n (n?.children ?? []).forEach(indexTags);\n };\n indexTags(doc);\n\n const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];\n\n const elements: Array<PxElementTracks> = [];\n for (const binding of bindings) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) continue;\n\n const props: Record<string, Array<string | number | Array<number>>> = {};\n for (let i = 0; i < sampleCount; i++) {\n const t = i === sampleCount - 1 ? duration : i * stepMs;\n const values = calcAnimationValues(animDef as PxAnimationDefinition, t);\n for (const [attr, value] of Object.entries(values)) {\n const rnProp = toRnPropName(attr);\n if (!rnProp) continue;\n let arr = props[rnProp];\n if (!arr) {\n arr = props[rnProp] = new Array(sampleCount);\n // A prop can appear late (e.g. attrs whose first kf is\n // beyond t=0) — backfill earlier samples with the first\n // computed value so the array is always fully populated.\n for (let j = 0; j < i; j++) arr[j] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n arr[i] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n }\n // Forward-fill any holes (attr disappeared from a later sample).\n for (const arr of Object.values(props)) {\n for (let i = 1; i < sampleCount; i++) {\n if (arr[i] === undefined) arr[i] = arr[i - 1];\n }\n }\n\n if (Object.keys(props).length > 0) {\n elements.push({ id: binding.id, props });\n }\n }\n\n return {\n duration,\n iterations,\n direction: config.direction || 'normal',\n delay: config.delay || 0,\n fill: config.fill ?? 'forwards',\n resetOnFinish: !!config.resetOnFinish,\n stepMs,\n sampleCount,\n elements,\n };\n}\n\n/**\n * Wire prop → the prop name the NATIVE view actually declares.\n *\n * react-native-svg's JS layer renames some props on the way down: a\n * `transform` (string or matrix) is parsed by `extractProps` and handed to the\n * native component as `matrix` — the Fabric spec has no `transform` prop at\n * all. Values sent through reanimated's animated-props path skip that JS\n * rename, so they must already use the native name or the native view drops\n * them silently. This is ONLY for the animated path; plain React renders still\n * go through the JS layer and must keep the wire name.\n */\nexport const NATIVE_PROP_NAME: Record<string, string> = {\n transform: 'matrix',\n};\n\n/**\n * Worklet-safe sample lookup: returns the per-prop values at time `tMs`\n * (already mapped into a single iteration by the caller). Kept deliberately\n * trivial — runs on the UI thread every frame.\n *\n * `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the\n * reanimated animated-props path of a real device. Props that are applied by\n * re-rendering through React (and therefore still pass through react-native-svg's\n * JS layer), and every value on the web, must keep the wire name.\n * @internal\n */\nexport function sampleProps(\n tracks: PxElementTracks,\n tMs: number,\n stepMs: number,\n sampleCount: number,\n native = false\n): Record<string, string | number | Array<number>> {\n 'worklet';\n const out: Record<string, string | number | Array<number>> = {};\n // Defensive: this runs on the UI thread, where a throw is a hard crash\n // with no React boundary to catch it.\n if (!tracks || !tracks.props || !(stepMs > 0)) return out;\n\n let idx = Math.round(tMs / stepMs);\n if (idx < 0) idx = 0;\n if (idx >= sampleCount) idx = sampleCount - 1;\n for (const key in tracks.props) {\n const values = tracks.props[key];\n if (!values) continue;\n const value = values[idx];\n if (value === undefined) continue;\n const name = native && key === 'transform' ? 'matrix' : key;\n out[name] = value;\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core/internal';\nimport { svgTransformToMatrix } from './PxRnMatrix';\n\n/** Attribute names with a react-native-svg prop equivalent under a\n * different name (not just a casing change). */\nconst ATTR_NAME_OVERRIDES: Record<string, string> = {\n 'xlink:href': 'href',\n};\n\n/** Props react-native-svg does not understand / must not receive. */\nconst DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xlink', 'data-px-meta']);\n\n/**\n * Converts one normalized wire attribute name (camelCase after core's\n * `toDomProps`, or kebab-case raw) to a react-native-svg prop name.\n * Returns undefined for props that must be dropped.\n *\n * Pure (no react-native-svg import) so the track compiler and its tests\n * don't need a React Native environment.\n * @internal\n */\nexport function toRnPropName(attrName: string): string | undefined {\n if (DROPPED_ATTRS.has(attrName)) return undefined;\n const override = ATTR_NAME_OVERRIDES[attrName];\n if (override) return override;\n // react-native-svg uses camelCase props (strokeWidth, fillOpacity, …);\n // core's kebabToCamelCaseWord is a no-op for already-camelCase input.\n return kebabToCamelCaseWord(attrName);\n}\n\n/** Props whose value is a LIST of lengths. react-native-svg's native side\n * expects a number array here (its JS `extractLengthList` splits strings, but\n * values delivered through reanimated's animated-props path bypass that JS\n * extraction and reach the native view directly). */\nconst LENGTH_LIST_PROPS = new Set(['strokeDasharray']);\n\n/**\n * Converts one already-renamed prop value into the shape react-native-svg\n * expects: length-list props become number arrays; numeric strings become\n * numbers; everything else passes through.\n */\nexport function toRnPropValue(\n rnPropName: string,\n value: string | number,\n /** The owning element's tag. The ROOT `<Svg>` handles `transform` through a\n * different code path (`extractTransformSvgView`, which wants a string or\n * an RN style) — a matrix there would be dropped, so leave it alone. */\n tag?: string,\n /** Opt in to the NATIVE representation of a value (see below). Defaults to\n * off, so web keeps the plain SVG/DOM form it has always been given. */\n native = false,\n): string | number | Array<number> {\n // On a device `transform` must arrive as a matrix, not a string: the\n // string→matrix parse happens in JS during render, which reanimated's\n // animated-props path skips entirely. See PxRnMatrix for the full why.\n // On the web the DOM parses the string itself and an array would serialize\n // to a meaningless `transform=\"1,0,0,1,3,4\"`, so it must stay a string.\n if (native && rnPropName === 'transform' && typeof value === 'string' && tag !== 'svg') {\n const m = svgTransformToMatrix(value);\n if (m) return m;\n }\n if (LENGTH_LIST_PROPS.has(rnPropName)) {\n const parts = String(value).trim().replace(/,/g, ' ').split(/\\s+/).map(Number).filter(n => Number.isFinite(n));\n // An odd-length dasharray repeats to become even (SVG spec); rn-svg\n // does this itself for the static path — mirror it so both paths agree.\n return parts.length % 2 === 1 ? parts.concat(parts) : parts;\n }\n if (typeof value === 'number') return value;\n const num = +value;\n return Number.isFinite(num) && String(num) === value ? num : value;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * SVG transform string → 2D affine matrix, in the order react-native-svg's\n * native side expects: `[a, b, c, d, e, f]`, i.e. SVG's own `matrix(…)` order\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n *\n * WHY THIS EXISTS: react-native-svg parses a `transform` STRING into this matrix\n * in JavaScript, inside `extractTransform`, during render. Values delivered\n * through reanimated's `animatedProps` bypass that JS step and reach the native\n * view directly, where a raw string is meaningless — an animated transform\n * simply does nothing. Feeding the matrix instead makes the animated and static\n * paths agree. (On the web the DOM parses the string itself, which is why this\n * only shows up on a device.)\n */\nexport type Mat2D = [number, number, number, number, number, number];\n\nexport const IDENTITY: Mat2D = [1, 0, 0, 1, 0, 0];\n\nconst DEG = Math.PI / 180;\n\n/** `m1 · m2` — apply m2 first, then m1 (same convention as SVG's left-to-right list). */\nfunction multiply(m1: Mat2D, m2: Mat2D): Mat2D {\n const [a1, b1, c1, d1, e1, f1] = m1;\n const [a2, b2, c2, d2, e2, f2] = m2;\n return [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n}\n\n/** Splits `translate(1,2)rotate(45)` into `[['translate',[1,2]], ['rotate',[45]]]`. */\nconst FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\nfunction numbers(raw: string): Array<number> {\n return raw\n .split(/[\\s,]+/)\n .filter(s => s.length > 0)\n .map(Number)\n .filter(n => Number.isFinite(n));\n}\n\n/**\n * Parses an SVG transform list. Returns `undefined` when the string contains no\n * recognizable function, so callers can leave the original value untouched\n * rather than silently replacing it with an identity matrix.\n */\nexport function svgTransformToMatrix(value: string): Mat2D | undefined {\n let m: Mat2D | undefined;\n FN_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = FN_RE.exec(value)) !== null) {\n const fn = match[1].toLowerCase();\n const n = numbers(match[2]);\n let step: Mat2D | undefined;\n\n switch (fn) {\n case 'translate':\n step = [1, 0, 0, 1, n[0] || 0, n[1] || 0];\n break;\n case 'scale': {\n const sx = n[0] ?? 1;\n const sy = n.length > 1 ? n[1] : sx;\n step = [sx, 0, 0, sy, 0, 0];\n break;\n }\n case 'rotate': {\n const rad = (n[0] || 0) * DEG;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n const rot: Mat2D = [cos, sin, -sin, cos, 0, 0];\n if (n.length >= 3) {\n // rotate(a, cx, cy) == translate(cx,cy) rotate(a) translate(-cx,-cy)\n const cx = n[1], cy = n[2];\n step = multiply(multiply([1, 0, 0, 1, cx, cy], rot), [1, 0, 0, 1, -cx, -cy]);\n } else {\n step = rot;\n }\n break;\n }\n case 'skewx':\n step = [1, 0, Math.tan((n[0] || 0) * DEG), 1, 0, 0];\n break;\n case 'skewy':\n step = [1, Math.tan((n[0] || 0) * DEG), 0, 1, 0, 0];\n break;\n case 'matrix':\n if (n.length >= 6) step = [n[0], n[1], n[2], n[3], n[4], n[5]];\n break;\n default:\n step = undefined; // unknown function — ignore it\n }\n\n if (step) m = m ? multiply(m, step) : step;\n }\n\n return m;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';\nimport { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';\nimport { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { RN_SVG_COMPONENTS } from './PxRnTypeMap';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/** @internal */\nexport interface RenderRnNodeOptions {\n /** Collects non-fatal issues (unsupported tags, dropped attrs). */\n warnings?: Array<string>;\n /** `definitions` from the document, used to resolve named `style` presets. */\n defs?: PxDefinitions;\n /**\n * Wraps the created element for animated nodes: receives the resolved\n * component + static props and returns the element to mount (the animator\n * substitutes an Animated component wired to its tracks). Return undefined\n * to keep the plain static element.\n *\n * `key` is handed over SEPARATELY and is deliberately absent from `props`:\n * React 19 warns when a props object containing `key` is spread into JSX,\n * and implementations of this hook do exactly that.\n */\n decorate?: (\n node: PxNode,\n Component: ComponentType<any>,\n props: Record<string, any>,\n children: ReactNode,\n key: string | number | undefined\n ) => ReactElement | undefined;\n}\n\n/**\n * Converts core-normalized wire props into react-native-svg props: RN prop\n * naming, sanitization (same security rules as the web renderer), numeric\n * coercion where possible.\n * @internal\n */\nexport function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {\n const normalized = toDomProps(props);\n const out: Record<string, any> = {};\n for (const key of Object.keys(normalized)) {\n const sanitized = sanitizeAttributeValue(key, normalized[key]);\n if (sanitized === undefined) continue;\n const rnKey = toRnPropName(key);\n if (!rnKey) continue;\n out[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n return out;\n}\n\n/**\n * Renders a (materialized) PxNode tree to react-native-svg elements.\n * Mirrors the web `renderNode` contract: unsupported/dangerous tags are\n * skipped with a warning, never a crash.\n * @internal\n */\nexport function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?: string | number): ReactElement | null {\n if (!node) return null;\n\n const { type, children, style, animate, meta, effects, ...props } = node as any;\n const tag = String(type || 'g');\n\n // ESCAPE KEY (S2): elements whose SVG `type` ATTRIBUTE collides with the reserved\n // `type` node-tag key carry it under `domType` — `feColorMatrix` (matrix/saturate/…),\n // `feTurbulence` (fractalNoise/turbulence), `feFunc*` (identity/table/…).\n // Restore it as a real prop, mirroring the web renderer.\n const domType: string | undefined = props.domType;\n if (domType !== undefined) delete props.domType;\n\n if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {\n opts.warnings?.push('tag blocked (dangerous): ' + tag);\n return null;\n }\n\n const Component = RN_SVG_COMPONENTS[tag];\n if (!Component) {\n opts.warnings?.push('tag not supported in react-native-svg mapping: ' + tag);\n return null;\n }\n\n // NB: `key` is never written into this object — see `decorate` above.\n const rnProps = toRnProps(props, opts.warnings, tag);\n if (domType !== undefined) rnProps.type = domType;\n\n // `node.style` — an inline record of declarations. react-native-svg has no CSS, so\n // they are applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).\n // Explicit attributes on the node win over the style block.\n const resolved = style;\n if (resolved) {\n for (const [k, v] of Object.entries(resolved)) {\n const rnKey = toRnPropName(k);\n if (!rnKey || rnKey in rnProps) continue;\n const sanitized = sanitizeAttributeValue(rnKey, v);\n if (sanitized === undefined) continue;\n rnProps[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n }\n\n // Text content: wire nodes carry it in `textContent` — the one key.\n const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];\n\n let childElements: ReactNode = undefined;\n if (Array.isArray(children) && children.length > 0) {\n childElements = children\n .map((ch: PxNode, i: number) => {\n // One malformed child should cost that child, not the whole tree.\n try {\n return renderRnNode(ch, opts, i);\n } catch (e) {\n opts.warnings?.push('child failed to render: ' + (e instanceof Error ? e.message : String(e)));\n return null;\n }\n })\n .filter(Boolean);\n } else if (textContent !== undefined) {\n childElements = String(textContent);\n }\n\n const decorated = opts.decorate?.(node, Component, rnProps, childElements, key);\n if (decorated !== undefined) return decorated;\n\n // `createElement` takes `key` in its config object — that path does NOT\n // trigger React's JSX-spread warning.\n return createElement(\n Component,\n key !== undefined ? { ...rnProps, key } : rnProps,\n childElements\n );\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n Circle,\n ClipPath,\n Defs,\n Ellipse,\n FeBlend,\n FeColorMatrix,\n FeComponentTransfer,\n FeComposite,\n FeConvolveMatrix,\n FeDiffuseLighting,\n FeDisplacementMap,\n FeDistantLight,\n FeDropShadow,\n FeFlood,\n FeFuncA,\n FeFuncB,\n FeFuncG,\n FeFuncR,\n FeGaussianBlur,\n FeImage,\n FeMerge,\n FeMergeNode,\n FeMorphology,\n FeOffset,\n FePointLight,\n FeSpecularLighting,\n FeSpotLight,\n FeTile,\n FeTurbulence,\n Filter,\n G,\n Image,\n Line,\n LinearGradient,\n Marker,\n Mask,\n Path,\n Pattern,\n Polygon,\n Polyline,\n RadialGradient,\n Rect,\n Stop,\n Svg,\n Symbol as SvgSymbol,\n Text as SvgText,\n TextPath,\n TSpan,\n Use,\n} from 'react-native-svg';\nimport type { ComponentType } from 'react';\n\n/**\n * SVG tag → react-native-svg component. Tags not in this map are skipped at\n * render time (with a warning collected by the renderer) — they go on the\n * feature-gap list rather than crashing the tree.\n *\n * Keys are the wire-format `node.type` values, which follow SVG's own casing\n * (`clipPath`, `feGaussianBlur`, `linearGradient`, …).\n * @internal\n */\nexport const RN_SVG_COMPONENTS: Record<string, ComponentType<any>> = {\n // Root & containers\n svg: Svg,\n g: G,\n defs: Defs,\n symbol: SvgSymbol,\n use: Use,\n\n // Shapes\n rect: Rect,\n circle: Circle,\n ellipse: Ellipse,\n line: Line,\n path: Path,\n polygon: Polygon,\n polyline: Polyline,\n image: Image,\n\n // Text\n text: SvgText,\n tspan: TSpan,\n textPath: TextPath,\n\n // Paint servers & clipping\n linearGradient: LinearGradient,\n radialGradient: RadialGradient,\n stop: Stop,\n pattern: Pattern,\n mask: Mask,\n clipPath: ClipPath,\n marker: Marker,\n\n // Filters — react-native-svg implements the full primitive set.\n // NOTE: filter rendering requires the New Architecture (Fabric) and is\n // newer than the rest of react-native-svg; treat visual parity with the\n // web player as unverified until checked on a device.\n filter: Filter,\n feBlend: FeBlend,\n feColorMatrix: FeColorMatrix,\n feComponentTransfer: FeComponentTransfer,\n feComposite: FeComposite,\n feConvolveMatrix: FeConvolveMatrix,\n feDiffuseLighting: FeDiffuseLighting,\n feDisplacementMap: FeDisplacementMap,\n feDistantLight: FeDistantLight,\n feDropShadow: FeDropShadow,\n feFlood: FeFlood,\n feFuncA: FeFuncA,\n feFuncB: FeFuncB,\n feFuncG: FeFuncG,\n feFuncR: FeFuncR,\n feGaussianBlur: FeGaussianBlur,\n feImage: FeImage,\n feMerge: FeMerge,\n feMergeNode: FeMergeNode,\n feMorphology: FeMorphology,\n feOffset: FeOffset,\n fePointLight: FePointLight,\n feSpecularLighting: FeSpecularLighting,\n feSpotLight: FeSpotLight,\n feTile: FeTile,\n feTurbulence: FeTurbulence,\n};\n\nexport { toRnPropName } from './PxRnPropNames';\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\nimport { PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics } from '@pixodesk/svg-animator-core/internal';\n\n/** @public @advanced */\nexport interface PxRnErrorBoundaryProps {\n children: ReactNode;\n /** Rendered instead of the children once something has thrown. */\n fallback?: (error: Error) => ReactNode;\n /**\n * Where the failure is reported (API review §5, §25.1): `error(internal, …)` with\n * `{ componentStack }` as the detail — so it reaches `onError` like every other failure.\n * Defaults to the console.\n */\n diag?: PxDiagnostics;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Keeps one bad animation from taking down the screen around it.\n *\n * A throw anywhere in the rendered SVG tree — an unsupported prop shape, a\n * react-native-svg internal, a reanimated attachment failure — otherwise\n * unmounts the whole React tree above it. Here it is contained to this one\n * animation, reported through the diagnostics channel, and replaced by `fallback`.\n *\n * NOTE the limit: this catches JavaScript errors only. A crash INSIDE the\n * native renderer (see `openClosedTextPathTargets` for a real example) never\n * reaches JavaScript and cannot be caught here — those have to be avoided\n * rather than handled.\n * @public @advanced\n */\nexport class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override componentDidCatch(error: Error, info: ErrorInfo): void {\n (this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))\n .error(PxDiagnosticKind.internal, error, { componentStack: info?.componentStack ?? undefined });\n }\n\n override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {\n // A new document deserves a fresh attempt — otherwise the boundary\n // would stay latched on the failure for the rest of its life.\n if (this.state.error && prev.children !== this.props.children) {\n this.setState({ error: null });\n }\n }\n\n override render(): ReactNode {\n const { error } = this.state;\n if (error) return this.props.fallback ? this.props.fallback(error) : null;\n return this.props.children;\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { type PxNode } from '@pixodesk/svg-animator-core';\nimport { deepClone, generateUniqueId } from '@pixodesk/svg-animator-core/internal';\n\n/**\n * Workarounds for defects in react-native-svg's NATIVE renderer that would\n * otherwise take the whole app down.\n *\n * These are applied only when the native views are in use — never on the web,\n * where the DOM handles all of this correctly and the document must be left\n * exactly as the core pipeline produced it.\n */\n\n/** True when a path's `d` contains a close-subpath command. */\nfunction isClosedPath(d: unknown): boolean {\n return typeof d === 'string' && /[zZ]/.test(d);\n}\n\n/** Drops close-subpath commands, turning a closed outline into an open one. */\nfunction openPath(d: string): string {\n return d.replace(/[zZ]/g, '').trimEnd();\n}\n\n/** `#foo` → `foo`. Returns undefined for anything that is not a local ref. */\nfunction localRef(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.startsWith('#') ? trimmed.slice(1) : undefined;\n}\n\nfunction forEachNode(node: PxNode | undefined, visit: (n: PxNode, parent?: PxNode) => void, parent?: PxNode): void {\n if (!node) return;\n visit(node, parent);\n for (const child of (node.children ?? [])) forEachNode(child, visit, node);\n}\n\n/**\n * Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.\n *\n * WHY: react-native-svg's native text-on-path layout crashes the app —\n * an uncatchable `NSRangeException` on iOS — for this combination.\n * `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,\n * but for a closed path it sets those bounds to `startOffset … startOffset +\n * pathLength` instead of `0 … pathLength`. Any glyph past the end of the path\n * therefore survives the bounds check and reaches `getPosAndTan`, whose\n * `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths\n * array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is\n * all it takes, and animating `startOffset` guarantees hitting it.\n *\n * Opening the path restores the `0 … pathLength` bounds, so out-of-range\n * glyphs are skipped as intended. The copy is private to the `<textPath>`, so\n * anything else drawing the same path still gets the closed original. For a\n * shape whose ends already meet (a circle, the usual case) the removed segment\n * has zero length and nothing changes visually at all.\n *\n * Returns the document unchanged — the same object — when nothing matches.\n * @internal\n */\nexport function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode {\n // Cheap pre-check: the overwhelming majority of documents have no textPath.\n let hasTextPath = false;\n forEachNode(doc, n => { if (String(n.type) === 'textPath') hasTextPath = true; });\n if (!hasTextPath) return doc;\n\n const result = deepClone(doc);\n\n const byId = new Map<string, PxNode>();\n forEachNode(result, n => {\n const id = (n as any).id;\n if (typeof id === 'string') byId.set(id, n);\n });\n\n /** The copy is a geometry reference, never something to draw — so it goes\n * in `<defs>`, alongside the paths textPath targets normally live in. */\n let defs = (result.children ?? []).find(c => String(c.type) === 'defs');\n const ensureDefs = (): PxNode => {\n if (!defs) {\n defs = { type: 'defs', children: [] } as unknown as PxNode;\n (result.children ??= []).unshift(defs);\n }\n return defs;\n };\n\n /** Original path id → id of the open copy, so N textPaths share one copy. */\n const openCopies = new Map<string, string>();\n\n forEachNode(result, node => {\n if (String(node.type) !== 'textPath') return;\n\n const anyNode = node as any;\n const attr = anyNode.href !== undefined ? 'href' : 'xlink:href';\n const targetId = localRef(anyNode[attr]);\n if (!targetId) return;\n\n const target = byId.get(targetId);\n if (!target || !isClosedPath((target as any).d)) return;\n\n let copyId = openCopies.get(targetId);\n if (!copyId) {\n const copy = deepClone(target) as any;\n copyId = 'px_open_' + generateUniqueId();\n copy.id = copyId;\n copy.d = openPath(String(copy.d));\n // A copy that also carried animation would animate twice; the copy\n // exists purely as a geometry reference for the text.\n delete copy.animate;\n delete copy.effects;\n\n (ensureDefs().children ??= []).push(copy);\n openCopies.set(targetId, copyId);\n warnings?.push(\n 'textPath follows a closed path (#' + targetId + '); using an open copy to ' +\n 'avoid a react-native-svg native crash'\n );\n }\n\n anyNode[attr] = '#' + copyId;\n });\n\n return result;\n}\n"],"mappings":"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","names":["import_svg_animator_core","import_internal","import_react","import_internal","_a","import_svg_animator_core","import_internal","SvgSymbol","SvgText","Component","_a","import_react","import_svg_animator_core","import_internal","import_internal","_a","Component","Animated"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/PixodeskSvgAnimator.tsx","../src/PxRnTracks.ts","../src/PxRnPropNames.ts","../src/PxRnMatrix.ts","../src/PxRnRender.tsx","../src/PxRnTypeMap.ts","../src/PxRnErrorBoundary.tsx","../src/PxRnSafety.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nexport { PixodeskSvgAnimator, default } from './PixodeskSvgAnimator';\nexport type { PixodeskSvgAnimatorProps, RnAnimatorApi } from './PixodeskSvgAnimator';\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PxDiagnosticCode, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';\nimport React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { Dimensions, Platform, Pressable, View } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedReaction,\n Easing,\n runOnJS,\n useAnimatedProps,\n useSharedValue,\n withDelay,\n withRepeat,\n withTiming,\n type SharedValue,\n} from 'react-native-reanimated';\nimport { compileTracks, sampleProps, type PxCompiledTracks, type PxElementTracks } from './PxRnTracks';\nimport { renderRnNode, type RenderRnNodeOptions } from './PxRnRender';\nimport { PxRnErrorBoundary } from './PxRnErrorBoundary';\nimport { openClosedTextPathTargets } from './PxRnSafety';\n\n\n// -- Public types -----------------------------------------------------------\n\n/**\n * The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's\n * name (review §9). It no longer \"mirrors\" the React one by hand: the local copy had already\n * drifted (its `setPlaybackRate` comment lost \"negative plays backwards\"). One definition.\n * @public\n */\nexport type RnAnimatorApi = PxAnimatorHandle;\n\n/**\n * The component's props. The playback override, the control props and the callbacks are core's\n * shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and\n * `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs\n * on this platform is declared here: `fallback`, which has no web counterpart.\n * @public\n */\nexport interface PixodeskSvgAnimatorProps\n extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {\n\n // -- Source ---------------------------------------------------------------\n\n /** The animation document to render. */\n doc: PxAnimatedSvgDocument;\n\n /**\n * Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.\n *\n * `engine` is accepted but ignored here: React Native always uses the `native` (fully\n * flattened) materialization, because react-native-svg has no `<use>` shadow-tree\n * propagation.\n */\n timeline?: PxTimelinePatch | string;\n\n // -- Imperative control ---------------------------------------------------\n\n /**\n * Ref populated with the imperative playback API. Filled in EVERY mode and never picks one\n * (review §1): `autoplay` next to it still autoplays.\n */\n apiRef?: React.RefObject<RnAnimatorApi | null>;\n\n // -- Failure handling -----------------------------------------------------\n // A document that cannot be compiled or rendered is reported through `onError` — the same\n // `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the\n // thrown Error and, when the error boundary caught it, the component stack in `diagnostic.data`.\n // The component renders `fallback` instead of throwing, so one broken animation never\n // takes down the screen around it. Only JavaScript failures reach this — a crash inside\n // react-native-svg's native renderer bypasses JavaScript entirely.\n\n /** Rendered in place of the animation after a failure. Default: nothing. */\n fallback?: (error: Error) => ReactElement | null;\n}\n\n\n// -- Animated element wrapper ------------------------------------------------\n\n/**\n * Whether react-native-svg is backed by NATIVE views here, rather than by the\n * DOM through react-native-web.\n *\n * The two want different things from an animated `transform`: a native view\n * declares a `matrix` prop taking six numbers, while the DOM wants a\n * `transform` attribute holding an SVG string. Getting it wrong is silent —\n * the value is dropped and the element simply never moves — so this single\n * constant decides it once and feeds both the track compiler (value form) and\n * the sampler (prop name). Everything else in the package defaults to the\n * DOM-compatible form.\n */\nconst NATIVE_SVG_VIEWS = Platform.OS !== 'web';\n\nconst animatedComponentCache = new Map<ComponentType<any>, ComponentType<any>>();\n\nfunction getAnimatedComponent(Component: ComponentType<any>): ComponentType<any> {\n let cached = animatedComponentCache.get(Component);\n if (!cached) {\n cached = Animated.createAnimatedComponent(Component as any);\n animatedComponentCache.set(Component, cached);\n }\n return cached;\n}\n\n/** One animated element: static props + UI-thread sampled animated props. */\nfunction AnimatedPxElement({\n Component, staticProps, children, tracks, progress, stepMs, sampleCount,\n}: {\n Component: ComponentType<any>;\n staticProps: Record<string, any>;\n children: ReactNode;\n tracks: PxElementTracks;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n}) {\n const AnimatedComponent = useMemo(() => getAnimatedComponent(Component), [Component]);\n\n // Runs on the UI thread every frame; `sampleProps` is a trivial indexed\n // lookup into the precompiled tracks — no interpolation logic on the hot path.\n const animatedProps = useAnimatedProps(() => {\n // On iOS/Android these values bypass react-native-svg's JS prop layer\n // and land on the native view, which declares `matrix`, not\n // `transform`. The web build keeps the DOM-facing `transform` name.\n return sampleProps(tracks, progress.value, stepMs, sampleCount, NATIVE_SVG_VIEWS);\n }, [tracks, stepMs, sampleCount]);\n\n return (\n <AnimatedComponent {...staticProps} animatedProps={animatedProps}>\n {children}\n </AnimatedComponent>\n );\n}\n\n\n/**\n * react-native-svg elements whose `render()` returns `null`. They carry data for\n * their PARENT (a `<Stop>` is read by the gradient that owns it) rather than\n * producing a native view, so reanimated has nothing to attach to — wrapping one\n * in `Animated.createAnimatedComponent` throws\n * \"Cannot find host instance for this component\".\n */\nconst NON_HOST_TAGS = new Set(['stop', 'feMergeNode']);\n\n/**\n * Definition elements — they describe paint/geometry for something else rather\n * than drawing themselves. Their animated attributes (a gradient's `y1`, a\n * stop's `stop-color`) do not reliably flow through reanimated's animated-props\n * path, so an animated def is rendered by re-sampling from JS instead. There\n * are only ever a handful per document and they change slowly, so the cost is\n * negligible — visual elements still animate entirely on the UI thread.\n */\nconst SAMPLED_DEF_TAGS = new Set(['linearGradient', 'radialGradient', ...NON_HOST_TAGS]);\n\n/** True when this subtree must be driven from JS rather than the UI thread:\n * either the node itself is an animated def, or it owns an animated non-host\n * child (an animated `<Stop>` only re-renders via its parent gradient). */\nfunction needsJsSampling(node: PxNode, trackById: Map<string, PxElementTracks>): boolean {\n const id = (node as any).id;\n if (SAMPLED_DEF_TAGS.has(String(node.type)) && id && trackById.has(id)) return true;\n return (node.children ?? []).some(c => needsJsSampling(c, trackById));\n}\n\n/**\n * Renders a subtree whose animation cannot run on the UI thread (see\n * {@link NON_HOST_TAGS}) by re-rendering it from JS with sampled values.\n *\n * Changing a `<Stop>`'s props does not re-render its parent gradient, so the\n * whole subtree is rebuilt — which is why this wraps the gradient rather than\n * the stop. The reaction itself runs on the UI thread and only crosses to JS\n * when the QUANTISED sample index changes, capping these few elements at\n * ~30fps instead of a JS call every frame.\n */\nfunction SampledSubtree({\n node, trackById, progress, stepMs, sampleCount, renderOpts,\n}: {\n node: PxNode;\n trackById: Map<string, PxElementTracks>;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n renderOpts: RenderRnNodeOptions;\n}) {\n const [idx, setIdx] = useState(0);\n\n useAnimatedReaction(\n () => Math.floor(Math.round(progress.value / stepMs) / 2) * 2, // half-rate\n (next, prev) => {\n if (next !== prev) runOnJS(setIdx)(next);\n },\n [stepMs]\n );\n\n const tMs = Math.min(Math.max(idx, 0), sampleCount - 1) * stepMs;\n\n return renderRnNode(node, {\n ...renderOpts,\n // Sampled values are baked in as PLAIN props — nothing reanimated-driven.\n decorate: (n, Component, staticProps, children, key) => {\n const id = (n as any).id;\n const tracks = id ? trackById.get(id) : undefined;\n if (!tracks) return undefined;\n // Wire prop names, NOT the native ones: these go back through\n // react-native-svg's JS prop layer, which does the renaming itself.\n const sampled = sampleProps(tracks, tMs, stepMs, sampleCount);\n return createElement(Component, { ...staticProps, ...sampled, key }, children);\n },\n });\n}\n\n\n\n/** Overrides that shadow the document's own `animator` config. */\n/** The override subset of the props — core's shared shape, not a local copy (review §9). */\ntype ConfigOverrides = PxPlaybackOverride;\n\ninterface Compiled {\n /** Materialized document, or null when compilation failed. */\n doc: PxAnimatedSvgDocument | null;\n tracks: PxCompiledTracks;\n error: Error | null;\n}\n\n/** Playable-but-empty tracks, so a failed compile still satisfies every hook\n * below it — React forbids skipping hooks on an error path. */\nconst EMPTY_TRACKS: PxCompiledTracks = {\n duration: 1, iterations: 1, direction: 'normal', delay: 0,\n fill: 'forwards', resetOnFinish: false, stepMs: 1, sampleCount: 2, elements: [],\n};\n\n/**\n * Materializes + compiles a document. Extracted from the component so the\n * whole thing sits behind one try/catch, and so it can be tested directly.\n */\nfunction compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {\n const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;\n const warnings = validateNodeEffects(doc as PxNode);\n for (const w of warnings) diag.warn(PxDiagnosticKind.document, PxDiagnosticCode.effectsShape, w);\n // The whole-document boundary diagnostic — see the note in the web player's entry.\n reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');\n\n // The per-instance override, applied to the WIRE document BEFORE anything reads the\n // config — `materializeAllInTree` samples motion paths against `duration`, so a later\n // patch would be read by none of the pipeline. Same call, same rules, on every surface.\n const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });\n if (patch !== undefined || resetTimeline) {\n const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });\n for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.timelineOverrideIgnored, w);\n doc = applied.doc;\n }\n\n // `native` = the FULLY-FLATTENED materialization: effects + loops +\n // sampled motion paths + animated `<use>` inlined into real `<g>`\n // clones + orphaned defs pruned. That last part is why RN must not use\n // the `js` flavor: the frame loop keeps `<use href=\"#animatedTarget\">`\n // live references, which only work because the DOM propagates\n // attribute writes through `<use>` shadow trees. react-native-svg has\n // no such live propagation, so an animated `<use>` would render frozen.\n let prepared = materializeAllInTree(doc, PxTimelineEngine.native);\n\n // Sidestep a react-native-svg NATIVE crash (see PxRnSafety). Guarded on\n // the platform because the DOM renders this case correctly and the web\n // document must stay exactly as the core pipeline produced it.\n if (NATIVE_SVG_VIEWS) {\n prepared = openClosedTextPathTargets(prepared as PxNode) as PxAnimatedSvgDocument;\n }\n\n prepared = generateNewIds(prepared);\n const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });\n return { doc: prepared, tracks, error: null };\n}\n\n\n// -- Main component ----------------------------------------------------------\n\n/**\n * React Native component for rendering and controlling Pixodesk SVG animations.\n *\n * The document is materialized once through the shared core pipeline (effects,\n * loops, motion-path sampling, animated-`<use>` inlining — identical to the\n * web's `native` engine, NOT the frame loop, which keeps `<use>` live), compiled\n * into densely sampled per-element tracks, and\n * played back natively: a single reanimated progress value driven by\n * `withTiming`/`withRepeat` on the UI thread, with per-element worklets\n * indexing the precompiled tracks. No JS-thread frame loop.\n * @public\n */\nexport function PixodeskSvgAnimator({\n doc, timeline, resetTimeline, duration, delay, iterations, startOn,\n // (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)\n autoplay, play, pause, apiRef, progress: progressProp, time,\n onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError,\n}: PixodeskSvgAnimatorProps): ReactElement | null {\n\n // -- Compile the document (once per doc/override change) ------------------\n\n // `timeline` is an object prop: a fresh literal every render would otherwise recompile the\n // whole document (materialize + compile tracks), which is the expensive path. Key on its\n // CONTENT instead — the override is small, the document is not.\n const timelineKey = typeof timeline === 'string' ? timeline : JSON.stringify(timeline ?? null);\n\n\n /**\n * The diagnostics channel, built from the CURRENT props each time (API review §5).\n * Deliberately not hoisted into a wrapper closure: `(m, d) => onWarn?.(m, d)` would always\n * be a function, so the channel would believe a handler exists and the console fallback\n * would never fire for anyone who passed nothing.\n */\n const makeDiag = (): PxDiagnostics => createDiagnostics(\n { onWarn, onError, muteWarn, muteError }, '[PixodeskSvgAnimator]');\n\n const compiled = useMemo((): Compiled => {\n try {\n return compileDocument(\n doc,\n { timeline, resetTimeline, duration, delay, iterations, startOn },\n makeDiag(),\n );\n } catch (e) {\n // A malformed document must not take the host screen down with it. This instance\n // will not play — an ERROR, reported once, here (review §25.1).\n const error = e instanceof Error ? e : new Error(String(e));\n makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnCompileFailed, error);\n return { doc: null, tracks: EMPTY_TRACKS, error };\n }\n // `timeline` is an object prop, so a fresh literal each render would recompile the whole\n // document. Key on its CONTENT — the override is small, unlike the document.\n }, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);\n\n const tracks: PxCompiledTracks = compiled.tracks;\n // The span `progress` 0–1 covers (ONE iteration when endless) — NOT the seek ceiling.\n const totalDuration = progressSpanMs(tracks.duration, tracks.iterations);\n // How far a seek may go: unbounded when endless (review §3).\n const seekCeiling = seekCeilingMs(tracks.duration, tracks.iterations);\n\n // Whole-run time lives on its own clock: `progress` below is deliberately within ONE\n // iteration, and `withRepeat` never reports how many have elapsed, so the run time cannot\n // be read back off it. See `createRunClock`.\n const runClock = useMemo(() => createRunClock(seekCeiling), [seekCeiling]);\n\n // -- Playback state -------------------------------------------------------\n\n // Progress in ms within ONE iteration; iteration repetition/alternation is\n // expressed through withRepeat, so worklets only ever see [0, duration].\n const progress = useSharedValue(0);\n const playingRef = useRef(false);\n const rateRef = useRef(1);\n\n /** True when the current rate plays the timeline backwards. */\n const reversePlayback = () => rateRef.current < 0;\n\n /** Where the playhead rests once playback ends. `resetOnFinish` snaps back\n * to the start; otherwise `fill` decides whether the final frame is held. */\n const restingPosition = () => {\n if (tracks.resetOnFinish) return 0;\n if (tracks.fill === 'none' || tracks.fill === 'backwards') return 0;\n return reversePlayback() ? 0 : tracks.duration;\n };\n\n const notifyFinish = () => {\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n };\n\n const startFrom = (fromMs: number) => {\n const dur = tracks.duration;\n const rate = rateRef.current || 1;\n const backwards = rate < 0;\n const speed = Math.abs(rate);\n // `direction` decides which end a leg runs toward; a negative playback\n // rate flips it again (the two compose, as in the Web Animations API).\n const directionReversed = tracks.direction === 'reverse' || tracks.direction === 'alternate-reverse';\n const reversedStart = backwards ? !directionReversed : directionReversed;\n const alternates = tracks.direction === 'alternate' || tracks.direction === 'alternate-reverse';\n const from = Math.max(0, Math.min(fromMs, dur));\n\n const legTarget = reversedStart ? 0 : dur;\n const legRemaining = Math.abs(legTarget - from) / speed;\n const repeats = tracks.iterations === Infinity ? -1 : tracks.iterations;\n\n cancelAnimation(progress);\n progress.value = reversedStart ? (from <= 0 ? dur : from) : (from >= dur ? 0 : from);\n\n const animation = repeats === 1\n ? withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }, (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n })\n : withRepeat(\n withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }),\n repeats, alternates,\n (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n }\n );\n\n progress.value = tracks.delay > 0 && from === 0\n ? withDelay(tracks.delay / speed, animation)\n : animation;\n\n playingRef.current = true;\n };\n\n const api: RnAnimatorApi = {\n isPlaying: () => playingRef.current,\n play: () => {\n // `startFrom` rewinds to the opposite end when the playhead is\n // already resting at a boundary (mirrors WAAPI, where play() on a\n // finished animation auto-rewinds) — the run clock rewinds with it,\n // or the time would keep counting on from the old end.\n if (Number.isFinite(seekCeiling) && runClock.now() >= seekCeiling) runClock.seek(0);\n runClock.start(rateRef.current);\n startFrom(progress.value);\n onPlay?.();\n },\n pause: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.stop();\n onPause?.();\n onStop?.();\n },\n cancel: () => {\n cancelAnimation(progress);\n progress.value = 0;\n playingRef.current = false;\n runClock.seek(0);\n runClock.stop();\n onCancel?.();\n onStop?.();\n },\n finish: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n },\n setPlaybackRate: (rate: number) => {\n if (!isValidPlaybackRate(rate)) {\n makeDiag().warn(PxDiagnosticKind.usage, PxDiagnosticCode.rateRejected);\n return;\n }\n rateRef.current = rate;\n if (playingRef.current) {\n runClock.start(rate); // resume from the current time at the new rate\n startFrom(progress.value);\n }\n },\n\n // Ms from the start of the WHOLE run, like every other engine (review §3). This used\n // to return `progress.value`, which is ms within the current iteration — so a slider\n // built on it jumped back to 0 every time the animation repeated.\n getCurrentTime: () => runClock.now(),\n\n setCurrentTime: (t: number) => {\n const wasPlaying = playingRef.current;\n cancelAnimation(progress);\n playingRef.current = false;\n // Clamp against the SEEK ceiling, not the progress span — the old clamp capped an\n // endless timeline at one iteration.\n const clamped = clampSeekMs(t, seekCeiling);\n runClock.seek(clamped);\n const withinIteration = tracks.duration > 0\n ? (clamped % tracks.duration) || (clamped === 0 ? 0 : tracks.duration)\n : 0;\n progress.value = withinIteration;\n // Seeking mid-playback continues from the new position rather than\n // silently pausing.\n if (wasPlaying) startFrom(withinIteration);\n else runClock.stop();\n },\n\n getCurrentProgress: () => timeToProgress(runClock.now(), tracks.duration, tracks.iterations),\n\n setCurrentProgress: (p: number) => {\n api.setCurrentTime(progressToTimeMs(p, tracks.duration, tracks.iterations));\n },\n };\n\n useImperativeHandle(apiRef, () => api, [compiled]);\n\n // -- Declarative control --------------------------------------------------\n\n // The EFFECTIVE trigger, read back off the COMPILED document — so it already reflects the\n // `timeline` override and the `startOn` shortcut, both merged in before compilation.\n // Resolved through core's one table, so a document means the same here as on the web:\n // no `startOn` = 'load', no `outAction` = 'continue'.\n const trigger = resolveTrigger(compiled.doc ? getAnimatorConfig(compiled.doc)?.trigger : undefined);\n const effectiveStartOn = trigger.startOn;\n const effectiveOutAction = trigger.outAction;\n\n // ONE control-mode rule, decided in core and shared with React and Vue (API review §1/§7).\n // This component always had the right ORDER but no name for it, and never told anyone when\n // two tiers of props were passed together.\n const { mode: compMode, warnings: modeWarnings } =\n resolveControlMode({ progress: progressProp, time, play, pause, autoplay });\n\n useEffect(() => {\n const diag = makeDiag();\n for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.controlPropsConflict, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modeWarnings.join('|')]);\n\n useEffect(() => {\n if (compMode === PxControlMode.fixedTime) {\n const seekMs = time !== undefined\n ? time\n : progressToTimeMs(progressProp ?? 0, tracks.duration, tracks.iterations);\n api.setCurrentTime(seekMs);\n return;\n }\n if (compMode === PxControlMode.play) {\n if (play && !pause) api.play();\n else if (pause) api.pause();\n else if (play === false) api.pause(); // hold, not finish() — review §8, same as web\n else api.play();\n return;\n }\n // 'click' and 'scrollIntoView' start from their own handlers below.\n if (compMode === PxControlMode.autoplay && effectiveStartOn === 'load') {\n api.play();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, compMode, autoplay, play, pause, progressProp, time]);\n\n // `startOn: 'scrollIntoView'` — react-native has no IntersectionObserver, so\n // visibility is sampled by measuring the view against the window box. The\n // poll is cheap (a native measure every 200ms) and only runs while this\n // trigger is active; `outAction` decides what leaving the viewport does.\n const scrollRef = useRef<View | null>(null);\n const inViewRef = useRef(false);\n useEffect(() => {\n if (!autoplay || effectiveStartOn !== 'scrollIntoView') return;\n const threshold = trigger.scrollIntoViewThreshold;\n inViewRef.current = false;\n\n const check = () => {\n const node = scrollRef.current;\n if (!node) return;\n node.measureInWindow((_x, y, _w, h) => {\n if (!h) return;\n const screen = Dimensions.get('window').height;\n const visible = Math.max(0, Math.min(y + h, screen) - Math.max(y, 0));\n const ratio = visible / h;\n const isIn = ratio > 0 && ratio >= threshold;\n if (isIn === inViewRef.current) return;\n inViewRef.current = isIn;\n if (isIn) {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n } else if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n });\n };\n\n check();\n const id = setInterval(check, 200);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);\n\n // Stop cleanly on unmount / doc swap — and say so, the way the web's destroy() does (§18):\n // both are \"the animator was thrown away\", so `onRemove` fires, and `onStop` with it.\n useEffect(() => {\n return () => {\n cancelAnimation(progress);\n playingRef.current = false;\n onRemove?.();\n onStop?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled]);\n\n // -- Render ---------------------------------------------------------------\n\n const trackById = useMemo(() => {\n const map = new Map<string, PxElementTracks>();\n for (const el of tracks.elements) map.set(el.id, el);\n return map;\n }, [tracks]);\n\n const warningsRef = useRef<Array<string>>([]);\n const renderErrorRef = useRef<Error | null>(null);\n const root = useMemo(() => {\n warningsRef.current = [];\n renderErrorRef.current = null;\n if (!compiled.doc) return null;\n\n const renderOpts: RenderRnNodeOptions = {\n warnings: warningsRef.current,\n defs: getDefinitions(compiled.doc),\n };\n try {\n return renderRnNode(compiled.doc as PxNode, {\n ...renderOpts,\n decorate: (node, Component, staticProps, children, key) => {\n // An animated definition subtree (gradient / its stops) cannot be\n // driven on the UI thread — hand the WHOLE subtree to the\n // JS-sampled renderer and stop descending here.\n if (needsJsSampling(node, trackById)) {\n return (\n <SampledSubtree\n key={key}\n node={node}\n trackById={trackById}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n renderOpts={renderOpts}\n />\n );\n }\n\n const id = (node as any).id;\n const elTracks = id ? trackById.get(id) : undefined;\n if (!elTracks) return undefined;\n return (\n <AnimatedPxElement\n key={key}\n Component={Component}\n staticProps={staticProps}\n tracks={elTracks}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n >\n {children}\n </AnimatedPxElement>\n );\n },\n });\n } catch (e) {\n // Building the element tree threw — this instance will not play: report it once\n // (an ERROR, review §25.1) and render nothing rather than unmount the host screen.\n const error = e instanceof Error ? e : new Error(String(e));\n renderErrorRef.current = error;\n makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnRenderFailed, error);\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, trackById]);\n\n useEffect(() => {\n const diag = makeDiag();\n // `platform`: these come from the react-native-svg prop mapper — shapes this renderer\n // cannot express, rather than anything wrong with the file.\n for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, PxDiagnosticCode.rnUnsupported, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [root]);\n\n // A compile/render failure was reported where it was caught (once, as an error); here it\n // only decides what to show.\n const failure = compiled.error ?? renderErrorRef.current;\n if (failure) return fallback ? fallback(failure) : null;\n\n // `startOn: 'click'` — the touch analogue of the web player's click trigger:\n // tap to start, tap again to apply `outAction`. Hover (`mouseOver`) has no\n // touch equivalent and `scrollIntoView` needs the surrounding scroll view,\n // so both are left to the host app.\n let content: ReactElement | null = root;\n\n if (autoplay && effectiveStartOn === 'scrollIntoView' && root) {\n // `collapsable={false}` keeps the view in the native tree so it can be measured.\n content = <View ref={scrollRef} collapsable={false}>{root}</View>;\n } else if (autoplay && effectiveStartOn === 'click' && root) {\n content = (\n <Pressable\n onPress={() => {\n if (playingRef.current) {\n if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n } else {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n }\n }}\n >\n {root}\n </Pressable>\n );\n }\n\n // Catches what the try/catch above cannot: throws during React's own render\n // and commit of the tree — react-native-svg internals, reanimated failing\n // to attach to a component that turns out not to be a host view, and so on.\n return (\n <PxRnErrorBoundary fallback={fallback} diag={makeDiag()}>\n {content}\n </PxRnErrorBoundary>\n );\n}\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';\nimport { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/**\n * Sampled animation tracks for ONE element: prop name → per-sample values.\n *\n * The compiler densely samples every animated property through core's\n * `calcAnimationValues` — the exact function the web frames engine renders\n * with — so RN playback is value-identical to the web player. Easing, loops,\n * transform composition, color interpolation and path morphing are all baked\n * into the samples at compile time; the UI-thread worklet only indexes arrays.\n * @internal\n */\nexport interface PxElementTracks {\n /** Element id (after id regeneration). */\n id: string;\n /** react-native-svg prop name → one value per sample. */\n props: Record<string, Array<string | number | Array<number>>>;\n}\n\n/** @internal */\nexport interface PxCompiledTracks {\n /** Per-iteration duration, ms. */\n duration: number;\n /** Iteration count (Infinity for 'infinite'). */\n iterations: number;\n /** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */\n direction: string;\n /** Delay before start, ms (positive = wait). */\n delay: number;\n /** WAAPI-style fill mode (default 'forwards'). */\n fill: string;\n /** When true, snap back to the start after a natural finish. */\n resetOnFinish: boolean;\n /** Sample step, ms. */\n stepMs: number;\n /** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */\n sampleCount: number;\n /** Tracks for every animated element. */\n elements: Array<PxElementTracks>;\n}\n\n/** @internal */\nexport interface CompileTracksOptions {\n /** Target sample rate, samples/second. Default 60 (one per frame). */\n sampleRate?: number;\n /** Hard cap on samples per iteration (memory guard). Default 600. */\n maxSamples?: number;\n /**\n * Sample values in the form the NATIVE react-native-svg views expect\n * (currently: `transform` as a 6-number matrix rather than an SVG string).\n *\n * Defaults to `false` — the plain SVG form, which is what react-native-web\n * hands straight to the DOM. Only the component knows the platform, so it\n * decides; every consumer that does not opt in keeps DOM-compatible values.\n */\n native?: boolean;\n}\n\n\n\n/**\n * Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`\n * + `generateNewIds` first) into densely sampled per-element tracks.\n * @internal\n */\nexport function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {\n const config = getAnimatorConfig(doc) || {};\n\n const duration = +(config.duration || PX_DEFAULT_DURATION_MS);\n const _iterations = config.iterations;\n let iterations = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const native = opts?.native ?? false;\n const sampleRate = opts?.sampleRate ?? 60;\n const maxSamples = opts?.maxSamples ?? 600;\n let sampleCount = Math.max(2, Math.round((duration / 1000) * sampleRate) + 1);\n if (sampleCount > maxSamples) sampleCount = maxSamples;\n const stepMs = duration / (sampleCount - 1);\n\n // Element tag per id — `toRnPropValue` needs it to leave the root `<Svg>`'s\n // transform as a string (see its `tag` parameter).\n const tagById = new Map<string, string>();\n const indexTags = (n: any): void => {\n if (n && typeof n.id === 'string') tagById.set(n.id, String(n.type));\n (n?.children ?? []).forEach(indexTags);\n };\n indexTags(doc);\n\n const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];\n\n const elements: Array<PxElementTracks> = [];\n for (const binding of bindings) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) continue;\n\n const props: Record<string, Array<string | number | Array<number>>> = {};\n for (let i = 0; i < sampleCount; i++) {\n const t = i === sampleCount - 1 ? duration : i * stepMs;\n const values = calcAnimationValues(animDef as PxAnimationDefinition, t);\n for (const [attr, value] of Object.entries(values)) {\n const rnProp = toRnPropName(attr);\n if (!rnProp) continue;\n let arr = props[rnProp];\n if (!arr) {\n arr = props[rnProp] = new Array(sampleCount);\n // A prop can appear late (e.g. attrs whose first kf is\n // beyond t=0) — backfill earlier samples with the first\n // computed value so the array is always fully populated.\n for (let j = 0; j < i; j++) arr[j] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n arr[i] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n }\n // Forward-fill any holes (attr disappeared from a later sample).\n for (const arr of Object.values(props)) {\n for (let i = 1; i < sampleCount; i++) {\n if (arr[i] === undefined) arr[i] = arr[i - 1];\n }\n }\n\n if (Object.keys(props).length > 0) {\n elements.push({ id: binding.id, props });\n }\n }\n\n return {\n duration,\n iterations,\n direction: config.direction || 'normal',\n delay: config.delay || 0,\n fill: config.fill ?? 'forwards',\n resetOnFinish: !!config.resetOnFinish,\n stepMs,\n sampleCount,\n elements,\n };\n}\n\n/**\n * Wire prop → the prop name the NATIVE view actually declares.\n *\n * react-native-svg's JS layer renames some props on the way down: a\n * `transform` (string or matrix) is parsed by `extractProps` and handed to the\n * native component as `matrix` — the Fabric spec has no `transform` prop at\n * all. Values sent through reanimated's animated-props path skip that JS\n * rename, so they must already use the native name or the native view drops\n * them silently. This is ONLY for the animated path; plain React renders still\n * go through the JS layer and must keep the wire name.\n */\nexport const NATIVE_PROP_NAME: Record<string, string> = {\n transform: 'matrix',\n};\n\n/**\n * Worklet-safe sample lookup: returns the per-prop values at time `tMs`\n * (already mapped into a single iteration by the caller). Kept deliberately\n * trivial — runs on the UI thread every frame.\n *\n * `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the\n * reanimated animated-props path of a real device. Props that are applied by\n * re-rendering through React (and therefore still pass through react-native-svg's\n * JS layer), and every value on the web, must keep the wire name.\n * @internal\n */\nexport function sampleProps(\n tracks: PxElementTracks,\n tMs: number,\n stepMs: number,\n sampleCount: number,\n native = false\n): Record<string, string | number | Array<number>> {\n 'worklet';\n const out: Record<string, string | number | Array<number>> = {};\n // Defensive: this runs on the UI thread, where a throw is a hard crash\n // with no React boundary to catch it.\n if (!tracks || !tracks.props || !(stepMs > 0)) return out;\n\n let idx = Math.round(tMs / stepMs);\n if (idx < 0) idx = 0;\n if (idx >= sampleCount) idx = sampleCount - 1;\n for (const key in tracks.props) {\n const values = tracks.props[key];\n if (!values) continue;\n const value = values[idx];\n if (value === undefined) continue;\n const name = native && key === 'transform' ? 'matrix' : key;\n out[name] = value;\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core/internal';\nimport { svgTransformToMatrix } from './PxRnMatrix';\n\n/** Attribute names with a react-native-svg prop equivalent under a\n * different name (not just a casing change). */\nconst ATTR_NAME_OVERRIDES: Record<string, string> = {\n 'xlink:href': 'href',\n};\n\n/** Props react-native-svg does not understand / must not receive. */\nconst DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xlink', 'data-px-meta']);\n\n/**\n * Converts one normalized wire attribute name (camelCase after core's\n * `toDomProps`, or kebab-case raw) to a react-native-svg prop name.\n * Returns undefined for props that must be dropped.\n *\n * Pure (no react-native-svg import) so the track compiler and its tests\n * don't need a React Native environment.\n * @internal\n */\nexport function toRnPropName(attrName: string): string | undefined {\n if (DROPPED_ATTRS.has(attrName)) return undefined;\n const override = ATTR_NAME_OVERRIDES[attrName];\n if (override) return override;\n // react-native-svg uses camelCase props (strokeWidth, fillOpacity, …);\n // core's kebabToCamelCaseWord is a no-op for already-camelCase input.\n return kebabToCamelCaseWord(attrName);\n}\n\n/** Props whose value is a LIST of lengths. react-native-svg's native side\n * expects a number array here (its JS `extractLengthList` splits strings, but\n * values delivered through reanimated's animated-props path bypass that JS\n * extraction and reach the native view directly). */\nconst LENGTH_LIST_PROPS = new Set(['strokeDasharray']);\n\n/**\n * Converts one already-renamed prop value into the shape react-native-svg\n * expects: length-list props become number arrays; numeric strings become\n * numbers; everything else passes through.\n */\nexport function toRnPropValue(\n rnPropName: string,\n value: string | number,\n /** The owning element's tag. The ROOT `<Svg>` handles `transform` through a\n * different code path (`extractTransformSvgView`, which wants a string or\n * an RN style) — a matrix there would be dropped, so leave it alone. */\n tag?: string,\n /** Opt in to the NATIVE representation of a value (see below). Defaults to\n * off, so web keeps the plain SVG/DOM form it has always been given. */\n native = false,\n): string | number | Array<number> {\n // On a device `transform` must arrive as a matrix, not a string: the\n // string→matrix parse happens in JS during render, which reanimated's\n // animated-props path skips entirely. See PxRnMatrix for the full why.\n // On the web the DOM parses the string itself and an array would serialize\n // to a meaningless `transform=\"1,0,0,1,3,4\"`, so it must stay a string.\n if (native && rnPropName === 'transform' && typeof value === 'string' && tag !== 'svg') {\n const m = svgTransformToMatrix(value);\n if (m) return m;\n }\n if (LENGTH_LIST_PROPS.has(rnPropName)) {\n const parts = String(value).trim().replace(/,/g, ' ').split(/\\s+/).map(Number).filter(n => Number.isFinite(n));\n // An odd-length dasharray repeats to become even (SVG spec); rn-svg\n // does this itself for the static path — mirror it so both paths agree.\n return parts.length % 2 === 1 ? parts.concat(parts) : parts;\n }\n if (typeof value === 'number') return value;\n const num = +value;\n return Number.isFinite(num) && String(num) === value ? num : value;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * SVG transform string → 2D affine matrix, in the order react-native-svg's\n * native side expects: `[a, b, c, d, e, f]`, i.e. SVG's own `matrix(…)` order\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n *\n * WHY THIS EXISTS: react-native-svg parses a `transform` STRING into this matrix\n * in JavaScript, inside `extractTransform`, during render. Values delivered\n * through reanimated's `animatedProps` bypass that JS step and reach the native\n * view directly, where a raw string is meaningless — an animated transform\n * simply does nothing. Feeding the matrix instead makes the animated and static\n * paths agree. (On the web the DOM parses the string itself, which is why this\n * only shows up on a device.)\n */\nexport type Mat2D = [number, number, number, number, number, number];\n\nexport const IDENTITY: Mat2D = [1, 0, 0, 1, 0, 0];\n\nconst DEG = Math.PI / 180;\n\n/** `m1 · m2` — apply m2 first, then m1 (same convention as SVG's left-to-right list). */\nfunction multiply(m1: Mat2D, m2: Mat2D): Mat2D {\n const [a1, b1, c1, d1, e1, f1] = m1;\n const [a2, b2, c2, d2, e2, f2] = m2;\n return [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n}\n\n/** Splits `translate(1,2)rotate(45)` into `[['translate',[1,2]], ['rotate',[45]]]`. */\nconst FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\nfunction numbers(raw: string): Array<number> {\n return raw\n .split(/[\\s,]+/)\n .filter(s => s.length > 0)\n .map(Number)\n .filter(n => Number.isFinite(n));\n}\n\n/**\n * Parses an SVG transform list. Returns `undefined` when the string contains no\n * recognizable function, so callers can leave the original value untouched\n * rather than silently replacing it with an identity matrix.\n */\nexport function svgTransformToMatrix(value: string): Mat2D | undefined {\n let m: Mat2D | undefined;\n FN_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = FN_RE.exec(value)) !== null) {\n const fn = match[1].toLowerCase();\n const n = numbers(match[2]);\n let step: Mat2D | undefined;\n\n switch (fn) {\n case 'translate':\n step = [1, 0, 0, 1, n[0] || 0, n[1] || 0];\n break;\n case 'scale': {\n const sx = n[0] ?? 1;\n const sy = n.length > 1 ? n[1] : sx;\n step = [sx, 0, 0, sy, 0, 0];\n break;\n }\n case 'rotate': {\n const rad = (n[0] || 0) * DEG;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n const rot: Mat2D = [cos, sin, -sin, cos, 0, 0];\n if (n.length >= 3) {\n // rotate(a, cx, cy) == translate(cx,cy) rotate(a) translate(-cx,-cy)\n const cx = n[1], cy = n[2];\n step = multiply(multiply([1, 0, 0, 1, cx, cy], rot), [1, 0, 0, 1, -cx, -cy]);\n } else {\n step = rot;\n }\n break;\n }\n case 'skewx':\n step = [1, 0, Math.tan((n[0] || 0) * DEG), 1, 0, 0];\n break;\n case 'skewy':\n step = [1, Math.tan((n[0] || 0) * DEG), 0, 1, 0, 0];\n break;\n case 'matrix':\n if (n.length >= 6) step = [n[0], n[1], n[2], n[3], n[4], n[5]];\n break;\n default:\n step = undefined; // unknown function — ignore it\n }\n\n if (step) m = m ? multiply(m, step) : step;\n }\n\n return m;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';\nimport { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';\nimport { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { RN_SVG_COMPONENTS } from './PxRnTypeMap';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/** @internal */\nexport interface RenderRnNodeOptions {\n /** Collects non-fatal issues (unsupported tags, dropped attrs). */\n warnings?: Array<string>;\n /** `definitions` from the document, used to resolve named `style` presets. */\n defs?: PxDefinitions;\n /**\n * Wraps the created element for animated nodes: receives the resolved\n * component + static props and returns the element to mount (the animator\n * substitutes an Animated component wired to its tracks). Return undefined\n * to keep the plain static element.\n *\n * `key` is handed over SEPARATELY and is deliberately absent from `props`:\n * React 19 warns when a props object containing `key` is spread into JSX,\n * and implementations of this hook do exactly that.\n */\n decorate?: (\n node: PxNode,\n Component: ComponentType<any>,\n props: Record<string, any>,\n children: ReactNode,\n key: string | number | undefined\n ) => ReactElement | undefined;\n}\n\n/**\n * Converts core-normalized wire props into react-native-svg props: RN prop\n * naming, sanitization (same security rules as the web renderer), numeric\n * coercion where possible.\n * @internal\n */\nexport function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {\n const normalized = toDomProps(props);\n const out: Record<string, any> = {};\n for (const key of Object.keys(normalized)) {\n const sanitized = sanitizeAttributeValue(key, normalized[key]);\n if (sanitized === undefined) continue;\n const rnKey = toRnPropName(key);\n if (!rnKey) continue;\n out[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n return out;\n}\n\n/**\n * Renders a (materialized) PxNode tree to react-native-svg elements.\n * Mirrors the web `renderNode` contract: unsupported/dangerous tags are\n * skipped with a warning, never a crash.\n * @internal\n */\nexport function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?: string | number): ReactElement | null {\n if (!node) return null;\n\n const { type, children, style, animate, meta, effects, ...props } = node as any;\n const tag = String(type || 'g');\n\n // ESCAPE KEY (S2): elements whose SVG `type` ATTRIBUTE collides with the reserved\n // `type` node-tag key carry it under `domType` — `feColorMatrix` (matrix/saturate/…),\n // `feTurbulence` (fractalNoise/turbulence), `feFunc*` (identity/table/…).\n // Restore it as a real prop, mirroring the web renderer.\n const domType: string | undefined = props.domType;\n if (domType !== undefined) delete props.domType;\n\n if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {\n opts.warnings?.push('tag blocked (dangerous): ' + tag);\n return null;\n }\n\n const Component = RN_SVG_COMPONENTS[tag];\n if (!Component) {\n opts.warnings?.push('tag not supported in react-native-svg mapping: ' + tag);\n return null;\n }\n\n // NB: `key` is never written into this object — see `decorate` above.\n const rnProps = toRnProps(props, opts.warnings, tag);\n if (domType !== undefined) rnProps.type = domType;\n\n // `node.style` — an inline record of declarations. react-native-svg has no CSS, so\n // they are applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).\n // Explicit attributes on the node win over the style block.\n const resolved = style;\n if (resolved) {\n for (const [k, v] of Object.entries(resolved)) {\n const rnKey = toRnPropName(k);\n if (!rnKey || rnKey in rnProps) continue;\n const sanitized = sanitizeAttributeValue(rnKey, v);\n if (sanitized === undefined) continue;\n rnProps[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n }\n\n // Text content: wire nodes carry it in `textContent` — the one key.\n const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];\n\n let childElements: ReactNode = undefined;\n if (Array.isArray(children) && children.length > 0) {\n childElements = children\n .map((ch: PxNode, i: number) => {\n // One malformed child should cost that child, not the whole tree.\n try {\n return renderRnNode(ch, opts, i);\n } catch (e) {\n opts.warnings?.push('child failed to render: ' + (e instanceof Error ? e.message : String(e)));\n return null;\n }\n })\n .filter(Boolean);\n } else if (textContent !== undefined) {\n childElements = String(textContent);\n }\n\n const decorated = opts.decorate?.(node, Component, rnProps, childElements, key);\n if (decorated !== undefined) return decorated;\n\n // `createElement` takes `key` in its config object — that path does NOT\n // trigger React's JSX-spread warning.\n return createElement(\n Component,\n key !== undefined ? { ...rnProps, key } : rnProps,\n childElements\n );\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n Circle,\n ClipPath,\n Defs,\n Ellipse,\n FeBlend,\n FeColorMatrix,\n FeComponentTransfer,\n FeComposite,\n FeConvolveMatrix,\n FeDiffuseLighting,\n FeDisplacementMap,\n FeDistantLight,\n FeDropShadow,\n FeFlood,\n FeFuncA,\n FeFuncB,\n FeFuncG,\n FeFuncR,\n FeGaussianBlur,\n FeImage,\n FeMerge,\n FeMergeNode,\n FeMorphology,\n FeOffset,\n FePointLight,\n FeSpecularLighting,\n FeSpotLight,\n FeTile,\n FeTurbulence,\n Filter,\n G,\n Image,\n Line,\n LinearGradient,\n Marker,\n Mask,\n Path,\n Pattern,\n Polygon,\n Polyline,\n RadialGradient,\n Rect,\n Stop,\n Svg,\n Symbol as SvgSymbol,\n Text as SvgText,\n TextPath,\n TSpan,\n Use,\n} from 'react-native-svg';\nimport type { ComponentType } from 'react';\n\n/**\n * SVG tag → react-native-svg component. Tags not in this map are skipped at\n * render time (with a warning collected by the renderer) — they go on the\n * feature-gap list rather than crashing the tree.\n *\n * Keys are the wire-format `node.type` values, which follow SVG's own casing\n * (`clipPath`, `feGaussianBlur`, `linearGradient`, …).\n * @internal\n */\nexport const RN_SVG_COMPONENTS: Record<string, ComponentType<any>> = {\n // Root & containers\n svg: Svg,\n g: G,\n defs: Defs,\n symbol: SvgSymbol,\n use: Use,\n\n // Shapes\n rect: Rect,\n circle: Circle,\n ellipse: Ellipse,\n line: Line,\n path: Path,\n polygon: Polygon,\n polyline: Polyline,\n image: Image,\n\n // Text\n text: SvgText,\n tspan: TSpan,\n textPath: TextPath,\n\n // Paint servers & clipping\n linearGradient: LinearGradient,\n radialGradient: RadialGradient,\n stop: Stop,\n pattern: Pattern,\n mask: Mask,\n clipPath: ClipPath,\n marker: Marker,\n\n // Filters — react-native-svg implements the full primitive set.\n // NOTE: filter rendering requires the New Architecture (Fabric) and is\n // newer than the rest of react-native-svg; treat visual parity with the\n // web player as unverified until checked on a device.\n filter: Filter,\n feBlend: FeBlend,\n feColorMatrix: FeColorMatrix,\n feComponentTransfer: FeComponentTransfer,\n feComposite: FeComposite,\n feConvolveMatrix: FeConvolveMatrix,\n feDiffuseLighting: FeDiffuseLighting,\n feDisplacementMap: FeDisplacementMap,\n feDistantLight: FeDistantLight,\n feDropShadow: FeDropShadow,\n feFlood: FeFlood,\n feFuncA: FeFuncA,\n feFuncB: FeFuncB,\n feFuncG: FeFuncG,\n feFuncR: FeFuncR,\n feGaussianBlur: FeGaussianBlur,\n feImage: FeImage,\n feMerge: FeMerge,\n feMergeNode: FeMergeNode,\n feMorphology: FeMorphology,\n feOffset: FeOffset,\n fePointLight: FePointLight,\n feSpecularLighting: FeSpecularLighting,\n feSpotLight: FeSpotLight,\n feTile: FeTile,\n feTurbulence: FeTurbulence,\n};\n\nexport { toRnPropName } from './PxRnPropNames';\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\nimport { PxDiagnosticCode, PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics } from '@pixodesk/svg-animator-core/internal';\n\n/** @public @advanced */\nexport interface PxRnErrorBoundaryProps {\n children: ReactNode;\n /** Rendered instead of the children once something has thrown. */\n fallback?: (error: Error) => ReactNode;\n /**\n * Where the failure is reported (API review §5, §25.1): `error(internal, …)` with\n * the component stack passed as data — so it reaches `onError` like every other failure.\n * Defaults to the console.\n */\n diag?: PxDiagnostics;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Keeps one bad animation from taking down the screen around it.\n *\n * A throw anywhere in the rendered SVG tree — an unsupported prop shape, a\n * react-native-svg internal, a reanimated attachment failure — otherwise\n * unmounts the whole React tree above it. Here it is contained to this one\n * animation, reported through the diagnostics channel, and replaced by `fallback`.\n *\n * NOTE the limit: this catches JavaScript errors only. A crash INSIDE the\n * native renderer (see `openClosedTextPathTargets` for a real example) never\n * reaches JavaScript and cannot be caught here — those have to be avoided\n * rather than handled.\n * @public @advanced\n */\nexport class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override componentDidCatch(error: Error, info: ErrorInfo): void {\n (this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))\n .error(PxDiagnosticKind.internal, PxDiagnosticCode.rnBoundaryCaught, error, info?.componentStack ?? undefined);\n }\n\n override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {\n // A new document deserves a fresh attempt — otherwise the boundary\n // would stay latched on the failure for the rest of its life.\n if (this.state.error && prev.children !== this.props.children) {\n this.setState({ error: null });\n }\n }\n\n override render(): ReactNode {\n const { error } = this.state;\n if (error) return this.props.fallback ? this.props.fallback(error) : null;\n return this.props.children;\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { type PxNode } from '@pixodesk/svg-animator-core';\nimport { deepClone, generateUniqueId } from '@pixodesk/svg-animator-core/internal';\n\n/**\n * Workarounds for defects in react-native-svg's NATIVE renderer that would\n * otherwise take the whole app down.\n *\n * These are applied only when the native views are in use — never on the web,\n * where the DOM handles all of this correctly and the document must be left\n * exactly as the core pipeline produced it.\n */\n\n/** True when a path's `d` contains a close-subpath command. */\nfunction isClosedPath(d: unknown): boolean {\n return typeof d === 'string' && /[zZ]/.test(d);\n}\n\n/** Drops close-subpath commands, turning a closed outline into an open one. */\nfunction openPath(d: string): string {\n return d.replace(/[zZ]/g, '').trimEnd();\n}\n\n/** `#foo` → `foo`. Returns undefined for anything that is not a local ref. */\nfunction localRef(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.startsWith('#') ? trimmed.slice(1) : undefined;\n}\n\nfunction forEachNode(node: PxNode | undefined, visit: (n: PxNode, parent?: PxNode) => void, parent?: PxNode): void {\n if (!node) return;\n visit(node, parent);\n for (const child of (node.children ?? [])) forEachNode(child, visit, node);\n}\n\n/**\n * Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.\n *\n * WHY: react-native-svg's native text-on-path layout crashes the app —\n * an uncatchable `NSRangeException` on iOS — for this combination.\n * `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,\n * but for a closed path it sets those bounds to `startOffset … startOffset +\n * pathLength` instead of `0 … pathLength`. Any glyph past the end of the path\n * therefore survives the bounds check and reaches `getPosAndTan`, whose\n * `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths\n * array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is\n * all it takes, and animating `startOffset` guarantees hitting it.\n *\n * Opening the path restores the `0 … pathLength` bounds, so out-of-range\n * glyphs are skipped as intended. The copy is private to the `<textPath>`, so\n * anything else drawing the same path still gets the closed original. For a\n * shape whose ends already meet (a circle, the usual case) the removed segment\n * has zero length and nothing changes visually at all.\n *\n * Returns the document unchanged — the same object — when nothing matches.\n * @internal\n */\nexport function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode {\n // Cheap pre-check: the overwhelming majority of documents have no textPath.\n let hasTextPath = false;\n forEachNode(doc, n => { if (String(n.type) === 'textPath') hasTextPath = true; });\n if (!hasTextPath) return doc;\n\n const result = deepClone(doc);\n\n const byId = new Map<string, PxNode>();\n forEachNode(result, n => {\n const id = (n as any).id;\n if (typeof id === 'string') byId.set(id, n);\n });\n\n /** The copy is a geometry reference, never something to draw — so it goes\n * in `<defs>`, alongside the paths textPath targets normally live in. */\n let defs = (result.children ?? []).find(c => String(c.type) === 'defs');\n const ensureDefs = (): PxNode => {\n if (!defs) {\n defs = { type: 'defs', children: [] } as unknown as PxNode;\n (result.children ??= []).unshift(defs);\n }\n return defs;\n };\n\n /** Original path id → id of the open copy, so N textPaths share one copy. */\n const openCopies = new Map<string, string>();\n\n forEachNode(result, node => {\n if (String(node.type) !== 'textPath') return;\n\n const anyNode = node as any;\n const attr = anyNode.href !== undefined ? 'href' : 'xlink:href';\n const targetId = localRef(anyNode[attr]);\n if (!targetId) return;\n\n const target = byId.get(targetId);\n if (!target || !isClosedPath((target as any).d)) return;\n\n let copyId = openCopies.get(targetId);\n if (!copyId) {\n const copy = deepClone(target) as any;\n copyId = 'px_open_' + generateUniqueId();\n copy.id = copyId;\n copy.d = openPath(String(copy.d));\n // A copy that also carried animation would animate twice; the copy\n // exists purely as a geometry reference for the text.\n delete copy.animate;\n delete copy.effects;\n\n (ensureDefs().children ??= []).push(copy);\n openCopies.set(targetId, copyId);\n warnings?.push(\n 'textPath follows a closed path (#' + targetId + '); using an open copy to ' +\n 'avoid a react-native-svg native crash'\n );\n }\n\n anyNode[attr] = '#' + copyId;\n });\n\n return result;\n}\n"],"mappings":"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","names":["import_svg_animator_core","import_internal","import_react","import_internal","_a","import_svg_animator_core","import_internal","SvgSymbol","SvgText","Component","_a","import_react","import_svg_animator_core","import_internal","import_internal","_a","Component","Animated"]}
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// src/PixodeskSvgAnimator.tsx
|
|
34
|
-
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs,
|
|
34
|
+
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PxDiagnosticCode as PxDiagnosticCode2, PxDiagnosticKind as PxDiagnosticKind2, seekCeilingMs, timeToProgress, generateNewIds, getAnimatorConfig as getAnimatorConfig2, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine as PxTimelineEngine2, PxControlMode, resolveControlMode, applyAnimatorConfig, foldTimelineOverride } from "@pixodesk/svg-animator-core";
|
|
35
35
|
import { createDiagnostics as createDiagnostics2, reportDocumentDiagnostics } from "@pixodesk/svg-animator-core/internal";
|
|
36
36
|
import { createElement as createElement2, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
37
37
|
import { Dimensions, Platform, Pressable, View } from "react-native";
|
|
@@ -412,7 +412,7 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
412
412
|
|
|
413
413
|
// src/PxRnErrorBoundary.tsx
|
|
414
414
|
import { Component } from "react";
|
|
415
|
-
import { PxDiagnosticKind } from "@pixodesk/svg-animator-core";
|
|
415
|
+
import { PxDiagnosticCode, PxDiagnosticKind } from "@pixodesk/svg-animator-core";
|
|
416
416
|
import { createDiagnostics } from "@pixodesk/svg-animator-core/internal";
|
|
417
417
|
var PxRnErrorBoundary = class extends Component {
|
|
418
418
|
constructor() {
|
|
@@ -424,7 +424,7 @@ var PxRnErrorBoundary = class extends Component {
|
|
|
424
424
|
}
|
|
425
425
|
componentDidCatch(error, info) {
|
|
426
426
|
var _a, _b;
|
|
427
|
-
((_a = this.props.diag) != null ? _a : createDiagnostics(void 0, "[PixodeskSvgAnimator]")).error(PxDiagnosticKind.internal, error,
|
|
427
|
+
((_a = this.props.diag) != null ? _a : createDiagnostics(void 0, "[PixodeskSvgAnimator]")).error(PxDiagnosticKind.internal, PxDiagnosticCode.rnBoundaryCaught, error, (_b = info == null ? void 0 : info.componentStack) != null ? _b : void 0);
|
|
428
428
|
}
|
|
429
429
|
componentDidUpdate(prev) {
|
|
430
430
|
if (this.state.error && prev.children !== this.props.children) {
|
|
@@ -586,12 +586,12 @@ var EMPTY_TRACKS = {
|
|
|
586
586
|
function compileDocument(doc, overrides, diag) {
|
|
587
587
|
const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
|
|
588
588
|
const warnings = validateNodeEffects(doc);
|
|
589
|
-
for (const w of warnings) diag.warn(PxDiagnosticKind2.document,
|
|
589
|
+
for (const w of warnings) diag.warn(PxDiagnosticKind2.document, PxDiagnosticCode2.effectsShape, w);
|
|
590
590
|
reportDocumentDiagnostics(doc, "[PixodeskSvgAnimator]");
|
|
591
591
|
const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
|
|
592
592
|
if (patch !== void 0 || resetTimeline) {
|
|
593
593
|
const applied = applyAnimatorConfig(doc, patch != null ? patch : {}, { resetTimeline: !!resetTimeline });
|
|
594
|
-
for (const w of applied.warnings) diag.warn(PxDiagnosticKind2.usage,
|
|
594
|
+
for (const w of applied.warnings) diag.warn(PxDiagnosticKind2.usage, PxDiagnosticCode2.timelineOverrideIgnored, w);
|
|
595
595
|
doc = applied.doc;
|
|
596
596
|
}
|
|
597
597
|
let prepared = materializeAllInTree(doc, PxTimelineEngine2.native);
|
|
@@ -644,7 +644,7 @@ function PixodeskSvgAnimator({
|
|
|
644
644
|
);
|
|
645
645
|
} catch (e) {
|
|
646
646
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
647
|
-
makeDiag().error(PxDiagnosticKind2.internal,
|
|
647
|
+
makeDiag().error(PxDiagnosticKind2.internal, PxDiagnosticCode2.rnCompileFailed, error);
|
|
648
648
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
649
649
|
}
|
|
650
650
|
}, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);
|
|
@@ -733,7 +733,7 @@ function PixodeskSvgAnimator({
|
|
|
733
733
|
},
|
|
734
734
|
setPlaybackRate: (rate) => {
|
|
735
735
|
if (!isValidPlaybackRate(rate)) {
|
|
736
|
-
makeDiag().warn(PxDiagnosticKind2.usage,
|
|
736
|
+
makeDiag().warn(PxDiagnosticKind2.usage, PxDiagnosticCode2.rateRejected);
|
|
737
737
|
return;
|
|
738
738
|
}
|
|
739
739
|
rateRef.current = rate;
|
|
@@ -769,7 +769,7 @@ function PixodeskSvgAnimator({
|
|
|
769
769
|
const { mode: compMode, warnings: modeWarnings } = resolveControlMode({ progress: progressProp, time, play, pause, autoplay });
|
|
770
770
|
useEffect(() => {
|
|
771
771
|
const diag = makeDiag();
|
|
772
|
-
for (const w of modeWarnings) diag.warn(PxDiagnosticKind2.usage, w);
|
|
772
|
+
for (const w of modeWarnings) diag.warn(PxDiagnosticKind2.usage, PxDiagnosticCode2.controlPropsConflict, w);
|
|
773
773
|
}, [modeWarnings.join("|")]);
|
|
774
774
|
useEffect(() => {
|
|
775
775
|
if (compMode === PxControlMode.fixedTime) {
|
|
@@ -880,13 +880,13 @@ function PixodeskSvgAnimator({
|
|
|
880
880
|
} catch (e) {
|
|
881
881
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
882
882
|
renderErrorRef.current = error;
|
|
883
|
-
makeDiag().error(PxDiagnosticKind2.internal,
|
|
883
|
+
makeDiag().error(PxDiagnosticKind2.internal, PxDiagnosticCode2.rnRenderFailed, error);
|
|
884
884
|
return null;
|
|
885
885
|
}
|
|
886
886
|
}, [compiled, trackById]);
|
|
887
887
|
useEffect(() => {
|
|
888
888
|
const diag = makeDiag();
|
|
889
|
-
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind2.platform, w);
|
|
889
|
+
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind2.platform, PxDiagnosticCode2.rnUnsupported, w);
|
|
890
890
|
}, [root]);
|
|
891
891
|
const failure = (_b = compiled.error) != null ? _b : renderErrorRef.current;
|
|
892
892
|
if (failure) return fallback ? fallback(failure) : null;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/PixodeskSvgAnimator.tsx","../src/PxRnTracks.ts","../src/PxRnPropNames.ts","../src/PxRnMatrix.ts","../src/PxRnRender.tsx","../src/PxRnTypeMap.ts","../src/PxRnErrorBoundary.tsx","../src/PxRnSafety.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PX_RATE_REJECTED, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';\nimport React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { Dimensions, Platform, Pressable, View } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedReaction,\n Easing,\n runOnJS,\n useAnimatedProps,\n useSharedValue,\n withDelay,\n withRepeat,\n withTiming,\n type SharedValue,\n} from 'react-native-reanimated';\nimport { compileTracks, sampleProps, type PxCompiledTracks, type PxElementTracks } from './PxRnTracks';\nimport { renderRnNode, type RenderRnNodeOptions } from './PxRnRender';\nimport { PxRnErrorBoundary } from './PxRnErrorBoundary';\nimport { openClosedTextPathTargets } from './PxRnSafety';\n\n\n// -- Public types -----------------------------------------------------------\n\n/**\n * The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's\n * name (review §9). It no longer \"mirrors\" the React one by hand: the local copy had already\n * drifted (its `setPlaybackRate` comment lost \"negative plays backwards\"). One definition.\n * @public\n */\nexport type RnAnimatorApi = PxAnimatorHandle;\n\n/**\n * The component's props. The playback override, the control props and the callbacks are core's\n * shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and\n * `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs\n * on this platform is declared here: `fallback`, which has no web counterpart.\n * @public\n */\nexport interface PixodeskSvgAnimatorProps\n extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {\n\n // -- Source ---------------------------------------------------------------\n\n /** The animation document to render. */\n doc: PxAnimatedSvgDocument;\n\n /**\n * Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.\n *\n * `engine` is accepted but ignored here: React Native always uses the `native` (fully\n * flattened) materialization, because react-native-svg has no `<use>` shadow-tree\n * propagation.\n */\n timeline?: PxTimelinePatch | string;\n\n // -- Imperative control ---------------------------------------------------\n\n /**\n * Ref populated with the imperative playback API. Filled in EVERY mode and never picks one\n * (review §1): `autoplay` next to it still autoplays.\n */\n apiRef?: React.RefObject<RnAnimatorApi | null>;\n\n // -- Failure handling -----------------------------------------------------\n // A document that cannot be compiled or rendered is reported through `onError` — the same\n // `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the\n // thrown Error and, when the error boundary caught it, `diagnostic.detail.componentStack`.\n // The component renders `fallback` instead of throwing, so one broken animation never\n // takes down the screen around it. Only JavaScript failures reach this — a crash inside\n // react-native-svg's native renderer bypasses JavaScript entirely.\n\n /** Rendered in place of the animation after a failure. Default: nothing. */\n fallback?: (error: Error) => ReactElement | null;\n}\n\n\n// -- Animated element wrapper ------------------------------------------------\n\n/**\n * Whether react-native-svg is backed by NATIVE views here, rather than by the\n * DOM through react-native-web.\n *\n * The two want different things from an animated `transform`: a native view\n * declares a `matrix` prop taking six numbers, while the DOM wants a\n * `transform` attribute holding an SVG string. Getting it wrong is silent —\n * the value is dropped and the element simply never moves — so this single\n * constant decides it once and feeds both the track compiler (value form) and\n * the sampler (prop name). Everything else in the package defaults to the\n * DOM-compatible form.\n */\nconst NATIVE_SVG_VIEWS = Platform.OS !== 'web';\n\nconst animatedComponentCache = new Map<ComponentType<any>, ComponentType<any>>();\n\nfunction getAnimatedComponent(Component: ComponentType<any>): ComponentType<any> {\n let cached = animatedComponentCache.get(Component);\n if (!cached) {\n cached = Animated.createAnimatedComponent(Component as any);\n animatedComponentCache.set(Component, cached);\n }\n return cached;\n}\n\n/** One animated element: static props + UI-thread sampled animated props. */\nfunction AnimatedPxElement({\n Component, staticProps, children, tracks, progress, stepMs, sampleCount,\n}: {\n Component: ComponentType<any>;\n staticProps: Record<string, any>;\n children: ReactNode;\n tracks: PxElementTracks;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n}) {\n const AnimatedComponent = useMemo(() => getAnimatedComponent(Component), [Component]);\n\n // Runs on the UI thread every frame; `sampleProps` is a trivial indexed\n // lookup into the precompiled tracks — no interpolation logic on the hot path.\n const animatedProps = useAnimatedProps(() => {\n // On iOS/Android these values bypass react-native-svg's JS prop layer\n // and land on the native view, which declares `matrix`, not\n // `transform`. The web build keeps the DOM-facing `transform` name.\n return sampleProps(tracks, progress.value, stepMs, sampleCount, NATIVE_SVG_VIEWS);\n }, [tracks, stepMs, sampleCount]);\n\n return (\n <AnimatedComponent {...staticProps} animatedProps={animatedProps}>\n {children}\n </AnimatedComponent>\n );\n}\n\n\n/**\n * react-native-svg elements whose `render()` returns `null`. They carry data for\n * their PARENT (a `<Stop>` is read by the gradient that owns it) rather than\n * producing a native view, so reanimated has nothing to attach to — wrapping one\n * in `Animated.createAnimatedComponent` throws\n * \"Cannot find host instance for this component\".\n */\nconst NON_HOST_TAGS = new Set(['stop', 'feMergeNode']);\n\n/**\n * Definition elements — they describe paint/geometry for something else rather\n * than drawing themselves. Their animated attributes (a gradient's `y1`, a\n * stop's `stop-color`) do not reliably flow through reanimated's animated-props\n * path, so an animated def is rendered by re-sampling from JS instead. There\n * are only ever a handful per document and they change slowly, so the cost is\n * negligible — visual elements still animate entirely on the UI thread.\n */\nconst SAMPLED_DEF_TAGS = new Set(['linearGradient', 'radialGradient', ...NON_HOST_TAGS]);\n\n/** True when this subtree must be driven from JS rather than the UI thread:\n * either the node itself is an animated def, or it owns an animated non-host\n * child (an animated `<Stop>` only re-renders via its parent gradient). */\nfunction needsJsSampling(node: PxNode, trackById: Map<string, PxElementTracks>): boolean {\n const id = (node as any).id;\n if (SAMPLED_DEF_TAGS.has(String(node.type)) && id && trackById.has(id)) return true;\n return (node.children ?? []).some(c => needsJsSampling(c, trackById));\n}\n\n/**\n * Renders a subtree whose animation cannot run on the UI thread (see\n * {@link NON_HOST_TAGS}) by re-rendering it from JS with sampled values.\n *\n * Changing a `<Stop>`'s props does not re-render its parent gradient, so the\n * whole subtree is rebuilt — which is why this wraps the gradient rather than\n * the stop. The reaction itself runs on the UI thread and only crosses to JS\n * when the QUANTISED sample index changes, capping these few elements at\n * ~30fps instead of a JS call every frame.\n */\nfunction SampledSubtree({\n node, trackById, progress, stepMs, sampleCount, renderOpts,\n}: {\n node: PxNode;\n trackById: Map<string, PxElementTracks>;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n renderOpts: RenderRnNodeOptions;\n}) {\n const [idx, setIdx] = useState(0);\n\n useAnimatedReaction(\n () => Math.floor(Math.round(progress.value / stepMs) / 2) * 2, // half-rate\n (next, prev) => {\n if (next !== prev) runOnJS(setIdx)(next);\n },\n [stepMs]\n );\n\n const tMs = Math.min(Math.max(idx, 0), sampleCount - 1) * stepMs;\n\n return renderRnNode(node, {\n ...renderOpts,\n // Sampled values are baked in as PLAIN props — nothing reanimated-driven.\n decorate: (n, Component, staticProps, children, key) => {\n const id = (n as any).id;\n const tracks = id ? trackById.get(id) : undefined;\n if (!tracks) return undefined;\n // Wire prop names, NOT the native ones: these go back through\n // react-native-svg's JS prop layer, which does the renaming itself.\n const sampled = sampleProps(tracks, tMs, stepMs, sampleCount);\n return createElement(Component, { ...staticProps, ...sampled, key }, children);\n },\n });\n}\n\n\n\n/** Overrides that shadow the document's own `animator` config. */\n/** The override subset of the props — core's shared shape, not a local copy (review §9). */\ntype ConfigOverrides = PxPlaybackOverride;\n\ninterface Compiled {\n /** Materialized document, or null when compilation failed. */\n doc: PxAnimatedSvgDocument | null;\n tracks: PxCompiledTracks;\n error: Error | null;\n}\n\n/** Playable-but-empty tracks, so a failed compile still satisfies every hook\n * below it — React forbids skipping hooks on an error path. */\nconst EMPTY_TRACKS: PxCompiledTracks = {\n duration: 1, iterations: 1, direction: 'normal', delay: 0,\n fill: 'forwards', resetOnFinish: false, stepMs: 1, sampleCount: 2, elements: [],\n};\n\n/**\n * Materializes + compiles a document. Extracted from the component so the\n * whole thing sits behind one try/catch, and so it can be tested directly.\n */\nfunction compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {\n const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;\n const warnings = validateNodeEffects(doc as PxNode);\n for (const w of warnings) diag.warn(PxDiagnosticKind.document, 'effects shape: ' + w);\n // The whole-document boundary diagnostic — see the note in the web player's entry.\n reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');\n\n // The per-instance override, applied to the WIRE document BEFORE anything reads the\n // config — `materializeAllInTree` samples motion paths against `duration`, so a later\n // patch would be read by none of the pipeline. Same call, same rules, on every surface.\n const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });\n if (patch !== undefined || resetTimeline) {\n const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });\n for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, 'timeline override: ' + w);\n doc = applied.doc;\n }\n\n // `native` = the FULLY-FLATTENED materialization: effects + loops +\n // sampled motion paths + animated `<use>` inlined into real `<g>`\n // clones + orphaned defs pruned. That last part is why RN must not use\n // the `js` flavor: the frame loop keeps `<use href=\"#animatedTarget\">`\n // live references, which only work because the DOM propagates\n // attribute writes through `<use>` shadow trees. react-native-svg has\n // no such live propagation, so an animated `<use>` would render frozen.\n let prepared = materializeAllInTree(doc, PxTimelineEngine.native);\n\n // Sidestep a react-native-svg NATIVE crash (see PxRnSafety). Guarded on\n // the platform because the DOM renders this case correctly and the web\n // document must stay exactly as the core pipeline produced it.\n if (NATIVE_SVG_VIEWS) {\n prepared = openClosedTextPathTargets(prepared as PxNode) as PxAnimatedSvgDocument;\n }\n\n prepared = generateNewIds(prepared);\n const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });\n return { doc: prepared, tracks, error: null };\n}\n\n\n// -- Main component ----------------------------------------------------------\n\n/**\n * React Native component for rendering and controlling Pixodesk SVG animations.\n *\n * The document is materialized once through the shared core pipeline (effects,\n * loops, motion-path sampling, animated-`<use>` inlining — identical to the\n * web's `native` engine, NOT the frame loop, which keeps `<use>` live), compiled\n * into densely sampled per-element tracks, and\n * played back natively: a single reanimated progress value driven by\n * `withTiming`/`withRepeat` on the UI thread, with per-element worklets\n * indexing the precompiled tracks. No JS-thread frame loop.\n * @public\n */\nexport function PixodeskSvgAnimator({\n doc, timeline, resetTimeline, duration, delay, iterations, startOn,\n // (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)\n autoplay, play, pause, apiRef, progress: progressProp, time,\n onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError,\n}: PixodeskSvgAnimatorProps): ReactElement | null {\n\n // -- Compile the document (once per doc/override change) ------------------\n\n // `timeline` is an object prop: a fresh literal every render would otherwise recompile the\n // whole document (materialize + compile tracks), which is the expensive path. Key on its\n // CONTENT instead — the override is small, the document is not.\n const timelineKey = typeof timeline === 'string' ? timeline : JSON.stringify(timeline ?? null);\n\n\n /**\n * The diagnostics channel, built from the CURRENT props each time (API review §5).\n * Deliberately not hoisted into a wrapper closure: `(m, d) => onWarn?.(m, d)` would always\n * be a function, so the channel would believe a handler exists and the console fallback\n * would never fire for anyone who passed nothing.\n */\n const makeDiag = (): PxDiagnostics => createDiagnostics(\n { onWarn, onError, muteWarn, muteError }, '[PixodeskSvgAnimator]');\n\n const compiled = useMemo((): Compiled => {\n try {\n return compileDocument(\n doc,\n { timeline, resetTimeline, duration, delay, iterations, startOn },\n makeDiag(),\n );\n } catch (e) {\n // A malformed document must not take the host screen down with it. This instance\n // will not play — an ERROR, reported once, here (review §25.1).\n const error = e instanceof Error ? e : new Error(String(e));\n makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'compile' });\n return { doc: null, tracks: EMPTY_TRACKS, error };\n }\n // `timeline` is an object prop, so a fresh literal each render would recompile the whole\n // document. Key on its CONTENT — the override is small, unlike the document.\n }, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);\n\n const tracks: PxCompiledTracks = compiled.tracks;\n // The span `progress` 0–1 covers (ONE iteration when endless) — NOT the seek ceiling.\n const totalDuration = progressSpanMs(tracks.duration, tracks.iterations);\n // How far a seek may go: unbounded when endless (review §3).\n const seekCeiling = seekCeilingMs(tracks.duration, tracks.iterations);\n\n // Whole-run time lives on its own clock: `progress` below is deliberately within ONE\n // iteration, and `withRepeat` never reports how many have elapsed, so the run time cannot\n // be read back off it. See `createRunClock`.\n const runClock = useMemo(() => createRunClock(seekCeiling), [seekCeiling]);\n\n // -- Playback state -------------------------------------------------------\n\n // Progress in ms within ONE iteration; iteration repetition/alternation is\n // expressed through withRepeat, so worklets only ever see [0, duration].\n const progress = useSharedValue(0);\n const playingRef = useRef(false);\n const rateRef = useRef(1);\n\n /** True when the current rate plays the timeline backwards. */\n const reversePlayback = () => rateRef.current < 0;\n\n /** Where the playhead rests once playback ends. `resetOnFinish` snaps back\n * to the start; otherwise `fill` decides whether the final frame is held. */\n const restingPosition = () => {\n if (tracks.resetOnFinish) return 0;\n if (tracks.fill === 'none' || tracks.fill === 'backwards') return 0;\n return reversePlayback() ? 0 : tracks.duration;\n };\n\n const notifyFinish = () => {\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n };\n\n const startFrom = (fromMs: number) => {\n const dur = tracks.duration;\n const rate = rateRef.current || 1;\n const backwards = rate < 0;\n const speed = Math.abs(rate);\n // `direction` decides which end a leg runs toward; a negative playback\n // rate flips it again (the two compose, as in the Web Animations API).\n const directionReversed = tracks.direction === 'reverse' || tracks.direction === 'alternate-reverse';\n const reversedStart = backwards ? !directionReversed : directionReversed;\n const alternates = tracks.direction === 'alternate' || tracks.direction === 'alternate-reverse';\n const from = Math.max(0, Math.min(fromMs, dur));\n\n const legTarget = reversedStart ? 0 : dur;\n const legRemaining = Math.abs(legTarget - from) / speed;\n const repeats = tracks.iterations === Infinity ? -1 : tracks.iterations;\n\n cancelAnimation(progress);\n progress.value = reversedStart ? (from <= 0 ? dur : from) : (from >= dur ? 0 : from);\n\n const animation = repeats === 1\n ? withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }, (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n })\n : withRepeat(\n withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }),\n repeats, alternates,\n (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n }\n );\n\n progress.value = tracks.delay > 0 && from === 0\n ? withDelay(tracks.delay / speed, animation)\n : animation;\n\n playingRef.current = true;\n };\n\n const api: RnAnimatorApi = {\n isPlaying: () => playingRef.current,\n play: () => {\n // `startFrom` rewinds to the opposite end when the playhead is\n // already resting at a boundary (mirrors WAAPI, where play() on a\n // finished animation auto-rewinds) — the run clock rewinds with it,\n // or the time would keep counting on from the old end.\n if (Number.isFinite(seekCeiling) && runClock.now() >= seekCeiling) runClock.seek(0);\n runClock.start(rateRef.current);\n startFrom(progress.value);\n onPlay?.();\n },\n pause: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.stop();\n onPause?.();\n onStop?.();\n },\n cancel: () => {\n cancelAnimation(progress);\n progress.value = 0;\n playingRef.current = false;\n runClock.seek(0);\n runClock.stop();\n onCancel?.();\n onStop?.();\n },\n finish: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n },\n setPlaybackRate: (rate: number) => {\n if (!isValidPlaybackRate(rate)) {\n makeDiag().warn(PxDiagnosticKind.usage, PX_RATE_REJECTED);\n return;\n }\n rateRef.current = rate;\n if (playingRef.current) {\n runClock.start(rate); // resume from the current time at the new rate\n startFrom(progress.value);\n }\n },\n\n // Ms from the start of the WHOLE run, like every other engine (review §3). This used\n // to return `progress.value`, which is ms within the current iteration — so a slider\n // built on it jumped back to 0 every time the animation repeated.\n getCurrentTime: () => runClock.now(),\n\n setCurrentTime: (t: number) => {\n const wasPlaying = playingRef.current;\n cancelAnimation(progress);\n playingRef.current = false;\n // Clamp against the SEEK ceiling, not the progress span — the old clamp capped an\n // endless timeline at one iteration.\n const clamped = clampSeekMs(t, seekCeiling);\n runClock.seek(clamped);\n const withinIteration = tracks.duration > 0\n ? (clamped % tracks.duration) || (clamped === 0 ? 0 : tracks.duration)\n : 0;\n progress.value = withinIteration;\n // Seeking mid-playback continues from the new position rather than\n // silently pausing.\n if (wasPlaying) startFrom(withinIteration);\n else runClock.stop();\n },\n\n getCurrentProgress: () => timeToProgress(runClock.now(), tracks.duration, tracks.iterations),\n\n setCurrentProgress: (p: number) => {\n api.setCurrentTime(progressToTimeMs(p, tracks.duration, tracks.iterations));\n },\n };\n\n useImperativeHandle(apiRef, () => api, [compiled]);\n\n // -- Declarative control --------------------------------------------------\n\n // The EFFECTIVE trigger, read back off the COMPILED document — so it already reflects the\n // `timeline` override and the `startOn` shortcut, both merged in before compilation.\n // Resolved through core's one table, so a document means the same here as on the web:\n // no `startOn` = 'load', no `outAction` = 'continue'.\n const trigger = resolveTrigger(compiled.doc ? getAnimatorConfig(compiled.doc)?.trigger : undefined);\n const effectiveStartOn = trigger.startOn;\n const effectiveOutAction = trigger.outAction;\n\n // ONE control-mode rule, decided in core and shared with React and Vue (API review §1/§7).\n // This component always had the right ORDER but no name for it, and never told anyone when\n // two tiers of props were passed together.\n const { mode: compMode, warnings: modeWarnings } =\n resolveControlMode({ progress: progressProp, time, play, pause, autoplay });\n\n useEffect(() => {\n const diag = makeDiag();\n for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modeWarnings.join('|')]);\n\n useEffect(() => {\n if (compMode === PxControlMode.fixedTime) {\n const seekMs = time !== undefined\n ? time\n : progressToTimeMs(progressProp ?? 0, tracks.duration, tracks.iterations);\n api.setCurrentTime(seekMs);\n return;\n }\n if (compMode === PxControlMode.play) {\n if (play && !pause) api.play();\n else if (pause) api.pause();\n else if (play === false) api.pause(); // hold, not finish() — review §8, same as web\n else api.play();\n return;\n }\n // 'click' and 'scrollIntoView' start from their own handlers below.\n if (compMode === PxControlMode.autoplay && effectiveStartOn === 'load') {\n api.play();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, compMode, autoplay, play, pause, progressProp, time]);\n\n // `startOn: 'scrollIntoView'` — react-native has no IntersectionObserver, so\n // visibility is sampled by measuring the view against the window box. The\n // poll is cheap (a native measure every 200ms) and only runs while this\n // trigger is active; `outAction` decides what leaving the viewport does.\n const scrollRef = useRef<View | null>(null);\n const inViewRef = useRef(false);\n useEffect(() => {\n if (!autoplay || effectiveStartOn !== 'scrollIntoView') return;\n const threshold = trigger.scrollIntoViewThreshold;\n inViewRef.current = false;\n\n const check = () => {\n const node = scrollRef.current;\n if (!node) return;\n node.measureInWindow((_x, y, _w, h) => {\n if (!h) return;\n const screen = Dimensions.get('window').height;\n const visible = Math.max(0, Math.min(y + h, screen) - Math.max(y, 0));\n const ratio = visible / h;\n const isIn = ratio > 0 && ratio >= threshold;\n if (isIn === inViewRef.current) return;\n inViewRef.current = isIn;\n if (isIn) {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n } else if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n });\n };\n\n check();\n const id = setInterval(check, 200);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);\n\n // Stop cleanly on unmount / doc swap — and say so, the way the web's destroy() does (§18):\n // both are \"the animator was thrown away\", so `onRemove` fires, and `onStop` with it.\n useEffect(() => {\n return () => {\n cancelAnimation(progress);\n playingRef.current = false;\n onRemove?.();\n onStop?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled]);\n\n // -- Render ---------------------------------------------------------------\n\n const trackById = useMemo(() => {\n const map = new Map<string, PxElementTracks>();\n for (const el of tracks.elements) map.set(el.id, el);\n return map;\n }, [tracks]);\n\n const warningsRef = useRef<Array<string>>([]);\n const renderErrorRef = useRef<Error | null>(null);\n const root = useMemo(() => {\n warningsRef.current = [];\n renderErrorRef.current = null;\n if (!compiled.doc) return null;\n\n const renderOpts: RenderRnNodeOptions = {\n warnings: warningsRef.current,\n defs: getDefinitions(compiled.doc),\n };\n try {\n return renderRnNode(compiled.doc as PxNode, {\n ...renderOpts,\n decorate: (node, Component, staticProps, children, key) => {\n // An animated definition subtree (gradient / its stops) cannot be\n // driven on the UI thread — hand the WHOLE subtree to the\n // JS-sampled renderer and stop descending here.\n if (needsJsSampling(node, trackById)) {\n return (\n <SampledSubtree\n key={key}\n node={node}\n trackById={trackById}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n renderOpts={renderOpts}\n />\n );\n }\n\n const id = (node as any).id;\n const elTracks = id ? trackById.get(id) : undefined;\n if (!elTracks) return undefined;\n return (\n <AnimatedPxElement\n key={key}\n Component={Component}\n staticProps={staticProps}\n tracks={elTracks}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n >\n {children}\n </AnimatedPxElement>\n );\n },\n });\n } catch (e) {\n // Building the element tree threw — this instance will not play: report it once\n // (an ERROR, review §25.1) and render nothing rather than unmount the host screen.\n const error = e instanceof Error ? e : new Error(String(e));\n renderErrorRef.current = error;\n makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'render' });\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, trackById]);\n\n useEffect(() => {\n const diag = makeDiag();\n // `platform`: these come from the react-native-svg prop mapper — shapes this renderer\n // cannot express, rather than anything wrong with the file.\n for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [root]);\n\n // A compile/render failure was reported where it was caught (once, as an error); here it\n // only decides what to show.\n const failure = compiled.error ?? renderErrorRef.current;\n if (failure) return fallback ? fallback(failure) : null;\n\n // `startOn: 'click'` — the touch analogue of the web player's click trigger:\n // tap to start, tap again to apply `outAction`. Hover (`mouseOver`) has no\n // touch equivalent and `scrollIntoView` needs the surrounding scroll view,\n // so both are left to the host app.\n let content: ReactElement | null = root;\n\n if (autoplay && effectiveStartOn === 'scrollIntoView' && root) {\n // `collapsable={false}` keeps the view in the native tree so it can be measured.\n content = <View ref={scrollRef} collapsable={false}>{root}</View>;\n } else if (autoplay && effectiveStartOn === 'click' && root) {\n content = (\n <Pressable\n onPress={() => {\n if (playingRef.current) {\n if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n } else {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n }\n }}\n >\n {root}\n </Pressable>\n );\n }\n\n // Catches what the try/catch above cannot: throws during React's own render\n // and commit of the tree — react-native-svg internals, reanimated failing\n // to attach to a component that turns out not to be a host view, and so on.\n return (\n <PxRnErrorBoundary fallback={fallback} diag={makeDiag()}>\n {content}\n </PxRnErrorBoundary>\n );\n}\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';\nimport { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/**\n * Sampled animation tracks for ONE element: prop name → per-sample values.\n *\n * The compiler densely samples every animated property through core's\n * `calcAnimationValues` — the exact function the web frames engine renders\n * with — so RN playback is value-identical to the web player. Easing, loops,\n * transform composition, color interpolation and path morphing are all baked\n * into the samples at compile time; the UI-thread worklet only indexes arrays.\n * @internal\n */\nexport interface PxElementTracks {\n /** Element id (after id regeneration). */\n id: string;\n /** react-native-svg prop name → one value per sample. */\n props: Record<string, Array<string | number | Array<number>>>;\n}\n\n/** @internal */\nexport interface PxCompiledTracks {\n /** Per-iteration duration, ms. */\n duration: number;\n /** Iteration count (Infinity for 'infinite'). */\n iterations: number;\n /** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */\n direction: string;\n /** Delay before start, ms (positive = wait). */\n delay: number;\n /** WAAPI-style fill mode (default 'forwards'). */\n fill: string;\n /** When true, snap back to the start after a natural finish. */\n resetOnFinish: boolean;\n /** Sample step, ms. */\n stepMs: number;\n /** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */\n sampleCount: number;\n /** Tracks for every animated element. */\n elements: Array<PxElementTracks>;\n}\n\n/** @internal */\nexport interface CompileTracksOptions {\n /** Target sample rate, samples/second. Default 60 (one per frame). */\n sampleRate?: number;\n /** Hard cap on samples per iteration (memory guard). Default 600. */\n maxSamples?: number;\n /**\n * Sample values in the form the NATIVE react-native-svg views expect\n * (currently: `transform` as a 6-number matrix rather than an SVG string).\n *\n * Defaults to `false` — the plain SVG form, which is what react-native-web\n * hands straight to the DOM. Only the component knows the platform, so it\n * decides; every consumer that does not opt in keeps DOM-compatible values.\n */\n native?: boolean;\n}\n\n\n\n/**\n * Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`\n * + `generateNewIds` first) into densely sampled per-element tracks.\n * @internal\n */\nexport function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {\n const config = getAnimatorConfig(doc) || {};\n\n const duration = +(config.duration || PX_DEFAULT_DURATION_MS);\n const _iterations = config.iterations;\n let iterations = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const native = opts?.native ?? false;\n const sampleRate = opts?.sampleRate ?? 60;\n const maxSamples = opts?.maxSamples ?? 600;\n let sampleCount = Math.max(2, Math.round((duration / 1000) * sampleRate) + 1);\n if (sampleCount > maxSamples) sampleCount = maxSamples;\n const stepMs = duration / (sampleCount - 1);\n\n // Element tag per id — `toRnPropValue` needs it to leave the root `<Svg>`'s\n // transform as a string (see its `tag` parameter).\n const tagById = new Map<string, string>();\n const indexTags = (n: any): void => {\n if (n && typeof n.id === 'string') tagById.set(n.id, String(n.type));\n (n?.children ?? []).forEach(indexTags);\n };\n indexTags(doc);\n\n const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];\n\n const elements: Array<PxElementTracks> = [];\n for (const binding of bindings) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) continue;\n\n const props: Record<string, Array<string | number | Array<number>>> = {};\n for (let i = 0; i < sampleCount; i++) {\n const t = i === sampleCount - 1 ? duration : i * stepMs;\n const values = calcAnimationValues(animDef as PxAnimationDefinition, t);\n for (const [attr, value] of Object.entries(values)) {\n const rnProp = toRnPropName(attr);\n if (!rnProp) continue;\n let arr = props[rnProp];\n if (!arr) {\n arr = props[rnProp] = new Array(sampleCount);\n // A prop can appear late (e.g. attrs whose first kf is\n // beyond t=0) — backfill earlier samples with the first\n // computed value so the array is always fully populated.\n for (let j = 0; j < i; j++) arr[j] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n arr[i] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n }\n // Forward-fill any holes (attr disappeared from a later sample).\n for (const arr of Object.values(props)) {\n for (let i = 1; i < sampleCount; i++) {\n if (arr[i] === undefined) arr[i] = arr[i - 1];\n }\n }\n\n if (Object.keys(props).length > 0) {\n elements.push({ id: binding.id, props });\n }\n }\n\n return {\n duration,\n iterations,\n direction: config.direction || 'normal',\n delay: config.delay || 0,\n fill: config.fill ?? 'forwards',\n resetOnFinish: !!config.resetOnFinish,\n stepMs,\n sampleCount,\n elements,\n };\n}\n\n/**\n * Wire prop → the prop name the NATIVE view actually declares.\n *\n * react-native-svg's JS layer renames some props on the way down: a\n * `transform` (string or matrix) is parsed by `extractProps` and handed to the\n * native component as `matrix` — the Fabric spec has no `transform` prop at\n * all. Values sent through reanimated's animated-props path skip that JS\n * rename, so they must already use the native name or the native view drops\n * them silently. This is ONLY for the animated path; plain React renders still\n * go through the JS layer and must keep the wire name.\n */\nexport const NATIVE_PROP_NAME: Record<string, string> = {\n transform: 'matrix',\n};\n\n/**\n * Worklet-safe sample lookup: returns the per-prop values at time `tMs`\n * (already mapped into a single iteration by the caller). Kept deliberately\n * trivial — runs on the UI thread every frame.\n *\n * `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the\n * reanimated animated-props path of a real device. Props that are applied by\n * re-rendering through React (and therefore still pass through react-native-svg's\n * JS layer), and every value on the web, must keep the wire name.\n * @internal\n */\nexport function sampleProps(\n tracks: PxElementTracks,\n tMs: number,\n stepMs: number,\n sampleCount: number,\n native = false\n): Record<string, string | number | Array<number>> {\n 'worklet';\n const out: Record<string, string | number | Array<number>> = {};\n // Defensive: this runs on the UI thread, where a throw is a hard crash\n // with no React boundary to catch it.\n if (!tracks || !tracks.props || !(stepMs > 0)) return out;\n\n let idx = Math.round(tMs / stepMs);\n if (idx < 0) idx = 0;\n if (idx >= sampleCount) idx = sampleCount - 1;\n for (const key in tracks.props) {\n const values = tracks.props[key];\n if (!values) continue;\n const value = values[idx];\n if (value === undefined) continue;\n const name = native && key === 'transform' ? 'matrix' : key;\n out[name] = value;\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core/internal';\nimport { svgTransformToMatrix } from './PxRnMatrix';\n\n/** Attribute names with a react-native-svg prop equivalent under a\n * different name (not just a casing change). */\nconst ATTR_NAME_OVERRIDES: Record<string, string> = {\n 'xlink:href': 'href',\n};\n\n/** Props react-native-svg does not understand / must not receive. */\nconst DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xlink', 'data-px-meta']);\n\n/**\n * Converts one normalized wire attribute name (camelCase after core's\n * `toDomProps`, or kebab-case raw) to a react-native-svg prop name.\n * Returns undefined for props that must be dropped.\n *\n * Pure (no react-native-svg import) so the track compiler and its tests\n * don't need a React Native environment.\n * @internal\n */\nexport function toRnPropName(attrName: string): string | undefined {\n if (DROPPED_ATTRS.has(attrName)) return undefined;\n const override = ATTR_NAME_OVERRIDES[attrName];\n if (override) return override;\n // react-native-svg uses camelCase props (strokeWidth, fillOpacity, …);\n // core's kebabToCamelCaseWord is a no-op for already-camelCase input.\n return kebabToCamelCaseWord(attrName);\n}\n\n/** Props whose value is a LIST of lengths. react-native-svg's native side\n * expects a number array here (its JS `extractLengthList` splits strings, but\n * values delivered through reanimated's animated-props path bypass that JS\n * extraction and reach the native view directly). */\nconst LENGTH_LIST_PROPS = new Set(['strokeDasharray']);\n\n/**\n * Converts one already-renamed prop value into the shape react-native-svg\n * expects: length-list props become number arrays; numeric strings become\n * numbers; everything else passes through.\n */\nexport function toRnPropValue(\n rnPropName: string,\n value: string | number,\n /** The owning element's tag. The ROOT `<Svg>` handles `transform` through a\n * different code path (`extractTransformSvgView`, which wants a string or\n * an RN style) — a matrix there would be dropped, so leave it alone. */\n tag?: string,\n /** Opt in to the NATIVE representation of a value (see below). Defaults to\n * off, so web keeps the plain SVG/DOM form it has always been given. */\n native = false,\n): string | number | Array<number> {\n // On a device `transform` must arrive as a matrix, not a string: the\n // string→matrix parse happens in JS during render, which reanimated's\n // animated-props path skips entirely. See PxRnMatrix for the full why.\n // On the web the DOM parses the string itself and an array would serialize\n // to a meaningless `transform=\"1,0,0,1,3,4\"`, so it must stay a string.\n if (native && rnPropName === 'transform' && typeof value === 'string' && tag !== 'svg') {\n const m = svgTransformToMatrix(value);\n if (m) return m;\n }\n if (LENGTH_LIST_PROPS.has(rnPropName)) {\n const parts = String(value).trim().replace(/,/g, ' ').split(/\\s+/).map(Number).filter(n => Number.isFinite(n));\n // An odd-length dasharray repeats to become even (SVG spec); rn-svg\n // does this itself for the static path — mirror it so both paths agree.\n return parts.length % 2 === 1 ? parts.concat(parts) : parts;\n }\n if (typeof value === 'number') return value;\n const num = +value;\n return Number.isFinite(num) && String(num) === value ? num : value;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * SVG transform string → 2D affine matrix, in the order react-native-svg's\n * native side expects: `[a, b, c, d, e, f]`, i.e. SVG's own `matrix(…)` order\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n *\n * WHY THIS EXISTS: react-native-svg parses a `transform` STRING into this matrix\n * in JavaScript, inside `extractTransform`, during render. Values delivered\n * through reanimated's `animatedProps` bypass that JS step and reach the native\n * view directly, where a raw string is meaningless — an animated transform\n * simply does nothing. Feeding the matrix instead makes the animated and static\n * paths agree. (On the web the DOM parses the string itself, which is why this\n * only shows up on a device.)\n */\nexport type Mat2D = [number, number, number, number, number, number];\n\nexport const IDENTITY: Mat2D = [1, 0, 0, 1, 0, 0];\n\nconst DEG = Math.PI / 180;\n\n/** `m1 · m2` — apply m2 first, then m1 (same convention as SVG's left-to-right list). */\nfunction multiply(m1: Mat2D, m2: Mat2D): Mat2D {\n const [a1, b1, c1, d1, e1, f1] = m1;\n const [a2, b2, c2, d2, e2, f2] = m2;\n return [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n}\n\n/** Splits `translate(1,2)rotate(45)` into `[['translate',[1,2]], ['rotate',[45]]]`. */\nconst FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\nfunction numbers(raw: string): Array<number> {\n return raw\n .split(/[\\s,]+/)\n .filter(s => s.length > 0)\n .map(Number)\n .filter(n => Number.isFinite(n));\n}\n\n/**\n * Parses an SVG transform list. Returns `undefined` when the string contains no\n * recognizable function, so callers can leave the original value untouched\n * rather than silently replacing it with an identity matrix.\n */\nexport function svgTransformToMatrix(value: string): Mat2D | undefined {\n let m: Mat2D | undefined;\n FN_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = FN_RE.exec(value)) !== null) {\n const fn = match[1].toLowerCase();\n const n = numbers(match[2]);\n let step: Mat2D | undefined;\n\n switch (fn) {\n case 'translate':\n step = [1, 0, 0, 1, n[0] || 0, n[1] || 0];\n break;\n case 'scale': {\n const sx = n[0] ?? 1;\n const sy = n.length > 1 ? n[1] : sx;\n step = [sx, 0, 0, sy, 0, 0];\n break;\n }\n case 'rotate': {\n const rad = (n[0] || 0) * DEG;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n const rot: Mat2D = [cos, sin, -sin, cos, 0, 0];\n if (n.length >= 3) {\n // rotate(a, cx, cy) == translate(cx,cy) rotate(a) translate(-cx,-cy)\n const cx = n[1], cy = n[2];\n step = multiply(multiply([1, 0, 0, 1, cx, cy], rot), [1, 0, 0, 1, -cx, -cy]);\n } else {\n step = rot;\n }\n break;\n }\n case 'skewx':\n step = [1, 0, Math.tan((n[0] || 0) * DEG), 1, 0, 0];\n break;\n case 'skewy':\n step = [1, Math.tan((n[0] || 0) * DEG), 0, 1, 0, 0];\n break;\n case 'matrix':\n if (n.length >= 6) step = [n[0], n[1], n[2], n[3], n[4], n[5]];\n break;\n default:\n step = undefined; // unknown function — ignore it\n }\n\n if (step) m = m ? multiply(m, step) : step;\n }\n\n return m;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';\nimport { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';\nimport { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { RN_SVG_COMPONENTS } from './PxRnTypeMap';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/** @internal */\nexport interface RenderRnNodeOptions {\n /** Collects non-fatal issues (unsupported tags, dropped attrs). */\n warnings?: Array<string>;\n /** `definitions` from the document, used to resolve named `style` presets. */\n defs?: PxDefinitions;\n /**\n * Wraps the created element for animated nodes: receives the resolved\n * component + static props and returns the element to mount (the animator\n * substitutes an Animated component wired to its tracks). Return undefined\n * to keep the plain static element.\n *\n * `key` is handed over SEPARATELY and is deliberately absent from `props`:\n * React 19 warns when a props object containing `key` is spread into JSX,\n * and implementations of this hook do exactly that.\n */\n decorate?: (\n node: PxNode,\n Component: ComponentType<any>,\n props: Record<string, any>,\n children: ReactNode,\n key: string | number | undefined\n ) => ReactElement | undefined;\n}\n\n/**\n * Converts core-normalized wire props into react-native-svg props: RN prop\n * naming, sanitization (same security rules as the web renderer), numeric\n * coercion where possible.\n * @internal\n */\nexport function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {\n const normalized = toDomProps(props);\n const out: Record<string, any> = {};\n for (const key of Object.keys(normalized)) {\n const sanitized = sanitizeAttributeValue(key, normalized[key]);\n if (sanitized === undefined) continue;\n const rnKey = toRnPropName(key);\n if (!rnKey) continue;\n out[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n return out;\n}\n\n/**\n * Renders a (materialized) PxNode tree to react-native-svg elements.\n * Mirrors the web `renderNode` contract: unsupported/dangerous tags are\n * skipped with a warning, never a crash.\n * @internal\n */\nexport function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?: string | number): ReactElement | null {\n if (!node) return null;\n\n const { type, children, style, animate, meta, effects, ...props } = node as any;\n const tag = String(type || 'g');\n\n // ESCAPE KEY (S2): elements whose SVG `type` ATTRIBUTE collides with the reserved\n // `type` node-tag key carry it under `domType` — `feColorMatrix` (matrix/saturate/…),\n // `feTurbulence` (fractalNoise/turbulence), `feFunc*` (identity/table/…).\n // Restore it as a real prop, mirroring the web renderer.\n const domType: string | undefined = props.domType;\n if (domType !== undefined) delete props.domType;\n\n if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {\n opts.warnings?.push('tag blocked (dangerous): ' + tag);\n return null;\n }\n\n const Component = RN_SVG_COMPONENTS[tag];\n if (!Component) {\n opts.warnings?.push('tag not supported in react-native-svg mapping: ' + tag);\n return null;\n }\n\n // NB: `key` is never written into this object — see `decorate` above.\n const rnProps = toRnProps(props, opts.warnings, tag);\n if (domType !== undefined) rnProps.type = domType;\n\n // `node.style` — an inline record of declarations. react-native-svg has no CSS, so\n // they are applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).\n // Explicit attributes on the node win over the style block.\n const resolved = style;\n if (resolved) {\n for (const [k, v] of Object.entries(resolved)) {\n const rnKey = toRnPropName(k);\n if (!rnKey || rnKey in rnProps) continue;\n const sanitized = sanitizeAttributeValue(rnKey, v);\n if (sanitized === undefined) continue;\n rnProps[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n }\n\n // Text content: wire nodes carry it in `textContent` — the one key.\n const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];\n\n let childElements: ReactNode = undefined;\n if (Array.isArray(children) && children.length > 0) {\n childElements = children\n .map((ch: PxNode, i: number) => {\n // One malformed child should cost that child, not the whole tree.\n try {\n return renderRnNode(ch, opts, i);\n } catch (e) {\n opts.warnings?.push('child failed to render: ' + (e instanceof Error ? e.message : String(e)));\n return null;\n }\n })\n .filter(Boolean);\n } else if (textContent !== undefined) {\n childElements = String(textContent);\n }\n\n const decorated = opts.decorate?.(node, Component, rnProps, childElements, key);\n if (decorated !== undefined) return decorated;\n\n // `createElement` takes `key` in its config object — that path does NOT\n // trigger React's JSX-spread warning.\n return createElement(\n Component,\n key !== undefined ? { ...rnProps, key } : rnProps,\n childElements\n );\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n Circle,\n ClipPath,\n Defs,\n Ellipse,\n FeBlend,\n FeColorMatrix,\n FeComponentTransfer,\n FeComposite,\n FeConvolveMatrix,\n FeDiffuseLighting,\n FeDisplacementMap,\n FeDistantLight,\n FeDropShadow,\n FeFlood,\n FeFuncA,\n FeFuncB,\n FeFuncG,\n FeFuncR,\n FeGaussianBlur,\n FeImage,\n FeMerge,\n FeMergeNode,\n FeMorphology,\n FeOffset,\n FePointLight,\n FeSpecularLighting,\n FeSpotLight,\n FeTile,\n FeTurbulence,\n Filter,\n G,\n Image,\n Line,\n LinearGradient,\n Marker,\n Mask,\n Path,\n Pattern,\n Polygon,\n Polyline,\n RadialGradient,\n Rect,\n Stop,\n Svg,\n Symbol as SvgSymbol,\n Text as SvgText,\n TextPath,\n TSpan,\n Use,\n} from 'react-native-svg';\nimport type { ComponentType } from 'react';\n\n/**\n * SVG tag → react-native-svg component. Tags not in this map are skipped at\n * render time (with a warning collected by the renderer) — they go on the\n * feature-gap list rather than crashing the tree.\n *\n * Keys are the wire-format `node.type` values, which follow SVG's own casing\n * (`clipPath`, `feGaussianBlur`, `linearGradient`, …).\n * @internal\n */\nexport const RN_SVG_COMPONENTS: Record<string, ComponentType<any>> = {\n // Root & containers\n svg: Svg,\n g: G,\n defs: Defs,\n symbol: SvgSymbol,\n use: Use,\n\n // Shapes\n rect: Rect,\n circle: Circle,\n ellipse: Ellipse,\n line: Line,\n path: Path,\n polygon: Polygon,\n polyline: Polyline,\n image: Image,\n\n // Text\n text: SvgText,\n tspan: TSpan,\n textPath: TextPath,\n\n // Paint servers & clipping\n linearGradient: LinearGradient,\n radialGradient: RadialGradient,\n stop: Stop,\n pattern: Pattern,\n mask: Mask,\n clipPath: ClipPath,\n marker: Marker,\n\n // Filters — react-native-svg implements the full primitive set.\n // NOTE: filter rendering requires the New Architecture (Fabric) and is\n // newer than the rest of react-native-svg; treat visual parity with the\n // web player as unverified until checked on a device.\n filter: Filter,\n feBlend: FeBlend,\n feColorMatrix: FeColorMatrix,\n feComponentTransfer: FeComponentTransfer,\n feComposite: FeComposite,\n feConvolveMatrix: FeConvolveMatrix,\n feDiffuseLighting: FeDiffuseLighting,\n feDisplacementMap: FeDisplacementMap,\n feDistantLight: FeDistantLight,\n feDropShadow: FeDropShadow,\n feFlood: FeFlood,\n feFuncA: FeFuncA,\n feFuncB: FeFuncB,\n feFuncG: FeFuncG,\n feFuncR: FeFuncR,\n feGaussianBlur: FeGaussianBlur,\n feImage: FeImage,\n feMerge: FeMerge,\n feMergeNode: FeMergeNode,\n feMorphology: FeMorphology,\n feOffset: FeOffset,\n fePointLight: FePointLight,\n feSpecularLighting: FeSpecularLighting,\n feSpotLight: FeSpotLight,\n feTile: FeTile,\n feTurbulence: FeTurbulence,\n};\n\nexport { toRnPropName } from './PxRnPropNames';\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\nimport { PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics } from '@pixodesk/svg-animator-core/internal';\n\n/** @public @advanced */\nexport interface PxRnErrorBoundaryProps {\n children: ReactNode;\n /** Rendered instead of the children once something has thrown. */\n fallback?: (error: Error) => ReactNode;\n /**\n * Where the failure is reported (API review §5, §25.1): `error(internal, …)` with\n * `{ componentStack }` as the detail — so it reaches `onError` like every other failure.\n * Defaults to the console.\n */\n diag?: PxDiagnostics;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Keeps one bad animation from taking down the screen around it.\n *\n * A throw anywhere in the rendered SVG tree — an unsupported prop shape, a\n * react-native-svg internal, a reanimated attachment failure — otherwise\n * unmounts the whole React tree above it. Here it is contained to this one\n * animation, reported through the diagnostics channel, and replaced by `fallback`.\n *\n * NOTE the limit: this catches JavaScript errors only. A crash INSIDE the\n * native renderer (see `openClosedTextPathTargets` for a real example) never\n * reaches JavaScript and cannot be caught here — those have to be avoided\n * rather than handled.\n * @public @advanced\n */\nexport class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override componentDidCatch(error: Error, info: ErrorInfo): void {\n (this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))\n .error(PxDiagnosticKind.internal, error, { componentStack: info?.componentStack ?? undefined });\n }\n\n override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {\n // A new document deserves a fresh attempt — otherwise the boundary\n // would stay latched on the failure for the rest of its life.\n if (this.state.error && prev.children !== this.props.children) {\n this.setState({ error: null });\n }\n }\n\n override render(): ReactNode {\n const { error } = this.state;\n if (error) return this.props.fallback ? this.props.fallback(error) : null;\n return this.props.children;\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { type PxNode } from '@pixodesk/svg-animator-core';\nimport { deepClone, generateUniqueId } from '@pixodesk/svg-animator-core/internal';\n\n/**\n * Workarounds for defects in react-native-svg's NATIVE renderer that would\n * otherwise take the whole app down.\n *\n * These are applied only when the native views are in use — never on the web,\n * where the DOM handles all of this correctly and the document must be left\n * exactly as the core pipeline produced it.\n */\n\n/** True when a path's `d` contains a close-subpath command. */\nfunction isClosedPath(d: unknown): boolean {\n return typeof d === 'string' && /[zZ]/.test(d);\n}\n\n/** Drops close-subpath commands, turning a closed outline into an open one. */\nfunction openPath(d: string): string {\n return d.replace(/[zZ]/g, '').trimEnd();\n}\n\n/** `#foo` → `foo`. Returns undefined for anything that is not a local ref. */\nfunction localRef(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.startsWith('#') ? trimmed.slice(1) : undefined;\n}\n\nfunction forEachNode(node: PxNode | undefined, visit: (n: PxNode, parent?: PxNode) => void, parent?: PxNode): void {\n if (!node) return;\n visit(node, parent);\n for (const child of (node.children ?? [])) forEachNode(child, visit, node);\n}\n\n/**\n * Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.\n *\n * WHY: react-native-svg's native text-on-path layout crashes the app —\n * an uncatchable `NSRangeException` on iOS — for this combination.\n * `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,\n * but for a closed path it sets those bounds to `startOffset … startOffset +\n * pathLength` instead of `0 … pathLength`. Any glyph past the end of the path\n * therefore survives the bounds check and reaches `getPosAndTan`, whose\n * `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths\n * array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is\n * all it takes, and animating `startOffset` guarantees hitting it.\n *\n * Opening the path restores the `0 … pathLength` bounds, so out-of-range\n * glyphs are skipped as intended. The copy is private to the `<textPath>`, so\n * anything else drawing the same path still gets the closed original. For a\n * shape whose ends already meet (a circle, the usual case) the removed segment\n * has zero length and nothing changes visually at all.\n *\n * Returns the document unchanged — the same object — when nothing matches.\n * @internal\n */\nexport function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode {\n // Cheap pre-check: the overwhelming majority of documents have no textPath.\n let hasTextPath = false;\n forEachNode(doc, n => { if (String(n.type) === 'textPath') hasTextPath = true; });\n if (!hasTextPath) return doc;\n\n const result = deepClone(doc);\n\n const byId = new Map<string, PxNode>();\n forEachNode(result, n => {\n const id = (n as any).id;\n if (typeof id === 'string') byId.set(id, n);\n });\n\n /** The copy is a geometry reference, never something to draw — so it goes\n * in `<defs>`, alongside the paths textPath targets normally live in. */\n let defs = (result.children ?? []).find(c => String(c.type) === 'defs');\n const ensureDefs = (): PxNode => {\n if (!defs) {\n defs = { type: 'defs', children: [] } as unknown as PxNode;\n (result.children ??= []).unshift(defs);\n }\n return defs;\n };\n\n /** Original path id → id of the open copy, so N textPaths share one copy. */\n const openCopies = new Map<string, string>();\n\n forEachNode(result, node => {\n if (String(node.type) !== 'textPath') return;\n\n const anyNode = node as any;\n const attr = anyNode.href !== undefined ? 'href' : 'xlink:href';\n const targetId = localRef(anyNode[attr]);\n if (!targetId) return;\n\n const target = byId.get(targetId);\n if (!target || !isClosedPath((target as any).d)) return;\n\n let copyId = openCopies.get(targetId);\n if (!copyId) {\n const copy = deepClone(target) as any;\n copyId = 'px_open_' + generateUniqueId();\n copy.id = copyId;\n copy.d = openPath(String(copy.d));\n // A copy that also carried animation would animate twice; the copy\n // exists purely as a geometry reference for the text.\n delete copy.animate;\n delete copy.effects;\n\n (ensureDefs().children ??= []).push(copy);\n openCopies.set(targetId, copyId);\n warnings?.push(\n 'textPath follows a closed path (#' + targetId + '); using an open copy to ' +\n 'avoid a react-native-svg native crash'\n );\n }\n\n anyNode[attr] = '#' + copyId;\n });\n\n return result;\n}\n"],"mappings":"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","names":["PxDiagnosticKind","getAnimatorConfig","PxTimelineEngine","createDiagnostics","createElement","_a","Component","_a","_a","Component","createElement","PxDiagnosticKind","PxTimelineEngine","createDiagnostics","getAnimatorConfig"]}
|
|
1
|
+
{"version":3,"sources":["../src/PixodeskSvgAnimator.tsx","../src/PxRnTracks.ts","../src/PxRnPropNames.ts","../src/PxRnMatrix.ts","../src/PxRnRender.tsx","../src/PxRnTypeMap.ts","../src/PxRnErrorBoundary.tsx","../src/PxRnSafety.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PxDiagnosticCode, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';\nimport React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { Dimensions, Platform, Pressable, View } from 'react-native';\nimport Animated, {\n cancelAnimation,\n useAnimatedReaction,\n Easing,\n runOnJS,\n useAnimatedProps,\n useSharedValue,\n withDelay,\n withRepeat,\n withTiming,\n type SharedValue,\n} from 'react-native-reanimated';\nimport { compileTracks, sampleProps, type PxCompiledTracks, type PxElementTracks } from './PxRnTracks';\nimport { renderRnNode, type RenderRnNodeOptions } from './PxRnRender';\nimport { PxRnErrorBoundary } from './PxRnErrorBoundary';\nimport { openClosedTextPathTargets } from './PxRnSafety';\n\n\n// -- Public types -----------------------------------------------------------\n\n/**\n * The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's\n * name (review §9). It no longer \"mirrors\" the React one by hand: the local copy had already\n * drifted (its `setPlaybackRate` comment lost \"negative plays backwards\"). One definition.\n * @public\n */\nexport type RnAnimatorApi = PxAnimatorHandle;\n\n/**\n * The component's props. The playback override, the control props and the callbacks are core's\n * shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and\n * `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs\n * on this platform is declared here: `fallback`, which has no web counterpart.\n * @public\n */\nexport interface PixodeskSvgAnimatorProps\n extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {\n\n // -- Source ---------------------------------------------------------------\n\n /** The animation document to render. */\n doc: PxAnimatedSvgDocument;\n\n /**\n * Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.\n *\n * `engine` is accepted but ignored here: React Native always uses the `native` (fully\n * flattened) materialization, because react-native-svg has no `<use>` shadow-tree\n * propagation.\n */\n timeline?: PxTimelinePatch | string;\n\n // -- Imperative control ---------------------------------------------------\n\n /**\n * Ref populated with the imperative playback API. Filled in EVERY mode and never picks one\n * (review §1): `autoplay` next to it still autoplays.\n */\n apiRef?: React.RefObject<RnAnimatorApi | null>;\n\n // -- Failure handling -----------------------------------------------------\n // A document that cannot be compiled or rendered is reported through `onError` — the same\n // `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the\n // thrown Error and, when the error boundary caught it, the component stack in `diagnostic.data`.\n // The component renders `fallback` instead of throwing, so one broken animation never\n // takes down the screen around it. Only JavaScript failures reach this — a crash inside\n // react-native-svg's native renderer bypasses JavaScript entirely.\n\n /** Rendered in place of the animation after a failure. Default: nothing. */\n fallback?: (error: Error) => ReactElement | null;\n}\n\n\n// -- Animated element wrapper ------------------------------------------------\n\n/**\n * Whether react-native-svg is backed by NATIVE views here, rather than by the\n * DOM through react-native-web.\n *\n * The two want different things from an animated `transform`: a native view\n * declares a `matrix` prop taking six numbers, while the DOM wants a\n * `transform` attribute holding an SVG string. Getting it wrong is silent —\n * the value is dropped and the element simply never moves — so this single\n * constant decides it once and feeds both the track compiler (value form) and\n * the sampler (prop name). Everything else in the package defaults to the\n * DOM-compatible form.\n */\nconst NATIVE_SVG_VIEWS = Platform.OS !== 'web';\n\nconst animatedComponentCache = new Map<ComponentType<any>, ComponentType<any>>();\n\nfunction getAnimatedComponent(Component: ComponentType<any>): ComponentType<any> {\n let cached = animatedComponentCache.get(Component);\n if (!cached) {\n cached = Animated.createAnimatedComponent(Component as any);\n animatedComponentCache.set(Component, cached);\n }\n return cached;\n}\n\n/** One animated element: static props + UI-thread sampled animated props. */\nfunction AnimatedPxElement({\n Component, staticProps, children, tracks, progress, stepMs, sampleCount,\n}: {\n Component: ComponentType<any>;\n staticProps: Record<string, any>;\n children: ReactNode;\n tracks: PxElementTracks;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n}) {\n const AnimatedComponent = useMemo(() => getAnimatedComponent(Component), [Component]);\n\n // Runs on the UI thread every frame; `sampleProps` is a trivial indexed\n // lookup into the precompiled tracks — no interpolation logic on the hot path.\n const animatedProps = useAnimatedProps(() => {\n // On iOS/Android these values bypass react-native-svg's JS prop layer\n // and land on the native view, which declares `matrix`, not\n // `transform`. The web build keeps the DOM-facing `transform` name.\n return sampleProps(tracks, progress.value, stepMs, sampleCount, NATIVE_SVG_VIEWS);\n }, [tracks, stepMs, sampleCount]);\n\n return (\n <AnimatedComponent {...staticProps} animatedProps={animatedProps}>\n {children}\n </AnimatedComponent>\n );\n}\n\n\n/**\n * react-native-svg elements whose `render()` returns `null`. They carry data for\n * their PARENT (a `<Stop>` is read by the gradient that owns it) rather than\n * producing a native view, so reanimated has nothing to attach to — wrapping one\n * in `Animated.createAnimatedComponent` throws\n * \"Cannot find host instance for this component\".\n */\nconst NON_HOST_TAGS = new Set(['stop', 'feMergeNode']);\n\n/**\n * Definition elements — they describe paint/geometry for something else rather\n * than drawing themselves. Their animated attributes (a gradient's `y1`, a\n * stop's `stop-color`) do not reliably flow through reanimated's animated-props\n * path, so an animated def is rendered by re-sampling from JS instead. There\n * are only ever a handful per document and they change slowly, so the cost is\n * negligible — visual elements still animate entirely on the UI thread.\n */\nconst SAMPLED_DEF_TAGS = new Set(['linearGradient', 'radialGradient', ...NON_HOST_TAGS]);\n\n/** True when this subtree must be driven from JS rather than the UI thread:\n * either the node itself is an animated def, or it owns an animated non-host\n * child (an animated `<Stop>` only re-renders via its parent gradient). */\nfunction needsJsSampling(node: PxNode, trackById: Map<string, PxElementTracks>): boolean {\n const id = (node as any).id;\n if (SAMPLED_DEF_TAGS.has(String(node.type)) && id && trackById.has(id)) return true;\n return (node.children ?? []).some(c => needsJsSampling(c, trackById));\n}\n\n/**\n * Renders a subtree whose animation cannot run on the UI thread (see\n * {@link NON_HOST_TAGS}) by re-rendering it from JS with sampled values.\n *\n * Changing a `<Stop>`'s props does not re-render its parent gradient, so the\n * whole subtree is rebuilt — which is why this wraps the gradient rather than\n * the stop. The reaction itself runs on the UI thread and only crosses to JS\n * when the QUANTISED sample index changes, capping these few elements at\n * ~30fps instead of a JS call every frame.\n */\nfunction SampledSubtree({\n node, trackById, progress, stepMs, sampleCount, renderOpts,\n}: {\n node: PxNode;\n trackById: Map<string, PxElementTracks>;\n progress: SharedValue<number>;\n stepMs: number;\n sampleCount: number;\n renderOpts: RenderRnNodeOptions;\n}) {\n const [idx, setIdx] = useState(0);\n\n useAnimatedReaction(\n () => Math.floor(Math.round(progress.value / stepMs) / 2) * 2, // half-rate\n (next, prev) => {\n if (next !== prev) runOnJS(setIdx)(next);\n },\n [stepMs]\n );\n\n const tMs = Math.min(Math.max(idx, 0), sampleCount - 1) * stepMs;\n\n return renderRnNode(node, {\n ...renderOpts,\n // Sampled values are baked in as PLAIN props — nothing reanimated-driven.\n decorate: (n, Component, staticProps, children, key) => {\n const id = (n as any).id;\n const tracks = id ? trackById.get(id) : undefined;\n if (!tracks) return undefined;\n // Wire prop names, NOT the native ones: these go back through\n // react-native-svg's JS prop layer, which does the renaming itself.\n const sampled = sampleProps(tracks, tMs, stepMs, sampleCount);\n return createElement(Component, { ...staticProps, ...sampled, key }, children);\n },\n });\n}\n\n\n\n/** Overrides that shadow the document's own `animator` config. */\n/** The override subset of the props — core's shared shape, not a local copy (review §9). */\ntype ConfigOverrides = PxPlaybackOverride;\n\ninterface Compiled {\n /** Materialized document, or null when compilation failed. */\n doc: PxAnimatedSvgDocument | null;\n tracks: PxCompiledTracks;\n error: Error | null;\n}\n\n/** Playable-but-empty tracks, so a failed compile still satisfies every hook\n * below it — React forbids skipping hooks on an error path. */\nconst EMPTY_TRACKS: PxCompiledTracks = {\n duration: 1, iterations: 1, direction: 'normal', delay: 0,\n fill: 'forwards', resetOnFinish: false, stepMs: 1, sampleCount: 2, elements: [],\n};\n\n/**\n * Materializes + compiles a document. Extracted from the component so the\n * whole thing sits behind one try/catch, and so it can be tested directly.\n */\nfunction compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {\n const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;\n const warnings = validateNodeEffects(doc as PxNode);\n for (const w of warnings) diag.warn(PxDiagnosticKind.document, PxDiagnosticCode.effectsShape, w);\n // The whole-document boundary diagnostic — see the note in the web player's entry.\n reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');\n\n // The per-instance override, applied to the WIRE document BEFORE anything reads the\n // config — `materializeAllInTree` samples motion paths against `duration`, so a later\n // patch would be read by none of the pipeline. Same call, same rules, on every surface.\n const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });\n if (patch !== undefined || resetTimeline) {\n const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });\n for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.timelineOverrideIgnored, w);\n doc = applied.doc;\n }\n\n // `native` = the FULLY-FLATTENED materialization: effects + loops +\n // sampled motion paths + animated `<use>` inlined into real `<g>`\n // clones + orphaned defs pruned. That last part is why RN must not use\n // the `js` flavor: the frame loop keeps `<use href=\"#animatedTarget\">`\n // live references, which only work because the DOM propagates\n // attribute writes through `<use>` shadow trees. react-native-svg has\n // no such live propagation, so an animated `<use>` would render frozen.\n let prepared = materializeAllInTree(doc, PxTimelineEngine.native);\n\n // Sidestep a react-native-svg NATIVE crash (see PxRnSafety). Guarded on\n // the platform because the DOM renders this case correctly and the web\n // document must stay exactly as the core pipeline produced it.\n if (NATIVE_SVG_VIEWS) {\n prepared = openClosedTextPathTargets(prepared as PxNode) as PxAnimatedSvgDocument;\n }\n\n prepared = generateNewIds(prepared);\n const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });\n return { doc: prepared, tracks, error: null };\n}\n\n\n// -- Main component ----------------------------------------------------------\n\n/**\n * React Native component for rendering and controlling Pixodesk SVG animations.\n *\n * The document is materialized once through the shared core pipeline (effects,\n * loops, motion-path sampling, animated-`<use>` inlining — identical to the\n * web's `native` engine, NOT the frame loop, which keeps `<use>` live), compiled\n * into densely sampled per-element tracks, and\n * played back natively: a single reanimated progress value driven by\n * `withTiming`/`withRepeat` on the UI thread, with per-element worklets\n * indexing the precompiled tracks. No JS-thread frame loop.\n * @public\n */\nexport function PixodeskSvgAnimator({\n doc, timeline, resetTimeline, duration, delay, iterations, startOn,\n // (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)\n autoplay, play, pause, apiRef, progress: progressProp, time,\n onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError,\n}: PixodeskSvgAnimatorProps): ReactElement | null {\n\n // -- Compile the document (once per doc/override change) ------------------\n\n // `timeline` is an object prop: a fresh literal every render would otherwise recompile the\n // whole document (materialize + compile tracks), which is the expensive path. Key on its\n // CONTENT instead — the override is small, the document is not.\n const timelineKey = typeof timeline === 'string' ? timeline : JSON.stringify(timeline ?? null);\n\n\n /**\n * The diagnostics channel, built from the CURRENT props each time (API review §5).\n * Deliberately not hoisted into a wrapper closure: `(m, d) => onWarn?.(m, d)` would always\n * be a function, so the channel would believe a handler exists and the console fallback\n * would never fire for anyone who passed nothing.\n */\n const makeDiag = (): PxDiagnostics => createDiagnostics(\n { onWarn, onError, muteWarn, muteError }, '[PixodeskSvgAnimator]');\n\n const compiled = useMemo((): Compiled => {\n try {\n return compileDocument(\n doc,\n { timeline, resetTimeline, duration, delay, iterations, startOn },\n makeDiag(),\n );\n } catch (e) {\n // A malformed document must not take the host screen down with it. This instance\n // will not play — an ERROR, reported once, here (review §25.1).\n const error = e instanceof Error ? e : new Error(String(e));\n makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnCompileFailed, error);\n return { doc: null, tracks: EMPTY_TRACKS, error };\n }\n // `timeline` is an object prop, so a fresh literal each render would recompile the whole\n // document. Key on its CONTENT — the override is small, unlike the document.\n }, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);\n\n const tracks: PxCompiledTracks = compiled.tracks;\n // The span `progress` 0–1 covers (ONE iteration when endless) — NOT the seek ceiling.\n const totalDuration = progressSpanMs(tracks.duration, tracks.iterations);\n // How far a seek may go: unbounded when endless (review §3).\n const seekCeiling = seekCeilingMs(tracks.duration, tracks.iterations);\n\n // Whole-run time lives on its own clock: `progress` below is deliberately within ONE\n // iteration, and `withRepeat` never reports how many have elapsed, so the run time cannot\n // be read back off it. See `createRunClock`.\n const runClock = useMemo(() => createRunClock(seekCeiling), [seekCeiling]);\n\n // -- Playback state -------------------------------------------------------\n\n // Progress in ms within ONE iteration; iteration repetition/alternation is\n // expressed through withRepeat, so worklets only ever see [0, duration].\n const progress = useSharedValue(0);\n const playingRef = useRef(false);\n const rateRef = useRef(1);\n\n /** True when the current rate plays the timeline backwards. */\n const reversePlayback = () => rateRef.current < 0;\n\n /** Where the playhead rests once playback ends. `resetOnFinish` snaps back\n * to the start; otherwise `fill` decides whether the final frame is held. */\n const restingPosition = () => {\n if (tracks.resetOnFinish) return 0;\n if (tracks.fill === 'none' || tracks.fill === 'backwards') return 0;\n return reversePlayback() ? 0 : tracks.duration;\n };\n\n const notifyFinish = () => {\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n };\n\n const startFrom = (fromMs: number) => {\n const dur = tracks.duration;\n const rate = rateRef.current || 1;\n const backwards = rate < 0;\n const speed = Math.abs(rate);\n // `direction` decides which end a leg runs toward; a negative playback\n // rate flips it again (the two compose, as in the Web Animations API).\n const directionReversed = tracks.direction === 'reverse' || tracks.direction === 'alternate-reverse';\n const reversedStart = backwards ? !directionReversed : directionReversed;\n const alternates = tracks.direction === 'alternate' || tracks.direction === 'alternate-reverse';\n const from = Math.max(0, Math.min(fromMs, dur));\n\n const legTarget = reversedStart ? 0 : dur;\n const legRemaining = Math.abs(legTarget - from) / speed;\n const repeats = tracks.iterations === Infinity ? -1 : tracks.iterations;\n\n cancelAnimation(progress);\n progress.value = reversedStart ? (from <= 0 ? dur : from) : (from >= dur ? 0 : from);\n\n const animation = repeats === 1\n ? withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }, (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n })\n : withRepeat(\n withTiming(legTarget, { duration: legRemaining, easing: Easing.linear }),\n repeats, alternates,\n (finished) => {\n 'worklet';\n if (finished) runOnJS(notifyFinish)();\n }\n );\n\n progress.value = tracks.delay > 0 && from === 0\n ? withDelay(tracks.delay / speed, animation)\n : animation;\n\n playingRef.current = true;\n };\n\n const api: RnAnimatorApi = {\n isPlaying: () => playingRef.current,\n play: () => {\n // `startFrom` rewinds to the opposite end when the playhead is\n // already resting at a boundary (mirrors WAAPI, where play() on a\n // finished animation auto-rewinds) — the run clock rewinds with it,\n // or the time would keep counting on from the old end.\n if (Number.isFinite(seekCeiling) && runClock.now() >= seekCeiling) runClock.seek(0);\n runClock.start(rateRef.current);\n startFrom(progress.value);\n onPlay?.();\n },\n pause: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.stop();\n onPause?.();\n onStop?.();\n },\n cancel: () => {\n cancelAnimation(progress);\n progress.value = 0;\n playingRef.current = false;\n runClock.seek(0);\n runClock.stop();\n onCancel?.();\n onStop?.();\n },\n finish: () => {\n cancelAnimation(progress);\n playingRef.current = false;\n runClock.seek(Number.isFinite(seekCeiling) ? seekCeiling : tracks.duration);\n runClock.stop();\n progress.value = restingPosition();\n onFinish?.();\n onStop?.();\n },\n setPlaybackRate: (rate: number) => {\n if (!isValidPlaybackRate(rate)) {\n makeDiag().warn(PxDiagnosticKind.usage, PxDiagnosticCode.rateRejected);\n return;\n }\n rateRef.current = rate;\n if (playingRef.current) {\n runClock.start(rate); // resume from the current time at the new rate\n startFrom(progress.value);\n }\n },\n\n // Ms from the start of the WHOLE run, like every other engine (review §3). This used\n // to return `progress.value`, which is ms within the current iteration — so a slider\n // built on it jumped back to 0 every time the animation repeated.\n getCurrentTime: () => runClock.now(),\n\n setCurrentTime: (t: number) => {\n const wasPlaying = playingRef.current;\n cancelAnimation(progress);\n playingRef.current = false;\n // Clamp against the SEEK ceiling, not the progress span — the old clamp capped an\n // endless timeline at one iteration.\n const clamped = clampSeekMs(t, seekCeiling);\n runClock.seek(clamped);\n const withinIteration = tracks.duration > 0\n ? (clamped % tracks.duration) || (clamped === 0 ? 0 : tracks.duration)\n : 0;\n progress.value = withinIteration;\n // Seeking mid-playback continues from the new position rather than\n // silently pausing.\n if (wasPlaying) startFrom(withinIteration);\n else runClock.stop();\n },\n\n getCurrentProgress: () => timeToProgress(runClock.now(), tracks.duration, tracks.iterations),\n\n setCurrentProgress: (p: number) => {\n api.setCurrentTime(progressToTimeMs(p, tracks.duration, tracks.iterations));\n },\n };\n\n useImperativeHandle(apiRef, () => api, [compiled]);\n\n // -- Declarative control --------------------------------------------------\n\n // The EFFECTIVE trigger, read back off the COMPILED document — so it already reflects the\n // `timeline` override and the `startOn` shortcut, both merged in before compilation.\n // Resolved through core's one table, so a document means the same here as on the web:\n // no `startOn` = 'load', no `outAction` = 'continue'.\n const trigger = resolveTrigger(compiled.doc ? getAnimatorConfig(compiled.doc)?.trigger : undefined);\n const effectiveStartOn = trigger.startOn;\n const effectiveOutAction = trigger.outAction;\n\n // ONE control-mode rule, decided in core and shared with React and Vue (API review §1/§7).\n // This component always had the right ORDER but no name for it, and never told anyone when\n // two tiers of props were passed together.\n const { mode: compMode, warnings: modeWarnings } =\n resolveControlMode({ progress: progressProp, time, play, pause, autoplay });\n\n useEffect(() => {\n const diag = makeDiag();\n for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.controlPropsConflict, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [modeWarnings.join('|')]);\n\n useEffect(() => {\n if (compMode === PxControlMode.fixedTime) {\n const seekMs = time !== undefined\n ? time\n : progressToTimeMs(progressProp ?? 0, tracks.duration, tracks.iterations);\n api.setCurrentTime(seekMs);\n return;\n }\n if (compMode === PxControlMode.play) {\n if (play && !pause) api.play();\n else if (pause) api.pause();\n else if (play === false) api.pause(); // hold, not finish() — review §8, same as web\n else api.play();\n return;\n }\n // 'click' and 'scrollIntoView' start from their own handlers below.\n if (compMode === PxControlMode.autoplay && effectiveStartOn === 'load') {\n api.play();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, compMode, autoplay, play, pause, progressProp, time]);\n\n // `startOn: 'scrollIntoView'` — react-native has no IntersectionObserver, so\n // visibility is sampled by measuring the view against the window box. The\n // poll is cheap (a native measure every 200ms) and only runs while this\n // trigger is active; `outAction` decides what leaving the viewport does.\n const scrollRef = useRef<View | null>(null);\n const inViewRef = useRef(false);\n useEffect(() => {\n if (!autoplay || effectiveStartOn !== 'scrollIntoView') return;\n const threshold = trigger.scrollIntoViewThreshold;\n inViewRef.current = false;\n\n const check = () => {\n const node = scrollRef.current;\n if (!node) return;\n node.measureInWindow((_x, y, _w, h) => {\n if (!h) return;\n const screen = Dimensions.get('window').height;\n const visible = Math.max(0, Math.min(y + h, screen) - Math.max(y, 0));\n const ratio = visible / h;\n const isIn = ratio > 0 && ratio >= threshold;\n if (isIn === inViewRef.current) return;\n inViewRef.current = isIn;\n if (isIn) {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n } else if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n });\n };\n\n check();\n const id = setInterval(check, 200);\n return () => clearInterval(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);\n\n // Stop cleanly on unmount / doc swap — and say so, the way the web's destroy() does (§18):\n // both are \"the animator was thrown away\", so `onRemove` fires, and `onStop` with it.\n useEffect(() => {\n return () => {\n cancelAnimation(progress);\n playingRef.current = false;\n onRemove?.();\n onStop?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled]);\n\n // -- Render ---------------------------------------------------------------\n\n const trackById = useMemo(() => {\n const map = new Map<string, PxElementTracks>();\n for (const el of tracks.elements) map.set(el.id, el);\n return map;\n }, [tracks]);\n\n const warningsRef = useRef<Array<string>>([]);\n const renderErrorRef = useRef<Error | null>(null);\n const root = useMemo(() => {\n warningsRef.current = [];\n renderErrorRef.current = null;\n if (!compiled.doc) return null;\n\n const renderOpts: RenderRnNodeOptions = {\n warnings: warningsRef.current,\n defs: getDefinitions(compiled.doc),\n };\n try {\n return renderRnNode(compiled.doc as PxNode, {\n ...renderOpts,\n decorate: (node, Component, staticProps, children, key) => {\n // An animated definition subtree (gradient / its stops) cannot be\n // driven on the UI thread — hand the WHOLE subtree to the\n // JS-sampled renderer and stop descending here.\n if (needsJsSampling(node, trackById)) {\n return (\n <SampledSubtree\n key={key}\n node={node}\n trackById={trackById}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n renderOpts={renderOpts}\n />\n );\n }\n\n const id = (node as any).id;\n const elTracks = id ? trackById.get(id) : undefined;\n if (!elTracks) return undefined;\n return (\n <AnimatedPxElement\n key={key}\n Component={Component}\n staticProps={staticProps}\n tracks={elTracks}\n progress={progress}\n stepMs={tracks.stepMs}\n sampleCount={tracks.sampleCount}\n >\n {children}\n </AnimatedPxElement>\n );\n },\n });\n } catch (e) {\n // Building the element tree threw — this instance will not play: report it once\n // (an ERROR, review §25.1) and render nothing rather than unmount the host screen.\n const error = e instanceof Error ? e : new Error(String(e));\n renderErrorRef.current = error;\n makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnRenderFailed, error);\n return null;\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [compiled, trackById]);\n\n useEffect(() => {\n const diag = makeDiag();\n // `platform`: these come from the react-native-svg prop mapper — shapes this renderer\n // cannot express, rather than anything wrong with the file.\n for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, PxDiagnosticCode.rnUnsupported, w);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [root]);\n\n // A compile/render failure was reported where it was caught (once, as an error); here it\n // only decides what to show.\n const failure = compiled.error ?? renderErrorRef.current;\n if (failure) return fallback ? fallback(failure) : null;\n\n // `startOn: 'click'` — the touch analogue of the web player's click trigger:\n // tap to start, tap again to apply `outAction`. Hover (`mouseOver`) has no\n // touch equivalent and `scrollIntoView` needs the surrounding scroll view,\n // so both are left to the host app.\n let content: ReactElement | null = root;\n\n if (autoplay && effectiveStartOn === 'scrollIntoView' && root) {\n // `collapsable={false}` keeps the view in the native tree so it can be measured.\n content = <View ref={scrollRef} collapsable={false}>{root}</View>;\n } else if (autoplay && effectiveStartOn === 'click' && root) {\n content = (\n <Pressable\n onPress={() => {\n if (playingRef.current) {\n if (effectiveOutAction === 'reset') api.cancel();\n else if (effectiveOutAction === 'reverse') { api.setPlaybackRate(-Math.abs(rateRef.current || 1)); api.play(); }\n else if (effectiveOutAction !== 'continue') api.pause();\n } else {\n if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));\n api.play();\n }\n }}\n >\n {root}\n </Pressable>\n );\n }\n\n // Catches what the try/catch above cannot: throws during React's own render\n // and commit of the tree — react-native-svg internals, reanimated failing\n // to attach to a component that turns out not to be a host view, and so on.\n return (\n <PxRnErrorBoundary fallback={fallback} diag={makeDiag()}>\n {content}\n </PxRnErrorBoundary>\n );\n}\n\nexport default PixodeskSvgAnimator;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';\nimport { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/**\n * Sampled animation tracks for ONE element: prop name → per-sample values.\n *\n * The compiler densely samples every animated property through core's\n * `calcAnimationValues` — the exact function the web frames engine renders\n * with — so RN playback is value-identical to the web player. Easing, loops,\n * transform composition, color interpolation and path morphing are all baked\n * into the samples at compile time; the UI-thread worklet only indexes arrays.\n * @internal\n */\nexport interface PxElementTracks {\n /** Element id (after id regeneration). */\n id: string;\n /** react-native-svg prop name → one value per sample. */\n props: Record<string, Array<string | number | Array<number>>>;\n}\n\n/** @internal */\nexport interface PxCompiledTracks {\n /** Per-iteration duration, ms. */\n duration: number;\n /** Iteration count (Infinity for 'infinite'). */\n iterations: number;\n /** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */\n direction: string;\n /** Delay before start, ms (positive = wait). */\n delay: number;\n /** WAAPI-style fill mode (default 'forwards'). */\n fill: string;\n /** When true, snap back to the start after a natural finish. */\n resetOnFinish: boolean;\n /** Sample step, ms. */\n stepMs: number;\n /** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */\n sampleCount: number;\n /** Tracks for every animated element. */\n elements: Array<PxElementTracks>;\n}\n\n/** @internal */\nexport interface CompileTracksOptions {\n /** Target sample rate, samples/second. Default 60 (one per frame). */\n sampleRate?: number;\n /** Hard cap on samples per iteration (memory guard). Default 600. */\n maxSamples?: number;\n /**\n * Sample values in the form the NATIVE react-native-svg views expect\n * (currently: `transform` as a 6-number matrix rather than an SVG string).\n *\n * Defaults to `false` — the plain SVG form, which is what react-native-web\n * hands straight to the DOM. Only the component knows the platform, so it\n * decides; every consumer that does not opt in keeps DOM-compatible values.\n */\n native?: boolean;\n}\n\n\n\n/**\n * Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`\n * + `generateNewIds` first) into densely sampled per-element tracks.\n * @internal\n */\nexport function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {\n const config = getAnimatorConfig(doc) || {};\n\n const duration = +(config.duration || PX_DEFAULT_DURATION_MS);\n const _iterations = config.iterations;\n let iterations = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const native = opts?.native ?? false;\n const sampleRate = opts?.sampleRate ?? 60;\n const maxSamples = opts?.maxSamples ?? 600;\n let sampleCount = Math.max(2, Math.round((duration / 1000) * sampleRate) + 1);\n if (sampleCount > maxSamples) sampleCount = maxSamples;\n const stepMs = duration / (sampleCount - 1);\n\n // Element tag per id — `toRnPropValue` needs it to leave the root `<Svg>`'s\n // transform as a string (see its `tag` parameter).\n const tagById = new Map<string, string>();\n const indexTags = (n: any): void => {\n if (n && typeof n.id === 'string') tagById.set(n.id, String(n.type));\n (n?.children ?? []).forEach(indexTags);\n };\n indexTags(doc);\n\n const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];\n\n const elements: Array<PxElementTracks> = [];\n for (const binding of bindings) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) continue;\n\n const props: Record<string, Array<string | number | Array<number>>> = {};\n for (let i = 0; i < sampleCount; i++) {\n const t = i === sampleCount - 1 ? duration : i * stepMs;\n const values = calcAnimationValues(animDef as PxAnimationDefinition, t);\n for (const [attr, value] of Object.entries(values)) {\n const rnProp = toRnPropName(attr);\n if (!rnProp) continue;\n let arr = props[rnProp];\n if (!arr) {\n arr = props[rnProp] = new Array(sampleCount);\n // A prop can appear late (e.g. attrs whose first kf is\n // beyond t=0) — backfill earlier samples with the first\n // computed value so the array is always fully populated.\n for (let j = 0; j < i; j++) arr[j] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n arr[i] = toRnPropValue(rnProp, value, tagById.get(binding.id), native);\n }\n }\n // Forward-fill any holes (attr disappeared from a later sample).\n for (const arr of Object.values(props)) {\n for (let i = 1; i < sampleCount; i++) {\n if (arr[i] === undefined) arr[i] = arr[i - 1];\n }\n }\n\n if (Object.keys(props).length > 0) {\n elements.push({ id: binding.id, props });\n }\n }\n\n return {\n duration,\n iterations,\n direction: config.direction || 'normal',\n delay: config.delay || 0,\n fill: config.fill ?? 'forwards',\n resetOnFinish: !!config.resetOnFinish,\n stepMs,\n sampleCount,\n elements,\n };\n}\n\n/**\n * Wire prop → the prop name the NATIVE view actually declares.\n *\n * react-native-svg's JS layer renames some props on the way down: a\n * `transform` (string or matrix) is parsed by `extractProps` and handed to the\n * native component as `matrix` — the Fabric spec has no `transform` prop at\n * all. Values sent through reanimated's animated-props path skip that JS\n * rename, so they must already use the native name or the native view drops\n * them silently. This is ONLY for the animated path; plain React renders still\n * go through the JS layer and must keep the wire name.\n */\nexport const NATIVE_PROP_NAME: Record<string, string> = {\n transform: 'matrix',\n};\n\n/**\n * Worklet-safe sample lookup: returns the per-prop values at time `tMs`\n * (already mapped into a single iteration by the caller). Kept deliberately\n * trivial — runs on the UI thread every frame.\n *\n * `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the\n * reanimated animated-props path of a real device. Props that are applied by\n * re-rendering through React (and therefore still pass through react-native-svg's\n * JS layer), and every value on the web, must keep the wire name.\n * @internal\n */\nexport function sampleProps(\n tracks: PxElementTracks,\n tMs: number,\n stepMs: number,\n sampleCount: number,\n native = false\n): Record<string, string | number | Array<number>> {\n 'worklet';\n const out: Record<string, string | number | Array<number>> = {};\n // Defensive: this runs on the UI thread, where a throw is a hard crash\n // with no React boundary to catch it.\n if (!tracks || !tracks.props || !(stepMs > 0)) return out;\n\n let idx = Math.round(tMs / stepMs);\n if (idx < 0) idx = 0;\n if (idx >= sampleCount) idx = sampleCount - 1;\n for (const key in tracks.props) {\n const values = tracks.props[key];\n if (!values) continue;\n const value = values[idx];\n if (value === undefined) continue;\n const name = native && key === 'transform' ? 'matrix' : key;\n out[name] = value;\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core/internal';\nimport { svgTransformToMatrix } from './PxRnMatrix';\n\n/** Attribute names with a react-native-svg prop equivalent under a\n * different name (not just a casing change). */\nconst ATTR_NAME_OVERRIDES: Record<string, string> = {\n 'xlink:href': 'href',\n};\n\n/** Props react-native-svg does not understand / must not receive. */\nconst DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xlink', 'data-px-meta']);\n\n/**\n * Converts one normalized wire attribute name (camelCase after core's\n * `toDomProps`, or kebab-case raw) to a react-native-svg prop name.\n * Returns undefined for props that must be dropped.\n *\n * Pure (no react-native-svg import) so the track compiler and its tests\n * don't need a React Native environment.\n * @internal\n */\nexport function toRnPropName(attrName: string): string | undefined {\n if (DROPPED_ATTRS.has(attrName)) return undefined;\n const override = ATTR_NAME_OVERRIDES[attrName];\n if (override) return override;\n // react-native-svg uses camelCase props (strokeWidth, fillOpacity, …);\n // core's kebabToCamelCaseWord is a no-op for already-camelCase input.\n return kebabToCamelCaseWord(attrName);\n}\n\n/** Props whose value is a LIST of lengths. react-native-svg's native side\n * expects a number array here (its JS `extractLengthList` splits strings, but\n * values delivered through reanimated's animated-props path bypass that JS\n * extraction and reach the native view directly). */\nconst LENGTH_LIST_PROPS = new Set(['strokeDasharray']);\n\n/**\n * Converts one already-renamed prop value into the shape react-native-svg\n * expects: length-list props become number arrays; numeric strings become\n * numbers; everything else passes through.\n */\nexport function toRnPropValue(\n rnPropName: string,\n value: string | number,\n /** The owning element's tag. The ROOT `<Svg>` handles `transform` through a\n * different code path (`extractTransformSvgView`, which wants a string or\n * an RN style) — a matrix there would be dropped, so leave it alone. */\n tag?: string,\n /** Opt in to the NATIVE representation of a value (see below). Defaults to\n * off, so web keeps the plain SVG/DOM form it has always been given. */\n native = false,\n): string | number | Array<number> {\n // On a device `transform` must arrive as a matrix, not a string: the\n // string→matrix parse happens in JS during render, which reanimated's\n // animated-props path skips entirely. See PxRnMatrix for the full why.\n // On the web the DOM parses the string itself and an array would serialize\n // to a meaningless `transform=\"1,0,0,1,3,4\"`, so it must stay a string.\n if (native && rnPropName === 'transform' && typeof value === 'string' && tag !== 'svg') {\n const m = svgTransformToMatrix(value);\n if (m) return m;\n }\n if (LENGTH_LIST_PROPS.has(rnPropName)) {\n const parts = String(value).trim().replace(/,/g, ' ').split(/\\s+/).map(Number).filter(n => Number.isFinite(n));\n // An odd-length dasharray repeats to become even (SVG spec); rn-svg\n // does this itself for the static path — mirror it so both paths agree.\n return parts.length % 2 === 1 ? parts.concat(parts) : parts;\n }\n if (typeof value === 'number') return value;\n const num = +value;\n return Number.isFinite(num) && String(num) === value ? num : value;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * SVG transform string → 2D affine matrix, in the order react-native-svg's\n * native side expects: `[a, b, c, d, e, f]`, i.e. SVG's own `matrix(…)` order\n *\n * ```\n * | a c e |\n * | b d f |\n * | 0 0 1 |\n * ```\n *\n * WHY THIS EXISTS: react-native-svg parses a `transform` STRING into this matrix\n * in JavaScript, inside `extractTransform`, during render. Values delivered\n * through reanimated's `animatedProps` bypass that JS step and reach the native\n * view directly, where a raw string is meaningless — an animated transform\n * simply does nothing. Feeding the matrix instead makes the animated and static\n * paths agree. (On the web the DOM parses the string itself, which is why this\n * only shows up on a device.)\n */\nexport type Mat2D = [number, number, number, number, number, number];\n\nexport const IDENTITY: Mat2D = [1, 0, 0, 1, 0, 0];\n\nconst DEG = Math.PI / 180;\n\n/** `m1 · m2` — apply m2 first, then m1 (same convention as SVG's left-to-right list). */\nfunction multiply(m1: Mat2D, m2: Mat2D): Mat2D {\n const [a1, b1, c1, d1, e1, f1] = m1;\n const [a2, b2, c2, d2, e2, f2] = m2;\n return [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1,\n ];\n}\n\n/** Splits `translate(1,2)rotate(45)` into `[['translate',[1,2]], ['rotate',[45]]]`. */\nconst FN_RE = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n\nfunction numbers(raw: string): Array<number> {\n return raw\n .split(/[\\s,]+/)\n .filter(s => s.length > 0)\n .map(Number)\n .filter(n => Number.isFinite(n));\n}\n\n/**\n * Parses an SVG transform list. Returns `undefined` when the string contains no\n * recognizable function, so callers can leave the original value untouched\n * rather than silently replacing it with an identity matrix.\n */\nexport function svgTransformToMatrix(value: string): Mat2D | undefined {\n let m: Mat2D | undefined;\n FN_RE.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = FN_RE.exec(value)) !== null) {\n const fn = match[1].toLowerCase();\n const n = numbers(match[2]);\n let step: Mat2D | undefined;\n\n switch (fn) {\n case 'translate':\n step = [1, 0, 0, 1, n[0] || 0, n[1] || 0];\n break;\n case 'scale': {\n const sx = n[0] ?? 1;\n const sy = n.length > 1 ? n[1] : sx;\n step = [sx, 0, 0, sy, 0, 0];\n break;\n }\n case 'rotate': {\n const rad = (n[0] || 0) * DEG;\n const cos = Math.cos(rad), sin = Math.sin(rad);\n const rot: Mat2D = [cos, sin, -sin, cos, 0, 0];\n if (n.length >= 3) {\n // rotate(a, cx, cy) == translate(cx,cy) rotate(a) translate(-cx,-cy)\n const cx = n[1], cy = n[2];\n step = multiply(multiply([1, 0, 0, 1, cx, cy], rot), [1, 0, 0, 1, -cx, -cy]);\n } else {\n step = rot;\n }\n break;\n }\n case 'skewx':\n step = [1, 0, Math.tan((n[0] || 0) * DEG), 1, 0, 0];\n break;\n case 'skewy':\n step = [1, Math.tan((n[0] || 0) * DEG), 0, 1, 0, 0];\n break;\n case 'matrix':\n if (n.length >= 6) step = [n[0], n[1], n[2], n[3], n[4], n[5]];\n break;\n default:\n step = undefined; // unknown function — ignore it\n }\n\n if (step) m = m ? multiply(m, step) : step;\n }\n\n return m;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';\nimport { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';\nimport { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';\nimport { RN_SVG_COMPONENTS } from './PxRnTypeMap';\nimport { toRnPropName, toRnPropValue } from './PxRnPropNames';\n\n/** @internal */\nexport interface RenderRnNodeOptions {\n /** Collects non-fatal issues (unsupported tags, dropped attrs). */\n warnings?: Array<string>;\n /** `definitions` from the document, used to resolve named `style` presets. */\n defs?: PxDefinitions;\n /**\n * Wraps the created element for animated nodes: receives the resolved\n * component + static props and returns the element to mount (the animator\n * substitutes an Animated component wired to its tracks). Return undefined\n * to keep the plain static element.\n *\n * `key` is handed over SEPARATELY and is deliberately absent from `props`:\n * React 19 warns when a props object containing `key` is spread into JSX,\n * and implementations of this hook do exactly that.\n */\n decorate?: (\n node: PxNode,\n Component: ComponentType<any>,\n props: Record<string, any>,\n children: ReactNode,\n key: string | number | undefined\n ) => ReactElement | undefined;\n}\n\n/**\n * Converts core-normalized wire props into react-native-svg props: RN prop\n * naming, sanitization (same security rules as the web renderer), numeric\n * coercion where possible.\n * @internal\n */\nexport function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {\n const normalized = toDomProps(props);\n const out: Record<string, any> = {};\n for (const key of Object.keys(normalized)) {\n const sanitized = sanitizeAttributeValue(key, normalized[key]);\n if (sanitized === undefined) continue;\n const rnKey = toRnPropName(key);\n if (!rnKey) continue;\n out[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n return out;\n}\n\n/**\n * Renders a (materialized) PxNode tree to react-native-svg elements.\n * Mirrors the web `renderNode` contract: unsupported/dangerous tags are\n * skipped with a warning, never a crash.\n * @internal\n */\nexport function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?: string | number): ReactElement | null {\n if (!node) return null;\n\n const { type, children, style, animate, meta, effects, ...props } = node as any;\n const tag = String(type || 'g');\n\n // ESCAPE KEY (S2): elements whose SVG `type` ATTRIBUTE collides with the reserved\n // `type` node-tag key carry it under `domType` — `feColorMatrix` (matrix/saturate/…),\n // `feTurbulence` (fractalNoise/turbulence), `feFunc*` (identity/table/…).\n // Restore it as a real prop, mirroring the web renderer.\n const domType: string | undefined = props.domType;\n if (domType !== undefined) delete props.domType;\n\n if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {\n opts.warnings?.push('tag blocked (dangerous): ' + tag);\n return null;\n }\n\n const Component = RN_SVG_COMPONENTS[tag];\n if (!Component) {\n opts.warnings?.push('tag not supported in react-native-svg mapping: ' + tag);\n return null;\n }\n\n // NB: `key` is never written into this object — see `decorate` above.\n const rnProps = toRnProps(props, opts.warnings, tag);\n if (domType !== undefined) rnProps.type = domType;\n\n // `node.style` — an inline record of declarations. react-native-svg has no CSS, so\n // they are applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).\n // Explicit attributes on the node win over the style block.\n const resolved = style;\n if (resolved) {\n for (const [k, v] of Object.entries(resolved)) {\n const rnKey = toRnPropName(k);\n if (!rnKey || rnKey in rnProps) continue;\n const sanitized = sanitizeAttributeValue(rnKey, v);\n if (sanitized === undefined) continue;\n rnProps[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);\n }\n }\n\n // Text content: wire nodes carry it in `textContent` — the one key.\n const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];\n\n let childElements: ReactNode = undefined;\n if (Array.isArray(children) && children.length > 0) {\n childElements = children\n .map((ch: PxNode, i: number) => {\n // One malformed child should cost that child, not the whole tree.\n try {\n return renderRnNode(ch, opts, i);\n } catch (e) {\n opts.warnings?.push('child failed to render: ' + (e instanceof Error ? e.message : String(e)));\n return null;\n }\n })\n .filter(Boolean);\n } else if (textContent !== undefined) {\n childElements = String(textContent);\n }\n\n const decorated = opts.decorate?.(node, Component, rnProps, childElements, key);\n if (decorated !== undefined) return decorated;\n\n // `createElement` takes `key` in its config object — that path does NOT\n // trigger React's JSX-spread warning.\n return createElement(\n Component,\n key !== undefined ? { ...rnProps, key } : rnProps,\n childElements\n );\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n Circle,\n ClipPath,\n Defs,\n Ellipse,\n FeBlend,\n FeColorMatrix,\n FeComponentTransfer,\n FeComposite,\n FeConvolveMatrix,\n FeDiffuseLighting,\n FeDisplacementMap,\n FeDistantLight,\n FeDropShadow,\n FeFlood,\n FeFuncA,\n FeFuncB,\n FeFuncG,\n FeFuncR,\n FeGaussianBlur,\n FeImage,\n FeMerge,\n FeMergeNode,\n FeMorphology,\n FeOffset,\n FePointLight,\n FeSpecularLighting,\n FeSpotLight,\n FeTile,\n FeTurbulence,\n Filter,\n G,\n Image,\n Line,\n LinearGradient,\n Marker,\n Mask,\n Path,\n Pattern,\n Polygon,\n Polyline,\n RadialGradient,\n Rect,\n Stop,\n Svg,\n Symbol as SvgSymbol,\n Text as SvgText,\n TextPath,\n TSpan,\n Use,\n} from 'react-native-svg';\nimport type { ComponentType } from 'react';\n\n/**\n * SVG tag → react-native-svg component. Tags not in this map are skipped at\n * render time (with a warning collected by the renderer) — they go on the\n * feature-gap list rather than crashing the tree.\n *\n * Keys are the wire-format `node.type` values, which follow SVG's own casing\n * (`clipPath`, `feGaussianBlur`, `linearGradient`, …).\n * @internal\n */\nexport const RN_SVG_COMPONENTS: Record<string, ComponentType<any>> = {\n // Root & containers\n svg: Svg,\n g: G,\n defs: Defs,\n symbol: SvgSymbol,\n use: Use,\n\n // Shapes\n rect: Rect,\n circle: Circle,\n ellipse: Ellipse,\n line: Line,\n path: Path,\n polygon: Polygon,\n polyline: Polyline,\n image: Image,\n\n // Text\n text: SvgText,\n tspan: TSpan,\n textPath: TextPath,\n\n // Paint servers & clipping\n linearGradient: LinearGradient,\n radialGradient: RadialGradient,\n stop: Stop,\n pattern: Pattern,\n mask: Mask,\n clipPath: ClipPath,\n marker: Marker,\n\n // Filters — react-native-svg implements the full primitive set.\n // NOTE: filter rendering requires the New Architecture (Fabric) and is\n // newer than the rest of react-native-svg; treat visual parity with the\n // web player as unverified until checked on a device.\n filter: Filter,\n feBlend: FeBlend,\n feColorMatrix: FeColorMatrix,\n feComponentTransfer: FeComponentTransfer,\n feComposite: FeComposite,\n feConvolveMatrix: FeConvolveMatrix,\n feDiffuseLighting: FeDiffuseLighting,\n feDisplacementMap: FeDisplacementMap,\n feDistantLight: FeDistantLight,\n feDropShadow: FeDropShadow,\n feFlood: FeFlood,\n feFuncA: FeFuncA,\n feFuncB: FeFuncB,\n feFuncG: FeFuncG,\n feFuncR: FeFuncR,\n feGaussianBlur: FeGaussianBlur,\n feImage: FeImage,\n feMerge: FeMerge,\n feMergeNode: FeMergeNode,\n feMorphology: FeMorphology,\n feOffset: FeOffset,\n fePointLight: FePointLight,\n feSpecularLighting: FeSpecularLighting,\n feSpotLight: FeSpotLight,\n feTile: FeTile,\n feTurbulence: FeTurbulence,\n};\n\nexport { toRnPropName } from './PxRnPropNames';\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { Component, type ErrorInfo, type ReactNode } from 'react';\nimport { PxDiagnosticCode, PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';\nimport { createDiagnostics } from '@pixodesk/svg-animator-core/internal';\n\n/** @public @advanced */\nexport interface PxRnErrorBoundaryProps {\n children: ReactNode;\n /** Rendered instead of the children once something has thrown. */\n fallback?: (error: Error) => ReactNode;\n /**\n * Where the failure is reported (API review §5, §25.1): `error(internal, …)` with\n * the component stack passed as data — so it reaches `onError` like every other failure.\n * Defaults to the console.\n */\n diag?: PxDiagnostics;\n}\n\ninterface State {\n error: Error | null;\n}\n\n/**\n * Keeps one bad animation from taking down the screen around it.\n *\n * A throw anywhere in the rendered SVG tree — an unsupported prop shape, a\n * react-native-svg internal, a reanimated attachment failure — otherwise\n * unmounts the whole React tree above it. Here it is contained to this one\n * animation, reported through the diagnostics channel, and replaced by `fallback`.\n *\n * NOTE the limit: this catches JavaScript errors only. A crash INSIDE the\n * native renderer (see `openClosedTextPathTargets` for a real example) never\n * reaches JavaScript and cannot be caught here — those have to be avoided\n * rather than handled.\n * @public @advanced\n */\nexport class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {\n override state: State = { error: null };\n\n static getDerivedStateFromError(error: Error): State {\n return { error };\n }\n\n override componentDidCatch(error: Error, info: ErrorInfo): void {\n (this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))\n .error(PxDiagnosticKind.internal, PxDiagnosticCode.rnBoundaryCaught, error, info?.componentStack ?? undefined);\n }\n\n override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {\n // A new document deserves a fresh attempt — otherwise the boundary\n // would stay latched on the failure for the rest of its life.\n if (this.state.error && prev.children !== this.props.children) {\n this.setState({ error: null });\n }\n }\n\n override render(): ReactNode {\n const { error } = this.state;\n if (error) return this.props.fallback ? this.props.fallback(error) : null;\n return this.props.children;\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { type PxNode } from '@pixodesk/svg-animator-core';\nimport { deepClone, generateUniqueId } from '@pixodesk/svg-animator-core/internal';\n\n/**\n * Workarounds for defects in react-native-svg's NATIVE renderer that would\n * otherwise take the whole app down.\n *\n * These are applied only when the native views are in use — never on the web,\n * where the DOM handles all of this correctly and the document must be left\n * exactly as the core pipeline produced it.\n */\n\n/** True when a path's `d` contains a close-subpath command. */\nfunction isClosedPath(d: unknown): boolean {\n return typeof d === 'string' && /[zZ]/.test(d);\n}\n\n/** Drops close-subpath commands, turning a closed outline into an open one. */\nfunction openPath(d: string): string {\n return d.replace(/[zZ]/g, '').trimEnd();\n}\n\n/** `#foo` → `foo`. Returns undefined for anything that is not a local ref. */\nfunction localRef(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.startsWith('#') ? trimmed.slice(1) : undefined;\n}\n\nfunction forEachNode(node: PxNode | undefined, visit: (n: PxNode, parent?: PxNode) => void, parent?: PxNode): void {\n if (!node) return;\n visit(node, parent);\n for (const child of (node.children ?? [])) forEachNode(child, visit, node);\n}\n\n/**\n * Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.\n *\n * WHY: react-native-svg's native text-on-path layout crashes the app —\n * an uncatchable `NSRangeException` on iOS — for this combination.\n * `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,\n * but for a closed path it sets those bounds to `startOffset … startOffset +\n * pathLength` instead of `0 … pathLength`. Any glyph past the end of the path\n * therefore survives the bounds check and reaches `getPosAndTan`, whose\n * `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths\n * array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is\n * all it takes, and animating `startOffset` guarantees hitting it.\n *\n * Opening the path restores the `0 … pathLength` bounds, so out-of-range\n * glyphs are skipped as intended. The copy is private to the `<textPath>`, so\n * anything else drawing the same path still gets the closed original. For a\n * shape whose ends already meet (a circle, the usual case) the removed segment\n * has zero length and nothing changes visually at all.\n *\n * Returns the document unchanged — the same object — when nothing matches.\n * @internal\n */\nexport function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode {\n // Cheap pre-check: the overwhelming majority of documents have no textPath.\n let hasTextPath = false;\n forEachNode(doc, n => { if (String(n.type) === 'textPath') hasTextPath = true; });\n if (!hasTextPath) return doc;\n\n const result = deepClone(doc);\n\n const byId = new Map<string, PxNode>();\n forEachNode(result, n => {\n const id = (n as any).id;\n if (typeof id === 'string') byId.set(id, n);\n });\n\n /** The copy is a geometry reference, never something to draw — so it goes\n * in `<defs>`, alongside the paths textPath targets normally live in. */\n let defs = (result.children ?? []).find(c => String(c.type) === 'defs');\n const ensureDefs = (): PxNode => {\n if (!defs) {\n defs = { type: 'defs', children: [] } as unknown as PxNode;\n (result.children ??= []).unshift(defs);\n }\n return defs;\n };\n\n /** Original path id → id of the open copy, so N textPaths share one copy. */\n const openCopies = new Map<string, string>();\n\n forEachNode(result, node => {\n if (String(node.type) !== 'textPath') return;\n\n const anyNode = node as any;\n const attr = anyNode.href !== undefined ? 'href' : 'xlink:href';\n const targetId = localRef(anyNode[attr]);\n if (!targetId) return;\n\n const target = byId.get(targetId);\n if (!target || !isClosedPath((target as any).d)) return;\n\n let copyId = openCopies.get(targetId);\n if (!copyId) {\n const copy = deepClone(target) as any;\n copyId = 'px_open_' + generateUniqueId();\n copy.id = copyId;\n copy.d = openPath(String(copy.d));\n // A copy that also carried animation would animate twice; the copy\n // exists purely as a geometry reference for the text.\n delete copy.animate;\n delete copy.effects;\n\n (ensureDefs().children ??= []).push(copy);\n openCopies.set(targetId, copyId);\n warnings?.push(\n 'textPath follows a closed path (#' + targetId + '); using an open copy to ' +\n 'avoid a react-native-svg native crash'\n );\n }\n\n anyNode[attr] = '#' + copyId;\n });\n\n return result;\n}\n"],"mappings":"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","names":["PxDiagnosticCode","PxDiagnosticKind","getAnimatorConfig","PxTimelineEngine","createDiagnostics","createElement","_a","Component","_a","_a","Component","createElement","PxDiagnosticKind","PxDiagnosticCode","PxTimelineEngine","createDiagnostics","getAnimatorConfig"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixodesk/svg-animator-rn",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.43",
|
|
4
4
|
"description": "Pixodesk SVG animator for React Native — renders animator documents via react-native-svg, driven natively by react-native-reanimated",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"src"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@pixodesk/svg-animator-core": "^1.0.
|
|
30
|
+
"@pixodesk/svg-animator-core": "^1.0.43"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=18",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs,
|
|
6
|
+
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PxDiagnosticCode, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';
|
|
7
7
|
import { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
8
8
|
import React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
9
9
|
import { Dimensions, Platform, Pressable, View } from 'react-native';
|
|
@@ -70,7 +70,7 @@ export interface PixodeskSvgAnimatorProps
|
|
|
70
70
|
// -- Failure handling -----------------------------------------------------
|
|
71
71
|
// A document that cannot be compiled or rendered is reported through `onError` — the same
|
|
72
72
|
// `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the
|
|
73
|
-
// thrown Error and, when the error boundary caught it, `diagnostic.
|
|
73
|
+
// thrown Error and, when the error boundary caught it, the component stack in `diagnostic.data`.
|
|
74
74
|
// The component renders `fallback` instead of throwing, so one broken animation never
|
|
75
75
|
// takes down the screen around it. Only JavaScript failures reach this — a crash inside
|
|
76
76
|
// react-native-svg's native renderer bypasses JavaScript entirely.
|
|
@@ -240,7 +240,7 @@ const EMPTY_TRACKS: PxCompiledTracks = {
|
|
|
240
240
|
function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {
|
|
241
241
|
const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
|
|
242
242
|
const warnings = validateNodeEffects(doc as PxNode);
|
|
243
|
-
for (const w of warnings) diag.warn(PxDiagnosticKind.document,
|
|
243
|
+
for (const w of warnings) diag.warn(PxDiagnosticKind.document, PxDiagnosticCode.effectsShape, w);
|
|
244
244
|
// The whole-document boundary diagnostic — see the note in the web player's entry.
|
|
245
245
|
reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');
|
|
246
246
|
|
|
@@ -250,7 +250,7 @@ function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides,
|
|
|
250
250
|
const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
|
|
251
251
|
if (patch !== undefined || resetTimeline) {
|
|
252
252
|
const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });
|
|
253
|
-
for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage,
|
|
253
|
+
for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.timelineOverrideIgnored, w);
|
|
254
254
|
doc = applied.doc;
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -325,7 +325,7 @@ export function PixodeskSvgAnimator({
|
|
|
325
325
|
// A malformed document must not take the host screen down with it. This instance
|
|
326
326
|
// will not play — an ERROR, reported once, here (review §25.1).
|
|
327
327
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
328
|
-
makeDiag().error(PxDiagnosticKind.internal,
|
|
328
|
+
makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnCompileFailed, error);
|
|
329
329
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
330
330
|
}
|
|
331
331
|
// `timeline` is an object prop, so a fresh literal each render would recompile the whole
|
|
@@ -450,7 +450,7 @@ export function PixodeskSvgAnimator({
|
|
|
450
450
|
},
|
|
451
451
|
setPlaybackRate: (rate: number) => {
|
|
452
452
|
if (!isValidPlaybackRate(rate)) {
|
|
453
|
-
makeDiag().warn(PxDiagnosticKind.usage,
|
|
453
|
+
makeDiag().warn(PxDiagnosticKind.usage, PxDiagnosticCode.rateRejected);
|
|
454
454
|
return;
|
|
455
455
|
}
|
|
456
456
|
rateRef.current = rate;
|
|
@@ -510,7 +510,7 @@ export function PixodeskSvgAnimator({
|
|
|
510
510
|
|
|
511
511
|
useEffect(() => {
|
|
512
512
|
const diag = makeDiag();
|
|
513
|
-
for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, w);
|
|
513
|
+
for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.controlPropsConflict, w);
|
|
514
514
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
515
515
|
}, [modeWarnings.join('|')]);
|
|
516
516
|
|
|
@@ -648,7 +648,7 @@ export function PixodeskSvgAnimator({
|
|
|
648
648
|
// (an ERROR, review §25.1) and render nothing rather than unmount the host screen.
|
|
649
649
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
650
650
|
renderErrorRef.current = error;
|
|
651
|
-
makeDiag().error(PxDiagnosticKind.internal,
|
|
651
|
+
makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnRenderFailed, error);
|
|
652
652
|
return null;
|
|
653
653
|
}
|
|
654
654
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -658,7 +658,7 @@ export function PixodeskSvgAnimator({
|
|
|
658
658
|
const diag = makeDiag();
|
|
659
659
|
// `platform`: these come from the react-native-svg prop mapper — shapes this renderer
|
|
660
660
|
// cannot express, rather than anything wrong with the file.
|
|
661
|
-
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, w);
|
|
661
|
+
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, PxDiagnosticCode.rnUnsupported, w);
|
|
662
662
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
663
663
|
}, [root]);
|
|
664
664
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
6
|
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
7
|
-
import { PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { PxDiagnosticCode, PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';
|
|
8
8
|
import { createDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
9
9
|
|
|
10
10
|
/** @public @advanced */
|
|
@@ -14,7 +14,7 @@ export interface PxRnErrorBoundaryProps {
|
|
|
14
14
|
fallback?: (error: Error) => ReactNode;
|
|
15
15
|
/**
|
|
16
16
|
* Where the failure is reported (API review §5, §25.1): `error(internal, …)` with
|
|
17
|
-
*
|
|
17
|
+
* the component stack passed as data — so it reaches `onError` like every other failure.
|
|
18
18
|
* Defaults to the console.
|
|
19
19
|
*/
|
|
20
20
|
diag?: PxDiagnostics;
|
|
@@ -47,7 +47,7 @@ export class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State>
|
|
|
47
47
|
|
|
48
48
|
override componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
49
49
|
(this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))
|
|
50
|
-
.error(PxDiagnosticKind.internal, error,
|
|
50
|
+
.error(PxDiagnosticKind.internal, PxDiagnosticCode.rnBoundaryCaught, error, info?.componentStack ?? undefined);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {
|