@instruments/taxonomy 0.1.0 → 0.2.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.ts CHANGED
@@ -1,28 +1,223 @@
1
- interface TaxonomyTerm {
1
+ import { T as Term } from './match-BDI6Evro.js';
2
+ export { A as AlternativeReason, a as AlternativesMatch, b as BundleMatch, c as BundleMember, B as BundleMemberInput, d as BundleRole, C as CanonicalAlternatives, e as CanonicalBundle, D as DEFAULT_BUNDLE_ROLE, E as ExternalMapping, f as ExternalScheme, M as MATCH_TEST_VECTORS, g as MATCH_WEIGHTS, h as MatchStrength, i as MatchTestCandidate, j as MatchTestVector, P as PeriodSpan, R as RelationPredicate, k as RelationRole, S as SearchedWithout, l as SourceBasis, m as StyleKind, n as TermProvenance, o as TermRelation, p as TermStatus, q as TermUsage, U as UsageBand, r as UsageWithheld, s as defineAlternatives, t as defineBundle, u as matchAlternatives, v as matchBundle } from './match-BDI6Evro.js';
3
+ export { AmbiguousAssertionMeaning, AmbiguousCanonicalisation, AssertionAuthority, AssertionMeaning, AssertionPolarity, AssertionProvenance, AssertionRole, AssertionScope, CanonicalisationInput, CanonicalisationVerdict, DeclinedCanonicalisation, PORTABLE_ASSERTION_TEST_VECTORS, PortableAssertionTestVector, PortableTasteAssertion, ProjectContextAssertion, RequirementAssertion, RequirementConstraint, RequirementOperator, ResolvedAssertionMeaning, ResolvedCanonicalisation, TASTE_ASSERTION_CONTRACT_VERSION, TAXONOMY_SNAPSHOT_VERSION, TasteAssertion, UnresolvedAssertionMeaning, UnresolvedCanonicalisation, assertionMeaningFrom } from './taste.js';
4
+
5
+ declare const ELEMENT_TERMS: readonly Term[];
6
+
7
+ /** How a product or material is made; never a claim about its style or visible motif. */
8
+ declare const CONSTRUCTION_TERMS: readonly Term[];
9
+
10
+ /** The deliberately produced state of the exposed surface, not its material or motif. */
11
+ declare const FINISH_TERMS: readonly Term[];
12
+
13
+ /** The supplied physical unit or delivery shape, independent of material and installation pattern. */
14
+ declare const FORMAT_TERMS: readonly Term[];
15
+
16
+ /** Specific substance or material system; narrower than the retrieval-oriented material family. */
17
+ declare const MATERIAL_TERMS: readonly Term[];
18
+
19
+ declare const MOOD_TERMS: readonly Term[];
20
+
21
+ /** Visible surface organisation or motif, independent of the substance carrying it. */
22
+ declare const PATTERN_TERMS: readonly Term[];
23
+
24
+ /** What kind of purchasable or specifiable thing the record describes, independent of substance. */
25
+ declare const PRODUCT_CATEGORY_TERMS: readonly Term[];
26
+
27
+ /** A dimension on which a project can impose a constraint; the assertion carries its operator/value. */
28
+ declare const REQUIREMENT_TERMS: readonly Term[];
29
+
30
+ declare const PALETTE_HUE_TERMS: readonly Term[];
31
+ declare const PALETTE_TEMPERATURE_TERMS: readonly Term[];
32
+ declare const PALETTE_CHARACTER_TERMS: readonly Term[];
33
+ /** The three palette facets, each a closed dictionary in its own right. */
34
+ declare const PALETTE_FACETS: readonly ["hue", "temperature", "character"];
35
+ type PaletteFacet = (typeof PALETTE_FACETS)[number];
36
+
37
+ declare const PERIOD_TERMS: readonly Term[];
38
+ /**
39
+ * The periods a year could belong to, best match first.
40
+ *
41
+ * Sibling spans overlap on purpose - Georgian and Regency genuinely do - so "what period is 1800?"
42
+ * has no single answer in the data. Resolving it lives here rather than in each consumer, because
43
+ * a tie-break reinvented five times is five different answers to one question.
44
+ *
45
+ * THE RANKING, and it is not quite the one TAX-10 proposed. That ticket said prefer the narrowest
46
+ * match, then the un-hedged one. Narrowest-first alone gets 1800 wrong: it returns Regency, whose
47
+ * core is 1811-1820, over Georgian, whose core contains 1800 outright. So the first key is whether
48
+ * the year falls in the period's UNCONTROVERSIAL CORE at all:
49
+ *
50
+ * 1. a core match beats an edge match 1800 is Georgian, only arguably Regency
51
+ * 2. then narrowest core 1815 is Regency, not merely Georgian
52
+ * 3. then `circa: false` dated boundaries beat conventional ones
53
+ * 4. among edge matches, least far outside 1832 is late Georgian, not late Regency
54
+ *
55
+ * `strict` drops the edge matches entirely, which is the difference between "give me a canonical
56
+ * period for this year" and "could this year defensibly be called that".
57
+ */
58
+ declare const periodsAt: (year: number, { strict }?: {
59
+ strict?: boolean | undefined;
60
+ }) => readonly Term[];
61
+ /** The single best period for a year, or undefined when none covers it. */
62
+ declare const periodAt: (year: number, options?: {
63
+ strict?: boolean;
64
+ }) => Term | undefined;
65
+
66
+ declare const PLACE_REGION_TERMS: readonly Term[];
67
+ declare const PLACE_LANDSCAPE_TERMS: readonly Term[];
68
+ declare const PLACE_FACETS: readonly ["region", "landscape"];
69
+ type PlaceFacet = (typeof PLACE_FACETS)[number];
70
+
71
+ declare const STYLE_TERMS: readonly Term[];
72
+
73
+ type StyleId = (typeof STYLE_TERMS)[number]["id"];
74
+ /** At least one anchor, so a key cannot be added and left empty. */
75
+ type Anchors$1 = readonly [string, ...string[]];
76
+ declare const STYLE_ANCHORS: Readonly<Record<string, Anchors$1>>;
77
+ /** The anchors for a style term, or undefined when the id names no style. */
78
+ declare const anchorsFor: (styleId: string) => Anchors$1 | undefined;
79
+
80
+ declare const MOOD_ANCHORS: Readonly<Record<string, Anchors$1>>;
81
+ /** The anchors for a mood term, or undefined when the id names no mood. */
82
+ declare const moodAnchorsFor: (moodId: string) => Anchors$1 | undefined;
83
+
84
+ declare const PERIOD_ANCHORS: Readonly<Record<string, Anchors$1>>;
85
+ /** The anchors for a period term, or undefined when the id names no period. */
86
+ declare const periodAnchorsFor: (periodId: string) => Anchors$1 | undefined;
87
+
88
+ declare const PLACE_ANCHORS: Readonly<Record<string, Anchors$1>>;
89
+ /** The anchors for a place term, or undefined when the id names no place. */
90
+ declare const placeAnchorsFor: (placeId: string) => Anchors$1 | undefined;
91
+
92
+ type Anchors = readonly [string, ...string[]];
93
+ /**
94
+ * Every space anchor, one file per sector so each stays inside the line budget and reads
95
+ * alphabetically within its own group.
96
+ */
97
+ declare const SPACE_ANCHORS: Readonly<Record<string, Anchors>>;
98
+ /** The anchors for a space term, or undefined when the id names no space. */
99
+ declare const spaceAnchorsFor: (spaceId: string) => Anchors | undefined;
100
+
101
+ /**
102
+ * A sector of the SPACE axis: a group of rooms that answer the same programme question.
103
+ *
104
+ * NOT THE SECTOR AXIS, despite the shared word, and the collision is old rather than chosen:
105
+ * these are PROGRAMME groups (where you sleep, wash, eat), while `sector.*` is the market a
106
+ * project serves. The market claim lives on individual terms as `serves` edges - see
107
+ * `marketsServed` below and the register in `space/market-neutral.ts` - and this grouping makes
108
+ * no market claim at all: the "healthcare" file holds `clean_room`, which serves no single
109
+ * market, and the "domestic" file is a programme word, not `sector.residential`.
110
+ *
111
+ * NOT A FACET, and not part of a term's identifier. `space.scullery` is the id whatever sector the
112
+ * scullery is filed under, and re-filing a room must never move its URI. This is a browse
113
+ * structure, and it exists because 197 rooms sorted alphabetically put Operating Room next to
114
+ * Orangery - which is a list you can search and not a list you can read.
115
+ *
116
+ * NOR IS IT `broaderTermId`. A scullery is not a kind of "Dining", so an ISA edge would be false;
117
+ * ADR 0001's relation rule is explicit that subsumption means every instance of the narrower term
118
+ * is an instance of the broader one. Sector is a filing decision about the vocabulary, which is a
119
+ * different kind of claim from a fact about the world, and conflating the two is how hierarchies
120
+ * fill up with things that are not parents.
121
+ */
122
+ interface SpaceSector {
2
123
  id: string;
124
+ /** The reader's word for the sector. */
3
125
  label: string;
4
- /** Explicitly authored Material Semantics id (dashed); absent where upstream authored none. */
5
- semanticId?: string;
6
- /** Parent term id for hierarchical dictionaries (applications). */
7
- broaderTermId?: string;
126
+ terms: readonly Term[];
8
127
  }
128
+ /**
129
+ * The seventeen sectors, in the order a browse page should show them.
130
+ *
131
+ * Ordered by programme rather than alphabetically or by size: where you arrive, where you move,
132
+ * where you sleep, wash, eat, gather, and so on out to the specialised sectors and the unclassified
133
+ * tail. A reader looking for their own corner of the built environment finds it by walking through
134
+ * a building, which is the order this list is in.
135
+ *
136
+ * `SPACE_TERMS` is DERIVED from this, so the flat list and the grouped one cannot disagree. It was
137
+ * previously the other way round - seventeen spreads into one array, with the grouping expressed
138
+ * only by which file a term happened to sit in, where nothing outside the package could read it.
139
+ */
140
+ declare const SPACE_SECTORS: readonly SpaceSector[];
141
+ declare const SPACE_TERMS: readonly Term[];
142
+ /**
143
+ * The markets a space exists to serve, resolved through its ISA chain, or null where no market is
144
+ * part of the room's identity.
145
+ *
146
+ * THE ACCESSOR EXISTS SO THE INHERITANCE IS NOT REINVENTED. A `serves` edge restricts every
147
+ * descendant - each suite is a hotel room, so each suite serves hospitality - and a consumer
148
+ * reading raw edges would see `suite` carrying none and read it as unrestricted. The walk stops at
149
+ * the NEAREST edge-bearing ancestor, because a child's own edges are a narrower claim that
150
+ * replaces the inherited one rather than adding to it (`training_room` serves workplace inside a
151
+ * neutral `classroom`).
152
+ *
153
+ * Null is a reviewed claim, not a gap: the term serves whatever market its project serves. The
154
+ * register in `space/market-neutral.ts` is what makes that true, and the disposition test in
155
+ * `axes.test.ts` is what keeps it true. Answering "what belongs in a residential scheme" is
156
+ * therefore: every term whose result is null or includes "residential" - the neutral majority
157
+ * spans all sectors, and excluding it would fail closed.
158
+ */
159
+ declare const marketsServed: (termId: string) => readonly Sector[] | null;
160
+
161
+ declare const MARKET_NEUTRAL_SPACES: ReadonlySet<string>;
162
+
163
+ declare const TYPOLOGY_TERMS: readonly Term[];
164
+
165
+ declare const AXIS_IDS: readonly ["material_family", "product_category", "material", "pattern", "finish", "format", "construction", "requirement", "sector", "application", "space", "element", "typology", "style", "period", "mood", "palette", "place", "tier", "procurement", "strategy", "form", "density"];
166
+ type AxisId = (typeof AXIS_IDS)[number];
167
+ interface AxisFacet {
168
+ id: string;
169
+ label: string;
170
+ terms: readonly Term[];
171
+ }
172
+ interface Axis {
173
+ id: AxisId;
174
+ label: string;
175
+ /** The question the axis answers, in a reader's words. One line. */
176
+ question: string;
177
+ /**
178
+ * Where this axis ends and its nearest neighbour begins, with the criterion that decides it.
179
+ * Rendered verbatim on the axis page, because a boundary nobody can read is a boundary that gets
180
+ * re-litigated.
181
+ */
182
+ boundary: string;
183
+ /** `authored` ships terms. `declared` is a real question with no terms yet, and says so. */
184
+ status: "authored" | "declared";
185
+ /** Single-dictionary axes carry one facet named for the axis. */
186
+ facets: readonly AxisFacet[];
187
+ /** Why the axis has no terms yet. Present only when status is "declared". */
188
+ gap?: string;
189
+ }
190
+ declare const AXES: readonly Axis[];
191
+ declare const axisById: (id: AxisId) => Axis | undefined;
192
+ /** Every term on an axis, across all its facets. */
193
+ declare const axisTerms: (axis: Axis) => readonly Term[];
194
+
195
+ declare const MATERIAL_FAMILY_TERMS: readonly Term[];
196
+ declare const SECTOR_TERMS: readonly Term[];
197
+ declare const APPLICATION_TERMS: readonly Term[];
198
+
199
+ /**
200
+ * The published term shape. Widened in 0.2.0 from the original three fields to the full `Term` in
201
+ * `./term`, which adds external mappings, provenance, usage bands, supersession and typed
202
+ * relations. Every added field is optional, so this is a backward-compatible minor exactly as the
203
+ * banner above planned: "adding them later is a backward-compatible minor".
204
+ */
205
+ type TaxonomyTerm = Term;
206
+
9
207
  declare const PROVENANCE: {
10
208
  readonly snapshot: "2026-07-08";
11
209
  readonly source: "materialgraph packages/schema/src/registry/value-dictionaries.ts";
12
210
  };
13
- declare const MATERIAL_FAMILY_TERMS: readonly TaxonomyTerm[];
14
211
  declare const MATERIAL_FAMILIES: readonly ["paint", "wall_finish", "wallcovering", "textile", "upholstery", "carpet", "wood", "stone", "tile", "terrazzo", "metal", "glass", "resilient_flooring", "composite", "concrete", "leather", "other"];
15
212
  type MaterialFamily = (typeof MATERIAL_FAMILIES)[number];
16
213
  declare const isMaterialFamily: (value: string) => value is MaterialFamily;
17
- declare const SECTOR_TERMS: readonly TaxonomyTerm[];
18
214
  declare const SECTORS: readonly ["hospitality", "healthcare", "workplace", "residential", "retail", "education", "civic", "mixed_use", "transportation", "other"];
19
215
  type Sector = (typeof SECTORS)[number];
20
216
  declare const isSector: (value: string) => value is Sector;
21
- declare const APPLICATION_TERMS: readonly TaxonomyTerm[];
22
217
  declare const APPLICATIONS: readonly ["wall", "flooring", "ceiling", "bath", "kitchen", "furniture", "lighting", "door", "window", "facade", "countertop", "fireplace", "stair_elevator", "bedding", "decor", "vertically_hanging", "transportation", "pool_fountain", "paving_deck", "partition", "millwork", "cabinetry", "masonry", "roof", "garage", "bar", "awning_umbrella", "recreation_sport", "ornamentation", "aquatic_environments", "wall_backsplash", "wall_upholstered", "wall_wet_shower", "flooring_wet_area", "flooring_entrance", "flooring_radiant_heat", "flooring_or_lab", "flooring_anti_fatigue", "flooring_esd", "flooring_safety_slip", "flooring_raised_access", "flooring_rigid_core", "flooring_dining_area", "flooring_subject_oil", "flooring_walk_in_freezer", "flooring_ramps_inclines", "furniture_seating", "furniture_headboard", "furniture_slipcover", "furniture_systems", "furniture_tackboard", "furniture_throw_pillow", "fireplace_firebox", "fireplace_hearth", "fireplace_mantel", "fireplace_surround", "bedding_bed_scarf", "bedding_sheets", "bedding_skirt", "bedding_bedspread", "bedding_box_spring_cover", "stair_riser", "stair_tread", "stair_railing", "stair_elevator_cladding", "vh_drapery", "vh_privacy_curtain", "vh_shower_curtain", "vh_theatrical_curtain", "vh_window_shade", "transportation_automotive", "transportation_aviation", "transportation_marine", "pool_coping", "pool_decking", "pool_lining", "paving_covered_areas", "paving_patio", "partition_toilet", "masonry_structural", "masonry_veneer", "recreation_gymnasium", "recreation_playground", "recreation_weightlifting", "awning", "tensile_structure", "umbrella", "countertop_chemical_resistant"];
23
218
  type Application = (typeof APPLICATIONS)[number];
24
219
  declare const isApplication: (value: string) => value is Application;
25
220
  declare const APPLICATION_PARENTS: Readonly<Partial<Record<Application, Application>>>;
26
221
  declare const applicationTopLevelOf: (application: Application) => Application;
27
222
 
28
- export { APPLICATIONS, APPLICATION_PARENTS, APPLICATION_TERMS, type Application, MATERIAL_FAMILIES, MATERIAL_FAMILY_TERMS, type MaterialFamily, PROVENANCE, SECTORS, SECTOR_TERMS, type Sector, type TaxonomyTerm, applicationTopLevelOf, isApplication, isMaterialFamily, isSector };
223
+ export { APPLICATIONS, APPLICATION_PARENTS, APPLICATION_TERMS, AXES, AXIS_IDS, type Anchors$1 as Anchors, type Application, type Axis, type AxisFacet, type AxisId, CONSTRUCTION_TERMS, ELEMENT_TERMS, FINISH_TERMS, FORMAT_TERMS, MARKET_NEUTRAL_SPACES, MATERIAL_FAMILIES, MATERIAL_FAMILY_TERMS, MATERIAL_TERMS, MOOD_ANCHORS, MOOD_TERMS, type MaterialFamily, PALETTE_CHARACTER_TERMS, PALETTE_FACETS, PALETTE_HUE_TERMS, PALETTE_TEMPERATURE_TERMS, PATTERN_TERMS, PERIOD_ANCHORS, PERIOD_TERMS, PLACE_ANCHORS, PLACE_FACETS, PLACE_LANDSCAPE_TERMS, PLACE_REGION_TERMS, PRODUCT_CATEGORY_TERMS, PROVENANCE, type PaletteFacet, type PlaceFacet, REQUIREMENT_TERMS, SECTORS, SECTOR_TERMS, SPACE_ANCHORS, SPACE_SECTORS, SPACE_TERMS, STYLE_ANCHORS, STYLE_TERMS, type Sector, type SpaceSector, type StyleId, TYPOLOGY_TERMS, type TaxonomyTerm, Term, anchorsFor, applicationTopLevelOf, axisById, axisTerms, isApplication, isMaterialFamily, isSector, marketsServed, moodAnchorsFor, periodAnchorsFor, periodAt, periodsAt, placeAnchorsFor, spaceAnchorsFor };