@graview/core 0.1.0

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 (327) hide show
  1. package/LICENSE +96 -0
  2. package/README.md +35 -0
  3. package/dist/app.d.ts +294 -0
  4. package/dist/app.d.ts.map +1 -0
  5. package/dist/app.js +49 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/arrange.d.ts +185 -0
  8. package/dist/arrange.d.ts.map +1 -0
  9. package/dist/arrange.js +456 -0
  10. package/dist/arrange.js.map +1 -0
  11. package/dist/beginning.d.ts +65 -0
  12. package/dist/beginning.d.ts.map +1 -0
  13. package/dist/beginning.js +94 -0
  14. package/dist/beginning.js.map +1 -0
  15. package/dist/bind.d.ts +42 -0
  16. package/dist/bind.d.ts.map +1 -0
  17. package/dist/bind.js +26 -0
  18. package/dist/bind.js.map +1 -0
  19. package/dist/city.d.ts +93 -0
  20. package/dist/city.d.ts.map +1 -0
  21. package/dist/city.js +160 -0
  22. package/dist/city.js.map +1 -0
  23. package/dist/cli/check/arrangement.d.ts +13 -0
  24. package/dist/cli/check/arrangement.d.ts.map +1 -0
  25. package/dist/cli/check/arrangement.js +63 -0
  26. package/dist/cli/check/arrangement.js.map +1 -0
  27. package/dist/cli/check/beginnings.d.ts +16 -0
  28. package/dist/cli/check/beginnings.d.ts.map +1 -0
  29. package/dist/cli/check/beginnings.js +53 -0
  30. package/dist/cli/check/beginnings.js.map +1 -0
  31. package/dist/cli/check/brand.d.ts +17 -0
  32. package/dist/cli/check/brand.d.ts.map +1 -0
  33. package/dist/cli/check/brand.js +153 -0
  34. package/dist/cli/check/brand.js.map +1 -0
  35. package/dist/cli/check/city.d.ts +17 -0
  36. package/dist/cli/check/city.d.ts.map +1 -0
  37. package/dist/cli/check/city.js +58 -0
  38. package/dist/cli/check/city.js.map +1 -0
  39. package/dist/cli/check/context.d.ts +50 -0
  40. package/dist/cli/check/context.d.ts.map +1 -0
  41. package/dist/cli/check/context.js +37 -0
  42. package/dist/cli/check/context.js.map +1 -0
  43. package/dist/cli/check/fields.d.ts +16 -0
  44. package/dist/cli/check/fields.d.ts.map +1 -0
  45. package/dist/cli/check/fields.js +237 -0
  46. package/dist/cli/check/fields.js.map +1 -0
  47. package/dist/cli/check/index.d.ts +14 -0
  48. package/dist/cli/check/index.d.ts.map +1 -0
  49. package/dist/cli/check/index.js +14 -0
  50. package/dist/cli/check/index.js.map +1 -0
  51. package/dist/cli/check/intelligence.d.ts +17 -0
  52. package/dist/cli/check/intelligence.d.ts.map +1 -0
  53. package/dist/cli/check/intelligence.js +136 -0
  54. package/dist/cli/check/intelligence.js.map +1 -0
  55. package/dist/cli/check/lenses.d.ts +17 -0
  56. package/dist/cli/check/lenses.d.ts.map +1 -0
  57. package/dist/cli/check/lenses.js +239 -0
  58. package/dist/cli/check/lenses.js.map +1 -0
  59. package/dist/cli/check/migrations.d.ts +16 -0
  60. package/dist/cli/check/migrations.d.ts.map +1 -0
  61. package/dist/cli/check/migrations.js +43 -0
  62. package/dist/cli/check/migrations.js.map +1 -0
  63. package/dist/cli/check/modules.d.ts +16 -0
  64. package/dist/cli/check/modules.d.ts.map +1 -0
  65. package/dist/cli/check/modules.js +123 -0
  66. package/dist/cli/check/modules.js.map +1 -0
  67. package/dist/cli/check/policy.d.ts +16 -0
  68. package/dist/cli/check/policy.d.ts.map +1 -0
  69. package/dist/cli/check/policy.js +90 -0
  70. package/dist/cli/check/policy.js.map +1 -0
  71. package/dist/cli/check/relations.d.ts +29 -0
  72. package/dist/cli/check/relations.d.ts.map +1 -0
  73. package/dist/cli/check/relations.js +279 -0
  74. package/dist/cli/check/relations.js.map +1 -0
  75. package/dist/cli/check/routes.d.ts +16 -0
  76. package/dist/cli/check/routes.d.ts.map +1 -0
  77. package/dist/cli/check/routes.js +31 -0
  78. package/dist/cli/check/routes.js.map +1 -0
  79. package/dist/cli/check/settings.d.ts +16 -0
  80. package/dist/cli/check/settings.d.ts.map +1 -0
  81. package/dist/cli/check/settings.js +81 -0
  82. package/dist/cli/check/settings.js.map +1 -0
  83. package/dist/cli/check.d.ts +36 -0
  84. package/dist/cli/check.d.ts.map +1 -0
  85. package/dist/cli/check.js +76 -0
  86. package/dist/cli/check.js.map +1 -0
  87. package/dist/cli/create.d.ts +20 -0
  88. package/dist/cli/create.d.ts.map +1 -0
  89. package/dist/cli/create.js +251 -0
  90. package/dist/cli/create.js.map +1 -0
  91. package/dist/cli/describe.d.ts +35 -0
  92. package/dist/cli/describe.d.ts.map +1 -0
  93. package/dist/cli/describe.js +230 -0
  94. package/dist/cli/describe.js.map +1 -0
  95. package/dist/cli/docs.d.ts +11 -0
  96. package/dist/cli/docs.d.ts.map +1 -0
  97. package/dist/cli/docs.js +152 -0
  98. package/dist/cli/docs.js.map +1 -0
  99. package/dist/cli/index.d.ts +18 -0
  100. package/dist/cli/index.d.ts.map +1 -0
  101. package/dist/cli/index.js +281 -0
  102. package/dist/cli/index.js.map +1 -0
  103. package/dist/extend.d.ts +23 -0
  104. package/dist/extend.d.ts.map +1 -0
  105. package/dist/extend.js +53 -0
  106. package/dist/extend.js.map +1 -0
  107. package/dist/graph/diff.d.ts +31 -0
  108. package/dist/graph/diff.d.ts.map +1 -0
  109. package/dist/graph/diff.js +71 -0
  110. package/dist/graph/diff.js.map +1 -0
  111. package/dist/graph/graph.d.ts +69 -0
  112. package/dist/graph/graph.d.ts.map +1 -0
  113. package/dist/graph/graph.js +284 -0
  114. package/dist/graph/graph.js.map +1 -0
  115. package/dist/graph/primitives.d.ts +52 -0
  116. package/dist/graph/primitives.d.ts.map +1 -0
  117. package/dist/graph/primitives.js +62 -0
  118. package/dist/graph/primitives.js.map +1 -0
  119. package/dist/graph/tracked.d.ts +31 -0
  120. package/dist/graph/tracked.d.ts.map +1 -0
  121. package/dist/graph/tracked.js +69 -0
  122. package/dist/graph/tracked.js.map +1 -0
  123. package/dist/graph/types.d.ts +34 -0
  124. package/dist/graph/types.d.ts.map +1 -0
  125. package/dist/graph/types.js +0 -0
  126. package/dist/graph/types.js.map +1 -0
  127. package/dist/index.d.ts +100 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +90 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/installation.d.ts +112 -0
  132. package/dist/installation.d.ts.map +1 -0
  133. package/dist/installation.js +193 -0
  134. package/dist/installation.js.map +1 -0
  135. package/dist/intelligence-bridge.d.ts +73 -0
  136. package/dist/intelligence-bridge.d.ts.map +1 -0
  137. package/dist/intelligence-bridge.js +31 -0
  138. package/dist/intelligence-bridge.js.map +1 -0
  139. package/dist/invariants/engine.d.ts +36 -0
  140. package/dist/invariants/engine.d.ts.map +1 -0
  141. package/dist/invariants/engine.js +88 -0
  142. package/dist/invariants/engine.js.map +1 -0
  143. package/dist/invariants/types.d.ts +75 -0
  144. package/dist/invariants/types.d.ts.map +1 -0
  145. package/dist/invariants/types.js +2 -0
  146. package/dist/invariants/types.js.map +1 -0
  147. package/dist/modules.d.ts +75 -0
  148. package/dist/modules.d.ts.map +1 -0
  149. package/dist/modules.js +87 -0
  150. package/dist/modules.js.map +1 -0
  151. package/dist/mutations/decidable.d.ts +26 -0
  152. package/dist/mutations/decidable.d.ts.map +1 -0
  153. package/dist/mutations/decidable.js +39 -0
  154. package/dist/mutations/decidable.js.map +1 -0
  155. package/dist/mutations/define-mutation.d.ts +32 -0
  156. package/dist/mutations/define-mutation.d.ts.map +1 -0
  157. package/dist/mutations/define-mutation.js +181 -0
  158. package/dist/mutations/define-mutation.js.map +1 -0
  159. package/dist/mutations/derive-edits.d.ts +75 -0
  160. package/dist/mutations/derive-edits.d.ts.map +1 -0
  161. package/dist/mutations/derive-edits.js +240 -0
  162. package/dist/mutations/derive-edits.js.map +1 -0
  163. package/dist/mutations/form.d.ts +63 -0
  164. package/dist/mutations/form.d.ts.map +1 -0
  165. package/dist/mutations/form.js +113 -0
  166. package/dist/mutations/form.js.map +1 -0
  167. package/dist/mutations/node-ref.d.ts +83 -0
  168. package/dist/mutations/node-ref.d.ts.map +1 -0
  169. package/dist/mutations/node-ref.js +113 -0
  170. package/dist/mutations/node-ref.js.map +1 -0
  171. package/dist/mutations/types.d.ts +136 -0
  172. package/dist/mutations/types.d.ts.map +1 -0
  173. package/dist/mutations/types.js +2 -0
  174. package/dist/mutations/types.js.map +1 -0
  175. package/dist/ops/log.d.ts +35 -0
  176. package/dist/ops/log.d.ts.map +1 -0
  177. package/dist/ops/log.js +103 -0
  178. package/dist/ops/log.js.map +1 -0
  179. package/dist/ops/types.d.ts +52 -0
  180. package/dist/ops/types.d.ts.map +1 -0
  181. package/dist/ops/types.js +2 -0
  182. package/dist/ops/types.js.map +1 -0
  183. package/dist/ops/undo.d.ts +33 -0
  184. package/dist/ops/undo.d.ts.map +1 -0
  185. package/dist/ops/undo.js +65 -0
  186. package/dist/ops/undo.js.map +1 -0
  187. package/dist/permissions/policy.d.ts +68 -0
  188. package/dist/permissions/policy.d.ts.map +1 -0
  189. package/dist/permissions/policy.js +191 -0
  190. package/dist/permissions/policy.js.map +1 -0
  191. package/dist/permissions/types.d.ts +78 -0
  192. package/dist/permissions/types.d.ts.map +1 -0
  193. package/dist/permissions/types.js +17 -0
  194. package/dist/permissions/types.js.map +1 -0
  195. package/dist/persistence/memory.d.ts +6 -0
  196. package/dist/persistence/memory.d.ts.map +1 -0
  197. package/dist/persistence/memory.js +31 -0
  198. package/dist/persistence/memory.js.map +1 -0
  199. package/dist/persistence/sqlite.d.ts +59 -0
  200. package/dist/persistence/sqlite.d.ts.map +1 -0
  201. package/dist/persistence/sqlite.js +131 -0
  202. package/dist/persistence/sqlite.js.map +1 -0
  203. package/dist/persistence/types.d.ts +22 -0
  204. package/dist/persistence/types.d.ts.map +1 -0
  205. package/dist/persistence/types.js +2 -0
  206. package/dist/persistence/types.js.map +1 -0
  207. package/dist/presence.d.ts +38 -0
  208. package/dist/presence.d.ts.map +1 -0
  209. package/dist/presence.js +50 -0
  210. package/dist/presence.js.map +1 -0
  211. package/dist/scaffold/domain.d.ts +8 -0
  212. package/dist/scaffold/domain.d.ts.map +1 -0
  213. package/dist/scaffold/domain.js +331 -0
  214. package/dist/scaffold/domain.js.map +1 -0
  215. package/dist/scaffold/index.d.ts +66 -0
  216. package/dist/scaffold/index.d.ts.map +1 -0
  217. package/dist/scaffold/index.js +142 -0
  218. package/dist/scaffold/index.js.map +1 -0
  219. package/dist/scaffold/lens.d.ts +31 -0
  220. package/dist/scaffold/lens.d.ts.map +1 -0
  221. package/dist/scaffold/lens.js +176 -0
  222. package/dist/scaffold/lens.js.map +1 -0
  223. package/dist/scaffold/names.d.ts +44 -0
  224. package/dist/scaffold/names.d.ts.map +1 -0
  225. package/dist/scaffold/names.js +69 -0
  226. package/dist/scaffold/names.js.map +1 -0
  227. package/dist/scaffold/project.d.ts +41 -0
  228. package/dist/scaffold/project.d.ts.map +1 -0
  229. package/dist/scaffold/project.js +604 -0
  230. package/dist/scaffold/project.js.map +1 -0
  231. package/dist/scaffold/ui.d.ts +15 -0
  232. package/dist/scaffold/ui.d.ts.map +1 -0
  233. package/dist/scaffold/ui.js +536 -0
  234. package/dist/scaffold/ui.js.map +1 -0
  235. package/dist/schema/define-node.d.ts +132 -0
  236. package/dist/schema/define-node.d.ts.map +1 -0
  237. package/dist/schema/define-node.js +254 -0
  238. package/dist/schema/define-node.js.map +1 -0
  239. package/dist/schema/figures.d.ts +42 -0
  240. package/dist/schema/figures.d.ts.map +1 -0
  241. package/dist/schema/figures.js +220 -0
  242. package/dist/schema/figures.js.map +1 -0
  243. package/dist/schema/json-schema.d.ts +39 -0
  244. package/dist/schema/json-schema.d.ts.map +1 -0
  245. package/dist/schema/json-schema.js +74 -0
  246. package/dist/schema/json-schema.js.map +1 -0
  247. package/dist/schema/schema.d.ts +43 -0
  248. package/dist/schema/schema.d.ts.map +1 -0
  249. package/dist/schema/schema.js +102 -0
  250. package/dist/schema/schema.js.map +1 -0
  251. package/dist/schema/types.d.ts +201 -0
  252. package/dist/schema/types.d.ts.map +1 -0
  253. package/dist/schema/types.js +2 -0
  254. package/dist/schema/types.js.map +1 -0
  255. package/dist/search.d.ts +215 -0
  256. package/dist/search.d.ts.map +1 -0
  257. package/dist/search.js +449 -0
  258. package/dist/search.js.map +1 -0
  259. package/dist/settings.d.ts +30 -0
  260. package/dist/settings.d.ts.map +1 -0
  261. package/dist/settings.js +74 -0
  262. package/dist/settings.js.map +1 -0
  263. package/dist/store.d.ts +284 -0
  264. package/dist/store.d.ts.map +1 -0
  265. package/dist/store.js +660 -0
  266. package/dist/store.js.map +1 -0
  267. package/dist/studio-door.d.ts +187 -0
  268. package/dist/studio-door.d.ts.map +1 -0
  269. package/dist/studio-door.js +20 -0
  270. package/dist/studio-door.js.map +1 -0
  271. package/dist/sync/conflict.d.ts +37 -0
  272. package/dist/sync/conflict.d.ts.map +1 -0
  273. package/dist/sync/conflict.js +56 -0
  274. package/dist/sync/conflict.js.map +1 -0
  275. package/dist/sync/engine.d.ts +118 -0
  276. package/dist/sync/engine.d.ts.map +1 -0
  277. package/dist/sync/engine.js +341 -0
  278. package/dist/sync/engine.js.map +1 -0
  279. package/dist/sync/google-calendar.d.ts +54 -0
  280. package/dist/sync/google-calendar.d.ts.map +1 -0
  281. package/dist/sync/google-calendar.js +167 -0
  282. package/dist/sync/google-calendar.js.map +1 -0
  283. package/dist/sync/types.d.ts +125 -0
  284. package/dist/sync/types.d.ts.map +1 -0
  285. package/dist/sync/types.js +6 -0
  286. package/dist/sync/types.js.map +1 -0
  287. package/dist/temporal/effectivity.d.ts +75 -0
  288. package/dist/temporal/effectivity.d.ts.map +1 -0
  289. package/dist/temporal/effectivity.js +89 -0
  290. package/dist/temporal/effectivity.js.map +1 -0
  291. package/dist/testing.d.ts +63 -0
  292. package/dist/testing.d.ts.map +1 -0
  293. package/dist/testing.js +194 -0
  294. package/dist/testing.js.map +1 -0
  295. package/dist/theme/contrast.d.ts +47 -0
  296. package/dist/theme/contrast.d.ts.map +1 -0
  297. package/dist/theme/contrast.js +172 -0
  298. package/dist/theme/contrast.js.map +1 -0
  299. package/dist/theme/derive.d.ts +81 -0
  300. package/dist/theme/derive.d.ts.map +1 -0
  301. package/dist/theme/derive.js +171 -0
  302. package/dist/theme/derive.js.map +1 -0
  303. package/dist/theme/kit.d.ts +106 -0
  304. package/dist/theme/kit.d.ts.map +1 -0
  305. package/dist/theme/kit.js +84 -0
  306. package/dist/theme/kit.js.map +1 -0
  307. package/dist/theme/palettes.d.ts +32 -0
  308. package/dist/theme/palettes.d.ts.map +1 -0
  309. package/dist/theme/palettes.js +96 -0
  310. package/dist/theme/palettes.js.map +1 -0
  311. package/dist/theme/types.d.ts +131 -0
  312. package/dist/theme/types.d.ts.map +1 -0
  313. package/dist/theme/types.js +23 -0
  314. package/dist/theme/types.js.map +1 -0
  315. package/dist/views/types.d.ts +89 -0
  316. package/dist/views/types.d.ts.map +1 -0
  317. package/dist/views/types.js +88 -0
  318. package/dist/views/types.js.map +1 -0
  319. package/dist/watched.d.ts +33 -0
  320. package/dist/watched.d.ts.map +1 -0
  321. package/dist/watched.js +50 -0
  322. package/dist/watched.js.map +1 -0
  323. package/dist/who.d.ts +26 -0
  324. package/dist/who.d.ts.map +1 -0
  325. package/dist/who.js +20 -0
  326. package/dist/who.js.map +1 -0
  327. package/package.json +77 -0
