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

spalatum

v4.1.0

Published

Render template and fragments

Downloads

3

Readme

Spalatum

All Contributors

Spalatum is a library to merge different fragment sources into a single template. With Spalatum you can get multiple external fragments and serve all together in your html page. This project is based on Tailor.

Some of Spalatum features and benefits:

  • Composes pre-rendered markup on the backend. This is important for SEO and fastens the initial render.
  • Enforces performance budget. This is quite challenging otherwise, because there is no single point where you can control performance.
  • Cache Management - When you use cache attribute in <fragment> tag, your app performace will be improved. With spalatum's cache management we give you the power to see what is cached, delete some specific endpoint or just purge all cached fragment.
  • Remove duplicated assets - Spalatum avoid multiple requests for an external Javascript or CSS, preserving only the first. So, if you have 2 or more fragments importing the same JS/CSS lib, we will remove all duplicated call starting from the second.

Before start

Before start, you must understand Fragment.

Fragment

We understand "Fragment" as every endpoint hosted on http(s) server that provide the content you want to include in your page. If you want to use some specific js or css, you can use script, style, Link or any other tags in your template page to provide this resources. Check our example app using Spalatum for the skeleton implementation.

Fragment Tag

You can represent a Fragment using the <fragment /> tag with this attributes: href, proxy, cache.

href (needed)

Represent the endpoint that provide the content you want to include in your page.

This endpoint must returns 200 as status code and text/html as content-type. Otherwise it will not be rendered.

Example:

<fragment href="http://example.fragment.com/" />
primary (optional)

Represents the main content. You can use only once primary attribute per template. If the request throws any error, will be returned an error object instead of the rendered html.

Example:

<fragment href="http://example.fragment.com/" primary />

Error object example:

{
    message: 'Spalatum can't render the primary fragment ({fragment.href}), the returned statusCode was {response.status}.',
    statusCode: 500
}

proxy (optional)

If your href need to be accessed via proxy, use the complete proxy url as PROTOCOL://HOST:PORT

Example:

<fragment href="http://example.fragment.com/" proxy="https://127.0.0.1:8081" />
cache (optional)

The presence of cache attribute is optional, if you use, the fragment will be cached as you specify, if you don't, the fragment will be requested each time the page is loaded.

Spalatum represent cache lifetime as Momentjs does.

Example:

| Time | Cache attribute | |-----|:-----------| | no cache | don't use the cache attribute | | 10 years | 10y | | 3 quarters | 3Q | | 6 months | 6M | | 2 weeks | 2w | | 7 days | 7d | | 5 hours | 5h | | 12 minutes | 12m | | 3 seconds | 3s | | 5000 milliseconds | 5000ms |

So, if you need to cache some fragment, you can use the cache attribute to represent how many time you want to cache.

Example:

Caching the fragment for 10 minutes:
<fragment href="http://example.fragment.com/" cache="10m" />
Caching the fragment for 10 days:
<fragment href="http://example.fragment.com/" cache="10d" />
No Cache:

If you don't want to use cache, just ommit the attribute:

<fragment href="http://example.fragment.com/" />

If you want to know how this cache works "under the hood", see the cache diagram for more details.


Instalation

Use the command below to add Spalatum as your project dependencie:

# You can use yarn, as well
npm install spalatum

Getting Started

To get started, you can create your own app using "spalatum": "^VERSION" as dependencie in your package.json; or clone the app skeleton using nodejs and Spalatum (RECOMENDED) that we provide.

Example

Given you have this template:

<html>
  <body>
    <fragment href="http://example.fragment.com/" />
  </body>
</html>

And the route http://example.fragment.com/ responds with:

<header>
  <h1>This is a Fragment</h1>
</header>

Spalatum will return:

<html>
  <body>
    <header>
      <h1>This is a Fragment</h1>
    </header>
  </body>
</html>

