@contractspec/lib.presentation-runtime-core 3.9.4 → 3.9.6

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.
@@ -1,532 +1,4 @@
1
- // src/table.ts
2
- function createEmptyTableState() {
3
- return {
4
- sorting: [],
5
- pagination: {
6
- pageIndex: 0,
7
- pageSize: 25
8
- },
9
- columnVisibility: {},
10
- columnSizing: {},
11
- columnPinning: {
12
- left: [],
13
- right: []
14
- },
15
- expanded: {},
16
- rowSelection: {}
17
- };
18
- }
19
-
20
- // src/visualization.utils.ts
21
- function formatVisualizationValue(value, format) {
22
- if (value == null)
23
- return "—";
24
- if (format === "currency" && typeof value === "number") {
25
- return new Intl.NumberFormat(undefined, {
26
- style: "currency",
27
- currency: "USD"
28
- }).format(value);
29
- }
30
- if (format === "percentage" && typeof value === "number") {
31
- return `${(value * 100).toFixed(1)}%`;
32
- }
33
- if ((format === "date" || format === "dateTime") && value) {
34
- const date = value instanceof Date ? value : new Date(String(value));
35
- return Number.isNaN(date.getTime()) ? String(value) : new Intl.DateTimeFormat(undefined, {
36
- dateStyle: "medium",
37
- timeStyle: format === "dateTime" ? "short" : undefined
38
- }).format(date);
39
- }
40
- return String(value);
41
- }
42
- function resolveVisualizationRows(data, resultPath) {
43
- const value = resultPath ? getAtPath(data, resultPath) : data;
44
- const candidate = value ?? data;
45
- if (Array.isArray(candidate))
46
- return candidate.map(asRow);
47
- if (Array.isArray(getAtPath(candidate, "items"))) {
48
- return getAtPath(candidate, "items").map(asRow);
49
- }
50
- if (Array.isArray(getAtPath(candidate, "rows"))) {
51
- return getAtPath(candidate, "rows").map(asRow);
52
- }
53
- if (Array.isArray(getAtPath(candidate, "data"))) {
54
- return getAtPath(candidate, "data").map(asRow);
55
- }
56
- return candidate && typeof candidate === "object" ? [asRow(candidate)] : [];
57
- }
58
- function getAtPath(source, path) {
59
- if (!path || source == null)
60
- return source;
61
- return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).reduce((current, segment) => {
62
- if (current == null || typeof current !== "object")
63
- return;
64
- return current[segment];
65
- }, source);
66
- }
67
- function toNumber(value) {
68
- if (typeof value === "number" && Number.isFinite(value))
69
- return value;
70
- if (typeof value === "string" && value.trim()) {
71
- const parsed = Number(value);
72
- return Number.isFinite(parsed) ? parsed : null;
73
- }
74
- return null;
75
- }
76
- function asRow(value) {
77
- return value && typeof value === "object" ? value : { value };
78
- }
79
-
80
- // src/visualization.model.helpers.ts
81
- function createVisualizationMaps(spec) {
82
- return {
83
- dimensions: new Map((spec.visualization.dimensions ?? []).map((dimension) => [
84
- dimension.key,
85
- dimension
86
- ])),
87
- measures: new Map((spec.visualization.measures ?? []).map((measure) => [
88
- measure.key,
89
- measure
90
- ]))
91
- };
92
- }
93
- function createVisualizationBaseModel(spec, rows, maps) {
94
- const config = spec.visualization;
95
- return {
96
- kind: config.kind,
97
- title: config.title ?? spec.meta.title,
98
- description: config.description ?? spec.meta.description,
99
- summary: `${spec.meta.title ?? spec.meta.key}: ${rows.length} row${rows.length === 1 ? "" : "s"}`,
100
- warnings: rows.length === 0 ? ["No visualization rows available."] : [],
101
- palette: config.palette,
102
- legend: config.legend,
103
- tooltip: config.tooltip,
104
- drilldown: config.drilldown,
105
- thresholds: config.thresholds ?? [],
106
- annotations: (config.annotations ?? []).map((annotation) => resolveAnnotation(annotation, rows[0] ?? {})),
107
- table: createTable(config.table?.caption, config, rows)
108
- };
109
- }
110
- function createMeasureSeries(measureKey, measures, rows, dimension, config) {
111
- const measure = measures.get(measureKey);
112
- if (!measure)
113
- return null;
114
- return {
115
- key: config?.key ?? measure.key,
116
- label: config?.label ?? measure.label,
117
- type: config?.type,
118
- color: config?.color ?? measure.color,
119
- stack: config?.stack,
120
- smooth: config?.smooth,
121
- points: rows.map((row, index) => ({
122
- id: `${measure.key}-${index}`,
123
- raw: row,
124
- x: dimension ? readDimensionValue(row, dimension) : index,
125
- y: numericValue(row, measure),
126
- value: numericValue(row, measure)
127
- }))
128
- };
129
- }
130
- function defaultSeries(keys) {
131
- return keys.map((key) => ({ key, label: key, measure: key }));
132
- }
133
- function createAxis(dimension) {
134
- if (!dimension)
135
- return;
136
- return {
137
- key: dimension.key,
138
- label: dimension.label,
139
- type: dimension.type === "time" ? "time" : dimension.type === "number" ? "number" : "category",
140
- format: dimension.format
141
- };
142
- }
143
- function createValueAxis(key, measures) {
144
- const measure = key ? measures.get(key) : undefined;
145
- if (!measure)
146
- return;
147
- return {
148
- key: measure.key,
149
- label: measure.label,
150
- type: "number",
151
- format: measure.format
152
- };
153
- }
154
- function readValue(row, measure) {
155
- return measure ? getAtPath(row, measure.dataPath) : undefined;
156
- }
157
- function readDimensionValue(row, dimension) {
158
- return dimension ? getAtPath(row, dimension.dataPath) : undefined;
159
- }
160
- function numericValue(row, measure) {
161
- return toNumber(readValue(row, measure));
162
- }
163
- function numericPathValue(row, dimension) {
164
- return toNumber(readDimensionValue(row, dimension));
165
- }
166
- function stringValue(row, dimension) {
167
- const value = readDimensionValue(row, dimension);
168
- return value == null ? undefined : String(value);
169
- }
170
- function createTable(caption, config, rows) {
171
- const dimensions = config.dimensions ?? [];
172
- const measures = config.measures ?? [];
173
- return {
174
- caption,
175
- columns: [
176
- ...dimensions.map((dimension) => ({
177
- key: dimension.key,
178
- label: dimension.label
179
- })),
180
- ...measures.map((measure) => ({
181
- key: measure.key,
182
- label: measure.label
183
- }))
184
- ],
185
- rows: rows.map((row) => ({
186
- ...Object.fromEntries(dimensions.map((dimension) => [
187
- dimension.key,
188
- readDimensionValue(row, dimension)
189
- ])),
190
- ...Object.fromEntries(measures.map((measure) => [measure.key, readValue(row, measure)]))
191
- }))
192
- };
193
- }
194
- function resolveAnnotation(annotation, row) {
195
- return {
196
- key: annotation.key,
197
- label: annotation.label,
198
- kind: annotation.kind,
199
- color: annotation.color,
200
- x: annotation.xDataPath ? getAtPath(row, annotation.xDataPath) : undefined,
201
- y: annotation.yDataPath ? toNumber(getAtPath(row, annotation.yDataPath)) : undefined,
202
- start: annotation.startDataPath ? getAtPath(row, annotation.startDataPath) : undefined,
203
- end: annotation.endDataPath ? getAtPath(row, annotation.endDataPath) : undefined
204
- };
205
- }
206
-
207
- // src/visualization.model.builders.ts
208
- function buildMetricModel(base, config, rows, maps) {
209
- const measure = maps.measures.get(config.measure);
210
- const comparison = config.comparisonMeasure ? maps.measures.get(config.comparisonMeasure) : undefined;
211
- const currentRow = rows.at(-1) ?? {};
212
- const sparkline = config.sparkline ? createMeasureSeries(config.sparkline.measure ?? config.measure, maps.measures, rows, maps.dimensions.get(config.sparkline.dimension)) : null;
213
- return {
214
- ...base,
215
- series: sparkline ? [sparkline] : [],
216
- metric: {
217
- label: measure?.label ?? config.measure,
218
- value: readValue(currentRow, measure),
219
- comparisonValue: comparison ? readValue(currentRow, comparison) : undefined,
220
- format: measure?.format
221
- }
222
- };
223
- }
224
- function buildCartesianModel(base, config, rows, maps) {
225
- const series = (config.series ?? defaultSeries(config.yMeasures ?? [])).map((seriesItem) => createMeasureSeries(seriesItem.measure, maps.measures, rows, maps.dimensions.get(config.xDimension), seriesItem)).filter((item) => Boolean(item));
226
- return {
227
- ...base,
228
- series,
229
- xAxis: createAxis(maps.dimensions.get(config.xDimension)),
230
- yAxis: createValueAxis(config.yMeasures?.[0], maps.measures)
231
- };
232
- }
233
- function buildDistributionModel(base, config, rows, maps) {
234
- const nameDimension = maps.dimensions.get(config.nameDimension);
235
- const valueMeasure = maps.measures.get(config.valueMeasure);
236
- return {
237
- ...base,
238
- series: [
239
- {
240
- key: valueMeasure?.key ?? config.valueMeasure,
241
- label: valueMeasure?.label ?? config.valueMeasure,
242
- type: config.kind,
243
- points: rows.map((row, index) => ({
244
- id: `${config.kind}-${index}`,
245
- raw: row,
246
- name: stringValue(row, nameDimension),
247
- value: numericValue(row, valueMeasure)
248
- }))
249
- }
250
- ]
251
- };
252
- }
253
- function buildHeatmapModel(base, config, rows, maps) {
254
- const xDimension = maps.dimensions.get(config.xDimension);
255
- const yDimension = maps.dimensions.get(config.yDimension);
256
- const valueMeasure = maps.measures.get(config.valueMeasure);
257
- return {
258
- ...base,
259
- series: [
260
- {
261
- key: config.valueMeasure,
262
- label: valueMeasure?.label ?? config.valueMeasure,
263
- type: "heatmap",
264
- points: rows.map((row, index) => ({
265
- id: `heatmap-${index}`,
266
- raw: row,
267
- name: stringValue(row, yDimension),
268
- x: readDimensionValue(row, xDimension),
269
- y: numericValue(row, valueMeasure),
270
- value: numericValue(row, valueMeasure)
271
- }))
272
- }
273
- ],
274
- xAxis: createAxis(xDimension),
275
- yAxis: createAxis(yDimension)
276
- };
277
- }
278
- function buildGeoModel(base, config, rows, maps) {
279
- return {
280
- ...base,
281
- series: [
282
- {
283
- key: "geo",
284
- label: "Geo",
285
- type: config.variant ?? "scatter",
286
- points: rows.map((row, index) => ({
287
- id: `geo-${index}`,
288
- raw: row,
289
- name: config.nameDimension ? stringValue(row, maps.dimensions.get(config.nameDimension)) : undefined,
290
- value: config.valueMeasure ? numericValue(row, maps.measures.get(config.valueMeasure)) : undefined,
291
- latitude: numericPathValue(row, maps.dimensions.get(config.latitudeDimension ?? "")),
292
- longitude: numericPathValue(row, maps.dimensions.get(config.longitudeDimension ?? ""))
293
- }))
294
- }
295
- ],
296
- geo: {
297
- mode: config.mode ?? "chart",
298
- variant: config.variant ?? "scatter",
299
- geoJson: config.geoJson
300
- }
301
- };
302
- }
303
-
304
- // src/visualization.model.ts
305
- function createVisualizationModel(spec, data) {
306
- const rows = resolveVisualizationRows(data, spec.source.resultPath);
307
- const maps = createVisualizationMaps(spec);
308
- const base = createVisualizationBaseModel(spec, rows, maps);
309
- switch (spec.visualization.kind) {
310
- case "metric":
311
- return buildMetricModel(base, spec.visualization, rows, maps);
312
- case "cartesian":
313
- return buildCartesianModel(base, spec.visualization, rows, maps);
314
- case "pie":
315
- case "funnel":
316
- return buildDistributionModel(base, spec.visualization, rows, maps);
317
- case "heatmap":
318
- return buildHeatmapModel(base, spec.visualization, rows, maps);
319
- case "geo":
320
- return buildGeoModel(base, spec.visualization, rows, maps);
321
- }
322
- }
323
- // src/visualization.echarts.ts
324
- function buildVisualizationEChartsOption(model) {
325
- const thresholdLines = model.thresholds.map((threshold) => ({
326
- yAxis: threshold.value,
327
- name: threshold.label,
328
- lineStyle: {
329
- color: threshold.color ?? "#ef4444",
330
- type: "dashed"
331
- }
332
- }));
333
- const annotationLines = model.annotations.filter((annotation) => annotation.kind === "line" && annotation.y != null).map((annotation) => toMarkLine(annotation));
334
- switch (model.kind) {
335
- case "cartesian":
336
- const cartesianSeries = model.series.map((series) => ({
337
- name: series.label,
338
- type: resolveCartesianSeriesType(series.type),
339
- smooth: series.smooth,
340
- stack: series.stack,
341
- areaStyle: series.type === "area" ? {} : undefined,
342
- itemStyle: series.color ? { color: series.color } : undefined,
343
- lineStyle: series.color ? { color: series.color } : undefined,
344
- data: series.points.filter((point) => point.y != null).map((point) => [point.x, point.y]),
345
- markLine: thresholdLines.length || annotationLines.length ? { data: [...thresholdLines, ...annotationLines] } : undefined
346
- }));
347
- return {
348
- color: model.palette,
349
- tooltip: model.tooltip === false ? undefined : { trigger: "axis" },
350
- legend: { show: model.legend ?? model.series.length > 1 },
351
- xAxis: { type: model.xAxis?.type === "time" ? "time" : "category" },
352
- yAxis: { type: "value", name: model.yAxis?.label },
353
- series: cartesianSeries
354
- };
355
- case "pie":
356
- const pieSeries = [
357
- {
358
- type: "pie",
359
- radius: ["0%", "70%"],
360
- data: model.series[0]?.points.filter((point) => point.value != null).map((point) => ({
361
- name: point.name ?? "",
362
- value: point.value
363
- })) ?? []
364
- }
365
- ];
366
- return {
367
- color: model.palette,
368
- tooltip: model.tooltip === false ? undefined : { trigger: "item" },
369
- series: pieSeries
370
- };
371
- case "heatmap":
372
- const heatmapSeries = [
373
- {
374
- type: "heatmap",
375
- data: model.series[0]?.points.filter((point) => point.value != null && point.name != null).map((point) => [point.x, point.name, point.value]) ?? []
376
- }
377
- ];
378
- return {
379
- color: model.palette,
380
- tooltip: model.tooltip === false ? undefined : { position: "top" },
381
- xAxis: {
382
- type: "category",
383
- data: uniqueValues(model.series[0]?.points.map((point) => point.x))
384
- },
385
- yAxis: {
386
- type: "category",
387
- data: uniqueValues(model.series[0]?.points.map((point) => point.name))
388
- },
389
- visualMap: {
390
- min: 0,
391
- max: maxValue(model.series[0]?.points.map((point) => point.value)),
392
- calculable: true,
393
- orient: "horizontal",
394
- left: "center",
395
- bottom: 0
396
- },
397
- series: heatmapSeries
398
- };
399
- case "funnel":
400
- const funnelSeries = [
401
- {
402
- type: "funnel",
403
- data: model.series[0]?.points.filter((point) => point.value != null).map((point) => ({
404
- name: point.name ?? "",
405
- value: point.value
406
- })) ?? []
407
- }
408
- ];
409
- return {
410
- color: model.palette,
411
- tooltip: model.tooltip === false ? undefined : { trigger: "item" },
412
- series: funnelSeries
413
- };
414
- case "geo":
415
- if (!model.geo || model.geo.mode === "slippy-map" || !model.geo.geoJson) {
416
- return {};
417
- }
418
- const geoSeries = [
419
- {
420
- type: model.geo.variant === "heatmap" ? "heatmap" : "scatter",
421
- coordinateSystem: "geo",
422
- data: model.series[0]?.points.filter((point) => point.longitude != null && point.latitude != null && point.value != null).map((point) => ({
423
- name: point.name ?? "",
424
- value: [
425
- point.longitude,
426
- point.latitude,
427
- point.value
428
- ]
429
- })) ?? []
430
- }
431
- ];
432
- return {
433
- color: model.palette,
434
- tooltip: model.tooltip === false ? undefined : { trigger: "item" },
435
- geo: {
436
- map: "contractspec-visualization-geo",
437
- roam: true
438
- },
439
- series: geoSeries
440
- };
441
- default:
442
- return {};
443
- }
444
- }
445
- function uniqueValues(values) {
446
- return Array.from(new Set((values ?? []).filter((value) => value != null).map(String)));
447
- }
448
- function maxValue(values) {
449
- return Math.max(...(values ?? []).map((value) => value ?? 0), 1);
450
- }
451
- function toMarkLine(annotation) {
452
- return {
453
- yAxis: annotation.y,
454
- name: annotation.label,
455
- lineStyle: {
456
- color: annotation.color ?? "#2563eb",
457
- type: "solid"
458
- }
459
- };
460
- }
461
- function resolveCartesianSeriesType(type) {
462
- if (type === "bar")
463
- return "bar";
464
- if (type === "scatter")
465
- return "scatter";
466
- return "line";
467
- }
468
-
469
- // src/index.ts
470
- function withPresentationNextAliases(config, opts = {}) {
471
- const uiWeb = opts.uiKitWeb ?? "@contractspec/lib.ui-kit-web";
472
- const uiNative = opts.uiKitNative ?? "@contractspec/lib.ui-kit";
473
- const presReact = opts.presentationReact ?? "@contractspec/lib.presentation-runtime-react";
474
- const presNative = opts.presentationNative ?? "@contractspec/lib.presentation-runtime-react-native";
475
- config.resolve ??= {};
476
- config.resolve.alias = {
477
- ...config.resolve.alias || {},
478
- [uiNative]: uiWeb,
479
- [presNative]: presReact
480
- };
481
- config.resolve.extensions = [
482
- ".web.js",
483
- ".web.jsx",
484
- ".web.ts",
485
- ".web.tsx",
486
- ...config.resolve.extensions || []
487
- ];
488
- return config;
489
- }
490
- function withPresentationMetroAliases(config, opts = {}) {
491
- const uiWeb = opts.uiKitWeb ?? "@contractspec/lib.ui-kit-web";
492
- const uiNative = opts.uiKitNative ?? "@contractspec/lib.ui-kit";
493
- const presReact = opts.presentationReact ?? "@contractspec/lib.presentation-runtime-react";
494
- const presNative = opts.presentationNative ?? "@contractspec/lib.presentation-runtime-react-native";
495
- config.resolver ??= {};
496
- config.resolver.unstable_enablePackageExports = true;
497
- config.resolver.platforms = [
498
- "ios",
499
- "android",
500
- "native",
501
- "mobile",
502
- "web",
503
- ...config.resolver.platforms || []
504
- ];
505
- const original = config.resolver.resolveRequest;
506
- config.resolver.resolveRequest = (ctx, moduleName, platform) => {
507
- if (platform === "ios" || platform === "android" || platform === "native") {
508
- if (typeof moduleName === "string" && moduleName.startsWith(uiWeb + "/ui")) {
509
- const mapped = moduleName.replace(uiWeb + "/ui", uiNative + "/ui");
510
- return (original ?? ctx.resolveRequest)(ctx, mapped, platform);
511
- }
512
- if (moduleName === presReact) {
513
- return (original ?? ctx.resolveRequest)(ctx, presNative, platform);
514
- }
515
- }
516
- return (original ?? ctx.resolveRequest)(ctx, moduleName, platform);
517
- };
518
- return config;
519
- }
520
- var tech_presentation_runtime_DocBlocks = [
521
- {
522
- id: "docs.tech.presentation-runtime",
523
- title: "Presentation Runtime",
524
- summary: "Cross-platform runtime for list pages, presentation flows, and headless ContractSpec tables.",
525
- kind: "reference",
526
- visibility: "public",
527
- route: "/docs/tech/presentation-runtime",
528
- tags: ["tech", "presentation-runtime"],
529
- body: `## Presentation Runtime
1
+ function I(){return{sorting:[],pagination:{pageIndex:0,pageSize:25},columnVisibility:{},columnSizing:{},columnPinning:{left:[],right:[]},expanded:{},rowSelection:{}}}function x(e,t){if(e==null)return"—";if(t==="currency"&&typeof e==="number")return new Intl.NumberFormat(void 0,{style:"currency",currency:"USD"}).format(e);if(t==="percentage"&&typeof e==="number")return`${(e*100).toFixed(1)}%`;if((t==="date"||t==="dateTime")&&e){let i=e instanceof Date?e:new Date(String(e));return Number.isNaN(i.getTime())?String(e):new Intl.DateTimeFormat(void 0,{dateStyle:"medium",timeStyle:t==="dateTime"?"short":void 0}).format(i)}return String(e)}function C(e,t){let n=(t?u(e,t):e)??e;if(Array.isArray(n))return n.map(m);if(Array.isArray(u(n,"items")))return u(n,"items").map(m);if(Array.isArray(u(n,"rows")))return u(n,"rows").map(m);if(Array.isArray(u(n,"data")))return u(n,"data").map(m);return n&&typeof n==="object"?[m(n)]:[]}function u(e,t){if(!t||e==null)return e;return t.replace(/\[(\d+)\]/g,".$1").split(".").filter(Boolean).reduce((i,n)=>{if(i==null||typeof i!=="object")return;return i[n]},e)}function y(e){if(typeof e==="number"&&Number.isFinite(e))return e;if(typeof e==="string"&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:null}return null}function m(e){return e&&typeof e==="object"?e:{value:e}}function f(e){return{dimensions:new Map((e.visualization.dimensions??[]).map((t)=>[t.key,t])),measures:new Map((e.visualization.measures??[]).map((t)=>[t.key,t]))}}function S(e,t,i){let n=e.visualization;return{kind:n.kind,title:n.title??e.meta.title,description:n.description??e.meta.description,summary:`${e.meta.title??e.meta.key}: ${t.length} row${t.length===1?"":"s"}`,warnings:t.length===0?["No visualization rows available."]:[],palette:n.palette,legend:n.legend,tooltip:n.tooltip,drilldown:n.drilldown,thresholds:n.thresholds??[],annotations:(n.annotations??[]).map((o)=>B(o,t[0]??{})),table:O(n.table?.caption,n,t)}}function g(e,t,i,n,o){let r=t.get(e);if(!r)return null;return{key:o?.key??r.key,label:o?.label??r.label,type:o?.type,color:o?.color??r.color,stack:o?.stack,smooth:o?.smooth,points:i.map((s,l)=>({id:`${r.key}-${l}`,raw:s,x:n?p(s,n):l,y:c(s,r),value:c(s,r)}))}}function k(e){return e.map((t)=>({key:t,label:t,measure:t}))}function z(e){if(!e)return;return{key:e.key,label:e.label,type:e.type==="time"?"time":e.type==="number"?"number":"category",format:e.format}}function v(e,t){let i=e?t.get(e):void 0;if(!i)return;return{key:i.key,label:i.label,type:"number",format:i.format}}function b(e,t){return t?u(e,t.dataPath):void 0}function p(e,t){return t?u(e,t.dataPath):void 0}function c(e,t){return y(b(e,t))}function V(e,t){return y(p(e,t))}function M(e,t){let i=p(e,t);return i==null?void 0:String(i)}function O(e,t,i){let n=t.dimensions??[],o=t.measures??[];return{caption:e,columns:[...n.map((r)=>({key:r.key,label:r.label})),...o.map((r)=>({key:r.key,label:r.label}))],rows:i.map((r)=>({...Object.fromEntries(n.map((s)=>[s.key,p(r,s)])),...Object.fromEntries(o.map((s)=>[s.key,b(r,s)]))}))}}function B(e,t){return{key:e.key,label:e.label,kind:e.kind,color:e.color,x:e.xDataPath?u(t,e.xDataPath):void 0,y:e.yDataPath?y(u(t,e.yDataPath)):void 0,start:e.startDataPath?u(t,e.startDataPath):void 0,end:e.endDataPath?u(t,e.endDataPath):void 0}}function T(e,t,i,n){let o=n.measures.get(t.measure),r=t.comparisonMeasure?n.measures.get(t.comparisonMeasure):void 0,s=i.at(-1)??{},l=t.sparkline?g(t.sparkline.measure??t.measure,n.measures,i,n.dimensions.get(t.sparkline.dimension)):null;return{...e,series:l?[l]:[],metric:{label:o?.label??t.measure,value:b(s,o),comparisonValue:r?b(s,r):void 0,format:o?.format}}}function h(e,t,i,n){let o=(t.series??k(t.yMeasures??[])).map((r)=>g(r.measure,n.measures,i,n.dimensions.get(t.xDimension),r)).filter((r)=>Boolean(r));return{...e,series:o,xAxis:z(n.dimensions.get(t.xDimension)),yAxis:v(t.yMeasures?.[0],n.measures)}}function R(e,t,i,n){let o=n.dimensions.get(t.nameDimension),r=n.measures.get(t.valueMeasure);return{...e,series:[{key:r?.key??t.valueMeasure,label:r?.label??t.valueMeasure,type:t.kind,points:i.map((s,l)=>({id:`${t.kind}-${l}`,raw:s,name:M(s,o),value:c(s,r)}))}]}}function w(e,t,i,n){let o=n.dimensions.get(t.xDimension),r=n.dimensions.get(t.yDimension),s=n.measures.get(t.valueMeasure);return{...e,series:[{key:t.valueMeasure,label:s?.label??t.valueMeasure,type:"heatmap",points:i.map((l,a)=>({id:`heatmap-${a}`,raw:l,name:M(l,r),x:p(l,o),y:c(l,s),value:c(l,s)}))}],xAxis:z(o),yAxis:z(r)}}function A(e,t,i,n){return{...e,series:[{key:"geo",label:"Geo",type:t.variant??"scatter",points:i.map((o,r)=>({id:`geo-${r}`,raw:o,name:t.nameDimension?M(o,n.dimensions.get(t.nameDimension)):void 0,value:t.valueMeasure?c(o,n.measures.get(t.valueMeasure)):void 0,latitude:V(o,n.dimensions.get(t.latitudeDimension??"")),longitude:V(o,n.dimensions.get(t.longitudeDimension??""))}))}],geo:{mode:t.mode??"chart",variant:t.variant??"scatter",geoJson:t.geoJson}}}function D(e,t){let i=C(t,e.source.resultPath),n=f(e),o=S(e,i,n);switch(e.visualization.kind){case"metric":return T(o,e.visualization,i,n);case"cartesian":return h(o,e.visualization,i,n);case"pie":case"funnel":return R(o,e.visualization,i,n);case"heatmap":return w(o,e.visualization,i,n);case"geo":return A(o,e.visualization,i,n)}}function $(e){let t=e.thresholds.map((n)=>({yAxis:n.value,name:n.label,lineStyle:{color:n.color??"#ef4444",type:"dashed"}})),i=e.annotations.filter((n)=>n.kind==="line"&&n.y!=null).map((n)=>F(n));switch(e.kind){case"cartesian":let n=e.series.map((a)=>({name:a.label,type:j(a.type),smooth:a.smooth,stack:a.stack,areaStyle:a.type==="area"?{}:void 0,itemStyle:a.color?{color:a.color}:void 0,lineStyle:a.color?{color:a.color}:void 0,data:a.points.filter((d)=>d.y!=null).map((d)=>[d.x,d.y]),markLine:t.length||i.length?{data:[...t,...i]}:void 0}));return{color:e.palette,tooltip:e.tooltip===!1?void 0:{trigger:"axis"},legend:{show:e.legend??e.series.length>1},xAxis:{type:e.xAxis?.type==="time"?"time":"category"},yAxis:{type:"value",name:e.yAxis?.label},series:n};case"pie":let o=[{type:"pie",radius:["0%","70%"],data:e.series[0]?.points.filter((a)=>a.value!=null).map((a)=>({name:a.name??"",value:a.value}))??[]}];return{color:e.palette,tooltip:e.tooltip===!1?void 0:{trigger:"item"},series:o};case"heatmap":let r=[{type:"heatmap",data:e.series[0]?.points.filter((a)=>a.value!=null&&a.name!=null).map((a)=>[a.x,a.name,a.value])??[]}];return{color:e.palette,tooltip:e.tooltip===!1?void 0:{position:"top"},xAxis:{type:"category",data:P(e.series[0]?.points.map((a)=>a.x))},yAxis:{type:"category",data:P(e.series[0]?.points.map((a)=>a.name))},visualMap:{min:0,max:N(e.series[0]?.points.map((a)=>a.value)),calculable:!0,orient:"horizontal",left:"center",bottom:0},series:r};case"funnel":let s=[{type:"funnel",data:e.series[0]?.points.filter((a)=>a.value!=null).map((a)=>({name:a.name??"",value:a.value}))??[]}];return{color:e.palette,tooltip:e.tooltip===!1?void 0:{trigger:"item"},series:s};case"geo":if(!e.geo||e.geo.mode==="slippy-map"||!e.geo.geoJson)return{};let l=[{type:e.geo.variant==="heatmap"?"heatmap":"scatter",coordinateSystem:"geo",data:e.series[0]?.points.filter((a)=>a.longitude!=null&&a.latitude!=null&&a.value!=null).map((a)=>({name:a.name??"",value:[a.longitude,a.latitude,a.value]}))??[]}];return{color:e.palette,tooltip:e.tooltip===!1?void 0:{trigger:"item"},geo:{map:"contractspec-visualization-geo",roam:!0},series:l};default:return{}}}function P(e){return Array.from(new Set((e??[]).filter((t)=>t!=null).map(String)))}function N(e){return Math.max(...(e??[]).map((t)=>t??0),1)}function F(e){return{yAxis:e.y,name:e.label,lineStyle:{color:e.color??"#2563eb",type:"solid"}}}function j(e){if(e==="bar")return"bar";if(e==="scatter")return"scatter";return"line"}function te(e,t={}){let i=t.uiKitWeb??"@contractspec/lib.ui-kit-web",n=t.uiKitNative??"@contractspec/lib.ui-kit",o=t.presentationReact??"@contractspec/lib.presentation-runtime-react",r=t.presentationNative??"@contractspec/lib.presentation-runtime-react-native";return e.resolve??={},e.resolve.alias={...e.resolve.alias||{},[n]:i,[r]:o},e.resolve.extensions=[".web.js",".web.jsx",".web.ts",".web.tsx",...e.resolve.extensions||[]],e}function ne(e,t={}){let i=t.uiKitWeb??"@contractspec/lib.ui-kit-web",n=t.uiKitNative??"@contractspec/lib.ui-kit",o=t.presentationReact??"@contractspec/lib.presentation-runtime-react",r=t.presentationNative??"@contractspec/lib.presentation-runtime-react-native";e.resolver??={},e.resolver.unstable_enablePackageExports=!0,e.resolver.platforms=["ios","android","native","mobile","web",...e.resolver.platforms||[]];let s=e.resolver.resolveRequest;return e.resolver.resolveRequest=(l,a,d)=>{if(d==="ios"||d==="android"||d==="native"){if(typeof a==="string"&&a.startsWith(i+"/ui")){let E=a.replace(i+"/ui",n+"/ui");return(s??l.resolveRequest)(l,E,d)}if(a===o)return(s??l.resolveRequest)(l,r,d)}return(s??l.resolveRequest)(l,a,d)},e}var ae=[{id:"docs.tech.presentation-runtime",title:"Presentation Runtime",summary:"Cross-platform runtime for list pages, presentation flows, and headless ContractSpec tables.",kind:"reference",visibility:"public",route:"/docs/tech/presentation-runtime",tags:["tech","presentation-runtime"],body:`## Presentation Runtime
530
2
 
531
3
  Cross-platform runtime for list pages, presentation flows, and headless ContractSpec tables.
532
4
 
@@ -592,15 +64,4 @@ Both list hooks accept a \`useUrlState\` adapter. On web, use \`useListUrlState\
592
64
  - Per‑page companion convention: add \`app/<route>/ai.ts\` exporting a \`PresentationSpec\`.
593
65
  - Build‑time tool: \`tools/generate-presentations-manifest.mjs <app-root>\` populates the manifest.
594
66
  - CI check: \`bunllms:check\` verifies coverage (% of pages with descriptors) and fails if below threshold.
595
- `
596
- }
597
- ];
598
- export {
599
- withPresentationNextAliases,
600
- withPresentationMetroAliases,
601
- tech_presentation_runtime_DocBlocks,
602
- formatVisualizationValue,
603
- createVisualizationModel,
604
- createEmptyTableState,
605
- buildVisualizationEChartsOption
606
- };
67
+ `}];export{te as withPresentationNextAliases,ne as withPresentationMetroAliases,ae as tech_presentation_runtime_DocBlocks,x as formatVisualizationValue,D as createVisualizationModel,I as createEmptyTableState,$ as buildVisualizationEChartsOption};
@@ -1,21 +1 @@
1
- // src/table.ts
2
- function createEmptyTableState() {
3
- return {
4
- sorting: [],
5
- pagination: {
6
- pageIndex: 0,
7
- pageSize: 25
8
- },
9
- columnVisibility: {},
10
- columnSizing: {},
11
- columnPinning: {
12
- left: [],
13
- right: []
14
- },
15
- expanded: {},
16
- rowSelection: {}
17
- };
18
- }
19
- export {
20
- createEmptyTableState
21
- };
1
+ function e(){return{sorting:[],pagination:{pageIndex:0,pageSize:25},columnVisibility:{},columnSizing:{},columnPinning:{left:[],right:[]},expanded:{},rowSelection:{}}}export{e as createEmptyTableState};