@glasshome/widget-sdk 1.9.0 → 1.9.2

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.
@@ -25,6 +25,12 @@ export declare function runSchemaGuard(args: {
25
25
  * must be bundled, because leaving it external is a runtime 404.
26
26
  */
27
27
  export declare function isWidgetExternal(id: string): boolean;
28
+ /**
29
+ * True when a widget source file imports `@glasshome/sync-layer` directly.
30
+ * Same file filters as `isDirectUiImportSource`: node_modules is the SDK's own
31
+ * business, and non-script assets are not scanned.
32
+ */
33
+ export declare function isDirectSyncLayerImportSource(id: string, code: string): boolean;
28
34
  /**
29
35
  * True when a widget source file imports `@glasshome/ui` directly. The regex is
30
36
  * the registry's `sourcePattern` for `direct-ui-import`, so the build warning and
@@ -33,6 +39,22 @@ export declare function isWidgetExternal(id: string): boolean;
33
39
  * BUILD_CACHE_DIR (the theme `@import`) are the SDK's business, not the widget's.
34
40
  */
35
41
  export declare function isDirectUiImportSource(id: string, code: string): boolean;
42
+ /**
43
+ * Warns (never fails) when widget source imports @glasshome/ui directly.
44
+ * Warn-only counterpart to syncLayerImportGuard: direct imports keep working
45
+ * until 2.0, but they bypass the sdkVersion gate, so ui can drift against
46
+ * published widgets with nothing checking compatibility. Detection scans
47
+ * module source in `transform` because externalized specifiers never reach
48
+ * `resolveId` (rollup consults `external` for the bare id first).
49
+ *
50
+ * `warned` carries the files already reported across every build in one run, so
51
+ * a module shared by N widgets is named once and not once per bundle it lands in.
52
+ */
53
+ export declare function createUiImportTracker(warned?: Set<string>): {
54
+ scan(id: string, code: string): void;
55
+ /** Offending files this run has not reported yet; marks them reported. */
56
+ take(): string[];
57
+ };
36
58
  interface DiscoveredWidget {
37
59
  name: string;
38
60
  entry: string;
@@ -129,48 +129,67 @@ function P() {
129
129
  function F(e) {
130
130
  return r(e);
131
131
  }
132
- function I() {
132
+ var I = /\.(ts|tsx|js|jsx)$/, L = /from\s+["']@glasshome\/sync-layer(\/[^"']*)?["']/;
133
+ function R(e, t) {
134
+ let n = N(e).split("?")[0] ?? "";
135
+ return n.includes("/node_modules/") || !I.test(n) ? !1 : L.test(t);
136
+ }
137
+ function z() {
133
138
  return {
134
139
  name: "glasshome-widget:sync-layer-guard",
135
140
  apply: "build",
136
141
  enforce: "pre",
137
- resolveId(e, t) {
138
- if (e === "@glasshome/sync-layer" || e.startsWith("@glasshome/sync-layer/")) throw Error(`Widgets must not import "${e}" directly` + (t ? ` (imported by ${t})` : "") + ". Import the equivalent hook from \"@glasshome/widget-sdk\" instead (e.g. useEntity, useEntities, useService).");
142
+ transform(e, t) {
143
+ if (R(t, e)) throw Error(`Widgets must not import "@glasshome/sync-layer" directly (imported by ${N(_(process.cwd(), t.split("?")[0] ?? t))}). Import the equivalent hook from "@glasshome/widget-sdk" instead (e.g. useEntity, useEntities, useService).`);
144
+ return null;
139
145
  }
140
146
  };
141
147
  }
142
- var L = /\.(ts|tsx|js|jsx)$/;
143
- function R(t, n) {
148
+ function B(t, n) {
144
149
  let r = N(t).split("?")[0] ?? "";
145
- if (r.includes("/node_modules/") || !L.test(r)) return !1;
150
+ if (r.includes("/node_modules/") || !I.test(r)) return !1;
146
151
  let i = e.find((e) => e.id === "direct-ui-import");
147
152
  return i?.sourcePattern ? new RegExp(i.sourcePattern).test(n) : !1;
148
153
  }
149
- function z() {
150
- let n = /* @__PURE__ */ new Set();
154
+ function V(e = /* @__PURE__ */ new Set()) {
155
+ let t = /* @__PURE__ */ new Set();
156
+ return {
157
+ scan(e, n) {
158
+ B(e, n) && t.add(N(_(process.cwd(), e.split("?")[0] ?? e)));
159
+ },
160
+ take() {
161
+ let n = [...t].filter((t) => !e.has(t));
162
+ for (let t of n) e.add(t);
163
+ return n;
164
+ }
165
+ };
166
+ }
167
+ function H(n) {
168
+ let r = V(n);
151
169
  return {
152
170
  name: "glasshome-widget:ui-import-guard",
153
171
  apply: "build",
154
172
  enforce: "pre",
155
173
  transform(e, t) {
156
- return R(t, e) && n.add(N(_(process.cwd(), t.split("?")[0] ?? t))), null;
174
+ return r.scan(t, e), null;
157
175
  },
158
176
  buildEnd() {
159
- if (n.size === 0) return;
160
- let r = e.find((e) => e.id === "direct-ui-import"), i = r ? t(r) : "[@glasshome/widget-sdk] Direct @glasshome/ui imports are deprecated; import the same export from \"@glasshome/widget-sdk\".", a = [...n].map((e) => ` ${e}`).join("\n");
161
- console.warn(`${i}\n Direct @glasshome/ui import(s) in:\n${a}`);
177
+ let n = r.take();
178
+ if (n.length === 0) return;
179
+ let i = e.find((e) => e.id === "direct-ui-import"), a = i ? t(i) : "[@glasshome/widget-sdk] Direct @glasshome/ui imports are deprecated; import the same export from \"@glasshome/widget-sdk\".", o = n.map((e) => ` ${e}`).join("\n");
180
+ console.warn(`${a}\n Direct @glasshome/ui import(s) in:\n${o}`);
162
181
  }
163
182
  };
164
183
  }
165
- var B = "node_modules/.cache/glasshome-widgets";
166
- function V(e) {
184
+ var U = "node_modules/.cache/glasshome-widgets";
185
+ function W(e) {
167
186
  try {
168
187
  return m(g(process.cwd(), "package.json")).resolve(e);
169
188
  } catch {
170
189
  return null;
171
190
  }
172
191
  }
173
- var H = [
192
+ var G = [
174
193
  "--radius",
175
194
  "--background",
176
195
  "--foreground",
@@ -180,21 +199,21 @@ var H = [
180
199
  "--muted",
181
200
  "--accent"
182
201
  ];
183
- function U(e, t) {
202
+ function K(e, t) {
184
203
  let n = g(e, `${t}.css`);
185
204
  if (!s(n)) return;
186
205
  let r = l(n, "utf-8");
187
206
  for (let e of r.matchAll(/:host[^{]*\{([^}]*)\}/g)) {
188
- let n = e[1] ?? "", r = H.find((e) => n.includes(`${e}:`));
207
+ let n = e[1] ?? "", r = G.find((e) => n.includes(`${e}:`));
189
208
  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.`);
190
209
  }
191
210
  }
192
- function W(e, t, n) {
193
- let r = v(e, B);
211
+ function q(e, t, n) {
212
+ let r = v(e, U);
194
213
  c(r, { recursive: !0 });
195
- let i = V("@glasshome/ui/styles");
214
+ let i = W("@glasshome/ui/styles");
196
215
  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.");
197
- let a = v(h(i), "../.."), o = V("@glasshome/widget-sdk/tailwind-sources"), l = o ? h(o) : null, u = [
216
+ let a = v(h(i), "../.."), o = W("@glasshome/widget-sdk/tailwind-sources"), l = o ? h(o) : null, u = [
198
217
  g(a, "src"),
199
218
  g(a, "dist"),
200
219
  ...l ? [g(l, "src"), g(l, "dist")] : [],
@@ -218,12 +237,12 @@ function W(e, t, n) {
218
237
  ""
219
238
  ].join("\n")), f;
220
239
  }
221
- function G() {
240
+ function J() {
222
241
  let e = x();
223
242
  for (let t of e) t.apply ??= "build";
224
243
  return e;
225
244
  }
226
- function K(e) {
245
+ function Y(e) {
227
246
  let t = [];
228
247
  if (!s(e)) return t;
229
248
  for (let n of u(e)) {
@@ -237,7 +256,7 @@ function K(e) {
237
256
  }
238
257
  return t;
239
258
  }
240
- function q(e, t) {
259
+ function X(e, t) {
241
260
  let r = [];
242
261
  if (s(e)) for (let a of u(e)) {
243
262
  if (!f(g(e, a)).isDirectory()) continue;
@@ -260,8 +279,8 @@ function q(e, t) {
260
279
  };
261
280
  s(t) || c(t, { recursive: !0 }), p(g(t, "registry.json"), JSON.stringify(a, null, 2)), console.log(`[registry] Generated registry.json with ${r.length} widget(s)`);
262
281
  }
263
- async function J(e) {
264
- let { build: t } = await import("vite"), n = process.cwd(), r = v(n, e?.srcDir ?? "src"), i = v(n, e?.outDir ?? "dist"), a = K(r);
282
+ async function Z(e) {
283
+ let { build: t } = await import("vite"), n = process.cwd(), r = v(n, e?.srcDir ?? "src"), i = v(n, e?.outDir ?? "dist"), a = Y(r);
265
284
  if (a.length === 0) {
266
285
  console.warn("[glasshome-widgets] No widgets found in", r);
267
286
  return;
@@ -271,19 +290,20 @@ async function J(e) {
271
290
  a = a.filter((e) => t.has(e.name));
272
291
  }
273
292
  e?.only || s(i) && d(i, { recursive: !0 }), s(i) || c(i, { recursive: !0 });
293
+ let o = /* @__PURE__ */ new Set();
274
294
  for (let r of a) await t({
275
295
  configFile: !1,
276
296
  root: n,
277
297
  plugins: [
278
- ...G(),
298
+ ...J(),
279
299
  ...e?.plugins ?? [],
280
- I(),
281
- z()
300
+ z(),
301
+ H(o)
282
302
  ],
283
303
  ...e?.viteConfig,
284
304
  build: {
285
305
  lib: {
286
- entry: W(n, r.name, r.entry),
306
+ entry: q(n, r.name, r.entry),
287
307
  formats: ["es"],
288
308
  fileName: r.name,
289
309
  cssFileName: r.name
@@ -295,15 +315,15 @@ async function J(e) {
295
315
  ...e?.viteConfig?.build
296
316
  },
297
317
  logLevel: "warn"
298
- }), U(i, r.name), await k({
318
+ }), K(i, r.name), await k({
299
319
  outFile: g(i, `${r.name}.js`),
300
320
  hashFile: g(h(r.entry), ".schema-hash"),
301
321
  widgetName: r.name,
302
322
  manifestPath: g(h(r.entry), "manifest.json")
303
323
  });
304
- q(r, i);
324
+ X(r, i);
305
325
  }
306
- function Y(e) {
326
+ function Q(e) {
307
327
  let t = e?.entry ?? "src/index.tsx", n = {
308
328
  name: "glasshome-widget:build",
309
329
  apply: "build",
@@ -311,7 +331,7 @@ function Y(e) {
311
331
  let e = process.cwd();
312
332
  return { build: {
313
333
  lib: {
314
- entry: W(e, "index", v(e, t)),
334
+ entry: q(e, "index", v(e, t)),
315
335
  formats: ["es"],
316
336
  fileName: "index",
317
337
  cssFileName: "index"
@@ -357,7 +377,7 @@ function Y(e) {
357
377
  name: "glasshome-widget:schema",
358
378
  apply: "build",
359
379
  async closeBundle() {
360
- U(v(process.cwd(), "dist"), "index"), await k({
380
+ K(v(process.cwd(), "dist"), "index"), await k({
361
381
  outFile: v(process.cwd(), "dist", "index.js"),
362
382
  hashFile: v(process.cwd(), ".schema-hash"),
363
383
  widgetName: "index",
@@ -366,15 +386,15 @@ function Y(e) {
366
386
  }
367
387
  };
368
388
  return [
369
- ...G(),
389
+ ...J(),
370
390
  n,
371
- I(),
372
391
  z(),
392
+ H(),
373
393
  i,
374
394
  r
375
395
  ];
376
396
  }
377
- function X(e) {
397
+ function $(e) {
378
398
  let t = e?.srcDir ?? "src", n = e?.outDir ?? "dist", r = [];
379
399
  return [{
380
400
  name: "glasshome-widgets:build",
@@ -393,7 +413,7 @@ function X(e) {
393
413
  if (e === "\0glasshome-noop") return "export {}";
394
414
  },
395
415
  async closeBundle() {
396
- await J({
416
+ await Z({
397
417
  srcDir: t,
398
418
  outDir: n,
399
419
  plugins: r
@@ -402,4 +422,4 @@ function X(e) {
402
422
  }];
403
423
  }
404
424
  //#endregion
405
- export { C as MAX_EXAMPLES, J as buildWidgets, K as discoverWidgets, q as generateRegistry, Y as glasshomeWidget, X as glasshomeWidgets, R as isDirectUiImportSource, F as isWidgetExternal, k as runSchemaGuard };
425
+ export { C as MAX_EXAMPLES, Z as buildWidgets, V as createUiImportTracker, Y as discoverWidgets, X as generateRegistry, Q as glasshomeWidget, $ as glasshomeWidgets, R as isDirectSyncLayerImportSource, B as isDirectUiImportSource, F as isWidgetExternal, k as runSchemaGuard };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glasshome/widget-sdk",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "SDK for building GlassHome dashboard widgets with SolidJS",
5
5
  "keywords": [
6
6
  "glasshome",
@@ -51,16 +51,21 @@
51
51
  "tailwind-sources.css"
52
52
  ],
53
53
  "scripts": {
54
- "build": "vite build && tsc",
54
+ "build": "vite build && tsc && bun scripts/check-host-singleton.ts",
55
55
  "dev": "vite build --watch",
56
56
  "test": "bun test",
57
57
  "typecheck:test": "tsc --noEmit -p tsconfig.test.json"
58
58
  },
59
59
  "peerDependencies": {
60
- "@glasshome/sync-layer": "0.5.0",
60
+ "@glasshome/sync-layer": "0.6.0",
61
61
  "@glasshome/ui": "1.3.0",
62
62
  "solid-js": "^1.9.11"
63
63
  },
64
+ "peerDependenciesMeta": {
65
+ "@glasshome/ui": {
66
+ "optional": true
67
+ }
68
+ },
64
69
  "dependencies": {
65
70
  "@glasshome/widget-contract": "0.2.0",
66
71
  "@modular-forms/solid": "^0.25.1",
@@ -72,6 +77,7 @@
72
77
  "zod": "^4.1.13"
73
78
  },
74
79
  "devDependencies": {
80
+ "@glasshome/ui": "1.3.0",
75
81
  "@types/bun": "latest",
76
82
  "@types/node": "^25.2.2",
77
83
  "typescript": "^5",
@@ -1,33 +0,0 @@
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/* Shell material. Two channels, both host/variant-driven:\n * - `--widget-backdrop`: the live backdrop filter (the shared glass recipe is\n * blur + saturate, matching ui's CARD_BLUR). Default none — a variant opts\n * in (classic-glass), and a performant-blur host disables it via override\n * sheet when it paints a precomputed frost instead.\n * - `--glass-frost`: one full background layer (image + position / size +\n * repeat) composited at the BOTTOM, under the accent gradient — the same\n * frost slot ui's `.glass` formula ends its background list with. Unset →\n * none. A performant-blur host sets it per shell with the viewport-aligned\n * slice of its pre-blurred bitmap. */\n.glasshome-widget {\n background:\n 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 var(--glass-frost, none);\n backdrop-filter: var(--widget-backdrop, none);\n -webkit-backdrop-filter: var(--widget-backdrop, none);\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 };