@orbat-mapper/tactical-draw 0.2.0-alpha.24 → 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 +80 -69
  2. package/dist/index.mjs +1210 -1520
  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
  */
@@ -909,15 +914,20 @@ interface GraphicEditSession<G extends Graphic = Graphic> {
909
914
  * transform box's corner-scale / rotate / body-translate gestures, applied to
910
915
  * every member at once. See the Phase 3 ("Multi-select") slice of ADR-0017.
911
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
+ *
912
922
  * The member set is mutable via [[setGraphics]] (#187): members can join or
913
- * leave a live session without a session boundary. Because membership changes
914
- * over the session's lifetime, snapshot arrays are keyed by **measure id**, not
915
- * by index — a snapshot's identity is `snapshot.graphic.id`. `graphics` is a
916
- * live view of the current members' join-time inputs; a `TransformChangeEvent`'s
917
- * arrays are index-aligned with `session.graphics` *as of that emission*. After
918
- * the session settles (`close` / `abort` / an emptying `setGraphics`), every
919
- * method is a silent no-op (except [[onSettled]] — late registration still
920
- * 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).
921
931
  */
922
932
  interface TransformSession {
923
933
  /** Undo/redo for completed gestures within the current membership baseline. */
@@ -928,29 +938,46 @@ interface TransformSession {
928
938
  * adds or removes members. Not stable across membership changes: key
929
939
  * snapshots by `snapshot.graphic.id` rather than relying on index alignment.
930
940
  */
931
- readonly graphics: readonly ControlMeasure[];
941
+ readonly graphics: readonly Graphic[];
942
+ /**
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[];
932
950
  /**
933
- * Live working control points for the member whose id is `graphicId`, or
934
- * `undefined` when no member carries that id. Copy on read.
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.
935
955
  */
936
956
  controlPointsFor(graphicId: string): readonly Position[] | undefined;
937
- /** `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. */
938
958
  readonly dirty: boolean;
939
959
  /**
940
- * Live size anchor, applied group-wide (ADR-0020). `"ground"` bakes each
941
- * 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.
942
964
  * Initialised from `EditManyOptions.sizeAnchor` and mutated by [[setSizeAnchor]].
943
965
  */
944
966
  readonly sizeAnchor: SizeAnchor;
945
- /** 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
+ */
946
972
  setSizeAnchor(anchor: SizeAnchor): void;
947
973
  /**
948
974
  * Replace the member set in place — the primitive behind shift-click toggle,
949
975
  * marquee replace, and single-edit → group folding, without tearing the
950
- * 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:
951
978
  *
952
979
  * - **Retained** members (id in both the current and next sets) carry their
953
- * current working state forward; the passed measure object is ignored for
980
+ * current working state forward; the passed graphic object is ignored for
954
981
  * them. Their `dirty` baseline stays their original join-time input, so a
955
982
  * session that has already moved things stays dirty across the call.
956
983
  * - **Removed** members (id in the current set, absent from the next) are
@@ -969,34 +996,37 @@ interface TransformSession {
969
996
  * undoable within the live session.
970
997
  *
971
998
  * **Return value** — the committed exit snapshots of the members removed *by
972
- * this call*, built exactly like [[close]]'s snapshots (pixel size baked to
973
- * ground unless `sizeAnchor` is `"screen"`, then cloned and rendered); an
974
- * empty array when nothing was removed. The outer `editMany` promise resolves
975
- * with the snapshots of the members in the set **at close time only**.
976
- * Removed members are NOT written back to the graphics layer by the
977
- * controller — the host folds the returned snapshots into its document and
978
- * calls `td.render()`, the same contract as [[close]]. A removed member's
979
- * exit snapshot is also delivered through [[onCommit]] — the recommended
980
- * channel, since it covers this return value and the close-time promise
981
- * resolution through a single subscription. Returns `undefined` (a silent
982
- * 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.
983
1010
  *
984
1011
  * `setGraphics([])` on a live session delegates to [[close]]: it commits every
985
1012
  * current member, resolves the promise with their snapshots, and returns that
986
1013
  * same array. Duplicate ids in `graphics` throw `TypeError` synchronously,
987
- * 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.
988
1018
  */
989
- setGraphics(graphics: readonly ControlMeasure[]): GraphicSnapshot<ControlMeasure>[] | undefined;
1019
+ setGraphics(graphics: readonly Graphic[]): GraphicSnapshot[] | undefined;
990
1020
  /**
991
- * Commit: returns the members' `GraphicSnapshot<ControlMeasure>[]` (the members in the
992
- * set at close time) and resolves the outer `editMany` promise with the same
993
- * 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
994
1024
  * member removed mid-session via [[setGraphics]] is not included here; its exit
995
1025
  * snapshot was returned from that `setGraphics` call (and delivered to
996
1026
  * [[onCommit]] at that time). Returns `undefined` after the session has
997
1027
  * settled (idempotent no-op).
998
1028
  */
999
- close(): GraphicSnapshot<ControlMeasure>[] | undefined;
1029
+ close(): GraphicSnapshot[] | undefined;
1000
1030
  /** Reject the outer `editMany` promise with reason `"session"`. */
1001
1031
  abort(): void;
1002
1032
  /**
@@ -1014,7 +1044,7 @@ interface TransformSession {
1014
1044
  onChange(listener: (event: TransformChangeEvent) => void): () => void;
1015
1045
  /**
1016
1046
  * Subscribe to committed exit-snapshot batches — the single delivery channel
1017
- * for every `GraphicSnapshot<ControlMeasure>[]` this session ever commits (#191). Fires
1047
+ * for every `GraphicSnapshot[]` this session ever commits (#191). Fires
1018
1048
  * exactly once per batch:
1019
1049
  *
1020
1050
  * - The members [[setGraphics]] removes, but only when that call actually
@@ -1039,7 +1069,7 @@ interface TransformSession {
1039
1069
  * session has settled returns a no-op unsubscribe and the listener never
1040
1070
  * fires.
1041
1071
  */
1042
- onCommit(handler: (snapshots: GraphicSnapshot<ControlMeasure>[]) => void): () => void;
1072
+ onCommit(handler: (snapshots: GraphicSnapshot[]) => void): () => void;
1043
1073
  /**
1044
1074
  * Subscribe to the session's settlement — the lifecycle complement of
1045
1075
  * [[onCommit]]: `onCommit` delivers *what* was committed, `onSettled` says
@@ -1081,9 +1111,9 @@ interface TransformChangeEvent {
1081
1111
  /** How this working-copy transition was initiated. */
1082
1112
  readonly source: SessionChangeSource;
1083
1113
  /** Working state after the completed gesture, index-aligned with `session.graphics` as of this emission. */
1084
- readonly graphics: GraphicSnapshot<ControlMeasure>[];
1114
+ readonly graphics: GraphicSnapshot[];
1085
1115
  /** State immediately before this gesture, index-aligned with `session.graphics` as of this emission. */
1086
- readonly previous: GraphicSnapshot<ControlMeasure>[];
1116
+ readonly previous: GraphicSnapshot[];
1087
1117
  /** The session the event belongs to. */
1088
1118
  readonly session: TransformSession;
1089
1119
  /**
@@ -1100,28 +1130,6 @@ interface TransformChangeEvent {
1100
1130
  abort(): void;
1101
1131
  }
1102
1132
  //#endregion
1103
- //#region src/tactical-draw/graphic-transform-session.d.ts
1104
- interface GraphicTransformChangeEvent {
1105
- readonly source: SessionChangeSource;
1106
- readonly graphics: GraphicSnapshot[];
1107
- readonly previous: GraphicSnapshot[];
1108
- readonly session: GraphicTransformSession;
1109
- reject(): void;
1110
- close(): void;
1111
- abort(): void;
1112
- }
1113
- interface GraphicTransformSession {
1114
- readonly history: SessionHistory;
1115
- readonly graphics: readonly Graphic[];
1116
- readonly workingGraphics: readonly Graphic[];
1117
- readonly dirty: boolean;
1118
- close(): GraphicSnapshot[] | undefined;
1119
- abort(): void;
1120
- onChange(listener: (event: GraphicTransformChangeEvent) => void): () => void;
1121
- onCommit(listener: (snapshots: GraphicSnapshot[]) => void): () => void;
1122
- onSettled(listener: (reason: SettleReason) => void): () => void;
1123
- }
1124
- //#endregion
1125
1133
  //#region src/tactical-draw/session.d.ts
1126
1134
  /**
1127
1135
  * Scoped surface delivered via `td.draw({ onSession })` for variable-length
@@ -1359,7 +1367,7 @@ interface EditManyOptions {
1359
1367
  * pointer event is processed. Lets a host wire Done/Cancel/Delete buttons to
1360
1368
  * the active session.
1361
1369
  */
1362
- onSession?: (session: TransformSession | GraphicTransformSession) => void;
1370
+ onSession?: (session: TransformSession) => void;
1363
1371
  /**
1364
1372
  * Default `true`. When `true`, a click on empty map (or on a graphics-layer
1365
1373
  * measure outside the group) closes the active transform. Clicks on preview
@@ -1650,12 +1658,15 @@ declare class TacticalDraw {
1650
1658
  editMany(measures: ControlMeasure[], options?: EditManyOptions): Promise<GraphicSnapshot<ControlMeasure>[]>;
1651
1659
  editMany(graphics: Graphic[], options?: EditManyOptions): Promise<GraphicSnapshot[]>;
1652
1660
  /**
1653
- * One-call selection-sync: mutate a live control-measure-only transform's
1654
- * member set in place, or start a fresh `editMany` when no compatible
1655
- * transform is live (#191). A selection containing a point symbol uses the
1656
- * unified graphic transform session, which does not yet support mutable
1657
- * membership; changing that selection preempts the current session and starts
1658
- * 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).
1659
1670
  *
1660
1671
  * The facade knows session liveness synchronously — `activeTransformSessionRef`
1661
1672
  * is cleared inside the settle path, before control returns to host code — so
@@ -1764,7 +1775,7 @@ declare class TacticalDraw {
1764
1775
  * `TransformSession` isn't part of its `DrawSession | EditSession` union —
1765
1776
  * see `activeTransformSessionRef`. Safe to read after `destroy()`.
1766
1777
  */
1767
- get activeTransformSession(): TransformSession | GraphicTransformSession | null;
1778
+ get activeTransformSession(): TransformSession | null;
1768
1779
  /**
1769
1780
  * Tear down the façade. Releases only layer slots the façade created; host
1770
1781
  * supplied layer ids are left untouched. Safe to call multiple times. After
@@ -1886,4 +1897,4 @@ declare function nearestWorldCopyLng(lng: number, refLng: number): number;
1886
1897
  /** `nearestWorldCopyLng` applied to a lon/lat position. */
1887
1898
  declare function nearestWorldCopyPosition(position: Position, refLng: number): Position;
1888
1899
  //#endregion
1889
- 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 };