@glasshome/widget-sdk 1.16.0 → 1.17.1

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/dist/ui.d.ts CHANGED
@@ -15,4 +15,4 @@
15
15
  * `@glasshome/ui/solid` is a vite external of this package: these re-exports
16
16
  * resolve to the host-provided singleton at runtime, never a bundled copy.
17
17
  */
18
- export { Badge, Button, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type CarouselTransition, type Color, ColorSlider, ColorWheel, CountPill, Icon, imageUrl, Input, Label, mediaUrl, parseColor, ResponsiveDialog, ResponsiveDialogBody, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogHeader, ResponsiveDialogTitle, SchemaForm, SectionIcon, SectionTitle, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Switch, Tabs, TabsContent, TabsList, TabsTrigger, } from "@glasshome/ui/solid";
18
+ export { Badge, Button, ButtonGroup, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type CarouselTransition, type Color, ColorDisc, ColorSlider, ColorWheel, CountPill, Icon, imagePreset, imageUrl, Input, Label, mediaUrl, parseColor, presetValue, Progress, ResponsiveDialog, ResponsiveDialogBody, ResponsiveDialogClose, ResponsiveDialogContent, ResponsiveDialogDescription, ResponsiveDialogFooter, ResponsiveDialogHeader, ResponsiveDialogTitle, SchemaForm, SectionIcon, SectionTitle, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, SwatchPicker, Switch, Tabs, TemperatureBar, TabsContent, TabsList, TabsTrigger, Toggle, ToggleGroup, ToggleGroupItem, } from "@glasshome/ui/solid";
@@ -1,3 +1,4 @@
1
+ import { type CapabilityGrant } from "@glasshome/widget-contract";
1
2
  import type { InlineConfig, Plugin } from "vite";
2
3
  import type { ExampleConfigIssue, WidgetIntrospection } from "./introspect-core";
3
4
  import { createIntrospectSession, type IntrospectSession, type IntrospectSessionOptions, introspectOnce } from "./introspect-session";
