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

react-limitless

v0.0.0

Published

The next-gen react framework

Downloads

5

Readme

react-framework

This is my new side-project. The idea is a React framework that unifies RSC, SSR and CSR under an entreprise-grade model inspired from the springframework.

You will write code like the writing a spring application, you will define Resources (Controller) and Endpoints (MethodMapping):


@Resource("/users")
class UsersResource {
  @Render // returns react elements / html
  @PageRoot // declares this as a PageRoot (a full client page)
  @ProgressiveEnhancement // ship html, then js in a second round if needed
  @GetMapping({path: "/", produces: "text/html"}) // makes this reachable via /users/
  async getUsersList({context, query}) {
    let users = use(axios.get())
    // If this is not an RSC, hooks will be possible here
    return <UsersList users={users} />
  }
}

The UsersList component can be defined anywhere, and its contraints will depend from the project itself (CSR, SSR, RSC...).

In RSC/SSR, the framework's router will render your function and return its output. In CSR, the use hook will either apply hydration or suspend until it loads data.

Endpoints will be able to produce all forms of data types; meaning you can design API endpoints serving JSON, streaming files, etc.

/**
 * the following is an example of how we can define a UsersPage
 * this would offer:
 * access to a /users; that's a PageRoot
 *
 * access to a /users/:id/posts fragment, that can either be a full page or
 * a piece of the page; that is rendered separately
 *
 *
 * The component in /users would be able to spawn the fragment of /users/:id/posts if needed
 * that fragment can be:
 * - a React server component
 * - totally rendered on the server
 * - totally rendered in the client
 * The fragment will be ported back to the client if rendered in the server
 * and would update just itself. A hydration and state management solution could
 * be able to re-propagate a client state update if the hydration says so.
 * To be able to use this Fragment inside PageRoot; an API or a dedicated
 * component should be provided; like:
 * <PageRootComponent data={data}>
 *   <PageFragmentRef reference={app.users.getUserPosts} props={customProps} />
 * </PageRootComponent>
 *
 * PageFragmentRef then will look-up the getUserPosts and render it
 *
 * All components will have access to some custom context (current user...)
 *
 * Some APIs can return json, plain text, blob, etc rather than a ReactNode
 *
 * @PreAuthorize and other custom decorators can be created to extend the WebFilters API
 * and perform authorization limitation on resources
 *
 *
 * Aside from this whole thing, this will work as follows:
 *
 * # Dev-phase:
 * Where we write code
 * # Compilation phase (target: RSC, SSR, CSR...)
 * - lookup all `@Resource`s and decorated stuff and parse and prepare decorators behavior
 * - infer web filters to apply on requests (aka middlewares :) ) (CorsFilter, SecurityFilter, JwtFilter, FeatureFlagsFilter...)
 * - Decide on the structure on the bundle (client, server, both ...)
 * - code-split each API as an entrypoint and generate its standalone package
 * - prepare entrypoints
 * # Runtime phase
 * - boot the dispatcher (detect env and capabilities, loads apis and filters)
 * - intercept requests etc
 *
 */
@Resource(path="/users")
class UserResource {
  @Render // returns react elements / html
  @PageRoot // declares this as a PageRoot (a full client page)
  @ProgressiveEnhancement // ship html, then js in a second round if needed
  @GetMapping({path: "/", produces: "text/html"}) // makes this reachable via /users/
  async getUsersList({context, query}) {
    let currentUser = context.principal
    let users = use(axios.get())

    return <UsersList users={users} />
  }

  @Render // returns react elements / html
  @ProgressiveEnhancement // ship html, then js in a second round if needed
  @GetMapping({path: "/:id/posts", produces: "text/html"}) // makes this reachable via /users/14/posts
  // Without page root, this is a PageFragment; means can be CSRed or SSRed
  // or RSCed alone without any need to re-render the full page.
  // this may alter client state if needed as well ;)
  async getUserPosts({context, match}) {
    let currentUser = context.principal
    let posts = use(axios.get(`/users/${match.id}/posts`))

    return <UsersPosts posts={posts} />
  }

  @PreAuthorize // will trigger some authorizationFilter on this resource
  @GetMapping({ path: "/me", produces: 'application/json' })
  async getCurrentUserDetails({context}) {
    return use(getUserDetails(context.principal.id))
  }
}

function UsersList({users}) {
  return (
    <div>
      {users.map(user => <UserDetails key={user.id} user={user} />)}
    </div>
  )
}