@codemem/core 0.29.2 → 0.30.0-alpha.1

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 (58) hide show
  1. package/dist/api-types.d.ts +27 -1
  2. package/dist/api-types.d.ts.map +1 -1
  3. package/dist/better-sqlite-coordinator-store.d.ts +10 -1
  4. package/dist/better-sqlite-coordinator-store.d.ts.map +1 -1
  5. package/dist/coordinator-actions.d.ts +58 -1
  6. package/dist/coordinator-actions.d.ts.map +1 -1
  7. package/dist/{coordinator-api-Dbgsu1O8.js → coordinator-api-B9ooTSx5.js} +391 -121
  8. package/dist/coordinator-api-B9ooTSx5.js.map +1 -0
  9. package/dist/coordinator-api.d.ts.map +1 -1
  10. package/dist/coordinator-store-contract.d.ts +114 -0
  11. package/dist/coordinator-store-contract.d.ts.map +1 -1
  12. package/dist/coordinator-store-test-harness.d.ts.map +1 -1
  13. package/dist/coordinator-store.d.ts +1 -1
  14. package/dist/coordinator-store.d.ts.map +1 -1
  15. package/dist/d1-coordinator-store.d.ts +10 -1
  16. package/dist/d1-coordinator-store.d.ts.map +1 -1
  17. package/dist/db.d.ts +1 -1
  18. package/dist/db.d.ts.map +1 -1
  19. package/dist/export-import.d.ts.map +1 -1
  20. package/dist/index.d.ts +17 -5
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6120 -4258
  23. package/dist/index.js.map +1 -1
  24. package/dist/internal/cloudflare-coordinator.js +240 -47
  25. package/dist/internal/cloudflare-coordinator.js.map +1 -1
  26. package/dist/schema-bootstrap.d.ts.map +1 -1
  27. package/dist/schema.d.ts +5166 -2662
  28. package/dist/schema.d.ts.map +1 -1
  29. package/dist/scope-backfill.d.ts +67 -0
  30. package/dist/scope-backfill.d.ts.map +1 -0
  31. package/dist/scope-membership-cache.d.ts +78 -0
  32. package/dist/scope-membership-cache.d.ts.map +1 -0
  33. package/dist/scope-membership-semantics.d.ts +25 -0
  34. package/dist/scope-membership-semantics.d.ts.map +1 -0
  35. package/dist/scope-resolution.d.ts +40 -0
  36. package/dist/scope-resolution.d.ts.map +1 -0
  37. package/dist/scope-stamping.d.ts +10 -0
  38. package/dist/scope-stamping.d.ts.map +1 -0
  39. package/dist/store.d.ts +27 -0
  40. package/dist/store.d.ts.map +1 -1
  41. package/dist/sync-bootstrap.d.ts +6 -4
  42. package/dist/sync-bootstrap.d.ts.map +1 -1
  43. package/dist/sync-capability.d.ts +14 -0
  44. package/dist/sync-capability.d.ts.map +1 -0
  45. package/dist/sync-daemon.d.ts.map +1 -1
  46. package/dist/sync-pass.d.ts.map +1 -1
  47. package/dist/sync-replication.d.ts +94 -11
  48. package/dist/sync-replication.d.ts.map +1 -1
  49. package/dist/sync-retention-runner.d.ts +1 -0
  50. package/dist/sync-retention-runner.d.ts.map +1 -1
  51. package/dist/sync-scope-protocol.d.ts +32 -0
  52. package/dist/sync-scope-protocol.d.ts.map +1 -0
  53. package/dist/test-schema.generated.d.ts +1 -1
  54. package/dist/test-schema.generated.d.ts.map +1 -1
  55. package/dist/types.d.ts +45 -1
  56. package/dist/types.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/coordinator-api-Dbgsu1O8.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { r as e, t } from "../coordinator-api-Dbgsu1O8.js";
1
+ import { r as e, t } from "../coordinator-api-B9ooTSx5.js";
2
2
  //#region src/d1-coordinator-store.ts
3
3
  function n(e) {
4
4
  if (e == null) throw Error("expected row");
@@ -65,6 +65,94 @@ function u(e) {
65
65
  };
66
66
  }
