@johnmorrisdotca/uchusen-rockets 0.3.0 → 0.4.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +16 -5
  2. package/README.md +241 -4
  3. package/dist/attrs.d.ts +70 -4
  4. package/dist/attrs.js +59 -4
  5. package/dist/build/glb.d.ts +25 -0
  6. package/dist/build/glb.js +14 -0
  7. package/dist/build/index.d.ts +89 -4
  8. package/dist/build/index.js +55 -4
  9. package/dist/build/lineup.d.ts +56 -2
  10. package/dist/build/lineup.js +23 -2
  11. package/dist/builder.d.ts +47 -1
  12. package/dist/builder.js +14 -1
  13. package/dist/crossfade.d.ts +44 -2
  14. package/dist/crossfade.js +44 -2
  15. package/dist/data/credits.d.ts +44 -1
  16. package/dist/data/credits.js +22 -1
  17. package/dist/data/flight-log.d.ts +33 -1
  18. package/dist/data/flight-log.js +22 -1
  19. package/dist/data/flights.d.ts +54 -2
  20. package/dist/data/flights.js +10 -0
  21. package/dist/data/makers.d.ts +21 -0
  22. package/dist/data/makers.js +10 -0
  23. package/dist/data/sources.d.ts +32 -0
  24. package/dist/data/sources.js +10 -0
  25. package/dist/data/types.d.ts +81 -1
  26. package/dist/data/types.js +26 -1
  27. package/dist/element.d.ts +61 -3
  28. package/dist/element.js +50 -3
  29. package/dist/embed.d.ts +110 -5
  30. package/dist/embed.js +88 -5
  31. package/dist/engines.d.ts +86 -4
  32. package/dist/engines.js +75 -4
  33. package/dist/fit.d.ts +68 -0
  34. package/dist/fit.js +13 -0
  35. package/dist/flight.d.ts +134 -9
  36. package/dist/flight.js +122 -9
  37. package/dist/flightbar.d.ts +12 -0
  38. package/dist/flightbar.js +12 -0
  39. package/dist/framing.d.ts +182 -8
  40. package/dist/framing.js +127 -6
  41. package/dist/layout.d.ts +65 -1
  42. package/dist/layout.js +43 -1
  43. package/dist/looks.d.ts +64 -1
  44. package/dist/looks.js +42 -1
  45. package/dist/model/materials.d.ts +32 -0
  46. package/dist/model/materials.js +10 -0
  47. package/dist/model/registry.d.ts +22 -0
  48. package/dist/model/registry.js +22 -0
  49. package/dist/parts.d.ts +33 -1
  50. package/dist/pixels.d.ts +44 -4
  51. package/dist/pixels.js +44 -4
  52. package/dist/react.d.ts +24 -0
  53. package/dist/react.js +13 -0
  54. package/dist/rockets.d.ts +91 -3
  55. package/dist/rockets.js +58 -2
  56. package/dist/spin.d.ts +57 -2
  57. package/dist/spin.js +35 -2
  58. package/dist/tilt.d.ts +48 -4
  59. package/dist/tilt.js +26 -4
  60. package/package.json +10 -5
@@ -5,11 +5,36 @@ import { type PartMesh, type Bounds, type Piece } from "../model/pieces.ts";
5
5
  import type { PartRecord } from "../parts.ts";
6
6
  import { type LitBell } from "../engines.ts";
7
7
  import { type Glb, toGlb } from "./glb.ts";
8
- /** Raised when a description does not fit: its report says why. */
8
+ /**
9
+ * Raised by `build` when a description does not fit. Its `report` says why, in the same words `check` gives.
10
+ *
11
+ * @param report The report of the fit check that failed.
12
+ * @example
13
+ * ```ts
14
+ * import { build, FitError } from "@johnmorrisdotca/uchusen-rockets/build";
15
+ *
16
+ * try {
17
+ * build({ rocket: "starship", variant: "v3", parts: { booster: "starship-v3-ship" } });
18
+ * } catch (error) {
19
+ * if (error instanceof FitError) console.log(error.report.issues[0]?.message);
20
+ * }
21
+ * ```
22
+ */
9
23
  export declare class FitError extends Error {
10
24
  readonly report: FitReport;
11
25
  constructor(report: FitReport);
12
26
  }
