@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/data.d.ts +1 -1
- package/dist/framework/components/WidgetContent.d.ts +7 -1
- package/dist/framework/components/anatomy.d.ts +78 -0
- package/dist/framework/config/index.d.ts +18 -9
- package/dist/framework/core/Widget.d.ts +14 -1
- package/dist/framework/dialogs/WidgetDialog.d.ts +16 -1
- package/dist/framework/dialogs/index.d.ts +1 -1
- package/dist/framework/gestures/use-widget-gestures.d.ts +12 -1
- package/dist/framework/hooks/index.d.ts +1 -0
- package/dist/framework/hooks/use-confirm.d.ts +13 -0
- package/dist/framework/hooks/use-daylight.d.ts +25 -0
- package/dist/framework/hooks/use-widget-context.d.ts +4 -0
- package/dist/framework/hooks/use-widget-dialog.d.ts +5 -3
- package/dist/framework/hooks/widget-registry.d.ts +19 -0
- package/dist/framework/image-src.d.ts +3 -0
- package/dist/framework/index.d.ts +9 -9
- package/dist/framework/panel/panel-entity.d.ts +18 -0
- package/dist/framework/panel/panel.d.ts +55 -0
- package/dist/host/index.js +42 -24
- package/dist/index.js +1744 -836
- package/dist/ui.d.ts +1 -1
- package/dist/vite/index.d.ts +26 -0
- package/dist/vite/index.js +186 -152
- package/package.json +5 -5
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";
|
package/dist/vite/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/vite/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { deprecations as e, formatDeprecation as t } from "../deprecations.js";
|
|
2
|
-
import { formatSchemaError as n, isHostProvidedModule as r,
|
|
3
|
-
import { createHash as
|
|
4
|
-
import { existsSync as
|
|
5
|
-
import { createRequire as
|
|
6
|
-
import { dirname as
|
|
7
|
-
import { fileURLToPath as
|
|
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
|
|
12
|
-
function
|
|
13
|
-
let t =
|
|
14
|
-
return [
|
|
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
|
|
17
|
-
let t =
|
|
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:
|
|
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
|
|
51
|
+
function ie() {
|
|
52
52
|
return {
|
|
53
|
-
introspect: async (e) =>
|
|
53
|
+
introspect: async (e) => w(e),
|
|
54
54
|
dispose: async () => {},
|
|
55
55
|
childPid: null
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
|
-
function
|
|
59
|
-
if (process.env.GLASSHOME_WIDGET_NO_WORKER === "1") return
|
|
60
|
-
let t = e?.rssLimitBytes ??
|
|
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 =
|
|
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
|
|
190
|
-
function
|
|
191
|
-
if (Array.isArray(e)) return `[${e.map(
|
|
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)}:${
|
|
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
|
|
199
|
-
return
|
|
198
|
+
function oe(e) {
|
|
199
|
+
return o("sha256").update(E(e)).digest("hex").slice(0, 16);
|
|
200
200
|
}
|
|
201
|
-
var
|
|
202
|
-
async function
|
|
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
|
|
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
|
|
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
|
|
244
|
-
let r =
|
|
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
|
|
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 &&
|
|
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 (!
|
|
254
|
-
let t = e.session ? await e.session.introspect(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
|
|
259
|
-
let i = n.jsonSchema;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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 ===
|
|
271
|
-
if (n.hash !==
|
|
272
|
-
} else console.warn(`[widget-sdk] Schema shape record for "${
|
|
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
|
|
275
|
-
hash:
|
|
276
|
-
configVersion:
|
|
277
|
-
hashVersion:
|
|
300
|
+
let m = `${JSON.stringify({
|
|
301
|
+
hash: c,
|
|
302
|
+
configVersion: u,
|
|
303
|
+
hashVersion: T
|
|
278
304
|
})}\n`;
|
|
279
|
-
|
|
305
|
+
m !== f && p(e.hashFile, m);
|
|
280
306
|
}
|
|
281
|
-
var
|
|
282
|
-
function
|
|
283
|
-
return
|
|
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
|
|
286
|
-
let e =
|
|
287
|
-
return
|
|
311
|
+
function F() {
|
|
312
|
+
let e = b(import.meta.url);
|
|
313
|
+
return v(h(e), "../../preview");
|
|
288
314
|
}
|
|
289
|
-
function
|
|
315
|
+
function I(e) {
|
|
290
316
|
return r(e);
|
|
291
317
|
}
|
|
292
|
-
var
|
|
293
|
-
function
|
|
294
|
-
let n =
|
|
295
|
-
return n.includes("/node_modules/") || !
|
|
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
|
|
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 (
|
|
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
|
|
309
|
-
let r =
|
|
310
|
-
if (r.includes("/node_modules/") || !
|
|
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
|
|
340
|
+
function H(e = /* @__PURE__ */ new Set()) {
|
|
315
341
|
let t = /* @__PURE__ */ new Set();
|
|
316
342
|
return {
|
|
317
343
|
scan(e, n) {
|
|
318
|
-
|
|
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
|
|
328
|
-
let r =
|
|
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
|
|
345
|
-
function
|
|
370
|
+
var me = "node_modules/.cache/glasshome-widgets";
|
|
371
|
+
function W(e) {
|
|
346
372
|
try {
|
|
347
|
-
return
|
|
373
|
+
return m(g(process.cwd(), "package.json")).resolve(e);
|
|
348
374
|
} catch {
|
|
349
375
|
return null;
|
|
350
376
|
}
|
|
351
377
|
}
|
|
352
|
-
var
|
|
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
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
|
372
|
-
let
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
let
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
-
...
|
|
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
|
|
394
|
-
return
|
|
395
|
-
`import "${
|
|
396
|
-
`export { default } from "${
|
|
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")),
|
|
432
|
+
].join("\n")), m;
|
|
399
433
|
}
|
|
400
434
|
function Y() {
|
|
401
|
-
let { Features: e } =
|
|
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 (!
|
|
412
|
-
for (let n of
|
|
413
|
-
let r =
|
|
414
|
-
if (!
|
|
415
|
-
let i =
|
|
416
|
-
|
|
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 (
|
|
426
|
-
if (!
|
|
427
|
-
let
|
|
428
|
-
if (!o
|
|
429
|
-
let
|
|
430
|
-
if (!
|
|
431
|
-
let u =
|
|
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
|
-
...
|
|
434
|
-
bundleUrl: `./${
|
|
435
|
-
...u ? { cssUrl: `./${
|
|
467
|
+
...c.data,
|
|
468
|
+
bundleUrl: `./${i}.js`,
|
|
469
|
+
...u ? { cssUrl: `./${i}.css` } : {}
|
|
436
470
|
});
|
|
437
471
|
}
|
|
438
|
-
let
|
|
472
|
+
let i = {
|
|
439
473
|
version: 1,
|
|
440
474
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
441
475
|
baseUrl: "./",
|
|
442
476
|
widgets: r
|
|
443
477
|
};
|
|
444
|
-
|
|
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 =
|
|
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 ||
|
|
457
|
-
let
|
|
458
|
-
for (let
|
|
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
|
-
|
|
465
|
-
|
|
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,
|
|
508
|
+
entry: J(n, s.name, s.entry, r),
|
|
475
509
|
formats: ["es"],
|
|
476
|
-
fileName:
|
|
477
|
-
cssFileName:
|
|
510
|
+
fileName: s.name,
|
|
511
|
+
cssFileName: s.name
|
|
478
512
|
},
|
|
479
|
-
rollupOptions: { external:
|
|
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
|
-
}),
|
|
487
|
-
outFile:
|
|
488
|
-
hashFile: h(
|
|
489
|
-
widgetName:
|
|
490
|
-
manifestPath: h(
|
|
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
|
|
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",
|
|
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:
|
|
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 =
|
|
553
|
+
let e = F(), t = process.cwd();
|
|
520
554
|
return { server: { fs: { allow: [
|
|
521
555
|
e,
|
|
522
556
|
t,
|
|
523
|
-
|
|
557
|
+
v(t, "..", "..")
|
|
524
558
|
] } } };
|
|
525
559
|
},
|
|
526
560
|
configureServer(e) {
|
|
527
|
-
let t =
|
|
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 =
|
|
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 ===
|
|
540
|
-
let e =
|
|
541
|
-
return
|
|
573
|
+
if (e === pe) {
|
|
574
|
+
let e = F();
|
|
575
|
+
return P(g(e, "host.tsx"));
|
|
542
576
|
}
|
|
543
|
-
if (e ===
|
|
577
|
+
if (e === fe) return N;
|
|
544
578
|
},
|
|
545
579
|
load(e) {
|
|
546
|
-
if (e === N) return `export { default } from "${
|
|
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
|
-
|
|
553
|
-
outFile:
|
|
554
|
-
hashFile:
|
|
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:
|
|
590
|
+
manifestPath: v(process.cwd(), "manifest.json")
|
|
557
591
|
});
|
|
558
592
|
}
|
|
559
593
|
};
|
|
560
594
|
return [
|
|
561
595
|
...X(),
|
|
562
596
|
n,
|
|
563
|
-
|
|
564
|
-
|
|
597
|
+
B(),
|
|
598
|
+
U(),
|
|
565
599
|
i,
|
|
566
600
|
r
|
|
567
601
|
];
|
|
568
602
|
}
|
|
569
|
-
function
|
|
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 {
|
|
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 };
|