mesurer-solid 0.1.9-beta.0 → 0.1.9-beta.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.
package/README.md CHANGED
@@ -41,6 +41,8 @@ For Vite, put this in the existing browser entry such as `src/main.tsx`, `src/ma
41
41
 
42
42
  `src/dev/mesurer.ts` is an optional organization pattern, not a required filename or directory. Do not mount Mesurer from `vite.config.ts`, server/API code, Node-only scripts, an Electron main process, or a module that also executes during SSR.
43
43
 
44
+ The returned handle owns the mount. Await `mesurer.ready` when startup completion, initial rendered stability, or direct host access matters, call `mesurer.dispose()` for explicit cleanup, or pass `signal` when an existing lifecycle should own disposal.
45
+
44
46
  Full placement examples: [Getting started](https://github.com/jhomra21/mesurer-solid/blob/main/docs/GETTING_STARTED.md).
45
47
 
46
48
  ## First-party plugins
@@ -62,11 +64,13 @@ const mesurer = mountMesurer({
62
64
  })
63
65
  ```
64
66
 
65
- The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, Settings, plugin hosting, direct text editing, and the low-level inspection API. Native Color Picker is available only when the host exposes an operational `EyeDropper`.
67
+ The base inspector includes Select, X-ray, Rulers, Typography, Guides, Distance, Settings, plugin hosting, direct text editing, and the low-level inspection API. Native Color Picker is available only when the host exposes an operational `EyeDropper`. A successful native sample is copied to the clipboard using `colorPickerClickFormat`.
68
+
69
+ `mesurer-solid/plugins` also exports the built-in factories for lower-level composition. Normal mounts already include the built-ins. Use `excludeBuiltins` with names such as `"xray"`, `"typography"`, and `"colorPicker"` when a mount should omit one.
66
70
 
67
- For explicit plugin composition, `mesurer-solid/plugins` also exports `select`, `xray`, `colorPicker`, `rulers`, `typography`, `guides`, `distance`, `settings`, `defaults`, and `compose`.
71
+ Resolve plugin-owned capabilities with `await mesurer.service<T>(serviceId)`. The helper waits for configured plugins to finish loading and keeps normal consumers on the mounted interface instead of requiring `pluginHost.service.get(...)`. Falsy registered values are returned unchanged.
68
72
 
69
- Resolve plugin-owned capabilities with `await mesurer.service<T>(serviceId)`. The helper waits for configured plugins to finish loading and keeps normal consumers on the mounted API instead of requiring `pluginHost.service.get(...)`.
73
+ Advanced integrations may supply their own `pluginHost`. That host remains caller-owned; disposing or aborting the Mesurer mount does not dispose it. Use `onPluginHost` only when code needs the host before startup settles.
70
74
 
71
75
  | Entry | Purpose |
72
76
  | --- | --- |
@@ -83,7 +87,7 @@ Programmatic injection reuses an existing connected instance by default. Lifecyc
83
87
 
84
88
  ## Features
85
89
 
86
- - Select one or many rendered HTML or SVG elements and inspect exact geometry.
90
+ - Select one or many rendered HTML or SVG elements and inspect exact geometry. Turning Select off clears the current element and Guide selection.
87
91
  - Measure distance and pairwise multi-selection spacing.
88
92
  - Use X-ray, guides, rulers, and persisted settings.
89
93
  - Add page-scoped columns, rows, or pixel grids with the optional `layoutGuides()` plugin. Guide edits participate in plugin undo/redo, and Context includes the current page's saved guides with their visibility state.
