@graview/core 0.1.0 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/README.md +7 -0
  2. package/dist/app.d.ts +17 -0
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js.map +1 -1
  5. package/dist/arrange.d.ts +3 -2
  6. package/dist/arrange.d.ts.map +1 -1
  7. package/dist/arrange.js +19 -2
  8. package/dist/arrange.js.map +1 -1
  9. package/dist/beginning.d.ts +5 -2
  10. package/dist/beginning.d.ts.map +1 -1
  11. package/dist/beginning.js +28 -0
  12. package/dist/beginning.js.map +1 -1
  13. package/dist/capabilities.d.ts +32 -0
  14. package/dist/capabilities.d.ts.map +1 -0
  15. package/dist/capabilities.js +31 -0
  16. package/dist/capabilities.js.map +1 -0
  17. package/dist/cli/check/index.d.ts +1 -0
  18. package/dist/cli/check/index.d.ts.map +1 -1
  19. package/dist/cli/check/index.js +1 -0
  20. package/dist/cli/check/index.js.map +1 -1
  21. package/dist/cli/check/lenses.d.ts.map +1 -1
  22. package/dist/cli/check/lenses.js +25 -0
  23. package/dist/cli/check/lenses.js.map +1 -1
  24. package/dist/cli/check/policy.d.ts.map +1 -1
  25. package/dist/cli/check/policy.js +35 -0
  26. package/dist/cli/check/policy.js.map +1 -1
  27. package/dist/cli/check/relations.d.ts.map +1 -1
  28. package/dist/cli/check/relations.js +31 -0
  29. package/dist/cli/check/relations.js.map +1 -1
  30. package/dist/cli/check/views.d.ts +14 -0
  31. package/dist/cli/check/views.d.ts.map +1 -0
  32. package/dist/cli/check/views.js +27 -0
  33. package/dist/cli/check/views.js.map +1 -0
  34. package/dist/cli/check.d.ts.map +1 -1
  35. package/dist/cli/check.js +2 -1
  36. package/dist/cli/check.js.map +1 -1
  37. package/dist/cli/create.d.ts +1 -1
  38. package/dist/cli/create.d.ts.map +1 -1
  39. package/dist/cli/create.js +63 -1
  40. package/dist/cli/create.js.map +1 -1
  41. package/dist/cli/index.d.ts +18 -1
  42. package/dist/cli/index.d.ts.map +1 -1
  43. package/dist/cli/index.js +66 -1
  44. package/dist/cli/index.js.map +1 -1
  45. package/dist/conformance/fixtures.d.ts +41 -0
  46. package/dist/conformance/fixtures.d.ts.map +1 -0
  47. package/dist/conformance/fixtures.js +950 -0
  48. package/dist/conformance/fixtures.js.map +1 -0
  49. package/dist/conformance/index.d.ts +54 -0
  50. package/dist/conformance/index.d.ts.map +1 -0
  51. package/dist/conformance/index.js +81 -0
  52. package/dist/conformance/index.js.map +1 -0
  53. package/dist/document/canonical.d.ts +4 -0
  54. package/dist/document/canonical.d.ts.map +1 -0
  55. package/dist/document/canonical.js +29 -0
  56. package/dist/document/canonical.js.map +1 -0
  57. package/dist/document/compile.d.ts +43 -0
  58. package/dist/document/compile.d.ts.map +1 -0
  59. package/dist/document/compile.js +807 -0
  60. package/dist/document/compile.js.map +1 -0
  61. package/dist/document/diff.d.ts +32 -0
  62. package/dist/document/diff.d.ts.map +1 -0
  63. package/dist/document/diff.js +148 -0
  64. package/dist/document/diff.js.map +1 -0
  65. package/dist/document/edit.d.ts +63 -0
  66. package/dist/document/edit.d.ts.map +1 -0
  67. package/dist/document/edit.js +1432 -0
  68. package/dist/document/edit.js.map +1 -0
  69. package/dist/document/expr/analyze.d.ts +14 -0
  70. package/dist/document/expr/analyze.d.ts.map +1 -0
  71. package/dist/document/expr/analyze.js +52 -0
  72. package/dist/document/expr/analyze.js.map +1 -0
  73. package/dist/document/expr/evaluate.d.ts +36 -0
  74. package/dist/document/expr/evaluate.d.ts.map +1 -0
  75. package/dist/document/expr/evaluate.js +344 -0
  76. package/dist/document/expr/evaluate.js.map +1 -0
  77. package/dist/document/expr/index.d.ts +8 -0
  78. package/dist/document/expr/index.d.ts.map +1 -0
  79. package/dist/document/expr/index.js +5 -0
  80. package/dist/document/expr/index.js.map +1 -0
  81. package/dist/document/expr/parse.d.ts +50 -0
  82. package/dist/document/expr/parse.d.ts.map +1 -0
  83. package/dist/document/expr/parse.js +240 -0
  84. package/dist/document/expr/parse.js.map +1 -0
  85. package/dist/document/expr/print.d.ts +4 -0
  86. package/dist/document/expr/print.d.ts.map +1 -0
  87. package/dist/document/expr/print.js +81 -0
  88. package/dist/document/expr/print.js.map +1 -0
  89. package/dist/document/findings.d.ts +15 -0
  90. package/dist/document/findings.d.ts.map +1 -0
  91. package/dist/document/findings.js +30 -0
  92. package/dist/document/findings.js.map +1 -0
  93. package/dist/document/graview-template.d.ts +148 -0
  94. package/dist/document/graview-template.d.ts.map +1 -0
  95. package/dist/document/graview-template.js +450 -0
  96. package/dist/document/graview-template.js.map +1 -0
  97. package/dist/document/index.d.ts +27 -0
  98. package/dist/document/index.d.ts.map +1 -0
  99. package/dist/document/index.js +16 -0
  100. package/dist/document/index.js.map +1 -0
  101. package/dist/document/migrate.d.ts +41 -0
  102. package/dist/document/migrate.d.ts.map +1 -0
  103. package/dist/document/migrate.js +252 -0
  104. package/dist/document/migrate.js.map +1 -0
  105. package/dist/document/patch.d.ts +16 -0
  106. package/dist/document/patch.d.ts.map +1 -0
  107. package/dist/document/patch.js +79 -0
  108. package/dist/document/patch.js.map +1 -0
  109. package/dist/document/rules.d.ts +40 -0
  110. package/dist/document/rules.d.ts.map +1 -0
  111. package/dist/document/rules.js +88 -0
  112. package/dist/document/rules.js.map +1 -0
  113. package/dist/document/schema.d.ts +461 -0
  114. package/dist/document/schema.d.ts.map +1 -0
  115. package/dist/document/schema.js +199 -0
  116. package/dist/document/schema.js.map +1 -0
  117. package/dist/document/template.d.ts +28 -0
  118. package/dist/document/template.d.ts.map +1 -0
  119. package/dist/document/template.js +117 -0
  120. package/dist/document/template.js.map +1 -0
  121. package/dist/document/to-document.d.ts +34 -0
  122. package/dist/document/to-document.d.ts.map +1 -0
  123. package/dist/document/to-document.js +186 -0
  124. package/dist/document/to-document.js.map +1 -0
  125. package/dist/document/upgrade.d.ts +9 -0
  126. package/dist/document/upgrade.d.ts.map +1 -0
  127. package/dist/document/upgrade.js +19 -0
  128. package/dist/document/upgrade.js.map +1 -0
  129. package/dist/document/views.d.ts +65 -0
  130. package/dist/document/views.d.ts.map +1 -0
  131. package/dist/document/views.js +264 -0
  132. package/dist/document/views.js.map +1 -0
  133. package/dist/formats.d.ts +50 -0
  134. package/dist/formats.d.ts.map +1 -0
  135. package/dist/formats.js +75 -0
  136. package/dist/formats.js.map +1 -0
  137. package/dist/graph/graph.d.ts +61 -3
  138. package/dist/graph/graph.d.ts.map +1 -1
  139. package/dist/graph/graph.js +187 -20
  140. package/dist/graph/graph.js.map +1 -1
  141. package/dist/index.d.ts +43 -18
  142. package/dist/index.d.ts.map +1 -1
  143. package/dist/index.js +31 -11
  144. package/dist/index.js.map +1 -1
  145. package/dist/integrity.d.ts +46 -0
  146. package/dist/integrity.d.ts.map +1 -0
  147. package/dist/integrity.js +179 -0
  148. package/dist/integrity.js.map +1 -0
  149. package/dist/invariants/engine.d.ts +8 -0
  150. package/dist/invariants/engine.d.ts.map +1 -1
  151. package/dist/invariants/engine.js +40 -2
  152. package/dist/invariants/engine.js.map +1 -1
  153. package/dist/invariants/types.d.ts +19 -0
  154. package/dist/invariants/types.d.ts.map +1 -1
  155. package/dist/labels.d.ts +65 -0
  156. package/dist/labels.d.ts.map +1 -0
  157. package/dist/labels.js +123 -0
  158. package/dist/labels.js.map +1 -0
  159. package/dist/mutations/define-mutation.d.ts.map +1 -1
  160. package/dist/mutations/define-mutation.js +5 -6
  161. package/dist/mutations/define-mutation.js.map +1 -1
  162. package/dist/mutations/derive-edits.d.ts.map +1 -1
  163. package/dist/mutations/derive-edits.js +20 -1
  164. package/dist/mutations/derive-edits.js.map +1 -1
  165. package/dist/mutations/form.d.ts +9 -0
  166. package/dist/mutations/form.d.ts.map +1 -1
  167. package/dist/mutations/form.js +20 -0
  168. package/dist/mutations/form.js.map +1 -1
  169. package/dist/mutations/node-ref.d.ts +6 -0
  170. package/dist/mutations/node-ref.d.ts.map +1 -1
  171. package/dist/mutations/node-ref.js +22 -8
  172. package/dist/mutations/node-ref.js.map +1 -1
  173. package/dist/mutations/types.d.ts +8 -0
  174. package/dist/mutations/types.d.ts.map +1 -1
  175. package/dist/mutations/words.d.ts +49 -0
  176. package/dist/mutations/words.d.ts.map +1 -0
  177. package/dist/mutations/words.js +61 -0
  178. package/dist/mutations/words.js.map +1 -0
  179. package/dist/ops/log.d.ts +156 -4
  180. package/dist/ops/log.d.ts.map +1 -1
  181. package/dist/ops/log.js +234 -51
  182. package/dist/ops/log.js.map +1 -1
  183. package/dist/ops/revisions.d.ts +66 -0
  184. package/dist/ops/revisions.d.ts.map +1 -0
  185. package/dist/ops/revisions.js +97 -0
  186. package/dist/ops/revisions.js.map +1 -0
  187. package/dist/ops/types.d.ts +49 -1
  188. package/dist/ops/types.d.ts.map +1 -1
  189. package/dist/ops/undo.d.ts +29 -2
  190. package/dist/ops/undo.d.ts.map +1 -1
  191. package/dist/ops/undo.js +110 -1
  192. package/dist/ops/undo.js.map +1 -1
  193. package/dist/ops/withheld.d.ts +37 -0
  194. package/dist/ops/withheld.d.ts.map +1 -0
  195. package/dist/ops/withheld.js +84 -0
  196. package/dist/ops/withheld.js.map +1 -0
  197. package/dist/permissions/policy.d.ts +15 -0
  198. package/dist/permissions/policy.d.ts.map +1 -1
  199. package/dist/permissions/policy.js +28 -1
  200. package/dist/permissions/policy.js.map +1 -1
  201. package/dist/permissions/sight.d.ts +66 -0
  202. package/dist/permissions/sight.d.ts.map +1 -0
  203. package/dist/permissions/sight.js +131 -0
  204. package/dist/permissions/sight.js.map +1 -0
  205. package/dist/permissions/types.d.ts +26 -0
  206. package/dist/permissions/types.d.ts.map +1 -1
  207. package/dist/permissions/types.js.map +1 -1
  208. package/dist/persistence/memory.d.ts.map +1 -1
  209. package/dist/persistence/memory.js +25 -0
  210. package/dist/persistence/memory.js.map +1 -1
  211. package/dist/persistence/sql.d.ts +43 -0
  212. package/dist/persistence/sql.d.ts.map +1 -0
  213. package/dist/persistence/sql.js +154 -0
  214. package/dist/persistence/sql.js.map +1 -0
  215. package/dist/persistence/sqlite.d.ts +17 -3
  216. package/dist/persistence/sqlite.d.ts.map +1 -1
  217. package/dist/persistence/sqlite.js +32 -96
  218. package/dist/persistence/sqlite.js.map +1 -1
  219. package/dist/persistence/types.d.ts +19 -0
  220. package/dist/persistence/types.d.ts.map +1 -1
  221. package/dist/presence.d.ts +56 -0
  222. package/dist/presence.d.ts.map +1 -1
  223. package/dist/presence.js +62 -2
  224. package/dist/presence.js.map +1 -1
  225. package/dist/refusal.d.ts +34 -0
  226. package/dist/refusal.d.ts.map +1 -0
  227. package/dist/refusal.js +40 -0
  228. package/dist/refusal.js.map +1 -0
  229. package/dist/scaffold/from-template.d.ts +16 -0
  230. package/dist/scaffold/from-template.d.ts.map +1 -0
  231. package/dist/scaffold/from-template.js +157 -0
  232. package/dist/scaffold/from-template.js.map +1 -0
  233. package/dist/scaffold/index.d.ts +10 -1
  234. package/dist/scaffold/index.d.ts.map +1 -1
  235. package/dist/scaffold/index.js +35 -7
  236. package/dist/scaffold/index.js.map +1 -1
  237. package/dist/scaffold/names.d.ts +4 -0
  238. package/dist/scaffold/names.d.ts.map +1 -1
  239. package/dist/scaffold/names.js.map +1 -1
  240. package/dist/scaffold/project.d.ts +1 -1
  241. package/dist/scaffold/project.d.ts.map +1 -1
  242. package/dist/scaffold/project.js +44 -13
  243. package/dist/scaffold/project.js.map +1 -1
  244. package/dist/scaffold/ui.d.ts.map +1 -1
  245. package/dist/scaffold/ui.js +19 -10
  246. package/dist/scaffold/ui.js.map +1 -1
  247. package/dist/schema/define-node.d.ts +20 -0
  248. package/dist/schema/define-node.d.ts.map +1 -1
  249. package/dist/schema/define-node.js +27 -2
  250. package/dist/schema/define-node.js.map +1 -1
  251. package/dist/schema/path.d.ts +19 -0
  252. package/dist/schema/path.d.ts.map +1 -0
  253. package/dist/schema/path.js +34 -0
  254. package/dist/schema/path.js.map +1 -0
  255. package/dist/schema/types.d.ts +17 -0
  256. package/dist/schema/types.d.ts.map +1 -1
  257. package/dist/seen.d.ts +64 -0
  258. package/dist/seen.d.ts.map +1 -0
  259. package/dist/seen.js +200 -0
  260. package/dist/seen.js.map +1 -0
  261. package/dist/store.d.ts +378 -8
  262. package/dist/store.d.ts.map +1 -1
  263. package/dist/store.js +801 -41
  264. package/dist/store.js.map +1 -1
  265. package/dist/testing.d.ts +6 -0
  266. package/dist/testing.d.ts.map +1 -1
  267. package/dist/testing.js +3 -1
  268. package/dist/testing.js.map +1 -1
  269. package/dist/theme/palettes.d.ts.map +1 -1
  270. package/dist/theme/palettes.js +4 -0
  271. package/dist/theme/palettes.js.map +1 -1
  272. package/dist/theme/types.d.ts +9 -0
  273. package/dist/theme/types.d.ts.map +1 -1
  274. package/dist/theme/types.js +4 -0
  275. package/dist/theme/types.js.map +1 -1
  276. package/dist/validate-graph.d.ts +84 -0
  277. package/dist/validate-graph.d.ts.map +1 -0
  278. package/dist/validate-graph.js +295 -0
  279. package/dist/validate-graph.js.map +1 -0
  280. package/dist/version.d.ts +3 -0
  281. package/dist/version.d.ts.map +1 -0
  282. package/dist/version.js +3 -0
  283. package/dist/version.js.map +1 -0
  284. package/dist/views/types.d.ts +8 -0
  285. package/dist/views/types.d.ts.map +1 -1
  286. package/dist/views/types.js +5 -0
  287. package/dist/views/types.js.map +1 -1
  288. package/dist/watched.d.ts +39 -0
  289. package/dist/watched.d.ts.map +1 -1
  290. package/dist/watched.js +94 -1
  291. package/dist/watched.js.map +1 -1
  292. package/dist/who.d.ts +24 -1
  293. package/dist/who.d.ts.map +1 -1
  294. package/dist/who.js +49 -2
  295. package/dist/who.js.map +1 -1
  296. package/package.json +9 -1
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/permissions/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAS,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAWpE;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAQD;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM;AACb;;;;;GAKG;AACH,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE;AACvB;;;GAGG;AACH,SAAS,CAAC,EAAE,MAAM;AAClB,qFAAqF;AACrF,KAAK,GAAE,WAAgB,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA8D3E;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAUzF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,MAAM,EAAE,CAcnB;AAED,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAQzD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,SAAS,EACpD,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,EAAE,GAC7C,SAAS,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAUrC"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/permissions/policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAS,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAKpE;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,CAMxD;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,WAAW,SAAS,KAAG,OAA4E,CAAC;AAQ7H;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAQD;;;;;;GAMG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM;AACb;;;;;GAKG;AACH,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE;AACvB;;;GAGG;AACH,SAAS,CAAC,EAAE,MAAM;AAClB,qFAAqF;AACrF,KAAK,GAAE,WAAgB,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAgE3E;AAwBD;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAUzF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,MAAM,EAAE,CAcnB;AAED,yEAAyE;AACzE,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAQzD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,SAAS,EACpD,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,EAAE,GAC7C,SAAS,qBAAqB,CAAC,CAAC,CAAC,EAAE,CAYrC"}
@@ -1,5 +1,27 @@
1
1
  import { humaniseField, withArticle } from "../schema/define-node.js";
