@instruments/materialgraph 0.10.0 → 0.11.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/browse-types.d.ts +147 -0
- package/browse-types.js +1 -0
- package/by-colour-types.d.ts +56 -0
- package/client-browse.d.ts +13 -3
- package/client-browse.js +12 -2
- package/client-exploration.d.ts +9 -0
- package/client-exploration.js +7 -0
- package/client-source-material-comments.d.ts +51 -0
- package/client-source-material-comments.js +40 -0
- package/client.d.ts +28 -22
- package/client.js +33 -24
- package/colour-aggregate-types.d.ts +58 -0
- package/colours-client.d.ts +8 -2
- package/colours-client.js +15 -2
- package/composition-client.d.ts +33 -0
- package/composition-client.js +27 -0
- package/composition-types.d.ts +46 -0
- package/coordinate-client.d.ts +23 -0
- package/coordinate-client.js +25 -0
- package/exploration-types.d.ts +110 -0
- package/exploration-types.js +1 -0
- package/fan-deck-types.d.ts +4 -1
- package/index.d.ts +4 -1
- package/operations.d.ts +1 -1
- package/operations.js +25 -0
- package/package.json +1 -1
- package/palette-search-types.d.ts +31 -0
- package/run-types.d.ts +132 -0
- package/runs.d.ts +35 -1
- package/runs.js +61 -1
- package/schedule-types.d.ts +128 -0
- package/schema-resource-types.d.ts +1 -1
- package/search-refinement-types.d.ts +28 -1
- package/search-request-types.d.ts +172 -0
- package/search-request-types.js +1 -0
- package/slot-pool-types.d.ts +370 -0
- package/slot-pool-types.js +1 -0
- package/source-material-validation.d.ts +5 -1
- package/source-material-validation.js +111 -4
- package/types.d.ts +149 -199
- package/validation.d.ts +12 -0
- package/validation.js +23 -0
|
@@ -88,6 +88,43 @@ export interface ColourStatsGroup {
|
|
|
88
88
|
productTypes: number;
|
|
89
89
|
variants: number;
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* One cell of the brand x category x colour-family matrix — the shape that
|
|
93
|
+
* answers questions no single dimension can, such as "how many whites does
|
|
94
|
+
* Benjamin Moore offer in paint".
|
|
95
|
+
*/
|
|
96
|
+
export interface ColourStatsRow {
|
|
97
|
+
/** Opaque brand id — the join key for brand reads. Never parse it. */
|
|
98
|
+
brandId: string;
|
|
99
|
+
brandSlug: string;
|
|
100
|
+
brandName: string;
|
|
101
|
+
/**
|
|
102
|
+
* Product-type key. NULL means these variants carry NO accepted primary
|
|
103
|
+
* product type — a real population, kept so the matrix sums to the corpus,
|
|
104
|
+
* not an error and not a residual bucket.
|
|
105
|
+
*/
|
|
106
|
+
categoryKey: string | null;
|
|
107
|
+
family: string;
|
|
108
|
+
/**
|
|
109
|
+
* Distinct variants at this (brand, category, family) carrying an ACCEPTED
|
|
110
|
+
* `colour_family`. Not every variant of the brand.
|
|
111
|
+
*/
|
|
112
|
+
variants: number;
|
|
113
|
+
}
|
|
114
|
+
/** How to narrow the matrix. Passing ANY of these asks for `rows`. */
|
|
115
|
+
export interface ColourStatsParams {
|
|
116
|
+
/** `"brand,category"` — ask for the whole matrix, unscoped. */
|
|
117
|
+
groupBy?: string;
|
|
118
|
+
brandId?: string;
|
|
119
|
+
brandSlug?: string;
|
|
120
|
+
/**
|
|
121
|
+
* A product-type key, or the literal `"null"` for the unclassified
|
|
122
|
+
* population. Omitting it means every category — a different question.
|
|
123
|
+
*/
|
|
124
|
+
categoryKey?: string;
|
|
125
|
+
family?: string;
|
|
126
|
+
limit?: number;
|
|
127
|
+
}
|
|
91
128
|
/** Where each section came from, how fresh it is, and what it does NOT answer. */
|
|
92
129
|
export interface ColourStatsBasis {
|
|
93
130
|
corpus: string;
|
|
@@ -95,11 +132,32 @@ export interface ColourStatsBasis {
|
|
|
95
132
|
groups: string;
|
|
96
133
|
groupsRefreshedAt: string | null;
|
|
97
134
|
groupsVariantCount: number;
|
|
135
|
+
/**
|
|
136
|
+
* Where `rows` came from, its freshness, and what it EXCLUDES — present only
|
|
137
|
+
* when `rows` is. Read it: the matrix deliberately omits Samplize, which is a
|
|
138
|
+
* sampling channel printing other manufacturers' colours rather than a maker.
|
|
139
|
+
*/
|
|
140
|
+
rows?: string;
|
|
98
141
|
omissions: string[];
|
|
99
142
|
}
|
|
100
143
|
export interface ColourStatsResponse {
|
|
101
144
|
corpus: ColourStatsCorpus;
|
|
102
145
|
families: ColourStatsFamily[];
|
|
103
146
|
groups: ColourStatsGroup[];
|
|
147
|
+
/**
|
|
148
|
+
* The brand x category x colour-family matrix. Present ONLY when you asked
|
|
149
|
+
* for it; ABSENT means nobody asked, never that the matrix is empty.
|
|
150
|
+
*
|
|
151
|
+
* `families` above is NOT scoped by the same parameters and stays
|
|
152
|
+
* platform-wide under all of them. Scoped counts live here.
|
|
153
|
+
*/
|
|
154
|
+
rows?: ColourStatsRow[];
|
|
155
|
+
/**
|
|
156
|
+
* Rows matching your query BEFORE the response cap — the honest total.
|
|
157
|
+
* A shortfall against `rows.length` means `rows` is a prefix.
|
|
158
|
+
*/
|
|
159
|
+
rowsMatched?: number;
|
|
160
|
+
/** TRUE when the matrix exceeded the cap and `rows` is a prefix. */
|
|
161
|
+
rowsTruncated?: boolean;
|
|
104
162
|
basis: ColourStatsBasis;
|
|
105
163
|
}
|
package/colours-client.d.ts
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* FROM PRODUCT IMAGERY, not declared by the manufacturer. Report visual
|
|
33
33
|
* likeness, never a stated colour specification.
|
|
34
34
|
*/
|
|
35
|
-
import type { CategoryColourProfilesResponse, ColourProfilesParams, ColourStatsResponse } from "./colour-aggregate-types.js";
|
|
35
|
+
import type { CategoryColourProfilesResponse, ColourProfilesParams, ColourStatsParams, ColourStatsResponse } from "./colour-aggregate-types.js";
|
|
36
36
|
import type { QueryParams } from "./http-transport.js";
|
|
37
37
|
import type { SdkOperationId } from "./operations.js";
|
|
38
38
|
import type { SearchGradientInput, SearchGradientResponse, SearchPaletteInput, SearchPaletteResponse } from "./palette-search-types.js";
|
|
@@ -87,8 +87,14 @@ export declare class ColoursClient {
|
|
|
87
87
|
* coverage per product-type group. `basis` states the source and freshness of
|
|
88
88
|
* each section plus `basis.omissions` — what this call deliberately does not
|
|
89
89
|
* answer, listed rather than silently absent.
|
|
90
|
+
*
|
|
91
|
+
* Pass `{ groupBy: "brand,category" }` for the whole brand x category x
|
|
92
|
+
* family matrix in one call, or a `brandSlug`/`categoryKey` scope for a slice
|
|
93
|
+
* of it — either way it arrives as `rows`, each row carrying `brandId` and
|
|
94
|
+
* `brandSlug` to join on. Without any of those parameters the payload is the
|
|
95
|
+
* platform-wide one and `rows` is absent. `families` is never scoped by them.
|
|
90
96
|
*/
|
|
91
|
-
stats(signal?: AbortSignal): Promise<ColourStatsResponse>;
|
|
97
|
+
stats(params?: ColourStatsParams, signal?: AbortSignal): Promise<ColourStatsResponse>;
|
|
92
98
|
/**
|
|
93
99
|
* THE QUESTION: "what goes with this WHOLE PALETTE?" — N colours at once, at
|
|
94
100
|
* stated proportions, not one colour repeated (POST `/api/v1/search/palettes`).
|
package/colours-client.js
CHANGED
|
@@ -53,9 +53,22 @@ export class ColoursClient {
|
|
|
53
53
|
* coverage per product-type group. `basis` states the source and freshness of
|
|
54
54
|
* each section plus `basis.omissions` — what this call deliberately does not
|
|
55
55
|
* answer, listed rather than silently absent.
|
|
56
|
+
*
|
|
57
|
+
* Pass `{ groupBy: "brand,category" }` for the whole brand x category x
|
|
58
|
+
* family matrix in one call, or a `brandSlug`/`categoryKey` scope for a slice
|
|
59
|
+
* of it — either way it arrives as `rows`, each row carrying `brandId` and
|
|
60
|
+
* `brandSlug` to join on. Without any of those parameters the payload is the
|
|
61
|
+
* platform-wide one and `rows` is absent. `families` is never scoped by them.
|
|
56
62
|
*/
|
|
57
|
-
stats(signal) {
|
|
58
|
-
return this.#transport.get("get_colour_stats",
|
|
63
|
+
stats(params = {}, signal) {
|
|
64
|
+
return this.#transport.get("get_colour_stats", {
|
|
65
|
+
groupBy: params.groupBy,
|
|
66
|
+
brandId: params.brandId,
|
|
67
|
+
brandSlug: params.brandSlug,
|
|
68
|
+
categoryKey: params.categoryKey,
|
|
69
|
+
family: params.family,
|
|
70
|
+
limit: params.limit,
|
|
71
|
+
}, signal);
|
|
59
72
|
}
|
|
60
73
|
/**
|
|
61
74
|
* THE QUESTION: "what goes with this WHOLE PALETTE?" — N colours at once, at
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The COMPOSITION lens: the two synchronous scheme surfaces, as thin wrappers
|
|
3
|
+
* over the shared {@link HttpTransport}. `MaterialGraphClient.varyScheme` and
|
|
4
|
+
* `.slotPools` delegate here; the contract lives in this file.
|
|
5
|
+
*
|
|
6
|
+
* They are two altitudes of the same capability. `varyScheme` re-derives a
|
|
7
|
+
* scheme MaterialGraph itself composed; `slotPools` hands the ranked candidates
|
|
8
|
+
* to a composer that is not MaterialGraph, and keeps none of the ownership.
|
|
9
|
+
*/
|
|
10
|
+
import type { VarySchemesRequest, VarySchemesResponse } from "./composition-types.js";
|
|
11
|
+
import { HttpTransport } from "./http-transport.js";
|
|
12
|
+
import type { SlotPoolsRequest, SlotPoolsResponse } from "./slot-pool-types.js";
|
|
13
|
+
/**
|
|
14
|
+
* THE QUESTION: "show me the same brief, decided differently." Re-derives an
|
|
15
|
+
* option B from a succeeded compose Run along ONE constraint axis. Deterministic
|
|
16
|
+
* and synchronous — the response IS the hydrated scheme (no Run envelope),
|
|
17
|
+
* stamped with axis + source provenance whose `notes` are the receipts.
|
|
18
|
+
* Requires the `mg:read` scope.
|
|
19
|
+
*/
|
|
20
|
+
export declare function varyScheme(transport: HttpTransport, body: VarySchemesRequest, signal?: AbortSignal): Promise<VarySchemesResponse>;
|
|
21
|
+
/**
|
|
22
|
+
* THE QUESTION: "for each of these slots, what should I be choosing between?"
|
|
23
|
+
* Up to 24 self-contained tasks in, one ranked and gated candidate pool each
|
|
24
|
+
* out, correlated by YOUR `taskKey`. Synchronous, uncached and project-free —
|
|
25
|
+
* no Run, no programme, no state kept on the MaterialGraph side.
|
|
26
|
+
*
|
|
27
|
+
* READ THE POOLS, NOT JUST THE CANDIDATES. A task whose search failed comes back
|
|
28
|
+
* with a `search-failed` shortfall while the rest answer normally; a candidate
|
|
29
|
+
* with `eligible: false` is LABELLED rather than dropped (read `flags`); and a
|
|
30
|
+
* criterion that graded `missing` or `not_evaluated` was never a failure.
|
|
31
|
+
* Requires the `mg:read` scope.
|
|
32
|
+
*/
|
|
33
|
+
export declare function slotPools(transport: HttpTransport, body: SlotPoolsRequest, signal?: AbortSignal): Promise<SlotPoolsResponse>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { HttpTransport } from "./http-transport.js";
|
|
2
|
+
import { resolveOperation } from "./operations.js";
|
|
3
|
+
/**
|
|
4
|
+
* THE QUESTION: "show me the same brief, decided differently." Re-derives an
|
|
5
|
+
* option B from a succeeded compose Run along ONE constraint axis. Deterministic
|
|
6
|
+
* and synchronous — the response IS the hydrated scheme (no Run envelope),
|
|
7
|
+
* stamped with axis + source provenance whose `notes` are the receipts.
|
|
8
|
+
* Requires the `mg:read` scope.
|
|
9
|
+
*/
|
|
10
|
+
export function varyScheme(transport, body, signal) {
|
|
11
|
+
return transport.requestJson(resolveOperation("vary_schemes"), { body, signal });
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* THE QUESTION: "for each of these slots, what should I be choosing between?"
|
|
15
|
+
* Up to 24 self-contained tasks in, one ranked and gated candidate pool each
|
|
16
|
+
* out, correlated by YOUR `taskKey`. Synchronous, uncached and project-free —
|
|
17
|
+
* no Run, no programme, no state kept on the MaterialGraph side.
|
|
18
|
+
*
|
|
19
|
+
* READ THE POOLS, NOT JUST THE CANDIDATES. A task whose search failed comes back
|
|
20
|
+
* with a `search-failed` shortfall while the rest answer normally; a candidate
|
|
21
|
+
* with `eligible: false` is LABELLED rather than dropped (read `flags`); and a
|
|
22
|
+
* criterion that graded `missing` or `not_evaluated` was never a failure.
|
|
23
|
+
* Requires the `mg:read` scope.
|
|
24
|
+
*/
|
|
25
|
+
export function slotPools(transport, body, signal) {
|
|
26
|
+
return transport.requestJson(resolveOperation("slot_pools"), { body, signal });
|
|
27
|
+
}
|
package/composition-types.d.ts
CHANGED
|
@@ -284,6 +284,34 @@ export interface ReviewProgrammeSuspendPayload {
|
|
|
284
284
|
categorySource?: SlotCategorySource;
|
|
285
285
|
provenance: ProgrammeProvenance;
|
|
286
286
|
}>;
|
|
287
|
+
/**
|
|
288
|
+
* Lines this room usually carries that the brief never named.
|
|
289
|
+
*
|
|
290
|
+
* Offered, never imposed: a programme that proceeds without them is a legal
|
|
291
|
+
* answer. `essential` marks the ones whose absence makes the room unbuildable
|
|
292
|
+
* as specified; `ffe` marks furniture and lighting the catalogue does not
|
|
293
|
+
* serve yet, carried because a bedroom with no bed on the schedule is a gap
|
|
294
|
+
* worth seeing coming. Add one with an `add-slot` correction.
|
|
295
|
+
*/
|
|
296
|
+
unstated?: Array<{
|
|
297
|
+
spaceId: string;
|
|
298
|
+
key: string;
|
|
299
|
+
name: string;
|
|
300
|
+
element: SlotElement;
|
|
301
|
+
/**
|
|
302
|
+
* Absent and `null` both mean the graph has no category for this line, and a
|
|
303
|
+
* reader must treat them as one answer.
|
|
304
|
+
*
|
|
305
|
+
* The distinction does not survive the wire. A `null` set server-side
|
|
306
|
+
* arrives as an absent key on the far side of the workflow runtime, so a
|
|
307
|
+
* client that branched on which one it received would be reading transport
|
|
308
|
+
* noise as meaning. An FF&E line the catalogue does not serve — a table
|
|
309
|
+
* lamp, bed linen, ironmongery — has no category under either reading.
|
|
310
|
+
*/
|
|
311
|
+
category?: string | null;
|
|
312
|
+
weight: "essential" | "optional";
|
|
313
|
+
ffe?: boolean;
|
|
314
|
+
}>;
|
|
287
315
|
}
|
|
288
316
|
/**
|
|
289
317
|
* Resume grammar for the `review-programme` step: drop a slot, drop a space
|
|
@@ -310,6 +338,24 @@ export interface ReviewProgrammeResumeData {
|
|
|
310
338
|
action: "set-slot-category";
|
|
311
339
|
slotId: string;
|
|
312
340
|
category: string;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* ADD a line the brief never named — usually one the payload offered under
|
|
344
|
+
* `unstated`, though any line is legal. Every other verb here subtracts,
|
|
345
|
+
* which made the programme a ceiling: whatever the brief happened to
|
|
346
|
+
* mention was the most a schedule could ever contain.
|
|
347
|
+
*
|
|
348
|
+
* `category` may be null or absent, because some real lines — grout,
|
|
349
|
+
* ironmongery, sanitaryware — have no catalog category yet. Such a slot is
|
|
350
|
+
* skipped at retrieval with a counted `no-category` shortfall, which is the
|
|
351
|
+
* honest treatment of a line we can hold but not yet fill.
|
|
352
|
+
*/
|
|
353
|
+
| {
|
|
354
|
+
action: "add-slot";
|
|
355
|
+
spaceId: string;
|
|
356
|
+
name: string;
|
|
357
|
+
element: SlotElement;
|
|
358
|
+
category?: string | null;
|
|
313
359
|
}>;
|
|
314
360
|
}
|
|
315
361
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The COORDINATION lens: given several materials already chosen, what completes
|
|
3
|
+
* them. A thin wrapper over the shared {@link HttpTransport};
|
|
4
|
+
* `MaterialGraphClient.coordinate` delegates here.
|
|
5
|
+
*
|
|
6
|
+
* Extracted from `client.ts`, which sits above the repository's source-size
|
|
7
|
+
* limit, in the same per-lens shape as `brands-client` / `codes-client` /
|
|
8
|
+
* `colours-client`. Behaviour is unchanged.
|
|
9
|
+
*/
|
|
10
|
+
import { HttpTransport } from "./http-transport.js";
|
|
11
|
+
import type { CoordinateInput, CoordinateResponse } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* THE QUESTION: "here is my whole scheme so far — what completes it?" The
|
|
14
|
+
* multi-seed form of `pairings`: lift is SUMMED across seeds, so a companion
|
|
15
|
+
* suiting one pick ranks below one suiting several. Returns demand-lift-ranked
|
|
16
|
+
* companions with colour swatches and an annotate-only `colourFit` that never
|
|
17
|
+
* reorders in v1.
|
|
18
|
+
*
|
|
19
|
+
* Instead use `pairings` for a single material, and `colours.palette()` when the
|
|
20
|
+
* scheme is COLOURS rather than materials. Check `unresolved` before presenting:
|
|
21
|
+
* a reference that resolved to nothing is named there, not dropped.
|
|
22
|
+
*/
|
|
23
|
+
export declare function coordinate(transport: HttpTransport, input: CoordinateInput, signal?: AbortSignal): Promise<CoordinateResponse>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The COORDINATION lens: given several materials already chosen, what completes
|
|
3
|
+
* them. A thin wrapper over the shared {@link HttpTransport};
|
|
4
|
+
* `MaterialGraphClient.coordinate` delegates here.
|
|
5
|
+
*
|
|
6
|
+
* Extracted from `client.ts`, which sits above the repository's source-size
|
|
7
|
+
* limit, in the same per-lens shape as `brands-client` / `codes-client` /
|
|
8
|
+
* `colours-client`. Behaviour is unchanged.
|
|
9
|
+
*/
|
|
10
|
+
import { HttpTransport } from "./http-transport.js";
|
|
11
|
+
import { resolveOperation } from "./operations.js";
|
|
12
|
+
/**
|
|
13
|
+
* THE QUESTION: "here is my whole scheme so far — what completes it?" The
|
|
14
|
+
* multi-seed form of `pairings`: lift is SUMMED across seeds, so a companion
|
|
15
|
+
* suiting one pick ranks below one suiting several. Returns demand-lift-ranked
|
|
16
|
+
* companions with colour swatches and an annotate-only `colourFit` that never
|
|
17
|
+
* reorders in v1.
|
|
18
|
+
*
|
|
19
|
+
* Instead use `pairings` for a single material, and `colours.palette()` when the
|
|
20
|
+
* scheme is COLOURS rather than materials. Check `unresolved` before presenting:
|
|
21
|
+
* a reference that resolved to nothing is named there, not dropped.
|
|
22
|
+
*/
|
|
23
|
+
export function coordinate(transport, input, signal) {
|
|
24
|
+
return transport.requestJson(resolveOperation("coordinate_materials"), { body: input, signal });
|
|
25
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { VariantId } from "./identifiers.js";
|
|
2
|
+
export type GraphOperator = "colourways" | "same_category" | "still_listed" | "looks_like" | "same_colour" | "pairs_with" | "often_specified_with" | "substitutes_for" | "more_durable" | "outdoor_suitable" | "lower_cost" | "more_sustainable";
|
|
3
|
+
export interface GraphOperatorAvailability {
|
|
4
|
+
operator: GraphOperator;
|
|
5
|
+
operatorClass: "identity" | "perceptual" | "relational" | "spec";
|
|
6
|
+
label: string;
|
|
7
|
+
available: boolean;
|
|
8
|
+
basis: string;
|
|
9
|
+
count?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface GraphOperatorEvidence {
|
|
12
|
+
variantId: VariantId;
|
|
13
|
+
operators: GraphOperatorAvailability[];
|
|
14
|
+
}
|
|
15
|
+
export interface CandidateReadInput {
|
|
16
|
+
operator: "looks_like";
|
|
17
|
+
corpusScope?: "all" | "materialBankOrderable";
|
|
18
|
+
limit?: number;
|
|
19
|
+
excludeVariantIds?: VariantId[];
|
|
20
|
+
}
|
|
21
|
+
export interface CandidateReadImage {
|
|
22
|
+
url: string;
|
|
23
|
+
source: "r2" | "origin";
|
|
24
|
+
/** Null means this image has not been analysed for a uniform light background. */
|
|
25
|
+
isIsolated: boolean | null;
|
|
26
|
+
}
|
|
27
|
+
export interface CandidateReadPaletteSwatch {
|
|
28
|
+
hex: string;
|
|
29
|
+
proportion: number;
|
|
30
|
+
name?: string | null;
|
|
31
|
+
}
|
|
32
|
+
export interface CandidateReadCard {
|
|
33
|
+
variantId: VariantId;
|
|
34
|
+
productId: string;
|
|
35
|
+
brandSlug: string;
|
|
36
|
+
materialBankId: string | null;
|
|
37
|
+
brand: string;
|
|
38
|
+
product: string;
|
|
39
|
+
variantName: string | null;
|
|
40
|
+
color: string | null;
|
|
41
|
+
image: CandidateReadImage | null;
|
|
42
|
+
palette: CandidateReadPaletteSwatch[];
|
|
43
|
+
}
|
|
44
|
+
export interface CandidateRankEvidence {
|
|
45
|
+
rank: number;
|
|
46
|
+
distance: number;
|
|
47
|
+
similarity: number;
|
|
48
|
+
basis: "active_main_image_embedding";
|
|
49
|
+
provenanceGrade: "measured";
|
|
50
|
+
displayImageMatchedEvidence: boolean | null;
|
|
51
|
+
}
|
|
52
|
+
export interface CandidateReadCandidate extends CandidateReadCard {
|
|
53
|
+
evidence: CandidateRankEvidence;
|
|
54
|
+
reason: string;
|
|
55
|
+
}
|
|
56
|
+
export interface CandidateSeedEvidence {
|
|
57
|
+
evidenceImageSha256: string;
|
|
58
|
+
displayImageSha256: string | null;
|
|
59
|
+
basis: "active_main_image_embedding";
|
|
60
|
+
provenanceGrade: "measured";
|
|
61
|
+
displayImageMatchedEvidence: boolean | null;
|
|
62
|
+
}
|
|
63
|
+
export interface CandidateReadReceipt {
|
|
64
|
+
operator: "looks_like";
|
|
65
|
+
corpusScope: {
|
|
66
|
+
scope: "all" | "materialBankOrderable";
|
|
67
|
+
description: string;
|
|
68
|
+
} | null;
|
|
69
|
+
requestedLimit: number;
|
|
70
|
+
returnedCount: number;
|
|
71
|
+
exclusions: {
|
|
72
|
+
requested: number;
|
|
73
|
+
unique: number;
|
|
74
|
+
applied: number;
|
|
75
|
+
};
|
|
76
|
+
dedupe: {
|
|
77
|
+
retrieved: number;
|
|
78
|
+
removed: number;
|
|
79
|
+
truncated: number;
|
|
80
|
+
projectionMisses: number;
|
|
81
|
+
};
|
|
82
|
+
timing: {
|
|
83
|
+
/** Internal seed projection completion; not a consumer response milestone. */
|
|
84
|
+
seedProjectionMs: number;
|
|
85
|
+
retrievalMs: number;
|
|
86
|
+
projectionMs: number;
|
|
87
|
+
completeMs: number;
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
interface CandidateReadResponseBase {
|
|
91
|
+
seed: CandidateReadCard;
|
|
92
|
+
receipt: CandidateReadReceipt;
|
|
93
|
+
}
|
|
94
|
+
export type CandidateReadResponse = (CandidateReadResponseBase & {
|
|
95
|
+
status: "ready";
|
|
96
|
+
seedEvidence: CandidateSeedEvidence;
|
|
97
|
+
candidates: CandidateReadCandidate[];
|
|
98
|
+
reason: null;
|
|
99
|
+
}) | (CandidateReadResponseBase & {
|
|
100
|
+
status: "no_candidates" | "no_unseen_candidates" | "bounded_retrieval_unavailable";
|
|
101
|
+
seedEvidence: CandidateSeedEvidence;
|
|
102
|
+
candidates: [];
|
|
103
|
+
reason: string;
|
|
104
|
+
}) | (CandidateReadResponseBase & {
|
|
105
|
+
status: "operator_unavailable";
|
|
106
|
+
seedEvidence: null;
|
|
107
|
+
candidates: [];
|
|
108
|
+
reason: string;
|
|
109
|
+
});
|
|
110
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/fan-deck-types.d.ts
CHANGED
|
@@ -26,7 +26,10 @@ export interface FanDeckFamily {
|
|
|
26
26
|
count: number;
|
|
27
27
|
}
|
|
28
28
|
export interface BrandFanDeck {
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The brand SLUGS the deck resolved to — round-trippable identifiers, not
|
|
31
|
+
* display names. The maker's name as it should be shown is on every swatch.
|
|
32
|
+
*/
|
|
30
33
|
brands: string[];
|
|
31
34
|
/** Grouped by `families` order, light to dark within each family. */
|
|
32
35
|
swatches: FanDeckSwatch[];
|
package/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { MaterialGraphClient, DEFAULT_BASE_URL, MAX_BATCH_IDS, } from "./client.js";
|
|
2
|
-
export type { MaterialGraphClientOptions, BrowseNamespace } from "./client.js";
|
|
2
|
+
export type { MaterialGraphClientOptions, BrowseNamespace, ExplorationNamespace, SourceMaterialCommentsNamespace, } from "./client.js";
|
|
3
3
|
export { MATERIALGRAPH_API_VERSION, SDK_OPERATIONS } from "./operations.js";
|
|
4
4
|
export type { SdkOperation, SdkOperationId } from "./operations.js";
|
|
5
5
|
export type * from "./identifiers.js";
|
|
6
|
+
export type * from "./exploration-types.js";
|
|
6
7
|
export { TERMINAL_RUN_EVENT_TYPES } from "./run-types.js";
|
|
7
8
|
export type * from "./run-types.js";
|
|
8
9
|
export type * from "./schedule-types.js";
|
|
9
10
|
export { VARY_AXES } from "./composition-types.js";
|
|
10
11
|
export type * from "./composition-types.js";
|
|
12
|
+
export type * from "./slot-pool-types.js";
|
|
11
13
|
export { PROJECT_EVENT_KINDS } from "./project-types.js";
|
|
12
14
|
export type * from "./project-types.js";
|
|
13
15
|
export { COMPOSITION_PHASE_EVENT_TYPES, COMPOSITION_PROGRAMME_EVENT_TYPES, COMPOSITION_REVIEW_CRITERIA_EVENT_TYPES, parseRunEvent, } from "./run-events.js";
|
|
@@ -16,6 +18,7 @@ export { MaterialGraphError } from "./errors.js";
|
|
|
16
18
|
export type { MaterialGraphErrorInit, MaterialGraphErrorKind, MaterialGraphRequestMetadata, ProblemDetail, RateLimit, SanitizedErrorValue, SanitizedIssue, SimpleErrorBody, } from "./errors.js";
|
|
17
19
|
export type * from "./types.js";
|
|
18
20
|
export type * from "./match-types.js";
|
|
21
|
+
export type * from "./browse-types.js";
|
|
19
22
|
export type * from "./by-colour-types.js";
|
|
20
23
|
export { MATCH_IMAGE_TYPES, MATCH_OUTCOMES, MATCH_MATERIAL_FUNCTIONS, MATCH_STREAM_EVENT_TYPES, MATCH_SURFACE_STATUSES, MATCH_WORKFLOW_STEPS, } from "./match-stream-types.js";
|
|
21
24
|
export type * from "./match-stream-types.js";
|
package/operations.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const MATERIALGRAPH_API_VERSION = "0.7.0";
|
|
2
|
-
declare const OPERATION_DEFINITIONS: readonly [readonly ["search", "POST", "/api/v1/search", "search_materials_post"], readonly ["searchGet", "GET", "/api/v1/search", "search_materials_get"], readonly ["match", "POST", "/api/v1/search/match", "match_material"], readonly ["byColour", "GET", "/api/v1/search/colours", "search_by_colour"], readonly ["material", "GET", "/api/v1/materials/{variantId}", "get_material"], readonly ["siblings", "GET", "/api/v1/materials/{variantId}/siblings", "get_material_siblings"], readonly ["materialBlocks", "GET", "/api/v1/materials/{variantId}/blocks", "list_material_blocks"], readonly ["materialAssets", "GET", "/api/v1/materials/{variantId}/assets", "list_material_assets"], readonly ["schema", "GET", "/api/v1/schema/blocks", "list_schema_blocks"], readonly ["schema", "GET", "/api/v1/schema/attributes", "list_schema_attributes"], readonly ["schema", "GET", "/api/v1/schema/verticals", "list_schema_verticals"], readonly ["schema", "GET", "/api/v1/schema/product-types", "list_schema_product_types"], readonly ["schema", "GET", "/api/v1/schema/units", "list_schema_units"], readonly ["schema", "GET", "/api/v1/schema/value-dictionaries", "list_schema_value_dictionaries"], readonly ["schema", "GET", "/api/v1/schema/source-requirements", "list_schema_source_requirements"], readonly ["schema", "GET", "/api/v1/schema/product-type-templates", "list_schema_product_type_templates"], readonly ["schema", "GET", "/api/v1/schema/mappings", "list_schema_mappings"], readonly ["pairings", "GET", "/api/v1/materials/{variantId}/pairings", "get_material_pairings"], readonly ["associatedFinishes", "GET", "/api/v1/associated/finishes", "list_associated_finishes"], readonly ["associatedProducts", "GET", "/api/v1/associated/products", "list_associated_products"], readonly ["materials", "POST", "/api/v1/materials/batch", "get_materials_batch_post"], readonly ["materialsCached", "GET", "/api/v1/materials/batch", "get_materials_batch_get"], readonly ["browse", "GET", "/api/v1/search/browse", "search_browse_by_colour"], readonly ["colourFacets", "GET", "/api/v1/colours/facets", "get_colour_facets"], readonly ["colours.profiles", "GET", "/api/v1/colours/profiles", "get_category_colour_profiles"], readonly ["colours.stats", "GET", "/api/v1/colours/stats", "get_colour_stats"], readonly ["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"], readonly ["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"], readonly ["suggest", "GET", "/api/v1/search/suggest", "search_suggest"], readonly ["resolveAttribute", "GET", "/api/v1/catalog/attributes/resolve", "catalog_resolve_attribute"], readonly ["resolveAttributeValue", "GET", "/api/v1/catalog/attributes/{attributeId}/values/resolve", "catalog_resolve_value"], readonly ["searchVocabulary", "GET", "/api/v1/catalog/vocabulary/search", "catalog_vocabulary_search"], readonly ["resolve", "POST", "/api/v1/resolve", "resolve_phrases"], readonly ["bySpec", "GET", "/api/v1/search/specifications", "catalog_by_spec"], readonly ["taxonomy", "GET", "/api/v1/taxonomy/categories", "get_category_taxonomy"], readonly ["whoami", "GET", "/api/v1/whoami", "whoami"], readonly ["coordinate", "POST", "/api/v1/pairings/coordinate", "coordinate_materials"], readonly ["demand", "GET", "/api/v1/demand", "get_material_demand"], readonly ["colours.palette", "POST", "/api/v1/search/palettes", "search_by_palette"], readonly ["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"], readonly ["colours.gradient", "POST", "/api/v1/search/gradients", "search_by_gradient"], readonly ["specificationFacets", "GET", "/api/v1/catalog/specifications/facets", "list_spec_facets"], readonly ["attributeValues", "GET", "/api/v1/catalog/attributes/{attributeId}/values", "list_attribute_values"], readonly ["applicableSpecs", "GET", "/api/v1/taxonomy/categories/{key}/specs", "get_applicable_specs"], readonly ["glossary", "GET", "/api/v1/glossary/{term}", "explain_material_term"], readonly ["brands", "GET", "/api/v1/brands", "list_brands"], readonly ["brand", "GET", "/api/v1/brands/{brandSlug}", "get_brand_profile"], readonly ["brandColourDeck", "GET", "/api/v1/brands/{brandSlug}/colours", "brand_colour_deck"], readonly ["uploadSourceMaterial", "POST", "/api/v1/source-material", "upload_source_material"], readonly ["sourceMaterialBatch", "GET", "/api/v1/source-material/{batchId}", "get_source_material_batch"], readonly ["capabilities", "GET", "/api/v1/capabilities", "list_public_capabilities"], readonly ["createRun", "POST", "/api/v1/runs", "create_public_run"], readonly ["listRuns", "GET", "/api/v1/runs", "list_public_runs"], readonly ["run", "GET", "/api/v1/runs/{runId}", "get_public_run"], readonly ["runSchedule", "GET", "/api/v1/runs/{runId}/schedule", "get_run_finish_schedule"], readonly ["streamRunEvents", "GET", "/api/v1/runs/{runId}/events", "list_public_run_events"], readonly ["resumeRun", "POST", "/api/v1/runs/{runId}/resume", "resume_public_run"], readonly ["cancelRun", "POST", "/api/v1/runs/{runId}/cancel", "cancel_public_run"], readonly ["varyScheme", "POST", "/api/v1/schemes/vary", "vary_schemes"], readonly ["createProject", "POST", "/api/v1/projects", "create_box_project"], readonly ["listProjects", "GET", "/api/v1/projects", "list_box_projects"], readonly ["getProject", "GET", "/api/v1/projects/{projectId}", "get_box_project"], readonly ["appendProjectEvent", "POST", "/api/v1/projects/{projectId}/events", "append_box_project_event"], readonly ["demandBatch", "POST", "/api/v1/demand/batch", "get_demand_batch"], readonly ["codeAdvisory", "POST", "/api/v1/codes/advisory", "resolveCodeAdvisory"], readonly ["codes.context", "GET", "/api/v1/codes/context", "list_code_context"], readonly ["codes.requirements", "GET", "/api/v1/codes/requirements", "list_code_requirements"]];
|
|
2
|
+
declare const OPERATION_DEFINITIONS: readonly [readonly ["search", "POST", "/api/v1/search", "search_materials_post"], readonly ["searchGet", "GET", "/api/v1/search", "search_materials_get"], readonly ["match", "POST", "/api/v1/search/match", "match_material"], readonly ["byColour", "GET", "/api/v1/search/colours", "search_by_colour"], readonly ["material", "GET", "/api/v1/materials/{variantId}", "get_material"], readonly ["siblings", "GET", "/api/v1/materials/{variantId}/siblings", "get_material_siblings"], readonly ["materialBlocks", "GET", "/api/v1/materials/{variantId}/blocks", "list_material_blocks"], readonly ["materialAssets", "GET", "/api/v1/materials/{variantId}/assets", "list_material_assets"], readonly ["exploration.operators", "GET", "/api/v1/materials/{variantId}/operators", "list_material_operators"], readonly ["exploration.candidates", "POST", "/api/v1/materials/{variantId}/candidates", "read_material_candidates"], readonly ["schema", "GET", "/api/v1/schema/blocks", "list_schema_blocks"], readonly ["schema", "GET", "/api/v1/schema/attributes", "list_schema_attributes"], readonly ["schema", "GET", "/api/v1/schema/verticals", "list_schema_verticals"], readonly ["schema", "GET", "/api/v1/schema/product-types", "list_schema_product_types"], readonly ["schema", "GET", "/api/v1/schema/units", "list_schema_units"], readonly ["schema", "GET", "/api/v1/schema/value-dictionaries", "list_schema_value_dictionaries"], readonly ["schema", "GET", "/api/v1/schema/source-requirements", "list_schema_source_requirements"], readonly ["schema", "GET", "/api/v1/schema/product-type-templates", "list_schema_product_type_templates"], readonly ["schema", "GET", "/api/v1/schema/mappings", "list_schema_mappings"], readonly ["pairings", "GET", "/api/v1/materials/{variantId}/pairings", "get_material_pairings"], readonly ["associatedFinishes", "GET", "/api/v1/associated/finishes", "list_associated_finishes"], readonly ["associatedProducts", "GET", "/api/v1/associated/products", "list_associated_products"], readonly ["materials", "POST", "/api/v1/materials/batch", "get_materials_batch_post"], readonly ["materialsCached", "GET", "/api/v1/materials/batch", "get_materials_batch_get"], readonly ["browse", "GET", "/api/v1/search/browse", "search_browse_by_colour"], readonly ["colourFacets", "GET", "/api/v1/colours/facets", "get_colour_facets"], readonly ["colours.profiles", "GET", "/api/v1/colours/profiles", "get_category_colour_profiles"], readonly ["colours.stats", "GET", "/api/v1/colours/stats", "get_colour_stats"], readonly ["resolveColour", "GET", "/api/v1/search/colours/resolve", "resolve_colour_name"], readonly ["suggestColour", "GET", "/api/v1/search/colours/suggest", "suggest_colour_names"], readonly ["suggest", "GET", "/api/v1/search/suggest", "search_suggest"], readonly ["resolveAttribute", "GET", "/api/v1/catalog/attributes/resolve", "catalog_resolve_attribute"], readonly ["resolveAttributeValue", "GET", "/api/v1/catalog/attributes/{attributeId}/values/resolve", "catalog_resolve_value"], readonly ["searchVocabulary", "GET", "/api/v1/catalog/vocabulary/search", "catalog_vocabulary_search"], readonly ["resolve", "POST", "/api/v1/resolve", "resolve_phrases"], readonly ["bySpec", "GET", "/api/v1/search/specifications", "catalog_by_spec"], readonly ["taxonomy", "GET", "/api/v1/taxonomy/categories", "get_category_taxonomy"], readonly ["whoami", "GET", "/api/v1/whoami", "whoami"], readonly ["coordinate", "POST", "/api/v1/pairings/coordinate", "coordinate_materials"], readonly ["demand", "GET", "/api/v1/demand", "get_material_demand"], readonly ["colours.palette", "POST", "/api/v1/search/palettes", "search_by_palette"], readonly ["extractPalette", "POST", "/api/v1/search/palettes/extract", "extract_image_palette"], readonly ["colours.gradient", "POST", "/api/v1/search/gradients", "search_by_gradient"], readonly ["specificationFacets", "GET", "/api/v1/catalog/specifications/facets", "list_spec_facets"], readonly ["attributeValues", "GET", "/api/v1/catalog/attributes/{attributeId}/values", "list_attribute_values"], readonly ["applicableSpecs", "GET", "/api/v1/taxonomy/categories/{key}/specs", "get_applicable_specs"], readonly ["glossary", "GET", "/api/v1/glossary/{term}", "explain_material_term"], readonly ["brands", "GET", "/api/v1/brands", "list_brands"], readonly ["brand", "GET", "/api/v1/brands/{brandSlug}", "get_brand_profile"], readonly ["brandColourDeck", "GET", "/api/v1/brands/{brandSlug}/colours", "brand_colour_deck"], readonly ["uploadSourceMaterial", "POST", "/api/v1/source-material", "upload_source_material"], readonly ["sourceMaterialBatch", "GET", "/api/v1/source-material/{batchId}", "get_source_material_batch"], readonly ["sourceMaterialComments", "GET", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "list_source_material_comments"], readonly ["sourceMaterialComments", "POST", "/api/v1/source-material/{batchId}/sources/{sourceId}/comments", "post_source_material_comment"], readonly ["capabilities", "GET", "/api/v1/capabilities", "list_public_capabilities"], readonly ["createRun", "POST", "/api/v1/runs", "create_public_run"], readonly ["listRuns", "GET", "/api/v1/runs", "list_public_runs"], readonly ["run", "GET", "/api/v1/runs/{runId}", "get_public_run"], readonly ["runSchedule", "GET", "/api/v1/runs/{runId}/schedule", "get_run_finish_schedule"], readonly ["streamRunEvents", "GET", "/api/v1/runs/{runId}/events", "list_public_run_events"], readonly ["resumeRun", "POST", "/api/v1/runs/{runId}/resume", "resume_public_run"], readonly ["cancelRun", "POST", "/api/v1/runs/{runId}/cancel", "cancel_public_run"], readonly ["varyScheme", "POST", "/api/v1/schemes/vary", "vary_schemes"], readonly ["slotPools", "POST", "/api/v1/schemes/pools", "slot_pools"], readonly ["createProject", "POST", "/api/v1/projects", "create_box_project"], readonly ["listProjects", "GET", "/api/v1/projects", "list_box_projects"], readonly ["getProject", "GET", "/api/v1/projects/{projectId}", "get_box_project"], readonly ["appendProjectEvent", "POST", "/api/v1/projects/{projectId}/events", "append_box_project_event"], readonly ["demandBatch", "POST", "/api/v1/demand/batch", "get_demand_batch"], readonly ["codeAdvisory", "POST", "/api/v1/codes/advisory", "resolveCodeAdvisory"], readonly ["codes.context", "GET", "/api/v1/codes/context", "list_code_context"], readonly ["codes.requirements", "GET", "/api/v1/codes/requirements", "list_code_requirements"]];
|
|
3
3
|
export type SdkOperationId = (typeof OPERATION_DEFINITIONS)[number][3];
|
|
4
4
|
export type SdkOperation = Readonly<{
|
|
5
5
|
clientMethod: (typeof OPERATION_DEFINITIONS)[number][0];
|
package/operations.js
CHANGED
|
@@ -24,6 +24,18 @@ const OPERATION_DEFINITIONS = [
|
|
|
24
24
|
"/api/v1/materials/{variantId}/assets",
|
|
25
25
|
"list_material_assets",
|
|
26
26
|
],
|
|
27
|
+
[
|
|
28
|
+
"exploration.operators",
|
|
29
|
+
"GET",
|
|
30
|
+
"/api/v1/materials/{variantId}/operators",
|
|
31
|
+
"list_material_operators",
|
|
32
|
+
],
|
|
33
|
+
[
|
|
34
|
+
"exploration.candidates",
|
|
35
|
+
"POST",
|
|
36
|
+
"/api/v1/materials/{variantId}/candidates",
|
|
37
|
+
"read_material_candidates",
|
|
38
|
+
],
|
|
27
39
|
["schema", "GET", "/api/v1/schema/blocks", "list_schema_blocks"],
|
|
28
40
|
["schema", "GET", "/api/v1/schema/attributes", "list_schema_attributes"],
|
|
29
41
|
["schema", "GET", "/api/v1/schema/verticals", "list_schema_verticals"],
|
|
@@ -176,6 +188,18 @@ const OPERATION_DEFINITIONS = [
|
|
|
176
188
|
"/api/v1/source-material/{batchId}",
|
|
177
189
|
"get_source_material_batch",
|
|
178
190
|
],
|
|
191
|
+
[
|
|
192
|
+
"sourceMaterialComments",
|
|
193
|
+
"GET",
|
|
194
|
+
"/api/v1/source-material/{batchId}/sources/{sourceId}/comments",
|
|
195
|
+
"list_source_material_comments",
|
|
196
|
+
],
|
|
197
|
+
[
|
|
198
|
+
"sourceMaterialComments",
|
|
199
|
+
"POST",
|
|
200
|
+
"/api/v1/source-material/{batchId}/sources/{sourceId}/comments",
|
|
201
|
+
"post_source_material_comment",
|
|
202
|
+
],
|
|
179
203
|
["capabilities", "GET", "/api/v1/capabilities", "list_public_capabilities"],
|
|
180
204
|
["createRun", "POST", "/api/v1/runs", "create_public_run"],
|
|
181
205
|
["listRuns", "GET", "/api/v1/runs", "list_public_runs"],
|
|
@@ -195,6 +219,7 @@ const OPERATION_DEFINITIONS = [
|
|
|
195
219
|
["resumeRun", "POST", "/api/v1/runs/{runId}/resume", "resume_public_run"],
|
|
196
220
|
["cancelRun", "POST", "/api/v1/runs/{runId}/cancel", "cancel_public_run"],
|
|
197
221
|
["varyScheme", "POST", "/api/v1/schemes/vary", "vary_schemes"],
|
|
222
|
+
["slotPools", "POST", "/api/v1/schemes/pools", "slot_pools"],
|
|
198
223
|
["createProject", "POST", "/api/v1/projects", "create_box_project"],
|
|
199
224
|
["listProjects", "GET", "/api/v1/projects", "list_box_projects"],
|
|
200
225
|
["getProject", "GET", "/api/v1/projects/{projectId}", "get_box_project"],
|
package/package.json
CHANGED
|
@@ -86,6 +86,18 @@ export interface MultiColourMatchBase {
|
|
|
86
86
|
imageUrl: string | null;
|
|
87
87
|
/** MB has retired or hidden this SKU. */
|
|
88
88
|
retired: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* The catalog GROUP — "Flooring", "Textile Materials", "Coatings" — or null
|
|
91
|
+
* when the material has no accepted primary product type.
|
|
92
|
+
*
|
|
93
|
+
* A palette query is cross-category BY INTENT: a designer building a scheme,
|
|
94
|
+
* not browsing one aisle. So this is the field that says whether a result
|
|
95
|
+
* answers the question — one real palette returned 30 of 40 results in a
|
|
96
|
+
* single category while every one of the fourteen groups held something
|
|
97
|
+
* closer on the same colours (MG-1245). Group by it, and keep null as its own
|
|
98
|
+
* bucket: null means UNKNOWN, not uncategorised, and it is not rare.
|
|
99
|
+
*/
|
|
100
|
+
category: string | null;
|
|
89
101
|
/** The candidate's full extracted palette — the evidence scored against. */
|
|
90
102
|
palette: CandidateSwatch[];
|
|
91
103
|
/** The aggregate match score in [0,1]; higher is closer. */
|
|
@@ -105,6 +117,23 @@ export interface GradientMatch extends MultiColourMatchBase {
|
|
|
105
117
|
/** One receipt per sampled point along the path, in path order. */
|
|
106
118
|
samples: ColourMatchReceipt[];
|
|
107
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* The hue-family ADMISSION gate the page was scored under: a candidate swatch
|
|
122
|
+
* may satisfy a query colour only if colorscope's `isHueCompatible` admits it
|
|
123
|
+
* at these exact thresholds. A refused swatch is absent from that colour's
|
|
124
|
+
* matching entirely — it did not merely rank low. Admission, not ranking: it
|
|
125
|
+
* decides which swatches count, never their order. Server-side and fixed (no
|
|
126
|
+
* request knob); the receipt exists so a threshold change is visible on the
|
|
127
|
+
* wire.
|
|
128
|
+
*/
|
|
129
|
+
export interface HueGateReceipt {
|
|
130
|
+
/** Below this query chroma the colour is achromatic and any hue is admitted. */
|
|
131
|
+
achromaticQueryChroma: number;
|
|
132
|
+
/** A swatch must carry at least this share of the query colour's chroma. */
|
|
133
|
+
minChromaRatio: number;
|
|
134
|
+
/** Floor on the cosine agreement between the two hue vectors. */
|
|
135
|
+
minHueCosine: number;
|
|
136
|
+
}
|
|
108
137
|
/**
|
|
109
138
|
* A PAGE, NOT A CORPUS. `count` is `matches.length` under `limit` (24 default,
|
|
110
139
|
* 48 max) — this surface states no corpus total and has no cursor, so "N
|
|
@@ -120,6 +149,8 @@ export interface SearchPaletteResponse {
|
|
|
120
149
|
}>;
|
|
121
150
|
logic: PaletteLogic;
|
|
122
151
|
};
|
|
152
|
+
/** The hue-family admission gate this page was scored under. */
|
|
153
|
+
hueGate: HueGateReceipt;
|
|
123
154
|
/** `matches.length`, capped by `limit`. Never a corpus total. */
|
|
124
155
|
count: number;
|
|
125
156
|
matches: PaletteMatch[];
|