UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

302 lines (301 loc) 10.2 kB
/* global _WORKLET _getCurrentTime _frameTimestamp _eventTimestamp, _setGlobalConsole */ import NativeReanimatedModule from './NativeReanimated'; import { Platform } from 'react-native'; import { nativeShouldBeMock, shouldBeUseWeb, isWeb } from './PlatformChecker'; global.__reanimatedWorkletInit = function (worklet) { worklet.__worklet = true; }; if (global._setGlobalConsole === undefined) { // it can happen when Reanimated plugin wasn't added, but the user uses the only API from version 1 global._setGlobalConsole = () => { // noop }; } const testWorklet = () => { 'worklet'; }; export const checkPluginState = (throwError = true) => { if (!testWorklet.__workletHash && !shouldBeUseWeb()) { if (throwError) { throw new Error("Reanimated 2 failed to create a worklet, maybe you forgot to add Reanimated's babel plugin?"); } return false; } return true; }; export const isConfigured = (throwError = false) => { return checkPluginState(throwError) && !NativeReanimatedModule.useOnlyV1; }; export const isConfiguredCheck = () => { if (!isConfigured(true)) { throw new Error('If you want to use Reanimated 2 then go through our installation steps https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation'); } }; function _toArrayReanimated(object) { 'worklet'; if (Array.isArray(object)) { return object; } if (typeof Symbol !== 'undefined' && (typeof Symbol === 'function' ? Symbol.iterator : '@@iterator') in Object(object)) { return Array.from(object); } throw new Error('Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'); } function _mergeObjectsReanimated() { 'worklet'; // we can't use rest parameters in worklets at the moment // eslint-disable-next-line prefer-rest-params const arr = Array.from(arguments); return Object.assign.apply(null, [arr[0], ...arr.slice(1)]); } global.__reanimatedWorkletInit = function (worklet) { worklet.__worklet = true; if (worklet._closure) { const closure = worklet._closure; Object.keys(closure).forEach((key) => { if (key === '_toConsumableArray') { closure[key] = _toArrayReanimated; } if (key === '_objectSpread') { closure[key] = _mergeObjectsReanimated; } }); } }; function pushFrame(frame) { NativeReanimatedModule.pushFrame(frame); } export function requestFrame(frame) { 'worklet'; if (NativeReanimatedModule.native) { requestAnimationFrame(frame); } else { pushFrame(frame); } } global._WORKLET = false; global._log = function (s) { console.log(s); }; export function runOnUI(worklet) { return makeShareable(worklet); } export function makeShareable(value) { isConfiguredCheck(); return NativeReanimatedModule.makeShareable(value); } export function getViewProp(viewTag, propName) { return new Promise((resolve, reject) => { return NativeReanimatedModule.getViewProp(viewTag, propName, (result) => { if (typeof result === 'string' && result.substr(0, 6) === 'error:') { reject(result); } else { resolve(result); } }); }); } let _getTimestamp; if (nativeShouldBeMock()) { _getTimestamp = () => { return NativeReanimatedModule.getTimestamp(); }; } else { _getTimestamp = () => { 'worklet'; if (_frameTimestamp) { return _frameTimestamp; } if (_eventTimestamp) { return _eventTimestamp; } return _getCurrentTime(); }; } export function getTimestamp() { 'worklet'; if (Platform.OS === 'web') { return NativeReanimatedModule.getTimestamp(); } return _getTimestamp(); } function workletValueSetter(value) { 'worklet'; const previousAnimation = this._animation; if (previousAnimation) { previousAnimation.cancelled = true; this._animation = null; } if (typeof value === 'function' || (value !== null && typeof value === 'object' && value.onFrame !== undefined)) { const animation = typeof value === 'function' ? value() : value; // prevent setting again to the same value // and triggering the mappers that treat this value as an input // this happens when the animation's target value(stored in animation.current until animation.onStart is called) is set to the same value as a current one(this._value) // built in animations that are not higher order(withTiming, withSpring) hold target value in .current if (this._value === animation.current && !animation.isHigherOrder) { animation.callback && animation.callback(true); return; } // animated set const initializeAnimation = (timestamp) => { animation.onStart(animation, this.value, timestamp, previousAnimation); }; initializeAnimation(getTimestamp()); const step = (timestamp) => { if (animation.cancelled) { animation.callback && animation.callback(false /* finished */); return; } const finished = animation.onFrame(animation, timestamp); animation.finished = true; animation.timestamp = timestamp; this._value = animation.current; if (finished) { animation.callback && animation.callback(true /* finished */); } else { requestAnimationFrame(step); } }; this._animation = animation; if (_frameTimestamp) { // frame step(_frameTimestamp); } else { requestAnimationFrame(step); } } else { // prevent setting again to the same value // and triggering the mappers that treat this value as an input if (this._value === value) { return; } this._value = value; } } // We cannot use pushFrame // so we use own implementation for js function workletValueSetterJS(value) { const previousAnimation = this._animation; if (previousAnimation) { previousAnimation.cancelled = true; this._animation = null; } if (typeof value === 'function' || (value !== null && typeof value === 'object' && value.onFrame)) { // animated set const animation = typeof value === 'function' ? value() : value; let initializeAnimation = (timestamp) => { animation.onStart(animation, this.value, timestamp, previousAnimation); }; const step = (timestamp) => { if (animation.cancelled) { animation.callback && animation.callback(false /* finished */); return; } if (initializeAnimation) { initializeAnimation(timestamp); initializeAnimation = null; // prevent closure from keeping ref to previous animation } const finished = animation.onFrame(animation, timestamp); animation.timestamp = timestamp; this._setValue && this._setValue(animation.current); if (finished) { animation.callback && animation.callback(true /* finished */); } else { requestFrame(step); } }; this._animation = animation; requestFrame(step); } else { this._setValue && this._setValue(value); } } export function makeMutable(value) { isConfiguredCheck(); return NativeReanimatedModule.makeMutable(value); } export function makeRemote(object = {}) { isConfiguredCheck(); return NativeReanimatedModule.makeRemote(object); } export function startMapper(mapper, inputs = [], outputs = [], updater = () => { // noop }, viewDescriptors = []) { isConfiguredCheck(); return NativeReanimatedModule.startMapper(mapper, inputs, outputs, updater, viewDescriptors); } export function stopMapper(mapperId) { NativeReanimatedModule.stopMapper(mapperId); } export function runOnJS(fun) { 'worklet'; if (!_WORKLET) { return fun; } if (!fun.__callAsync) { throw new Error("Attempting to call runOnJS with an object that is not a host function. Using runOnJS is only possible with methods that are defined on the main React-Native Javascript thread and that aren't marked as worklets"); } else { return fun.__callAsync; } } if (!NativeReanimatedModule.useOnlyV1) { NativeReanimatedModule.installCoreFunctions(NativeReanimatedModule.native ? workletValueSetter : workletValueSetterJS); if (!isWeb() && isConfigured()) { const capturableConsole = console; runOnUI(() => { 'worklet'; const console = { debug: runOnJS(capturableConsole.debug), log: runOnJS(capturableConsole.log), warn: runOnJS(capturableConsole.warn), error: runOnJS(capturableConsole.error), info: runOnJS(capturableConsole.info), }; _setGlobalConsole(console); global.performance = { now: global._chronoNow, }; })(); } } let featuresConfig = { enableLayoutAnimations: false, setByUser: false, }; export function enableLayoutAnimations(flag, isCallByUser = true) { if (isCallByUser) { featuresConfig = { enableLayoutAnimations: flag, setByUser: true, }; NativeReanimatedModule.enableLayoutAnimations(flag); } else if (!featuresConfig.setByUser && featuresConfig.enableLayoutAnimations !== flag) { featuresConfig.enableLayoutAnimations = flag; NativeReanimatedModule.enableLayoutAnimations(flag); } }