@lukas_holdings/castdom 1.0.1 → 1.0.3
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/README.md +8 -21
- package/bin/castdom.js +0 -0
- package/dist/astro.cjs +31 -13
- package/dist/astro.cjs.map +1 -1
- package/dist/astro.d.cts +8 -4
- package/dist/astro.d.ts +8 -4
- package/dist/astro.js +25 -7
- package/dist/astro.js.map +1 -1
- package/dist/{chunk-ZBJB7WVV.js → chunk-275VEEA7.js} +4 -4
- package/dist/{chunk-ZBJB7WVV.js.map → chunk-275VEEA7.js.map} +1 -1
- package/dist/chunk-4LFW65DU.js +38 -0
- package/dist/chunk-4LFW65DU.js.map +1 -0
- package/dist/{chunk-ONS533CQ.js → chunk-6RFGWOGG.js} +3 -3
- package/dist/{chunk-ONS533CQ.js.map → chunk-6RFGWOGG.js.map} +1 -1
- package/dist/{chunk-XS5HAU5E.cjs → chunk-ASS2BFPN.cjs} +8 -8
- package/dist/{chunk-XS5HAU5E.cjs.map → chunk-ASS2BFPN.cjs.map} +1 -1
- package/dist/{chunk-ORY4OMZ5.cjs → chunk-BDIAGFG5.cjs} +4 -4
- package/dist/{chunk-ORY4OMZ5.cjs.map → chunk-BDIAGFG5.cjs.map} +1 -1
- package/dist/{chunk-QLEBTZIB.cjs → chunk-C2D4NZQB.cjs} +7 -7
- package/dist/{chunk-QLEBTZIB.cjs.map → chunk-C2D4NZQB.cjs.map} +1 -1
- package/dist/{chunk-JRQ6EVQP.cjs → chunk-C3VW72Z3.cjs} +10 -2
- package/dist/chunk-C3VW72Z3.cjs.map +1 -0
- package/dist/{chunk-O4OOMGGM.cjs → chunk-CC4LCPVY.cjs} +8 -8
- package/dist/{chunk-O4OOMGGM.cjs.map → chunk-CC4LCPVY.cjs.map} +1 -1
- package/dist/{chunk-ZWZ5ZLJE.js → chunk-GVFBT6MD.js} +3 -3
- package/dist/{chunk-ZWZ5ZLJE.js.map → chunk-GVFBT6MD.js.map} +1 -1
- package/dist/{chunk-COLESJ66.js → chunk-M4OXJTRQ.js} +3 -3
- package/dist/{chunk-COLESJ66.js.map → chunk-M4OXJTRQ.js.map} +1 -1
- package/dist/{chunk-KGLTVTHU.js → chunk-V4FV5XFF.js} +4 -4
- package/dist/{chunk-KGLTVTHU.js.map → chunk-V4FV5XFF.js.map} +1 -1
- package/dist/{chunk-YDT4TPB7.cjs → chunk-W236FF4E.cjs} +11 -11
- package/dist/{chunk-YDT4TPB7.cjs.map → chunk-W236FF4E.cjs.map} +1 -1
- package/dist/cli.js +12 -12
- package/dist/index.cjs +48 -48
- package/dist/index.js +8 -8
- package/dist/next.cjs +15 -15
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +3 -3
- package/dist/next.d.ts +3 -3
- package/dist/next.js +6 -6
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +9 -9
- package/dist/react.js +5 -5
- package/dist/ssr.cjs +12 -12
- package/dist/ssr.js +3 -3
- package/dist/vite.cjs +3 -3
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +2 -2
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EJRNKHL5.js +0 -31
- package/dist/chunk-EJRNKHL5.js.map +0 -1
- package/dist/chunk-JRQ6EVQP.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<img src="https://img.shields.io/badge/license-MIT-000?style=flat-square" alt="license" />
|
|
5
5
|
<img src="https://img.shields.io/badge/runtime-CSS%20only-000?style=flat-square" alt="CSS only runtime" />
|
|
6
6
|
<img src="https://img.shields.io/badge/bundle-~14KB-000?style=flat-square" alt="bundle size" />
|
|
7
|
-
<img src="https://img.shields.io/badge/
|
|
7
|
+
<img src="https://img.shields.io/badge/AI--friendly-CASTDOM.md-blue?style=flat-square" alt="AI friendly" />
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<h1 align="center">CastDOM</h1>
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
21
|
<p align="center">
|
|
22
|
+
<a href="https://kameeleonn.github.io/CastDOM/"><strong>Live Demo</strong></a> •
|
|
22
23
|
<a href="#quick-start">Quick Start</a> •
|
|
23
24
|
<a href="#how-it-works">How It Works</a> •
|
|
24
25
|
<a href="#react">React</a> •
|
|
@@ -29,6 +30,10 @@
|
|
|
29
30
|
<a href="#api-reference">API</a>
|
|
30
31
|
</p>
|
|
31
32
|
|
|
33
|
+
<p align="center">
|
|
34
|
+
<sub>Ships with <a href="CASTDOM.md"><code>CASTDOM.md</code></a> — an AI context file for Claude, Gemini, GPT, Cursor, Copilot, and Windsurf.<br/>Ask any AI assistant to integrate CastDOM and it will know every API, type, and pattern.</sub>
|
|
35
|
+
</p>
|
|
36
|
+
|
|
32
37
|
---
|
|
33
38
|
|
|
34
39
|
## Why CastDOM?
|
|
@@ -694,27 +699,9 @@ export type SkeletonName = "user-card" | "feed-item";
|
|
|
694
699
|
|
|
695
700
|
---
|
|
696
701
|
|
|
697
|
-
##
|
|
698
|
-
|
|
699
|
-
Open `demo/index.html` to see a live side-by-side comparison:
|
|
700
|
-
|
|
701
|
-
- **Left panel**: Traditional spinner — blank until data loads, layout shifts on content render
|
|
702
|
-
- **Right panel**: CastDOM skeleton — pixel-perfect placeholder visible instantly, zero CLS
|
|
703
|
-
|
|
704
|
-
The demo simulates network latency (1s, 2s, 3s) and shows real-time Core Web Vitals metrics (CLS, FCP, LCP) for both approaches. [View the demo →](demo/index.html)
|
|
705
|
-
|
|
706
|
-
---
|
|
707
|
-
|
|
708
|
-
## AI Integration
|
|
709
|
-
|
|
710
|
-
CastDOM ships AI-friendly reference files for use with LLMs, AI coding assistants, and generative engine optimization:
|
|
711
|
-
|
|
712
|
-
| File | Purpose |
|
|
713
|
-
|------|---------|
|
|
714
|
-
| [`llms.txt`](llms.txt) | Short summary — install, concepts, exports, links |
|
|
715
|
-
| [`llms-full.txt`](llms-full.txt) | Complete reference — all types, APIs, patterns, config, file structure |
|
|
702
|
+
## AI-Friendly
|
|
716
703
|
|
|
717
|
-
|
|
704
|
+
CastDOM ships [`CASTDOM.md`](CASTDOM.md) — a comprehensive context file for AI coding assistants (Claude, Gemini, GPT, Cursor, Copilot, Windsurf, etc.). It contains every type, API, integration pattern, and CLI command so any AI can help you integrate CastDOM correctly.
|
|
718
705
|
|
|
719
706
|
---
|
|
720
707
|
|
package/bin/castdom.js
CHANGED
|
File without changes
|
package/dist/astro.cjs
CHANGED
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
require('./chunk-
|
|
3
|
+
var chunkW236FF4E_cjs = require('./chunk-W236FF4E.cjs');
|
|
4
|
+
var chunkC2D4NZQB_cjs = require('./chunk-C2D4NZQB.cjs');
|
|
5
|
+
var chunkASS2BFPN_cjs = require('./chunk-ASS2BFPN.cjs');
|
|
6
|
+
var chunkC3VW72Z3_cjs = require('./chunk-C3VW72Z3.cjs');
|
|
7
7
|
|
|
8
8
|
// src/adapters/astro.ts
|
|
9
9
|
function castdomIntegration(options) {
|
|
10
10
|
return {
|
|
11
11
|
name: "castdom",
|
|
12
12
|
hooks: {
|
|
13
|
-
"astro:config:setup"({
|
|
13
|
+
"astro:config:setup"({
|
|
14
|
+
injectScript,
|
|
15
|
+
logger
|
|
16
|
+
}) {
|
|
14
17
|
const manifestPath = options?.manifestPath ?? ".castdom/manifest.json";
|
|
18
|
+
let manifestExists = false;
|
|
19
|
+
try {
|
|
20
|
+
const fs = chunkC3VW72Z3_cjs.__require("fs");
|
|
21
|
+
const path = chunkC3VW72Z3_cjs.__require("path");
|
|
22
|
+
const absolute = path.isAbsolute(manifestPath) ? manifestPath : path.resolve(process.cwd(), manifestPath);
|
|
23
|
+
manifestExists = fs.existsSync(absolute);
|
|
24
|
+
} catch {
|
|
25
|
+
manifestExists = false;
|
|
26
|
+
}
|
|
27
|
+
if (!manifestExists) {
|
|
28
|
+
logger?.warn(
|
|
29
|
+
`[castdom] No manifest found at "${manifestPath}". Skipping skeleton registry injection. Run \`npx castdom build\` to generate one.`
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
15
33
|
injectScript(
|
|
16
34
|
"page-ssr",
|
|
17
35
|
`import manifest from "${manifestPath}" with { type: "json" };
|
|
18
|
-
import { loadManifest } from "castdom";
|
|
36
|
+
import { loadManifest } from "@lukas_holdings/castdom";
|
|
19
37
|
loadManifest(manifest);`
|
|
20
38
|
);
|
|
21
39
|
},
|
|
@@ -25,17 +43,17 @@ loadManifest(manifest);`
|
|
|
25
43
|
};
|
|
26
44
|
}
|
|
27
45
|
function skeleton(name, config) {
|
|
28
|
-
const entry =
|
|
46
|
+
const entry = chunkW236FF4E_cjs.get(name);
|
|
29
47
|
if (!entry) {
|
|
30
48
|
return { html: "", css: "", exists: false };
|
|
31
49
|
}
|
|
32
|
-
const html =
|
|
33
|
-
const css =
|
|
50
|
+
const html = chunkC2D4NZQB_cjs.renderSkeleton(entry.data, { config });
|
|
51
|
+
const css = chunkASS2BFPN_cjs.generateCriticalCSS([entry.data], config);
|
|
34
52
|
return { html, css, exists: true };
|
|
35
53
|
}
|
|
36
54
|
function generateAstroComponent(name, config) {
|
|
37
55
|
return `---
|
|
38
|
-
import { skeleton } from "castdom/astro";
|
|
56
|
+
import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
39
57
|
const { html, css } = skeleton("${name}");
|
|
40
58
|
---
|
|
41
59
|
|
|
@@ -67,13 +85,13 @@ function viewTransitionProps(name) {
|
|
|
67
85
|
function head(skeletonNames, config) {
|
|
68
86
|
const skeletons = [];
|
|
69
87
|
for (const name of skeletonNames) {
|
|
70
|
-
const entry =
|
|
88
|
+
const entry = chunkW236FF4E_cjs.get(name);
|
|
71
89
|
if (entry) skeletons.push(entry.data);
|
|
72
90
|
}
|
|
73
91
|
if (skeletons.length === 0) return "";
|
|
74
92
|
return [
|
|
75
|
-
|
|
76
|
-
|
|
93
|
+
chunkC2D4NZQB_cjs.renderCriticalStyleTag(skeletons, config),
|
|
94
|
+
chunkC2D4NZQB_cjs.renderHydrationScript()
|
|
77
95
|
].join("\n");
|
|
78
96
|
}
|
|
79
97
|
|
package/dist/astro.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/astro.ts"],"names":["get","renderSkeleton","generateCriticalCSS","renderCriticalStyleTag","renderHydrationScript"],"mappings":";;;;;;;;AA0CO,SAAS,mBAAmB,OAAA,EAGhC;AACD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO;AAAA,MACL,oBAAA,CAAqB,
|
|
1
|
+
{"version":3,"sources":["../src/adapters/astro.ts"],"names":["__require","get","renderSkeleton","generateCriticalCSS","renderCriticalStyleTag","renderHydrationScript"],"mappings":"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","file":"astro.cjs","sourcesContent":["import type { SkeletonData, CastDOMConfig } from \"../core/types.js\";\nimport { renderSkeleton, renderCriticalStyleTag, renderHydrationScript } from \"../seo/ssr.js\";\nimport { get as getFromRegistry, loadManifest } from \"../core/registry.js\";\nimport { generateCriticalCSS } from \"../core/renderer.js\";\nimport { renderStandalone } from \"../core/renderer.js\";\n\n/**\n * Astro adapter for CastDOM.\n *\n * Supports:\n * - Astro components (SSG and SSR)\n * - Island-aware skeletons (client:load, client:idle, client:visible)\n * - Automatic <style> injection\n * - View Transitions integration\n *\n * Usage:\n * ```astro\n * ---\n * // src/components/UserCard.astro\n * import { skeleton } from \"@lukas_holdings/castdom/astro\";\n * const { html, css } = skeleton(\"user-card\");\n * ---\n *\n * <style set:html={css}></style>\n * <div class=\"user-card-wrapper\" data-castdom=\"user-card\">\n * <Fragment set:html={html} />\n * </div>\n * ```\n */\n\n/**\n * Astro integration for CastDOM.\n * Add to your astro.config.mjs:\n *\n * ```js\n * import { castdomIntegration } from \"@lukas_holdings/castdom/astro\";\n *\n * export default defineConfig({\n * integrations: [castdomIntegration()],\n * });\n * ```\n */\nexport function castdomIntegration(options?: {\n manifestPath?: string;\n config?: Partial<CastDOMConfig>;\n}) {\n return {\n name: \"castdom\",\n hooks: {\n \"astro:config:setup\"({\n injectScript,\n logger,\n }: {\n injectScript: (stage: string, content: string) => void;\n logger?: { info: (msg: string) => void; warn: (msg: string) => void };\n }) {\n // Only inject the manifest loader if a manifest file actually exists.\n // Otherwise the build fails trying to resolve a non-existent JSON import.\n // This lets users add the integration before running `castdom build`.\n const manifestPath = options?.manifestPath ?? \".castdom/manifest.json\";\n\n // Resolve manifest path relative to the project root (process.cwd()).\n // Using require(\"fs\") keeps this hook synchronous without ESM top-level await.\n let manifestExists = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const fs = require(\"fs\");\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const path = require(\"path\");\n const absolute = path.isAbsolute(manifestPath)\n ? manifestPath\n : path.resolve(process.cwd(), manifestPath);\n manifestExists = fs.existsSync(absolute);\n } catch {\n manifestExists = false;\n }\n\n if (!manifestExists) {\n logger?.warn(\n `[castdom] No manifest found at \"${manifestPath}\". Skipping skeleton registry injection. ` +\n `Run \\`npx castdom build\\` to generate one.`\n );\n return;\n }\n\n injectScript(\n \"page-ssr\",\n `import manifest from \"${manifestPath}\" with { type: \"json\" };\\nimport { loadManifest } from \"@lukas_holdings/castdom\";\\nloadManifest(manifest);`\n );\n },\n\n \"astro:build:done\"() {\n // Could run extraction here if dev server is available\n },\n },\n };\n}\n\n/**\n * Get skeleton HTML and CSS for use in Astro components.\n *\n * ```astro\n * ---\n * import { skeleton } from \"@lukas_holdings/castdom/astro\";\n * const sk = skeleton(\"user-card\");\n * ---\n *\n * {sk.html && <Fragment set:html={sk.html} />}\n * ```\n */\nexport function skeleton(\n name: string,\n config?: Partial<CastDOMConfig>\n): { html: string; css: string; exists: boolean } {\n const entry = getFromRegistry(name);\n\n if (!entry) {\n return { html: \"\", css: \"\", exists: false };\n }\n\n const html = renderSkeleton(entry.data, { config });\n const css = generateCriticalCSS([entry.data], config);\n\n return { html, css, exists: true };\n}\n\n/**\n * Generate a complete Astro component string for a skeleton.\n * Useful for programmatic component generation.\n */\nexport function generateAstroComponent(\n name: string,\n config?: Partial<CastDOMConfig>\n): string {\n return `---\nimport { skeleton } from \"@lukas_holdings/castdom/astro\";\nconst { html, css } = skeleton(\"${name}\");\n---\n\n<style set:html={css}></style>\n<div data-castdom=\"${name}\">\n <Fragment set:html={html} />\n <slot />\n</div>\n\n<script>\n // Hydration: remove skeleton when slot content renders\n const wrapper = document.querySelector('[data-castdom=\"${name}\"]');\n if (wrapper) {\n const skeleton = wrapper.querySelector('.castdom-skeleton');\n if (skeleton && wrapper.children.length > 1) {\n skeleton.remove();\n }\n }\n</script>\n`;\n}\n\n/**\n * View Transitions helper — preserves skeleton state during navigation.\n *\n * ```astro\n * <div transition:persist data-castdom=\"sidebar\">\n * <Fragment set:html={skeleton(\"sidebar\").html} />\n * </div>\n * ```\n */\nexport function viewTransitionProps(name: string): Record<string, string> {\n return {\n \"transition:persist\": \"\",\n \"data-castdom\": name,\n \"transition:name\": `castdom-${name}`,\n };\n}\n\n/**\n * Generate <head> content for Astro pages.\n * Include in your Layout component.\n */\nexport function head(\n skeletonNames: string[],\n config?: Partial<CastDOMConfig>\n): string {\n const skeletons: SkeletonData[] = [];\n\n for (const name of skeletonNames) {\n const entry = getFromRegistry(name);\n if (entry) skeletons.push(entry.data);\n }\n\n if (skeletons.length === 0) return \"\";\n\n return [\n renderCriticalStyleTag(skeletons, config),\n renderHydrationScript(),\n ].join(\"\\n\");\n}\n"]}
|
package/dist/astro.d.cts
CHANGED
|
@@ -13,7 +13,7 @@ import { C as CastDOMConfig } from './types-ChD5jENU.cjs';
|
|
|
13
13
|
* ```astro
|
|
14
14
|
* ---
|
|
15
15
|
* // src/components/UserCard.astro
|
|
16
|
-
* import { skeleton } from "castdom/astro";
|
|
16
|
+
* import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
17
17
|
* const { html, css } = skeleton("user-card");
|
|
18
18
|
* ---
|
|
19
19
|
*
|
|
@@ -28,7 +28,7 @@ import { C as CastDOMConfig } from './types-ChD5jENU.cjs';
|
|
|
28
28
|
* Add to your astro.config.mjs:
|
|
29
29
|
*
|
|
30
30
|
* ```js
|
|
31
|
-
* import { castdomIntegration } from "castdom/astro";
|
|
31
|
+
* import { castdomIntegration } from "@lukas_holdings/castdom/astro";
|
|
32
32
|
*
|
|
33
33
|
* export default defineConfig({
|
|
34
34
|
* integrations: [castdomIntegration()],
|
|
@@ -41,8 +41,12 @@ declare function castdomIntegration(options?: {
|
|
|
41
41
|
}): {
|
|
42
42
|
name: string;
|
|
43
43
|
hooks: {
|
|
44
|
-
"astro:config:setup"({ injectScript }: {
|
|
44
|
+
"astro:config:setup"({ injectScript, logger, }: {
|
|
45
45
|
injectScript: (stage: string, content: string) => void;
|
|
46
|
+
logger?: {
|
|
47
|
+
info: (msg: string) => void;
|
|
48
|
+
warn: (msg: string) => void;
|
|
49
|
+
};
|
|
46
50
|
}): void;
|
|
47
51
|
"astro:build:done"(): void;
|
|
48
52
|
};
|
|
@@ -52,7 +56,7 @@ declare function castdomIntegration(options?: {
|
|
|
52
56
|
*
|
|
53
57
|
* ```astro
|
|
54
58
|
* ---
|
|
55
|
-
* import { skeleton } from "castdom/astro";
|
|
59
|
+
* import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
56
60
|
* const sk = skeleton("user-card");
|
|
57
61
|
* ---
|
|
58
62
|
*
|
package/dist/astro.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { C as CastDOMConfig } from './types-ChD5jENU.js';
|
|
|
13
13
|
* ```astro
|
|
14
14
|
* ---
|
|
15
15
|
* // src/components/UserCard.astro
|
|
16
|
-
* import { skeleton } from "castdom/astro";
|
|
16
|
+
* import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
17
17
|
* const { html, css } = skeleton("user-card");
|
|
18
18
|
* ---
|
|
19
19
|
*
|
|
@@ -28,7 +28,7 @@ import { C as CastDOMConfig } from './types-ChD5jENU.js';
|
|
|
28
28
|
* Add to your astro.config.mjs:
|
|
29
29
|
*
|
|
30
30
|
* ```js
|
|
31
|
-
* import { castdomIntegration } from "castdom/astro";
|
|
31
|
+
* import { castdomIntegration } from "@lukas_holdings/castdom/astro";
|
|
32
32
|
*
|
|
33
33
|
* export default defineConfig({
|
|
34
34
|
* integrations: [castdomIntegration()],
|
|
@@ -41,8 +41,12 @@ declare function castdomIntegration(options?: {
|
|
|
41
41
|
}): {
|
|
42
42
|
name: string;
|
|
43
43
|
hooks: {
|
|
44
|
-
"astro:config:setup"({ injectScript }: {
|
|
44
|
+
"astro:config:setup"({ injectScript, logger, }: {
|
|
45
45
|
injectScript: (stage: string, content: string) => void;
|
|
46
|
+
logger?: {
|
|
47
|
+
info: (msg: string) => void;
|
|
48
|
+
warn: (msg: string) => void;
|
|
49
|
+
};
|
|
46
50
|
}): void;
|
|
47
51
|
"astro:build:done"(): void;
|
|
48
52
|
};
|
|
@@ -52,7 +56,7 @@ declare function castdomIntegration(options?: {
|
|
|
52
56
|
*
|
|
53
57
|
* ```astro
|
|
54
58
|
* ---
|
|
55
|
-
* import { skeleton } from "castdom/astro";
|
|
59
|
+
* import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
56
60
|
* const sk = skeleton("user-card");
|
|
57
61
|
* ---
|
|
58
62
|
*
|
package/dist/astro.js
CHANGED
|
@@ -1,19 +1,37 @@
|
|
|
1
|
-
import { get } from './chunk-
|
|
2
|
-
import { renderSkeleton, renderCriticalStyleTag, renderHydrationScript } from './chunk-
|
|
3
|
-
import { generateCriticalCSS } from './chunk-
|
|
4
|
-
import './chunk-
|
|
1
|
+
import { get } from './chunk-V4FV5XFF.js';
|
|
2
|
+
import { renderSkeleton, renderCriticalStyleTag, renderHydrationScript } from './chunk-M4OXJTRQ.js';
|
|
3
|
+
import { generateCriticalCSS } from './chunk-GVFBT6MD.js';
|
|
4
|
+
import { __require } from './chunk-4LFW65DU.js';
|
|
5
5
|
|
|
6
6
|
// src/adapters/astro.ts
|
|
7
7
|
function castdomIntegration(options) {
|
|
8
8
|
return {
|
|
9
9
|
name: "castdom",
|
|
10
10
|
hooks: {
|
|
11
|
-
"astro:config:setup"({
|
|
11
|
+
"astro:config:setup"({
|
|
12
|
+
injectScript,
|
|
13
|
+
logger
|
|
14
|
+
}) {
|
|
12
15
|
const manifestPath = options?.manifestPath ?? ".castdom/manifest.json";
|
|
16
|
+
let manifestExists = false;
|
|
17
|
+
try {
|
|
18
|
+
const fs = __require("fs");
|
|
19
|
+
const path = __require("path");
|
|
20
|
+
const absolute = path.isAbsolute(manifestPath) ? manifestPath : path.resolve(process.cwd(), manifestPath);
|
|
21
|
+
manifestExists = fs.existsSync(absolute);
|
|
22
|
+
} catch {
|
|
23
|
+
manifestExists = false;
|
|
24
|
+
}
|
|
25
|
+
if (!manifestExists) {
|
|
26
|
+
logger?.warn(
|
|
27
|
+
`[castdom] No manifest found at "${manifestPath}". Skipping skeleton registry injection. Run \`npx castdom build\` to generate one.`
|
|
28
|
+
);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
13
31
|
injectScript(
|
|
14
32
|
"page-ssr",
|
|
15
33
|
`import manifest from "${manifestPath}" with { type: "json" };
|
|
16
|
-
import { loadManifest } from "castdom";
|
|
34
|
+
import { loadManifest } from "@lukas_holdings/castdom";
|
|
17
35
|
loadManifest(manifest);`
|
|
18
36
|
);
|
|
19
37
|
},
|
|
@@ -33,7 +51,7 @@ function skeleton(name, config) {
|
|
|
33
51
|
}
|
|
34
52
|
function generateAstroComponent(name, config) {
|
|
35
53
|
return `---
|
|
36
|
-
import { skeleton } from "castdom/astro";
|
|
54
|
+
import { skeleton } from "@lukas_holdings/castdom/astro";
|
|
37
55
|
const { html, css } = skeleton("${name}");
|
|
38
56
|
---
|
|
39
57
|
|
package/dist/astro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/astro.ts"],"names":[],"mappings":";;;;;;AA0CO,SAAS,mBAAmB,OAAA,EAGhC;AACD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO;AAAA,MACL,oBAAA,CAAqB,
|
|
1
|
+
{"version":3,"sources":["../src/adapters/astro.ts"],"names":[],"mappings":";;;;;;AA0CO,SAAS,mBAAmB,OAAA,EAGhC;AACD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO;AAAA,MACL,oBAAA,CAAqB;AAAA,QACnB,YAAA;AAAA,QACA;AAAA,OACF,EAGG;AAID,QAAA,MAAM,YAAA,GAAe,SAAS,YAAA,IAAgB,wBAAA;AAI9C,QAAA,IAAI,cAAA,GAAiB,KAAA;AACrB,QAAA,IAAI;AAEF,UAAA,MAAM,EAAA,GAAK,UAAQ,IAAI,CAAA;AAEvB,UAAA,MAAM,IAAA,GAAO,UAAQ,MAAM,CAAA;AAC3B,UAAA,MAAM,QAAA,GAAW,IAAA,CAAK,UAAA,CAAW,YAAY,CAAA,GACzC,YAAA,GACA,IAAA,CAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,EAAI,EAAG,YAAY,CAAA;AAC5C,UAAA,cAAA,GAAiB,EAAA,CAAG,WAAW,QAAQ,CAAA;AAAA,QACzC,CAAA,CAAA,MAAQ;AACN,UAAA,cAAA,GAAiB,KAAA;AAAA,QACnB;AAEA,QAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,UAAA,MAAA,EAAQ,IAAA;AAAA,YACN,mCAAmC,YAAY,CAAA,mFAAA;AAAA,WAEjD;AACA,UAAA;AAAA,QACF;AAEA,QAAA,YAAA;AAAA,UACE,UAAA;AAAA,UACA,yBAAyB,YAAY,CAAA;AAAA;AAAA,uBAAA;AAAA,SACvC;AAAA,MACF,CAAA;AAAA,MAEA,kBAAA,GAAqB;AAAA,MAErB;AAAA;AACF,GACF;AACF;AAcO,SAAS,QAAA,CACd,MACA,MAAA,EACgD;AAChD,EAAA,MAAM,KAAA,GAAQ,IAAgB,IAAI,CAAA;AAElC,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,EAAE,IAAA,EAAM,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,QAAQ,KAAA,EAAM;AAAA,EAC5C;AAEA,EAAA,MAAM,OAAO,cAAA,CAAe,KAAA,CAAM,IAAA,EAAM,EAAE,QAAQ,CAAA;AAClD,EAAA,MAAM,MAAM,mBAAA,CAAoB,CAAC,KAAA,CAAM,IAAI,GAAG,MAAM,CAAA;AAEpD,EAAA,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,MAAA,EAAQ,IAAA,EAAK;AACnC;AAMO,SAAS,sBAAA,CACd,MACA,MAAA,EACQ;AACR,EAAA,OAAO,CAAA;AAAA;AAAA,gCAAA,EAEyB,IAAI,CAAA;AAAA;;AAAA;AAAA,mBAAA,EAIjB,IAAI,CAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA,yDAAA,EAOkC,IAAI,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAS/D;AAWO,SAAS,oBAAoB,IAAA,EAAsC;AACxE,EAAA,OAAO;AAAA,IACL,oBAAA,EAAsB,EAAA;AAAA,IACtB,cAAA,EAAgB,IAAA;AAAA,IAChB,iBAAA,EAAmB,WAAW,IAAI,CAAA;AAAA,GACpC;AACF;AAMO,SAAS,IAAA,CACd,eACA,MAAA,EACQ;AACR,EAAA,MAAM,YAA4B,EAAC;AAEnC,EAAA,KAAA,MAAW,QAAQ,aAAA,EAAe;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAgB,IAAI,CAAA;AAClC,IAAA,IAAI,KAAA,EAAO,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAAA,EACtC;AAEA,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,EAAA;AAEnC,EAAA,OAAO;AAAA,IACL,sBAAA,CAAuB,WAAW,MAAM,CAAA;AAAA,IACxC,qBAAA;AAAsB,GACxB,CAAE,KAAK,IAAI,CAAA;AACb","file":"astro.js","sourcesContent":["import type { SkeletonData, CastDOMConfig } from \"../core/types.js\";\nimport { renderSkeleton, renderCriticalStyleTag, renderHydrationScript } from \"../seo/ssr.js\";\nimport { get as getFromRegistry, loadManifest } from \"../core/registry.js\";\nimport { generateCriticalCSS } from \"../core/renderer.js\";\nimport { renderStandalone } from \"../core/renderer.js\";\n\n/**\n * Astro adapter for CastDOM.\n *\n * Supports:\n * - Astro components (SSG and SSR)\n * - Island-aware skeletons (client:load, client:idle, client:visible)\n * - Automatic <style> injection\n * - View Transitions integration\n *\n * Usage:\n * ```astro\n * ---\n * // src/components/UserCard.astro\n * import { skeleton } from \"@lukas_holdings/castdom/astro\";\n * const { html, css } = skeleton(\"user-card\");\n * ---\n *\n * <style set:html={css}></style>\n * <div class=\"user-card-wrapper\" data-castdom=\"user-card\">\n * <Fragment set:html={html} />\n * </div>\n * ```\n */\n\n/**\n * Astro integration for CastDOM.\n * Add to your astro.config.mjs:\n *\n * ```js\n * import { castdomIntegration } from \"@lukas_holdings/castdom/astro\";\n *\n * export default defineConfig({\n * integrations: [castdomIntegration()],\n * });\n * ```\n */\nexport function castdomIntegration(options?: {\n manifestPath?: string;\n config?: Partial<CastDOMConfig>;\n}) {\n return {\n name: \"castdom\",\n hooks: {\n \"astro:config:setup\"({\n injectScript,\n logger,\n }: {\n injectScript: (stage: string, content: string) => void;\n logger?: { info: (msg: string) => void; warn: (msg: string) => void };\n }) {\n // Only inject the manifest loader if a manifest file actually exists.\n // Otherwise the build fails trying to resolve a non-existent JSON import.\n // This lets users add the integration before running `castdom build`.\n const manifestPath = options?.manifestPath ?? \".castdom/manifest.json\";\n\n // Resolve manifest path relative to the project root (process.cwd()).\n // Using require(\"fs\") keeps this hook synchronous without ESM top-level await.\n let manifestExists = false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const fs = require(\"fs\");\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const path = require(\"path\");\n const absolute = path.isAbsolute(manifestPath)\n ? manifestPath\n : path.resolve(process.cwd(), manifestPath);\n manifestExists = fs.existsSync(absolute);\n } catch {\n manifestExists = false;\n }\n\n if (!manifestExists) {\n logger?.warn(\n `[castdom] No manifest found at \"${manifestPath}\". Skipping skeleton registry injection. ` +\n `Run \\`npx castdom build\\` to generate one.`\n );\n return;\n }\n\n injectScript(\n \"page-ssr\",\n `import manifest from \"${manifestPath}\" with { type: \"json\" };\\nimport { loadManifest } from \"@lukas_holdings/castdom\";\\nloadManifest(manifest);`\n );\n },\n\n \"astro:build:done\"() {\n // Could run extraction here if dev server is available\n },\n },\n };\n}\n\n/**\n * Get skeleton HTML and CSS for use in Astro components.\n *\n * ```astro\n * ---\n * import { skeleton } from \"@lukas_holdings/castdom/astro\";\n * const sk = skeleton(\"user-card\");\n * ---\n *\n * {sk.html && <Fragment set:html={sk.html} />}\n * ```\n */\nexport function skeleton(\n name: string,\n config?: Partial<CastDOMConfig>\n): { html: string; css: string; exists: boolean } {\n const entry = getFromRegistry(name);\n\n if (!entry) {\n return { html: \"\", css: \"\", exists: false };\n }\n\n const html = renderSkeleton(entry.data, { config });\n const css = generateCriticalCSS([entry.data], config);\n\n return { html, css, exists: true };\n}\n\n/**\n * Generate a complete Astro component string for a skeleton.\n * Useful for programmatic component generation.\n */\nexport function generateAstroComponent(\n name: string,\n config?: Partial<CastDOMConfig>\n): string {\n return `---\nimport { skeleton } from \"@lukas_holdings/castdom/astro\";\nconst { html, css } = skeleton(\"${name}\");\n---\n\n<style set:html={css}></style>\n<div data-castdom=\"${name}\">\n <Fragment set:html={html} />\n <slot />\n</div>\n\n<script>\n // Hydration: remove skeleton when slot content renders\n const wrapper = document.querySelector('[data-castdom=\"${name}\"]');\n if (wrapper) {\n const skeleton = wrapper.querySelector('.castdom-skeleton');\n if (skeleton && wrapper.children.length > 1) {\n skeleton.remove();\n }\n }\n</script>\n`;\n}\n\n/**\n * View Transitions helper — preserves skeleton state during navigation.\n *\n * ```astro\n * <div transition:persist data-castdom=\"sidebar\">\n * <Fragment set:html={skeleton(\"sidebar\").html} />\n * </div>\n * ```\n */\nexport function viewTransitionProps(name: string): Record<string, string> {\n return {\n \"transition:persist\": \"\",\n \"data-castdom\": name,\n \"transition:name\": `castdom-${name}`,\n };\n}\n\n/**\n * Generate <head> content for Astro pages.\n * Include in your Layout component.\n */\nexport function head(\n skeletonNames: string[],\n config?: Partial<CastDOMConfig>\n): string {\n const skeletons: SkeletonData[] = [];\n\n for (const name of skeletonNames) {\n const entry = getFromRegistry(name);\n if (entry) skeletons.push(entry.data);\n }\n\n if (skeletons.length === 0) return \"\";\n\n return [\n renderCriticalStyleTag(skeletons, config),\n renderHydrationScript(),\n ].join(\"\\n\");\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { selectBreakpoint } from './chunk-
|
|
2
|
-
import { get } from './chunk-
|
|
1
|
+
import { selectBreakpoint } from './chunk-6RFGWOGG.js';
|
|
2
|
+
import { get } from './chunk-V4FV5XFF.js';
|
|
3
3
|
import { useState, useRef, useEffect, createElement, useCallback, useMemo } from 'react';
|
|
4
4
|
|
|
5
5
|
function CastDOM({
|
|
@@ -189,5 +189,5 @@ function useCastDOM(name) {
|
|
|
189
189
|
var react_default = CastDOM;
|
|
190
190
|
|
|
191
191
|
export { CastDOM, CastDOMStyle, react_default, useCastDOM };
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
193
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-275VEEA7.js.map
|
|
193
|
+
//# sourceMappingURL=chunk-275VEEA7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/react.tsx"],"names":[],"mappings":"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","file":"chunk-ZBJB7WVV.js","sourcesContent":["\"use client\";\n\nimport {\n type ReactNode,\n type CSSProperties,\n useState,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n createElement,\n} from \"react\";\nimport type { SkeletonData, BreakpointData, CastDOMConfig } from \"../core/types.js\";\nimport { get as getFromRegistry } from \"../core/registry.js\";\nimport { selectBreakpoint } from \"../core/responsive.js\";\n\nexport interface CastDOMProps {\n /** Name of the registered skeleton */\n name: string;\n /** Children to render once loaded */\n children: ReactNode;\n /** Whether the content is still loading (default: false when children mount) */\n loading?: boolean;\n /** Custom fallback while skeleton data loads from registry */\n fallback?: ReactNode;\n /** Animation type override */\n animation?: \"shimmer\" | \"pulse\" | \"wave\" | \"none\";\n /** Base color override */\n color?: string;\n /** Shimmer highlight color override */\n shimmerColor?: string;\n /** Animation duration override (ms) */\n duration?: number;\n /** Additional CSS class */\n className?: string;\n /** Additional inline styles */\n style?: CSSProperties;\n /** Callback when skeleton is shown */\n onSkeletonShow?: () => void;\n /** Callback when real content replaces skeleton */\n onContentShow?: () => void;\n /** Aria label for the loading state */\n ariaLabel?: string;\n}\n\n/**\n * <CastDOM> — wraps your component and shows an extracted skeleton while loading.\n *\n * Usage:\n * ```tsx\n * <CastDOM name=\"user-card\" loading={isLoading}>\n * <UserCard data={data} />\n * </CastDOM>\n * ```\n *\n * The skeleton auto-resolves from the global registry.\n * Register skeletons once at app entry with `loadManifest()`.\n */\nexport function CastDOM({\n name,\n children,\n loading,\n fallback,\n animation = \"shimmer\",\n color,\n shimmerColor,\n duration,\n className,\n style,\n onSkeletonShow,\n onContentShow,\n ariaLabel,\n}: CastDOMProps): ReactNode {\n const [isLoading, setIsLoading] = useState(loading ?? true);\n const [viewportWidth, setViewportWidth] = useState<number>(\n typeof window !== \"undefined\" ? window.innerWidth : 1280\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const shownRef = useRef(false);\n\n // Track loading state\n useEffect(() => {\n if (loading !== undefined) {\n setIsLoading(loading);\n }\n }, [loading]);\n\n // Auto-detect loading completion when loading prop is not provided\n useEffect(() => {\n if (loading === undefined && children) {\n setIsLoading(false);\n }\n }, [loading, children]);\n\n // Track viewport width for responsive skeletons\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const onResize = () => setViewportWidth(window.innerWidth);\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, []);\n\n // Callbacks\n useEffect(() => {\n if (isLoading && !shownRef.current) {\n shownRef.current = true;\n onSkeletonShow?.();\n }\n if (!isLoading && shownRef.current) {\n onContentShow?.();\n }\n }, [isLoading, onSkeletonShow, onContentShow]);\n\n // Get skeleton from registry\n const entry = getFromRegistry(name);\n\n if (!isLoading) {\n return createElement(\n \"div\",\n {\n ref: containerRef,\n className,\n style,\n \"data-castdom\": name,\n },\n children\n );\n }\n\n // No skeleton data — show fallback or nothing\n if (!entry) {\n return fallback\n ? createElement(\"div\", { className, style }, fallback)\n : null;\n }\n\n // Select best breakpoint\n const bp = selectBreakpoint(entry.data, viewportWidth);\n if (!bp) return fallback ? createElement(\"div\", { className, style }, fallback) : null;\n\n // Render skeleton\n return createElement(SkeletonRenderer, {\n name,\n breakpoint: bp,\n animation,\n color,\n shimmerColor,\n duration,\n className,\n style,\n ariaLabel,\n });\n}\n\n/** Internal skeleton renderer — pure CSS, no JS animation runtime */\ninterface SkeletonRendererProps {\n name: string;\n breakpoint: BreakpointData;\n animation: \"shimmer\" | \"pulse\" | \"wave\" | \"none\";\n color?: string;\n shimmerColor?: string;\n duration?: number;\n className?: string;\n style?: CSSProperties;\n ariaLabel?: string;\n}\n\nfunction SkeletonRenderer({\n name,\n breakpoint,\n animation,\n color = \"#e0e0e0\",\n shimmerColor = \"#f0f0f0\",\n duration = 1500,\n className,\n style,\n ariaLabel,\n}: SkeletonRendererProps): ReactNode {\n const bones = breakpoint.bones;\n\n const containerStyle: CSSProperties = {\n position: \"relative\",\n width: breakpoint.containerWidth,\n height: breakpoint.containerHeight,\n overflow: \"hidden\",\n ...style,\n };\n\n const getBackground = useCallback(() => {\n switch (animation) {\n case \"shimmer\":\n return `linear-gradient(90deg, ${color} 25%, ${shimmerColor} 50%, ${color} 75%)`;\n case \"pulse\":\n case \"wave\":\n case \"none\":\n return color;\n }\n }, [animation, color, shimmerColor]);\n\n const getAnimationCSS = useCallback((): string => {\n switch (animation) {\n case \"shimmer\":\n return `castdom-shimmer ${duration}ms ease-in-out infinite`;\n case \"pulse\":\n return `castdom-pulse ${duration}ms ease-in-out infinite`;\n case \"wave\":\n return `castdom-wave ${duration}ms ease-in-out infinite`;\n case \"none\":\n return \"none\";\n }\n }, [animation, duration]);\n\n return createElement(\n \"div\",\n {\n className: `castdom-skeleton castdom-${name}${className ? ` ${className}` : \"\"}`,\n style: containerStyle,\n role: \"status\",\n \"aria-busy\": true,\n \"aria-label\": ariaLabel ?? `Loading ${name}`,\n },\n bones.map((bone, i) =>\n createElement(\"div\", {\n key: i,\n className: \"castdom-bone\",\n \"aria-hidden\": true,\n style: {\n position: \"absolute\" as const,\n left: bone.x,\n top: bone.y,\n width: bone.w,\n height: bone.h,\n borderRadius: bone.r >= 9999 ? \"50%\" : bone.r,\n background: getBackground(),\n backgroundSize: animation === \"shimmer\" ? \"200% 100%\" : undefined,\n animation: getAnimationCSS(),\n animationDelay: animation === \"wave\" ? `${i * 50}ms` : undefined,\n } satisfies CSSProperties,\n })\n )\n );\n}\n\n/**\n * <CastDOMStyle> — renders the critical CSS for registered skeletons.\n * Place this in your <head> or layout for optimal performance.\n *\n * ```tsx\n * <head>\n * <CastDOMStyle skeletons={[\"user-card\", \"feed-item\"]} />\n * </head>\n * ```\n */\nexport function CastDOMStyle({\n skeletons,\n}: {\n skeletons?: string[];\n}): ReactNode {\n const css = useMemo(() => {\n const parts: string[] = [\n \"@keyframes castdom-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}\",\n \"@keyframes castdom-pulse{0%,100%{opacity:1}50%{opacity:0.4}}\",\n \"@keyframes castdom-wave{0%{opacity:0.4}50%{opacity:1}100%{opacity:0.4}}\",\n \"@media(prefers-reduced-motion:reduce){.castdom-bone{animation:none!important}}\",\n ];\n return parts.join(\"\");\n }, []);\n\n return createElement(\"style\", {\n dangerouslySetInnerHTML: { __html: css },\n \"data-castdom\": \"critical\",\n });\n}\n\n/**\n * Hook: useCastDOM — programmatic access to skeleton data.\n */\nexport function useCastDOM(name: string) {\n const entry = getFromRegistry(name);\n const [vw, setVW] = useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1280\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onResize = () => setVW(window.innerWidth);\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, []);\n\n const breakpoint = entry ? selectBreakpoint(entry.data, vw) : null;\n\n return {\n exists: !!entry,\n data: entry?.data ?? null,\n breakpoint,\n css: entry?.css ?? \"\",\n html: breakpoint ? entry?.html[breakpoint.viewport] ?? \"\" : \"\",\n };\n}\n\nexport default CastDOM;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/react.tsx"],"names":[],"mappings":"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","file":"chunk-275VEEA7.js","sourcesContent":["\"use client\";\n\nimport {\n type ReactNode,\n type CSSProperties,\n useState,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n createElement,\n} from \"react\";\nimport type { SkeletonData, BreakpointData, CastDOMConfig } from \"../core/types.js\";\nimport { get as getFromRegistry } from \"../core/registry.js\";\nimport { selectBreakpoint } from \"../core/responsive.js\";\n\nexport interface CastDOMProps {\n /** Name of the registered skeleton */\n name: string;\n /** Children to render once loaded */\n children: ReactNode;\n /** Whether the content is still loading (default: false when children mount) */\n loading?: boolean;\n /** Custom fallback while skeleton data loads from registry */\n fallback?: ReactNode;\n /** Animation type override */\n animation?: \"shimmer\" | \"pulse\" | \"wave\" | \"none\";\n /** Base color override */\n color?: string;\n /** Shimmer highlight color override */\n shimmerColor?: string;\n /** Animation duration override (ms) */\n duration?: number;\n /** Additional CSS class */\n className?: string;\n /** Additional inline styles */\n style?: CSSProperties;\n /** Callback when skeleton is shown */\n onSkeletonShow?: () => void;\n /** Callback when real content replaces skeleton */\n onContentShow?: () => void;\n /** Aria label for the loading state */\n ariaLabel?: string;\n}\n\n/**\n * <CastDOM> — wraps your component and shows an extracted skeleton while loading.\n *\n * Usage:\n * ```tsx\n * <CastDOM name=\"user-card\" loading={isLoading}>\n * <UserCard data={data} />\n * </CastDOM>\n * ```\n *\n * The skeleton auto-resolves from the global registry.\n * Register skeletons once at app entry with `loadManifest()`.\n */\nexport function CastDOM({\n name,\n children,\n loading,\n fallback,\n animation = \"shimmer\",\n color,\n shimmerColor,\n duration,\n className,\n style,\n onSkeletonShow,\n onContentShow,\n ariaLabel,\n}: CastDOMProps): ReactNode {\n const [isLoading, setIsLoading] = useState(loading ?? true);\n const [viewportWidth, setViewportWidth] = useState<number>(\n typeof window !== \"undefined\" ? window.innerWidth : 1280\n );\n const containerRef = useRef<HTMLDivElement>(null);\n const shownRef = useRef(false);\n\n // Track loading state\n useEffect(() => {\n if (loading !== undefined) {\n setIsLoading(loading);\n }\n }, [loading]);\n\n // Auto-detect loading completion when loading prop is not provided\n useEffect(() => {\n if (loading === undefined && children) {\n setIsLoading(false);\n }\n }, [loading, children]);\n\n // Track viewport width for responsive skeletons\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const onResize = () => setViewportWidth(window.innerWidth);\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, []);\n\n // Callbacks\n useEffect(() => {\n if (isLoading && !shownRef.current) {\n shownRef.current = true;\n onSkeletonShow?.();\n }\n if (!isLoading && shownRef.current) {\n onContentShow?.();\n }\n }, [isLoading, onSkeletonShow, onContentShow]);\n\n // Get skeleton from registry\n const entry = getFromRegistry(name);\n\n if (!isLoading) {\n return createElement(\n \"div\",\n {\n ref: containerRef,\n className,\n style,\n \"data-castdom\": name,\n },\n children\n );\n }\n\n // No skeleton data — show fallback or nothing\n if (!entry) {\n return fallback\n ? createElement(\"div\", { className, style }, fallback)\n : null;\n }\n\n // Select best breakpoint\n const bp = selectBreakpoint(entry.data, viewportWidth);\n if (!bp) return fallback ? createElement(\"div\", { className, style }, fallback) : null;\n\n // Render skeleton\n return createElement(SkeletonRenderer, {\n name,\n breakpoint: bp,\n animation,\n color,\n shimmerColor,\n duration,\n className,\n style,\n ariaLabel,\n });\n}\n\n/** Internal skeleton renderer — pure CSS, no JS animation runtime */\ninterface SkeletonRendererProps {\n name: string;\n breakpoint: BreakpointData;\n animation: \"shimmer\" | \"pulse\" | \"wave\" | \"none\";\n color?: string;\n shimmerColor?: string;\n duration?: number;\n className?: string;\n style?: CSSProperties;\n ariaLabel?: string;\n}\n\nfunction SkeletonRenderer({\n name,\n breakpoint,\n animation,\n color = \"#e0e0e0\",\n shimmerColor = \"#f0f0f0\",\n duration = 1500,\n className,\n style,\n ariaLabel,\n}: SkeletonRendererProps): ReactNode {\n const bones = breakpoint.bones;\n\n const containerStyle: CSSProperties = {\n position: \"relative\",\n width: breakpoint.containerWidth,\n height: breakpoint.containerHeight,\n overflow: \"hidden\",\n ...style,\n };\n\n const getBackground = useCallback(() => {\n switch (animation) {\n case \"shimmer\":\n return `linear-gradient(90deg, ${color} 25%, ${shimmerColor} 50%, ${color} 75%)`;\n case \"pulse\":\n case \"wave\":\n case \"none\":\n return color;\n }\n }, [animation, color, shimmerColor]);\n\n const getAnimationCSS = useCallback((): string => {\n switch (animation) {\n case \"shimmer\":\n return `castdom-shimmer ${duration}ms ease-in-out infinite`;\n case \"pulse\":\n return `castdom-pulse ${duration}ms ease-in-out infinite`;\n case \"wave\":\n return `castdom-wave ${duration}ms ease-in-out infinite`;\n case \"none\":\n return \"none\";\n }\n }, [animation, duration]);\n\n return createElement(\n \"div\",\n {\n className: `castdom-skeleton castdom-${name}${className ? ` ${className}` : \"\"}`,\n style: containerStyle,\n role: \"status\",\n \"aria-busy\": true,\n \"aria-label\": ariaLabel ?? `Loading ${name}`,\n },\n bones.map((bone, i) =>\n createElement(\"div\", {\n key: i,\n className: \"castdom-bone\",\n \"aria-hidden\": true,\n style: {\n position: \"absolute\" as const,\n left: bone.x,\n top: bone.y,\n width: bone.w,\n height: bone.h,\n borderRadius: bone.r >= 9999 ? \"50%\" : bone.r,\n background: getBackground(),\n backgroundSize: animation === \"shimmer\" ? \"200% 100%\" : undefined,\n animation: getAnimationCSS(),\n animationDelay: animation === \"wave\" ? `${i * 50}ms` : undefined,\n } satisfies CSSProperties,\n })\n )\n );\n}\n\n/**\n * <CastDOMStyle> — renders the critical CSS for registered skeletons.\n * Place this in your <head> or layout for optimal performance.\n *\n * ```tsx\n * <head>\n * <CastDOMStyle skeletons={[\"user-card\", \"feed-item\"]} />\n * </head>\n * ```\n */\nexport function CastDOMStyle({\n skeletons,\n}: {\n skeletons?: string[];\n}): ReactNode {\n const css = useMemo(() => {\n const parts: string[] = [\n \"@keyframes castdom-shimmer{0%{background-position:-200% 0}100%{background-position:200% 0}}\",\n \"@keyframes castdom-pulse{0%,100%{opacity:1}50%{opacity:0.4}}\",\n \"@keyframes castdom-wave{0%{opacity:0.4}50%{opacity:1}100%{opacity:0.4}}\",\n \"@media(prefers-reduced-motion:reduce){.castdom-bone{animation:none!important}}\",\n ];\n return parts.join(\"\");\n }, []);\n\n return createElement(\"style\", {\n dangerouslySetInnerHTML: { __html: css },\n \"data-castdom\": \"critical\",\n });\n}\n\n/**\n * Hook: useCastDOM — programmatic access to skeleton data.\n */\nexport function useCastDOM(name: string) {\n const entry = getFromRegistry(name);\n const [vw, setVW] = useState(\n typeof window !== \"undefined\" ? window.innerWidth : 1280\n );\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const onResize = () => setVW(window.innerWidth);\n window.addEventListener(\"resize\", onResize, { passive: true });\n return () => window.removeEventListener(\"resize\", onResize);\n }, []);\n\n const breakpoint = entry ? selectBreakpoint(entry.data, vw) : null;\n\n return {\n exists: !!entry,\n data: entry?.data ?? null,\n breakpoint,\n css: entry?.css ?? \"\",\n html: breakpoint ? entry?.html[breakpoint.viewport] ?? \"\" : \"\",\n };\n}\n\nexport default CastDOM;\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/core/types.ts
|
|
9
|
+
var DEFAULTS = {
|
|
10
|
+
outDir: ".castdom",
|
|
11
|
+
breakpoints: [375, 768, 1280],
|
|
12
|
+
color: "#e0e0e0",
|
|
13
|
+
shimmerColor: "#f0f0f0",
|
|
14
|
+
animationDuration: 1500,
|
|
15
|
+
contentAware: true,
|
|
16
|
+
minBoneSize: 4,
|
|
17
|
+
classPrefix: "castdom",
|
|
18
|
+
inlineStyles: false,
|
|
19
|
+
ssr: true
|
|
20
|
+
};
|
|
21
|
+
var BONE_KIND_INDEX = {
|
|
22
|
+
text: 1,
|
|
23
|
+
heading: 2,
|
|
24
|
+
image: 3,
|
|
25
|
+
avatar: 4,
|
|
26
|
+
button: 5,
|
|
27
|
+
input: 6,
|
|
28
|
+
icon: 7,
|
|
29
|
+
divider: 8,
|
|
30
|
+
block: 0
|
|
31
|
+
};
|
|
32
|
+
var BONE_KIND_FROM_INDEX = Object.fromEntries(
|
|
33
|
+
Object.entries(BONE_KIND_INDEX).map(([k, v]) => [v, k])
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
export { BONE_KIND_FROM_INDEX, BONE_KIND_INDEX, DEFAULTS, __require };
|
|
37
|
+
//# sourceMappingURL=chunk-4LFW65DU.js.map
|
|
38
|
+
//# sourceMappingURL=chunk-4LFW65DU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/types.ts"],"names":[],"mappings":";;;;;;;;AAqHO,IAAM,QAAA,GAcT;AAAA,EACF,MAAA,EAAQ,UAAA;AAAA,EACR,WAAA,EAAa,CAAC,GAAA,EAAK,GAAA,EAAK,IAAI,CAAA;AAAA,EAC5B,KAAA,EAAO,SAAA;AAAA,EACP,YAAA,EAAc,SAAA;AAAA,EACd,iBAAA,EAAmB,IAAA;AAAA,EACnB,YAAA,EAAc,IAAA;AAAA,EACd,WAAA,EAAa,CAAA;AAAA,EACb,WAAA,EAAa,SAAA;AAAA,EACb,YAAA,EAAc,KAAA;AAAA,EACd,GAAA,EAAK;AACP;AAGO,IAAM,eAAA,GAA4C;AAAA,EACvD,IAAA,EAAM,CAAA;AAAA,EACN,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO,CAAA;AAAA,EACP,MAAA,EAAQ,CAAA;AAAA,EACR,MAAA,EAAQ,CAAA;AAAA,EACR,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,CAAA;AAAA,EACN,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO;AACT;AAEO,IAAM,uBAAiD,MAAA,CAAO,WAAA;AAAA,EACnE,MAAA,CAAO,OAAA,CAAQ,eAAe,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAC,CAAA,EAAG,CAAa,CAAC;AACpE","file":"chunk-4LFW65DU.js","sourcesContent":["/** A single bone — one rectangular skeleton element */\nexport interface Bone {\n /** X position relative to container (px) */\n x: number;\n /** Y position relative to container (px) */\n y: number;\n /** Width (px) */\n w: number;\n /** Height (px) */\n h: number;\n /** Border radius (px). 9999 = circle */\n r: number;\n /** Element type hint for content-aware rendering */\n kind?: BoneKind;\n}\n\nexport type BoneKind =\n | \"text\"\n | \"heading\"\n | \"image\"\n | \"avatar\"\n | \"button\"\n | \"input\"\n | \"icon\"\n | \"divider\"\n | \"block\";\n\n/** Bone data for a single breakpoint */\nexport interface BreakpointData {\n /** Viewport width this was captured at */\n viewport: number;\n /** Container width at capture time */\n containerWidth: number;\n /** Container height at capture time */\n containerHeight: number;\n /** All bones at this breakpoint */\n bones: Bone[];\n}\n\n/** Complete skeleton definition for a named component */\nexport interface SkeletonData {\n /** Unique name for this skeleton */\n name: string;\n /** Version hash for cache busting */\n hash: string;\n /** Breakpoint data, sorted ascending by viewport width */\n breakpoints: BreakpointData[];\n /** Timestamp of last extraction */\n extractedAt: number;\n}\n\n/** Configuration for CastDOM */\nexport interface CastDOMConfig {\n /** Directory to output generated skeleton data */\n outDir?: string;\n /** Breakpoint widths to capture at (default: [375, 768, 1280]) */\n breakpoints?: number[];\n /** Base color for skeleton bones (default: \"#e0e0e0\") */\n color?: string;\n /** Shimmer highlight color (default: \"#f0f0f0\") */\n shimmerColor?: string;\n /** Animation duration in ms (default: 1500) */\n animationDuration?: number;\n /** Enable content-aware bone detection (default: true) */\n contentAware?: boolean;\n /** Minimum bone size to include in px (default: 4) */\n minBoneSize?: number;\n /** CSS class prefix (default: \"castdom\") */\n classPrefix?: string;\n /** Generate inline styles instead of class-based (default: false) */\n inlineStyles?: boolean;\n /** Enable SSR rendering (default: true) */\n ssr?: boolean;\n /** URL or path to dev server for extraction */\n devServer?: string;\n /** Routes to snapshot for extraction */\n routes?: string[];\n /** Playwright launch options */\n playwright?: {\n headless?: boolean;\n timeout?: number;\n };\n}\n\n/** Registry entry used at runtime */\nexport interface RegistryEntry {\n data: SkeletonData;\n css: string;\n html: Record<number, string>;\n}\n\n/** Extraction target — what to snapshot */\nexport interface ExtractionTarget {\n name: string;\n selector: string;\n route?: string;\n}\n\n/** Result from the extraction process */\nexport interface ExtractionResult {\n target: ExtractionTarget;\n skeleton: SkeletonData;\n}\n\n/** Compressed bone format for wire/storage (delta-encoded) */\nexport interface CompressedBones {\n /** Version of compression format */\n v: 1;\n /** Viewport width */\n vw: number;\n /** Container dimensions [w, h] */\n c: [number, number];\n /** Flat array: [x, y, w, h, r, kind, ...] per bone. kind is enum index. */\n d: number[];\n}\n\n/** Default configuration values */\nexport const DEFAULTS: Required<\n Pick<\n CastDOMConfig,\n | \"outDir\"\n | \"breakpoints\"\n | \"color\"\n | \"shimmerColor\"\n | \"animationDuration\"\n | \"contentAware\"\n | \"minBoneSize\"\n | \"classPrefix\"\n | \"inlineStyles\"\n | \"ssr\"\n >\n> = {\n outDir: \".castdom\",\n breakpoints: [375, 768, 1280],\n color: \"#e0e0e0\",\n shimmerColor: \"#f0f0f0\",\n animationDuration: 1500,\n contentAware: true,\n minBoneSize: 4,\n classPrefix: \"castdom\",\n inlineStyles: false,\n ssr: true,\n};\n\n/** Map bone kind to numeric index for compression */\nexport const BONE_KIND_INDEX: Record<BoneKind, number> = {\n text: 1,\n heading: 2,\n image: 3,\n avatar: 4,\n button: 5,\n input: 6,\n icon: 7,\n divider: 8,\n block: 0,\n};\n\nexport const BONE_KIND_FROM_INDEX: Record<number, BoneKind> = Object.fromEntries(\n Object.entries(BONE_KIND_INDEX).map(([k, v]) => [v, k as BoneKind])\n) as Record<number, BoneKind>;\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULTS } from './chunk-
|
|
1
|
+
import { DEFAULTS } from './chunk-4LFW65DU.js';
|
|
2
2
|
|
|
3
3
|
// src/core/responsive.ts
|
|
4
4
|
function selectBreakpoint(skeleton, viewportWidth) {
|
|
@@ -100,5 +100,5 @@ function getStaleBreakpoints(skeleton, targetBreakpoints) {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export { diffBreakpoints, getStaleBreakpoints, interpolateBones, selectBreakpoint, validateBreakpoints };
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
104
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-6RFGWOGG.js.map
|
|
104
|
+
//# sourceMappingURL=chunk-6RFGWOGG.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/responsive.ts"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/core/responsive.ts"],"names":[],"mappings":";;;AAaO,SAAS,gBAAA,CACd,UACA,aAAA,EACuB;AACvB,EAAA,MAAM,GAAA,GAAM,CAAC,GAAG,QAAA,CAAS,WAAW,CAAA,CAAE,IAAA;AAAA,IACpC,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA,CAAE;AAAA,GAC3B;AAEA,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC7B,EAAA,IAAI,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG,OAAO,IAAI,CAAC,CAAA;AAGlC,EAAA,IAAI,IAAA,GAAO,IAAI,CAAC,CAAA;AAChB,EAAA,IAAI,QAAA,GAAW,IAAA,CAAK,GAAA,CAAI,aAAA,GAAgB,KAAK,QAAQ,CAAA;AAErD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,gBAAgB,GAAA,CAAI,CAAC,EAAE,QAAQ,CAAA;AACrD,IAAA,IAAI,OAAO,QAAA,EAAU;AACnB,MAAA,IAAA,GAAO,IAAI,CAAC,CAAA;AACZ,MAAA,QAAA,GAAW,IAAA;AAAA,IACb;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAMO,SAAS,gBAAA,CACd,IAAA,EACA,EAAA,EACA,WAAA,EACgB;AAEhB,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,QAAA,GAAW,IAAA,CAAK,QAAA;AACjC,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,IAAA;AAExB,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAA,CAAI,WAAA,GAAc,IAAA,CAAK,QAAA,IAAY,KAAK,CAAC,CAAA;AAGxE,EAAA,MAAM,iBAAiB,IAAA,CAAK,IAAA,CAAK,cAAA,EAAgB,EAAA,CAAG,gBAAgB,CAAC,CAAA;AACrE,EAAA,MAAM,kBAAkB,IAAA,CAAK,IAAA,CAAK,eAAA,EAAiB,EAAA,CAAG,iBAAiB,CAAC,CAAA;AAGxE,EAAe,iBAAiB,IAAA,CAAK;AACrC,EAAe,kBAAkB,IAAA,CAAK;AAGtC,EAAA,IAAI,IAAA,CAAK,KAAA,CAAM,MAAA,KAAW,EAAA,CAAG,MAAM,MAAA,EAAQ;AACzC,IAAA,MAAM,IAAA,GAAO,CAAA,GAAI,GAAA,GAAM,IAAA,GAAO,EAAA;AAC9B,IAAA,MAAM,EAAA,GAAK,iBAAiB,IAAA,CAAK,cAAA;AACjC,IAAA,MAAM,EAAA,GAAK,kBAAkB,IAAA,CAAK,eAAA;AAElC,IAAA,OAAO;AAAA,MACL,QAAA,EAAU,WAAA;AAAA,MACV,cAAA;AAAA,MACA,eAAA;AAAA,MACA,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,QAC/B,GAAG,IAAA;AAAA,QACH,CAAA,EAAG,KAAK,CAAA,GAAI,EAAA;AAAA,QACZ,CAAA,EAAG,KAAK,CAAA,GAAI,EAAA;AAAA,QACZ,CAAA,EAAG,KAAK,CAAA,GAAI,EAAA;AAAA,QACZ,CAAA,EAAG,KAAK,CAAA,GAAI;AAAA,OACd,CAAE;AAAA,KACJ;AAAA,EACF;AAGA,EAAA,MAAM,QAAgB,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,CAAC,UAAU,CAAA,KAAM;AACpD,IAAA,MAAM,MAAA,GAAS,EAAA,CAAG,KAAA,CAAM,CAAC,CAAA;AACzB,IAAA,OAAO;AAAA,MACL,GAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MAC/B,GAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MAC/B,GAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MAC/B,GAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MAC/B,GAAG,IAAA,CAAK,QAAA,CAAS,CAAA,EAAG,MAAA,CAAO,GAAG,CAAC,CAAA;AAAA,MAC/B,IAAA,EAAM,CAAA,GAAI,GAAA,GAAM,QAAA,CAAS,OAAO,MAAA,CAAO;AAAA,KACzC;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,WAAA;AAAA,IACV,cAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF;AACF;AAGA,SAAS,IAAA,CAAK,CAAA,EAAW,CAAA,EAAW,CAAA,EAAmB;AACrD,EAAA,OAAO,CAAA,GAAA,CAAK,IAAI,CAAA,IAAK,CAAA;AACvB;AAOO,SAAS,eAAA,CACd,IAAA,EACA,MAAA,EACA,SAAA,GAAY,CAAA,EAC0B;AACtC,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,MAAM,QAAgB,EAAC;AAEvB,EAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,IAAA,CAAK,MAAM,MAAA,EAAQ,MAAA,CAAO,MAAM,MAAM,CAAA;AAE9D,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,CAAC,CAAA;AACtB,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AAExB,IAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG;AACZ,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AACd,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,CAAC,CAAA;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAC7B,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAC7B,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAC7B,IAAA,MAAM,KAAK,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAA,GAAI,EAAE,CAAC,CAAA;AAE7B,IAAA,IAAI,KAAK,SAAA,IAAa,EAAA,GAAK,aAAa,EAAA,GAAK,SAAA,IAAa,KAAK,SAAA,EAAW;AACxE,MAAA,OAAA,CAAQ,KAAK,CAAC,CAAA;AACd,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,IACd;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,SAAS,KAAA,EAAM;AAC1B;AAMO,SAAS,oBAAoB,WAAA,EAAiC;AACnE,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,IAAI,GAAA,CAAI,WAAW,CAAC,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,IAAI,CAAC,CAAA;AAE7D,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,CAAC,GAAG,QAAA,CAAS,WAAW,CAAA;AAAA,EACjC;AAGA,EAAA,OAAO,OAAO,MAAA,CAAO,CAAC,OAAO,EAAA,IAAM,GAAA,IAAO,MAAM,IAAI,CAAA;AACtD;AAMO,SAAS,mBAAA,CACd,UACA,iBAAA,EACU;AACV,EAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,QAAA,CAAS,WAAA,CAAY,IAAI,CAAC,EAAA,KAAO,EAAA,CAAG,QAAQ,CAAC,CAAA;AACtE,EAAA,OAAO,iBAAA,CAAkB,OAAO,CAAC,EAAA,KAAO,CAAC,QAAA,CAAS,GAAA,CAAI,EAAE,CAAC,CAAA;AAC3D","file":"chunk-6RFGWOGG.js","sourcesContent":["import type { BreakpointData, Bone, SkeletonData } from \"./types.js\";\nimport { DEFAULTS } from \"./types.js\";\n\n/**\n * Responsive breakpoint system for CastDOM.\n *\n * Handles:\n * - Selecting the best breakpoint for a given viewport width\n * - Interpolating between breakpoints for fluid layouts\n * - Diffing breakpoints to only store changes\n */\n\n/** Select the best breakpoint for a given viewport width */\nexport function selectBreakpoint(\n skeleton: SkeletonData,\n viewportWidth: number\n): BreakpointData | null {\n const bps = [...skeleton.breakpoints].sort(\n (a, b) => a.viewport - b.viewport\n );\n\n if (bps.length === 0) return null;\n if (bps.length === 1) return bps[0];\n\n // Find closest breakpoint\n let best = bps[0];\n let bestDist = Math.abs(viewportWidth - best.viewport);\n\n for (let i = 1; i < bps.length; i++) {\n const dist = Math.abs(viewportWidth - bps[i].viewport);\n if (dist < bestDist) {\n best = bps[i];\n bestDist = dist;\n }\n }\n\n return best;\n}\n\n/**\n * Interpolate bones between two breakpoints for a target viewport width.\n * Provides fluid skeleton sizing between captured breakpoints.\n */\nexport function interpolateBones(\n from: BreakpointData,\n to: BreakpointData,\n targetWidth: number\n): BreakpointData {\n // Calculate interpolation factor\n const range = to.viewport - from.viewport;\n if (range === 0) return from;\n\n const t = Math.max(0, Math.min(1, (targetWidth - from.viewport) / range));\n\n // Interpolate container dimensions\n const containerWidth = lerp(from.containerWidth, to.containerWidth, t);\n const containerHeight = lerp(from.containerHeight, to.containerHeight, t);\n\n // Scale factor for bone positions\n const scaleX = containerWidth / from.containerWidth;\n const scaleY = containerHeight / from.containerHeight;\n\n // If bone counts differ, use the closest breakpoint's bones\n if (from.bones.length !== to.bones.length) {\n const base = t < 0.5 ? from : to;\n const sx = containerWidth / base.containerWidth;\n const sy = containerHeight / base.containerHeight;\n\n return {\n viewport: targetWidth,\n containerWidth,\n containerHeight,\n bones: base.bones.map((bone) => ({\n ...bone,\n x: bone.x * sx,\n y: bone.y * sy,\n w: bone.w * sx,\n h: bone.h * sy,\n })),\n };\n }\n\n // Interpolate matching bones\n const bones: Bone[] = from.bones.map((fromBone, i) => {\n const toBone = to.bones[i];\n return {\n x: lerp(fromBone.x, toBone.x, t),\n y: lerp(fromBone.y, toBone.y, t),\n w: lerp(fromBone.w, toBone.w, t),\n h: lerp(fromBone.h, toBone.h, t),\n r: lerp(fromBone.r, toBone.r, t),\n kind: t < 0.5 ? fromBone.kind : toBone.kind,\n };\n });\n\n return {\n viewport: targetWidth,\n containerWidth,\n containerHeight,\n bones,\n };\n}\n\n/** Linear interpolation */\nfunction lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n/**\n * Compute a diff between two breakpoints.\n * Only stores bones that changed position/size significantly.\n * Used to reduce storage when breakpoints are similar.\n */\nexport function diffBreakpoints(\n base: BreakpointData,\n target: BreakpointData,\n threshold = 2\n): { changed: number[]; bones: Bone[] } {\n const changed: number[] = [];\n const bones: Bone[] = [];\n\n const maxLen = Math.max(base.bones.length, target.bones.length);\n\n for (let i = 0; i < maxLen; i++) {\n const a = base.bones[i];\n const b = target.bones[i];\n\n if (!a || !b) {\n changed.push(i);\n bones.push(b || a);\n continue;\n }\n\n const dx = Math.abs(a.x - b.x);\n const dy = Math.abs(a.y - b.y);\n const dw = Math.abs(a.w - b.w);\n const dh = Math.abs(a.h - b.h);\n\n if (dx > threshold || dy > threshold || dw > threshold || dh > threshold) {\n changed.push(i);\n bones.push(b);\n }\n }\n\n return { changed, bones };\n}\n\n/**\n * Validate breakpoint configuration.\n * Ensures breakpoints are sorted, unique, and reasonable.\n */\nexport function validateBreakpoints(breakpoints: number[]): number[] {\n const unique = [...new Set(breakpoints)].sort((a, b) => a - b);\n\n if (unique.length === 0) {\n return [...DEFAULTS.breakpoints];\n }\n\n // Filter out unreasonable values\n return unique.filter((bp) => bp >= 200 && bp <= 3840);\n}\n\n/**\n * Determine which breakpoints need re-extraction.\n * Compares existing data against current config.\n */\nexport function getStaleBreakpoints(\n skeleton: SkeletonData,\n targetBreakpoints: number[]\n): number[] {\n const existing = new Set(skeleton.breakpoints.map((bp) => bp.viewport));\n return targetBreakpoints.filter((bp) => !existing.has(bp));\n}\n"]}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkC3VW72Z3_cjs = require('./chunk-C3VW72Z3.cjs');
|
|
4
4
|
|
|
5
5
|
// src/core/renderer.ts
|
|
6
6
|
function resolveConfig(config) {
|
|
7
7
|
return {
|
|
8
|
-
color: config?.color ??
|
|
9
|
-
shimmerColor: config?.shimmerColor ??
|
|
10
|
-
animationDuration: config?.animationDuration ??
|
|
11
|
-
classPrefix: config?.classPrefix ??
|
|
12
|
-
inlineStyles: config?.inlineStyles ??
|
|
8
|
+
color: config?.color ?? chunkC3VW72Z3_cjs.DEFAULTS.color,
|
|
9
|
+
shimmerColor: config?.shimmerColor ?? chunkC3VW72Z3_cjs.DEFAULTS.shimmerColor,
|
|
10
|
+
animationDuration: config?.animationDuration ?? chunkC3VW72Z3_cjs.DEFAULTS.animationDuration,
|
|
11
|
+
classPrefix: config?.classPrefix ?? chunkC3VW72Z3_cjs.DEFAULTS.classPrefix,
|
|
12
|
+
inlineStyles: config?.inlineStyles ?? chunkC3VW72Z3_cjs.DEFAULTS.inlineStyles
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
15
|
function renderBone(bone, config, index) {
|
|
@@ -105,5 +105,5 @@ exports.generateCriticalCSS = generateCriticalCSS;
|
|
|
105
105
|
exports.renderBonesHTML = renderBonesHTML;
|
|
106
106
|
exports.renderResponsiveHTML = renderResponsiveHTML;
|
|
107
107
|
exports.renderStandalone = renderStandalone;
|
|
108
|
-
//# sourceMappingURL=chunk-
|
|
109
|
-
//# sourceMappingURL=chunk-
|
|
108
|
+
//# sourceMappingURL=chunk-ASS2BFPN.cjs.map
|
|
109
|
+
//# sourceMappingURL=chunk-ASS2BFPN.cjs.map
|