Skip to content

Commit 8dabc8a

Browse files
fix(registry): glass-shard-title renders when mounted, and 4 skipped blocks install again (#4423)
* fix(registry): glass-shard-title renders when mounted, and 4 skipped blocks install again * fix(registry): glass-shard-title loads in Studio and ?play, and its docs payload fails loudly * test(scripts): pin the glass payload's hdr guard for any quote style
1 parent b9e5a16 commit 8dabc8a

10 files changed

Lines changed: 91 additions & 35 deletions

File tree

‎packages/cli/src/registry/validation.test.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { existsSync, readFileSync, readdirSync } from "node:fs";
2+
import { join } from "node:path";
13
import { describe, expect, it } from "vitest";
24
import { validRegistryName, validRegistryManifest, validRegistryItem } from "./validation.js";
35

@@ -39,4 +41,21 @@ describe("registry manifest boundary", () => {
3941
validRegistryManifest({ ...manifest, items: Array(10_001).fill(manifest.items[0]) }),
4042
).toBe(false);
4143
});
44+
it("accepts every registry-item.json the repo publishes", () => {
45+
const registry = join(import.meta.dirname, "../../../../registry");
46+
const rejected = readdirSync(registry, { withFileTypes: true })
47+
.filter((dir) => dir.isDirectory())
48+
.flatMap((dir) =>
49+
readdirSync(join(registry, dir.name)).map((name) => ({ dir: dir.name, name })),
50+
)
51+
.filter(({ dir, name }) => existsSync(join(registry, dir, name, "registry-item.json")))
52+
.filter(({ dir, name }) => {
53+
const item = JSON.parse(
54+
readFileSync(join(registry, dir, name, "registry-item.json"), "utf8"),
55+
);
56+
return !validRegistryItem(item, name, item.type);
57+
})
58+
.map(({ dir, name }) => `${dir}/${name}`);
59+
expect(rejected).toEqual([]);
60+
});
4261
});

‎registry/blocks/glass-shard-title/assets/glass-main.js‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎registry/blocks/glass-shard-title/assets/glass-main.mjs‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,17 @@ point.position.set(0, -3, 1);
6767
scene.add(point);
6868

6969
/* ---- Environment + matcap (glass look) ---- */
70-
const hdrTex = await new HDRLoader().loadAsync("assets/ferndale_studio_01_1k.hdr");
70+
const hdrTex = await new HDRLoader().loadAsync(document.getElementById("gst-hdr").href);
7171
const pmrem = new THREE.PMREMGenerator(renderer);
7272
const envRT = pmrem.fromEquirectangular(hdrTex);
7373
scene.environment = envRT.texture;
7474
scene.environmentRotation = new THREE.Euler(0, 0.6, 0);
7575
hdrTex.dispose();
7676
pmrem.dispose();
7777

78-
const matcapTex = await new THREE.TextureLoader().loadAsync("assets/matcap-1.png");
78+
const matcapTex = await new THREE.TextureLoader().loadAsync(
79+
document.getElementById("gst-matcap").href,
80+
);
7981
matcapTex.colorSpace = THREE.SRGBColorSpace;
8082
matcapTex.wrapS = matcapTex.wrapT = THREE.RepeatWrapping;
8183
const mk = 1 / 0.2;

