elm-ssr 0.91.5 → 0.91.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/build.mjs +49 -27
  2. package/package.json +3 -2
package/lib/build.mjs CHANGED
@@ -1,10 +1,6 @@
1
1
  import { mkdir, readdir, readFile, rm, writeFile, stat } from "node:fs/promises";
2
2
  import { dirname, relative, resolve } from "node:path";
3
3
  import { gzipSync } from "node:zlib";
4
- import { exec } from "node:child_process";
5
- import { promisify } from "node:util";
6
-
7
- const execAsync = promisify(exec);
8
4
 
9
5
  // This lib is part of elm-ssr. It handles generating Main.elm and
10
6
  // compiling the route apps and island bundles.
@@ -203,21 +199,50 @@ main =
203
199
  await rm(rawOutputPath, { force: true });
204
200
  };
205
201
 
206
- const findLocalTailwind = async (startDir) => {
207
- let current = resolve(startDir);
208
- while (true) {
209
- const candidate = resolve(current, "node_modules", ".bin", "tailwindcss");
210
- try {
211
- await stat(candidate);
212
- return candidate;
213
- } catch {
214
- // ignore
202
+ const findLocalTailwindCli = async (startDir) => {
203
+ const candidate = resolve(startDir, "node_modules", "tailwindcss", "lib", "cli.js");
204
+ try {
205
+ await stat(candidate);
206
+ return candidate;
207
+ } catch {
208
+ return null;
209
+ }
210
+ };
211
+
212
+ const runTailwind = async ({ rootPath, cliRoot, appRoot, inputPath, contentGlob }) => {
213
+ const tailwindSearchRoots = [
214
+ rootPath,
215
+ cliRoot,
216
+ resolve(cliRoot, "..", ".."),
217
+ process.cwd()
218
+ ];
219
+ let tailwindCli = null;
220
+ for (const searchRoot of [...new Set(tailwindSearchRoots)]) {
221
+ tailwindCli = await findLocalTailwindCli(searchRoot);
222
+ if (tailwindCli) {
223
+ break;
215
224
  }
216
- const parent = dirname(current);
217
- if (parent === current) break;
218
- current = parent;
219
225
  }
220
- return null;
226
+
227
+ const command = tailwindCli
228
+ ? [process.execPath, tailwindCli]
229
+ : ["npx", "--yes", "tailwindcss"];
230
+
231
+ const child = Bun.spawn(
232
+ [...command, "-i", inputPath, "--content", contentGlob, "--minify"],
233
+ { cwd: appRoot, stdout: "pipe", stderr: "pipe" }
234
+ );
235
+ const [stdout, stderr, exitCode] = await Promise.all([
236
+ new Response(child.stdout).text(),
237
+ new Response(child.stderr).text(),
238
+ child.exited
239
+ ]);
240
+
241
+ if (exitCode !== 0) {
242
+ throw new Error((stderr || stdout || `Tailwind exited with code ${exitCode}`).trim());
243
+ }
244
+
245
+ return stdout.toString().trim();
221
246
  };
222
247
 
223
248
  const compileStylesheet = async ({ inputPath, outputPath, appConfig, appRoot }) => {
@@ -234,17 +259,14 @@ const findLocalTailwind = async (startDir) => {
234
259
  try {
235
260
  console.log(`[elm-ssr] Compiling Tailwind CSS for app "${appConfig.name}"...`);
236
261
  const contentGlob = "src/**/*.elm,src/**/*.ts,src/**/*.js";
237
-
238
- let tailwindBin = await findLocalTailwind(rootPath);
239
- if (!tailwindBin) {
240
- tailwindBin = await findLocalTailwind(cliRoot);
241
- }
242
- const binCommand = tailwindBin ? tailwindBin : "npx --yes tailwindcss";
243
-
244
- const command = `${binCommand} -i ${inputPath} --content "${contentGlob}" --minify`;
245
- const { stdout } = await execAsync(command, { cwd: appRoot });
246
- css = stdout.toString().trim();
262
+ css = await runTailwind({ rootPath, cliRoot, appRoot, inputPath, contentGlob });
247
263
  } catch (err) {
264
+ if (appConfig.tailwindFallback !== true) {
265
+ throw new Error(
266
+ `[elm-ssr] Tailwind CSS compilation failed for app "${appConfig.name}". ` +
267
+ `Install tailwindcss in the workspace or set "tailwindFallback": true for development-only fallback. ${err.message}`
268
+ );
269
+ }
248
270
  console.warn(`[elm-ssr] Tailwind CSS compilation failed. Falling back to plain CSS read. Error:`, err.message);
249
271
  const raw = await readFile(inputPath, "utf8");
250
272
  css = raw.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "elm-ssr",
3
- "version": "0.91.5",
3
+ "version": "0.91.6",
4
4
  "description": "Elm-first SSR library and framework for Cloudflare Workers (and Bun): file-based routes/islands, backend-neutral effect adapters (KV/D1/Redis/Postgres), background tasks (waitUntil/Queues), SQL-file migrations, CLI scaffold + build.",
5
5
  "license": "MIT",
6
6
  "author": "Michał Majchrzak <michmajchrzak@gmail.com>",
@@ -58,6 +58,7 @@
58
58
  "bun": ">=1.3"
59
59
  },
60
60
  "dependencies": {
61
- "cookie": "^1.0.1"
61
+ "cookie": "^1.0.1",
62
+ "tailwindcss": "3.4.17"
62
63
  }
63
64
  }