It's possible to set a proxy server as a fragment attribute, if needed:

  <!-- Note that it's required to set the protocol (`http(s)`) in the proxy url attribute -->
  <fragment href="http://example.fragment.com/" proxy="http://example.proxyserver.com" />

You can set how many time you want to cache some fragment attribute using proxy too:

  <!-- Note that it's required to set the protocol (`http(s)`) in the proxy url attribute -->
  <fragment href="http://example.fragment.com/" proxy="http://example.proxyserver.com" cache="1d" />

You can use multiple fragments together to assembly a web application:

<html>
  <body>
    <fragment href="http://header.fragment.com/" cache="1w" />
    <div>Main Localy Rendered App</div>
    <fragment href="http://banner.fragment.com/" proxy="http://proxyserver.com" />
    <fragment href="http://footer.fragment.com/" cache="1w" />
  </body>
</html>

This nodejs example create a Spalatum instance, setting to it a cache object, then call the render method passing to it a template string that returns a Promise instance, which will be resolved with the parsed html or reject in error case:

const spalatum = require('spalatum');
const express = require('express');

const app = express();

app.get('/', async (req, res) => {
  const template = `
    <html>
      <body>
        <fragment href="https://github.com/catho/spalatum" />
      </body>
    </html>
  `;

  const templateResult = await spalatum.render(template);
  res.send(templateResult);
});

app.listen(3000);

Also, the render method accepts a custom header object, if you need to pass headers between all fragments.

  ...

  const headers = {
    Cookies: 'foo=bar',
    'Content-type': 'text/html',
  }

  const templateResult = await spalatum.render(template, { headers });

  ...

Caching

When you use the fragment tag and add a cache attribute, internally, the Spalatum create a cache object that store: href (as key), content, timestamp.

  cacheObject = {
    '[href]': {
      content: '[encrypted_fragment_content]',
      timestamp: '[cache_expiration_time]'
    }
  }

If you want, you can manage the cache inside your Spalatum instance.

Cache Management

There are some methods that you can use to manage Spalatum cache: getCache, clearCacheItem, clearAllCache.

Spalatum.getCache

Returns the cache object.

  {
    'http://localhost:9000/': {
      content: 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kN2w5MWduV0EzSQ==',
      timestamp: '2017-10-10T15:10:33-03:00'
    },
    'http://localhost:9001/': {
      content: 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1KNXdmNlVNWkVZNA==',
      timestamp: '2017-10-10T15:10:33-03:00'
    }
  }

Spalatum.clearCacheItem(endpoint)

Remove a specific cache item by endpoint.

Given you have some cache:

  {
    'http://localhost:9000/': {
      ...
    },
    'http://localhost:9001/': {
      ...
    }
  }

When you call the method Spalatum.clearCacheItem('http://localhost:9000/'), this specified endpoint will be removed and the cache object will be:

  {
    'http://localhost:9001/': {
      ...
    }
  }

Spalatum.clearAllCache()

Remove all cache items from cacheObject.

Given you have this cache:

  {
    'http://localhost:9000/': {
      ...
    }
  }

When you call the method Spalatum.clearAllCache(), all cached endpoints will be removed and the cache object will be:

  {}

Contributing

Technical prerequisites

Clone this repository:

git clone https://github.com/catho/spalatum

Access the folder and install the project's dependencies:

cd spalatum && npm install

Before send a pull request, always runs the unit tests:

npm test
# or
npm run coverage

Contributors

Thanks goes to these wonderful people (emoji key):

| Allysson dos Santos💻 📖 👀 | Daniel Silva💻 📖 👀 | Luiz Kota💻 📖 👀 | José Luiz Coe💻 📖 👀 | Gabriel Gonçalves Daltoso💻 📖 👀 | Alan Oliv.💻 👀 | | :---: | :---: | :---: | :---: | :---: | :---: |

This project follows the all-contributors specification. Contributions of any kind welcome!