‎registry/blocks/glass-shard-title/glass-shard-title.html‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
data-composition-variables='[{"id":"headline","type":"string","label":"Headline","default":"Designed in glass","maxLength":40},{"id":"tileCount","type":"number","label":"Tiles","default":8,"min":1,"max":400,"step":1},{"id":"roundness","type":"number","label":"Roundness (0-1)","default":0.4,"min":0,"max":1,"step":0.01},{"id":"bevel","type":"number","label":"Bevel (0-1)","default":0.35,"min":0,"max":1,"step":0.01},{"id":"meshSmooth","type":"number","label":"Surface smoothness (0-1)","default":0.6,"min":0,"max":1,"step":0.01},{"id":"flyInTime","type":"number","label":"Fly-in time (s)","default":2.3,"min":0.2,"max":6,"step":0.05},{"id":"flyOutTime","type":"number","label":"Fly-out time (s)","default":2.4,"min":0.2,"max":6,"step":0.05},{"id":"stagger","type":"number","label":"Stagger (0-1)","default":0.27,"min":0,"max":1,"step":0.01},{"id":"flyInRotation","type":"number","label":"Fly-in rotation (0-60)","description":"Amount of inbound tumbling over the entire flight. 0 disables flight rotation; final orientation lands with each shard position.","default":5,"min":0,"max":60,"step":0.1},{"id":"flyOutRotation","type":"number","label":"Fly-out rotation (0-6)","default":6,"min":0,"max":6,"step":0.1},{"id":"chaos","type":"number","label":"Outline chaos (0-1)","default":0.25,"min":0,"max":1,"step":0.01},{"id":"padding","type":"number","label":"Edge padding (0-1)","default":1,"min":0,"max":1,"step":0.01},{"id":"sizeVariance","type":"number","label":"Size variance (0-1)","default":0.35,"min":0,"max":1,"step":0.01},{"id":"gap","type":"number","label":"Tile gap","default":0.03,"min":0,"max":0.3,"step":0.002},{"id":"easePow","type":"number","label":"Fly-in position ease (1-10)","description":"Shapes lateral and depth travel. Rotation uses the same staggered flight window with a gentle settle through arrival.","default":10,"min":1,"max":10,"step":0.1},{"id":"sideDist","type":"number","label":"Side fly distance","default":3,"min":0,"max":60,"step":0.5},{"id":"zDist","type":"number","label":"Z fly-from (negative)","default":-42,"min":-400,"max":0,"step":2},{"id":"zOut","type":"number","label":"Z fly-out to (+ = past camera)","default":14,"min":-400,"max":60,"step":2},{"id":"fog","type":"number","label":"Fog distance (0 = off)","default":36,"min":0,"max":400,"step":2}]'
55
>
66
<head>
7-
<script>
8-
/* ?play standalone mode only: this file lives in compositions/ but its
9-
asset paths are project-root-relative (they resolve there when the
10-
runtime inlines it into the host). Never runs for Studio/render. */
11-
if (new URLSearchParams(location.search).has("play")) document.write('<base href="../">');
12-
</script>
13-
147
<meta charset="UTF-8" />
158
<meta name="viewport" content="width=1920, height=1080" />
169
<title>Glass Shard Title</title>
@@ -103,6 +96,21 @@
10396
<span data-hf-id="hf-kqtg" style="font-weight: 400">Aa</span
10497
><span data-hf-id="hf-7bxm" style="font-weight: 600">Aa</span>
10598
</div>
99+
<!-- glass-main.js reads these hrefs: a mounted block's src/href are rebased, strings in its script are not. -->
100+
<link
101+
id="gst-hdr"
102+
rel="preload"
103+
as="fetch"
104+
crossorigin="anonymous"
105+
href="assets/ferndale_studio_01_1k.hdr"
106+
/>
107+
<link
108+
id="gst-matcap"
109+
rel="preload"
110+
as="image"
111+
crossorigin="anonymous"
112+
href="assets/matcap-1.png"
113+
/>
106114
</div>
107115

108116
<script>

