@graview/core 0.1.9 → 0.1.12

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 (200) hide show
  1. package/README.md +19 -8
  2. package/dist/app.d.ts +41 -2
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js.map +1 -1
  5. package/dist/blocks.d.ts +5 -0
  6. package/dist/blocks.d.ts.map +1 -0
  7. package/dist/blocks.js +14 -0
  8. package/dist/blocks.js.map +1 -0
  9. package/dist/capabilities.js +1 -1
  10. package/dist/capabilities.js.map +1 -1
  11. package/dist/check.d.ts +8 -0
  12. package/dist/check.d.ts.map +1 -0
  13. package/dist/check.js +19 -0
  14. package/dist/check.js.map +1 -0
  15. package/dist/cli/check/arrangement.d.ts.map +1 -1
  16. package/dist/cli/check/arrangement.js +3 -2
  17. package/dist/cli/check/arrangement.js.map +1 -1
  18. package/dist/cli/check/brand.d.ts.map +1 -1
  19. package/dist/cli/check/brand.js +21 -0
  20. package/dist/cli/check/brand.js.map +1 -1
  21. package/dist/cli/check/computed.d.ts +14 -0
  22. package/dist/cli/check/computed.d.ts.map +1 -0
  23. package/dist/cli/check/computed.js +34 -0
  24. package/dist/cli/check/computed.js.map +1 -0
  25. package/dist/cli/check/hidden-reads.d.ts +4 -0
  26. package/dist/cli/check/hidden-reads.d.ts.map +1 -0
  27. package/dist/cli/check/hidden-reads.js +152 -0
  28. package/dist/cli/check/hidden-reads.js.map +1 -0
  29. package/dist/cli/check/index.d.ts +2 -0
  30. package/dist/cli/check/index.d.ts.map +1 -1
  31. package/dist/cli/check/index.js +2 -0
  32. package/dist/cli/check/index.js.map +1 -1
  33. package/dist/cli/check/lenses.d.ts +10 -0
  34. package/dist/cli/check/lenses.d.ts.map +1 -1
  35. package/dist/cli/check/lenses.js +37 -19
  36. package/dist/cli/check/lenses.js.map +1 -1
  37. package/dist/cli/check/relations.d.ts.map +1 -1
  38. package/dist/cli/check/relations.js +2 -1
  39. package/dist/cli/check/relations.js.map +1 -1
  40. package/dist/cli/check/views.d.ts.map +1 -1
  41. package/dist/cli/check/views.js +13 -3
  42. package/dist/cli/check/views.js.map +1 -1
  43. package/dist/cli/check.d.ts.map +1 -1
  44. package/dist/cli/check.js +5 -1
  45. package/dist/cli/check.js.map +1 -1
  46. package/dist/cli/create.d.ts.map +1 -1
  47. package/dist/cli/create.js +1 -1
  48. package/dist/cli/create.js.map +1 -1
  49. package/dist/cli/describe.d.ts.map +1 -1
  50. package/dist/cli/describe.js +66 -1
  51. package/dist/cli/describe.js.map +1 -1
  52. package/dist/cli/index.d.ts +2 -2
  53. package/dist/cli/index.d.ts.map +1 -1
  54. package/dist/cli/index.js +23 -2
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/columns.d.ts +73 -0
  57. package/dist/columns.d.ts.map +1 -0
  58. package/dist/columns.js +100 -0
  59. package/dist/columns.js.map +1 -0
  60. package/dist/conformance/index.js +1 -1
  61. package/dist/conformance/index.js.map +1 -1
  62. package/dist/describe.d.ts +5 -0
  63. package/dist/describe.d.ts.map +1 -0
  64. package/dist/describe.js +19 -0
  65. package/dist/describe.js.map +1 -0
  66. package/dist/document/blocks.d.ts +187 -0
  67. package/dist/document/blocks.d.ts.map +1 -0
  68. package/dist/document/blocks.js +372 -0
  69. package/dist/document/blocks.js.map +1 -0
  70. package/dist/document/compile-checked.d.ts +8 -0
  71. package/dist/document/compile-checked.d.ts.map +1 -0
  72. package/dist/document/compile-checked.js +36 -0
  73. package/dist/document/compile-checked.js.map +1 -0
  74. package/dist/document/compile.d.ts +8 -6
  75. package/dist/document/compile.d.ts.map +1 -1
  76. package/dist/document/compile.js +68 -46
  77. package/dist/document/compile.js.map +1 -1
  78. package/dist/document/computed-values.d.ts +33 -0
  79. package/dist/document/computed-values.d.ts.map +1 -0
  80. package/dist/document/computed-values.js +60 -0
  81. package/dist/document/computed-values.js.map +1 -0
  82. package/dist/document/computed.d.ts +42 -0
  83. package/dist/document/computed.d.ts.map +1 -0
  84. package/dist/document/computed.js +173 -0
  85. package/dist/document/computed.js.map +1 -0
  86. package/dist/document/describe-place.d.ts +95 -0
  87. package/dist/document/describe-place.d.ts.map +1 -0
  88. package/dist/document/describe-place.js +286 -0
  89. package/dist/document/describe-place.js.map +1 -0
  90. package/dist/document/diff.d.ts.map +1 -1
  91. package/dist/document/diff.js +78 -4
  92. package/dist/document/diff.js.map +1 -1
  93. package/dist/document/edit.d.ts +1 -1
  94. package/dist/document/edit.d.ts.map +1 -1
  95. package/dist/document/edit.js +908 -107
  96. package/dist/document/edit.js.map +1 -1
  97. package/dist/document/expr/analyze.d.ts +22 -0
  98. package/dist/document/expr/analyze.d.ts.map +1 -1
  99. package/dist/document/expr/analyze.js +51 -4
  100. package/dist/document/expr/analyze.js.map +1 -1
  101. package/dist/document/expr/evaluate.d.ts +7 -1
  102. package/dist/document/expr/evaluate.d.ts.map +1 -1
  103. package/dist/document/expr/evaluate.js +121 -8
  104. package/dist/document/expr/evaluate.js.map +1 -1
  105. package/dist/document/expr/index.d.ts +1 -1
  106. package/dist/document/expr/index.d.ts.map +1 -1
  107. package/dist/document/expr/index.js +1 -1
  108. package/dist/document/expr/index.js.map +1 -1
  109. package/dist/document/expr/parse.d.ts +2 -1
  110. package/dist/document/expr/parse.d.ts.map +1 -1
  111. package/dist/document/expr/parse.js +6 -3
  112. package/dist/document/expr/parse.js.map +1 -1
  113. package/dist/document/expr/print.d.ts.map +1 -1
  114. package/dist/document/expr/print.js +4 -2
  115. package/dist/document/expr/print.js.map +1 -1
  116. package/dist/document/graview-template.d.ts +20 -12
  117. package/dist/document/graview-template.d.ts.map +1 -1
  118. package/dist/document/graview-template.js +5 -44
  119. package/dist/document/graview-template.js.map +1 -1
  120. package/dist/document/index.d.ts +8 -8
  121. package/dist/document/index.d.ts.map +1 -1
  122. package/dist/document/index.js +5 -5
  123. package/dist/document/index.js.map +1 -1
  124. package/dist/document/instantiate-template.d.ts +14 -0
  125. package/dist/document/instantiate-template.d.ts.map +1 -0
  126. package/dist/document/instantiate-template.js +46 -0
  127. package/dist/document/instantiate-template.js.map +1 -0
  128. package/dist/document/rules.d.ts +2 -1
  129. package/dist/document/rules.d.ts.map +1 -1
  130. package/dist/document/rules.js +5 -1
  131. package/dist/document/rules.js.map +1 -1
  132. package/dist/document/schema.d.ts +46 -5
  133. package/dist/document/schema.d.ts.map +1 -1
  134. package/dist/document/schema.js +31 -3
  135. package/dist/document/schema.js.map +1 -1
  136. package/dist/document/template.d.ts +33 -2
  137. package/dist/document/template.d.ts.map +1 -1
  138. package/dist/document/template.js +156 -18
  139. package/dist/document/template.js.map +1 -1
  140. package/dist/document/thumbnail.d.ts +5 -4
  141. package/dist/document/thumbnail.d.ts.map +1 -1
  142. package/dist/document/thumbnail.js +29 -21
  143. package/dist/document/thumbnail.js.map +1 -1
  144. package/dist/document/to-document.d.ts.map +1 -1
  145. package/dist/document/to-document.js +6 -1
  146. package/dist/document/to-document.js.map +1 -1
  147. package/dist/document/views.d.ts +58 -3
  148. package/dist/document/views.d.ts.map +1 -1
  149. package/dist/document/views.js +356 -24
  150. package/dist/document/views.js.map +1 -1
  151. package/dist/figures.d.ts +3 -0
  152. package/dist/figures.d.ts.map +1 -0
  153. package/dist/figures.js +14 -0
  154. package/dist/figures.js.map +1 -0
  155. package/dist/index.d.ts +3 -12
  156. package/dist/index.d.ts.map +1 -1
  157. package/dist/index.js +2 -7
  158. package/dist/index.js.map +1 -1
  159. package/dist/mutations/types.d.ts +12 -0
  160. package/dist/mutations/types.d.ts.map +1 -1
  161. package/dist/places.d.ts +197 -0
  162. package/dist/places.d.ts.map +1 -0
  163. package/dist/places.js +376 -0
  164. package/dist/places.js.map +1 -0
  165. package/dist/scaffold/domain.js +1 -1
  166. package/dist/scaffold/from-template.d.ts.map +1 -1
  167. package/dist/scaffold/from-template.js +3 -3
  168. package/dist/scaffold/from-template.js.map +1 -1
  169. package/dist/scaffold/project.d.ts.map +1 -1
  170. package/dist/scaffold/project.js +13 -0
  171. package/dist/scaffold/project.js.map +1 -1
  172. package/dist/scaffold/ui.d.ts.map +1 -1
  173. package/dist/scaffold/ui.js +13 -10
  174. package/dist/scaffold/ui.js.map +1 -1
  175. package/dist/scene-districts.d.ts +5 -1
  176. package/dist/scene-districts.d.ts.map +1 -1
  177. package/dist/scene-districts.js +11 -4
  178. package/dist/scene-districts.js.map +1 -1
  179. package/dist/scene.d.ts +7 -0
  180. package/dist/scene.d.ts.map +1 -0
  181. package/dist/scene.js +16 -0
  182. package/dist/scene.js.map +1 -0
  183. package/dist/schema/define-node.d.ts +3 -0
  184. package/dist/schema/define-node.d.ts.map +1 -1
  185. package/dist/schema/define-node.js +3 -1
  186. package/dist/schema/define-node.js.map +1 -1
  187. package/dist/schema/types.d.ts +17 -0
  188. package/dist/schema/types.d.ts.map +1 -1
  189. package/dist/theme/types.d.ts +9 -0
  190. package/dist/theme/types.d.ts.map +1 -1
  191. package/dist/theme/types.js.map +1 -1
  192. package/dist/version.d.ts +1 -1
  193. package/dist/version.d.ts.map +1 -1
  194. package/dist/version.js +1 -1
  195. package/dist/version.js.map +1 -1
  196. package/dist/views/types.d.ts +19 -0
  197. package/dist/views/types.d.ts.map +1 -1
  198. package/dist/views/types.js +14 -0
  199. package/dist/views/types.js.map +1 -1
  200. package/package.json +21 -1
