@graview/core 0.1.12 → 0.1.15

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 (176) hide show
  1. package/README.md +31 -2
  2. package/dist/address.d.ts +31 -0
  3. package/dist/address.d.ts.map +1 -0
  4. package/dist/address.js +53 -0
  5. package/dist/address.js.map +1 -0
  6. package/dist/app.d.ts +1 -1
  7. package/dist/app.d.ts.map +1 -1
  8. package/dist/arrange.d.ts +13 -183
  9. package/dist/arrange.d.ts.map +1 -1
  10. package/dist/arrange.js +12 -470
  11. package/dist/arrange.js.map +1 -1
  12. package/dist/arrangement.d.ts +169 -0
  13. package/dist/arrangement.d.ts.map +1 -0
  14. package/dist/arrangement.js +220 -0
  15. package/dist/arrangement.js.map +1 -0
  16. package/dist/arranging.d.ts +28 -0
  17. package/dist/arranging.d.ts.map +1 -0
  18. package/dist/arranging.js +264 -0
  19. package/dist/arranging.js.map +1 -0
  20. package/dist/capabilities.js +1 -1
  21. package/dist/capabilities.js.map +1 -1
  22. package/dist/cli/check/hidden-reads.d.ts.map +1 -1
  23. package/dist/cli/check/hidden-reads.js +32 -1
  24. package/dist/cli/check/hidden-reads.js.map +1 -1
  25. package/dist/cli/check/lenses.d.ts.map +1 -1
  26. package/dist/cli/check/lenses.js +29 -1
  27. package/dist/cli/check/lenses.js.map +1 -1
  28. package/dist/cli/describe.d.ts.map +1 -1
  29. package/dist/cli/describe.js +16 -6
  30. package/dist/cli/describe.js.map +1 -1
  31. package/dist/cli/docs.js +1 -1
  32. package/dist/cli/docs.js.map +1 -1
  33. package/dist/columns.d.ts +48 -16
  34. package/dist/columns.d.ts.map +1 -1
  35. package/dist/columns.js +65 -22
  36. package/dist/columns.js.map +1 -1
  37. package/dist/compiled.d.ts +19 -0
  38. package/dist/compiled.d.ts.map +1 -0
  39. package/dist/compiled.js +60 -0
  40. package/dist/compiled.js.map +1 -0
  41. package/dist/conformance/fixtures.d.ts.map +1 -1
  42. package/dist/conformance/fixtures.js +41 -1
  43. package/dist/conformance/fixtures.js.map +1 -1
  44. package/dist/describe.d.ts +2 -2
  45. package/dist/describe.d.ts.map +1 -1
  46. package/dist/describe.js +1 -1
  47. package/dist/describe.js.map +1 -1
  48. package/dist/document/act-findings.d.ts +5 -0
  49. package/dist/document/act-findings.d.ts.map +1 -0
  50. package/dist/document/act-findings.js +84 -0
  51. package/dist/document/act-findings.js.map +1 -0
  52. package/dist/document/blocks.d.ts.map +1 -1
  53. package/dist/document/blocks.js +2 -1
  54. package/dist/document/blocks.js.map +1 -1
  55. package/dist/document/compile-checked.d.ts.map +1 -1
  56. package/dist/document/compile-checked.js +11 -4
  57. package/dist/document/compile-checked.js.map +1 -1
  58. package/dist/document/compile.d.ts +7 -21
  59. package/dist/document/compile.d.ts.map +1 -1
  60. package/dist/document/compile.js +145 -371
  61. package/dist/document/compile.js.map +1 -1
  62. package/dist/document/compiled.d.ts +130 -0
  63. package/dist/document/compiled.d.ts.map +1 -0
  64. package/dist/document/compiled.js +466 -0
  65. package/dist/document/compiled.js.map +1 -0
  66. package/dist/document/describe-coverage.d.ts +37 -0
  67. package/dist/document/describe-coverage.d.ts.map +1 -0
  68. package/dist/document/describe-coverage.js +162 -0
  69. package/dist/document/describe-coverage.js.map +1 -0
  70. package/dist/document/describe-place.d.ts.map +1 -1
  71. package/dist/document/describe-place.js +14 -1
  72. package/dist/document/describe-place.js.map +1 -1
  73. package/dist/document/diff.d.ts +5 -0
  74. package/dist/document/diff.d.ts.map +1 -1
  75. package/dist/document/diff.js +12 -3
  76. package/dist/document/diff.js.map +1 -1
  77. package/dist/document/edit.d.ts +1 -1
  78. package/dist/document/edit.d.ts.map +1 -1
  79. package/dist/document/edit.js +64 -7
  80. package/dist/document/edit.js.map +1 -1
  81. package/dist/document/far-end.d.ts +15 -0
  82. package/dist/document/far-end.d.ts.map +1 -0
  83. package/dist/document/far-end.js +26 -0
  84. package/dist/document/far-end.js.map +1 -0
  85. package/dist/document/index.d.ts +5 -2
  86. package/dist/document/index.d.ts.map +1 -1
  87. package/dist/document/index.js +3 -1
  88. package/dist/document/index.js.map +1 -1
  89. package/dist/document/migrate.d.ts.map +1 -1
  90. package/dist/document/migrate.js +7 -5
  91. package/dist/document/migrate.js.map +1 -1
  92. package/dist/document/range.d.ts +17 -0
  93. package/dist/document/range.d.ts.map +1 -0
  94. package/dist/document/range.js +46 -0
  95. package/dist/document/range.js.map +1 -0
  96. package/dist/document/remembered.d.ts +6 -0
  97. package/dist/document/remembered.d.ts.map +1 -0
  98. package/dist/document/remembered.js +16 -0
  99. package/dist/document/remembered.js.map +1 -0
  100. package/dist/document/rules.d.ts.map +1 -1
  101. package/dist/document/rules.js +2 -1
  102. package/dist/document/rules.js.map +1 -1
  103. package/dist/document/schema.d.ts +23 -0
  104. package/dist/document/schema.d.ts.map +1 -1
  105. package/dist/document/schema.js +26 -2
  106. package/dist/document/schema.js.map +1 -1
  107. package/dist/document/template-parse.d.ts +18 -0
  108. package/dist/document/template-parse.d.ts.map +1 -0
  109. package/dist/document/template-parse.js +124 -0
  110. package/dist/document/template-parse.js.map +1 -0
  111. package/dist/document/template.d.ts +1 -17
  112. package/dist/document/template.d.ts.map +1 -1
  113. package/dist/document/template.js +6 -115
  114. package/dist/document/template.js.map +1 -1
  115. package/dist/document/thumbnail.d.ts +25 -1
  116. package/dist/document/thumbnail.d.ts.map +1 -1
  117. package/dist/document/thumbnail.js +167 -32
  118. package/dist/document/thumbnail.js.map +1 -1
  119. package/dist/document/to-document.d.ts +1 -4
  120. package/dist/document/to-document.d.ts.map +1 -1
  121. package/dist/document/to-document.js +18 -11
  122. package/dist/document/to-document.js.map +1 -1
  123. package/dist/document/views.d.ts.map +1 -1
  124. package/dist/document/views.js +1 -1
  125. package/dist/document/views.js.map +1 -1
  126. package/dist/index.d.ts +4 -3
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +4 -3
  129. package/dist/index.js.map +1 -1
  130. package/dist/mutations/define-mutation.d.ts +12 -0
  131. package/dist/mutations/define-mutation.d.ts.map +1 -1
  132. package/dist/mutations/define-mutation.js +38 -2
  133. package/dist/mutations/define-mutation.js.map +1 -1
  134. package/dist/mutations/derive-edits.d.ts +8 -0
  135. package/dist/mutations/derive-edits.d.ts.map +1 -1
  136. package/dist/mutations/derive-edits.js +30 -7
  137. package/dist/mutations/derive-edits.js.map +1 -1
  138. package/dist/mutations/form.d.ts +2 -0
  139. package/dist/mutations/form.d.ts.map +1 -1
  140. package/dist/mutations/form.js +1 -0
  141. package/dist/mutations/form.js.map +1 -1
  142. package/dist/mutations/node-ref.d.ts +4 -1
  143. package/dist/mutations/node-ref.d.ts.map +1 -1
  144. package/dist/mutations/node-ref.js +6 -0
  145. package/dist/mutations/node-ref.js.map +1 -1
  146. package/dist/mutations/types.d.ts +16 -0
  147. package/dist/mutations/types.d.ts.map +1 -1
  148. package/dist/places.js +1 -1
  149. package/dist/places.js.map +1 -1
  150. package/dist/refusal.d.ts +11 -6
  151. package/dist/refusal.d.ts.map +1 -1
  152. package/dist/refusal.js +15 -6
  153. package/dist/refusal.js.map +1 -1
  154. package/dist/refused.d.ts +27 -0
  155. package/dist/refused.d.ts.map +1 -0
  156. package/dist/refused.js +31 -0
  157. package/dist/refused.js.map +1 -0
  158. package/dist/scaffold/project.d.ts.map +1 -1
  159. package/dist/scaffold/project.js +4 -0
  160. package/dist/scaffold/project.js.map +1 -1
  161. package/dist/schema/json-schema.d.ts.map +1 -1
  162. package/dist/schema/json-schema.js +4 -1
  163. package/dist/schema/json-schema.js.map +1 -1
  164. package/dist/search.d.ts +1 -1
  165. package/dist/search.d.ts.map +1 -1
  166. package/dist/search.js +1 -1
  167. package/dist/search.js.map +1 -1
  168. package/dist/theme/derive.d.ts.map +1 -1
  169. package/dist/theme/derive.js +5 -4
  170. package/dist/theme/derive.js.map +1 -1
  171. package/dist/theme/types.d.ts.map +1 -1
  172. package/dist/theme/types.js +5 -0
  173. package/dist/theme/types.js.map +1 -1
  174. package/dist/version.d.ts +1 -1
  175. package/dist/version.js +1 -1
  176. package/package.json +9 -1
