@forestadmin/datasource-replica 1.0.0 → 1.0.2-alpha-widgets.1
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/cache-interface/collection.d.ts +54 -0
- package/dist/cache-interface/collection.js +89 -0
- package/dist/cache-interface/datasource.d.ts +14 -0
- package/dist/cache-interface/datasource.js +33 -0
- package/dist/decorators/schema/collection.d.ts +8 -0
- package/dist/decorators/schema/collection.js +35 -0
- package/dist/decorators/schema/data-source.d.ts +9 -0
- package/dist/decorators/schema/data-source.js +18 -0
- package/dist/decorators/sync/collection.d.ts +15 -0
- package/dist/decorators/sync/collection.js +107 -0
- package/dist/decorators/sync/data-source.d.ts +9 -0
- package/dist/decorators/sync/data-source.js +15 -0
- package/dist/decorators/write/collection.d.ts +11 -0
- package/dist/decorators/write/collection.js +54 -0
- package/dist/decorators/write/data-source.d.ts +8 -0
- package/dist/decorators/write/data-source.js +23 -0
- package/dist/flattener.d.ts +3 -0
- package/dist/flattener.js +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/options/flattener/options.d.ts +5 -0
- package/dist/options/flattener/options.js +103 -0
- package/dist/options/flattener/schema.d.ts +8 -0
- package/dist/options/flattener/schema.js +39 -0
- package/dist/options/index.d.ts +5 -0
- package/dist/options/index.js +37 -0
- package/dist/options/schema/analyzer.d.ts +11 -0
- package/dist/options/schema/analyzer.js +53 -0
- package/dist/options/schema/index.d.ts +6 -0
- package/dist/options/schema/index.js +43 -0
- package/dist/options/utils.d.ts +3 -0
- package/dist/options/utils.js +8 -0
- package/dist/sequelize.d.ts +6 -0
- package/dist/sequelize.js +122 -0
- package/dist/synchronization/analysis-passthrough.d.ts +20 -0
- package/dist/synchronization/analysis-passthrough.js +79 -0
- package/dist/synchronization/cache-target.d.ts +15 -0
- package/dist/synchronization/cache-target.js +85 -0
- package/dist/synchronization/customer-source.d.ts +31 -0
- package/dist/synchronization/customer-source.js +188 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.js +11 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +35 -0
- package/package.json +7 -7
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const sequelize_1 = require("sequelize");
|
|
7
|
+
const flattener_1 = __importDefault(require("../flattener"));
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
class CacheTarget {
|
|
10
|
+
constructor(connection, options, logger) {
|
|
11
|
+
this.connection = connection;
|
|
12
|
+
this.options = options;
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
}
|
|
15
|
+
async applyDump(changes, firstPage) {
|
|
16
|
+
if (firstPage) {
|
|
17
|
+
// Truncate tables
|
|
18
|
+
for (const collection of this.options.flattenSchema) {
|
|
19
|
+
await this.connection.model(collection.name).truncate();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const recordsByCollection = {};
|
|
23
|
+
const entries = changes.entries.flatMap(entry => this.flattenRecord(entry));
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
if (entry !== undefined) {
|
|
26
|
+
if (!recordsByCollection[entry.collection])
|
|
27
|
+
recordsByCollection[entry.collection] = [];
|
|
28
|
+
recordsByCollection[entry.collection].push(entry.record);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
await this.connection.transaction(async (transaction) => {
|
|
32
|
+
for (const [collection, records] of Object.entries(recordsByCollection)) {
|
|
33
|
+
await this.connection.model(collection).bulkCreate(records, { transaction });
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async applyDelta(changes) {
|
|
38
|
+
await this.connection.transaction(async (transaction) => {
|
|
39
|
+
for (const entry of changes.deletedEntries) {
|
|
40
|
+
if (this.checkCollection(entry.collection)) {
|
|
41
|
+
await this.destroySubModels(entry, transaction);
|
|
42
|
+
await this.connection
|
|
43
|
+
.model(entry.collection)
|
|
44
|
+
.destroy({ where: entry.record, transaction });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Upsert records in both root and virtual collections
|
|
48
|
+
for (const entry of changes.newOrUpdatedEntries) {
|
|
49
|
+
if (this.checkCollection(entry.collection)) {
|
|
50
|
+
await this.destroySubModels(entry, transaction);
|
|
51
|
+
for (const subEntry of this.flattenRecord(entry))
|
|
52
|
+
await this.connection
|
|
53
|
+
.model(subEntry.collection)
|
|
54
|
+
.upsert(subEntry.record, { transaction });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
flattenRecord(recordWithCollection) {
|
|
60
|
+
if (this.checkCollection(recordWithCollection.collection))
|
|
61
|
+
return (0, flattener_1.default)(recordWithCollection, this.options.schema.find(s => s.name === recordWithCollection.collection).fields, this.options?.flattenOptions?.[recordWithCollection.collection]?.asFields ?? [], this.options?.flattenOptions?.[recordWithCollection.collection]?.asModels ?? []);
|
|
62
|
+
}
|
|
63
|
+
async destroySubModels(entry, transaction) {
|
|
64
|
+
const { asModels } = this.options.flattenOptions[entry.collection];
|
|
65
|
+
const { fields } = this.options.schema.find(c => c.name === entry.collection);
|
|
66
|
+
const promises = asModels.map(asModel => {
|
|
67
|
+
const recordId = (0, utils_1.getRecordId)(fields, entry.record);
|
|
68
|
+
return this.connection.model((0, utils_1.escape) `${entry.collection}.${asModel}`).destroy({
|
|
69
|
+
where: { _fid: { [sequelize_1.Op.startsWith]: `${recordId}.${asModel}` } },
|
|
70
|
+
transaction,
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
await Promise.all(promises);
|
|
74
|
+
}
|
|
75
|
+
checkCollection(collection) {
|
|
76
|
+
const collectionName = this.options.schema.find(s => s.name === collection);
|
|
77
|
+
if (!collectionName) {
|
|
78
|
+
this.logger('Error', `Collection '${collection}' not found in schema. Skipping.`);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.default = CacheTarget;
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtdGFyZ2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXphdGlvbi9jYWNoZS10YXJnZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFXQSx5Q0FBNEM7QUFFNUMsNkRBQXlDO0FBQ3pDLG9DQUErQztBQUUvQyxNQUFxQixXQUFXO0lBSzlCLFlBQVksVUFBcUIsRUFBRSxPQUF3QixFQUFFLE1BQWM7UUFDekUsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBeUIsRUFBRSxTQUFrQjtRQUMzRCxJQUFJLFNBQVMsRUFBRTtZQUNiLGtCQUFrQjtZQUNsQixLQUFLLE1BQU0sVUFBVSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFO2dCQUNuRCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQzthQUN6RDtTQUNGO1FBRUQsTUFBTSxtQkFBbUIsR0FBRyxFQUFrQyxDQUFDO1FBQy9ELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRTVFLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFO1lBQzNCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtnQkFDdkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7b0JBQUUsbUJBQW1CLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDdkYsbUJBQW1C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
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type CacheDataSourceInterface from '../cache-interface/datasource';
|
|
2
|
+
import type { PullDeltaReason, PullDumpReason, ReplicaDataSourceOptions, SynchronizationSource, SynchronizationTarget } from '../types';
|
|
3
|
+
import type { Logger } from '@forestadmin/datasource-toolkit';
|
|
4
|
+
import type { Sequelize } from 'sequelize';
|
|
5
|
+
export default class CustomerSource implements SynchronizationSource {
|
|
6
|
+
requestCache: CacheDataSourceInterface;
|
|
7
|
+
private readonly logger;
|
|
8
|
+
private options;
|
|
9
|
+
private connection;
|
|
10
|
+
private isRunning;
|
|
11
|
+
private queuedPullDumpReasons;
|
|
12
|
+
private queuedPullDeltaReasons;
|
|
13
|
+
private queuedPushDeltaRequest;
|
|
14
|
+
private schedules;
|
|
15
|
+
private target;
|
|
16
|
+
constructor(connection: Sequelize, options: ReplicaDataSourceOptions, logger: Logger);
|
|
17
|
+
start(target: SynchronizationTarget): Promise<void>;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
private queuePushDelta;
|
|
20
|
+
queuePullDump(reason: PullDumpReason): Promise<void>;
|
|
21
|
+
queuePullDelta(reason: PullDeltaReason): Promise<void>;
|
|
22
|
+
private tick;
|
|
23
|
+
private runPushDelta;
|
|
24
|
+
private runPullDump;
|
|
25
|
+
private runPullDelta;
|
|
26
|
+
private getStartupState;
|
|
27
|
+
private setStartupState;
|
|
28
|
+
private getDeltaState;
|
|
29
|
+
private setDeltaState;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=customer-source.d.ts.map
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const datasource_toolkit_1 = require("@forestadmin/datasource-toolkit");
|
|
4
|
+
const croner_1 = require("croner");
|
|
5
|
+
class CustomerSource {
|
|
6
|
+
constructor(connection, options, logger) {
|
|
7
|
+
this.requestCache = null;
|
|
8
|
+
this.isRunning = false;
|
|
9
|
+
this.queuedPullDumpReasons = null;
|
|
10
|
+
this.queuedPullDeltaReasons = null;
|
|
11
|
+
this.queuedPushDeltaRequest = null;
|
|
12
|
+
this.schedules = [];
|
|
13
|
+
this.connection = connection;
|
|
14
|
+
this.options = options;
|
|
15
|
+
this.logger = logger;
|
|
16
|
+
const hasPullDeltaFlag = options.pullDeltaOnRestart ||
|
|
17
|
+
options.pullDeltaOnSchedule ||
|
|
18
|
+
options.pullDeltaOnAfterWrite ||
|
|
19
|
+
options.pullDeltaOnBeforeAccess;
|
|
20
|
+
if (options.pullDeltaHandler && !hasPullDeltaFlag)
|
|
21
|
+
throw new Error('Using pullDeltaHandler without pullDelta[*] flags');
|
|
22
|
+
if (hasPullDeltaFlag && !options.pullDeltaHandler)
|
|
23
|
+
throw new Error('Using pullDelta[*] flags without pullDeltaHandler');
|
|
24
|
+
}
|
|
25
|
+
async start(target) {
|
|
26
|
+
const { options } = this;
|
|
27
|
+
if (this.target)
|
|
28
|
+
throw new Error('Already started');
|
|
29
|
+
this.target = target;
|
|
30
|
+
if (options.pullDumpHandler &&
|
|
31
|
+
(options.pullDumpOnRestart || (await this.getStartupState()) !== 'done'))
|
|
32
|
+
await this.queuePullDump({ name: 'startup' });
|
|
33
|
+
if (options.pullDeltaHandler && options.pullDeltaOnRestart)
|
|
34
|
+
await this.queuePullDelta({ name: 'startup' });
|
|
35
|
+
if (options.pushDeltaHandler) {
|
|
36
|
+
options.pushDeltaHandler({ cache: this.requestCache, getPreviousDeltaState: () => this.getDeltaState() }, async (changes) => this.queuePushDelta(changes));
|
|
37
|
+
}
|
|
38
|
+
if (options.pullDumpHandler && options.pullDumpOnSchedule) {
|
|
39
|
+
const schedule = options.pullDumpOnSchedule;
|
|
40
|
+
for (const pattern of Array.isArray(schedule) ? schedule : [schedule]) {
|
|
41
|
+
this.schedules.push((0, croner_1.Cron)(pattern, () => this.queuePullDump({ name: 'schedule' })));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (options.pullDeltaHandler && options.pullDeltaOnSchedule) {
|
|
45
|
+
const schedule = options.pullDeltaOnSchedule;
|
|
46
|
+
for (const pattern of Array.isArray(schedule) ? schedule : [schedule]) {
|
|
47
|
+
this.schedules.push((0, croner_1.Cron)(pattern, () => this.queuePullDelta({ name: 'schedule' })));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async stop() {
|
|
52
|
+
this.schedules.forEach(cron => cron.stop());
|
|
53
|
+
this.schedules.length = 0;
|
|
54
|
+
}
|
|
55
|
+
queuePushDelta(delta) {
|
|
56
|
+
if (!this.queuedPushDeltaRequest)
|
|
57
|
+
this.queuedPushDeltaRequest = { newOrUpdatedEntries: [], deletedEntries: [] };
|
|
58
|
+
this.queuedPushDeltaRequest.deletedEntries.push(...delta.deletedEntries);
|
|
59
|
+
this.queuedPushDeltaRequest.newOrUpdatedEntries.push(...delta.newOrUpdatedEntries);
|
|
60
|
+
if (delta.nextDeltaState)
|
|
61
|
+
this.queuedPushDeltaRequest.nextDeltaState = delta.nextDeltaState;
|
|
62
|
+
this.tick();
|
|
63
|
+
}
|
|
64
|
+
queuePullDump(reason) {
|
|
65
|
+
if (!this.queuedPullDumpReasons)
|
|
66
|
+
this.queuedPullDumpReasons = { deferred: new datasource_toolkit_1.Deferred(), reasons: [] };
|
|
67
|
+
const { deferred } = this.queuedPullDumpReasons;
|
|
68
|
+
this.queuedPullDumpReasons.reasons.push({ ...reason, at: new Date() });
|
|
69
|
+
this.tick();
|
|
70
|
+
return deferred.promise;
|
|
71
|
+
}
|
|
72
|
+
queuePullDelta(reason) {
|
|
73
|
+
if (!this.queuedPullDeltaReasons)
|
|
74
|
+
this.queuedPullDeltaReasons = { deferred: new datasource_toolkit_1.Deferred(), reasons: [] };
|
|
75
|
+
const { deferred } = this.queuedPullDeltaReasons;
|
|
76
|
+
this.queuedPullDeltaReasons.reasons.push({ ...reason, at: new Date() });
|
|
77
|
+
// We wait for the access delay before running the delta
|
|
78
|
+
// This allows to batch delta requests at the cost of adding a floor delay to all requests.
|
|
79
|
+
if (this.options.pullDeltaOnBeforeAccessDelay)
|
|
80
|
+
setTimeout(() => this.tick(), this.options.pullDeltaOnBeforeAccessDelay);
|
|
81
|
+
else
|
|
82
|
+
this.tick();
|
|
83
|
+
return deferred.promise;
|
|
84
|
+
}
|
|
85
|
+
tick() {
|
|
86
|
+
if (!this.isRunning) {
|
|
87
|
+
if (this.queuedPushDeltaRequest) {
|
|
88
|
+
this.runPushDelta(this.queuedPushDeltaRequest);
|
|
89
|
+
this.queuedPushDeltaRequest = null;
|
|
90
|
+
}
|
|
91
|
+
else if (this.queuedPullDumpReasons) {
|
|
92
|
+
this.runPullDump(this.queuedPullDumpReasons);
|
|
93
|
+
this.queuedPullDumpReasons = null;
|
|
94
|
+
}
|
|
95
|
+
else if (this.queuedPullDeltaReasons) {
|
|
96
|
+
this.runPullDelta(this.queuedPullDeltaReasons);
|
|
97
|
+
this.queuedPullDeltaReasons = null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async runPushDelta(changes) {
|
|
102
|
+
this.isRunning = true;
|
|
103
|
+
await this.target.applyDelta(changes);
|
|
104
|
+
this.isRunning = false;
|
|
105
|
+
this.tick();
|
|
106
|
+
}
|
|
107
|
+
/* eslint-disable no-await-in-loop */
|
|
108
|
+
async runPullDump(queue) {
|
|
109
|
+
this.isRunning = true;
|
|
110
|
+
let state = null;
|
|
111
|
+
let more = true;
|
|
112
|
+
let firstPage = true;
|
|
113
|
+
await this.setStartupState('in_progress');
|
|
114
|
+
// Fill table with dump
|
|
115
|
+
while (more) {
|
|
116
|
+
try {
|
|
117
|
+
const changes = await this.options.pullDumpHandler({
|
|
118
|
+
reasons: queue.reasons,
|
|
119
|
+
cache: this.requestCache,
|
|
120
|
+
previousDumpState: state,
|
|
121
|
+
});
|
|
122
|
+
await this.target.applyDump(changes, firstPage);
|
|
123
|
+
firstPage = false;
|
|
124
|
+
more = changes.more;
|
|
125
|
+
if (changes.more === true)
|
|
126
|
+
state = changes.nextDumpState;
|
|
127
|
+
if (changes.more === false && changes.nextDeltaState)
|
|
128
|
+
await this.setDeltaState(changes.nextDeltaState);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
more = false;
|
|
132
|
+
this.logger('Warn', `Dump failed for the namespace "${this.options.cacheNamespace}": ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
await this.setStartupState('done');
|
|
136
|
+
this.isRunning = false;
|
|
137
|
+
queue.deferred.resolve();
|
|
138
|
+
this.tick();
|
|
139
|
+
}
|
|
140
|
+
async runPullDelta(queue) {
|
|
141
|
+
this.isRunning = true;
|
|
142
|
+
let more = true;
|
|
143
|
+
while (more) {
|
|
144
|
+
// Update records in database
|
|
145
|
+
const previousState = await this.getDeltaState();
|
|
146
|
+
const collections = queue.reasons.flatMap(r => 'affectedCollections' in r ? r.affectedCollections : []);
|
|
147
|
+
try {
|
|
148
|
+
const changes = await this.options.pullDeltaHandler({
|
|
149
|
+
reasons: queue.reasons,
|
|
150
|
+
affectedCollections: [...new Set(collections)],
|
|
151
|
+
cache: this.requestCache,
|
|
152
|
+
previousDeltaState: previousState,
|
|
153
|
+
});
|
|
154
|
+
await this.target.applyDelta(changes);
|
|
155
|
+
await this.setDeltaState(changes.nextDeltaState);
|
|
156
|
+
more = changes.more;
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
more = false;
|
|
160
|
+
this.logger('Warn', `Delta failed for the namespace "${this.options.cacheNamespace}": ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
this.isRunning = false;
|
|
164
|
+
queue.deferred.resolve();
|
|
165
|
+
this.tick();
|
|
166
|
+
}
|
|
167
|
+
/* eslint-enable no-await-in-loop */
|
|
168
|
+
async getStartupState() {
|
|
169
|
+
const metadataModel = this.connection.model(`${this.options.cacheNamespace}_metadata`);
|
|
170
|
+
const stateRecord = await metadataModel.findByPk('statup_state');
|
|
171
|
+
return stateRecord ? JSON.parse(stateRecord.dataValues.content) : 'pending';
|
|
172
|
+
}
|
|
173
|
+
async setStartupState(state) {
|
|
174
|
+
const metadataModel = this.connection.model(`${this.options.cacheNamespace}_metadata`);
|
|
175
|
+
await metadataModel.upsert({ id: 'statup_state', content: JSON.stringify(state) });
|
|
176
|
+
}
|
|
177
|
+
async getDeltaState() {
|
|
178
|
+
const metadataModel = this.connection.model(`${this.options.cacheNamespace}_metadata`);
|
|
179
|
+
const stateRecord = await metadataModel.findByPk('delta_state');
|
|
180
|
+
return stateRecord ? JSON.parse(stateRecord.dataValues.content) : null;
|
|
181
|
+
}
|
|
182
|
+
async setDeltaState(state) {
|
|
183
|
+
const metadataModel = this.connection.model(`${this.options.cacheNamespace}_metadata`);
|
|
184
|
+
await metadataModel.upsert({ id: 'delta_state', content: JSON.stringify(state) });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.default = CustomerSource;
|
|
188
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXItc291cmNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNocm9uaXphdGlvbi9jdXN0b21lci1zb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFZQSx3RUFBMkQ7QUFDM0QsbUNBQThCO0FBYzlCLE1BQXFCLGNBQWM7SUFnQmpDLFlBQVksVUFBcUIsRUFBRSxPQUFpQyxFQUFFLE1BQWM7UUFmcEYsaUJBQVksR0FBNkIsSUFBSSxDQUFDO1FBTXRDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFbEIsMEJBQXFCLEdBQTBCLElBQUksQ0FBQztRQUNwRCwyQkFBc0IsR0FBMkIsSUFBSSxDQUFDO1FBQ3RELDJCQUFzQixHQUFzQixJQUFJLENBQUM7UUFFakQsY0FBUyxHQUFXLEVBQUUsQ0FBQztRQUk3QixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUVyQixNQUFNLGdCQUFnQixHQUNwQixPQUFPLENBQUMsa0JBQWtCO1lBQzFCLE9BQU8sQ0FBQyxtQkFBbUI7WUFDM0IsT0FBTyxDQUFDLHFCQUFxQjtZQUM3QixPQUFPLENBQUMsdUJBQXVCLENBQUM7UUFFbEMsSUFBSSxPQUFPLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxnQkFBZ0I7WUFDL0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxtREFBbUQsQ0FBQyxDQUFDO1FBRXZFLElBQUksZ0JBQWdCLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCO1lBQy9DLE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUE2QjtRQUN2QyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBRXpCLElBQUksSUFBSSxDQUFDLE1BQU07WUFB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
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import type CacheDataSourceInterface from './cache-interface/datasource';
|
|
2
|
+
import type { TFilter, TPaginatedFilter } from '@forestadmin/datasource-customizer';
|
|
3
|
+
import type { ConnectionOptions } from '@forestadmin/datasource-sql';
|
|
4
|
+
import type { Aggregation, Caller, ColumnSchema, Logger, PrimitiveTypes, Projection, RecordData } from '@forestadmin/datasource-toolkit';
|
|
5
|
+
export type ValueOrPromiseOrFactory<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
|
|
6
|
+
export type RecordDataWithCollection = {
|
|
7
|
+
collection: string;
|
|
8
|
+
record: RecordData;
|
|
9
|
+
};
|
|
10
|
+
export declare function isLeafField(field: Field): field is LeafField;
|
|
11
|
+
export type ObjectField = {
|
|
12
|
+
[key: string]: Field;
|
|
13
|
+
};
|
|
14
|
+
export type ArrayField = [Field];
|
|
15
|
+
export type LeafField = {
|
|
16
|
+
type: PrimitiveTypes | 'Integer';
|
|
17
|
+
defaultValue?: unknown;
|
|
18
|
+
enumValues?: string[];
|
|
19
|
+
isPrimaryKey?: boolean;
|
|
20
|
+
isReadOnly?: boolean;
|
|
21
|
+
unique?: boolean;
|
|
22
|
+
validation?: ColumnSchema['validation'];
|
|
23
|
+
reference?: {
|
|
24
|
+
relationName: string;
|
|
25
|
+
targetCollection: string;
|
|
26
|
+
targetField: string;
|
|
27
|
+
relationInverse?: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export type Field = ArrayField | ObjectField | LeafField;
|
|
31
|
+
export type CollectionReplicaSchema = {
|
|
32
|
+
name: string;
|
|
33
|
+
fields: Record<string, Field>;
|
|
34
|
+
};
|
|
35
|
+
export type PullDumpReason = {
|
|
36
|
+
name: 'startup' | 'schedule';
|
|
37
|
+
};
|
|
38
|
+
export type PullDeltaReason = {
|
|
39
|
+
collection?: string;
|
|
40
|
+
affectedCollections?: string[];
|
|
41
|
+
} & ({
|
|
42
|
+
name: 'startup';
|
|
43
|
+
} | {
|
|
44
|
+
name: 'schedule';
|
|
45
|
+
} | {
|
|
46
|
+
name: 'before-list';
|
|
47
|
+
caller: Caller;
|
|
48
|
+
filter: TPaginatedFilter;
|
|
49
|
+
projection: Projection;
|
|
50
|
+
} | {
|
|
51
|
+
name: 'before-aggregate';
|
|
52
|
+
caller: Caller;
|
|
53
|
+
filter: TFilter;
|
|
54
|
+
aggregation: Aggregation;
|
|
55
|
+
} | {
|
|
56
|
+
name: 'after-create';
|
|
57
|
+
caller: Caller;
|
|
58
|
+
records: RecordData[];
|
|
59
|
+
} | {
|
|
60
|
+
name: 'after-update';
|
|
61
|
+
caller: Caller;
|
|
62
|
+
filter: TFilter;
|
|
63
|
+
patch: RecordData;
|
|
64
|
+
} | {
|
|
65
|
+
name: 'after-delete';
|
|
66
|
+
caller: Caller;
|
|
67
|
+
filter: TFilter;
|
|
68
|
+
});
|
|
69
|
+
export type PullDeltaRequest = {
|
|
70
|
+
previousDeltaState: unknown;
|
|
71
|
+
cache: CacheDataSourceInterface;
|
|
72
|
+
affectedCollections: string[];
|
|
73
|
+
reasons: Array<PullDeltaReason & {
|
|
74
|
+
at: Date;
|
|
75
|
+
}>;
|
|
76
|
+
};
|
|
77
|
+
export type PullDumpRequest = {
|
|
78
|
+
previousDumpState: unknown;
|
|
79
|
+
cache: CacheDataSourceInterface;
|
|
80
|
+
reasons: Array<PullDumpReason & {
|
|
81
|
+
at: Date;
|
|
82
|
+
}>;
|
|
83
|
+
};
|
|
84
|
+
export type PushDeltaRequest = {
|
|
85
|
+
getPreviousDeltaState(): unknown;
|
|
86
|
+
cache: CacheDataSourceInterface;
|
|
87
|
+
};
|
|
88
|
+
export type PullDumpResponse = {
|
|
89
|
+
more: true;
|
|
90
|
+
entries: RecordDataWithCollection[];
|
|
91
|
+
nextDumpState: unknown;
|
|
92
|
+
} | {
|
|
93
|
+
more: false;
|
|
94
|
+
entries: RecordDataWithCollection[];
|
|
95
|
+
nextDeltaState?: unknown;
|
|
96
|
+
};
|
|
97
|
+
export type PullDeltaResponse = {
|
|
98
|
+
more: boolean;
|
|
99
|
+
nextDeltaState: unknown;
|
|
100
|
+
newOrUpdatedEntries: RecordDataWithCollection[];
|
|
101
|
+
deletedEntries: RecordDataWithCollection[];
|
|
102
|
+
};
|
|
103
|
+
export type PushDeltaResponse = Omit<PullDeltaResponse, 'more' | 'nextDeltaState'> & {
|
|
104
|
+
nextDeltaState?: unknown;
|
|
105
|
+
};
|
|
106
|
+
export type FlattenOptions = {
|
|
107
|
+
[modelName: string]: {
|
|
108
|
+
asModels?: string[];
|
|
109
|
+
asFields?: Array<string | {
|
|
110
|
+
field: string;
|
|
111
|
+
level: number;
|
|
112
|
+
}>;
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
export type ReplicaDataSourceOptions = {
|
|
116
|
+
/** URL of the cache database (default to in-memory sqlite) */
|
|
117
|
+
cacheInto?: ConnectionOptions;
|
|
118
|
+
/**
|
|
119
|
+
* Prefix that should be used when creating the tables on the cache
|
|
120
|
+
* Defaults to 'forest_cache_'.
|
|
121
|
+
*
|
|
122
|
+
* Using a prefix allows to share the same database between multiple projects, environments, or
|
|
123
|
+
* datasources.
|
|
124
|
+
*/
|
|
125
|
+
cacheNamespace?: string;
|
|
126
|
+
/** Schema options */
|
|
127
|
+
schema?: ValueOrPromiseOrFactory<CollectionReplicaSchema[]>;
|
|
128
|
+
flattenMode?: 'auto' | 'manual';
|
|
129
|
+
flattenOptions?: ValueOrPromiseOrFactory<FlattenOptions>;
|
|
130
|
+
/** Writing options */
|
|
131
|
+
createRecordHandler?: (collectionName: string, record: RecordData) => Promise<RecordData>;
|
|
132
|
+
updateRecordHandler?: (collectionName: string, record: RecordData) => Promise<void>;
|
|
133
|
+
deleteRecordHandler?: (collectionName: string, record: RecordData) => Promise<void>;
|
|
134
|
+
/** Push options */
|
|
135
|
+
pushDeltaHandler?: (request: PushDeltaRequest, onChanges: (changes: PushDeltaResponse) => Promise<void>) => void | Promise<void>;
|
|
136
|
+
/** Pull dump options */
|
|
137
|
+
pullDumpHandler?: (request: PullDumpRequest) => Promise<PullDumpResponse>;
|
|
138
|
+
pullDumpOnRestart?: boolean;
|
|
139
|
+
pullDumpOnSchedule?: string | string[];
|
|
140
|
+
/** Pull delta options */
|
|
141
|
+
pullDeltaHandler?: (request: PullDeltaRequest) => Promise<PullDeltaResponse>;
|
|
142
|
+
pullDeltaOnRestart?: boolean;
|
|
143
|
+
pullDeltaOnSchedule?: string | string[];
|
|
144
|
+
pullDeltaOnBeforeAccess?: boolean;
|
|
145
|
+
pullDeltaOnAfterWrite?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Delay that should be waited before each cache access to give the opportunity for
|
|
148
|
+
* multiple requests to be batched together.
|
|
149
|
+
*
|
|
150
|
+
* Note that this delay will add latency to each request, so set it to a low value (< 100ms)
|
|
151
|
+
*/
|
|
152
|
+
pullDeltaOnBeforeAccessDelay?: number;
|
|
153
|
+
};
|
|
154
|
+
export type ResolvedOptions = Pick<ReplicaDataSourceOptions, 'cacheInto' | 'cacheNamespace' | 'createRecordHandler' | 'updateRecordHandler' | 'deleteRecordHandler' | 'pullDeltaOnBeforeAccess' | 'pullDeltaOnAfterWrite'> & {
|
|
155
|
+
schema?: CollectionReplicaSchema[];
|
|
156
|
+
flattenSchema?: CollectionReplicaSchema[];
|
|
157
|
+
flattenOptions?: {
|
|
158
|
+
[modelName: string]: {
|
|
159
|
+
asModels?: string[];
|
|
160
|
+
asFields?: string[];
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
logger: Logger;
|
|
164
|
+
source: SynchronizationSource;
|
|
165
|
+
};
|
|
166
|
+
export interface SynchronizationTarget {
|
|
167
|
+
applyDump(changes: PullDumpResponse, firstPage: boolean): Promise<void>;
|
|
168
|
+
applyDelta(changes: PushDeltaResponse): Promise<void>;
|
|
169
|
+
}
|
|
170
|
+
export interface SynchronizationSource {
|
|
171
|
+
requestCache: CacheDataSourceInterface;
|
|
172
|
+
start(target: SynchronizationTarget): Promise<void>;
|
|
173
|
+
queuePullDump(reason: PullDumpReason): Promise<void>;
|
|
174
|
+
queuePullDelta(reason: PullDeltaReason): Promise<void>;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isLeafField = void 0;
|
|
4
|
+
/// //////
|
|
5
|
+
// Schema
|
|
6
|
+
/// //////
|
|
7
|
+
function isLeafField(field) {
|
|
8
|
+
return typeof field === 'object' && 'type' in field;
|
|
9
|
+
}
|
|
10
|
+
exports.isLeafField = isLeafField;
|
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBZ0JBLFVBQVU7QUFDVixTQUFTO0FBQ1QsVUFBVTtBQUVWLFNBQWdCLFdBQVcsQ0FBQyxLQUFZO0lBQ3RDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxLQUFLLENBQUM7QUFDdEQsQ0FBQztBQUZELGtDQUVDIn0=
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CollectionReplicaSchema } from './types';
|
|
2
|
+
import type { RecordData } from '@forestadmin/datasource-toolkit';
|
|
3
|
+
export declare function escape(strings: TemplateStringsArray, ...exps: unknown[]): string;
|
|
4
|
+
export declare function deepclone(any: unknown): any;
|
|
5
|
+
export declare function extractValue(record: RecordData, path: string, remove: boolean): any;
|
|
6
|
+
export declare function getRecordId(fields: CollectionReplicaSchema['fields'], record: RecordData): unknown;
|
|
7
|
+
//# sourceMappingURL=utils.d.ts.map
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRecordId = exports.extractValue = exports.deepclone = exports.escape = void 0;
|
|
4
|
+
function escape(strings, ...exps) {
|
|
5
|
+
return strings.reduce((acc, str, i) => acc + str + (exps[i] ?? ''), '').replace(/\./g, '_');
|
|
6
|
+
}
|
|
7
|
+
exports.escape = escape;
|
|
8
|
+
function deepclone(any) {
|
|
9
|
+
return JSON.parse(JSON.stringify(any));
|
|
10
|
+
}
|
|
11
|
+
exports.deepclone = deepclone;
|
|
12
|
+
function extractValue(record, path, remove) {
|
|
13
|
+
if (!path)
|
|
14
|
+
return record;
|
|
15
|
+
const [prefix, suffix] = path.split(/\.(.*)/);
|
|
16
|
+
const value = extractValue(record?.[prefix], suffix, remove);
|
|
17
|
+
if (remove && record && (!suffix || !Object.keys(record?.[prefix] ?? {}).length))
|
|
18
|
+
delete record[prefix];
|
|
19
|
+
return value;
|
|
20
|
+
}
|
|
21
|
+
exports.extractValue = extractValue;
|
|
22
|
+
function getRecordId(fields, record) {
|
|
23
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
24
|
+
if (record._fid)
|
|
25
|
+
return record._fid;
|
|
26
|
+
const pks = Object.entries(fields)
|
|
27
|
+
.filter(([, v]) => 'type' in v && v.isPrimaryKey)
|
|
28
|
+
.map(([k]) => record[k]);
|
|
29
|
+
if (pks.length === 0)
|
|
30
|
+
throw new Error('No primary key found');
|
|
31
|
+
else if (pks.length === 1)
|
|
32
|
+
return pks[0];
|
|
33
|
+
}
|
|
34
|
+
exports.getRecordId = getRecordId;
|
|
35
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsU0FBZ0IsTUFBTSxDQUFDLE9BQTZCLEVBQUUsR0FBRyxJQUFlO0lBQ3RFLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDOUYsQ0FBQztBQUZELHdCQUVDO0FBRUQsU0FBZ0IsU0FBUyxDQUFDLEdBQVk7SUFDcEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBRkQsOEJBRUM7QUFFRCxTQUFnQixZQUFZLENBQUMsTUFBa0IsRUFBRSxJQUFZLEVBQUUsTUFBZTtJQUM1RSxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sTUFBTSxDQUFDO0lBRXpCLE1BQU0sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM5QyxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzdELElBQUksTUFBTSxJQUFJLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDOUUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFeEIsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBVEQsb0NBU0M7QUFFRCxTQUFnQixXQUFXLENBQ3pCLE1BQXlDLEVBQ3pDLE1BQWtCO0lBRWxCLGdEQUFnRDtJQUNoRCxJQUFJLE1BQU0sQ0FBQyxJQUFJO1FBQUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0lBRXBDLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1NBQy9CLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsWUFBWSxDQUFDO1NBQ2hELEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRTNCLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1NBQ3pELElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0MsQ0FBQztBQWJELGtDQWFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forestadmin/datasource-replica",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2-alpha-widgets.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"directory": "packages/datasource-replica"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
|
-
"dist
|
|
16
|
-
"dist
|
|
15
|
+
"dist/**/*.js",
|
|
16
|
+
"dist/**/*.d.ts"
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc",
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"test": "jest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@forestadmin/datasource-customizer": "1.
|
|
27
|
-
"@forestadmin/datasource-sequelize": "1.5.
|
|
28
|
-
"@forestadmin/datasource-sql": "1.7.
|
|
29
|
-
"@forestadmin/datasource-toolkit": "1.
|
|
26
|
+
"@forestadmin/datasource-customizer": "1.16.0-alpha-widgets.1",
|
|
27
|
+
"@forestadmin/datasource-sequelize": "1.5.1-alpha-widgets.1",
|
|
28
|
+
"@forestadmin/datasource-sql": "1.7.11-alpha-widgets.1",
|
|
29
|
+
"@forestadmin/datasource-toolkit": "1.10.0-alpha-widgets.1",
|
|
30
30
|
"croner": "^6.0.6",
|
|
31
31
|
"sequelize": "^6.28.0"
|
|
32
32
|
}
|