2
2
  const matches = (allowed, value) => allowed === "*" || allowed.includes(value);
3
+ /**
4
+ * THE SEAT A POLICY JUDGES, delegation read through (FR-06). An agent acting
5
+ * for a person may do what BOTH may: its roles are the intersection of its
6
+ * own and theirs (an agent that declared none takes the person's), and a
7
+ * `self` grant — "you, on yours" — is about the person, not the agent. A
8
+ * principal acting for nobody is judged as itself.
9
+ */
10
+ export function actingAs(principal) {
11
+ const person = principal.onBehalfOf;
12
+ if (!person)
13
+ return principal;
14
+ const theirs = person.roles ?? [];
15
+ const roles = principal.roles === undefined ? theirs : principal.roles.filter((role) => theirs.includes(role));
16
+ return { ...principal, ...(person.id !== undefined ? { id: person.id } : {}), roles };
17
+ }
18
+ /**
19
+ * THE HOST'S OWN WORK HAS A SEAT (FR-17). A template's setup, a seed, a
20
+ * migration applied by the system is not a person a policy was written
21
+ * about, and `roles: ["*"]` matched no grant — so a host gave its system
22
+ * every role the policy named. `system` is a kind, not a role: it passes.
23
+ */
24
+ export const isSystem = (principal) => principal.kind === "system" && principal.onBehalfOf === undefined;
3
25
  /** Whether a grant covers a principal at all, before looking at the call. */
