@ontrails/core 1.0.0-beta.13 → 1.0.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +19 -14
  4. package/dist/branded.d.ts +1 -1
  5. package/dist/branded.d.ts.map +1 -1
  6. package/dist/branded.js +1 -1
  7. package/dist/branded.js.map +1 -1
  8. package/dist/context.d.ts +13 -1
  9. package/dist/context.d.ts.map +1 -1
  10. package/dist/context.js +19 -3
  11. package/dist/context.js.map +1 -1
  12. package/dist/contour.d.ts +81 -0
  13. package/dist/contour.d.ts.map +1 -0
  14. package/dist/contour.js +176 -0
  15. package/dist/contour.js.map +1 -0
  16. package/dist/cross-schema.d.ts +18 -0
  17. package/dist/cross-schema.d.ts.map +1 -0
  18. package/dist/cross-schema.js +29 -0
  19. package/dist/cross-schema.js.map +1 -0
  20. package/dist/derive.d.ts +6 -0
  21. package/dist/derive.d.ts.map +1 -1
  22. package/dist/derive.js +29 -5
  23. package/dist/derive.js.map +1 -1
  24. package/dist/draft.d.ts +28 -0
  25. package/dist/draft.d.ts.map +1 -0
  26. package/dist/draft.js +157 -0
  27. package/dist/draft.js.map +1 -0
  28. package/dist/errors.d.ts +62 -4
  29. package/dist/errors.d.ts.map +1 -1
  30. package/dist/errors.js +44 -1
  31. package/dist/errors.js.map +1 -1
  32. package/dist/execute.d.ts +26 -9
  33. package/dist/execute.d.ts.map +1 -1
  34. package/dist/execute.js +441 -20
  35. package/dist/execute.js.map +1 -1
  36. package/dist/fire.d.ts +43 -0
  37. package/dist/fire.d.ts.map +1 -0
  38. package/dist/fire.js +185 -0
  39. package/dist/fire.js.map +1 -0
  40. package/dist/index.d.ts +33 -17
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +26 -12
  43. package/dist/index.js.map +1 -1
  44. package/dist/internal/cross-batch.d.ts +44 -0
  45. package/dist/internal/cross-batch.d.ts.map +1 -0
  46. package/dist/internal/cross-batch.js +58 -0
  47. package/dist/internal/cross-batch.js.map +1 -0
  48. package/dist/internal/fork-ctx.d.ts +41 -0
  49. package/dist/internal/fork-ctx.d.ts.map +1 -0
  50. package/dist/internal/fork-ctx.js +47 -0
  51. package/dist/internal/fork-ctx.js.map +1 -0
  52. package/dist/internal/signal-ref.d.ts +15 -0
  53. package/dist/internal/signal-ref.d.ts.map +1 -0
  54. package/dist/internal/signal-ref.js +41 -0
  55. package/dist/internal/signal-ref.js.map +1 -0
  56. package/dist/internal/topo-saves.d.ts +53 -0
  57. package/dist/internal/topo-saves.d.ts.map +1 -0
  58. package/dist/internal/topo-saves.js +449 -0
  59. package/dist/internal/topo-saves.js.map +1 -0
  60. package/dist/internal/topo-snapshots.d.ts +57 -0
  61. package/dist/internal/topo-snapshots.d.ts.map +1 -0
  62. package/dist/internal/topo-snapshots.js +372 -0
  63. package/dist/internal/topo-snapshots.js.map +1 -0
  64. package/dist/internal/topo-store-read.d.ts +70 -0
  65. package/dist/internal/topo-store-read.d.ts.map +1 -0
  66. package/dist/internal/topo-store-read.js +221 -0
  67. package/dist/internal/topo-store-read.js.map +1 -0
  68. package/dist/internal/topo-store.d.ts +26 -0
  69. package/dist/internal/topo-store.d.ts.map +1 -0
  70. package/dist/internal/topo-store.js +621 -0
  71. package/dist/internal/topo-store.js.map +1 -0
  72. package/dist/internal/tracing.d.ts +98 -0
  73. package/dist/internal/tracing.d.ts.map +1 -0
  74. package/dist/internal/tracing.js +102 -0
  75. package/dist/internal/tracing.js.map +1 -0
  76. package/dist/internal/trails-db.d.ts +16 -0
  77. package/dist/internal/trails-db.d.ts.map +1 -0
  78. package/dist/internal/trails-db.js +118 -0
  79. package/dist/internal/trails-db.js.map +1 -0
  80. package/dist/internal/zod-wrappers.d.ts +40 -0
  81. package/dist/internal/zod-wrappers.d.ts.map +1 -0
  82. package/dist/internal/zod-wrappers.js +59 -0
  83. package/dist/internal/zod-wrappers.js.map +1 -0
  84. package/dist/layer.d.ts +22 -5
  85. package/dist/layer.d.ts.map +1 -1
  86. package/dist/layer.js +20 -3
  87. package/dist/layer.js.map +1 -1
  88. package/dist/path-security.d.ts +1 -1
  89. package/dist/path-security.d.ts.map +1 -1
  90. package/dist/path-security.js +1 -1
  91. package/dist/path-security.js.map +1 -1
  92. package/dist/resilience.d.ts +1 -1
  93. package/dist/resilience.d.ts.map +1 -1
  94. package/dist/resilience.js +3 -3
  95. package/dist/resilience.js.map +1 -1
  96. package/dist/resource-config.d.ts +22 -0
  97. package/dist/resource-config.d.ts.map +1 -0
  98. package/dist/resource-config.js +210 -0
  99. package/dist/resource-config.js.map +1 -0
  100. package/dist/resource.d.ts +74 -0
  101. package/dist/resource.d.ts.map +1 -0
  102. package/dist/resource.js +61 -0
  103. package/dist/resource.js.map +1 -0
  104. package/dist/run.d.ts +4 -3
  105. package/dist/run.d.ts.map +1 -1
  106. package/dist/run.js +5 -4
  107. package/dist/run.js.map +1 -1
  108. package/dist/serialization.d.ts.map +1 -1
  109. package/dist/serialization.js +2 -1
  110. package/dist/serialization.js.map +1 -1
  111. package/dist/store/accessor-protocol.d.ts +51 -0
  112. package/dist/store/accessor-protocol.d.ts.map +1 -0
  113. package/dist/store/accessor-protocol.js +2 -0
  114. package/dist/store/accessor-protocol.js.map +1 -0
  115. package/dist/store/index.d.ts +2 -0
  116. package/dist/store/index.d.ts.map +1 -0
  117. package/dist/store/index.js +2 -0
  118. package/dist/store/index.js.map +1 -0
  119. package/dist/surface-filter.d.ts +13 -0
  120. package/dist/surface-filter.d.ts.map +1 -0
  121. package/dist/surface-filter.js +76 -0
  122. package/dist/surface-filter.js.map +1 -0
  123. package/dist/topo-store.d.ts +62 -0
  124. package/dist/topo-store.d.ts.map +1 -0
  125. package/dist/topo-store.js +319 -0
  126. package/dist/topo-store.js.map +1 -0
  127. package/dist/topo.d.ts +23 -9
  128. package/dist/topo.d.ts.map +1 -1
  129. package/dist/topo.js +175 -46
  130. package/dist/topo.js.map +1 -1
  131. package/dist/trail.d.ts +86 -19
  132. package/dist/trail.d.ts.map +1 -1
  133. package/dist/trail.js +59 -4
  134. package/dist/trail.js.map +1 -1
  135. package/dist/trails/derive-trail.d.ts +66 -0
  136. package/dist/trails/derive-trail.d.ts.map +1 -0
  137. package/dist/trails/derive-trail.js +378 -0
  138. package/dist/trails/derive-trail.js.map +1 -0
  139. package/dist/trails/index.d.ts +5 -0
  140. package/dist/trails/index.d.ts.map +1 -0
  141. package/dist/trails/index.js +3 -0
  142. package/dist/trails/index.js.map +1 -0
  143. package/dist/trails/ingest.d.ts +24 -0
  144. package/dist/trails/ingest.d.ts.map +1 -0
  145. package/dist/trails/ingest.js +63 -0
  146. package/dist/trails/ingest.js.map +1 -0
  147. package/dist/transport-error-map.d.ts +106 -0
  148. package/dist/transport-error-map.d.ts.map +1 -0
  149. package/dist/transport-error-map.js +24 -0
  150. package/dist/transport-error-map.js.map +1 -0
  151. package/dist/type-checks.test-d.d.ts +71 -0
  152. package/dist/type-checks.test-d.d.ts.map +1 -0
  153. package/dist/type-checks.test-d.js +12 -0
  154. package/dist/type-checks.test-d.js.map +1 -0
  155. package/dist/type-utils.d.ts +11 -2
  156. package/dist/type-utils.d.ts.map +1 -1
  157. package/dist/type-utils.js.map +1 -1
  158. package/dist/types.d.ts +113 -7
  159. package/dist/types.d.ts.map +1 -1
  160. package/dist/types.js.map +1 -1
  161. package/dist/validate-established-topo.d.ts +76 -0
  162. package/dist/validate-established-topo.d.ts.map +1 -0
  163. package/dist/validate-established-topo.js +43 -0
  164. package/dist/validate-established-topo.js.map +1 -0
  165. package/dist/validate-topo.d.ts.map +1 -1
  166. package/dist/validate-topo.js +27 -8
  167. package/dist/validate-topo.js.map +1 -1
  168. package/dist/workspace.d.ts +1 -1
  169. package/dist/workspace.d.ts.map +1 -1
  170. package/dist/workspace.js +1 -1
  171. package/dist/workspace.js.map +1 -1
  172. package/package.json +10 -1
  173. package/src/__tests__/branded.test.ts +5 -5
  174. package/src/__tests__/context.test.ts +3 -3
  175. package/src/__tests__/contour.test.ts +263 -0
  176. package/src/__tests__/derive-trail.test.ts +668 -0
  177. package/src/__tests__/derive.test.ts +58 -1
  178. package/src/__tests__/errors.test.ts +118 -0
  179. package/src/__tests__/execute.test.ts +1179 -141
  180. package/src/__tests__/fire.test.ts +1056 -0
  181. package/src/__tests__/fork-ctx.test.ts +83 -0
  182. package/src/__tests__/ingest.test.ts +191 -0
  183. package/src/__tests__/{gate.test.ts → layer.test.ts} +21 -21
  184. package/src/__tests__/path-security.test.ts +7 -7
  185. package/src/__tests__/resilience.test.ts +8 -8
  186. package/src/__tests__/resource.test.ts +204 -0
  187. package/src/__tests__/run.test.ts +13 -13
  188. package/src/__tests__/service-config.test.ts +28 -32
  189. package/src/__tests__/surface-filter.test.ts +196 -0
  190. package/src/__tests__/topo-store-read.test.ts +256 -0
  191. package/src/__tests__/topo-store.test.ts +869 -0
  192. package/src/__tests__/topo.test.ts +350 -54
  193. package/src/__tests__/trail.test.ts +189 -24
  194. package/src/__tests__/trails-db.test.ts +198 -0
  195. package/src/__tests__/transport-error-map.test.ts +82 -0
  196. package/src/__tests__/type-utils.test.ts +29 -1
  197. package/src/__tests__/validate-topo.test.ts +305 -16
  198. package/src/__tests__/workspace.test.ts +6 -6
  199. package/src/__tests__/zod-wrappers.test.ts +62 -0
  200. package/src/branded.ts +1 -1
  201. package/src/context.ts +24 -4
  202. package/src/contour.ts +344 -0
  203. package/src/cross-schema.ts +36 -0
  204. package/src/derive.ts +39 -8
  205. package/src/draft.ts +338 -0
  206. package/src/errors.ts +62 -18
  207. package/src/execute.ts +840 -29
  208. package/src/fire.ts +295 -0
  209. package/src/index.ts +142 -26
  210. package/src/internal/cross-batch.ts +77 -0
  211. package/src/internal/fork-ctx.ts +69 -0
  212. package/src/internal/signal-ref.ts +87 -0
  213. package/src/internal/topo-snapshots.ts +517 -0
  214. package/src/internal/topo-store-read.ts +481 -0
  215. package/src/internal/topo-store.ts +1192 -0
  216. package/src/internal/tracing.ts +187 -0
  217. package/src/internal/trails-db.ts +187 -0
  218. package/src/internal/zod-wrappers.ts +78 -0
  219. package/src/layer.ts +50 -0
  220. package/src/path-security.ts +1 -1
  221. package/src/resilience.ts +3 -3
  222. package/src/{provision-config.ts → resource-config.ts} +109 -123
  223. package/src/resource.ts +155 -0
  224. package/src/run.ts +5 -4
  225. package/src/serialization.ts +2 -0
  226. package/src/store/accessor-protocol.ts +56 -0
  227. package/src/store/index.ts +4 -0
  228. package/src/surface-filter.ts +182 -0
  229. package/src/topo-store.ts +510 -0
  230. package/src/topo.ts +328 -57
  231. package/src/trail.ts +199 -31
  232. package/src/trails/derive-trail.ts +842 -0
  233. package/src/trails/index.ts +9 -0
  234. package/src/trails/ingest.ts +146 -0
  235. package/src/transport-error-map.ts +56 -0
  236. package/src/type-checks.test-d.ts +106 -0
  237. package/src/type-utils.ts +17 -2
  238. package/src/types.ts +148 -11
  239. package/src/validate-established-topo.ts +63 -0
  240. package/src/validate-topo.ts +37 -9
  241. package/src/workspace.ts +1 -1
  242. package/tsconfig.tests.json +10 -0
  243. package/tsconfig.tsbuildinfo +1 -1
  244. package/dist/adapters.d.ts +0 -39
  245. package/dist/adapters.d.ts.map +0 -1
  246. package/dist/adapters.js +0 -2
  247. package/dist/adapters.js.map +0 -1
  248. package/dist/dispatch.d.ts +0 -27
  249. package/dist/dispatch.d.ts.map +0 -1
  250. package/dist/dispatch.js +0 -34
  251. package/dist/dispatch.js.map +0 -1
  252. package/dist/event.d.ts +0 -8
  253. package/dist/event.d.ts.map +0 -1
  254. package/dist/event.js +0 -7
  255. package/dist/event.js.map +0 -1
  256. package/dist/gate.d.ts +0 -17
  257. package/dist/gate.d.ts.map +0 -1
  258. package/dist/gate.js +0 -21
  259. package/dist/gate.js.map +0 -1
  260. package/dist/health.d.ts +0 -18
  261. package/dist/health.d.ts.map +0 -1
  262. package/dist/health.js +0 -5
  263. package/dist/health.js.map +0 -1
  264. package/dist/job.d.ts +0 -24
  265. package/dist/job.d.ts.map +0 -1
  266. package/dist/job.js +0 -17
  267. package/dist/job.js.map +0 -1
  268. package/dist/provision-config.d.ts +0 -22
  269. package/dist/provision-config.d.ts.map +0 -1
  270. package/dist/provision-config.js +0 -210
  271. package/dist/provision-config.js.map +0 -1
  272. package/dist/provision.d.ts +0 -71
  273. package/dist/provision.d.ts.map +0 -1
  274. package/dist/provision.js +0 -56
  275. package/dist/provision.js.map +0 -1
  276. package/dist/service-config.d.ts +0 -22
  277. package/dist/service-config.d.ts.map +0 -1
  278. package/dist/service-config.js +0 -210
  279. package/dist/service-config.js.map +0 -1
  280. package/dist/service.d.ts +0 -71
  281. package/dist/service.d.ts.map +0 -1
  282. package/dist/service.js +0 -56
  283. package/dist/service.js.map +0 -1
  284. package/src/__tests__/service.test.ts +0 -197
  285. package/src/event.ts +0 -15
  286. package/src/gate.ts +0 -44
  287. package/src/provision.ts +0 -148
