@rei-standard/amsg-server 2.6.0-next.8 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +861 -35
  3. package/dist/adapters/d1.d.ts +693 -0
  4. package/dist/adapters/factory.d.ts +39 -0
  5. package/dist/adapters/interface.d.ts +384 -0
  6. package/dist/adapters/neon.d.ts +105 -0
  7. package/dist/adapters/pg-shared.d.ts +194 -0
  8. package/dist/adapters/pg.d.ts +101 -0
  9. package/dist/adapters/schema.d.ts +57 -0
  10. package/dist/adapters/schema.sqlite.d.ts +80 -0
  11. package/dist/chunk-7NMQFTDJ.cjs +148 -0
  12. package/dist/{chunk-GOBCWCJP.mjs → chunk-GN44PST5.mjs} +68 -1
  13. package/dist/chunk-RL7V7VSS.mjs +8784 -0
  14. package/dist/chunk-TKDISKCF.cjs +163 -0
  15. package/dist/chunk-XKUWMYVF.mjs +163 -0
  16. package/dist/chunk-YBDQJVFQ.cjs +8784 -0
  17. package/dist/cloudflare/single-user-worker.d.ts +39 -0
  18. package/dist/cloudflare.cjs +35 -2
  19. package/dist/cloudflare.d.ts +11 -2
  20. package/dist/cloudflare.mjs +36 -3
  21. package/dist/handlers/cancel-message.d.ts +3 -0
  22. package/dist/handlers/capabilities.d.ts +4 -0
  23. package/dist/handlers/client-state-namespaces.d.ts +5 -0
  24. package/dist/handlers/client-state.d.ts +7 -0
  25. package/dist/handlers/cloud-data.d.ts +4 -0
  26. package/dist/handlers/get-message.d.ts +3 -0
  27. package/dist/handlers/get-user-key.d.ts +3 -0
  28. package/dist/handlers/init-tenant.d.ts +23 -0
  29. package/dist/handlers/llm-credentials.d.ts +5 -0
  30. package/dist/handlers/messages.d.ts +3 -0
  31. package/dist/handlers/outbox.d.ts +9 -0
  32. package/dist/handlers/push-subscription.d.ts +5 -0
  33. package/dist/handlers/schedule-message.d.ts +3 -0
  34. package/dist/handlers/send-notifications.d.ts +3 -0
  35. package/dist/handlers/single-user-init.d.ts +13 -0
  36. package/dist/handlers/update-message.d.ts +3 -0
  37. package/dist/handlers/vapid-public-key.d.ts +19 -0
  38. package/dist/index.cjs +133 -44
  39. package/dist/index.d.cts +145 -766
  40. package/dist/index.d.ts +145 -766
  41. package/dist/index.mjs +125 -36
  42. package/dist/lib/agentic-fire.d.ts +177 -0
  43. package/dist/lib/client-state-store.d.ts +88 -0
  44. package/dist/lib/cloud-data-cleanup.d.ts +36 -0
  45. package/dist/lib/cloud-data-guard.d.ts +14 -0
  46. package/dist/lib/cloud-data-inventory.d.ts +15 -0
  47. package/dist/lib/constant-time.d.ts +14 -0
  48. package/dist/lib/db-errors.d.ts +10 -0
  49. package/dist/lib/encryption.d.ts +48 -0
  50. package/dist/lib/errors.d.ts +273 -0
  51. package/dist/lib/llm-credentials-store.d.ts +147 -0
  52. package/dist/lib/llm.d.ts +12 -0
  53. package/dist/lib/message-processor.d.ts +82 -0
  54. package/dist/lib/outbox-store.d.ts +162 -0
  55. package/dist/lib/push-policy.d.ts +11 -0
  56. package/dist/lib/push-subscription-store.d.ts +94 -0
  57. package/dist/lib/recurrence.d.ts +51 -0
  58. package/dist/lib/request.d.ts +182 -0
  59. package/dist/lib/result-emitter.d.ts +60 -0
  60. package/dist/lib/retry-policy.d.ts +11 -0
  61. package/dist/lib/run-tick.d.ts +121 -0
  62. package/dist/lib/schema-version.d.ts +50 -0
  63. package/dist/lib/state-accessors.d.ts +70 -0
  64. package/dist/lib/state-chunks.d.ts +65 -0
  65. package/dist/lib/task-projection.d.ts +92 -0
  66. package/dist/lib/validation.d.ts +97 -0
  67. package/dist/lib/version.d.ts +7 -0
  68. package/dist/lib/webcrypto-utils.d.ts +1 -0
  69. package/dist/lib/webpush-webcrypto.d.ts +78 -0
  70. package/dist/{neon-QJ7KYHEX.mjs → neon-GKLT4UY3.mjs} +116 -44
  71. package/dist/{neon-V4VOH55N.cjs → neon-XHPJZESV.cjs} +121 -49
  72. package/dist/{pg-6X74HKMX.cjs → pg-FHXQ6BJP.cjs} +109 -48
  73. package/dist/{pg-DFJSFOJQ.mjs → pg-J4YXRQP5.mjs} +104 -43
  74. package/dist/single-user.d.ts +106 -0
  75. package/dist/tenant/blob-store.d.ts +30 -0
  76. package/dist/tenant/context.d.ts +47 -0
  77. package/dist/tenant/single-user-context.d.ts +29 -0
  78. package/dist/tenant/token.d.ts +26 -0
  79. package/package.json +3 -3
  80. package/dist/chunk-DCKCAGFV.cjs +0 -81
  81. package/dist/chunk-HQHRXSQA.cjs +0 -2710
  82. package/dist/chunk-LEE5KQ7Y.mjs +0 -2710
  83. package/dist/cloudflare-CH3dBl5b.d.cts +0 -4235
  84. package/dist/cloudflare-CH3dBl5b.d.ts +0 -4235
  85. package/dist/cloudflare.d.cts +0 -2
  86. package/dist/neon-D8Z2Nn97.d.cts +0 -295
  87. package/dist/neon-PqNFJIz2.d.ts +0 -295
  88. package/dist/pg-C48FwCWW.d.cts +0 -289
  89. package/dist/pg-C5gtWUfU.d.ts +0 -289
  90. package/dist/schema-BHuyH_6Z.d.cts +0 -88
  91. package/dist/schema-BHuyH_6Z.d.ts +0 -88
