@adia-ai/a2ui-retrieval 0.0.1

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.
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Wiring Catalog — Knowledge base for the gen-ui pipeline.
3
+ *
4
+ * Indexes available wiring capabilities so the generator can emit valid
5
+ * wireComponents declarations alongside component trees.
6
+ *
7
+ * The schema has 5 docking points:
8
+ * DATA — sources, params (how the surface gets its data)
9
+ * STATE — controllers, model (how components manage behavior)
10
+ * ACTIONS — AdiaEvent → handler chains (what happens on events)
11
+ * PROVIDES — context injection into subtrees
12
+ * LIFECYCLE — onMount, onUnmount, onModelChange hooks
13
+ *
14
+ * Each point is optional. A static display surface needs none.
15
+ * A form needs STATE (FormController) + ACTIONS (submit).
16
+ * A dashboard needs DATA (sources) + STATE (DataStreamController).
17
+ * A full app needs all five.
18
+ */
19
+
20
+ // ── AdiaEvent ──────────────────────────────────────────────────
21
+ // A typed event object that the wiring system understands natively.
22
+ // Maps 1:1 to DOM events but with AdiaUI semantics and payload contracts.
23
+ //
24
+ // { "event": "press", "target": "save-btn" }
25
+ // { "event": "input", "target": "search", "debounce": 300 }
26
+ // { "event": "submit", "target": "form-col" }
27
+ // { "event": "mount" }
28
+ //
29
+ // "event" — AdiaEvent type name (see adiaEvents below)
30
+ // "target" — component id that emits. Omit for surface-level events.
31
+ // "debounce" — ms, coalesce rapid-fire (input, resize)
32
+ // "throttle" — ms, limit frequency (scroll, drag)
33
+ // "condition" — guard: { path, equals|notEquals|exists }
34
+
35
+ const adiaEvents = [
36
+ { event: 'press', payload: null, description: 'Button or interactive element activated.' },
37
+ { event: 'submit', payload: 'form-values', description: 'Form submission with validated field values.' },
38
+ { event: 'input', payload: 'target-value', description: 'Value changed (fires on every keystroke).' },
39
+ { event: 'change', payload: 'event-detail', description: 'Value committed (fires on blur or selection).' },
40
+ { event: 'select', payload: 'event-detail', description: 'Item selected from list, table, or menu.' },
41
+ { event: 'toggle', payload: 'boolean', description: 'Boolean state flipped (switch, checkbox).' },
42
+ { event: 'dismiss', payload: null, description: 'Close/dismiss (dialog, toast, popover).' },
43
+ { event: 'navigate', payload: 'route', description: 'Internal navigation request.' },
44
+ { event: 'mount', payload: null, description: 'Surface or component entered the DOM.' },
45
+ { event: 'unmount', payload: null, description: 'Surface or component left the DOM.' },
46
+ { event: 'focus', payload: null, description: 'Element received focus.' },
47
+ { event: 'blur', payload: null, description: 'Element lost focus.' },
48
+ { event: 'drag', payload: 'event-detail', description: 'Drag operation on a sortable/draggable.' },
49
+ { event: 'drop', payload: 'event-detail', description: 'Drop completed on a sortable/draggable.' },
50
+ ];
51
+
52
+ /**
53
+ * Get the full wiring catalog.
54
+ * @returns {object}
55
+ */
56
+ export function getWiringCatalog() {
57
+ return {
58
+ // ── ADIA EVENTS ──
59
+ adiaEvents,
60
+
61
+ // ── DATA: how the surface gets its data ──
62
+ data: {
63
+ description: 'Fetch external data into the surface model. Sources are URI-based with refresh strategies.',
64
+ paramSources: ['route', 'store', 'literal', 'query', 'parent'],
65
+ uriSchemes: ['resource://', 'api://', 'mock://', 'ws://', 'sse://'],
66
+ refreshStrategies: ['once', 'on-focus', 'interval:{ms}', 'stream'],
67
+ example: {
68
+ params: { userId: { from: 'route', key: 'id' } },
69
+ sources: [
70
+ { id: 'user', uri: 'resource://users/{userId}', path: '/user', refresh: 'once' },
71
+ { id: 'activity', uri: 'resource://users/{userId}/activity', path: '/activity', refresh: 'on-focus' },
72
+ ],
73
+ },
74
+ },
75
+
76
+ // ── STATE: controllers that manage component behavior ──
77
+ controllers: [
78
+ {
79
+ type: 'FormController',
80
+ description: 'Manages field values, validation, dirty/pristine tracking. Attach to a Column/Section containing form fields.',
81
+ config: {
82
+ validateOn: { type: 'string', enum: ['blur', 'change', 'submit'], default: 'blur' },
83
+ },
84
+ commands: ['validate', 'reset', 'setFieldError'],
85
+ bind: { values: '/form/values', valid: '/form/valid', dirty: '/form/dirty' },
86
+ },
87
+ {
88
+ type: 'DataStreamController',
89
+ description: 'Live data buffer for charts, tables, feeds. Supports push, SSE, WebSocket, polling.',
90
+ config: {
91
+ max: { type: 'number', default: 100, description: 'FIFO buffer size' },
92
+ throttle: { type: 'number', default: 0, description: 'Min ms between renders' },
93
+ },
94
+ commands: ['push', 'pushMany', 'connect', 'poll', 'consume', 'stop', 'clear'],
95
+ bind: { data: '/stream/data', status: '/stream/status' },
96
+ },
97
+ {
98
+ type: 'SelectionController',
99
+ description: 'Single or multi-select state for lists, tables, grids.',
100
+ config: { mode: { type: 'string', enum: ['single', 'multi'], default: 'single' } },
101
+ commands: ['select', 'deselect', 'toggle', 'selectAll', 'clear'],
102
+ bind: { selected: '/selection/items', count: '/selection/count' },
103
+ },
104
+ {
105
+ type: 'ToggleController',
106
+ description: 'Boolean on/off state with attribute reflection.',
107
+ config: {},
108
+ commands: ['toggle', 'set'],
109
+ bind: { value: '/toggle/on' },
110
+ },
111
+ {
112
+ type: 'AccordionController',
113
+ description: 'Panel expand/collapse with mutual exclusion.',
114
+ config: { multiple: { type: 'boolean', default: false } },
115
+ commands: ['open', 'close', 'toggle'],
116
+ bind: { openPanels: '/accordion/open' },
117
+ },
118
+ ],
119
+
120
+ // ── ACTIONS: event → handler chains ──
121
+ handlers: [
122
+ { name: 'submit-resource', description: 'POST/PUT/PATCH/DELETE to a resource URI.', config: ['uri', 'method', 'body'] },
123
+ { name: 'update-model', description: 'Update the surface data model at a path.', config: ['path', 'value'] },
124
+ { name: 'navigate', description: 'Route to a path (supports {param} templates).', config: ['navigate'] },
125
+ { name: 'navigate-back', description: 'Go back in browser history.', config: [] },
126
+ { name: 'controller-command', description: 'Invoke a command on a controller.', config: ['controllerId', 'command', 'args'] },
127
+ { name: 'emit-event', description: 'Dispatch a named CustomEvent on the surface.', config: ['eventName', 'detail'] },
128
+ { name: 'refresh-source', description: 'Re-fetch a named data source.', config: ['sourceId'] },
129
+ { name: 'notify', description: 'Show a toast/alert notification.', config: ['message', 'variant'] },
130
+ ],
131
+
132
+ // ── ACTION SHAPE (AdiaEvent → handler) ──
133
+ actionShape: {
134
+ event: 'AdiaEvent object: { event, target?, debounce?, throttle?, condition? }',
135
+ handler: 'Handler name from the handlers list.',
136
+ config: 'Handler-specific configuration object.',
137
+ onSuccess: 'Follow-up actions array (each is { handler, config }).',
138
+ onError: 'Follow-up actions array on failure.',
139
+ },
140
+
141
+ // ── PROVIDES: context injection ──
142
+ provides: {
143
+ description: 'Inject shared state into a component subtree via a2ui-provider. Children consume via context name.',
144
+ example: { name: 'auth', host: 'root', value: { user: null, token: null } },
145
+ },
146
+
147
+ // ── LIFECYCLE hooks ──
148
+ lifecycle: {
149
+ onMount: 'Actions to run when the surface first renders (fetch initial data, start streams).',
150
+ onUnmount: 'Cleanup actions when the surface is destroyed (close WebSocket, stop polling).',
151
+ onModelChange: 'Watch a model path and fire actions when it changes (debounce supported).',
152
+ },
153
+
154
+ // ── VALUE EXTRACTION (how actions read data) ──
155
+ valueSources: [
156
+ { from: 'event-detail', description: 'Read from event.detail (key = property)' },
157
+ { from: 'event-target', description: 'Read from event.target (key = property, e.g., value)' },
158
+ { from: 'model', description: 'Read from data model (path = JSON Pointer)' },
159
+ { from: 'literal', description: 'Static value (value = the value)' },
160
+ { from: 'param', description: 'Read from resolved parameters (key = param name)' },
161
+ { from: 'controller', description: 'Read from a controller state (controllerId + key)' },
162
+ ],
163
+
164
+ // ── MULTI-SURFACE ASSOCIATIONS ──
165
+ associations: [
166
+ { name: 'routes-to', description: 'Navigation — source links to target.' },
167
+ { name: 'feeds', description: 'Data flow — source output → target input.' },
168
+ { name: 'shares-context', description: 'Shared state — both read/write same context.' },
169
+ { name: 'depends-on', description: 'Lifecycle — source waits for target.' },
170
+ { name: 'triggers', description: 'Side effect — source event → target update.' },
171
+ { name: 'contains', description: 'Composition — target renders inside source.' },
172
+ ],
173
+ };
174
+ }
175
+
176
+ /**
177
+ * Get AdiaEvent type info.
178
+ */
179
+ export function getAdiaEvent(type) {
180
+ return adiaEvents.find(e => e.event === type) || null;
181
+ }
182
+
183
+ /**
184
+ * Get controller catalog entry by type name.
185
+ */
186
+ export function getControllerInfo(type) {
187
+ return getWiringCatalog().controllers.find(c => c.type === type) || null;
188
+ }
189
+
190
+ /**
191
+ * Get handler catalog entry by name.
192
+ */
193
+ export function getHandlerInfo(name) {
194
+ return getWiringCatalog().handlers.find(h => h.name === name) || null;
195
+ }