@modelprofile.com/flexharness 11.3.0 → 12.0.0
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_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.flexharness.core.d.ts +4 -0
- package/dist_ts/classes.flexharness.core.js +69 -25
- package/dist_ts/classes.flexharness.imports.js +4 -3
- package/dist_ts/classes.flexharness.reversions.d.ts +7 -1
- package/dist_ts/classes.flexharness.reversions.js +43 -29
- package/dist_ts/classes.flexharness.sessions.js +2 -6
- package/dist_ts/classes.stores.js +20 -18
- package/dist_ts/index.d.ts +1 -0
- package/dist_ts/index.js +2 -1
- package/dist_ts/interfaces.d.ts +24 -2
- package/dist_ts/interfaces.flexharness.d.ts +8 -1
- package/dist_ts/interfaces.js +1 -1
- package/dist_ts/plugins.d.ts +3 -3
- package/dist_ts/plugins.js +3 -3
- package/dist_ts/utils.projectionchange.d.ts +34 -0
- package/dist_ts/utils.projectionchange.js +135 -0
- package/dist_ts/utils.storecodecs.d.ts +10 -3
- package/dist_ts/utils.storecodecs.js +29 -4
- package/dist_ts/utils.storerules.d.ts +1 -1
- package/dist_ts/utils.storerules.js +1 -1
- package/dist_ts_migration/v3_legacyflexharness.js +6 -5
- package/dist_ts_stores_nosqldb/classes.nosqldbstores.d.ts +5 -4
- package/dist_ts_stores_nosqldb/classes.nosqldbstores.js +56 -54
- package/dist_ts_stores_nosqldb/classes.recordstore.d.ts +176 -19
- package/dist_ts_stores_nosqldb/classes.recordstore.js +392 -67
- package/dist_ts_stores_nosqldb/index.d.ts +1 -1
- package/dist_ts_stores_nosqldb/index.js +2 -2
- package/dist_ts_stores_nosqldb/plugins.d.ts +1 -1
- package/dist_ts_stores_nosqldb/plugins.js +1 -1
- package/dist_ts_stores_testing/contract.d.ts +33 -0
- package/dist_ts_stores_testing/contract.js +566 -0
- package/dist_ts_stores_testing/fixtures.d.ts +20 -0
- package/dist_ts_stores_testing/fixtures.js +112 -0
- package/dist_ts_stores_testing/index.d.ts +2 -0
- package/dist_ts_stores_testing/index.js +3 -0
- package/dist_ts_stores_testing/plugins.d.ts +5 -0
- package/dist_ts_stores_testing/plugins.js +7 -0
- package/package.json +9 -3
- package/readme.md +6 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.flexharness.core.ts +74 -24
- package/ts/classes.flexharness.imports.ts +3 -2
- package/ts/classes.flexharness.reversions.ts +53 -28
- package/ts/classes.flexharness.sessions.ts +2 -5
- package/ts/classes.stores.ts +40 -37
- package/ts/index.ts +5 -0
- package/ts/interfaces.flexharness.ts +8 -1
- package/ts/interfaces.ts +27 -2
- package/ts/plugins.ts +12 -7
- package/ts/readme.md +6 -3
- package/ts/utils.projectionchange.ts +190 -0
- package/ts/utils.storecodecs.ts +42 -7
- package/ts/utils.storerules.ts +2 -2
- package/ts_migration/v3_legacyflexharness.ts +11 -6
- package/ts_stores_nosqldb/classes.nosqldbstores.ts +79 -71
- package/ts_stores_nosqldb/classes.recordstore.ts +491 -66
- package/ts_stores_nosqldb/index.ts +1 -0
- package/ts_stores_nosqldb/plugins.ts +4 -3
- package/ts_stores_nosqldb/readme.md +6 -2
- package/ts_stores_testing/contract.ts +776 -0
- package/ts_stores_testing/fixtures.ts +127 -0
- package/ts_stores_testing/index.ts +17 -0
- package/ts_stores_testing/plugins.ts +20 -0
- package/ts_stores_testing/readme.md +62 -0
|
@@ -2,14 +2,21 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import { FlexHarnessStoreConflictError, FlexHarnessValidationError } from '../dist_ts/errors.js';
|
|
3
3
|
import { assertFlexPermissionSnapshot, assertFlexProjectionSnapshot, assertFlexScopeSnapshot, assertJsonSerializable, } from '../dist_ts/utils.json.js';
|
|
4
4
|
import { assertFlexProjectManagementRecord, assertFlexProjectManagementSnapshot, assertFlexProjectManagementTombstone, } from '../dist_ts/utils.projectmanagement.js';
|
|
5
|
-
import {
|
|
5
|
+
import { applyFlexProjectionChange, assertFlexProjectionChange, validateProjectionChangeSave, } from '../dist_ts/utils.projectionchange.js';
|
|
6
|
+
import { assertFlexToolJobSnapshot, createChangedAgentEventSnapshot, createToolJobSnapshot, normalizeAgentEventChange, normalizeJsonObjectUndefined, validateAgentEventArchive, validateAgentEventSnapshot, } from '../dist_ts/utils.storecodecs.js';
|
|
6
7
|
import { assertProjectManagementSaveAdmitted, assertSameArchiveEvents, isProjectManagementTombstoneAdmitted, providerKey, validateExpectedRevision, validateIdentifier, validateProjectManagementWriteContext, validateResultIndex, validateSnapshotSave, } from '../dist_ts/utils.storerules.js';
|
|
7
|
-
import { FlexRecordStore } from './classes.recordstore.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
import { FlexRecordStore, } from './classes.recordstore.js';
|
|
9
|
+
/** Replaces a record with a snapshot while the record's revision is the expected one. */
|
|
10
|
+
function revisionReplacement(snapshot, expectedRevision, conflict, abortSignal) {
|
|
11
|
+
return {
|
|
12
|
+
decide: (actualRevision) => {
|
|
13
|
+
abortSignal?.throwIfAborted();
|
|
14
|
+
if (actualRevision !== expectedRevision)
|
|
15
|
+
throw conflict(actualRevision);
|
|
16
|
+
return { revision: snapshot.revision, value: snapshot };
|
|
17
|
+
},
|
|
18
|
+
contention: conflict,
|
|
19
|
+
};
|
|
13
20
|
}
|
|
14
21
|
function validateScope(value) {
|
|
15
22
|
assertFlexScopeSnapshot(value);
|
|
@@ -40,36 +47,39 @@ class NoSqlScopeStore {
|
|
|
40
47
|
validateIdentifier(storageKey, 'storageKey');
|
|
41
48
|
const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexScopeSnapshot);
|
|
42
49
|
const conflict = (actualRevision) => new FlexHarnessStoreConflictError(storageKey, expectedRevision, actualRevision);
|
|
43
|
-
await this.records.
|
|
44
|
-
validate: validateScope,
|
|
45
|
-
decide: (current) => revisionWrite(current, validated, expectedRevision, conflict),
|
|
46
|
-
contention: conflict,
|
|
47
|
-
});
|
|
50
|
+
await this.records.replace({ domain: 'scope', storageKey }, revisionReplacement(validated, expectedRevision, conflict));
|
|
48
51
|
}
|
|
49
52
|
}
|
|
53
|
+
/** A projection is a log record: a save writes its change, checked in form. */
|
|
50
54
|
class NoSqlProjectionStore {
|
|
51
55
|
records;
|
|
52
56
|
constructor(records) {
|
|
53
57
|
this.records = records;
|
|
54
58
|
}
|
|
55
|
-
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
log(sessionId) {
|
|
60
|
+
return {
|
|
61
|
+
validate: (value) => {
|
|
62
|
+
assertFlexProjectionSnapshot(value, sessionId);
|
|
63
|
+
return value;
|
|
64
|
+
},
|
|
65
|
+
validateChange: (value) => {
|
|
66
|
+
assertFlexProjectionChange(value);
|
|
67
|
+
return value;
|
|
68
|
+
},
|
|
69
|
+
apply: applyFlexProjectionChange,
|
|
59
70
|
};
|
|
60
71
|
}
|
|
61
72
|
load(storageKey, sessionId) {
|
|
62
73
|
providerKey(storageKey, sessionId);
|
|
63
|
-
return this.records.
|
|
74
|
+
return this.records.readLog({ domain: 'projection', storageKey, sessionId }, this.log(sessionId));
|
|
64
75
|
}
|
|
65
|
-
async save(storageKey, sessionId,
|
|
76
|
+
async save(storageKey, sessionId, change, expectedRevision) {
|
|
66
77
|
const key = providerKey(storageKey, sessionId);
|
|
67
|
-
const validated =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
contention: conflict,
|
|
78
|
+
const validated = validateProjectionChangeSave(change, expectedRevision);
|
|
79
|
+
await this.records.append({ domain: 'projection', storageKey, sessionId }, this.log(sessionId), {
|
|
80
|
+
expectedRevision,
|
|
81
|
+
value: validated,
|
|
82
|
+
conflict: (actualRevision) => new FlexHarnessStoreConflictError(key, expectedRevision, actualRevision),
|
|
73
83
|
});
|
|
74
84
|
}
|
|
75
85
|
deleteSession(storageKey, sessionId) {
|
|
@@ -90,11 +100,7 @@ class NoSqlPermissionStore {
|
|
|
90
100
|
const key = providerKey(storageKey, sessionId);
|
|
91
101
|
const validated = validateSnapshotSave(snapshot, expectedRevision, assertFlexPermissionSnapshot);
|
|
92
102
|
const conflict = (actualRevision) => new FlexHarnessStoreConflictError(key, expectedRevision, actualRevision);
|
|
93
|
-
await this.records.
|
|
94
|
-
validate: validatePermission,
|
|
95
|
-
decide: (current) => revisionWrite(current, validated, expectedRevision, conflict),
|
|
96
|
-
contention: conflict,
|
|
97
|
-
});
|
|
103
|
+
await this.records.replace({ domain: 'permission', storageKey, sessionId }, revisionReplacement(validated, expectedRevision, conflict));
|
|
98
104
|
}
|
|
99
105
|
deleteSession(storageKey, sessionId) {
|
|
100
106
|
providerKey(storageKey, sessionId);
|
|
@@ -139,11 +145,11 @@ class NoSqlProjectManagementStore {
|
|
|
139
145
|
return this.records.purgeNamespace(storageKey, 'projectManagement');
|
|
140
146
|
}
|
|
141
147
|
}
|
|
148
|
+
/** A session's event log is a log record: a save writes its change, checked in form. */
|
|
142
149
|
class NoSqlAgentEventStore {
|
|
143
150
|
records;
|
|
144
151
|
storageKey;
|
|
145
152
|
sessionId;
|
|
146
|
-
eventSchemaVersion = 2;
|
|
147
153
|
constructor(records, storageKey, sessionId) {
|
|
148
154
|
this.records = records;
|
|
149
155
|
this.storageKey = storageKey;
|
|
@@ -154,23 +160,25 @@ class NoSqlAgentEventStore {
|
|
|
154
160
|
throw new FlexHarnessValidationError(`Agent event store is bound to session "${this.sessionId}", not "${sessionId}".`);
|
|
155
161
|
}
|
|
156
162
|
}
|
|
157
|
-
|
|
163
|
+
log = {
|
|
164
|
+
validate: (value) => validateAgentEventSnapshot(value, this.sessionId),
|
|
165
|
+
validateChange: normalizeAgentEventChange,
|
|
166
|
+
apply: (current, change) => createChangedAgentEventSnapshot(this.sessionId, current, change),
|
|
167
|
+
};
|
|
158
168
|
load(sessionId) {
|
|
159
169
|
this.assertSession(sessionId);
|
|
160
|
-
return this.records.
|
|
170
|
+
return this.records.readLog({ domain: 'agentEvents', storageKey: this.storageKey, sessionId }, this.log);
|
|
161
171
|
}
|
|
162
|
-
async save(sessionId,
|
|
172
|
+
async save(sessionId, change, expectedRevision) {
|
|
163
173
|
this.assertSession(sessionId);
|
|
164
174
|
validateExpectedRevision(expectedRevision);
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
decide: (current) => revisionWrite(current, snapshot, expectedRevision, conflict),
|
|
171
|
-
contention: conflict,
|
|
175
|
+
const normalized = normalizeAgentEventChange(change);
|
|
176
|
+
await this.records.append({ domain: 'agentEvents', storageKey: this.storageKey, sessionId }, this.log, {
|
|
177
|
+
expectedRevision,
|
|
178
|
+
value: normalized,
|
|
179
|
+
conflict: (actualRevision) => new plugins.AgentEventStoreConflictError(sessionId, expectedRevision, actualRevision),
|
|
172
180
|
});
|
|
173
|
-
return
|
|
181
|
+
return expectedRevision + 1;
|
|
174
182
|
}
|
|
175
183
|
async archive(archive) {
|
|
176
184
|
this.assertSession(archive.sessionId);
|
|
@@ -243,14 +251,7 @@ class NoSqlToolJobStore {
|
|
|
243
251
|
validateExpectedRevision(expectedRevision);
|
|
244
252
|
const snapshot = createToolJobSnapshot(jobs, expectedRevision + 1);
|
|
245
253
|
const conflict = (actualRevision) => new plugins.ToolJobStoreConflictError(expectedRevision, actualRevision);
|
|
246
|
-
await this.records.
|
|
247
|
-
validate: validateToolJobs,
|
|
248
|
-
decide: (current) => {
|
|
249
|
-
abortSignal?.throwIfAborted();
|
|
250
|
-
return revisionWrite(current, snapshot, expectedRevision, conflict);
|
|
251
|
-
},
|
|
252
|
-
contention: conflict,
|
|
253
|
-
});
|
|
254
|
+
await this.records.replace({ domain: 'jobs', storageKey: this.storageKey, sessionId: this.sessionId }, revisionReplacement(snapshot, expectedRevision, conflict, abortSignal));
|
|
254
255
|
return snapshot.revision;
|
|
255
256
|
}
|
|
256
257
|
}
|
|
@@ -337,8 +338,9 @@ function validateResult(value) {
|
|
|
337
338
|
/**
|
|
338
339
|
* Every FlexHarness persistence domain on `@lossless.org/client/nosqldb`, with compare-and-swap
|
|
339
340
|
* that holds across processes. Records live in `flexharness_records`; payloads longer than one
|
|
340
|
-
* chunk live in `flexharness_chunks`;
|
|
341
|
-
*
|
|
341
|
+
* chunk live in `flexharness_chunks`; the changes saved to a projection or an Agent event log
|
|
342
|
+
* since its last compaction live in its head and, beyond the head's inline room, in pages in
|
|
343
|
+
* `flexharness_changes`; `flexharness_namespaces` holds each storage namespace's fence.
|
|
342
344
|
*/
|
|
343
345
|
export class NoSqlFlexHarnessStores {
|
|
344
346
|
scopes;
|
|
@@ -363,14 +365,14 @@ export class NoSqlFlexHarnessStores {
|
|
|
363
365
|
this.results = new NoSqlResultStore(this.records);
|
|
364
366
|
}
|
|
365
367
|
/**
|
|
366
|
-
* Creates or verifies the
|
|
368
|
+
* Creates or verifies the four collections and their indexes. Every store operation awaits the
|
|
367
369
|
* same preparation, so calling it at startup only moves that work, and its failure, forward.
|
|
368
370
|
*/
|
|
369
371
|
prepare() {
|
|
370
372
|
return this.records.prepare();
|
|
371
373
|
}
|
|
372
374
|
/**
|
|
373
|
-
* Physically removes every record and
|
|
375
|
+
* Physically removes every record, chunk and change of one storage namespace in every domain: the
|
|
374
376
|
* scope snapshot, each session's projection, permissions, Agent events and archives, jobs and
|
|
375
377
|
* results, and the project-management records and tombstones. This is the host's durable
|
|
376
378
|
* deletion of a scope. Stop new admission for every alias of the scope first. Without `fence`,
|
|
@@ -390,4 +392,4 @@ export class NoSqlFlexHarnessStores {
|
|
|
390
392
|
: this.records.purgeNamespace(storageKey);
|
|
391
393
|
}
|
|
392
394
|
}
|
|
393
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ub3NxbGRic3RvcmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfc3RvcmVzX25vc3FsZGIvY2xhc3Nlcy5ub3NxbGRic3RvcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBb0I1RixPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLDRCQUE0QixFQUM1Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLGlDQUFpQyxFQUNqQyxtQ0FBbUMsRUFDbkMsb0NBQW9DLEdBQ3JDLE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUNMLHlCQUF5QixFQUN6Qix3QkFBd0IsRUFDeEIscUJBQXFCLEVBQ3JCLDRCQUE0QixFQUM1Qix5QkFBeUIsRUFDekIsMEJBQTBCLEdBQzNCLE1BQU0sNEJBQTRCLENBQUM7QUFDcEMsT0FBTyxFQUNMLG1DQUFtQyxFQUNuQyx1QkFBdUIsRUFDdkIsb0NBQW9DLEVBQ3BDLFdBQVcsRUFDWCx3QkFBd0IsRUFDeEIsa0JBQWtCLEVBQ2xCLHFDQUFxQyxFQUNyQyxtQkFBbUIsRUFDbkIsb0JBQW9CLEdBQ3JCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLGVBQWUsRUFBeUIsTUFBTSwwQkFBMEIsQ0FBQztBQUVsRixTQUFTLGFBQWEsQ0FDcEIsT0FBeUMsRUFDekMsUUFBbUIsRUFDbkIsZ0JBQXdCLEVBQ3hCLFFBQTJDO0lBRTNDLE1BQU0sY0FBYyxHQUFHLE9BQU8sRUFBRSxRQUFRLElBQUksQ0FBQyxDQUFDO0lBQzlDLElBQUksY0FBYyxLQUFLLGdCQUFnQjtRQUFFLE1BQU0sUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDMUQsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLEtBQWM7SUFDbkMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxLQUFjO0lBQ3hDLDRCQUE0QixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsS0FBYztJQUN0Qyx5QkFBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLEtBQWM7SUFDL0MsaUNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekMsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQsTUFBTSxlQUFlO0lBQ1UsT0FBTztJQUFwQyxZQUE2QixPQUF3Qjt1QkFBeEIsT0FBTztJQUFvQixDQUFDO0lBRWxELElBQUksQ0FBQyxVQUFrQjtRQUM1QixrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDN0MsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDM0UsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLENBQ2YsVUFBa0IsRUFDbEIsUUFBNEIsRUFDNUIsZ0JBQXdCO1FBRXhCLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM3QyxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztRQUM1RixNQUFNLFFBQVEsR0FBRyxDQUFDLGNBQXNCLEVBQUUsRUFBRSxDQUMxQyxJQUFJLDZCQUE2QixDQUFDLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUNsRixNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUN6RCxRQUFRLEVBQUUsYUFBYTtZQUN2QixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQztZQUNsRixVQUFVLEVBQUUsUUFBUTtTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLG9CQUFvQjtJQUNLLE9BQU87SUFBcEMsWUFBNkIsT0FBd0I7dUJBQXhCLE9BQU87SUFBb0IsQ0FBQztJQUVqRCxTQUFTLENBQUMsU0FBaUI7UUFDakMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ2YsNEJBQTRCLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQy9DLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUVNLElBQUksQ0FBQyxVQUFrQixFQUFFLFNBQWlCO1FBQy9DLFdBQVcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDdEIsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFDL0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FDMUIsQ0FBQztJQUNKLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxDQUNmLFVBQWtCLEVBQ2xCLFNBQWlCLEVBQ2pCLFFBQW1DLEVBQ25DLGdCQUF3QjtRQUV4QixNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sU0FBUyxHQUFHLG9CQUFvQixDQUNwQyxRQUFRLEVBQ1IsZ0JBQWdCLEVBQ2hCLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQzFELENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxDQUFDLGNBQXNCLEVBQUUsRUFBRSxDQUMxQyxJQUFJLDZCQUE2QixDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUMzRSxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQUU7WUFDekUsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQ25DLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDO1lBQ2xGLFVBQVUsRUFBRSxRQUFRO1NBQ3JCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxhQUFhLENBQUMsVUFBa0IsRUFBRSxTQUFpQjtRQUN4RCxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDekUsQ0FBQztDQUNGO0FBRUQsTUFBTSxvQkFBb0I7SUFDSyxPQUFPO0lBQXBDLFlBQTZCLE9BQXdCO3VCQUF4QixPQUFPO0lBQW9CLENBQUM7SUFFbEQsSUFBSSxDQUFDLFVBQWtCLEVBQUUsU0FBaUI7UUFDL0MsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNuQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztJQUNoRyxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FDZixVQUFrQixFQUNsQixTQUFpQixFQUNqQixRQUFpQyxFQUNqQyxnQkFBd0I7UUFFeEIsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQyxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztRQUNqRyxNQUFNLFFBQVEsR0FBRyxDQUFDLGNBQXNCLEVBQUUsRUFBRSxDQUMxQyxJQUFJLDZCQUE2QixDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUMzRSxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQUU7WUFDekUsUUFBUSxFQUFFLGtCQUFrQjtZQUM1QixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQztZQUNsRixVQUFVLEVBQUUsUUFBUTtTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sYUFBYSxDQUFDLFVBQWtCLEVBQUUsU0FBaUI7UUFDeEQsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNuQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7Q0FDRjtBQUVELE1BQU0sMkJBQTJCO0lBQ0YsT0FBTztJQUFwQyxZQUE2QixPQUF3Qjt1QkFBeEIsT0FBTztJQUFvQixDQUFDO0lBRWxELElBQUksQ0FDVCxVQUFrQixFQUNsQixTQUFpQjtRQUVqQixXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ3RCLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFDdEQseUJBQXlCLENBQzFCLENBQUM7SUFDSixDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FDZixVQUFrQixFQUNsQixTQUFpQixFQUNqQixRQUF3QyxFQUN4QyxnQkFBd0IsRUFDeEIsWUFBZ0Q7UUFFaEQsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQyxxQ0FBcUMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNwRCxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsQ0FDcEMsUUFBUSxFQUNSLGdCQUFnQixFQUNoQixtQ0FBbUMsQ0FDcEMsQ0FBQztRQUNGLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQ2hGLFFBQVEsRUFBRSx5QkFBeUI7WUFDbkMsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ2xCLG1DQUFtQyxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBQy9FLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUM7WUFDNUQsQ0FBQztZQUNELFVBQVUsRUFBRSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQzdCLElBQUksNkJBQTZCLENBQUMsR0FBRyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsQ0FBQztTQUMzRSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sS0FBSyxDQUFDLGdCQUFnQixDQUMzQixVQUFrQixFQUNsQixTQUFpQixFQUNqQixTQUEwQyxFQUMxQyxnQkFBd0I7UUFFeEIsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQyxNQUFNLFNBQVMsR0FBRyxvQkFBb0IsQ0FDcEMsU0FBUyxFQUNULGdCQUFnQixFQUNoQixvQ0FBb0MsQ0FDckMsQ0FBQztRQUNGLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsbUJBQW1CLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQ2hGLFFBQVEsRUFBRSx5QkFBeUI7WUFDbkMsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUNuQixvQ0FBb0MsQ0FBQyxHQUFHLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQztnQkFDN0UsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtnQkFDcEQsQ0FBQyxDQUFDLFNBQVMsQ0FDZDtZQUNELFVBQVUsRUFBRSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQzdCLElBQUksNkJBQTZCLENBQUMsR0FBRyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsQ0FBQztTQUMzRSxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sY0FBYyxDQUFDLFVBQWtCO1FBQ3RDLGtCQUFrQixDQUFDLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUM3QyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7Q0FDRjtBQUVELE1BQU0sb0JBQW9CO0lBSUwsT0FBTztJQUNQLFVBQVU7SUFDVixTQUFTO0lBTFosa0JBQWtCLEdBQUcsQ0FBVSxDQUFDO0lBRWhELFlBQ21CLE9BQXdCLEVBQ3hCLFVBQWtCLEVBQ2xCLFNBQWlCO3VCQUZqQixPQUFPOzBCQUNQLFVBQVU7eUJBQ1YsU0FBUztJQUN6QixDQUFDO0lBRUksYUFBYSxDQUFDLFNBQWlCO1FBQ3JDLElBQUksU0FBUyxLQUFLLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksMEJBQTBCLENBQ2xDLDBDQUEwQyxJQUFJLENBQUMsU0FBUyxXQUFXLFNBQVMsSUFBSSxDQUNqRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFZ0IsZ0JBQWdCLEdBQUcsQ0FBQyxLQUFjLEVBQWlDLEVBQUUsQ0FDcEYsMEJBQTBCLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU3QyxJQUFJLENBQUMsU0FBaUI7UUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUN0QixFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLEVBQ2pFLElBQUksQ0FBQyxnQkFBZ0IsQ0FDdEIsQ0FBQztJQUNKLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxDQUNmLFNBQWlCLEVBQ2pCLE1BQXNDLEVBQ3RDLGdCQUF3QjtRQUV4QixJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzlCLHdCQUF3QixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDM0MsTUFBTSxRQUFRLEdBQUcsd0JBQXdCLENBQUMsU0FBUyxFQUFFLE1BQU0sRUFBRSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNuRiwwQkFBMEIsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDaEQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxjQUFzQixFQUFFLEVBQUUsQ0FDMUMsSUFBSSxPQUFPLENBQUMsNEJBQTRCLENBQUMsU0FBUyxFQUFFLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQ3hGLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFO1lBQzNGLFFBQVEsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO1lBQy9CLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDO1lBQ2pGLFVBQVUsRUFBRSxRQUFRO1NBQ3JCLENBQUMsQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLFFBQVEsQ0FBQztJQUMzQixDQUFDO0lBRU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFxQztRQUN4RCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN0QyxNQUFNLFVBQVUsR0FBRyw0QkFBNEIsQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckUsTUFBTSxTQUFTLEdBQUcseUJBQXlCLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNGLE1BQU0sT0FBTyxHQUFHO1lBQ2QsTUFBTSxFQUFFLG1CQUE0QjtZQUNwQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDM0IsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLE9BQU8sRUFBRSxPQUFPLENBQUMsU0FBUztTQUMzQixDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7WUFDakMsUUFBUSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDO1lBQ3hGLE1BQU0sRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFO2dCQUNsQixJQUFJLENBQUMsT0FBTztvQkFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUM7Z0JBQ3ZELHVCQUF1QixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQztnQkFDNUMsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FDZixJQUFJLEtBQUssQ0FBQyxZQUFZLE9BQU8sQ0FBQyxTQUFTLHVDQUF1QyxDQUFDO1NBQ2xGLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxXQUFXLENBQ2hCLFNBQWlCLEVBQ2pCLFNBQWlCO1FBRWpCLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUIsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQ3RCLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEVBQzNGLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FDdkUsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQUVELE1BQU0sNEJBQTRCO0lBR0gsT0FBTztJQUZuQixNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWdDLENBQUM7SUFFbEUsWUFBNkIsT0FBd0I7dUJBQXhCLE9BQU87SUFBb0IsQ0FBQztJQUVsRCxRQUFRLENBQUMsVUFBa0IsRUFBRSxTQUFpQjtRQUNuRCxNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9DLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLEtBQUssR0FBRyxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3RFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRU0sY0FBYyxDQUFDLFVBQWtCLEVBQUUsU0FBaUI7UUFDekQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFTSxLQUFLLENBQUMsYUFBYSxDQUFDLFVBQWtCLEVBQUUsU0FBaUI7UUFDOUQsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUMvQyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxhQUFhLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1FBQzVGLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzFCLENBQUM7Q0FDRjtBQUVELE1BQU0saUJBQWlCO0lBRUYsT0FBTztJQUNQLFVBQVU7SUFDVixTQUFTO0lBSDVCLFlBQ21CLE9BQXdCLEVBQ3hCLFVBQWtCLEVBQ2xCLFNBQWlCO3VCQUZqQixPQUFPOzBCQUNQLFVBQVU7eUJBQ1YsU0FBUztJQUN6QixDQUFDO0lBRUcsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUF5QjtRQUN6QyxXQUFXLEVBQUUsY0FBYyxFQUFFLENBQUM7UUFDOUIsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FDdEMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQzFFLGdCQUFnQixDQUNqQixDQUFDO1FBQ0YsV0FBVyxFQUFFLGNBQWMsRUFBRSxDQUFDO1FBQzlCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxDQUNmLElBQXNDLEVBQ3RDLGdCQUF3QixFQUN4QixXQUF5QjtRQUV6QixXQUFXLEVBQUUsY0FBYyxFQUFFLENBQUM7UUFDOUIsd0JBQXdCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMzQyxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDbkUsTUFBTSxRQUFRLEdBQUcsQ0FBQyxjQUFzQixFQUFFLEVBQUUsQ0FDMUMsSUFBSSxPQUFPLENBQUMseUJBQXlCLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDMUUsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FDdkIsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQzFFO1lBQ0UsUUFBUSxFQUFFLGdCQUFnQjtZQUMxQixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDbEIsV0FBVyxFQUFFLGNBQWMsRUFBRSxDQUFDO2dCQUM5QixPQUFPLGFBQWEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxVQUFVLEVBQUUsUUFBUTtTQUNyQixDQUNGLENBQUM7UUFDRixPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUM7SUFDM0IsQ0FBQztDQUNGO0FBRUQsTUFBTSx5QkFBeUI7SUFHQSxPQUFPO0lBRm5CLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBNkIsQ0FBQztJQUUvRCxZQUE2QixPQUF3Qjt1QkFBeEIsT0FBTztJQUFvQixDQUFDO0lBRWxELFFBQVEsQ0FBQyxVQUFrQixFQUFFLFNBQWlCO1FBQ25ELE1BQU0sR0FBRyxHQUFHLFdBQVcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0MsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsS0FBSyxHQUFHLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDbkUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTSxjQUFjLENBQUMsVUFBa0IsRUFBRSxTQUFpQjtRQUN6RCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDekQsQ0FBQztJQUVNLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBa0IsRUFBRSxTQUFpQjtRQUM5RCxNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9DLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUIsQ0FBQztDQUNGO0FBcUJEOzs7O0dBSUc7QUFDSCxNQUFNLGdCQUFnQjtJQUNTLE9BQU87SUFBcEMsWUFBNkIsT0FBd0I7dUJBQXhCLE9BQU87SUFBb0IsQ0FBQztJQUVsRCxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQWtCLEVBQUUsU0FBaUIsRUFBRSxNQUFjLEVBQUUsS0FBaUI7UUFDeEYsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLE1BQU0sUUFBUSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksNkJBQTZCLENBQUMsR0FBRyxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxJQUFJLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsSCxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUN0RixRQUFRLEVBQUUsY0FBYztZQUN4QixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRTtnQkFDbEIsSUFBSSxPQUFPLEtBQUssU0FBUztvQkFBRSxNQUFNLFFBQVEsRUFBRSxDQUFDO2dCQUM1QyxPQUFPLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUNoQyxDQUFDO1lBQ0QsVUFBVSxFQUFFLFFBQVE7U0FDckIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNuRixDQUFDO0lBRU0sSUFBSSxDQUFDLFVBQWtCLEVBQUUsU0FBaUIsRUFBRSxNQUFjO1FBQy9ELGtCQUFrQixDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNyQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUN6RyxDQUFDO0lBRU0sS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFrQixFQUFFLFNBQWlCO1FBQ3JELE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1FBQ3hHLE9BQU8sS0FBSyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVNLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBa0IsRUFBRSxTQUFpQixFQUFFLE1BQWM7UUFDdkUsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN4RyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFTSxhQUFhLENBQUMsVUFBa0IsRUFBRSxTQUFpQjtRQUN4RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLENBQUM7SUFFRCw0RkFBNEY7SUFDcEYsV0FBVyxDQUFDLFVBQWtCLEVBQUUsU0FBaUIsRUFBRSxNQUF1QztRQUNoRyxNQUFNLFVBQVUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsU0FBUyx1Q0FBdUMsQ0FBQyxDQUFDO1FBQ3JILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsRUFBRTtZQUN0RSxRQUFRLEVBQUUsbUJBQW1CO1lBQzdCLHFGQUFxRjtZQUNyRixNQUFNLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDMUYsVUFBVTtTQUNYLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQUVELFNBQVMsY0FBYyxDQUFDLEtBQWM7SUFDcEMsc0JBQXNCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUIsT0FBTyxLQUFtQixDQUFDO0FBQzdCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxzQkFBc0I7SUFDakIsTUFBTSxDQUFrQjtJQUN4QixXQUFXLENBQXVCO0lBQ2xDLFdBQVcsQ0FBdUI7SUFDbEMsaUJBQWlCLENBQThCO0lBQy9DLFdBQVcsQ0FBK0I7SUFDMUMsSUFBSSxDQUE0QjtJQUNoQyxPQUFPLENBQW1CO0lBQ3pCLE9BQU8sQ0FBa0I7SUFFMUMsWUFBWSxPQUF1QztRQUNqRCxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxZQUFZLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sSUFBSSwwQkFBMEIsQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBQ3pGLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSwyQkFBMkIsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLDRCQUE0QixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUkseUJBQXlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7T0FHRztJQUNJLE9BQU87UUFDWixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSSxjQUFjLENBQUMsVUFBa0IsRUFBRSxPQUFPLEdBQWtDLEVBQUU7UUFDbkYsa0JBQWtCLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQzdDLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3RFLE1BQU0sSUFBSSwwQkFBMEIsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFDRCxPQUFPLE9BQU8sQ0FBQyxLQUFLO1lBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUM7WUFDekMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7Q0FDRiJ9
|
|
395
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ub3NxbGRic3RvcmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfc3RvcmVzX25vc3FsZGIvY2xhc3Nlcy5ub3NxbGRic3RvcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBb0I1RixPQUFPLEVBQ0wsNEJBQTRCLEVBQzVCLDRCQUE0QixFQUM1Qix1QkFBdUIsRUFDdkIsc0JBQXNCLEdBQ3ZCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLGlDQUFpQyxFQUNqQyxtQ0FBbUMsRUFDbkMsb0NBQW9DLEdBQ3JDLE1BQU0sa0NBQWtDLENBQUM7QUFDMUMsT0FBTyxFQUNMLHlCQUF5QixFQUN6QiwwQkFBMEIsRUFDMUIsNEJBQTRCLEdBQzdCLE1BQU0saUNBQWlDLENBQUM7QUFDekMsT0FBTyxFQUNMLHlCQUF5QixFQUN6QiwrQkFBK0IsRUFDL0IscUJBQXFCLEVBQ3JCLHlCQUF5QixFQUN6Qiw0QkFBNEIsRUFDNUIseUJBQXlCLEVBQ3pCLDBCQUEwQixHQUMzQixNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFDTCxtQ0FBbUMsRUFDbkMsdUJBQXVCLEVBQ3ZCLG9DQUFvQyxFQUNwQyxXQUFXLEVBQ1gsd0JBQXdCLEVBQ3hCLGtCQUFrQixFQUNsQixxQ0FBcUMsRUFDckMsbUJBQW1CLEVBQ25CLG9CQUFvQixHQUNyQixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFDTCxlQUFlLEdBR2hCLE1BQU0sMEJBQTBCLENBQUM7QUFFbEMseUZBQXlGO0FBQ3pGLFNBQVMsbUJBQW1CLENBQzFCLFFBQW1CLEVBQ25CLGdCQUF3QixFQUN4QixRQUEyQyxFQUMzQyxXQUF5QjtJQUV6QixPQUFPO1FBQ0wsTUFBTSxFQUFFLENBQUMsY0FB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
|
|
@@ -20,20 +20,66 @@ export interface IFlexRecordMutation<TValue> {
|
|
|
20
20
|
/** The conflict to report when concurrent writers keep winning the compare-and-swap. */
|
|
21
21
|
contention: (actualRevision: number) => Error;
|
|
22
22
|
}
|
|
23
|
+
/** A write that replaces the stored value whole, decided from the record's revision alone. */
|
|
24
|
+
export interface IFlexRecordReplacement {
|
|
25
|
+
/** Decides on the stored value from the head's revision, 0 for an absent record. */
|
|
26
|
+
decide: (actualRevision: number) => IFlexRecordWrite | undefined;
|
|
27
|
+
/** The conflict to report when concurrent writers keep winning the compare-and-swap. */
|
|
28
|
+
contention: (actualRevision: number) => Error;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* How a record holds a snapshot as a base plus the changes saved since. Every function throws a
|
|
32
|
+
* `FlexHarnessStoreFormatError` for a value it rejects.
|
|
33
|
+
*/
|
|
34
|
+
export interface IFlexRecordLog<TSnapshot extends {
|
|
35
|
+
revision: number;
|
|
36
|
+
}, TChange> {
|
|
37
|
+
/** Checks a snapshot in full. */
|
|
38
|
+
validate: (value: unknown) => TSnapshot;
|
|
39
|
+
/** Checks the form of a change. */
|
|
40
|
+
validateChange: (value: unknown) => TChange;
|
|
41
|
+
/** The snapshot `change` makes of `current`, before `validate` checks it. */
|
|
42
|
+
apply: (current: TSnapshot | undefined, change: TChange) => TSnapshot;
|
|
43
|
+
}
|
|
44
|
+
/** A change to save while the record's head holds `expectedRevision`; it makes the next one. */
|
|
45
|
+
export interface IFlexRecordChange<TChange> {
|
|
46
|
+
expectedRevision: number;
|
|
47
|
+
/** The change, already checked by the log's `validateChange`. */
|
|
48
|
+
value: TChange;
|
|
49
|
+
/** The conflict to report when the head holds another revision. */
|
|
50
|
+
conflict: (actualRevision: number) => Error;
|
|
51
|
+
}
|
|
23
52
|
export declare const FLEX_RECORD_COLLECTION = "flexharness_records";
|
|
24
53
|
export declare const FLEX_CHUNK_COLLECTION = "flexharness_chunks";
|
|
25
54
|
export declare const FLEX_NAMESPACE_COLLECTION = "flexharness_namespaces";
|
|
55
|
+
export declare const FLEX_CHANGE_COLLECTION = "flexharness_changes";
|
|
26
56
|
/**
|
|
27
57
|
* UTF-16 code units a record holds inline, and the size of each chunk of a longer payload. A
|
|
28
58
|
* chunk stays below 3 MiB of UTF-8, far under the 16 MiB document limit NoSQLDB and MongoDB
|
|
29
59
|
* enforce, so a record and each of its chunks always fit one document.
|
|
30
60
|
*/
|
|
31
61
|
export declare const FLEX_RECORD_CHUNK_CODE_UNITS: number;
|
|
62
|
+
/**
|
|
63
|
+
* UTF-16 code units the changes of a log may reach however short its base, so a young record
|
|
64
|
+
* keeps its changes instead of compacting on nearly every save.
|
|
65
|
+
*/
|
|
66
|
+
export declare const FLEX_RECORD_MIN_LOG_CODE_UNITS: number;
|
|
67
|
+
/**
|
|
68
|
+
* UTF-16 code units of changes a log record's head holds inline. The save that would exceed it
|
|
69
|
+
* moves them, with its own change, into one change page.
|
|
70
|
+
*/
|
|
71
|
+
export declare const FLEX_RECORD_INLINE_CHANGE_CODE_UNITS: number;
|
|
32
72
|
/**
|
|
33
73
|
* The head of one record. A payload up to one chunk is stored inline; a longer one lives in
|
|
34
74
|
* immutable chunks named by `blobId`. `writeToken` changes on every committed write and is the
|
|
35
75
|
* compare-and-swap fence. A head without payload or blob is a placeholder that reserves the
|
|
36
|
-
* record for a
|
|
76
|
+
* record for a first write longer than one chunk; it reads as absent.
|
|
77
|
+
*
|
|
78
|
+
* A log record's payload is a base, `{ base }`, always in chunks, and its head names a log,
|
|
79
|
+
* `logId`: the `changeCount` changes saved since the base. The head holds the latest of them in
|
|
80
|
+
* `recentChanges`; the earlier ones fill change pages, chained from `lastPageId` back to the log.
|
|
81
|
+
* A head without `logId`, also one an earlier version wrote, holds its value whole. A write that
|
|
82
|
+
* replaces a log names it `retiredLogId`, and the next write deletes its pages.
|
|
37
83
|
*/
|
|
38
84
|
export declare class FlexRecordDocument extends plugins.SmartDataDbDoc<FlexRecordDocument, FlexRecordDocument> {
|
|
39
85
|
recordId: string;
|
|
@@ -49,6 +95,21 @@ export declare class FlexRecordDocument extends plugins.SmartDataDbDoc<FlexRecor
|
|
|
49
95
|
/** Set before the first chunk of this record is written; the record's writes then sweep. */
|
|
50
96
|
chunked: boolean;
|
|
51
97
|
sweepCount: number;
|
|
98
|
+
/** The write token of the base's commit, which names the log; null without a log. */
|
|
99
|
+
logId: string | null;
|
|
100
|
+
changeCount: number;
|
|
101
|
+
/** The log's changes saved since its last page, oldest first; empty without a log. */
|
|
102
|
+
recentChanges: string[];
|
|
103
|
+
/** The log's latest change page; null while the log has none. */
|
|
104
|
+
lastPageId: string | null;
|
|
105
|
+
/**
|
|
106
|
+
* UTF-16 code units of the log's changes and of its base; a log outgrows neither its base nor,
|
|
107
|
+
* for a shorter base, `FLEX_RECORD_MIN_LOG_CODE_UNITS`.
|
|
108
|
+
*/
|
|
109
|
+
changeLength: number;
|
|
110
|
+
baseLength: number;
|
|
111
|
+
/** The log the last write replaced, whose pages the next write deletes; null without one. */
|
|
112
|
+
retiredLogId: string | null;
|
|
52
113
|
}
|
|
53
114
|
/** One immutable piece of a chunked payload, written against the head token it will replace. */
|
|
54
115
|
export declare class FlexChunkDocument extends plugins.SmartDataDbDoc<FlexChunkDocument, FlexChunkDocument> {
|
|
@@ -62,6 +123,20 @@ export declare class FlexChunkDocument extends plugins.SmartDataDbDoc<FlexChunkD
|
|
|
62
123
|
index: number;
|
|
63
124
|
data: string;
|
|
64
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* One immutable page of a log record's changes, oldest first, written before the head swap that
|
|
128
|
+
* commits it. `previousId` names the log's previous page, or the log itself for its first page.
|
|
129
|
+
*/
|
|
130
|
+
export declare class FlexChangePageDocument extends plugins.SmartDataDbDoc<FlexChangePageDocument, FlexChangePageDocument> {
|
|
131
|
+
pageId: string;
|
|
132
|
+
recordId: string;
|
|
133
|
+
domain: TFlexRecordDomain;
|
|
134
|
+
ownerKey: string;
|
|
135
|
+
namespaceKey: string;
|
|
136
|
+
logId: string;
|
|
137
|
+
previousId: string;
|
|
138
|
+
changes: string[];
|
|
139
|
+
}
|
|
65
140
|
/**
|
|
66
141
|
* One storage namespace. Every record creation in the namespace increments `creationCount` in
|
|
67
142
|
* its transaction, so a concurrent fenced purge, which sets `fenced`, conflicts with it. A fenced
|
|
@@ -72,6 +147,18 @@ export declare class FlexNamespaceDocument extends plugins.SmartDataDbDoc<FlexNa
|
|
|
72
147
|
fenced: boolean;
|
|
73
148
|
creationCount: number;
|
|
74
149
|
}
|
|
150
|
+
type TRecordModel = typeof FlexRecordDocument;
|
|
151
|
+
type TChunkModel = typeof FlexChunkDocument;
|
|
152
|
+
type TChangePageModel = typeof FlexChangePageDocument;
|
|
153
|
+
type TNamespaceModel = typeof FlexNamespaceDocument;
|
|
154
|
+
export interface IFlexRecordModels {
|
|
155
|
+
records: TRecordModel;
|
|
156
|
+
chunks: TChunkModel;
|
|
157
|
+
changes: TChangePageModel;
|
|
158
|
+
namespaces: TNamespaceModel;
|
|
159
|
+
}
|
|
160
|
+
/** Binds the record, chunk, change page and namespace models to a database. */
|
|
161
|
+
export declare function bindFlexRecordModels(db: plugins.SmartdataDb): IFlexRecordModels;
|
|
75
162
|
export interface IFlexRecordStoreOptions {
|
|
76
163
|
db: plugins.SmartdataDb;
|
|
77
164
|
operationTimeoutMs?: number;
|
|
@@ -82,12 +169,22 @@ export interface IFlexRecordStoreOptions {
|
|
|
82
169
|
* replaced or abandoned payload are swept in a transaction that also touches the head, so a
|
|
83
170
|
* concurrent deletion or writer can never lose chunks its head references. A head is created in
|
|
84
171
|
* a transaction that checks its namespace document, so a fenced namespace gains no record.
|
|
172
|
+
*
|
|
173
|
+
* A log record takes a change in the head swap itself, which appends it to the head's recent
|
|
174
|
+
* changes, so a save costs the change rather than the record and reads and writes only the head.
|
|
175
|
+
* The save that would grow the recent changes past `FLEX_RECORD_INLINE_CHANGE_CODE_UNITS` writes
|
|
176
|
+
* them, with its own change, as one change page first and empties them in its swap. The base lives
|
|
177
|
+
* in chunks whatever its length, so the head the swap rewrites holds no payload. Once the changes
|
|
178
|
+
* would outgrow the base, or a shorter base's minimum room, a save compacts the record instead: it
|
|
179
|
+
* writes the base with every change applied, checked in full.
|
|
180
|
+
* The change pages of earlier logs are swept like chunks.
|
|
85
181
|
*/
|
|
86
182
|
export declare class FlexRecordStore {
|
|
87
183
|
private readonly db;
|
|
88
184
|
private readonly timeoutMs;
|
|
89
185
|
private readonly records;
|
|
90
186
|
private readonly chunks;
|
|
187
|
+
private readonly changes;
|
|
91
188
|
private readonly namespaces;
|
|
92
189
|
private preparation?;
|
|
93
190
|
constructor(options: IFlexRecordStoreOptions);
|
|
@@ -96,48 +193,108 @@ export declare class FlexRecordStore {
|
|
|
96
193
|
private prepareCollections;
|
|
97
194
|
private resolve;
|
|
98
195
|
read<TValue>(address: IFlexRecordAddress, validate: (value: unknown) => TValue): Promise<TValue | undefined>;
|
|
196
|
+
/** Reads a log record: its base with every change applied, checked in full. */
|
|
197
|
+
readLog<TSnapshot extends {
|
|
198
|
+
revision: number;
|
|
199
|
+
}, TChange>(address: IFlexRecordAddress, log: IFlexRecordLog<TSnapshot, TChange>): Promise<TSnapshot | undefined>;
|
|
200
|
+
/**
|
|
201
|
+
* Saves a change to a log record while its head holds the expected revision. Only the head is
|
|
202
|
+
* read when the record takes the change; a compaction loads the record and checks the result in
|
|
203
|
+
* full. A change the record takes is checked in form only, by the caller; its content is checked
|
|
204
|
+
* once a compaction or a read applies it.
|
|
205
|
+
*/
|
|
206
|
+
append<TSnapshot extends {
|
|
207
|
+
revision: number;
|
|
208
|
+
}, TChange>(address: IFlexRecordAddress, log: IFlexRecordLog<TSnapshot, TChange>, change: IFlexRecordChange<TChange>): Promise<void>;
|
|
99
209
|
mutate<TValue>(address: IFlexRecordAddress, mutation: IFlexRecordMutation<TValue>): Promise<void>;
|
|
100
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* Replaces a record's value on a decision from its revision alone. Only the head is read: the
|
|
212
|
+
* stored payload and its chunks are neither loaded nor validated, since the write replaces them.
|
|
213
|
+
*/
|
|
214
|
+
replace(address: IFlexRecordAddress, replacement: IFlexRecordReplacement): Promise<void>;
|
|
215
|
+
/** Decides and commits until a head swap wins or a decision writes nothing. */
|
|
216
|
+
private swap;
|
|
217
|
+
/** Deletes one record with its chunks and change pages. */
|
|
101
218
|
delete(address: IFlexRecordAddress): Promise<void>;
|
|
102
|
-
/** Deletes every record and
|
|
219
|
+
/** Deletes every record, chunk and change page one session owns in the given domains. */
|
|
103
220
|
deleteOwner(storageKey: string, sessionId: string, domains: readonly TFlexRecordDomain[]): Promise<void>;
|
|
104
221
|
/**
|
|
105
|
-
* Deletes every record and
|
|
106
|
-
* together with its namespace document unless a fence holds it.
|
|
222
|
+
* Deletes every record, chunk and change page of a storage namespace in one domain, or in every
|
|
223
|
+
* domain together with its namespace document unless a fence holds it.
|
|
107
224
|
*/
|
|
108
225
|
purgeNamespace(storageKey: string, domain?: TFlexRecordDomain): Promise<void>;
|
|
109
226
|
/**
|
|
110
|
-
* Fences a storage namespace and deletes every record and
|
|
111
|
-
* fence is permanent: every later record creation in the namespace is refused,
|
|
112
|
-
* that runs concurrently either commits first and is deleted, or conflicts and is
|
|
227
|
+
* Fences a storage namespace and deletes every record, chunk and change page of it in one
|
|
228
|
+
* transaction. The fence is permanent: every later record creation in the namespace is refused,
|
|
229
|
+
* and a creation that runs concurrently either commits first and is deleted, or conflicts and is
|
|
230
|
+
* refused.
|
|
113
231
|
*/
|
|
114
232
|
fenceNamespace(storageKey: string): Promise<void>;
|
|
115
|
-
/** Deletes the selected records and
|
|
233
|
+
/** Deletes the selected records, chunks and change pages, after `namespace` changes the namespace document. */
|
|
116
234
|
private deleteInTransaction;
|
|
117
235
|
private parse;
|
|
236
|
+
/** Runs a check of stored data and names the record in a format error it throws. */
|
|
237
|
+
private check;
|
|
118
238
|
private findHead;
|
|
119
239
|
private readHead;
|
|
240
|
+
/**
|
|
241
|
+
* Loads a log record with the head it was read at. A head without a log holds its value whole;
|
|
242
|
+
* a base must be wrapped, so a version that reads values whole fails on it.
|
|
243
|
+
*/
|
|
244
|
+
private loadLog;
|
|
245
|
+
/**
|
|
246
|
+
* The data of the head's changes, oldest first: its pages, found by walking back from its last
|
|
247
|
+
* page to its log, then its recent changes. Undefined when the pages are incomplete.
|
|
248
|
+
*/
|
|
249
|
+
private readChanges;
|
|
250
|
+
/** The base with every change applied, checked in full and at the head's revision. */
|
|
251
|
+
private fold;
|
|
120
252
|
private readBlob;
|
|
121
|
-
/**
|
|
253
|
+
/**
|
|
254
|
+
* Writes the value whole, or as the base of a new log, empty, when `log` is set; a base always
|
|
255
|
+
* goes into chunks. Returns false when another writer swapped the head first; nothing of this
|
|
256
|
+
* write remains.
|
|
257
|
+
*/
|
|
122
258
|
private commit;
|
|
259
|
+
/**
|
|
260
|
+
* Whether the record takes a change: a log that stays no longer than its base, or than the
|
|
261
|
+
* minimum room of a shorter base. A head whose recent changes are no list takes none, so the
|
|
262
|
+
* compaction's read refuses it.
|
|
263
|
+
*/
|
|
264
|
+
private takesChange;
|
|
265
|
+
/**
|
|
266
|
+
* Appends a change to the head's recent changes in the head swap, or, when they would grow past
|
|
267
|
+
* their inline room, writes them with the change as a new page and empties them in the swap.
|
|
268
|
+
* Returns false when another writer swapped the head first; nothing of this write remains.
|
|
269
|
+
*/
|
|
270
|
+
private commitChange;
|
|
123
271
|
private newHead;
|
|
272
|
+
/**
|
|
273
|
+
* Creates the record with a first payload of up to one chunk in one transaction: inline, or as
|
|
274
|
+
* the single chunk of a log's base. The creation never touches the head again, so a concurrent
|
|
275
|
+
* fenced purge conflicts with it at most once.
|
|
276
|
+
*/
|
|
124
277
|
private insertHead;
|
|
125
|
-
/** Reserves the record for a
|
|
278
|
+
/** Reserves the record for a first write longer than one chunk, so its chunks have a head token to replace. */
|
|
126
279
|
private insertPlaceholder;
|
|
127
280
|
/**
|
|
128
|
-
* Inserts a new head unless a fence holds its namespace.
|
|
129
|
-
* namespace document, so it conflicts with a concurrent
|
|
130
|
-
* retries on a snapshot that holds the other. Returns
|
|
131
|
-
* record first.
|
|
281
|
+
* Inserts a new head, and the chunk it references if any, unless a fence holds its namespace.
|
|
282
|
+
* The transaction also increments the namespace document, so it conflicts with a concurrent
|
|
283
|
+
* fenced purge: whichever commits second retries on a snapshot that holds the other. Returns
|
|
284
|
+
* false when another writer created the record first.
|
|
132
285
|
*/
|
|
133
286
|
private create;
|
|
134
287
|
private markChunked;
|
|
135
288
|
private writeBlob;
|
|
289
|
+
private newChunk;
|
|
136
290
|
/**
|
|
137
|
-
* Deletes the record's chunks that no head can reference any more: every blob
|
|
138
|
-
* one that was written against another head token
|
|
139
|
-
*
|
|
140
|
-
*
|
|
291
|
+
* Deletes the record's chunks and change pages that no head can reference any more: every blob
|
|
292
|
+
* but the current one that was written against another head token, and every page of the log the
|
|
293
|
+
* last write retired, found by its index rather than by scanning the current log's pages. A
|
|
294
|
+
* writer that read the current token keeps its chunks.
|
|
295
|
+
* Touching the head in the same transaction makes a concurrent deletion conflict, so chunks and
|
|
296
|
+
* pages written after a deletion are never swept by a transaction that predates it.
|
|
141
297
|
*/
|
|
142
298
|
private sweep;
|
|
143
299
|
}
|
|
300
|
+
export {};
|