@cruba/crubal-postgres 0.0.0-stage → 0.3.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/README.md +126 -2
- package/dist/bin/crubal-pg.d.ts +2 -0
- package/dist/bin/crubal-pg.js +115 -0
- package/dist/bin/crubal-pg.js.map +1 -0
- package/dist/src/border.d.ts +122 -0
- package/dist/src/border.js +432 -0
- package/dist/src/border.js.map +1 -0
- package/dist/src/db.d.ts +19 -0
- package/dist/src/db.js +60 -0
- package/dist/src/db.js.map +1 -0
- package/dist/src/definitions.d.ts +11 -0
- package/dist/src/definitions.js +119 -0
- package/dist/src/definitions.js.map +1 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/projector.d.ts +24 -0
- package/dist/src/projector.js +148 -0
- package/dist/src/projector.js.map +1 -0
- package/dist/src/schema.sql +273 -0
- package/dist/src/state.d.ts +16 -0
- package/dist/src/state.js +138 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/store.d.ts +269 -0
- package/dist/src/store.js +1003 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/working.d.ts +64 -0
- package/dist/src/working.js +312 -0
- package/dist/src/working.js.map +1 -0
- package/package.json +44 -4
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
// border.ts: the border (spec chapter 7) running over the store. Every run is one entry: the engine's
|
|
2
|
+
// Exchange is built over the commit's draft, runs, and what it changed plus its run write become the entry.
|
|
3
|
+
// Intake records keep their bytes in the intake table (9.1); idempotency keys and run counts live in the
|
|
4
|
+
// runs table, so a run never acts twice across restarts (7.5); stream contracts read the projection stream
|
|
5
|
+
// and keep an index's cursor (12.6.2); scheduled contracts tick from the schedules table (7.11).
|
|
6
|
+
import { Access } from "@cruba/crubal";
|
|
7
|
+
import { Exchange } from "@cruba/crubal";
|
|
8
|
+
import { MemoryRecords } from "@cruba/crubal";
|
|
9
|
+
import { isSchedule, readSchedule, ticksDue } from "@cruba/crubal";
|
|
10
|
+
import { openItems } from "@cruba/crubal";
|
|
11
|
+
import { receive } from "@cruba/crubal";
|
|
12
|
+
/** The border's options from the store's own definitions (docs/design/publishing.md). */
|
|
13
|
+
export async function borderOptions(store) {
|
|
14
|
+
const p = await store.definitions();
|
|
15
|
+
const thresholds = {};
|
|
16
|
+
for (const k of ["confirm", "split"])
|
|
17
|
+
if (p.info.header[k])
|
|
18
|
+
thresholds[k] = Number(p.info.header[k]);
|
|
19
|
+
return { dict: p.dict, contracts: p.contracts, rules: p.rules, perms: p.perms, thresholds, ...(p.info.version ? { versions: { package: `${p.info.name} /${p.info.version}` } } : {}) };
|
|
20
|
+
}
|
|
21
|
+
export class PgBorder {
|
|
22
|
+
store;
|
|
23
|
+
o;
|
|
24
|
+
contracts;
|
|
25
|
+
/** Set for one request when a system acts for a person (14.9); every run of this border then runs as the person. */
|
|
26
|
+
acting;
|
|
27
|
+
constructor(store, o) {
|
|
28
|
+
this.store = store;
|
|
29
|
+
this.o = o;
|
|
30
|
+
this.contracts = new Map(o.contracts.map((c) => [c.name, c]));
|
|
31
|
+
}
|
|
32
|
+
/** The person's access, narrowed as they chose (14.9), laid over the owner's access for this run. */
|
|
33
|
+
cap(access, acting) {
|
|
34
|
+
const { person, items, gated } = acting;
|
|
35
|
+
const effective = access.effective.bind(access);
|
|
36
|
+
access.effective = (callerId, recordId) => {
|
|
37
|
+
const e = effective(callerId, recordId);
|
|
38
|
+
if (callerId !== person)
|
|
39
|
+
return e;
|
|
40
|
+
if (items?.length)
|
|
41
|
+
e.items = new Set([...e.items].filter((i) => items.includes(i)));
|
|
42
|
+
if (gated && e.mode !== "none")
|
|
43
|
+
e.gated = true;
|
|
44
|
+
return e;
|
|
45
|
+
};
|
|
46
|
+
if (gated) {
|
|
47
|
+
const was = access.gated.bind(access);
|
|
48
|
+
access.gated = (callerId, recordId) => (callerId === person ? { edge: "acting-for", who: acting.system, relation: "agent", mode: "control", on: recordId, grants: [], by: person, gate: "review", reviewer: person, line: 0 } : was(callerId, recordId));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Refuse what a system acting for a person may never do (14.9, 14.12 items 8 and 9). */
|
|
52
|
+
refuseActing(acting, recordId, access, edgesBefore, edgesAfter) {
|
|
53
|
+
if (recordId && access) {
|
|
54
|
+
const eff = access.effective(acting.person, recordId);
|
|
55
|
+
if (eff.edges.some((e) => e.relation === "emergency" || e.by === "platform"))
|
|
56
|
+
throw Object.assign(new Error(`${acting.system} may not act for ${acting.person} under an emergency edge`), { status: 403 });
|
|
57
|
+
}
|
|
58
|
+
for (const [k, e] of edgesAfter) {
|
|
59
|
+
if (edgesBefore.has(k))
|
|
60
|
+
continue;
|
|
61
|
+
const who = e.who;
|
|
62
|
+
if (who !== acting.person)
|
|
63
|
+
throw Object.assign(new Error(`${acting.system} acting for ${acting.person} may not grant onward (${k})`), { status: 403 });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/** A border over a store's own definitions. */
|
|
67
|
+
static async over(store) {
|
|
68
|
+
return new PgBorder(store, await borderOptions(store));
|
|
69
|
+
}
|
|
70
|
+
get owner() {
|
|
71
|
+
return this.store.owner;
|
|
72
|
+
}
|
|
73
|
+
/** Runs so far and the keys acted on, from the runs table, so a fresh Exchange continues where the last left off. */
|
|
74
|
+
async past() {
|
|
75
|
+
const { rows } = await this.store.pool.query("select run, json from runs where owner = $1", [this.owner]);
|
|
76
|
+
const sent = new Set();
|
|
77
|
+
const known = new Map();
|
|
78
|
+
const open = new Map();
|
|
79
|
+
// A retry decision releases a dead run's key (runs.md), so the same payload may go again.
|
|
80
|
+
const released = new Set((await this.store.pool.query("select json->>'releases' as k from review where owner = $1 and json->>'decision' = 'retry' and json ? 'releases'", [this.owner])).rows.map((x) => String(x.k)));
|
|
81
|
+
for (const r of rows) {
|
|
82
|
+
const j = r.json;
|
|
83
|
+
const run = String(r.run);
|
|
84
|
+
known.set(run, { contract: String(j.contract), record: String(j.record ?? "") });
|
|
85
|
+
if (typeof j.key !== "string")
|
|
86
|
+
continue;
|
|
87
|
+
if (released.has(j.key) && j.state === "failed")
|
|
88
|
+
continue;
|
|
89
|
+
if (j.state === "acted" || j.state === "closed" || j.state === "started" || j.state === "failed")
|
|
90
|
+
sent.add(j.key);
|
|
91
|
+
// A run still open: started, or failed with attempts left (docs/design/runs.md).
|
|
92
|
+
const c = this.contracts.get(String(j.contract));
|
|
93
|
+
const allowed = c ? 1 + Number((c.parts.retry ?? "").match(/^(\d+)\s+every\s+/)?.[1] ?? 0) : 1;
|
|
94
|
+
const attempts = Number(j.attempt ?? 0);
|
|
95
|
+
if (j.state === "started" || (j.state === "failed" && attempts < allowed))
|
|
96
|
+
open.set(run, { contract: String(j.contract), record: String(j.record ?? ""), key: j.key, attempts });
|
|
97
|
+
}
|
|
98
|
+
return { runs: rows.length, sent, known, open };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* One border run as one entry: the Exchange is built over the draft, with the store's edges, runs and
|
|
102
|
+
* keys; `fn` runs it; its changes and its run write become the entry. The function MUST be pure over the
|
|
103
|
+
* draft (it may run more than once while the working set loads).
|
|
104
|
+
*/
|
|
105
|
+
/** The highest number behind each id prefix the owner has (`P-` → 3050), so an arrival mints the next (9.2a). */
|
|
106
|
+
async idCounts() {
|
|
107
|
+
const { rows } = await this.store.pool.query("select split_part(id, '-', 1) as p, max(case when id ~ '^[A-Z]+-[0-9]+$' then split_part(id, '-', 2)::bigint else 0 end) as n from records where owner = $1 and id like '%-%' group by 1", [this.owner]);
|
|
108
|
+
return Object.fromEntries(rows.map((r) => [r.p, Number(r.n)]));
|
|
109
|
+
}
|
|
110
|
+
async run(fn, at, seed = {}) {
|
|
111
|
+
const { runs, sent, known, open } = await this.past();
|
|
112
|
+
const counts = await this.idCounts();
|
|
113
|
+
const { out } = await this.store.commitFrom((draft) => {
|
|
114
|
+
const ex = new Exchange(this.o.dict, this.o.contracts, this.o.roles ?? [], this.o.rules ?? []);
|
|
115
|
+
ex.owner = this.owner;
|
|
116
|
+
// Ids are minted from the owner's highest per prefix, afresh each pass (the function may run more than once).
|
|
117
|
+
const next = { ...counts };
|
|
118
|
+
ex.mint = (level) => {
|
|
119
|
+
const p = this.o.idPrefixes?.[level] ?? level.charAt(0).toUpperCase();
|
|
120
|
+
next[p] = (next[p] ?? 0) + 1;
|
|
121
|
+
return `${p}-${next[p]}`;
|
|
122
|
+
};
|
|
123
|
+
ex.records = draft.records;
|
|
124
|
+
ex.bindings = draft.bindings;
|
|
125
|
+
ex.review = draft.review;
|
|
126
|
+
// The observations and open items this run reads, loaded apart from the draft: the entry's own
|
|
127
|
+
// observation and review writes are what the store keeps.
|
|
128
|
+
ex.observations = [...(seed.observations ?? [])];
|
|
129
|
+
ex.knownReview = seed.review ?? [];
|
|
130
|
+
if (this.o.thresholds)
|
|
131
|
+
ex.thresholds = this.o.thresholds;
|
|
132
|
+
if (this.o.versions)
|
|
133
|
+
ex.versions = this.o.versions;
|
|
134
|
+
ex.runs = runs;
|
|
135
|
+
for (const k of sent)
|
|
136
|
+
ex.sent.add(k);
|
|
137
|
+
for (const [k, v] of known)
|
|
138
|
+
ex.runsKnown.set(k, v);
|
|
139
|
+
// A copy each run: the operation may run more than once while the working set loads (working.ts).
|
|
140
|
+
for (const [k, v] of open)
|
|
141
|
+
ex.started.set(k, { ...v });
|
|
142
|
+
if (this.o.perms) {
|
|
143
|
+
ex.access = new Access(this.o.dict, this.o.perms, draft.records, [...draft.edges.values()], this.owner);
|
|
144
|
+
ex.access.edges = draft.edges;
|
|
145
|
+
if (this.acting)
|
|
146
|
+
this.cap(ex.access, this.acting);
|
|
147
|
+
}
|
|
148
|
+
// The rules engine knows every record the working set holds, as the memory border's does.
|
|
149
|
+
for (const [, r] of Map.prototype.entries.call(draft.records))
|
|
150
|
+
ex.engine.put(r);
|
|
151
|
+
let captured = { by: { contract: "" }, extra: [] };
|
|
152
|
+
ex.journal = { commit: (by, _m, _at, extra = []) => { captured = { by, extra }; return null; } };
|
|
153
|
+
const edgesBefore = new Set(draft.edges.keys());
|
|
154
|
+
const result = fn(ex);
|
|
155
|
+
if (this.acting) {
|
|
156
|
+
const recordId = typeof result.record === "string" ? result.record : undefined;
|
|
157
|
+
this.refuseActing(this.acting, recordId, ex.access, edgesBefore, draft.edges);
|
|
158
|
+
// Every write names both (14.9): the system that acted and the person it acted for.
|
|
159
|
+
captured.by = { ...captured.by, caller: this.acting.system, for: this.acting.person };
|
|
160
|
+
}
|
|
161
|
+
return { by: captured.by, extra: captured.extra, out: result };
|
|
162
|
+
}, at);
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
/** Keep an intake record with its bytes (9.1), beside the log. */
|
|
166
|
+
async keepIntake(c, body, forRecord, log, at) {
|
|
167
|
+
const intake = receive(c, body, forRecord, this.o.dict, `I-${log.slice(2)}`);
|
|
168
|
+
const raw = intake.raw;
|
|
169
|
+
const bytes = Buffer.from(raw.body, "utf8");
|
|
170
|
+
await this.store.pool.query(`insert into intake (owner, intake, contract, received, "for", raw, sha256, type, json) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) on conflict (owner, intake) do nothing`, [this.owner, intake.intake, c.name, at ?? null, forRecord || null, bytes, raw.sha256, raw.type, { ...intake, raw: { type: raw.type, sha256: raw.sha256 } }]);
|
|
171
|
+
}
|
|
172
|
+
/** A receive contract's run on a record (7.4 steps 5–6), its intake kept; with `forRun`, a late answer closing that run. */
|
|
173
|
+
async receive(name, recordId, body, callerId, at, forRun) {
|
|
174
|
+
const c = this.contracts.get(name);
|
|
175
|
+
if (!c)
|
|
176
|
+
throw new Error(`no contract ${name}`);
|
|
177
|
+
const seed = c.lands === "observation" ? await this.evidenceFor(recordId) : {};
|
|
178
|
+
const r = await this.run((ex) => ex.receiveRun(name, recordId, body, callerId, forRun), at, seed);
|
|
179
|
+
if (typeof r.log === "string")
|
|
180
|
+
await this.keepIntake(c, body, recordId, r.log, at);
|
|
181
|
+
return r;
|
|
182
|
+
}
|
|
183
|
+
/** An arrival (9.2a): the payload finds or makes its record; its intake kept. */
|
|
184
|
+
async arrive(name, body, level, callerId, of, at, within) {
|
|
185
|
+
const c = this.contracts.get(name);
|
|
186
|
+
if (!c)
|
|
187
|
+
throw new Error(`no contract ${name}`);
|
|
188
|
+
const r = await this.run((ex) => ex.arriveRun(name, body, level, callerId, of, within), at);
|
|
189
|
+
const record = r.arrival?.record;
|
|
190
|
+
if (typeof r.log === "string")
|
|
191
|
+
await this.keepIntake(c, body, typeof record === "string" ? record : "", r.log, at);
|
|
192
|
+
return r;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* A send (7.4, docs/design/runs.md): `started` in one entry with the payload kept in outtake, the adapter
|
|
196
|
+
* outside any transaction, then `acted` or `failed` in another; an answer the adapter brings back closes
|
|
197
|
+
* the run as a receive. Without an adapter the act is nothing and the run is acted.
|
|
198
|
+
*/
|
|
199
|
+
async send(name, recordId, callerId, at) {
|
|
200
|
+
const p = await this.run((ex) => ex.prepare(name, recordId, callerId), at);
|
|
201
|
+
if (p.started !== true)
|
|
202
|
+
return p;
|
|
203
|
+
const payload = (p.payload ?? {});
|
|
204
|
+
const bytes = Buffer.from(JSON.stringify(payload), "utf8");
|
|
205
|
+
const { createHash } = await import("node:crypto");
|
|
206
|
+
await this.store.pool.query("insert into outtake (owner, run, contract, record, key, raw, sha256) values ($1, $2, $3, $4, $5, $6, $7) on conflict (owner, run) do nothing", [this.owner, String(p.log), name, recordId, String(p.key), bytes, createHash("sha256").update(bytes).digest("hex")]);
|
|
207
|
+
return { ...p, ...(await this.act(name, String(p.log), recordId, payload, callerId, at)) };
|
|
208
|
+
}
|
|
209
|
+
/** The act and what follows it: acted or failed, and the answer landed against the run. */
|
|
210
|
+
async act(name, run, recordId, payload, callerId, at) {
|
|
211
|
+
const c = this.contracts.get(name);
|
|
212
|
+
if (!c)
|
|
213
|
+
throw new Error(`no contract ${name}`);
|
|
214
|
+
const adapter = this.o.adapters?.[name];
|
|
215
|
+
let outcome;
|
|
216
|
+
try {
|
|
217
|
+
outcome = adapter ? await adapter(c, payload, run) : { acted: true };
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
outcome = { failed: e instanceof Error ? e.message : String(e) };
|
|
221
|
+
}
|
|
222
|
+
if ("failed" in outcome)
|
|
223
|
+
return this.run((ex) => ex.failed(run, outcome.failed), at);
|
|
224
|
+
const acted = await this.run((ex) => ex.acted(run, at), at);
|
|
225
|
+
if (outcome.body) {
|
|
226
|
+
const answered = await this.receive(name, recordId, outcome.body, callerId, at, run);
|
|
227
|
+
return { ...acted, answer: answered };
|
|
228
|
+
}
|
|
229
|
+
return acted;
|
|
230
|
+
}
|
|
231
|
+
/** Try a failed run again from its kept payload (7.5 `retry`), never re-mapping it. */
|
|
232
|
+
async retry(run, callerId, at) {
|
|
233
|
+
const { rows } = await this.store.pool.query("select contract, record, raw from outtake where owner = $1 and run = $2", [this.owner, run]);
|
|
234
|
+
const row = rows[0];
|
|
235
|
+
if (!row)
|
|
236
|
+
throw new Error(`no payload kept for ${run}`);
|
|
237
|
+
const payload = JSON.parse(Buffer.from(row.raw).toString("utf8"));
|
|
238
|
+
return this.act(String(row.contract), run, String(row.record ?? ""), payload, callerId, at);
|
|
239
|
+
}
|
|
240
|
+
/** What an observation run reads (9.7.3): the observations supporting the record or its parent, and the open split items on them. */
|
|
241
|
+
async evidenceFor(recordId) {
|
|
242
|
+
const q = async (sql, args) => (await this.store.pool.query(sql, args)).rows;
|
|
243
|
+
const parent = (await q('select "of" from records where owner = $1 and id = $2', [this.owner, recordId]))[0]?.of;
|
|
244
|
+
const ids = [recordId, ...(typeof parent === "string" ? [parent] : [])];
|
|
245
|
+
const observations = (await q("select json from observations where owner = $1 and json->>'supports' = any($2) order by ord", [this.owner, ids])).map((r) => r.json);
|
|
246
|
+
const items = (await q("select json from review where owner = $1 and json->>'key' = any($2) order by ord", [this.owner, ids.map((id) => `split:${id}`)])).map((r) => r.json);
|
|
247
|
+
return { observations, review: openItems(items) };
|
|
248
|
+
}
|
|
249
|
+
/** The owner's offer (7.8), with the signed log entries its values came from, for another owner's take. */
|
|
250
|
+
async offer(name, only) {
|
|
251
|
+
const ex = new Exchange(this.o.dict, this.o.contracts, this.o.roles ?? [], this.o.rules ?? []);
|
|
252
|
+
ex.owner = this.owner;
|
|
253
|
+
// An offer that names what it is `for` is answered by target; one that doesn't walks the owner's records
|
|
254
|
+
// (name `for:` on a large owner), and a request for named ids walks nothing.
|
|
255
|
+
const walks = !only && !this.contracts.get(name)?.parts.for;
|
|
256
|
+
const o = await this.store.read((s) => { ex.records = s.records; return ex.offer(name, this.owner, only); }, walks ? { allowAll: true } : {});
|
|
257
|
+
// The wrapper names the package version the records were written under (3.8, 10.1): the installed
|
|
258
|
+
// bundle that declares the offer contract.
|
|
259
|
+
// The latest installed version of each package: the install log keeps every version it took.
|
|
260
|
+
const latest = new Map();
|
|
261
|
+
for (const i of await this.store.installed()) {
|
|
262
|
+
const pkg = String(i.package);
|
|
263
|
+
const version = String(i.version);
|
|
264
|
+
if ((latest.get(pkg) ?? "") < version)
|
|
265
|
+
latest.set(pkg, version);
|
|
266
|
+
}
|
|
267
|
+
for (const [pkg, version] of latest) {
|
|
268
|
+
const { rows: b } = await this.store.pool.query("select json from bundles where owner = $1 and package = $2 and version = $3", [this.owner, pkg, version]);
|
|
269
|
+
const json = b[0]?.json;
|
|
270
|
+
const contracts = json?.contracts ?? [];
|
|
271
|
+
if (contracts.some((c) => c.contract === name)) {
|
|
272
|
+
o.package = `${pkg} /${version}`;
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const vias = [...new Set(o.records.flatMap((r) => Object.values(r.sources ?? {}).map((s) => s.via)))];
|
|
277
|
+
const { rows } = await this.store.pool.query("select entry from log where owner = $1 and log_id = any($2) order by seq", [this.owner, vias]);
|
|
278
|
+
o.log = rows.map((r) => r.entry);
|
|
279
|
+
return o;
|
|
280
|
+
}
|
|
281
|
+
/** A take (7.8) of a presenter's record into one of ours, by the offer's mode; one entry naming the presenter's. */
|
|
282
|
+
async take(takeName, offer, recordId, presenter, callerId, at) {
|
|
283
|
+
return this.run((ex) => ex.take(takeName, offer, recordId, presenter), at);
|
|
284
|
+
}
|
|
285
|
+
/** Taken values past their terms (7.8): removed, one entry per record. */
|
|
286
|
+
async expire(now, at) {
|
|
287
|
+
const { out } = await this.store.commitFrom((draft) => {
|
|
288
|
+
const ex = new Exchange(this.o.dict, this.o.contracts, this.o.roles ?? [], this.o.rules ?? []);
|
|
289
|
+
ex.owner = this.owner;
|
|
290
|
+
ex.records = draft.records;
|
|
291
|
+
const ids = ex.expire(now);
|
|
292
|
+
return { by: { take: "expired", at: now }, extra: [], out: ids };
|
|
293
|
+
}, at);
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
/** A decision on a dead run (runs.md): retry (a new run, the key released) or drop; then the act for a retry. */
|
|
297
|
+
async decideRun(run, decision, callerId, at) {
|
|
298
|
+
const p = await this.run((ex) => ex.decideRun(run, decision, callerId), at);
|
|
299
|
+
if (p.started !== true)
|
|
300
|
+
return p;
|
|
301
|
+
const payload = (p.payload ?? {});
|
|
302
|
+
const bytes = Buffer.from(JSON.stringify(payload), "utf8");
|
|
303
|
+
const { createHash } = await import("node:crypto");
|
|
304
|
+
await this.store.pool.query("insert into outtake (owner, run, contract, record, key, raw, sha256) values ($1, $2, $3, $4, $5, $6, $7) on conflict (owner, run) do nothing", [this.owner, String(p.log), String(p.contract), String(p.record), String(p.key), bytes, createHash("sha256").update(bytes).digest("hex")]);
|
|
305
|
+
return { ...p, ...(await this.act(String(p.contract), String(p.log), String(p.record), payload, callerId, at)) };
|
|
306
|
+
}
|
|
307
|
+
/** Run the contract that reverses a run (7.5 `undo`), naming its cause. */
|
|
308
|
+
async undo(run, callerId, at) {
|
|
309
|
+
const p = await this.run((ex) => ex.undo(run, callerId), at);
|
|
310
|
+
if (p.started !== true)
|
|
311
|
+
return p;
|
|
312
|
+
const payload = (p.payload ?? {});
|
|
313
|
+
const bytes = Buffer.from(JSON.stringify(payload), "utf8");
|
|
314
|
+
const { createHash } = await import("node:crypto");
|
|
315
|
+
await this.store.pool.query("insert into outtake (owner, run, contract, record, key, raw, sha256) values ($1, $2, $3, $4, $5, $6, $7) on conflict (owner, run) do nothing", [this.owner, String(p.log), String(p.contract), String(p.record), String(p.key), bytes, createHash("sha256").update(bytes).digest("hex")]);
|
|
316
|
+
return { ...p, ...(await this.act(String(p.contract), String(p.log), String(p.record), payload, callerId, at)) };
|
|
317
|
+
}
|
|
318
|
+
/** The stored cursor of a stream contract for a view, when it is for the view's current version. */
|
|
319
|
+
async cursorOf(contract, view, version, audience) {
|
|
320
|
+
const { rows } = await this.store.pool.query("select seq from cursors where owner = $1 and contract = $2 and view = $3 and version = $4 and audience = $5", [this.owner, contract, view, version, audience]);
|
|
321
|
+
return rows.length ? Number(rows[0].seq) : undefined;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* A stream contract's run (12.6.2): the entries of each view since the cursor, pushed (the stored
|
|
325
|
+
* cursor) or pulled (the caller's). A view above public goes only to a party holding `run` for the
|
|
326
|
+
* contract. A batch with entries is logged as a run keyed by the contract, the views and the ranges.
|
|
327
|
+
*/
|
|
328
|
+
async streamRun(name, callerId, cursor, at) {
|
|
329
|
+
const c = this.contracts.get(name);
|
|
330
|
+
if (!c)
|
|
331
|
+
throw new Error(`no contract ${name}`);
|
|
332
|
+
if (!c.stream.length)
|
|
333
|
+
throw new Error(`${name} carries no stream`);
|
|
334
|
+
const p = await this.store.projecting();
|
|
335
|
+
if (!p)
|
|
336
|
+
throw new Error("the store has no views to stream from");
|
|
337
|
+
const party = callerId ?? c.parts.to ?? "";
|
|
338
|
+
const head = { contract: name, caller: party };
|
|
339
|
+
for (const v of c.stream) {
|
|
340
|
+
const view = p.views.views.get(v);
|
|
341
|
+
if (view && view.show !== "public") {
|
|
342
|
+
const edges = (await this.store.pool.query("select json from edges where owner = $1", [this.owner])).rows.map((r) => r.json);
|
|
343
|
+
const access = this.o.perms ? new Access(this.o.dict, this.o.perms, new MemoryRecords(), edges, this.owner) : undefined;
|
|
344
|
+
if (!access?.mayAnywhere(party, "run", name))
|
|
345
|
+
return { ...head, stopped: "permission", view: v };
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
const entries = {};
|
|
349
|
+
const out = {};
|
|
350
|
+
const batches = [];
|
|
351
|
+
for (const v of c.stream) {
|
|
352
|
+
const view = p.views.views.get(v);
|
|
353
|
+
if (!view)
|
|
354
|
+
throw new Error(`no view ${v}`);
|
|
355
|
+
const version = view.version ?? "";
|
|
356
|
+
const since = cursor?.[v] ?? (await this.cursorOf(name, v, version, view.show)) ?? 0;
|
|
357
|
+
const list = await this.store.entriesSince(v, since);
|
|
358
|
+
entries[v] = list;
|
|
359
|
+
out[v] = list.at(-1)?.seq ?? since;
|
|
360
|
+
if (list.length)
|
|
361
|
+
batches.push(`${name}|${v}|${version}|${list[0]?.seq}-${list.at(-1)?.seq}`);
|
|
362
|
+
}
|
|
363
|
+
if (!batches.length)
|
|
364
|
+
return { ...head, entries, cursor: out };
|
|
365
|
+
const { runs } = await this.past();
|
|
366
|
+
const log = `L-R${runs + 1}`;
|
|
367
|
+
await this.store.commitFrom(() => ({ by: { contract: name, run: log }, extra: [{ run: log, contract: name, key: batches.join(" "), state: "acted" }], out: null }), at);
|
|
368
|
+
return { ...head, entries, cursor: out, key: batches.join(" "), log };
|
|
369
|
+
}
|
|
370
|
+
/** An index acknowledges the last `seq` it holds per view (12.6.2); the store resumes from the next. */
|
|
371
|
+
async ack(name, cursor) {
|
|
372
|
+
const c = this.contracts.get(name);
|
|
373
|
+
if (!c)
|
|
374
|
+
throw new Error(`no contract ${name}`);
|
|
375
|
+
const p = await this.store.projecting();
|
|
376
|
+
if (!p)
|
|
377
|
+
throw new Error("the store has no views");
|
|
378
|
+
for (const [v, seq] of Object.entries(cursor)) {
|
|
379
|
+
const view = p.views.views.get(v);
|
|
380
|
+
if (!view)
|
|
381
|
+
continue;
|
|
382
|
+
await this.store.pool.query("insert into cursors (owner, contract, view, version, audience, seq) values ($1, $2, $3, $4, $5, $6) on conflict (owner, contract, view, version, audience) do update set seq = excluded.seq", [this.owner, name, v, view.version ?? "", view.show, seq]);
|
|
383
|
+
}
|
|
384
|
+
return { contract: name, cursor };
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* A scheduled contract's tick (7.11): every tick due since the last one runs (or the latest, or none,
|
|
388
|
+
* by `missed`), each keyed by the contract and the tick so a restarted host never runs one twice. The
|
|
389
|
+
* schedule begins at the first clock reading.
|
|
390
|
+
*/
|
|
391
|
+
async tick(name, now, callerId) {
|
|
392
|
+
const c = this.contracts.get(name);
|
|
393
|
+
if (!c)
|
|
394
|
+
throw new Error(`no contract ${name}`);
|
|
395
|
+
if (!isSchedule(c.when))
|
|
396
|
+
throw new Error(`${name} isn't scheduled`);
|
|
397
|
+
const sch = readSchedule(c.when);
|
|
398
|
+
const { rows } = await this.store.pool.query("select last_tick from schedules where owner = $1 and contract = $2", [this.owner, name]);
|
|
399
|
+
if (!rows.length) {
|
|
400
|
+
await this.store.pool.query("insert into schedules (owner, contract, last_tick) values ($1, $2, $3)", [this.owner, name, now]);
|
|
401
|
+
return { contract: name, now, ticks: [], runs: [], began: now };
|
|
402
|
+
}
|
|
403
|
+
const last = String(rows[0].last_tick);
|
|
404
|
+
const due = ticksDue(sch, last, now);
|
|
405
|
+
const missed = c.parts.missed ?? "once";
|
|
406
|
+
const run = missed === "all" ? due : missed === "once" ? due.slice(-1) : [];
|
|
407
|
+
const skipped = due.filter((t) => !run.includes(t));
|
|
408
|
+
const results = [];
|
|
409
|
+
for (const tick of run) {
|
|
410
|
+
const key = `${name}|${tick}`;
|
|
411
|
+
const { sent } = await this.past();
|
|
412
|
+
if (sent.has(key))
|
|
413
|
+
continue;
|
|
414
|
+
if (c.stream.length) {
|
|
415
|
+
results.push({ tick, ...(await this.streamRun(name, callerId, undefined, now)) });
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
const targets = c.parts.for ? (await this.store.pool.query("select id from records where owner = $1 and ($2 = any(wears) or level = $2 or kind = $2) order by ord", [this.owner, c.parts.for])).rows.map((r) => String(r.id)) : [];
|
|
419
|
+
for (const id of targets)
|
|
420
|
+
results.push({ tick, ...(await this.send(name, id, callerId, now)) });
|
|
421
|
+
}
|
|
422
|
+
// The tick itself is a run, keyed so it never runs twice (7.11).
|
|
423
|
+
const { runs } = await this.past();
|
|
424
|
+
const log = `L-R${runs + 1}`;
|
|
425
|
+
await this.store.commitFrom(() => ({ by: { contract: name, run: log }, extra: [{ run: log, contract: name, tick, key, state: "acted" }], out: null }), now);
|
|
426
|
+
results.push({ tick, log, acted: true });
|
|
427
|
+
}
|
|
428
|
+
await this.store.pool.query("update schedules set last_tick = $3 where owner = $1 and contract = $2", [this.owner, name, now]);
|
|
429
|
+
return { contract: name, now, ticks: due, runs: results, ...(skipped.length ? { skipped } : {}) };
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=border.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"border.js","sourceRoot":"","sources":["../../src/border.ts"],"names":[],"mappings":"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"}
|
package/dist/src/db.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
export type Pool = pg.Pool;
|
|
3
|
+
export type Client = pg.PoolClient;
|
|
4
|
+
/**
|
|
5
|
+
* A pool for a connection string, or the `CRUBAL_PG_URL` environment variable. With a schema (the argument,
|
|
6
|
+
* or `CRUBAL_PG_SCHEMA`), every connection is pinned to it: on a shared database such as a Supabase
|
|
7
|
+
* project the store and host tables live in their own schema, never in `public`, which the database's own
|
|
8
|
+
* API serves to its anonymous role.
|
|
9
|
+
*/
|
|
10
|
+
export declare function connect(url?: string | undefined, schema?: string | undefined): Pool;
|
|
11
|
+
/** Create or update the store's tables in the current search path. Idempotent. */
|
|
12
|
+
export declare function migrate(client: Client): Promise<void>;
|
|
13
|
+
/** Run `fn` inside one transaction, committing on return and rolling back on a throw. */
|
|
14
|
+
export declare function transaction<T>(pool: Pool, fn: (client: Client) => Promise<T>): Promise<T>;
|
|
15
|
+
/**
|
|
16
|
+
* A fresh schema for one test: created, migrated, made the pool's search path, and dropped by the
|
|
17
|
+
* returned function. Every connection of the pool is pinned to it, so a test's store is its own.
|
|
18
|
+
*/
|
|
19
|
+
export declare function testSchema(pool: Pool, name?: string): Promise<() => Promise<void>>;
|
package/dist/src/db.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// db.ts: connecting, the schema, and a schema per test so cases never see each other.
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import pg from "pg";
|
|
4
|
+
const SCHEMA_SQL = readFileSync(new URL("./schema.sql", import.meta.url), "utf8");
|
|
5
|
+
/**
|
|
6
|
+
* A pool for a connection string, or the `CRUBAL_PG_URL` environment variable. With a schema (the argument,
|
|
7
|
+
* or `CRUBAL_PG_SCHEMA`), every connection is pinned to it: on a shared database such as a Supabase
|
|
8
|
+
* project the store and host tables live in their own schema, never in `public`, which the database's own
|
|
9
|
+
* API serves to its anonymous role.
|
|
10
|
+
*/
|
|
11
|
+
export function connect(url = process.env.CRUBAL_PG_URL, schema = process.env.CRUBAL_PG_SCHEMA) {
|
|
12
|
+
if (!url)
|
|
13
|
+
throw new Error("no Postgres URL: pass one or set CRUBAL_PG_URL");
|
|
14
|
+
if (schema && !/^[a-z_][a-z0-9_]*$/.test(schema))
|
|
15
|
+
throw new Error(`a schema is a lower-case word: ${schema}`);
|
|
16
|
+
// The schema rides as a startup parameter, which Postgres and the Supabase session pooler both honour; a
|
|
17
|
+
// query on each connection's open would race the first statement (pg warns, and will refuse).
|
|
18
|
+
return new pg.Pool({ connectionString: url, ...(schema ? { options: `-c search_path=${schema}` } : {}) });
|
|
19
|
+
}
|
|
20
|
+
/** Create or update the store's tables in the current search path. Idempotent. */
|
|
21
|
+
export async function migrate(client) {
|
|
22
|
+
await client.query(SCHEMA_SQL);
|
|
23
|
+
}
|
|
24
|
+
/** Run `fn` inside one transaction, committing on return and rolling back on a throw. */
|
|
25
|
+
export async function transaction(pool, fn) {
|
|
26
|
+
const client = await pool.connect();
|
|
27
|
+
try {
|
|
28
|
+
await client.query("begin");
|
|
29
|
+
const out = await fn(client);
|
|
30
|
+
await client.query("commit");
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
await client.query("rollback").catch(() => { });
|
|
35
|
+
throw e;
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
client.release();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A fresh schema for one test: created, migrated, made the pool's search path, and dropped by the
|
|
43
|
+
* returned function. Every connection of the pool is pinned to it, so a test's store is its own.
|
|
44
|
+
*/
|
|
45
|
+
export async function testSchema(pool, name = `t_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`) {
|
|
46
|
+
await pool.query(`create schema "${name}"`);
|
|
47
|
+
pool.on("connect", (c) => void c.query(`set search_path to "${name}"`));
|
|
48
|
+
const client = await pool.connect();
|
|
49
|
+
try {
|
|
50
|
+
await client.query(`set search_path to "${name}"`);
|
|
51
|
+
await migrate(client);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
client.release();
|
|
55
|
+
}
|
|
56
|
+
return async () => {
|
|
57
|
+
await pool.query(`drop schema "${name}" cascade`);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Parsed } from "@cruba/crubal";
|
|
2
|
+
import type { JsonObject } from "@cruba/crubal";
|
|
3
|
+
import type { Client } from "./db.ts";
|
|
4
|
+
/** The owner's working package as one bundle: the define writes grouped by member kind, in log order. */
|
|
5
|
+
/** The owner's units extension (11.9), from the last `units` define write. */
|
|
6
|
+
export declare function unitsExtensionOf(definitions: Iterable<JsonObject>): JsonObject[];
|
|
7
|
+
export declare function workingBundle(owner: string, definitions: Iterable<JsonObject>): JsonObject;
|
|
8
|
+
/** Build the definitions in force: installed bundles in order, then the working package. */
|
|
9
|
+
export declare function definitionsOf(client: Client, owner: string, extra?: JsonObject[]): Promise<Parsed>;
|
|
10
|
+
/** Every publish check (11.5) over a set of definitions. Throws the first problem. */
|
|
11
|
+
export declare function checkAll(p: Parsed): void;
|