@cosmicdrift/kumiko-server-runtime 0.316.0 → 0.318.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-server-runtime",
3
- "version": "0.316.0",
3
+ "version": "0.318.0",
4
4
  "description": "Production server-boot runtime for Kumiko apps: connections, schema-drift-gate, seeds, lifecycle, graceful shutdown. Symmetric to kumiko-dev-server's runDevApp, without dev/scaffold/codegen tooling.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -80,9 +80,9 @@
80
80
  }
81
81
  },
82
82
  "dependencies": {
83
- "@cosmicdrift/kumiko-bundled-features": "0.316.0",
84
- "@cosmicdrift/kumiko-framework": "0.316.0",
85
- "@cosmicdrift/kumiko-headless": "0.316.0",
83
+ "@cosmicdrift/kumiko-bundled-features": "0.318.0",
84
+ "@cosmicdrift/kumiko-framework": "0.318.0",
85
+ "@cosmicdrift/kumiko-headless": "0.318.0",
86
86
  "temporal-polyfill": "^0.3.2"
87
87
  },
88
88
  "publishConfig": {
@@ -0,0 +1,77 @@
1
+ // The app theme plugin only works if its base-layer output lands AFTER the framework's light
2
+ // palette (`@layer base :root:not(.dark)`); same selector, same layer, so source order decides.
3
+ // This runs the real Tailwind one-shot over an app stylesheet that imports the framework CSS and
4
+ // loads a theme module through the published `theme-plugin` subpath.
5
+
6
+ import { describe, expect, test } from "bun:test";
7
+ import { execFileSync } from "node:child_process";
8
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { fileURLToPath } from "node:url";
11
+ import { runTailwindOnce } from "../build-prod-bundle";
12
+
13
+ const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../../..");
14
+ const FRAMEWORK_LIGHT_PRIMARY = "--color-primary:#171717";
15
+
16
+ function bunAvailable(): boolean {
17
+ try {
18
+ execFileSync("bun", ["--version"], { stdio: "ignore" });
19
+ return true;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ describe("renderer-web theme plugin in a real Tailwind build", () => {
26
+ test.skipIf(!bunAvailable())(
27
+ "app theme overrides the framework light palette, sets dark values and adds utilities for new colors",
28
+ async () => {
29
+ const dir = await mkdtemp(join(REPO_ROOT, ".theme-plugin-"));
30
+ try {
31
+ await writeFile(
32
+ join(dir, "theme.ts"),
33
+ `import { createThemePlugin, defineAppTheme } from "@cosmicdrift/kumiko-renderer-web/theme-plugin";
34
+ export default createThemePlugin(defineAppTheme({
35
+ colors: {
36
+ primary: { light: "#0a7d5a", dark: "#34d399" },
37
+ "brand-soft": "#e0f5ee",
38
+ },
39
+ shadows: { card: "none" },
40
+ fonts: { sans: "Manrope, sans-serif" },
41
+ }));
42
+ `,
43
+ );
44
+ await writeFile(
45
+ join(dir, "probe.tsx"),
46
+ `export const Probe = () => <div className="bg-brand-soft text-primary" />;\n`,
47
+ );
48
+ await writeFile(
49
+ join(dir, "styles.css"),
50
+ `@import "@cosmicdrift/kumiko-renderer-web/styles.css";\n@plugin "./theme.ts";\n@source "./probe.tsx";\n`,
51
+ );
52
+
53
+ const css = await runTailwindOnce(join(dir, "styles.css"), dir);
54
+
55
+ const frameworkLight = css.indexOf(FRAMEWORK_LIGHT_PRIMARY);
56
+ const appLight = css.indexOf("--color-primary:#0a7d5a");
57
+ expect(frameworkLight).toBeGreaterThan(-1);
58
+ expect(appLight).toBeGreaterThan(frameworkLight);
59
+
60
+ expect(css).toMatch(/\.dark\{[^}]*--color-primary:#34d399/);
61
+ expect(css).toMatch(/\.bg-brand-soft\{background-color:var\(--color-brand-soft\)\}/);
62
+
63
+ const frameworkCardShadow = css.indexOf("--card-shadow:0 1px 3px");
64
+ const appCardShadow = css.indexOf("--card-shadow:none");
65
+ expect(frameworkCardShadow).toBeGreaterThan(-1);
66
+ expect(appCardShadow).toBeGreaterThan(frameworkCardShadow);
67
+ // An unlayered framework :root would beat the plugin's base layer despite the order.
68
+ expect(css).toMatch(/:root\{[^}]*--kumiko-grid-row-h/);
69
+ expect(css).not.toMatch(/:root\{[^}]*--kumiko-grid-row-h[^}]*--card-/);
70
+ expect(css).not.toMatch(/:root\{[^}]*--card-[^}]*--kumiko-grid-row-h/);
71
+ expect(css).toMatch(/body\{font-family:var\(--font-sans\)\}/);
72
+ } finally {
73
+ await rm(dir, { recursive: true, force: true });
74
+ }
75
+ },
76
+ );
77
+ });