Skip to content
Merged

2.x #15

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
8a16fac
Use current .fbp syntax
bergie Jul 1, 2026
5b47f7a
Modernize exports
bergie Jul 1, 2026
f4f19d5
Modernize exports
bergie Jul 1, 2026
5b1f782
Newly serialized
bergie Jul 1, 2026
8e7a89f
Start the 2.x reimplementation: assembly relay components
bergie Oct 12, 2026
b08afa3
Commit the lockfile for the CI npm cache
bergie Oct 12, 2026
b108eef
Add DocumentBuilder and drop the initialized-flag antipattern
bergie Oct 12, 2026
0db2027
PostCollector: drop the initialized flag too
bergie Oct 12, 2026
1af8288
PostCollector: keep the buffered config reference for the comparison
bergie Oct 12, 2026
bc08a05
Remove the 1.x CoffeeScript sources and the replaced nodeunit test
bergie Oct 16, 2026
59e2950
Add LoadDocument and FrontMatter relays
bergie Oct 16, 2026
fcb1b85
PostCollector: stateless collect-until-stream-close
bergie Oct 16, 2026
ab806a8
Add the 2.x graph set: the redesigned build pipeline
bergie Oct 16, 2026
99df11c
Build graph: target-based output paths and the static copy leg
bergie Oct 16, 2026
24651bc
bin/noflo-jekyll.js: the CLI on the asPromise-based library
bergie Oct 16, 2026
8ebed21
Remove the remaining 1.x graph files
bergie Oct 16, 2026
0d12c6e
Clean up the test suite: drop the debug Pipeline test, simplify the e2e
bergie Oct 16, 2026
ca583e8
Bump to @noflo/noflo, @noflo/assembly, @noflo/assembly-utils 2.0.0-al…
bergie Oct 16, 2026
098092f
Trigger a fresh CI run
bergie Oct 16, 2026
ef297eb
EndToEnd: the static copy assertion is the guaranteed pass; the docum…
bergie Oct 16, 2026
936d193
Don't lint fixtures
bergie Oct 16, 2026
094f3f8
DocumentBuilder: buffer documents until their referenced parts arrive
bergie Oct 16, 2026
3ba34d1
Jekyll: drop the forced network stop, the build self-ends
bergie Oct 16, 2026
1e6d2ae
Add CHANGELOG with the 2.x reimplementation summary
bergie Oct 16, 2026
a89d0ab
Remove the leftover 1.x tests and their fixture trees
bergie Oct 16, 2026
b652012
Add the e2e trace debugger
bergie Oct 16, 2026
8ba62ba
Bump the @noflo monorepo packages to ^2.0.0-alpha.7
bergie Oct 16, 2026
71f302c
BuildPostPath: real-Jekyll permalink semantics
bergie Oct 16, 2026
6ce3d45
DocumentBuilder: two-pass site enrichment and layout variables
bergie Oct 16, 2026
edb2bd3
Add the root pages leg: front-matter pages render, static copies
bergie Oct 16, 2026
ac0ec09
Update CHANGELOG: permalink semantics, pages leg, site-root splitting
bergie Oct 16, 2026
6921adb
Parity test against the 3.9-generated Jekyll reference
bergie Oct 16, 2026
0372bce
Flowtrace the e2e builds and upload the artifacts from CI
bergie Oct 16, 2026
6c94325
ExpandPosts: document the deferred per-message scope stamping
bergie Oct 16, 2026
d745667
Restore the corpus-leg wiring and make the static copy binary-safe
bergie Oct 16, 2026
a74d4b0
debug-e2e: formatting
bergie Oct 16, 2026
7ef2daf
Per-message scope stamping on the closedown build
bergie Oct 16, 2026
1b20aa2
Parity test: honour the gap set on both sides of the comparison
bergie Oct 16, 2026
5c1a28a
Hold activations across async work; consume documents on arrival
bergie Oct 17, 2026
378fa06
Strip brackets on the liquid includes leg; the error-to-null-corpus m…
bergie Oct 17, 2026
7271a8d
Bump @noflo/assembly and @noflo/assembly-utils to ^2.0.0-alpha.8
bergie Oct 17, 2026
3954f4d
Spin on noflo/noflo#1093: the framing termination, the marker bypass,…
bergie Oct 17, 2026
3844644
ScanSource: drop the Merge from the includes leg
bergie Oct 17, 2026
7582e71
Deps to the released alpha.9 set; the scoped-drain gap as a visible todo
bergie Oct 17, 2026
442fcff
Deps to the released alpha.9 set
bergie Oct 17, 2026
fdcbf30
CI: include hidden files in the artifact upload; encode the corpus-ra…
bergie Oct 17, 2026
fc4ee4c
Deps to the released alpha.10 set; the corpus-race strand closed
bergie Oct 17, 2026
0dcf7f3
The nested _posts discovery: the EOT-frame envelope closes the collec…
bergie Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
61 changes: 61 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Publish to npm

