s3db.js 11.2.0 → 11.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/dist/s3db-cli.js +55029 -0
- package/dist/s3db.cjs.js +52 -5
- package/dist/s3db.cjs.js.map +1 -1
- package/dist/s3db.es.js +52 -5
- package/dist/s3db.es.js.map +1 -1
- package/package.json +1 -4
- package/src/plugins/eventual-consistency/config.js +4 -1
- package/src/plugins/eventual-consistency/consolidation.js +38 -4
- package/src/plugins/eventual-consistency/install.js +22 -0
package/dist/s3db.cjs.js
CHANGED
|
@@ -5105,8 +5105,10 @@ function createConfig(options, detectedTimezone) {
|
|
|
5105
5105
|
consolidationWindow: consolidation.window ?? 24,
|
|
5106
5106
|
autoConsolidate: consolidation.auto !== false,
|
|
5107
5107
|
mode: consolidation.mode || "async",
|
|
5108
|
-
// ✅
|
|
5108
|
+
// ✅ Performance tuning - Mark applied concurrency (default 50, up from 10)
|
|
5109
5109
|
markAppliedConcurrency: consolidation.markAppliedConcurrency ?? 50,
|
|
5110
|
+
// ✅ Performance tuning - Recalculate concurrency (default 50, up from 10)
|
|
5111
|
+
recalculateConcurrency: consolidation.recalculateConcurrency ?? 50,
|
|
5110
5112
|
// Late arrivals
|
|
5111
5113
|
lateArrivalStrategy: lateArrivals.strategy || "warn",
|
|
5112
5114
|
// Batch transactions
|
|
@@ -5935,11 +5937,33 @@ async function consolidateRecord(originalId, transactionResource, targetResource
|
|
|
5935
5937
|
const transactionsToUpdate = transactions.filter((txn) => txn.id !== "__synthetic__");
|
|
5936
5938
|
const markAppliedConcurrency = config.markAppliedConcurrency || 50;
|
|
5937
5939
|
const { results, errors } = await promisePool.PromisePool.for(transactionsToUpdate).withConcurrency(markAppliedConcurrency).process(async (txn) => {
|
|
5940
|
+
const txnWithCohorts = ensureCohortHour(txn, config.cohort.timezone, false);
|
|
5941
|
+
const updateData = { applied: true };
|
|
5942
|
+
if (txnWithCohorts.cohortHour && !txn.cohortHour) {
|
|
5943
|
+
updateData.cohortHour = txnWithCohorts.cohortHour;
|
|
5944
|
+
}
|
|
5945
|
+
if (txnWithCohorts.cohortDate && !txn.cohortDate) {
|
|
5946
|
+
updateData.cohortDate = txnWithCohorts.cohortDate;
|
|
5947
|
+
}
|
|
5948
|
+
if (txnWithCohorts.cohortWeek && !txn.cohortWeek) {
|
|
5949
|
+
updateData.cohortWeek = txnWithCohorts.cohortWeek;
|
|
5950
|
+
}
|
|
5951
|
+
if (txnWithCohorts.cohortMonth && !txn.cohortMonth) {
|
|
5952
|
+
updateData.cohortMonth = txnWithCohorts.cohortMonth;
|
|
5953
|
+
}
|
|
5954
|
+
if (txn.value === null || txn.value === void 0) {
|
|
5955
|
+
updateData.value = 1;
|
|
5956
|
+
}
|
|
5938
5957
|
const [ok2, err2] = await tryFn(
|
|
5939
|
-
() => transactionResource.update(txn.id,
|
|
5958
|
+
() => transactionResource.update(txn.id, updateData)
|
|
5940
5959
|
);
|
|
5941
5960
|
if (!ok2 && config.verbose) {
|
|
5942
|
-
console.warn(
|
|
5961
|
+
console.warn(
|
|
5962
|
+
`[EventualConsistency] Failed to mark transaction ${txn.id} as applied:`,
|
|
5963
|
+
err2?.message,
|
|
5964
|
+
"Update data:",
|
|
5965
|
+
updateData
|
|
5966
|
+
);
|
|
5943
5967
|
}
|
|
5944
5968
|
return ok2;
|
|
5945
5969
|
});
|
|
@@ -6131,7 +6155,8 @@ async function recalculateRecord(originalId, transactionResource, targetResource
|
|
|
6131
6155
|
}
|
|
6132
6156
|
}
|
|
6133
6157
|
const transactionsToReset = allTransactions.filter((txn) => txn.source !== "anchor");
|
|
6134
|
-
const
|
|
6158
|
+
const recalculateConcurrency = config.recalculateConcurrency || 50;
|
|
6159
|
+
const { results, errors } = await promisePool.PromisePool.for(transactionsToReset).withConcurrency(recalculateConcurrency).process(async (txn) => {
|
|
6135
6160
|
const [ok, err] = await tryFn(
|
|
6136
6161
|
() => transactionResource.update(txn.id, { applied: false })
|
|
6137
6162
|
);
|
|
@@ -7222,6 +7247,28 @@ async function createAnalyticsResource(handler, database, resourceName, fieldNam
|
|
|
7222
7247
|
},
|
|
7223
7248
|
behavior: "body-overflow",
|
|
7224
7249
|
timestamps: false,
|
|
7250
|
+
asyncPartitions: true,
|
|
7251
|
+
// ✅ Multi-attribute partitions for optimal analytics query performance
|
|
7252
|
+
partitions: {
|
|
7253
|
+
// Query by period (hour/day/week/month)
|
|
7254
|
+
byPeriod: {
|
|
7255
|
+
fields: { period: "string" }
|
|
7256
|
+
},
|
|
7257
|
+
// Query by period + cohort (e.g., all hour records for specific hours)
|
|
7258
|
+
byPeriodCohort: {
|
|
7259
|
+
fields: {
|
|
7260
|
+
period: "string",
|
|
7261
|
+
cohort: "string"
|
|
7262
|
+
}
|
|
7263
|
+
},
|
|
7264
|
+
// Query by field + period (e.g., all daily analytics for clicks field)
|
|
7265
|
+
byFieldPeriod: {
|
|
7266
|
+
fields: {
|
|
7267
|
+
field: "string",
|
|
7268
|
+
period: "string"
|
|
7269
|
+
}
|
|
7270
|
+
}
|
|
7271
|
+
},
|
|
7225
7272
|
createdBy: "EventualConsistencyPlugin"
|
|
7226
7273
|
})
|
|
7227
7274
|
);
|
|
@@ -13751,7 +13798,7 @@ class Database extends EventEmitter {
|
|
|
13751
13798
|
this.id = idGenerator(7);
|
|
13752
13799
|
this.version = "1";
|
|
13753
13800
|
this.s3dbVersion = (() => {
|
|
13754
|
-
const [ok, err, version] = tryFn(() => true ? "11.2.
|
|
13801
|
+
const [ok, err, version] = tryFn(() => true ? "11.2.2" : "latest");
|
|
13755
13802
|
return ok ? version : "latest";
|
|
13756
13803
|
})();
|
|
13757
13804
|
this.resources = {};
|