‎registry/blocks/liquid-glass-notification/registry-item.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
{
2121
"path": "assets/hyperframes-logo-dark.svg",
2222
"target": "compositions/assets/hyperframes-logo-dark.svg",
23-
"type": "registry:asset"
23+
"type": "hyperframes:asset"
2424
},
2525
{
2626
"path": "lib/liquid-glass.iife.js",
2727
"target": "compositions/lib/liquid-glass.iife.js",
28-
"type": "registry:asset"
28+
"type": "hyperframes:asset"
2929
}
3030
],
3131
"preview": {

‎registry/blocks/liquid-glass-widgets/registry-item.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
{
2121
"path": "assets/hyperframes-logo-dark.svg",
2222
"target": "compositions/assets/hyperframes-logo-dark.svg",
23-
"type": "registry:asset"
23+
"type": "hyperframes:asset"
2424
},
2525
{
2626
"path": "lib/liquid-glass.iife.js",
2727
"target": "compositions/lib/liquid-glass.iife.js",
28-
"type": "registry:asset"
28+
"type": "hyperframes:asset"
2929
}
3030
],
3131
"preview": {

‎registry/blocks/lt-neon-border/registry-item.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@
100100
"files": [
101101
{
102102
"path": "lt-neon-border.html",
103-
"type": "hyperframes:block"
103+
"target": "compositions/lt-neon-border.html",
104+
"type": "hyperframes:composition"
104105
}
105106
],
106107
"params": [

‎registry/blocks/vfx-iphone-device/registry-item.json‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,22 @@
2020
{
2121
"path": "models/iphone.glb",
2222
"target": "models/iphone.glb",
23-
"type": "asset"
23+
"type": "hyperframes:asset"
2424
},
2525
{
2626
"path": "models/macbook.glb",
2727
"target": "models/macbook.glb",
28-
"type": "asset"
28+
"type": "hyperframes:asset"
2929
},
3030
{
3131
"path": "models/hyperframes-mobile.png",
3232
"target": "models/hyperframes-mobile.png",
33-
"type": "asset"
33+
"type": "hyperframes:asset"
3434
},
3535
{
3636
"path": "models/hyperframes-desktop.png",
3737
"target": "models/hyperframes-desktop.png",
38-
"type": "asset"
38+
"type": "hyperframes:asset"
3939
}
4040
],
4141
"preview": {

‎scripts/catalog-script-inlining.test.ts‎

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
1+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
22
import { tmpdir } from "node:os";
33
import { join } from "node:path";
44
import { describe, it } from "node:test";
55
import assert from "node:assert/strict";
6-
import { withHostedRefs } from "./catalog-script-inlining.ts";
6+
import { inlineCatalogScripts, withHostedRefs } from "./catalog-script-inlining.ts";
77

88
const CDN = "https://static.example.com/registry-assets";
99

@@ -52,3 +52,40 @@ describe("withHostedRefs", () => {
5252
}
5353
});
5454
});
55+
56+
describe("glass-shard-title payload", () => {
57+
const scriptTag = `<script src="assets/glass-main.js"></script>`;
58+
const withGlassMain = (fn: (dir: string) => void) => {
59+
const dir = mkdtempSync(join(tmpdir(), "hf-inlining-"));
60+
try {
61+
mkdirSync(join(dir, "assets"));
62+
writeFileSync(join(dir, "assets/glass-main.js"), "window.GLASS = 1;");
63+
fn(dir);
64+
} finally {
65+
rmSync(dir, { recursive: true, force: true });
66+
}
67+
};
68+
69+
it("inlines glass-main.js once the hdr link is a data URL", () => {
70+
withGlassMain((dir) => {
71+
const html = `<link id="gst-hdr" href="data:image/vnd.radiance;base64,AA">${scriptTag}`;
72+
const out = inlineCatalogScripts("glass-shard-title", html, dir, {});
73+
assert.ok(out.includes("window.GLASS = 1;"));
74+
assert.ok(!out.includes(scriptTag));
75+
});
76+
});
77+
78+
it("refuses a payload whose hdr link still points at the local file", () => {
79+
withGlassMain((dir) => {
80+
for (const link of [
81+
`<link id="gst-hdr" href="assets/ferndale_studio_01_1k.hdr">`,
82+
`<link id='gst-hdr' href='assets/ferndale_studio_01_1k.hdr'>`,
83+
]) {
84+
assert.throws(
85+
() => inlineCatalogScripts("glass-shard-title", link + scriptTag, dir, {}),
86+
/hdr <link> was not inlined/,
87+
);
88+
}
89+
});
90+
});
91+
});

‎scripts/catalog-script-inlining.ts‎

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -227,21 +227,10 @@ ${gsapLoaderJs(vendorUrls)}
227227
}
228228

229229
function inlineGlassScripts(html: string, projectDir: string): string {
230-
const hdrRelPath = "assets/ferndale_studio_01_1k.hdr";
231-
let glassText = withHostedRefs(
232-
readFileSync(join(projectDir, "assets/glass-main.js"), "utf-8"),
233-
projectDir,
234-
);
235-
if (!glassText.includes(hdrRelPath)) {
236-
throw new Error(
237-
`catalog-script-inlining: glass-main.js no longer references "${hdrRelPath}"; ` +
238-
`the hdr substitution needs updating.`,
239-
);
230+
if (html.includes("assets/ferndale_studio_01_1k.hdr")) {
231+
throw new Error("catalog-script-inlining: glass-shard-title's hdr <link> was not inlined.");
240232
}
241-
const hdrBytes = readFileSync(join(projectDir, hdrRelPath));
242-
const hdrDataUrl = `data:application/octet-stream;base64,${hdrBytes.toString("base64")}`;
243-
glassText = glassText.split(hdrRelPath).join(hdrDataUrl);
244-
233+
const glassText = readFileSync(join(projectDir, "assets/glass-main.js"), "utf-8");
245234
const bootstrap = `<script>(0,eval)(${jsStringLiteral(glassText)});</script>`;
246235
return replaceOnce(
247236
html,

0 commit comments

Comments
 (0)