@graview/core 0.1.10 → 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 (148) hide show
  1. package/README.md +19 -8
  2. package/dist/blocks.d.ts +5 -0
  3. package/dist/blocks.d.ts.map +1 -0
  4. package/dist/blocks.js +14 -0
  5. package/dist/blocks.js.map +1 -0
  6. package/dist/capabilities.js +1 -1
  7. package/dist/capabilities.js.map +1 -1
  8. package/dist/check.d.ts +8 -0
  9. package/dist/check.d.ts.map +1 -0
  10. package/dist/check.js +19 -0
  11. package/dist/check.js.map +1 -0
  12. package/dist/cli/check/brand.d.ts.map +1 -1
  13. package/dist/cli/check/brand.js +21 -0
  14. package/dist/cli/check/brand.js.map +1 -1
  15. package/dist/cli/check/hidden-reads.d.ts +4 -0
  16. package/dist/cli/check/hidden-reads.d.ts.map +1 -0
  17. package/dist/cli/check/hidden-reads.js +152 -0
  18. package/dist/cli/check/hidden-reads.js.map +1 -0
  19. package/dist/cli/check/index.d.ts +1 -0
  20. package/dist/cli/check/index.d.ts.map +1 -1
  21. package/dist/cli/check/index.js +1 -0
  22. package/dist/cli/check/index.js.map +1 -1
  23. package/dist/cli/check/views.d.ts.map +1 -1
  24. package/dist/cli/check/views.js +5 -1
  25. package/dist/cli/check/views.js.map +1 -1
  26. package/dist/cli/check.d.ts.map +1 -1
  27. package/dist/cli/check.js +2 -1
  28. package/dist/cli/check.js.map +1 -1
  29. package/dist/cli/create.d.ts.map +1 -1
  30. package/dist/cli/create.js +1 -1
  31. package/dist/cli/create.js.map +1 -1
  32. package/dist/cli/describe.d.ts.map +1 -1
  33. package/dist/cli/describe.js +12 -0
  34. package/dist/cli/describe.js.map +1 -1
  35. package/dist/cli/index.d.ts +1 -1
  36. package/dist/cli/index.d.ts.map +1 -1
  37. package/dist/cli/index.js +2 -1
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/columns.d.ts +73 -0
  40. package/dist/columns.d.ts.map +1 -0
  41. package/dist/columns.js +100 -0
  42. package/dist/columns.js.map +1 -0
  43. package/dist/conformance/index.js +1 -1
  44. package/dist/conformance/index.js.map +1 -1
  45. package/dist/describe.d.ts +2 -0
  46. package/dist/describe.d.ts.map +1 -1
  47. package/dist/describe.js +7 -0
  48. package/dist/describe.js.map +1 -1
  49. package/dist/document/blocks.d.ts +11 -6
  50. package/dist/document/blocks.d.ts.map +1 -1
  51. package/dist/document/blocks.js +21 -31
  52. package/dist/document/blocks.js.map +1 -1
  53. package/dist/document/compile-checked.d.ts +8 -0
  54. package/dist/document/compile-checked.d.ts.map +1 -0
  55. package/dist/document/compile-checked.js +36 -0
  56. package/dist/document/compile-checked.js.map +1 -0
  57. package/dist/document/compile.d.ts +8 -6
  58. package/dist/document/compile.d.ts.map +1 -1
  59. package/dist/document/compile.js +14 -34
  60. package/dist/document/compile.js.map +1 -1
  61. package/dist/document/describe-place.d.ts.map +1 -1
  62. package/dist/document/describe-place.js +30 -1
  63. package/dist/document/describe-place.js.map +1 -1
  64. package/dist/document/diff.d.ts.map +1 -1
  65. package/dist/document/diff.js +6 -1
  66. package/dist/document/diff.js.map +1 -1
  67. package/dist/document/edit.d.ts.map +1 -1
  68. package/dist/document/edit.js +92 -4
  69. package/dist/document/edit.js.map +1 -1
  70. package/dist/document/expr/analyze.d.ts.map +1 -1
  71. package/dist/document/expr/analyze.js +2 -1
  72. package/dist/document/expr/analyze.js.map +1 -1
  73. package/dist/document/expr/evaluate.d.ts.map +1 -1
  74. package/dist/document/expr/evaluate.js +26 -2
  75. package/dist/document/expr/evaluate.js.map +1 -1
  76. package/dist/document/expr/parse.d.ts +2 -1
  77. package/dist/document/expr/parse.d.ts.map +1 -1
  78. package/dist/document/expr/parse.js +6 -3
  79. package/dist/document/expr/parse.js.map +1 -1
  80. package/dist/document/expr/print.d.ts.map +1 -1
  81. package/dist/document/expr/print.js +4 -2
  82. package/dist/document/expr/print.js.map +1 -1
  83. package/dist/document/graview-template.d.ts +20 -12
  84. package/dist/document/graview-template.d.ts.map +1 -1
  85. package/dist/document/graview-template.js +5 -44
  86. package/dist/document/graview-template.js.map +1 -1
  87. package/dist/document/index.d.ts +4 -10
  88. package/dist/document/index.d.ts.map +1 -1
  89. package/dist/document/index.js +3 -6
  90. package/dist/document/index.js.map +1 -1
  91. package/dist/document/instantiate-template.d.ts +14 -0
  92. package/dist/document/instantiate-template.d.ts.map +1 -0
  93. package/dist/document/instantiate-template.js +46 -0
  94. package/dist/document/instantiate-template.js.map +1 -0
  95. package/dist/document/schema.d.ts +11 -2
  96. package/dist/document/schema.d.ts.map +1 -1
  97. package/dist/document/schema.js +9 -1
  98. package/dist/document/schema.js.map +1 -1
  99. package/dist/document/template.d.ts +18 -2
  100. package/dist/document/template.d.ts.map +1 -1
  101. package/dist/document/template.js +27 -9
  102. package/dist/document/template.js.map +1 -1
  103. package/dist/document/thumbnail.d.ts +5 -4
  104. package/dist/document/thumbnail.d.ts.map +1 -1
  105. package/dist/document/thumbnail.js +29 -21
  106. package/dist/document/thumbnail.js.map +1 -1
  107. package/dist/document/to-document.d.ts.map +1 -1
  108. package/dist/document/to-document.js +2 -0
  109. package/dist/document/to-document.js.map +1 -1
  110. package/dist/document/views.d.ts +11 -0
  111. package/dist/document/views.d.ts.map +1 -1
  112. package/dist/document/views.js +76 -12
  113. package/dist/document/views.js.map +1 -1
  114. package/dist/figures.d.ts +3 -0
  115. package/dist/figures.d.ts.map +1 -0
  116. package/dist/figures.js +14 -0
  117. package/dist/figures.js.map +1 -0
  118. package/dist/index.d.ts +0 -11
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +0 -7
  121. package/dist/index.js.map +1 -1
  122. package/dist/mutations/types.d.ts +12 -0
  123. package/dist/mutations/types.d.ts.map +1 -1
  124. package/dist/places.d.ts +11 -0
  125. package/dist/places.d.ts.map +1 -1
  126. package/dist/places.js +18 -0
  127. package/dist/places.js.map +1 -1
  128. package/dist/scaffold/domain.js +1 -1
  129. package/dist/scaffold/from-template.d.ts.map +1 -1
  130. package/dist/scaffold/from-template.js +3 -3
  131. package/dist/scaffold/from-template.js.map +1 -1
  132. package/dist/scaffold/project.d.ts.map +1 -1
  133. package/dist/scaffold/project.js +4 -0
  134. package/dist/scaffold/project.js.map +1 -1
  135. package/dist/scene-districts.d.ts +5 -1
  136. package/dist/scene-districts.d.ts.map +1 -1
  137. package/dist/scene-districts.js +11 -4
  138. package/dist/scene-districts.js.map +1 -1
  139. package/dist/scene.d.ts +7 -0
  140. package/dist/scene.d.ts.map +1 -0
  141. package/dist/scene.js +16 -0
  142. package/dist/scene.js.map +1 -0
  143. package/dist/theme/types.d.ts +9 -0
  144. package/dist/theme/types.d.ts.map +1 -1
  145. package/dist/theme/types.js.map +1 -1
  146. package/dist/version.d.ts +1 -1
  147. package/dist/version.js +1 -1
  148. package/package.json +17 -1