27
+ /**
28
+ * One part of a built rocket: its slot, its record, the pieces it is made of, its mesh and its bounds in metres.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { build, type BuiltPart } from "@johnmorrisdotca/uchusen-rockets/build";
33
+ *
34
+ * const first: BuiltPart | undefined = build({ rocket: "falcon-9", variant: "block-5" }).parts[0];
35
+ * console.log(first?.slot, first?.record.name);
36
+ * ```
37
+ */
13
38
  export interface BuiltPart {
14
39
  slot: string;
15
40
  record: PartRecord;
@@ -17,6 +42,17 @@ export interface BuiltPart {
17
42
  mesh: PartMesh;
18
43
  bounds: Bounds;
19
44
  }
45
+ /**
46
+ * What a drawing is asked for: the look, the view, what to show and whether the engines are lit. Anything left out takes its default.
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * import { build, type SvgOptions } from "@johnmorrisdotca/uchusen-rockets/build";
51
+ *
52
+ * const options: SvgOptions = { look: "thick", view: "below", show: "booster" };
53
+ * console.log(build({ rocket: "starship", variant: "v3" }).svg(options).startsWith("<svg"));
54
+ * ```
55
+ */
20
56
  export interface SvgOptions {
21
57
  look?: LookName;
22
58
  view?: ViewName | Angle;
@@ -24,6 +60,18 @@ export interface SvgOptions {
24
60
  /** A flame at each engine that is showing, or as many as a count names for each part. The length is a picture, not a measured flame. Left out, the drawing is unchanged. */
25
61
  engines?: boolean | Readonly<Record<string, number>>;
26
62
  }
63
+ /**
64
+ * A rocket built from a description: the fit report, its parts, and the ways to ask for its size, where each part stands, its lit engines, a `.glb` file and a drawing.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * import { build, type Built } from "@johnmorrisdotca/uchusen-rockets/build";
69
+ *
70
+ * const rocket: Built = build({ rocket: "starship", variant: "v3" });
71
+ * console.log(rocket.shows.join(", "));
72
+ * console.log(rocket.boundsOf("together").max);
73
+ * ```
74
+ */
27
75
  export interface Built {
28
76
  report: FitReport;
29
77
  parts: readonly BuiltPart[];
@@ -44,14 +92,51 @@ export interface Built {
44
92
  /** The drawing, in a look, from an angle. */
45
93
  svg(options?: SvgOptions): string;
46
94
  }
47
- /** What a drawing draws of a part: in a stack, what nests inside the part below is out of sight. */
95
+ /**
96
+ * What a drawing draws of a part: in a stack, what nests inside the part below is out of sight.
97
+ *
98
+ * @param part A built part: its record and its pieces.
99
+ * @param together True when the part stands in a stack, false when it is shown alone.
100
+ * @returns The pieces to draw. In a stack, what nests inside the part below is left out.
101
+ * @example
102
+ * ```ts
103
+ * import { build, drawnPieces } from "@johnmorrisdotca/uchusen-rockets/build";
104
+ *
105
+ * const [first] = build({ rocket: "falcon-9", variant: "block-5" }).parts;
106
+ * if (first) console.log(drawnPieces(first, true).length, drawnPieces(first, false).length);
107
+ * ```
108
+ */
48
109
  export declare function drawnPieces(part: {
49
110
  record: PartRecord;
50
111
  pieces: readonly Piece[];
51
112
  }, together: boolean): readonly Piece[];
52
- /** A rocket from a description. Throws FitError when it does not go together. */
113
+ /**
114
+ * A rocket from a description. Throws FitError when it does not go together.
115
+ *
116
+ * @param description The rocket, its variant and any other part in a slot.
117
+ * @returns The built rocket. It throws a `FitError` when the description does not go together.
118
+ * @example
119
+ * ```ts
120
+ * import { build } from "@johnmorrisdotca/uchusen-rockets/build";
121
+ *
122
+ * const rocket = build({ rocket: "falcon-heavy" });
123
+ * console.log(rocket.report.label, rocket.glb().bytes.length > 1000);
124
+ * ```
125
+ */
53
126
  export declare function build(description: Description): Built;
54
- /** One part on its own, by its id. */
127
+ /**
128
+ * One part on its own, by its id.
129
+ *
130
+ * @param id A part's id, as `PART_ENTRIES` lists it.
131
+ * @returns The part's record and bounds, a function for its `.glb` and one for its drawing. It throws for an id that is not a part.
132
+ * @example
133
+ * ```ts
134
+ * import { buildPart } from "@johnmorrisdotca/uchusen-rockets/build";
135
+ *
136
+ * const raptor = buildPart("raptor-vacuum");
137
+ * console.log(raptor.record.name, raptor.bounds.max);
138
+ * ```
139
+ */
55
140
  export declare function buildPart(id: string): {
56
141
  record: PartRecord;
57
142
  bounds: Bounds;
@@ -9,7 +9,21 @@ import { plumeMarkup } from "../draw/plume.js";
9
9
  import { defsOf, drawPart, perspective } from "../draw/svg.js";
10
10
  import { bellsOf, litBells, pickBells, plumeLength } from "../engines.js";
11
11
  import { toGlb } from "./glb.js";
12
- /** Raised when a description does not fit: its report says why. */
12
+ /**
13
+ * Raised by `build` when a description does not fit. Its `report` says why, in the same words `check` gives.
14
+ *
15
+ * @param report The report of the fit check that failed.
16
+ * @example
17
+ * ```ts
18
+ * import { build, FitError } from "@johnmorrisdotca/uchusen-rockets/build";
19
+ *
20
+ * try {
21
+ * build({ rocket: "starship", variant: "v3", parts: { booster: "starship-v3-ship" } });
22
+ * } catch (error) {
23
+ * if (error instanceof FitError) console.log(error.report.issues[0]?.message);
24
+ * }
25
+ * ```
26
+ */
13
27
  export class FitError extends Error {
14
28
  report;
15
29
  constructor(report) {
@@ -108,21 +122,58 @@ function assembled(report) {
108
122
  },
109
123
  };
110
124
  }
111
- /** What a drawing draws of a part: in a stack, what nests inside the part below is out of sight. */
125
+ /**
126
+ * What a drawing draws of a part: in a stack, what nests inside the part below is out of sight.
127
+ *
128
+ * @param part A built part: its record and its pieces.
129
+ * @param together True when the part stands in a stack, false when it is shown alone.
130
+ * @returns The pieces to draw. In a stack, what nests inside the part below is left out.
131
+ * @example
132
+ * ```ts
133
+ * import { build, drawnPieces } from "@johnmorrisdotca/uchusen-rockets/build";
134
+ *
135
+ * const [first] = build({ rocket: "falcon-9", variant: "block-5" }).parts;
136
+ * if (first) console.log(drawnPieces(first, true).length, drawnPieces(first, false).length);
137
+ * ```
138
+ */
112
139
  export function drawnPieces(part, together) {
113
140
  const joint = part.record.joints.bottom?.y ?? 0;
114
141
  if (!together || joint <= 0)
115
142
  return part.pieces;
116
143
  return part.pieces.filter((piece) => !(piece.kind === "lathe" && piece.under && Math.max(...piece.profile.map(([, y]) => y)) <= joint + 0.01));
117
144
  }
118
- /** A rocket from a description. Throws FitError when it does not go together. */
145
+ /**
146
+ * A rocket from a description. Throws FitError when it does not go together.
147
+ *
148
+ * @param description The rocket, its variant and any other part in a slot.
149
+ * @returns The built rocket. It throws a `FitError` when the description does not go together.
150
+ * @example
151
+ * ```ts
152
+ * import { build } from "@johnmorrisdotca/uchusen-rockets/build";
153
+ *
154
+ * const rocket = build({ rocket: "falcon-heavy" });
155
+ * console.log(rocket.report.label, rocket.glb().bytes.length > 1000);
156
+ * ```
157
+ */
119
158
  export function build(description) {
120
159
  const report = check(description);
121
160
  if (!report.ok)
122
161
  throw new FitError(report);
123
162
  return assembled(report);
124
163
  }
125
- /** One part on its own, by its id. */
164
+ /**
165
+ * One part on its own, by its id.
166
+ *
167
+ * @param id A part's id, as `PART_ENTRIES` lists it.
168
+ * @returns The part's record and bounds, a function for its `.glb` and one for its drawing. It throws for an id that is not a part.
169
+ * @example
170
+ * ```ts
171
+ * import { buildPart } from "@johnmorrisdotca/uchusen-rockets/build";
172
+ *
173
+ * const raptor = buildPart("raptor-vacuum");
174
+ * console.log(raptor.record.name, raptor.bounds.max);
175
+ * ```
176
+ */
126
177
  export function buildPart(id) {
127
178
  const entry = partEntry(id);
128
179
  if (!entry)
@@ -1,6 +1,15 @@
1
1
  import { type ViewName } from "../framing.ts";
2
2
  import { type LookName } from "../looks.ts";
3
- /** Comparison shapes: plain round sizes, for scale, not facts about anything. */
3
+ /**
4
+ * Comparison shapes: plain round sizes, for scale, not facts about anything.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { COMPARES } from "@johnmorrisdotca/uchusen-rockets/build";
9
+ *
10
+ * console.log(COMPARES.person.height, COMPARES.building.height);
11
+ * ```
12
+ */
4
13
  export declare const COMPARES: {
5
14
  readonly person: {
6
15
  readonly name: "A person, 1.8 m";
@@ -13,13 +22,46 @@ export declare const COMPARES: {
13
22
  readonly width: 18;
14
23
  };
15
24
  };
25
+ /**
26
+ * The name of a comparison shape that can stand in a lineup: `person` or `building`.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import type { CompareId } from "@johnmorrisdotca/uchusen-rockets/build";
31
+ *
32
+ * const id: CompareId = "person";
33
+ * console.log(id);
34
+ * ```
35
+ */
16
36
  export type CompareId = keyof typeof COMPARES;
37
+ /**
38
+ * One thing standing in a lineup: its key (`starship:v3` or a comparison's name), its label and its height in metres.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * import { lineupSvg, type LineupItem } from "@johnmorrisdotca/uchusen-rockets/build";
43
+ *
44
+ * const items: LineupItem[] = lineupSvg({ items: ["starship:v3", "person"], unit: 3 }).items;
45
+ * console.log(items.map((item) => item.label));
46
+ * ```
47
+ */
17
48
  export interface LineupItem {
18
49
  /** "starship:v3" or a comparison's name. */
19
50
  key: string;
20
51
  label: string;
21
52
  height: number;
22
53
  }
54
+ /**
55
+ * What a lineup is asked for: the items by key, how many pixels make a metre, and optionally the look, the view, what to show, a ruler and labels.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { lineupSvg, type LineupOptions } from "@johnmorrisdotca/uchusen-rockets/build";
60
+ *
61
+ * const options: LineupOptions = { items: ["starship:v2", "starship:v3", "building"], unit: 3, ruler: true, labels: true };
62
+ * console.log(lineupSvg(options).width);
63
+ * ```
64
+ */
23
65
  export interface LineupOptions {
24
66
  /** "starship:v1,starship:v3,person,building". */
25
67
  items: readonly string[];
@@ -31,7 +73,19 @@ export interface LineupOptions {
31
73
  ruler?: boolean;
32
74
  labels?: boolean;
33
75
  }
34
- /** The whole picture as SVG text. Unknown items are left out. */
76
+ /**
77
+ * The whole picture as SVG text. Unknown items are left out.
78
+ *
79
+ * @param options The items and how they are drawn.
80
+ * @returns The picture as SVG text, the items it holds, and its width and height.
81
+ * @example
82
+ * ```ts
83
+ * import { lineupSvg } from "@johnmorrisdotca/uchusen-rockets/build";
84
+ *
85
+ * const picture = lineupSvg({ items: ["falcon-9:block-5", "falcon-heavy:falcon-heavy", "person"], unit: 4, ruler: true });
86
+ * console.log(picture.items.length, picture.svg.startsWith("<svg"));
87
+ * ```
88
+ */
35
89
  export declare function lineupSvg(options: LineupOptions): {
36
90
  svg: string;
37
91
  items: LineupItem[];
@@ -6,7 +6,16 @@ import { DEFAULT_LOOK, LOOKS } from "../looks.js";
6
6
  import { defsOf, drawPart, orthographic } from "../draw/svg.js";
7
7
  import { MATERIALS } from "../model/materials.js";
8
8
  import { variantOf } from "../rockets.js";
9
- /** Comparison shapes: plain round sizes, for scale, not facts about anything. */
9
+ /**
10
+ * Comparison shapes: plain round sizes, for scale, not facts about anything.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { COMPARES } from "@johnmorrisdotca/uchusen-rockets/build";
15
+ *
16
+ * console.log(COMPARES.person.height, COMPARES.building.height);
17
+ * ```
18
+ */
10
19
  export const COMPARES = {
11
20
  person: { name: "A person, 1.8 m", height: 1.8, width: 0.5 },
12
21
  building: { name: "A ten-storey building, 30 m", height: 30, width: 18 },
@@ -33,7 +42,19 @@ function comparison(id, x, base, unit, line, fill) {
33
42
  floors += `M${n(x)} ${n(base - (h * i) / 10)}h${n(w)}`;
34
43
  return `<rect x="${n(x)}" y="${n(base - h)}" width="${n(w)}" height="${n(h)}" fill="${fill}" stroke="${line}" stroke-width=".9"/><path d="${floors}" stroke="${line}" stroke-width=".35" opacity=".6"/>`;
35
44
  }
36
- /** The whole picture as SVG text. Unknown items are left out. */
45
+ /**
46
+ * The whole picture as SVG text. Unknown items are left out.
47
+ *
48
+ * @param options The items and how they are drawn.
49
+ * @returns The picture as SVG text, the items it holds, and its width and height.
50
+ * @example
51
+ * ```ts
52
+ * import { lineupSvg } from "@johnmorrisdotca/uchusen-rockets/build";
53
+ *
54
+ * const picture = lineupSvg({ items: ["falcon-9:block-5", "falcon-heavy:falcon-heavy", "person"], unit: 4, ruler: true });
55
+ * console.log(picture.items.length, picture.svg.startsWith("<svg"));
56
+ * ```
57
+ */
37
58
  export function lineupSvg(options) {
38
59
  const { items, unit, look = DEFAULT_LOOK, view = "front", ruler = true, labels = true } = options;
39
60
  const angle = VIEWS[cleanView(view)];
package/dist/builder.d.ts CHANGED
@@ -1,10 +1,32 @@
1
1
  import { type Description, type FitReport } from "./fit.ts";
2
+ /**
3
+ * One part a row of the builder offers: its id, its name and the rocket it comes from.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { builderState, type BuilderOption } from "@johnmorrisdotca/uchusen-rockets";
8
+ *
9
+ * const first: BuilderOption | undefined = builderState().rows[0]?.options[0];
10
+ * console.log(first);
11
+ * ```
12
+ */
2
13
  export interface BuilderOption {
3
14
  id: string;
4
15
  name: string;
5
16
  /** Which rocket it comes from, to group a long list. */
6
17
  rocket: string;
7
18
  }
19
+ /**
20
+ * One row of the builder, from the bottom: what it chooses, the parts it offers, the one chosen, and whether the builder made the choice because only one part fits.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * import { builderState, type BuilderRow } from "@johnmorrisdotca/uchusen-rockets";
25
+ *
26
+ * const row: BuilderRow | undefined = builderState().rows[0];
27
+ * console.log(row?.label, row?.chosen, row?.auto);
28
+ * ```
29
+ */
8
30
  export interface BuilderRow {
9
31
  /** What this row chooses. */
10
32
  label: string;
@@ -13,10 +35,34 @@ export interface BuilderRow {
13
35
  /** One answer only: the builder made the choice. */
14
36
  auto: boolean;
15
37
  }
38
+ /**
39
+ * What the builder shows for a set of picks: its rows, the description they make and the fit report for it.
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import { builderState, type BuilderState } from "@johnmorrisdotca/uchusen-rockets";
44
+ *
45
+ * const state: BuilderState = builderState();
46
+ * console.log(state.rows.length, state.report.ok);
47
+ * ```
48
+ */
16
49
  export interface BuilderState {
17
50
  rows: readonly BuilderRow[];
18
51
  description: Description;
19
52
  report: FitReport;
20
53
  }
21
- /** The rows for these picks, from the bottom. A pick that is not offered, for a change lower down or a hostile value, gives way to the part that belongs with what is below, or else the first that fits. */
54
+ /**
55
+ * The rows for these picks, from the bottom. A pick that is not offered, for a change lower down or a hostile value, gives way to the part that belongs with what is below, or else the first that fits.
56
+ *
57
+ * @param picks The part ids chosen so far, row by row from the bottom. Leave it out to start.
58
+ * @returns The rows to show, the description they make and its fit report.
59
+ * @example
60
+ * ```ts
61
+ * import { builderState } from "@johnmorrisdotca/uchusen-rockets";
62
+ *
63
+ * const start = builderState();
64
+ * const next = builderState([start.rows[0]?.chosen ?? ""]);
65
+ * console.log(next.description, next.report.label);
66
+ * ```
67
+ */
22
68
  export declare function builderState(picks?: readonly string[]): BuilderState;
package/dist/builder.js CHANGED
@@ -24,7 +24,20 @@ const fitsOn = (part, below) => {
24
24
  };
25
25
  const REAL_PARTS = () => PART_ENTRIES.map(({ record }) => record).filter((record) => record.trueTo.length > 0);
26
26
  const optionOf = (part) => ({ id: part.id, name: part.name, rocket: ROCKETS[part.rocket]?.name ?? part.rocket });
27
- /** The rows for these picks, from the bottom. A pick that is not offered, for a change lower down or a hostile value, gives way to the part that belongs with what is below, or else the first that fits. */
27
+ /**
28
+ * The rows for these picks, from the bottom. A pick that is not offered, for a change lower down or a hostile value, gives way to the part that belongs with what is below, or else the first that fits.
29
+ *
30
+ * @param picks The part ids chosen so far, row by row from the bottom. Leave it out to start.
31
+ * @returns The rows to show, the description they make and its fit report.
32
+ * @example
33
+ * ```ts
34
+ * import { builderState } from "@johnmorrisdotca/uchusen-rockets";
35
+ *
36
+ * const start = builderState();
37
+ * const next = builderState([start.rows[0]?.chosen ?? ""]);
38
+ * console.log(next.description, next.report.label);
39
+ * ```
40
+ */
28
41
  export function builderState(picks = []) {
29
42
  const every = framesOf();
30
43
  const parts = REAL_PARTS();
@@ -1,6 +1,48 @@
1
- /** The drawing stays at least this long after it first comes on screen. */
1
+ /**
2
+ * The drawing stays at least this long after it first comes on screen.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { DRAWING_HOLD_MS } from "@johnmorrisdotca/uchusen-rockets";
7
+ *
8
+ * console.log(DRAWING_HOLD_MS);
9
+ * ```
10
+ */
2
11
  export declare const DRAWING_HOLD_MS = 1200;
12
+ /**
13
+ * How long the drawing and the 3D view cross-fade, in milliseconds.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { CROSSFADE_MS } from "@johnmorrisdotca/uchusen-rockets";
18
+ *
19
+ * console.log(CROSSFADE_MS);
20
+ * ```
21
+ */
3
22
  export declare const CROSSFADE_MS = 1500;
23
+ /**
24
+ * How long the cross-fade lasts for a reader who asked for reduced motion, in milliseconds.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { REDUCED_FADE_MS } from "@johnmorrisdotca/uchusen-rockets";
29
+ *
30
+ * console.log(REDUCED_FADE_MS);
31
+ * ```
32
+ */
4
33
  export declare const REDUCED_FADE_MS = 400;
5
- /** How long to wait, once the 3D view is ready at `readyAt`, before it takes over from a drawing first seen at `shownAt` (0 under reduced motion). */
34
+ /**
35
+ * How long to wait, once the 3D view is ready at `readyAt`, before it takes over from a drawing first seen at `shownAt` (0 under reduced motion).
36
+ *
37
+ * @param shownAt When the drawing first came on screen, in milliseconds.
38
+ * @param readyAt When the 3D view became ready, on the same clock.
39
+ * @param reducedMotion True when the reader asked for reduced motion.
40
+ * @returns The milliseconds to wait before the 3D view takes over.
41
+ * @example
42
+ * ```ts
43
+ * import { revealDelay } from "@johnmorrisdotca/uchusen-rockets";
44
+ *
45
+ * console.log(revealDelay(0, 300, false), revealDelay(0, 300, true));
46
+ * ```
47
+ */
6
48
  export declare function revealDelay(shownAt: number, readyAt: number, reducedMotion: boolean): number;
package/dist/crossfade.js CHANGED
@@ -1,9 +1,51 @@
1
1
  // The change from a rocket's drawing to its 3D view: the drawing stays a moment even when the 3D view is ready sooner, then a slow crossfade; under reduced motion, a plain short fade. Pure.
2
- /** The drawing stays at least this long after it first comes on screen. */
2
+ /**
3
+ * The drawing stays at least this long after it first comes on screen.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { DRAWING_HOLD_MS } from "@johnmorrisdotca/uchusen-rockets";
8
+ *
9
+ * console.log(DRAWING_HOLD_MS);
10
+ * ```
11
+ */
3
12
  export const DRAWING_HOLD_MS = 1200;
13
+ /**
14
+ * How long the drawing and the 3D view cross-fade, in milliseconds.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { CROSSFADE_MS } from "@johnmorrisdotca/uchusen-rockets";
19
+ *
20
+ * console.log(CROSSFADE_MS);
21
+ * ```
22
+ */
4
23
  export const CROSSFADE_MS = 1500;
24
+ /**
25
+ * How long the cross-fade lasts for a reader who asked for reduced motion, in milliseconds.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import { REDUCED_FADE_MS } from "@johnmorrisdotca/uchusen-rockets";
30
+ *
31
+ * console.log(REDUCED_FADE_MS);
32
+ * ```
33
+ */
5
34
  export const REDUCED_FADE_MS = 400;
6
- /** How long to wait, once the 3D view is ready at `readyAt`, before it takes over from a drawing first seen at `shownAt` (0 under reduced motion). */
35
+ /**
36
+ * How long to wait, once the 3D view is ready at `readyAt`, before it takes over from a drawing first seen at `shownAt` (0 under reduced motion).
37
+ *
38
+ * @param shownAt When the drawing first came on screen, in milliseconds.
39
+ * @param readyAt When the 3D view became ready, on the same clock.
40
+ * @param reducedMotion True when the reader asked for reduced motion.
41
+ * @returns The milliseconds to wait before the 3D view takes over.
42
+ * @example
43
+ * ```ts
44
+ * import { revealDelay } from "@johnmorrisdotca/uchusen-rockets";
45
+ *
46
+ * console.log(revealDelay(0, 300, false), revealDelay(0, 300, true));
47
+ * ```
48
+ */
7
49
  export function revealDelay(shownAt, readyAt, reducedMotion) {
8
50
  if (reducedMotion)
9
51
  return 0;
@@ -1,3 +1,14 @@
1
+ /**
2
+ * The credit for one licensed model: its title, its creator and their page, where it came from, its licence and what this package changed.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { MODEL_CREDITS, type ModelCredit } from "@johnmorrisdotca/uchusen-rockets";
7
+ *
8
+ * const credit: ModelCredit = MODEL_CREDITS["clarence365-block3"];
9
+ * console.log(credit.creator, credit.licence);
10
+ * ```
11
+ */
1
12
  export interface ModelCredit {
2
13
  title: string;
3
14
  creator: string;
@@ -8,6 +19,16 @@ export interface ModelCredit {
8
19
  /** What this package changed. */
9
20
  changes: string;
10
21
  }
22
+ /**
23
+ * Every licensed model this package paints with, by credit id. A painted rocket must carry the credit of the parts that are showing; `embedCode` writes it for you.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { MODEL_CREDITS } from "@johnmorrisdotca/uchusen-rockets";
28
+ *
29
+ * console.log(Object.keys(MODEL_CREDITS).length > 10);
30
+ * ```
31
+ */
11
32
  export declare const MODEL_CREDITS: {
12
33
  readonly "clarence365-block3": {
13
34
  readonly title: "SpaceX Starship Block 3";
@@ -100,6 +121,28 @@ export declare const MODEL_CREDITS: {
100
121
  readonly "nasa-iss": ModelCredit;
101
122
  readonly "nasa-hubble": ModelCredit;
102
123
  };
124
+ /**
125
+ * The id of one model's credit in `MODEL_CREDITS`.
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * import type { CreditId } from "@johnmorrisdotca/uchusen-rockets";
130
+ *
131
+ * const id: CreditId = "clarence365-block3";
132
+ * console.log(id);
133
+ * ```
134
+ */
103
135
  export type CreditId = keyof typeof MODEL_CREDITS;
104
- /** One credit as a line of text. */
136
+ /**
137
+ * One credit as a line of text.
138
+ *
139
+ * @param id The id of a credit in `MODEL_CREDITS`.
140
+ * @returns The credit as one line of text.
141
+ * @example
142
+ * ```ts
143
+ * import { creditLine } from "@johnmorrisdotca/uchusen-rockets";
144
+ *
145
+ * console.log(creditLine("clarence365-block3"));
146
+ * ```
147
+ */
105
148
  export declare function creditLine(id: CreditId): string;
@@ -11,6 +11,16 @@ const nasa = (title, slug, changes) => ({
11
11
  licenceUrl: "https://www.nasa.gov/nasa-brand-center/images-and-media/",
12
12
  changes,
13
13
  });
14
+ /**
15
+ * Every licensed model this package paints with, by credit id. A painted rocket must carry the credit of the parts that are showing; `embedCode` writes it for you.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { MODEL_CREDITS } from "@johnmorrisdotca/uchusen-rockets";
20
+ *
21
+ * console.log(Object.keys(MODEL_CREDITS).length > 10);
22
+ * ```
23
+ */
14
24
  export const MODEL_CREDITS = {
15
25
  "clarence365-block3": {
16
26
  title: "SpaceX Starship Block 3",
@@ -104,7 +114,18 @@ export const MODEL_CREDITS = {
104
114
  "nasa-hubble": nasa("Hubble Space Telescope", "nasa-3d-models-hubble-space-telescope", "A lettered plate painted out of its picture; rescaled to the sourced length; its materials made into one picture."),
105
115
  // new rows go here
106
116
  };
107
- /** One credit as a line of text. */
117
+ /**
118
+ * One credit as a line of text.
119
+ *
120
+ * @param id The id of a credit in `MODEL_CREDITS`.
121
+ * @returns The credit as one line of text.
122
+ * @example
123
+ * ```ts
124
+ * import { creditLine } from "@johnmorrisdotca/uchusen-rockets";
125
+ *
126
+ * console.log(creditLine("clarence365-block3"));
127
+ * ```
128
+ */
108
129
  export function creditLine(id) {
109
130
  const c = MODEL_CREDITS[id];
110
131
  return `"${c.title}" by ${c.creator} (${c.sourceUrl}), ${c.licence} (${c.licenceUrl}). ${c.changes}`;
@@ -1,4 +1,15 @@
1
1
  import type { SourceId } from "./sources.ts";
2
+ /**
3
+ * One flight from the flight log: its name, the rocket and variant that show it, the date, whether the launch succeeded, the source's own words on the outcome, and the source.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * import { FLIGHT_LOG, type LoggedFlight } from "@johnmorrisdotca/uchusen-rockets";
8
+ *
9
+ * const flight: LoggedFlight | undefined = FLIGHT_LOG[0];
10
+ * console.log(flight?.name, flight?.launch);
11
+ * ```
12
+ */
2
13
  export interface LoggedFlight {
3
14
  id: string;
4
15
  name: string;
@@ -13,6 +24,27 @@ export interface LoggedFlight {
13
24
  outcome: string;
14
25
  source: SourceId;
15
26
  }
27
+ /**
28
+ * The flights this package keeps a record of, each from a named source. Use `flightLogOf` for one rocket.
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * import { FLIGHT_LOG } from "@johnmorrisdotca/uchusen-rockets";
33
+ *
34
+ * console.log(FLIGHT_LOG.length > 0);
35
+ * ```
36
+ */
16
37
  export declare const FLIGHT_LOG: readonly LoggedFlight[];
17
- /** A rocket's flights, in order. */
38
+ /**
39
+ * A rocket's flights, in order.
40
+ *
41
+ * @param rocket A rocket's id, such as `falcon-1`.
42
+ * @returns That rocket's logged flights, in order. It is empty for a rocket with none.
43
+ * @example
44
+ * ```ts
45
+ * import { flightLogOf } from "@johnmorrisdotca/uchusen-rockets";
46
+ *
47
+ * console.log(flightLogOf("falcon-1").map((flight) => flight.name));
48
+ * ```
49
+ */
18
50
  export declare const flightLogOf: (rocket: string) => readonly LoggedFlight[];