on:
push:
tags:
- "v*"

permissions:
id-token: write # Required for OIDC trusted publishing
contents: read

concurrency:
group: npm-publish-${{ github.ref }}
cancel-in-progress: false

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "24.x"
cache: npm
registry-url: https://registry.npmjs.org

- run: npm ci

- name: Verify the tag matches the package version
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME#v}"
VERSION=$(node -p "require('./package.json').version")
if [ "$TAG" != "$VERSION" ]; then
echo "::error::Tag 'v$TAG' does not match package version '$VERSION'"
exit 1
fi

- name: Test
run: npm test

- name: Generate the component manifest
run: node "$(node -p "require.resolve('@noflo/manifest/src/cli.js')")" . --revision "$GITHUB_SHA"

- name: Publish
run: |
NAME=$(node -p "require('./package.json').name")
VERSION=$(node -p "require('./package.json').version")
# Skip versions already on the registry (the first publish of each
# package is done manually before its tag exists)
if npm view "$NAME@$VERSION" version >/dev/null 2>&1; then
echo "Version $NAME@$VERSION already published, skipping"
exit 0
fi
# npm requires an explicit tag for prerelease versions
case "$VERSION" in
*-*) npm publish --tag next ;;
*) npm publish ;;
esac
33 changes: 33 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Test

on:
push:
branches:
- master
pull_request:

jobs:
test:
name: Node.js ${{ matrix.node-version }}
runs-on: ubuntu-latest
strategy:
matrix:
node-version:
- "22.x"
- "24.x"
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm test
- name: Upload flowtrace artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: flowtrace-${{ matrix.node-version }}
path: .flowtrace/
if-no-files-found: ignore
include-hidden-files: true
10 changes: 7 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
node_modules/
.node_shell
bergie/
npm-debug.log
/fbp.json
/noflo.json

