@orbat-mapper/tactical-draw 0.2.0-alpha.23 → 0.2.0-alpha.25

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.
Files changed (3) hide show
  1. package/dist/index.d.mts +89 -70
  2. package/dist/index.mjs +1214 -1510
  3. package/package.json +2 -2
package/dist/index.d.mts CHANGED
@@ -220,6 +220,11 @@ interface MapAdapter {
220
220
  toLonLat(coordinate: number[]): Position;
221
221
  fromLonLat(position: Position): number[];
222
222
  getPixelFromCoordinate(position: Position): PixelCoordinate | null;
223
+ /**
224
+ * Convert a viewport pixel to longitude/latitude. Optional so third-party
225
+ * adapters compiled against an older ABI remain valid.
226
+ */
227
+ getCoordinateFromPixel?(pixel: PixelCoordinate): Position | null;
223
228
  /**
224
229
  * Get current viewport size in CSS pixels.
225
230
  */
@@ -264,6 +269,12 @@ interface MapAdapter {
264
269
  */
265
270
  onViewChange(handler: () => void): void;
266
271
  offViewChange(handler: () => void): void;
272
+ /**
273
+ * The engine evaluates the meters→pixels clamp for ground-sized point
274
+ * symbols inside its own style layer, so meters-sized point symbols don't
275
+ * need view-change re-renders for size.
276
+ */
277
+ readonly scalesGroundPointSymbolsNatively?: boolean;
267
278
  /**
268
279
  * Construct an {@link EditPointerDriver} for `TacticalDraw`'s edit
269
280
  * controller. The controller subscribes to pointer events on the returned
@@ -465,7 +476,9 @@ type PointSymbolSize = {
465
476
  unit: "pixels";
466
477
  } | {
467
478
  value: number;
468
- unit: "meters";
479
+ unit: "meters"; /** Floor for the on-screen projection of the ground-based size; none when omitted. */
480
+ minPixels?: number; /** Cap on the on-screen projection of the ground-based size — typically the pixel size the symbol had when anchored to ground; unclamped when omitted. */
481
+ maxPixels?: number;
469
482
  };
470
483
  interface PointSymbolGraphicModifiers {
471
484
  /** Radians clockwise, relative to the point symbol's own orientation. */
@@ -901,15 +914,20 @@ interface GraphicEditSession<G extends Graphic = Graphic> {
901
914
  * transform box's corner-scale / rotate / body-translate gestures, applied to
902
915
  * every member at once. See the Phase 3 ("Multi-select") slice of ADR-0017.
903
916
  *
917
+ * Typed on `Graphic` (ADR-0032): a member is either a `ControlMeasure` or a
918
+ * point symbol, and the two coexist in one session. Hosts narrow with
919
+ * `isPointSymbol`. `controlPointsFor` is a control-measure accessor and returns
920
+ * `undefined` for a point-symbol id.
921
+ *
904
922
  * The member set is mutable via [[setGraphics]] (#187): members can join or
905
- * leave a live session without a session boundary. Because membership changes
906
- * over the session's lifetime, snapshot arrays are keyed by **measure id**, not
907
- * by index — a snapshot's identity is `snapshot.graphic.id`. `graphics` is a
908
- * live view of the current members' join-time inputs; a `TransformChangeEvent`'s
909
- * arrays are index-aligned with `session.graphics` *as of that emission*. After
910
- * the session settles (`close` / `abort` / an emptying `setGraphics`), every
911
- * method is a silent no-op (except [[onSettled]] — late registration still
912
- * delivers, asynchronously).
923
+ * leave a live session without a session boundary — point symbols exactly like
924
+ * measures. Because membership changes over the session's lifetime, snapshot
925
+ * arrays are keyed by **graphic id**, not by index — a snapshot's identity is
926
+ * `snapshot.graphic.id`. `graphics` is a live view of the current members'
927
+ * join-time inputs; a `TransformChangeEvent`'s arrays are index-aligned with
928
+ * `session.graphics` *as of that emission*. After the session settles (`close`
929
+ * / `abort` / an emptying `setGraphics`), every method is a silent no-op
930
+ * (except [[onSettled]] — late registration still delivers, asynchronously).
913
931
  */
914
932
  interface TransformSession {
915
933
  /** Undo/redo for completed gestures within the current membership baseline. */
@@ -920,29 +938,46 @@ interface TransformSession {
920
938
  * adds or removes members. Not stable across membership changes: key
921
939
  * snapshots by `snapshot.graphic.id` rather than relying on index alignment.
922
940
  */
923
- readonly graphics: readonly ControlMeasure[];
941
+ readonly graphics: readonly Graphic[];
924
942
  /**
925
- * Live working control points for the member whose id is `graphicId`, or
926
- * `undefined` when no member carries that id. Copy on read.
943
+ * Live view of the current members' working graphics — a fresh array on each
944
+ * read, in current membership order, reflecting every gesture applied so far.
945
+ * Measures carry their working control points (and any transform-frozen
946
+ * options); point symbols carry their working position, size value, and
947
+ * rotation. Copy on read.
948
+ */
949
+ readonly workingGraphics: readonly Graphic[];
950
+ /**
951
+ * Live working control points for the control-measure member whose id is
952
+ * `graphicId`, or `undefined` when no such member carries that id — including
953
+ * when `graphicId` names a point symbol (which has no control points; read
954
+ * its working `position` from [[workingGraphics]] instead). Copy on read.
927
955
  */
928
956
  controlPointsFor(graphicId: string): readonly Position[] | undefined;
929
- /** `true` when any member's working points differ from its edit-start input beyond tolerance. */
957
+ /** `true` when any member's working state differs from its edit-start input beyond tolerance. */
930
958
  readonly dirty: boolean;
931
959
  /**
932
- * Live size anchor, applied group-wide (ADR-0020). `"ground"` bakes each
933
- * member's pixel size to meters on commit; `"screen"` keeps it zoom-aware.
960
+ * Live size anchor, applied group-wide to the **control-measure** members
961
+ * only (ADR-0020). `"ground"` bakes each measure's pixel size to meters on
962
+ * commit; `"screen"` keeps it zoom-aware. A point symbol's persisted
963
+ * pixel/meter size is its own anchor and is never rewritten by this setting.
934
964
  * Initialised from `EditManyOptions.sizeAnchor` and mutated by [[setSizeAnchor]].
935
965
  */
936
966
  readonly sizeAnchor: SizeAnchor;
937
- /** Switch the group's size anchor (ADR-0020). Takes effect on the next emitted snapshot and on `close()`. */
967
+ /**
968
+ * Switch the group's size anchor (ADR-0020) for its control-measure members.
969
+ * Takes effect on the next emitted snapshot and on `close()`. Point-symbol
970
+ * members are unaffected.
971
+ */
938
972
  setSizeAnchor(anchor: SizeAnchor): void;
939
973
  /**
940
974
  * Replace the member set in place — the primitive behind shift-click toggle,
941
975
  * marquee replace, and single-edit → group folding, without tearing the
942
- * session down (#187). Members are matched to the current set by measure id:
976
+ * session down (#187). Members (measures and point symbols alike) are matched
977
+ * to the current set by graphic id:
943
978
  *
944
979
  * - **Retained** members (id in both the current and next sets) carry their
945
- * current working state forward; the passed measure object is ignored for
980
+ * current working state forward; the passed graphic object is ignored for
946
981
  * them. Their `dirty` baseline stays their original join-time input, so a
947
982
  * session that has already moved things stays dirty across the call.
948
983
  * - **Removed** members (id in the current set, absent from the next) are
@@ -961,34 +996,37 @@ interface TransformSession {
961
996
  * undoable within the live session.
962
997
  *
963
998
  * **Return value** — the committed exit snapshots of the members removed *by
964
- * this call*, built exactly like [[close]]'s snapshots (pixel size baked to
965
- * ground unless `sizeAnchor` is `"screen"`, then cloned and rendered); an
966
- * empty array when nothing was removed. The outer `editMany` promise resolves
967
- * with the snapshots of the members in the set **at close time only**.
968
- * Removed members are NOT written back to the graphics layer by the
969
- * controller — the host folds the returned snapshots into its document and
970
- * calls `td.render()`, the same contract as [[close]]. A removed member's
971
- * exit snapshot is also delivered through [[onCommit]] — the recommended
972
- * channel, since it covers this return value and the close-time promise
973
- * resolution through a single subscription. Returns `undefined` (a silent
974
- * no-op) after the session has settled.
999
+ * this call*, built exactly like [[close]]'s snapshots (a measure's pixel
1000
+ * size baked to ground unless `sizeAnchor` is `"screen"`, a point symbol's
1001
+ * size left untouched, then cloned and rendered); an empty array when nothing
1002
+ * was removed. The outer `editMany` promise resolves with the snapshots of
1003
+ * the members in the set **at close time only**. Removed members are NOT
1004
+ * written back to the graphics layer by the controller — the host folds the
1005
+ * returned snapshots into its document and calls `td.render()`, the same
1006
+ * contract as [[close]]. A removed member's exit snapshot is also delivered
1007
+ * through [[onCommit]] — the recommended channel, since it covers this return
1008
+ * value and the close-time promise resolution through a single subscription.
1009
+ * Returns `undefined` (a silent no-op) after the session has settled.
975
1010
  *
976
1011
  * `setGraphics([])` on a live session delegates to [[close]]: it commits every
977
1012
  * current member, resolves the promise with their snapshots, and returns that
978
1013
  * same array. Duplicate ids in `graphics` throw `TypeError` synchronously,
979
- * without mutating session state.
1014
+ * without mutating session state. A point-symbol member entering a session
1015
+ * whose controller was created without a point-symbol capability throws
1016
+ * `PointSymbolCapabilityRequiredError` synchronously, also without mutating
1017
+ * session state.
980
1018
  */
981
- setGraphics(graphics: readonly ControlMeasure[]): GraphicSnapshot<ControlMeasure>[] | undefined;
1019
+ setGraphics(graphics: readonly Graphic[]): GraphicSnapshot[] | undefined;
982
1020
  /**
983
- * Commit: returns the members' `GraphicSnapshot<ControlMeasure>[]` (the members in the
984
- * set at close time) and resolves the outer `editMany` promise with the same
985
- * value (the same reference — no double-bake of ground-anchored sizes). A
1021
+ * Commit: returns the members' `GraphicSnapshot[]` (the members in the set at
1022
+ * close time) and resolves the outer `editMany` promise with the same value
1023
+ * (the same reference — no double-bake of ground-anchored measure sizes). A
986
1024
  * member removed mid-session via [[setGraphics]] is not included here; its exit
987
1025
  * snapshot was returned from that `setGraphics` call (and delivered to
988
1026
  * [[onCommit]] at that time). Returns `undefined` after the session has
989
1027
  * settled (idempotent no-op).
990
1028
  */
991
- close(): GraphicSnapshot<ControlMeasure>[] | undefined;
1029
+ close(): GraphicSnapshot[] | undefined;
992
1030
  /** Reject the outer `editMany` promise with reason `"session"`. */
993
1031
  abort(): void;
994
1032
  /**
@@ -1006,7 +1044,7 @@ interface TransformSession {
1006
1044
  onChange(listener: (event: TransformChangeEvent) => void): () => void;
1007
1045
  /**
1008
1046
  * Subscribe to committed exit-snapshot batches — the single delivery channel
1009
- * for every `GraphicSnapshot<ControlMeasure>[]` this session ever commits (#191). Fires
1047
+ * for every `GraphicSnapshot[]` this session ever commits (#191). Fires
1010
1048
  * exactly once per batch:
1011
1049
  *
1012
1050
  * - The members [[setGraphics]] removes, but only when that call actually
@@ -1031,7 +1069,7 @@ interface TransformSession {
1031
1069
  * session has settled returns a no-op unsubscribe and the listener never
1032
1070
  * fires.
1033
1071
  */
1034
- onCommit(handler: (snapshots: GraphicSnapshot<ControlMeasure>[]) => void): () => void;
1072
+ onCommit(handler: (snapshots: GraphicSnapshot[]) => void): () => void;
1035
1073
  /**
1036
1074
  * Subscribe to the session's settlement — the lifecycle complement of
1037
1075
  * [[onCommit]]: `onCommit` delivers *what* was committed, `onSettled` says
@@ -1073,9 +1111,9 @@ interface TransformChangeEvent {
1073
1111
  /** How this working-copy transition was initiated. */
1074
1112
  readonly source: SessionChangeSource;
1075
1113
  /** Working state after the completed gesture, index-aligned with `session.graphics` as of this emission. */
1076
- readonly graphics: GraphicSnapshot<ControlMeasure>[];
1114
+ readonly graphics: GraphicSnapshot[];
1077
1115
  /** State immediately before this gesture, index-aligned with `session.graphics` as of this emission. */
1078
- readonly previous: GraphicSnapshot<ControlMeasure>[];
1116
+ readonly previous: GraphicSnapshot[];
1079
1117
  /** The session the event belongs to. */
1080
1118
  readonly session: TransformSession;
1081
1119
  /**
@@ -1092,28 +1130,6 @@ interface TransformChangeEvent {
1092
1130
  abort(): void;
1093
1131
  }
1094
1132
  //#endregion
1095
- //#region src/tactical-draw/graphic-transform-session.d.ts
1096
- interface GraphicTransformChangeEvent {
1097
- readonly source: SessionChangeSource;
1098
- readonly graphics: GraphicSnapshot[];
1099
- readonly previous: GraphicSnapshot[];
1100
- readonly session: GraphicTransformSession;
1101
- reject(): void;
1102
- close(): void;
1103
- abort(): void;
1104
- }
1105
- interface GraphicTransformSession {
1106
- readonly history: SessionHistory;
1107
- readonly graphics: readonly Graphic[];
1108
- readonly workingGraphics: readonly Graphic[];
1109
- readonly dirty: boolean;
1110
- close(): GraphicSnapshot[] | undefined;
1111
- abort(): void;
1112
- onChange(listener: (event: GraphicTransformChangeEvent) => void): () => void;
1113
- onCommit(listener: (snapshots: GraphicSnapshot[]) => void): () => void;
1114
- onSettled(listener: (reason: SettleReason) => void): () => void;
1115
- }
1116
- //#endregion
1117
1133
  //#region src/tactical-draw/session.d.ts
1118
1134
  /**
1119
1135
  * Scoped surface delivered via `td.draw({ onSession })` for variable-length
@@ -1351,7 +1367,7 @@ interface EditManyOptions {
1351
1367
  * pointer event is processed. Lets a host wire Done/Cancel/Delete buttons to
1352
1368
  * the active session.
1353
1369
  */
1354
- onSession?: (session: TransformSession | GraphicTransformSession) => void;
1370
+ onSession?: (session: TransformSession) => void;
1355
1371
  /**
1356
1372
  * Default `true`. When `true`, a click on empty map (or on a graphics-layer
1357
1373
  * measure outside the group) closes the active transform. Clicks on preview
@@ -1642,12 +1658,15 @@ declare class TacticalDraw {
1642
1658
  editMany(measures: ControlMeasure[], options?: EditManyOptions): Promise<GraphicSnapshot<ControlMeasure>[]>;
1643
1659
  editMany(graphics: Graphic[], options?: EditManyOptions): Promise<GraphicSnapshot[]>;
1644
1660
  /**
1645
- * One-call selection-sync: mutate a live control-measure-only transform's
1646
- * member set in place, or start a fresh `editMany` when no compatible
1647
- * transform is live (#191). A selection containing a point symbol uses the
1648
- * unified graphic transform session, which does not yet support mutable
1649
- * membership; changing that selection preempts the current session and starts
1650
- * a new one, resetting its box angle and other session-local state.
1661
+ * One-call selection-sync: mutate a live transform's member set in place, or
1662
+ * start a fresh `editMany` when none is live (#191). Any mix of control
1663
+ * measures and point symbols is handled by the one Graphic-typed session
1664
+ * (ADR-0032): a point symbol joins or leaves the live session exactly like a
1665
+ * measure via `setGraphics`, preserving box angle, size anchor, and history
1666
+ * baseline — no preempt-and-restart. A point symbol in the selection with no
1667
+ * point-symbol capability configured throws `PointSymbolCapabilityRequiredError`
1668
+ * synchronously (from `setGraphics` on a live session, or from `editMany` on a
1669
+ * fresh one).
1651
1670
  *
1652
1671
  * The facade knows session liveness synchronously — `activeTransformSessionRef`
1653
1672
  * is cleared inside the settle path, before control returns to host code — so
@@ -1756,7 +1775,7 @@ declare class TacticalDraw {
1756
1775
  * `TransformSession` isn't part of its `DrawSession | EditSession` union —
1757
1776
  * see `activeTransformSessionRef`. Safe to read after `destroy()`.
1758
1777
  */
1759
- get activeTransformSession(): TransformSession | GraphicTransformSession | null;
1778
+ get activeTransformSession(): TransformSession | null;
1760
1779
  /**
1761
1780
  * Tear down the façade. Releases only layer slots the façade created; host
1762
1781
  * supplied layer ids are left untouched. Safe to call multiple times. After
@@ -1878,4 +1897,4 @@ declare function nearestWorldCopyLng(lng: number, refLng: number): number;
1878
1897
  /** `nearestWorldCopyLng` applied to a lon/lat position. */
1879
1898
  declare function nearestWorldCopyPosition(position: Position, refLng: number): Position;
1880
1899
  //#endregion
1881
- export { BaseMapAdapter, type CombinedAbort, DEFAULT_LABEL_SIZE_PIXELS, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, type DrawMeasureDraft, type DrawOptions, type DrawPointSymbolDraft, type DrawSession, type EditChangeEvent, type EditManyOptions, type EditMode, type EditOptions, type EditPointerDriver, type EditSession, type FeatureOps, type Graphic, type GraphicEditChangeEvent, type GraphicEditSession, type GraphicGeometrySnappingOptions, type GraphicRender, type GraphicSnapshot, type GraphicTransformChangeEvent, type GraphicTransformSession, type GuideStyle, type HandleStyle, type IconResource, type InteractionHit, type InteractionStyle, type LayerId, type MapAdapter, type MapCursor, type MapEvent, type MapEventHandler, type NativeEventEntry, type PickEvent, type PickHandler, type PickOptions, type PixelCoordinate, type PointSymbol, type PointSymbolAnchor, type PointSymbolCapability, PointSymbolCapabilityRequiredError, type PointSymbolColors, type PointSymbolFootprint, type PointSymbolGraphicModifiers, type PointSymbolRender, type PointSymbolSize, type PointSymbolStyle, type PointerCallback, PointerCallbackHub, type PointerEventInfo, type SessionChangeSource, type SessionHistory, type SessionHistoryState, type SettleReason, type SizeAnchor, type SnapCandidate, type SnapCandidateProvider, type SnapCandidateRequest, type SnapInteraction, type SnapResult, type SnappingOptions, type StyleOptions, TOUCH_HIT_TOLERANCE_PX, TacticalDraw, TacticalDrawAbortError, type TacticalDrawAbortReason, TacticalDrawDestroyedError, type TacticalDrawLayerOptions, type TacticalDrawOptions, type TextStyleOptions, type ToPixel, type TransformBox, type TransformChangeEvent, type TransformSession, bindAbortable, clonePointSymbol, coerceHandleStyle, combineWithHostSignal, getSizeAnchor, hitTestFeature, hitTestIconFeature, ignoreAbort, isPointSymbol, isTacticalDrawAbortError, nearestWorldCopyLng, nearestWorldCopyPosition, pickHitTolerance, pointSymbolFootprint, resolveGroundTextSizePixels, tryControlMeasureIdFromFeature };
1900
+ export { BaseMapAdapter, type CombinedAbort, DEFAULT_LABEL_SIZE_PIXELS, DEFAULT_TEXT_SIZE_MAX_PIXELS, DEFAULT_TEXT_SIZE_MIN_PIXELS, type DrawMeasureDraft, type DrawOptions, type DrawPointSymbolDraft, type DrawSession, type EditChangeEvent, type EditManyOptions, type EditMode, type EditOptions, type EditPointerDriver, type EditSession, type FeatureOps, type Graphic, type GraphicEditChangeEvent, type GraphicEditSession, type GraphicGeometrySnappingOptions, type GraphicRender, type GraphicSnapshot, type GuideStyle, type HandleStyle, type IconResource, type InteractionHit, type InteractionStyle, type LayerId, type MapAdapter, type MapCursor, type MapEvent, type MapEventHandler, type NativeEventEntry, type PickEvent, type PickHandler, type PickOptions, type PixelCoordinate, type PointSymbol, type PointSymbolAnchor, type PointSymbolCapability, PointSymbolCapabilityRequiredError, type PointSymbolColors, type PointSymbolFootprint, type PointSymbolGraphicModifiers, type PointSymbolRender, type PointSymbolSize, type PointSymbolStyle, type PointerCallback, PointerCallbackHub, type PointerEventInfo, type SessionChangeSource, type SessionHistory, type SessionHistoryState, type SettleReason, type SizeAnchor, type SnapCandidate, type SnapCandidateProvider, type SnapCandidateRequest, type SnapInteraction, type SnapResult, type SnappingOptions, type StyleOptions, TOUCH_HIT_TOLERANCE_PX, TacticalDraw, TacticalDrawAbortError, type TacticalDrawAbortReason, TacticalDrawDestroyedError, type TacticalDrawLayerOptions, type TacticalDrawOptions, type TextStyleOptions, type ToPixel, type TransformBox, type TransformChangeEvent, type TransformSession, bindAbortable, clonePointSymbol, coerceHandleStyle, combineWithHostSignal, getSizeAnchor, hitTestFeature, hitTestIconFeature, ignoreAbort, isPointSymbol, isTacticalDrawAbortError, nearestWorldCopyLng, nearestWorldCopyPosition, pickHitTolerance, pointSymbolFootprint, resolveGroundTextSizePixels, tryControlMeasureIdFromFeature };