A server side agnostic way to stream JavaScript.

Overview

JS in JSON

A server side agnostic way to stream JavaScript, ideal for:

  • inline hydration
  • network free ad-hoc dependencies
  • bootstrap on demand
  • libraries on demand
  • one JSON file to rule all SSR cases

The Session utility is currently available for:


An "islands friendly" approach to Server Side Rendering able to produce stream-able JS on demand, via any programming language, through a single JSON bundle file instrumented to flush() any script, after optional transpilation and/or minification.

The produced output can be also pre-generated and served as static content, with the advantages that js-in-json bundles require zero network activity: forget round-trips, thousand ESM requests per library or project, and simply provide all it's needed right on the page.

// a basic serving example
const {JSinJSON} = require('js-in-json');

// see ## Options
const {options} = require('./js-in-json-options.js');

const islands = JSinJSON(options);
// islands.save(); when needed to create the JSON bundle

http.createServer((req, res) => {
  // see ## Session
  const js = islands.session();
  js.add('Main');
  res.writeHead(200, {'content-type': 'text/html'});
  res.write(`
    <!doctype html>
    <script src="//external.cdn.js"></script>
    <script>${js.flush()}</script>
    <body>
      <div class="component"></div>
      <script>${js.add('UI/component').flush()}</script>
    </body>
  `.trim());
  js.add('Footer');
  if (global.condition) {
    js.add('SpecialCondition');
    res.write(`<script>${js.flush()}</script>`);
  }
  res.end();
});

Session

A js-in-json session can be initialized right away via js-in-json/session exported Session class, or through the main JSinJSON(options).session() utility.

A session created via JSinJSON optionally accepts a JSON bundle, retrieved from options, if not provided, and it exposes 2 methods:

  • add("ModuleName") to flush its content only once and, if repeatedly added, and available, bootstrap its code
  • flush() to return all modules and their dependencies previously added and, if available, their code to bootstrap

In order to have a session, a JSON bundle must be created.

Options

Following the object literal with all its defaults that can be passed to the JSinJSON(options) export.

const {save, session} = JSinJSON({

  // TOP LEVEL CONFIG ONLY

  // MANDATORY
  // the root folder from which each `input` is retrieved
  // used to resolve the optional output, if relative to this folder
  root: '/full/project/root/folder'

  // OPTIONAL
  // where to store the resulting JSON cache usable via JSinJSON.session(cache)
  // if omitted, the cache is still processed and returned
  output: './bundle.json',
  // the global context used to attach the `require` like function
  global: 'self',
  // the `require` like unique function name, automatically generated,
  // and it's different per each saved JSON (hint: don't specify it)
  prefix: '_uid',


  // OPTIONAL EXTRAS: CAN BE OVERWRITTEN PER EACH MODULE
  // use Babel transformer to target @babel/preset-env
  babel: true,
  // use terser to minify produced code
  minify: true,
  // transform specific bare imports into other imports, it's {} by default
  // see: rollup-plugin-includepaths
  replace: {
    // example: replace CE polyfill with an empty file
    '@ungap/custom-elements': './empty.js'
  },
  // executed each time a JSinJSON.session.flush() happens
  // no matter which module has been added to the stack
  // it's missing/no-op by default and it has no access
  // to the outer scope of this file (it's serialized as function)
  code(require) {
    // each code receives the `require` like function
    const {upgradeAll} = require('Bootstrap');
    upgradeAll();
  },
  // an object literal to define all modules flushed in the page
  // whenever any of these is needed
  modules: {
    // the module name available via the `require` like function
    Bootstrap: {
      // MANDATORY
      // the ESM entry point for this module
      input: './bootstrap.js',

      // OPTIONAL: overwrite top level options per each module
      // don't transform and/or don't minify
      babel: false,
      minify: false,
      // will be merged with the top level
      replace: {'other': './file.js'},
      // don't flush anything when injected
      code: null
    },

    // other module example
    Login: {
      input: './login.js',
      code() {
        document.documentElement.classList.add('wait');
        fetch('/login/challenge').then(b => b.json).then(result => {
          self.challenge = result;
          document.documentElement.classList.remove('wait');
        });
      }
    }
  }
});