package/dist/agent.d.ts CHANGED
@@ -110,13 +110,13 @@ export type AgentViewportSnapshot = {
110
110
  export type AgentFeedbackSnapshot = {
111
111
  viewport: AgentViewportSnapshot;
112
112
  elements: AgentElementInspection[];
113
- plugins: MesurerPluginDescription | undefined;
113
+ plugins: MesurerPluginDescription;
114
114
  pluginState: PluginStateSnapshot;
115
115
  };
116
116
  type AgentCommandArgs = Parameters<MesurerPluginHost["command"]["execute"]>[1];
117
117
  export type MesurerAgentHarness = {
118
118
  ready(): Promise<void>;
119
- describe(): Promise<MesurerPluginDescription | undefined>;
119
+ describe(): Promise<MesurerPluginDescription>;
120
120
  inspect(selector: string, index?: number): AgentElementInspection | null;
121
121
  inspectAll(selector: string, limit?: number): AgentElementInspection[];
122
122
  at(x: number, y: number): AgentElementInspection | null;
@@ -11,7 +11,7 @@ export type MesurerContextService = {
11
11
  context(request?: MesurerContextRequest): Promise<MesurerContextV1>;
12
12
  contextText(request?: MesurerContextRequest): Promise<string>;
13
13
  copyContext(request?: MesurerContextRequest): Promise<void>;
14
- select(selectors: string | string[]): Promise<MesurerContextV1>;
14
+ select(selectors: string | readonly string[]): Promise<MesurerContextV1>;
15
15
  annotations(): Promise<MesurerAnnotation[]>;
16
16
  /** Remove one saved annotation after a trusted workflow has completed it. */
17
17
  removeAnnotation(annotationId: string): Promise<void>;
package/dist/core.d.ts CHANGED
@@ -120,8 +120,8 @@ export type MesurerPluginContext = {
120
120
  export type MesurerPlugin = {
121
121
  id: PluginId;
122
122
  version?: string;
123
- requires?: string[];
124
- provides?: string[];
123
+ requires?: readonly string[];
124
+ provides?: readonly string[];
125
125
  setup(context: MesurerPluginContext): void | Promise<void>;
126
126
  };
127
127
  export type MesurerPluginDescription = {
@@ -190,6 +190,7 @@ export type MesurerPluginHost = {
190
190
  };
191
191
  export declare const defineMesurerPlugin: <T extends MesurerPlugin>(plugin: T) => T;
192
192
  export declare function createMesurerPluginHost(): MesurerPluginHost;
193
- export declare function createMesurerRuntime(options?: {
194
- plugins?: MesurerPlugin[];
195
- }): Promise<MesurerPluginHost>;
193
+ export type MesurerRuntimeOptions = {
194
+ plugins?: readonly MesurerPlugin[];
195
+ };
196
+ export declare function createMesurerRuntime(options?: MesurerRuntimeOptions): Promise<MesurerPluginHost>;
package/dist/core.js CHANGED
@@ -226,8 +226,8 @@ function i() {
226
226
  plugins: [...a.values()].map(({ plugin: e }) => ({
227
227
  id: e.id,
228
228
  version: e.version,
229
- requires: e.requires ?? [],
230
- provides: e.provides ?? []
229
+ requires: [...e.requires ?? []],
230
+ provides: [...e.provides ?? []]
231
231
  })),
232
232
  tools: z.tools().map(({ active: e, disabled: t, hidden: n, icon: r, menu: i, ...a }) => a),
233
233
  settings: z.settings().map(({ controls: e = [], ...t }) => ({
@@ -261,15 +261,24 @@ function i() {
261
261
  return z;
262
262
  }
263
263
  //#endregion
264
+ //#region ../mesurer-core/dist/runtime.js
265
+ async function a(e = {}) {
266
+ let t = i();
267
+ try {
268
+ for (let n of e.plugins ?? []) await t.load(n);
269
+ return t;
270
+ } catch (e) {
271
+ throw t.dispose(), e;
272
+ }
273
+ }
274
+ //#endregion
264
275
  //#region src/core.ts
265
- var a = (e) => e;
266
- function o() {
276
+ var o = (e) => e;
277
+ function s() {
267
278
  return i();
268
279
  }
269
- async function s(e = {}) {
270
- let t = o();
271
- for (let n of e.plugins ?? []) await t.load(n);
272
- return t;
280
+ async function c(e = {}) {
281
+ return a(e);
273
282
  }
274
283
  //#endregion
275
- export { o as createMesurerPluginHost, s as createMesurerRuntime, a as defineMesurerPlugin };
284
+ export { s as createMesurerPluginHost, c as createMesurerRuntime, o as defineMesurerPlugin };
package/dist/index.d.ts CHANGED
@@ -5,6 +5,9 @@ import type { MesurerPlugin, MesurerPluginDescription, MesurerPluginHost } from
5
5
  import { type MesurerHostLayerMode } from "./host-layer";
6
6
  export type ColorPickerFormat = "hex" | "rgb" | "hsl" | "oklch";
7
7
  export type MesurerTheme = "system" | "light" | "dark";
8
+ /** Public built-in names, aligned with the factories exported by `mesurer-solid/plugins`. */
9
+ export type MesurerBuiltin = "select" | "xray" | "colorPicker" | "rulers" | "typography" | "guides" | "distance" | "settings";
10
+ /** @deprecated Internal compatibility ids used by the older `excludePlugins` option. */
8
11
  export type MesurerBuiltinPluginId = "select" | "xray" | "color-picker" | "rulers" | "text-inspector" | "guides" | "distance" | "settings";
9
12
  export type LinePattern = "solid" | "dashed" | "dotted";
10
13
  export type LineStyle = {
@@ -143,10 +146,19 @@ export type MesurerOptions = {
143
146
  * Omitted first-party plugins remain toggleable in Settings from the same canonical
144
147
  * registry; callers never maintain a separate availability or Settings list.
145
148
  */
146
- plugins?: MesurerPlugin[];
147
- excludePlugins?: MesurerBuiltinPluginId[];
149
+ plugins?: readonly MesurerPlugin[];
150
+ /** Built-in tools to omit from this mount. Names match the public plugin factories. */
151
+ excludeBuiltins?: readonly MesurerBuiltin[];
152
+ /** @deprecated Use `excludeBuiltins`. This compatibility option uses internal built-in ids. */
153
+ excludePlugins?: readonly MesurerBuiltinPluginId[];
154
+ /**
155
+ * Advanced: supply a plugin host owned outside this mount.
156
+ * The caller remains responsible for disposing the supplied host.
157
+ */
148
158
  pluginHost?: MesurerPluginHost;
159
+ /** Advanced: receive the live host before configured plugin setup settles. */
149
160
  onPluginHost?: (host: MesurerPluginHost) => void;
161
+ /** @deprecated Await `mounted.ready` instead. */
150
162
  onPluginsReady?: (host: MesurerPluginHost) => void;
151
163
  onPluginError?: (cause: unknown, pluginId: string) => void;
152
164
  };
@@ -155,7 +167,16 @@ export type MountMesurerOptions = MesurerOptions & {
155
167
  isolate?: boolean;
156
168
  shadowMode?: ShadowRootMode;
157
169
  topLayer?: boolean;
170
+ /**
171
+ * Expose the browser agent API on the owning Window. The mounted handle always
172
+ * exposes `agent`; this option controls only the global bridge.
173
+ */
158
174
  agent?: boolean | AgentBridgeOptions;
175
+ /**
176
+ * Dispose this mount when the signal aborts.
177
+ * A caller-supplied pluginHost keeps its separate lifecycle.
178
+ */
179
+ signal?: AbortSignal;
159
180
  };
160
181
  export type MesurerAgentCapabilities = {
161
182
  protocol: "mesurer.agent/v1";
@@ -174,7 +195,7 @@ export type MesurerContextHarness = {
174
195
  capabilities(): MesurerAgentCapabilities;
175
196
  context(request?: MesurerContextRequest): Promise<MesurerContextV1>;
176
197
  contextText(request?: MesurerContextRequest): Promise<string>;
177
- select(selectors: string | string[]): Promise<MesurerContextV1>;
198
+ select(selectors: string | readonly string[]): Promise<MesurerContextV1>;
178
199
  annotations(): Promise<MesurerAnnotation[]>;
179
200
  review(annotationId?: string): Promise<MesurerReviewV1 | MesurerReviewV1[]>;
180
201
  capturePlan(request?: MesurerContextRequest): Promise<MesurerCapturePlanV1>;
@@ -190,17 +211,19 @@ export type MesurerArrangeHarness = {
190
211
  };
191
212
  export type MesurerBrowserAgent = MesurerAgentHarness & MesurerContextHarness & MesurerArrangeHarness;
192
213
  export type MountedMesurer = {
193
- element: HTMLDivElement;
194
- root: HTMLDivElement | ShadowRoot;
214
+ readonly element: HTMLDivElement;
215
+ readonly root: HTMLDivElement | ShadowRoot;
195
216
  readonly hostLayer: MesurerHostLayerMode;
217
+ /** @deprecated Await `ready` when direct plugin-host access is required. */
196
218
  readonly pluginHost: MesurerPluginHost | undefined;
197
- readonly ready: Promise<void>;
219
+ /** Resolves to the live plugin host after startup and initial rendered state settle. */
220
+ readonly ready: Promise<MesurerPluginHost>;
198
221
  readonly agent: MesurerBrowserAgent;
199
222
  service<T>(id: string): Promise<T>;
200
223
  context(request?: MesurerContextRequest): Promise<MesurerContextV1>;
201
224
  contextText(request?: MesurerContextRequest): Promise<string>;
202
225
  copyContext(request?: MesurerContextRequest): Promise<void>;
203
- select(selectors: string | string[]): Promise<MesurerContextV1>;
226
+ select(selectors: string | readonly string[]): Promise<MesurerContextV1>;
204
227
  annotations(): Promise<MesurerAnnotation[]>;
205
228
  review(annotationId?: string): Promise<MesurerReviewV1 | MesurerReviewV1[]>;
206
229
  capturePlan(request?: MesurerContextRequest): Promise<MesurerCapturePlanV1>;
@@ -214,7 +237,7 @@ export type MountedMesurer = {
214
237
  textEdits(): Promise<MesurerTextEditIntent[]>;
215
238
  textEdit(id: string): Promise<MesurerTextEditIntent>;
216
239
  bringToFront(): void;
217
- describe(): MesurerPluginDescription | undefined;
240
+ describe(): Promise<MesurerPluginDescription>;
218
241
  dispose(): void;
219
242
  };
220
243
  export declare function mountMesurer(options?: MountMesurerOptions): MountedMesurer;