@glasshome/widget-sdk 1.15.1 → 1.17.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.
- package/dist/data.d.ts +1 -1
- package/dist/deprecations.js +16 -0
- package/dist/framework/backgrounds/WidgetSliderFill.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 +15 -2
- package/dist/framework/dialogs/WidgetDialog.d.ts +16 -1
- package/dist/framework/dialogs/debug-view.d.ts +27 -0
- package/dist/framework/dialogs/index.d.ts +2 -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 +10 -10
- package/dist/framework/panel/panel-entity.d.ts +18 -0
- package/dist/framework/panel/panel.d.ts +55 -0
- package/dist/framework/types.d.ts +1 -1
- package/dist/framework/utils/clipboard.d.ts +9 -0
- package/dist/framework/utils/index.d.ts +1 -0
- package/dist/framework/variants/variant-utils.d.ts +5 -5
- package/dist/host/index.js +42 -24
- package/dist/index.js +2073 -751
- package/dist/ui.d.ts +1 -1
- package/dist/vite/index.d.ts +25 -0
- package/dist/vite/index.js +159 -129
- 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,25 @@ 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
|
+
/**
|
|
71
|
+
* Widgets render inside a closed shadow root in the host, which cuts them off
|
|
72
|
+
* from the host document stylesheet. Every widget bundle must therefore carry
|
|
73
|
+
* its own complete CSS: the ui theme + component styles, the SDK shell
|
|
74
|
+
* classes, and the Tailwind utilities its own JSX uses. This writes a
|
|
75
|
+
* generated css entry (a Tailwind pass over exactly those sources) plus a
|
|
76
|
+
* wrapper module that imports it ahead of the real widget entry, so Vite lib
|
|
77
|
+
* mode emits it as the widget's `<name>.css`.
|
|
78
|
+
*
|
|
79
|
+
* `source(none)` disables Tailwind's automatic project-root scan — without it
|
|
80
|
+
* every widget in a multi-widget repo gets the superset of all widgets'
|
|
81
|
+
* classes. The dark variant is redefined shadow-aware: `.dark *` cannot match
|
|
82
|
+
* across a shadow boundary, so the host mirrors the document's `dark` class
|
|
83
|
+
* onto the shadow host element and `:host(.dark)` picks it up.
|
|
84
|
+
*/
|
|
85
|
+
/** The widget's own folder plus the project's shared folders: Tailwind only
|
|
86
|
+
* emits utilities for files it is pointed at, and a widget's shared component
|
|
87
|
+
* is as much its source as its entry. A sibling widget's folder stays out. */
|
|
88
|
+
export declare function widgetProjectScanDirs(srcDir: string, widgetEntry: string): string[];
|
|
64
89
|
interface DiscoveredWidget {
|
|
65
90
|
name: string;
|
|
66
91
|
entry: string;
|
package/dist/vite/index.js
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
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
|
-
import { spawn as te, spawnSync as
|
|
9
|
+
import { spawn as te, spawnSync as x } from "node:child_process";
|
|
10
10
|
//#region src/vite/introspect-session.ts
|
|
11
|
-
var
|
|
12
|
-
function
|
|
13
|
-
let t =
|
|
14
|
-
return [
|
|
11
|
+
var S = 262144e3, C = 3e4, ne = 3e3;
|
|
12
|
+
function w(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 T(e) {
|
|
17
|
+
let t = w("introspect");
|
|
18
18
|
if (!t) return {
|
|
19
19
|
ok: !1,
|
|
20
20
|
reason: "introspect not found next to the sdk"
|
|
21
21
|
};
|
|
22
|
-
let n =
|
|
22
|
+
let n = x(process.execPath, [
|
|
23
23
|
"--conditions",
|
|
24
24
|
"browser",
|
|
25
25
|
t,
|
|
26
26
|
e
|
|
27
27
|
], {
|
|
28
28
|
encoding: "utf-8",
|
|
29
|
-
timeout:
|
|
29
|
+
timeout: C
|
|
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 re() {
|
|
52
52
|
return {
|
|
53
|
-
introspect: async (e) =>
|
|
53
|
+
introspect: async (e) => T(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 ie(e) {
|
|
59
|
+
if (process.env.GLASSHOME_WIDGET_NO_WORKER === "1") return re();
|
|
60
|
+
let t = e?.rssLimitBytes ?? S, n = e?.timeoutMs ?? C, r = e?.slowMs ?? ne, 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 = w("introspect-worker");
|
|
132
132
|
if (!t) return {
|
|
133
133
|
ok: !1,
|
|
134
134
|
reason: "introspect-worker not found next to the sdk"
|
|
@@ -186,19 +186,19 @@ 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 E = 2;
|
|
190
|
+
function D(e) {
|
|
191
|
+
if (Array.isArray(e)) return `[${e.map(D).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)}:${D(t[e])}`).join(",")}}`;
|
|
195
195
|
}
|
|
196
196
|
return JSON.stringify(e) ?? "null";
|
|
197
197
|
}
|
|
198
|
-
function
|
|
199
|
-
return
|
|
198
|
+
function ae(e) {
|
|
199
|
+
return o("sha256").update(D(e)).digest("hex").slice(0, 16);
|
|
200
200
|
}
|
|
201
|
-
var
|
|
201
|
+
var oe = 20;
|
|
202
202
|
async function O(e, t) {
|
|
203
203
|
if (e === void 0) return;
|
|
204
204
|
let n;
|
|
@@ -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 se = [
|
|
231
231
|
"schema",
|
|
232
232
|
"defaultConfig",
|
|
233
233
|
"examples",
|
|
@@ -240,51 +240,77 @@ var A = [
|
|
|
240
240
|
"minSize",
|
|
241
241
|
"maxSize"
|
|
242
242
|
];
|
|
243
|
-
function
|
|
244
|
-
let r =
|
|
243
|
+
function ce(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 se) 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
251
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
let t =
|
|
252
|
+
var le = /import\s*(\{[^}]*\}|\*\s*as\s+[\w$]+)\s*from\s*["']@glasshome\/widget-sdk["']/g, ue = /import\(\s*["']@glasshome\/widget-sdk["']\s*\)/;
|
|
253
|
+
function A(e) {
|
|
254
|
+
let t = /* @__PURE__ */ new Set();
|
|
255
|
+
ue.test(e) && t.add("*");
|
|
256
|
+
for (let [, n = ""] of e.matchAll(le)) {
|
|
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 j = { useDaylight: "sun.sun" };
|
|
269
|
+
function M(e, t, n) {
|
|
270
|
+
let r = A(e);
|
|
271
|
+
for (let [e, a] of Object.entries(j)) {
|
|
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
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async function N(e) {
|
|
278
|
+
if (!s(e.outFile)) return;
|
|
279
|
+
let t = e.session ? await e.session.introspect(e.outFile) : T(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
283
|
await O(n.manifest?.examples, r), k(n.exampleConfigIssues, r);
|
|
259
|
-
let i = n.jsonSchema;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
284
|
+
let i = n.jsonSchema, a = e.manifestPath && s(e.manifestPath) ? e.manifestPath : null;
|
|
285
|
+
i && a && ce(a, n, i);
|
|
286
|
+
let o = a ? JSON.parse(l(a, "utf-8")).capabilities : n.manifest?.capabilities;
|
|
287
|
+
if (M(l(e.outFile, "utf-8"), o ?? [], r), !i) return;
|
|
288
|
+
let c = ae(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 === E) {
|
|
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 ${E}. 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: E
|
|
278
304
|
})}\n`;
|
|
279
|
-
|
|
305
|
+
m !== f && p(e.hashFile, m);
|
|
280
306
|
}
|
|
281
|
-
var
|
|
307
|
+
var de = "virtual:glasshome-widget", P = "\0virtual:glasshome-widget", fe = "/@glasshome/preview";
|
|
282
308
|
function F(e) {
|
|
283
|
-
return
|
|
309
|
+
return y === "\\" ? e.split(y).join("/") : e;
|
|
284
310
|
}
|
|
285
311
|
function I() {
|
|
286
|
-
let e =
|
|
287
|
-
return
|
|
312
|
+
let e = b(import.meta.url);
|
|
313
|
+
return v(h(e), "../../preview");
|
|
288
314
|
}
|
|
289
315
|
function L(e) {
|
|
290
316
|
return r(e);
|
|
@@ -300,7 +326,7 @@ function V() {
|
|
|
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(
|
|
329
|
+
if (B(t, e)) throw Error(`Widgets must not import "@glasshome/sync-layer" directly (imported by ${F(_(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
|
};
|
|
@@ -315,7 +341,7 @@ function U(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(
|
|
344
|
+
H(e, n) && t.add(F(_(process.cwd(), e.split("?")[0] ?? e)));
|
|
319
345
|
},
|
|
320
346
|
take() {
|
|
321
347
|
let n = [...t].filter((t) => !e.has(t));
|
|
@@ -341,15 +367,15 @@ function W(n) {
|
|
|
341
367
|
}
|
|
342
368
|
};
|
|
343
369
|
}
|
|
344
|
-
var
|
|
345
|
-
function
|
|
370
|
+
var pe = "node_modules/.cache/glasshome-widgets";
|
|
371
|
+
function G(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 me = [
|
|
353
379
|
"--radius",
|
|
354
380
|
"--background",
|
|
355
381
|
"--foreground",
|
|
@@ -359,46 +385,50 @@ var se = [
|
|
|
359
385
|
"--muted",
|
|
360
386
|
"--accent"
|
|
361
387
|
];
|
|
362
|
-
function
|
|
363
|
-
let n =
|
|
364
|
-
if (!
|
|
365
|
-
let r =
|
|
388
|
+
function K(e, t) {
|
|
389
|
+
let n = g(e, `${t}.css`);
|
|
390
|
+
if (!s(n)) return;
|
|
391
|
+
let r = l(n, "utf-8");
|
|
366
392
|
for (let e of r.matchAll(/:host[^{]*\{([^}]*)\}/g)) {
|
|
367
|
-
let n = e[1] ?? "", r =
|
|
393
|
+
let n = e[1] ?? "", r = me.find((e) => n.includes(`${e}:`));
|
|
368
394
|
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
395
|
}
|
|
370
396
|
}
|
|
371
|
-
function
|
|
372
|
-
let
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
let
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
397
|
+
function q(e, t) {
|
|
398
|
+
let n = v(e), r = h(t), i = new Set(Z(n).map((e) => h(e.entry)));
|
|
399
|
+
return [r, ...u(n, { withFileTypes: !0 }).filter((e) => e.isDirectory()).map((e) => g(n, e.name)).filter((e) => !i.has(e))];
|
|
400
|
+
}
|
|
401
|
+
function J(e, t, n, r) {
|
|
402
|
+
let i = v(e, pe);
|
|
403
|
+
c(i, { recursive: !0 });
|
|
404
|
+
let a = G("@glasshome/ui/styles");
|
|
405
|
+
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.");
|
|
406
|
+
let o = v(h(a), "../.."), l = G("@glasshome/widget-sdk/tailwind-sources"), u = l ? h(l) : null, d = [
|
|
407
|
+
g(o, "src"),
|
|
408
|
+
g(o, "dist"),
|
|
409
|
+
...u ? [g(u, "src"), g(u, "dist")] : [],
|
|
410
|
+
...q(r, n)
|
|
411
|
+
].filter((e) => s(e)), f = v(i, `${t}.tailwind.css`);
|
|
412
|
+
p(f, [
|
|
383
413
|
"@import \"tailwindcss\" source(none);",
|
|
384
414
|
"@import \"tw-animate-css\";",
|
|
385
415
|
"@import \"@glasshome/ui/styles/theme\";",
|
|
386
|
-
...
|
|
416
|
+
...d.map((e) => `@source "${F(e)}";`),
|
|
387
417
|
"@custom-variant dark {",
|
|
388
418
|
" &:is(.dark *) { @slot }",
|
|
389
419
|
" :host(.dark) & { @slot }",
|
|
390
420
|
"}",
|
|
391
421
|
""
|
|
392
422
|
].join("\n"));
|
|
393
|
-
let
|
|
394
|
-
return
|
|
395
|
-
`import "${F(
|
|
423
|
+
let m = v(i, `${t}.entry.ts`);
|
|
424
|
+
return p(m, [
|
|
425
|
+
`import "${F(f)}";`,
|
|
396
426
|
`export { default } from "${F(n)}";`,
|
|
397
427
|
""
|
|
398
|
-
].join("\n")),
|
|
428
|
+
].join("\n")), m;
|
|
399
429
|
}
|
|
400
430
|
function Y() {
|
|
401
|
-
let { Features: e } =
|
|
431
|
+
let { Features: e } = m(import.meta.url)("lightningcss");
|
|
402
432
|
return { lightningcss: { include: e.HexAlphaColors } };
|
|
403
433
|
}
|
|
404
434
|
function X() {
|
|
@@ -408,12 +438,12 @@ function X() {
|
|
|
408
438
|
}
|
|
409
439
|
function Z(e) {
|
|
410
440
|
let t = [];
|
|
411
|
-
if (!
|
|
412
|
-
for (let n of
|
|
413
|
-
let r =
|
|
414
|
-
if (!
|
|
415
|
-
let i =
|
|
416
|
-
|
|
441
|
+
if (!s(e)) return t;
|
|
442
|
+
for (let n of u(e)) {
|
|
443
|
+
let r = v(e, n);
|
|
444
|
+
if (!f(r).isDirectory()) continue;
|
|
445
|
+
let i = v(r, "index.tsx"), a = v(r, "manifest.json");
|
|
446
|
+
s(i) && s(a) && t.push({
|
|
417
447
|
name: n,
|
|
418
448
|
entry: i
|
|
419
449
|
});
|
|
@@ -422,29 +452,29 @@ function Z(e) {
|
|
|
422
452
|
}
|
|
423
453
|
function Q(e, t) {
|
|
424
454
|
let r = [];
|
|
425
|
-
if (
|
|
426
|
-
if (!
|
|
427
|
-
let
|
|
428
|
-
if (!o
|
|
429
|
-
let
|
|
430
|
-
if (!
|
|
431
|
-
let u =
|
|
455
|
+
if (s(e)) for (let i of u(e)) {
|
|
456
|
+
if (!f(g(e, i)).isDirectory()) continue;
|
|
457
|
+
let o = g(e, i, "manifest.json");
|
|
458
|
+
if (!s(o)) continue;
|
|
459
|
+
let c = a.safeParse(JSON.parse(l(o, "utf-8")));
|
|
460
|
+
if (!c.success) throw Error(`[registry] Invalid manifest for "${i}": ${n(c.error)}`);
|
|
461
|
+
let u = s(g(t, `${i}.css`));
|
|
432
462
|
r.push({
|
|
433
|
-
...
|
|
434
|
-
bundleUrl: `./${
|
|
435
|
-
...u ? { cssUrl: `./${
|
|
463
|
+
...c.data,
|
|
464
|
+
bundleUrl: `./${i}.js`,
|
|
465
|
+
...u ? { cssUrl: `./${i}.css` } : {}
|
|
436
466
|
});
|
|
437
467
|
}
|
|
438
|
-
let
|
|
468
|
+
let i = {
|
|
439
469
|
version: 1,
|
|
440
470
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
441
471
|
baseUrl: "./",
|
|
442
472
|
widgets: r
|
|
443
473
|
};
|
|
444
|
-
|
|
474
|
+
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
475
|
}
|
|
446
476
|
async function $(e) {
|
|
447
|
-
let { build: t } = await import("vite"), n = process.cwd(), r =
|
|
477
|
+
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
478
|
if (a.length === 0) {
|
|
449
479
|
console.warn("[glasshome-widgets] No widgets found in", r);
|
|
450
480
|
return;
|
|
@@ -453,16 +483,16 @@ async function $(e) {
|
|
|
453
483
|
let t = new Set(e.only);
|
|
454
484
|
a = a.filter((e) => t.has(e.name));
|
|
455
485
|
}
|
|
456
|
-
e?.only ||
|
|
457
|
-
let
|
|
458
|
-
for (let
|
|
486
|
+
e?.only || s(i) && d(i, { recursive: !0 }), s(i) || c(i, { recursive: !0 });
|
|
487
|
+
let o = /* @__PURE__ */ new Set();
|
|
488
|
+
for (let s of a) await t({
|
|
459
489
|
configFile: !1,
|
|
460
490
|
root: n,
|
|
461
491
|
plugins: [
|
|
462
492
|
...X(),
|
|
463
493
|
...e?.plugins ?? [],
|
|
464
494
|
V(),
|
|
465
|
-
W(
|
|
495
|
+
W(o)
|
|
466
496
|
],
|
|
467
497
|
...e?.viteConfig,
|
|
468
498
|
css: {
|
|
@@ -471,10 +501,10 @@ async function $(e) {
|
|
|
471
501
|
},
|
|
472
502
|
build: {
|
|
473
503
|
lib: {
|
|
474
|
-
entry: J(n,
|
|
504
|
+
entry: J(n, s.name, s.entry, r),
|
|
475
505
|
formats: ["es"],
|
|
476
|
-
fileName:
|
|
477
|
-
cssFileName:
|
|
506
|
+
fileName: s.name,
|
|
507
|
+
cssFileName: s.name
|
|
478
508
|
},
|
|
479
509
|
rollupOptions: { external: L },
|
|
480
510
|
outDir: i,
|
|
@@ -483,16 +513,16 @@ async function $(e) {
|
|
|
483
513
|
...e?.viteConfig?.build
|
|
484
514
|
},
|
|
485
515
|
logLevel: "warn"
|
|
486
|
-
}),
|
|
487
|
-
outFile:
|
|
488
|
-
hashFile: h(
|
|
489
|
-
widgetName:
|
|
490
|
-
manifestPath: h(
|
|
516
|
+
}), K(i, s.name), await N({
|
|
517
|
+
outFile: g(i, `${s.name}.js`),
|
|
518
|
+
hashFile: g(h(s.entry), ".schema-hash"),
|
|
519
|
+
widgetName: s.name,
|
|
520
|
+
manifestPath: g(h(s.entry), "manifest.json"),
|
|
491
521
|
session: e?.session
|
|
492
522
|
});
|
|
493
523
|
Q(r, i);
|
|
494
524
|
}
|
|
495
|
-
function
|
|
525
|
+
function he(e) {
|
|
496
526
|
let t = e?.entry ?? "src/index.tsx", n = {
|
|
497
527
|
name: "glasshome-widget:build",
|
|
498
528
|
apply: "build",
|
|
@@ -502,7 +532,7 @@ function ce(e) {
|
|
|
502
532
|
css: Y(),
|
|
503
533
|
build: {
|
|
504
534
|
lib: {
|
|
505
|
-
entry: J(e, "index",
|
|
535
|
+
entry: J(e, "index", v(e, t), h(v(e, t))),
|
|
506
536
|
formats: ["es"],
|
|
507
537
|
fileName: "index",
|
|
508
538
|
cssFileName: "index"
|
|
@@ -520,14 +550,14 @@ function ce(e) {
|
|
|
520
550
|
return { server: { fs: { allow: [
|
|
521
551
|
e,
|
|
522
552
|
t,
|
|
523
|
-
|
|
553
|
+
v(t, "..", "..")
|
|
524
554
|
] } } };
|
|
525
555
|
},
|
|
526
556
|
configureServer(e) {
|
|
527
|
-
let t = I(), n =
|
|
557
|
+
let t = I(), n = g(t, "preview.html");
|
|
528
558
|
e.middlewares.use(async (t, r, i) => {
|
|
529
559
|
if (t.url === "/" || t.url === "/index.html") try {
|
|
530
|
-
let i =
|
|
560
|
+
let i = l(n, "utf-8");
|
|
531
561
|
i = await e.transformIndexHtml(t.url, i), r.setHeader("Content-Type", "text/html"), r.statusCode = 200, r.end(i);
|
|
532
562
|
} catch (e) {
|
|
533
563
|
i(e);
|
|
@@ -536,24 +566,24 @@ function ce(e) {
|
|
|
536
566
|
});
|
|
537
567
|
},
|
|
538
568
|
resolveId(e) {
|
|
539
|
-
if (e ===
|
|
569
|
+
if (e === fe) {
|
|
540
570
|
let e = I();
|
|
541
|
-
return F(
|
|
571
|
+
return F(g(e, "host.tsx"));
|
|
542
572
|
}
|
|
543
|
-
if (e ===
|
|
573
|
+
if (e === de) return P;
|
|
544
574
|
},
|
|
545
575
|
load(e) {
|
|
546
|
-
if (e ===
|
|
576
|
+
if (e === P) return `export { default } from "${F(v(process.cwd(), t))}";`;
|
|
547
577
|
}
|
|
548
578
|
}, i = {
|
|
549
579
|
name: "glasshome-widget:schema",
|
|
550
580
|
apply: "build",
|
|
551
581
|
async closeBundle() {
|
|
552
|
-
|
|
553
|
-
outFile:
|
|
554
|
-
hashFile:
|
|
582
|
+
K(v(process.cwd(), "dist"), "index"), await N({
|
|
583
|
+
outFile: v(process.cwd(), "dist", "index.js"),
|
|
584
|
+
hashFile: v(process.cwd(), ".schema-hash"),
|
|
555
585
|
widgetName: "index",
|
|
556
|
-
manifestPath:
|
|
586
|
+
manifestPath: v(process.cwd(), "manifest.json")
|
|
557
587
|
});
|
|
558
588
|
}
|
|
559
589
|
};
|
|
@@ -566,7 +596,7 @@ function ce(e) {
|
|
|
566
596
|
r
|
|
567
597
|
];
|
|
568
598
|
}
|
|
569
|
-
function
|
|
599
|
+
function ge(e) {
|
|
570
600
|
let t = e?.srcDir ?? "src", n = e?.outDir ?? "dist", r = [];
|
|
571
601
|
return [{
|
|
572
602
|
name: "glasshome-widgets:build",
|
|
@@ -594,4 +624,4 @@ function le(e) {
|
|
|
594
624
|
}];
|
|
595
625
|
}
|
|
596
626
|
//#endregion
|
|
597
|
-
export {
|
|
627
|
+
export { j as HOOK_READS, oe as MAX_EXAMPLES, M as assertHookReadsDeclared, $ as buildWidgets, ie as createIntrospectSession, U as createUiImportTracker, Z as discoverWidgets, Q as generateRegistry, he as glasshomeWidget, ge as glasshomeWidgets, T as introspectOnce, B as isDirectSyncLayerImportSource, H as isDirectUiImportSource, L as isWidgetExternal, N as runSchemaGuard, A as sdkImportsOf, q as widgetProjectScanDirs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glasshome/widget-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "SDK for building GlassHome dashboard widgets with SolidJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"glasshome",
|
|
@@ -59,12 +59,12 @@
|
|
|
59
59
|
"typecheck:test": "tsc --noEmit -p tsconfig.test.json"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@glasshome/sync-layer": "0.
|
|
63
|
-
"@glasshome/ui": "1.
|
|
62
|
+
"@glasshome/sync-layer": "0.9.0",
|
|
63
|
+
"@glasshome/ui": "1.20.0",
|
|
64
64
|
"solid-js": "^1.9.11"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@glasshome/widget-contract": "0.
|
|
67
|
+
"@glasshome/widget-contract": "0.3.0",
|
|
68
68
|
"@modular-forms/solid": "^0.25.1",
|
|
69
69
|
"@tailwindcss/vite": "^4.1.13",
|
|
70
70
|
"clsx": "^2.1.1",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"zod": "^4.1.13"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
|
-
"@glasshome/ui": "1.
|
|
78
|
+
"@glasshome/ui": "1.20.0",
|
|
79
79
|
"@solidjs/testing-library": "^0.8.10",
|
|
80
80
|
"@types/bun": "^1.4.0",
|
|
81
81
|
"@types/node": "^25.2.2",
|