Options Rules / Limitations

  • the root should better be a fully qualified path, instead of relative
  • the code is always transformed with @babel/preset-env target
  • the code cannot be asynchronous
  • modules cannot have _ as name prefix, that's reserved for internal resolutions
  • modules should have non-npm modules names, to avoid conflicts/clashing with imports
  • modules can be capitalized
You might also like...

catbot-9000 is a javascript market-loser bot running on node.js.

catbot-9000 catbot-9000 is a Chia bot framework running on node.js. It was used during the CATMOS launch event on Hashgreen. If you are looking for th

Nov 16, 2022

Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation

Aphrodite Framework-agnostic CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation. Support for colocating y

Jan 1, 2023

Fast and minimal JS head server-side writer and client-side manager.

unihead Fast and minimal JS head server-side writer and client-side manager. Nearly every SSR framework out there relies on server-side components t

Sep 4, 2022

Easy server-side and client-side validation for FormData, URLSearchParams and JSON data in your Fresh app 🍋

Fresh Validation 🍋     Easily validate FormData, URLSearchParams and JSON data in your Fresh app server-side or client-side! Validation Fresh Validat

Dec 23, 2022

Restream is a module that allows you to create a stream of an audio/video file from the Firebase storage, protected from direct download through the client-side.

nuxt-restream Restream is a module that allows you to create a stream of an audio/video file from the Firebase storage, protected from direct download

Dec 13, 2022

It shows an effective way to correct bus arrival information using data analytics based on Amazon Serverless such as Kiness Data Stream, Kinesis Data Firehose, S3, and Lambda.

It shows an effective way to correct bus arrival information using data analytics based on Amazon Serverless such as Kiness Data Stream, Kinesis Data Firehose, S3, and Lambda.

Amazon Serverless를 이용한 실시간 버스 정보 수집 및 저장 본 github repository는 버스 정보를 주기적으로 수집하여 분석할 수 있도록, Amazon Serverless인 Amazon Kinesis Data Stream, Kinesis Data

Nov 13, 2022

framework-agnostic styled alert system for javascript

