Navigation

Node service example

This tour builds a tiny HTTP service from server.js. The point is not to mimic a full Node packaging API; it is to show how a builder can name its domain concepts and then expose several views of the same build.

The worked artifact is a runnable package with a copied service source, generated package metadata, a wrapper script, an HTTP service descriptor, a runtime unit declaration, and a materialization plan.

Start from the artifact

The source fixture is one file: node-service/server.js. The builder turns that file into a runnable tree:

  • bin/node-service-demo starts the service with Node.
  • lib/node-service-demo/server.js contains the copied source.
  • share/node-service-demo/package.json is generated from the typed builder spec.
  • the runtime view describes the service as HTTP on port 3000 with a /health endpoint.

Source files

These pages are the complete source for the worked example: the builder module plus the files it consumes.

  • Node service builder module - Source for the Node service builder constructor and worked demo program.
  • server.js - HTTP service fixture copied into the materialized Node demo package.

Builder vocabulary

NodeServiceBuilder ornaments the generic BuilderSpec with the fields a service builder cares about: runtime version, entrypoint, package manager, script table, test command, service descriptor, and runtime operations. The constructor keeps the public surface small.

nix
nodeService {
  name = "node-service-demo";
  source = ./node-service/server.js;
}

Program walkthrough

The constructor lowers the service spec into an internalized program. The builder-facing operations read the source, declare node and bash, generate package.json, run a syntax check, install the runnable tree, emit metadata, and declare the materialized outputs.

The runtime operations are part of the same program. They declare the lifecycle capability set, the HTTP protocol, the concrete service, and the runtime unit. That is why dependency analysis, dry-run output, plan-view output, and self-documentation all see the service shape.

One build, many views

The section below is generated from mb.program.introspect.run program. It is not a hand-written summary. It validates the program, extracts the dependency graph, renders dry-run and plan-view output, includes service descriptors, and reports the materialized outputs.

The same internalized program is interpreted several ways.

Validation

  • result: ok

Dependency Graph

  • nodes: 5
  • edges: 2
  • services: 1
  • node tool:node (tool) package nodejs
  • node tool:bash (tool) package bash-interactive
  • node operation:syntax-check (operation) via node
  • node operation:install-service (operation) via bash
  • node service:node-service-demo-service (service) package nodejs
  • edge tool:node -> operation:syntax-check (uses-tool)
  • edge tool:bash -> operation:install-service (uses-tool)

Dry Run - Builder

  • source server.js
  • tool node
  • tool bash
  • write share/node-service-demo/package.json
  • run syntax-check with node
  • run install-service with bash
  • descriptor node-service-demo-metadata
  • transform service-tree (tree)
  • transform package-json (json)
  • materialize node-service-demo-artifact with runCommand
  • evidence self-test

Dry Run - Runtime

  • runtime capability lifecycle
  • runtime protocol http
  • runtime service node-service-demo-service
  • runtime unit node-service-demo-service

Plan View

  • write write:share/node-service-demo/package.json
  • run syntax-check
  • run install-service
  • write:share/node-service-demo/package.json: mkdir -p "$(dirname "$out/share/node-service-demo/package.json")"
  • syntax-check: node --check "$pathMap_85e860eb67550a011692fa61e2a4543318fcdb72bf6de38c7f85842029ee99ae"
  • install-service: bash -c 'set -eu

Plan Shell Excerpt

sh
pathMap_85e860eb67550a011692fa61e2a4543318fcdb72bf6de38c7f85842029ee99ae=<source:server.js>
mkdir -p "$(dirname "$out/share/node-service-demo/package.json")"
cat > "$out/share/node-service-demo/package.json" <<'METABUILDER_HEREDOC_83625931feff0ed1f14d2f61a28aea1a87b63276765f4ca0cc2bceddf130aeed'
{"main":"server.js","name":"node-service-demo","private":true,"scripts":{"start":"node server.js","test":"node --check server.js"},"type":"module","version":"0.1.0"}
METABUILDER_HEREDOC_83625931feff0ed1f14d2f61a28aea1a87b63276765f4ca0cc2bceddf130aeed
node --check "$pathMap_85e860eb67550a011692fa61e2a4543318fcdb72bf6de38c7f85842029ee99ae"
bash -c 'set -eu
src="$1"
mkdir -p "'"$out"'/bin" "'"$out"'/lib/node-service-demo" "'"$out"'/share/node-service-demo"
cp "$src" "'"$out"'/lib/node-service-demo/server.js"

Runtime Services

  • service node-service-demo-service exposes http/TCP/JSON PORT:3000; capabilities start, stop, health

Descriptors

  • descriptor node-service-demo-metadata (payload keys entrypoint, healthPath, kind, packageManager, port, runtimeVersion)

Builder Self-Documentation

  • documented operations: 15
  • runtime services: 1

Materialized Outputs

  • service-tree -> $out (tree)
  • package-json -> share/node-service-demo/package.json (json)

Materialization

  • derivation: node-service-demo-artifact
  • outputs: 2
  • runtime artifacts: 1
  • service node-service-demo-service

Substrates

  • dockerfile: supported
  • shell: supported