@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,540 @@
1
+ import { boundary } from '../internal/adapter.js';
2
+ const { text } = boundary('attend/redis');
3
+ /** Lua library prepended to scripts, providing position formatting, row fields, key type checks and retention. */
4
+ const COMMON = `
5
+ local function position(id)
6
+ local ms, seq = string.match(id, '^(%d+)%-(%d+)$')
7
+ return string.rep('0', 20 - #ms) .. ms .. '-' .. string.rep('0', 20 - #seq) .. seq
8
+ end
9
+ local function fields(row)
10
+ local result = {}
11
+ for i = 1, #row[2], 2 do result[row[2][i]] = row[2][i + 1] end
12
+ return result
13
+ end
14
+ local function checkType(key, expected)
15
+ local actual = redis.call('TYPE', key).ok
16
+ if actual ~= 'none' and actual ~= expected then error('attend/redis: wrong type for ' .. key) end
17
+ end
18
+ local function trim(stream, decided, prefix, maximum, cutoff, budget)
19
+ local length = redis.call('XLEN', stream)
20
+ local rows = redis.call('XRANGE', stream, '-', '+', 'COUNT', budget + 1)
21
+ local dropped = 0
22
+ for _, row in ipairs(rows) do
23
+ if dropped == budget or length <= 1 then break end
24
+ local value = fields(row)
25
+ if (maximum < 0 or length <= maximum) and (cutoff == '' or tonumber(value.at) >= tonumber(cutoff)) then break end
26
+ redis.call('XDEL', stream, row[1])
27
+ redis.call('HDEL', decided, value.kind .. ':' .. value.id)
28
+ redis.call('ZREM', prefix .. 'by-scope:' .. value.scope, position(row[1]))
29
+ length = length - 1
30
+ dropped = dropped + 1
31
+ end
32
+ return dropped
33
+ end`;
34
+ /** KEYS: due index, decisions, decided, scope/input/index keys. ARGV: prefix, max rows, cutoff, write count; each write's scope, version, input count, snapshot flag, due, append count, inputs, snapshot fields, append fields. */
35
+ const COMMIT = `${COMMON}
36
+ local prefix = ARGV[1]
37
+ local function finite(value)
38
+ local n = tonumber(value)
39
+ if not n or n ~= n or n == math.huge or n == -math.huge then error('invalid number') end
40
+ return n
41
+ end
42
+ local function count(value)
43
+ local n = finite(value)
44
+ if n < 0 or n % 1 ~= 0 or n > 9007199254740991 then error('invalid count') end
45
+ return n
46
+ end
47
+ local maximum = finite(ARGV[2])
48
+ local cutoff = ARGV[3]
49
+ if maximum < -1 or maximum % 1 ~= 0 or maximum > 9007199254740991 or (cutoff ~= '' and not finite(cutoff)) then error('invalid retention') end
50
+ local writeCount = count(ARGV[4])
51
+ checkType(KEYS[1], 'zset')
52
+ checkType(KEYS[2], 'stream')
53
+ checkType(KEYS[3], 'hash')
54
+ local seen, outcomes = {}, {}
55
+ local proposedAppends = 0
56
+ local arg = 5
57
+ for i = 1, writeCount do
58
+ local scope, expected = ARGV[arg], count(ARGV[arg + 1])
59
+ local inputCount, hasSnapshot = count(ARGV[arg + 2]), ARGV[arg + 3]
60
+ local due, appendCount = ARGV[arg + 4], count(ARGV[arg + 5])
61
+ arg = arg + 6
62
+ if not scope or seen[scope] then error('duplicate or invalid scope') end
63
+ seen[scope] = true
64
+ if expected + inputCount > 9007199254740991 then error('invalid version') end
65
+ if hasSnapshot ~= '0' and hasSnapshot ~= '1' then error('invalid snapshot flag') end
66
+ if not due or (due ~= 'keep' and due ~= '' and (#due ~= 16 or string.find(due, '[^0-9a-f]'))) then error('invalid due') end
67
+ checkType(prefix .. 'scope:' .. scope, 'hash')
68
+ checkType(prefix .. 'inputs:' .. scope, 'hash')
69
+ arg = arg + inputCount
70
+ if hasSnapshot == '1' then
71
+ if count(ARGV[arg + 1]) ~= expected + inputCount then error('invalid snapshot') end
72
+ finite(ARGV[arg + 3])
73
+ arg = arg + 4
74
+ end
75
+ if arg + appendCount * 6 - 1 > #ARGV then error('missing write arguments') end
76
+ for j = 1, appendCount do
77
+ local kind, rowScope = ARGV[arg], ARGV[arg + 2]
78
+ if kind ~= 'decision' and kind ~= 'deadLetter' then error('invalid append') end
79
+ finite(ARGV[arg + 3])
80
+ checkType(prefix .. 'by-scope:' .. rowScope, 'zset')
81
+ arg = arg + 6
82
+ end
83
+ proposedAppends = proposedAppends + appendCount
84
+ local current = redis.call('HGET', prefix .. 'scope:' .. scope, 'version')
85
+ if current and not tonumber(current) then error('corrupt scope version') end
86
+ outcomes[i] = (tonumber(current) or 0) == expected and 'ok' or 'conflict'
87
+ end
88
+ if arg ~= #ARGV + 1 then error('invalid write arguments') end
89
+ local head = redis.call('XREVRANGE', KEYS[2], '+', '-', 'COUNT', 1)
90
+ local repair = false
91
+ if #head > 0 then
92
+ local row = fields(head[1])
93
+ local pos = position(head[1][1])
94
+ checkType(prefix .. 'by-scope:' .. row.scope, 'zset')
95
+ if redis.call('HGET', KEYS[3], row.kind .. ':' .. row.id) ~= pos or not redis.call('ZSCORE', prefix .. 'by-scope:' .. row.scope, pos) then
96
+ repair = {row, pos}
97
+ end
98
+ end
99
+ if maximum >= 0 or cutoff ~= '' then
100
+ for _, row in ipairs(redis.call('XRANGE', KEYS[2], '-', '+', 'COUNT', proposedAppends + 65)) do
101
+ checkType(prefix .. 'by-scope:' .. fields(row).scope, 'zset')
102
+ end
103
+ end
104
+ if repair then
105
+ -- XADD may have survived an error before either index was written.
106
+ redis.call('HSET', KEYS[3], repair[1].kind .. ':' .. repair[1].id, repair[2])
107
+ redis.call('ZADD', prefix .. 'by-scope:' .. repair[1].scope, 0, repair[2])
108
+ end
109
+ local appended = 0
110
+ arg = 5
111
+ for i = 1, writeCount do
112
+ local scope, expected = ARGV[arg], tonumber(ARGV[arg + 1])
113
+ local inputCount, hasSnapshot = tonumber(ARGV[arg + 2]), ARGV[arg + 3] == '1'
114
+ local due, appendCount = ARGV[arg + 4], tonumber(ARGV[arg + 5])
115
+ arg = arg + 6
116
+ local inputs = arg
117
+ local snapshot = inputs + inputCount
118
+ arg = snapshot + (hasSnapshot and 4 or 0)
119
+ if outcomes[i] == 'ok' then
120
+ local scopeKey = prefix .. 'scope:' .. scope
121
+ local inputKey = prefix .. 'inputs:' .. scope
122
+ local oldDue = redis.call('HGET', scopeKey, 'due') or ''
123
+ if not hasSnapshot then
124
+ for j = 1, inputCount do redis.call('HSET', inputKey, string.format('%.0f', expected + j), ARGV[inputs + j - 1]) end
125
+ end
126
+ for j = 1, appendCount do
127
+ local row = arg + (j - 1) * 6
128
+ local id = ARGV[row] .. ':' .. ARGV[row + 1]
129
+ if redis.call('HEXISTS', KEYS[3], id) == 0 then
130
+ local pos = position(redis.call('XADD', KEYS[2], '*', 'kind', ARGV[row], 'id', ARGV[row + 1], 'scope', ARGV[row + 2], 'at', ARGV[row + 3], 'route', ARGV[row + 4], 'body', ARGV[row + 5]))
131
+ appended = appended + 1
132
+ redis.call('HSET', KEYS[3], id, pos)
133
+ redis.call('ZADD', prefix .. 'by-scope:' .. ARGV[row + 2], 0, pos)
134
+ end
135
+ end
136
+ if due ~= 'keep' and due ~= '' and due ~= oldDue then redis.call('ZADD', KEYS[1], 0, due .. ':' .. scope) end
137
+ local update = {'version', string.format('%.0f', expected + inputCount)}
138
+ if due ~= 'keep' then table.insert(update, 'due'); table.insert(update, due) end
139
+ if hasSnapshot then
140
+ table.insert(update, 'snapshot'); table.insert(update, ARGV[snapshot])
141
+ table.insert(update, 'snapshotVersion'); table.insert(update, ARGV[snapshot + 1])
142
+ table.insert(update, 'policy'); table.insert(update, ARGV[snapshot + 2])
143
+ table.insert(update, 'reducer'); table.insert(update, ARGV[snapshot + 3])
144
+ end
145
+ redis.call('HSET', scopeKey, unpack(update))
146
+ if due ~= 'keep' and due ~= oldDue and oldDue ~= '' then redis.call('ZREM', KEYS[1], oldDue .. ':' .. scope) end
147
+ if hasSnapshot then redis.call('DEL', inputKey) end
148
+ end
149
+ arg = arg + appendCount * 6
150
+ end
151
+ if maximum >= 0 or cutoff ~= '' then trim(KEYS[2], KEYS[3], prefix, maximum, cutoff, appended + 64) end
152
+ return outcomes`;
153
+ /** KEYS: scope hash, inputs hash. ARGV: none. */
154
+ const LOAD = `
155
+ local state = redis.call('HMGET', KEYS[1], 'version', 'snapshot', 'snapshotVersion', 'policy', 'reducer')
156
+ if not state[1] then return false end
157
+ local version = tonumber(state[1])
158
+ local floor = tonumber(state[3]) or 0
159
+ if not version or floor > version then return redis.error_reply('attend/redis: corrupt scope') end
160
+ local inputs, tail = redis.call('HGETALL', KEYS[2]), {}
161
+ for i = 1, #inputs, 2 do
162
+ local n = tonumber(inputs[i])
163
+ if n and n > floor and n <= version then table.insert(tail, {n, inputs[i + 1]}) end
164
+ end
165
+ table.sort(tail, function(a, b) return a[1] < b[1] end)
166
+ if #tail ~= version - floor then return redis.error_reply('attend/redis: corrupt scope') end
167
+ local result = {}
168
+ for i, item in ipairs(tail) do
169
+ if item[1] ~= floor + i then return redis.error_reply('attend/redis: corrupt scope') end
170
+ result[i] = item[2]
171
+ end
172
+ return {state[1], state[2], state[3], state[4], state[5], result}`;
173
+ /** KEYS: due index. ARGV: prefix, lower bound, upper bound, limit. */
174
+ const DUE = `
175
+ local result, after = {}, ARGV[2]
176
+ local limit = tonumber(ARGV[4])
177
+ while #result < limit do
178
+ local rows = redis.call('ZRANGEBYLEX', KEYS[1], after, ARGV[3], 'LIMIT', 0, limit - #result)
179
+ if #rows == 0 then break end
180
+ for _, member in ipairs(rows) do
181
+ local hex, scope = string.sub(member, 1, 16), string.sub(member, 18)
182
+ if redis.call('HGET', ARGV[1] .. 'scope:' .. scope, 'due') == hex then table.insert(result, member)
183
+ else redis.call('ZREM', KEYS[1], member) end
184
+ after = '(' .. member
185
+ end
186
+ end
187
+ return result`;
188
+ /** KEYS: scope hash, inputs hash, due index. ARGV: scope. */
189
+ const REMOVE = `
190
+ local due = redis.call('HGET', KEYS[1], 'due')
191
+ redis.call('DEL', KEYS[1], KEYS[2])
192
+ if due and due ~= '' then redis.call('ZREM', KEYS[3], due .. ':' .. ARGV[1]) end
193
+ return 1`;
194
+ /** KEYS: decisions, scope index. ARGV: after, scope flag/value, prefix flag/value, kind count/values, route count/values (-1 means no filter), sinceAt, limit, scanLimit. */
195
+ const READ = `${COMMON}
196
+ local q = {after = ARGV[1] ~= '' and ARGV[1] or false, scope = ARGV[2] == '1' and ARGV[3] or false, prefix = ARGV[4] == '1' and ARGV[5] or false}
197
+ local arg = 6
198
+ local function values()
199
+ local count = tonumber(ARGV[arg])
200
+ arg = arg + 1
201
+ if count == -1 then return false end
202
+ local result = {}
203
+ for i = 1, count do result[i] = ARGV[arg]; arg = arg + 1 end
204
+ return result
205
+ end
206
+ q.kinds = values()
207
+ q.routes = values()
208
+ q.sinceAt = ARGV[arg] ~= '' and tonumber(ARGV[arg]) or false
209
+ q.limit = tonumber(ARGV[arg + 1])
210
+ q.scanLimit = tonumber(ARGV[arg + 2])
211
+ local head = redis.call('XREVRANGE', KEYS[1], '+', '-', 'COUNT', 1)
212
+ local checked = q.after
213
+ if #head > 0 then
214
+ local pos = position(head[1][1])
215
+ if checked == false or pos > checked then checked = pos end
216
+ end
217
+ local after = q.after == false and '-' or '(' .. q.after
218
+ local rows
219
+ if q.scope ~= false then
220
+ rows = redis.call('ZRANGEBYLEX', KEYS[2], after, '+', 'LIMIT', 0, q.scanLimit + 1)
221
+ if #head > 0 and #rows < q.scanLimit + 1 then
222
+ local pos = position(head[1][1])
223
+ if fields(head[1]).scope == q.scope and (q.after == false or pos > q.after) and rows[#rows] ~= pos then table.insert(rows, pos) end
224
+ end
225
+ else rows = redis.call('XRANGE', KEYS[1], after, '+', 'COUNT', q.scanLimit + 1) end
226
+ local function contains(values, value)
227
+ if values == false then return true end
228
+ for _, item in ipairs(values) do if value == item then return true end end
229
+ return false
230
+ end
231
+ local result, examined, last = {}, 0, q.after
232
+ for _, item in ipairs(rows) do
233
+ if #result >= q.limit or examined >= q.scanLimit then return {result, last, 1} end
234
+ examined = examined + 1
235
+ local row = item
236
+ if q.scope ~= false then
237
+ last = item
238
+ row = redis.call('XRANGE', KEYS[1], item, item)[1]
239
+ else last = position(row[1]) end
240
+ if row then
241
+ local value = fields(row)
242
+ if (q.prefix == false or string.sub(value.scope, 1, #q.prefix) == q.prefix)
243
+ and contains(q.kinds, value.kind)
244
+ and (q.routes == false or (value.route ~= '' and contains(q.routes, value.route)))
245
+ and (q.sinceAt == false or tonumber(value.at) >= q.sinceAt) then table.insert(result, row) end
246
+ end
247
+ end
248
+ return {result, checked, 0}`;
249
+ /** KEYS: decisions, decided. ARGV: kind:id. */
250
+ const FIND = `${COMMON}
251
+ local pos = redis.call('HGET', KEYS[2], ARGV[1])
252
+ if pos then return redis.call('XRANGE', KEYS[1], pos, pos)[1] or false end
253
+ local head = redis.call('XREVRANGE', KEYS[1], '+', '-', 'COUNT', 1)
254
+ if #head > 0 then
255
+ local value = fields(head[1])
256
+ if value.kind .. ':' .. value.id == ARGV[1] then return head[1] end
257
+ end
258
+ return false`;
259
+ /** KEYS: decisions. ARGV: none. */
260
+ const BOUNDS = `${COMMON}
261
+ local first = redis.call('XRANGE', KEYS[1], '-', '+', 'COUNT', 1)
262
+ local last = redis.call('XREVRANGE', KEYS[1], '+', '-', 'COUNT', 1)
263
+ return {first[1] and position(first[1][1]) or false, last[1] and position(last[1][1]) or false}`;
264
+ /** KEYS: decisions, decided. ARGV: prefix, max rows, age cutoff. */
265
+ const TRIM = `${COMMON}
266
+ return trim(KEYS[1], KEYS[2], ARGV[1], tonumber(ARGV[2]), ARGV[3], 256)`;
267
+ /** KEYS: meta hash. ARGV: candidate epoch. */
268
+ const EPOCH = `
269
+ redis.call('HSETNX', KEYS[1], 'epoch', ARGV[1])
270
+ return redis.call('HGET', KEYS[1], 'epoch')`;
271
+ /** One EVALSHA per group: validates every version first, then writes each scope with its version bumped last. */
272
+ export function redisStore(send, options) {
273
+ const prefix = options?.prefix ?? 'attend:';
274
+ const scopeKey = (scope) => `${prefix}scope:${scope}`;
275
+ const inputsKey = (scope) => `${prefix}inputs:${scope}`;
276
+ const indexKey = (scope) => `${prefix}by-scope:${scope}`;
277
+ const dueKey = `${prefix}due-index`;
278
+ const stream = `${prefix}decisions`;
279
+ const decided = `${prefix}decided`;
280
+ const scripts = new Map();
281
+ const load = (source) => {
282
+ const pending = send(['SCRIPT', 'LOAD', source]).then(text);
283
+ scripts.set(source, pending);
284
+ void pending.catch(() => { if (scripts.get(source) === pending)
285
+ scripts.delete(source); });
286
+ return pending;
287
+ };
288
+ const run = async (source, keys, args = []) => {
289
+ const sha = await (scripts.get(source) ?? load(source));
290
+ try {
291
+ return await send(['EVALSHA', sha, String(keys.length), ...keys, ...args]);
292
+ }
293
+ catch (error) {
294
+ if (!(error instanceof Error) || !error.message.includes('NOSCRIPT'))
295
+ throw error;
296
+ return send(['EVALSHA', await load(source), String(keys.length), ...keys, ...args]);
297
+ }
298
+ };
299
+ const log = {
300
+ async epoch() { return text(await run(EPOCH, [`${prefix}meta`], [crypto.randomUUID()])); },
301
+ async bounds() {
302
+ const [first, last] = list(await run(BOUNDS, [stream]));
303
+ return { first: nullableText(first), last: nullableText(last) };
304
+ },
305
+ async read(query) {
306
+ if (query.after !== null)
307
+ validatePosition(query.after);
308
+ positiveInteger(query.limit, 'limit');
309
+ positiveInteger(query.scanLimit ?? query.limit * 4, 'scanLimit');
310
+ const [rows, checked, more] = list(await run(READ, [stream, indexKey(query.scope ?? '')], [
311
+ query.after ?? '', query.scope === undefined ? '0' : '1', query.scope ?? '',
312
+ query.scopePrefix === undefined ? '0' : '1', query.scopePrefix ?? '',
313
+ String(query.kinds?.length ?? -1), ...query.kinds ?? [],
314
+ String(query.routes?.length ?? -1), ...query.routes ?? [],
315
+ query.sinceAt === undefined ? '' : String(query.sinceAt), String(query.limit), String(query.scanLimit ?? query.limit * 4),
316
+ ]));
317
+ return { rows: list(rows).map(parseRow), checked: nullableText(checked), more: numeric(more) === 1 };
318
+ },
319
+ async find(kind, id) {
320
+ const reply = await run(FIND, [stream, decided], [`${kind}:${id}`]);
321
+ return reply === null || reply === false ? null : parseRow(reply);
322
+ },
323
+ async wait(after, blockMs, signal) {
324
+ try {
325
+ if (after !== null)
326
+ validatePosition(after);
327
+ }
328
+ catch {
329
+ return;
330
+ }
331
+ if (signal.aborted || blockMs <= 0)
332
+ return;
333
+ await new Promise((resolve) => {
334
+ const deadline = Date.now() + blockMs;
335
+ let timer;
336
+ let wakeSleep = () => { };
337
+ let done = false;
338
+ const finish = () => {
339
+ if (done)
340
+ return;
341
+ done = true;
342
+ clearTimeout(timer);
343
+ clearTimeout(timeout);
344
+ wakeSleep();
345
+ signal.removeEventListener('abort', finish);
346
+ resolve();
347
+ };
348
+ const sleep = async () => {
349
+ if (!done)
350
+ await new Promise((wake) => {
351
+ wakeSleep = wake;
352
+ timer = setTimeout(wake, Math.max(0, Math.min(deadline - Date.now(), 250)));
353
+ });
354
+ };
355
+ signal.addEventListener('abort', finish, { once: true });
356
+ const timeout = setTimeout(finish, blockMs);
357
+ void (async () => {
358
+ try {
359
+ while (!done && Date.now() < deadline) {
360
+ try {
361
+ const { last } = await log.bounds();
362
+ if (done)
363
+ return;
364
+ if (last !== null && (after === null || last > after))
365
+ break;
366
+ if (options?.blockingSend) {
367
+ const reply = await options.blockingSend(['XREAD', 'BLOCK', String(Math.max(1, Math.ceil(Math.min(deadline - Date.now(), 1000)))), 'COUNT', '1', 'STREAMS', stream, after ?? '0-0']);
368
+ if (reply !== null && reply !== undefined)
369
+ break;
370
+ }
371
+ else
372
+ await sleep();
373
+ }
374
+ catch {
375
+ await sleep();
376
+ }
377
+ }
378
+ }
379
+ finally {
380
+ finish();
381
+ }
382
+ })();
383
+ });
384
+ },
385
+ async trim(retain) {
386
+ const args = retention(retain);
387
+ for (;;) {
388
+ if (numeric(await run(TRIM, [stream, decided], [prefix, ...args])) < 256)
389
+ return;
390
+ }
391
+ },
392
+ compare: (a, b) => a < b ? -1 : a > b ? 1 : 0,
393
+ };
394
+ return {
395
+ durable: true,
396
+ log,
397
+ async load(scope) {
398
+ const reply = await run(LOAD, [scopeKey(scope), inputsKey(scope)]);
399
+ if (reply === null || reply === false)
400
+ return null;
401
+ const [version, snapshot, snapshotVersion, policy, reducer, tail] = list(reply);
402
+ return {
403
+ version: numeric(version),
404
+ snapshot: snapshot === null || snapshot === false ? null : {
405
+ version: numeric(snapshotVersion), record: parseRecord(snapshot, scope),
406
+ policy: parsePolicy(policy), reducer: numeric(reducer),
407
+ },
408
+ tail: list(tail).map(parseInput),
409
+ };
410
+ },
411
+ async commit(writes) {
412
+ if (writes.length === 0)
413
+ return [];
414
+ const prepared = writes.flatMap(prepare);
415
+ const keys = [dueKey, stream, decided, ...writes.flatMap((w) => [scopeKey(w.scope), inputsKey(w.scope), ...w.appends.map((row) => indexKey(row.scope))])];
416
+ return list(await run(COMMIT, keys, [prefix, ...retention(options?.retain), String(writes.length), ...prepared])).map((reply) => {
417
+ const outcome = text(reply);
418
+ if (outcome !== 'ok' && outcome !== 'conflict')
419
+ throw new Error('attend/redis: invalid commit outcome');
420
+ return outcome;
421
+ });
422
+ },
423
+ async due(now, limit, after) {
424
+ positiveInteger(limit, 'limit');
425
+ const lower = after ? `(${dueHex(after.due)}:${after.scope}` : '-';
426
+ return list(await run(DUE, [dueKey], [prefix, lower, `(${dueHex(now)};`, String(limit)])).map((reply) => {
427
+ const member = text(reply);
428
+ return { due: fromDueHex(member.slice(0, 16)), scope: member.slice(17) };
429
+ });
430
+ },
431
+ async remove(scope) { await run(REMOVE, [scopeKey(scope), inputsKey(scope), dueKey], [scope]); },
432
+ };
433
+ }
434
+ function prepare(write) {
435
+ if (!Number.isSafeInteger(write.expectedVersion) || write.expectedVersion < 0 || !Number.isSafeInteger(write.expectedVersion + write.inputs.length))
436
+ throw new Error('attend/redis: invalid version');
437
+ const snapshot = write.snapshot;
438
+ if (snapshot && snapshot.version !== write.expectedVersion + write.inputs.length)
439
+ throw new Error('attend/redis: invalid snapshot version');
440
+ if (write.serialized && (write.serialized.inputs.length !== write.inputs.length || write.serialized.appends.length !== write.appends.length))
441
+ throw new Error('attend/redis: invalid serialized write');
442
+ const args = [
443
+ write.scope, String(write.expectedVersion), String(write.inputs.length), snapshot === null ? '0' : '1',
444
+ write.due === undefined ? 'keep' : write.due === null ? '' : dueHex(write.due), String(write.appends.length),
445
+ ...write.serialized?.inputs ?? write.inputs.map((input) => JSON.stringify(input)),
446
+ ];
447
+ if (snapshot !== null) {
448
+ const record = write.serialized ? write.serialized.snapshot : JSON.stringify(snapshot.record);
449
+ if (record === null)
450
+ throw new Error('attend/redis: missing serialized snapshot');
451
+ args.push(record, String(snapshot.version), JSON.stringify(snapshot.policy), String(snapshot.reducer));
452
+ }
453
+ for (const [i, row] of write.appends.entries()) {
454
+ if (!Number.isFinite(row.at))
455
+ throw new Error('attend/redis: invalid append time');
456
+ const body = write.serialized ? write.serialized.appends[i] : JSON.stringify(row.body);
457
+ if (body === undefined)
458
+ throw new Error('attend/redis: missing serialized append');
459
+ args.push(row.kind, row.id, row.scope, String(row.at), row.route ?? '', body);
460
+ }
461
+ return args;
462
+ }
463
+ function retention(value) {
464
+ if (value?.maxRows !== undefined && (!Number.isSafeInteger(value.maxRows) || value.maxRows < 0))
465
+ throw new Error('attend/redis: invalid maxRows');
466
+ if (value?.olderThanMs !== undefined && (!Number.isFinite(value.olderThanMs) || value.olderThanMs < 0))
467
+ throw new Error('attend/redis: invalid olderThanMs');
468
+ return [String(value?.maxRows ?? -1), value?.olderThanMs === undefined ? '' : String(Date.now() - value.olderThanMs)];
469
+ }
470
+ function dueHex(value) {
471
+ if (!Number.isFinite(value))
472
+ throw new Error('attend/redis: due must be finite');
473
+ const view = new DataView(new ArrayBuffer(8));
474
+ view.setFloat64(0, value === 0 ? 0 : value);
475
+ const bits = view.getBigUint64(0);
476
+ return ((bits & (1n << 63n)) !== 0n ? BigInt.asUintN(64, ~bits) : bits | (1n << 63n)).toString(16).padStart(16, '0');
477
+ }
478
+ function fromDueHex(hex) {
479
+ const bits = BigInt(`0x${hex}`);
480
+ const view = new DataView(new ArrayBuffer(8));
481
+ view.setBigUint64(0, (bits & (1n << 63n)) !== 0n ? bits & ((1n << 63n) - 1n) : BigInt.asUintN(64, ~bits));
482
+ return view.getFloat64(0);
483
+ }
484
+ function validatePosition(position) {
485
+ if (!/^\d{20}-\d{20}$/.test(position))
486
+ throw new Error(`attend/redis: not a position from this log: "${position}"`);
487
+ }
488
+ function positiveInteger(value, name) {
489
+ if (!Number.isSafeInteger(value) || value <= 0)
490
+ throw new Error(`attend/redis: invalid ${name}`);
491
+ }
492
+ function numeric(reply) {
493
+ return typeof reply === 'number' ? reply : typeof reply === 'bigint' ? Number(reply) : Number(text(reply));
494
+ }
495
+ function list(reply) {
496
+ if (!Array.isArray(reply))
497
+ throw new Error(`attend/redis: expected an array reply, got ${typeof reply}`);
498
+ return reply;
499
+ }
500
+ function nullableText(reply) {
501
+ return reply === null || reply === false ? null : text(reply);
502
+ }
503
+ function parseRecord(reply, scope) {
504
+ const value = JSON.parse(text(reply));
505
+ if (typeof value !== 'object' || value === null || Reflect.get(value, 'scope') !== scope || typeof Reflect.get(value, 'version') !== 'number')
506
+ throw new Error('attend/redis: corrupt scope');
507
+ return value;
508
+ }
509
+ function parsePolicy(reply) {
510
+ const value = JSON.parse(text(reply));
511
+ if (typeof value !== 'object' || value === null || typeof Reflect.get(value, 'closingGraceMs') !== 'number')
512
+ throw new Error('attend/redis: corrupt policy');
513
+ return value;
514
+ }
515
+ function parseInput(reply) {
516
+ const value = JSON.parse(text(reply));
517
+ if (typeof value !== 'object' || value === null || typeof Reflect.get(value, 'now') !== 'number' || typeof Reflect.get(value, 'input') !== 'object' || Reflect.get(value, 'input') === null)
518
+ throw new Error('attend/redis: corrupt input');
519
+ return value;
520
+ }
521
+ function parseRow(reply) {
522
+ const [id, raw] = list(reply);
523
+ const values = list(raw);
524
+ const fields = new Map();
525
+ for (let i = 0; i < values.length; i += 2)
526
+ fields.set(text(values[i]), values[i + 1]);
527
+ const kind = text(fields.get('kind'));
528
+ const body = JSON.parse(text(fields.get('body')));
529
+ if ((kind !== 'decision' && kind !== 'deadLetter') || typeof body !== 'object' || body === null || Reflect.get(body, 'id') !== text(fields.get('id')))
530
+ throw new Error('attend/redis: corrupt decision');
531
+ const [ms, seq] = text(id).split('-');
532
+ if (ms === undefined || seq === undefined)
533
+ throw new Error('attend/redis: corrupt position');
534
+ return {
535
+ kind, id: text(fields.get('id')), scope: text(fields.get('scope')), at: numeric(fields.get('at')),
536
+ route: text(fields.get('route')) || null, body,
537
+ position: `${ms.padStart(20, '0')}-${seq.padStart(20, '0')}`,
538
+ };
539
+ }
540
+ //# sourceMappingURL=redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/store/redis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import type { SqliteDatabase } from './sqlite.js';
2
+ import type { CommitOutcome, DecisionQuery, DueKey, Retention } from './types.js';
3
+ /** A write whose JSON was encoded before entering the commit queue. */
4
+ export interface EncodedWrite {
5
+ scope: string;
6
+ expectedVersion: number;
7
+ inputs: string[];
8
+ snapshot: {
9
+ version: number;
10
+ policy: string;
11
+ reducer: number;
12
+ record: string;
13
+ } | null;
14
+ setDue: boolean;
15
+ due: number | null;
16
+ appends: {
17
+ kind: string;
18
+ id: string;
19
+ scope: string;
20
+ at: number;
21
+ route: string | null;
22
+ body: string;
23
+ }[];
24
+ }
25
+ /** A scope with driver values and unparsed JSON. */
26
+ export interface RawScope {
27
+ version: unknown;
28
+ snapshot: unknown;
29
+ tail: unknown[];
30
+ }
31
+ /** A decision with its numeric position and unparsed body. */
32
+ export interface RawRow {
33
+ position: number;
34
+ scope: unknown;
35
+ kind: unknown;
36
+ id: unknown;
37
+ at: unknown;
38
+ route: unknown;
39
+ body: unknown;
40
+ }
41
+ /** A page whose cursor is still a numeric rowid. */
42
+ export interface RawPage {
43
+ rows: RawRow[];
44
+ checked: number | null;
45
+ more: boolean;
46
+ }
47
+ /** A query with its cursor decoded before transport. */
48
+ export type EncodedQuery = Omit<DecisionQuery, 'after'> & {
49
+ after: number | null;
50
+ };
51
+ /** Outcomes and whether this group inserted any decision rows. */
52
+ export interface CommitResult {
53
+ outcomes: CommitOutcome[];
54
+ appended: boolean;
55
+ }
56
+ type GroupResult = {
57
+ value: CommitResult;
58
+ } | {
59
+ error: unknown;
60
+ };
61
+ /** Creates or adopts the tables and returns the synchronous SQL engine. */
62
+ export declare function openTables(db: SqliteDatabase, prefix: string): {
63
+ epoch: () => unknown;
64
+ load(scope: string): RawScope | null;
65
+ commit(groups: EncodedWrite[][], retention?: Retention): GroupResult[];
66
+ due(now: number, limit: number, after?: DueKey): unknown[];
67
+ remove(scope: string): void;
68
+ bounds(): unknown;
69
+ read(query: EncodedQuery): RawPage;
70
+ find(kind: string, id: string): RawRow | null;
71
+ trim(retention: Retention): void;
72
+ };
73
+ /** The synchronous operations shared by the two transports. */
74
+ export type Engine = ReturnType<typeof openTables>;
75
+ /** Coalesces every group queued before the next immediate into one transaction. */
76
+ export declare function queueCommits(engine: Engine, retention?: Retention): (writes: EncodedWrite[]) => Promise<CommitResult>;
77
+ /** Operations sent across the worker port. */
78
+ export interface Operations extends Omit<Engine, 'commit'> {
79
+ commit(writes: EncodedWrite[]): CommitResult;
80
+ close(): void;
81
+ }
82
+ /** A request ties its operation name to its positional arguments. */
83
+ export type Request = {
84
+ [K in keyof Operations]: {
85
+ id: number;
86
+ op: K;
87
+ args: Parameters<Operations[K]>;
88
+ };
89
+ }[keyof Operations];
90
+ export {};
91
+ //# sourceMappingURL=sqlite-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-worker.d.ts","sourceRoot":"","sources":["../../src/store/sqlite-worker.ts"],"names":[],"mappings":"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"}