@@ -0,0 +1,163 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/server/adapters/pg-shared.js
2
+ async function claimTask(query, taskId, expectedNextSendAt, leaseUntil, serializeGroup = null) {
3
+ const grouped = typeof serializeGroup === "string" && serializeGroup.length > 0;
4
+ const params = [leaseUntil, taskId, expectedNextSendAt];
5
+ let setClause = "lease_until = $1, updated_at = NOW()";
6
+ let groupGuard = "";
7
+ if (grouped) {
8
+ params.push(serializeGroup);
9
+ setClause = "lease_until = $1, serialize_group = $4, updated_at = NOW()";
10
+ groupGuard = `
11
+ AND NOT EXISTS (
12
+ SELECT 1 FROM scheduled_messages busy
13
+ WHERE busy.serialize_group = $4 AND busy.id <> $2
14
+ AND busy.status = 'pending' AND busy.lease_until > NOW()
15
+ )`;
16
+ }
17
+ const rows = await query(
18
+ `UPDATE scheduled_messages
19
+ SET ${setClause}
20
+ WHERE id = $2 AND status = 'pending'
21
+ AND date_trunc('milliseconds', next_send_at)
22
+ = date_trunc('milliseconds', $3::timestamptz)
23
+ AND (lease_until IS NULL OR lease_until <= NOW())${groupGuard}
24
+ RETURNING id`,
25
+ params
26
+ );
27
+ if (rows.length === 0) return false;
28
+ if (!grouped) return true;
29
+ const conflict = await query(
30
+ `SELECT 1 FROM scheduled_messages busy
31
+ WHERE busy.serialize_group = $1 AND busy.id <> $2
32
+ AND busy.status = 'pending' AND busy.lease_until > NOW()
33
+ LIMIT 1`,
34
+ [serializeGroup, taskId]
35
+ );
36
+ if (conflict.length === 0) return true;
37
+ await query(
38
+ "UPDATE scheduled_messages SET lease_until = NULL, updated_at = NOW() WHERE id = $1",
39
+ [taskId]
40
+ );
41
+ return false;
42
+ }
43
+ async function renewTaskLease(query, taskId, leaseUntil) {
44
+ const rows = await query(
45
+ `UPDATE scheduled_messages SET lease_until = $1
46
+ WHERE id = $2 AND status = 'pending' AND lease_until IS NOT NULL
47
+ RETURNING id`,
48
+ [leaseUntil, taskId]
49
+ );
50
+ return rows.length > 0;
51
+ }
52
+ async function createTaskSuperseding(query, params, supersedesUuid) {
53
+ const rows = await query(
54
+ `WITH deleted AS (
55
+ DELETE FROM scheduled_messages
56
+ WHERE uuid = $6 AND user_id = $1
57
+ RETURNING id
58
+ ), inserted AS (
59
+ INSERT INTO scheduled_messages
60
+ (user_id, uuid, encrypted_payload, next_send_at, message_type, status, retry_count, created_at, updated_at)
61
+ VALUES ($1, $2, $3, $4, $5, 'pending', 0, NOW(), NOW())
62
+ RETURNING id, uuid, next_send_at, status, created_at
63
+ )
64
+ SELECT inserted.*, (SELECT count(*) FROM deleted) > 0 AS superseded
65
+ FROM inserted`,
66
+ [
67
+ params.user_id,
68
+ params.uuid,
69
+ params.encrypted_payload,
70
+ params.next_send_at,
71
+ params.message_type,
72
+ supersedesUuid
73
+ ]
74
+ );
75
+ const row = rows[0];
76
+ if (!row) return null;
77
+ return { ...row, superseded: row.superseded === true };
78
+ }
79
+ async function getTaskStatusInfo(query, uuid, userId) {
80
+ const rows = await query(
81
+ "SELECT status, last_error FROM scheduled_messages WHERE uuid = $1 AND user_id = $2 LIMIT 1",
82
+ [uuid, userId]
83
+ );
84
+ if (rows.length === 0) return null;
85
+ return { status: rows[0].status, last_error: _nullishCoalesce(rows[0].last_error, () => ( null)) };
86
+ }
87
+ async function getPushSubscription(query, userId) {
88
+ const rows = await query(
89
+ "SELECT subscription, updated_at FROM push_subscriptions WHERE user_id = $1 LIMIT 1",
90
+ [userId]
91
+ );
92
+ if (rows.length === 0) return null;
93
+ return { subscription: rows[0].subscription, updated_at: Number(rows[0].updated_at) };
94
+ }
95
+ async function upsertPushSubscription(query, userId, encryptedSubscription, updatedAt) {
96
+ const rows = await query(
97
+ `INSERT INTO push_subscriptions (user_id, subscription, updated_at)
98
+ VALUES ($1, $2, $3)
99
+ ON CONFLICT (user_id) DO UPDATE SET
100
+ subscription = EXCLUDED.subscription,
101
+ updated_at = EXCLUDED.updated_at
102
+ RETURNING user_id`,
103
+ [userId, encryptedSubscription, updatedAt]
104
+ );
105
+ return rows.length > 0;
106
+ }
107
+ async function deletePushSubscription(query, userId) {
108
+ const rows = await query(
109
+ "DELETE FROM push_subscriptions WHERE user_id = $1 RETURNING user_id",
110
+ [userId]
111
+ );
112
+ return rows.length > 0;
113
+ }
114
+ async function upsertLlmCredentials(query, userId, entries, now) {
115
+ let upserted = 0;
116
+ for (const entry of entries) {
117
+ const rows = await query(
118
+ `INSERT INTO llm_credentials (user_id, cred_id, encrypted_value, created_at, updated_at)
119
+ VALUES ($1, $2, $3, $4, $4)
120
+ ON CONFLICT (user_id, cred_id) DO UPDATE SET
121
+ encrypted_value = EXCLUDED.encrypted_value,
122
+ updated_at = EXCLUDED.updated_at
123
+ RETURNING cred_id`,
124
+ [userId, entry.credId, entry.encryptedValue, now]
125
+ );
126
+ if (rows.length > 0) upserted++;
127
+ }
128
+ return upserted;
129
+ }
130
+ async function getLlmCredentials(query, userId, credIds) {
131
+ if (!credIds || credIds.length === 0) return [];
132
+ return query(
133
+ `SELECT cred_id, encrypted_value, updated_at
134
+ FROM llm_credentials
135
+ WHERE user_id = $1 AND cred_id = ANY($2)`,
136
+ [userId, credIds]
137
+ );
138
+ }
139
+ async function listLlmCredentials(query, userId) {
140
+ return query(
141
+ "SELECT cred_id, updated_at FROM llm_credentials WHERE user_id = $1 ORDER BY cred_id ASC",
142
+ [userId]
143
+ );
144
+ }
145
+ async function deleteLlmCredentials(query, userId, credIds = null) {
146
+ if (credIds !== null && credIds.length === 0) return 0;
147
+ const rows = credIds === null ? await query("DELETE FROM llm_credentials WHERE user_id = $1 RETURNING cred_id", [userId]) : await query("DELETE FROM llm_credentials WHERE user_id = $1 AND cred_id = ANY($2) RETURNING cred_id", [userId, credIds]);
148
+ return rows.length;
149
+ }
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+ exports.claimTask = claimTask; exports.renewTaskLease = renewTaskLease; exports.createTaskSuperseding = createTaskSuperseding; exports.getTaskStatusInfo = getTaskStatusInfo; exports.getPushSubscription = getPushSubscription; exports.upsertPushSubscription = upsertPushSubscription; exports.deletePushSubscription = deletePushSubscription; exports.upsertLlmCredentials = upsertLlmCredentials; exports.getLlmCredentials = getLlmCredentials; exports.listLlmCredentials = listLlmCredentials; exports.deleteLlmCredentials = deleteLlmCredentials;
@@ -0,0 +1,163 @@
1
+ // src/server/adapters/pg-shared.js
2
+ async function claimTask(query, taskId, expectedNextSendAt, leaseUntil, serializeGroup = null) {
3
+ const grouped = typeof serializeGroup === "string" && serializeGroup.length > 0;
4
+ const params = [leaseUntil, taskId, expectedNextSendAt];
5
+ let setClause = "lease_until = $1, updated_at = NOW()";
6
+ let groupGuard = "";
7
+ if (grouped) {
8
+ params.push(serializeGroup);
9
+ setClause = "lease_until = $1, serialize_group = $4, updated_at = NOW()";
10
+ groupGuard = `
11
+ AND NOT EXISTS (
12
+ SELECT 1 FROM scheduled_messages busy
13
+ WHERE busy.serialize_group = $4 AND busy.id <> $2
14
+ AND busy.status = 'pending' AND busy.lease_until > NOW()
15
+ )`;
16
+ }
17
+ const rows = await query(
18
+ `UPDATE scheduled_messages
19
+ SET ${setClause}
20
+ WHERE id = $2 AND status = 'pending'
21
+ AND date_trunc('milliseconds', next_send_at)
22
+ = date_trunc('milliseconds', $3::timestamptz)
23
+ AND (lease_until IS NULL OR lease_until <= NOW())${groupGuard}
24
+ RETURNING id`,
25
+ params
26
+ );
27
+ if (rows.length === 0) return false;
28
+ if (!grouped) return true;
29
+ const conflict = await query(
30
+ `SELECT 1 FROM scheduled_messages busy
31
+ WHERE busy.serialize_group = $1 AND busy.id <> $2
32
+ AND busy.status = 'pending' AND busy.lease_until > NOW()
33
+ LIMIT 1`,
34
+ [serializeGroup, taskId]
35
+ );
36
+ if (conflict.length === 0) return true;
37
+ await query(
38
+ "UPDATE scheduled_messages SET lease_until = NULL, updated_at = NOW() WHERE id = $1",
39
+ [taskId]
40
+ );
41
+ return false;
42
+ }
43
+ async function renewTaskLease(query, taskId, leaseUntil) {
44
+ const rows = await query(
45
+ `UPDATE scheduled_messages SET lease_until = $1
46
+ WHERE id = $2 AND status = 'pending' AND lease_until IS NOT NULL
47
+ RETURNING id`,
48
+ [leaseUntil, taskId]
49
+ );
50
+ return rows.length > 0;
51
+ }
52
+ async function createTaskSuperseding(query, params, supersedesUuid) {
53
+ const rows = await query(
54
+ `WITH deleted AS (
55
+ DELETE FROM scheduled_messages
56
+ WHERE uuid = $6 AND user_id = $1
57
+ RETURNING id
58
+ ), inserted AS (
59
+ INSERT INTO scheduled_messages
60
+ (user_id, uuid, encrypted_payload, next_send_at, message_type, status, retry_count, created_at, updated_at)
61
+ VALUES ($1, $2, $3, $4, $5, 'pending', 0, NOW(), NOW())
62
+ RETURNING id, uuid, next_send_at, status, created_at
63
+ )
64
+ SELECT inserted.*, (SELECT count(*) FROM deleted) > 0 AS superseded
65
+ FROM inserted`,
66
+ [
67
+ params.user_id,
68
+ params.uuid,
69
+ params.encrypted_payload,
70
+ params.next_send_at,
71
+ params.message_type,
72
+ supersedesUuid
73
+ ]
74
+ );
75
+ const row = rows[0];
76
+ if (!row) return null;
77
+ return { ...row, superseded: row.superseded === true };
78
+ }
79
+ async function getTaskStatusInfo(query, uuid, userId) {
80
+ const rows = await query(
81
+ "SELECT status, last_error FROM scheduled_messages WHERE uuid = $1 AND user_id = $2 LIMIT 1",
82
+ [uuid, userId]
83
+ );
84
+ if (rows.length === 0) return null;
85
+ return { status: rows[0].status, last_error: rows[0].last_error ?? null };
86
+ }
87
+ async function getPushSubscription(query, userId) {
88
+ const rows = await query(
89
+ "SELECT subscription, updated_at FROM push_subscriptions WHERE user_id = $1 LIMIT 1",
90
+ [userId]
91
+ );
92
+ if (rows.length === 0) return null;
93
+ return { subscription: rows[0].subscription, updated_at: Number(rows[0].updated_at) };
94
+ }
95
+ async function upsertPushSubscription(query, userId, encryptedSubscription, updatedAt) {
96
+ const rows = await query(
97
+ `INSERT INTO push_subscriptions (user_id, subscription, updated_at)
98
+ VALUES ($1, $2, $3)
99
+ ON CONFLICT (user_id) DO UPDATE SET
100
+ subscription = EXCLUDED.subscription,
101
+ updated_at = EXCLUDED.updated_at
102
+ RETURNING user_id`,
103
+ [userId, encryptedSubscription, updatedAt]
104
+ );
105
+ return rows.length > 0;
106
+ }
107
+ async function deletePushSubscription(query, userId) {
108
+ const rows = await query(
109
+ "DELETE FROM push_subscriptions WHERE user_id = $1 RETURNING user_id",
110
+ [userId]
111
+ );
112
+ return rows.length > 0;
113
+ }
114
+ async function upsertLlmCredentials(query, userId, entries, now) {
115
+ let upserted = 0;
116
+ for (const entry of entries) {
117
+ const rows = await query(
118
+ `INSERT INTO llm_credentials (user_id, cred_id, encrypted_value, created_at, updated_at)
119
+ VALUES ($1, $2, $3, $4, $4)
120
+ ON CONFLICT (user_id, cred_id) DO UPDATE SET
121
+ encrypted_value = EXCLUDED.encrypted_value,
122
+ updated_at = EXCLUDED.updated_at
123
+ RETURNING cred_id`,
124
+ [userId, entry.credId, entry.encryptedValue, now]
125
+ );
126
+ if (rows.length > 0) upserted++;
127
+ }
128
+ return upserted;
129
+ }
130
+ async function getLlmCredentials(query, userId, credIds) {
131
+ if (!credIds || credIds.length === 0) return [];
132
+ return query(
133
+ `SELECT cred_id, encrypted_value, updated_at
134
+ FROM llm_credentials
135
+ WHERE user_id = $1 AND cred_id = ANY($2)`,
136
+ [userId, credIds]
137
+ );
138
+ }
139
+ async function listLlmCredentials(query, userId) {
140
+ return query(
141
+ "SELECT cred_id, updated_at FROM llm_credentials WHERE user_id = $1 ORDER BY cred_id ASC",
142
+ [userId]
143
+ );
144
+ }
145
+ async function deleteLlmCredentials(query, userId, credIds = null) {
146
+ if (credIds !== null && credIds.length === 0) return 0;
147
+ const rows = credIds === null ? await query("DELETE FROM llm_credentials WHERE user_id = $1 RETURNING cred_id", [userId]) : await query("DELETE FROM llm_credentials WHERE user_id = $1 AND cred_id = ANY($2) RETURNING cred_id", [userId, credIds]);
148
+ return rows.length;
149
+ }
150
+
151
+ export {
152
+ claimTask,
153
+ renewTaskLease,
154
+ createTaskSuperseding,
155
+ getTaskStatusInfo,
156
+ getPushSubscription,
157
+ upsertPushSubscription,
158
+ deletePushSubscription,
159
+ upsertLlmCredentials,
160
+ getLlmCredentials,
161
+ listLlmCredentials,
162
+ deleteLlmCredentials
163
+ };