aws-classify-server 0.1.5 → 0.1.7

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.
@@ -16,6 +16,7 @@ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
16
16
  const client_apigatewaymanagementapi_1 = require("@aws-sdk/client-apigatewaymanagementapi");
17
17
  const ddbClient = new client_dynamodb_1.DynamoDBClient({ region: process.env.DD_REGION, endpoint: process.env.DD_ENDPOINT });
18
18
  const ddbDocClient = lib_dynamodb_1.DynamoDBDocument.from(ddbClient);
19
+ const updateDebounceInterval = 1000 * 60 * 10; // Don't update session unless 10 minutes have passed or data changed
19
20
  class ClassifyServerless {
20
21
  constructor() {
21
22
  this.logLevel = {};
@@ -82,13 +83,16 @@ class ClassifyServerless {
82
83
  // Instantiate the class
83
84
  const obj = new classDef.serverClass();
84
85
  // Retrieve session data from DynamoDB base on sessionId in request
86
+ let orignalSessionData = "";
85
87
  const result = yield getSessionData(sessionId, request.interfaceName);
86
88
  if (!result)
87
89
  sessionId = context.awsRequestId;
88
90
  else {
89
91
  const sessionData = result[`interface_${request.interfaceName}`];
90
- if (sessionData) // Enrich it with session data
91
- Object.assign(obj, (0, js_freeze_dry_1.deserialize)(sessionData, classes));
92
+ if (sessionData) { // Enrich it with session data
93
+ orignalSessionData = (0, js_freeze_dry_1.deserialize)(sessionData, classes);
94
+ Object.assign(obj, orignalSessionData);
95
+ }
92
96
  }
93
97
  obj.__sessionId__ = sessionId;
94
98
  obj.__connectionId__ = result === null || result === void 0 ? void 0 : result.connectionId;
@@ -109,7 +113,7 @@ class ClassifyServerless {
109
113
  return (0, js_freeze_dry_1.serialize)(lambdaResponse, classes);
110
114
  }
111
115
  const updatedSessionData = (0, js_freeze_dry_1.serialize)(obj, classes);
112
- if (!result || updatedSessionData !== result.sessionData)
116
+ if (!result || updatedSessionData !== orignalSessionData || (Date.now() > (result.updated + updateDebounceInterval)))
113
117
  sessionId = yield saveSessionData(sessionId, request.interfaceName, updatedSessionData, undefined, obj.__userId__, this.expirationMinutes);
114
118
  // Formulate response
115
119
  const lambdaResponse = {
@@ -242,7 +246,7 @@ class ClassifyServerless {
242
246
  this.log(`creating response for ${interfaceName} with sessionId=${sessionId} connectionId= ${obj.__connectionId__} sessionData=${sessionData}`);
243
247
  const ret = yield callback(obj);
244
248
  const updatedSessionData = (0, js_freeze_dry_1.serialize)(obj, classes);
245
- if (updatedSessionData !== result.sessionData || Math.floor(Date.now() / 1000 / 60) !== result.expires / 60) {
249
+ if (updatedSessionData !== sessionData || (Date.now() > (result.updated + updateDebounceInterval))) {
246
250
  if (this.logLevel.calls)
247
251
  this.log(`saving session data for ${interfaceName} with sessionId=${sessionId} connectionId= ${obj.__connectionId__} sessionData=${updatedSessionData}`);
248
252
  yield saveSessionData(sessionId, interfaceName, updatedSessionData, undefined, undefined, this.expirationMinutes);
@@ -338,7 +342,7 @@ function saveSessionData(sessionId, interfaceName, sessionData, connectionId, us
338
342
  const expires = new Date();
339
343
  expires.setMinutes(expires.getMinutes() + expirationMinutes);
340
344
  updateExpressionComponents.push('expires = :expires');
341
- expressionAttributeValues[':expires'] = expires.getTime() / 1000;
345
+ expressionAttributeValues[':expires'] = Math.floor(expires.getTime() / 1000);
342
346
  }
343
347
  if (sessionData && interfaceName) {
344
348
  updateExpressionComponents.push(`interface_${interfaceName} = :data`);
@@ -13,6 +13,7 @@ import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
13
13
  import { ApiGatewayManagementApiClient, PostToConnectionCommand } from "@aws-sdk/client-apigatewaymanagementapi";
14
14
  const ddbClient = new DynamoDBClient({ region: process.env.DD_REGION, endpoint: process.env.DD_ENDPOINT });
15
15
  const ddbDocClient = DynamoDBDocument.from(ddbClient);
16
+ const updateDebounceInterval = 1000 * 60 * 10; // Don't update session unless 10 minutes have passed or data changed
16
17
  export class ClassifyServerless {
17
18
  constructor() {
18
19
  this.logLevel = {};
@@ -79,13 +80,16 @@ export class ClassifyServerless {
79
80
  // Instantiate the class
80
81
  const obj = new classDef.serverClass();
81
82
  // Retrieve session data from DynamoDB base on sessionId in request
83
+ let orignalSessionData = "";
82
84
  const result = yield getSessionData(sessionId, request.interfaceName);
83
85
  if (!result)
84
86
  sessionId = context.awsRequestId;
85
87
  else {
86
88
  const sessionData = result[`interface_${request.interfaceName}`];
87
- if (sessionData) // Enrich it with session data
88
- Object.assign(obj, deserialize(sessionData, classes));
89
+ if (sessionData) { // Enrich it with session data
90
+ orignalSessionData = deserialize(sessionData, classes);
91
+ Object.assign(obj, orignalSessionData);
92
+ }
89
93
  }
90
94
  obj.__sessionId__ = sessionId;
91
95
  obj.__connectionId__ = result === null || result === void 0 ? void 0 : result.connectionId;
@@ -106,7 +110,7 @@ export class ClassifyServerless {
106
110
  return serialize(lambdaResponse, classes);
107
111
  }
108
112
  const updatedSessionData = serialize(obj, classes);
109
- if (!result || updatedSessionData !== result.sessionData)
113
+ if (!result || updatedSessionData !== orignalSessionData || (Date.now() > (result.updated + updateDebounceInterval)))
110
114
  sessionId = yield saveSessionData(sessionId, request.interfaceName, updatedSessionData, undefined, obj.__userId__, this.expirationMinutes);
111
115
  // Formulate response
112
116
  const lambdaResponse = {
@@ -239,7 +243,7 @@ export class ClassifyServerless {
239
243
  this.log(`creating response for ${interfaceName} with sessionId=${sessionId} connectionId= ${obj.__connectionId__} sessionData=${sessionData}`);
240
244
  const ret = yield callback(obj);
241
245
  const updatedSessionData = serialize(obj, classes);
242
- if (updatedSessionData !== result.sessionData || Math.floor(Date.now() / 1000 / 60) !== result.expires / 60) {
246
+ if (updatedSessionData !== sessionData || (Date.now() > (result.updated + updateDebounceInterval))) {
243
247
  if (this.logLevel.calls)
244
248
  this.log(`saving session data for ${interfaceName} with sessionId=${sessionId} connectionId= ${obj.__connectionId__} sessionData=${updatedSessionData}`);
245
249
  yield saveSessionData(sessionId, interfaceName, updatedSessionData, undefined, undefined, this.expirationMinutes);
@@ -333,7 +337,7 @@ export function saveSessionData(sessionId, interfaceName, sessionData, connectio
333
337
  const expires = new Date();
334
338
  expires.setMinutes(expires.getMinutes() + expirationMinutes);
335
339
  updateExpressionComponents.push('expires = :expires');
336
- expressionAttributeValues[':expires'] = expires.getTime() / 1000;
340
+ expressionAttributeValues[':expires'] = Math.floor(expires.getTime() / 1000);
337
341
  }
338
342
  if (sessionData && interfaceName) {
339
343
  updateExpressionComponents.push(`interface_${interfaceName} = :data`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-classify-server",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "main": "./lib/cjs/index.js",
5
5
  "module": "./lib/esm/index.js",
6
6
  "types": "./lib/esm/index.d.ts",
@@ -0,0 +1,24 @@
1
+ Resources:
2
+ AWSClassifySessionTable:
3
+ Type: AWS::DynamoDB::Table
4
+ Properties:
5
+ TableName: classifySessionStore.${self:custom.domainName}
6
+ BillingMode: PAY_PER_REQUEST
7
+ AttributeDefinitions:
8
+ - AttributeName: sessionId
9
+ AttributeType: S
10
+ - AttributeName: userId
11
+ AttributeType: S
12
+ KeySchema:
13
+ - AttributeName: sessionId
14
+ KeyType: HASH
15
+ TimeToLiveSpecification:
16
+ AttributeName: expires
17
+ Enabled: true
18
+ GlobalSecondaryIndexes:
19
+ - IndexName: userId
20
+ KeySchema:
21
+ - AttributeName: userId
22
+ KeyType: HASH
23
+ Projection:
24
+ ProjectionType: KEYS_ONLY
@@ -23,4 +23,4 @@ Resources:
23
23
  Projection:
24
24
  ProjectionType: KEYS_ONLY
25
25
  StreamSpecification:
26
- StreamViewType: ${self:custom.SessionStreamViewType, 'NEW_IMAGE'}
26
+ StreamViewType: ${self:custom.SessionStreamViewType, 'NEW_AND_OLD_IMAGES'}