# Debug run artifacts
/.flowtrace*.json
/test/fixtures/target-*/
.flowtrace/
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- The nested `_posts` discovery: the scan subgraph joins every root entry with `/_posts` (`strings/Append`, whose standing suffix control keeps the value readable across the whole entry stream) and reads each discovered directory. The merged posts leg is wrapped by the new `jekyll/StreamEnvelope` relay, which terminates the per-listing framing and emits one outer bracket frame that closes when the leg reaches EOT — the stream-level collector flushes once over the complete collection instead of once per source group. This is the component-level form of the EOT-to-packet terminator convention (work documents #40 update #10 and #47 §8); the nested post's path-derived category rides the same wave (`jekyll/PathMetadata`'s `source` control is now fed and declared `scoped: false`).
- NoFlo 2.x reimplementation of the Jekyll static site generator on the `2.x` branch: plain ESM with zero build step, Node.js >= 22, components built on the `@noflo/assembly` message-relay conventions (assembly `Component` base class, `errors` array, `fail`/`failed` helpers) instead of the 1.x WirePattern queues.
- New component set: `jekyll/LoadDocument`, `jekyll/FrontMatter`, `jekyll/PathMetadata`, `jekyll/BuildPostPath`, `jekyll/PostCollector` (stateless collect-until-stream-close), `jekyll/ExpandPosts`, `jekyll/DocumentBuilder` (template inheritance and pagination), `jekyll/CopyStatic`, and the `jekyll/ScanSource` source-tree scan subgraph.
- Redesigned graph set: a single `Build` pipeline graph plus the `ScanSource` subgraph, generated with `scripts/generate-graphs.js` and committed for the package manifest. The 0.x eight-graph set is replaced by message-shaped relay wiring with transport-level brackets.
- `lib/Jekyll` embedding library on the 2.x network API (`asPromise` with a live `GraphModel`), the `bin/noflo-jekyll` CLI with an unchanged command-line contract (`noflo-jekyll source target`), and `scripts/generate-graphs.js`.
- Test suite on `node:test`: per-component units and an end-to-end fixture-site build test pinning the expected build outputs.
- Behavior parity is asserted against the 1.x fixtures, including the 1.x name-with-extension permalink quirk (`:title` keeping `.md`).

### Changed

- Dependencies moved to the `@noflo` namespace (`@noflo/noflo`, `@noflo/assembly`, `@noflo/assembly-utils`, `@noflo/core`, `@noflo/filesystem`, `@noflo/groups`, `@noflo/liquid`, `@noflo/markdown`), all on the 2.x line; site config parsing uses `yaml`.
- Platform dependencies moved to the released `2.0.0-alpha.10` set (`@noflo/noflo`, `@noflo/assembly`, `@noflo/assembly-utils`), which carries the gate semantics for control ports (noflo/noflo#1094) and the one-firing-rule removal of the `triggering` property (work document #47). The build is deterministic under load: repeated fixture builds produce one output tree, and the four root posts join the strict Jekyll-reference comparison again after having been gap-set exclusions of the firing-model strand (work document #35 updates #19–#22).
- Document building is order-tolerant: no arrival ordering is assumed between the template corpus, the site config, and the documents — documents whose referenced parts have not arrived stay buffered and are retried on later arrivals, matching the 1.x retry semantics without WirePattern.
- Permalinks follow Jekyll semantics: `:title` expands to the slug (source name without extension — a deliberate change from the 1.x name-with-extension quirk), `:month`/`:day` zero-pad, and trailing-slash permalinks write `index.html` into the directory.
- Site root entries split at the static leg: files with YAML front matter render through layouts and liquid (including the paginator), files without front matter and directory trees copy verbatim with underscore/dot exclusions at every level.
- The layout chain contributes the `{{ content }}` substitution only: a layout's own front matter is the layout's variables, not page variables — the Jekyll-generated reference is the contract (a `class: index` on a layout does not reach `page.class`; a page's class comes from its own front matter). The paginator's `previous_page_path` follows the same reference: page 1 of a paginated document is the document itself at its own URL (the site root's `index.html` maps to `/`).

### Removed

- The 1.x CoffeeScript component sources and their `nodeunit` tests, the Grunt toolchain, and the `coffeescript`/`mimetype` dependencies.
- The 0.x graph set (`BuildDocuments`, `ConvertMarkdown`, `CopyFile`, `GetConfig`, `GroupDocuments`, `Jekyll`, `LoadDocuments`, `SaveFile`): group-scraping for post metadata is replaced by path-derived message fields, the split template/variables streams are folded into a single document message, and the separate convert/copy/save graphs are folded into the single build flow.
37 changes: 0 additions & 37 deletions Gruntfile.coffee

This file was deleted.

Empty file added LICENSE
Empty file.
38 changes: 0 additions & 38 deletions bin/noflo-jekyll

This file was deleted.

39 changes: 39 additions & 0 deletions bin/noflo-jekyll.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env node
import path from "node:path";
import process from "node:process";
import { stat } from "node:fs/promises";
import { jekyll } from "../lib/Jekyll.js";

const source = path.resolve(process.argv[2]);
const target = path.resolve(process.argv[3]);

if (process.argv.length !== 4) {
console.log(`Usage: $ noflo-jekyll source_dir target_dir`);
process.exit(0);
}

try {
await stat(source);
} catch {
console.error(`Source directory ${source} doesn't exist`);
process.exit(1);
}

console.log(`NoFlo Jekyll ${source} -> ${target}`);

try {
const started = Date.now();
const output = await jekyll(source, target);
const written = output.written ?? [];
const copied = output.copied ?? [];
for (const file of written) {
console.log(`Created file ${file.path ?? file}`);
}
for (const file of copied) {
console.log(`Copied ${file.destination ?? file}`);
}
console.log(`Build finished in ${(Date.now() - started) / 1000} sec.`);
} catch (error) {
console.error(error);
process.exit(1);
}
114 changes: 0 additions & 114 deletions components/BuildPostPath.coffee

This file was deleted.

Loading
Loading