67
67
  function d(e) {
68
+ return e?.trim() || null;
69
+ }
70
+ function f(e, t = 0) {
71
+ if (e == null) return t;
72
+ if (!Number.isFinite(e) || e < 0) throw Error("membershipEpoch must be non-negative.");
73
+ return Math.trunc(e);
74
+ }
75
+ function p(e) {
76
+ let t = d(e.scopeId), n = d(e.label);
77
+ if (!t || !n) throw Error("scopeId and label are required.");
78
+ return {
79
+ scopeId: t,
80
+ label: n,
81
+ kind: d(e.kind) ?? "user",
82
+ authorityType: d(e.authorityType) ?? "coordinator",
83
+ coordinatorId: d(e.coordinatorId),
84
+ groupId: d(e.groupId),
85
+ manifestIssuerDeviceId: d(e.manifestIssuerDeviceId),
86
+ membershipEpoch: f(e.membershipEpoch),
87
+ manifestHash: d(e.manifestHash),
88
+ status: d(e.status) ?? "active"
89
+ };
90
+ }
91
+ function m(e, t, n) {
92
+ if (e === void 0) return t;
93
+ let r = d(e);
94
+ if (!r) throw Error(`${n} must not be empty.`);
95
+ return r;
96
+ }
97
+ function h(e, t) {
98
+ return e === void 0 ? t : d(e);
99
+ }
100
+ function g(e, t) {
101
+ let n = d(e.scopeId);
102
+ if (!n) throw Error("scopeId is required.");
103
+ let r = e.membershipEpoch == null ? null : f(e.membershipEpoch);
104
+ if (r != null && r < t.membership_epoch) throw Error("membershipEpoch must not move backwards.");
105
+ return {
106
+ scopeId: n,
107
+ label: m(e.label, t.label, "label"),
108
+ kind: m(e.kind, t.kind, "kind"),
109
+ authorityType: m(e.authorityType, t.authority_type, "authorityType"),
110
+ coordinatorId: h(e.coordinatorId, t.coordinator_id),
111
+ groupId: h(e.groupId, t.group_id),
112
+ manifestIssuerDeviceId: h(e.manifestIssuerDeviceId, t.manifest_issuer_device_id),
113
+ membershipEpoch: r ?? t.membership_epoch,
114
+ manifestHash: h(e.manifestHash, t.manifest_hash),
115
+ status: m(e.status, t.status, "status")
116
+ };
117
+ }
118
+ function _(e, t, n) {
119
+ let r = d(e.scopeId), i = d(e.deviceId);
120
+ if (!r || !i) throw Error("scopeId and deviceId are required.");
121
+ let a = d(e.coordinatorId), o = d(e.groupId);
122
+ if (a && a !== t?.coordinator_id) throw Error("membership coordinatorId must match the scope coordinatorId.");
123
+ if (o && o !== t?.group_id) throw Error("membership groupId must match the scope groupId.");
124
+ let s = e.membershipEpoch == null ? null : f(e.membershipEpoch), c = t?.membership_epoch ?? 0;
125
+ if (s != null && s < c) throw Error("membershipEpoch must not be lower than the scope membershipEpoch.");
126
+ if (s != null && n && s < (n.status === "revoked" ? n.membership_epoch + 1 : n.membership_epoch)) throw Error("membershipEpoch must not move backwards.");
127
+ let l = s ?? (n ? Math.max(c, n.membership_epoch + +(n.status === "revoked")) : c);
128
+ return {
129
+ scopeId: r,
130
+ deviceId: i,
131
+ role: d(e.role) ?? "member",
132
+ membershipEpoch: l,
133
+ coordinatorId: t?.coordinator_id ?? null,
134
+ groupId: t?.group_id ?? null,
135
+ manifestIssuerDeviceId: d(e.manifestIssuerDeviceId) ?? t?.manifest_issuer_device_id ?? null,
136
+ manifestHash: d(e.manifestHash) ?? t?.manifest_hash ?? null,
137
+ signedManifestJson: d(e.signedManifestJson),
138
+ actorType: d(e.actorType),
139
+ actorId: d(e.actorId)
140
+ };
141
+ }
142
+ function v(e) {
143
+ return e == null || !Number.isFinite(e) ? 100 : Math.max(1, Math.min(1e3, Math.trunc(e)));
144
+ }
145
+ function y(e, t) {
146
+ return e.prepare("INSERT INTO coordinator_scope_membership_audit_log(\n action, scope_id, device_id, role, status, membership_epoch,\n previous_role, previous_status, previous_membership_epoch,\n coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at\n )\n SELECT ?, membership.scope_id, membership.device_id, membership.role, membership.status,\n membership.membership_epoch, ?, ?, ?, membership.coordinator_id, membership.group_id,\n ?, ?, membership.manifest_hash, ?\n FROM (SELECT 1 WHERE changes() > 0) AS required\n LEFT JOIN coordinator_scope_memberships AS membership\n ON membership.scope_id = ?\n AND membership.device_id = ?\n AND membership.status = ?\n AND membership.membership_epoch = ?\n AND membership.updated_at = ?").bind(t.action, t.previous?.role ?? null, t.previous?.status ?? null, t.previous?.membership_epoch ?? null, t.actorType, t.actorId, t.createdAt, t.scopeId, t.deviceId, t.status, t.membershipEpoch, t.updatedAt);
147
+ }
148
+ async function b(e, t) {
149
+ if (!e.batch) throw Error("D1 batch support is required for audited scope membership changes.");
150
+ return await e.batch(t);
151
+ }
152
+ function x(e) {
153
+ return Number(e?.meta?.changes ?? 0);
154
+ }
155
+ function S(e) {
68
156
  if (!e) return null;
69
157
  let t = String(e.seedDeviceId ?? "").trim(), n = String(e.expiresAt ?? "").trim(), r = String(e.createdBy ?? "").trim() || null;
70
158
  if (!t || !n) throw Error("bootstrapGrant.seedDeviceId and expiresAt are required.");
@@ -76,18 +164,18 @@ function d(e) {
76
164
  createdBy: r
77
165
  };
78
166
  }
