@farukada/aws-langgraph-dynamodb-ts 0.3.2 → 0.6.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 (148) hide show
  1. package/README.md +10 -3
  2. package/dist/checkpointer/actions/delete-thread.js +1 -1
  3. package/dist/checkpointer/actions/delete-thread.js.map +1 -1
  4. package/dist/checkpointer/actions/list.d.ts.map +1 -1
  5. package/dist/checkpointer/actions/list.js +3 -1
  6. package/dist/checkpointer/actions/list.js.map +1 -1
  7. package/dist/checkpointer/actions/put-writes.d.ts +4 -4
  8. package/dist/checkpointer/actions/put-writes.d.ts.map +1 -1
  9. package/dist/checkpointer/actions/put-writes.js +21 -20
  10. package/dist/checkpointer/actions/put-writes.js.map +1 -1
  11. package/dist/checkpointer/internal/item-writer.d.ts +18 -9
  12. package/dist/checkpointer/internal/item-writer.d.ts.map +1 -1
  13. package/dist/checkpointer/internal/item-writer.js +28 -11
  14. package/dist/checkpointer/internal/item-writer.js.map +1 -1
  15. package/dist/checkpointer/internal/query.d.ts +5 -1
  16. package/dist/checkpointer/internal/query.d.ts.map +1 -1
  17. package/dist/checkpointer/internal/query.js +5 -2
  18. package/dist/checkpointer/internal/query.js.map +1 -1
  19. package/dist/checkpointer/internal/setup.d.ts.map +1 -1
  20. package/dist/checkpointer/internal/setup.js +8 -1
  21. package/dist/checkpointer/internal/setup.js.map +1 -1
  22. package/dist/checkpointer/internal/special-write-cleanup.d.ts +18 -0
  23. package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +1 -0
  24. package/dist/checkpointer/internal/special-write-cleanup.js +108 -0
  25. package/dist/checkpointer/internal/special-write-cleanup.js.map +1 -0
  26. package/dist/factory/factory.d.ts +3 -1
  27. package/dist/factory/factory.d.ts.map +1 -1
  28. package/dist/factory/factory.js +4 -6
  29. package/dist/factory/factory.js.map +1 -1
  30. package/dist/history/actions/add-messages.d.ts.map +1 -1
  31. package/dist/history/actions/add-messages.js +4 -3
  32. package/dist/history/actions/add-messages.js.map +1 -1
  33. package/dist/history/actions/clear.js +1 -1
  34. package/dist/history/actions/clear.js.map +1 -1
  35. package/dist/history/actions/list-sessions.d.ts +1 -0
  36. package/dist/history/actions/list-sessions.d.ts.map +1 -1
  37. package/dist/history/actions/list-sessions.js +1 -0
  38. package/dist/history/actions/list-sessions.js.map +1 -1
  39. package/dist/history/actions/reconcile-count.d.ts +4 -1
  40. package/dist/history/actions/reconcile-count.d.ts.map +1 -1
  41. package/dist/history/actions/reconcile-count.js +21 -9
  42. package/dist/history/actions/reconcile-count.js.map +1 -1
  43. package/dist/history/chat-message-history.d.ts +1 -0
  44. package/dist/history/chat-message-history.d.ts.map +1 -1
  45. package/dist/history/chat-message-history.js.map +1 -1
  46. package/dist/history/internal/append-saga.d.ts +1 -0
  47. package/dist/history/internal/append-saga.d.ts.map +1 -1
  48. package/dist/history/internal/append-saga.js +25 -21
  49. package/dist/history/internal/append-saga.js.map +1 -1
  50. package/dist/history/internal/message-transaction.d.ts +11 -6
  51. package/dist/history/internal/message-transaction.d.ts.map +1 -1
  52. package/dist/history/internal/message-transaction.js +40 -13
  53. package/dist/history/internal/message-transaction.js.map +1 -1
  54. package/dist/history/internal/query.d.ts +5 -1
  55. package/dist/history/internal/query.d.ts.map +1 -1
  56. package/dist/history/internal/query.js +5 -2
  57. package/dist/history/internal/query.js.map +1 -1
  58. package/dist/history/internal/session-count.d.ts +20 -0
  59. package/dist/history/internal/session-count.d.ts.map +1 -0
  60. package/dist/history/internal/session-count.js +58 -0
  61. package/dist/history/internal/session-count.js.map +1 -0
  62. package/dist/history/internal/session-update.d.ts +9 -1
  63. package/dist/history/internal/session-update.d.ts.map +1 -1
  64. package/dist/history/internal/session-update.js +26 -2
  65. package/dist/history/internal/session-update.js.map +1 -1
  66. package/dist/history/internal/setup.d.ts.map +1 -1
  67. package/dist/history/internal/setup.js +8 -1
  68. package/dist/history/internal/setup.js.map +1 -1
  69. package/dist/history/internal/ttl-anchor.d.ts +20 -7
  70. package/dist/history/internal/ttl-anchor.d.ts.map +1 -1
  71. package/dist/history/internal/ttl-anchor.js +19 -7
  72. package/dist/history/internal/ttl-anchor.js.map +1 -1
  73. package/dist/index.d.ts +1 -1
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +2 -1
  76. package/dist/index.js.map +1 -1
  77. package/dist/shared/codec/s3/client.d.ts +7 -1
  78. package/dist/shared/codec/s3/client.d.ts.map +1 -1
  79. package/dist/shared/codec/s3/client.js +8 -2
  80. package/dist/shared/codec/s3/client.js.map +1 -1
  81. package/dist/shared/codec/s3/config.d.ts +2 -0
  82. package/dist/shared/codec/s3/config.d.ts.map +1 -1
  83. package/dist/shared/codec/s3/config.js +5 -0
  84. package/dist/shared/codec/s3/config.js.map +1 -1
  85. package/dist/shared/codec/s3/offloader.js +1 -1
  86. package/dist/shared/codec/s3/offloader.js.map +1 -1
  87. package/dist/shared/codec/s3/read-write.d.ts.map +1 -1
  88. package/dist/shared/codec/s3/read-write.js +3 -6
  89. package/dist/shared/codec/s3/read-write.js.map +1 -1
  90. package/dist/shared/constants.d.ts +3 -0
  91. package/dist/shared/constants.d.ts.map +1 -1
  92. package/dist/shared/constants.js +3 -0
  93. package/dist/shared/constants.js.map +1 -1
  94. package/dist/shared/dynamodb/batch-write.d.ts +15 -2
  95. package/dist/shared/dynamodb/batch-write.d.ts.map +1 -1
  96. package/dist/shared/dynamodb/batch-write.js +38 -3
  97. package/dist/shared/dynamodb/batch-write.js.map +1 -1
  98. package/dist/shared/dynamodb/cancellation.d.ts +7 -0
  99. package/dist/shared/dynamodb/cancellation.d.ts.map +1 -0
  100. package/dist/shared/dynamodb/cancellation.js +8 -0
  101. package/dist/shared/dynamodb/cancellation.js.map +1 -0
  102. package/dist/shared/dynamodb/client.js +1 -1
  103. package/dist/shared/dynamodb/client.js.map +1 -1
  104. package/dist/shared/dynamodb/retry-classifier.d.ts.map +1 -1
  105. package/dist/shared/dynamodb/retry-classifier.js +5 -1
  106. package/dist/shared/dynamodb/retry-classifier.js.map +1 -1
  107. package/dist/shared/errors/errors.d.ts +18 -0
  108. package/dist/shared/errors/errors.d.ts.map +1 -1
  109. package/dist/shared/errors/errors.js +28 -1
  110. package/dist/shared/errors/errors.js.map +1 -1
  111. package/dist/store/actions/list-namespaces.d.ts.map +1 -1
  112. package/dist/store/actions/list-namespaces.js +10 -2
  113. package/dist/store/actions/list-namespaces.js.map +1 -1
  114. package/dist/store/actions/put.d.ts +5 -5
  115. package/dist/store/actions/put.d.ts.map +1 -1
  116. package/dist/store/actions/put.js +20 -36
  117. package/dist/store/actions/put.js.map +1 -1
  118. package/dist/store/actions/search.d.ts.map +1 -1
  119. package/dist/store/actions/search.js +29 -11
  120. package/dist/store/actions/search.js.map +1 -1
  121. package/dist/store/internal/filter.d.ts.map +1 -1
  122. package/dist/store/internal/filter.js +15 -8
  123. package/dist/store/internal/filter.js.map +1 -1
  124. package/dist/store/internal/index-reconcile.d.ts.map +1 -1
  125. package/dist/store/internal/index-reconcile.js +4 -1
  126. package/dist/store/internal/index-reconcile.js.map +1 -1
  127. package/dist/store/internal/item-mapper.d.ts +2 -1
  128. package/dist/store/internal/item-mapper.d.ts.map +1 -1
  129. package/dist/store/internal/item-mapper.js +1 -1
  130. package/dist/store/internal/item-mapper.js.map +1 -1
  131. package/dist/store/internal/persist.d.ts +11 -0
  132. package/dist/store/internal/persist.d.ts.map +1 -0
  133. package/dist/store/internal/persist.js +38 -0
  134. package/dist/store/internal/persist.js.map +1 -0
  135. package/dist/store/internal/ranker.d.ts.map +1 -1
  136. package/dist/store/internal/ranker.js +3 -1
  137. package/dist/store/internal/ranker.js.map +1 -1
  138. package/dist/store/internal/setup.d.ts +1 -0
  139. package/dist/store/internal/setup.d.ts.map +1 -1
  140. package/dist/store/internal/setup.js +8 -1
  141. package/dist/store/internal/setup.js.map +1 -1
  142. package/dist/store/internal/write-verify.d.ts +12 -0
  143. package/dist/store/internal/write-verify.d.ts.map +1 -0
  144. package/dist/store/internal/write-verify.js +28 -0
  145. package/dist/store/internal/write-verify.js.map +1 -0
  146. package/dist/store/types.d.ts +2 -0
  147. package/dist/store/types.d.ts.map +1 -1
  148. package/package.json +9 -8