SMOKE.JS - 0.1.3 Notify or get approval from your users quickly and with style. This alert system uses css animations and background (so there are no

Dec 25, 2022

Make drag-and-drop easier using DropPoint. Drag content without having to open side-by-side windows

Make drag-and-drop easier using DropPoint. Drag content without having to open side-by-side windows

Make drag-and-drop easier using DropPoint! DropPoint helps you drag content without having to open side-by-side windows Works on Windows, Linux and Ma

Dec 29, 2022

This is an application that entered the market with a mobile application in real life. We wrote the backend side with node.js and the mobile side with flutter.

HAUSE TAXI API Get Started Must be installed on your computer Git Node Firebase Database Config You should read this easy documentation Firebase-Fires

Nov 4, 2021

This plugin allows side-by-side notetaking with videos. Annotate your notes with timestamps to directly control the video and remember where each note comes from.

Obsidian Timestamp Notes Use Case Hello Obsidian users! Like all of you, I love using Obsidian for taking notes. My usual workflow is a video in my br

Jan 2, 2023

This Plugin is For Logseq. If you're using wide monitors, you can place journals, linked references, and journal queries side by side.

This Plugin is For Logseq. If you're using wide monitors, you can place journals, linked references, and journal queries side by side.

Logseq Column-Layout Plugin Journals, linked references, and journal queries can be placed side by side if the minimum screen width is "1850px" or mor

Dec 14, 2022

Simple example script that receives the signal from one iptv channel and relays it via websocket to another server to replicate the stream to multiple players

Simple example script that receives the signal from one iptv channel and relays it via websocket to another server to replicate the stream to multiple players

Simple example script that receives the signal from one iptv channel and relays it via websocket to another server to replicate the stream to multiple players

Feb 20, 2022

MQTT broker that can run on any stream server

 MQTT broker that can run on any stream server

Nest.js MQTT broker that can run on any stream server Topics What is MQTT ? Installation Usage Handlers Events Methods Packets Middleware & Plugins De

Nov 26, 2022

:dizzy: TransitionEnd is an agnostic and cross-browser library to work with transitionend event.

TransitionEnd TransitionEnd is an agnostic and cross-browser library to work with event transitionend. Browser Support 1.0+ ✔ 4.0+ ✔ 10+ ✔ 10.5 ✔ 3.2+

Dec 21, 2022

A renderer agnostic two-dimensional drawing api for the web.

Two.js A two-dimensional drawing api meant for modern browsers. It is renderer agnostic enabling the same api to render in multiple contexts: webgl, c

Dec 31, 2022

:musical_score: ts-audio is an agnostic library that makes it easy to work with AudioContext and create audio playlists in the browser

ts-audio · ts-audio is an agnostic and easy-to-use library to work with the AudioContext API and create Playlists. Features Simple API that abstracts

Dec 25, 2022

Placebo, a beautiful new language agnostic diagnostics printer! It won't solve your problems, but you will feel better about them.

Placebo, a beautiful new language agnostic diagnostics printer! It won't solve your problems, but you will feel better about them.

Placebo A beautiful new language agnostic diagnostics printer! ┌─[./README.md] │ 1 │ What is Placebo? · ───┬──── ·

Dec 16, 2022

Library agnostic in-process recording of http(s) requests and responses

@gr2m/http-recorder Library agnostic in-process recording of http(s) requests and responses Install npm install @gr2m/http-recorder Usage import http

May 12, 2022
Comments
  • blog post?

    blog post?

    Hi, as always you are making some neat stuff. But lately it is beyond me; I'm still not sure what this is for? Maybe I could use better examples &/or why use this over other tech.

    (No need to reply right away; I assume you or someone else will blog about your latest stuff, so just link here if you happen to remember please.)

    opened by tomByrer 1
Owner
Andrea Giammarchi
Web, Mobile, IoT and all Web & JS things since 00's
Andrea Giammarchi
Async node.js implementation of the UDP Minecraft Server Query Protocol and TCP Minecraft Server List Ping Protocol

?? Mc Server Status Async node.js implementation of the UDP Minecraft Server Query Protocol and TCP Minecraft Server List Ping Protocol. Also availabl

Daniel 5 Nov 10, 2022
HTTP server mocking and expectations library for Node.js

Nock HTTP server mocking and expectations library for Node.js Nock can be used to test modules that perform HTTP requests in isolation. For instance,

Nock 11.9k Jan 3, 2023
SPDY server on Node.js

SPDY Server for node.js With this module you can create HTTP2 / SPDY servers in node.js with natural http module interface and fallback to regular htt

SPDY & HTTP2 in JavaScript 2.8k Jan 4, 2023
:dash: Simple yet powerful file-based mock server with recording abilities

?? smoke Simple yet powerful file-based mock server with recording abilities Just drop a bunch of (JSON) files in a folder and you're ready to go! Bas

Yohan Lasorsa 159 Dec 13, 2022
An HTTP Web Server for Chrome (chrome.sockets API)

An HTTP Web Server for Chrome (chrome.sockets API)

Kyle Graehl 1.2k Dec 31, 2022
A TurboRepo local cache server which uploads artifact cache to GH artifacts.

TurboRepo Github Artifacts action This action allows you use Github artifacts as TurboRepo remote cache server. How it works? It's starts a local Turb

Felix Mosheev 65 Dec 18, 2022
Node.js web server framework for Http/1.1 or Http/2

Node.js web server framework for Http/1.1 or Http/2 Description: This is http framework, you can use it to create Http/1.1 or Http/2 service。 Now let'

Jeremy Yu 10 Mar 24, 2022
A window.fetch JavaScript polyfill.

window.fetch polyfill The fetch() function is a Promise-based mechanism for programmatically making web requests in the browser. This project is a pol

GitHub 25.6k Jan 4, 2023
Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes.

http-fake-backend Build a fake backend by providing the content of JSON files or JavaScript objects through configurable routes. It actually can serve

Micromata GmbH 279 Dec 11, 2022
A JavaScript, zero-dependency, super small version of IP2Location LITE country lookups.

ip3country This is a zero-dependency, super small, IP address to 2-letter country code lookup library. There are already several libraries available,

Statsig 34 Dec 14, 2022