@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.
- package/LICENSE +21 -0
- package/README.md +580 -2
- package/dist/attend.d.ts +30 -0
- package/dist/attend.d.ts.map +1 -0
- package/dist/attend.js +428 -0
- package/dist/attend.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/ids.d.ts +12 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/ids.js +97 -0
- package/dist/core/ids.js.map +1 -0
- package/dist/core/reducer.d.ts +26 -0
- package/dist/core/reducer.d.ts.map +1 -0
- package/dist/core/reducer.js +437 -0
- package/dist/core/reducer.js.map +1 -0
- package/dist/core/seen.d.ts +22 -0
- package/dist/core/seen.d.ts.map +1 -0
- package/dist/core/seen.js +61 -0
- package/dist/core/seen.js.map +1 -0
- package/dist/core/state.d.ts +12 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +90 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/step.d.ts +14 -0
- package/dist/core/step.d.ts.map +1 -0
- package/dist/core/step.js +17 -0
- package/dist/core/step.js.map +1 -0
- package/dist/core/threshold.d.ts +40 -0
- package/dist/core/threshold.d.ts.map +1 -0
- package/dist/core/threshold.js +72 -0
- package/dist/core/threshold.js.map +1 -0
- package/dist/core/types.d.ts +704 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +24 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/window.d.ts +38 -0
- package/dist/core/window.d.ts.map +1 -0
- package/dist/core/window.js +322 -0
- package/dist/core/window.js.map +1 -0
- package/dist/decisions.d.ts +53 -0
- package/dist/decisions.d.ts.map +1 -0
- package/dist/decisions.js +115 -0
- package/dist/decisions.js.map +1 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/adapter.d.ts +21 -0
- package/dist/internal/adapter.d.ts.map +1 -0
- package/dist/internal/adapter.js +62 -0
- package/dist/internal/adapter.js.map +1 -0
- package/dist/internal/assert.d.ts +5 -0
- package/dist/internal/assert.d.ts.map +1 -0
- package/dist/internal/assert.js +14 -0
- package/dist/internal/assert.js.map +1 -0
- package/dist/internal/clock.d.ts +8 -0
- package/dist/internal/clock.d.ts.map +1 -0
- package/dist/internal/clock.js +38 -0
- package/dist/internal/clock.js.map +1 -0
- package/dist/internal/http.d.ts +42 -0
- package/dist/internal/http.d.ts.map +1 -0
- package/dist/internal/http.js +122 -0
- package/dist/internal/http.js.map +1 -0
- package/dist/internal/images.d.ts +18 -0
- package/dist/internal/images.d.ts.map +1 -0
- package/dist/internal/images.js +75 -0
- package/dist/internal/images.js.map +1 -0
- package/dist/internal/json.d.ts +3 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +5 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/prompt.d.ts +31 -0
- package/dist/internal/prompt.d.ts.map +1 -0
- package/dist/internal/prompt.js +149 -0
- package/dist/internal/prompt.js.map +1 -0
- package/dist/internal/shared.d.ts +12 -0
- package/dist/internal/shared.d.ts.map +1 -0
- package/dist/internal/shared.js +134 -0
- package/dist/internal/shared.js.map +1 -0
- package/dist/jev.d.ts +74 -0
- package/dist/jev.d.ts.map +1 -0
- package/dist/jev.js +156 -0
- package/dist/jev.js.map +1 -0
- package/dist/llm.d.ts +164 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +79 -0
- package/dist/llm.js.map +1 -0
- package/dist/mcp.d.ts +130 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +550 -0
- package/dist/mcp.js.map +1 -0
- package/dist/memory.d.ts +10 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +50 -0
- package/dist/memory.js.map +1 -0
- package/dist/postgres.d.ts +25 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +56 -0
- package/dist/postgres.js.map +1 -0
- package/dist/redis.d.ts +20 -0
- package/dist/redis.d.ts.map +1 -0
- package/dist/redis.js +83 -0
- package/dist/redis.js.map +1 -0
- package/dist/server/compat.d.ts +13 -0
- package/dist/server/compat.d.ts.map +1 -0
- package/dist/server/compat.js +5 -0
- package/dist/server/compat.js.map +1 -0
- package/dist/server/cursor.d.ts +15 -0
- package/dist/server/cursor.d.ts.map +1 -0
- package/dist/server/cursor.js +50 -0
- package/dist/server/cursor.js.map +1 -0
- package/dist/server/events.d.ts +42 -0
- package/dist/server/events.d.ts.map +1 -0
- package/dist/server/events.js +189 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/fanout.d.ts +28 -0
- package/dist/server/fanout.d.ts.map +1 -0
- package/dist/server/fanout.js +184 -0
- package/dist/server/fanout.js.map +1 -0
- package/dist/server/guard.d.ts +19 -0
- package/dist/server/guard.d.ts.map +1 -0
- package/dist/server/guard.js +27 -0
- package/dist/server/guard.js.map +1 -0
- package/dist/server/http.d.ts +4 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +323 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/ingest.d.ts +4 -0
- package/dist/server/ingest.d.ts.map +1 -0
- package/dist/server/ingest.js +400 -0
- package/dist/server/ingest.js.map +1 -0
- package/dist/server/install.d.ts +5 -0
- package/dist/server/install.d.ts.map +1 -0
- package/dist/server/install.js +91 -0
- package/dist/server/install.js.map +1 -0
- package/dist/server/poll.d.ts +4 -0
- package/dist/server/poll.d.ts.map +1 -0
- package/dist/server/poll.js +45 -0
- package/dist/server/poll.js.map +1 -0
- package/dist/server/serve.d.ts +19 -0
- package/dist/server/serve.d.ts.map +1 -0
- package/dist/server/serve.js +238 -0
- package/dist/server/serve.js.map +1 -0
- package/dist/server/sessions.d.ts +14 -0
- package/dist/server/sessions.d.ts.map +1 -0
- package/dist/server/sessions.js +54 -0
- package/dist/server/sessions.js.map +1 -0
- package/dist/server/stream.d.ts +11 -0
- package/dist/server/stream.d.ts.map +1 -0
- package/dist/server/stream.js +216 -0
- package/dist/server/stream.js.map +1 -0
- package/dist/server/tools.d.ts +22 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +55 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/server/types.d.ts +351 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +5 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +10 -0
- package/dist/server.js.map +1 -0
- package/dist/shell/budget.d.ts +4 -0
- package/dist/shell/budget.d.ts.map +1 -0
- package/dist/shell/budget.js +5 -0
- package/dist/shell/budget.js.map +1 -0
- package/dist/shell/copy.d.ts +17 -0
- package/dist/shell/copy.d.ts.map +1 -0
- package/dist/shell/copy.js +67 -0
- package/dist/shell/copy.js.map +1 -0
- package/dist/shell/decisions.d.ts +6 -0
- package/dist/shell/decisions.d.ts.map +1 -0
- package/dist/shell/decisions.js +42 -0
- package/dist/shell/decisions.js.map +1 -0
- package/dist/shell/read.d.ts +7 -0
- package/dist/shell/read.d.ts.map +1 -0
- package/dist/shell/read.js +21 -0
- package/dist/shell/read.js.map +1 -0
- package/dist/shell/scheduler.d.ts +4 -0
- package/dist/shell/scheduler.d.ts.map +1 -0
- package/dist/shell/scheduler.js +90 -0
- package/dist/shell/scheduler.js.map +1 -0
- package/dist/shell/scope.d.ts +27 -0
- package/dist/shell/scope.d.ts.map +1 -0
- package/dist/shell/scope.js +343 -0
- package/dist/shell/scope.js.map +1 -0
- package/dist/shell/types.d.ts +156 -0
- package/dist/shell/types.d.ts.map +1 -0
- package/dist/shell/types.js +2 -0
- package/dist/shell/types.js.map +1 -0
- package/dist/sqlite.d.ts +14 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +39 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/step.d.ts +18 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +14 -0
- package/dist/step.js.map +1 -0
- package/dist/store/memory.d.ts +12 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +264 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/postgres.d.ts +24 -0
- package/dist/store/postgres.d.ts.map +1 -0
- package/dist/store/postgres.js +364 -0
- package/dist/store/postgres.js.map +1 -0
- package/dist/store/redis.d.ts +12 -0
- package/dist/store/redis.d.ts.map +1 -0
- package/dist/store/redis.js +540 -0
- package/dist/store/redis.js.map +1 -0
- package/dist/store/sqlite-worker.d.ts +91 -0
- package/dist/store/sqlite-worker.d.ts.map +1 -0
- package/dist/store/sqlite-worker.js +322 -0
- package/dist/store/sqlite-worker.js.map +1 -0
- package/dist/store/sqlite.d.ts +34 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +238 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/types.d.ts +137 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/dist/testing/conformance.d.ts +13 -0
- package/dist/testing/conformance.d.ts.map +1 -0
- package/dist/testing/conformance.js +542 -0
- package/dist/testing/conformance.js.map +1 -0
- package/dist/testing/wire.d.ts +16 -0
- package/dist/testing/wire.d.ts.map +1 -0
- package/dist/testing/wire.js +304 -0
- package/dist/testing/wire.js.map +1 -0
- package/dist/testing.d.ts +113 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +655 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +130 -4
- package/skills/attend/SKILL.md +231 -0
- package/skills/attend/references/judges.md +283 -0
- package/skills/attend/references/kinds.md +62 -0
- package/skills/attend/references/mcp.md +132 -0
- package/skills/attend/references/sinks.md +73 -0
- package/skills/attend/references/stores.md +90 -0
- 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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"}
|