Giter Site home page Giter Site logo

research's Introduction

research's People

Contributors

brillout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

research's Issues

A new kind of database: event-based + computed props + full-stack reactive + solid business model

Someone shares an image on Facebook:

  1. Database saves event "User X shared image https://example.org/image.jpg".
  2. Facebook defined a computed prop that downloads the image and meta data.

Someone clicks on the like button of the image:

  1. Database saves event "User Y likes image".
  2. Facebook defined a computed prop "total amount of likes" (the computed prop is just a JavaScript function that runs Math.sum() over the array of "User like" events) => the databse automatically re-runs the computed prop function => the computed prop is automatically updated.
  3. Row-level permissions:
    // Read
    export async function read({ row, context }) {
      if (context.user.role === 'admin') {
        return true
      }
      if( row.rolesAllowed.includes('public')) {
        return true
      }
      // Forbidden
      return false
    }
    // Mutations
    export async function write({ row, rowBefore, context }) {
      if (row.authorId === context.user.id) {
        return true
      }
      // `rowBefore` is `null` if mutation is `INSERT`
      if (rowBefore === null) {
        return true
      }
      return false
    }
  4. The database has a built-in ORM with deep UI framework (React, Vue, ...) integrations.
    import { useDb } from '@new-kind-of-database/react'
    
    function Image({ id }) {
      // `useDb.findOne()` is a React Hook (=> works with Suspense parent loader component)
      const { src, totalLikes } = useDb.findOne(id, select: {
        src: true,
        // We mark `totalLikes` as reactive => when `totalLikes` changes, the ORM
        // automaticallly updates the component (using React's hook system)
        totalLikes: 'reactive'
      })
    
      return <>
        <img src="{src}" />
        <p>
          Number of likes: {totalLikes}
        </p>
      </>
    }
    Everything is done automaticallly, e.g. the database automaticallly creates a socket connection to the server in order to listen to the corresponding database updates.

This leads to many drastic DX improvement, especially for user-centric highly-reactive apps such as Twitter or Facebook.

Solid business model: offer a SaaS with all bell and whistles (automatic scale, automatic backup, etc.). That said it's of paramount importance to fully support self-hosted, and open sourcing the entire source code (include of the SaaS). We are not afraid of AWS doing a SaaS clone; users will prefer the original over the AWS copy-cat.

If you feel drawn to work on this, let me know. Also, I'm ok with you being the CEO and me only being the "master mind" behind the whole thing.

Vite Server RFC

Authors: @cyco130, @brillout. (Let us know if you want to join us in writting this RFC.)

Structure of this RFC:

  • Motivation: why this RFC is important.
  • High-Level Goal: the future this RFC enables.
  • Plan: strategy of progressively implementing this RFC.

Motivation

Vite's native SSR API has enabled deep collaboration between SSR frameworks.

This RFC enables the same for deploy: there are an increasing number of deploy targets (Deno Edge, Supabase Functions, Netlify Functions, Vercel, Cloudflare Workers, AWS Lamda, AWS EC2, ...) and, instead of having each SSR framework reinventing the wheel, this RFC enables a common ecosystem of deploy integrations.

Deploy integration is deeply intertwined with the topic of how Vite should handle the server.

That's why this RFC is called Vite Server RFC. But the most important consequence of this RFC is a shared ecosystem of deploy integrations.

Vite is becoming the "Web Compiler Commons" that powers a flourishing ecosystem of tools and frameworks. This RFC spurs that.

High-Level Goal

The goal is to enable the following DX.

In this section, we intentionally skip middle- and low-level details. We discuss potential problems in comments to this RFC, and RFC related tickets (see Plan).

We show an example for Express.js and Cloudflare Workers.

Express.js Example

// vite.config.js

import { svelteKit } from 'sveltekit/plugin'
/* Or:
import { marko } from 'marko/plugin'
import { rakkas } from 'rakkas/plugin'
import { ssr } from 'vite-plugin-ssr/plugin'
*/

export default {
  // Note the new config `vite.config.js#server`
  server: './server.js'
  plugins: [
    svelteKit(),
  ],
}

