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

@replit/workspace

v2.5.2

Published

[![Run on Repl.it](https://repl.it/badge/github/replit/workspace)](https://repl.it/github/replit/workspace)

Downloads

91

Readme

workspace

Run on Repl.it

to run the dev server locally:

  • run yarn in the repos root
  • then yarn start:dev
  • should be up and running with a dev server at localhost:1234

Technology and architecture

At its core the workspace consists of a window manager and an event bus/state manager. In reality the architecutre can be used for building any application, we only use it to build the IDE at repl.it.

You should read Mason's blog post to understand why we ended up building our IDE using this technology and to get a high level overview of what the main constituents are. We'll divelge into details below, focusing on how to build a plugin.

disclaimer this is work in progress and the API will likely change, there are some nuances that are under heavy consideration. The core architecture will remain the same and we'll probably provide a backwards compatibility layer for old plugins

Prequisits

Although the core of the architecture does not rely on it but we decided to go with React for rendering and window management and Redux for message passing and state management.

Plugins

A plugin can consist of a reducer (internal state builder), receiver (a side-effect manager), and/or a component (react component). A plugin can have one or more of these parts.

Reducer

Each plugin builds its state from actions that are passed to it. They are no different from Redux Reducers.

Plugins can only reach into their own state, since actions are global any state a plugin needs can be built in the reducers.

Receiver

Since reducers should be pure functions but real applications generally need some way to do side-effects we introduced the concept of receivers. Receivers are implemented using Redux Middlewares. Receivers get an action and return a function that gets dispatch and getState passed, the returned function is basically a redux thunk.

Receivers' signature looks like this.

function receiver(
  workspaceId: Opaque<string>,
  pluginId: Opaque<string>,
  action: string,
): null | Thunk;

type Thunk = (dispatch: ReduxDispatch, getState: ReduxGetState) => any;

We hope to get rid of pluginId and workspaceId as we clearup some things, see the state fiasco below.

The state fiasco

  • wid = workspace id
  • pud = plugin id

For now to access a plugin's state, you would getState().workspace[wid].plugins[pud].state. Reaching into another plugin's state will get you fired.

Also when you dispatch an action that needs to be consumed by the workspace you should include the workspace id (wid). So your action would like this, dispatch({ wid, type: 'EVAL' }). If your notice you're actions aren't being passed to the reducers, this is probably why, we're sorry, we'll fix this soon. Something that you might find useful is that if you also include pud the action will only be consumed by your plugin (reducer/receiver)

For historical reasons, we eneded up having some global state that's shared between plugins, see here, we can easily move these to be part of each plugin's internal state for the plugins that need them, right now they're part of the core's reducer. if you wanna access this state: getState().workspace[wid].activeFile.

Also there is some state that's outside the workspace's state this is because we had a gradual move to the workspace from our redux app, see here. To access this state: getState().user

Components

Components are just good old React components. They recieve the following props from the window manager:

  wid: string;
  pud: string;
  style: { [prop: string]: string | number };
  dimensions: { w: { px: number; pc: number }; h: { px: number; pc: number } };
  theme: ReplitThemes;
  • wid is for you dispatch actions and access state
  • pud is for accessing state
  • style should be passed to your top level div (it's literally just width: 100%, height: 100%)
  • dimensions are calculated by the window manager, you can use it to figure out your plugin's dimensions, you generally don't need this
  • Themes are a string oneof 'replitlight' | 'replitdark', these should be explained elsewhere (ping Tim for now) but it's what we use for theming and we'll be looking into a more robust thing that probably passes the full theme object.

You can wrap your component in react-redux's connect or use the react-redux hooks to access state, you can use wid and pud props if you need as explained in the state fiasco.