@@ -3,11 +3,13 @@ import { ExprSyntaxError, parseExpr } from "./expr/parse.js";
3
3
  import { printExpr } from "./expr/print.js";
4
4
  import { error } from "./findings.js";
5
5
  import { coerce } from "./migrate.js";
6
+ import { outsideRange, rangeWords } from "./range.js";
7
+ import { farEnd } from "./far-end.js";
6
8
  import { ActSpec, EDGE_NAME, EdgeSpec, FIELD_NAME, FIELD_TYPES, FieldSpec, KindSpec, NAME, RuleSpec, } from "./schema.js";
7
9
  import { SHIPPED_LENSES, isShippedLens, SHIPPED_LENS_NAMES } from "../places.js";
8
10
  import { placeSlug } from "../views/types.js";
9
11
  import { computedOf, validateComputed } from "./computed.js";
10
- import { parseTemplate, templateBraces, TemplateError } from "./template.js";
12
+ import { parseTemplate, templateBraces, TemplateError } from "./template-parse.js";
11
13
  import { validateViews, VIEW_SLOTS } from "./views.js";
12
14
  /** The ops, for tool schemas and the guide. */
13
15
  export const EDIT_OPS = [
@@ -18,6 +20,7 @@ export const EDIT_OPS = [
18
20
  "rename-field",
19
21
  "retype-field",
20
22
  "set-options",
23
+ "set-range",
21
24
  "set-required",
22
25
  "set-default",
23
26
  "remove-field",
@@ -56,6 +59,7 @@ const SHAPES = {
56
59
  "rename-field": z.object({ op: z.literal("rename-field"), kind: kindName, field: fieldName, to: fieldName }).strict(),
57
60
  "retype-field": z.object({ op: z.literal("retype-field"), kind: kindName, field: fieldName, type: z.enum(FIELD_TYPES), options: z.array(z.string().min(1).max(80)).min(1).max(100).optional(), of: z.enum(["string", "number", "date"]).optional(), format: z.enum(["money", "percent", "duration"]).optional() }).strict(),
58
61
  "set-options": z.object({ op: z.literal("set-options"), kind: kindName, field: fieldName, add: z.array(z.string().min(1).max(80)).optional(), remove: z.array(z.string().min(1).max(80)).optional() }).strict(),
62
+ "set-range": z.object({ op: z.literal("set-range"), kind: kindName, field: fieldName, min: z.union([z.number(), z.null()]).optional(), max: z.union([z.number(), z.null()]).optional(), step: z.union([z.number().positive(), z.null()]).optional() }).strict(),
59
63
  "set-required": z.object({ op: z.literal("set-required"), kind: kindName, field: fieldName, required: z.boolean() }).strict(),
60
64
  "set-default": z.object({ op: z.literal("set-default"), kind: kindName, field: fieldName, default: z.unknown() }).strict(),
61
65
  "remove-field": z.object({ op: z.literal("remove-field"), kind: kindName, field: fieldName }).strict(),
@@ -361,8 +365,8 @@ function proseSwap(from, to) {
361
365
  }
362
366
  // ── what an act touches ──────────────────────────────────────────────────────
363
367
  const subjectKinds = (act) => (act.on ? new Set(asArray(act.on)) : NONE);
364
- /** The kinds each `set` in an act writes to: its subject, a record it made, or (for a `$ref` target) any kind. */
365
- function setTargets(act) {
368
+ /** The kinds each `set` in an act writes to: its subject, a record it made, the other end of what it connects (FR-115), or (for a `$ref` target) any kind. */
369
+ function setTargets(act, doc) {
366
370
  const out = [];
367
371
  const made = new Map();
368
372
  if (act.creates)
@@ -373,6 +377,11 @@ function setTargets(act) {
373
377
  });
374
378
  if (act.sets)
375
379
  out.push({ set: act.sets, kinds: subjectKinds(act), where: "sets" });
380
+ if (act.setsOther) {
381
+ const relation = act.connects ?? act.severs;
382
+ const end = doc && relation ? farEnd(doc.kinds, relation, asArray(act.on)) : undefined;
383
+ out.push({ set: act.setsOther, kinds: end && end.kinds !== "*" ? new Set(end.kinds) : "*", where: "setsOther" });
384
+ }
376
385
  (act.effects ?? []).forEach((e, index) => {
377
386
  if (e.create)
378
387
  out.push({ set: e.set ?? {}, kinds: new Set([e.create]), where: "create", index });
@@ -469,6 +478,8 @@ class Editor {
469
478
  return this.retypeField(i, e);
470
479
  case "set-options":
471
480
  return this.setOptions(i, e);
481
+ case "set-range":
482
+ return this.setRange(i, e);
472
483
  case "set-required": {
473
484
  const f = this.field(i, e.kind, e.field);
474
485
  if (!f)
@@ -491,6 +502,9 @@ class Editor {
491
502
  else {
492
503
  if (f.type === "enum" && !(f.options ?? []).includes(e.default))
493
504
  return this.fail(i, "default", `"${String(e.default)}" is not one of ${e.field}'s options (${(f.options ?? []).join(", ")})`);
505
+ const outside = outsideRange(e.default, f, e.field);
506
+ if (outside)
507
+ return this.fail(i, "default", outside);
494
508
  f.default = e.default;
495
509
  this.said.push(`${e.kind}'s ${e.field} starts as ${JSON.stringify(e.default)} on new records.`);
496
510
  }
@@ -1220,12 +1234,43 @@ class Editor {
1220
1234
  f.format = e.format;
1221
1235
  else if (e.type !== "number" && e.type !== "integer")
1222
1236
  delete f.format;
1237
+ // A range is a number's (FR-114): a field that is no longer one lets it go.
1238
+ if (e.type !== "number" && e.type !== "integer")
1239
+ for (const key of ["min", "max", "step"])
1240
+ delete f[key];
1223
1241
  if (f.default !== undefined && coerce(f.default, was, f) === undefined)
1224
1242
  delete f.default;
1225
1243
  else if (f.default !== undefined)
1226
1244
  f.default = coerce(f.default, was, f);
1227
1245
  this.said.push(`${e.kind}'s ${e.field} changes from ${was} to ${e.type}; values that convert are kept.`);
1228
1246
  }
1247
+ /** A number's range (FR-114): a key given sets it, `null` clears it, one left out stays. */
1248
+ setRange(i, e) {
1249
+ const f = this.field(i, e.kind, e.field);
1250
+ if (!f)
1251
+ return;
1252
+ if (f.type !== "number" && f.type !== "integer")
1253
+ return this.fail(i, "field", `${e.field} is ${f.type === "integer" ? "an" : "a"} ${f.type}, not a number; a range belongs on a number or integer field`);
1254
+ const next = { ...f };
1255
+ for (const key of ["min", "max", "step"]) {
1256
+ if (e[key] === null)
1257
+ delete next[key];
1258
+ else if (e[key] !== undefined)
1259
+ next[key] = e[key];
1260
+ }
1261
+ if (next.min !== undefined && next.max !== undefined && next.min > next.max)
1262
+ return this.fail(i, "max", `the most (${next.max}) is below the least (${next.min})`);
1263
+ const outside = next.default !== undefined ? outsideRange(next.default, next, e.field) : undefined;
1264
+ if (outside)
1265
+ return this.fail(i, "default", `${e.field}'s default, ${outside.replace(/ is /, ", is ")}; change the default first`);
1266
+ for (const key of ["min", "max", "step"]) {
1267
+ if (next[key] === undefined)
1268
+ delete f[key];
1269
+ else
1270
+ f[key] = next[key];
1271
+ }
1272
+ this.said.push(`${e.kind}'s ${e.field} takes ${rangeWords(f)}.`);
1273
+ }
1229
1274
  setOptions(i, e) {
1230
1275
  const f = this.field(i, e.kind, e.field);
1231
1276
  if (!f)
@@ -1252,7 +1297,7 @@ class Editor {
1252
1297
  }
1253
1298
  // An act that sets a dropped option cannot stand.
1254
1299
  for (const [name, act] of Object.entries(this.doc.acts ?? {})) {
1255
- for (const t of setTargets(act))
1300
+ for (const t of setTargets(act, this.doc))
1256
1301
  if (hasKind(t.kinds, e.kind) && typeof t.set[e.field] === "string" && remove.includes(t.set[e.field])) {
1257
1302
  this.removeActQuietly(name);
1258
1303
  out.push(`the act ${name} (it set that option) is removed`);
@@ -1500,6 +1545,8 @@ class Editor {
1500
1545
  act.connects = r.to;
1501
1546
  if (act.severs === r.from)
1502
1547
  act.severs = r.to;
1548
+ if (Array.isArray(act.replaces))
1549
+ act.replaces = act.replaces.map((e) => (e === r.from ? r.to : e));
1503
1550
  for (const e of act.effects ?? []) {
1504
1551
  if (e.connect === r.from)
1505
1552
  e.connect = r.to;
@@ -1509,7 +1556,7 @@ class Editor {
1509
1556
  }
1510
1557
  if (r.t === "field") {
1511
1558
  const args = new Map();
1512
- for (const t of setTargets(act)) {
1559
+ for (const t of setTargets(act, doc)) {
1513
1560
  if (!hasKind(t.kinds, r.kind) || !(r.from in t.set))
1514
1561
  continue;
1515
1562
  if (t.kinds === "*" && Object.entries(doc.kinds).some(([k, s]) => k !== r.kind && s.fields[r.from]))
@@ -1521,6 +1568,8 @@ class Editor {
1521
1568
  args.set(r.from, r.to);
1522
1569
  if (t.where === "sets")
1523
1570
  act.sets = renamed;
1571
+ else if (t.where === "setsOther")
1572
+ act.setsOther = renamed;
1524
1573
  else
1525
1574
  act.effects[t.index].set = renamed;
1526
1575
  }
@@ -1549,7 +1598,7 @@ class Editor {
1549
1598
  act.allowedWhen = argRename?.has(r.from) && r.t === "field" && !hasKind(on, r.kind) ? rewriteBinding(guard, r.from, r.to) : guard;
1550
1599
  if (act.refusal !== undefined)
1551
1600
  act.refusal = tmplAt(act.refusal, on);
1552
- for (const t of setTargets(act))
1601
+ for (const t of setTargets(act, doc))
1553
1602
  for (const [k, v] of Object.entries(t.set))
1554
1603
  if (isObject(v) && typeof v["expr"] === "string")
1555
1604
  t.set[k] = { expr: exprAt(v["expr"], t.kinds === "*" ? on : t.kinds) };
@@ -1704,9 +1753,15 @@ class Editor {
1704
1753
  let uses = exprMentions(doc, act.allowedWhen, on, r) || templateMentions(doc, act.refusal, on, r);
1705
1754
  if (r.t === "edge")
1706
1755
  uses ||= act.connects === r.from || act.severs === r.from || (act.effects ?? []).some((e) => e.connect === r.from || e.sever === r.from);
1756
+ // A relation it only replaced goes from the list; one that replaced nothing else goes with it (FR-115).
1757
+ if (r.t === "edge" && !uses && Array.isArray(act.replaces) && act.replaces.includes(r.from)) {
1758
+ act.replaces = act.replaces.filter((e) => e !== r.from);
1759
+ if (act.replaces.length === 0)
1760
+ delete act.replaces;
1761
+ }
1707
1762
  if (r.t === "field" && !worked) {
1708
1763
  // An act that sets other things too loses only this field; one that did nothing else goes.
1709
- for (const t of setTargets(act)) {
1764
+ for (const t of setTargets(act, doc)) {
1710
1765
  if (!hasKind(t.kinds, r.kind) || t.kinds === "*")
1711
1766
  continue;
1712
1767
  if (r.from in t.set)
@@ -1726,6 +1781,8 @@ class Editor {
1726
1781
  delete act.args;
1727
1782
  if (act.sets && Object.keys(act.sets).length === 0)
1728
1783
  delete act.sets;
1784
+ if (act.setsOther && Object.keys(act.setsOther).length === 0)
1785
+ delete act.setsOther;
1729
1786
  const doesSomething = act.creates || act.writes || act.sets || act.connects || act.severs || act.removes || (act.effects ?? []).some((e) => e.create || e.connect || e.sever || e.remove || (e.set && Object.keys(e.set).length > 0));
1730
1787
  if (!doesSomething)
1731
1788
  uses = true;