@glasshome/widget-sdk 1.6.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,33 @@
1
+ import { createContext as e, useContext as t } from "solid-js";
2
+ //#region src/framework/hooks/use-widget-context.ts
3
+ var n = e();
4
+ function r() {
5
+ let e = t(n);
6
+ if (!e) throw Error("useWidgetContext must be used within a Widget component");
7
+ return e;
8
+ }
9
+ //#endregion
10
+ //#region src/framework/theming/tokens.css?raw
11
+ var i = "/* Authoritative SDK CSS contract. Injected once on first Widget mount\n * via framework/theming/tokens.ts.\n *\n * All widget-internal visual scale is driven from CSS custom properties +\n * container queries on the `.glasshome-widget` shell (`container-type: size`).\n * No JS classifier, no size tier enum.\n */\n\n:root {\n --tone-success: oklch(0.70 0.18 145);\n --tone-warning: oklch(0.80 0.17 75);\n --tone-danger: oklch(0.64 0.22 27);\n --tone-info: oklch(0.66 0.20 245);\n --tone-neutral: oklch(0.65 0.02 250);\n --tone-accent: oklch(0.74 0.18 60);\n\n --widget-grad-strength: 1;\n --widget-glow-default: 0.4;\n --widget-border-highlight: oklch(0.98 0 0 / 0.4);\n}\n\n.dark {\n --tone-success: oklch(0.74 0.18 145);\n --tone-warning: oklch(0.82 0.17 75);\n --tone-danger: oklch(0.68 0.22 27);\n --tone-info: oklch(0.70 0.20 245);\n --tone-neutral: oklch(0.69 0.02 250);\n --tone-accent: oklch(0.78 0.18 60);\n\n --widget-grad-strength: 1.1;\n --widget-glow-default: 0.5;\n --widget-border-highlight: oklch(1 0 0 / 0.08);\n}\n\n@property --widget-color {\n syntax: \"<color>\";\n inherits: true;\n initial-value: oklch(0.65 0.02 250);\n}\n\n/* === Widget shell ===\n * Fluid scale tokens — tied to the shell's own container box (cqb=height, cqi=width).\n * Icon/pad/gap track HEIGHT (cqb) not the shortest side: two widgets of equal\n * height match regardless of width (a 2×2 and a 4×2 get the same icon). cqmin\n * starved portrait tiles by pinning the icon to the narrow width. Tune\n * multipliers / clamps to adjust density. */\n.glasshome-widget {\n --widget-color: var(--tone-neutral);\n --widget-glow-strength: var(--widget-glow-default);\n\n --widget-icon-box: clamp(44px, 25cqb, 58px);\n --widget-icon-glyph: clamp(24px, 14cqb, 33px);\n --widget-pad: clamp(8px, 3.5cqb, 22px);\n --widget-gap: clamp(6px, 2cqb, 14px);\n --widget-title-size: clamp(12px, 2cqi, 18px);\n --widget-subtitle: clamp(12px, 2.5cqi, 20px);\n --widget-status-size: clamp(14px, 5cqi, 36px);\n --widget-value-size: clamp(18px, 7cqi, 48px);\n --widget-badge-size: clamp(11px, 1.6cqi, 14px);\n}\n\n.glasshome-widget {\n background: var(--widget-gradient,\n linear-gradient(135deg,\n color-mix(in oklch, var(--widget-color) calc(22% * var(--widget-grad-strength)), transparent),\n color-mix(in oklch, var(--widget-color-to, var(--widget-color)) calc(11% * var(--widget-grad-strength)), transparent)\n )\n );\n box-shadow: inset 0 1px 0 var(--widget-border-highlight);\n}\n\n/* === Slot: content layout === */\n/* Default: column. Flip to row only on wide-and-short widgets (matches the\n * old contentLayout heuristic: aspect > 1 AND height < 150px). */\n.glasshome-widget-content {\n position: relative;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n width: 100%;\n height: 100%;\n padding: var(--widget-pad);\n gap: var(--widget-gap);\n overflow: hidden;\n}\n@container widget (min-aspect-ratio: 1) and (max-height: 149px) {\n .glasshome-widget-content {\n flex-direction: row;\n align-items: center;\n justify-content: flex-start;\n }\n}\n\n/* === Compact 1×1 ===\n * Small in BOTH axes → stack the tile: icon on top, label + status centered\n * under it. Icon stays moderate (not a hero) so the text keeps room. Wide\n * tiles (2×1) fail the width test and keep the row layout above. Placed after\n * the row-flip so it wins. */\n@container widget (max-width: 189px) and (max-height: 189px) {\n .glasshome-widget-content {\n flex-direction: column;\n align-items: center;\n justify-content: center;\n text-align: center;\n gap: clamp(4px, 2.5cqmin, 8px);\n }\n .glasshome-widget-content > * { align-items: center; text-align: center; }\n .glasshome-widget-icon {\n --widget-icon-box: clamp(36px, 30cqmin, 56px);\n --widget-icon-glyph: clamp(20px, 17cqmin, 32px);\n }\n .glasshome-widget-title { font-size: clamp(11px, 6cqmin, 14px); max-width: 100%; }\n .glasshome-widget-status,\n .glasshome-widget-value { font-size: clamp(13px, 7cqmin, 17px); }\n .glasshome-widget-content [class*=\"ml-auto\"] { margin-left: 0 !important; }\n}\n.glasshome-widget-content [class*=\"ml-auto\"] {\n position: relative;\n z-index: 30;\n}\n\n/* === Slot: icon === */\n.glasshome-widget-icon {\n width: var(--widget-icon-box);\n height: var(--widget-icon-box);\n border-radius: var(--radius-sm, 12px);\n background: var(--widget-icon-color, var(--widget-color));\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 30px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 50%, transparent);\n color: oklch(from var(--widget-icon-color, var(--widget-color)) calc(0.52 + sign(0.5 - l) * 0.43) calc(c * 0.2) h);\n}\n.glasshome-widget-icon-glyph {\n font-size: var(--widget-icon-glyph);\n line-height: 1;\n}\n.glasshome-widget-icon-stack {\n position: absolute;\n width: 102%;\n height: 102%;\n border-radius: var(--radius-sm, 12px);\n}\n.glasshome-widget-icon-stack-2 { bottom: -14%; right: -10%; opacity: 0.45; z-index: -2; }\n.glasshome-widget-icon-stack-3 { bottom: -28%; right: -20%; opacity: 0.20; z-index: -3; }\n\n/* === Slot: text === */\n.glasshome-widget-title {\n font-size: var(--widget-title-size);\n line-height: 1.2;\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.glasshome-widget-subtitle {\n font-size: var(--widget-subtitle);\n color: color-mix(in oklch, var(--color-foreground, currentColor) 60%, transparent);\n}\n.glasshome-widget-status {\n font-size: var(--widget-status-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.1;\n}\n.glasshome-widget-value {\n font-size: var(--widget-value-size);\n font-weight: 700;\n color: var(--color-foreground, currentColor);\n line-height: 1.05;\n}\n.glasshome-widget-badge {\n font-size: var(--widget-badge-size);\n font-weight: 500;\n padding: 0.125rem 0.5rem;\n border-radius: 9999px;\n background: color-mix(in oklch, var(--color-foreground, currentColor) 20%, transparent);\n color: var(--color-foreground, currentColor);\n}\n\n.glasshome-widget-loading {\n background: color-mix(in oklch, var(--widget-color) 20%, transparent);\n}\n\n/* === Slider fill ===\n * Value flows in via --widget-fill-value (0-100). Vertical orientation auto-\n * detected via container query. */\n.glasshome-widget-slider-fill {\n --widget-fill-value: 0;\n background: color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 30%, transparent);\n box-shadow: 0 0 calc(var(--widget-glow-strength) * 40px)\n color-mix(in oklch, var(--widget-icon-color, var(--widget-color)) 40%, transparent);\n clip-path: inset(0 calc((100 - var(--widget-fill-value)) * 1%) 0 0);\n}\n@container widget (max-aspect-ratio: 1) {\n .glasshome-widget-slider-fill {\n clip-path: inset(calc((100 - var(--widget-fill-value)) * 1%) 0 0 0);\n }\n}\n", a = !1, o, s = /* @__PURE__ */ new WeakSet();
12
+ function c() {
13
+ return o || (o = new CSSStyleSheet(), o.replaceSync(i.replace(/:root\b/g, ":host").replace(/^\.dark\b/gm, ":host(.dark)"))), o;
14
+ }
15
+ function l(e) {
16
+ if (typeof ShadowRoot < "u" && e instanceof ShadowRoot) {
17
+ if (s.has(e)) return;
18
+ let t = c();
19
+ e.adoptedStyleSheets.includes(t) || (e.adoptedStyleSheets = [...e.adoptedStyleSheets, t]), s.add(e);
20
+ return;
21
+ }
22
+ if (a) return;
23
+ let t = e ?? (typeof document > "u" ? void 0 : document);
24
+ if (!t) return;
25
+ if (t.head.querySelector?.("style[data-glasshome-tokens]")) {
26
+ a = !0;
27
+ return;
28
+ }
29
+ let n = t.createElement("style");
30
+ n.setAttribute("data-glasshome-tokens", ""), n.textContent = i, t.head.appendChild(n), a = !0;
31
+ }
32
+ //#endregion
33
+ export { n, r, l as t };
@@ -3,6 +3,24 @@ export interface GlasshomeWidgetOptions {
3
3
  /** Entry file for the widget (default: "src/index.tsx") */
4
4
  entry?: string;
5
5
  }