Note that all these SSR frameworks (SvelteKit, Marko, Rakkas, vite-plugin-ssr) have shown intereset in such RFC.

// server.js

import express from 'express'
import { viteMiddleware } from 'vite/server/dev' // Vite's middleware for development
import { stripeMiddleware } from 'stripe/server'
import { expressAdapter } from 'vavite/express'

startServer()

async function startServer() {
  const app = express()

  app.use(expressAdapter([
    // `viteMiddleware` includes:
    //  - Vite's dev server
    //  - The middleware of Vite plugins, e.g. the SSR middleware of SevleteKit / ...
    viteMiddleware,
    stripeMiddleware,
    // ...
  ]))

  app.listen(3000)
  console.log(`Server running at http://localhost:3000`)
}

Vavite is a collection of adapters developed by @cyco130. Note that there is no lock-in here: both sides of adapters follow an open specification.

The server.js file above showcases Middleware Mode: the user manually sets up and controls the server. Middleware Mode is needed for advanced integrations such as Stripe. (This example makes Stripe integration seem easy, but a real world integration is more complex and warrants the need for Middleware Mode.)

The goal of this RFC is to also support Server Mode: the user uses Vite's built-in dev server. This means that, with Server Mode, the user doesn't have to write the server.js file.

Server Mode is the default but the user can opt-in Middleware Mode by setting vite.config.js#server.

If SSR frameworks show interests for it, we can develop a possibility for plugins (e.g. the SvelteKit plugin) to provide a custom built-in server for Server Mode, in replacement of Vite's built-in server.

CLI integration:

$ vite

The CLI command $ vite executes the server entry defined at vite.config.js#server (or, if missing, Vite's built-in server). It would support server HMR.

$ vite build

The CLI command $ vite build builds not only the browser-side JavaScript, but also the server entry defined at vite.config.js#server. (The user can then, for example, use the server production build for a production server on AWS EC2.)

Cloudflare Workers Example

// vite.config.js

import { cloudflareWorkers } from 'vite-plugin-cloudflare-workers'

import { svelteKit } from 'svleteKit/plugin'
/* Or:
import { marko } from 'marko/plugin'
import { rakkas } from 'rakkas/plugin'
import { ssr } from 'vite-plugin-ssr/plugin'
*/

export default {
  plugins: [
    svelteKit(),
    cloudflareWorkers({
      worker: './worker.js'
    })
  ]
}
// worker.js

// A Cloudflare Worker for production

import { viteMiddleware } from 'vite/server/prod' // Vite's middleware for production
import { stripeMiddleware } from 'stripe/server'
import { cloudflareAdapter } from 'vavite/cloudflare-workers'

const handler = cloudflareAdapter([
  // `viteMiddleware` includes the middlewares of all Vite plugins, e.g. the SSR middleware of SvelteKit
  viteMiddleware,
  stripeMiddleware,
  // ...
])

addEventListener('fetch', handler)

Here again, Middleware Mode is indispensable for advanced use cases. (FYI Stripe is actually showing interest in supporting Cloudflare Workers.) That said, vite-plugin-cloudflare-workers can provide a built-in worker to enable Server Mode for Cloudflare Workers.

CLI integration:

$ vite build

The CLI vite build takes care of everything, including bundling worker.js into a single file. (Plugins, such as vite-plugin-cloudflare-workers, can add a custom build step.)

$ vite deploy

Plugins, such as vite-plugin-cloudflare-workers, can provide a $ vite deploy implementation.

Vite's dev server assumes a filesystem, but no filesystem exists in the context of a Cloudflare worker. This means that $ vite uses Vite's built-in dev server instead of using worker.js.

Plan

We progressively implement parts of this RFC.

For example, we can start by implementing:

  • vitejs/vite#5936
  • vitejs/vite#6394
  • TODO: create ticket for allowing plugins to provide a deploy implementation for $ vite deploy.
  • TODO: create ticket for allowing plugins to add server middleware.
  • TODO: create tickets for vavite (e.g. ticket for dual support for connect-compatible middlewares as well as non-connect-compatible middlewares)
  • TODO: create ticket for implementing vavite-compatible Vite dev middleware.
  • ...