4
26
  function grantsTo(grant, principal) {
5
27
  if (grant.roles === "*")
@@ -36,6 +58,9 @@ words = {}) {
36
58
  // No policy means permission is not a concern in this installation.
37
59
  if (!policy)
38
60
  return { ok: true };
61
+ if (isSystem(principal))
62
+ return { ok: true };
63
+ principal = actingAs(principal);
39
64
  /*
40
65
  * A derived act is permitted when the policy names it (or says `*`) —
41
66
  * the grants are read first, as for any act — and otherwise when any of
@@ -185,7 +210,9 @@ export function permittedMutations(policy, principal, mutations) {
185
210
  const kinds = subject && subject.kinds !== "*" ? subject.kinds : [undefined];
186
211
  // Permitted for ANY of its subject kinds is enough to offer the tool; the
187
212
  // store still refuses the individual call that is not allowed.
188
- return kinds.some((kind) => permits(policy, principal, mutation.name, kind).ok);
213
+ // A `self` grant is offered with the principal as its subject: "ask, on
214
+ // yours" is an act the principal has, though only ever on themselves.
215
+ return kinds.some((kind) => permits(policy, principal, mutation.name, kind, undefined, actingAs(principal).id).ok);
189
216
  });
190
217
  }
191
218
  //# sourceMappingURL=policy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/permissions/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/permissions/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import type { Operation } from "../ops/types.js";
2
+ import type { Policy, Principal } from "./types.js";
3
+ /** The edges a graph can be asked about, to say what is joined to whom. */
4
+ interface Joined {
5
+ out(id: string): readonly {
6
+ readonly id: string;
7
+ }[];
8
+ in(id: string): readonly {
9
+ readonly id: string;
10
+ }[];
11
+ }
12
+ /** The kinds a policy keeps to those its sights name. */
13
+ export declare function sightedKinds(policy: Policy | undefined): ReadonlySet<string>;
14
+ /**
15
+ * WHAT THE LOG KNOWS ABOUT A RECORD that the graph may no longer: its kind
16
+ * (a record since removed is still judged as what it was) and who made it.
17
+ */
18
+ export interface Records {
19
+ kindOf(id: string): string | undefined;
20
+ /** The id of the seat that first added it — the person, for an agent acting for one. */
21
+ creatorOf(id: string): string | undefined;
22
+ }
23
+ /** A log as `recordsOf` reads it: its ops, and, for an `OperationLog`, the seq it has reached (FR-23). */
24
+ export interface RecordedLog {
25
+ all(): readonly Operation[];
26
+ /** The seq the next op takes, counting what a compaction archived; without it, the ops it holds. */
27
+ readonly length?: number;
28
+ }
29
+ /**
30
+ * The records a log names, read from its add- and remove-node primitives.
31
+ * The first op that added a record made it: putting one back by an undo is
32
+ * not a new author.
33
+ *
34
+ * KEPT AS THE LOG GOES (FR-51), as the label index follows the graph: a
35
+ * call reads only the ops appended since the last one, so a commit costs
36
+ * its own ops, not the log's. A log cut back (`truncate`, under a rebase)
37
+ * is noticed by its ops no longer being the ones read, and what they wrote
38
+ * is taken out, back to where the log and the index still agree. A log
39
+ * compacted behind its horizon (FR-23) keeps what the index had already
40
+ * read of the archived ops, so a record made behind the horizon is still
41
+ * known by its maker for as long as this log is open; a log OPENED
42
+ * compacted never read them, and knows its makers from the horizon on.
43
+ * The `Records` returned is the same object every time, and answers as of
44
+ * the last call.
45
+ */
46
+ export declare function recordsOf(log: RecordedLog): Records;
47
+ /**
48
+ * Whether a principal may see one record.
49
+ *
50
+ * ONE MEANING, the document's and the framework's alike (FR-02). With no
51
+ * `sees`, everybody sees everything. Once a policy says who sees what, it
52
+ * says it for every kind: a kind no sight names is seen by nobody but the
53
+ * system — the host's own seat — which is how a store fails closed when a
54
+ * kind is added and nobody said who sees it. A kind a sight names is seen
55
+ * by the roles it lists, and with `own` only the principal's own records:
56
+ * their record itself, what an edge joins to it ("a shopper sees their own
57
+ * test drives" without a field naming the owner), and what they made.
58
+ */
59
+ export declare function sees(policy: Policy | undefined, principal: Principal, node: {
60
+ readonly id: string;
61
+ readonly kind: string;
62
+ }, graph: Joined,
63
+ /** Who made a record, from the log; without it, `own` reads the graph alone. */
64
+ records?: Pick<Records, "creatorOf">): boolean;
65
+ export {};
66
+ //# sourceMappingURL=sight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sight.d.ts","sourceRoot":"","sources":["../../src/permissions/sight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAS,MAAM,YAAY,CAAC;AAE3D,2EAA2E;AAC3E,UAAU,MAAM;IACd,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACpD;AAKD,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAE5E;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvC,wFAAwF;IACxF,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,0GAA0G;AAC1G,MAAM,WAAW,WAAW;IAC1B,GAAG,IAAI,SAAS,SAAS,EAAE,CAAC;IAC5B,oGAAoG;IACpG,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AA0DD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAwBnD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAClB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACpD,KAAK,EAAE,MAAM;AACb,gFAAgF;AAChF,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,GACnC,OAAO,CAmBT"}
@@ -0,0 +1,131 @@
1
+ import { actingAs, isSystem } from "./policy.js";
2
+ const sightGrantsTo = (sight, principal) => sight.roles === "*" || (principal.roles ?? []).some((role) => sight.roles.includes(role));
3
+ /** The kinds a policy keeps to those its sights name. */
4
+ export function sightedKinds(policy) {
5
+ return new Set((policy?.sees ?? []).flatMap((sight) => sight.kinds));
6
+ }
7
+ const INDEXES = new WeakMap();
8
+ function indexFrom(base) {
9
+ const kinds = new Map();
10
+ const creators = new Map();
11
+ return { base, end: base, read: [], kinds, creators, entries: [], records: { kindOf: (id) => kinds.get(id), creatorOf: (id) => creators.get(id) } };
12
+ }
13
+ /** Reads one op into the index: the kind of each record it first adds or removes, and who first made one. */
14
+ function readInto(index, op) {
15
+ const seq = index.end;
16
+ for (const primitive of op.primitives) {
17
+ if (primitive.op !== "add-node" && primitive.op !== "remove-node")
18
+ continue;
19
+ const { id, kind } = primitive.node;
20
+ if (!index.kinds.has(id)) {
21
+ index.kinds.set(id, kind);
22
+ index.entries.push({ seq, id, creator: false });
23
+ }
24
+ if (primitive.op !== "add-node" || index.creators.has(id) || op.undoes !== undefined)
25
+ continue;
26
+ const by = actingAs(op.author).id;
27
+ if (by === undefined)
28
+ continue;
29
+ index.creators.set(id, by);
30
+ index.entries.push({ seq, id, creator: true });
31
+ }
32
+ index.read.push(op);
33
+ index.end++;
34
+ }
35
+ /** Takes out what the ops from `seq` on wrote: the log was cut back there. */
36
+ function cutBack(index, seq) {
37
+ while (index.entries.length > 0 && index.entries.at(-1).seq >= seq) {
38
+ const entry = index.entries.pop();
39
+ (entry.creator ? index.creators : index.kinds).delete(entry.id);
40
+ }
41
+ index.read.length = seq - index.base;
42
+ index.end = seq;
43
+ }
44
+ /**
45
+ * The records a log names, read from its add- and remove-node primitives.
46
+ * The first op that added a record made it: putting one back by an undo is
47
+ * not a new author.
48
+ *
49
+ * KEPT AS THE LOG GOES (FR-51), as the label index follows the graph: a
50
+ * call reads only the ops appended since the last one, so a commit costs
51
+ * its own ops, not the log's. A log cut back (`truncate`, under a rebase)
52
+ * is noticed by its ops no longer being the ones read, and what they wrote
53
+ * is taken out, back to where the log and the index still agree. A log
54
+ * compacted behind its horizon (FR-23) keeps what the index had already
55
+ * read of the archived ops, so a record made behind the horizon is still
56
+ * known by its maker for as long as this log is open; a log OPENED
57
+ * compacted never read them, and knows its makers from the horizon on.
58
+ * The `Records` returned is the same object every time, and answers as of
59
+ * the last call.
60
+ */
61
+ export function recordsOf(log) {
62
+ const ops = log.all();
63
+ const end = typeof log.length === "number" ? log.length : ops.length;
64
+ const first = end - ops.length;
65
+ let index = INDEXES.get(log);
66
+ if (index && index.base <= first && first <= index.end) {
67
+ // Back to the last seq where the log still holds the op the index read: a log is only ever cut from its end.
68
+ let agreed = Math.min(index.end, end);
69
+ while (agreed > first && ops[agreed - 1 - first] !== index.read[agreed - 1 - index.base])
70
+ agreed--;
71
+ if (agreed === first && first > index.base && agreed < index.end) {
72
+ // It disagrees all the way back to its horizon: not the log this index read.
73
+ index = undefined;
74
+ }
75
+ else {
76
+ if (agreed < index.end)
77
+ cutBack(index, agreed);
78
+ // What a compaction archived is no longer held here to compare against (FR-23).
79
+ if (first > index.base) {
80
+ index.read = index.read.slice(first - index.base);
81
+ index.base = first;
82
+ }
83
+ }
84
+ }
85
+ else
86
+ index = undefined;
87
+ if (!index)
88
+ INDEXES.set(log, (index = indexFrom(first)));
89
+ for (let seq = index.end; seq < end; seq++)
90
+ readInto(index, ops[seq - first]);
91
+ return index.records;
92
+ }
93
+ /**
94
+ * Whether a principal may see one record.
95
+ *
96
+ * ONE MEANING, the document's and the framework's alike (FR-02). With no
97
+ * `sees`, everybody sees everything. Once a policy says who sees what, it
98
+ * says it for every kind: a kind no sight names is seen by nobody but the
99
+ * system — the host's own seat — which is how a store fails closed when a
100
+ * kind is added and nobody said who sees it. A kind a sight names is seen
101
+ * by the roles it lists, and with `own` only the principal's own records:
102
+ * their record itself, what an edge joins to it ("a shopper sees their own
103
+ * test drives" without a field naming the owner), and what they made.
104
+ */
105
+ export function sees(policy, principal, node, graph,
106
+ /** Who made a record, from the log; without it, `own` reads the graph alone. */
107
+ records) {
108
+ if (!policy?.sees?.length)
109
+ return true;
110
+ // The system sees what it keeps; an agent sees what it AND its person may (FR-06, FR-17).
111
+ if (isSystem(principal))
112
+ return true;
113
+ const sights = policy.sees.filter((sight) => sight.kinds.includes(node.kind));
114
+ if (sights.length === 0)
115
+ return false;
116
+ principal = actingAs(principal);
117
+ return sights.some((sight) => {
118
+ if (!sightGrantsTo(sight, principal))
119
+ return false;
120
+ if (!sight.own)
121
+ return true;
122
+ const me = principal.id;
123
+ if (me === undefined)
124
+ return false;
125
+ return (node.id === me ||
126
+ graph.out(node.id).some((other) => other.id === me) ||
127
+ graph.in(node.id).some((other) => other.id === me) ||
128
+ records?.creatorOf(node.id) === me);
129
+ });
130
+ }
131
+ //# sourceMappingURL=sight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sight.js","sourceRoot":"","sources":["../../src/permissions/sight.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ import type { Author } from "../ops/types.js";
10
10
  */
11
11
  export interface Principal extends Author {
12
12
  readonly roles?: readonly string[];
13
+ /** The person an agent acts for: its roles bound the agent's, and a `self` grant reads their id. */
14
+ readonly onBehalfOf?: Principal;
13
15
  }
14
16
  /**
15
17
  * One permission: these roles may run these mutations, optionally only
@@ -43,8 +45,32 @@ export interface Grant {
43
45
  * a store where nothing works, it is a store where permission is not a
44
46
  * concern yet. An app opts in by declaring one.
45
47
  */
48
+ /**
49
+ * WHO MAY SEE WHAT. A grant says who may DO an act; a sight says who may
50
+ * see the records of a kind at all. Like grants, sights are deny by
51
+ * default once there are any (FR-02): a kind no sight names is seen by
52
+ * nobody but the system, so a kind added tomorrow is kept from everybody
53
+ * until somebody says who sees it, rather than shown to everybody. A kind
54
+ * a sight names is seen by the roles it lists (`"*"`: everybody), and with
55
+ * `own` only when it is theirs: their own record, one joined to it by an
56
+ * edge (a shopper's test drive, their enquiry), or one they made.
57
+ */
58
+ export interface Sight {
59
+ readonly roles: readonly string[] | "*";
60
+ readonly kinds: readonly string[];
61
+ /** Only the principal's own records: their own record, what an edge joins to it, and what they made. */
62
+ readonly own?: boolean;
63
+ readonly describe?: string;
64
+ }
46
65
  export interface Policy {
47
66
  readonly grants: readonly Grant[];
67
+ /**
68
+ * Who may see the records of which kinds. Absent, everybody sees
69
+ * everything — a storefront that declares none shows every customer's
70
+ * name, email and finance question to whoever opens it. Present, every
71
+ * kind is kept from everybody but the system until a sight names it.
72
+ */
73
+ readonly sees?: readonly Sight[];
48
74
  /**
49
75
  * Roles the policy knows about, so `graview check` can report a role that
50
76
  * may do nothing. Derived from the grants when absent.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/permissions/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAU,SAAQ,MAAM;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,KAAK;IACpB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBACd,OAAO,EAAE,OAAO;CAK7B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/permissions/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAU,SAAQ,MAAM;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,oGAAoG;IACpG,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,KAAK;IACpB,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IAC5C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;GAMG;AACH;;;;;;;;;GASG;AACH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,wGAAwG;IACxG,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;gBACd,OAAO,EAAE,OAAO;CAK7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/permissions/types.ts"],"names":[],"mappings":"AAsEA;;;;;;;GAOG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,OAAO,CAAU;IAC1B,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/permissions/types.ts"],"names":[],"mappings":"AAiGA;;;;;;;GAOG;AACH,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,OAAO,CAAU;IAC1B,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/persistence/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;gDACgD;AAChD,wBAAgB,mBAAmB,CACjC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM,GACvC,kBAAkB,CAAC,MAAM,CAAC,CA2B5B"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/persistence/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;gDACgD;AAChD,wBAAgB,mBAAmB,CACjC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM,GACvC,kBAAkB,CAAC,MAAM,CAAC,CAoD5B"}
@@ -3,6 +3,9 @@
3
3
  export function createMemoryAdapter(seed = {}) {
4
4
  const graphs = new Map(Object.entries(seed).map(([k, v]) => [k, clone(v)]));
5
5
  const logs = new Map();
6
+ const epochs = new Map();
7
+ // What a compaction moved behind the undo horizon (FR-23): kept, never loaded on open.
8
+ const archives = new Map();
6
9
  return {
7
10
  name: "memory",
8
11
  async load(scope) {
@@ -15,6 +18,8 @@ export function createMemoryAdapter(seed = {}) {
15
18
  async delete(scope) {
16
19
  graphs.delete(scope);
17
20
  logs.delete(scope);
21
+ epochs.delete(scope);
22
+ archives.delete(scope);
18
23
  },
19
24
  async loadLog(scope) {
20
25
  return clone(logs.get(scope) ?? []);
@@ -23,6 +28,26 @@ export function createMemoryAdapter(seed = {}) {
23
28
  const existing = logs.get(scope) ?? [];
24
29
  logs.set(scope, [...existing, ...clone([...ops])]);
25
30
  },
31
+ async loadEpochs(scope) {
32
+ return clone(epochs.get(scope) ?? []);
33
+ },
34
+ async saveEpochs(scope, list) {
35
+ epochs.set(scope, clone([...list]));
36
+ },
37
+ async compact(scope, checkpoint) {
38
+ const log = logs.get(scope) ?? [];
39
+ const marks = epochs.get(scope) ?? [];
40
+ const held = archives.get(scope) ?? { ops: [], epochs: [] };
41
+ archives.set(scope, {
42
+ ops: [...held.ops, ...clone(log.filter((op) => op.seq < checkpoint.seq))],
43
+ epochs: [...held.epochs, ...clone(marks.filter((epoch) => epoch.seq < checkpoint.seq))],
44
+ });
45
+ logs.set(scope, log.filter((op) => op.seq >= checkpoint.seq));
46
+ epochs.set(scope, [clone({ ...checkpoint, horizon: true }), ...marks.filter((epoch) => epoch.seq > checkpoint.seq)]);
47
+ },
48
+ async loadArchive(scope) {
49
+ return clone(archives.get(scope) ?? { ops: [], epochs: [] });
50
+ },
26
51
  };
27
52
  }
28
53
  function clone(value) {
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/persistence/memory.ts"],"names":[],"mappings":"AAIA;gDACgD;AAChD,MAAM,UAAU,mBAAmB,CACjC,OAAsC,EAAE;IAExC,MAAM,MAAM,GAAG,IAAI,GAAG,CACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CACpD,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE5C,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,CAAC,IAAI,CAAC,KAAK;YACd,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ;YACxB,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,KAAK;YAChB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG;YACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAI,KAAQ;IACxB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/persistence/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type { PersistenceAdapter } from "./types.js";
2
+ /**
3
+ * PERSISTENCE OVER PLAIN SQL — one synchronous `exec` (FR-09).
4
+ *
5
+ * The shape a Durable Object's storage already has (`ctx.storage.sql`
6
+ * passes as it is) and better-sqlite3 has once `sqlFromDatabase` wraps it:
7
+ * one statement in, its rows out. Nothing else is asked of the database, so
8
+ * the adapter runs wherever SQLite does — a Worker, Node, Deno — and no
9
+ * native module is ever imported here.
10
+ */
11
+ export interface SqlExec {
12
+ /** Runs ONE statement with `?` parameters; the rows, iterable, when it reads any. */
13
+ exec(sql: string, ...params: unknown[]): Iterable<unknown>;
14
+ }
15
+ export interface SqlAdapterOptions {
16
+ readonly sql: SqlExec;
17
+ /**
18
+ * Runs `fn` as one transaction, so a snapshot is rewritten all or nothing.
19
+ * A Durable Object passes `(fn) => ctx.storage.transactionSync(fn)`;
20
+ * `sqlFromDatabase` supplies better-sqlite3's. Absent, `fn` simply runs.
21
+ */
22
+ readonly transaction?: <T>(fn: () => T) => T;
23
+ /** Defaults match the household example's existing tables exactly. */
24
+ readonly nodeTable?: string;
25
+ readonly edgeTable?: string;
26
+ readonly opTable?: string;
27
+ /** The framework's epochs (FR-27), live and archived: `graview_epochs`. */
28
+ readonly epochTable?: string;
29
+ /** The ops a compaction moved behind the undo horizon (FR-23): `graview_ops_archive`. */
30
+ readonly archiveTable?: string;
31
+ /** Column holding the scope key (the household example: `household_id`). */
32
+ readonly scopeColumn?: string;
33
+ /** Creates the tables when absent. Off by default: never touch an app's schema. */
34
+ readonly createTables?: boolean;
35
+ }
36
+ /**
37
+ * Reads and writes an app's `graph_nodes` / `graph_edges` tables, and the
38
+ * framework's own op table, through `exec` alone. `data` is schemaless JSON
39
+ * on disk and becomes a typed node on the way in, validated by the schema
40
+ * registry when the snapshot is loaded into a Graph.
41
+ */
42
+ export declare function createSqlAdapter(options: SqlAdapterOptions): PersistenceAdapter<string>;
43
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/persistence/sql.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,qFAAqF;IACrF,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7C,sEAAsE;IACtE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,yFAAyF;IACzF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAyJvF"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Reads and writes an app's `graph_nodes` / `graph_edges` tables, and the
3
+ * framework's own op table, through `exec` alone. `data` is schemaless JSON
4
+ * on disk and becomes a typed node on the way in, validated by the schema
5
+ * registry when the snapshot is loaded into a Graph.
6
+ */
7
+ export function createSqlAdapter(options) {
8
+ const { sql } = options;
9
+ const transaction = options.transaction ?? ((fn) => fn());
10
+ const nodeTable = options.nodeTable ?? "graph_nodes";
11
+ const edgeTable = options.edgeTable ?? "graph_edges";
12
+ const opTable = options.opTable ?? "graview_ops";
13
+ const epochTable = options.epochTable ?? "graview_epochs";
14
+ const archiveTable = options.archiveTable ?? "graview_ops_archive";
15
+ const scope = options.scopeColumn ?? "household_id";
16
+ const rows = (statement, ...params) => [...sql.exec(statement, ...params)];
17
+ const run = (statement, ...params) => {
18
+ // Drained, so a lazy cursor (a Durable Object's) has really run.
19
+ for (const _ of sql.exec(statement, ...params))
20
+ void _;
21
+ };
22
+ const createOpTable = `CREATE TABLE IF NOT EXISTS ${opTable} (
23
+ ${scope} TEXT NOT NULL, seq INTEGER NOT NULL, data TEXT NOT NULL,
24
+ PRIMARY KEY (${scope}, seq))`;
25
+ /*
26
+ * THE FRAMEWORK'S OTHER TABLES, beside the op table and as much its own:
27
+ * the epochs the log folds from (`archived` 0), the epochs and ops a
28
+ * compaction moved behind the undo horizon (`archived` 1, and the archive
29
+ * table, shaped like the op table). A normal open reads neither archive.
30
+ */
31
+ const createEpochTable = `CREATE TABLE IF NOT EXISTS ${epochTable} (
32
+ ${scope} TEXT NOT NULL, archived INTEGER NOT NULL, position INTEGER NOT NULL, data TEXT NOT NULL,
33
+ PRIMARY KEY (${scope}, archived, position))`;
34
+ const createArchiveTable = `CREATE TABLE IF NOT EXISTS ${archiveTable} (
35
+ ${scope} TEXT NOT NULL, seq INTEGER NOT NULL, data TEXT NOT NULL,
36
+ PRIMARY KEY (${scope}, seq))`;
37
+ if (options.createTables) {
38
+ run(`CREATE TABLE IF NOT EXISTS ${nodeTable} (
39
+ ${scope} TEXT NOT NULL, id TEXT NOT NULL,
40
+ kind TEXT NOT NULL, data TEXT NOT NULL,
41
+ PRIMARY KEY (${scope}, id))`);
42
+ run(`CREATE TABLE IF NOT EXISTS ${edgeTable} (
43
+ ${scope} TEXT NOT NULL, position INTEGER NOT NULL,
44
+ kind TEXT NOT NULL, from_id TEXT NOT NULL, to_id TEXT NOT NULL,
45
+ PRIMARY KEY (${scope}, position))`);
46
+ run(createOpTable);
47
+ run(createEpochTable);
48
+ run(createArchiveTable);
49
+ }
50
+ /**
51
+ * The op table is the framework's own, not the app's, so it is created on
52
+ * demand. The node and edge tables are the app's and are never touched
53
+ * unless `createTables` explicitly asks for them.
54
+ */
55
+ let opTableReady = false;
56
+ function ensureOpTable() {
57
+ if (opTableReady)
58
+ return;
59
+ run(createOpTable);
60
+ run(createEpochTable);
61
+ run(createArchiveTable);
62
+ opTableReady = true;
63
+ }
64
+ const epochsOf = (key, archived) => rows(`SELECT data FROM ${epochTable} WHERE ${scope} = ? AND archived = ? ORDER BY position ASC`, key, archived).map((row) => JSON.parse(row.data));
65
+ const writeEpochs = (key, archived, epochs, from = 0) => {
66
+ epochs.forEach((epoch, index) => {
67
+ run(`INSERT INTO ${epochTable} (${scope}, archived, position, data) VALUES (?, ?, ?, ?)`, key, archived, from + index, JSON.stringify(epoch));
68
+ });
69
+ };
70
+ const clear = (key) => {
71
+ run(`DELETE FROM ${edgeTable} WHERE ${scope} = ?`, key);
72
+ run(`DELETE FROM ${nodeTable} WHERE ${scope} = ?`, key);
73
+ };
74
+ return {
75
+ name: "sqlite",
76
+ async load(key) {
77
+ const nodeRows = rows(`SELECT id, kind, data FROM ${nodeTable} WHERE ${scope} = ?`, key);
78
+ if (nodeRows.length === 0)
79
+ return null;
80
+ const edgeRows = rows(`SELECT kind, from_id, to_id FROM ${edgeTable} WHERE ${scope} = ? ORDER BY position ASC`, key);
81
+ const nodes = nodeRows.map((row) => {
82
+ const parsed = JSON.parse(row.data);
83
+ // `id` and `kind` live in columns as well as the JSON blob; the
84
+ // columns win so a row is never internally inconsistent.
85
+ return { ...parsed, id: row.id, kind: row.kind };
86
+ });
87
+ const edges = edgeRows.map((row) => ({ kind: row.kind, from: row.from_id, to: row.to_id }));
88
+ return { nodes, edges };
89
+ },
90
+ async save(key, snapshot) {
91
+ transaction(() => {
92
+ clear(key);
93
+ for (const node of snapshot.nodes) {
94
+ run(`INSERT INTO ${nodeTable} (${scope}, id, kind, data) VALUES (?, ?, ?, ?)`, key, node.id, node.kind, JSON.stringify(node));
95
+ }
96
+ snapshot.edges.forEach((edge, position) => {
97
+ run(`INSERT INTO ${edgeTable} (${scope}, position, kind, from_id, to_id) VALUES (?, ?, ?, ?, ?)`, key, position, edge.kind, edge.from, edge.to);
98
+ });
99
+ });
100
+ },
101
+ async delete(key) {
102
+ ensureOpTable();
103
+ transaction(() => {
104
+ clear(key);
105
+ // A deleted scope is gone with its history, as in every other adapter.
106
+ for (const table of [opTable, epochTable, archiveTable])
107
+ run(`DELETE FROM ${table} WHERE ${scope} = ?`, key);
108
+ });
109
+ },
110
+ async loadLog(key) {
111
+ ensureOpTable();
112
+ return rows(`SELECT data FROM ${opTable} WHERE ${scope} = ? ORDER BY seq ASC`, key).map((row) => JSON.parse(row.data));
113
+ },
114
+ async appendOps(key, ops) {
115
+ if (ops.length === 0)
116
+ return;
117
+ ensureOpTable();
118
+ transaction(() => {
119
+ for (const op of ops)
120
+ run(`INSERT OR REPLACE INTO ${opTable} (${scope}, seq, data) VALUES (?, ?, ?)`, key, op.seq, JSON.stringify(op));
121
+ });
122
+ },
123
+ async loadEpochs(key) {
124
+ ensureOpTable();
125
+ return epochsOf(key, 0);
126
+ },
127
+ async saveEpochs(key, epochs) {
128
+ ensureOpTable();
129
+ transaction(() => {
130
+ run(`DELETE FROM ${epochTable} WHERE ${scope} = ? AND archived = 0`, key);
131
+ writeEpochs(key, 0, epochs);
132
+ });
133
+ },
134
+ async compact(key, checkpoint) {
135
+ ensureOpTable();
136
+ transaction(() => {
137
+ run(`INSERT OR REPLACE INTO ${archiveTable} (${scope}, seq, data) SELECT ${scope}, seq, data FROM ${opTable} WHERE ${scope} = ? AND seq < ?`, key, checkpoint.seq);
138
+ run(`DELETE FROM ${opTable} WHERE ${scope} = ? AND seq < ?`, key, checkpoint.seq);
139
+ const live = epochsOf(key, 0);
140
+ writeEpochs(key, 1, live.filter((epoch) => epoch.seq < checkpoint.seq), epochsOf(key, 1).length);
141
+ run(`DELETE FROM ${epochTable} WHERE ${scope} = ? AND archived = 0`, key);
142
+ writeEpochs(key, 0, [{ ...checkpoint, horizon: true }, ...live.filter((epoch) => epoch.seq > checkpoint.seq)]);
143
+ });
144
+ },
145
+ async loadArchive(key) {
146
+ ensureOpTable();
147
+ return {
148
+ ops: rows(`SELECT data FROM ${archiveTable} WHERE ${scope} = ? ORDER BY seq ASC`, key).map((row) => JSON.parse(row.data)),
149
+ epochs: epochsOf(key, 1),
150
+ };
151
+ },
152
+ };
153
+ }
154
+ //# sourceMappingURL=sql.js.map