recoil#SerializableParam TypeScript Examples

The following examples show how to use recoil#SerializableParam. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: family-utils.ts    From Chromogen with MIT License 7 votes vote down vote up
wrapFamilyGetter = (key: string, configGet: Function) => {
  let returnedPromise = false;

  return (params: SerializableParam) => (utils: any) => {
    const { get } = utils;
    const value = configGet(params)(utils);
    // Only capture selector data if currently recording

    if (get(recordingState)) {
      if (transactions.length === 0) {
        // Promise-validation is expensive, so we only do it once, on initial load
        if (
          typeof value === 'object'
          && value !== null
          && Object.prototype.toString.call(value) === '[object Promise]'
        ) {
          delete selectorFamilies[key];
          returnedPromise = true;
        } else {
          initialRenderFamilies.push({ key, params, value });
        }
      } else if (!returnedPromise) {
        // Track every new params
        if (!selectorFamilies[key].prevParams.has(params)) {
          selectorFamilies[key].prevParams.add(params);
        }
        // Debouncing allows TransactionObserver to push to array first
        // Length must be computed within debounce to correctly find last transaction
        // Excluding dummy selector created by ChromogenObserver's onload useEffect hook
        if (params !== dummyParam) debouncedAddToTransactions(key, value, params);
      }
    }

    // Return value from original get method
    return value;
  };
}
Example #2
Source File: family-utils.ts    From Chromogen with MIT License 7 votes vote down vote up
wrapFamilySetter = (key: string, set: Function) => (params: SerializableParam) => (
  utils: any,
  newValue: any,
) => {
  if (utils.get(recordingState) && setTransactions.length > 0) {
    // allow TransactionObserver to push to array first
    // Length must be computed after timeout to correctly find last transaction
    setTimeout(() => {
      setTransactions[setTransactions.length - 1].setter = { key, params, newValue };
    }, 0);
  }
  return set(params)(utils, newValue);
}
Example #3
Source File: output-utils.ts    From Chromogen with MIT License 7 votes vote down vote up
export function selectorFamilyHook(
  selectorFamilyTracker: SelectorFamilies<any, SerializableParam>,
  isSettable: boolean,
): string {
  return Object.entries(selectorFamilyTracker)
    .filter((familyArr) => familyArr[1].isSettable === isSettable)
    .reduce((str: string, familyArr: [string, { prevParams: Set<any> }]): string => {
      const [familyName, { prevParams }] = familyArr;
      // converting prevParams from set to array
      return `${str}${[...prevParams].reduce((innerStr: string, param: any) => {
        let scrubbedParams;
        if (typeof param === 'string') {
          scrubbedParams = param.replace(/[^\w\s]/gi, '');
        }

        return isSettable
          ? `${innerStr}\tconst [${`${familyName}__${
              scrubbedParams !== undefined ? scrubbedParams : param
            }__Value`}, ${`set${familyName}__${
              scrubbedParams !== undefined ? scrubbedParams : param
            }`}] = useRecoilState(${familyName}(${
              typeof param === 'string' ? `"${param}"` : `${JSON.parse(param)}`
            }));\n`
          : `${innerStr}\tconst ${`${familyName}__${
              scrubbedParams !== undefined ? scrubbedParams : param
            }__Value`} = useRecoilValue(${familyName}(${
              typeof param === 'string' ? `"${param}"` : `${JSON.parse(param)}`
            }));\n`;
      }, '')}`;
    }, '');
}
Example #4
Source File: output-utils.ts    From Chromogen with MIT License 7 votes vote down vote up
export function returnSelectorFamily(
  selectorFamilyTracker: SelectorFamilies<any, SerializableParam>,
  isSettable: boolean,
) {
  return Object.entries(selectorFamilyTracker)
    .filter((familyArr) => familyArr[1].isSettable === isSettable)
    .reduce(
      (str: string, familyArr: [string, SelectorFamilyMembers<any, SerializableParam>]): string => {
        const [familyName, { prevParams }] = familyArr;
        if (isSettable) {
          return `${str}${[...prevParams].reduce((innerStr: string, param: any) => {
            let scrubbedParams;
            if (typeof param === 'string') {
              scrubbedParams = param.replace(/[^\w\s]/gi, '');
            }

            return `${innerStr}\t\t${`${familyName}__${
              scrubbedParams !== undefined ? scrubbedParams : param
            }__Value`},
            ${`set${familyName}__${scrubbedParams !== undefined ? scrubbedParams : param}`},\n`;
          }, '')}`;
        }
        return `${str}${[...prevParams].reduce((innerStr: string, param: any) => {
          let scrubbedParams;
          if (typeof param === 'string') {
            scrubbedParams = param.replace(/[^\w\s]/gi, '');
          }
          return `${innerStr}\t\t${`${familyName}__${
            scrubbedParams !== undefined ? scrubbedParams : param
          }__Value`},\n`;
        }, '')}`;
      },
      '',
    );
}
Example #5
Source File: utils.ts    From Chromogen with MIT License 7 votes vote down vote up
export function convertFamilyTrackerKeys(
  familyTracker: AtomFamilies | SelectorFamilies<any, SerializableParam>,
  storeMap: Map<string, string>,
) {
  const refactoredTracker: AtomFamilies | SelectorFamilies<any, SerializableParam> = {};

  Object.keys(familyTracker).forEach((key) => {
    const newKey: string = storeMap.get(key) || key;
    refactoredTracker[newKey] = familyTracker[key];
  });

  return refactoredTracker;
}
Example #6
Source File: api.ts    From Chromogen with MIT License 6 votes vote down vote up
/* ----- ATOM FAMILY ----- */
export function atomFamily<T, P extends SerializableParam>(
  config: AtomFamilyOptions<T, P>,
): (params: P) => RecoilState<T> {
  const { atomFamilies } = ledger;
  const { key } = config;

  // Initialize new family in atomFamilies tracker
  atomFamilies[key] = {};

  return (params: P): RecoilState<T> => {
    const strParams = JSON.stringify(params);
    // If the atom has already been created, return from cache, otherwise we'll be creating a new
    // instance of an atom every time we invoke this func (which can lead to infinite re-render loop)
    const cachedAtom = atomFamilies[key][strParams];
    if (cachedAtom !== undefined) return cachedAtom;

    const newAtomFamilyMember = recoilAtomFamily(config)(params);
    // Storing every atom created except for dummy atom created by ChromogenObserver's onload useEffect hook
    if (strParams !== dummyParam) atomFamilies[key][strParams] = newAtomFamilyMember;
    return newAtomFamilyMember;
  };
}
Example #7
Source File: api.ts    From Chromogen with MIT License 6 votes vote down vote up
// Overload function signature
export function selectorFamily<T>(
  config:
    | ReadWriteSelectorFamilyOptions<T, SerializableParam>
    | ReadOnlySelectorFamilyOptions<T, SerializableParam>,
) {
  const { key, get } = config;
  const { transactions, selectorFamilies } = ledger;

  // Testing whether returned function from configGet is async
  if (
    !get
    || transactions.length > 0
    || get(dummyParam).constructor.name === 'AsyncFunction'
    || get(dummyParam)
      .toString()
      .match(/^\s*return\s*_.*\.apply\(this, arguments\);$/m)
  ) {
    return recoilSelectorFamily(config);
  }

  const getter = wrapFamilyGetter(key, get);

  const newConfig: SelectorFamilyConfig<any, SerializableParam> = { key, get: getter };

  let isSettable = false;

  if ('set' in config) {
    isSettable = true;
    const setter = wrapFamilySetter(key, config.set);
    newConfig.set = setter;
  }

  // Create selector generator & add to selectorFamily for test setup
  const trackedSelectorFamily = recoilSelectorFamily(newConfig);
  selectorFamilies[key] = { trackedSelectorFamily, prevParams: new Set(), isSettable };
  return trackedSelectorFamily;
}
Example #8
Source File: component-utils.ts    From Chromogen with MIT License 6 votes vote down vote up
generateFile = (setFile: Function, storeMap: Map<string, string>): string[] => {
  const {
    atoms,
    selectors,
    setters,
    atomFamilies,
    selectorFamilies,
    initialRender,
    initialRenderFamilies,
    transactions,
    setTransactions,
  } = ledger;

  const finalLedger: Ledger<string, any, SerializableParam> =
    storeMap.size > 0
      ? {
          atoms: atoms.map(({ key }) => storeMap.get(key) || key),
          selectors: selectors.map((key) => storeMap.get(key) || key),
          atomFamilies: convertFamilyTrackerKeys(atomFamilies, storeMap),
          selectorFamilies: convertFamilyTrackerKeys(selectorFamilies, storeMap),
          setters: setters.map((key) => storeMap.get(key) || key),
          initialRender: initialRender.map(({ key, value }) => {
            const newKey = storeMap.get(key) || key;
            return { key: newKey, value };
          }),
          initialRenderFamilies: initialRenderFamilies.map(({ key, value, params }) => {
            const newKey = storeMap.get(key) || key;
            return { key: newKey, value, params };
          }),
          transactions: transactions.map(({ state, updates, atomFamilyState, familyUpdates }) => {
            const newState = state.map((eachAtom) => {
              const key = storeMap.get(eachAtom.key) || eachAtom.key;
              return { ...eachAtom, key };
            });
            const newUpdates = updates.map((eachSelector) => {
              const key = storeMap.get(eachSelector.key) || eachSelector.key;
              const { value } = eachSelector;
              return { key, value };
            });
            const newAtomFamilyState = atomFamilyState.map((eachFamAtom) => {
              const family = storeMap.get(eachFamAtom.family) || eachFamAtom.family;
              const oldKey = eachFamAtom.key;
              const keySuffix = oldKey.substring(eachFamAtom.family.length);
              const key = family + keySuffix;
              return { ...eachFamAtom, family, key };
            });
            const newFamilyUpdates = familyUpdates.map((eachFamSelector) => {
              const key = storeMap.get(eachFamSelector.key) || eachFamSelector.key;
              return { ...eachFamSelector, key };
            });
            return {
              state: newState,
              updates: newUpdates,
              atomFamilyState: newAtomFamilyState,
              familyUpdates: newFamilyUpdates,
            };
          }),
          setTransactions: setTransactions.map(({ state, setter }) => {
            const newState = state.map((eachAtom) => {
              const key = storeMap.get(eachAtom.key) || eachAtom.key;
              return { ...eachAtom, key };
            });
            const newSetter = setter;
            if (newSetter) {
              const { key } = newSetter;
              newSetter.key = storeMap.get(key) || key;
            }
            return { state: newState, setter: newSetter };
          }),
        }
      : { ...ledger, atoms: atoms.map(({ key }) => key) };

  //return setFile(URL.createObjectURL(new Blob([output(finalLedger)])));
  const blob = new Blob([output(finalLedger)])
  setFile(URL.createObjectURL(blob));
  return [output(finalLedger)];
}
Example #9
Source File: output-utils.ts    From Chromogen with MIT License 6 votes vote down vote up
export function importRecoilFamily(
  familyObj: AtomFamilies | SelectorFamilies<any, SerializableParam>,
): string {
  return Object.keys(familyObj).reduce(
    (importStr, familyName) => `${importStr}\t${familyName},\n`,
    '',
  );
}
Example #10
Source File: ledger.ts    From Chromogen with MIT License 6 votes vote down vote up
ledger: Ledger<RecoilState<any>, any, SerializableParam> = {
  atoms: [],
  selectors: [], //get
  atomFamilies: {},
  selectorFamilies: {},
  setters: [], //set
  initialRender: [],
  initialRenderFamilies: [],
  transactions: [],//get
  setTransactions: [],//set
}
Example #11
Source File: output.ts    From Chromogen with MIT License 5 votes vote down vote up
output = ({
  atoms,
  selectors,
  setters,
  atomFamilies,
  selectorFamilies,
  initialRender,
  transactions,
  setTransactions,
}: Ledger<string, any, SerializableParam>): string =>
  `import { renderRecoilHook, act } from 'react-recoil-hooks-testing-library';
import { useRecoilValue, useRecoilState } from 'recoil';
import {
${
  importRecoilState(selectors)
  + importRecoilFamily(selectorFamilies)
}
} from '<ADD STORE FILEPATH>';
import { 
${
  importRecoilState(atoms)
  + importRecoilFamily(atomFamilies)
}
} from '<ADD ATOM FILEPATH>';

// Suppress 'Batcher' warnings from React / Recoil conflict
console.error = jest.fn();

// Hook to return atom/selector values and/or modifiers for react-recoil-hooks-testing-library
const useStoreHook = () => {
  // atoms
${writeableHook(atoms)}
  // writeable selectors
${writeableHook(setters)}
  // read-only selectors
${readableHook(setFilter(selectors, setters))}
  // atom families
${atomFamilyHook(transactions)}
  // writeable selector families
${selectorFamilyHook(selectorFamilies, true)}
  // read-only selector families
${selectorFamilyHook(selectorFamilies, false)}



  return {
${
  returnWriteable(atoms)
  + returnWriteable(setters)
  + returnReadable(setFilter(selectors, setters))
  + returnAtomFamily(transactions)
  + returnSelectorFamily(selectorFamilies, true)
  + returnSelectorFamily(selectorFamilies, false)
}\t};
};

describe('INITIAL RENDER', () => { 
  const { result } = renderRecoilHook(useStoreHook); 
  
${initializeSelectors(initialRender)}
});

describe('SELECTORS', () => {
${testSelectors(transactions)}});

describe('SETTERS', () => {
${testSetters(setTransactions)}});`