From 30d9ad05ac3d33b70fd62e0ebe7f33de90069166 Mon Sep 17 00:00:00 2001 From: Hellings Date: Fri, 23 Oct 2026 19:14:28 -0400 Subject: [PATCH] Subproject update --- dbg.mjs | 17 +++++ dbg2.mjs | 18 +++++ dbg3.mjs | 19 +++++ deno.lock | 94 ++++++++++++++++++++++++ docs/install.md | 26 +------ package.json | 1 + tests/stcss-modules.test.ts | 72 +++++++++++++++++++ views/css/index.ts | 6 ++ views/css/modules.ts | 138 ++++++++++++++++++++++++++++++++++++ views/engine/runtime.ts | 93 ++++++++++++++++++++++-- views/integrations.ts | 31 ++++++-- 11 files changed, 478 insertions(+), 37 deletions(-) create mode 100644 dbg.mjs create mode 100644 dbg2.mjs create mode 100644 dbg3.mjs create mode 100644 deno.lock create mode 100644 tests/stcss-modules.test.ts create mode 100644 views/css/modules.ts diff --git a/dbg.mjs b/dbg.mjs new file mode 100644 index 0000000..e3d1f9b --- /dev/null +++ b/dbg.mjs @@ -0,0 +1,17 @@ +import { readFile } from "node:fs/promises"; +import { lex } from "./views/engine/lexer.ts"; +import { parse } from "./views/engine/parser.ts"; +import { compileTemplate } from "./views/engine/compiler.ts"; +const src = await readFile( + "./critdotrip/muddle/modules/app/views/index.spug", + "utf8", +); +const tokens = lex(src); +const parsed = parse(tokens); +console.log("frontmatter:", JSON.stringify(parsed.frontmatter)); +const { source } = compileTemplate(parsed.nodes, { + path: "/x/index.spug", + dir: "/x", + frontmatter: "", +}); +console.log(source.slice(0, 1200)); diff --git a/dbg2.mjs b/dbg2.mjs new file mode 100644 index 0000000..5105641 --- /dev/null +++ b/dbg2.mjs @@ -0,0 +1,18 @@ +import { readFile } from "node:fs/promises"; +import { lex } from "./views/engine/lexer.ts"; +import { parse } from "./views/engine/parser.ts"; +import { compileTemplate } from "./views/engine/compiler.ts"; +const src = await readFile( + "./critdotrip/muddle/modules/app/views/index.spug", + "utf8", +); +const tokens = lex(src); +const parsed = parse(tokens); +const { source } = compileTemplate(parsed.nodes, { + path: "/x/index.spug", + dir: "/x", + frontmatter: parsed.frontmatter || "", +}); +const i = source.indexOf("hellings"); +console.log("index", i); +if (i >= 0) console.log(source.slice(Math.max(0, i - 400), i + 200)); diff --git a/dbg3.mjs b/dbg3.mjs new file mode 100644 index 0000000..3f66e29 --- /dev/null +++ b/dbg3.mjs @@ -0,0 +1,19 @@ +import { readFile } from "node:fs/promises"; +import { lex } from "./views/engine/lexer.ts"; +import { parse } from "./views/engine/parser.ts"; +import { compileTemplate } from "./views/engine/compiler.ts"; +const src = await readFile( + "./critdotrip/muddle/modules/app/views/index.spug", + "utf8", +); +const parsed = parse(lex(src)); +const { source } = compileTemplate(parsed.nodes, { + path: "/x/i.spug", + dir: "/x", + frontmatter: parsed.frontmatter || "", +}); +const a = source.indexOf("with (__ctx) {"); +const b = source.indexOf('return __out.join(""");', a); +console.log("TEMPLATE BODY START", a); +console.log(source.slice(a, b).slice(0, 400)); +console.log("...LEN", b - a); diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..0603279 --- /dev/null +++ b/deno.lock @@ -0,0 +1,94 @@ +{ + "version": "5", + "specifiers": { + "jsr:@std/fs@*": "1.0.24", + "jsr:@std/internal@^1.0.14": "1.0.14", + "jsr:@std/path@^1.1.5": "1.1.6" + }, + "jsr": { + "@std/fs@1.0.24": { + "integrity": "f3061b45b81673a2bece689da041df32d174be064c89eb6397fb5718d3fb7877", + "dependencies": [ + "jsr:@std/path" + ] + }, + "@std/internal@1.0.14": { + "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7" + }, + "@std/path@1.1.6": { + "integrity": "c68485c2a4dfbb5ae3cc74fae4e8c4e5d874cf8a8ed12927917235c758b46cbe", + "dependencies": [ + "jsr:@std/internal" + ] + } + }, + "workspace": { + "packageJson": { + "dependencies": [ + "npm:@eslint/js@^10.0.1", + "npm:@types/bun@latest", + "npm:@types/pg@^8.15.5", + "npm:lightningcss@^1.33.0", + "npm:playwright@^1.64.1", + "npm:prettier@^3.9.10", + "npm:sass@^1.106.1", + "npm:typescript-eslint@^8.72.0" + ] + }, + "members": { + "modules/astro": { + "packageJson": { + "dependencies": [ + "npm:@astrojs/compiler@2", + "npm:astro@5", + "npm:typescript@5.9.3" + ] + } + }, + "modules/database": { + "packageJson": { + "dependencies": [ + "npm:pg@^8.23.1" + ] + } + }, + "modules/latex": { + "packageJson": { + "dependencies": [ + "npm:katex@0.19" + ] + } + }, + "modules/mdx": { + "packageJson": { + "dependencies": [ + "npm:@mdx-js/mdx@^3.1.1", + "npm:@types/react-dom@^19.3.0", + "npm:@types/react@^19.3.0", + "npm:react-dom@^19.3.1", + "npm:react@^19.3.1" + ] + } + }, + "modules/optimize": { + "packageJson": { + "dependencies": [ + "npm:@types/csso@^5.0.5", + "npm:@types/html-minifier-terser@^7.0.2", + "npm:csso@^5.0.5", + "npm:html-minifier-terser@^7.2.0", + "npm:svgo@^4.1.0", + "npm:terser@^5.51.2" + ] + } + }, + "modules/tailwind": { + "packageJson": { + "dependencies": [ + "npm:tailwindcss@^4.3.3" + ] + } + } + } + } +} diff --git a/docs/install.md b/docs/install.md index 6aaf129..2507790 100644 --- a/docs/install.md +++ b/docs/install.md @@ -10,32 +10,8 @@ bun add muddle@git+https://git.crit.rip/mdl/muddle.git npm install muddle@git+https://git.crit.rip/mdl/muddle.git ``` -Integrations are isolated `@muddle/*` modules. After their Forgejo repositories are provisioned, install one independently. +Integrations are `@muddle/*` modules. ```sh bun add @muddle/shadcn@git+https://git.crit.rip/mdl/shadcn.git ``` - -Create a Forgejo personal access token with repository creation rights, then provision the namespace repositories. The script only reads `MUDDLE_FORGEJO_TOKEN` from the environment and never prints it. - -```sh -MUDDLE_FORGEJO_TOKEN=token bun scripts/forgejo-modules.ts -``` - -Preview without network writes. - -```sh -bun scripts/forgejo-modules.ts --dry-run -``` - -To commit changed integration module directories with generic `chore: update @muddle/ integration` messages and push their subtree history, preview the operation first. Unchanged modules are also synced so newly created Forgejo repositories receive their initial branch. - -```sh -bun scripts/forgejo-push.ts -``` - -Push only after review. This requires the same token and creates local commits. - -```sh -MUDDLE_FORGEJO_TOKEN=token bun scripts/forgejo-push.ts --push -``` diff --git a/package.json b/package.json index 0da52cc..6576346 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "./contracts": "./contracts/index.ts", "./contracts/*": "./contracts/*", "./metadata": "./core/metadata.ts", + "./decorators": "./decorators/index.ts", "./markdown": "./views/markdown.ts", "./views": "./views/api.ts", "./views/integrations": "./views/integrations.ts", diff --git a/tests/stcss-modules.test.ts b/tests/stcss-modules.test.ts new file mode 100644 index 0000000..f7d4ba1 --- /dev/null +++ b/tests/stcss-modules.test.ts @@ -0,0 +1,72 @@ +import { expect, test } from "bun:test"; +import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { tmpdir } from "node:os"; +import { compileStcssModule } from "../views/css/modules.ts"; +import { createViews } from "../views/api.ts"; + +test("STCSS modules scope classes and inline relative imports", async () => { + const root = await mkdtemp(join(tmpdir(), "muddle-stcss-module-")); + try { + const imported = join(root, "tokens.stcss"); + await writeFile(imported, ".token { color: red; }"); + const result = await compileStcssModule( + '@import "./tokens.stcss"; .card { color: blue; }', + { filename: join(root, "card.module.stcss"), root }, + ); + expect(result.classes.card).toBeDefined(); + expect(result.classes.token).toBeDefined(); + expect(result.css).toContain(`.${result.classes.card}`); + expect(result.css).toContain(`.${result.classes.token}`); + expect(result.css).not.toContain(".card {"); + } finally { + await rm(root, { recursive: true, force: true }); + } +}); + +test("a component automatically receives its adjacent STCSS module", async () => { + const root = await mkdtemp(join(tmpdir(), "muddle-component-module-")); + try { + const components = join(root, "components"); + await mkdir(components); + await writeFile(join(components, "badge.spug"), "span.badge badge"); + await writeFile( + join(components, "badge.module.stcss"), + ".badge { color: rebeccapurple; }", + ); + await writeFile(join(root, "index.spug"), "component badge"); + const html = await createViews({ + root, + viewsDir: root, + componentsDir: components, + }).render("index.spug", {}); + expect(html).toContain("