@@ -1,4 +1,5 @@
1
- import { DynamoDBClient, type DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
1
+ import type { DynamoDBClient, DynamoDBClientConfig } from '@aws-sdk/client-dynamodb';
2
+ import type { DynamoDBDocument } from '@aws-sdk/lib-dynamodb';
2
3
  import { DynamoDBSaver } from '../checkpointer/saver';
3
4
  import type { DynamoDBSaverOptions } from '../checkpointer/types';
4
5
  import { DynamoDBChatMessageHistory } from '../history/chat-message-history';
@@ -8,6 +9,7 @@ import { DynamoDBStore } from '../store/store';
8
9
  import type { DynamoDBStoreOptions } from '../store/types';
9
10
  /** Shared client/logger defaults applied to every adapter the factory builds. */
10
11
  export interface FactoryBaseOptions {
12
+ client?: DynamoDBDocument;
11
13
  clientConfig?: DynamoDBClientConfig;
12
14
  createClient?: (config: DynamoDBClientConfig) => DynamoDBClient;
13
15
  logger?: Logger;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/factory/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,cAAc,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;IAC9E,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;IAC9E,OAAO,EAAE,IAAI,CAAC,iCAAiC,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;CAC9F;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,0BAA0B,CAAC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,GAAE,kBAAuB,EAAI;IAE9D,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAExD;IAED,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAExD;IAED,wBAAwB,CAAC,OAAO,EAAE,iCAAiC,GAAG,0BAA0B,CAE/F;IAED,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAkBpD;CACF"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/factory/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,kBAAkB,CAAC;AAE1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,iFAAiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,cAAc,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oFAAoF;AACpF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;IAC9E,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;IAC9E,OAAO,EAAE,IAAI,CAAC,iCAAiC,EAAE,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC,CAAC;CAC9F;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,0BAA0B,CAAC;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,GAAE,kBAAuB,EAAI;IAE9D,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAExD;IAED,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAExD;IAED,wBAAwB,CAAC,OAAO,EAAE,iCAAiC,GAAG,0BAA0B,CAE/F;IAED,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,CAiBpD;CACF"}
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DynamoDBFactory = void 0;
4
- const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
5
- const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
6
4
  const saver_1 = require("../checkpointer/saver");
7
5
  const chat_message_history_1 = require("../history/chat-message-history");
6
+ const client_1 = require("../shared/dynamodb/client");
8
7
  const store_1 = require("../store/store");
9
8
  /**
10
9
  * Convenience constructors for the adapters. Individual `create*` methods each
@@ -26,9 +25,8 @@ class DynamoDBFactory {
26
25
  return new chat_message_history_1.DynamoDBChatMessageHistory({ ...this.base, ...options });
27
26
  }
28
27
  createAll(options) {
29
- const build = this.base.createClient ?? ((config) => new client_dynamodb_1.DynamoDBClient(config));
30
- const ddbClient = build(this.base.clientConfig ?? {});
31
- const client = lib_dynamodb_1.DynamoDBDocument.from(ddbClient);
28
+ const resolved = (0, client_1.resolveDynamoDBClient)(this.base);
29
+ const client = resolved.client;
32
30
  const saver = new saver_1.DynamoDBSaver({ ...this.base, ...options.saver, client });
33
31
  const store = new store_1.DynamoDBStore({ ...this.base, ...options.store, client });
34
32
  const history = new chat_message_history_1.DynamoDBChatMessageHistory({ ...this.base, ...options.history, client });
@@ -40,7 +38,7 @@ class DynamoDBFactory {
40
38
  saver.destroy();
41
39
  store.destroy();
42
40
  history.destroy();
43
- ddbClient.destroy();
41
+ resolved.ddbClient?.destroy();
44
42
  },
45
43
  };
46
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/factory/factory.ts"],"names":[],"mappings":";;;AAAA,8DAAqF;AACrF,wDAAyD;AAEzD,iDAAsD;AAEtD,0EAA6E;AAG7E,0CAA+C;AAyB/C;;;;GAIG;AACH;IAC+B,IAAI;IAAjC,YAA6B,IAAI,GAAuB,EAAE;oBAA7B,IAAI;IAA4B,CAAC;IAE9D,WAAW,CAAC,OAA6B;QACvC,OAAO,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,WAAW,CAAC,OAA6B;QACvC,OAAO,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,wBAAwB,CAAC,OAA0C;QACjE,OAAO,IAAI,iDAA0B,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,SAAS,CAAC,OAAyB;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,gCAAc,CAAC,MAAM,CAAC,CAAC,CAAC;QACjF,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,+BAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAG,IAAI,iDAA0B,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7F,OAAO;YACL,KAAK;YACL,KAAK;YACL,OAAO;YACP,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/factory/factory.ts"],"names":[],"mappings":";;;AAGA,iDAAsD;AAEtD,0EAA6E;AAE7E,sDAAkE;AAElE,0CAA+C;AA0B/C;;;;GAIG;AACH;IAC+B,IAAI;IAAjC,YAA6B,IAAI,GAAuB,EAAE;oBAA7B,IAAI;IAA4B,CAAC;IAE9D,WAAW,CAAC,OAA6B;QACvC,OAAO,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,WAAW,CAAC,OAA6B;QACvC,OAAO,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,wBAAwB,CAAC,OAA0C;QACjE,OAAO,IAAI,iDAA0B,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,SAAS,CAAC,OAAyB;QACjC,MAAM,QAAQ,GAAG,IAAA,8BAAqB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,IAAI,qBAAa,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAG,IAAI,iDAA0B,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7F,OAAO;YACL,KAAK;YACL,KAAK;YACL,OAAO;YACP,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;YAChC,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4BxD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAcf"}
1
+ {"version":3,"file":"add-messages.d.ts","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGjB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA4BxD;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -42,15 +42,16 @@ async function addMessages(context, sessionId, messages) {
42
42
  if (messages.length === 0)
43
43
  return;
44
44
  const stored = (0, messages_1.mapChatMessagesToStoredMessages)(messages);
45
- const ttlTimestamp = context.ttl
45
+ const anchor = context.ttl
46
46
  ? await (0, ttl_anchor_1.resolveTtlAnchor)(context, sessionId, (0, ttl_1.calculateTtlTimestamp)(context.ttl))
47
47
  : undefined;
48
- const items = await buildItems(context, sessionId, stored, ttlTimestamp);
48
+ const items = await buildItems(context, sessionId, stored, anchor?.ttlTimestamp);
49
49
  const chunks = (0, message_chunker_1.chunkBySize)(items, MAX_MESSAGES_PER_TRANSACTION, MAX_TRANSACTION_BYTES);
50
50
  await (0, append_saga_1.appendChunks)(context, sessionId, chunks, {
51
51
  now: (0, clock_1.nowIso)(),
52
52
  title: (0, title_generator_1.deriveTitle)(stored),
53
- ttlTimestamp,
53
+ ttlTimestamp: anchor?.ttlTimestamp,
54
+ forceTtlRefresh: anchor?.refresh,
54
55
  });
55
56
  }
56
57
  //# sourceMappingURL=add-messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,mEAA4E;AAC5E,qDAAoE;AACpE,yDAAuD;AACvD,yDAA2D;AAC3D,iEAA0D;AAE1D,iEAA0D;AAC1D,uDAA0D;AAG1D,yFAAyF;AACzF,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAExC,KAAK,UAAU,UAAU,CACvB,OAAuB,EACvB,SAAiB,EACjB,MAAuB,EACvB,YAAqB;IAErB,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAA,8BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,sBACV,OAAuB,EACvB,SAAiB,EACjB,QAAuB;IAEvB,IAAA,mCAAsB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,IAAA,0CAA+B,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG;QAC9B,CAAC,CAAC,MAAM,IAAA,6BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,IAAA,2BAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG,IAAA,6BAAW,EAAC,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACvF,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;QAC7C,GAAG,EAAE,IAAA,cAAM,GAAE;QACb,KAAK,EAAE,IAAA,6BAAW,EAAC,MAAM,CAAC;QAC1B,YAAY;KACb,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"add-messages.js","sourceRoot":"","sources":["../../../src/history/actions/add-messages.ts"],"names":[],"mappings":";;;AAAA,uDAIkC;AAElC,8CAA4C;AAC5C,mEAA4E;AAC5E,qDAAoE;AACpE,yDAAuD;AACvD,yDAA2D;AAC3D,iEAA0D;AAE1D,iEAA0D;AAC1D,uDAA0D;AAG1D,yFAAyF;AACzF,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAExC;;;;GAIG;AACH,MAAM,qBAAqB,GAAG,SAAS,CAAC;AAExC,KAAK,UAAU,UAAU,CACvB,OAAuB,EACvB,SAAiB,EACjB,MAAuB,EACvB,YAAqB;IAErB,MAAM,KAAK,GAAsB,EAAE,CAAC;IACpC,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,IAAA,8BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;GAWG;AACI,KAAK,sBACV,OAAuB,EACvB,SAAiB,EACjB,QAAuB;IAEvB,IAAA,mCAAsB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,IAAA,0CAA+B,EAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG;QACxB,CAAC,CAAC,MAAM,IAAA,6BAAgB,EAAC,OAAO,EAAE,SAAS,EAAE,IAAA,2BAAqB,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChF,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,IAAA,6BAAW,EAAC,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACvF,MAAM,IAAA,0BAAY,EAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE;QAC7C,GAAG,EAAE,IAAA,cAAM,GAAE;QACb,KAAK,EAAE,IAAA,6BAAW,EAAC,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,EAAE,YAAY;QAClC,eAAe,EAAE,MAAM,EAAE,OAAO;KACjC,CAAC,CAAC;AACL,CAAC"}
@@ -29,7 +29,7 @@ async function clearSession(context, sessionId) {
29
29
  const buffer = { keys: [], descriptors: [] };
30
30
  const pages = (0, paginate_1.paginateQuery)({
31
31
  client: context.client,
32
- params: (0, query_1.sessionItemsQuery)(context.tableName, sessionId),
32
+ params: (0, query_1.sessionItemsQuery)(context.tableName, sessionId, { consistent: true }),
33
33
  maxItems: Number.POSITIVE_INFINITY,
34
34
  maxIterations: Number.POSITIVE_INFINITY,
35
35
  });
@@ -1 +1 @@
1
- {"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":";;;AACA,wEAAmE;AACnE,2DAAiE;AACjE,sDAAyD;AACzD,mEAAkE;AAClE,6DAA+D;AAC/D,6CAAsD;AAStD,KAAK,UAAU,WAAW,CAAC,OAAuB,EAAE,MAAoB;IACtE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACrC,MAAM,IAAA,2BAAa,EACjB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,SAAS,EACjB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CACvD,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAA,0BAAgB,EACpB,OAAO,CAAC,SAAS,EACjB,IAAA,+BAAa,EAAC,MAAM,CAAC,WAAW,CAAC,EACjC,eAAe,EACf,OAAO,CAAC,MAAM,CACf,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,uBAAuB,OAAuB,EAAE,SAAiB;IAC3E,MAAM,MAAM,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAA,wBAAa,EAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,IAAA,yBAAiB,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC;QACvD,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,aAAa,EAAE,MAAM,CAAC,iBAAiB;KACxC,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,GAAsB,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,2BAAe;YAAE,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
1
+ {"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../src/history/actions/clear.ts"],"names":[],"mappings":";;;AACA,wEAAmE;AACnE,2DAAiE;AACjE,sDAAyD;AACzD,mEAAkE;AAClE,6DAA+D;AAC/D,6CAAsD;AAStD,KAAK,UAAU,WAAW,CAAC,OAAuB,EAAE,MAAoB;IACtE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACrC,MAAM,IAAA,2BAAa,EACjB,OAAO,CAAC,MAAM,EACd,OAAO,CAAC,SAAS,EACjB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CACvD,CAAC;IACF,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAA,0BAAgB,EACpB,OAAO,CAAC,SAAS,EACjB,IAAA,+BAAa,EAAC,MAAM,CAAC,WAAW,CAAC,EACjC,eAAe,EACf,OAAO,CAAC,MAAM,CACf,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;IACjB,MAAM,CAAC,WAAW,GAAG,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,uBAAuB,OAAuB,EAAE,SAAiB;IAC3E,MAAM,MAAM,GAAiB,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAA,wBAAa,EAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,IAAA,yBAAiB,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QAC7E,QAAQ,EAAE,MAAM,CAAC,iBAAiB;QAClC,aAAa,EAAE,MAAM,CAAC,iBAAiB;KACxC,CAAC,CAAC;IACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,GAAsB,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,2BAAe;YAAE,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC"}
@@ -7,5 +7,6 @@ import type { SessionMetadata } from '../types';
7
7
  */
8
8
  export declare function listSessions(context: HistoryContext, options?: {
9
9
  maxIterations?: number;
10
+ maxItems?: number;
10
11
  }): Promise<SessionMetadata[]>;
11
12
  //# sourceMappingURL=list-sessions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list-sessions.d.ts","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjE;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,OAAO,CAAC,eAAe,EAAE,CAAC,CAwB5B"}
1
+ {"version":3,"file":"list-sessions.d.ts","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,UAAU,CAAC;AAEjE;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACtD,OAAO,CAAC,eAAe,EAAE,CAAC,CAyB5B"}
@@ -19,6 +19,7 @@ async function listSessions(context, options) {
19
19
  ExpressionAttributeValues: { ':session': keys_1.SESSION_SORT_KEY },
20
20
  },
21
21
  maxIterations: options?.maxIterations,
22
+ maxItems: options?.maxItems,
22
23
  })) {
23
24
  const item = raw;
24
25
  if (item.SK !== keys_1.SESSION_SORT_KEY || typeof item.sessionId !== 'string')
@@ -1 +1 @@
1
- {"version":3,"file":"list-sessions.js","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":";;;AAAA,qDAA0D;AAC1D,2CAAoD;AAIpD;;;;GAIG;AACI,KAAK,uBACV,OAAuB,EACvB,OAAoC;IAEpC,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAA,mBAAY,EAAC;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE;YACN,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,gBAAgB,EAAE,gBAAgB;YAClC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;YACzC,yBAAyB,EAAE,EAAE,UAAU,EAAE,uBAAgB,EAAE;SAC5D;QACD,aAAa,EAAE,OAAO,EAAE,aAAa;KACtC,CAAC,EAAE,CAAC;QACH,MAAM,IAAI,GAAG,GAAsB,CAAC;QACpC,IAAI,IAAI,CAAC,EAAE,KAAK,uBAAgB,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;YAAE,SAAS;QACjF,QAAQ,CAAC,IAAI,CAAC;YACZ,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"list-sessions.js","sourceRoot":"","sources":["../../../src/history/actions/list-sessions.ts"],"names":[],"mappings":";;;AAAA,qDAA0D;AAC1D,2CAAoD;AAIpD;;;;GAIG;AACI,KAAK,uBACV,OAAuB,EACvB,OAAuD;IAEvD,MAAM,QAAQ,GAAsB,EAAE,CAAC;IACvC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAA,mBAAY,EAAC;QACnC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE;YACN,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,gBAAgB,EAAE,gBAAgB;YAClC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;YACzC,yBAAyB,EAAE,EAAE,UAAU,EAAE,uBAAgB,EAAE;SAC5D;QACD,aAAa,EAAE,OAAO,EAAE,aAAa;QACrC,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC5B,CAAC,EAAE,CAAC;QACH,MAAM,IAAI,GAAG,GAAsB,CAAC;QACpC,IAAI,IAAI,CAAC,EAAE,KAAK,uBAAgB,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;YAAE,SAAS;QACjF,QAAQ,CAAC,IAAI,CAAC;YACZ,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -4,7 +4,10 @@ import type { HistoryContext } from '../internal/setup';
4
4
  * and write it back, repairing any drift. A repair tool: the append path keeps
5
5
  * the count consistent transactionally, so this is only needed after external
6
6
  * corruption. Run it when the session is quiescent — it `SET`s the count, so a
7
- * concurrent append's increment could be clobbered. Returns the reconciled count.
7
+ * concurrent append's increment could be clobbered. Requires the session to
8
+ * already exist; reconciling a nonexistent session throws {@link ConflictError}
9
+ * rather than creating a permanent, TTL-less metadata-only row. Returns the
10
+ * reconciled count.
8
11
  */
9
12
  export declare function reconcileMessageCount(context: HistoryContext, sessionId: string): Promise<number>;
10
13
  //# sourceMappingURL=reconcile-count.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-count.d.ts","sourceRoot":"","sources":["../../../src/history/actions/reconcile-count.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAiBxD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAajB"}
1
+ {"version":3,"file":"reconcile-count.d.ts","sourceRoot":"","sources":["../../../src/history/actions/reconcile-count.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAgBxD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAwBjB"}
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reconcileMessageCount = reconcileMessageCount;
4
4
  const retry_1 = require("../../shared/dynamodb/retry");
5
+ const errors_1 = require("../../shared/errors/errors");
5
6
  const primitives_1 = require("../../shared/validation/primitives");
6
7
  const keys_1 = require("../internal/keys");
7
8
  const query_1 = require("../internal/query");
8
- /** Count a session's message items with a server-side `COUNT` query, all pages. */
9
9
  async function countMessages(context, sessionId) {
10
10
  const base = (0, query_1.messageQuery)(context.tableName, sessionId);
11
11
  let total = 0;
@@ -22,18 +22,30 @@ async function countMessages(context, sessionId) {
22
22
  * and write it back, repairing any drift. A repair tool: the append path keeps
23
23
  * the count consistent transactionally, so this is only needed after external
24
24
  * corruption. Run it when the session is quiescent — it `SET`s the count, so a
25
- * concurrent append's increment could be clobbered. Returns the reconciled count.
25
+ * concurrent append's increment could be clobbered. Requires the session to
26
+ * already exist; reconciling a nonexistent session throws {@link ConflictError}
27
+ * rather than creating a permanent, TTL-less metadata-only row. Returns the
28
+ * reconciled count.
26
29
  */
27
30
  async function reconcileMessageCount(context, sessionId) {
28
31
  (0, primitives_1.validateNonEmptyString)(sessionId, 'sessionId');
29
32
  const count = await countMessages(context, sessionId);
30
- await (0, retry_1.withDynamoDBRetry)(() => context.client.update({
31
- TableName: context.tableName,
32
- Key: { PK: (0, keys_1.sessionPartition)(sessionId), SK: keys_1.SESSION_SORT_KEY },
33
- UpdateExpression: 'SET #count = :count',
34
- ExpressionAttributeNames: { '#count': 'messageCount' },
35
- ExpressionAttributeValues: { ':count': count },
36
- }));
33
+ try {
34
+ await (0, retry_1.withDynamoDBRetry)(() => context.client.update({
35
+ TableName: context.tableName,
36
+ Key: { PK: (0, keys_1.sessionPartition)(sessionId), SK: keys_1.SESSION_SORT_KEY },
37
+ UpdateExpression: 'SET #count = :count',
38
+ ExpressionAttributeNames: { '#count': 'messageCount' },
39
+ ExpressionAttributeValues: { ':count': count },
40
+ ConditionExpression: 'attribute_exists(PK)',
41
+ }));
42
+ }
43
+ catch (error) {
44
+ if (error.name === 'ConditionalCheckFailedException') {
45
+ throw new errors_1.ConflictError(`Cannot reconcile messageCount: session "${sessionId}" does not exist`, error);
46
+ }
47
+ throw error;
48
+ }
37
49
  return count;
38
50
  }
39
51
  //# sourceMappingURL=reconcile-count.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reconcile-count.js","sourceRoot":"","sources":["../../../src/history/actions/reconcile-count.ts"],"names":[],"mappings":";;;AAEA,uDAAgE;AAChE,mEAA4E;AAC5E,2CAAsE;AACtE,6CAAiD;AAGjD,mFAAmF;AACnF,KAAK,UAAU,aAAa,CAAC,OAAuB,EAAE,SAAiB;IACrE,MAAM,IAAI,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAA0D,CAAC;IAC/D,GAAG,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAChF,CAAC;QACF,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QACzB,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;IACnC,CAAC,QAAQ,QAAQ,EAAE;IACnB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACI,KAAK,gCACV,OAAuB,EACvB,SAAiB;IAEjB,IAAA,mCAAsB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;QACpB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC,EAAE,EAAE,EAAE,uBAAgB,EAAE;QAC9D,gBAAgB,EAAE,qBAAqB;QACvC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE;QACtD,yBAAyB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;KAC/C,CAAC,CACH,CAAC;IACF,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"reconcile-count.js","sourceRoot":"","sources":["../../../src/history/actions/reconcile-count.ts"],"names":[],"mappings":";;;AAEA,uDAAgE;AAChE,uDAA2D;AAC3D,mEAA4E;AAC5E,2CAAsE;AACtE,6CAAiD;AAGjD,KAAK,UAAU,aAAa,CAAC,OAAuB,EAAE,SAAiB;IACrE,MAAM,IAAI,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAA0D,CAAC;IAC/D,GAAG,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,CAChF,CAAC;QACF,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;QACzB,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;IACnC,CAAC,QAAQ,QAAQ,EAAE;IACnB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,gCACV,OAAuB,EACvB,SAAiB;IAEjB,IAAA,mCAAsB,EAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YACpB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,GAAG,EAAE,EAAE,EAAE,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC,EAAE,EAAE,EAAE,uBAAgB,EAAE;YAC9D,gBAAgB,EAAE,qBAAqB;YACvC,wBAAwB,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE;YACtD,yBAAyB,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;YAC9C,mBAAmB,EAAE,sBAAsB;SAC5C,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA2B,CAAC,IAAI,KAAK,iCAAiC,EAAE,CAAC;YAC5E,MAAM,IAAI,sBAAa,CACrB,2CAA2C,SAAS,kBAAkB,EACtE,KAAc,CACf,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -24,6 +24,7 @@ export declare class DynamoDBChatMessageHistory {
24
24
  /** List all sessions as metadata summaries. */
25
25
  listSessions(options?: {
26
26
  maxIterations?: number;
27
+ maxItems?: number;
27
28
  }): Promise<SessionMetadata[]>;
28
29
  /**
29
30
  * Recompute and repair a session's `messageCount` from the stored messages.
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message-history.d.ts","sourceRoot":"","sources":["../../src/history/chat-message-history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAS5D,OAAO,EAAE,iCAAiC,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAElF;;;;;;GAMG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+C;IAEzE,YAAY,OAAO,EAAE,iCAAiC,EAKrD;IAED,yCAAyC;IACzC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErD;IAED,oCAAoC;IACpC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;IAED,4CAA4C;IAC5C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAED,kDAAkD;IAClD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtC;IAED,+CAA+C;IAC/C,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAE7E;IAED;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAExD;IAED,8DAA8D;IAC9D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,iCAAiC,CAE/D;IAED,yEAAyE;IACzE,OAAO,IAAI,IAAI,CAGd;IAED;;;;;;;OAOG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3C;CACF"}
1
+ {"version":3,"file":"chat-message-history.d.ts","sourceRoot":"","sources":["../../src/history/chat-message-history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAS5D,OAAO,EAAE,iCAAiC,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,iCAAiC,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAElF;;;;;;GAMG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+C;IAEzE,YAAY,OAAO,EAAE,iCAAiC,EAKrD;IAED,yCAAyC;IACzC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAErD;IAED,oCAAoC;IACpC,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAErE;IAED,4CAA4C;IAC5C,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjE;IAED,kDAAkD;IAClD,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtC;IAED,+CAA+C;IAC/C,YAAY,CAAC,OAAO,CAAC,EAAE;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAE7B;IAED;;;OAGG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAExD;IAED,8DAA8D;IAC9D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,iCAAiC,CAE/D;IAED,yEAAyE;IACzE,OAAO,IAAI,IAAI,CAGd;IAED;;;;;;;OAOG;IACG,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3C;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-message-history.js","sourceRoot":"","sources":["../../src/history/chat-message-history.ts"],"names":[],"mappings":";;;AAEA,kDAA8D;AAC9D,yDAA0E;AAC1E,2CAA+C;AAC/C,yDAA0E;AAC1E,2DAA6E;AAC7E,+DAAiG;AACjG,4CAAqE;AACrE,uDAAsE;AAGtE;;;;;;GAMG;AACH;IACmB,OAAO,CAAiB;IACxB,UAAU,CAAU;IACpB,SAAS,CAA+C;IAEzE,YAAY,OAA0C;QACpD,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,yCAAyC;IACzC,WAAW,CAAC,SAAiB;QAC3B,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,oCAAoC;IACpC,WAAW,CAAC,SAAiB,EAAE,QAAuB;QACpD,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED,4CAA4C;IAC5C,UAAU,CAAC,SAAiB,EAAE,OAAoB;QAChD,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,SAAiB;QACrB,OAAO,IAAA,oBAAY,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,+CAA+C;IAC/C,YAAY,CAAC,OAAoC;QAC/C,OAAO,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,qBAAqB,CAAC,SAAiB;QACrC,OAAO,IAAA,uCAA2B,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,8DAA8D;IAC9D,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,mDAAiC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,yEAAyE;IACzE,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAA,wBAAkB,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC;CACF"}
1
+ {"version":3,"file":"chat-message-history.js","sourceRoot":"","sources":["../../src/history/chat-message-history.ts"],"names":[],"mappings":";;;AAEA,kDAA8D;AAC9D,yDAA0E;AAC1E,2CAA+C;AAC/C,yDAA0E;AAC1E,2DAA6E;AAC7E,+DAAiG;AACjG,4CAAqE;AACrE,uDAAsE;AAGtE;;;;;;GAMG;AACH;IACmB,OAAO,CAAiB;IACxB,UAAU,CAAU;IACpB,SAAS,CAA+C;IAEzE,YAAY,OAA0C;QACpD,MAAM,KAAK,GAAG,IAAA,oBAAY,EAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACnC,CAAC;IAED,yCAAyC;IACzC,WAAW,CAAC,SAAiB;QAC3B,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,oCAAoC;IACpC,WAAW,CAAC,SAAiB,EAAE,QAAuB;QACpD,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC;IAED,4CAA4C;IAC5C,UAAU,CAAC,SAAiB,EAAE,OAAoB;QAChD,OAAO,IAAA,0BAAiB,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,kDAAkD;IAClD,KAAK,CAAC,SAAiB;QACrB,OAAO,IAAA,oBAAY,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,+CAA+C;IAC/C,YAAY,CAAC,OAGZ;QACC,OAAO,IAAA,4BAAkB,EAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACH,qBAAqB,CAAC,SAAiB;QACrC,OAAO,IAAA,uCAA2B,EAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,8DAA8D;IAC9D,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,mDAAiC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,yEAAyE;IACzE,OAAO;QACL,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,UAAU;YAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;IACjD,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO;QACzD,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,IAAA,wBAAkB,EAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC;CACF"}
@@ -5,6 +5,7 @@ export interface AppendFields {
5
5
  now: string;
6
6
  title?: string;
7
7
  ttlTimestamp?: number;
8
+ forceTtlRefresh?: boolean;
8
9
  }
9
10
  /**
10
11
  * Append message chunks with caller-observed atomicity. Each chunk commits its
@@ -1 +1 @@
1
- {"version":3,"file":"append-saga.d.ts","sourceRoot":"","sources":["../../../src/history/internal/append-saga.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAmGD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EAAE,EAAE,EAC3B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAmBf"}
1
+ {"version":3,"file":"append-saga.d.ts","sourceRoot":"","sources":["../../../src/history/internal/append-saga.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,0EAA0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmGD;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,EAAE,EAAE,EAC3B,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -4,23 +4,10 @@ exports.appendChunks = appendChunks;
4
4
  const descriptor_keys_1 = require("../../shared/codec/descriptor-keys");
5
5
  const orphans_1 = require("../../shared/codec/s3/orphans");
6
6
  const batch_write_1 = require("../../shared/dynamodb/batch-write");
7
- const retry_1 = require("../../shared/dynamodb/retry");
8
7
  const errors_1 = require("../../shared/errors/errors");
9
8
  const wrap_error_1 = require("../../shared/errors/wrap-error");
10
- const keys_1 = require("./keys");
11
9
  const message_transaction_1 = require("./message-transaction");
12
- /** Subtract a previously-added count from the session, leaving it consistent. */
13
- async function revertSessionCount(context, sessionId, delta) {
14
- if (delta === 0)
15
- return;
16
- await (0, retry_1.withDynamoDBRetry)(() => context.client.update({
17
- TableName: context.tableName,
18
- Key: { PK: (0, keys_1.sessionPartition)(sessionId), SK: keys_1.SESSION_SORT_KEY },
19
- UpdateExpression: 'ADD #count :neg',
20
- ExpressionAttributeNames: { '#count': 'messageCount' },
21
- ExpressionAttributeValues: { ':neg': -delta },
22
- }));
23
- }
10
+ const session_count_1 = require("./session-count");
24
11
  /**
25
12
  * Best-effort delete the offloaded S3 objects of the `chunks` slice given.
26
13
  * {@link compensate} calls it once per commit status, never for the whole
@@ -32,14 +19,33 @@ async function cleanBatchS3(context, chunks) {
32
19
  const descriptors = chunks.flat().map((item) => item.message);
33
20
  await (0, orphans_1.cleanUpS3Orphans)(context.offloader, (0, descriptor_keys_1.collectS3Keys)(descriptors), 'history.addMessages', context.logger);
34
21
  }
35
- /** Delete every committed chunk's items and revert their counted total. */
22
+ /**
23
+ * Delete every committed chunk's items, then revert the counted total by
24
+ * however many rows the delete actually persisted before failing (not
25
+ * necessarily every committed row — see the catch branch below).
26
+ */
36
27
  async function rollbackCommitted(context, sessionId, committed) {
37
28
  const keys = committed.flatMap((chunk) => chunk.keys);
38
- if (keys.length > 0) {
29
+ const total = committed.reduce((sum, chunk) => sum + chunk.count, 0);
30
+ if (keys.length === 0) {
31
+ await (0, session_count_1.revertSessionCount)(context, sessionId, total);
32
+ return;
33
+ }
34
+ try {
39
35
  await (0, batch_write_1.batchWriteAll)(context.client, context.tableName, keys.map((Key) => ({ DeleteRequest: { Key } })));
40
36
  }
41
- const total = committed.reduce((sum, chunk) => sum + chunk.count, 0);
42
- await revertSessionCount(context, sessionId, total);
37
+ catch (error) {
38
+ /**
39
+ * batchWriteAll has exactly one throw site and it is always a
40
+ * BatchWriteAllIncompleteError (see Task 9) — asserted, not instanceof-
41
+ * checked, since the false case is unreachable and this project
42
+ * enforces 100% branch coverage with no exceptions.
43
+ */
44
+ const deleted = error.succeededCount;
45
+ await (0, session_count_1.revertSessionCount)(context, sessionId, deleted);
46
+ throw error;
47
+ }
48
+ await (0, session_count_1.revertSessionCount)(context, sessionId, total);
43
49
  }
44
50
  /**
45
51
  * Undo a failed batch. Always throws. S3 cleanup is split by commit status so
@@ -88,11 +94,9 @@ async function appendChunks(context, sessionId, chunks, fields) {
88
94
  for (const chunk of chunks) {
89
95
  try {
90
96
  await (0, message_transaction_1.writeMessageChunk)(context, chunk, {
97
+ ...fields,
91
98
  sessionId,
92
99
  count: chunk.length,
93
- now: fields.now,
94
- title: fields.title,
95
- ttlTimestamp: fields.ttlTimestamp,
96
100
  });
97
101
  committed.push({
98
102
  keys: chunk.map((item) => ({ PK: item.PK, SK: item.SK })),
@@ -1 +1 @@
1
- {"version":3,"file":"append-saga.js","sourceRoot":"","sources":["../../../src/history/internal/append-saga.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"append-saga.js","sourceRoot":"","sources":["../../../src/history/internal/append-saga.ts"],"names":[],"mappings":"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"}
@@ -10,12 +10,17 @@ export interface ChunkRetryOptions {
10
10
  * Atomically write a chunk of message items together with the session-metadata
11
11
  * count update in one {@link https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html | TransactWriteItems}
12
12
  * call, so `messageCount` can never disagree with the messages that landed. A
13
- * single `ClientRequestToken` is reused across retries so a re-sent commit (e.g.
14
- * after a lost response) is idempotent and never double-applies the count `ADD`.
15
- * The transaction always touches the session's shared metadata row, so
16
- * concurrent appends to the same session contend on it; retries use
17
- * {@link MESSAGE_APPEND_RETRY_MAX_ATTEMPTS} rather than the default budget so a
18
- * burst of concurrent callers can drain via backoff instead of erroring.
13
+ * single `ClientRequestToken` is used per attempt so a re-sent commit (e.g.
14
+ * after a lost response) is idempotent and never double-applies the count
15
+ * `ADD`. When `fields.forceTtlRefresh` is set, the session update carries a
16
+ * monotonic ConditionExpression (see session-update.ts); if — and only if —
17
+ * that specific condition loses a race against a concurrent caller who just
18
+ * healed the same anchor, this retries the identical chunk once with
19
+ * `forceTtlRefresh: false` (safe: `if_not_exists` then converges to whatever
20
+ * already won) rather than losing the message writes to a benign ttl race. A
21
+ * cancellation caused by any other item (a genuine message-row conflict) is
22
+ * not retried here — it propagates for the normal transient-conflict retry
23
+ * budget inside `withDynamoDBRetry` to handle, or to the caller otherwise.
19
24
  */
20
25
  export declare function writeMessageChunk(context: HistoryContext, items: ChatMessageItem[], fields: SessionUpdateFields, retry?: ChunkRetryOptions): Promise<void>;
21
26
  //# sourceMappingURL=message-transaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-transaction.d.ts","sourceRoot":"","sources":["../../../src/history/internal/message-transaction.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,eAAe,EAAE,EACxB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,GAAE,iBAAsB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAaf"}
1
+ {"version":3,"file":"message-transaction.d.ts","sourceRoot":"","sources":["../../../src/history/internal/message-transaction.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wEAAwE;AACxE,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAuCD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,eAAe,EAAE,EACxB,MAAM,EAAE,mBAAmB,EAC3B,KAAK,GAAE,iBAAsB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAUf"}
@@ -3,31 +3,58 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.writeMessageChunk = writeMessageChunk;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const constants_1 = require("../../shared/constants");
6
+ const cancellation_1 = require("../../shared/dynamodb/cancellation");
6
7
  const retry_1 = require("../../shared/dynamodb/retry");
7
8
  const session_update_1 = require("./session-update");
8
- /**
9
- * Atomically write a chunk of message items together with the session-metadata
10
- * count update in one {@link https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html | TransactWriteItems}
11
- * call, so `messageCount` can never disagree with the messages that landed. A
12
- * single `ClientRequestToken` is reused across retries so a re-sent commit (e.g.
13
- * after a lost response) is idempotent and never double-applies the count `ADD`.
14
- * The transaction always touches the session's shared metadata row, so
15
- * concurrent appends to the same session contend on it; retries use
16
- * {@link MESSAGE_APPEND_RETRY_MAX_ATTEMPTS} rather than the default budget so a
17
- * burst of concurrent callers can drain via backoff instead of erroring.
18
- */
19
- async function writeMessageChunk(context, items, fields, retry = {}) {
20
- const input = {
9
+ /** True when a TransactWriteItems cancellation was caused solely by the SESSION update's ttl condition (always TransactItems index 0 — see buildInput below), not by any message item. */
10
+ function isTtlConditionLoss(error) {
11
+ const reasons = (0, cancellation_1.getCancellationReasons)(error);
12
+ return (reasons?.[0]?.Code === 'ConditionalCheckFailed' &&
13
+ reasons.slice(1).every((reason) => reason.Code === 'None'));
14
+ }
15
+ function buildInput(context, items, fields) {
16
+ return {
21
17
  TransactItems: [
22
18
  (0, session_update_1.buildSessionUpdateItem)(context.tableName, fields),
23
19
  ...items.map((item) => ({ Put: { TableName: context.tableName, Item: item } })),
24
20
  ],
25
21
  ClientRequestToken: (0, node_crypto_1.randomUUID)(),
26
22
  };
23
+ }
24
+ async function attempt(context, items, fields, retry) {
25
+ const input = buildInput(context, items, fields);
27
26
  await (0, retry_1.withDynamoDBRetry)(() => context.client.transactWrite(input), {
28
27
  maxAttempts: constants_1.MESSAGE_APPEND_RETRY_MAX_ATTEMPTS,
29
28
  rng: retry.rng,
30
29
  signal: retry.signal,
31
30
  });
32
31
  }
32
+ /**
33
+ * Atomically write a chunk of message items together with the session-metadata
34
+ * count update in one {@link https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html | TransactWriteItems}
35
+ * call, so `messageCount` can never disagree with the messages that landed. A
36
+ * single `ClientRequestToken` is used per attempt so a re-sent commit (e.g.
37
+ * after a lost response) is idempotent and never double-applies the count
38
+ * `ADD`. When `fields.forceTtlRefresh` is set, the session update carries a
39
+ * monotonic ConditionExpression (see session-update.ts); if — and only if —
40
+ * that specific condition loses a race against a concurrent caller who just
41
+ * healed the same anchor, this retries the identical chunk once with
42
+ * `forceTtlRefresh: false` (safe: `if_not_exists` then converges to whatever
43
+ * already won) rather than losing the message writes to a benign ttl race. A
44
+ * cancellation caused by any other item (a genuine message-row conflict) is
45
+ * not retried here — it propagates for the normal transient-conflict retry
46
+ * budget inside `withDynamoDBRetry` to handle, or to the caller otherwise.
47
+ */
48
+ async function writeMessageChunk(context, items, fields, retry = {}) {
49
+ try {
50
+ await attempt(context, items, fields, retry);
51
+ }
52
+ catch (error) {
53
+ if (fields.forceTtlRefresh && isTtlConditionLoss(error)) {
54
+ await attempt(context, items, { ...fields, forceTtlRefresh: false }, retry);
55
+ return;
56
+ }
57
+ throw error;
58
+ }
59
+ }
33
60
  //# sourceMappingURL=message-transaction.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-transaction.js","sourceRoot":"","sources":["../../../src/history/internal/message-transaction.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAEzC,sDAA2E;AAC3E,uDAAgE;AAEhE,qDAAoF;AASpF;;;;;;;;;;GAUG;AACI,KAAK,4BACV,OAAuB,EACvB,KAAwB,EACxB,MAA2B,EAC3B,KAAK,GAAsB,EAAE;IAE7B,MAAM,KAAK,GAAG;QACZ,aAAa,EAAE;YACb,IAAA,uCAAsB,EAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;YACjD,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;SAChF;QACD,kBAAkB,EAAE,IAAA,wBAAU,GAAE;KACjC,CAAC;IACF,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;QACjE,WAAW,EAAE,6CAAiC;QAC9C,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"message-transaction.js","sourceRoot":"","sources":["../../../src/history/internal/message-transaction.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAEzC,sDAA2E;AAC3E,qEAA4E;AAC5E,uDAAgE;AAEhE,qDAI0B;AAS1B,0LAA0L;AAC1L,SAAS,kBAAkB,CAAC,KAAY;IACtC,MAAM,OAAO,GAAG,IAAA,qCAAsB,EAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,CACL,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,wBAAwB;QAC/C,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAC3D,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,OAAuB,EACvB,KAAwB,EACxB,MAA2B;IAE3B,OAAO;QACL,aAAa,EAAE;YACb,IAAA,uCAAsB,EAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC;YACjD,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;SAChF;QACD,kBAAkB,EAAE,IAAA,wBAAU,GAAE;KACjC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,OAAO,CACpB,OAAuB,EACvB,KAAwB,EACxB,MAA2B,EAC3B,KAAwB;IAExB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE;QACjE,WAAW,EAAE,6CAAiC;QAC9C,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACI,KAAK,4BACV,OAAuB,EACvB,KAAwB,EACxB,MAA2B,EAC3B,KAAK,GAAsB,EAAE;IAE7B,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,MAAM,CAAC,eAAe,IAAI,kBAAkB,CAAC,KAAc,CAAC,EAAE,CAAC;YACjE,MAAM,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,6 +1,10 @@
1
1
  import type { QueryCommandInput } from '@aws-sdk/lib-dynamodb';
2
+ /** Options for {@link sessionItemsQuery}. */
3
+ export interface SessionItemsQueryOptions {
4
+ consistent?: boolean;
5
+ }
2
6
  /** Query input selecting every item in a session's partition (messages + metadata). */
3
- export declare function sessionItemsQuery(tableName: string, sessionId: string): QueryCommandInput;
7
+ export declare function sessionItemsQuery(tableName: string, sessionId: string, options?: SessionItemsQueryOptions): QueryCommandInput;
4
8
  /** Query input selecting a session's message items in chronological order. */
5
9
  export declare function messageQuery(tableName: string, sessionId: string): QueryCommandInput;
6
10
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/history/internal/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI/D,uFAAuF;AACvF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAOzF;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAWpF"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/history/internal/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI/D,6CAA6C;AAC7C,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,uFAAuF;AACvF,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,wBAA6B,GACrC,iBAAiB,CASnB;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAWpF"}
@@ -4,13 +4,16 @@ exports.sessionItemsQuery = sessionItemsQuery;
4
4
  exports.messageQuery = messageQuery;
5
5
  const keys_1 = require("./keys");
6
6
  /** Query input selecting every item in a session's partition (messages + metadata). */
7
- function sessionItemsQuery(tableName, sessionId) {
8
- return {
7
+ function sessionItemsQuery(tableName, sessionId, options = {}) {
8
+ const params = {
9
9
  TableName: tableName,
10
10
  KeyConditionExpression: '#pk = :pk',
11
11
  ExpressionAttributeNames: { '#pk': 'PK' },
12
12
  ExpressionAttributeValues: { ':pk': (0, keys_1.sessionPartition)(sessionId) },
13
13
  };
14
+ if (options.consistent)
15
+ params.ConsistentRead = true;
16
+ return params;
14
17
  }
15
18
  /** Query input selecting a session's message items in chronological order. */
16
19
  function messageQuery(tableName, sessionId) {
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/history/internal/query.ts"],"names":[],"mappings":";;;;AAEA,iCAAgE;AAEhE,uFAAuF;AACvF,2BAAkC,SAAiB,EAAE,SAAiB;IACpE,OAAO;QACL,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,WAAW;QACnC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QACzC,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC,EAAE;KAClE,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,sBAA6B,SAAiB,EAAE,SAAiB;IAC/D,OAAO;QACL,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,sCAAsC;QAC9D,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACtD,yBAAyB,EAAE;YACzB,KAAK,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC;YAClC,MAAM,EAAE,IAAA,2BAAoB,GAAE;SAC/B;QACD,gBAAgB,EAAE,IAAI;KACvB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/history/internal/query.ts"],"names":[],"mappings":";;;;AAEA,iCAAgE;AAOhE,uFAAuF;AACvF,2BACE,SAAiB,EACjB,SAAiB,EACjB,OAAO,GAA6B,EAAE;IAEtC,MAAM,MAAM,GAAsB;QAChC,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,WAAW;QACnC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;QACzC,yBAAyB,EAAE,EAAE,KAAK,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC,EAAE;KAClE,CAAC;IACF,IAAI,OAAO,CAAC,UAAU;QAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,sBAA6B,SAAiB,EAAE,SAAiB;IAC/D,OAAO;QACL,SAAS,EAAE,SAAS;QACpB,sBAAsB,EAAE,sCAAsC;QAC9D,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACtD,yBAAyB,EAAE;YACzB,KAAK,EAAE,IAAA,uBAAgB,EAAC,SAAS,CAAC;YAClC,MAAM,EAAE,IAAA,2BAAoB,GAAE;SAC/B;QACD,gBAAgB,EAAE,IAAI;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { HistoryContext } from './setup';
2
+ /**
3
+ * Subtract a previously-added count from the session, leaving it consistent.
4
+ * Guarded so a concurrently-deleted SESSION row is never resurrected as a
5
+ * permanent, ttl-less junk row: if the row is already gone there is nothing
6
+ * to revert, so that specific condition failure is swallowed rather than
7
+ * surfaced — this runs only from an already-in-progress rollback, where a
8
+ * spurious error for a no-op would misrepresent what happened.
9
+ *
10
+ * Deliberately does not revert a `forceTtlRefresh`-driven ttl SET from an
11
+ * earlier committed chunk: the healed anchor is never shorter than what
12
+ * was there before, so leaving it in place after a rollback only means the
13
+ * session's metadata row outlives its content a bit longer than ideal —
14
+ * self-healing (the next successful append, or DynamoDB's own TTL sweep,
15
+ * resolves it), unlike reverting, which would need to re-check for a
16
+ * concurrent legitimate extension to avoid regressing it. See README.md's
17
+ * "TTL expiry" section.
18
+ */
19
+ export declare function revertSessionCount(context: HistoryContext, sessionId: string, delta: number): Promise<void>;
20
+ //# sourceMappingURL=session-count.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-count.d.ts","sourceRoot":"","sources":["../../../src/history/internal/session-count.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAe9C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAiBf"}