dynamodb-reactive 0.2.1 → 0.2.2
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 +60 -1
- package/dist/infra.cjs +16 -5
- package/dist/infra.cjs.map +1 -1
- package/dist/infra.d.cts +8 -1
- package/dist/infra.d.ts +8 -1
- package/dist/infra.js +16 -5
- package/dist/infra.js.map +1 -1
- package/dist/server.cjs +66 -35
- package/dist/server.cjs.map +1 -1
- package/dist/server.js +66 -35
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -2068,7 +2068,7 @@ async function mapWithConcurrency(values, concurrency, mapper) {
|
|
|
2068
2068
|
await Promise.all(workers);
|
|
2069
2069
|
return results;
|
|
2070
2070
|
}
|
|
2071
|
-
|
|
2071
|
+
function extractRecordAffectedKeys(record) {
|
|
2072
2072
|
const tableName = extractTableName(record);
|
|
2073
2073
|
if (!tableName || !record.dynamodb) {
|
|
2074
2074
|
throw new Error("Malformed DynamoDB stream record");
|
|
@@ -2079,53 +2079,84 @@ async function processRecord(record, utils) {
|
|
|
2079
2079
|
const item = unmarshall(image);
|
|
2080
2080
|
for (const key of extractAffectedKeys(tableName, item)) affectedKeys.add(key);
|
|
2081
2081
|
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2082
|
+
return affectedKeys;
|
|
2083
|
+
}
|
|
2084
|
+
function subscriptionKey(subscription) {
|
|
2085
|
+
return JSON.stringify([
|
|
2086
|
+
subscription.connectionId,
|
|
2087
|
+
subscription.subscriptionId
|
|
2088
|
+
]);
|
|
2089
|
+
}
|
|
2090
|
+
function failureIdentifier(record, cause) {
|
|
2091
|
+
const itemIdentifier = record.dynamodb?.SequenceNumber;
|
|
2092
|
+
if (!itemIdentifier) {
|
|
2093
|
+
throw new Error("Failed DynamoDB stream record has no sequence number", {
|
|
2094
|
+
cause
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
return itemIdentifier;
|
|
2098
|
+
}
|
|
2099
|
+
async function processStreamEvent(event, utils) {
|
|
2100
|
+
const failures = /* @__PURE__ */ new Map();
|
|
2101
|
+
const dependencies = /* @__PURE__ */ new Map();
|
|
2102
|
+
for (const [recordIndex, record] of event.Records.entries()) {
|
|
2103
|
+
try {
|
|
2104
|
+
for (const dependencyKey of extractRecordAffectedKeys(record)) {
|
|
2105
|
+
const recordIndexes = dependencies.get(dependencyKey) ?? /* @__PURE__ */ new Set();
|
|
2106
|
+
recordIndexes.add(recordIndex);
|
|
2107
|
+
dependencies.set(dependencyKey, recordIndexes);
|
|
2108
|
+
}
|
|
2109
|
+
} catch (error2) {
|
|
2110
|
+
error("[stream] Record dependency extraction failed:", error2);
|
|
2111
|
+
failures.set(recordIndex, error2);
|
|
2094
2112
|
}
|
|
2095
2113
|
}
|
|
2114
|
+
const subscriptions = /* @__PURE__ */ new Map();
|
|
2096
2115
|
await mapWithConcurrency(
|
|
2097
|
-
[...
|
|
2116
|
+
[...dependencies],
|
|
2098
2117
|
MAX_FANOUT_CONCURRENCY,
|
|
2099
|
-
(
|
|
2118
|
+
async ([dependencyKey, recordIndexes]) => {
|
|
2119
|
+
try {
|
|
2120
|
+
const affectedSubscriptions = await utils.findAffectedSubscriptions(dependencyKey);
|
|
2121
|
+
for (const subscription of affectedSubscriptions) {
|
|
2122
|
+
const key = subscriptionKey(subscription);
|
|
2123
|
+
const work = subscriptions.get(key) ?? {
|
|
2124
|
+
...subscription,
|
|
2125
|
+
recordIndexes: /* @__PURE__ */ new Set()
|
|
2126
|
+
};
|
|
2127
|
+
for (const recordIndex of recordIndexes) {
|
|
2128
|
+
work.recordIndexes.add(recordIndex);
|
|
2129
|
+
}
|
|
2130
|
+
subscriptions.set(key, work);
|
|
2131
|
+
}
|
|
2132
|
+
} catch (error2) {
|
|
2133
|
+
error("[stream] Subscription dependency lookup failed:", error2);
|
|
2134
|
+
for (const recordIndex of recordIndexes) {
|
|
2135
|
+
failures.set(recordIndex, error2);
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2100
2139
|
);
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
const results = await mapWithConcurrency(
|
|
2104
|
-
event.Records,
|
|
2140
|
+
await mapWithConcurrency(
|
|
2141
|
+
[...subscriptions.values()],
|
|
2105
2142
|
MAX_FANOUT_CONCURRENCY,
|
|
2106
|
-
async (
|
|
2143
|
+
async ({ connectionId, subscriptionId, recordIndexes }) => {
|
|
2107
2144
|
try {
|
|
2108
|
-
await
|
|
2109
|
-
return null;
|
|
2145
|
+
await utils.processSubscription(connectionId, subscriptionId);
|
|
2110
2146
|
} catch (error2) {
|
|
2111
|
-
error("[stream]
|
|
2112
|
-
const
|
|
2113
|
-
|
|
2114
|
-
throw new Error(
|
|
2115
|
-
"Failed DynamoDB stream record has no sequence number",
|
|
2116
|
-
{ cause: error2 }
|
|
2117
|
-
);
|
|
2147
|
+
error("[stream] Subscription refresh failed:", error2);
|
|
2148
|
+
for (const recordIndex of recordIndexes) {
|
|
2149
|
+
failures.set(recordIndex, error2);
|
|
2118
2150
|
}
|
|
2119
|
-
return {
|
|
2120
|
-
itemIdentifier
|
|
2121
|
-
};
|
|
2122
2151
|
}
|
|
2123
2152
|
}
|
|
2124
2153
|
);
|
|
2125
2154
|
return {
|
|
2126
|
-
batchItemFailures:
|
|
2127
|
-
(
|
|
2128
|
-
|
|
2155
|
+
batchItemFailures: event.Records.flatMap((record, recordIndex) => {
|
|
2156
|
+
if (!failures.has(recordIndex)) return [];
|
|
2157
|
+
const cause = failures.get(recordIndex);
|
|
2158
|
+
return [{ itemIdentifier: failureIdentifier(record, cause) }];
|
|
2159
|
+
})
|
|
2129
2160
|
};
|
|
2130
2161
|
}
|
|
2131
2162
|
function clients(config) {
|