@acquiredintelligence/attend 0.0.0-stage → 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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +580 -2
  3. package/dist/attend.d.ts +30 -0
  4. package/dist/attend.d.ts.map +1 -0
  5. package/dist/attend.js +428 -0
  6. package/dist/attend.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +4 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/core/ids.d.ts +12 -0
  12. package/dist/core/ids.d.ts.map +1 -0
  13. package/dist/core/ids.js +97 -0
  14. package/dist/core/ids.js.map +1 -0
  15. package/dist/core/reducer.d.ts +26 -0
  16. package/dist/core/reducer.d.ts.map +1 -0
  17. package/dist/core/reducer.js +437 -0
  18. package/dist/core/reducer.js.map +1 -0
  19. package/dist/core/seen.d.ts +22 -0
  20. package/dist/core/seen.d.ts.map +1 -0
  21. package/dist/core/seen.js +61 -0
  22. package/dist/core/seen.js.map +1 -0
  23. package/dist/core/state.d.ts +12 -0
  24. package/dist/core/state.d.ts.map +1 -0
  25. package/dist/core/state.js +90 -0
  26. package/dist/core/state.js.map +1 -0
  27. package/dist/core/step.d.ts +14 -0
  28. package/dist/core/step.d.ts.map +1 -0
  29. package/dist/core/step.js +17 -0
  30. package/dist/core/step.js.map +1 -0
  31. package/dist/core/threshold.d.ts +40 -0
  32. package/dist/core/threshold.d.ts.map +1 -0
  33. package/dist/core/threshold.js +72 -0
  34. package/dist/core/threshold.js.map +1 -0
  35. package/dist/core/types.d.ts +704 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +24 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/window.d.ts +38 -0
  40. package/dist/core/window.d.ts.map +1 -0
  41. package/dist/core/window.js +322 -0
  42. package/dist/core/window.js.map +1 -0
  43. package/dist/decisions.d.ts +53 -0
  44. package/dist/decisions.d.ts.map +1 -0
  45. package/dist/decisions.js +115 -0
  46. package/dist/decisions.js.map +1 -0
  47. package/dist/errors.d.ts +36 -0
  48. package/dist/errors.d.ts.map +1 -0
  49. package/dist/errors.js +53 -0
  50. package/dist/errors.js.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/internal/adapter.d.ts +21 -0
  56. package/dist/internal/adapter.d.ts.map +1 -0
  57. package/dist/internal/adapter.js +62 -0
  58. package/dist/internal/adapter.js.map +1 -0
  59. package/dist/internal/assert.d.ts +5 -0
  60. package/dist/internal/assert.d.ts.map +1 -0
  61. package/dist/internal/assert.js +14 -0
  62. package/dist/internal/assert.js.map +1 -0
  63. package/dist/internal/clock.d.ts +8 -0
  64. package/dist/internal/clock.d.ts.map +1 -0
  65. package/dist/internal/clock.js +38 -0
  66. package/dist/internal/clock.js.map +1 -0
  67. package/dist/internal/http.d.ts +42 -0
  68. package/dist/internal/http.d.ts.map +1 -0
  69. package/dist/internal/http.js +122 -0
  70. package/dist/internal/http.js.map +1 -0
  71. package/dist/internal/images.d.ts +18 -0
  72. package/dist/internal/images.d.ts.map +1 -0
  73. package/dist/internal/images.js +75 -0
  74. package/dist/internal/images.js.map +1 -0
  75. package/dist/internal/json.d.ts +3 -0
  76. package/dist/internal/json.d.ts.map +1 -0
  77. package/dist/internal/json.js +5 -0
  78. package/dist/internal/json.js.map +1 -0
  79. package/dist/internal/prompt.d.ts +31 -0
  80. package/dist/internal/prompt.d.ts.map +1 -0
  81. package/dist/internal/prompt.js +149 -0
  82. package/dist/internal/prompt.js.map +1 -0
  83. package/dist/internal/shared.d.ts +12 -0
  84. package/dist/internal/shared.d.ts.map +1 -0
  85. package/dist/internal/shared.js +134 -0
  86. package/dist/internal/shared.js.map +1 -0
  87. package/dist/jev.d.ts +74 -0
  88. package/dist/jev.d.ts.map +1 -0
  89. package/dist/jev.js +156 -0
  90. package/dist/jev.js.map +1 -0
  91. package/dist/llm.d.ts +164 -0
  92. package/dist/llm.d.ts.map +1 -0
  93. package/dist/llm.js +79 -0
  94. package/dist/llm.js.map +1 -0
  95. package/dist/mcp.d.ts +130 -0
  96. package/dist/mcp.d.ts.map +1 -0
  97. package/dist/mcp.js +550 -0
  98. package/dist/mcp.js.map +1 -0
  99. package/dist/memory.d.ts +10 -0
  100. package/dist/memory.d.ts.map +1 -0
  101. package/dist/memory.js +50 -0
  102. package/dist/memory.js.map +1 -0
  103. package/dist/postgres.d.ts +25 -0
  104. package/dist/postgres.d.ts.map +1 -0
  105. package/dist/postgres.js +56 -0
  106. package/dist/postgres.js.map +1 -0
  107. package/dist/redis.d.ts +20 -0
  108. package/dist/redis.d.ts.map +1 -0
  109. package/dist/redis.js +83 -0
  110. package/dist/redis.js.map +1 -0
  111. package/dist/server/compat.d.ts +13 -0
  112. package/dist/server/compat.d.ts.map +1 -0
  113. package/dist/server/compat.js +5 -0
  114. package/dist/server/compat.js.map +1 -0
  115. package/dist/server/cursor.d.ts +15 -0
  116. package/dist/server/cursor.d.ts.map +1 -0
  117. package/dist/server/cursor.js +50 -0
  118. package/dist/server/cursor.js.map +1 -0
  119. package/dist/server/events.d.ts +42 -0
  120. package/dist/server/events.d.ts.map +1 -0
  121. package/dist/server/events.js +189 -0
  122. package/dist/server/events.js.map +1 -0
  123. package/dist/server/fanout.d.ts +28 -0
  124. package/dist/server/fanout.d.ts.map +1 -0
  125. package/dist/server/fanout.js +184 -0
  126. package/dist/server/fanout.js.map +1 -0
  127. package/dist/server/guard.d.ts +19 -0
  128. package/dist/server/guard.d.ts.map +1 -0
  129. package/dist/server/guard.js +27 -0
  130. package/dist/server/guard.js.map +1 -0
  131. package/dist/server/http.d.ts +4 -0
  132. package/dist/server/http.d.ts.map +1 -0
  133. package/dist/server/http.js +323 -0
  134. package/dist/server/http.js.map +1 -0
  135. package/dist/server/ingest.d.ts +4 -0
  136. package/dist/server/ingest.d.ts.map +1 -0
  137. package/dist/server/ingest.js +400 -0
  138. package/dist/server/ingest.js.map +1 -0
  139. package/dist/server/install.d.ts +5 -0
  140. package/dist/server/install.d.ts.map +1 -0
  141. package/dist/server/install.js +91 -0
  142. package/dist/server/install.js.map +1 -0
  143. package/dist/server/poll.d.ts +4 -0
  144. package/dist/server/poll.d.ts.map +1 -0
  145. package/dist/server/poll.js +45 -0
  146. package/dist/server/poll.js.map +1 -0
  147. package/dist/server/serve.d.ts +19 -0
  148. package/dist/server/serve.d.ts.map +1 -0
  149. package/dist/server/serve.js +238 -0
  150. package/dist/server/serve.js.map +1 -0
  151. package/dist/server/sessions.d.ts +14 -0
  152. package/dist/server/sessions.d.ts.map +1 -0
  153. package/dist/server/sessions.js +54 -0
  154. package/dist/server/sessions.js.map +1 -0
  155. package/dist/server/stream.d.ts +11 -0
  156. package/dist/server/stream.d.ts.map +1 -0
  157. package/dist/server/stream.js +216 -0
  158. package/dist/server/stream.js.map +1 -0
  159. package/dist/server/tools.d.ts +22 -0
  160. package/dist/server/tools.d.ts.map +1 -0
  161. package/dist/server/tools.js +55 -0
  162. package/dist/server/tools.js.map +1 -0
  163. package/dist/server/types.d.ts +351 -0
  164. package/dist/server/types.d.ts.map +1 -0
  165. package/dist/server/types.js +5 -0
  166. package/dist/server/types.js.map +1 -0
  167. package/dist/server.d.ts +11 -0
  168. package/dist/server.d.ts.map +1 -0
  169. package/dist/server.js +10 -0
  170. package/dist/server.js.map +1 -0
  171. package/dist/shell/budget.d.ts +4 -0
  172. package/dist/shell/budget.d.ts.map +1 -0
  173. package/dist/shell/budget.js +5 -0
  174. package/dist/shell/budget.js.map +1 -0
  175. package/dist/shell/copy.d.ts +17 -0
  176. package/dist/shell/copy.d.ts.map +1 -0
  177. package/dist/shell/copy.js +67 -0
  178. package/dist/shell/copy.js.map +1 -0
  179. package/dist/shell/decisions.d.ts +6 -0
  180. package/dist/shell/decisions.d.ts.map +1 -0
  181. package/dist/shell/decisions.js +42 -0
  182. package/dist/shell/decisions.js.map +1 -0
  183. package/dist/shell/read.d.ts +7 -0
  184. package/dist/shell/read.d.ts.map +1 -0
  185. package/dist/shell/read.js +21 -0
  186. package/dist/shell/read.js.map +1 -0
  187. package/dist/shell/scheduler.d.ts +4 -0
  188. package/dist/shell/scheduler.d.ts.map +1 -0
  189. package/dist/shell/scheduler.js +90 -0
  190. package/dist/shell/scheduler.js.map +1 -0
  191. package/dist/shell/scope.d.ts +27 -0
  192. package/dist/shell/scope.d.ts.map +1 -0
  193. package/dist/shell/scope.js +343 -0
  194. package/dist/shell/scope.js.map +1 -0
  195. package/dist/shell/types.d.ts +156 -0
  196. package/dist/shell/types.d.ts.map +1 -0
  197. package/dist/shell/types.js +2 -0
  198. package/dist/shell/types.js.map +1 -0
  199. package/dist/sqlite.d.ts +14 -0
  200. package/dist/sqlite.d.ts.map +1 -0
  201. package/dist/sqlite.js +39 -0
  202. package/dist/sqlite.js.map +1 -0
  203. package/dist/step.d.ts +18 -0
  204. package/dist/step.d.ts.map +1 -0
  205. package/dist/step.js +14 -0
  206. package/dist/step.js.map +1 -0
  207. package/dist/store/memory.d.ts +12 -0
  208. package/dist/store/memory.d.ts.map +1 -0
  209. package/dist/store/memory.js +264 -0
  210. package/dist/store/memory.js.map +1 -0
  211. package/dist/store/postgres.d.ts +24 -0
  212. package/dist/store/postgres.d.ts.map +1 -0
  213. package/dist/store/postgres.js +364 -0
  214. package/dist/store/postgres.js.map +1 -0
  215. package/dist/store/redis.d.ts +12 -0
  216. package/dist/store/redis.d.ts.map +1 -0
  217. package/dist/store/redis.js +540 -0
  218. package/dist/store/redis.js.map +1 -0
  219. package/dist/store/sqlite-worker.d.ts +91 -0
  220. package/dist/store/sqlite-worker.d.ts.map +1 -0
  221. package/dist/store/sqlite-worker.js +322 -0
  222. package/dist/store/sqlite-worker.js.map +1 -0
  223. package/dist/store/sqlite.d.ts +34 -0
  224. package/dist/store/sqlite.d.ts.map +1 -0
  225. package/dist/store/sqlite.js +238 -0
  226. package/dist/store/sqlite.js.map +1 -0
  227. package/dist/store/types.d.ts +137 -0
  228. package/dist/store/types.d.ts.map +1 -0
  229. package/dist/store/types.js +2 -0
  230. package/dist/store/types.js.map +1 -0
  231. package/dist/testing/conformance.d.ts +13 -0
  232. package/dist/testing/conformance.d.ts.map +1 -0
  233. package/dist/testing/conformance.js +542 -0
  234. package/dist/testing/conformance.js.map +1 -0
  235. package/dist/testing/wire.d.ts +16 -0
  236. package/dist/testing/wire.d.ts.map +1 -0
  237. package/dist/testing/wire.js +304 -0
  238. package/dist/testing/wire.js.map +1 -0
  239. package/dist/testing.d.ts +113 -0
  240. package/dist/testing.d.ts.map +1 -0
  241. package/dist/testing.js +655 -0
  242. package/dist/testing.js.map +1 -0
  243. package/dist/types.d.ts +5 -0
  244. package/dist/types.d.ts.map +1 -0
  245. package/dist/types.js +5 -0
  246. package/dist/types.js.map +1 -0
  247. package/package.json +130 -4
  248. package/skills/attend/SKILL.md +231 -0
  249. package/skills/attend/references/judges.md +283 -0
  250. package/skills/attend/references/kinds.md +62 -0
  251. package/skills/attend/references/mcp.md +132 -0
  252. package/skills/attend/references/sinks.md +73 -0
  253. package/skills/attend/references/stores.md +90 -0
  254. package/skills/attend/references/testing.md +120 -0
