@glasshome/widget-cli 0.10.1 → 0.10.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/package.json +3 -3
- package/src/commands/publish.ts +17 -13
- package/src/preview/harness/harness.tsx +32 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glasshome/widget-cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "CLI for creating and managing GlassHome widgets",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"@fontsource-variable/caveat": "^5.2.8",
|
|
29
29
|
"@fontsource-variable/geist": "^5.2.9",
|
|
30
30
|
"@fontsource-variable/geist-mono": "^5.2.8",
|
|
31
|
-
"@glasshome/sync-layer": "0.
|
|
31
|
+
"@glasshome/sync-layer": "0.7.0",
|
|
32
32
|
"@glasshome/widget-contract": "0.2.0",
|
|
33
|
-
"@glasshome/widget-sdk": "1.
|
|
33
|
+
"@glasshome/widget-sdk": "1.10.0",
|
|
34
34
|
"@iconify-json/lucide": "^1.2.0",
|
|
35
35
|
"@iconify-json/mdi": "^1.2.3",
|
|
36
36
|
"@tailwindcss/vite": "^4.1.13",
|
package/src/commands/publish.ts
CHANGED
|
@@ -193,6 +193,10 @@ export async function runPublish(
|
|
|
193
193
|
process.exit(1);
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
// Re-read after the build: it rewrites the bundle-owned manifest keys, and
|
|
197
|
+
// serializing the pre-build object would ship them one publish behind.
|
|
198
|
+
const builtManifest = readManifest(cwd, widgetName);
|
|
199
|
+
|
|
196
200
|
// Step 7: Publish
|
|
197
201
|
const distPath = resolve(cwd, "dist", `${widgetName}.js`);
|
|
198
202
|
|
|
@@ -217,37 +221,37 @@ export async function runPublish(
|
|
|
217
221
|
? createHash("sha256").update(cssBuffer).digest("hex")
|
|
218
222
|
: undefined;
|
|
219
223
|
|
|
220
|
-
s.start(`Publishing ${
|
|
224
|
+
s.start(`Publishing ${builtManifest.name}@${version}...`);
|
|
221
225
|
|
|
222
226
|
let publishData: Awaited<ReturnType<typeof requestPublish>>;
|
|
223
227
|
try {
|
|
224
228
|
publishData = await requestPublish(hubUrl, token!, {
|
|
225
229
|
scope,
|
|
226
230
|
name: widgetName,
|
|
227
|
-
displayName:
|
|
228
|
-
description:
|
|
229
|
-
icon:
|
|
230
|
-
minSize:
|
|
231
|
-
maxSize:
|
|
232
|
-
sdkVersion:
|
|
231
|
+
displayName: builtManifest.name,
|
|
232
|
+
description: builtManifest.description,
|
|
233
|
+
icon: builtManifest.icon,
|
|
234
|
+
minSize: builtManifest.minSize,
|
|
235
|
+
maxSize: builtManifest.maxSize,
|
|
236
|
+
sdkVersion: builtManifest.sdkVersion,
|
|
233
237
|
version,
|
|
234
238
|
bundleSize: bundleBuffer.byteLength,
|
|
235
239
|
sha256Hash,
|
|
236
240
|
...(cssBuffer && cssSha256Hash
|
|
237
241
|
? { cssSize: cssBuffer.byteLength, cssSha256Hash }
|
|
238
242
|
: {}),
|
|
239
|
-
manifestJson: JSON.stringify(
|
|
243
|
+
manifestJson: JSON.stringify(builtManifest),
|
|
240
244
|
});
|
|
241
245
|
} catch (err: any) {
|
|
242
246
|
if (err.status === 409) {
|
|
243
|
-
s.stop(`${
|
|
247
|
+
s.stop(`${builtManifest.name}@${version} already published, bump version to republish`);
|
|
244
248
|
process.exit(0);
|
|
245
249
|
}
|
|
246
250
|
s.stop(`Publish failed: ${err.message}`);
|
|
247
251
|
process.exit(1);
|
|
248
252
|
}
|
|
249
253
|
|
|
250
|
-
s.message(`Uploading ${
|
|
254
|
+
s.message(`Uploading ${builtManifest.name} to CDN...`);
|
|
251
255
|
try {
|
|
252
256
|
await uploadToR2(publishData.uploadUrl, bundleBuffer);
|
|
253
257
|
} catch (err: any) {
|
|
@@ -262,7 +266,7 @@ export async function runPublish(
|
|
|
262
266
|
);
|
|
263
267
|
process.exit(1);
|
|
264
268
|
}
|
|
265
|
-
s.message(`Uploading ${
|
|
269
|
+
s.message(`Uploading ${builtManifest.name} styles to CDN...`);
|
|
266
270
|
try {
|
|
267
271
|
await uploadToR2(publishData.cssUploadUrl, cssBuffer, "text/css");
|
|
268
272
|
} catch (err: any) {
|
|
@@ -271,10 +275,10 @@ export async function runPublish(
|
|
|
271
275
|
}
|
|
272
276
|
}
|
|
273
277
|
|
|
274
|
-
s.message(`Confirming ${
|
|
278
|
+
s.message(`Confirming ${builtManifest.name}...`);
|
|
275
279
|
try {
|
|
276
280
|
const result = await confirmPublish(hubUrl, token!, publishData.versionId);
|
|
277
|
-
s.stop(`Published ${
|
|
281
|
+
s.stop(`Published ${builtManifest.name}@${version}`);
|
|
278
282
|
log.info(`CDN: ${result.bundleUrl}`);
|
|
279
283
|
if (result.cssUrl) log.info(`CSS: ${result.cssUrl}`);
|
|
280
284
|
} catch (err: any) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ReactiveWidgetContext, WidgetDefinition } from "@glasshome/widget-sdk";
|
|
2
2
|
import { instantiateWidget } from "@glasshome/widget-sdk/host";
|
|
3
|
-
import {
|
|
4
|
-
import { getEntityView } from "@glasshome/sync-layer";
|
|
3
|
+
import { claimHostApi, getEntityView } from "@glasshome/sync-layer";
|
|
5
4
|
import { byDomain, useAreas, useEntities } from "@glasshome/sync-layer/solid";
|
|
6
5
|
import type { EntityDataAdapter } from "@glasshome/ui/solid";
|
|
7
6
|
import { provideEntityData } from "@glasshome/ui/solid";
|
|
@@ -85,7 +84,13 @@ async function loadWidget(name: string): Promise<{ def: WidgetDefinition; css: s
|
|
|
85
84
|
// Grid geometry mirrored from the dash route (rowHeight 70, margin 16, lg 12
|
|
86
85
|
// cols at a 1024px reference container). A preview approximates one dashboard
|
|
87
86
|
// width rather than mirroring every breakpoint.
|
|
88
|
-
|
|
87
|
+
// max-w-7xl (1280px) minus the route's px-3 padding, i.e. the width the grid
|
|
88
|
+
// actually gets on a desktop dashboard. NOT the lg breakpoint's 1024 minimum:
|
|
89
|
+
// that is the narrowest a desktop can be, and using it rendered every
|
|
90
|
+
// size-responsive widget one tier below what users see (energy-flow never
|
|
91
|
+
// reached its node-graph tier, so the storefront advertised the compact
|
|
92
|
+
// layout).
|
|
93
|
+
const CONTAINER = 1256;
|
|
89
94
|
const COLS = 12;
|
|
90
95
|
const GAP = 16;
|
|
91
96
|
const ROW_H = 70;
|
|
@@ -98,11 +103,26 @@ function tilePx(size: { w: number; h: number }): { width: number; height: number
|
|
|
98
103
|
};
|
|
99
104
|
}
|
|
100
105
|
|
|
106
|
+
/* The shell composites `--glass-frost` as its bottom background layer and
|
|
107
|
+
defaults it to `none`, because in the app a live backdrop-filter blurs the
|
|
108
|
+
dashboard wallpaper behind the widget. A preview is shot alone on a
|
|
109
|
+
transparent page, so there is nothing to blur and the widget would render
|
|
110
|
+
with no surface at all: legible by luck in light mode, white-on-nothing in
|
|
111
|
+
dark. ui registers --glass-frost with `inherits: false`, so it cannot be
|
|
112
|
+
handed down from the host and has to be set on the shell element itself,
|
|
113
|
+
which is what dash's performant-blur override sheet does too.
|
|
114
|
+
|
|
115
|
+
`--card` is an ordinary inheriting theme token, so it crosses the shadow
|
|
116
|
+
boundary and follows the `dark` class already mirrored onto the host. */
|
|
117
|
+
const FROST_SHEET = new CSSStyleSheet();
|
|
118
|
+
FROST_SHEET.replaceSync(
|
|
119
|
+
".glasshome-widget { --glass-frost: linear-gradient(var(--card), var(--card)); }",
|
|
120
|
+
);
|
|
121
|
+
|
|
101
122
|
/** Mount via the shared SDK recipe (`@glasshome/widget-sdk/host`): closed shadow
|
|
102
123
|
root, injected tokens, adopted widget CSS, WidgetCtx provider, `dark`
|
|
103
|
-
mirrored onto the host.
|
|
104
|
-
|
|
105
|
-
`dark` document class is toggled by the caller before this runs. */
|
|
124
|
+
mirrored onto the host. `dark` is the default `mirrorClasses`; the `dark`
|
|
125
|
+
document class is toggled by the caller before this runs. */
|
|
106
126
|
function mount(
|
|
107
127
|
host: HTMLElement,
|
|
108
128
|
def: WidgetDefinition,
|
|
@@ -115,6 +135,7 @@ function mount(
|
|
|
115
135
|
config: () => config,
|
|
116
136
|
ctx,
|
|
117
137
|
cssText,
|
|
138
|
+
extraSheets: [FROST_SHEET],
|
|
118
139
|
onCrash: (err) => console.error("[harness] widget threw:", err),
|
|
119
140
|
});
|
|
120
141
|
}
|
|
@@ -144,7 +165,11 @@ async function main(): Promise<void> {
|
|
|
144
165
|
// triggers the (now dead) network lookup and renders blank.
|
|
145
166
|
await preloadIcons();
|
|
146
167
|
|
|
147
|
-
|
|
168
|
+
// The harness is a host: claim the privileged surface once at boot
|
|
169
|
+
// (sync-layer keeps demo control off the widget-reachable entry).
|
|
170
|
+
const hostApi = claimHostApi();
|
|
171
|
+
if (!hostApi) throw new Error("harness: host API already claimed");
|
|
172
|
+
await hostApi.loadDemoData();
|
|
148
173
|
|
|
149
174
|
// Background and padding are the renderer's job: the preview is the widget
|
|
150
175
|
// alone, tight and transparent (omitBackground on capture).
|