Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rfc: add Declartive Bindings to fast-element #6914

Open
mohamedmansour opened this issue Feb 23, 2024 · 0 comments
Open

rfc: add Declartive Bindings to fast-element #6914

mohamedmansour opened this issue Feb 23, 2024 · 0 comments
Labels
area:fast-element Pertains to fast-element area:ssr Pertains to SSR. status:needs-investigation Needs additional investigation status:under-consideration Issue is being reviewed by the team.

Comments

@mohamedmansour
Copy link

💬 RFC

Update FAST-Element Templating to understand declarative bindings

🔦 Context

I am proposing a new Web Architecture called "Build Time Rendering" BTR for short that combines the insights gained from integrating Islands, SSR, and SSG. BTR determines the rendering process in advance, guided by cues provided by the web application itself. A key feature of BTR is the introduction of a simplified streaming protocol. This protocol is language-agnostic, enabling web servers written in any programming language to deliver experiences akin to SSR, eliminating the dependency on Node.js.

BDR requires hints within your web application relating to conditionals, lists, and variables. During the post-build process, these hints facilitate the division of the initially rendered page into streamable segments. The server no longer requires Node.js, as its primary function becomes reading the protocol of these streamable chunks and writing to the stream.

Only three declarative bindings are needed to facilitate the BTR process in generating streamable chunks post build process. The client side JavaScript will use these bindings when it hydrates the DOM into each Web Component’s @observable decorator. These bindings adhere to the dot notation, thereby supporting any JSON/Object notations. Finally, the client will resume as it was.

At the end, zero JavaScript is needed for FCP since everything will be streamed in from server. JS will kick in after paint, to add resumability with Web Components to make them interactive.

Minimum Declarative Bindings needed

To make that BDR concept work for FAST Element, we need to introduce three attributes that FAST understands. Intentionally named it after fast nomenclature.

f-signal

The f-signal binding serves as a wrapper around a value, capable of alerting relevant consumers when the value undergoes a change.

<div f-signal=”name”>Default Name</div>

In this example, the name class variable within the Web Component is assigned to the value "Default Name". Any mutation to this.name triggers an update in the corresponding DOM element.

f-when

The f-when binding is a conditional element that can toggle between true and false states.

<span f-when=”active”>Active</span>  

In this instance, the active class variable within the Web Component is set to true. If the user alters this to false, the associated element ceases to be displayed. It supports these operators '&&', '||', '!', '==', '>', '>=', '<', '<=' and supports object dot notations.

f-repeat

The f-repeat binding represents an array of templates.

<div f-repeat=”users” w-component=”name-item”>
  <name-item>Mohamed</name-item>
  <name-item>Alex</name-item>
  <name-item>Andrew</name-item>
  <name-item>Lisa</name-item>
</div>

In the above example, users class variable in the Web Component is set to a list of names that it is set to what its current children are. Same as the other bindings, once mutated, the DOM mutates. I am still not strict on convention, the w-component here just tells it what the web component for the children is, but it would be better if the f-repeat was a list of objects, then we could reserve two keys (key, and component) so we could create dynamic components.

💻 Examples

The following is a todo app, fully streamable, fully SSRable, requires 0 JS at start, and resumability happens after paint fast:

  <div class="header">
    Todo (<span f-signal="items.length">0</span>)
  </div>
  
  <p class="toast" f-when="toast" f-signal="toast"></p>
  
  <div>
    <app-button f-on-click="onClick">Add New</app-button>
    <app-button f-on-click="onClear">Clear All</app-button>
  </div>
  
  <div f-when="items.length > 5">You have more than 5 items!</div>
  
  <div class="items" f-repeat="items" w-component="app-item">
  </div>
  
  <div f-when="!items.length">No items to show</div>
@customElement({ name: 'app-shell', cssModule: './app-shell.css' })
export class AppElement extends FASTElement {
  @observer
  toast: string | null = null

  @observer
  items: string[] = []


  onClick(_e: Event) {
    this.setItems([...this.items, `Item ${++this.itemId}`])
    this.setToast(`Item ${this.itemId} added`)
  }

  onClear(_e: Event) {
    this.setItems([])
    this.setToast('Items cleared')
  }


  setItems(items: string[]) {
    this.items = items
    fetch('/api/items', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(items),
    })
  }

  setToast(msg: string | null) {
    this.toast = msg
    if (msg) {
      clearTimeout(this.toastId)
      this.toastId = window.setTimeout(() => {
        this.toast = null
      }, 2000)
    }
  }
}

Prototype

I have created a micro (1.75KB) FAST Element framework which does this end to end. Please take a look at the repo https://github.com/mohamedmansour/build-time-rendering-js where end to end prototype showcases how this works.

@mohamedmansour mohamedmansour added the status:triage New Issue - needs triage label Feb 23, 2024
@janechu janechu added status:under-consideration Issue is being reviewed by the team. area:fast-element Pertains to fast-element area:ssr Pertains to SSR. status:needs-investigation Needs additional investigation and removed status:triage New Issue - needs triage labels May 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:fast-element Pertains to fast-element area:ssr Pertains to SSR. status:needs-investigation Needs additional investigation status:under-consideration Issue is being reviewed by the team.
Projects
None yet
Development

No branches or pull requests

2 participants