We progressively include implemented RFC parts into Vite releases. We don't foresee any breaking changes; we can hook into but not disrupt Vite's release lifecycle.

Stem

@cyco130 the new idea I was mentioning:

// package.json
{
  "dependencies": {
    "stem-react": "0.1.0",
    // For GraphQL users, instead of `stem-react`:
    "stem-react-relay": "0.1.0",
    "stem-react-apollo": "0.1.0",

    // For Vue users
    "stem-vue": "0.1.0",
    // Or:
    "stem-vue-relay": "0.1.0",

    "stem-zustand": "0.1.0",
    // Or:
    "stem-pinia": "0.1.0",

    "stem-tailwind": "0.1.0",
    "stem-sentry": "0.1.0",
    "stem-telefunc": "0.1.0",
    "stem-google-analytics": "0.1.0",
    "stem-sitemap": "0.1.0",
    // I don't think Prisma would need this, but you get the idea
    "stem-prisma": "0.1.0"
  }
}
// .env
GOOGLE_ANALYTICS=GA-12345
SENTRY=678910

Everything is zero-config, there is not even a need to import 'stem-react'. It's auto-loaded.

A stem.config.js for configuration is optional; the hope is that it's not needed most of the times.

All the user has to do is to write his components, data models, and telefunctions (or GraphQL queries).

Stem plugins can:

  • Extend vps
  • Extend Rakkas (@cyco130 if you want?)
  • Modify the Vite config
  • Add middlewares to HatTip
  • Add scripts to the client-side
  • Wrap the root view component

Stem is only a thin layer of automatic integrations on top of do-one-thing-do-it-well tools that are independent of each other.

Neat thing: there is no proprietary lock-in. It may seem like there is, but it's actually not the case. Let me elaborate.

// node_modules/stem-react/vite-plugin-ssr/_default.page.client.jsx

// The directory `stem-react/vite-plugin-ssr/` implements the integration with vps

export { render }

import React from 'react'
import { hydrateRoot } from 'react-dom/client'
import { PageShell } from './PageShell'

async function render(pageContext) {
  const { Page, pageProps } = pageContext
  hydrateRoot(
    document.getElementById('page-view'),
    <PageShell>
      <Page {...pageProps} />
    </PageShell>,
  )
}
// node_modules/stem-react/rakkas/client.jsx

// The directory `stem-react/rakkas/` implements the integration with Rakkas

// ...

This means stem-react can include integrations for both vps and rakkas. The only thing that is slightly "proprietary" is the stem- namespace (because we'll have the de-facto authority of what these stem- packages should or should not include). But anyone is free to introduce a new namespace. Bottom line: vps's extension mechanism is completly independent of HatTip's extension mechanism. This means anyone is free to ship an npm package that extends HatTip while also extending a new vps/Rakkas "competitor".

The no lock-in part is really neat, but it's going to be tricky to explain succinctly and clearly: at first sight, Stem will seem like "yet another monstrous monolith full of lock-in, doom to fail like Meteor". But I've idea for how to communicate that part.

Similarly to to Vite: there are Stem pugins and there are also Stem wrappers.

This means frameworks like Wind can still completely wrap things while using Stem plugins. Alternatively, Wind can use vps without Stem like it does today.

I'm thinking Vilay could be a stem-react-relay package. (We can still keep its name vilay though — I like that name. Just seeing that it now has a logo btw. 😀.)

CC @aleclarson @thetre97 @XiNiHa @Sajad-Sharhani

Imperative TypeScript alternative (drastically simpler than TypeScript)

The idea is to allow types to be defined imperatively:

type SomeType<T> = {
  if (T is string)
     return boolean
  if (T is SomeOtherType)
    return string
  return never
}

To-do:

  • Create a better example that showcases both how much simpler and how much more powerful imperatively defined types would be.
  • Create a new TypeScript feature request for it https://github.com/microsoft/TypeScript/issues. Ideally it is the TypeScript team that would add such feature to TypeScript. Otherwise, someone else will eventually create such imperative TypeScript alternative.

Contribution welcome to work on the to-do list above or even create a simple prototype.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.