6
+ /**
7
+ * Configuration-drift guard (D-11). Imports the built bundle, derives the JSON
8
+ * Schema from its configSchema, and compares against the recorded
9
+ * `.schema-hash`. A shape change without a configVersion bump fails the build:
10
+ * tsc cannot catch this class of break because the old persisted config still
11
+ * parses, only its meaning shifts. Legacy plain-hash records (written by
12
+ * pre-1.7 builds) cannot prove a missing bump, so they only warn, then upgrade
13
+ * to the JSON record format.
14
+ *
15
+ * When `manifestPath` is given (single-widget projects), the generated JSON
16
+ * Schema is also written into `manifest.json` as `schema`.
17
+ */
18
+ export declare function runSchemaGuard(args: {
19
+ outFile: string;
20
+ hashFile: string;
21
+ widgetName: string;
22
+ manifestPath?: string;
23
+ }): Promise<void>;
6
24
  /**
7
25
  * Packages provided by the host import map — widgets must not bundle these.
8
26
  * Delegates to the shared list in @glasshome/widget-contract so the host's
@@ -10,17 +10,54 @@ function v(e) {
10
10
  let t = JSON.stringify(e, Object.keys(e).sort());
11
11
  return r("sha256").update(t).digest("hex").slice(0, 16);
12
12
  }
13
- var y = "virtual:glasshome-widget", b = "\0virtual:glasshome-widget", x = "/@glasshome/preview";
14
- function S(e) {
13
+ async function y(e) {
14
+ if (!i(e.outFile)) return;
15
+ let t;
16
+ try {
17
+ t = (await import(`${e.outFile}?t=${Date.now()}`)).default;
18
+ } catch {
19
+ return;
20
+ }
21
+ if (!t?.configSchema) return;
22
+ let n;
23
+ try {
24
+ let { z: e } = await import("zod");
25
+ n = e.toJSONSchema(t.configSchema, { unrepresentable: "any" });
26
+ } catch {
27
+ return;
28
+ }
29
+ if (e.manifestPath && i(e.manifestPath)) {
30
+ let t = JSON.parse(o(e.manifestPath, "utf-8"));
31
+ t.schema = n, u(e.manifestPath, JSON.stringify(t, null, 2));
32
+ }
33
+ let r = v(n), a = t.manifest?.configVersion ?? null, s = t.manifest?.name ?? e.widgetName;
34
+ if (i(e.hashFile)) {
35
+ let t = o(e.hashFile, "utf-8").trim(), n = null;
36
+ if (t.startsWith("{")) try {
37
+ n = JSON.parse(t);
38
+ } catch {
39
+ n = null;
40
+ }
41
+ if (n) {
42
+ if (n.hash !== r && n.configVersion === a) throw Error(`[widget-sdk] Config schema shape changed for "${s}" without a configVersion bump. Bump configVersion in defineWidget (currently ${a ?? "unset"}) or revert the schema change, then rebuild. Recorded in ${e.hashFile}`);
43
+ } else t !== r && console.warn(`[widget-sdk] Schema shape changed for "${s}" — verify configVersion was bumped`);
44
+ }
45
+ u(e.hashFile, `${JSON.stringify({
46
+ hash: r,
47
+ configVersion: a
48
+ })}\n`);
49
+ }
50
+ var b = "virtual:glasshome-widget", x = "\0virtual:glasshome-widget", S = "/@glasshome/preview";
51
+ function C(e) {
15
52
  return h === "\\" ? e.split(h).join("/") : e;
16
53
  }
17
- function C() {
54
+ function w() {
18
55
  return m(f(g(import.meta.url)), "../../preview");
19
56
  }
20
- function w(e) {
57
+ function T(e) {
21
58
  return t(e);
22
59
  }
23
- function T() {
60
+ function E() {
24
61
  return {
25
62
  name: "glasshome-widget:sync-layer-guard",
26
63
  apply: "build",
@@ -30,15 +67,15 @@ function T() {
30
67
  }
31
68
  };
32
69
  }
33
- var E = "node_modules/.cache/glasshome-widgets";
34
- function D(e) {
70
+ var D = "node_modules/.cache/glasshome-widgets";
71
+ function O(e) {
35
72
  try {
36
73
  return d(p(process.cwd(), "package.json")).resolve(e);
37
74
  } catch {
38
75
  return null;
39
76
  }
40
77
  }
41
- var O = [
78
+ var k = [
42
79
  "--radius",
43
80
  "--background",
44
81
  "--foreground",
@@ -48,21 +85,21 @@ var O = [
48
85
  "--muted",
49
86
  "--accent"
50
87
  ];
51
- function k(e, t) {
88
+ function A(e, t) {
52
89
  let n = p(e, `${t}.css`);
53
90
  if (!i(n)) return;
54
91
  let r = o(n, "utf-8");
55
92
  for (let e of r.matchAll(/:host[^{]*\{([^}]*)\}/g)) {
56
- let n = e[1] ?? "", r = O.find((e) => n.includes(`${e}:`));
93
+ let n = e[1] ?? "", r = k.find((e) => n.includes(`${e}:`));
57
94
  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.`);
58
95
  }
59
96
  }
60
- function A(e, t, n) {
61
- let r = m(e, E);
97
+ function j(e, t, n) {
98
+ let r = m(e, D);
62
99
  a(r, { recursive: !0 });
63
- let o = D("@glasshome/ui/styles");
100
+ let o = O("@glasshome/ui/styles");
64
101
  if (!o) 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.");
65
- let s = m(f(o), "../.."), c = D("@glasshome/widget-sdk/tailwind-sources"), l = c ? f(c) : null, d = [
102
+ let s = m(f(o), "../.."), c = O("@glasshome/widget-sdk/tailwind-sources"), l = c ? f(c) : null, d = [
66
103
  p(s, "src"),
67
104
  p(s, "dist"),
68
105
  ...l ? [p(l, "src"), p(l, "dist")] : [],
@@ -72,7 +109,7 @@ function A(e, t, n) {
72
109
  "@import \"tailwindcss\" source(none);",
73
110
  "@import \"tw-animate-css\";",
74
111
  "@import \"@glasshome/ui/styles/theme\";",
75
- ...d.map((e) => `@source "${S(e)}";`),
112
+ ...d.map((e) => `@source "${C(e)}";`),
76
113
  "@custom-variant dark {",
77
114
  " &:is(.dark *) { @slot }",
78
115
  " :host(.dark) & { @slot }",
@@ -81,17 +118,17 @@ function A(e, t, n) {
81
118
  ].join("\n"));
82
119
  let g = m(r, `${t}.entry.ts`);
83
120
  return u(g, [
84
- `import "${S(h)}";`,
85
- `export { default } from "${S(n)}";`,
121
+ `import "${C(h)}";`,
122
+ `export { default } from "${C(n)}";`,
86
123
  ""
87
124
  ].join("\n")), g;
88
125
  }
89
- function j() {
126
+ function M() {
90
127
  let e = _();
91
128
  for (let t of e) t.apply ??= "build";
92
129
  return e;
93
130
  }
94
- function M(e) {
131
+ function N(e) {
95
132
  let t = [];
96
133
  if (!i(e)) return t;
97
134
  for (let n of s(e)) {
@@ -105,7 +142,7 @@ function M(e) {
105
142
  }
106
143
  return t;
107
144
  }
108
- function N(t, r) {
145
+ function P(t, r) {
109
146
  let c = [];
110
147
  if (i(t)) for (let a of s(t)) {
111
148
  if (!l(p(t, a)).isDirectory()) continue;
@@ -128,8 +165,8 @@ function N(t, r) {
128
165
  };
129
166
  i(r) || a(r, { recursive: !0 }), u(p(r, "registry.json"), JSON.stringify(d, null, 2)), console.log(`[registry] Generated registry.json with ${c.length} widget(s)`);
130
167
  }
131
- async function P(e) {
132
- let { build: t } = await import("vite"), n = process.cwd(), r = m(n, e?.srcDir ?? "src"), o = m(n, e?.outDir ?? "dist"), s = M(r);
168
+ async function F(e) {
169
+ let { build: t } = await import("vite"), n = process.cwd(), r = m(n, e?.srcDir ?? "src"), o = m(n, e?.outDir ?? "dist"), s = N(r);
133
170
  if (s.length === 0) {
134
171
  console.warn("[glasshome-widgets] No widgets found in", r);
135
172
  return;
@@ -143,29 +180,33 @@ async function P(e) {
143
180
  configFile: !1,
144
181
  root: n,
145
182
  plugins: [
146
- ...j(),
183
+ ...M(),
147
184
  ...e?.plugins ?? [],
148
- T()
185
+ E()
149
186
  ],
150
187
  ...e?.viteConfig,
151
188
  build: {
152
189
  lib: {
153
- entry: A(n, r.name, r.entry),
190
+ entry: j(n, r.name, r.entry),
154
191
  formats: ["es"],
155
192
  fileName: r.name,
156
193
  cssFileName: r.name
157
194
  },
158
- rollupOptions: { external: w },
195
+ rollupOptions: { external: T },
159
196
  outDir: o,
160
197
  emptyOutDir: !1,
161
198
  copyPublicDir: !1,
162
199
  ...e?.viteConfig?.build
163
200
  },
164
201
  logLevel: "warn"
165
- }), k(o, r.name);
166
- N(r, o);
202
+ }), A(o, r.name), await y({
203
+ outFile: p(o, `${r.name}.js`),
204
+ hashFile: p(f(r.entry), ".schema-hash"),
205
+ widgetName: r.name
206
+ });
207
+ P(r, o);
167
208
  }
168
- function F(e) {
209
+ function I(e) {
169
210
  let t = e?.entry ?? "src/index.tsx", n = {
170
211
  name: "glasshome-widget:build",
171
212
  apply: "build",
@@ -173,12 +214,12 @@ function F(e) {
173
214
  let e = process.cwd();
174
215
  return { build: {
175
216
  lib: {
176
- entry: A(e, "index", m(e, t)),
217
+ entry: j(e, "index", m(e, t)),
177
218
  formats: ["es"],
178
219
  fileName: "index",
179
220
  cssFileName: "index"
180
221
  },
181
- rollupOptions: { external: w }
222
+ rollupOptions: { external: T }
182
223
  } };
183
224
  }
184
225
  }, r = {
@@ -186,7 +227,7 @@ function F(e) {
186
227
  apply: "serve",
187
228
  enforce: "pre",
188
229
  config() {
189
- let e = C(), t = process.cwd();
230
+ let e = w(), t = process.cwd();
190
231
  return { server: { fs: { allow: [
191
232
  e,
192
233
  t,
@@ -194,7 +235,7 @@ function F(e) {
194
235
  ] } } };
195
236
  },
196
237
  configureServer(e) {
197
- let t = p(C(), "preview.html");
238
+ let t = p(w(), "preview.html");
198
239
  e.middlewares.use(async (n, r, i) => {
199
240
  if (n.url === "/" || n.url === "/index.html") try {
200
241
  let i = o(t, "utf-8");
@@ -206,44 +247,33 @@ function F(e) {
206
247
  });
207
248
  },
208
249
  resolveId(e) {
209
- if (e === x) return S(p(C(), "host.tsx"));
210
- if (e === y) return b;
250
+ if (e === S) return C(p(w(), "host.tsx"));
251
+ if (e === b) return x;
211
252
  },
212
253
  load(e) {
213
- if (e === b) return `export { default } from "${S(m(process.cwd(), t))}";`;
254
+ if (e === x) return `export { default } from "${C(m(process.cwd(), t))}";`;
214
255
  }
215
- }, a = {
256
+ }, i = {
216
257
  name: "glasshome-widget:schema",
217
258
  apply: "build",
218
259
  async closeBundle() {
219
- k(m(process.cwd(), "dist"), "index");
220
- let e = m(process.cwd(), "dist", "index.js");
221
- if (i(e)) try {
222
- let t = (await import(`${e}?t=${Date.now()}`)).default;
223
- if (!t?.configSchema) return;
224
- let { z: n } = await import("zod"), r = n.toJSONSchema(t.configSchema, { unrepresentable: "any" }), a = m(process.cwd(), "manifest.json");
225
- if (i(a)) {
226
- let e = JSON.parse(o(a, "utf-8"));
227
- e.schema = r, u(a, JSON.stringify(e, null, 2));
228
- }
229
- let s = v(r), c = m(process.cwd(), ".schema-hash");
230
- if (i(c) && o(c, "utf-8").trim() !== s) {
231
- let e = t.manifest?.name ?? "unknown";
232
- console.warn(`[widget-sdk] Schema shape changed for "${e}" — verify configVersion was bumped`);
233
- }
234
- u(c, s);
235
- } catch {}
260
+ A(m(process.cwd(), "dist"), "index"), await y({
261
+ outFile: m(process.cwd(), "dist", "index.js"),
262
+ hashFile: m(process.cwd(), ".schema-hash"),
263
+ widgetName: "index",
264
+ manifestPath: m(process.cwd(), "manifest.json")
265
+ });
236
266
  }
237
267
  };
238
268
  return [
239
- ...j(),
269
+ ...M(),
240
270
  n,
241
- T(),
242
- a,
271
+ E(),
272
+ i,
243
273
  r
244
274
  ];
245
275
  }
246
- function I(e) {
276
+ function L(e) {
247
277
  let t = e?.srcDir ?? "src", n = e?.outDir ?? "dist", r = [];
248
278
  return [{
249
279
  name: "glasshome-widgets:build",
@@ -262,7 +292,7 @@ function I(e) {
262
292
  if (e === "\0glasshome-noop") return "export {}";
263
293
  },
264
294
  async closeBundle() {
265
- await P({
295
+ await F({
266
296
  srcDir: t,
267
297
  outDir: n,
268
298
  plugins: r
@@ -271,4 +301,4 @@ function I(e) {
271
301
  }];
272
302
  }
273
303
  //#endregion
274
- export { P as buildWidgets, M as discoverWidgets, N as generateRegistry, F as glasshomeWidget, I as glasshomeWidgets, w as isWidgetExternal };
304
+ export { F as buildWidgets, N as discoverWidgets, P as generateRegistry, I as glasshomeWidget, L as glasshomeWidgets, T as isWidgetExternal, y as runSchemaGuard };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-sdk",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "SDK for building GlassHome dashboard widgets with SolidJS",
5
5
  "keywords": [
6
6
  "glasshome",
@@ -32,6 +32,11 @@
32
32
  "types": "./dist/deprecations.d.ts",
33
33
  "import": "./dist/deprecations.js"
34
34
  },
35
+ "./host": {
36
+ "@glasshome/source": "./src/host/index.ts",
37
+ "types": "./dist/host/index.d.ts",
38
+ "import": "./dist/host/index.js"
39
+ },
35
40
  "./vite": {
36
41
  "@glasshome/source": "./src/vite/index.ts",
37
42
  "types": "./dist/vite/index.d.ts",