loadmap 0.1 npm GitHub
Theme

Start

Without a bundler

Getting started assumes a bundler that understands new Worker(new URL(…, import.meta.url)), as Vite does: it finds the layout's worker next to @loadmap/react and serves it. Two pages that have none: one that loads everything from a CDN, and one HTML file that carries everything.

From a CDN

An import map points the bare names at esm.sh, which serves each package as a module and rewrites its imports; ?external=react,react-dom keeps one copy of React, the one the map names. JSX needs a compiler, so the page writes h(Loadmap, …); the model and the view are the quick start's.

<!doctype html>
<meta charset="utf-8">
<script type="importmap">
  {
    "imports": {
      "react": "https://esm.sh/react@19.3.1",
      "react/": "https://esm.sh/react@19.3.1/",
      "react-dom/client": "https://esm.sh/react-dom@19.3.1/client?external=react",
      "@loadmap/react": "https://esm.sh/@loadmap/react@0.26.0?external=react,react-dom"
    }
  }
</script>
<div id="root"></div>
<script type="module">
  import { createElement as h } from 'react'
  import { createRoot } from 'react-dom/client'
  import { defineModel, defineView, edge, Loadmap, measured, node, p, workerElk } from '@loadmap/react'

  const shop = defineModel({ /* the quick start's model */ })
  const view = defineView(shop, { /* and its view */ })

  // the layout's worker, from esm.sh through a Blob: a page cannot start a worker from another origin
  const worker = 'import "https://esm.sh/@loadmap/react@0.26.0/dist/elk.worker.js"'
  const elk = workerElk(() => new Worker(URL.createObjectURL(new Blob([worker], { type: 'text/javascript' })), { type: 'module' }))

  createRoot(document.getElementById('root')).render(h(Loadmap, { model: shop, view, elk }))
</script>

In one HTML file

For a page with no server at all, one file that opens from disk: Vite builds the page into one script, the worker inlined in it (?worker&inline), and a few lines put the script into the HTML. The page is the quick start's, then:

// page.jsx
import { createRoot } from 'react-dom/client'
import ElkWorker from '@loadmap/react/elk.worker.js?worker&inline'

// … the quick start's model and view, and workerElk in its import …

const elk = workerElk(() => new ElkWorker())
createRoot(document.getElementById('root')).render(<Loadmap model={shop} view={view} elk={elk} />)
// build.mjs: node build.mjs writes dist/shop.html
import { readFileSync, writeFileSync } from 'node:fs'
import { build } from 'vite'

await build({
  define: { 'process.env.NODE_ENV': '"production"' },
  build: {
    outDir: 'dist',
    minify: true,
    lib: { entry: 'page.jsx', formats: ['iife'], name: 'shop', fileName: () => 'page.js' },
    rolldownOptions: { output: { codeSplitting: false } },
  },
})
const js = readFileSync('dist/page.js', 'utf8').replace(/<\/script/gi, '<\\/script')
writeFileSync('dist/shop.html', `<!doctype html><meta charset="utf-8"><div id="root"></div><script>${js}</script>`)