@willcgage/module-schematic 0.66.0 → 0.67.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -789,9 +789,11 @@ interface EditorBranch {
789
789
  * draws track to it; the plate is placed first, connected later). */
790
790
  trackId?: string | null;
791
791
  }
792
- /** Endplate B on a loop module: a standard endplate makes the balloon an
793
- * INTERCHANGE (a second route connects at the loop, e.g. Seaford); "none"
794
- * makes it a pure turnback. Non-loop modules always have a real B. */
792
+ /** Endplate B's configuration or `"none"`, meaning **the module has no far
793
+ * endplate**: an end of the line, a pocket, or a loop's pure turnback. On a
794
+ * loop, a standard endplate B instead makes the balloon an INTERCHANGE (a second
795
+ * route connects there, e.g. Seaford). A module presents one conforming face,
796
+ * or two, or more; the standard governs the faces it offers, not how many (#184). */
795
797
  type EndplateBConfig = TrackConfig | "none";
796
798
  interface EditorState {
797
799
  lengthInches: number;
@@ -1667,8 +1669,10 @@ interface ModuleGeometryInput {
1667
1669
  geometryType?: string | null;
1668
1670
  geometryDegrees?: number | null;
1669
1671
  geometryOffsetInches?: number | null;
1670
- /** Axial endplate configs (A first, then B). Missing → single. */
1671
- endplateConfigs?: ("single" | "double" | null | undefined)[];
1672
+ /** Axial endplate configs (A first, then B). Missing → single. `"none"` at B
1673
+ * means the module has no far endplate at all — an end of the line, a pocket,
1674
+ * or a turnback (#184). */
1675
+ endplateConfigs?: ("single" | "double" | "none" | null | undefined)[];
1672
1676
  /** Branch endplates (from the schematic doc, #170), positioned along the
1673
1677
  * mainline axis. */
1674
1678
  branches?: {
package/dist/index.d.ts CHANGED
@@ -789,9 +789,11 @@ interface EditorBranch {
789
789
  * draws track to it; the plate is placed first, connected later). */
790
790
  trackId?: string | null;
791
791
  }
792
- /** Endplate B on a loop module: a standard endplate makes the balloon an
793
- * INTERCHANGE (a second route connects at the loop, e.g. Seaford); "none"
794
- * makes it a pure turnback. Non-loop modules always have a real B. */
792
+ /** Endplate B's configuration or `"none"`, meaning **the module has no far
793
+ * endplate**: an end of the line, a pocket, or a loop's pure turnback. On a
794
+ * loop, a standard endplate B instead makes the balloon an INTERCHANGE (a second
795
+ * route connects there, e.g. Seaford). A module presents one conforming face,
796
+ * or two, or more; the standard governs the faces it offers, not how many (#184). */
795
797
  type EndplateBConfig = TrackConfig | "none";
796
798
  interface EditorState {
797
799
  lengthInches: number;
@@ -1667,8 +1669,10 @@ interface ModuleGeometryInput {
1667
1669
  geometryType?: string | null;
1668
1670
  geometryDegrees?: number | null;
1669
1671
  geometryOffsetInches?: number | null;
1670
- /** Axial endplate configs (A first, then B). Missing → single. */
1671
- endplateConfigs?: ("single" | "double" | null | undefined)[];
1672
+ /** Axial endplate configs (A first, then B). Missing → single. `"none"` at B
1673
+ * means the module has no far endplate at all — an end of the line, a pocket,
1674
+ * or a turnback (#184). */
1675
+ endplateConfigs?: ("single" | "double" | "none" | null | undefined)[];
1672
1676
  /** Branch endplates (from the schematic doc, #170), positioned along the
1673
1677
  * mainline axis. */
1674
1678
  branches?: {
package/dist/index.js CHANGED
@@ -701,18 +701,20 @@ function stateToDoc(state, recordNumber) {
701
701
  ]
702
702
  ) : [
703
703
  { id: "A", label: "West", tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configA }] },
704
- // Non-loop modules always have a real B ("none" never applies).
705
- {
706
- id: "B",
707
- label: "East",
708
- tracks: [
709
- {
710
- trackId: MAIN_TRACK_ID,
711
- lane: 0,
712
- config: state.configB === "none" ? "single" : state.configB
713
- }
714
- ]
715
- }
704
+ // ⚠️ `configB: "none"` means the module HAS NO FAR ENDPLATE, and
705
+ // that is not loop-only (#184). An *end of the line* or a *pocket*
706
+ // presents one conforming face and the track simply stops. The
707
+ // standard governs the ends a module offers for joining; it never
708
+ // required a module to offer two. This used to coerce "none" to
709
+ // "single" and emit a B regardless, so a single-ended module was
710
+ // impossible to author.
711
+ ...state.configB !== "none" ? [
712
+ {
713
+ id: "B",
714
+ label: "East",
715
+ tracks: [{ trackId: MAIN_TRACK_ID, lane: 0, config: state.configB }]
716
+ }
717
+ ] : []
716
718
  ],
717
719
  // Branch endplates C, D, … — junction connections at pos, off one side
718
720
  // (#170). A set can carry several (e.g. a second railroad through).
@@ -1982,7 +1984,7 @@ function deriveEndplatePoses(geo) {
1982
1984
  trackOffsets: offsetsFor(cfg(0), half)
1983
1985
  })
1984
1986
  );
1985
- const noB = geo.geometryType === "dead_end" || geo.loop === true;
1987
+ const noB = geo.geometryType === "dead_end" || geo.loop === true || geo.endplateConfigs?.[1] === "none";
1986
1988
  const end = sectionedEndPose({ sections: geo.sections });
1987
1989
  if (!noB && end) {
1988
1990
  poses.push(