@@ -66,7 +66,15 @@ const SHAPES = {
66
66
  "remove-act": z.object({ op: z.literal("remove-act"), act: actName }).strict(),
67
67
  "add-rule": z.object({ op: z.literal("add-rule"), rule: actName, replace: z.boolean().optional() }).passthrough(),
68
68
  "remove-rule": z.object({ op: z.literal("remove-rule"), rule: actName }).strict(),
69
- "set-brand": z.object({ op: z.literal("set-brand"), accent: z.union([z.string(), z.null()]), name: z.string().min(1).max(60).optional() }).strict(),
69
+ "set-brand": z
70
+ .object({
71
+ op: z.literal("set-brand"),
72
+ accent: z.union([z.string(), z.null()]).optional(),
73
+ name: z.string().min(1).max(60).optional(),
74
+ currency: z.union([z.string(), z.null()]).optional(),
75
+ locale: z.union([z.string(), z.null()]).optional(),
76
+ })
77
+ .strict(),
70
78
  "set-label": z.object({ op: z.literal("set-label"), kind: kindName, field: fieldName.optional(), label: z.union([z.string().min(1).max(300), z.null()]) }).strict(),
71
79
  "set-describe": z.object({ op: z.literal("set-describe"), kind: kindName, describe: z.union([z.string().min(1).max(300), z.null()]) }).strict(),
72
80
  // A kind's slot; the front page (`slot: "home"`, no kind); or a blocks lens's blocks, by its title (FR-84).
@@ -148,6 +156,12 @@ function kindsOf(doc, e, ctx) {
148
156
  return kindsOf(doc, e.set, ctx);
149
157
  case "call": {
150
158
  const lit = e.args[0]?.t === "lit" && typeof e.args[0].value === "string" ? e.args[0].value : undefined;
159
+ // A walk from every member of a set (FR-101): its relation is its second word.
160
+ const walked = e.args.length === 2 && e.args[1]?.t === "lit" && typeof e.args[1].value === "string" ? e.args[1].value : undefined;
161
+ if (e.fn === "out" && walked)
162
+ return targets(doc, kindsOf(doc, e.args[0], ctx), walked);
163
+ if (e.fn === "in" && walked)
164
+ return sources(doc, walked);
151
165
  if (e.fn === "out" && lit)
152
166
  return targets(doc, "*", lit);
153
167
  if (e.fn === "in" && lit)
@@ -212,6 +226,12 @@ function mapNames(doc, e, ctx, rename) {
212
226
  const name = rename({ role: x.fn === "all" ? "kind" : "edge", kinds: NONE, name: literal });
213
227
  args = name === literal ? [...x.args] : [{ ...first, value: name }];
214
228
  }
229
+ else if ((x.fn === "out" || x.fn === "in") && x.args.length === 2 && x.args[1].t === "lit" && typeof x.args[1].value === "string") {
230
+ // out(S, 'edge'): the set is read where the walk stands, and its relation renamed like any walk's (FR-101).
231
+ const relation = x.args[1];
232
+ const name = rename({ role: "edge", kinds: NONE, name: relation.value });
233
+ args = [go(first, at), name === relation.value ? relation : { ...relation, value: name }];
234
+ }
215
235
  else if (((x.fn === "every" || x.fn === "some") && x.args.length === 2) || (x.fn === "sort" && x.args.length >= 2)) {
216
236
  // Read once per member, with the member as its subject: its names are the members'.
217
237
  args = [go(x.args[0], at), go(x.args[1], kindsOf(doc, x.args[0], at)), ...x.args.slice(2).map((a) => go(a, at))];
@@ -499,16 +519,45 @@ class Editor {
499
519
  return;
500
520
  }
501
521
  case "set-brand": {
522
+ // The colours and the money (FR-100) are set apart: what an edit does not name stays as it was.
523
+ const brand = { ...(this.doc.brand ?? {}) };
502
524
  if (e.accent === null) {
503
- delete this.doc.brand;
525
+ delete brand["accent"];
504
526
  this.said.push("The app goes back to Graview's colours.");
505
527
  }
506
- else {
528
+ else if (e.accent !== undefined) {
507
529
  if (!/^#[0-9a-fA-F]{6}$/.test(e.accent))
508
530
  return this.fail(i, "accent", 'an accent is a colour like "#c2577a"');
509
- this.doc.brand = { accent: e.accent, ...(e.name ? { name: e.name } : this.doc.brand?.name ? { name: this.doc.brand.name } : {}) };
531
+ brand["accent"] = e.accent;
510
532
  this.said.push(`The app's accent colour becomes ${e.accent}.`);
511
533
  }
534
+ if (e.currency === null) {
535
+ delete brand["currency"];
536
+ this.said.push("Money is said with no currency.");
537
+ }
538
+ else if (e.currency !== undefined) {
539
+ if (!/^[A-Z]{3}$/.test(e.currency))
540
+ return this.fail(i, "currency", 'a currency is its three-letter code, like "USD" or "EUR"');
541
+ brand["currency"] = e.currency;
542
+ this.said.push(`Money is said in ${e.currency}.`);
543
+ }
544
+ if (e.locale === null)
545
+ delete brand["locale"];
546
+ else if (e.locale !== undefined) {
547
+ if (!/^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/.test(e.locale))
548
+ return this.fail(i, "locale", 'a locale is a language tag, like "en-US" or "de-DE"');
549
+ brand["locale"] = e.locale;
550
+ this.said.push(`Money is written for ${e.locale}.`);
551
+ }
552
+ if (e.name) {
553
+ brand["name"] = e.name;
554
+ this.said.push(`The app's wordmark says ${e.name}.`);
555
+ }
556
+ // A brand that holds only a name holds nothing to apply.
557
+ if (Object.keys(brand).every((key) => key === "name"))
558
+ delete this.doc.brand;
559
+ else
560
+ this.doc.brand = brand;
512
561
  return;
513
562
  }
514
563
  case "set-label": {
@@ -699,6 +748,8 @@ class Editor {
699
748
  if (!Array.isArray(e.options?.blocks) || e.options.blocks.length === 0)
700
749
  return this.fail(i, "options.blocks", 'a lens drawn from blocks has blocks: "options": {"blocks": [{"headline": "…"}, {"list": "all(\'<kind>\')", "as": "card"}]}');
701
750
  }
751
+ if (name === "columns" && !this.columnsHold(i, e.bindings))
752
+ return;
702
753
  if (was)
703
754
  lenses[at] = lens;
704
755
  else
@@ -721,6 +772,35 @@ class Editor {
721
772
  }
722
773
  this.said.push(retitled ? `The lens "${String(was["title"])}" is now "${e.title}"${where}${follows}.` : `The lens "${e.title}" changes${where}.`);
723
774
  }
775
+ /**
776
+ * A STATUS BOARD'S BINDINGS (FR-97), held before it is added: each kind it
777
+ * binds is a kind, and its `column` is a field of that kind whose values
778
+ * are choices — the columns. Refused at the binding's path otherwise, so a
779
+ * chat is told which word to change rather than shown an empty board.
780
+ */
781
+ columnsHold(i, bindings) {
782
+ const example = '"bindings": {"<kind>": {"column": "<a choice field, like status>"}}';
783
+ if (!isObject(bindings) || Object.keys(bindings).length === 0)
784
+ return (this.fail(i, "bindings", "a board binds a kind's choice field to its columns", example), false);
785
+ for (const [kind, roles] of Object.entries(bindings)) {
786
+ if (!isObject(this.doc.kinds[kind]))
787
+ return (this.fail(i, `bindings.${kind}`, `"${kind}" is not a kind this app has; it has ${Object.keys(this.doc.kinds).join(", ")}`), false);
788
+ const field = isObject(roles) ? roles["column"] : undefined;
789
+ const fields = this.doc.kinds[kind].fields;
790
+ if (typeof field !== "string")
791
+ return (this.fail(i, `bindings.${kind}.column`, `the board does not say which field of ${kind} its columns are`, example), false);
792
+ if (!(field in fields))
793
+ return (this.fail(i, `bindings.${kind}.column`, `${kind} has no field "${field}"; it has ${Object.keys(fields).join(", ")}`), false);
794
+ if (fields[field]["type"] !== "enum") {
795
+ const choices = Object.keys(fields).filter((one) => fields[one]["type"] === "enum");
796
+ return (this.fail(i, `bindings.${kind}.column`, `${kind}'s ${field} is not a choice, so it has no columns`, choices.length > 0 ? `bind one of ${choices.join(", ")}` : `give ${kind} a choice field first: add-field with "type": "enum" and its "options", in the order the columns go`), false);
797
+ }
798
+ const others = Object.keys(roles).filter((role) => role !== "column");
799
+ if (others.length > 0)
800
+ return (this.fail(i, `bindings.${kind}.${others[0]}`, `a board binds only "column"`), false);
801
+ }
802
+ return true;
803
+ }
724
804
  removeLens(i, e) {
725
805
  const index = this.lensIndex(i, e.title, e.on);
726
806
  if (index < 0)
@@ -2064,6 +2144,9 @@ function rewriteBlock(doc, b, ctx, r, kind) {
2064
2144
  next[key] = rewriteTemplate(doc, next[key], ctx, r);
2065
2145
  if (typeof next["figure"] === "string")
2066
2146
  next["figure"] = rewriteExpr(doc, next["figure"], ctx, r);
2147
+ // A figure's and a meter's label is a template (FR-99); a field's is words.
2148
+ if ((typeof next["figure"] === "string" || "progress" in next) && typeof next["label"] === "string")
2149
+ next["label"] = rewriteTemplate(doc, next["label"], ctx, r);
2067
2150
  if (typeof next["list"] === "string") {
2068
2151
  const members = listMembers(doc, next["list"], ctx);
2069
2152
  next["list"] = rewriteExpr(doc, next["list"], ctx, r);
@@ -2111,6 +2194,11 @@ function pruneBlock(doc, b, ctx, r, kind) {
2111
2194
  for (const k of ["value", "max"])
2112
2195
  if (exprMentions(doc, b["progress"][k], ctx, r))
2113
2196
  return null;
2197
+ // A label that says what is gone goes; the figure or meter stays (FR-99).
2198
+ if ((typeof b["figure"] === "string" || "progress" in b) && typeof b["label"] === "string" && templateMentions(doc, b["label"], ctx, r)) {
2199
+ const { label: _gone, ...kept } = b;
2200
+ return kept;
2201
+ }
2114
2202
  if (typeof b["list"] === "string") {
2115
2203
  if (exprMentions(doc, b["list"], ctx, r))
2116
2204
  return null;