@ai-matrx/records 0.93.1 → 0.93.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.
Files changed (42) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/{client-D4mLGnph.d.ts → client-DM3dRewB.d.ts} +1 -1
  3. package/dist/{client-BPcc-V2O.d.cts → client-icpxhaRE.d.cts} +1 -1
  4. package/dist/core/index.d.cts +3 -3
  5. package/dist/core/index.d.ts +3 -3
  6. package/dist/data/index.d.cts +2 -2
  7. package/dist/data/index.d.ts +2 -2
  8. package/dist/{declareTable-BSHX1Abl.d.cts → declareTable-BtpsSJCr.d.cts} +1 -1
  9. package/dist/{declareTable-Br_4v6L7.d.ts → declareTable-MN4WuhWK.d.ts} +1 -1
  10. package/dist/first-page/index.cjs +627 -0
  11. package/dist/first-page/index.cjs.map +1 -0
  12. package/dist/first-page/index.d.cts +1298 -0
  13. package/dist/first-page/index.d.ts +1298 -0
  14. package/dist/first-page/index.js +604 -0
  15. package/dist/first-page/index.js.map +1 -0
  16. package/dist/index.d.cts +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/memory/index.d.cts +2 -2
  19. package/dist/memory/index.d.ts +2 -2
  20. package/dist/questions/index.cjs +7 -2
  21. package/dist/questions/index.cjs.map +1 -1
  22. package/dist/questions/index.d.cts +2 -2
  23. package/dist/questions/index.d.ts +2 -2
  24. package/dist/questions/index.js +7 -2
  25. package/dist/questions/index.js.map +1 -1
  26. package/dist/setup/index.d.cts +2 -2
  27. package/dist/setup/index.d.ts +2 -2
  28. package/dist/{subscription-BGgwsJ8c.d.ts → subscription-DucBLG-Y.d.ts} +1 -1
  29. package/dist/{subscription-DVM2vL4e.d.cts → subscription-ycCVo9e2.d.cts} +1 -1
  30. package/dist/templates/index.d.cts +3 -3
  31. package/dist/templates/index.d.ts +3 -3
  32. package/dist/typed-table/index.d.cts +3 -3
  33. package/dist/typed-table/index.d.ts +3 -3
  34. package/dist/{types-C3ywxkho.d.ts → types-Cl0b_Hy8.d.ts} +1 -1
  35. package/dist/{types-reNR-zMe.d.cts → types-SezYoQ5_.d.cts} +1 -1
  36. package/dist/views/index.cjs +102 -0
  37. package/dist/views/index.cjs.map +1 -1
  38. package/dist/views/index.d.cts +46 -3
  39. package/dist/views/index.d.ts +46 -3
  40. package/dist/views/index.js +102 -0
  41. package/dist/views/index.js.map +1 -1
  42. package/package.json +12 -2
