@decantr/registry 1.0.2 → 1.0.3

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.js CHANGED
@@ -1,262 +1,3 @@
1
- // src/types.ts
2
- var CONTENT_TYPES = [
3
- "pattern",
4
- "theme",
5
- "blueprint",
6
- "archetype",
7
- "shell"
8
- ];
9
- var API_CONTENT_TYPES = [
10
- "patterns",
11
- "themes",
12
- "blueprints",
13
- "archetypes",
14
- "shells"
15
- ];
16
- var CONTENT_TYPE_TO_API_CONTENT_TYPE = {
17
- pattern: "patterns",
18
- theme: "themes",
19
- blueprint: "blueprints",
20
- archetype: "archetypes",
21
- shell: "shells"
22
- };
23
- var API_CONTENT_TYPE_TO_CONTENT_TYPE = {
24
- patterns: "pattern",
25
- themes: "theme",
26
- blueprints: "blueprint",
27
- archetypes: "archetype",
28
- shells: "shell"
29
- };
30
- function isContentType(value) {
31
- return CONTENT_TYPES.includes(value);
32
- }
33
- function isApiContentType(value) {
34
- return API_CONTENT_TYPES.includes(value);
35
- }
36
- var PUBLIC_CONTENT_SOURCES = [
37
- "official",
38
- "community",
39
- "organization"
40
- ];
41
- function isPublicContentSource(value) {
42
- return PUBLIC_CONTENT_SOURCES.includes(value);
43
- }
44
- var CONTENT_INTELLIGENCE_SOURCES = [
45
- "authored",
46
- "benchmark",
47
- "hybrid"
48
- ];
49
- function isContentIntelligenceSource(value) {
50
- return CONTENT_INTELLIGENCE_SOURCES.includes(value);
51
- }
52
-
53
- // src/resolver.ts
54
- import { readFile } from "fs/promises";
55
- import { join } from "path";
56
- var TYPE_DIRS = {
57
- pattern: "patterns",
58
- archetype: "archetypes",
59
- theme: "themes",
60
- blueprint: "blueprints",
61
- shell: "shells"
62
- };
63
- async function tryLoadJson(filePath) {
64
- try {
65
- const content = await readFile(filePath, "utf-8");
66
- return JSON.parse(content);
67
- } catch {
68
- return null;
69
- }
70
- }
71
- function createResolver(options) {
72
- const { contentRoot, overridePaths = [] } = options;
73
- return {
74
- async resolve(type, id) {
75
- const dir = TYPE_DIRS[type];
76
- const fileName = `${id}.json`;
77
- for (const overridePath of overridePaths) {
78
- const filePath = join(overridePath, dir, fileName);
79
- const item = await tryLoadJson(filePath);
80
- if (item) return { item, source: "local", path: filePath };
81
- }
82
- const mainPath = join(contentRoot, dir, fileName);
83
- const mainItem = await tryLoadJson(mainPath);
84
- if (mainItem) return { item: mainItem, source: "core", path: mainPath };
85
- const corePath = join(contentRoot, "core", dir, fileName);
86
- const coreItem = await tryLoadJson(corePath);
87
- if (coreItem) return { item: coreItem, source: "core", path: corePath };
88
- return null;
89
- }
90
- };
91
- }
92
-
93
- // src/pattern.ts
94
- function resolvePatternPreset(pattern, explicitPreset, themeDefaultPresets) {
95
- const presets = pattern.presets;
96
- const hasPresets = Object.keys(presets).length > 0;
97
- if (!hasPresets) {
98
- return {
99
- preset: "",
100
- layout: { layout: "row", atoms: "" },
101
- code: pattern.code ?? { imports: "", example: "" }
102
- };
103
- }
104
- let presetName = explicitPreset;
105
- if (presetName && !presets[presetName]) presetName = void 0;
106
- if (!presetName && themeDefaultPresets?.[pattern.id]) {
107
- const themeName = themeDefaultPresets[pattern.id];
108
- if (presets[themeName]) presetName = themeName;
109
- }
110
- if (!presetName) presetName = pattern.default_preset;
111
- if (!presetName || !presets[presetName]) presetName = Object.keys(presets)[0];
112
- const preset = presets[presetName];
113
- return { preset: presetName, layout: preset.layout, code: preset.code };
114
- }
115
-
116
- // src/wiring.ts
117
- var WIRING_RULES = [
118
- {
119
- pair: ["filter-bar", "data-table"],
120
- signals: [
121
- { name: "pageSearch", init: "''", hookType: "search" },
122
- { name: "pageStatus", init: "'all'", hookType: "filter" }
123
- ],
124
- props: {
125
- "filter-bar": { onSearch: "setPageSearch", onCategory: "setPageStatus" },
126
- "data-table": { search: "pageSearch", status: "pageStatus" }
127
- },
128
- hookProps: {
129
- "filter-bar": { search: "search", filters: "filters" },
130
- "data-table": { search: "search", filters: "filters" }
131
- }
132
- },
133
- {
134
- pair: ["filter-bar", "activity-feed"],
135
- signals: [
136
- { name: "pageSearch", init: "''", hookType: "search" },
137
- { name: "pageView", init: "'all'", hookType: "filter" }
138
- ],
139
- props: {
140
- "filter-bar": { onSearch: "setPageSearch", onView: "setPageView" },
141
- "activity-feed": { search: "pageSearch", view: "pageView" }
142
- },
143
- hookProps: {
144
- "filter-bar": { search: "search", filters: "filters" },
145
- "activity-feed": { search: "search", filters: "filters" }
146
- }
147
- },
148
- {
149
- pair: ["filter-bar", "card-grid"],
150
- signals: [
151
- { name: "pageSearch", init: "''", hookType: "search" }
152
- ],
153
- props: {
154
- "filter-bar": { onSearch: "setPageSearch" },
155
- "card-grid": { search: "pageSearch" }
156
- },
157
- hookProps: {
158
- "filter-bar": { search: "search" },
159
- "card-grid": { search: "search" }
160
- }
161
- }
162
- ];
163
- function getPatternId(item) {
164
- if (typeof item === "string") return item;
165
- if ("pattern" in item) return item.pattern;
166
- return null;
167
- }
168
- function deriveIOWirings(layoutIds, patternIOMap) {
169
- const edges = [];
170
- const layoutSet = new Set(layoutIds);
171
- for (const producerId of layoutIds) {
172
- const producerIO = patternIOMap.get(producerId);
173
- if (!producerIO?.produces?.length) continue;
174
- for (const consumerId of layoutIds) {
175
- if (producerId === consumerId) continue;
176
- if (!layoutSet.has(consumerId)) continue;
177
- const consumerIO = patternIOMap.get(consumerId);
178
- if (!consumerIO?.consumes?.length) continue;
179
- const shared = producerIO.produces.filter(
180
- (signal) => consumerIO.consumes.includes(signal)
181
- );
182
- if (shared.length > 0) {
183
- edges.push({ producer: producerId, consumer: consumerId, signals: shared });
184
- }
185
- }
186
- }
187
- return edges;
188
- }
189
- function buildIOMap(entries) {
190
- const map = /* @__PURE__ */ new Map();
191
- for (const entry of entries) {
192
- map.set(entry.id, entry.io);
193
- }
194
- return map;
195
- }
196
- function detectWirings(layout, patternIOMap) {
197
- const patternIds = layout.map(getPatternId).filter((id) => id !== null);
198
- const results = [];
199
- const coveredPairs = /* @__PURE__ */ new Set();
200
- for (const rule of WIRING_RULES) {
201
- const [a, b] = rule.pair;
202
- if (patternIds.includes(a) && patternIds.includes(b)) {
203
- results.push({ rule, signals: rule.signals, props: rule.props, hookProps: rule.hookProps });
204
- coveredPairs.add(`${a}:${b}`);
205
- coveredPairs.add(`${b}:${a}`);
206
- }
207
- }
208
- if (patternIOMap) {
209
- const ioEdges = deriveIOWirings(patternIds, patternIOMap);
210
- for (const edge of ioEdges) {
211
- const pairKey = `${edge.producer}:${edge.consumer}`;
212
- if (coveredPairs.has(pairKey)) continue;
213
- coveredPairs.add(pairKey);
214
- const signals = edge.signals.map((sig) => {
215
- const camel = toCamelCase(sig);
216
- return {
217
- name: `page${capitalize(camel)}`,
218
- init: "''",
219
- hookType: classifySignal(sig)
220
- };
221
- });
222
- const producerProps = {};
223
- const consumerProps = {};
224
- const producerHookProps = {};
225
- const consumerHookProps = {};
226
- for (const sig of edge.signals) {
227
- const camel = toCamelCase(sig);
228
- const stateName = `page${capitalize(camel)}`;
229
- const setterName = `set${capitalize(stateName)}`;
230
- producerProps[`on${capitalize(camel)}`] = setterName;
231
- consumerProps[sig] = stateName;
232
- producerHookProps[sig] = sig;
233
- consumerHookProps[sig] = sig;
234
- }
235
- const rule = {
236
- pair: [edge.producer, edge.consumer],
237
- signals,
238
- props: { [edge.producer]: producerProps, [edge.consumer]: consumerProps },
239
- hookProps: { [edge.producer]: producerHookProps, [edge.consumer]: consumerHookProps }
240
- };
241
- results.push({ rule, signals, props: rule.props, hookProps: rule.hookProps });
242
- }
243
- }
244
- return results;
245
- }
246
- function toCamelCase(str) {
247
- return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
248
- }
249
- function capitalize(str) {
250
- return str.charAt(0).toUpperCase() + str.slice(1);
251
- }
252
- function classifySignal(signal) {
253
- const normalized = toCamelCase(signal);
254
- if (normalized === "search") return "search";
255
- if (normalized === "selection") return "selection";
256
- if (normalized === "sort") return "sort";
257
- return "filter";
258
- }
259
-
260
1
  // src/api-client.ts
