@instruments/materialgraph 0.1.0 → 0.3.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/by-spec-types.d.ts +73 -0
- package/by-spec-types.js +7 -0
- package/client.d.ts +186 -7
- package/client.js +242 -125
- package/codes-client.d.ts +82 -0
- package/codes-client.js +73 -0
- package/codes-types.d.ts +238 -0
- package/codes-types.js +1 -0
- package/colour-aggregate-types.d.ts +93 -0
- package/colour-aggregate-types.js +1 -0
- package/colours-client.d.ts +52 -0
- package/colours-client.js +39 -0
- package/composition-types.d.ts +343 -0
- package/composition-types.js +10 -0
- package/http-transport.d.ts +74 -0
- package/http-transport.js +201 -0
- package/index.d.ts +19 -0
- package/index.js +9 -0
- package/match-stream-types.d.ts +150 -0
- package/match-stream-types.js +28 -0
- package/match-stream.d.ts +22 -0
- package/match-stream.js +280 -0
- package/material-block-types.d.ts +23 -2
- package/material-types.d.ts +92 -0
- package/material-types.js +1 -0
- package/ndjson.d.ts +46 -0
- package/ndjson.js +103 -0
- package/operations.d.ts +6 -2
- package/operations.js +30 -2
- package/package.json +1 -1
- package/project-types.d.ts +67 -0
- package/project-types.js +16 -0
- package/projects.d.ts +13 -0
- package/projects.js +46 -0
- package/run-events.d.ts +82 -0
- package/run-events.js +29 -0
- package/run-types.d.ts +266 -0
- package/run-types.js +6 -0
- package/runs.d.ts +84 -0
- package/runs.js +253 -0
- package/schedule-types.d.ts +88 -0
- package/schedule-types.js +12 -0
- package/search-refinement-types.d.ts +26 -1
- package/search-result-validation.d.ts +27 -0
- package/search-result-validation.js +174 -0
- package/source-material-validation.d.ts +3 -0
- package/source-material-validation.js +109 -0
- package/spec-types.d.ts +82 -0
- package/spec-types.js +44 -0
- package/specifications.d.ts +72 -0
- package/specifications.js +82 -0
- package/sse.d.ts +35 -0
- package/sse.js +147 -0
- package/types.d.ts +204 -77
- package/validation.d.ts +119 -0
- package/validation.js +241 -0
package/codes-types.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand-mirrored wire types for the advisory building-code surface
|
|
3
|
+
* (`GET /api/v1/codes/context`, `GET /api/v1/codes/requirements`,
|
|
4
|
+
* `POST /api/v1/codes/advisory` — MG-433, MG-674).
|
|
5
|
+
*
|
|
6
|
+
* Like the rest of the SDK these interfaces have NO runtime dependency on any
|
|
7
|
+
* `@materialgraph/*` package — they mirror the `codeAdvisoryInputSchema` /
|
|
8
|
+
* `codeAdvisoryResultSchema` Zod contracts the route is built from. Response
|
|
9
|
+
* enums follow the SDK's TOLERANT-PARSING contract (widened with `OpenEnum` so a
|
|
10
|
+
* new server value still type-checks); `requirement.scale` is an open IBC-scale
|
|
11
|
+
* id and `caveat` is the AHJ advisory sentence, both read as plain strings.
|
|
12
|
+
*
|
|
13
|
+
* ADVISORY ONLY: every verdict and the envelope carry the AHJ caveat — this is
|
|
14
|
+
* model code as adopted, never a legal determination.
|
|
15
|
+
*/
|
|
16
|
+
import type { OpenEnum } from "./types.js";
|
|
17
|
+
/**
|
|
18
|
+
* Badge a bounded set of materials against the code-requirement registry for one
|
|
19
|
+
* (jurisdiction, occupancy, space, sprinklered) context. `results` preserve
|
|
20
|
+
* input order and cardinality (duplicate ids are echoed).
|
|
21
|
+
*/
|
|
22
|
+
export interface CodeContextRequest {
|
|
23
|
+
/** A seeded jurisdiction id (e.g. `"us-tx"`); an unknown id is a 400. */
|
|
24
|
+
jurisdictionId: string;
|
|
25
|
+
/**
|
|
26
|
+
* The IBC occupancy group for the space (e.g. `"I-2"` hospital, `"A-2"`
|
|
27
|
+
* restaurant). Required unless `roomType` correlates to one.
|
|
28
|
+
*/
|
|
29
|
+
occupancyGroup?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The finish location: `"corridors"`, `"exit_stairs_passageways"`, or
|
|
32
|
+
* `"rooms_enclosed_spaces"`. Required unless `roomType` correlates to one.
|
|
33
|
+
*/
|
|
34
|
+
spaceType?: string;
|
|
35
|
+
/**
|
|
36
|
+
* An `ms_room` term id (e.g. `"hotel_room"`) to correlate the regulatory axes
|
|
37
|
+
* from. Explicit `occupancyGroup` / `spaceType` always win. A room that
|
|
38
|
+
* correlates to neither axis is a 400 naming the axis — never a guess.
|
|
39
|
+
*/
|
|
40
|
+
roomType?: string;
|
|
41
|
+
/** Whether the space is sprinklered — relaxes several fire-finish floors. No default. */
|
|
42
|
+
sprinklered: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface CodeAdvisoryInput extends CodeContextRequest {
|
|
45
|
+
/** 1–100 opaque variant ids to badge, echoed back in `results` in this exact order. */
|
|
46
|
+
variantIds: string[];
|
|
47
|
+
}
|
|
48
|
+
/** The resolved jurisdiction the verdicts were evaluated against. */
|
|
49
|
+
export interface CodeAdvisoryJurisdiction {
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
codeFamily: string;
|
|
53
|
+
edition: string;
|
|
54
|
+
adoptionNote: string;
|
|
55
|
+
}
|
|
56
|
+
/** The echoed evaluation context (the space the badges apply to). */
|
|
57
|
+
export interface CodeAdvisoryContext {
|
|
58
|
+
occupancyGroup: string;
|
|
59
|
+
spaceType: string;
|
|
60
|
+
sprinklered: boolean;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* What one material is, and therefore what it was held to. `dimensions` are the
|
|
64
|
+
* regulatory dimensions the material can be scored on; `basis` names which
|
|
65
|
+
* source(s) produced them: a mapped `productTypeId`, `applicationIds`, both, or
|
|
66
|
+
* `unresolved` when neither yielded anything. `unresolved` does NOT mean the
|
|
67
|
+
* material is answerable for nothing — it means we could not tell what the
|
|
68
|
+
* material is, so every requirement the space imposes was scored against it and
|
|
69
|
+
* `notApplicable` on the result is empty. That is a coverage gap in the
|
|
70
|
+
* product-type/application map, not a narrow material. A short `requirements`
|
|
71
|
+
* list under `product_type` / `application` / `both` is a genuine intersection;
|
|
72
|
+
* a full list under `unresolved` is the map falling short.
|
|
73
|
+
*/
|
|
74
|
+
export interface MaterialCodeProfile {
|
|
75
|
+
/** The variant's accepted primary product type, or null if it has none. */
|
|
76
|
+
productTypeId: string | null;
|
|
77
|
+
/** The variant's accepted `applications` terms, as stored. */
|
|
78
|
+
applicationIds: string[];
|
|
79
|
+
/** Regulatory dimensions this material can be held to. Empty ONLY when `basis` is `unresolved`. */
|
|
80
|
+
dimensions: OpenEnum<"fire" | "floor" | "slip" | "decorative">[];
|
|
81
|
+
basis: OpenEnum<"product_type" | "application" | "both" | "unresolved">;
|
|
82
|
+
}
|
|
83
|
+
/** Why one requirement the space imposes was excluded from this material's `requirements`. */
|
|
84
|
+
export interface CodeRequirementExclusion {
|
|
85
|
+
requirementId: string;
|
|
86
|
+
dimension: OpenEnum<"fire" | "floor" | "slip" | "decorative">;
|
|
87
|
+
reason: OpenEnum<"not_a_material_dimension">;
|
|
88
|
+
/** One readable line, e.g. `"Slip resistance is not a dimension wallcovering answers for."`. */
|
|
89
|
+
detail: string;
|
|
90
|
+
}
|
|
91
|
+
/** The threshold one requirement imposes: a class floor and/or a numeric floor. */
|
|
92
|
+
export interface CodeRequirementThreshold {
|
|
93
|
+
/** The IBC classification scale this requirement is measured on (open id). */
|
|
94
|
+
scale: string;
|
|
95
|
+
/** The minimum acceptable class on `scale`, or null when only a numeric floor applies. */
|
|
96
|
+
minClass: string | null;
|
|
97
|
+
/** A numeric floor (e.g. a DCOF minimum), or null when only a class floor applies. */
|
|
98
|
+
numericFloor: {
|
|
99
|
+
metric: string;
|
|
100
|
+
value: number;
|
|
101
|
+
unit: string;
|
|
102
|
+
} | null;
|
|
103
|
+
}
|
|
104
|
+
/** The accepted fact a verdict was decided from (null when the material carried none). */
|
|
105
|
+
export interface CodeRequirementEvidence {
|
|
106
|
+
attributeId: OpenEnum<"fire_classifications" | "slip_resistance_dcof">;
|
|
107
|
+
value: string;
|
|
108
|
+
confidence: number | null;
|
|
109
|
+
sourceBasis: string | null;
|
|
110
|
+
}
|
|
111
|
+
/** One requirement badged against one material. */
|
|
112
|
+
export interface CodeRequirementVerdict {
|
|
113
|
+
requirementId: string;
|
|
114
|
+
dimension: OpenEnum<"fire" | "floor" | "slip" | "decorative">;
|
|
115
|
+
section: string;
|
|
116
|
+
requirement: CodeRequirementThreshold;
|
|
117
|
+
/** `meets` / `shortfall` / `unknown` — `unknown` when no defensible fact maps onto `scale`. */
|
|
118
|
+
verdict: OpenEnum<"meets" | "shortfall" | "unknown">;
|
|
119
|
+
evidence: CodeRequirementEvidence | null;
|
|
120
|
+
/** The AHJ advisory caveat — model code as adopted, never a legal determination. */
|
|
121
|
+
caveat: string;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* One candidate's requirement verdicts folded into a single status and sentence.
|
|
125
|
+
* A shortfall outranks an unknown, and an unknown NEVER rolls up to a pass:
|
|
126
|
+
* `not_applicable` (nothing applied) is deliberately distinct from `meets`.
|
|
127
|
+
*/
|
|
128
|
+
export interface CodeAdvisorySummary {
|
|
129
|
+
status: OpenEnum<"meets" | "shortfall" | "unverified" | "not_applicable">;
|
|
130
|
+
/** One deterministic sentence naming what failed, e.g. `"Falls short on fire for A-2 corridors."`. */
|
|
131
|
+
headline: string;
|
|
132
|
+
shortfallDimensions: OpenEnum<"fire" | "floor" | "slip" | "decorative">[];
|
|
133
|
+
unverifiedDimensions: OpenEnum<"fire" | "floor" | "slip" | "decorative">[];
|
|
134
|
+
}
|
|
135
|
+
/** Per-variant advisory outcome, in input order. */
|
|
136
|
+
export interface CodeAdvisoryVariantResult {
|
|
137
|
+
variantId: string;
|
|
138
|
+
/** `evaluated` when the id resolved; `unknown_variant` (with `requirements: []`) when it did not. */
|
|
139
|
+
state: OpenEnum<"evaluated" | "unknown_variant">;
|
|
140
|
+
/** What this material is and what it was scored against. Null only for `state: "unknown_variant"`. */
|
|
141
|
+
material: MaterialCodeProfile | null;
|
|
142
|
+
/** Verdicts for the requirements this material is answerable for — the answerable subset only. */
|
|
143
|
+
requirements: CodeRequirementVerdict[];
|
|
144
|
+
/** Requirements the space imposes that this material cannot answer. Empty when nothing was excluded. */
|
|
145
|
+
notApplicable: CodeRequirementExclusion[];
|
|
146
|
+
/** The rolled-up card, or null for an id that resolved to nothing. */
|
|
147
|
+
summary: CodeAdvisorySummary | null;
|
|
148
|
+
}
|
|
149
|
+
/** The `POST /api/v1/codes/advisory` envelope — per-variant, per-requirement verdicts. */
|
|
150
|
+
export interface CodeAdvisoryResponse {
|
|
151
|
+
jurisdiction: CodeAdvisoryJurisdiction;
|
|
152
|
+
/** The context AS SUPPLIED, echoed verbatim. */
|
|
153
|
+
context: CodeAdvisoryContext;
|
|
154
|
+
/** The canonical axes the registry was queried with, and where they came from. */
|
|
155
|
+
resolvedContext: ResolvedCodeContext;
|
|
156
|
+
/** The AHJ advisory caveat, at the envelope level too. */
|
|
157
|
+
caveat: string;
|
|
158
|
+
results: CodeAdvisoryVariantResult[];
|
|
159
|
+
}
|
|
160
|
+
/** Where a resolved axis came from: stated outright, or correlated from a room type. */
|
|
161
|
+
export interface ResolvedCodeContext {
|
|
162
|
+
jurisdictionId: string;
|
|
163
|
+
occupancyGroup: string;
|
|
164
|
+
/** The canonical finish-location term id the registry was queried with. */
|
|
165
|
+
spaceType: string;
|
|
166
|
+
sprinklered: boolean;
|
|
167
|
+
basis: OpenEnum<"explicit" | "derived_from_room">;
|
|
168
|
+
/** The `ms_room` term the axes were correlated from, or null. */
|
|
169
|
+
roomType: string | null;
|
|
170
|
+
}
|
|
171
|
+
/** How far a jurisdiction's rows have been reviewed against that AHJ's own tables. */
|
|
172
|
+
export type CodeCoverageTier = OpenEnum<"thorough" | "model_baseline">;
|
|
173
|
+
export interface CodeJurisdictionSummary {
|
|
174
|
+
id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
codeFamily: string;
|
|
177
|
+
edition: string;
|
|
178
|
+
coverage: CodeCoverageTier;
|
|
179
|
+
/** One honest line on how the model code actually applies in this jurisdiction. */
|
|
180
|
+
adoptionNote: string;
|
|
181
|
+
}
|
|
182
|
+
/** The `GET /api/v1/codes/context` envelope — the vocabulary for stating a context. */
|
|
183
|
+
export interface CodeContextResponse {
|
|
184
|
+
jurisdictions: CodeJurisdictionSummary[];
|
|
185
|
+
occupancyGroups: {
|
|
186
|
+
id: string;
|
|
187
|
+
label: string;
|
|
188
|
+
}[];
|
|
189
|
+
finishLocations: {
|
|
190
|
+
id: string;
|
|
191
|
+
label: string;
|
|
192
|
+
shortLabel: string;
|
|
193
|
+
}[];
|
|
194
|
+
dimensions: {
|
|
195
|
+
id: OpenEnum<"fire" | "floor" | "slip" | "decorative">;
|
|
196
|
+
label: string;
|
|
197
|
+
description: string;
|
|
198
|
+
/** The MaterialGraph attribute this dimension is scored against. */
|
|
199
|
+
attributeId: string;
|
|
200
|
+
}[];
|
|
201
|
+
scales: {
|
|
202
|
+
id: string;
|
|
203
|
+
label: string;
|
|
204
|
+
detail: string;
|
|
205
|
+
/** Ordered BEST FIRST: index 0 outranks index 1. */
|
|
206
|
+
classes: string[];
|
|
207
|
+
}[];
|
|
208
|
+
/** `ms_room` → regulatory axes. `null` where the registry refuses to correlate. */
|
|
209
|
+
roomCorrelations: {
|
|
210
|
+
roomType: string;
|
|
211
|
+
label: string;
|
|
212
|
+
occupancyGroup: string | null;
|
|
213
|
+
finishLocation: string | null;
|
|
214
|
+
}[];
|
|
215
|
+
/** The AHJ advisory caveat. */
|
|
216
|
+
caveat: string;
|
|
217
|
+
}
|
|
218
|
+
/** One requirement a context imposes, independent of any candidate material. */
|
|
219
|
+
export interface CodeRequirementListing {
|
|
220
|
+
requirementId: string;
|
|
221
|
+
dimension: OpenEnum<"fire" | "floor" | "slip" | "decorative">;
|
|
222
|
+
/** The code section this demand is cited from. */
|
|
223
|
+
section: string;
|
|
224
|
+
attributeId: string;
|
|
225
|
+
requirement: CodeRequirementThreshold;
|
|
226
|
+
/** One readable line, e.g. `"Class A or better · ASTM E84 / UL 723"`. */
|
|
227
|
+
label: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* The `GET /api/v1/codes/requirements` envelope. An empty `requirements` array
|
|
231
|
+
* means the registry holds nothing for this context — it is not a pass.
|
|
232
|
+
*/
|
|
233
|
+
export interface CodeRequirementsResponse {
|
|
234
|
+
jurisdiction: CodeJurisdictionSummary;
|
|
235
|
+
context: ResolvedCodeContext;
|
|
236
|
+
requirements: CodeRequirementListing[];
|
|
237
|
+
caveat: string;
|
|
238
|
+
}
|
package/codes-types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire types for the colour AGGREGATE surface — `GET /api/v1/colours/profiles`
|
|
3
|
+
* and `GET /api/v1/colours/stats`.
|
|
4
|
+
*
|
|
5
|
+
* Kept out of `types.ts` for the same reason `material-types.ts` and
|
|
6
|
+
* `codes-types.ts` are: the shared mirror is at its source-size budget. Same
|
|
7
|
+
* tolerant-parsing contract as the rest of the mirror — response enums are
|
|
8
|
+
* widened so a new server value still type-checks.
|
|
9
|
+
*/
|
|
10
|
+
import type { OpenEnum } from "./types.js";
|
|
11
|
+
/** Which taxonomy tier a colour profile's `categoryKey` names. */
|
|
12
|
+
export type CategoryTier = OpenEnum<"group" | "type">;
|
|
13
|
+
/** How the endpoint picks which colours to keep. */
|
|
14
|
+
export type ColourProfileSelect = OpenEnum<"frequency" | "diverse">;
|
|
15
|
+
/** One representative colour bucket of a category. */
|
|
16
|
+
export interface CategoryColour {
|
|
17
|
+
hex: string;
|
|
18
|
+
oklab: {
|
|
19
|
+
l: number;
|
|
20
|
+
a: number;
|
|
21
|
+
b: number;
|
|
22
|
+
};
|
|
23
|
+
variantCount: number;
|
|
24
|
+
/** This bucket's share of the category's coloured variants, 0–1. */
|
|
25
|
+
proportion: number;
|
|
26
|
+
}
|
|
27
|
+
export interface CategoryColourProfile {
|
|
28
|
+
categoryKey: string;
|
|
29
|
+
level: CategoryTier;
|
|
30
|
+
name: string;
|
|
31
|
+
path: string;
|
|
32
|
+
variantCount: number;
|
|
33
|
+
avgLightness: number;
|
|
34
|
+
avgChroma: number;
|
|
35
|
+
colours: CategoryColour[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The snapshot a profile response was computed from. Compare `variantCount`
|
|
39
|
+
* against `colours/stats`' `corpus.withColour` to see how complete the
|
|
40
|
+
* underlying materialized view currently is, and `refreshedAt` for its age.
|
|
41
|
+
*/
|
|
42
|
+
export interface CategoryColourProfilesBasis {
|
|
43
|
+
variantCount: number;
|
|
44
|
+
refreshedAt: string | null;
|
|
45
|
+
}
|
|
46
|
+
export interface CategoryColourProfilesResponse {
|
|
47
|
+
profiles: CategoryColourProfile[];
|
|
48
|
+
basis: CategoryColourProfilesBasis;
|
|
49
|
+
}
|
|
50
|
+
/** Request parameters for `colours.profiles()`. */
|
|
51
|
+
export interface ColourProfilesParams {
|
|
52
|
+
/** 1–8 category keys, at the tier named by `groupBy`. */
|
|
53
|
+
productTypeIds: readonly string[];
|
|
54
|
+
/** `"group"` merges each group's leaf product types into one palette. */
|
|
55
|
+
groupBy?: "group" | "type";
|
|
56
|
+
/** Representative colours per category, 1–64. */
|
|
57
|
+
topN?: number;
|
|
58
|
+
/** `"diverse"` maximises visual distinctness instead of frequency. */
|
|
59
|
+
select?: "frequency" | "diverse";
|
|
60
|
+
}
|
|
61
|
+
export interface ColourStatsCorpus {
|
|
62
|
+
variants: number;
|
|
63
|
+
withColour: number;
|
|
64
|
+
/** `withColour / variants`, 0–1. */
|
|
65
|
+
coverage: number;
|
|
66
|
+
}
|
|
67
|
+
export interface ColourStatsFamily {
|
|
68
|
+
id: string;
|
|
69
|
+
label: string;
|
|
70
|
+
variants: number;
|
|
71
|
+
brands: number;
|
|
72
|
+
}
|
|
73
|
+
export interface ColourStatsGroup {
|
|
74
|
+
key: string;
|
|
75
|
+
name: string;
|
|
76
|
+
productTypes: number;
|
|
77
|
+
variants: number;
|
|
78
|
+
}
|
|
79
|
+
/** Where each section came from, how fresh it is, and what it does NOT answer. */
|
|
80
|
+
export interface ColourStatsBasis {
|
|
81
|
+
corpus: string;
|
|
82
|
+
families: string;
|
|
83
|
+
groups: string;
|
|
84
|
+
groupsRefreshedAt: string | null;
|
|
85
|
+
groupsVariantCount: number;
|
|
86
|
+
omissions: string[];
|
|
87
|
+
}
|
|
88
|
+
export interface ColourStatsResponse {
|
|
89
|
+
corpus: ColourStatsCorpus;
|
|
90
|
+
families: ColourStatsFamily[];
|
|
91
|
+
groups: ColourStatsGroup[];
|
|
92
|
+
basis: ColourStatsBasis;
|
|
93
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The colour AGGREGATE surface, namespaced as `mg.colours`.
|
|
3
|
+
*
|
|
4
|
+
* Two reads that answer the same question at two altitudes — "how much colour
|
|
5
|
+
* does the graph hold at all" (`stats`) and "what colours does this category
|
|
6
|
+
* come in" (`profiles`) — so they live together rather than as two more flat
|
|
7
|
+
* methods on an already-large client facade. `mg.codes` and `mg.browse` set the
|
|
8
|
+
* precedent for a namespace when a capability is a small family rather than a
|
|
9
|
+
* single verb.
|
|
10
|
+
*
|
|
11
|
+
* The namespace holds no transport of its own: the client hands it a bound
|
|
12
|
+
* `get`, so auth, rate-limit accounting and error shaping stay in one place.
|
|
13
|
+
*
|
|
14
|
+
* Both responses carry a `basis`. These are reads of a materialized view that is
|
|
15
|
+
* refreshed on a schedule, not on write, so a caller can and should check how
|
|
16
|
+
* much of the corpus the answer actually covers before treating it as complete.
|
|
17
|
+
*/
|
|
18
|
+
import type { CategoryColourProfilesResponse, ColourProfilesParams, ColourStatsResponse } from "./colour-aggregate-types.js";
|
|
19
|
+
import type { QueryParams } from "./http-transport.js";
|
|
20
|
+
import type { SdkOperationId } from "./operations.js";
|
|
21
|
+
/** The client's own request primitive, handed down so this file owns no transport. */
|
|
22
|
+
export interface ColoursTransport {
|
|
23
|
+
get<T>(operationId: SdkOperationId, query?: QueryParams, signal?: AbortSignal): Promise<T>;
|
|
24
|
+
}
|
|
25
|
+
export declare class ColoursClient {
|
|
26
|
+
#private;
|
|
27
|
+
constructor(transport: ColoursTransport);
|
|
28
|
+
/**
|
|
29
|
+
* The representative colour palette of 1–8 categories in ONE call
|
|
30
|
+
* (GET `/api/v1/colours/profiles`).
|
|
31
|
+
*
|
|
32
|
+
* `groupBy: "group"` takes product-type GROUP keys and merges every leaf type
|
|
33
|
+
* under a group into one histogram BEFORE ranking — a group's palette, not the
|
|
34
|
+
* union of its leaves' heads. `select: "diverse"` returns visually spread
|
|
35
|
+
* swatches (greedy max-min over OKLab, 0.02 minimum separation, backfilled by
|
|
36
|
+
* frequency if fewer survive) instead of the most frequent ones; a client
|
|
37
|
+
* cannot recover that spread from a truncated frequency list, which is why it
|
|
38
|
+
* is a server mode rather than a local sort.
|
|
39
|
+
*
|
|
40
|
+
* A selected category with no colour data comes back as a zero-count profile,
|
|
41
|
+
* not a missing key.
|
|
42
|
+
*/
|
|
43
|
+
profiles(params: ColourProfilesParams, signal?: AbortSignal): Promise<CategoryColourProfilesResponse>;
|
|
44
|
+
/**
|
|
45
|
+
* Corpus colour coverage (GET `/api/v1/colours/stats`): how much of the graph
|
|
46
|
+
* carries colour at all, the split across the canonical colour families, and
|
|
47
|
+
* coverage per product-type group. `basis` states the source and freshness of
|
|
48
|
+
* each section plus `basis.omissions` — what this call deliberately does not
|
|
49
|
+
* answer, listed rather than silently absent.
|
|
50
|
+
*/
|
|
51
|
+
stats(signal?: AbortSignal): Promise<ColourStatsResponse>;
|
|
52
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export class ColoursClient {
|
|
2
|
+
#transport;
|
|
3
|
+
constructor(transport) {
|
|
4
|
+
this.#transport = transport;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* The representative colour palette of 1–8 categories in ONE call
|
|
8
|
+
* (GET `/api/v1/colours/profiles`).
|
|
9
|
+
*
|
|
10
|
+
* `groupBy: "group"` takes product-type GROUP keys and merges every leaf type
|
|
11
|
+
* under a group into one histogram BEFORE ranking — a group's palette, not the
|
|
12
|
+
* union of its leaves' heads. `select: "diverse"` returns visually spread
|
|
13
|
+
* swatches (greedy max-min over OKLab, 0.02 minimum separation, backfilled by
|
|
14
|
+
* frequency if fewer survive) instead of the most frequent ones; a client
|
|
15
|
+
* cannot recover that spread from a truncated frequency list, which is why it
|
|
16
|
+
* is a server mode rather than a local sort.
|
|
17
|
+
*
|
|
18
|
+
* A selected category with no colour data comes back as a zero-count profile,
|
|
19
|
+
* not a missing key.
|
|
20
|
+
*/
|
|
21
|
+
profiles(params, signal) {
|
|
22
|
+
return this.#transport.get("get_category_colour_profiles", {
|
|
23
|
+
productTypeIds: params.productTypeIds.join(","),
|
|
24
|
+
groupBy: params.groupBy,
|
|
25
|
+
topN: params.topN,
|
|
26
|
+
select: params.select,
|
|
27
|
+
}, signal);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Corpus colour coverage (GET `/api/v1/colours/stats`): how much of the graph
|
|
31
|
+
* carries colour at all, the split across the canonical colour families, and
|
|
32
|
+
* coverage per product-type group. `basis` states the source and freshness of
|
|
33
|
+
* each section plus `basis.omissions` — what this call deliberately does not
|
|
34
|
+
* answer, listed rather than silently absent.
|
|
35
|
+
*/
|
|
36
|
+
stats(signal) {
|
|
37
|
+
return this.#transport.get("get_colour_stats", undefined, signal);
|
|
38
|
+
}
|
|
39
|
+
}
|