@@ -0,0 +1,372 @@
1
+ import { ensureSubsystemSchema } from './trails-db.js';
2
+ const TOPO_SUBSYSTEM = 'topo';
3
+ const TOPO_TABLE_STATEMENTS = [
4
+ `CREATE TABLE IF NOT EXISTS topo_snapshots (
5
+ id TEXT PRIMARY KEY,
6
+ git_sha TEXT,
7
+ git_dirty INTEGER NOT NULL DEFAULT 0,
8
+ trail_count INTEGER NOT NULL DEFAULT 0,
9
+ signal_count INTEGER NOT NULL DEFAULT 0,
10
+ resource_count INTEGER NOT NULL DEFAULT 0,
11
+ pinned_as TEXT,
12
+ created_at TEXT NOT NULL
13
+ )`,
14
+ `CREATE TABLE IF NOT EXISTS topo_trails (
15
+ id TEXT NOT NULL,
16
+ intent TEXT,
17
+ idempotent INTEGER NOT NULL DEFAULT 0,
18
+ has_output INTEGER NOT NULL DEFAULT 0,
19
+ has_examples INTEGER NOT NULL DEFAULT 0,
20
+ example_count INTEGER NOT NULL DEFAULT 0,
21
+ description TEXT,
22
+ pattern TEXT,
23
+ meta TEXT,
24
+ snapshot_id TEXT NOT NULL,
25
+ PRIMARY KEY (id, snapshot_id),
26
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
27
+ )`,
28
+ `CREATE TABLE IF NOT EXISTS topo_crossings (
29
+ source_id TEXT NOT NULL,
30
+ target_id TEXT NOT NULL,
31
+ snapshot_id TEXT NOT NULL,
32
+ PRIMARY KEY (source_id, target_id, snapshot_id),
33
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
34
+ )`,
35
+ `CREATE TABLE IF NOT EXISTS topo_trail_resources (
36
+ trail_id TEXT NOT NULL,
37
+ resource_id TEXT NOT NULL,
38
+ snapshot_id TEXT NOT NULL,
39
+ PRIMARY KEY (trail_id, resource_id, snapshot_id),
40
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
41
+ )`,
42
+ `CREATE TABLE IF NOT EXISTS topo_resources (
43
+ id TEXT NOT NULL,
44
+ has_mock INTEGER NOT NULL DEFAULT 0,
45
+ has_health INTEGER NOT NULL DEFAULT 0,
46
+ snapshot_id TEXT NOT NULL,
47
+ PRIMARY KEY (id, snapshot_id),
48
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
49
+ )`,
50
+ `CREATE TABLE IF NOT EXISTS topo_signals (
51
+ id TEXT NOT NULL,
52
+ description TEXT,
53
+ snapshot_id TEXT NOT NULL,
54
+ PRIMARY KEY (id, snapshot_id),
55
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
56
+ )`,
57
+ `CREATE TABLE IF NOT EXISTS topo_trail_signals (
58
+ trail_id TEXT NOT NULL,
59
+ signal_id TEXT NOT NULL,
60
+ snapshot_id TEXT NOT NULL,
61
+ PRIMARY KEY (trail_id, signal_id, snapshot_id),
62
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
63
+ )`,
64
+ `CREATE TABLE IF NOT EXISTS topo_surfaces (
65
+ trail_id TEXT NOT NULL,
66
+ surface TEXT NOT NULL,
67
+ derived_name TEXT NOT NULL,
68
+ method TEXT,
69
+ snapshot_id TEXT NOT NULL,
70
+ PRIMARY KEY (trail_id, surface, snapshot_id),
71
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
72
+ )`,
73
+ `CREATE TABLE IF NOT EXISTS topo_examples (
74
+ id TEXT PRIMARY KEY,
75
+ trail_id TEXT NOT NULL,
76
+ ordinal INTEGER NOT NULL,
77
+ name TEXT NOT NULL,
78
+ description TEXT,
79
+ input TEXT NOT NULL,
80
+ expected TEXT,
81
+ error TEXT,
82
+ snapshot_id TEXT NOT NULL,
83
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
84
+ )`,
85
+ `CREATE TABLE IF NOT EXISTS topo_schemas (
86
+ owner_id TEXT NOT NULL,
87
+ owner_kind TEXT NOT NULL,
88
+ schema_kind TEXT NOT NULL,
89
+ zod_hash TEXT NOT NULL,
90
+ json_schema TEXT NOT NULL,
91
+ snapshot_id TEXT NOT NULL,
92
+ PRIMARY KEY (owner_id, owner_kind, schema_kind, snapshot_id),
93
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
94
+ )`,
95
+ `CREATE TABLE IF NOT EXISTS topo_exports (
96
+ snapshot_id TEXT PRIMARY KEY,
97
+ surface_map TEXT NOT NULL,
98
+ surface_hash TEXT NOT NULL,
99
+ serialized_lock TEXT NOT NULL,
100
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
101
+ )`,
102
+ `CREATE TABLE IF NOT EXISTS topo_trail_fires (
103
+ trail_id TEXT NOT NULL,
104
+ signal_id TEXT NOT NULL,
105
+ snapshot_id TEXT NOT NULL,
106
+ PRIMARY KEY (trail_id, signal_id, snapshot_id),
107
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
108
+ )`,
109
+ `CREATE TABLE IF NOT EXISTS topo_trail_on (
110
+ trail_id TEXT NOT NULL,
111
+ signal_id TEXT NOT NULL,
112
+ snapshot_id TEXT NOT NULL,
113
+ PRIMARY KEY (trail_id, signal_id, snapshot_id),
114
+ FOREIGN KEY (snapshot_id) REFERENCES topo_snapshots(id) ON DELETE CASCADE
115
+ )`,
116
+ ];
117
+ const TOPO_INDEX_STATEMENTS = [
118
+ 'CREATE INDEX IF NOT EXISTS idx_topo_snapshots_created_at ON topo_snapshots(created_at DESC)',
119
+ `CREATE UNIQUE INDEX IF NOT EXISTS idx_topo_snapshots_pinned_as
120
+ ON topo_snapshots(pinned_as) WHERE pinned_as IS NOT NULL`,
121
+ 'CREATE INDEX IF NOT EXISTS idx_topo_trails_snapshot_id ON topo_trails(snapshot_id)',
122
+ 'CREATE INDEX IF NOT EXISTS idx_topo_crossings_snapshot_id ON topo_crossings(snapshot_id)',
123
+ 'CREATE INDEX IF NOT EXISTS idx_topo_trail_resources_snapshot_id ON topo_trail_resources(snapshot_id)',
124
+ 'CREATE INDEX IF NOT EXISTS idx_topo_resources_snapshot_id ON topo_resources(snapshot_id)',
125
+ 'CREATE INDEX IF NOT EXISTS idx_topo_signals_snapshot_id ON topo_signals(snapshot_id)',
126
+ 'CREATE INDEX IF NOT EXISTS idx_topo_trail_signals_snapshot_id ON topo_trail_signals(snapshot_id)',
127
+ 'CREATE INDEX IF NOT EXISTS idx_topo_surfaces_snapshot_id ON topo_surfaces(snapshot_id)',
128
+ 'CREATE UNIQUE INDEX IF NOT EXISTS idx_topo_examples_snapshot_trail_ordinal ON topo_examples(snapshot_id, trail_id, ordinal)',
129
+ 'CREATE INDEX IF NOT EXISTS idx_topo_schemas_snapshot_id ON topo_schemas(snapshot_id)',
130
+ `CREATE INDEX IF NOT EXISTS idx_topo_schemas_lookup
131
+ ON topo_schemas(owner_id, owner_kind, schema_kind, zod_hash)`,
132
+ 'CREATE INDEX IF NOT EXISTS idx_topo_trail_fires_snapshot_id ON topo_trail_fires(snapshot_id)',
133
+ 'CREATE INDEX IF NOT EXISTS idx_topo_trail_on_snapshot_id ON topo_trail_on(snapshot_id)',
134
+ ];
135
+ const rowToSnapshot = (row) => ({
136
+ createdAt: row.created_at,
137
+ gitDirty: row.git_dirty === 1,
138
+ id: row.id,
139
+ resourceCount: row.resource_count,
140
+ signalCount: row.signal_count,
141
+ trailCount: row.trail_count,
142
+ ...(row.git_sha === null ? {} : { gitSha: row.git_sha }),
143
+ ...(row.pinned_as === null ? {} : { pinnedAs: row.pinned_as }),
144
+ });
145
+ const tableExists = (db, tableName) => {
146
+ const row = db
147
+ .query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?")
148
+ .get(tableName);
149
+ return row?.name === tableName;
150
+ };
151
+ const runStatements = (db, statements) => {
152
+ for (const statement of statements) {
153
+ db.run(statement);
154
+ }
155
+ };
156
+ const createAllTopoTables = (db) => {
157
+ runStatements(db, TOPO_TABLE_STATEMENTS);
158
+ runStatements(db, TOPO_INDEX_STATEMENTS);
159
+ };
160
+ /**
161
+ * Current topo subsystem schema version.
162
+ *
163
+ * Version 8 adds `pattern TEXT` column to `topo_trails`.
164
+ *
165
+ * Version 7 defined the snapshot-first topo tables (`topo_snapshots`,
166
+ * `topo_surfaces`, and `snapshot_id` foreign keys) as the only supported
167
+ * schema. Older pre-release tables are ignored in place; we create the current
168
+ * tables and advance the subsystem version without translating or deleting
169
+ * legacy rows.
170
+ */
171
+ export const TOPO_SCHEMA_VERSION = 8;
172
+ export const ensureTopoSnapshotSchema = (db) => {
173
+ ensureSubsystemSchema(db, {
174
+ migrate: (currentVersion) => {
175
+ createAllTopoTables(db);
176
+ if (currentVersion === 7) {
177
+ db.run('ALTER TABLE topo_trails ADD COLUMN pattern TEXT');
178
+ }
179
+ },
180
+ subsystem: TOPO_SUBSYSTEM,
181
+ version: TOPO_SCHEMA_VERSION,
182
+ });
183
+ };
184
+ export const insertTopoSnapshotRecord = (db, input) => {
185
+ const record = {
186
+ createdAt: input?.createdAt ?? new Date().toISOString(),
187
+ gitDirty: input?.gitDirty ?? false,
188
+ id: input?.id ?? Bun.randomUUIDv7(),
189
+ resourceCount: input?.resourceCount ?? 0,
190
+ signalCount: input?.signalCount ?? 0,
191
+ trailCount: input?.trailCount ?? 0,
192
+ ...(input?.gitSha === undefined ? {} : { gitSha: input.gitSha }),
193
+ };
194
+ db.run(`INSERT INTO topo_snapshots (
195
+ id, git_sha, git_dirty, trail_count, signal_count, resource_count, pinned_as, created_at
196
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
197
+ record.id,
198
+ record.gitSha ?? null,
199
+ record.gitDirty ? 1 : 0,
200
+ record.trailCount,
201
+ record.signalCount,
202
+ record.resourceCount,
203
+ null,
204
+ record.createdAt,
205
+ ]);
206
+ return record;
207
+ };
208
+ const normalizeLimit = (limit) => {
209
+ if (limit === undefined) {
210
+ return undefined;
211
+ }
212
+ return Math.max(0, Math.trunc(limit));
213
+ };
214
+ export const readTopoSnapshot = (db, id) => {
215
+ if (!tableExists(db, 'topo_snapshots')) {
216
+ return undefined;
217
+ }
218
+ const row = db
219
+ .query(`SELECT id, git_sha, git_dirty, trail_count, signal_count, resource_count, pinned_as, created_at
220
+ FROM topo_snapshots
221
+ WHERE id = ?`)
222
+ .get(id);
223
+ return row === null || row === undefined ? undefined : rowToSnapshot(row);
224
+ };
225
+ export const readPinnedTopoSnapshot = (db, name) => {
226
+ if (!tableExists(db, 'topo_snapshots')) {
227
+ return undefined;
228
+ }
229
+ const row = db
230
+ .query(`SELECT id, git_sha, git_dirty, trail_count, signal_count, resource_count, pinned_as, created_at
231
+ FROM topo_snapshots
232
+ WHERE pinned_as = ?
233
+ LIMIT 1`)
234
+ .get(name);
235
+ return row === null || row === undefined ? undefined : rowToSnapshot(row);
236
+ };
237
+ const applyBeforeSnapshotClause = (db, beforeId, bindings, conditions) => {
238
+ if (beforeId === undefined) {
239
+ return true;
240
+ }
241
+ const before = readTopoSnapshot(db, beforeId);
242
+ if (before === undefined) {
243
+ return false;
244
+ }
245
+ conditions.push('(created_at < ? OR (created_at = ? AND id < ?))');
246
+ bindings.push(before.createdAt, before.createdAt, before.id);
247
+ return true;
248
+ };
249
+ const applyPinnedSnapshotClause = (pinned, conditions) => {
250
+ if (pinned === true) {
251
+ conditions.push('pinned_as IS NOT NULL');
252
+ return;
253
+ }
254
+ if (pinned === false) {
255
+ conditions.push('pinned_as IS NULL');
256
+ }
257
+ };
258
+ const buildSnapshotWhereClause = (conditions) => conditions.length === 0 ? '' : ` WHERE ${conditions.join(' AND ')}`;
259
+ const buildSnapshotLimitClause = (limit, bindings) => {
260
+ if (limit === undefined) {
261
+ return '';
262
+ }
263
+ bindings.push(limit);
264
+ return ' LIMIT ?';
265
+ };
266
+ const listSnapshotRows = (db, options) => {
267
+ if (!tableExists(db, 'topo_snapshots')) {
268
+ return [];
269
+ }
270
+ const bindings = [];
271
+ const conditions = [];
272
+ if (!applyBeforeSnapshotClause(db, options?.before, bindings, conditions)) {
273
+ return [];
274
+ }
275
+ applyPinnedSnapshotClause(options?.pinned, conditions);
276
+ const whereClause = buildSnapshotWhereClause(conditions);
277
+ const limitClause = buildSnapshotLimitClause(normalizeLimit(options?.limit), bindings);
278
+ return db
279
+ .query(`SELECT id, git_sha, git_dirty, trail_count, signal_count, resource_count, pinned_as, created_at
280
+ FROM topo_snapshots${whereClause}
281
+ ORDER BY created_at DESC, id DESC${limitClause}`)
282
+ .all(...bindings);
283
+ };
284
+ export const listTopoSnapshots = (db, options) => listSnapshotRows(db, options).map(rowToSnapshot);
285
+ const countSnapshots = (db, whereClause) => {
286
+ const query = whereClause === undefined
287
+ ? 'SELECT COUNT(*) as count FROM topo_snapshots'
288
+ : `SELECT COUNT(*) as count FROM topo_snapshots WHERE ${whereClause}`;
289
+ const row = db.query(query).get();
290
+ return row?.count ?? 0;
291
+ };
292
+ export const countTopoSnapshots = (db) => {
293
+ if (!tableExists(db, 'topo_snapshots')) {
294
+ return 0;
295
+ }
296
+ return countSnapshots(db);
297
+ };
298
+ export const countPinnedSnapshots = (db) => {
299
+ if (!tableExists(db, 'topo_snapshots')) {
300
+ return 0;
301
+ }
302
+ return countSnapshots(db, 'pinned_as IS NOT NULL');
303
+ };
304
+ export const countPrunableSnapshots = (db, options) => {
305
+ if (!tableExists(db, 'topo_snapshots')) {
306
+ return 0;
307
+ }
308
+ const row = db
309
+ .query(`SELECT COUNT(*) as count
310
+ FROM (
311
+ SELECT id
312
+ FROM topo_snapshots
313
+ WHERE pinned_as IS NULL
314
+ ORDER BY created_at DESC, id DESC
315
+ LIMIT -1 OFFSET ?
316
+ )`)
317
+ .get(options.keep);
318
+ return row?.count ?? 0;
319
+ };
320
+ export const createTopoSnapshot = (db, input) => {
321
+ ensureTopoSnapshotSchema(db);
322
+ return insertTopoSnapshotRecord(db, input);
323
+ };
324
+ export const pinTopoSnapshot = (db, input) => {
325
+ ensureTopoSnapshotSchema(db);
326
+ return db.transaction(() => {
327
+ const snapshot = readTopoSnapshot(db, input.id);
328
+ if (snapshot === undefined) {
329
+ return;
330
+ }
331
+ db.run('UPDATE topo_snapshots SET pinned_as = NULL WHERE pinned_as = ?', [
332
+ input.name,
333
+ ]);
334
+ db.run('UPDATE topo_snapshots SET pinned_as = ? WHERE id = ?', [
335
+ input.name,
336
+ input.id,
337
+ ]);
338
+ return readTopoSnapshot(db, input.id);
339
+ })();
340
+ };
341
+ export const unpinTopoSnapshot = (db, nameOrId) => {
342
+ ensureTopoSnapshotSchema(db);
343
+ return db.transaction(() => {
344
+ const snapshot = readPinnedTopoSnapshot(db, nameOrId) ?? readTopoSnapshot(db, nameOrId);
345
+ if (snapshot?.pinnedAs === undefined) {
346
+ return;
347
+ }
348
+ db.run('UPDATE topo_snapshots SET pinned_as = NULL WHERE id = ?', [
349
+ snapshot.id,
350
+ ]);
351
+ return readTopoSnapshot(db, snapshot.id);
352
+ })();
353
+ };
354
+ export const pruneUnpinnedSnapshots = (db, options) => {
355
+ if (!tableExists(db, 'topo_snapshots')) {
356
+ return 0;
357
+ }
358
+ if (countPrunableSnapshots(db, options) === 0) {
359
+ return 0;
360
+ }
361
+ db.run(`DELETE FROM topo_snapshots
362
+ WHERE id IN (
363
+ SELECT id
364
+ FROM topo_snapshots
365
+ WHERE pinned_as IS NULL
366
+ ORDER BY created_at DESC, id DESC
367
+ LIMIT -1 OFFSET ?
368
+ )`, [options.keep]);
369
+ return (db.query('SELECT changes() as changes').get()
370
+ ?.changes ?? 0);
371
+ };
372
+ //# sourceMappingURL=topo-snapshots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topo-snapshots.js","sourceRoot":"","sources":["../../src/internal/topo-snapshots.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { Database, SQLQueryBindings } from 'bun:sqlite';
2
+ import type { ListTopoSnapshotsOptions, TopoSnapshot } from './topo-snapshots.js';
3
+ import type { StoredTopoExport } from './topo-store.js';
4
+ export interface TopoStoreRef {
5
+ readonly pin?: string;
6
+ readonly snapshotId?: string;
7
+ }
8
+ export interface TopoStoreTrailRecord {
9
+ readonly description: string | null;
10
+ readonly exampleCount: number;
11
+ readonly hasExamples: boolean;
12
+ readonly hasOutput: boolean;
13
+ readonly id: string;
14
+ readonly idempotent: boolean;
15
+ readonly intent: 'destroy' | 'read' | 'write';
16
+ readonly kind: 'trail';
17
+ readonly meta: Readonly<Record<string, unknown>> | null;
18
+ readonly pattern: string | null;
19
+ readonly safety: '-' | 'destroy' | 'read' | 'write';
20
+ readonly snapshotId: string;
21
+ }
22
+ export interface TopoStoreExampleRecord {
23
+ readonly description: string | null;
24
+ readonly error: string | null;
25
+ readonly expected: unknown;
26
+ readonly input: unknown;
27
+ readonly name: string;
28
+ readonly ordinal: number;
29
+ }
30
+ export interface TopoStoreTrailDetailRecord extends TopoStoreTrailRecord {
31
+ readonly crosses: readonly string[];
32
+ readonly detours: readonly {
33
+ readonly on: string;
34
+ readonly maxAttempts: number;
35
+ }[] | null;
36
+ readonly examples: readonly TopoStoreExampleRecord[];
37
+ readonly resources: readonly string[];
38
+ }
39
+ export interface TopoStoreResourceRecord {
40
+ readonly description: string | null;
41
+ readonly hasHealth: boolean;
42
+ readonly hasMock: boolean;
43
+ readonly health: 'available' | 'none';
44
+ readonly id: string;
45
+ readonly kind: 'resource';
46
+ readonly lifetime: 'singleton';
47
+ readonly snapshotId: string;
48
+ readonly usedBy: readonly string[];
49
+ }
50
+ export interface TopoStoreExportRecord extends StoredTopoExport {
51
+ readonly snapshot: TopoSnapshot;
52
+ }
53
+ export declare const readTopoStoreSnapshot: (db: Database, ref?: TopoStoreRef) => TopoSnapshot | undefined;
54
+ export declare const listTopoStoreSnapshots: (db: Database, options?: ListTopoSnapshotsOptions) => readonly TopoSnapshot[];
55
+ export declare const getTopoStoreExport: (db: Database, ref?: TopoStoreRef) => TopoStoreExportRecord | undefined;
56
+ export declare const listTopoStoreTrails: (db: Database, options?: {
57
+ readonly intent?: TopoStoreTrailRecord["intent"];
58
+ readonly snapshot?: TopoStoreRef;
59
+ }) => readonly TopoStoreTrailRecord[];
60
+ export declare const getTopoStoreTrail: (db: Database, trailId: string, options?: {
61
+ readonly snapshot?: TopoStoreRef;
62
+ }) => TopoStoreTrailDetailRecord | undefined;
63
+ export declare const listTopoStoreResources: (db: Database, options?: {
64
+ readonly snapshot?: TopoStoreRef;
65
+ }) => readonly TopoStoreResourceRecord[];
66
+ export declare const getTopoStoreResource: (db: Database, resourceId: string, options?: {
67
+ readonly snapshot?: TopoStoreRef;
68
+ }) => TopoStoreResourceRecord | undefined;
69
+ export declare const queryTopoStore: <TRow extends Record<string, unknown>>(db: Database, sql: string, bindings?: readonly SQLQueryBindings[]) => readonly TRow[];
70
+ //# sourceMappingURL=topo-store-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topo-store-read.d.ts","sourceRoot":"","sources":["../../src/internal/topo-store-read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,221 @@
1
+ import { ValidationError } from '../errors.js';
2
+ import { listTopoSnapshots, readPinnedTopoSnapshot, readTopoSnapshot, } from './topo-snapshots.js';
3
+ import { getStoredTopoExport } from './topo-store.js';
4
+ const ensureSingleRefSelector = (ref) => {
5
+ if (ref?.pin !== undefined && ref.snapshotId !== undefined) {
6
+ throw new ValidationError('Topo store references may use pin or snapshotId, not both');
7
+ }
8
+ };
9
+ const normalizeIntent = (intent) => {
10
+ if (intent === 'destroy' || intent === 'read') {
11
+ return intent;
12
+ }
13
+ return 'write';
14
+ };
15
+ const safetyForIntent = (intent) => {
16
+ if (intent === 'destroy') {
17
+ return 'destroy';
18
+ }
19
+ if (intent === 'read') {
20
+ return 'read';
21
+ }
22
+ return 'write';
23
+ };
24
+ const parseMeta = (value) => value === null
25
+ ? null
26
+ : JSON.parse(value);
27
+ const parseJson = (value) => JSON.parse(value);
28
+ const readSnapshotRef = (db, ref) => {
29
+ ensureSingleRefSelector(ref);
30
+ if (ref?.snapshotId !== undefined) {
31
+ return readTopoSnapshot(db, ref.snapshotId);
32
+ }
33
+ if (ref?.pin !== undefined) {
34
+ return readPinnedTopoSnapshot(db, ref.pin);
35
+ }
36
+ return listTopoSnapshots(db, { limit: 1 })[0];
37
+ };
38
+ const readStoredEntry = (db, snapshotId, kind, id) => {
39
+ const stored = getStoredTopoExport(db, snapshotId);
40
+ if (stored === undefined) {
41
+ return undefined;
42
+ }
43
+ const map = JSON.parse(stored.surfaceMapJson);
44
+ return map.entries.find((entry) => entry.id === id && entry.kind === kind);
45
+ };
46
+ const mapTrailRow = (row) => {
47
+ const intent = normalizeIntent(row.intent);
48
+ return {
49
+ description: row.description,
50
+ exampleCount: row.example_count,
51
+ hasExamples: row.has_examples === 1,
52
+ hasOutput: row.has_output === 1,
53
+ id: row.id,
54
+ idempotent: row.idempotent === 1,
55
+ intent,
56
+ kind: 'trail',
57
+ meta: parseMeta(row.meta),
58
+ pattern: row.pattern,
59
+ safety: safetyForIntent(intent),
60
+ snapshotId: row.snapshot_id,
61
+ };
62
+ };
63
+ const readTrailCrossings = (db, snapshotId, trailId) => db
64
+ .query(`SELECT target_id
65
+ FROM topo_crossings
66
+ WHERE snapshot_id = ? AND source_id = ?
67
+ ORDER BY target_id ASC`)
68
+ .all(snapshotId, trailId)
69
+ .map((row) => row.target_id);
70
+ const readTrailResourceIds = (db, snapshotId, trailId) => db
71
+ .query(`SELECT resource_id
72
+ FROM topo_trail_resources
73
+ WHERE snapshot_id = ? AND trail_id = ?
74
+ ORDER BY resource_id ASC`)
75
+ .all(snapshotId, trailId)
76
+ .map((row) => row.resource_id);
77
+ const readTrailExamples = (db, snapshotId, trailId) => db
78
+ .query(`SELECT ordinal, name, description, input, expected, error
79
+ FROM topo_examples
80
+ WHERE snapshot_id = ? AND trail_id = ?
81
+ ORDER BY ordinal ASC`)
82
+ .all(snapshotId, trailId)
83
+ .map((row) => ({
84
+ description: row.description,
85
+ error: row.error,
86
+ expected: row.expected === null ? null : parseJson(row.expected),
87
+ input: parseJson(row.input),
88
+ name: row.name,
89
+ ordinal: row.ordinal,
90
+ }));
91
+ const readResourceUsage = (db, snapshotId) => {
92
+ const rows = db
93
+ .query(`SELECT resource_id, trail_id
94
+ FROM topo_trail_resources
95
+ WHERE snapshot_id = ?
96
+ ORDER BY resource_id ASC, trail_id ASC`)
97
+ .all(snapshotId);
98
+ const usage = new Map();
99
+ for (const row of rows) {
100
+ const trails = usage.get(row.resource_id) ?? [];
101
+ trails.push(row.trail_id);
102
+ usage.set(row.resource_id, trails);
103
+ }
104
+ return new Map([...usage.entries()].map(([id, trails]) => [id, trails]));
105
+ };
106
+ export const readTopoStoreSnapshot = (db, ref) => readSnapshotRef(db, ref);
107
+ export const listTopoStoreSnapshots = (db, options) => listTopoSnapshots(db, options);
108
+ export const getTopoStoreExport = (db, ref) => {
109
+ const snapshot = readSnapshotRef(db, ref);
110
+ if (snapshot === undefined) {
111
+ return undefined;
112
+ }
113
+ const stored = getStoredTopoExport(db, snapshot.id);
114
+ if (stored === undefined) {
115
+ return undefined;
116
+ }
117
+ return {
118
+ ...stored,
119
+ snapshot,
120
+ };
121
+ };
122
+ export const listTopoStoreTrails = (db, options) => {
123
+ const snapshot = readSnapshotRef(db, options?.snapshot);
124
+ if (snapshot === undefined) {
125
+ return [];
126
+ }
127
+ const baseQuery = `SELECT id, intent, idempotent, has_output, has_examples, example_count, description, pattern, meta, snapshot_id
128
+ FROM topo_trails`;
129
+ let rows;
130
+ if (options?.intent === undefined) {
131
+ rows = db
132
+ .query(`${baseQuery} WHERE snapshot_id = ? ORDER BY id ASC`)
133
+ .all(snapshot.id);
134
+ }
135
+ else if (options.intent === 'write') {
136
+ rows = db
137
+ .query(`${baseQuery} WHERE snapshot_id = ? AND intent = 'write' ORDER BY id ASC`)
138
+ .all(snapshot.id);
139
+ }
140
+ else {
141
+ rows = db
142
+ .query(`${baseQuery} WHERE snapshot_id = ? AND intent = ? ORDER BY id ASC`)
143
+ .all(snapshot.id, options.intent);
144
+ }
145
+ return rows.map(mapTrailRow);
146
+ };
147
+ export const getTopoStoreTrail = (db, trailId, options) => {
148
+ const snapshot = readSnapshotRef(db, options?.snapshot);
149
+ if (snapshot === undefined) {
150
+ return undefined;
151
+ }
152
+ const row = db
153
+ .query(`SELECT id, intent, idempotent, has_output, has_examples, example_count, description, pattern, meta, snapshot_id
154
+ FROM topo_trails
155
+ WHERE snapshot_id = ? AND id = ?
156
+ LIMIT 1`)
157
+ .get(snapshot.id, trailId);
158
+ if (row === null || row === undefined) {
159
+ return undefined;
160
+ }
161
+ const storedEntry = readStoredEntry(db, snapshot.id, 'trail', trailId);
162
+ return {
163
+ ...mapTrailRow(row),
164
+ crosses: readTrailCrossings(db, snapshot.id, trailId),
165
+ detours: storedEntry?.detours ?? null,
166
+ examples: readTrailExamples(db, snapshot.id, trailId),
167
+ resources: readTrailResourceIds(db, snapshot.id, trailId),
168
+ };
169
+ };
170
+ const mapResourceRow = (row, usedBy, storedEntry) => ({
171
+ description: storedEntry?.description ?? null,
172
+ hasHealth: row.has_health === 1,
173
+ hasMock: row.has_mock === 1,
174
+ health: row.has_health === 1 || storedEntry?.healthcheck === true
175
+ ? 'available'
176
+ : 'none',
177
+ id: row.id,
178
+ kind: 'resource',
179
+ lifetime: 'singleton',
180
+ snapshotId: row.snapshot_id,
181
+ usedBy,
182
+ });
183
+ export const listTopoStoreResources = (db, options) => {
184
+ const snapshot = readSnapshotRef(db, options?.snapshot);
185
+ if (snapshot === undefined) {
186
+ return [];
187
+ }
188
+ const usage = readResourceUsage(db, snapshot.id);
189
+ const rows = db
190
+ .query(`SELECT id, has_mock, has_health, snapshot_id
191
+ FROM topo_resources
192
+ WHERE snapshot_id = ?
193
+ ORDER BY id ASC`)
194
+ .all(snapshot.id);
195
+ const stored = getStoredTopoExport(db, snapshot.id);
196
+ const entries = stored
197
+ ? JSON.parse(stored.surfaceMapJson).entries
198
+ : [];
199
+ return rows.map((row) => mapResourceRow(row, usage.get(row.id) ?? [], entries.find((entry) => entry.id === row.id && entry.kind === 'resource')));
200
+ };
201
+ export const getTopoStoreResource = (db, resourceId, options) => {
202
+ const snapshot = readSnapshotRef(db, options?.snapshot);
203
+ if (snapshot === undefined) {
204
+ return undefined;
205
+ }
206
+ const row = db
207
+ .query(`SELECT id, has_mock, has_health, snapshot_id
208
+ FROM topo_resources
209
+ WHERE snapshot_id = ? AND id = ?
210
+ LIMIT 1`)
211
+ .get(snapshot.id, resourceId);
212
+ if (row === null || row === undefined) {
213
+ return undefined;
214
+ }
215
+ const usage = readResourceUsage(db, snapshot.id);
216
+ return mapResourceRow(row, usage.get(resourceId) ?? [], readStoredEntry(db, snapshot.id, 'resource', resourceId));
217
+ };
218
+ export const queryTopoStore = (db, sql, bindings) => db
219
+ .query(sql)
220
+ .all(...(bindings === undefined ? [] : [...bindings]));
221
+ //# sourceMappingURL=topo-store-read.js.map