@@ -0,0 +1,627 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/first-page/index.ts
21
+ var first_page_exports = {};
22
+ __export(first_page_exports, {
23
+ EMBEDDED_PAGE_SIZE: () => EMBEDDED_PAGE_SIZE,
24
+ REVERSE_CELL_CHIPS: () => REVERSE_CELL_CHIPS,
25
+ SUMMARY_OPERATIONS: () => SUMMARY_OPERATIONS,
26
+ TABLE_PAGE_SIZE: () => TABLE_PAGE_SIZE,
27
+ askChartSeed: () => askChartSeed,
28
+ askEntityBlockSeed: () => askEntityBlockSeed,
29
+ askTablePageSeed: () => askTablePageSeed,
30
+ askTileSeed: () => askTileSeed,
31
+ bindFirstPageCodec: () => bindFirstPageCodec,
32
+ choiceFieldKeys: () => choiceFieldKeys,
33
+ defaultSortOf: () => defaultSortOf,
34
+ entityChartQuestion: () => entityChartQuestion,
35
+ entityTableQuery: () => entityTableQuery,
36
+ firstGridPageArgs: () => firstGridPageArgs,
37
+ firstGridPageRequest: () => firstGridPageRequest,
38
+ groupFactMeasures: () => groupFactMeasures,
39
+ groupedPageSort: () => groupedPageSort,
40
+ holdsNumbers: () => holdsNumbers,
41
+ isPlainGrouping: () => isPlainGrouping,
42
+ mergeSeeds: () => mergeSeeds,
43
+ pageSortFor: () => pageSortFor,
44
+ serverRowsOf: () => serverRowsOf,
45
+ sortAsFor: () => sortAsFor,
46
+ summaryBarMeasures: () => summaryBarMeasures,
47
+ viewFilterOf: () => viewFilterOf
48
+ });
49
+ module.exports = __toCommonJS(first_page_exports);
50
+
51
+ // src/aggregate.ts
52
+ function isRuleFilter(filter) {
53
+ if (!filter || typeof filter !== "object" || Array.isArray(filter)) return false;
54
+ const node = filter;
55
+ return typeof node.op === "string" && Array.isArray(node.args);
56
+ }
57
+
58
+ // src/coerce.ts
59
+ var import_uuid = require("@ai-matrx/kit/uuid");
60
+ function fieldKindFor(field, kernel) {
61
+ const format = (field.format ?? "").toLowerCase();
62
+ const config = field.config ?? {};
63
+ switch (field.type) {
64
+ case "boolean":
65
+ return "checkbox";
66
+ case "text":
67
+ if (format === "email") return "email";
68
+ if (format === "phone") return "phone";
69
+ if (format === "url") return "url";
70
+ if (format === "json" || config["json"] === true) return "json";
71
+ if (format === "long" || config["multiline"] === true) return "long_text";
72
+ return "text";
73
+ case "range": {
74
+ const kind = String(config["kind"] ?? "number");
75
+ if (kind === "date" || kind === "datetime") return "datetime";
76
+ if (format === "currency") return "currency";
77
+ if (format === "percent" || field.unit === "%") return "percent";
78
+ return "number";
79
+ }
80
+ case "list":
81
+ return field.multi ? "multi_select" : "select";
82
+ case "relation": {
83
+ if (isEntityReferenceConfig(config)) return "entity_reference";
84
+ const parity = String(config["parity"] ?? "");
85
+ if (parity === "attachment" || parity === "member") return parity;
86
+ if (kernel?.file && field.relation_target === kernel.file) return "attachment";
87
+ if (kernel?.person && field.relation_target === kernel.person) return "member";
88
+ return "relation";
89
+ }
90
+ case "formula": {
91
+ const via = config["via"];
92
+ if (via && config["agg"]) return "rollup";
93
+ if (via) return "lookup";
94
+ return "formula";
95
+ }
96
+ default:
97
+ return "text";
98
+ }
99
+ }
100
+ function isEntityReferenceConfig(config) {
101
+ const allowed = config?.["allowed_types"];
102
+ return Array.isArray(allowed) && allowed.length > 0;
103
+ }
104
+
105
+ // src/store.generated.ts
106
+ var KERNEL_TABLES = [
107
+ { id: "11111111-0000-4000-8000-000000000002", name: "Field" },
108
+ { id: "11111111-0000-4000-8000-000000000006", name: "File" },
109
+ { id: "11111111-0000-4000-8000-000000000009", name: "Merge Field" },
110
+ { id: "11111111-0000-4000-8000-000000000004", name: "Organization" },
111
+ { id: "11111111-0000-4000-8000-000000000005", name: "Person" },
112
+ { id: "11111111-0000-4000-8000-000000000007", name: "Presentation" },
113
+ { id: "11111111-0000-4000-8000-000000000003", name: "Rule" },
114
+ { id: "11111111-0000-4000-8000-000000000001", name: "Table" },
115
+ { id: "11111111-0000-4000-8000-000000000008", name: "Widget" }
116
+ ];
117
+
118
+ // src/fieldKind.ts
119
+ var kernelId = (name) => KERNEL_TABLES.find((t) => t.name === name)?.id ?? "";
120
+ var KERNEL = { file: kernelId("File"), person: kernelId("Person") };
121
+ function storeFieldKind(field) {
122
+ return fieldKindFor(field, KERNEL);
123
+ }
124
+
125
+ // src/first-page/reads.ts
126
+ function holdsNumbers(field) {
127
+ const kind = String(storeFieldKind(field));
128
+ if (kind === "number" || kind === "currency" || kind === "percent") return true;
129
+ return String((field.config ?? {})["system"] ?? "") === "autonumber";
130
+ }
131
+ function sortAsFor(field) {
132
+ if (holdsNumbers(field)) return "number";
133
+ if (String(storeFieldKind(field)) === "datetime") return "date";
134
+ return "text";
135
+ }
136
+ function pageSortFor(fields, sort) {
137
+ if (!sort) return [];
138
+ const field = fields.find((f) => f.key === sort.id);
139
+ if (!field) return [];
140
+ return [{ field: field.key, direction: sort.direction === "desc" ? "desc" : "asc", as: sortAsFor(field) }];
141
+ }
142
+ function defaultSortOf(table, fields) {
143
+ const raw = table?.default_sort ?? null;
144
+ const first = Array.isArray(raw) ? raw[0] : raw;
145
+ let name = null;
146
+ let direction = "asc";
147
+ if (typeof first === "string") {
148
+ const trimmed = first.trim();
149
+ if (trimmed === "") return null;
150
+ if (trimmed.startsWith("-")) {
151
+ name = trimmed.slice(1).trim();
152
+ direction = "desc";
153
+ } else {
154
+ const [head, tail] = trimmed.split(/\s+/);
155
+ name = head ?? null;
156
+ if (tail && tail.toLowerCase() === "desc") direction = "desc";
157
+ }
158
+ } else if (first && typeof first === "object") {
159
+ const entry = first;
160
+ const named = entry["field"] ?? entry["key"] ?? entry["id"];
161
+ name = typeof named === "string" ? named : null;
162
+ if (String(entry["direction"] ?? "").toLowerCase() === "desc") direction = "desc";
163
+ }
164
+ if (!name) return null;
165
+ const field = fields.find((f) => f.key === name) ?? fields.find((f) => f.id === name);
166
+ return field ? { id: field.key, direction } : null;
167
+ }
168
+ function isPlainGrouping(grouping) {
169
+ return Boolean(grouping) && !(grouping.then && grouping.then.length > 0) && !grouping.across && !(grouping.trail && grouping.trail.length > 0);
170
+ }
171
+ function groupedPageSort(fields, groupKey, sort) {
172
+ if (!groupKey) return sort;
173
+ const field = fields.find((f) => f.key === groupKey);
174
+ if (!field) return sort;
175
+ return [{ field: groupKey, direction: "asc", as: sortAsFor(field) }, ...sort.filter((s) => s.field !== groupKey)];
176
+ }
177
+ var SUMMARY_OPERATIONS = [
178
+ "count",
179
+ "sum",
180
+ "avg",
181
+ "min",
182
+ "max",
183
+ "median",
184
+ "filled",
185
+ "empty",
186
+ "unique",
187
+ "percent_empty",
188
+ "percent_filled",
189
+ "range"
190
+ ];
191
+ function chosenEntries(chosen) {
192
+ return JSON.parse(JSON.stringify(Object.entries(chosen).sort())).filter(
193
+ ([, op]) => SUMMARY_OPERATIONS.includes(op)
194
+ );
195
+ }
196
+ function groupFactMeasures(chosen) {
197
+ return [{ op: "count" }, ...chosenEntries(chosen).filter(([, op]) => op !== "count").map(([key, op]) => ({ op, key }))];
198
+ }
199
+ function summaryBarMeasures(chosen) {
200
+ return chosenEntries(chosen).map(([key, op]) => op === "count" ? { op: "count" } : { op, key });
201
+ }
202
+ function choiceFieldKeys(fields) {
203
+ return fields.filter((f) => {
204
+ const kind = String(storeFieldKind(f));
205
+ return kind === "select" || kind === "multi_select";
206
+ }).map((f) => f.key);
207
+ }
208
+ var REVERSE_CELL_CHIPS = 3;
209
+ function viewFilterOf(shown, _fields) {
210
+ if (!shown) return void 0;
211
+ const base = shown.where ?? (shown.filters && Object.keys(shown.filters).length > 0 ? shown.filters : void 0);
212
+ if (!base) return void 0;
213
+ if (isRuleFilter(base)) return base;
214
+ return Object.keys(base).length > 0 ? base : void 0;
215
+ }
216
+
217
+ // src/first-page/seed.ts
218
+ var import_uuid2 = require("@ai-matrx/kit/uuid");
219
+ var import_core = require("@ai-matrx/records/core");
220
+ var import_entity = require("@ai-matrx/records/entity");
221
+
222
+ // src/versions/rowVersion.ts
223
+ function ownVersion(row) {
224
+ const v = row.version;
225
+ return typeof v === "number" ? v : null;
226
+ }
227
+
228
+ // src/views/keys.ts
229
+ var plainPresentation = {
230
+ parse: (raw) => raw && typeof raw === "object" && !Array.isArray(raw) ? { ...raw } : {},
231
+ isEmpty: (presentation) => Object.keys(presentation).length === 0,
232
+ toDocument: (presentation) => ({ ...presentation })
233
+ };
234
+ function plainCodec() {
235
+ return plainPresentation;
236
+ }
237
+ var STORE_KEEPS_TIMELINE = true;
238
+ var ALL = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
239
+ var HIDES = ["grid", "gallery", "kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
240
+ var GRIDS = ["grid"];
241
+ var VIEW_KEYS = [
242
+ { path: "layout", shape: "kind", layouts: ALL, writer: "caller" },
243
+ { path: "filters", shape: "filter", layouts: ALL, writer: "caller" },
244
+ { path: "where", shape: "rule", layouts: ALL, writer: "caller" },
245
+ { path: "group_field", shape: "field", layouts: ["kanban", ...STORE_KEEPS_TIMELINE ? ["timeline"] : []], writer: "caller" },
246
+ { path: "swimlane_field", shape: "field:lane", layouts: ["kanban"], writer: "caller" },
247
+ { path: "collapsed_columns", shape: "values", layouts: ["kanban"], writer: "caller" },
248
+ { path: "measure", shape: "field:number", layouts: ["kanban"], writer: "caller" },
249
+ { path: "date_field", shape: "field:date", layouts: ["calendar"], writer: "caller" },
250
+ ...STORE_KEEPS_TIMELINE ? [
251
+ { path: "start_field", shape: "field:date", layouts: ["timeline"], writer: "caller" },
252
+ { path: "end_field", shape: "field:date", layouts: ["calendar", "timeline"], writer: "caller" }
253
+ ] : [],
254
+ { path: "image_field", shape: "field", layouts: ["gallery"], writer: "caller" },
255
+ { path: "sorts", shape: "sorts", layouts: ALL, writer: "caller" },
256
+ { path: "rule_id", shape: "uuid", layouts: ALL, writer: "caller" },
257
+ { path: "is_default", shape: "boolean", layouts: ALL, writer: "caller" },
258
+ { path: "presentation", shape: "presentation", layouts: ALL, writer: "caller" },
259
+ { path: "presentation.style", shape: "style", layouts: ALL, writer: "caller" },
260
+ { path: "presentation.formats", shape: "object", layouts: GRIDS, writer: "caller" },
261
+ { path: "presentation.frozen", shape: "fields", layouts: GRIDS, writer: "caller" },
262
+ { path: "presentation.grouping", shape: "grouping", layouts: ["grid", "gallery", "list"], writer: "caller" },
263
+ { path: "presentation.widths", shape: "widths", layouts: GRIDS, writer: "caller" },
264
+ { path: "presentation.rowHeight", shape: "row_height", layouts: GRIDS, writer: "caller" },
265
+ { path: "presentation.hiddenFields", shape: "fields", layouts: HIDES, writer: "caller" },
266
+ { path: "presentation.cardHidden", shape: "fields", layouts: ["kanban", "calendar", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list", "gallery"], writer: "caller" },
267
+ { path: "presentation.columnOrder", shape: "fields", layouts: GRIDS, writer: "caller" },
268
+ { path: "presentation.gallerySize", shape: "gallery_size", layouts: ["gallery"], writer: "caller" },
269
+ { path: "presentation.wrap", shape: "boolean", layouts: GRIDS, writer: "caller" },
270
+ { path: "presentation.wrapColumns", shape: "fields", layouts: GRIDS, writer: "caller" },
271
+ { path: "presentation.fit", shape: "fit", layouts: GRIDS, writer: "caller" },
272
+ { path: "presentation.freezeFirst", shape: "boolean", layouts: GRIDS, writer: "caller" },
273
+ { path: "presentation.footer", shape: "footer", layouts: GRIDS, writer: "caller" },
274
+ { path: "presentation.summaries", shape: "summaries", layouts: GRIDS, writer: "caller" },
275
+ { path: "grid", shape: "grid", layouts: GRIDS, writer: "caller" },
276
+ { path: "hidden_fields", shape: "input", layouts: HIDES, writer: "input" },
277
+ { path: "table_id", shape: "server", layouts: ALL, writer: "server" },
278
+ { path: "order", shape: "server", layouts: GRIDS, writer: "server" },
279
+ { path: "moved_from", shape: "server", layouts: ALL, writer: "server" }
280
+ ];
281
+ var STORE_KEPT_LAYOUTS = ["grid", "kanban", "calendar", "gallery", ...STORE_KEEPS_TIMELINE ? ["timeline"] : [], "list"];
282
+ var KINDS = STORE_KEPT_LAYOUTS;
283
+ function viewSettings(definition, rowFilters, codec = plainCodec()) {
284
+ const data = definition ?? {};
285
+ const text = (key) => {
286
+ const v = data[key];
287
+ return typeof v === "string" && v !== "" ? v : null;
288
+ };
289
+ const layout = String(data["layout"] ?? "grid");
290
+ const flat = rowFilters ?? (isObject(data["filters"]) ? data["filters"] : null);
291
+ const moved = data["moved_from"];
292
+ return {
293
+ layout: KINDS.includes(layout) ? layout : "grid",
294
+ filters: flat && Object.keys(flat).length > 0 ? flat : null,
295
+ where: isRule(data["where"]) ? data["where"] : null,
296
+ groupField: text("group_field"),
297
+ swimlaneField: text("swimlane_field"),
298
+ collapsedColumns: Array.isArray(data["collapsed_columns"]) ? data["collapsed_columns"].filter((v) => ["string", "number", "boolean"].includes(typeof v)).map(String) : [],
299
+ measure: text("measure"),
300
+ dateField: text("date_field"),
301
+ startField: text("start_field"),
302
+ endField: text("end_field"),
303
+ imageField: text("image_field"),
304
+ sorts: parseSorts(data["sorts"]),
305
+ ruleId: text("rule_id"),
306
+ isDefault: data["is_default"] === true || data["is_default"] === "true",
307
+ presentation: codec.parse(data["presentation"]),
308
+ movedFrom: isObject(moved) ? moved : null
309
+ };
310
+ }
311
+ function isObject(raw) {
312
+ return Boolean(raw) && typeof raw === "object" && !Array.isArray(raw);
313
+ }
314
+ function isRule(raw) {
315
+ if (!isObject(raw)) return false;
316
+ const node = raw;
317
+ return typeof node.op === "string" && Array.isArray(node.args);
318
+ }
319
+ function parseSorts(raw) {
320
+ let list = raw;
321
+ if (typeof raw === "string") {
322
+ try {
323
+ list = raw.trim() === "" ? [] : JSON.parse(raw);
324
+ } catch {
325
+ return [];
326
+ }
327
+ }
328
+ if (!Array.isArray(list)) return [];
329
+ return list.filter((s) => isObject(s) && typeof s.field === "string").map((s) => ({ field: s.field, direction: s.direction === "desc" ? "desc" : "asc" }));
330
+ }
331
+
332
+ // src/views/views.ts
333
+ function plainCodec2() {
334
+ return plainPresentation;
335
+ }
336
+ var VIEW_LAYOUTS = ["grid", "kanban", "calendar", "gallery", "timeline", "list"];
337
+ var LAYOUT_LABEL = {
338
+ grid: "Grid",
339
+ kanban: "Kanban",
340
+ calendar: "Calendar",
341
+ gallery: "Gallery",
342
+ timeline: "Timeline",
343
+ list: "List"
344
+ };
345
+ function viewOrderOf(definition) {
346
+ const raw = definition?.["order"];
347
+ return raw === "manual" ? "manual" : raw === "sorted" ? "sorted" : null;
348
+ }
349
+ function defaultViewOf(views) {
350
+ return views.find((v) => v.isDefault);
351
+ }
352
+ var PAGE_VIEWS = [...VIEW_LAYOUTS, "dashboards", "archived"];
353
+ var PAGE_VIEW_LABEL = {
354
+ ...LAYOUT_LABEL,
355
+ dashboards: "Dashboards",
356
+ archived: "Archived"
357
+ };
358
+ function viewFromRow(row, codec = plainCodec2()) {
359
+ const data = row.definition ?? {};
360
+ const k = viewSettings(data, row.filters && Object.keys(row.filters).length > 0 ? row.filters : null, codec);
361
+ const tableFromDefinition = typeof data["table_id"] === "string" && data["table_id"] !== "" ? data["table_id"] : null;
362
+ return {
363
+ id: row.view_id,
364
+ name: row.name || "Untitled view",
365
+ subject: row.table_id ?? tableFromDefinition ?? "",
366
+ layout: k.layout,
367
+ groupField: k.groupField,
368
+ swimlaneField: k.swimlaneField,
369
+ collapsedColumns: k.collapsedColumns,
370
+ measure: k.measure,
371
+ dateField: k.dateField,
372
+ startField: k.startField,
373
+ endField: k.endField,
374
+ imageField: k.imageField,
375
+ sorts: k.sorts,
376
+ order: viewOrderOf(data),
377
+ ruleId: k.ruleId,
378
+ ...k.filters ? { filters: k.filters } : {},
379
+ where: k.where,
380
+ // The older table's own default view, carried in by the mover, IS this table's default —
381
+ // the mover wrote the row's column, which `custom.views` does not return. Read as anything
382
+ // else, the page would seed a second "All records" beside it and open on that.
383
+ isDefault: k.isDefault || k.movedFrom?.["kind"] === "default_view",
384
+ presentation: k.presentation,
385
+ movedFrom: k.movedFrom
386
+ };
387
+ }
388
+
389
+ // src/views/look.ts
390
+ var plain = () => plainPresentation;
391
+ function lookFromDocument(doc, codec = plain()) {
392
+ const data = doc ?? {};
393
+ const read = viewSettings(data, void 0, codec);
394
+ const out = {};
395
+ const has = (key) => Object.prototype.hasOwnProperty.call(data, key);
396
+ if (has("layout") && VIEW_LAYOUTS.includes(String(data["layout"]))) {
397
+ out.layout = data["layout"];
398
+ }
399
+ if (has("group_field")) out.groupField = read.groupField;
400
+ if (has("swimlane_field")) out.swimlaneField = read.swimlaneField;
401
+ if (has("collapsed_columns")) out.collapsedColumns = read.collapsedColumns;
402
+ if (has("measure")) out.measure = read.measure;
403
+ if (has("date_field")) out.dateField = read.dateField;
404
+ if (has("start_field")) out.startField = read.startField;
405
+ if (has("end_field")) out.endField = read.endField;
406
+ if (has("image_field")) out.imageField = read.imageField;
407
+ if (has("sorts")) out.sorts = read.sorts;
408
+ if (has("where")) out.where = read.where;
409
+ if (has("presentation")) out.presentation = codec.parse(data["presentation"]);
410
+ return out;
411
+ }
412
+ function applyLook(view, look) {
413
+ if (!look) return view;
414
+ return { ...view, ...look };
415
+ }
416
+ async function readLooks(client, tableId, codec = plain()) {
417
+ const answered = await client.viewLookRead({ table_id: tableId });
418
+ if (!answered.ok) return answered;
419
+ const out = {};
420
+ for (const [viewId, row] of Object.entries(answered.data ?? {})) {
421
+ out[viewId] = lookFromDocument(row?.look ?? null, codec);
422
+ }
423
+ return { ok: true, data: out };
424
+ }
425
+
426
+ // src/first-page/seed.ts
427
+ var TABLE_PAGE_SIZE = 100;
428
+ var EMBEDDED_PAGE_SIZE = 50;
429
+ function presentationFacts(presentation) {
430
+ const p = presentation && typeof presentation === "object" ? presentation : {};
431
+ const g = p["grouping"];
432
+ const grouping = g && typeof g === "object" && typeof g.field === "string" ? g : void 0;
433
+ const s = p["summaries"];
434
+ return { grouping, summaries: s && typeof s === "object" ? s : {} };
435
+ }
436
+ function firstGridPageArgs(input) {
437
+ const { shown, fields } = input;
438
+ if (!shown) return null;
439
+ if ((shown.layout ?? "grid") !== "grid") return null;
440
+ if (shown.ruleId) return null;
441
+ if (shown.order === "manual") return null;
442
+ const { grouping } = presentationFacts(shown.presentation);
443
+ if (grouping && !(input.merged && isPlainGrouping(grouping))) return null;
444
+ const first = (shown.sorts ?? [])[0];
445
+ const viewSort = first && fields.some((f) => f.key === first.field) ? { id: first.field, direction: first.direction } : null;
446
+ const opening = viewSort ?? defaultSortOf(input.table, fields);
447
+ return {
448
+ p_table_id: input.tableId,
449
+ p_filter: viewFilterOf(shown) ?? {},
450
+ p_search: null,
451
+ p_sort: groupedPageSort(fields, grouping?.field ?? null, pageSortFor(fields, opening)),
452
+ p_view_id: null,
453
+ p_limit: input.pageSize ?? TABLE_PAGE_SIZE,
454
+ p_offset: 0
455
+ };
456
+ }
457
+ async function firstGridPageRequest(client, tableId, options = {}) {
458
+ return (await firstGridOpening(client, tableId, options))?.args ?? null;
459
+ }
460
+ function shownFromSpec(spec, tableId) {
461
+ return { ...spec, subject: spec.subject ?? tableId, id: "", movedFrom: null };
462
+ }
463
+ async function firstGridOpening(client, tableId, options) {
464
+ const codec = options.codec ?? plainPresentation;
465
+ const explicit = options.view;
466
+ const [table, fields, views, looks] = await Promise.all([
467
+ client.tableRead({ table_id: tableId }),
468
+ client.fields({ table_id: tableId }),
469
+ explicit ? Promise.resolve(null) : client.views({ table_id: tableId }),
470
+ explicit ? Promise.resolve(null) : readLooks(client, tableId, codec)
471
+ ]);
472
+ if (!table.ok || !fields.ok) return null;
473
+ let shown;
474
+ if (explicit) {
475
+ shown = shownFromSpec(explicit, tableId);
476
+ } else {
477
+ if (!views?.ok || !looks?.ok) return null;
478
+ const mine = views.data.map((row) => viewFromRow(row, codec)).filter((v) => v.subject === tableId);
479
+ const view = defaultViewOf(mine) ?? mine[0] ?? null;
480
+ shown = view ? applyLook(view, looks.data[view.id]) : shownFromSpec({ name: "All", subject: tableId, layout: "grid", isDefault: true }, tableId);
481
+ }
482
+ const args = firstGridPageArgs({
483
+ tableId,
484
+ table: table.data,
485
+ fields: fields.data,
486
+ shown,
487
+ ...options.pageSize ? { pageSize: options.pageSize } : {},
488
+ ...options.merged ? { merged: true } : {}
489
+ });
490
+ return args ? { args, shown, fields: fields.data } : null;
491
+ }
492
+ function serverRowsOf(seed) {
493
+ const found = seed?.answers.find((a) => a.door === "server_rows");
494
+ const data = found?.data;
495
+ if (!data || typeof data !== "object") return null;
496
+ return { on: data.on === true, capMs: typeof data.cap_ms === "number" && data.cap_ms > 0 ? data.cap_ms : null };
497
+ }
498
+ async function askTablePageSeed(input) {
499
+ const recording = (0, import_core.recordingDataSource)((0, import_core.asRecordsDataSource)(input.dataSource));
500
+ const client = (0, import_core.createRecordsClient)({
501
+ dataSource: recording.source,
502
+ organizationId: input.organizationId,
503
+ actor: input.actor,
504
+ onError: () => {
505
+ }
506
+ });
507
+ const record = input.recordId ? Promise.resolve(
508
+ recording.source.rpc("record_page_bundle", { p_organization_id: input.organizationId, p_record_id: input.recordId }, { schema: "custom" })
509
+ ).catch(() => null) : null;
510
+ try {
511
+ const pageSize = input.pageSize ?? (input.embedded ? EMBEDDED_PAGE_SIZE : TABLE_PAGE_SIZE);
512
+ const opening = await firstGridOpening(client, input.tableId, {
513
+ pageSize,
514
+ ...input.merged ? { merged: true } : {},
515
+ ...input.view ? { view: input.view } : {},
516
+ ...input.codec ? { codec: input.codec } : {}
517
+ });
518
+ const wantRows = typeof input.rows === "function" ? input.rows(recording.seed()) : input.rows !== false;
519
+ if (opening && wantRows) {
520
+ const { args, shown, fields } = opening;
521
+ const page = await client.listPage({
522
+ table_id: args.p_table_id,
523
+ filter: args.p_filter,
524
+ search: args.p_search,
525
+ sort: args.p_sort,
526
+ view_id: args.p_view_id,
527
+ limit: args.p_limit,
528
+ offset: args.p_offset
529
+ });
530
+ if (page.ok) {
531
+ const { grouping, summaries: chosen } = presentationFacts(shown?.presentation);
532
+ const groupKey = grouping?.field ?? null;
533
+ const reads = [];
534
+ const filter = args.p_filter && Object.keys(args.p_filter).length > 0 ? args.p_filter : void 0;
535
+ if (groupKey) {
536
+ reads.push(client.recordAggregate({ table_id: input.tableId, groupBy: [groupKey], measures: groupFactMeasures(chosen), limit: 1e3, ...filter ? { filter } : {} }));
537
+ }
538
+ const bar = summaryBarMeasures(chosen);
539
+ if (bar.length > 0) reads.push(client.recordAggregate({ table_id: input.tableId, measures: bar, ...filter ? { filter } : {} }));
540
+ for (const field of fields) {
541
+ if (field.type !== "list" && field.type !== "relation") continue;
542
+ const ids = /* @__PURE__ */ new Set();
543
+ for (const row of page.data.rows) {
544
+ const value = row.document?.[field.key];
545
+ for (const id of Array.isArray(value) ? value.map(String) : typeof value === "string" ? [value] : []) if ((0, import_uuid2.isUuidShape)(id)) ids.add(id);
546
+ }
547
+ if (ids.size > 0) reads.push(client.relationWordsMany({ field_id: field.id, record_ids: [...ids] }));
548
+ }
549
+ if (input.merged) {
550
+ for (const key of choiceFieldKeys(fields)) {
551
+ reads.push(client.recordAggregate({ table_id: input.tableId, groupBy: [key], measures: [{ op: "count" }], limit: 500, ...filter ? { filter } : {} }));
552
+ }
553
+ }
554
+ const unversioned = page.data.rows.filter((row) => ownVersion(row) === null).map((row) => row.id);
555
+ if (unversioned.length > 0) reads.push(client.recordHeaders({ ids: unversioned }));
556
+ reads.push(
557
+ client.reverseColumns({ table_id: input.tableId }).then(async (columns) => {
558
+ if (!columns.ok || columns.data.length === 0) return null;
559
+ const record_ids = page.data.rows.map((row) => row.id);
560
+ const all = await client.reverseLinksFields({ table_id: input.tableId, source_field_ids: columns.data.map((c) => c.source_field_id), record_ids, limit: REVERSE_CELL_CHIPS });
561
+ if (all.ok || all.error.code !== "door_absent") return null;
562
+ return Promise.all(columns.data.map((c) => client.reverseLinksMany({ table_id: input.tableId, source_field_id: c.source_field_id, record_ids, limit: REVERSE_CELL_CHIPS })));
563
+ })
564
+ );
565
+ await Promise.all(reads.map((read) => read.catch(() => null)));
566
+ }
567
+ }
568
+ } catch {
569
+ }
570
+ if (record) await record;
571
+ return recording.seed();
572
+ }
573
+ function recordedClient(input) {
574
+ const recording = (0, import_core.recordingDataSource)((0, import_core.asRecordsDataSource)(input.dataSource));
575
+ const client = (0, import_core.createRecordsClient)({ dataSource: recording.source, organizationId: input.organizationId, actor: input.actor, onError: () => {
576
+ } });
577
+ return { recording, client };
578
+ }
579
+ function entityTableQuery(options = {}) {
580
+ const search = (options.search ?? "").trim();
581
+ return { ...options.pageSize ? { pageSize: options.pageSize } : {}, ...search ? { search } : {} };
582
+ }
583
+ function entityChartQuestion(input) {
584
+ const m = input.measure ?? { op: "count" };
585
+ return {
586
+ ...input.by ? { by: [input.by] } : {},
587
+ show: [m.op === "count" ? "count" : { op: m.op, of: m.of }],
588
+ ...input.where ? { where: input.where } : {},
589
+ ...input.organization ? { organization: input.organization } : {}
590
+ };
591
+ }
592
+ function mergeSeeds(...seeds) {
593
+ const held = seeds.filter((s) => Boolean(s));
594
+ const answers = /* @__PURE__ */ new Map();
595
+ for (const seed of held) for (const a of seed.answers) answers.set(`${a.door}|${JSON.stringify(a.args)}`, a);
596
+ return { at: held.length ? Math.min(...held.map((s) => s.at)) : Date.now(), answers: [...answers.values()] };
597
+ }
598
+ async function askEntityBlockSeed(input) {
599
+ const recording = (0, import_core.recordingDataSource)((0, import_core.asRecordsDataSource)(input.dataSource));
600
+ const port = (0, import_entity.createSeedPort)(recording.source);
601
+ try {
602
+ await Promise.all([port.describe(input.token), port.list(input.token, entityTableQuery(input.question ?? {}))]);
603
+ } catch {
604
+ }
605
+ return recording.seed();
606
+ }
607
+ async function askChartSeed(input) {
608
+ const { recording, client } = recordedClient(input);
609
+ try {
610
+ await client.drillAsk({ source: input.source, question: entityChartQuestion(input.question ?? {}) });
611
+ } catch {
612
+ }
613
+ return recording.seed();
614
+ }
615
+ async function askTileSeed(input) {
616
+ const { recording, client } = recordedClient(input);
617
+ const specs = Array.isArray(input.spec) ? input.spec : [input.spec];
618
+ await Promise.all(specs.map((spec) => client.recordAggregate({ table_id: input.tableId, ...spec }).catch(() => null)));
619
+ return recording.seed();
620
+ }
621
+ function bindFirstPageCodec(codec) {
622
+ return {
623
+ firstGridPageRequest: (client, tableId, options = {}) => firstGridPageRequest(client, tableId, { ...options, codec }),
624
+ askTablePageSeed: (input) => askTablePageSeed({ ...input, codec })
625
+ };
626
+ }
627
+ //# sourceMappingURL=index.cjs.map