dynamodb-reactive 0.1.10 → 0.1.12

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/dist/server.js CHANGED
@@ -1,10 +1,331 @@
1
1
  import { SystemTableNames } from './chunk-L4NOAOXX.js';
2
+ import { __commonJS, __toESM } from './chunk-5WRI5ZAA.js';
2
3
  import { DynamoDBClient, ExecuteStatementCommand } from '@aws-sdk/client-dynamodb';
3
4
  import { UpdateCommand, DeleteCommand, PutCommand, GetCommand, DynamoDBDocumentClient, QueryCommand } from '@aws-sdk/lib-dynamodb';
4
5
  import { unmarshall } from '@aws-sdk/util-dynamodb';
5
6
  import jsonpatch from 'fast-json-patch';
6
7
  import { ApiGatewayManagementApiClient, PostToConnectionCommand, GoneException } from '@aws-sdk/client-apigatewaymanagementapi';
7
8
 
9
+ // ../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/array.js
10
+ var require_array = __commonJS({
11
+ "../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/array.js"(exports$1) {
12
+ Object.defineProperty(exports$1, "__esModule", { value: true });
13
+ exports$1.insertElementAtIndex = exports$1.distinct = exports$1.notEmpty = exports$1.partition = exports$1.chunk = exports$1.take = exports$1.flat = exports$1.arrayToObject = void 0;
14
+ exports$1.distinctBy = distinctBy;
15
+ exports$1.findLastIndex = findLastIndex;
16
+ var arrayToObject = (arr, keyF, valueF) => {
17
+ const ret = {};
18
+ if (!arr || !keyF) {
19
+ return ret;
20
+ }
21
+ arr.forEach((v) => {
22
+ const k = keyF(v);
23
+ ret[k] = valueF(v);
24
+ });
25
+ return ret;
26
+ };
27
+ exports$1.arrayToObject = arrayToObject;
28
+ var flat = (arr) => [].concat(...arr);
29
+ exports$1.flat = flat;
30
+ var take = (array, num) => {
31
+ const safeNum = Math.max(0, Math.min(num, array.length));
32
+ const part = array.slice(0, safeNum);
33
+ const rest = array.slice(safeNum);
34
+ return { part, rest };
35
+ };
36
+ exports$1.take = take;
37
+ var chunk = (array, max) => {
38
+ const rows = [];
39
+ let row = [];
40
+ for (const k in array) {
41
+ const item = array[k];
42
+ row.push(item);
43
+ if (row.length >= max) {
44
+ rows.push(row);
45
+ row = [];
46
+ }
47
+ }
48
+ if (row.length > 0) {
49
+ rows.push(row);
50
+ }
51
+ return rows;
52
+ };
53
+ exports$1.chunk = chunk;
54
+ var partition = (array, func) => !array.length ? null : [array.filter((r) => func(r)), array.filter((r) => !func(r))];
55
+ exports$1.partition = partition;
56
+ var notEmpty = (value) => value !== null && value !== void 0 && value !== false && value !== "";
57
+ exports$1.notEmpty = notEmpty;
58
+ function distinctBy(data, key, ignoreEmpty) {
59
+ if (!data || data.length === 0) {
60
+ return data;
61
+ }
62
+ const hashSet = /* @__PURE__ */ new Set();
63
+ return data.filter((x) => {
64
+ let keyVal;
65
+ if (typeof key === "string") {
66
+ keyVal = x[key];
67
+ } else {
68
+ keyVal = key(x);
69
+ }
70
+ if (!keyVal && ignoreEmpty) {
71
+ return false;
72
+ }
73
+ if (!hashSet.has(keyVal)) {
74
+ hashSet.add(keyVal);
75
+ return true;
76
+ }
77
+ return false;
78
+ });
79
+ }
80
+ var distinct = (arr) => [
81
+ ...new Set(arr)
82
+ ];
83
+ exports$1.distinct = distinct;
84
+ function findLastIndex(arr, predicate) {
85
+ for (let i = arr.length - 1; i >= 0; i--) {
86
+ if (predicate(arr[i], i, arr)) {
87
+ return i;
88
+ }
89
+ }
90
+ return -1;
91
+ }
92
+ var insertElementAtIndex = (arr, element, index) => [...arr.slice(0, index), element, ...arr.slice(index)];
93
+ exports$1.insertElementAtIndex = insertElementAtIndex;
94
+ }
95
+ });
96
+
97
+ // ../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/string/redact.js
98
+ var require_redact = __commonJS({
99
+ "../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/string/redact.js"(exports$1) {
100
+ Object.defineProperty(exports$1, "__esModule", { value: true });
101
+ exports$1.redactString = redactString;
102
+ exports$1.redactObject = redactObject;
103
+ function redactString(str) {
104
+ let ret = str;
105
+ ret = ret || "";
106
+ const repl = "$1<redacted>$2";
107
+ ret = ret.replace(/(\b)grant_type.+?(\b)/gm, repl);
108
+ ret = ret.replace(/(\b)Bearer .+?(\b)/gm, repl);
109
+ ret = ret.replace(/(eyJ[\w-_.]*\.[\w-_.]*\.[\w-_.]*)/gim, "<redacted>");
110
+ ret = ret.replace(/(\b)(sk_live_|sk_test_|pk_live_|pk_test_)[\w-]+/gi, "$1<redacted>");
111
+ ret = ret.replace(/(\b)(AKIA[0-9A-Z]{16})/gi, "$1<redacted>");
112
+ ret = ret.replace(/(aws_secret_access_key["\s]*[:=]["\s]*)([0-9a-zA-Z/+]{40})/gi, "$1<redacted>");
113
+ ret = ret.replace(/(\b)(AIza[0-9A-Za-z\\-_]{35})/gi, "$1<redacted>");
114
+ ret = ret.replace(/(\b)(ya29\.[0-9A-Za-z\\-_]+)/gi, "$1<redacted>");
115
+ ret = ret.replace(/(\b)(glpat-[a-zA-Z0-9\\-_]{20})/gi, "$1<redacted>");
116
+ ret = ret.replace(/(\b)(ghp_[a-zA-Z0-9]{36})/gi, "$1<redacted>");
117
+ ret = ret.replace(/(\b)(github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})/gi, "$1<redacted>");
118
+ ret = ret.replace(/(password["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
119
+ ret = ret.replace(/(passwd["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
120
+ ret = ret.replace(/(pwd["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
121
+ ret = ret.replace(/(secret["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
122
+ ret = ret.replace(/(token["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
123
+ ret = ret.replace(/(^|[^a-zA-Z])(api_?key|private_?key|secret_?key)["\s]*[:=]["\s]*([^",\s}]+)/gi, "$1$2<redacted>");
124
+ ret = ret.replace(/(auth["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
125
+ ret = ret.replace(/(mongodb:\/\/[^:]+:)([^@]+)(@)/gi, "$1<redacted>$3");
126
+ ret = ret.replace(/(mysql:\/\/[^:]+:)([^@]+)(@)/gi, "$1<redacted>$3");
127
+ ret = ret.replace(/(postgresql:\/\/[^:]+:)([^@]+)(@)/gi, "$1<redacted>$3");
128
+ ret = ret.replace(/(redis:\/\/[^:]+:)([^@]+)(@)/gi, "$1<redacted>$3");
129
+ ret = ret.replace(/(\b)([3-6]\d{3}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{3,4})(\b)/g, "$1<redacted>$3");
130
+ ret = ret.replace(/(\b)(\d{3}[-\s]?\d{2}[-\s]?\d{4})(\b)/g, "$1<redacted>$3");
131
+ ret = ret.replace(/(-----BEGIN [A-Z\s]+PRIVATE KEY-----)([\s\S]*?)(-----END [A-Z\s]+PRIVATE KEY-----)/gi, "$1\n<redacted>\n$3");
132
+ ret = ret.replace(/(sessionid["\s]*[:=]["\s]*)([a-zA-Z0-9]{32,})/gi, "$1<redacted>");
133
+ ret = ret.replace(/(session["\s]*[:=]["\s]*)([a-zA-Z0-9]{32,})/gi, "$1<redacted>");
134
+ ret = ret.replace(/(csrftoken["\s]*[:=]["\s]*)([a-zA-Z0-9]{32,})/gi, "$1<redacted>");
135
+ ret = ret.replace(/(DATABASE_URL["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
136
+ ret = ret.replace(/(REDIS_URL["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
137
+ ret = ret.replace(/(SMTP_PASSWORD["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
138
+ ret = ret.replace(/(ENCRYPTION_KEY["\s]*[:=]["\s]*)([^",\s}]+)/gi, "$1<redacted>");
139
+ ret = ret.replace(/\b([a-zA-Z0-9+/=_-]{20,})\b/g, (match) => {
140
+ if (match.endsWith("==") && match.length > 30) {
141
+ return "<redacted>";
142
+ }
143
+ if (getShannonEntropy(match) > 4.5) {
144
+ return "<redacted>";
145
+ }
146
+ return match;
147
+ });
148
+ return ret;
149
+ }
150
+ function getShannonEntropy(str) {
151
+ var _a;
152
+ const len = str.length;
153
+ if (len === 0)
154
+ return 0;
155
+ const frequencies = /* @__PURE__ */ new Map();
156
+ for (const char of str) {
157
+ frequencies.set(char, ((_a = frequencies.get(char)) !== null && _a !== void 0 ? _a : 0) + 1);
158
+ }
159
+ let entropy = 0;
160
+ for (const count of frequencies.values()) {
161
+ const p = count / len;
162
+ entropy -= p * Math.log2(p);
163
+ }
164
+ return entropy;
165
+ }
166
+ function redactObject(ob) {
167
+ if (typeof ob === "string") {
168
+ return redactString(ob);
169
+ } else if (typeof ob === "object") {
170
+ try {
171
+ return JSON.parse(redactString(JSON.stringify(ob)));
172
+ } catch (e) {
173
+ return ob;
174
+ }
175
+ }
176
+ return ob;
177
+ }
178
+ }
179
+ });
180
+
181
+ // ../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/log.js
182
+ var require_log = __commonJS({
183
+ "../../node_modules/.pnpm/ag-common@0.0.864_jiti@2.6.1_postcss@8.5.6/node_modules/ag-common/dist/common/helpers/log.js"(exports$1) {
184
+ Object.defineProperty(exports$1, "__esModule", { value: true });
185
+ exports$1.fatal = exports$1.error = exports$1.trace = exports$1.warn = exports$1.info = exports$1.debug = exports$1.SetLogLevel = exports$1.SetLogShim = exports$1.GetLogLevel = void 0;
186
+ var array_1 = require_array();
187
+ var redact_1 = require_redact();
188
+ var GetLogLevel = (l) => ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"].findIndex((s) => s === l);
189
+ exports$1.GetLogLevel = GetLogLevel;
190
+ var logShim;
191
+ var SetLogShim = (ls) => {
192
+ logShim = ls;
193
+ };
194
+ exports$1.SetLogShim = SetLogShim;
195
+ var userLogLevel;
196
+ var SetLogLevel = (l) => {
197
+ const lu = (l !== null && l !== void 0 ? l : "INFO").toUpperCase();
198
+ if ((0, exports$1.GetLogLevel)(lu) === -1) {
199
+ return;
200
+ }
201
+ userLogLevel = lu;
202
+ };
203
+ exports$1.SetLogLevel = SetLogLevel;
204
+ function logprocess(type, args) {
205
+ if (!userLogLevel) {
206
+ (0, exports$1.SetLogLevel)(process.env.LOG_LEVEL);
207
+ }
208
+ const min = (0, exports$1.GetLogLevel)(userLogLevel !== null && userLogLevel !== void 0 ? userLogLevel : "WARN");
209
+ const typesLogLevel = (0, exports$1.GetLogLevel)(type);
210
+ if (typesLogLevel < min) {
211
+ return;
212
+ }
213
+ const datetime = (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB");
214
+ const log = [
215
+ `[${datetime}]`,
216
+ type,
217
+ ...args.filter(array_1.notEmpty).map((s) => {
218
+ if (s instanceof Error) {
219
+ return (0, redact_1.redactObject)({
220
+ message: s.message,
221
+ name: s.name,
222
+ stack: s.stack
223
+ });
224
+ }
225
+ return (0, redact_1.redactObject)(s);
226
+ })
227
+ ];
228
+ if (logShim) {
229
+ logShim(...log);
230
+ return;
231
+ }
232
+ switch (type) {
233
+ case "TRACE": {
234
+ console.trace(...log);
235
+ break;
236
+ }
237
+ case "DEBUG": {
238
+ console.debug(...log);
239
+ break;
240
+ }
241
+ case "INFO": {
242
+ console.log(...log);
243
+ break;
244
+ }
245
+ case "WARN": {
246
+ console.warn(...log);
247
+ break;
248
+ }
249
+ case "ERROR": {
250
+ console.error(...log);
251
+ break;
252
+ }
253
+ case "FATAL": {
254
+ console.error(...log);
255
+ break;
256
+ }
257
+ default: {
258
+ console.log(...log);
259
+ break;
260
+ }
261
+ }
262
+ }
263
+ function printStackTrace(...args) {
264
+ var _a;
265
+ const callstack = [];
266
+ let isCallstackPopulated = false;
267
+ try {
268
+ throw new Error("Test");
269
+ } catch (e) {
270
+ const er = e;
271
+ if (er.stack) {
272
+ const lines = er.stack.split("\n");
273
+ for (let i = 0, len = lines.length; i < len; i += 1) {
274
+ callstack.push(` ${lines[i]} `);
275
+ }
276
+ callstack.shift();
277
+ isCallstackPopulated = true;
278
+ } else if (window.opera && er.message) {
279
+ const lines = er.message.split("\n");
280
+ for (let i = 0, len = lines.length; i < len; i += 1) {
281
+ if (lines[i].match(/^\s*[A-Za-z0-9\-_$]+\(/)) {
282
+ let entry = lines[i];
283
+ if (lines[i + 1]) {
284
+ entry += ` at ${lines[i + 1]}`;
285
+ i += 1;
286
+ }
287
+ callstack.push(entry);
288
+ }
289
+ }
290
+ callstack.shift();
291
+ isCallstackPopulated = true;
292
+ }
293
+ }
294
+ if (!isCallstackPopulated) {
295
+ let currentFunction = args.callee.caller;
296
+ while (currentFunction) {
297
+ const fn = currentFunction.toString();
298
+ const fname = (_a = fn.substring(fn.indexOf("function") + 8, fn.indexOf("("))) !== null && _a !== void 0 ? _a : "anonymous";
299
+ callstack.push(fname);
300
+ currentFunction = currentFunction.caller;
301
+ }
302
+ }
303
+ return callstack.join("\n");
304
+ }
305
+ var debug3 = (...args) => logprocess("DEBUG", args);
306
+ exports$1.debug = debug3;
307
+ var info3 = (...args) => logprocess("INFO", args);
308
+ exports$1.info = info3;
309
+ var warn4 = (...args) => logprocess("WARN", args);
310
+ exports$1.warn = warn4;
311
+ var trace = (...args) => {
312
+ args.push(printStackTrace());
313
+ logprocess("TRACE", args);
314
+ };
315
+ exports$1.trace = trace;
316
+ var error = (...args) => {
317
+ args.push(printStackTrace());
318
+ logprocess("ERROR", args);
319
+ };
320
+ exports$1.error = error;
321
+ var fatal = (...args) => {
322
+ args.push(printStackTrace());
323
+ logprocess("FATAL", args);
324
+ };
325
+ exports$1.fatal = fatal;
326
+ }
327
+ });
328
+
8
329
  // ../server/src/procedure.ts
9
330
  var ProcedureBuilder = class _ProcedureBuilder {
10
331
  inputSchema;
@@ -562,7 +883,8 @@ function extractAffectedKeys(tableName, item) {
562
883
  if (fieldValue !== null && fieldValue !== void 0) {
563
884
  keys.push(`${tableName}#${fieldName}#${String(fieldValue)}`);
564
885
  if (typeof fieldValue === "string") {
565
- for (let i = 1; i <= fieldValue.length; i++) {
886
+ const maxPrefixLen = Math.min(fieldValue.length, 10);
887
+ for (let i = 1; i <= maxPrefixLen; i++) {
566
888
  keys.push(
567
889
  `${tableName}#${fieldName}#prefix:${fieldValue.substring(0, i)}`
568
890
  );
@@ -740,6 +1062,7 @@ function batchPatches(patchSets) {
740
1062
  const allPatches = patchSets.flat();
741
1063
  return optimizePatches(allPatches);
742
1064
  }
1065
+ var import_log = __toESM(require_log());
743
1066
  function createReactiveHandler(config) {
744
1067
  const ttlSeconds = config.ttlSeconds ?? 3600;
745
1068
  const prefix = config.tablePrefix ? `${config.tablePrefix}-` : "";
@@ -755,6 +1078,11 @@ function createReactiveHandler(config) {
755
1078
  async function handleRequest(request, headers) {
756
1079
  try {
757
1080
  const connectionId = request.connectionId;
1081
+ (0, import_log.debug)("[reactive-handler] handleRequest:", {
1082
+ type: request.type,
1083
+ connectionId,
1084
+ path: "path" in request ? request.path : void 0
1085
+ });
758
1086
  const ctx = await config.getContext({ connectionId, headers });
759
1087
  const dependencyTracker = new DependencyTracker();
760
1088
  const db = createDbContext(config.dbConfig ?? {}, dependencyTracker);
@@ -795,7 +1123,7 @@ function createReactiveHandler(config) {
795
1123
  const queryMetadata = dependencyTracker.getQueryMetadata();
796
1124
  const dependencyKeys = dependencyTracker.getDependencyKeys();
797
1125
  if (!queryMetadata) {
798
- console.warn("No query metadata captured for subscription");
1126
+ (0, import_log.warn)("[reactive-handler] No query metadata captured for subscription");
799
1127
  }
800
1128
  const now = Date.now();
801
1129
  const ttl = Math.floor(now / 1e3) + ttlSeconds;
@@ -834,11 +1162,13 @@ function createReactiveHandler(config) {
834
1162
  })
835
1163
  );
836
1164
  }
837
- console.log("Subscription created:", {
1165
+ (0, import_log.debug)("[reactive-handler] Subscription created:", {
838
1166
  connectionId,
839
1167
  subscriptionId: request.subscriptionId,
840
- queryMetadata: queryMetadata?.tableName,
841
- dependencies: dependencyKeys
1168
+ tableName: queryMetadata?.tableName,
1169
+ filterConditions: queryMetadata?.filterConditions,
1170
+ dependencies: dependencyKeys,
1171
+ resultCount: Array.isArray(result) ? result.length : 1
842
1172
  });
843
1173
  return {
844
1174
  type: "snapshot",
@@ -870,7 +1200,7 @@ function createReactiveHandler(config) {
870
1200
  Key: { pk: connectionId, sk: request.subscriptionId }
871
1201
  })
872
1202
  );
873
- console.log("Subscription removed:", {
1203
+ (0, import_log.debug)("[reactive-handler] Subscription removed:", {
874
1204
  connectionId,
875
1205
  subscriptionId: request.subscriptionId
876
1206
  });
@@ -905,7 +1235,7 @@ function createReactiveHandler(config) {
905
1235
  Item: connectionEntry
906
1236
  })
907
1237
  );
908
- console.log("Connection registered:", connectionEntry);
1238
+ (0, import_log.debug)("[reactive-handler] Connection registered:", connectionEntry);
909
1239
  }
910
1240
  async function unregisterConnection(connectionId) {
911
1241
  await docClient.send(
@@ -914,7 +1244,7 @@ function createReactiveHandler(config) {
914
1244
  Key: { connectionId }
915
1245
  })
916
1246
  );
917
- console.log("Connection unregistered:", connectionId);
1247
+ (0, import_log.debug)("[reactive-handler] Connection unregistered:", connectionId);
918
1248
  }
919
1249
  async function query(path, input, headers) {
920
1250
  const ctx = await config.getContext({ connectionId: "query", headers });
@@ -946,6 +1276,7 @@ function createReactiveHandler(config) {
946
1276
  createCaller
947
1277
  };
948
1278
  }
1279
+ var import_log2 = __toESM(require_log());
949
1280
  function createStreamHandler(config) {
950
1281
  const connectionsTable = config.connectionsTableName ?? SystemTableNames.connections;
951
1282
  const dependenciesTable = config.dependenciesTableName ?? SystemTableNames.dependencies;
@@ -958,6 +1289,11 @@ function createStreamHandler(config) {
958
1289
  endpoint: config.apiGatewayEndpoint
959
1290
  });
960
1291
  async function handler(event) {
1292
+ (0, import_log2.debug)(
1293
+ "[stream-handler] Processing stream event with",
1294
+ event.Records.length,
1295
+ "records"
1296
+ );
961
1297
  const affectedSubscriptions = /* @__PURE__ */ new Map();
962
1298
  for (const record of event.Records) {
963
1299
  if (!record.dynamodb) continue;
@@ -976,8 +1312,15 @@ function createStreamHandler(config) {
976
1312
  affectedKeys.add(key);
977
1313
  }
978
1314
  }
1315
+ (0, import_log2.debug)("[stream-handler] Affected keys:", Array.from(affectedKeys));
979
1316
  for (const key of affectedKeys) {
980
1317
  const subscriptions = await findAffectedSubscriptions(key);
1318
+ (0, import_log2.debug)(
1319
+ "[stream-handler] Found",
1320
+ subscriptions.length,
1321
+ "subscriptions for key:",
1322
+ key
1323
+ );
981
1324
  for (const sub of subscriptions) {
982
1325
  const connId = sub.connectionId;
983
1326
  const subId = sub.subscriptionId;
@@ -988,6 +1331,10 @@ function createStreamHandler(config) {
988
1331
  }
989
1332
  }
990
1333
  }
1334
+ (0, import_log2.debug)(
1335
+ "[stream-handler] Total affected subscriptions:",
1336
+ affectedSubscriptions.size
1337
+ );
991
1338
  const sendPromises = [];
992
1339
  for (const [connectionId, subscriptionIds] of affectedSubscriptions) {
993
1340
  for (const subscriptionId of subscriptionIds) {
@@ -1018,34 +1365,51 @@ function createStreamHandler(config) {
1018
1365
  subscriptionId: item.subscriptionId
1019
1366
  }));
1020
1367
  } catch (error) {
1021
- console.error("Error finding affected subscriptions:", error);
1368
+ (0, import_log2.error)("[stream-handler] Error finding affected subscriptions:", error);
1022
1369
  return [];
1023
1370
  }
1024
1371
  }
1025
1372
  async function processSubscription(connectionId, subscriptionId) {
1373
+ (0, import_log2.debug)("[stream-handler] Processing subscription:", {
1374
+ connectionId,
1375
+ subscriptionId
1376
+ });
1026
1377
  try {
1027
1378
  const queryState = await getQueryState(connectionId, subscriptionId);
1028
1379
  if (!queryState) {
1029
- console.warn(
1030
- `Subscription not found: ${connectionId}/${subscriptionId}`
1380
+ (0, import_log2.warn)(
1381
+ "[stream-handler] Subscription not found:",
1382
+ connectionId,
1383
+ subscriptionId
1031
1384
  );
1032
1385
  return;
1033
1386
  }
1387
+ (0, import_log2.debug)("[stream-handler] Query metadata:", {
1388
+ tableName: queryState.queryMetadata.tableName,
1389
+ filterConditions: queryState.queryMetadata.filterConditions,
1390
+ lastResultCount: queryState.lastResult?.length
1391
+ });
1034
1392
  const newResult = await executeQueryFromMetadata(
1035
1393
  queryState.queryMetadata
1036
1394
  );
1395
+ (0, import_log2.debug)("[stream-handler] New result count:", newResult.length);
1037
1396
  if (!hasChanges(queryState.lastResult, newResult)) {
1397
+ (0, import_log2.debug)("[stream-handler] No changes detected, skipping patch");
1038
1398
  return;
1039
1399
  }
1040
1400
  const patches = generatePatches(queryState.lastResult, newResult);
1401
+ (0, import_log2.debug)("[stream-handler] Generated", patches.length, "patches");
1041
1402
  await updateQueryState(connectionId, subscriptionId, newResult);
1042
1403
  await sendPatch(connectionId, subscriptionId, patches);
1404
+ (0, import_log2.debug)("[stream-handler] Patch sent successfully");
1043
1405
  } catch (error) {
1044
1406
  if (error instanceof GoneException) {
1045
1407
  await cleanupConnection(connectionId);
1046
1408
  } else {
1047
- console.error(
1048
- `Error processing subscription ${connectionId}/${subscriptionId}:`,
1409
+ (0, import_log2.error)(
1410
+ "[stream-handler] Error processing subscription:",
1411
+ connectionId,
1412
+ subscriptionId,
1049
1413
  error
1050
1414
  );
1051
1415
  }
@@ -1064,7 +1428,7 @@ function createStreamHandler(config) {
1064
1428
  );
1065
1429
  return response.Item ?? null;
1066
1430
  } catch (error) {
1067
- console.error("Error getting query state:", error);
1431
+ (0, import_log2.error)("[stream-handler] Error getting query state:", error);
1068
1432
  return null;
1069
1433
  }
1070
1434
  }
@@ -1084,8 +1448,8 @@ function createStreamHandler(config) {
1084
1448
  (item) => unmarshall(item)
1085
1449
  );
1086
1450
  } catch (error) {
1087
- console.error("Error executing query from metadata:", error);
1088
- console.error("Statement:", statement);
1451
+ (0, import_log2.error)("[stream-handler] Error executing query from metadata:", error);
1452
+ (0, import_log2.error)("[stream-handler] Statement:", statement);
1089
1453
  return [];
1090
1454
  }
1091
1455
  }
@@ -1177,7 +1541,7 @@ function createStreamHandler(config) {
1177
1541
  })
1178
1542
  );
1179
1543
  } catch (error) {
1180
- console.error("Error updating query state:", error);
1544
+ (0, import_log2.error)("[stream-handler] Error updating query state:", error);
1181
1545
  }
1182
1546
  }
1183
1547
  async function sendPatch(connectionId, subscriptionId, patches) {
@@ -1197,11 +1561,11 @@ function createStreamHandler(config) {
1197
1561
  if (error instanceof GoneException) {
1198
1562
  throw error;
1199
1563
  }
1200
- console.error(`Error sending patch to ${connectionId}:`, error);
1564
+ (0, import_log2.error)("[stream-handler] Error sending patch to", connectionId, error);
1201
1565
  }
1202
1566
  }
1203
1567
  async function cleanupConnection(connectionId) {
1204
- console.log("Cleaning up disconnected connection:", connectionId);
1568
+ (0, import_log2.info)("[stream-handler] Cleaning up disconnected connection:", connectionId);
1205
1569
  try {
1206
1570
  const queriesResponse = await docClient.send(
1207
1571
  new QueryCommand({
@@ -1244,11 +1608,14 @@ function createStreamHandler(config) {
1244
1608
  }
1245
1609
  })
1246
1610
  );
1247
- console.log(
1248
- `Cleaned up connection ${connectionId}: ${subscriptions.length} subscriptions removed`
1611
+ (0, import_log2.info)(
1612
+ "[stream-handler] Cleaned up connection:",
1613
+ connectionId,
1614
+ subscriptions.length,
1615
+ "subscriptions removed"
1249
1616
  );
1250
1617
  } catch (error) {
1251
- console.error("Error cleaning up connection:", error);
1618
+ (0, import_log2.error)("[stream-handler] Error cleaning up connection:", error);
1252
1619
  }
1253
1620
  }
1254
1621
  return { handler };
@@ -1271,10 +1638,10 @@ function createConnectHandler(config) {
1271
1638
  }
1272
1639
  })
1273
1640
  );
1274
- console.log("Connection established:", connectionId);
1641
+ (0, import_log2.debug)("[stream-handler] Connection established:", connectionId);
1275
1642
  return { statusCode: 200 };
1276
1643
  } catch (error) {
1277
- console.error("Error creating connection:", error);
1644
+ (0, import_log2.error)("[stream-handler] Error creating connection:", error);
1278
1645
  return { statusCode: 500 };
1279
1646
  }
1280
1647
  };
@@ -1294,14 +1661,15 @@ function createDisconnectHandler(config) {
1294
1661
  Key: { connectionId }
1295
1662
  })
1296
1663
  );
1297
- console.log("Connection removed:", connectionId);
1664
+ (0, import_log2.debug)("[stream-handler] Connection removed:", connectionId);
1298
1665
  return { statusCode: 200 };
1299
1666
  } catch (error) {
1300
- console.error("Error removing connection:", error);
1667
+ (0, import_log2.error)("[stream-handler] Error removing connection:", error);
1301
1668
  return { statusCode: 500 };
1302
1669
  }
1303
1670
  };
1304
1671
  }
1672
+ var import_log3 = __toESM(require_log());
1305
1673
  function createLambdaHandlers() {
1306
1674
  const connectionsTable = process.env.CONNECTIONS_TABLE ?? SystemTableNames.connections;
1307
1675
  const dependenciesTable = process.env.DEPENDENCIES_TABLE ?? SystemTableNames.dependencies;
@@ -1331,26 +1699,54 @@ function createLambdaHandlers() {
1331
1699
  Item: connectionEntry
1332
1700
  })
1333
1701
  );
1334
- console.log("Connection established:", connectionId);
1702
+ (0, import_log3.info)("Connection established:", connectionId);
1335
1703
  return { statusCode: 200, body: "Connected" };
1336
1704
  } catch (error) {
1337
- console.error("Error creating connection:", error);
1705
+ (0, import_log3.error)("Error creating connection:", error);
1338
1706
  return { statusCode: 500, body: "Failed to connect" };
1339
1707
  }
1340
1708
  }
1341
1709
  async function disconnectHandler(event) {
1342
1710
  const connectionId = event.requestContext.connectionId;
1343
1711
  try {
1712
+ const subsResponse = await docClient.send(
1713
+ new QueryCommand({
1714
+ TableName: queriesTable,
1715
+ KeyConditionExpression: "pk = :pk",
1716
+ ExpressionAttributeValues: { ":pk": connectionId }
1717
+ })
1718
+ );
1719
+ const subscriptions = subsResponse.Items ?? [];
1720
+ for (const sub of subscriptions) {
1721
+ for (const depKey of sub.dependencies ?? []) {
1722
+ await docClient.send(
1723
+ new DeleteCommand({
1724
+ TableName: dependenciesTable,
1725
+ Key: { pk: depKey, sk: `${connectionId}#${sub.sk}` }
1726
+ })
1727
+ );
1728
+ }
1729
+ await docClient.send(
1730
+ new DeleteCommand({
1731
+ TableName: queriesTable,
1732
+ Key: { pk: connectionId, sk: sub.sk }
1733
+ })
1734
+ );
1735
+ }
1344
1736
  await docClient.send(
1345
1737
  new DeleteCommand({
1346
1738
  TableName: connectionsTable,
1347
1739
  Key: { connectionId }
1348
1740
  })
1349
1741
  );
1350
- console.log("Connection removed:", connectionId);
1742
+ (0, import_log3.info)(
1743
+ "Connection removed:",
1744
+ connectionId,
1745
+ `(${subscriptions.length} subscriptions cleaned up)`
1746
+ );
1351
1747
  return { statusCode: 200, body: "Disconnected" };
1352
1748
  } catch (error) {
1353
- console.error("Error removing connection:", error);
1749
+ (0, import_log3.error)("Error removing connection:", error);
1354
1750
  return { statusCode: 500, body: "Failed to disconnect" };
1355
1751
  }
1356
1752
  }
@@ -1416,11 +1812,14 @@ function createLambdaHandlers() {
1416
1812
  );
1417
1813
  return { statusCode: 200, body: "OK" };
1418
1814
  } catch (error) {
1419
- console.error("Error handling message:", error);
1815
+ (0, import_log3.error)("Error handling message:", error);
1420
1816
  return { statusCode: 500, body: "Internal server error" };
1421
1817
  }
1422
1818
  }
1423
1819
  async function streamHandler(event) {
1820
+ (0, import_log3.info)(
1821
+ `[stream] Processing ${event.Records.length} records from DynamoDB stream`
1822
+ );
1424
1823
  const affectedSubscriptions = /* @__PURE__ */ new Map();
1425
1824
  for (const record of event.Records) {
1426
1825
  if (!record.dynamodb) continue;
@@ -1454,6 +1853,7 @@ function createLambdaHandlers() {
1454
1853
  }
1455
1854
  }
1456
1855
  }
1856
+ (0, import_log3.info)(`[stream] Found ${affectedSubscriptions.size} affected connections`);
1457
1857
  const sendPromises = [];
1458
1858
  for (const [connectionId, subscriptions] of affectedSubscriptions) {
1459
1859
  for (const [subscriptionId] of subscriptions) {
@@ -1461,6 +1861,7 @@ function createLambdaHandlers() {
1461
1861
  }
1462
1862
  }
1463
1863
  await Promise.allSettled(sendPromises);
1864
+ (0, import_log3.info)("[stream] Processing complete");
1464
1865
  }
1465
1866
  function extractTableName(record) {
1466
1867
  const arn = record.eventSourceARN;
@@ -1484,7 +1885,7 @@ function createLambdaHandlers() {
1484
1885
  subscriptionId: item.subscriptionId
1485
1886
  }));
1486
1887
  } catch (error) {
1487
- console.error("Error finding affected subscriptions:", error);
1888
+ (0, import_log3.error)("Error finding affected subscriptions:", error);
1488
1889
  return [];
1489
1890
  }
1490
1891
  }
@@ -1498,9 +1899,7 @@ function createLambdaHandlers() {
1498
1899
  );
1499
1900
  const queryState = response.Item;
1500
1901
  if (!queryState) {
1501
- console.warn(
1502
- `Subscription not found: ${connectionId}/${subscriptionId}`
1503
- );
1902
+ (0, import_log3.warn)(`Subscription not found: ${connectionId}/${subscriptionId}`);
1504
1903
  return;
1505
1904
  }
1506
1905
  const newResult = await executeQueryFromMetadata(
@@ -1525,7 +1924,7 @@ function createLambdaHandlers() {
1525
1924
  if (error instanceof GoneException) {
1526
1925
  await cleanupConnection(connectionId);
1527
1926
  } else {
1528
- console.error(
1927
+ (0, import_log3.error)(
1529
1928
  `Error processing subscription ${connectionId}/${subscriptionId}:`,
1530
1929
  error
1531
1930
  );
@@ -1549,8 +1948,8 @@ function createLambdaHandlers() {
1549
1948
  (item) => unmarshall(item)
1550
1949
  );
1551
1950
  } catch (error) {
1552
- console.error("Error executing query from metadata:", error);
1553
- console.error("Statement:", statement);
1951
+ (0, import_log3.error)("Error executing query from metadata:", error);
1952
+ (0, import_log3.error)("Statement:", statement);
1554
1953
  return [];
1555
1954
  }
1556
1955
  }
@@ -1638,11 +2037,11 @@ function createLambdaHandlers() {
1638
2037
  if (error instanceof GoneException) {
1639
2038
  throw error;
1640
2039
  }
1641
- console.error(`Error sending patch to ${connectionId}:`, error);
2040
+ (0, import_log3.error)(`Error sending patch to ${connectionId}:`, error);
1642
2041
  }
1643
2042
  }
1644
2043
  async function cleanupConnection(connectionId) {
1645
- console.log("Cleaning up disconnected connection:", connectionId);
2044
+ (0, import_log3.info)("Cleaning up disconnected connection:", connectionId);
1646
2045
  try {
1647
2046
  await docClient.send(
1648
2047
  new DeleteCommand({
@@ -1651,7 +2050,7 @@ function createLambdaHandlers() {
1651
2050
  })
1652
2051
  );
1653
2052
  } catch (error) {
1654
- console.error("Error cleaning up connection:", error);
2053
+ (0, import_log3.error)("Error cleaning up connection:", error);
1655
2054
  }
1656
2055
  }
1657
2056
  return {