261
2
  var DEFAULT_BASE_URL = "https://api.decantr.ai/v1";
262
3
  var DEFAULT_TIMEOUT_MS = 3e4;
@@ -297,7 +38,7 @@ var RegistryAPIClient = class {
297
38
  // ── HTTP helpers ──
298
39
  buildHeaders() {
299
40
  const headers = {
300
- "Accept": "application/json"
41
+ Accept: "application/json"
301
42
  };
302
43
  if (this.apiKey) {
303
44
  headers["X-API-Key"] = this.apiKey;
@@ -378,7 +119,8 @@ var RegistryAPIClient = class {
378
119
  if (params?.source) searchParams.set("source", params.source);
379
120
  if (params?.sort) searchParams.set("sort", params.sort);
380
121
  if (params?.recommended) searchParams.set("recommended", "true");
381
- if (params?.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
122
+ if (params?.intelligenceSource)
123
+ searchParams.set("intelligence_source", params.intelligenceSource);
382
124
  if (params?.limit) searchParams.set("limit", String(params.limit));
383
125
  if (params?.offset) searchParams.set("offset", String(params.offset));
384
126
  const query = searchParams.toString();
@@ -436,7 +178,8 @@ var RegistryAPIClient = class {
436
178
  if (params.source) searchParams.set("source", params.source);
437
179
  if (params.sort) searchParams.set("sort", params.sort);
438
180
  if (params.recommended) searchParams.set("recommended", "true");
439
- if (params.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
181
+ if (params.intelligenceSource)
182
+ searchParams.set("intelligence_source", params.intelligenceSource);
440
183
  if (params.limit) searchParams.set("limit", String(params.limit));
441
184
  if (params.offset) searchParams.set("offset", String(params.offset));
442
185
  return this.request(`/search?${searchParams}`);
@@ -458,7 +201,8 @@ var RegistryAPIClient = class {
458
201
  if (params?.source) searchParams.set("source", params.source);
459
202
  if (params?.sort) searchParams.set("sort", params.sort);
460
203
  if (params?.recommended) searchParams.set("recommended", "true");
461
- if (params?.intelligenceSource) searchParams.set("intelligence_source", params.intelligenceSource);
204
+ if (params?.intelligenceSource)
205
+ searchParams.set("intelligence_source", params.intelligenceSource);
462
206
  if (params?.limit != null) searchParams.set("limit", String(params.limit));
463
207
  if (params?.offset != null) searchParams.set("offset", String(params.offset));
464
208
  const query = searchParams.toString();
@@ -540,27 +284,21 @@ var RegistryAPIClient = class {
540
284
  const searchParams = new URLSearchParams();
541
285
  if (params?.namespace) searchParams.set("namespace", params.namespace);
542
286
  const query = searchParams.toString();
543
- return this.request(
544
- `/packs/compile${query ? `?${query}` : ""}`,
545
- {
546
- method: "POST",
547
- headers: { "Content-Type": "application/json" },
548
- body: JSON.stringify(essence)
549
- }
550
- );
287
+ return this.request(`/packs/compile${query ? `?${query}` : ""}`, {
288
+ method: "POST",
289
+ headers: { "Content-Type": "application/json" },
290
+ body: JSON.stringify(essence)
291
+ });
551
292
  }
552
293
  async selectExecutionPack(input, params) {
553
294
  const searchParams = new URLSearchParams();
554
295
  if (params?.namespace) searchParams.set("namespace", params.namespace);
555
296
  const query = searchParams.toString();
556
- return this.request(
557
- `/packs/select${query ? `?${query}` : ""}`,
558
- {
559
- method: "POST",
560
- headers: { "Content-Type": "application/json" },
561
- body: JSON.stringify(input)
562
- }
563
- );
297
+ return this.request(`/packs/select${query ? `?${query}` : ""}`, {
298
+ method: "POST",
299
+ headers: { "Content-Type": "application/json" },
300
+ body: JSON.stringify(input)
301
+ });
564
302
  }
565
303
  async getExecutionPackManifest(essence, params) {
566
304
  const selected = await this.selectExecutionPack(
@@ -576,27 +314,21 @@ var RegistryAPIClient = class {
576
314
  const searchParams = new URLSearchParams();
577
315
  if (params?.namespace) searchParams.set("namespace", params.namespace);
578
316
  const query = searchParams.toString();
579
- return this.request(
580
- `/critique/file${query ? `?${query}` : ""}`,
581
- {
582
- method: "POST",
583
- headers: { "Content-Type": "application/json" },
584
- body: JSON.stringify(input)
585
- }
586
- );
317
+ return this.request(`/critique/file${query ? `?${query}` : ""}`, {
318
+ method: "POST",
319
+ headers: { "Content-Type": "application/json" },
320
+ body: JSON.stringify(input)
321
+ });
587
322
  }
588
323
  async auditProject(input, params) {
589
324
  const searchParams = new URLSearchParams();
590
325
  if (params?.namespace) searchParams.set("namespace", params.namespace);
591
326
  const query = searchParams.toString();
592
- return this.request(
593
- `/audit/project${query ? `?${query}` : ""}`,
594
- {
595
- method: "POST",
596
- headers: { "Content-Type": "application/json" },
597
- body: JSON.stringify(input)
598
- }
599
- );
327
+ return this.request(`/audit/project${query ? `?${query}` : ""}`, {
328
+ method: "POST",
329
+ headers: { "Content-Type": "application/json" },
330
+ body: JSON.stringify(input)
331
+ });
600
332
  }
601
333
  };
602
334
  function createRegistryClient(options = {}) {
@@ -620,6 +352,29 @@ function createRegistryClient(options = {}) {
620
352
  };
621
353
  }
622
354
 
355
+ // src/pattern.ts
356
+ function resolvePatternPreset(pattern, explicitPreset, themeDefaultPresets) {
357
+ const presets = pattern.presets;
358
+ const hasPresets = Object.keys(presets).length > 0;
359
+ if (!hasPresets) {
360
+ return {
361
+ preset: "",
362
+ layout: { layout: "row", atoms: "" },
363
+ code: pattern.code ?? { imports: "", example: "" }
364
+ };
365
+ }
366
+ let presetName = explicitPreset;
367
+ if (presetName && !presets[presetName]) presetName = void 0;
368
+ if (!presetName && themeDefaultPresets?.[pattern.id]) {
369
+ const themeName = themeDefaultPresets[pattern.id];
370
+ if (presets[themeName]) presetName = themeName;
371
+ }
372
+ if (!presetName) presetName = pattern.default_preset;
373
+ if (!presetName || !presets[presetName]) presetName = Object.keys(presets)[0];
374
+ const preset = presets[presetName];
375
+ return { preset: presetName, layout: preset.layout, code: preset.code };
376
+ }
377
+
623
378
  // src/ranking.ts
624
379
  function verificationScore(status) {
625
380
  switch (status) {
@@ -726,6 +481,224 @@ function comparePublicContent(a, b, sort = "recommended") {
726
481
  function sortPublicContent(items, sort = "recommended") {
727
482
  return [...items].sort((left, right) => comparePublicContent(left, right, sort));
728
483
  }
484
+
485
+ // src/resolver.ts
486
+ import { readFile } from "fs/promises";
487
+ import { join } from "path";
488
+ var TYPE_DIRS = {
489
+ pattern: "patterns",
490
+ archetype: "archetypes",
491
+ theme: "themes",
492
+ blueprint: "blueprints",
493
+ shell: "shells"
494
+ };
495
+ async function tryLoadJson(filePath) {
496
+ try {
497
+ const content = await readFile(filePath, "utf-8");
498
+ return JSON.parse(content);
499
+ } catch {
500
+ return null;
501
+ }
502
+ }
503
+ function createResolver(options) {
504
+ const { contentRoot, overridePaths = [] } = options;
505
+ return {
506
+ async resolve(type, id) {
507
+ const dir = TYPE_DIRS[type];
508
+ const fileName = `${id}.json`;
509
+ for (const overridePath of overridePaths) {
510
+ const filePath = join(overridePath, dir, fileName);
511
+ const item = await tryLoadJson(filePath);
512
+ if (item) return { item, source: "local", path: filePath };
513
+ }
514
+ const mainPath = join(contentRoot, dir, fileName);
515
+ const mainItem = await tryLoadJson(mainPath);
516
+ if (mainItem) return { item: mainItem, source: "core", path: mainPath };
517
+ const corePath = join(contentRoot, "core", dir, fileName);
518
+ const coreItem = await tryLoadJson(corePath);
519
+ if (coreItem) return { item: coreItem, source: "core", path: corePath };
520
+ return null;
521
+ }
522
+ };
523
+ }
524
+
525
+ // src/types.ts
526
+ var CONTENT_TYPES = ["pattern", "theme", "blueprint", "archetype", "shell"];
527
+ var API_CONTENT_TYPES = [
528
+ "patterns",
529
+ "themes",
530
+ "blueprints",
531
+ "archetypes",
532
+ "shells"
533
+ ];
534
+ var CONTENT_TYPE_TO_API_CONTENT_TYPE = {
535
+ pattern: "patterns",
536
+ theme: "themes",
537
+ blueprint: "blueprints",
538
+ archetype: "archetypes",
539
+ shell: "shells"
540
+ };
541
+ var API_CONTENT_TYPE_TO_CONTENT_TYPE = {
542
+ patterns: "pattern",
543
+ themes: "theme",
544
+ blueprints: "blueprint",
545
+ archetypes: "archetype",
546
+ shells: "shell"
547
+ };
548
+ function isContentType(value) {
549
+ return CONTENT_TYPES.includes(value);
550
+ }
551
+ function isApiContentType(value) {
552
+ return API_CONTENT_TYPES.includes(value);
553
+ }
554
+ var PUBLIC_CONTENT_SOURCES = ["official", "community", "organization"];
555
+ function isPublicContentSource(value) {
556
+ return PUBLIC_CONTENT_SOURCES.includes(value);
557
+ }
558
+ var CONTENT_INTELLIGENCE_SOURCES = ["authored", "benchmark", "hybrid"];
559
+ function isContentIntelligenceSource(value) {
560
+ return CONTENT_INTELLIGENCE_SOURCES.includes(value);
561
+ }
562
+
563
+ // src/wiring.ts
564
+ var WIRING_RULES = [
565
+ {
566
+ pair: ["filter-bar", "data-table"],
567
+ signals: [
568
+ { name: "pageSearch", init: "''", hookType: "search" },
569
+ { name: "pageStatus", init: "'all'", hookType: "filter" }
570
+ ],
571
+ props: {
572
+ "filter-bar": { onSearch: "setPageSearch", onCategory: "setPageStatus" },
573
+ "data-table": { search: "pageSearch", status: "pageStatus" }
574
+ },
575
+ hookProps: {
576
+ "filter-bar": { search: "search", filters: "filters" },
577
+ "data-table": { search: "search", filters: "filters" }
578
+ }
579
+ },
580
+ {
581
+ pair: ["filter-bar", "activity-feed"],
582
+ signals: [
583
+ { name: "pageSearch", init: "''", hookType: "search" },
584
+ { name: "pageView", init: "'all'", hookType: "filter" }
585
+ ],
586
+ props: {
587
+ "filter-bar": { onSearch: "setPageSearch", onView: "setPageView" },
588
+ "activity-feed": { search: "pageSearch", view: "pageView" }
589
+ },
590
+ hookProps: {
591
+ "filter-bar": { search: "search", filters: "filters" },
592
+ "activity-feed": { search: "search", filters: "filters" }
593
+ }
594
+ },
595
+ {
596
+ pair: ["filter-bar", "card-grid"],
597
+ signals: [{ name: "pageSearch", init: "''", hookType: "search" }],
598
+ props: {
599
+ "filter-bar": { onSearch: "setPageSearch" },
600
+ "card-grid": { search: "pageSearch" }
601
+ },
602
+ hookProps: {
603
+ "filter-bar": { search: "search" },
604
+ "card-grid": { search: "search" }
605
+ }
606
+ }
607
+ ];
608
+ function getPatternId(item) {
609
+ if (typeof item === "string") return item;
610
+ if ("pattern" in item) return item.pattern;
611
+ return null;
612
+ }
613
+ function deriveIOWirings(layoutIds, patternIOMap) {
614
+ const edges = [];
615
+ const layoutSet = new Set(layoutIds);
616
+ for (const producerId of layoutIds) {
617
+ const producerIO = patternIOMap.get(producerId);
618
+ if (!producerIO?.produces?.length) continue;
619
+ for (const consumerId of layoutIds) {
620
+ if (producerId === consumerId) continue;
621
+ if (!layoutSet.has(consumerId)) continue;
622
+ const consumerIO = patternIOMap.get(consumerId);
623
+ if (!consumerIO?.consumes?.length) continue;
624
+ const shared = producerIO.produces.filter((signal) => consumerIO.consumes.includes(signal));
625
+ if (shared.length > 0) {
626
+ edges.push({ producer: producerId, consumer: consumerId, signals: shared });
627
+ }
628
+ }
629
+ }
630
+ return edges;
631
+ }
632
+ function buildIOMap(entries) {
633
+ const map = /* @__PURE__ */ new Map();
634
+ for (const entry of entries) {
635
+ map.set(entry.id, entry.io);
636
+ }
637
+ return map;
638
+ }
639
+ function detectWirings(layout, patternIOMap) {
640
+ const patternIds = layout.map(getPatternId).filter((id) => id !== null);
641
+ const results = [];
642
+ const coveredPairs = /* @__PURE__ */ new Set();
643
+ for (const rule of WIRING_RULES) {
644
+ const [a, b] = rule.pair;
645
+ if (patternIds.includes(a) && patternIds.includes(b)) {
646
+ results.push({ rule, signals: rule.signals, props: rule.props, hookProps: rule.hookProps });
647
+ coveredPairs.add(`${a}:${b}`);
648
+ coveredPairs.add(`${b}:${a}`);
649
+ }
650
+ }
651
+ if (patternIOMap) {
652
+ const ioEdges = deriveIOWirings(patternIds, patternIOMap);
653
+ for (const edge of ioEdges) {
654
+ const pairKey = `${edge.producer}:${edge.consumer}`;
655
+ if (coveredPairs.has(pairKey)) continue;
656
+ coveredPairs.add(pairKey);
657
+ const signals = edge.signals.map((sig) => {
658
+ const camel = toCamelCase(sig);
659
+ return {
660
+ name: `page${capitalize(camel)}`,
661
+ init: "''",
662
+ hookType: classifySignal(sig)
663
+ };
664
+ });
665
+ const producerProps = {};
666
+ const consumerProps = {};
667
+ const producerHookProps = {};
668
+ const consumerHookProps = {};
669
+ for (const sig of edge.signals) {
670
+ const camel = toCamelCase(sig);
671
+ const stateName = `page${capitalize(camel)}`;
672
+ const setterName = `set${capitalize(stateName)}`;
673
+ producerProps[`on${capitalize(camel)}`] = setterName;
674
+ consumerProps[sig] = stateName;
675
+ producerHookProps[sig] = sig;
676
+ consumerHookProps[sig] = sig;
677
+ }
678
+ const rule = {
679
+ pair: [edge.producer, edge.consumer],
680
+ signals,
681
+ props: { [edge.producer]: producerProps, [edge.consumer]: consumerProps },
682
+ hookProps: { [edge.producer]: producerHookProps, [edge.consumer]: consumerHookProps }
683
+ };
684
+ results.push({ rule, signals, props: rule.props, hookProps: rule.hookProps });
685
+ }
686
+ }
687
+ return results;
688
+ }
689
+ function toCamelCase(str) {
690
+ return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
691
+ }
692
+ function capitalize(str) {
693
+ return str.charAt(0).toUpperCase() + str.slice(1);
694
+ }
695
+ function classifySignal(signal) {
696
+ const normalized = toCamelCase(signal);
697
+ if (normalized === "search") return "search";
698
+ if (normalized === "selection") return "selection";
699
+ if (normalized === "sort") return "sort";
700
+ return "filter";
701
+ }
729
702
  export {
730
703
  API_CONTENT_TYPES,
731
704
  API_CONTENT_TYPE_TO_CONTENT_TYPE,