@@ -0,0 +1,364 @@
1
+ import { boundary } from '../internal/adapter.js';
2
+ const { column, parseRecord, tablePrefix, text } = boundary('attend/postgres');
3
+ /** Creates the scopes, inputs, snapshots, decisions and meta tables. Idempotent. Needs PostgreSQL 13 or later. */
4
+ export async function migrate(client, options) {
5
+ const p = tablePrefix(options?.prefix, { lowercase: true });
6
+ // fillfactor 50 leaves room on every page of scope rows, so version bumps stay HOT once thousands of scopes fill the table.
7
+ await client.query(`SELECT pg_advisory_xact_lock(hashtext('attend.migrate'));
8
+ CREATE TABLE IF NOT EXISTS ${p}scopes (scope text COLLATE "C" PRIMARY KEY, version bigint NOT NULL, due double precision) WITH (fillfactor = 50);
9
+ CREATE INDEX IF NOT EXISTS ${p}scopes_due ON ${p}scopes (due, scope) WHERE due IS NOT NULL;
10
+ CREATE TABLE IF NOT EXISTS ${p}inputs (scope text COLLATE "C" NOT NULL, version bigint NOT NULL, input json NOT NULL, PRIMARY KEY (scope, version));
11
+ CREATE TABLE IF NOT EXISTS ${p}snapshots (scope text COLLATE "C" PRIMARY KEY, version bigint NOT NULL, policy json NOT NULL, reducer int NOT NULL, record json NOT NULL);
12
+ CREATE TABLE IF NOT EXISTS ${p}decisions (
13
+ txid xid8 NOT NULL DEFAULT pg_current_xact_id(), n int NOT NULL, scope text COLLATE "C" NOT NULL,
14
+ kind text NOT NULL, id text NOT NULL, route text, at double precision NOT NULL, body json NOT NULL,
15
+ PRIMARY KEY (txid, n), UNIQUE (kind, id));
16
+ CREATE INDEX IF NOT EXISTS ${p}decisions_scope ON ${p}decisions (scope, txid, n);
17
+ CREATE INDEX IF NOT EXISTS ${p}decisions_at ON ${p}decisions (at);
18
+ CREATE TABLE IF NOT EXISTS ${p}meta (key text PRIMARY KEY, value text NOT NULL);
19
+ INSERT INTO ${p}meta (key, value) VALUES ('epoch', gen_random_uuid()::text) ON CONFLICT DO NOTHING;
20
+ CREATE OR REPLACE FUNCTION ${p}decisions_notify() RETURNS trigger LANGUAGE plpgsql AS $$
21
+ BEGIN
22
+ IF EXISTS (SELECT 1 FROM added) THEN PERFORM pg_notify('${p}decisions', ''); END IF;
23
+ RETURN NULL;
24
+ END $$;
25
+ DO $$ BEGIN
26
+ IF NOT EXISTS (SELECT 1 FROM pg_trigger WHERE tgrelid = '${p}decisions'::regclass AND tgname = '${p}decisions_notify') THEN
27
+ CREATE TRIGGER ${p}decisions_notify AFTER INSERT ON ${p}decisions REFERENCING NEW TABLE AS added
28
+ FOR EACH STATEMENT EXECUTE FUNCTION ${p}decisions_notify();
29
+ END IF;
30
+ END $$;
31
+ CREATE OR REPLACE FUNCTION ${p}remove(target text) RETURNS void LANGUAGE plpgsql AS $$
32
+ BEGIN
33
+ DELETE FROM ${p}scopes WHERE scope = target;
34
+ DELETE FROM ${p}inputs WHERE scope = target;
35
+ DELETE FROM ${p}snapshots WHERE scope = target;
36
+ END $$;`);
37
+ }
38
+ export function postgresStore(client, options) {
39
+ const p = tablePrefix(options?.prefix, { lowercase: true });
40
+ const horizon = 'h AS MATERIALIZED (SELECT pg_snapshot_xmin(pg_current_snapshot()) AS xid)';
41
+ const position = "txid::text || '.' || n::text";
42
+ const head = `SELECT ${position} FROM ${p}decisions, h WHERE txid < (SELECT xid FROM h) ORDER BY txid DESC, n DESC LIMIT 1`;
43
+ let ownTxid;
44
+ let visible = 0n;
45
+ let epoch;
46
+ let closed = false;
47
+ let listening;
48
+ let retained;
49
+ let lastTrim = -Infinity;
50
+ const wakeups = new Set();
51
+ const wake = () => { for (const notify of wakeups)
52
+ notify(); };
53
+ // The horizon is cluster-wide, so this store's newest rows can sit above it for a moment; waiting lets it read its own writes.
54
+ async function settle() {
55
+ const target = ownTxid;
56
+ if (target === undefined || target < visible)
57
+ return;
58
+ const deadline = Date.now() + 2000;
59
+ for (let delay = 1; !closed; delay = Math.min(delay * 2, 50)) {
60
+ const { rows } = await client.query('SELECT pg_snapshot_xmin(pg_current_snapshot())::text AS xid');
61
+ const horizon = BigInt(text(column(rows[0], 'xid')));
62
+ if (horizon > visible)
63
+ visible = horizon;
64
+ if (horizon > target)
65
+ return;
66
+ if (Date.now() >= deadline) {
67
+ if (target >= visible)
68
+ visible = target + 1n;
69
+ return;
70
+ }
71
+ await new Promise((resolve) => setTimeout(resolve, delay));
72
+ }
73
+ }
74
+ function listen() {
75
+ return listening ??= options?.listener?.listen(`${p}decisions`, wake).catch(() => undefined) ?? Promise.resolve(undefined);
76
+ }
77
+ const log = {
78
+ epoch() {
79
+ return epoch ??= client.query(`SELECT value FROM ${p}meta WHERE key = 'epoch'`).then(({ rows }) => text(column(rows[0], 'value')), (error) => { epoch = undefined; throw error; });
80
+ },
81
+ compare,
82
+ async bounds() {
83
+ await settle();
84
+ const { rows } = await client.query(`WITH ${horizon} SELECT
85
+ (SELECT ${position} FROM ${p}decisions, h WHERE txid < (SELECT xid FROM h) ORDER BY txid, n LIMIT 1) AS first,
86
+ (${head}) AS last`);
87
+ return { first: nullableText(column(rows[0], 'first')), last: nullableText(column(rows[0], 'last')) };
88
+ },
89
+ async find(kind, id) {
90
+ await settle();
91
+ const { rows } = await client.query(`WITH ${horizon} SELECT d.*, ${position} AS position FROM ${p}decisions d, h
92
+ WHERE kind = $1 AND id = $2 AND txid < (SELECT xid FROM h)`, [kind, id]);
93
+ return rows.length === 0 ? null : decisionRow(rows[0]);
94
+ },
95
+ async read(query) {
96
+ const after = query.after === null ? null : parsePosition(query.after);
97
+ await settle();
98
+ const values = [];
99
+ const bind = (value) => { values.push(value); return `$${values.length}`; };
100
+ const where = ['txid < (SELECT xid FROM h)'];
101
+ if (after)
102
+ where.push(`(txid, n) > (${bind(after.txid)}::xid8, ${bind(after.n)}::int)`);
103
+ if (query.scope !== undefined)
104
+ where.push(`scope = ${bind(query.scope)}`);
105
+ const hits = [];
106
+ if (query.scopePrefix !== undefined)
107
+ hits.push(`starts_with(scope, ${bind(query.scopePrefix)})`);
108
+ if (query.kinds !== undefined)
109
+ hits.push(`kind = ANY(${bind(query.kinds)}::text[])`);
110
+ if (query.routes !== undefined)
111
+ hits.push(`route = ANY(${bind(query.routes)}::text[])`);
112
+ if (query.sinceAt !== undefined)
113
+ hits.push(`at >= ${bind(query.sinceAt)}`);
114
+ const scanLimit = query.scanLimit ?? 4 * query.limit;
115
+ const candidates = bind(scanLimit + 1);
116
+ const limit = bind(query.limit);
117
+ const { rows } = await client.query(`WITH ${horizon}, candidates AS MATERIALIZED (
118
+ SELECT d.*, COALESCE(${hits.join(' AND ') || 'true'}, false) AS hit FROM ${p}decisions d, h
119
+ WHERE ${where.join(' AND ')} ORDER BY txid, n LIMIT ${candidates}
120
+ ), ranked AS (
121
+ SELECT *, count(*) FILTER (WHERE hit) OVER (ORDER BY txid, n) AS hits FROM candidates
122
+ ), head AS (SELECT (${head}) AS head)
123
+ SELECT head.head, ${position} AS position, scope, kind, id, route, at, hit,
124
+ CASE WHEN hit AND hits <= ${limit} THEN body END AS body
125
+ FROM head LEFT JOIN ranked ON true ORDER BY txid, n`, values);
126
+ const seenHead = nullableText(column(rows[0], 'head'));
127
+ const candidatesRows = rows.filter((row) => column(row, 'position') !== null);
128
+ const result = [];
129
+ let examined = 0;
130
+ let checked = query.after;
131
+ for (const row of candidatesRows) {
132
+ if (examined >= scanLimit || result.length >= query.limit)
133
+ break;
134
+ examined += 1;
135
+ checked = text(column(row, 'position'));
136
+ if (column(row, 'hit') === true)
137
+ result.push(decisionRow(row));
138
+ }
139
+ const more = examined < candidatesRows.length;
140
+ if (!more && seenHead !== null && (checked === null || compare(seenHead, checked) > 0))
141
+ checked = seenHead;
142
+ return { rows: result, checked, more };
143
+ },
144
+ async wait(after, blockMs, signal) {
145
+ if (signal.aborted || closed)
146
+ return;
147
+ let timer;
148
+ let resume;
149
+ let notified = false;
150
+ const notify = () => { notified = true; resume?.(); };
151
+ const abort = () => resume?.();
152
+ wakeups.add(notify);
153
+ signal.addEventListener('abort', abort);
154
+ try {
155
+ if (after !== null)
156
+ parsePosition(after);
157
+ const registration = listen();
158
+ let subscribed = false;
159
+ void registration.then((stop) => { subscribed = stop !== undefined; notify(); });
160
+ const deadline = Date.now() + blockMs;
161
+ let delay = 5;
162
+ while (!closed && !signal.aborted) {
163
+ notified = false;
164
+ const { rows } = await client.query(`WITH ${horizon} SELECT (${head}) AS head,
165
+ COALESCE((SELECT txid FROM ${p}decisions ORDER BY txid DESC, n DESC LIMIT 1) >= (SELECT xid FROM h), false) AS pending`);
166
+ const last = nullableText(column(rows[0], 'head'));
167
+ if (last !== null && (after === null || compare(last, after) > 0))
168
+ return;
169
+ const left = deadline - Date.now();
170
+ if (left <= 0 || closed || signal.aborted)
171
+ return;
172
+ if (notified) {
173
+ delay = 5;
174
+ continue;
175
+ }
176
+ const pending = column(rows[0], 'pending') === true;
177
+ const poll = pending ? delay : subscribed ? left : 100;
178
+ await new Promise((resolve) => {
179
+ resume = resolve;
180
+ timer = setTimeout(resolve, Math.min(left, poll));
181
+ });
182
+ clearTimeout(timer);
183
+ resume = undefined;
184
+ delay = notified ? 5 : Math.min(delay * 2, 250);
185
+ }
186
+ }
187
+ catch {
188
+ return;
189
+ }
190
+ finally {
191
+ clearTimeout(timer);
192
+ wakeups.delete(notify);
193
+ signal.removeEventListener('abort', abort);
194
+ }
195
+ },
196
+ async trim(retention) {
197
+ await settle();
198
+ const values = [];
199
+ const bind = (value) => { values.push(value); return `$${values.length}`; };
200
+ const ctes = [];
201
+ const floors = [];
202
+ if (retention.maxRows !== undefined) {
203
+ ctes.push(`count_floor AS (SELECT txid, n FROM visible ORDER BY txid DESC, n DESC OFFSET ${bind(Math.max(0, retention.maxRows - 1))} LIMIT 1)`);
204
+ floors.push('SELECT * FROM count_floor', 'SELECT * FROM oldest WHERE NOT EXISTS (SELECT 1 FROM count_floor)');
205
+ }
206
+ if (retention.olderThanMs !== undefined) {
207
+ ctes.push(`age_floor AS (SELECT txid, n FROM visible WHERE at >= ${bind(Date.now() - retention.olderThanMs)} ORDER BY txid, n LIMIT 1)`);
208
+ floors.push('SELECT * FROM age_floor', 'SELECT * FROM head WHERE NOT EXISTS (SELECT 1 FROM age_floor)');
209
+ }
210
+ if (ctes.length === 0)
211
+ return;
212
+ await client.query(`WITH ${horizon}, visible AS NOT MATERIALIZED (
213
+ SELECT txid, n, at FROM ${p}decisions, h WHERE txid < (SELECT xid FROM h)
214
+ ), head AS (SELECT txid, n FROM visible ORDER BY txid DESC, n DESC LIMIT 1),
215
+ oldest AS (SELECT txid, n FROM visible ORDER BY txid, n LIMIT 1),
216
+ ${ctes.join(', ')}, floor AS (
217
+ ${floors.join(' UNION ALL ')} ORDER BY txid DESC, n DESC LIMIT 1
218
+ ) DELETE FROM ${p}decisions d USING head, floor
219
+ WHERE (d.txid, d.n) < (head.txid, head.n) AND (d.txid, d.n) < (floor.txid, floor.n)`, values);
220
+ },
221
+ };
222
+ return {
223
+ durable: true,
224
+ log,
225
+ async load(scope) {
226
+ const { rows } = await client.query(`SELECT s.version, sn.version AS snapshot_version, sn.policy, sn.reducer, sn.record,
227
+ (SELECT json_agg(input ORDER BY version) FROM ${p}inputs WHERE scope = s.scope AND version > COALESCE(sn.version, 0)) AS tail
228
+ FROM ${p}scopes s LEFT JOIN ${p}snapshots sn USING (scope) WHERE s.scope = $1`, [scope]);
229
+ if (rows.length === 0)
230
+ return null;
231
+ const row = rows[0];
232
+ return {
233
+ version: number(column(row, 'version')),
234
+ snapshot: column(row, 'snapshot_version') === null ? null : {
235
+ version: number(column(row, 'snapshot_version')),
236
+ policy: json(column(row, 'policy')),
237
+ reducer: number(column(row, 'reducer')),
238
+ record: parseRecord(column(row, 'record'), scope),
239
+ },
240
+ tail: column(row, 'tail') === null ? [] : json(column(row, 'tail')),
241
+ };
242
+ },
243
+ async commit(writes) {
244
+ if (new Set(writes.map((write) => write.scope)).size !== writes.length)
245
+ throw new Error('attend/postgres: duplicate scope in group');
246
+ if (writes.length === 0)
247
+ return [];
248
+ const sorted = [...writes].sort((a, b) => a.scope < b.scope ? -1 : a.scope > b.scope ? 1 : 0);
249
+ const { sql, values, appends } = commitStatement(p, sorted, writes, options?.asyncCommit === true);
250
+ const { rows } = await client.query(sql, values);
251
+ const ok = new Set(rows.map((row) => text(column(row, 'scope'))));
252
+ const txid = appends && rows.length > 0 ? nullableText(column(rows[0], 'txid')) : null;
253
+ if (txid !== null) {
254
+ const committed = BigInt(txid);
255
+ if (ownTxid === undefined || committed > ownTxid)
256
+ ownTxid = committed;
257
+ if (options?.retain && !closed && !retained && Date.now() - lastTrim >= 60_000) {
258
+ lastTrim = Date.now();
259
+ // A failed background trim is retried by the next eligible commit.
260
+ retained = log.trim(options.retain).catch(() => { }).finally(() => { retained = undefined; });
261
+ }
262
+ }
263
+ return writes.map((write) => ok.has(write.scope) ? 'ok' : 'conflict');
264
+ },
265
+ async due(now, limit, after) {
266
+ const values = [now, limit];
267
+ if (after)
268
+ values.push(after.due, after.scope);
269
+ const { rows } = await client.query(`SELECT due, scope FROM ${p}scopes WHERE due <= $1
270
+ ${after ? 'AND (due, scope) > ($3, $4)' : ''} ORDER BY due, scope LIMIT $2`, values);
271
+ return rows.map((row) => ({ due: number(column(row, 'due')), scope: text(column(row, 'scope')) }));
272
+ },
273
+ async remove(scope) {
274
+ await client.query(`SELECT ${p}remove($1)`, [scope]);
275
+ },
276
+ async close() {
277
+ closed = true;
278
+ wake();
279
+ const stop = await listening;
280
+ await stop?.();
281
+ await retained;
282
+ },
283
+ };
284
+ }
285
+ function commitStatement(p, sorted, writes, asyncCommit) {
286
+ const values = [];
287
+ const bind = (value) => { values.push(value); return `$${values.length}`; };
288
+ const pieces = (serialized) => bind(`[${serialized.join(',')}]`);
289
+ const scopes = bind(sorted.map((w) => w.scope));
290
+ const expected = bind(sorted.map((w) => w.expectedVersion));
291
+ const versions = bind(sorted.map((w) => w.expectedVersion + w.inputs.length));
292
+ const due = bind(sorted.map((w) => w.due ?? null));
293
+ const setDue = bind(sorted.map((w) => w.due !== undefined));
294
+ const ctes = asyncCommit ? ["cfg AS MATERIALIZED (SELECT set_config('synchronous_commit', 'off', true))"] : [];
295
+ ctes.push(`w AS (SELECT w.* FROM unnest(${scopes}::text[], ${expected}::bigint[], ${versions}::bigint[], ${due}::float8[], ${setDue}::bool[]) w(scope, expected, version, due, set_due) ${asyncCommit ? 'CROSS JOIN cfg' : ''})`, `lk AS MATERIALIZED (SELECT scope FROM ${p}scopes WHERE scope = ANY(${scopes}::text[]) ORDER BY scope FOR NO KEY UPDATE)`, `cas AS (UPDATE ${p}scopes s SET version = w.version, due = CASE WHEN w.set_due THEN w.due ELSE s.due END
296
+ FROM w JOIN lk USING (scope) WHERE s.scope = w.scope AND s.version = w.expected AND w.expected > 0 RETURNING s.scope)`, `ins AS (INSERT INTO ${p}scopes (scope, version, due) SELECT scope, version, due FROM w WHERE expected = 0
297
+ ORDER BY scope COLLATE "C" ON CONFLICT (scope) DO NOTHING RETURNING scope)`, 'ok AS (SELECT scope FROM cas UNION ALL SELECT scope FROM ins)');
298
+ const inputs = sorted.flatMap((w) => w.snapshot === null ? w.inputs.map((input, i) => ({ scope: w.scope, version: w.expectedVersion + i + 1, json: w.serialized?.inputs[i] ?? JSON.stringify(input) })) : []);
299
+ if (inputs.length > 0)
300
+ ctes.push(`inp AS (INSERT INTO ${p}inputs (scope, version, input)
301
+ SELECT i.scope, i.version, j.value FROM unnest(${bind(inputs.map((i) => i.scope))}::text[], ${bind(inputs.map((i) => i.version))}::bigint[]) WITH ORDINALITY i(scope, version, ord)
302
+ JOIN json_array_elements(${pieces(inputs.map((i) => i.json))}::json) WITH ORDINALITY j(value, ord) USING (ord) JOIN ok USING (scope))`);
303
+ const snapshots = sorted.flatMap((w) => w.snapshot === null ? [] : [{ scope: w.scope, version: w.snapshot.version, snapshot: w.snapshot, record: w.serialized?.snapshot ?? JSON.stringify(w.snapshot.record) }]);
304
+ if (snapshots.length > 0) {
305
+ const snapshotScopes = bind(snapshots.map((s) => s.scope));
306
+ const snapshotVersions = bind(snapshots.map((s) => s.version));
307
+ ctes.push(`snp AS (INSERT INTO ${p}snapshots (scope, version, policy, reducer, record)
308
+ SELECT s.scope, s.version, policy.value, s.reducer, record.value
309
+ FROM unnest(${snapshotScopes}::text[], ${snapshotVersions}::bigint[], ${bind(snapshots.map((s) => s.snapshot.reducer))}::int[]) WITH ORDINALITY s(scope, version, reducer, ord)
310
+ JOIN json_array_elements(${pieces(snapshots.map((s) => JSON.stringify(s.snapshot.policy)))}::json) WITH ORDINALITY policy(value, ord) USING (ord)
311
+ JOIN json_array_elements(${pieces(snapshots.map((s) => s.record))}::json) WITH ORDINALITY record(value, ord) USING (ord) JOIN ok USING (scope)
312
+ ON CONFLICT (scope) DO UPDATE SET version = EXCLUDED.version, policy = EXCLUDED.policy, reducer = EXCLUDED.reducer, record = EXCLUDED.record)`, `trm AS (DELETE FROM ${p}inputs d USING unnest(${snapshotScopes}::text[], ${snapshotVersions}::bigint[]) t(scope, version) JOIN ok USING (scope)
313
+ WHERE d.scope = t.scope AND d.version <= t.version)`);
314
+ }
315
+ const appends = writes.flatMap((w) => w.appends.map((row, i) => ({ row, scope: w.scope, json: w.serialized?.appends[i] ?? JSON.stringify(row.body) })));
316
+ if (appends.length > 0)
317
+ ctes.push(`dec AS (INSERT INTO ${p}decisions (n, scope, kind, id, route, at, body)
318
+ SELECT r.ord::int, r.scope, r.kind, r.id, r.route, r.at, j.value
319
+ FROM unnest(${bind(appends.map((a) => a.scope))}::text[], ${bind(appends.map((a) => a.row.kind))}::text[], ${bind(appends.map((a) => a.row.id))}::text[], ${bind(appends.map((a) => a.row.route))}::text[], ${bind(appends.map((a) => a.row.at))}::float8[]) WITH ORDINALITY r(scope, kind, id, route, at, ord)
320
+ JOIN json_array_elements(${pieces(appends.map((a) => a.json))}::json) WITH ORDINALITY j(value, ord) USING (ord) JOIN ok USING (scope)
321
+ ORDER BY r.ord ON CONFLICT (kind, id) DO NOTHING RETURNING txid)`);
322
+ return { sql: `WITH ${ctes.join(',\n')} SELECT scope${appends.length > 0 ? ', (SELECT txid::text FROM dec LIMIT 1) AS txid' : ''} FROM ok`, values, appends: appends.length > 0 };
323
+ }
324
+ function parsePosition(value) {
325
+ const match = /^(\d{1,20})\.(\d{1,10})$/.exec(value);
326
+ if (!match?.[1] || !match[2])
327
+ throw new Error(`attend/postgres: not a position from this log: "${value}"`);
328
+ return { txid: match[1], n: match[2] };
329
+ }
330
+ function compare(a, b) {
331
+ const left = parsePosition(a);
332
+ const right = parsePosition(b);
333
+ const x = BigInt(left.txid);
334
+ const y = BigInt(right.txid);
335
+ return x < y ? -1 : x > y ? 1 : Number(left.n) - Number(right.n);
336
+ }
337
+ function nullableText(value) {
338
+ return value === null ? null : text(value);
339
+ }
340
+ function number(value) {
341
+ const result = typeof value === 'number' ? value : Number(text(value));
342
+ if (!Number.isFinite(result))
343
+ throw new Error('attend/postgres: expected a finite number');
344
+ return result;
345
+ }
346
+ function json(value) {
347
+ return typeof value === 'string' || value instanceof Uint8Array ? JSON.parse(text(value)) : value;
348
+ }
349
+ function decisionRow(row) {
350
+ const kind = text(column(row, 'kind'));
351
+ const route = nullableText(column(row, 'route'));
352
+ if (route !== null && route !== 'interrupt' && route !== 'queue' && route !== 'note' && route !== 'ask')
353
+ throw new Error('attend/postgres: invalid route');
354
+ const common = { position: text(column(row, 'position')), id: text(column(row, 'id')), scope: text(column(row, 'scope')), at: number(column(row, 'at')) };
355
+ const body = json(column(row, 'body'));
356
+ if (typeof body !== 'object' || body === null)
357
+ throw new Error('attend/postgres: invalid decision body');
358
+ if (kind === 'decision' && route !== null)
359
+ return { ...common, kind, route, body: body };
360
+ if (kind === 'deadLetter')
361
+ return { ...common, kind, route, body: body };
362
+ throw new Error('attend/postgres: invalid decision kind');
363
+ }
364
+ //# sourceMappingURL=postgres.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../../src/store/postgres.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Retention, ScopeStore } from './types.js';
2
+ export type RedisSend = (args: string[]) => Promise<unknown>;
3
+ export interface RedisStoreOptions {
4
+ /** Must contain a hash tag on Redis Cluster, so every key one script touches is in one slot. Default 'attend:'. */
5
+ prefix?: string;
6
+ retain?: Retention;
7
+ /** A dedicated connection for XREAD BLOCK on the decision stream. */
8
+ blockingSend?: RedisSend;
9
+ }
10
+ /** One EVALSHA per group: validates every version first, then writes each scope with its version bumped last. */
11
+ export declare function redisStore(send: RedisSend, options?: RedisStoreOptions): ScopeStore;
12
+ //# sourceMappingURL=redis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/store/redis.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAe,SAAS,EAAE,UAAU,EAAc,MAAM,YAAY,CAAC;AAIjF,MAAM,MAAM,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE7D,MAAM,WAAW,iBAAiB;IAChC,mHAAmH;IACnH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,CAAC;CAC1B;AAwRD,iHAAiH;AACjH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAqInF"}