npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react2voby

v1.0.9

Published

Transform React code to Voby

Downloads

16

Readme

react2voby

Transform React code to Voby

Read 'rootDir' & 'exclude' from tsconfig.ts and outputs to ./voby folder

react2voby --config test.tsconfig.json

--config is optional

Online Transformer/Playground

See also use-voby

From (useState, useEffect, useCallback)

import React, { useCallback, useState, useEffect } from 'react'
import * as M from Math
import { random } from Math
import 'some'

export default function MyApp() {
    /* comment */
    const [count, setCount] = useState<number>(0)
    const [s] = useState(0)
    const a = useState([])
    const [, hack] = useState(0)
    const [] = useState(0)
    const arr = useState<{}>(null)
    const onClick = useCallback<() => void>(() => { })
    const [value, setValue] = useState(0)

    function handleClick() {
        setCount(count + 1)
    }

    useEffect(() => {
        (() => { })()

        console.log(arr[0])
        arr[1](123)
    }, [arr])

    React.useEffect(() => {
        (() => { })()

        console.log(count)
    }, [count])

    React.useEffect(() => {
        (() => { })()
        console.log(a[0][0])
    }, ...arr)

    const obj = { count, SS: s }

    const handleKeyDown = useCallback(
        (event: KeyboardEvent<HTMLSpanElement>) => {
            onKeyDown?.(event)

            if (tryToSubmitRelatedForm(event)) {
                return
            }

            if (
                ![" ", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"].includes(
                    event.key
                )
            ) {
                return
            }

            /* istanbul ignore next: can't really happen */
            const radio = (event.target as HTMLElement)?.closest<HTMLSpanElement>(
                '[role="radio"]'
            )
            if (!radio) {
                return
            }

            event.preventDefault()
            event.stopPropagation()
            if (event.key === " ") {
                radio.click()
                return
            }

            const increment =
                event.key === "ArrowRight" || event.key === "ArrowDown"
            const index = refs.findIndex(({ current }) => current === radio)
            /* istanbul ignore next: can't really happen */
            if (index !== -1) {
                const nextIndex = loop({
                    value: index,
                    max: items.length - 1,
                    increment,
                })
                refs[nextIndex].current?.focus()
                onChange(getRadioItemValue(items[nextIndex]))
            }
        },
        [onChange, onKeyDown]
    )


    // comment
    return <div style={{}} className="css">
        <h1>Counters that update separately</h1>
        <span>{count}{a}</span>
        <span>{s}</span>
        <button onClick={handleClick} value={value}>increment</button>
    </div>
}

Transformed code

import React, { $, useEffect } from 'voby'
import * as M from Math
import { random } from Math
import 'some'

export default function MyApp() {
    /* comment */
    const count = $<number>(0)
    const s = $(0)
    const a = $([])
    const hack = $(0)
    const {} = $(0)
    const arr = $<{}>(null)
    const onClick = () => { }
    const value = $(0)

    function handleClick() {
        count(count() + 1)
    }

    useEffect() => {
        (() => { })()

        console.log(arr())
        arr(123)
    }

    useEffect() => {
        (() => { })()

        console.log(count())
    }

    useEffect() => {
        (() => { })()
        console.log(a()
    }

    const obj = { count(), SS: s() }

    const handleKeyDown = (event: KeyboardEvent<HTMLSpanElement>) => {
            onKeyDown?.(event)

            if (tryToSubmitRelatedForm(event)) {
                return
            }

            if (
                ![" ", "ArrowLeft", "ArrowUp", "ArrowRight", "ArrowDown"].includes(
                    event.key
                )
            ) {
                return
            }

            /* istanbul ignore next: can't really happen */
            const radio = (event.target as HTMLElement)?.closest<HTMLSpanElement>(
                '[role="radio"]'
            )
            if (!radio) {
                return
            }

            event.preventDefault()
            event.stopPropagation()
            if (event.key === " ") {
                radio.click()
                return
            }

            const increment =
                event.key === "ArrowRight" || event.key === "ArrowDown"
            const index = refs.findIndex(({ current }) => current === radio)
            /* istanbul ignore next: can't really happen */
            if (index !== -1) {
                const nextIndex = loop({
                    value: value(),
                    max: items.length - 1,
                    increment,
                })
                refs[nextIndex].current.focus()
                onChange(getRadioItemValue(items[nextIndex]))
            }
        }


    // comment
    return <div style={{}} className="css">
        <h1>Counters that update separately</h1>
        <span>{count}{a}</span>
        <span>{s}</span>
        <button onClick={handleClick} value={value}>increment</button>
    </div>
}

From (useRef, useCallback)

import type { MutableRefObject } from "react";
import { useCallback, useRef } from "react";

type CurrentValueRef<T> = MutableRefObject<T>;
type SetValue<T> = (nextValue: T) => void;
type ResetValue = () => void;

type ReturnValue<T> = [CurrentValueRef<T>, SetValue<T>, ResetValue];

/**
 * Creates a temporary value that gets reset every `x`ms back to the provided
 * default value. This is useful when doing keyboard searching or other
 * interactions.
 *
 * NOTE: This does not force a re-render when the value changes and instead uses
 * a ref value instead.
 *
 * @typeParam T - the type for the value
 * @param defaultValue - The default value to use. Each time the reset timeout
 * is triggered, this value will be set again.
 * @param resetTime - The amount of time before the value is reset back to the
 * default value
 */
export function useTempValue<T>(
  defaultValue: T,
  resetTime = 500
): ReturnValue<T> {
  const value = useRef(defaultValue);
  const timeout = useRef<number>();
  const resetValue = useCallback(() => {
    window.clearTimeout(timeout.current);
    value.current = defaultValue;
  }, [defaultValue]);

  const setValue = useCallback(
    (nextValue: T) => {
      value.current = nextValue;
      window.clearTimeout(timeout.current);
      timeout.current = window.setTimeout(resetValue, resetTime);
    },
    [resetTime, resetValue]
  );

  return [value, setValue, resetValue];
}

Transformed code

import type { Observable } from 'voby';
import { $ } from 'voby';

type CurrentValueRef<T> = Observable<T>;
type SetValue<T> = (nextValue: T) => void;
type ResetValue = () => void;

type ReturnValue<T> = [CurrentValueRef<T>, SetValue<T>, ResetValue];

/**
 * Creates a temporary value that gets reset every `x`ms back to the provided
 * default value. This is useful when doing keyboard searching or other
 * interactions.
 *
 * NOTE: This does not force a re-render when the value changes and instead uses
 * a ref value instead.
 *
 * @typeParam T - the type for the value
 * @param defaultValue - The default value to use. Each time the reset timeout
 * is triggered, this value will be set again.
 * @param resetTime - The amount of time before the value is reset back to the
 * default value
 */
export function useTempValue<T>(
  defaultValue: T,
  resetTime = 500
): ReturnValue<T> {
  const value = $(defaultValue);
  const timeout = $<number>();
  const resetValue = () => {
    window.clearTimeout(timeout());
    value(defaultValue);
  };

  const setValue = (nextValue: T) => {
      value(nextValue);
      window.clearTimeout(timeout());
      timeout(window.setTimeout(resetValue, resetTime));
    };

  return [value, setValue, resetValue];
}

Known issues: Renamed imports will be not processed.

If https://github.com/phenomnomnominal/tsquery pull not done, please use this: https://github.com/wongchichong/tsquery