From 4019a4344fdf4e7f7f4fe5dabbf83e7163680224 Mon Sep 17 00:00:00 2001 From: Phil Leggetter Date: Sat, 8 Aug 2026 11:08:51 +0100 Subject: [PATCH] fix: sort published samples explicitly instead of relying on readdir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing in compile.ts sorted. Providers, versions and topics were emitted in `fs.readdir` order, which is filesystem-dependent: APFS returns entries sorted, ext4 with dir_index returns them in hash order. The published files look alphabetical today only because they were last built on a Mac. There is no CI in this repo and `public/` is gitignored, so the order consumers receive depends on whose machine ran the build. Providers, versions and topics are now sorted explicitly. Topics are sorted by the topic they publish, not by filename. Those are different strings — `orders.create.json` publishes `orders/create` — and the topic is what consumers see. They happen to sort identically today because `.` and `/` are adjacent in ASCII with nothing between them, but that is a coincidence, not a reason to sort the wrong key. Also writes each version file once rather than once per topic. The write was inside the topic loop, so shopify/2026-07 was written 217 times per build, each time with a progressively more complete object. Output is byte-identical to the previous build across all 112 providers, and two consecutive runs now produce identical bytes. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_019pce9oHWGjdwHsJNya1ovP --- compile.ts | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/compile.ts b/compile.ts index 4e8ca81..8df2ec1 100644 --- a/compile.ts +++ b/compile.ts @@ -15,11 +15,14 @@ type Provenance = { sourced_via: SourcedVia; sourced_on?: string }; const compile = async () => { const root = path.join(__dirname, "providers"); const data: any = {}; - const providers = await fs.readdir(root); + // Everything published is sorted explicitly. `fs.readdir` returns entries in + // filesystem order — sorted on APFS, hash order on ext4 — so without this the + // published order silently depends on which machine ran the build. + const providers = (await fs.readdir(root)).sort(); for (const provider of providers) { const provider_path = path.join(root, provider); if (!(await fs.stat(provider_path)).isDirectory()) continue; - const versions = await fs.readdir(provider_path); + const versions = (await fs.readdir(provider_path)).sort(); const config_file = await fs.readFile( path.join(provider_path, "index.json"), "utf8" @@ -53,11 +56,13 @@ const compile = async () => { for (const version of versions.filter((v) => v !== "index.json")) { const version_path = path.join(provider_path, version); if (!(await fs.stat(version_path)).isDirectory()) continue; - data[provider].versions[version] = {}; const topics = await fs.readdir(version_path); - data[provider].versions[version] = {}; + // Collect first, then emit in topic order. Sorting the filenames is not + // the same thing: a file is `orders.create.json` where the topic it + // publishes is `orders/create`, and it is the topic that consumers see. + const by_topic: Record = {}; for (const topic of topics) { const topic_data = await fs.readFile( path.join(root, provider, version, topic), @@ -80,22 +85,23 @@ const compile = async () => { ); } - data[provider].versions[version][parsed_topic.topic] = parsed_topic; - await fs.mkdir(path.join(__dirname, "public", "providers", provider), { - recursive: true, - }); - await fs.writeFile( - path.join( - __dirname, - "public", - "providers", - provider, - `${version}.json` - ), - JSON.stringify(data[provider].versions[version], null), - "utf8" - ); + by_topic[parsed_topic.topic] = parsed_topic; } + + const sorted_version: Record = {}; + for (const topic of Object.keys(by_topic).sort()) { + sorted_version[topic] = by_topic[topic]; + } + data[provider].versions[version] = sorted_version; + + await fs.mkdir(path.join(__dirname, "public", "providers", provider), { + recursive: true, + }); + await fs.writeFile( + path.join(__dirname, "public", "providers", provider, `${version}.json`), + JSON.stringify(sorted_version, null), + "utf8" + ); } } return data;