@@ -0,0 +1,60 @@
1
+ import { labelOf } from "../schema/define-node.js";
2
+ import { computedOf } from "./computed.js";
3
+ import { evaluateExpr, ExprEvalError, NodeSet } from "./expr/evaluate.js";
4
+ import { shapesOfSchema } from "./rules.js";
5
+ const SHAPES = new WeakMap();
6
+ function shapesFor(schema) {
7
+ let shapes = SHAPES.get(schema);
8
+ if (!shapes)
9
+ SHAPES.set(schema, (shapes = shapesOfSchema(schema)));
10
+ return shapes;
11
+ }
12
+ /**
13
+ * Every computed field of one record, worked out over `graph` — the graph
14
+ * of the seat it is for. Each field has its own budget (`budget`, else the
15
+ * language's default); one that cannot be worked out is `refused`, not thrown.
16
+ */
17
+ export function computedValues(schema, graph, node, options = {}) {
18
+ const kinds = shapesFor(schema);
19
+ const values = {};
20
+ const refused = {};
21
+ const plain = (value) => {
22
+ if (value instanceof NodeSet)
23
+ return value.nodes.map((n) => plain(n));
24
+ if (Array.isArray(value))
25
+ return value.map((v) => plain(v));
26
+ if (value !== null && typeof value === "object") {
27
+ const record = value;
28
+ return { id: record.id, kind: record.kind, label: labelOf(schema.tryDefinition(record.kind), record) };
29
+ }
30
+ return value;
31
+ };
32
+ for (const [name, expr] of kinds.get(node.kind)?.computed ?? []) {
33
+ try {
34
+ values[name] = plain(evaluateExpr(expr, { graph, subject: node, kinds, ...(options.today ? { today: options.today } : {}), ...(options.budget ? { budget: options.budget } : {}) }));
35
+ }
36
+ catch (e) {
37
+ if (!(e instanceof ExprEvalError))
38
+ throw e;
39
+ refused[name] = e.sentence;
40
+ }
41
+ }
42
+ return { values, refused };
43
+ }
44
+ /**
45
+ * A record with its computed values beside its stored ones, as words a
46
+ * surface shows (a record as its name, a set as their names) — for the
47
+ * facts a page or an agent reads, never for a write.
48
+ */
49
+ export function withComputed(schema, graph, node) {
50
+ const { values } = computedValues(schema, graph, node);
51
+ if (Object.keys(values).length === 0)
52
+ return node;
53
+ const said = (v) => (Array.isArray(v) ? v.map(said) : v !== null && typeof v === "object" ? v.label : v);
54
+ return { ...node, ...Object.fromEntries(Object.entries(values).map(([k, v]) => [k, said(v)])) };
55
+ }
56
+ /** The names of a kind's computed fields, in declaration order. */
57
+ export function computedNames(schema, kind) {
58
+ return [...computedOf(schema.tryDefinition(kind)).keys()];
59
+ }
60
+ //# sourceMappingURL=computed-values.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed-values.js","sourceRoot":"","sources":["../../src/document/computed-values.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { ComputedField } from "../schema/types.js";
2
+ import { type Expr } from "./expr/parse.js";
3
+ import { type Finding } from "./findings.js";
4
+ export interface ComputedEntry {
5
+ readonly expr: string;
6
+ readonly label?: string;
7
+ readonly description?: string;
8
+ }
9
+ /** A kind's computed fields, each in its long form, in declaration order. */
10
+ export declare function computedOf(definition: {
11
+ readonly computed?: Readonly<Record<string, ComputedField>>;
12
+ } | undefined): ReadonlyMap<string, ComputedEntry>;
13
+ /** A kind's computed fields, parsed, for the evaluator; one that does not parse is left out (the check says why). */
14
+ export declare function parsedComputed(definition: {
15
+ readonly computed?: Readonly<Record<string, ComputedField>>;
16
+ } | undefined): ReadonlyMap<string, Expr> | undefined;
17
+ /** What the check reads of one kind. */
18
+ export interface ComputedKind {
19
+ readonly fields: ReadonlySet<string>;
20
+ readonly edges: ReadonlySet<string>;
21
+ readonly computed: ReadonlyMap<string, ComputedEntry>;
22
+ }
23
+ /**
24
+ * Findings about every kind's computed fields. `at(kind, name)` is where a
25
+ * finding points: `kinds.<kind>.computed.<name>` in a document,
26
+ * `defineNode("<kind>").computed.<name>` in a declaration.
27
+ */
28
+ export declare function validateComputed(kinds: ReadonlyMap<string, ComputedKind>, at: (kind: string, name: string) => string): Finding[];
29
+ /**
30
+ * WHETHER A COMPUTED FIELD IS WORKED OUT FROM ITS RECORD ALONE — its stored
31
+ * fields and other such computed fields, no relation walked and no kind
32
+ * swept. A label and a describe are said with no graph in hand (a label
33
+ * function is handed the record and nothing else), so they may name a
34
+ * computed field only when this is true: `total = list * units` is said
35
+ * rightly anywhere, and a price after a discount read from another record
36
+ * would be said wrongly everywhere.
37
+ */
38
+ export declare function workedOutAlone(definition: {
39
+ readonly fields: ReadonlySet<string> | Readonly<Record<string, unknown>>;
40
+ readonly computed?: Readonly<Record<string, ComputedField>>;
41
+ } | undefined, name: string, seen?: ReadonlySet<string>): boolean;
42
+ //# sourceMappingURL=computed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../../src/document/computed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAA8B,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAmB7D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,UAAU,EAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAItJ;AAED,qHAAqH;AACrH,wBAAgB,cAAc,CAAC,UAAU,EAAE;IAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,SAAS,CAY7J;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACvD;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,EAAE,CA+EhI;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAA;CAAE,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAW,CAAC,MAAM,CAAa,GAAG,OAAO,CAe9P"}
@@ -0,0 +1,173 @@
1
+ import { analyzeExpr, costDegree } from "./expr/analyze.js";
2
+ import { ExprSyntaxError, parseExpr } from "./expr/parse.js";
3
+ import { error, warning } from "./findings.js";
4
+ /** A kind's computed fields, each in its long form, in declaration order. */
5
+ export function computedOf(definition) {
6
+ const out = new Map();
7
+ for (const [name, field] of Object.entries(definition?.computed ?? {}))
8
+ out.set(name, typeof field === "string" ? { expr: field } : field);
9
+ return out;
10
+ }
11
+ /** A kind's computed fields, parsed, for the evaluator; one that does not parse is left out (the check says why). */
12
+ export function parsedComputed(definition) {
13
+ const entries = computedOf(definition);
14
+ if (entries.size === 0)
15
+ return undefined;
16
+ const parsed = new Map();
17
+ for (const [name, entry] of entries) {
18
+ try {
19
+ parsed.set(name, parseExpr(entry.expr));
20
+ }
21
+ catch (e) {
22
+ if (!(e instanceof ExprSyntaxError))
23
+ throw e;
24
+ }
25
+ }
26
+ return parsed;
27
+ }
28
+ /** Work that grows with the square of the graph per read is said; with the cube, refused. */
29
+ const WARN_AT = 2;
30
+ const REFUSE_AT = 3;
31
+ /**
32
+ * Findings about every kind's computed fields. `at(kind, name)` is where a
33
+ * finding points: `kinds.<kind>.computed.<name>` in a document,
34
+ * `defineNode("<kind>").computed.<name>` in a declaration.
35
+ */
36
+ export function validateComputed(kinds, at) {
37
+ const findings = [];
38
+ const edges = new Set([...kinds.values()].flatMap((k) => [...k.edges]));
39
+ const parsed = new Map();
40
+ for (const [kind, spec] of kinds) {
41
+ const exprs = new Map();
42
+ parsed.set(kind, exprs);
43
+ for (const [name, entry] of spec.computed) {
44
+ const path = at(kind, name);
45
+ if (!/^[a-z][A-Za-z0-9]*$/.test(name) || name === "id" || name === "kind") {
46
+ findings.push(error("computed-name", path, `"${name}" cannot name a computed field`, 'a computed field is named like a field: one word or camelCase, like "net" or "leadPackage"'));
47
+ continue;
48
+ }
49
+ if (spec.fields.has(name) || spec.edges.has(name)) {
50
+ findings.push(error("computed-clash", path, `"${name}" is already a ${spec.fields.has(name) ? "field" : "relation"} of ${kind}, so it cannot also be worked out`, "give the computed field a name of its own"));
51
+ continue;
52
+ }
53
+ let expr;
54
+ try {
55
+ expr = parseExpr(entry.expr);
56
+ }
57
+ catch (e) {
58
+ if (!(e instanceof ExprSyntaxError))
59
+ throw e;
60
+ findings.push(error("expression", path, `${e.sentence} (at character ${e.at + 1})`));
61
+ continue;
62
+ }
63
+ exprs.set(name, expr);
64
+ const shape = analyzeExpr(expr);
65
+ for (const fn of shape.unknownFunctions)
66
+ findings.push(error("unknown-function", path, `"${fn}" is not a function the rule language knows`, "see the rule language in the graview-invariant skill"));
67
+ for (const n of shape.names) {
68
+ if (n === "id" || spec.fields.has(n) || spec.edges.has(n) || spec.computed.has(n))
69
+ continue;
70
+ findings.push(error("computed-name", path, `${kind} has no field, relation or computed field called "${n}"`));
71
+ }
72
+ for (const e of shape.edges)
73
+ if (!edges.has(e))
74
+ findings.push(error("computed-edge", path, `"${e}" is not a relation any kind declares`));
75
+ for (const k of shape.sweeps)
76
+ if (!kinds.has(k))
77
+ findings.push(error("computed-kind", path, `"${k}" is not a kind this declaration has`));
78
+ }
79
+ }
80
+ // ── cycles among one kind's computed fields ────────────────────────────────
81
+ for (const [kind, exprs] of parsed) {
82
+ const reads = new Map([...exprs].map(([name, expr]) => [name, [...analyzeExpr(expr).names].filter((n) => exprs.has(n))]));
83
+ const said = new Set();
84
+ for (const start of exprs.keys()) {
85
+ const cycle = cycleFrom(start, reads);
86
+ if (!cycle)
87
+ continue;
88
+ const key = [...cycle].slice(0, -1).sort().join(" ");
89
+ if (said.has(key))
90
+ continue;
91
+ said.add(key);
92
+ findings.push(error("computed-cycle", at(kind, start), `${kind}'s computed fields work each other out in a circle: ${cycle.join(" → ")}`, "work one of them out from stored fields instead"));
93
+ }
94
+ }
95
+ // ── cost: how a read grows with the graph ──────────────────────────────────
96
+ const degrees = new Map();
97
+ const pending = new Set();
98
+ const degreeOf = (kind, name) => {
99
+ const key = `${kind}.${name}`;
100
+ if (degrees.has(key))
101
+ return degrees.get(key);
102
+ const expr = parsed.get(kind)?.get(name);
103
+ if (!expr || pending.has(key))
104
+ return 0;
105
+ pending.add(key);
106
+ const d = costDegree(expr, (n, bare) => bare ? (parsed.get(kind)?.has(n) ? degreeOf(kind, n) : 0) : Math.max(0, ...[...parsed].filter(([, e]) => e.has(n)).map(([k]) => degreeOf(k, n))));
107
+ pending.delete(key);
108
+ degrees.set(key, d);
109
+ return d;
110
+ };
111
+ for (const [kind, exprs] of parsed) {
112
+ for (const name of exprs.keys()) {
113
+ const d = degreeOf(kind, name);
114
+ if (d >= REFUSE_AT) {
115
+ findings.push(error("computed-cost", at(kind, name), `working out ${name} sweeps a kind inside a sweep inside a sweep, so its work grows with the cube of the graph — more than a page can afford`, "walk a relation with out()/in() instead of sweeping with all(), or work part of it out on the records it sweeps"));
116
+ }
117
+ else if (d >= WARN_AT) {
118
+ findings.push(warning("computed-cost", at(kind, name), `working out ${name} reads every record of one kind for each record of another, which grows quickly as the app grows`, "walk a relation with out()/in() instead of all() where you can"));
119
+ }
120
+ }
121
+ }
122
+ return findings;
123
+ }
124
+ /** A path from `start` back to itself through what each name reads, or nothing. */
125
+ function cycleFrom(start, reads) {
126
+ const path = [];
127
+ const seen = new Set();
128
+ const walk = (name) => {
129
+ if (name === start && path.length > 0)
130
+ return [...path, start];
131
+ if (seen.has(name))
132
+ return undefined;
133
+ seen.add(name);
134
+ path.push(name);
135
+ for (const next of reads.get(name) ?? []) {
136
+ const found = walk(next);
137
+ if (found)
138
+ return found;
139
+ }
140
+ path.pop();
141
+ return undefined;
142
+ };
143
+ return walk(start);
144
+ }
145
+ /**
146
+ * WHETHER A COMPUTED FIELD IS WORKED OUT FROM ITS RECORD ALONE — its stored
147
+ * fields and other such computed fields, no relation walked and no kind
148
+ * swept. A label and a describe are said with no graph in hand (a label
149
+ * function is handed the record and nothing else), so they may name a
150
+ * computed field only when this is true: `total = list * units` is said
151
+ * rightly anywhere, and a price after a discount read from another record
152
+ * would be said wrongly everywhere.
153
+ */
154
+ export function workedOutAlone(definition, name, seen = new Set()) {
155
+ const entry = computedOf(definition).get(name);
156
+ if (!entry || seen.has(name))
157
+ return false;
158
+ let expr;
159
+ try {
160
+ expr = parseExpr(entry.expr);
161
+ }
162
+ catch {
163
+ return false;
164
+ }
165
+ const shape = analyzeExpr(expr);
166
+ if (shape.edges.length > 0 || shape.sweeps.length > 0 || [...shape.functions].some((fn) => fn === "out" || fn === "in" || fn === "all"))
167
+ return false;
168
+ const fields = definition.fields;
169
+ const isField = (n) => (fields instanceof Set ? fields.has(n) : Object.prototype.hasOwnProperty.call(fields, n));
170
+ const next = new Set([...seen, name]);
171
+ return [...shape.names].every((n) => isField(n) || workedOutAlone(definition, n, next));
172
+ }
173
+ //# sourceMappingURL=computed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed.js","sourceRoot":"","sources":["../../src/document/computed.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,SAAS,EAAa,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAgB,MAAM,eAAe,CAAC;AAyB7D,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,UAAuF;IAChH,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,IAAI,EAAE,CAAC;QAAE,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC3I,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qHAAqH;AACrH,MAAM,UAAU,cAAc,CAAC,UAAuF;IACpH,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgB,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,CAAC,CAAC,YAAY,eAAe,CAAC;gBAAE,MAAM,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AASD,6FAA6F;AAC7F,MAAM,OAAO,GAAG,CAAC,CAAC;AAClB,MAAM,SAAS,GAAG,CAAC,CAAC;AAEpB;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAwC,EAAE,EAA0C;IACnH,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEpD,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1E,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,IAAI,gCAAgC,EAAE,4FAA4F,CAAC,CAAC,CAAC;gBACpL,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,IAAI,kBAAkB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,OAAO,IAAI,mCAAmC,EAAE,2CAA2C,CAAC,CAAC,CAAC;gBAChN,SAAS;YACX,CAAC;YACD,IAAI,IAAU,CAAC;YACf,IAAI,CAAC;gBACH,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,IAAI,CAAC,CAAC,CAAC,YAAY,eAAe,CAAC;oBAAE,MAAM,CAAC,CAAC;gBAC7C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,QAAQ,kBAAkB,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;gBACrF,SAAS;YACX,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;YAChC,KAAK,MAAM,EAAE,IAAI,KAAK,CAAC,gBAAgB;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,6CAA6C,EAAE,sDAAsD,CAAC,CAAC,CAAC;YACrM,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,SAAS;gBAC5F,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,GAAG,IAAI,qDAAqD,CAAC,GAAG,CAAC,CAAC,CAAC;YAChH,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;YAC1I,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM;gBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;QAC5I,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1H,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK;gBAAE,SAAS;YACrB,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,uDAAuD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,iDAAiD,CAAC,CAAC,CAAC;QAChM,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE;QACtD,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACjB,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CACrC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CACjJ,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACpB,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;gBACnB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,eAAe,IAAI,0HAA0H,EAAE,iHAAiH,CAAC,CAAC,CAAC;YAC1T,CAAC;iBAAM,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,eAAe,IAAI,kGAAkG,EAAE,gEAAgE,CAAC,CAAC,CAAC;YACnP,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mFAAmF;AACnF,SAAS,SAAS,CAAC,KAAa,EAAE,KAA6C;IAC7E,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,IAAI,GAAG,CAAC,IAAY,EAAwB,EAAE;QAClD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,SAAS,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiK,EAAE,IAAY,EAAE,OAA4B,IAAI,GAAG,EAAE;IACnP,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,IAAU,CAAC;IACf,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,KAAK,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtJ,MAAM,MAAM,GAAG,UAAW,CAAC,MAAM,CAAC;IAClC,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACzH,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,UAAU,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,95 @@
1
+ import type { GraviewApp, Principal, Store } from "../index.js";
2
+ import { type AppPlace } from "../places.js";
3
+ import type { AnySchema } from "../schema/schema.js";
4
+ export interface DescribePlaceOptions<S extends AnySchema> {
5
+ /** The app whose place this is: its home, lenses, views and arrangement. */
6
+ readonly app: GraviewApp<S>;
7
+ /** The viewport's width in CSS pixels; 390 is a phone. 1440 when unsaid. */
8
+ readonly width?: number;
9
+ /** The day it is, for dates said relatively; today when unsaid. */
10
+ readonly today?: string;
11
+ }
12
+ /** One record in a list, as its card or row says it. */
13
+ export interface DescribedItem {
14
+ readonly id: string;
15
+ readonly kind: string;
16
+ readonly title: string;
17
+ /** What its card or row says beyond its title, in order. */
18
+ readonly parts: readonly DescribedPart[];
19
+ }
20
+ export type DescribedPart = {
21
+ readonly t: "heading";
22
+ readonly level: number;
23
+ readonly text: string;
24
+ } | {
25
+ readonly t: "text";
26
+ readonly text: string;
27
+ readonly tone?: string;
28
+ } | {
29
+ readonly t: "badge";
30
+ readonly text: string;
31
+ } | {
32
+ readonly t: "field";
33
+ readonly label: string;
34
+ readonly text: string;
35
+ } | {
36
+ readonly t: "figure";
37
+ readonly text: string;
38
+ readonly label?: string;
39
+ } | {
40
+ readonly t: "progress";
41
+ readonly label: string;
42
+ readonly text: string;
43
+ } | {
44
+ readonly t: "list";
45
+ readonly as: "card" | "row" | "name";
46
+ /** The columns a card list makes at this width; a row list is one. */
47
+ readonly columns: number;
48
+ readonly groups: readonly {
49
+ readonly heading?: string;
50
+ readonly items: readonly DescribedItem[];
51
+ }[];
52
+ /** What it says when it lists nothing. */
53
+ readonly empty?: string;
54
+ readonly more?: number;
55
+ };
56
+ export interface DescribedProblem {
57
+ /** Where: the block's path in the declaration (`views.home.3`, `lenses.1.options.blocks.0`, `views.offer.card.5`), with the record it was about. */
58
+ readonly at: string;
59
+ readonly says: string;
60
+ }
61
+ export interface PlaceDescription {
62
+ readonly place: {
63
+ readonly slug: string;
64
+ readonly title: string;
65
+ readonly kind: string | null;
66
+ readonly address: string;
67
+ };
68
+ /** Who it was described for: the seat's roles, or "the system". */
69
+ readonly seat: string;
70
+ readonly width: number;
71
+ readonly variant: "phone" | "wide";
72
+ /** What draws it: the app's blocks, the framework's derived page, a shipped lens, a record's page, or a worker view run headless (FR-95). */
73
+ readonly drawnBy: "blocks" | "derived" | "record" | `lens:${string}` | `view:${string}`;
74
+ readonly parts: readonly DescribedPart[];
75
+ readonly problems: readonly DescribedProblem[];
76
+ /** The same, as plain text a chat can quote. */
77
+ readonly text: string;
78
+ }
79
+ export type DescribePlaceResult = {
80
+ readonly ok: true;
81
+ readonly description: PlaceDescription;
82
+ } | {
83
+ readonly ok: false;
84
+ readonly error: string;
85
+ readonly places: readonly string[];
86
+ };
87
+ /**
88
+ * Say what a place shows one seat. `place` is a `placesOf` entry or its
89
+ * slug ("home", "the-offers", "offers"), or a record's id. A place nobody
90
+ * declared is refused with the places there are.
91
+ */
92
+ export declare function describePlace<S extends AnySchema>(store: Store<S>, principal: Principal, place: string | AppPlace, options: DescribePlaceOptions<S>): DescribePlaceResult;
93
+ /** A description as plain text: a heading as `#`s, a list's records as bullets under their group's heading, indented by depth. */
94
+ export declare function placeText(description: Omit<PlaceDescription, "text">): string;
95
+ //# sourceMappingURL=describe-place.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-place.d.ts","sourceRoot":"","sources":["../../src/document/describe-place.ts"],"names":[],"mappings":"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"}