@@ -15,6 +16,11 @@ export interface GlasshomeWidgetOptions {
15
16
  * author decide which states matter rather than discovering the loss never.
16
17
  */
17
18
  export declare const MAX_EXAMPLES = 20;
19
+ /** What a built bundle imports from the SDK, by exported name; `*` for a namespace or dynamic import. */
20
+ export declare function sdkImportsOf(code: string): Set<string>;
21
+ /** SDK hooks that read a fixed entity on the widget's behalf, so the widget must declare that read. */
22
+ export declare const HOOK_READS: Record<string, string>;
23
+ export declare function assertHookReadsDeclared(code: string, capabilities: readonly CapabilityGrant[], widgetName: string): void;
18
24
  export declare function runSchemaGuard(args: {
19
25
  outFile: string;
20
26
  hashFile: string;
@@ -61,6 +67,26 @@ export declare function createUiImportTracker(warned?: Set<string>): {
61
67
  /** Offending files this run has not reported yet; marks them reported. */
62
68
  take(): string[];
63
69
  };
70
+ export declare function dropSelfReferencingVars(css: string): string;
71
+ /**
72
+ * Widgets render inside a closed shadow root in the host, which cuts them off
73
+ * from the host document stylesheet. Every widget bundle must therefore carry
74
+ * its own complete CSS: the ui theme + component styles, the SDK shell
75
+ * classes, and the Tailwind utilities its own JSX uses. This writes a
76
+ * generated css entry (a Tailwind pass over exactly those sources) plus a
77
+ * wrapper module that imports it ahead of the real widget entry, so Vite lib
78
+ * mode emits it as the widget's `<name>.css`.
79
+ *
80
+ * `source(none)` disables Tailwind's automatic project-root scan — without it
81
+ * every widget in a multi-widget repo gets the superset of all widgets'
82
+ * classes. The dark variant is redefined shadow-aware: `.dark *` cannot match
83
+ * across a shadow boundary, so the host mirrors the document's `dark` class
84
+ * onto the shadow host element and `:host(.dark)` picks it up.
85
+ */
86
+ /** The widget's own folder plus the project's shared folders: Tailwind only
87
+ * emits utilities for files it is pointed at, and a widget's shared component
88
+ * is as much its source as its entry. A sibling widget's folder stays out. */
89
+ export declare function widgetProjectScanDirs(srcDir: string, widgetEntry: string): string[];
64
90
  interface DiscoveredWidget {
65
91
  name: string;
66
92
  entry: string;
@@ -1,20 +1,20 @@
1
1
  import { deprecations as e, formatDeprecation as t } from "../deprecations.js";
2
- import { formatSchemaError as n, isHostProvidedModule as r, widgetManifestSchema as i } from "@glasshome/widget-contract";
3
- import { createHash as a } from "node:crypto";
4
- import { existsSync as o, mkdirSync as s, readFileSync as c, readdirSync as l, rmSync as u, statSync as d, writeFileSync as f } from "node:fs";
5
- import { createRequire as p } from "node:module";
6
- import { dirname as m, join as h, relative as g, resolve as _, sep as v } from "node:path";
7
- import { fileURLToPath as y } from "node:url";
2
+ import { formatSchemaError as n, isHostProvidedModule as r, matchesRead as i, widgetManifestSchema as a } from "@glasshome/widget-contract";
3
+ import { createHash as o } from "node:crypto";
4
+ import { existsSync as s, mkdirSync as c, readFileSync as l, readdirSync as u, rmSync as d, statSync as f, writeFileSync as p } from "node:fs";
5
+ import { createRequire as m } from "node:module";
6
+ import { dirname as h, join as g, relative as _, resolve as v, sep as y } from "node:path";
7
+ import { fileURLToPath as b } from "node:url";
8
8
  import ee from "@tailwindcss/vite";
9
9
  import { spawn as te, spawnSync as ne } from "node:child_process";
10
10
  //#region src/vite/introspect-session.ts
11
- var re = 262144e3, b = 3e4, ie = 3e3;
12
- function x(e) {
13
- let t = m(y(import.meta.url));
14
- return [h(t, `${e}.js`), h(t, `${e}.ts`)].find((e) => o(e)) ?? null;
11
+ var x = 262144e3, S = 3e4, re = 3e3;
12
+ function C(e) {
13
+ let t = h(b(import.meta.url));
14
+ return [g(t, `${e}.js`), g(t, `${e}.ts`)].find((e) => s(e)) ?? null;
15
15
  }
16
- function S(e) {
17
- let t = x("introspect");
16
+ function w(e) {
17
+ let t = C("introspect");
18
18
  if (!t) return {
19
19
  ok: !1,
20
20
  reason: "introspect not found next to the sdk"
@@ -26,7 +26,7 @@ function S(e) {
26
26
  e
27
27
  ], {
28
28
  encoding: "utf-8",
29
- timeout: b
29
+ timeout: S
30
30
  });
31
31
  if (n.error) return {
32
32
  ok: !1,
@@ -48,16 +48,16 @@ function S(e) {
48
48
  };
49
49
  }
50
50
  }
51
- function ae() {
51
+ function ie() {
52
52
  return {
53
- introspect: async (e) => S(e),
53
+ introspect: async (e) => w(e),
54
54
  dispose: async () => {},
55
55
  childPid: null
56
56
  };
57
57
  }
58
- function C(e) {
59
- if (process.env.GLASSHOME_WIDGET_NO_WORKER === "1") return ae();
60
- let t = e?.rssLimitBytes ?? re, n = e?.timeoutMs ?? b, r = e?.slowMs ?? ie, i = null, a = !1, o = 0, s = Promise.resolve();
58
+ function ae(e) {
59
+ if (process.env.GLASSHOME_WIDGET_NO_WORKER === "1") return ie();
60
+ let t = e?.rssLimitBytes ?? x, n = e?.timeoutMs ?? S, r = e?.slowMs ?? re, i = null, a = !1, o = 0, s = Promise.resolve();
61
61
  function c(e, t) {
62
62
  for (let n of e.pending.values()) n({
63
63
  ok: !1,
@@ -128,7 +128,7 @@ function C(e) {
128
128
  ok: !1,
129
129
  reason: "introspect session disposed"
130
130
  };
131
- let t = x("introspect-worker");
131
+ let t = C("introspect-worker");
132
132
  if (!t) return {
133
133
  ok: !1,
134
134
  reason: "introspect-worker not found next to the sdk"
@@ -186,20 +186,20 @@ function C(e) {
186
186
  }
187
187
  //#endregion
188
188
  //#region src/vite/index.ts
189
- var w = 2;
190
- function T(e) {
191
- if (Array.isArray(e)) return `[${e.map(T).join(",")}]`;
189
+ var T = 2;
190
+ function E(e) {
191
+ if (Array.isArray(e)) return `[${e.map(E).join(",")}]`;
192
192
  if (typeof e == "object" && e) {
193
193
  let t = e;
194
- return `{${Object.keys(t).sort().filter((e) => t[e] !== void 0).map((e) => `${JSON.stringify(e)}:${T(t[e])}`).join(",")}}`;
194
+ return `{${Object.keys(t).sort().filter((e) => t[e] !== void 0).map((e) => `${JSON.stringify(e)}:${E(t[e])}`).join(",")}}`;
195
195
  }
196
196
  return JSON.stringify(e) ?? "null";
197
197
  }
198
- function E(e) {
199
- return a("sha256").update(T(e)).digest("hex").slice(0, 16);
198
+ function oe(e) {
199
+ return o("sha256").update(E(e)).digest("hex").slice(0, 16);
200
200
  }
201
- var D = 20;
202
- async function O(e, t) {
201
+ var se = 20;
202
+ async function D(e, t) {
203
203
  if (e === void 0) return;
204
204
  let n;
205
205
  try {
@@ -219,7 +219,7 @@ async function O(e, t) {
219
219
  let a = i.error.issues.map((e) => ` examples${e.path.length ? `[${e.path.join("][")}]` : ""}: ${e.message}`).join("\n");
220
220
  throw Error(`[widget-sdk] Invalid \`examples\` for "${t}":\n${a}\nEach example needs a \`config\` object and a \`size\` of whole positive tiles, and at most 20 are rendered.`);
221
221
  }
222
- function k(e, t) {
222
+ function O(e, t) {
223
223
  if (!e?.length) return;
224
224
  let n = e.map((e) => {
225
225
  let t = e.label ? `"${e.label}"` : `#${e.index}`;
@@ -227,7 +227,7 @@ function k(e, t) {
227
227
  }).join("\n");
228
228
  throw Error(`[widget-sdk] Example config rejected by "${t}"'s own configSchema:\n${n}\nEach example's \`config\` must be a config the widget would actually accept, or its preview renders empty.`);
229
229
  }
230
- var A = [
230
+ var ce = [
231
231
  "schema",
232
232
  "defaultConfig",
233
233
  "examples",
@@ -240,82 +240,108 @@ var A = [
240
240
  "minSize",
241
241
  "maxSize"
242
242
  ];
243
- function j(e, t, n) {
244
- let r = c(e, "utf-8"), i = JSON.parse(r), a = {
243
+ function le(e, t, n) {
244
+ let r = l(e, "utf-8"), i = JSON.parse(r), a = {
245
245
  ...t.manifest ?? {},
246
246
  schema: n
247
247
  };
248
- for (let e of A) a[e] !== void 0 && (i[e] = a[e]);
248
+ for (let e of ce) a[e] !== void 0 && (i[e] = a[e]);
249
249
  let o = `${JSON.stringify(i, null, 2)}\n`;
250
- o !== r && f(e, o);
250
+ o !== r && p(e, o);
251
+ }
252
+ var ue = /import\s*(\{[^}]*\}|\*\s*as\s+[\w$]+)\s*from\s*["']@glasshome\/widget-sdk["']/g, de = /import\(\s*["']@glasshome\/widget-sdk["']\s*\)/;
253
+ function k(e) {
254
+ let t = /* @__PURE__ */ new Set();
255
+ de.test(e) && t.add("*");
256
+ for (let [, n = ""] of e.matchAll(ue)) {
257
+ if (!n.startsWith("{")) {
258
+ t.add("*");
259
+ continue;
260
+ }
261
+ for (let e of n.slice(1, -1).split(",")) {
262
+ let n = e.trim().split(/\s+as\s+/)[0];
263
+ n && t.add(n);
264
+ }
265
+ }
266
+ return t;
267
+ }
268
+ var A = { useDaylight: "sun.sun" };
269
+ function j(e, t, n) {
270
+ let r = k(e);
271
+ for (let [e, a] of Object.entries(A)) {
272
+ if (!r.has(e) && !r.has("*") || i(t, a)) continue;
273
+ let o = a.split(".")[0];
274
+ throw Error(`[widget-sdk] "${n}" uses ${e}(), which reads ${a}, but its capabilities grant no read of it.\n Add { "domain": "${o}", "access": "read" } to capabilities, so the homeowner is told before installing.`);
275
+ }
251
276
  }
252
277
  async function M(e) {
253
- if (!o(e.outFile)) return;
254
- let t = e.session ? await e.session.introspect(e.outFile) : S(e.outFile);
278
+ if (!s(e.outFile)) return;
279
+ let t = e.session ? await e.session.introspect(e.outFile) : w(e.outFile);
255
280
  if (!t.ok) throw Error(`[widget-sdk] Could not read "${e.widgetName}" to check it: ${t.reason}\n Its examples and config schema could not be validated, so the build cannot continue.
256
281
  This usually means the bundle throws while being imported.`);
257
282
  let n = t.value, r = n.manifest?.name ?? e.widgetName;
258
- await O(n.manifest?.examples, r), k(n.exampleConfigIssues, r);
259
- let i = n.jsonSchema;
260
- if (!i) return;
261
- e.manifestPath && o(e.manifestPath) && j(e.manifestPath, n, i);
262
- let a = E(i), s = n.manifest?.configVersion ?? null, l = n.manifest?.name ?? e.widgetName, u = o(e.hashFile) ? c(e.hashFile, "utf-8") : null;
263
- if (u !== null) {
264
- let t = u.trim(), n = null;
283
+ await D(n.manifest?.examples, r), O(n.exampleConfigIssues, r);
284
+ let i = n.jsonSchema, a = e.manifestPath && s(e.manifestPath) ? e.manifestPath : null;
285
+ i && a && le(a, n, i);
286
+ let o = a ? JSON.parse(l(a, "utf-8")).capabilities : n.manifest?.capabilities;
287
+ if (j(l(e.outFile, "utf-8"), o ?? [], r), !i) return;
288
+ let c = oe(i), u = n.manifest?.configVersion ?? null, d = n.manifest?.name ?? e.widgetName, f = s(e.hashFile) ? l(e.hashFile, "utf-8") : null;
289
+ if (f !== null) {
290
+ let t = f.trim(), n = null;
265
291
  if (t.startsWith("{")) try {
266
292
  n = JSON.parse(t);
267
293
  } catch {
268
294
  n = null;
269
295
  }
270
- if (n && n.hashVersion === w) {
271
- if (n.hash !== a && n.configVersion === s) throw Error(`[widget-sdk] Config schema shape changed for "${l}" without a configVersion bump. Bump configVersion in defineWidget (currently ${s ?? "unset"}) or revert the schema change, then rebuild. Recorded in ${e.hashFile}`);
272
- } else console.warn(`[widget-sdk] Schema shape record for "${l}" was written by an older SDK, so it cannot be compared. Re-recording it under hash format ${w}. This build is not checked for a missing configVersion bump; the next one is. (${e.hashFile})`);
296
+ if (n && n.hashVersion === T) {
297
+ if (n.hash !== c && n.configVersion === u) throw Error(`[widget-sdk] Config schema shape changed for "${d}" without a configVersion bump. Bump configVersion in defineWidget (currently ${u ?? "unset"}) or revert the schema change, then rebuild. Recorded in ${e.hashFile}`);
298
+ } else console.warn(`[widget-sdk] Schema shape record for "${d}" was written by an older SDK, so it cannot be compared. Re-recording it under hash format ${T}. This build is not checked for a missing configVersion bump; the next one is. (${e.hashFile})`);
273
299
  }
274
- let d = `${JSON.stringify({
275
- hash: a,
276
- configVersion: s,
277
- hashVersion: w
300
+ let m = `${JSON.stringify({
301
+ hash: c,
302
+ configVersion: u,
303
+ hashVersion: T
278
304
  })}\n`;
279
- d !== u && f(e.hashFile, d);
305
+ m !== f && p(e.hashFile, m);
280
306
  }
281
- var oe = "virtual:glasshome-widget", N = "\0virtual:glasshome-widget", P = "/@glasshome/preview";
282
- function F(e) {
283
- return v === "\\" ? e.split(v).join("/") : e;
307
+ var fe = "virtual:glasshome-widget", N = "\0virtual:glasshome-widget", pe = "/@glasshome/preview";
308
+ function P(e) {
309
+ return y === "\\" ? e.split(y).join("/") : e;
284
310
  }
285
- function I() {
286
- let e = y(import.meta.url);
287
- return _(m(e), "../../preview");
311
+ function F() {
312
+ let e = b(import.meta.url);
313
+ return v(h(e), "../../preview");
288
314
  }
289
- function L(e) {
315
+ function I(e) {
290
316
  return r(e);
291
317
  }
292
- var R = /\.(ts|tsx|js|jsx)$/, z = /from\s+["']@glasshome\/sync-layer(\/[^"']*)?["']/;
293
- function B(e, t) {
294
- let n = F(e).split("?")[0] ?? "";
295
- return n.includes("/node_modules/") || !R.test(n) ? !1 : z.test(t);
318
+ var L = /\.(ts|tsx|js|jsx)$/, R = /from\s+["']@glasshome\/sync-layer(\/[^"']*)?["']/;
319
+ function z(e, t) {
320
+ let n = P(e).split("?")[0] ?? "";
321
+ return n.includes("/node_modules/") || !L.test(n) ? !1 : R.test(t);
296
322
  }
297
- function V() {
323
+ function B() {
298
324
  return {
299
325
  name: "glasshome-widget:sync-layer-guard",
300
326
  apply: "build",
301
327
  enforce: "pre",
302
328
  transform(e, t) {
303
- if (B(t, e)) throw Error(`Widgets must not import "@glasshome/sync-layer" directly (imported by ${F(g(process.cwd(), t.split("?")[0] ?? t))}). Import the equivalent hook from "@glasshome/widget-sdk" instead (e.g. useEntity, useEntities, useService).`);
329
+ if (z(t, e)) throw Error(`Widgets must not import "@glasshome/sync-layer" directly (imported by ${P(_(process.cwd(), t.split("?")[0] ?? t))}). Import the equivalent hook from "@glasshome/widget-sdk" instead (e.g. useEntity, useEntities, useService).`);
304
330
  return null;
305
331
  }
306
332
  };
307
333
  }
308
- function H(t, n) {
309
- let r = F(t).split("?")[0] ?? "";
310
- if (r.includes("/node_modules/") || !R.test(r)) return !1;
334
+ function V(t, n) {
335
+ let r = P(t).split("?")[0] ?? "";
336
+ if (r.includes("/node_modules/") || !L.test(r)) return !1;
311
337
  let i = e.find((e) => e.id === "direct-ui-import");
312
338
  return i?.sourcePattern ? new RegExp(i.sourcePattern).test(n) : !1;
313
339
  }
314
- function U(e = /* @__PURE__ */ new Set()) {
340
+ function H(e = /* @__PURE__ */ new Set()) {
315
341
  let t = /* @__PURE__ */ new Set();
316
342
  return {
317
343
  scan(e, n) {
318
- H(e, n) && t.add(F(g(process.cwd(), e.split("?")[0] ?? e)));
344
+ V(e, n) && t.add(P(_(process.cwd(), e.split("?")[0] ?? e)));
319
345
  },
320
346
  take() {
321
347
  let n = [...t].filter((t) => !e.has(t));
@@ -324,8 +350,8 @@ function U(e = /* @__PURE__ */ new Set()) {
324
350
  }
325
351
  };
326
352
  }
327
- function W(n) {
328
- let r = U(n);
353
+ function U(n) {
354
+ let r = H(n);
329
355
  return {
330
356
  name: "glasshome-widget:ui-import-guard",
331
357
  apply: "build",
@@ -341,15 +367,15 @@ function W(n) {
341
367
  }
342
368
  };
343
369
  }
344
- var G = "node_modules/.cache/glasshome-widgets";
345
- function K(e) {
370
+ var me = "node_modules/.cache/glasshome-widgets";
371
+ function W(e) {
346
372
  try {
347
- return p(h(process.cwd(), "package.json")).resolve(e);
373
+ return m(g(process.cwd(), "package.json")).resolve(e);
348
374
  } catch {
349
375
  return null;
350
376
  }
351
377
  }
352
- var se = [
378
+ var he = [
353
379
  "--radius",
354
380
  "--background",
355
381
  "--foreground",
@@ -359,46 +385,54 @@ var se = [
359
385
  "--muted",
360
386
  "--accent"
361
387
  ];
362
- function q(e, t) {
363
- let n = h(e, `${t}.css`);
364
- if (!o(n)) return;
365
- let r = c(n, "utf-8");
366
- for (let e of r.matchAll(/:host[^{]*\{([^}]*)\}/g)) {
367
- let n = e[1] ?? "", r = se.find((e) => n.includes(`${e}:`));
388
+ function G(e) {
389
+ return e.replace(/(?<=[{;])\s*(--[\w-]+)\s*:\s*var\(\s*\1\s*\)\s*(;|(?=\}))/g, "");
390
+ }
391
+ function K(e, t) {
392
+ let n = g(e, `${t}.css`);
393
+ if (!s(n)) return;
394
+ let r = l(n, "utf-8"), i = G(r);
395
+ i !== r && p(n, i);
396
+ for (let e of i.matchAll(/:host[^{]*\{([^}]*)\}/g)) {
397
+ let n = e[1] ?? "", r = he.find((e) => n.includes(`${e}:`));
368
398
  if (r) throw Error(`[glasshome-widget] "${t}.css" defines theme variable "${r}" on :host. Theme variables must inherit from the document so widgets follow the household theme — never re-scope them into the widget's shadow root.`);
369
399
  }
370
400
  }
371
- function J(e, t, n) {
372
- let r = _(e, G);
373
- s(r, { recursive: !0 });
374
- let i = K("@glasshome/ui/styles");
375
- if (!i) throw Error("[widget-sdk] @glasshome/ui is required to build widgets (it provides the theme every GlassHome widget ships with). Add it to your widget's dependencies.");
376
- let a = _(m(i), "../.."), c = K("@glasshome/widget-sdk/tailwind-sources"), l = c ? m(c) : null, u = [
377
- h(a, "src"),
378
- h(a, "dist"),
379
- ...l ? [h(l, "src"), h(l, "dist")] : [],
380
- m(n)
381
- ].filter((e) => o(e)), d = _(r, `${t}.tailwind.css`);
382
- f(d, [
401
+ function q(e, t) {
402
+ let n = v(e), r = h(t), i = new Set(Z(n).map((e) => h(e.entry)));
403
+ return [r, ...u(n, { withFileTypes: !0 }).filter((e) => e.isDirectory()).map((e) => g(n, e.name)).filter((e) => !i.has(e))];
404
+ }
405
+ function J(e, t, n, r) {
406
+ let i = v(e, me);
407
+ c(i, { recursive: !0 });
408
+ let a = W("@glasshome/ui/styles");
409
+ if (!a) throw Error("[widget-sdk] @glasshome/ui is required to build widgets (it provides the theme every GlassHome widget ships with). Add it to your widget's dependencies.");
410
+ let o = v(h(a), "../.."), l = W("@glasshome/widget-sdk/tailwind-sources"), u = l ? h(l) : null, d = [
411
+ g(o, "src"),
412
+ g(o, "dist"),
413
+ ...u ? [g(u, "src"), g(u, "dist")] : [],
414
+ ...q(r, n)
415
+ ].filter((e) => s(e)), f = v(i, `${t}.tailwind.css`);
416
+ p(f, [
383
417
  "@import \"tailwindcss\" source(none);",
384
418
  "@import \"tw-animate-css\";",
385
419
  "@import \"@glasshome/ui/styles/theme\";",
386
- ...u.map((e) => `@source "${F(e)}";`),
420
+ ...d.map((e) => `@source "${P(e)}";`),
387
421
  "@custom-variant dark {",
388
422
  " &:is(.dark *) { @slot }",
389
423
  " :host(.dark) & { @slot }",
390
424
  "}",
391
425
  ""
392
426
  ].join("\n"));
393
- let p = _(r, `${t}.entry.ts`);
394
- return f(p, [
395
- `import "${F(d)}";`,
396
- `export { default } from "${F(n)}";`,
427
+ let m = v(i, `${t}.entry.ts`);
428
+ return p(m, [
429
+ `import "${P(f)}";`,
430
+ `export { default } from "${P(n)}";`,
397
431
  ""
398
- ].join("\n")), p;
432
+ ].join("\n")), m;
399
433
  }
400
434
  function Y() {
401
- let { Features: e } = p(import.meta.url)("lightningcss");
435
+ let { Features: e } = m(import.meta.url)("lightningcss");
402
436
  return { lightningcss: { include: e.HexAlphaColors } };
403
437
  }
404
438
  function X() {
@@ -408,12 +442,12 @@ function X() {
408
442
  }
409
443
  function Z(e) {
410
444
  let t = [];
411
- if (!o(e)) return t;
412
- for (let n of l(e)) {
413
- let r = _(e, n);
414
- if (!d(r).isDirectory()) continue;
415
- let i = _(r, "index.tsx"), a = _(r, "manifest.json");
416
- o(i) && o(a) && t.push({
445
+ if (!s(e)) return t;
446
+ for (let n of u(e)) {
447
+ let r = v(e, n);
448
+ if (!f(r).isDirectory()) continue;
449
+ let i = v(r, "index.tsx"), a = v(r, "manifest.json");
450
+ s(i) && s(a) && t.push({
417
451
  name: n,
418
452
  entry: i
419
453
  });
@@ -422,29 +456,29 @@ function Z(e) {
422
456
  }
423
457
  function Q(e, t) {
424
458
  let r = [];
425
- if (o(e)) for (let a of l(e)) {
426
- if (!d(h(e, a)).isDirectory()) continue;
427
- let s = h(e, a, "manifest.json");
428
- if (!o(s)) continue;
429
- let l = i.safeParse(JSON.parse(c(s, "utf-8")));
430
- if (!l.success) throw Error(`[registry] Invalid manifest for "${a}": ${n(l.error)}`);
431
- let u = o(h(t, `${a}.css`));
459
+ if (s(e)) for (let i of u(e)) {
460
+ if (!f(g(e, i)).isDirectory()) continue;
461
+ let o = g(e, i, "manifest.json");
462
+ if (!s(o)) continue;
463
+ let c = a.safeParse(JSON.parse(l(o, "utf-8")));
464
+ if (!c.success) throw Error(`[registry] Invalid manifest for "${i}": ${n(c.error)}`);
465
+ let u = s(g(t, `${i}.css`));
432
466
  r.push({
433
- ...l.data,
434
- bundleUrl: `./${a}.js`,
435
- ...u ? { cssUrl: `./${a}.css` } : {}
467
+ ...c.data,
468
+ bundleUrl: `./${i}.js`,
469
+ ...u ? { cssUrl: `./${i}.css` } : {}
436
470
  });
437
471
  }
438
- let a = {
472
+ let i = {
439
473
  version: 1,
440
474
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
441
475
  baseUrl: "./",
442
476
  widgets: r
443
477
  };
444
- o(t) || s(t, { recursive: !0 }), f(h(t, "registry.json"), JSON.stringify(a, null, 2)), console.log(`[registry] Generated registry.json with ${r.length} widget(s)`);
478
+ s(t) || c(t, { recursive: !0 }), p(g(t, "registry.json"), JSON.stringify(i, null, 2)), console.log(`[registry] Generated registry.json with ${r.length} widget(s)`);
445
479
  }
446
480
  async function $(e) {
447
- let { build: t } = await import("vite"), n = process.cwd(), r = _(n, e?.srcDir ?? "src"), i = _(n, e?.outDir ?? "dist"), a = Z(r);
481
+ let { build: t } = await import("vite"), n = process.cwd(), r = v(n, e?.srcDir ?? "src"), i = v(n, e?.outDir ?? "dist"), a = Z(r);
448
482
  if (a.length === 0) {
449
483
  console.warn("[glasshome-widgets] No widgets found in", r);
450
484
  return;
@@ -453,16 +487,16 @@ async function $(e) {
453
487
  let t = new Set(e.only);
454
488
  a = a.filter((e) => t.has(e.name));
455
489
  }
456
- e?.only || o(i) && u(i, { recursive: !0 }), o(i) || s(i, { recursive: !0 });
457
- let c = /* @__PURE__ */ new Set();
458
- for (let r of a) await t({
490
+ e?.only || s(i) && d(i, { recursive: !0 }), s(i) || c(i, { recursive: !0 });
491
+ let o = /* @__PURE__ */ new Set();
492
+ for (let s of a) await t({
459
493
  configFile: !1,
460
494
  root: n,
461
495
  plugins: [
462
496
  ...X(),
463
497
  ...e?.plugins ?? [],
464
- V(),
465
- W(c)
498
+ B(),
499
+ U(o)
466
500
  ],
467
501
  ...e?.viteConfig,
468
502
  css: {
@@ -471,28 +505,28 @@ async function $(e) {
471
505
  },
472
506
  build: {
473
507
  lib: {
474
- entry: J(n, r.name, r.entry),
508
+ entry: J(n, s.name, s.entry, r),
475
509
  formats: ["es"],
476
- fileName: r.name,
477
- cssFileName: r.name
510
+ fileName: s.name,
511
+ cssFileName: s.name
478
512
  },
479
- rollupOptions: { external: L },
513
+ rollupOptions: { external: I },
480
514
  outDir: i,
481
515
  emptyOutDir: !1,
482
516
  copyPublicDir: !1,
483
517
  ...e?.viteConfig?.build
484
518
  },
485
519
  logLevel: "warn"
486
- }), q(i, r.name), await M({
487
- outFile: h(i, `${r.name}.js`),
488
- hashFile: h(m(r.entry), ".schema-hash"),
489
- widgetName: r.name,
490
- manifestPath: h(m(r.entry), "manifest.json"),
520
+ }), K(i, s.name), await M({
521
+ outFile: g(i, `${s.name}.js`),
522
+ hashFile: g(h(s.entry), ".schema-hash"),
523
+ widgetName: s.name,
524
+ manifestPath: g(h(s.entry), "manifest.json"),
491
525
  session: e?.session
492
526
  });
493
527
  Q(r, i);
494
528
  }
495
- function ce(e) {
529
+ function ge(e) {
496
530
  let t = e?.entry ?? "src/index.tsx", n = {
497
531
  name: "glasshome-widget:build",
498
532
  apply: "build",
@@ -502,12 +536,12 @@ function ce(e) {
502
536
  css: Y(),
503
537
  build: {
504
538
  lib: {
505
- entry: J(e, "index", _(e, t)),
539
+ entry: J(e, "index", v(e, t), h(v(e, t))),
506
540
  formats: ["es"],
507
541
  fileName: "index",
508
542
  cssFileName: "index"
509
543
  },
510
- rollupOptions: { external: L }
544
+ rollupOptions: { external: I }
511
545
  }
512
546
  };
513
547
  }
@@ -516,18 +550,18 @@ function ce(e) {
516
550
  apply: "serve",
517
551
  enforce: "pre",
518
552
  config() {
519
- let e = I(), t = process.cwd();
553
+ let e = F(), t = process.cwd();
520
554
  return { server: { fs: { allow: [
521
555
  e,
522
556
  t,
523
- _(t, "..", "..")
557
+ v(t, "..", "..")
524
558
  ] } } };
525
559
  },
526
560
  configureServer(e) {
527
- let t = I(), n = h(t, "preview.html");
561
+ let t = F(), n = g(t, "preview.html");
528
562
  e.middlewares.use(async (t, r, i) => {
529
563
  if (t.url === "/" || t.url === "/index.html") try {
530
- let i = c(n, "utf-8");
564
+ let i = l(n, "utf-8");
531
565
  i = await e.transformIndexHtml(t.url, i), r.setHeader("Content-Type", "text/html"), r.statusCode = 200, r.end(i);
532
566
  } catch (e) {
533
567
  i(e);
@@ -536,37 +570,37 @@ function ce(e) {
536
570
  });
537
571
  },
538
572
  resolveId(e) {
539
- if (e === P) {
540
- let e = I();
541
- return F(h(e, "host.tsx"));
573
+ if (e === pe) {
574
+ let e = F();
575
+ return P(g(e, "host.tsx"));
542
576
  }
543
- if (e === oe) return N;
577
+ if (e === fe) return N;
544
578
  },
545
579
  load(e) {
546
- if (e === N) return `export { default } from "${F(_(process.cwd(), t))}";`;
580
+ if (e === N) return `export { default } from "${P(v(process.cwd(), t))}";`;
547
581
  }
548
582
  }, i = {
549
583
  name: "glasshome-widget:schema",
550
584
  apply: "build",
551
585
  async closeBundle() {
552
- q(_(process.cwd(), "dist"), "index"), await M({
553
- outFile: _(process.cwd(), "dist", "index.js"),
554
- hashFile: _(process.cwd(), ".schema-hash"),
586
+ K(v(process.cwd(), "dist"), "index"), await M({
587
+ outFile: v(process.cwd(), "dist", "index.js"),
588
+ hashFile: v(process.cwd(), ".schema-hash"),
555
589
  widgetName: "index",
556
- manifestPath: _(process.cwd(), "manifest.json")
590
+ manifestPath: v(process.cwd(), "manifest.json")
557
591
  });
558
592
  }
559
593
  };
560
594
  return [
561
595
  ...X(),
562
596
  n,
563
- V(),
564
- W(),
597
+ B(),
598
+ U(),
565
599
  i,
566
600
  r
567
601
  ];
568
602
  }
569
- function le(e) {
603
+ function _e(e) {
570
604
  let t = e?.srcDir ?? "src", n = e?.outDir ?? "dist", r = [];
571
605
  return [{
572
606
  name: "glasshome-widgets:build",
@@ -594,4 +628,4 @@ function le(e) {
594
628
  }];
595
629
  }
596
630
  //#endregion
597
- export { D as MAX_EXAMPLES, $ as buildWidgets, C as createIntrospectSession, U as createUiImportTracker, Z as discoverWidgets, Q as generateRegistry, ce as glasshomeWidget, le as glasshomeWidgets, S as introspectOnce, B as isDirectSyncLayerImportSource, H as isDirectUiImportSource, L as isWidgetExternal, M as runSchemaGuard };
631
+ export { A as HOOK_READS, se as MAX_EXAMPLES, j as assertHookReadsDeclared, $ as buildWidgets, ae as createIntrospectSession, H as createUiImportTracker, Z as discoverWidgets, G as dropSelfReferencingVars, Q as generateRegistry, ge as glasshomeWidget, _e as glasshomeWidgets, w as introspectOnce, z as isDirectSyncLayerImportSource, V as isDirectUiImportSource, I as isWidgetExternal, M as runSchemaGuard, k as sdkImportsOf, q as widgetProjectScanDirs };