@@ -0,0 +1,113 @@
1
+ import { describeArg, nodeRefKinds, unwrap } from "./node-ref.js";
2
+ const isOptional = (schema) => schema.safeParse?.(undefined).success ?? false;
3
+ const shapeOf = (schema) => unwrap(schema).shape;
4
+ /** The single literal value of a zod literal, or undefined. */
5
+ const literalValue = (schema) => {
6
+ const field = unwrap(schema);
7
+ if (field._def?.type !== "literal")
8
+ return undefined;
9
+ const values = field._def.values;
10
+ return values && values.length === 1 && typeof values[0] === "string" ? values[0] : undefined;
11
+ };
12
+ /** Describes one argument as a form control tree. */
13
+ export function formField(name, schema) {
14
+ const optional = isOptional(schema);
15
+ const field = unwrap(schema);
16
+ const type = field._def?.type;
17
+ const kinds = nodeRefKinds(schema);
18
+ if (kinds)
19
+ return { control: "node", name, optional, kinds };
20
+ if (type === "boolean")
21
+ return { control: "boolean", name, optional };
22
+ if (type === "object") {
23
+ const shape = field.shape ?? {};
24
+ return {
25
+ control: "group",
26
+ name,
27
+ optional,
28
+ fields: Object.entries(shape).map(([child, childSchema]) => formField(child, childSchema)),
29
+ };
30
+ }
31
+ if (type === "union") {
32
+ const options = field._def?.options ?? [];
33
+ /*
34
+ * A DISCRIMINATED union renders as one picker and then that option's
35
+ * fields — the household example's constraint spec is the canonical case. The tag is
36
+ * whichever literal field every option shares; without one, a union of
37
+ * scalars collapses to a choice when every arm is a literal, and
38
+ * anything else is opaque rather than guessed at.
39
+ */
40
+ const shapes = options.map((option) => shapeOf(option));
41
+ if (shapes.every((shape) => shape !== undefined)) {
42
+ const tag = Object.keys(shapes[0] ?? {}).find((key) => shapes.every((shape) => literalValue(shape?.[key]) !== undefined));
43
+ if (tag) {
44
+ return {
45
+ control: "variant",
46
+ name,
47
+ optional,
48
+ tag,
49
+ options: options.map((_, index) => ({
50
+ value: literalValue(shapes[index]?.[tag]) ?? "",
51
+ fields: Object.entries(shapes[index] ?? {})
52
+ .filter(([key]) => key !== tag)
53
+ .map(([child, childSchema]) => formField(child, childSchema)),
54
+ })),
55
+ };
56
+ }
57
+ }
58
+ const literals = options.map((option) => literalValue(option));
59
+ if (literals.every((value) => value !== undefined)) {
60
+ return { control: "choice", name, optional, options: literals };
61
+ }
62
+ return { control: "opaque", name, optional };
63
+ }
64
+ if (type === "array") {
65
+ const element = field._def?.element;
66
+ if (element !== undefined) {
67
+ return { control: "list", name, optional, item: formField(name, element) };
68
+ }
69
+ return { control: "opaque", name, optional };
70
+ }
71
+ const scalar = describeArg(schema);
72
+ if (scalar.type === "text")
73
+ return { control: "text", name, optional };
74
+ if (scalar.type === "date")
75
+ return { control: "date", name, optional, ...(scalar.time ? { time: true } : {}) };
76
+ if (scalar.type === "number") {
77
+ return {
78
+ control: "number",
79
+ name,
80
+ optional,
81
+ ...(scalar.min === undefined ? {} : { min: scalar.min }),
82
+ ...(scalar.max === undefined ? {} : { max: scalar.max }),
83
+ };
84
+ }
85
+ if (scalar.type === "choice")
86
+ return { control: "choice", name, optional, options: scalar.options };
87
+ return { control: "opaque", name, optional };
88
+ }
89
+ /** The whole form for a mutation input object, one field per argument. */
90
+ export function formFields(input) {
91
+ const shape = input.shape;
92
+ if (!shape)
93
+ return [];
94
+ return Object.entries(shape).map(([name, schema]) => formField(name, schema));
95
+ }
96
+ /** True when every control in the tree is renderable — nothing opaque. */
97
+ export function formComplete(fields) {
98
+ return fields.every((field) => {
99
+ switch (field.control) {
100
+ case "opaque":
101
+ return false;
102
+ case "group":
103
+ return formComplete(field.fields);
104
+ case "variant":
105
+ return field.options.every((option) => formComplete(option.fields));
106
+ case "list":
107
+ return formComplete([field.item]);
108
+ default:
109
+ return true;
110
+ }
111
+ });
112
+ }
113
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/mutations/form.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * A mutation argument that names a node. Declaring the acceptable kinds is
4
+ * what lets the affordance layer bind a selection to an argument without
5
+ * anyone writing per-selection code, and lets an agent tool schema say
6
+ * which ids are legal.
7
+ */
8
+ export declare function nodeRef<const K extends string>(kinds?: readonly K[] | "*"): z.ZodString;
9
+ /** The node kinds an argument accepts, or undefined if it is not a node ref. */
10
+ export declare function nodeRefKinds(schema: unknown): readonly string[] | undefined;
11
+ /** Reads the node-ref arguments off a mutation input object schema. */
12
+ export declare function nodeRefArgs(input: z.ZodType): {
13
+ name: string;
14
+ kinds: readonly string[];
15
+ optional: boolean;
16
+ }[];
17
+ /**
18
+ * What sort of answer an argument wants, read off its own declaration.
19
+ *
20
+ * The affordance layer could already say "this needs a `label`" and offer
21
+ * candidate ids for a node reference — but for a plain string or a date it
22
+ * offered a list of nothing, so half the actions in an interface were dead
23
+ * ends that looked live. The mutation's schema knows perfectly well that
24
+ * `label` is a non-empty string and `date` is `YYYY-MM-DD`; nothing had
25
+ * asked it.
26
+ */
27
+ export type ArgShape = {
28
+ readonly type: "text";
29
+ }
30
+ /**
31
+ * A DATE, AND WITH `time` A TIME OF DAY IN IT. A workshop's start is
32
+ * `YYYY-MM-DDTHH:MM`; read as a plain date it got a date picker, whose
33
+ * `YYYY-MM-DD` the act's own pattern refused — on every face, so the
34
+ * workshop could not be made and the talk could not be given its slot.
35
+ */
36
+ | {
37
+ readonly type: "date";
38
+ readonly time?: true;
39
+ } | {
40
+ readonly type: "number";
41
+ readonly min?: number;
42
+ readonly max?: number;
43
+ } | {
44
+ readonly type: "choice";
45
+ readonly options: readonly string[];
46
+ }
47
+ /**
48
+ * YES OR NO — an argument that takes a boolean.
49
+ *
50
+ * Undescribable until now, for the same reason a list was: an interface
51
+ * can only offer what it can ask for, so "Add a field" — whose `required`
52
+ * is a plain boolean — was derived NOWHERE. The studio's central act, in
53
+ * the studio, unreachable, because nothing could ask one question.
54
+ */
55
+ | {
56
+ readonly type: "boolean";
57
+ }
58
+ /**
59
+ * SEVERAL OF A THING — an argument that takes a list.
60
+ *
61
+ * "Invite somebody as coordinator and gardener" is one act with two roles
62
+ * in one argument, and without this shape it described itself as `unknown`:
63
+ * an interface can only offer what it can ask for, so the act was offered
64
+ * NOWHERE. Not hidden behind a refusal — simply never derived, in every
65
+ * installation the framework ships.
66
+ */
67
+ | {
68
+ readonly type: "several";
69
+ readonly of: ArgShape;
70
+ } | {
71
+ readonly type: "unknown";
72
+ };
73
+ /** Unwraps optional/default/nullable so a wrapped field still describes itself. */
74
+ export declare function unwrap(schema: unknown): unknown;
75
+ /**
76
+ * Zod 4 keeps the primitive type on `_def.type` and the refinements a UI
77
+ * actually needs — bounds, patterns — in `_zod.bag`. Reading them here, in
78
+ * one place, keeps every other layer free of zod internals.
79
+ */
80
+ export declare function describeArg(schema: unknown): ArgShape;
81
+ /** The declared shape of one named argument of a mutation input object. */
82
+ export declare function argShape(input: unknown, name: string): ArgShape;
83
+ //# sourceMappingURL=node-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-ref.d.ts","sourceRoot":"","sources":["../../src/mutations/node-ref.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAC5C,KAAK,GAAE,SAAS,CAAC,EAAE,GAAG,GAAS,GAC9B,CAAC,CAAC,SAAS,CAab;AAED,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAW3E;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CACzB,KAAK,EAAE,CAAC,CAAC,OAAO,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,EAAE,CAUjE;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAChB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AAC3B;;;;;GAKG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,GAC/C;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE;AAClE;;;;;;;GAOG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE;AAC9B;;;;;;;;GAQG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAEjC,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAG/C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,CAmDrD;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAI/D"}
@@ -0,0 +1,113 @@
1
+ import { z } from "zod";
2
+ const NODE_REFS = new WeakMap();
3
+ /**
4
+ * A mutation argument that names a node. Declaring the acceptable kinds is
5
+ * what lets the affordance layer bind a selection to an argument without
6
+ * anyone writing per-selection code, and lets an agent tool schema say
7
+ * which ids are legal.
8
+ */
9
+ export function nodeRef(kinds = "*") {
10
+ const schema = z.string().min(1);
11
+ const accepted = kinds === "*" ? ["*"] : kinds;
12
+ NODE_REFS.set(schema, accepted);
13
+ /*
14
+ * `.describe()` and `.meta()` CLONE the schema and share its def, so a
15
+ * described node reference — the natural thing to write, since the
16
+ * description is the question a decision provider is asked — used to
17
+ * come back as a plain string. The def is the stable identity.
18
+ */
19
+ const def = schema._def;
20
+ if (def)
21
+ NODE_REFS.set(def, accepted);
22
+ return schema;
23
+ }
24
+ /** The node kinds an argument accepts, or undefined if it is not a node ref. */
25
+ export function nodeRefKinds(schema) {
26
+ if (typeof schema !== "object" || schema === null)
27
+ return undefined;
28
+ const direct = NODE_REFS.get(schema);
29
+ if (direct)
30
+ return direct;
31
+ const def = schema._def;
32
+ const byDef = def ? NODE_REFS.get(def) : undefined;
33
+ if (byDef)
34
+ return byDef;
35
+ // Unwrap optional/default/nullable wrappers so `nodeRef([...]).optional()`
36
+ // keeps its meaning.
37
+ const inner = schema._def?.innerType;
38
+ return inner ? nodeRefKinds(inner) : undefined;
39
+ }
40
+ /** Reads the node-ref arguments off a mutation input object schema. */
41
+ export function nodeRefArgs(input) {
42
+ const shape = input.shape;
43
+ if (!shape)
44
+ return [];
45
+ const args = [];
46
+ for (const [name, field] of Object.entries(shape)) {
47
+ const kinds = nodeRefKinds(field);
48
+ if (!kinds)
49
+ continue;
50
+ args.push({ name, kinds, optional: field.safeParse(undefined).success });
51
+ }
52
+ return args;
53
+ }
54
+ /** Unwraps optional/default/nullable so a wrapped field still describes itself. */
55
+ export function unwrap(schema) {
56
+ const inner = schema._def?.innerType;
57
+ return inner === undefined ? schema : unwrap(inner);
58
+ }
59
+ /**
60
+ * Zod 4 keeps the primitive type on `_def.type` and the refinements a UI
61
+ * actually needs — bounds, patterns — in `_zod.bag`. Reading them here, in
62
+ * one place, keeps every other layer free of zod internals.
63
+ */
64
+ export function describeArg(schema) {
65
+ const field = unwrap(schema);
66
+ const type = field?._def?.type;
67
+ const bag = field?._zod?.bag ?? {};
68
+ if (type === "enum")
69
+ return { type: "choice", options: Object.keys(field?._def?.entries ?? {}) };
70
+ if (type === "boolean")
71
+ return { type: "boolean" };
72
+ /*
73
+ * A list describes itself through what it holds. An array of something
74
+ * nothing can describe is still unknown — saying "several unknowns" would
75
+ * make an unaskable argument look askable, which is the failure this whole
76
+ * shape exists to prevent.
77
+ */
78
+ if (type === "array") {
79
+ const of = describeArg(field._def?.element);
80
+ return of.type === "unknown" ? { type: "unknown" } : { type: "several", of };
81
+ }
82
+ if (type === "number") {
83
+ const min = typeof bag["minimum"] === "number" ? bag["minimum"] : undefined;
84
+ const max = typeof bag["maximum"] === "number" ? bag["maximum"] : undefined;
85
+ return {
86
+ type: "number",
87
+ ...(min === undefined ? {} : { min }),
88
+ ...(max === undefined ? {} : { max }),
89
+ };
90
+ }
91
+ if (type === "string") {
92
+ // A date is a string with a date-shaped pattern. Recognising it means
93
+ // the interface offers a date picker instead of a free text box, which
94
+ // is the difference between an action anyone can run and one only its
95
+ // author knows the format for.
96
+ const patterns = bag["patterns"];
97
+ const sources = patterns instanceof Set ? [...patterns].map((pattern) => String(pattern.source)) : [];
98
+ if (sources.some((source) => source.includes("\\d{4}"))) {
99
+ // A time of day in the pattern as well: `T\d{2}:\d{2}`, or a space before it.
100
+ return sources.some((source) => source.includes("\\d{2}:\\d{2}")) ? { type: "date", time: true } : { type: "date" };
101
+ }
102
+ return { type: "text" };
103
+ }
104
+ return { type: "unknown" };
105
+ }
106
+ /** The declared shape of one named argument of a mutation input object. */
107
+ export function argShape(input, name) {
108
+ const shape = input?.shape;
109
+ if (!shape || !(name in shape))
110
+ return { type: "unknown" };
111
+ return describeArg(shape[name]);
112
+ }
113
+ //# sourceMappingURL=node-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-ref.js","sourceRoot":"","sources":["../../src/mutations/node-ref.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,136 @@
1
+ import type { z } from "zod";
2
+ import type { Primitive } from "../graph/primitives.js";
3
+ import type { GraphEdge, GraphReader } from "../graph/types.js";
4
+ import type { AnySchema, KindOfSchema, NodeOfSchema } from "../schema/schema.js";
5
+ /**
6
+ * What a mutation is handed. Reads go through a tracked reader so the op log
7
+ * records causality; writes go out as primitives so every op has an inverse.
8
+ */
9
+ export interface MutationContext<S extends AnySchema> {
10
+ readonly graph: GraphReader<NodeOfSchema<S>>;
11
+ readonly schema: S;
12
+ addNode(node: NodeOfSchema<S>): void;
13
+ /** Removes a node together with every edge touching it. */
14
+ removeNode(id: string): void;
15
+ patchNode(id: string, fields: Record<string, unknown>): void;
16
+ addEdge(edge: GraphEdge): void;
17
+ removeEdge(edge: GraphEdge): void;
18
+ /** Replaces every `kind` edge arriving at `to` with one from `from`. */
19
+ setSingleSource(kind: string, to: string, from: string): void;
20
+ /** A deterministic, collision-free id derived from a label. */
21
+ freshId(label: string, prefix?: string): string;
22
+ /** Raw escape hatch — prefer the helpers above. */
23
+ emit(primitive: Primitive): void;
24
+ }
25
+ export interface MutationDefinitionSpec<S extends AnySchema, I extends z.ZodType> {
26
+ readonly input: I;
27
+ /** Short human title, e.g. "Reassign run". */
28
+ readonly title?: string;
29
+ readonly description?: string;
30
+ /**
31
+ * Node kinds this mutation acts on, and the argument the subject binds to.
32
+ * This is the seam that makes affordances derivable: given a selection of
33
+ * `duty` nodes, every mutation whose subject accepts `duty` is legal.
34
+ */
35
+ readonly subject?: {
36
+ readonly kinds: readonly KindOfSchema<S>[] | "*";
37
+ readonly arg: string;
38
+ };
39
+ /**
40
+ * True when applying this loses something a person made — a node removed,
41
+ * work dropped, an edge severed for good. The interface lists these after
42
+ * everything else and marks them; an agent seat inherits the same order.
43
+ * Absent means safe, which is the common case and the safe default to get
44
+ * wrong: an unmarked destructive mutation is merely unranked, a marked
45
+ * safe one is merely over-cautious.
46
+ */
47
+ readonly destructive?: boolean;
48
+ /**
49
+ * Node kinds this mutation brings into existence.
50
+ *
51
+ * The other half of the affordance seam. `subject` answers "what can I do
52
+ * WITH this thing"; `creates` answers the question an empty kind card
53
+ * poses — "how does the first one get here". Declared rather than
54
+ * inferred, because what `apply` adds is not statically knowable, and the
55
+ * empty state is exactly where a wrong guess would strand someone.
56
+ *
57
+ * An act that declares this also takes an optional `id` argument the
58
+ * framework adds: the id of the node it makes, when the caller has one —
59
+ * a seed being synced, an agent that will refer to the node in its next
60
+ * call. `freshId` hands it out first; an id already in the graph is
61
+ * refused by name rather than quietly suffixed.
62
+ */
63
+ readonly creates?: readonly KindOfSchema<S>[];
64
+ /**
65
+ * Edge kinds this mutation makes, and edge kinds it breaks.
66
+ *
67
+ * The seam that lets a LINE offer its own actions: select the drawn edge
68
+ * and every mutation that declares its kind derives an offer, endpoints
69
+ * prefilled by matching argument kinds. Declared, like `creates`, because
70
+ * what `apply` does to edges is not statically knowable.
71
+ */
72
+ readonly connects?: readonly string[];
73
+ readonly severs?: readonly string[];
74
+ /**
75
+ * How this act reads from the OTHER end of the tie.
76
+ *
77
+ * An act that declares what it connects or severs is offered from either
78
+ * endpoint — standing on a person, "take this one off the run" is the
79
+ * natural thing to say. The button there was labelled with `title`, which
80
+ * is written from the subject's side: "Hand it to someone", offered on the
81
+ * person, reads as handing the PERSON to someone.
82
+ *
83
+ * Declared rather than derived, for the reason `connects` is: an edge's
84
+ * `inverse` gives the relation's two readings but not the verb, and a
85
+ * guessed verb on a control that changes the graph is the wrong place to
86
+ * be nearly right. `graview check` warns `act-without-far-end-reading`
87
+ * when an act is offerable from an end it has no words for, naming that
88
+ * end — the same warning shape as `edge-without-inverse`.
89
+ */
90
+ readonly fromTheOtherEnd?: string;
91
+ /**
92
+ * Fields of the SUBJECT this mutation writes.
93
+ *
94
+ * The declared answer to "what changes this field", which the in-place
95
+ * edit and the derived edit act both read. Without it the framework
96
+ * guesses from names — an input argument called exactly like a field
97
+ * writes that field — which is right for `rename(label)` and blind to
98
+ * `finish()` setting `done`. Declared, the guess is replaced rather than
99
+ * added to: a mutation that says what it writes is believed about it, and
100
+ * only about it.
101
+ */
102
+ readonly writes?: readonly string[];
103
+ /**
104
+ * The app saying "this is the act of this product". A pinned mutation
105
+ * ranks above its unpinned peers wherever actions are offered — never
106
+ * above a rule's repairs, never out of the destructive tail — and sits
107
+ * in the menu's head section. A person's own pins, made from the menu,
108
+ * outrank the app's.
109
+ */
110
+ readonly pinned?: boolean;
111
+ /** One-line description of a concrete application, for previews and logs. */
112
+ readonly describe?: (args: z.infer<I>, graph: GraphReader<NodeOfSchema<S>>) => string;
113
+ readonly apply: (context: MutationContext<S>, args: z.infer<I>) => void;
114
+ }
115
+ export interface MutationDefinition<S extends AnySchema = AnySchema, Name extends string = string, I extends z.ZodType = z.ZodType> extends MutationDefinitionSpec<S, I> {
116
+ readonly name: Name;
117
+ /**
118
+ * Set by the framework on a mutation it derived rather than an app
119
+ * declared: the per-kind edit act, or the per-kind remove act. An edit's
120
+ * permission resolves through the declared acts that already write or
121
+ * create the kind; a remove's through the acts that create it — who may
122
+ * bring a thing into being may take it out — so a policy needs no second
123
+ * list for either.
124
+ */
125
+ readonly derived?: {
126
+ readonly kind: string;
127
+ readonly act: "edit" | "remove";
128
+ };
129
+ }
130
+ export type AnyMutationDefinition<S extends AnySchema = AnySchema> = MutationDefinition<S, string, z.ZodType>;
131
+ /** A concrete, ready-to-apply mutation: a name plus validated arguments. */
132
+ export interface MutationCall<Name extends string = string> {
133
+ readonly name: Name;
134
+ readonly args: Record<string, unknown>;
135
+ }
136
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mutations/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mutations/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { Graph } from "../graph/graph.js";
2
+ import type { AnySchema } from "../schema/schema.js";
3
+ import type { Batch, Operation } from "./types.js";
4
+ /**
5
+ * The append-only log. Nothing here mutates or removes an entry: an undo is
6
+ * a new op carrying the inverse, so history is never destroyed and the log
7
+ * doubles as an audit trail of what an agent did on your behalf.
8
+ */
9
+ export declare class OperationLog {
10
+ private readonly ops;
11
+ get length(): number;
12
+ all(): readonly Operation[];
13
+ append(op: Operation): void;
14
+ /** Restores a log from storage, checking the sequence is intact. */
15
+ static from(ops: readonly Operation[]): OperationLog;
16
+ get(id: string): Operation | undefined;
17
+ /** Ops that have not been inverted by a later op. */
18
+ live(): Operation[];
19
+ /**
20
+ * An op stands unless a LIVE op undoes it. That one sentence is the whole
21
+ * redo mechanism: undoing an undo makes the undo itself not live, which
22
+ * revives its target. Undoers always follow their target, so resolving
23
+ * from the end of the log backwards terminates in one pass.
24
+ */
25
+ undoneIds(): Set<string>;
26
+ opsInBatch(batchId: string): Operation[];
27
+ batches(): Batch[];
28
+ /** Rebuilds the graph from empty by folding every live op forward. */
29
+ fold<S extends AnySchema>(schema: S, options?: {
30
+ validate?: boolean;
31
+ }): Graph<S>;
32
+ /** Serializable form for a persistence adapter. */
33
+ toJSON(): Operation[];
34
+ }
35
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAmB;IAEvC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,GAAG,IAAI,SAAS,SAAS,EAAE;IAI3B,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI;IAS3B,oEAAoE;IACpE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,SAAS,EAAE,GAAG,YAAY;IAMpD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItC,qDAAqD;IACrD,IAAI,IAAI,SAAS,EAAE;IAKnB;;;;;OAKG;IACH,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC;IAqBxB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE;IAIxC,OAAO,IAAI,KAAK,EAAE;IA0BlB,sEAAsE;IACtE,IAAI,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IAQhF,mDAAmD;IACnD,MAAM,IAAI,SAAS,EAAE;CAGtB"}
@@ -0,0 +1,103 @@
1
+ import { Graph } from "../graph/graph.js";
2
+ /**
3
+ * The append-only log. Nothing here mutates or removes an entry: an undo is
4
+ * a new op carrying the inverse, so history is never destroyed and the log
5
+ * doubles as an audit trail of what an agent did on your behalf.
6
+ */
7
+ export class OperationLog {
8
+ ops = [];
9
+ get length() {
10
+ return this.ops.length;
11
+ }
12
+ all() {
13
+ return this.ops;
14
+ }
15
+ append(op) {
16
+ if (op.seq !== this.ops.length) {
17
+ throw new Error(`Op "${op.id}" has seq ${op.seq} but the log is ${this.ops.length} long`);
18
+ }
19
+ this.ops.push(op);
20
+ }
21
+ /** Restores a log from storage, checking the sequence is intact. */
22
+ static from(ops) {
23
+ const log = new OperationLog();
24
+ for (const op of ops)
25
+ log.append(op);
26
+ return log;
27
+ }
28
+ get(id) {
29
+ return this.ops.find((op) => op.id === id);
30
+ }
31
+ /** Ops that have not been inverted by a later op. */
32
+ live() {
33
+ const undone = this.undoneIds();
34
+ return this.ops.filter((op) => !undone.has(op.id));
35
+ }
36
+ /**
37
+ * An op stands unless a LIVE op undoes it. That one sentence is the whole
38
+ * redo mechanism: undoing an undo makes the undo itself not live, which
39
+ * revives its target. Undoers always follow their target, so resolving
40
+ * from the end of the log backwards terminates in one pass.
41
+ */
42
+ undoneIds() {
43
+ const undoers = new Map();
44
+ for (const op of this.ops) {
45
+ if (!op.undoes)
46
+ continue;
47
+ const list = undoers.get(op.undoes);
48
+ if (list)
49
+ list.push(op.id);
50
+ else
51
+ undoers.set(op.undoes, [op.id]);
52
+ }
53
+ const live = new Map();
54
+ for (let i = this.ops.length - 1; i >= 0; i--) {
55
+ const op = this.ops[i];
56
+ const mine = undoers.get(op.id) ?? [];
57
+ live.set(op.id, !mine.some((id) => live.get(id) === true));
58
+ }
59
+ return new Set(this.ops.filter((op) => live.get(op.id) === false).map((op) => op.id));
60
+ }
61
+ opsInBatch(batchId) {
62
+ return this.ops.filter((op) => op.batch === batchId);
63
+ }
64
+ batches() {
65
+ const undone = this.undoneIds();
66
+ const order = [];
67
+ const grouped = new Map();
68
+ for (const op of this.ops) {
69
+ const list = grouped.get(op.batch);
70
+ if (list)
71
+ list.push(op);
72
+ else {
73
+ grouped.set(op.batch, [op]);
74
+ order.push(op.batch);
75
+ }
76
+ }
77
+ return order.map((id) => {
78
+ const ops = grouped.get(id) ?? [];
79
+ const first = ops[0];
80
+ return {
81
+ id,
82
+ author: first.author,
83
+ intent: first.intent,
84
+ at: first.at,
85
+ ops,
86
+ undone: ops.every((op) => undone.has(op.id)),
87
+ };
88
+ });
89
+ }
90
+ /** Rebuilds the graph from empty by folding every live op forward. */
91
+ fold(schema, options) {
92
+ const graph = new Graph(schema, options);
93
+ for (const op of this.ops) {
94
+ graph.applyPrimitives(op.primitives);
95
+ }
96
+ return graph;
97
+ }
98
+ /** Serializable form for a persistence adapter. */
99
+ toJSON() {
100
+ return [...this.ops];
101
+ }
102
+ }
103
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/ops/log.ts"],"names":[],"mappings":"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"}