lineadraw 0.9.0 → 0.11.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/README.md +154 -20
- package/bin/lineadraw.mjs +60 -10
- package/dist/bridge.d.ts +1 -0
- package/dist/bridge.js +1 -1
- package/dist/{chunk-BQCSFVAF.js → chunk-7UFXC7OI.js} +5570 -1174
- package/dist/chunk-7UFXC7OI.js.map +1 -0
- package/dist/chunk-FDLANLIC.js +1161 -0
- package/dist/chunk-FDLANLIC.js.map +1 -0
- package/dist/chunk-M3EDRSHW.js +81 -0
- package/dist/chunk-M3EDRSHW.js.map +1 -0
- package/dist/chunk-MYP7RUYK.js +9 -0
- package/dist/chunk-MYP7RUYK.js.map +1 -0
- package/dist/{chunk-L2CWZAKW.js → chunk-RNA2RDGL.js} +13 -6
- package/dist/chunk-RNA2RDGL.js.map +1 -0
- package/dist/dist-56K6CNML.js +188 -0
- package/dist/dist-56K6CNML.js.map +1 -0
- package/dist/dist-IEN64QSV.js +10 -0
- package/dist/dist-IEN64QSV.js.map +1 -0
- package/dist/emscripten-module-Q67P5WYC-ITCU5LXL.js +2424 -0
- package/dist/emscripten-module-Q67P5WYC-ITCU5LXL.js.map +1 -0
- package/dist/{exportDxf-T2RTSTH5.js → exportDxf-6XTXQ4XN.js} +2 -2
- package/dist/ffi-SHMEF5YV.js +82 -0
- package/dist/ffi-SHMEF5YV.js.map +1 -0
- package/dist/module-ES6BEMUI-BJFWC656.js +14 -0
- package/dist/module-ES6BEMUI-BJFWC656.js.map +1 -0
- package/dist/module-asyncify-2EFITU5U-7F5WZXRA.js +9 -0
- package/dist/module-asyncify-2EFITU5U-7F5WZXRA.js.map +1 -0
- package/dist/sdk.d.ts +1118 -128
- package/dist/sdk.js +742 -620
- package/dist/sdk.js.map +1 -1
- package/lineadraw.d.ts +666 -44
- package/package.json +1 -1
- package/templates/README.md +6 -4
- package/dist/chunk-BQCSFVAF.js.map +0 -1
- package/dist/chunk-L2CWZAKW.js.map +0 -1
- /package/dist/{exportDxf-T2RTSTH5.js.map → exportDxf-6XTXQ4XN.js.map} +0 -0
package/lineadraw.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// GENERATED — do not edit. Typings for the virtual "lineadraw" and
|
|
2
2
|
// "lineadraw/helpers" modules block scripts import from, emitted from
|
|
3
|
-
// packages/core/src/extensions/{scriptTypes,scriptHelpers}.ts.
|
|
3
|
+
// packages/core/src/extensions/{scriptTypes,scriptHelpers,scriptBooleans,scriptCurves}.ts.
|
|
4
|
+
// Regenerate with:
|
|
4
5
|
// npm run gen:lineadraw-dts -w @lineadraw/core
|
|
5
6
|
|
|
6
7
|
declare module "lineadraw" {
|
|
@@ -96,11 +97,64 @@ declare module "lineadraw" {
|
|
|
96
97
|
startAngle?: number;
|
|
97
98
|
endAngle?: number;
|
|
98
99
|
}>;
|
|
100
|
+
/**
|
|
101
|
+
* A NURBS curve (DXF SPLINE). `knots` number controlPoints + degree + 1,
|
|
102
|
+
* non-decreasing; `weights` (one per control point) make it rational. With
|
|
103
|
+
* `fitPoints` the curve was drawn through them. Easiest to create through
|
|
104
|
+
* points: `splineThrough(points)` from "lineadraw/helpers".
|
|
105
|
+
*/
|
|
106
|
+
export type SplineInput = ObjectInputShape<{
|
|
107
|
+
type: "spline";
|
|
108
|
+
degree: number;
|
|
109
|
+
controlPoints: readonly Vec2Like[];
|
|
110
|
+
knots: readonly number[];
|
|
111
|
+
weights?: readonly number[];
|
|
112
|
+
fitPoints?: readonly Vec2Like[];
|
|
113
|
+
/** Fit splines: the direction the curve leaves its first fit point. */
|
|
114
|
+
startTangent?: Vec2Like;
|
|
115
|
+
/** Fit splines: the direction the curve arrives at its last fit point. */
|
|
116
|
+
endTangent?: Vec2Like;
|
|
117
|
+
closed?: boolean;
|
|
118
|
+
}>;
|
|
119
|
+
/**
|
|
120
|
+
* A hatch boundary edge — the geometry of a line, an arc, an elliptic arc or
|
|
121
|
+
* a spline. An arc runs CCW from startAngle to endAngle (equal = a full
|
|
122
|
+
* circle); an ellipse in DXF form (parameters, 0 → 2π = whole). Edges are
|
|
123
|
+
* chained by their ends, stored in either direction. A polygon or bulged
|
|
124
|
+
* outline: `hatchLoop(points)` from "lineadraw/helpers".
|
|
125
|
+
*/
|
|
126
|
+
export type HatchEdgeInput = {
|
|
127
|
+
kind: "line";
|
|
128
|
+
a: Vec2Like;
|
|
129
|
+
b: Vec2Like;
|
|
130
|
+
} | {
|
|
131
|
+
kind: "arc";
|
|
132
|
+
center: Vec2Like;
|
|
133
|
+
radius: number;
|
|
134
|
+
startAngle: number;
|
|
135
|
+
endAngle: number;
|
|
136
|
+
} | {
|
|
137
|
+
kind: "ellipse";
|
|
138
|
+
center: Vec2Like;
|
|
139
|
+
majorAxis: Vec2Like;
|
|
140
|
+
ratio: number;
|
|
141
|
+
startAngle?: number;
|
|
142
|
+
endAngle?: number;
|
|
143
|
+
} | {
|
|
144
|
+
kind: "spline";
|
|
145
|
+
degree: number;
|
|
146
|
+
controlPoints: readonly Vec2Like[];
|
|
147
|
+
knots: readonly number[];
|
|
148
|
+
weights?: readonly number[];
|
|
149
|
+
/** Drawn through points: those points, as on a spline. */
|
|
150
|
+
fitPoints?: readonly Vec2Like[];
|
|
151
|
+
};
|
|
99
152
|
export type HatchInput = ObjectInputShape<{
|
|
100
153
|
type: "hatch";
|
|
101
|
-
/** loops[0] = outer boundary, the rest are holes (even-odd)
|
|
154
|
+
/** loops[0] = outer boundary, the rest are holes (even-odd); each a
|
|
155
|
+
* closed chain of edges (a circle, ellipse or closed spline is one). */
|
|
102
156
|
loops: readonly {
|
|
103
|
-
|
|
157
|
+
edges: readonly HatchEdgeInput[];
|
|
104
158
|
}[];
|
|
105
159
|
fill?: {
|
|
106
160
|
kind: "solid";
|
|
@@ -204,9 +258,12 @@ declare module "lineadraw" {
|
|
|
204
258
|
/** Applied last, about the pivot (the first input point). */
|
|
205
259
|
rotation?: number;
|
|
206
260
|
scale?: number;
|
|
207
|
-
params?: Record<string, number | string | boolean | readonly number[] | readonly string[]>;
|
|
208
|
-
/** Input points in the PARENT's local coords
|
|
209
|
-
|
|
261
|
+
params?: Record<string, number | string | boolean | readonly number[] | readonly string[] | JsonValue>;
|
|
262
|
+
/** Input points in the PARENT's local coords (the first is the pivot):
|
|
263
|
+
* in pick order, or by input name for a block declaring an `inputs`
|
|
264
|
+
* table. Object ids (a `host`, picked objects) only on instances a
|
|
265
|
+
* script ADDS to the document — a block's own children can't reference. */
|
|
266
|
+
inputs?: readonly Vec2Like[] | Readonly<Record<string, Vec2Like | readonly Vec2Like[] | string | readonly string[]>>;
|
|
210
267
|
}>;
|
|
211
268
|
/** A table cell: plain text, or text with merge / alignment / style. */
|
|
212
269
|
export type TableCellInput = string | {
|
|
@@ -302,7 +359,7 @@ declare module "lineadraw" {
|
|
|
302
359
|
modelCenter?: Vec2Like;
|
|
303
360
|
/** Drawing-scale denominator (model mm per paper mm); 1:50 => 50. */
|
|
304
361
|
scale?: number;
|
|
305
|
-
/** Pinned: no pan/zoom-through, no move/resize
|
|
362
|
+
/** Pinned: no pan/zoom-through, no move/resize handles. */
|
|
306
363
|
locked?: boolean;
|
|
307
364
|
/** Layer ids hidden in this viewport only. */
|
|
308
365
|
hiddenLayerIds?: readonly string[];
|
|
@@ -317,7 +374,7 @@ declare module "lineadraw" {
|
|
|
317
374
|
}>;
|
|
318
375
|
/** What a script WRITES — the union of the authoring DTOs above (what
|
|
319
376
|
* `document.add` takes). Reads return `ModelObject`. */
|
|
320
|
-
export type ModelObjectInput = LineInput | PointInput | PolylineInput | CircleInput | ArcInput | EllipseInput | HatchInput | TextInput | DimensionInput | BlockInput | TableInput | ViewportInput | CommentInput | ReferenceInput;
|
|
377
|
+
export type ModelObjectInput = LineInput | PointInput | PolylineInput | CircleInput | ArcInput | EllipseInput | SplineInput | HatchInput | TextInput | DimensionInput | BlockInput | TableInput | ViewportInput | CommentInput | ReferenceInput;
|
|
321
378
|
/** One child a block's `draw` may return: every input except viewports and
|
|
322
379
|
* comments (both are drawn only as a space's own objects — a block's would
|
|
323
380
|
* never show). An `asset` reference resolves in the document the instance
|
|
@@ -380,6 +437,17 @@ declare module "lineadraw" {
|
|
|
380
437
|
startAngle: number;
|
|
381
438
|
endAngle: number;
|
|
382
439
|
}>;
|
|
440
|
+
export type Spline = ObjectShape<{
|
|
441
|
+
type: "spline";
|
|
442
|
+
degree: number;
|
|
443
|
+
controlPoints: readonly Vec2[];
|
|
444
|
+
knots: readonly number[];
|
|
445
|
+
weights?: readonly number[];
|
|
446
|
+
fitPoints?: readonly Vec2[];
|
|
447
|
+
startTangent?: Vec2;
|
|
448
|
+
endTangent?: Vec2;
|
|
449
|
+
closed: boolean;
|
|
450
|
+
}>;
|
|
383
451
|
export type HatchFill = {
|
|
384
452
|
kind: "solid";
|
|
385
453
|
} | {
|
|
@@ -400,11 +468,37 @@ declare module "lineadraw" {
|
|
|
400
468
|
color2: string;
|
|
401
469
|
angle: number;
|
|
402
470
|
};
|
|
471
|
+
/** Stored hatch boundary edge — see HatchEdgeInput. */
|
|
472
|
+
export type HatchEdge = {
|
|
473
|
+
kind: "line";
|
|
474
|
+
a: Vec2;
|
|
475
|
+
b: Vec2;
|
|
476
|
+
} | {
|
|
477
|
+
kind: "arc";
|
|
478
|
+
center: Vec2;
|
|
479
|
+
radius: number;
|
|
480
|
+
startAngle: number;
|
|
481
|
+
endAngle: number;
|
|
482
|
+
} | {
|
|
483
|
+
kind: "ellipse";
|
|
484
|
+
center: Vec2;
|
|
485
|
+
majorAxis: Vec2;
|
|
486
|
+
ratio: number;
|
|
487
|
+
startAngle: number;
|
|
488
|
+
endAngle: number;
|
|
489
|
+
} | {
|
|
490
|
+
kind: "spline";
|
|
491
|
+
degree: number;
|
|
492
|
+
controlPoints: readonly Vec2[];
|
|
493
|
+
knots: readonly number[];
|
|
494
|
+
weights?: readonly number[];
|
|
495
|
+
fitPoints?: readonly Vec2[];
|
|
496
|
+
};
|
|
403
497
|
export type Hatch = ObjectShape<{
|
|
404
498
|
type: "hatch";
|
|
405
499
|
/** loops[0] = outer boundary, the rest are holes (even-odd). */
|
|
406
500
|
loops: readonly {
|
|
407
|
-
|
|
501
|
+
edges: readonly HatchEdge[];
|
|
408
502
|
}[];
|
|
409
503
|
fill: HatchFill;
|
|
410
504
|
scale: number;
|
|
@@ -448,9 +542,10 @@ declare module "lineadraw" {
|
|
|
448
542
|
definitionId: string;
|
|
449
543
|
rotation: number;
|
|
450
544
|
scale: number;
|
|
451
|
-
params: Readonly<Record<string, number | string | boolean | readonly number[] | readonly string[]>>;
|
|
452
|
-
/** World points and/or referenced object ids
|
|
453
|
-
|
|
545
|
+
params: Readonly<Record<string, number | string | boolean | readonly number[] | readonly string[] | JsonValue>>;
|
|
546
|
+
/** World points and/or referenced object ids: in pick order, or by
|
|
547
|
+
* input name for a block declaring an `inputs` table. */
|
|
548
|
+
inputs: readonly (Vec2 | string)[] | Readonly<Record<string, Vec2 | string | readonly Vec2[] | readonly string[]>>;
|
|
454
549
|
}>;
|
|
455
550
|
/** Paper-space window into model space; exists only in layout spaces. */
|
|
456
551
|
export type Viewport = ObjectShape<{
|
|
@@ -540,7 +635,7 @@ declare module "lineadraw" {
|
|
|
540
635
|
styleOverride?: TextStyleOverride;
|
|
541
636
|
}>;
|
|
542
637
|
/** Any object as stored in the document — what reads hand to scripts. */
|
|
543
|
-
export type ModelObject = Line | Point | Polyline | Circle | Arc | Ellipse | Hatch | Text | Dimension | Block | Viewport | Comment | Table | Reference;
|
|
638
|
+
export type ModelObject = Line | Point | Polyline | Circle | Arc | Ellipse | Spline | Hatch | Text | Dimension | Block | Viewport | Comment | Table | Reference;
|
|
544
639
|
/**
|
|
545
640
|
* One choice of a "Select" parameter: the value (what scripts receive) with
|
|
546
641
|
* an optional properties-panel label. A plain string is shorthand for
|
|
@@ -641,6 +736,12 @@ declare module "lineadraw" {
|
|
|
641
736
|
* value: it never appears in the `params` record `draw` receives.
|
|
642
737
|
* `name` stays the unique key (paramVisibility can hide it by name). */
|
|
643
738
|
| (ParamBase & {
|
|
739
|
+
/** Structured data the block owns (any JSON value) — no panel row;
|
|
740
|
+
* edited through handles, handle menus and actions. Typed by its
|
|
741
|
+
* default: `default: {} as Record<string, Wall>`. */
|
|
742
|
+
type: "data";
|
|
743
|
+
default: JsonValue;
|
|
744
|
+
}) | (ParamBase & {
|
|
644
745
|
type: "label";
|
|
645
746
|
})
|
|
646
747
|
/** Layout only: 2–3 compact params on one panel row, each item's label a
|
|
@@ -711,12 +812,147 @@ declare module "lineadraw" {
|
|
|
711
812
|
* declares (or a block's function form returns).
|
|
712
813
|
*/
|
|
713
814
|
export type ParamDefs = readonly ParamDef[];
|
|
815
|
+
/**
|
|
816
|
+
* One declared input — a row of the `inputs` table a block or command
|
|
817
|
+
* spec declares. Inputs are read by `name` (`inputs.<name>`); `label` is
|
|
818
|
+
* the pick prompt. `types` limits object picks to those object types
|
|
819
|
+
* (empty / absent = any). Optional inputs are skipped with Enter.
|
|
820
|
+
*/
|
|
821
|
+
export type InputDef = {
|
|
822
|
+
name: string;
|
|
823
|
+
label?: string;
|
|
824
|
+
description?: string;
|
|
825
|
+
type: "point";
|
|
826
|
+
optional?: boolean;
|
|
827
|
+
} | {
|
|
828
|
+
name: string;
|
|
829
|
+
label?: string;
|
|
830
|
+
description?: string;
|
|
831
|
+
type: "points";
|
|
832
|
+
/** Default 1. */
|
|
833
|
+
min?: number;
|
|
834
|
+
max?: number;
|
|
835
|
+
/** A polygon (closing segment previewed) rather than an open chain. */
|
|
836
|
+
closed?: boolean;
|
|
837
|
+
} | {
|
|
838
|
+
name: string;
|
|
839
|
+
label?: string;
|
|
840
|
+
description?: string;
|
|
841
|
+
type: "object";
|
|
842
|
+
types?: readonly ModelObject["type"][];
|
|
843
|
+
optional?: boolean;
|
|
844
|
+
} | {
|
|
845
|
+
name: string;
|
|
846
|
+
label?: string;
|
|
847
|
+
description?: string;
|
|
848
|
+
type: "objects";
|
|
849
|
+
types?: readonly ModelObject["type"][];
|
|
850
|
+
/** Default 1. */
|
|
851
|
+
min?: number;
|
|
852
|
+
max?: number;
|
|
853
|
+
} | {
|
|
854
|
+
name: string;
|
|
855
|
+
label?: string;
|
|
856
|
+
description?: string;
|
|
857
|
+
/** The block instance this one LIVES ON (a door on a floor plan): it
|
|
858
|
+
* draws in the host's frame and reads the host's `expose` as `host`;
|
|
859
|
+
* the host's `draw` sees it in `hosted`. Picked by clicking the host;
|
|
860
|
+
* `attach` turns the click into params. */
|
|
861
|
+
type: "host";
|
|
862
|
+
/** Accepted host DEFINITION ids (empty = any block). */
|
|
863
|
+
types?: readonly string[];
|
|
864
|
+
};
|
|
865
|
+
/** A custom handle's marker shape (cosmetic: triangle / arrow = "pull this
|
|
866
|
+
* way", diamond = "options here", plus / minus = "add / remove"). */
|
|
867
|
+
export type HandleShape = "square" | "circle" | "diamond" | "triangle" | "arrow" | "double-arrow" | "plus" | "minus";
|
|
868
|
+
/** Icons a button handle may show (lucide glyphs). */
|
|
869
|
+
export type HandleIcon = "plus" | "minus" | "x" | "check" | "flip-horizontal" | "flip-vertical" | "rotate-cw" | "rotate-ccw" | "refresh-cw" | "arrow-left-right" | "arrow-up-down" | "settings-2" | "ellipsis";
|
|
870
|
+
/** An inputs table. */
|
|
871
|
+
export type InputDefs = readonly InputDef[];
|
|
872
|
+
/** A command's inputs table: a `host` is a block-only input. */
|
|
873
|
+
export type CommandInputDefs = readonly Exclude<InputDef, {
|
|
874
|
+
type: "host";
|
|
875
|
+
}>[];
|
|
876
|
+
/** The object type an object input's `types` filter admits. */
|
|
877
|
+
type PickedObject<D> = D extends {
|
|
878
|
+
types: readonly (infer T)[];
|
|
879
|
+
} ? [T] extends [never] ? ModelObject : Extract<ModelObject, {
|
|
880
|
+
type: T;
|
|
881
|
+
}> : ModelObject;
|
|
882
|
+
type DrawInputValue<D> = D extends {
|
|
883
|
+
type: "point";
|
|
884
|
+
} ? D extends {
|
|
885
|
+
optional: true;
|
|
886
|
+
} ? Vec2 | undefined : Vec2 : D extends {
|
|
887
|
+
type: "points";
|
|
888
|
+
} ? readonly Vec2[] : D extends {
|
|
889
|
+
type: "object";
|
|
890
|
+
} ? PickedObject<D> | null : readonly PickedObject<D>[];
|
|
891
|
+
/**
|
|
892
|
+
* What a block's `draw` receives as `inputs` for a table: points
|
|
893
|
+
* pivot-localized, object inputs as the referenced object (pivot-local) or
|
|
894
|
+
* null once deleted, lists as arrays (deleted objects dropped).
|
|
895
|
+
*/
|
|
896
|
+
export type DrawInputs<I extends InputDefs> = {
|
|
897
|
+
readonly [D in I[number] as D extends {
|
|
898
|
+
type: "host";
|
|
899
|
+
} ? never : D["name"]]: DrawInputValue<D>;
|
|
900
|
+
};
|
|
901
|
+
type StoredInputValue<D> = D extends {
|
|
902
|
+
type: "host";
|
|
903
|
+
} ? string : D extends {
|
|
904
|
+
type: "point";
|
|
905
|
+
} ? Vec2Like : D extends {
|
|
906
|
+
type: "points";
|
|
907
|
+
} ? readonly Vec2Like[] : D extends {
|
|
908
|
+
type: "object";
|
|
909
|
+
} ? string : readonly string[];
|
|
910
|
+
/**
|
|
911
|
+
* Inputs as STORED for a table (what `place` returns and `previewInputs`
|
|
912
|
+
* holds): points in world coords ([x, y] accepted), objects as ids.
|
|
913
|
+
* Optional inputs may be left out.
|
|
914
|
+
*/
|
|
915
|
+
export type StoredInputs<I extends InputDefs> = {
|
|
916
|
+
readonly [D in I[number] as D extends {
|
|
917
|
+
optional: true;
|
|
918
|
+
} ? never : D["name"]]: StoredInputValue<D>;
|
|
919
|
+
} & {
|
|
920
|
+
readonly [D in I[number] as D extends {
|
|
921
|
+
optional: true;
|
|
922
|
+
} ? D["name"] : never]?: StoredInputValue<D>;
|
|
923
|
+
};
|
|
924
|
+
type CommandInputValue<D> = D extends {
|
|
925
|
+
type: "point";
|
|
926
|
+
} ? D extends {
|
|
927
|
+
optional: true;
|
|
928
|
+
} ? Vec2 | undefined : Vec2 : D extends {
|
|
929
|
+
type: "points";
|
|
930
|
+
} ? readonly Vec2[] : D extends {
|
|
931
|
+
type: "object";
|
|
932
|
+
} ? D extends {
|
|
933
|
+
optional: true;
|
|
934
|
+
} ? string | undefined : string : readonly string[];
|
|
935
|
+
/**
|
|
936
|
+
* What a command's `ctx.inputs` is: the points in label order for a
|
|
937
|
+
* labels array, a record by name for a table (objects as ids — read them
|
|
938
|
+
* with `document.getObject`).
|
|
939
|
+
*/
|
|
940
|
+
export type CommandInputs<I> = I extends readonly string[] ? readonly Vec2[] : I extends CommandInputDefs ? {
|
|
941
|
+
readonly [D in I[number] as D["name"]]: CommandInputValue<D>;
|
|
942
|
+
} : readonly Vec2[];
|
|
714
943
|
/** The value an enum option denotes (its string, or `value` of the record form). */
|
|
715
944
|
type OptionValue<O extends ParamOption> = O extends string ? O : O extends {
|
|
716
945
|
value: infer V extends string;
|
|
717
946
|
} ? V : never;
|
|
947
|
+
/** Any JSON value — what a `data` param holds. */
|
|
948
|
+
export type JsonValue = string | number | boolean | null | readonly JsonValue[] | {
|
|
949
|
+
readonly [key: string]: JsonValue;
|
|
950
|
+
};
|
|
718
951
|
/** The runtime value type of one `params` table entry. */
|
|
719
952
|
type ParamValue<Q extends ParamDef> = Q extends {
|
|
953
|
+
type: "data";
|
|
954
|
+
default: infer D;
|
|
955
|
+
} ? D : Q extends {
|
|
720
956
|
type: "enum";
|
|
721
957
|
} ? OptionValue<Q["options"][number]> : Q extends {
|
|
722
958
|
type: "number";
|
|
@@ -812,6 +1048,7 @@ declare module "lineadraw" {
|
|
|
812
1048
|
}[];
|
|
813
1049
|
settings: {
|
|
814
1050
|
units: "mm" | "in";
|
|
1051
|
+
modelScale: number;
|
|
815
1052
|
};
|
|
816
1053
|
};
|
|
817
1054
|
/** What `renderSvg` draws: model space or one layout. */
|
|
@@ -889,6 +1126,9 @@ declare module "lineadraw" {
|
|
|
889
1126
|
authors?: readonly string[];
|
|
890
1127
|
tags?: readonly string[];
|
|
891
1128
|
dependencies?: readonly string[];
|
|
1129
|
+
/** The declared inputs table, when the block has one (instances then
|
|
1130
|
+
* store their inputs by name). */
|
|
1131
|
+
inputs?: InputDefs;
|
|
892
1132
|
};
|
|
893
1133
|
/** A command module's identity/metadata (from its exports). */
|
|
894
1134
|
export type CommandInfo = {
|
|
@@ -898,8 +1138,11 @@ declare module "lineadraw" {
|
|
|
898
1138
|
version?: string;
|
|
899
1139
|
authors?: readonly string[];
|
|
900
1140
|
tags?: readonly string[];
|
|
901
|
-
/** Declared
|
|
902
|
-
|
|
1141
|
+
/** Declared inputs, picked or supplied before `run`: point labels
|
|
1142
|
+
* (positional) or an inputs table (by name). */
|
|
1143
|
+
inputs?: readonly string[] | CommandInputDefs;
|
|
1144
|
+
/** Asks during the run, so headless runners refuse it. */
|
|
1145
|
+
requiresEditor?: boolean;
|
|
903
1146
|
/** Declared parameters (same table as a block's), prompted or supplied
|
|
904
1147
|
* before `run`. */
|
|
905
1148
|
params?: readonly ParamDef[];
|
|
@@ -973,8 +1216,8 @@ declare module "lineadraw" {
|
|
|
973
1216
|
/** A sheet: a bare preset (orientation from context — landscape for a new
|
|
974
1217
|
* layout, the current one when patching), a preset with its orientation, or
|
|
975
1218
|
* explicit millimetres. */
|
|
976
|
-
export type SheetSpec = "A4" | "A3" | "A2" | "A1" | "A0" | {
|
|
977
|
-
name: "A4" | "A3" | "A2" | "A1" | "A0";
|
|
1219
|
+
export type SheetSpec = "A5" | "A4" | "A3" | "A2" | "A1" | "A0" | "Letter" | {
|
|
1220
|
+
name: "A5" | "A4" | "A3" | "A2" | "A1" | "A0" | "Letter";
|
|
978
1221
|
orientation: "portrait" | "landscape";
|
|
979
1222
|
} | {
|
|
980
1223
|
width: number;
|
|
@@ -1012,6 +1255,7 @@ declare module "lineadraw" {
|
|
|
1012
1255
|
version: number;
|
|
1013
1256
|
settings: {
|
|
1014
1257
|
units: "mm" | "in";
|
|
1258
|
+
modelScale: number;
|
|
1015
1259
|
};
|
|
1016
1260
|
layers: readonly Layer[];
|
|
1017
1261
|
currentLayerId: string;
|
|
@@ -1271,10 +1515,43 @@ declare module "lineadraw" {
|
|
|
1271
1515
|
label?: string;
|
|
1272
1516
|
referencePoint?: Vec2Like;
|
|
1273
1517
|
}): Promise<Vec2>;
|
|
1274
|
-
/** Await one object click; resolves the object's id.
|
|
1518
|
+
/** Await one object click; resolves the object's id. `types` limits
|
|
1519
|
+
* what can be picked (empty / absent = any). */
|
|
1275
1520
|
pickObject(opts?: {
|
|
1276
1521
|
label?: string;
|
|
1522
|
+
types?: readonly ModelObject["type"][];
|
|
1277
1523
|
}): Promise<string>;
|
|
1524
|
+
/** Await a chain of snapped points (rubber band from the previous);
|
|
1525
|
+
* Enter / Esc finishes once `min` (default 1) is met, `max` ends it,
|
|
1526
|
+
* `closed` previews the closing segment. Rejects on cancel below `min`. */
|
|
1527
|
+
pickPoints(opts?: {
|
|
1528
|
+
label?: string;
|
|
1529
|
+
min?: number;
|
|
1530
|
+
max?: number;
|
|
1531
|
+
closed?: boolean;
|
|
1532
|
+
referencePoint?: Vec2Like;
|
|
1533
|
+
}): Promise<Vec2[]>;
|
|
1534
|
+
/** Await several object picks (each once); Enter / Esc finishes once
|
|
1535
|
+
* `min` (default 1) is met. Rejects on cancel below `min`. */
|
|
1536
|
+
pickObjects(opts?: {
|
|
1537
|
+
label?: string;
|
|
1538
|
+
types?: readonly ModelObject["type"][];
|
|
1539
|
+
min?: number;
|
|
1540
|
+
max?: number;
|
|
1541
|
+
}): Promise<string[]>;
|
|
1542
|
+
/**
|
|
1543
|
+
* Ask several values in ONE dialog — the same form a command's `params`
|
|
1544
|
+
* table shows, from a params table (number / string / boolean / enum …):
|
|
1545
|
+
* const { count, label } = await editor.ask(
|
|
1546
|
+
* [{ name: "count", type: "number", default: 3 },
|
|
1547
|
+
* { name: "label", type: "string", default: "A" }],
|
|
1548
|
+
* { title: "Array" });
|
|
1549
|
+
* Resolves the values typed by the table; rejects on cancel.
|
|
1550
|
+
*/
|
|
1551
|
+
ask<const P extends ParamDefs>(params: P, opts?: {
|
|
1552
|
+
title?: string;
|
|
1553
|
+
description?: string;
|
|
1554
|
+
}): Promise<ParamValues<P>>;
|
|
1278
1555
|
/** Await a typed value from a small input dialog. */
|
|
1279
1556
|
prompt(message: string, opts?: {
|
|
1280
1557
|
initial?: string;
|
|
@@ -1286,20 +1563,21 @@ declare module "lineadraw" {
|
|
|
1286
1563
|
/** Trigger a command by id — like the user pressing its hotkey. A macro
|
|
1287
1564
|
* takes its declared `inputs` / `params` up front (params passed skip its
|
|
1288
1565
|
* params dialog). */
|
|
1289
|
-
runCommand(id: string, inputs?: readonly Vec2Like[], params?: Readonly<Record<string, unknown>>): Promise<void>;
|
|
1566
|
+
runCommand(id: string, inputs?: readonly Vec2Like[] | Readonly<Record<string, Vec2Like | readonly Vec2Like[] | string | readonly string[]>>, params?: Readonly<Record<string, unknown>>): Promise<void>;
|
|
1290
1567
|
}
|
|
1291
1568
|
/**
|
|
1292
1569
|
* What `run` receives. `document` is the Drawing; `editor` the interactive
|
|
1293
|
-
* surface when there is one; `inputs`
|
|
1294
|
-
*
|
|
1295
|
-
* caller)
|
|
1296
|
-
*
|
|
1297
|
-
*
|
|
1570
|
+
* surface when there is one; `inputs` what the command's declared `inputs`
|
|
1571
|
+
* produced (picked in the editor — object inputs take the selection first
|
|
1572
|
+
* — or supplied by the caller): the points in label order for labels, a
|
|
1573
|
+
* record by name for a table (see CommandInputs); `params` the values of
|
|
1574
|
+
* the declared `params` table (asked for in a dialog in the editor, or
|
|
1575
|
+
* passed by the caller; omitted ones take their defaults).
|
|
1298
1576
|
*/
|
|
1299
|
-
export interface CommandContext<P = Readonly<Record<string, unknown
|
|
1577
|
+
export interface CommandContext<P = Readonly<Record<string, unknown>>, I = readonly Vec2[]> {
|
|
1300
1578
|
document: Drawing;
|
|
1301
1579
|
editor?: EditorSurface;
|
|
1302
|
-
inputs:
|
|
1580
|
+
inputs: I;
|
|
1303
1581
|
params: P;
|
|
1304
1582
|
}
|
|
1305
1583
|
|
|
@@ -1371,9 +1649,164 @@ declare module "lineadraw" {
|
|
|
1371
1649
|
export interface PlaceProps<P = BlockParams> {
|
|
1372
1650
|
params: ParamValues<P>;
|
|
1373
1651
|
pickPoint: (label?: string) => Promise<Vec2>;
|
|
1374
|
-
pickObject: (
|
|
1652
|
+
pickObject: (
|
|
1653
|
+
label?: string,
|
|
1654
|
+
opts?: { types?: readonly ModelObject["type"][] },
|
|
1655
|
+
) => Promise<string>;
|
|
1656
|
+
/** A chain of points; Enter / Esc finishes once `min` (default 1) is met. */
|
|
1657
|
+
pickPoints: (
|
|
1658
|
+
label?: string,
|
|
1659
|
+
opts?: { min?: number; max?: number; closed?: boolean },
|
|
1660
|
+
) => Promise<Vec2[]>;
|
|
1661
|
+
/** Several objects; Enter / Esc finishes once `min` (default 1) is met. */
|
|
1662
|
+
pickObjects: (
|
|
1663
|
+
label?: string,
|
|
1664
|
+
opts?: {
|
|
1665
|
+
types?: readonly ModelObject["type"][];
|
|
1666
|
+
min?: number;
|
|
1667
|
+
max?: number;
|
|
1668
|
+
},
|
|
1669
|
+
) => Promise<string[]>;
|
|
1375
1670
|
}
|
|
1376
1671
|
|
|
1672
|
+
// ——— Custom handles ———
|
|
1673
|
+
|
|
1674
|
+
/** The names of a params table's NUMBER parameters. */
|
|
1675
|
+
export type NumberParamName<P> = {
|
|
1676
|
+
[K in keyof ParamValues<P>]: ParamValues<P>[K] extends number ? K : never;
|
|
1677
|
+
}[keyof ParamValues<P>] &
|
|
1678
|
+
string;
|
|
1679
|
+
|
|
1680
|
+
/**
|
|
1681
|
+
* What a handle's drag / click / action changes: params by name (numbers
|
|
1682
|
+
* are clamped to the param's min / max), and — for a block with an
|
|
1683
|
+
* `inputs` table — inputs by name in block-LOCAL coordinates.
|
|
1684
|
+
*/
|
|
1685
|
+
export interface HandlePatch<P = BlockParams, S = never> {
|
|
1686
|
+
params?: Partial<ParamValues<P>>;
|
|
1687
|
+
inputs?: S;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
/** What a `drag` function receives — the values at drag START (not
|
|
1691
|
+
* compounding) plus where the cursor is, already constrained. */
|
|
1692
|
+
export interface HandleDragEvent<P = BlockParams, D = unknown> {
|
|
1693
|
+
params: ParamValues<P>;
|
|
1694
|
+
inputs: D;
|
|
1695
|
+
/** The cursor, block-local, after the handle's constraint. */
|
|
1696
|
+
point: Vec2;
|
|
1697
|
+
/** The handle's position when the drag started. */
|
|
1698
|
+
start: Vec2;
|
|
1699
|
+
/** `along`: signed distance from its origin; `around`: the angle
|
|
1700
|
+
* (radians); free: undefined. */
|
|
1701
|
+
value: number | undefined;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* One custom handle on a selected instance, in block-LOCAL coordinates
|
|
1706
|
+
* (pivot at the origin, before the instance's rotation / scale). Give it
|
|
1707
|
+
* ONE drag behaviour — `param` (the constrained value → a number param),
|
|
1708
|
+
* `input` (moves a point input), or `drag` (anything else) — or mark it
|
|
1709
|
+
* `fixed`; `click` makes it a button (a press without a move).
|
|
1710
|
+
*/
|
|
1711
|
+
/**
|
|
1712
|
+
* A button in a handle's hover menu, or in the instance's context menu
|
|
1713
|
+
* (the block's top-level `actions`). One undo step.
|
|
1714
|
+
*/
|
|
1715
|
+
export interface BlockAction<P = BlockParams, D = unknown, S = never> {
|
|
1716
|
+
label: string;
|
|
1717
|
+
icon?: HandleIcon;
|
|
1718
|
+
/** Pick a point first (snapping as usual); `run` receives it,
|
|
1719
|
+
* block-local, as `point`. Esc cancels. */
|
|
1720
|
+
pick?: "point";
|
|
1721
|
+
run: (s: {
|
|
1722
|
+
params: ParamValues<P>;
|
|
1723
|
+
inputs: D;
|
|
1724
|
+
point?: Vec2;
|
|
1725
|
+
}) => HandlePatch<P, S> | undefined;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
/** A field in a handle's hover menu: a parameter by name, or a field
|
|
1729
|
+
* bound to any value (one wall's thickness inside a `data` param), with
|
|
1730
|
+
* `set` returning what an edit changes. Each edit is one undo step. */
|
|
1731
|
+
export type MenuField<P = BlockParams, S = never> =
|
|
1732
|
+
| (keyof ParamValues<P> & string)
|
|
1733
|
+
| {
|
|
1734
|
+
/** The field: any value parameter row without name / default
|
|
1735
|
+
* (`{ type: "number", label: "Thickness", min: 50 }`). */
|
|
1736
|
+
field: Record<string, unknown> & { type: string; label?: string };
|
|
1737
|
+
value: unknown;
|
|
1738
|
+
set: (value: never) => HandlePatch<P, S> | undefined;
|
|
1739
|
+
};
|
|
1740
|
+
|
|
1741
|
+
interface HandleBase<P, D, S> {
|
|
1742
|
+
/** Stable within the instance (hover / drag continuity, tests). */
|
|
1743
|
+
id: string;
|
|
1744
|
+
/** Tooltip, and the hover menu's title. */
|
|
1745
|
+
label?: string;
|
|
1746
|
+
/** Not draggable (a button, or menu-only). */
|
|
1747
|
+
fixed?: boolean;
|
|
1748
|
+
/** The constrained value → this NUMBER param. */
|
|
1749
|
+
param?: NumberParamName<P>;
|
|
1750
|
+
drag?: (e: HandleDragEvent<P, D>) => HandlePatch<P, S> | undefined;
|
|
1751
|
+
/** Button behaviour: one undo step; the selection doesn't change. */
|
|
1752
|
+
click?: (s: {
|
|
1753
|
+
params: ParamValues<P>;
|
|
1754
|
+
inputs: D;
|
|
1755
|
+
}) => HandlePatch<P, S> | undefined;
|
|
1756
|
+
/** Fields shown in the hover menu (see MenuField). */
|
|
1757
|
+
menu?: readonly MenuField<P, S>[];
|
|
1758
|
+
/** Buttons in the hover menu. */
|
|
1759
|
+
actions?: readonly BlockAction<P, D, S>[];
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* One custom point handle on a selected instance, in block-LOCAL
|
|
1764
|
+
* coordinates (pivot at the origin, before the instance's rotation /
|
|
1765
|
+
* scale). Give it ONE drag behaviour — `param` (the constrained value →
|
|
1766
|
+
* a number param), `input` (moves a point input), or `drag` (anything
|
|
1767
|
+
* else) — or mark it `fixed`; `click` makes it a button.
|
|
1768
|
+
*/
|
|
1769
|
+
export interface PointHandleDef<P = BlockParams, D = unknown, S = never>
|
|
1770
|
+
extends HandleBase<P, D, S> {
|
|
1771
|
+
kind?: "point";
|
|
1772
|
+
at: Vec2Like;
|
|
1773
|
+
shape?: HandleShape;
|
|
1774
|
+
/** Radians — points a triangle / arrow (default: the constraint axis). */
|
|
1775
|
+
direction?: number;
|
|
1776
|
+
/** Constrain to a line through `origin`; value = signed distance. */
|
|
1777
|
+
along?: {
|
|
1778
|
+
origin: Vec2Like;
|
|
1779
|
+
direction: Vec2Like;
|
|
1780
|
+
min?: number;
|
|
1781
|
+
max?: number;
|
|
1782
|
+
};
|
|
1783
|
+
/** Constrain to the circle through `at` around `center`; value =
|
|
1784
|
+
* the angle (radians). */
|
|
1785
|
+
around?: { center: Vec2Like };
|
|
1786
|
+
/** Move a point input: `"hinge"`, or one point of a list
|
|
1787
|
+
* (`{ name: "path", index: 2 }`). Replaces that point's default handle. */
|
|
1788
|
+
input?: string | { name: string; index: number };
|
|
1789
|
+
/** A lucide glyph drawn in the handle — the button look. */
|
|
1790
|
+
icon?: HandleIcon;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
/**
|
|
1794
|
+
* A line handle (a wall face, an offset): drawn while hovered, dragged
|
|
1795
|
+
* along its NORMAL by default (value = the signed offset, left of
|
|
1796
|
+
* from → to positive); `along` gives another direction.
|
|
1797
|
+
*/
|
|
1798
|
+
export interface LineHandleDef<P = BlockParams, D = unknown, S = never>
|
|
1799
|
+
extends HandleBase<P, D, S> {
|
|
1800
|
+
kind: "line";
|
|
1801
|
+
from: Vec2Like;
|
|
1802
|
+
to: Vec2Like;
|
|
1803
|
+
along?: { direction: Vec2Like; min?: number; max?: number };
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
export type HandleDef<P = BlockParams, D = unknown, S = never> =
|
|
1807
|
+
| PointHandleDef<P, D, S>
|
|
1808
|
+
| LineHandleDef<P, D, S>;
|
|
1809
|
+
|
|
1377
1810
|
// ——— defineBlock ———
|
|
1378
1811
|
|
|
1379
1812
|
/**
|
|
@@ -1423,6 +1856,7 @@ declare module "lineadraw" {
|
|
|
1423
1856
|
export interface BlockSpec<
|
|
1424
1857
|
P extends ParamDefs = readonly [],
|
|
1425
1858
|
Pl extends PlaceSpec<P> | undefined = undefined,
|
|
1859
|
+
I extends InputDefs | undefined = undefined,
|
|
1426
1860
|
> {
|
|
1427
1861
|
id: string;
|
|
1428
1862
|
name: string;
|
|
@@ -1447,16 +1881,58 @@ declare module "lineadraw" {
|
|
|
1447
1881
|
paramVisibility?: (props: {
|
|
1448
1882
|
params: ParamValues<P>;
|
|
1449
1883
|
}) => Partial<Record<keyof ParamValues<P> & string, boolean>>;
|
|
1450
|
-
/**
|
|
1451
|
-
|
|
1884
|
+
/**
|
|
1885
|
+
* The block's declared inputs, by name — picked in table order at
|
|
1886
|
+
* insertion (`points` until Enter, `objects` from the selection when
|
|
1887
|
+
* it fits), and read in `draw` as `inputs.<name>`. Instances store
|
|
1888
|
+
* them by name, so reordering or adding inputs never breaks existing
|
|
1889
|
+
* instances. Replaces `place` labels.
|
|
1890
|
+
*/
|
|
1891
|
+
inputs?: I;
|
|
1892
|
+
/**
|
|
1893
|
+
* Point labels (fixed picks) or an interactive function (see
|
|
1894
|
+
* PlaceSpec). With an `inputs` table, only the function form: it
|
|
1895
|
+
* returns the inputs by name (for conditional or chained picks).
|
|
1896
|
+
*/
|
|
1897
|
+
place?: [I] extends [InputDefs]
|
|
1898
|
+
? (props: PlaceProps<P>) => StoredInputs<I> | Promise<StoredInputs<I>>
|
|
1899
|
+
: Pl;
|
|
1452
1900
|
/**
|
|
1453
1901
|
* Optional inputs used for the block's PREVIEW (panel/Library
|
|
1454
1902
|
* thumbnails, marketplace cards, save-time dry run) instead of the
|
|
1455
1903
|
* generic stand-in picks — curate them so the preview shows the block
|
|
1456
|
-
* at its best. Same shape `place` produces
|
|
1457
|
-
* object-id strings resolve to
|
|
1904
|
+
* at its best. Same shape `place` produces (by name with an
|
|
1905
|
+
* `inputs` table); points accept [x, y]; object-id strings resolve to
|
|
1906
|
+
* a stand-in line in previews.
|
|
1907
|
+
*/
|
|
1908
|
+
previewInputs?: [I] extends [InputDefs] ? StoredInputs<I> : PreviewInputs<Pl>;
|
|
1909
|
+
/**
|
|
1910
|
+
* Custom handles on a selected instance — pure, block-local, re-run
|
|
1911
|
+
* whenever params / inputs change, so positions follow the values (a
|
|
1912
|
+
* width handle sits at the width). See HandleDef.
|
|
1913
|
+
*/
|
|
1914
|
+
handles?: (props: {
|
|
1915
|
+
params: ParamValues<P>;
|
|
1916
|
+
inputs: [I] extends [InputDefs] ? DrawInputs<I> : PlaceInputs<Pl>;
|
|
1917
|
+
/** Hosted blocks: the host's `expose` result (null when this block
|
|
1918
|
+
* has no host). Shape it as the host documents it. */
|
|
1919
|
+
host: any;
|
|
1920
|
+
/** Hosting: what lives on this instance — each one's `expose`. */
|
|
1921
|
+
hosted: readonly HostedBlock[];
|
|
1922
|
+
}) => readonly HandleDef<
|
|
1923
|
+
P,
|
|
1924
|
+
[I] extends [InputDefs] ? DrawInputs<I> : PlaceInputs<Pl>,
|
|
1925
|
+
[I] extends [InputDefs] ? Partial<StoredInputs<I>> : never
|
|
1926
|
+
>[];
|
|
1927
|
+
/**
|
|
1928
|
+
* Actions in the instance's context menu (right-click) — e.g. "Add
|
|
1929
|
+
* window" with `pick: "point"`. Static records; one undo step each.
|
|
1458
1930
|
*/
|
|
1459
|
-
|
|
1931
|
+
actions?: readonly BlockAction<
|
|
1932
|
+
P,
|
|
1933
|
+
[I] extends [InputDefs] ? DrawInputs<I> : PlaceInputs<Pl>,
|
|
1934
|
+
[I] extends [InputDefs] ? Partial<StoredInputs<I>> : never
|
|
1935
|
+
>[];
|
|
1460
1936
|
/**
|
|
1461
1937
|
* Children in block-LOCAL coordinates (pure, runs per evaluation).
|
|
1462
1938
|
* The first point input is the pivot; `inputs` arrive localized
|
|
@@ -1466,12 +1942,51 @@ declare module "lineadraw" {
|
|
|
1466
1942
|
*/
|
|
1467
1943
|
draw: (props: {
|
|
1468
1944
|
params: ParamValues<P>;
|
|
1469
|
-
inputs: PlaceInputs<Pl>;
|
|
1945
|
+
inputs: [I] extends [InputDefs] ? DrawInputs<I> : PlaceInputs<Pl>;
|
|
1470
1946
|
/** The document's text / dimension styles by id — for blocks that
|
|
1471
1947
|
* lay out with real text sizes. Pass a picked id on to children as
|
|
1472
1948
|
* `styleId` to let them follow the style. */
|
|
1473
1949
|
styles: BlockStyles;
|
|
1950
|
+
/** Hosted blocks: the host's `expose` result (null when this block
|
|
1951
|
+
* has no host). Shape it as the host documents it. */
|
|
1952
|
+
host: any;
|
|
1953
|
+
/** Hosting: what lives on this instance — each one's `expose`. */
|
|
1954
|
+
hosted: readonly HostedBlock[];
|
|
1474
1955
|
}) => BlockChildInput[];
|
|
1956
|
+
/**
|
|
1957
|
+
* Hosting (blocks living on blocks — a door on a floor plan): JSON
|
|
1958
|
+
* this block PUBLISHES for others to read — a host its `walls`, a
|
|
1959
|
+
* door its `cut`. It sees only its own params, which is what keeps
|
|
1960
|
+
* a host and what lives on it from looping.
|
|
1961
|
+
*/
|
|
1962
|
+
expose?: (props: { params: ParamValues<P> }) => JsonValue;
|
|
1963
|
+
/**
|
|
1964
|
+
* A hosted block (one with a `host` input): turns the click on the
|
|
1965
|
+
* host — host-local, with the host's exposed data — into this
|
|
1966
|
+
* instance's params (`{ wall: "B/1-2", at: 1200 }`).
|
|
1967
|
+
*/
|
|
1968
|
+
attach?: (props: {
|
|
1969
|
+
host: any;
|
|
1970
|
+
point: Vec2;
|
|
1971
|
+
params: ParamValues<P>;
|
|
1972
|
+
}) => Partial<ParamValues<P>>;
|
|
1973
|
+
/**
|
|
1974
|
+
* A hosted block's stand-in host for previews, Library / marketplace
|
|
1975
|
+
* thumbnails and the save-time dry run: the JSON a real host's
|
|
1976
|
+
* `expose` would return. The preview places the block as if its host
|
|
1977
|
+
* were clicked at the origin (`attach`), and `draw` gets this as
|
|
1978
|
+
* `host`. Add a flag (`preview: true`) to draw extra context there,
|
|
1979
|
+
* e.g. a stretch of wall around a door.
|
|
1980
|
+
*/
|
|
1981
|
+
previewHost?: JsonValue;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
/** One block living on a host, as the host's `draw` sees it. */
|
|
1985
|
+
export interface HostedBlock {
|
|
1986
|
+
id: string;
|
|
1987
|
+
definitionId: string;
|
|
1988
|
+
/** Its `expose` result (null without one). */
|
|
1989
|
+
exposed: any;
|
|
1475
1990
|
}
|
|
1476
1991
|
|
|
1477
1992
|
/**
|
|
@@ -1510,13 +2025,21 @@ declare module "lineadraw" {
|
|
|
1510
2025
|
>(
|
|
1511
2026
|
spec: BlockSpec<P, (props: PlaceProps<P>) => R>,
|
|
1512
2027
|
): BlockSpec<P, (props: PlaceProps<P>) => R>;
|
|
2028
|
+
// An `inputs` table: `draw`'s inputs are typed by name from it.
|
|
2029
|
+
export function defineBlock<
|
|
2030
|
+
const P extends ParamDefs = readonly [],
|
|
2031
|
+
const I extends InputDefs = readonly [],
|
|
2032
|
+
>(spec: BlockSpec<P, undefined, I>): BlockSpec<P, undefined, I>;
|
|
1513
2033
|
|
|
1514
2034
|
// ——— Commands (macro scripts) ———
|
|
1515
2035
|
// Drawing / EditorSurface / CommandContext are emitted from scriptTypes.ts
|
|
1516
2036
|
// above (the script-facing mirror of core's real interfaces).
|
|
1517
2037
|
|
|
1518
2038
|
/** One user command (macro): identity, metadata, and the `run` body. */
|
|
1519
|
-
export interface CommandSpec<
|
|
2039
|
+
export interface CommandSpec<
|
|
2040
|
+
P extends ParamDefs = readonly [],
|
|
2041
|
+
I extends readonly string[] | CommandInputDefs = readonly [],
|
|
2042
|
+
> {
|
|
1520
2043
|
id: string;
|
|
1521
2044
|
name: string;
|
|
1522
2045
|
description?: string;
|
|
@@ -1524,13 +2047,24 @@ declare module "lineadraw" {
|
|
|
1524
2047
|
authors?: readonly string[];
|
|
1525
2048
|
tags?: readonly string[];
|
|
1526
2049
|
/**
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
1529
|
-
*
|
|
1530
|
-
*
|
|
1531
|
-
*
|
|
2050
|
+
* The inputs the command needs: an inputs TABLE
|
|
2051
|
+
* (`[{ name: "doors", type: "objects", types: ["block"] }]`, arriving
|
|
2052
|
+
* as `ctx.inputs.doors`), or point labels (`["Start", "End"]`,
|
|
2053
|
+
* arriving as `ctx.inputs` in order). In the editor they are acquired
|
|
2054
|
+
* before `run` — object inputs take the current selection when it
|
|
2055
|
+
* fits, the rest are picked; a headless or remote caller supplies them
|
|
2056
|
+
* up front (by name for a table). This is what lets one script run in
|
|
2057
|
+
* the editor, from a shell, and from an agent alike.
|
|
1532
2058
|
*/
|
|
1533
|
-
inputs?:
|
|
2059
|
+
inputs?: I;
|
|
2060
|
+
/**
|
|
2061
|
+
* The command ASKS during the run (`editor.pickPoint`, `prompt`,
|
|
2062
|
+
* `ask` — the next question depends on the last answer), so it can't
|
|
2063
|
+
* run headless: CLI / agent / SDK runners refuse it up front instead of
|
|
2064
|
+
* failing halfway. Leave it off for commands whose `inputs` /
|
|
2065
|
+
* `params` cover everything.
|
|
2066
|
+
*/
|
|
2067
|
+
requiresEditor?: boolean;
|
|
1534
2068
|
/**
|
|
1535
2069
|
* Parameters the command needs — the same table a block's `params`
|
|
1536
2070
|
* declares (number / string / boolean / enum / label rows), or a
|
|
@@ -1546,7 +2080,7 @@ declare module "lineadraw" {
|
|
|
1546
2080
|
* uncaught error rolls everything back. A return value is handed to
|
|
1547
2081
|
* the caller (the agent tool / CLI) — the editor ignores it.
|
|
1548
2082
|
*/
|
|
1549
|
-
run(ctx: CommandContext<ParamValues<P>>): unknown;
|
|
2083
|
+
run(ctx: CommandContext<ParamValues<P>, CommandInputs<I>>): unknown;
|
|
1550
2084
|
}
|
|
1551
2085
|
|
|
1552
2086
|
/**
|
|
@@ -1572,9 +2106,10 @@ declare module "lineadraw" {
|
|
|
1572
2106
|
* },
|
|
1573
2107
|
* });
|
|
1574
2108
|
*/
|
|
1575
|
-
export function defineCommand<
|
|
1576
|
-
|
|
1577
|
-
|
|
2109
|
+
export function defineCommand<
|
|
2110
|
+
const P extends ParamDefs = readonly [],
|
|
2111
|
+
const I extends readonly string[] | CommandInputDefs = readonly [],
|
|
2112
|
+
>(spec: CommandSpec<P, I>): CommandSpec<P, I>;
|
|
1578
2113
|
}
|
|
1579
2114
|
|
|
1580
2115
|
declare module "lineadraw/helpers" {
|
|
@@ -1607,4 +2142,91 @@ declare module "lineadraw/helpers" {
|
|
|
1607
2142
|
export const dot: (a: Vec2, b: Vec2) => number;
|
|
1608
2143
|
/** Rotate vector by `angle` (radians, CCW). */
|
|
1609
2144
|
export const rotate: (p: Vec2, angle: number) => Vec2;
|
|
2145
|
+
/** A point as scripts write it: [x, y] or { x, y }. */
|
|
2146
|
+
export type PointLike = readonly [number, number] | {
|
|
2147
|
+
readonly x: number;
|
|
2148
|
+
readonly y: number;
|
|
2149
|
+
};
|
|
2150
|
+
/** A polygon: one ring of points (implicitly closed), or several rings —
|
|
2151
|
+
* the first the outer boundary, the rest holes. */
|
|
2152
|
+
export type PolygonLike = readonly PointLike[] | readonly (readonly PointLike[])[];
|
|
2153
|
+
/** A result ring: closed implicitly (the first point is not repeated). */
|
|
2154
|
+
export type Ring = {
|
|
2155
|
+
x: number;
|
|
2156
|
+
y: number;
|
|
2157
|
+
}[];
|
|
2158
|
+
/**
|
|
2159
|
+
* The union of polygons: overlapping walls become one outline. Returns
|
|
2160
|
+
* every ring of the result — outer boundaries and holes alike. Draw them as
|
|
2161
|
+
* closed polylines, or hand them all to ONE hatch (`loops: rings.map((r) =>
|
|
2162
|
+
* ({ points: r }))`): hatches fill even-odd, so holes stay holes.
|
|
2163
|
+
*/
|
|
2164
|
+
export const union: (...polygons: PolygonLike[]) => Ring[];
|
|
2165
|
+
/** `subject` minus every clip polygon (openings cut from a wall). Same
|
|
2166
|
+
* result rings as `union`. */
|
|
2167
|
+
export const difference: (subject: PolygonLike, ...clips: PolygonLike[]) => Ring[];
|
|
2168
|
+
/** Where ALL the polygons overlap. Same result rings as `union`. */
|
|
2169
|
+
export const intersection: (...polygons: PolygonLike[]) => Ring[];
|
|
2170
|
+
/** A point as scripts write it: [x, y] or { x, y }. */
|
|
2171
|
+
export type CurvePointLike = readonly [number, number] | {
|
|
2172
|
+
readonly x: number;
|
|
2173
|
+
readonly y: number;
|
|
2174
|
+
};
|
|
2175
|
+
/** A `spline` object input, ready for `document.add` or a block's `draw`. */
|
|
2176
|
+
export type SplineThrough = {
|
|
2177
|
+
type: "spline";
|
|
2178
|
+
degree: number;
|
|
2179
|
+
controlPoints: {
|
|
2180
|
+
x: number;
|
|
2181
|
+
y: number;
|
|
2182
|
+
}[];
|
|
2183
|
+
knots: number[];
|
|
2184
|
+
fitPoints: {
|
|
2185
|
+
x: number;
|
|
2186
|
+
y: number;
|
|
2187
|
+
}[];
|
|
2188
|
+
};
|
|
2189
|
+
/**
|
|
2190
|
+
* The smooth spline passing THROUGH `points` (in order) — what the Spline
|
|
2191
|
+
* tool draws. `degree` 3 (default) or 2; fewer points lower it. Throws on
|
|
2192
|
+
* fewer than two distinct points.
|
|
2193
|
+
*/
|
|
2194
|
+
export const splineThrough: (points: readonly CurvePointLike[], degree?: number) => SplineThrough;
|
|
2195
|
+
/** A loop point: [x, y, bulge?] or { x, y, bulge? } — the bulge (tan of a
|
|
2196
|
+
* quarter of the sweep, as on a polyline) bends the edge to the NEXT point
|
|
2197
|
+
* into an arc. */
|
|
2198
|
+
export type LoopPointLike = readonly [number, number, number?] | {
|
|
2199
|
+
readonly x: number;
|
|
2200
|
+
readonly y: number;
|
|
2201
|
+
readonly bulge?: number;
|
|
2202
|
+
};
|
|
2203
|
+
/** A hatch loop of lines and arcs, ready for a hatch's `loops`. */
|
|
2204
|
+
export type HatchLoopEdges = {
|
|
2205
|
+
edges: ({
|
|
2206
|
+
kind: "line";
|
|
2207
|
+
a: {
|
|
2208
|
+
x: number;
|
|
2209
|
+
y: number;
|
|
2210
|
+
};
|
|
2211
|
+
b: {
|
|
2212
|
+
x: number;
|
|
2213
|
+
y: number;
|
|
2214
|
+
};
|
|
2215
|
+
} | {
|
|
2216
|
+
kind: "arc";
|
|
2217
|
+
center: {
|
|
2218
|
+
x: number;
|
|
2219
|
+
y: number;
|
|
2220
|
+
};
|
|
2221
|
+
radius: number;
|
|
2222
|
+
startAngle: number;
|
|
2223
|
+
endAngle: number;
|
|
2224
|
+
})[];
|
|
2225
|
+
};
|
|
2226
|
+
/**
|
|
2227
|
+
* The closed hatch loop through `points`: straight edges between them, an
|
|
2228
|
+
* arc where a point carries a bulge — the way to hatch a polygon or a
|
|
2229
|
+
* polyline outline (`loops: rings.map(hatchLoop)` for polygon booleans).
|
|
2230
|
+
*/
|
|
2231
|
+
export const hatchLoop: (points: readonly LoopPointLike[]) => HatchLoopEdges;
|
|
1610
2232
|
}
|