dynamodb-reactive 0.1.1 → 0.1.4
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/README.md +114 -24
- package/dist/{chunk-KRZQWA2W.js → chunk-MI2ZLLB2.js} +363 -51
- package/dist/chunk-MI2ZLLB2.js.map +1 -0
- package/dist/client.d.ts +12 -2
- package/dist/client.js +1 -1
- package/dist/core.d.ts +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/infra.d.ts +1 -1
- package/dist/infra.js +1 -1
- package/dist/infra.js.map +1 -1
- package/dist/{react-BMZQ8Mth.d.ts → react-B8Q_XoCk.d.ts} +183 -16
- package/dist/react.d.ts +1 -1
- package/dist/react.js +1 -1
- package/dist/server.d.ts +43 -15
- package/dist/server.js +106 -12
- package/dist/server.js.map +1 -1
- package/dist/{table-CSJysZPQ.d.ts → table-CfIWxbuJ.d.ts} +1 -1
- package/dist/{types-Ci7IieDA.d.ts → types-DeshTSf5.d.ts} +1 -1
- package/package.json +4 -2
- package/dist/chunk-KRZQWA2W.js.map +0 -1
package/dist/server.js
CHANGED
|
@@ -2,7 +2,7 @@ import { SystemTableNames } from './chunk-HZ6JHAJJ.js';
|
|
|
2
2
|
import { DynamoDBClient, ExecuteStatementCommand } from '@aws-sdk/client-dynamodb';
|
|
3
3
|
import { UpdateCommand, DeleteCommand, PutCommand, GetCommand, DynamoDBDocumentClient, QueryCommand } from '@aws-sdk/lib-dynamodb';
|
|
4
4
|
import { unmarshall } from '@aws-sdk/util-dynamodb';
|
|
5
|
-
import
|
|
5
|
+
import jsonpatch from 'fast-json-patch';
|
|
6
6
|
import { ApiGatewayManagementApiClient, PostToConnectionCommand, GoneException } from '@aws-sdk/client-apigatewaymanagementapi';
|
|
7
7
|
|
|
8
8
|
// ../server/src/procedure.ts
|
|
@@ -683,6 +683,7 @@ var DependencyTracker = class {
|
|
|
683
683
|
this.operations = [];
|
|
684
684
|
}
|
|
685
685
|
};
|
|
686
|
+
var { applyPatch, compare } = jsonpatch;
|
|
686
687
|
function generatePatches(oldValue, newValue) {
|
|
687
688
|
const operations = compare(
|
|
688
689
|
oldValue,
|
|
@@ -741,31 +742,35 @@ function batchPatches(patchSets) {
|
|
|
741
742
|
}
|
|
742
743
|
function createReactiveHandler(config) {
|
|
743
744
|
const ttlSeconds = config.ttlSeconds ?? 3600;
|
|
744
|
-
const
|
|
745
|
-
const
|
|
746
|
-
const
|
|
745
|
+
const prefix = config.tablePrefix ? `${config.tablePrefix}-` : "";
|
|
746
|
+
const connectionsTable = `${prefix}${SystemTableNames.connections}`;
|
|
747
|
+
const dependenciesTable = `${prefix}${SystemTableNames.dependencies}`;
|
|
748
|
+
const queriesTable = `${prefix}${SystemTableNames.queries}`;
|
|
747
749
|
const ddbClient = new DynamoDBClient({
|
|
748
750
|
region: config.dbConfig?.region ?? process.env.AWS_REGION
|
|
749
751
|
});
|
|
750
|
-
const docClient = DynamoDBDocumentClient.from(ddbClient
|
|
751
|
-
|
|
752
|
+
const docClient = DynamoDBDocumentClient.from(ddbClient, {
|
|
753
|
+
marshallOptions: { removeUndefinedValues: true }
|
|
754
|
+
});
|
|
755
|
+
async function handleRequest(request, headers) {
|
|
752
756
|
try {
|
|
753
|
-
const
|
|
757
|
+
const connectionId = request.connectionId;
|
|
758
|
+
const ctx = await config.getContext({ connectionId, headers });
|
|
754
759
|
const dependencyTracker = new DependencyTracker();
|
|
755
760
|
const db = createDbContext(config.dbConfig ?? {}, dependencyTracker);
|
|
756
761
|
const fullCtx = { ...ctx, db };
|
|
757
762
|
switch (request.type) {
|
|
758
763
|
case "subscribe":
|
|
759
|
-
return handleSubscribe(
|
|
764
|
+
return await handleSubscribe(
|
|
760
765
|
connectionId,
|
|
761
766
|
request,
|
|
762
767
|
fullCtx,
|
|
763
768
|
dependencyTracker
|
|
764
769
|
);
|
|
765
770
|
case "unsubscribe":
|
|
766
|
-
return handleUnsubscribe(connectionId, request);
|
|
771
|
+
return await handleUnsubscribe(connectionId, request);
|
|
767
772
|
case "call":
|
|
768
|
-
return handleCall(request, fullCtx);
|
|
773
|
+
return await handleCall(request, fullCtx);
|
|
769
774
|
default:
|
|
770
775
|
return {
|
|
771
776
|
type: "error",
|
|
@@ -776,6 +781,7 @@ function createReactiveHandler(config) {
|
|
|
776
781
|
return {
|
|
777
782
|
type: "error",
|
|
778
783
|
message: error instanceof Error ? error.message : "Unknown error",
|
|
784
|
+
code: error.code,
|
|
779
785
|
subscriptionId: "subscriptionId" in request ? request.subscriptionId : void 0
|
|
780
786
|
};
|
|
781
787
|
}
|
|
@@ -910,13 +916,38 @@ function createReactiveHandler(config) {
|
|
|
910
916
|
);
|
|
911
917
|
console.log("Connection unregistered:", connectionId);
|
|
912
918
|
}
|
|
919
|
+
async function query(path, input, headers) {
|
|
920
|
+
const ctx = await config.getContext({ connectionId: "query", headers });
|
|
921
|
+
const dependencyTracker = new DependencyTracker();
|
|
922
|
+
const db = createDbContext(config.dbConfig ?? {}, dependencyTracker);
|
|
923
|
+
const fullCtx = { ...ctx, db };
|
|
924
|
+
return config.router.execute(path, fullCtx, input);
|
|
925
|
+
}
|
|
926
|
+
function createCaller() {
|
|
927
|
+
function buildProxy(path = []) {
|
|
928
|
+
return new Proxy(() => {
|
|
929
|
+
}, {
|
|
930
|
+
get(_target, prop) {
|
|
931
|
+
return buildProxy([...path, prop]);
|
|
932
|
+
},
|
|
933
|
+
apply(_target, _thisArg, args) {
|
|
934
|
+
const procedurePath = path.join(".");
|
|
935
|
+
return query(procedurePath, args[0]);
|
|
936
|
+
}
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
return buildProxy();
|
|
940
|
+
}
|
|
913
941
|
return {
|
|
914
942
|
handleRequest,
|
|
915
943
|
registerConnection,
|
|
916
|
-
unregisterConnection
|
|
944
|
+
unregisterConnection,
|
|
945
|
+
query,
|
|
946
|
+
createCaller
|
|
917
947
|
};
|
|
918
948
|
}
|
|
919
949
|
function createStreamHandler(config) {
|
|
950
|
+
const connectionsTable = config.connectionsTableName ?? SystemTableNames.connections;
|
|
920
951
|
const dependenciesTable = config.dependenciesTableName ?? SystemTableNames.dependencies;
|
|
921
952
|
const queriesTable = config.queriesTableName ?? SystemTableNames.queries;
|
|
922
953
|
const ddbClient = new DynamoDBClient({
|
|
@@ -1083,6 +1114,7 @@ function createStreamHandler(config) {
|
|
|
1083
1114
|
return `"${field}" <= ${escapedValue}`;
|
|
1084
1115
|
case "between":
|
|
1085
1116
|
return `"${field}" BETWEEN ${escapedValue} AND ${escapeValue(value2)}`;
|
|
1117
|
+
case void 0:
|
|
1086
1118
|
default:
|
|
1087
1119
|
return "";
|
|
1088
1120
|
}
|
|
@@ -1094,6 +1126,7 @@ function createStreamHandler(config) {
|
|
|
1094
1126
|
return `begins_with("${field}", ${escapedValue})`;
|
|
1095
1127
|
case "contains":
|
|
1096
1128
|
return `contains("${field}", ${escapedValue})`;
|
|
1129
|
+
case void 0:
|
|
1097
1130
|
default:
|
|
1098
1131
|
return "";
|
|
1099
1132
|
}
|
|
@@ -1108,6 +1141,7 @@ function createStreamHandler(config) {
|
|
|
1108
1141
|
return `(${subclauses.join(" OR ")})`;
|
|
1109
1142
|
case "not":
|
|
1110
1143
|
return subclauses.length > 0 ? `NOT (${subclauses[0]})` : "";
|
|
1144
|
+
case void 0:
|
|
1111
1145
|
default:
|
|
1112
1146
|
return "";
|
|
1113
1147
|
}
|
|
@@ -1168,6 +1202,54 @@ function createStreamHandler(config) {
|
|
|
1168
1202
|
}
|
|
1169
1203
|
async function cleanupConnection(connectionId) {
|
|
1170
1204
|
console.log("Cleaning up disconnected connection:", connectionId);
|
|
1205
|
+
try {
|
|
1206
|
+
const queriesResponse = await docClient.send(
|
|
1207
|
+
new QueryCommand({
|
|
1208
|
+
TableName: queriesTable,
|
|
1209
|
+
KeyConditionExpression: "pk = :pk",
|
|
1210
|
+
ExpressionAttributeValues: {
|
|
1211
|
+
":pk": connectionId
|
|
1212
|
+
}
|
|
1213
|
+
})
|
|
1214
|
+
);
|
|
1215
|
+
const subscriptions = queriesResponse.Items ?? [];
|
|
1216
|
+
for (const sub of subscriptions) {
|
|
1217
|
+
const deps = sub.dependencies ?? [];
|
|
1218
|
+
for (const depKey of deps) {
|
|
1219
|
+
await docClient.send(
|
|
1220
|
+
new DeleteCommand({
|
|
1221
|
+
TableName: dependenciesTable,
|
|
1222
|
+
Key: {
|
|
1223
|
+
pk: depKey,
|
|
1224
|
+
sk: `${connectionId}#${sub.sk}`
|
|
1225
|
+
}
|
|
1226
|
+
})
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
await docClient.send(
|
|
1230
|
+
new DeleteCommand({
|
|
1231
|
+
TableName: queriesTable,
|
|
1232
|
+
Key: {
|
|
1233
|
+
pk: connectionId,
|
|
1234
|
+
sk: sub.sk
|
|
1235
|
+
}
|
|
1236
|
+
})
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
await docClient.send(
|
|
1240
|
+
new DeleteCommand({
|
|
1241
|
+
TableName: connectionsTable,
|
|
1242
|
+
Key: {
|
|
1243
|
+
connectionId
|
|
1244
|
+
}
|
|
1245
|
+
})
|
|
1246
|
+
);
|
|
1247
|
+
console.log(
|
|
1248
|
+
`Cleaned up connection ${connectionId}: ${subscriptions.length} subscriptions removed`
|
|
1249
|
+
);
|
|
1250
|
+
} catch (error) {
|
|
1251
|
+
console.error("Error cleaning up connection:", error);
|
|
1252
|
+
}
|
|
1171
1253
|
}
|
|
1172
1254
|
return { handler };
|
|
1173
1255
|
}
|
|
@@ -1287,6 +1369,13 @@ function createLambdaHandlers() {
|
|
|
1287
1369
|
const { type, subscriptionId } = body;
|
|
1288
1370
|
let response;
|
|
1289
1371
|
switch (type) {
|
|
1372
|
+
case "init": {
|
|
1373
|
+
response = {
|
|
1374
|
+
type: "connected",
|
|
1375
|
+
connectionId
|
|
1376
|
+
};
|
|
1377
|
+
break;
|
|
1378
|
+
}
|
|
1290
1379
|
case "unsubscribe": {
|
|
1291
1380
|
const subResponse = await docClient.send(
|
|
1292
1381
|
new GetCommand({
|
|
@@ -1416,7 +1505,9 @@ function createLambdaHandlers() {
|
|
|
1416
1505
|
);
|
|
1417
1506
|
return;
|
|
1418
1507
|
}
|
|
1419
|
-
const newResult = await executeQueryFromMetadata(
|
|
1508
|
+
const newResult = await executeQueryFromMetadata(
|
|
1509
|
+
queryState.queryMetadata
|
|
1510
|
+
);
|
|
1420
1511
|
if (!hasChanges(queryState.lastResult, newResult)) {
|
|
1421
1512
|
return;
|
|
1422
1513
|
}
|
|
@@ -1490,6 +1581,7 @@ function createLambdaHandlers() {
|
|
|
1490
1581
|
return `"${field}" <= ${escapedValue}`;
|
|
1491
1582
|
case "between":
|
|
1492
1583
|
return `"${field}" BETWEEN ${escapedValue} AND ${escapeValue(value2)}`;
|
|
1584
|
+
case void 0:
|
|
1493
1585
|
default:
|
|
1494
1586
|
return "";
|
|
1495
1587
|
}
|
|
@@ -1501,6 +1593,7 @@ function createLambdaHandlers() {
|
|
|
1501
1593
|
return `begins_with("${field}", ${escapedValue})`;
|
|
1502
1594
|
case "contains":
|
|
1503
1595
|
return `contains("${field}", ${escapedValue})`;
|
|
1596
|
+
case void 0:
|
|
1504
1597
|
default:
|
|
1505
1598
|
return "";
|
|
1506
1599
|
}
|
|
@@ -1515,6 +1608,7 @@ function createLambdaHandlers() {
|
|
|
1515
1608
|
return `(${subclauses.join(" OR ")})`;
|
|
1516
1609
|
case "not":
|
|
1517
1610
|
return subclauses.length > 0 ? `NOT (${subclauses[0]})` : "";
|
|
1611
|
+
case void 0:
|
|
1518
1612
|
default:
|
|
1519
1613
|
return "";
|
|
1520
1614
|
}
|