79
- async function f(e) {
167
+ async function C(e) {
80
168
  let t = await e.all();
81
169
  return Array.isArray(t?.results) ? t.results : [];
82
170
  }
83
- async function p(e) {
171
+ async function w(e) {
84
172
  return await e.first();
85
173
  }
86
- async function m(e) {
174
+ async function T(e) {
87
175
  let t = await e.run();
88
176
  return Number(t?.meta?.changes ?? 0);
89
177
  }
90
- var h = class {
178
+ var E = class {
91
179
  db;
92
180
  constructor(e) {
93
181
  this.db = e;
@@ -97,80 +185,80 @@ var h = class {
97
185
  await this.db.prepare("INSERT OR IGNORE INTO groups(group_id, display_name, archived_at, created_at) VALUES (?, ?, NULL, ?)").bind(e, t ?? null, o()).run();
98
186
  }
99
187
  async getGroup(e) {
100
- let t = await p(this.db.prepare("SELECT group_id, display_name, archived_at, created_at FROM groups WHERE group_id = ?").bind(e));
188
+ let t = await w(this.db.prepare("SELECT group_id, display_name, archived_at, created_at FROM groups WHERE group_id = ?").bind(e));
101
189
  return t ? n(t) : null;
102
190
  }
103
191
  async listGroups(e = !1) {
104
192
  let t = e ? "" : "WHERE archived_at IS NULL";
105
- return (await f(this.db.prepare(`SELECT group_id, display_name, archived_at, created_at FROM groups ${t} ORDER BY created_at ASC`))).map((e) => n(e));
193
+ return (await C(this.db.prepare(`SELECT group_id, display_name, archived_at, created_at FROM groups ${t} ORDER BY created_at ASC`))).map((e) => n(e));
106
194
  }
107
195
  async renameGroup(e, t) {
108
- return await m(this.db.prepare("UPDATE groups SET display_name = ? WHERE group_id = ?").bind(t, e)) > 0;
196
+ return await T(this.db.prepare("UPDATE groups SET display_name = ? WHERE group_id = ?").bind(t, e)) > 0;
109
197
  }
110
198
  async archiveGroup(e, t = o()) {
111
- return await m(this.db.prepare("UPDATE groups SET archived_at = ? WHERE group_id = ? AND archived_at IS NULL").bind(t, e)) > 0;
199
+ return await T(this.db.prepare("UPDATE groups SET archived_at = ? WHERE group_id = ? AND archived_at IS NULL").bind(t, e)) > 0;
112
200
  }
113
201
  async unarchiveGroup(e) {
114
- return await m(this.db.prepare("UPDATE groups SET archived_at = NULL WHERE group_id = ? AND archived_at IS NOT NULL").bind(e)) > 0;
202
+ return await T(this.db.prepare("UPDATE groups SET archived_at = NULL WHERE group_id = ? AND archived_at IS NOT NULL").bind(e)) > 0;
115
203
  }
116
204
  async enrollDevice(e, t) {
117
205
  await this.db.prepare("INSERT INTO enrolled_devices(\n group_id, device_id, public_key, fingerprint, display_name, enabled, created_at\n ) VALUES (?, ?, ?, ?, ?, 1, ?)\n ON CONFLICT(group_id, device_id) DO UPDATE SET\n public_key = excluded.public_key,\n fingerprint = excluded.fingerprint,\n display_name = excluded.display_name,\n enabled = 1").bind(e, t.deviceId, t.publicKey, t.fingerprint, t.displayName ?? null, o()).run();
118
206
  }
119
207
  async listEnrolledDevices(e, t) {
120
208
  let r = t ? "" : "AND enabled = 1";
121
- return (await f(this.db.prepare(`SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at
209
+ return (await C(this.db.prepare(`SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at
122
210
  FROM enrolled_devices
123
211
  WHERE group_id = ? ${r}
124
212
  ORDER BY created_at ASC, device_id ASC`).bind(e))).map((e) => n(e));
125
213
  }
126
214
  async getEnrollment(e, t) {
127
- let r = await p(this.db.prepare("SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at\n FROM enrolled_devices\n WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(e, t));
215
+ let r = await w(this.db.prepare("SELECT group_id, device_id, public_key, fingerprint, display_name, enabled, created_at\n FROM enrolled_devices\n WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(e, t));
128
216
  return r ? n(r) : null;
129
217
  }
130
218
  async renameDevice(e, t, n) {
131
- return await m(this.db.prepare("UPDATE enrolled_devices SET display_name = ?\n WHERE group_id = ? AND device_id = ?").bind(n, e, t)) > 0;
219
+ return await T(this.db.prepare("UPDATE enrolled_devices SET display_name = ?\n WHERE group_id = ? AND device_id = ?").bind(n, e, t)) > 0;
132
220
  }
133
221
  async setDeviceEnabled(e, t, n) {
134
- return await m(this.db.prepare("UPDATE enrolled_devices SET enabled = ?\n WHERE group_id = ? AND device_id = ?").bind(+!!n, e, t)) > 0;
222
+ return await T(this.db.prepare("UPDATE enrolled_devices SET enabled = ?\n WHERE group_id = ? AND device_id = ?").bind(+!!n, e, t)) > 0;
135
223
  }
136
224
  async removeDevice(e, t) {
137
- return await this.db.prepare("DELETE FROM presence_records WHERE group_id = ? AND device_id = ?").bind(e, t).run(), await this.db.prepare("DELETE FROM coordinator_reciprocal_approvals WHERE group_id = ? AND (requesting_device_id = ? OR requested_device_id = ?)").bind(e, t, t).run(), await m(this.db.prepare("DELETE FROM enrolled_devices WHERE group_id = ? AND device_id = ?").bind(e, t)) > 0;
225
+ return await this.db.prepare("DELETE FROM presence_records WHERE group_id = ? AND device_id = ?").bind(e, t).run(), await this.db.prepare("DELETE FROM coordinator_reciprocal_approvals WHERE group_id = ? AND (requesting_device_id = ? OR requested_device_id = ?)").bind(e, t, t).run(), await T(this.db.prepare("DELETE FROM enrolled_devices WHERE group_id = ? AND device_id = ?").bind(e, t)) > 0;
138
226
  }
139
227
  async recordNonce(e, t, n) {
140
- return await m(this.db.prepare("INSERT OR IGNORE INTO request_nonces(device_id, nonce, created_at) VALUES (?, ?, ?)").bind(e, t, n)) > 0;
228
+ return await T(this.db.prepare("INSERT OR IGNORE INTO request_nonces(device_id, nonce, created_at) VALUES (?, ?, ?)").bind(e, t, n)) > 0;
141
229
  }
142
230
  async cleanupNonces(e) {
143
231
  await this.db.prepare("DELETE FROM request_nonces WHERE created_at < ?").bind(e).run();
144
232
  }
145
233
  async createInvite(e) {
146
234
  let t = o(), r = l(12), i = l(24), a = await this.getGroup(e.groupId);
147
- return await this.db.prepare("INSERT INTO coordinator_invites(\n invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)").bind(r, e.groupId, i, e.policy, e.expiresAt, t, e.createdBy ?? null, a?.display_name ?? null).run(), n(await p(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE invite_id = ?").bind(r)));
235
+ return await this.db.prepare("INSERT INTO coordinator_invites(\n invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL)").bind(r, e.groupId, i, e.policy, e.expiresAt, t, e.createdBy ?? null, a?.display_name ?? null).run(), n(await w(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE invite_id = ?").bind(r)));
148
236
  }
149
237
  async getInviteByToken(e) {
150
- let t = await p(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites\n WHERE token = ?\n AND revoked_at IS NULL\n AND expires_at > ?").bind(e, o()));
238
+ let t = await w(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites\n WHERE token = ?\n AND revoked_at IS NULL\n AND expires_at > ?").bind(e, o()));
151
239
  return t ? n(t) : null;
152
240
  }
153
241
  async listInvites(e) {
154
- return (await f(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE group_id = ?\n ORDER BY created_at DESC").bind(e))).map((e) => n(e));
242
+ return (await C(this.db.prepare("SELECT invite_id, group_id, token, policy, expires_at, created_at, created_by, team_name_snapshot, revoked_at\n FROM coordinator_invites WHERE group_id = ?\n ORDER BY created_at DESC").bind(e))).map((e) => n(e));
155
243
  }
156
244
  async createJoinRequest(e) {
157
245
  let t = o(), r = l(12);
158
- return await this.db.prepare("INSERT INTO coordinator_join_requests(\n request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, NULL, NULL)").bind(r, e.groupId, e.deviceId, e.publicKey, e.fingerprint, e.displayName ?? null, e.token, t).run(), n(await p(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(r)));
246
+ return await this.db.prepare("INSERT INTO coordinator_join_requests(\n request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n ) VALUES (?, ?, ?, ?, ?, ?, ?, 'pending', ?, NULL, NULL)").bind(r, e.groupId, e.deviceId, e.publicKey, e.fingerprint, e.displayName ?? null, e.token, t).run(), n(await w(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(r)));
159
247
  }
160
248
  async listJoinRequests(e, t) {
161
249
  let r = t ?? "pending";
162
- return (await f(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests\n WHERE group_id = ? AND status = ?\n ORDER BY created_at ASC, device_id ASC").bind(e, r))).map((e) => n(e));
250
+ return (await C(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests\n WHERE group_id = ? AND status = ?\n ORDER BY created_at ASC, device_id ASC").bind(e, r))).map((e) => n(e));
163
251
  }
164
252
  async reviewJoinRequest(e) {
165
- let t = await p(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status,\n created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
253
+ let t = await w(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status,\n created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
166
254
  if (!t) return null;
167
255
  if (t.status !== "pending") return {
168
256
  ...n(t),
169
257
  _no_transition: !0
170
258
  };
171
- let r = d(e.bootstrapGrant), i = o(), a = e.approved ? "approved" : "denied", s = null, c = null;
259
+ let r = S(e.bootstrapGrant), i = o(), a = e.approved ? "approved" : "denied", s = null, c = null;
172
260
  if (e.approved && r) {
173
- if (!await p(this.db.prepare("SELECT device_id FROM enrolled_devices WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(t.group_id, r.seedDeviceId))) throw Error("bootstrap grant seed device is not enrolled in the group.");
261
+ if (!await w(this.db.prepare("SELECT device_id FROM enrolled_devices WHERE group_id = ? AND device_id = ? AND enabled = 1").bind(t.group_id, r.seedDeviceId))) throw Error("bootstrap grant seed device is not enrolled in the group.");
174
262
  if (r.seedDeviceId === t.device_id) throw Error("bootstrap grant seed and worker device ids must differ.");
175
263
  s = {
176
264
  ...r,
@@ -197,67 +285,172 @@ var h = class {
197
285
  let e = await this.createBootstrapGrant(s);
198
286
  r = e.grant_id, c = e.grant_id;
199
287
  }
200
- if (await m(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(a, i, e.reviewedBy ?? null, e.requestId)) === 0) {
288
+ if (await T(this.db.prepare("UPDATE coordinator_join_requests\n SET status = ?, reviewed_at = ?, reviewed_by = ?\n WHERE request_id = ? AND status = 'pending'").bind(a, i, e.reviewedBy ?? null, e.requestId)) === 0) {
201
289
  r && await this.revokeBootstrapGrant(r);
202
- let t = await p(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
290
+ let t = await w(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
203
291
  return t ? {
204
292
  ...n(t),
205
293
  _no_transition: !0
206
294
  } : null;
207
295
  }
208
296
  }
209
- let u = await p(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
297
+ let u = await w(this.db.prepare("SELECT request_id, group_id, device_id, public_key, fingerprint, display_name, token, status, created_at, reviewed_at, reviewed_by\n FROM coordinator_join_requests WHERE request_id = ?").bind(e.requestId));
210
298
  if (!u) return null;
211
- let f = s ? c ? await this.getBootstrapGrant(c) : await this.createBootstrapGrant(s) : null;
299
+ let d = s ? c ? await this.getBootstrapGrant(c) : await this.createBootstrapGrant(s) : null;
212
300
  return {
213
301
  ...n(u),
214
- bootstrap_grant: f
302
+ bootstrap_grant: d
215
303
  };
216
304
  }
217
305
  async createReciprocalApproval(e) {
218
306
  let t = e.groupId.trim(), r = e.requestingDeviceId.trim(), i = e.requestedDeviceId.trim();
219
307
  if (!t || !r || !i) throw Error("groupId, requestingDeviceId, and requestedDeviceId are required.");
220
308
  if (r === i) throw Error("requesting and requested device ids must differ.");
221
- let a = s(r, i), u = await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, i));
309
+ let a = s(r, i), u = await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, i));
222
310
  if (u) return n(u);
223
- let d = await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, i, r));
311
+ let d = await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, i, r));
224
312
  if (d) {
225
313
  let e = o();
226
- return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, d.request_id).run(), n(await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(d.request_id)));
314
+ return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, d.request_id).run(), n(await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(d.request_id)));
227
315
  }
228
- let f = l(12), m = o();
316
+ let f = l(12), p = o();
229
317
  try {
230
- await this.db.prepare("INSERT INTO coordinator_reciprocal_approvals(\n request_id,\n group_id,\n requesting_device_id,\n requested_device_id,\n pending_pair_low_device_id,\n pending_pair_high_device_id,\n status,\n created_at,\n resolved_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, NULL)").bind(f, t, r, i, a.low, a.high, m).run();
318
+ await this.db.prepare("INSERT INTO coordinator_reciprocal_approvals(\n request_id,\n group_id,\n requesting_device_id,\n requested_device_id,\n pending_pair_low_device_id,\n pending_pair_high_device_id,\n status,\n created_at,\n resolved_at\n ) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?, NULL)").bind(f, t, r, i, a.low, a.high, p).run();
231
319
  } catch (e) {
232
320
  if (!c(e)) throw e;
233
- let a = await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, i));
321
+ let a = await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, r, i));
234
322
  if (a) return n(a);
235
- let s = await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, i, r));
323
+ let s = await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals\n WHERE group_id = ? AND requesting_device_id = ? AND requested_device_id = ? AND status = 'pending'\n ORDER BY created_at DESC LIMIT 1").bind(t, i, r));
236
324
  if (s) {
237
325
  let e = o();
238
- return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, s.request_id).run(), n(await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(s.request_id)));
326
+ return await this.db.prepare("UPDATE coordinator_reciprocal_approvals SET status = 'completed', resolved_at = ? WHERE request_id = ?").bind(e, s.request_id).run(), n(await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(s.request_id)));
239
327
  }
240
328
  throw e;
241
329
  }
242
- return n(await p(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(f)));
330
+ return n(await w(this.db.prepare("SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at\n FROM coordinator_reciprocal_approvals WHERE request_id = ?").bind(f)));
243
331
  }
244
332
  async createBootstrapGrant(e) {
245
333
  let t = u(e), r = l(12), i = o();
246
- return await this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL)").bind(r, t.groupId, t.seedDeviceId, t.workerDeviceId, t.expiresAt, i, t.createdBy).run(), n(await p(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(r)));
334
+ return await this.db.prepare("INSERT INTO coordinator_bootstrap_grants(\n grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, NULL)").bind(r, t.groupId, t.seedDeviceId, t.workerDeviceId, t.expiresAt, i, t.createdBy).run(), n(await w(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(r)));
335
+ }
336
+ async getScope(e) {
337
+ let t = await w(this.db.prepare("SELECT scope_id, label, kind, authority_type, coordinator_id, group_id,\n manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at\n FROM coordinator_scopes WHERE scope_id = ?").bind(e));
338
+ return t ? n(t) : null;
339
+ }
340
+ async getScopeMembership(e, t) {
341
+ let r = await w(this.db.prepare("SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,\n manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at\n FROM coordinator_scope_memberships\n WHERE scope_id = ? AND device_id = ?").bind(e, t));
342
+ return r ? n(r) : null;
343
+ }
344
+ async createScope(e) {
345
+ let t = p(e);
346
+ if (await this.getScope(t.scopeId)) throw Error("scopeId already exists.");
347
+ let n = o();
348
+ await this.db.prepare("INSERT INTO coordinator_scopes(\n scope_id, label, kind, authority_type, coordinator_id, group_id,\n manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)").bind(t.scopeId, t.label, t.kind, t.authorityType, t.coordinatorId, t.groupId, t.manifestIssuerDeviceId, t.membershipEpoch, t.manifestHash, t.status, n, n).run();
349
+ let r = await this.getScope(t.scopeId);
350
+ if (!r) throw Error("scope insert returned no row");
351
+ return r;
352
+ }
353
+ async updateScope(e) {
354
+ let t = d(e.scopeId), n = t ? await this.getScope(t) : null;
355
+ if (!n) return null;
356
+ let r = g(e, n);
357
+ return await this.db.prepare("UPDATE coordinator_scopes\n SET label = ?,\n kind = ?,\n authority_type = ?,\n coordinator_id = ?,\n group_id = ?,\n manifest_issuer_device_id = ?,\n membership_epoch = ?,\n manifest_hash = ?,\n status = ?,\n updated_at = ?\n WHERE scope_id = ?").bind(r.label, r.kind, r.authorityType, r.coordinatorId, r.groupId, r.manifestIssuerDeviceId, r.membershipEpoch, r.manifestHash, r.status, o(), r.scopeId).run(), await this.getScope(r.scopeId);
358
+ }
359
+ async listScopes(e = {}) {
360
+ let t = [], r = [], i = d(e.coordinatorId), a = d(e.groupId), o = d(e.status);
361
+ i && (t.push("coordinator_id = ?"), r.push(i)), a && (t.push("group_id = ?"), r.push(a)), o ? (t.push("status = ?"), r.push(o)) : e.includeInactive || t.push("status = 'active'");
362
+ let s = t.length ? `WHERE ${t.join(" AND ")}` : "", c = this.db.prepare(`SELECT scope_id, label, kind, authority_type, coordinator_id, group_id,
363
+ manifest_issuer_device_id, membership_epoch, manifest_hash, status, created_at, updated_at
364
+ FROM coordinator_scopes ${s}
365
+ ORDER BY coordinator_id ASC, group_id ASC, scope_id ASC`);
366
+ return (await C(r.length ? c.bind(...r) : c)).map((e) => n(e));
367
+ }
368
+ async grantScopeMembership(e) {
369
+ let t = d(e.scopeId), r = d(e.deviceId), i = t ? await this.getScope(t) : null;
370
+ if (!i) throw Error("scopeId must reference an existing scope.");
371
+ let a = t && r ? await this.getScopeMembership(t, r) : null, s = _(e, i, a);
372
+ if (s.groupId && !await this.getEnrollment(s.groupId, s.deviceId)) throw Error("device must be enrolled and enabled in the scope group.");
373
+ let c = o();
374
+ if (x((await b(this.db, [this.db.prepare("INSERT INTO coordinator_scope_memberships(\n scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,\n manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at\n ) VALUES (?, ?, ?, 'active', ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(scope_id, device_id) DO UPDATE SET\n role = excluded.role,\n status = 'active',\n membership_epoch = excluded.membership_epoch,\n coordinator_id = excluded.coordinator_id,\n group_id = excluded.group_id,\n manifest_issuer_device_id = excluded.manifest_issuer_device_id,\n manifest_hash = excluded.manifest_hash,\n signed_manifest_json = excluded.signed_manifest_json,\n updated_at = excluded.updated_at\n WHERE excluded.membership_epoch > coordinator_scope_memberships.membership_epoch\n OR (\n excluded.membership_epoch = coordinator_scope_memberships.membership_epoch\n AND coordinator_scope_memberships.status != 'revoked'\n )").bind(s.scopeId, s.deviceId, s.role, s.membershipEpoch, s.coordinatorId, s.groupId, s.manifestIssuerDeviceId, s.manifestHash, s.signedManifestJson, c), y(this.db, {
375
+ action: "grant",
376
+ previous: a,
377
+ scopeId: s.scopeId,
378
+ deviceId: s.deviceId,
379
+ status: "active",
380
+ membershipEpoch: s.membershipEpoch,
381
+ updatedAt: c,
382
+ actorType: s.actorType,
383
+ actorId: s.actorId,
384
+ createdAt: c
385
+ })]))[0]) <= 0) throw Error("scope membership grant was not applied.");
386
+ return n(await w(this.db.prepare("SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,\n manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at\n FROM coordinator_scope_memberships\n WHERE scope_id = ? AND device_id = ?").bind(s.scopeId, s.deviceId)));
387
+ }
388
+ async revokeScopeMembership(e) {
389
+ let t = d(e.scopeId), n = d(e.deviceId);
390
+ if (!t || !n) throw Error("scopeId and deviceId are required.");
391
+ let r = e.membershipEpoch == null ? null : f(e.membershipEpoch), i = await this.getScopeMembership(t, n);
392
+ if (!i) return !1;
393
+ if (r != null && i && r <= i.membership_epoch) throw Error("membershipEpoch must increase on revoke.");
394
+ let a = o(), s = r ?? i.membership_epoch + 1, c = this.db.prepare("UPDATE coordinator_scope_memberships\n SET status = 'revoked',\n membership_epoch = CASE WHEN ? IS NULL THEN membership_epoch + 1 ELSE ? END,\n manifest_hash = COALESCE(?, manifest_hash),\n signed_manifest_json = COALESCE(?, signed_manifest_json),\n updated_at = ?\n WHERE scope_id = ? AND device_id = ? AND membership_epoch = ? AND status = ?").bind(r, r, d(e.manifestHash), d(e.signedManifestJson), a, t, n, i.membership_epoch, i.status), l = y(this.db, {
395
+ action: "revoke",
396
+ previous: i,
397
+ scopeId: t,
398
+ deviceId: n,
399
+ status: "revoked",
400
+ membershipEpoch: s,
401
+ updatedAt: a,
402
+ actorType: d(e.actorType),
403
+ actorId: d(e.actorId),
404
+ createdAt: a
405
+ }), u;
406
+ try {
407
+ u = await b(this.db, [c, l]);
408
+ } catch (e) {
409
+ let r = await this.getScopeMembership(t, n);
410
+ if (!r || r.membership_epoch !== i.membership_epoch || r.status !== i.status) return !1;
411
+ throw e;
412
+ }
413
+ return !(x(u[0]) <= 0);
414
+ }
415
+ async listScopeMemberships(e, t = !1) {
416
+ let r = d(e);
417
+ if (!r) throw Error("scopeId is required.");
418
+ let i = t ? "" : "AND status = 'active'";
419
+ return (await C(this.db.prepare(`SELECT scope_id, device_id, role, status, membership_epoch, coordinator_id, group_id,
420
+ manifest_issuer_device_id, manifest_hash, signed_manifest_json, updated_at
421
+ FROM coordinator_scope_memberships
422
+ WHERE scope_id = ? ${i}
423
+ ORDER BY device_id ASC`).bind(r))).map((e) => n(e));
424
+ }
425
+ async listScopeMembershipAuditEvents(e) {
426
+ let t = d(e.scopeId);
427
+ if (!t) throw Error("scopeId is required.");
428
+ let r = d(e.deviceId), i = v(e.limit), a = r ? "scope_id = ? AND device_id = ?" : "scope_id = ?", o = r ? [
429
+ t,
430
+ r,
431
+ i
432
+ ] : [t, i];
433
+ return (await C(this.db.prepare(`SELECT event_id, action, scope_id, device_id, role, status, membership_epoch,
434
+ previous_role, previous_status, previous_membership_epoch,
435
+ coordinator_id, group_id, actor_type, actor_id, manifest_hash, created_at
436
+ FROM coordinator_scope_membership_audit_log
437
+ WHERE ${a}
438
+ ORDER BY event_id ASC
439
+ LIMIT ?`).bind(...o))).map((e) => n(e));
247
440
  }
248
441
  async getBootstrapGrant(e) {
249
- let t = await p(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(e));
442
+ let t = await w(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE grant_id = ?").bind(e));
250
443
  return t ? n(t) : null;
251
444
  }
252
445
  async listBootstrapGrants(e) {
253
- return (await f(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE group_id = ?\n ORDER BY created_at DESC, grant_id DESC").bind(e))).map((e) => n(e));
446
+ return (await C(this.db.prepare("SELECT grant_id, group_id, seed_device_id, worker_device_id, expires_at, created_at, created_by, revoked_at\n FROM coordinator_bootstrap_grants WHERE group_id = ?\n ORDER BY created_at DESC, grant_id DESC").bind(e))).map((e) => n(e));
254
447
  }
255
448
  async revokeBootstrapGrant(e, t = o()) {
256
- return await m(this.db.prepare("UPDATE coordinator_bootstrap_grants\n SET revoked_at = COALESCE(revoked_at, ?)\n WHERE grant_id = ?").bind(t, e)) > 0;
449
+ return await T(this.db.prepare("UPDATE coordinator_bootstrap_grants\n SET revoked_at = COALESCE(revoked_at, ?)\n WHERE grant_id = ?").bind(t, e)) > 0;
257
450
  }
258
451
  async listReciprocalApprovals(e) {
259
452
  let t = e.direction === "incoming" ? "requested_device_id" : "requesting_device_id", r = e.status?.trim() || "pending";
260
- return (await f(this.db.prepare(`SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at
453
+ return (await C(this.db.prepare(`SELECT request_id, group_id, requesting_device_id, requested_device_id, status, created_at, resolved_at
261
454
  FROM coordinator_reciprocal_approvals
262
455
  WHERE group_id = ? AND ${t} = ? AND status = ?
263
456
  ORDER BY created_at ASC, request_id ASC`).bind(e.groupId, e.deviceId, r))).map((e) => n(e));
@@ -273,7 +466,7 @@ var h = class {
273
466
  }
274
467
  async listGroupPeers(e, t) {
275
468
  let n = o();
276
- return (await f(this.db.prepare("SELECT enrolled_devices.device_id, enrolled_devices.public_key, enrolled_devices.fingerprint, enrolled_devices.display_name,\n presence_records.addresses_json, presence_records.last_seen_at, presence_records.expires_at,\n presence_records.capabilities_json\n FROM enrolled_devices\n LEFT JOIN presence_records\n ON presence_records.group_id = enrolled_devices.group_id\n AND presence_records.device_id = enrolled_devices.device_id\n WHERE enrolled_devices.group_id = ?\n AND enrolled_devices.enabled = 1\n AND enrolled_devices.device_id != ?\n ORDER BY enrolled_devices.device_id ASC").bind(e, t))).map((e) => {
469
+ return (await C(this.db.prepare("SELECT enrolled_devices.device_id, enrolled_devices.public_key, enrolled_devices.fingerprint, enrolled_devices.display_name,\n presence_records.addresses_json, presence_records.last_seen_at, presence_records.expires_at,\n presence_records.capabilities_json\n FROM enrolled_devices\n LEFT JOIN presence_records\n ON presence_records.group_id = enrolled_devices.group_id\n AND presence_records.device_id = enrolled_devices.device_id\n WHERE enrolled_devices.group_id = ?\n AND enrolled_devices.enabled = 1\n AND enrolled_devices.device_id != ?\n ORDER BY enrolled_devices.device_id ASC").bind(e, t))).map((e) => {
277
470
  let t = String(e.expires_at ?? "").trim(), r = !0;
278
471
  if (t) {
279
472
  let e = new Date(t);
@@ -296,9 +489,9 @@ var h = class {
296
489
  };
297
490
  //#endregion
298
491
  //#region src/d1-coordinator-runtime.ts
299
- function g(e) {
492
+ function D(e) {
300
493
  return t({
301
- storeFactory: () => new h(e.db),
494
+ storeFactory: () => new E(e.db),
302
495
  runtime: {
303
496
  adminSecret: () => String(e.adminSecret ?? "").trim() || null,
304
497
  now: e.now ?? (() => (/* @__PURE__ */ new Date()).toISOString())
@@ -307,6 +500,6 @@ function g(e) {
307
500
  });
308
501
  }
309
502
  //#endregion
310
- export { h as D1CoordinatorStore, e as DEFAULT_TIME_WINDOW_S, g as createD1CoordinatorApp };
503
+ export { E as D1CoordinatorStore, e as DEFAULT_TIME_WINDOW_S, D as createD1CoordinatorApp };
311
504
 
312
505
  //# sourceMappingURL=cloudflare-coordinator.js.map