@vrtmrz/livesync-commonlib 0.1.33 → 0.1.35
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/common/models/setting.policy.d.ts +808 -0
- package/dist/common/models/setting.policy.js +298 -0
- package/dist/common/utils.patch.js +49 -30
- package/dist/managers/ChunkFetcher.d.ts +16 -0
- package/dist/managers/ChunkFetcher.js +231 -82
- package/dist/managers/chunkFetcher.helper.d.ts +21 -0
- package/dist/managers/chunkFetcher.helper.js +43 -0
- package/dist/mock_and_interop/stores.d.ts +4 -0
- package/dist/mock_and_interop/stores.js +2 -0
- package/dist/services/base/SettingService.d.ts +2 -1
- package/dist/services/base/SettingService.js +42 -63
- package/dist/services/implements/injectable/InjectableSettingService.d.ts +2 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.js +10 -0
- package/docs/proven-in-use.md +7 -1
- package/docs/settings-lifecycle.md +13 -1
- package/package.json +1 -1
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import { DEFAULT_SETTINGS } from "./setting.const.defaults.js";
|
|
2
|
+
const SettingPolicies = {
|
|
3
|
+
Default: { markdown: "include", persistence: "include" },
|
|
4
|
+
LocalOnly: { markdown: "omit", persistence: "include" },
|
|
5
|
+
DeviceLocal: { markdown: "include", persistence: "device" },
|
|
6
|
+
MarkdownCredentials: { markdown: "credentials", persistence: "include" },
|
|
7
|
+
RemoteProfiles: { markdown: "credentials", persistence: "profiles" },
|
|
8
|
+
LocalConnection: { markdown: "include", persistence: "connection" },
|
|
9
|
+
ConnectionCredentials: { markdown: "credentials", persistence: "connection" },
|
|
10
|
+
ConnectionContext: { markdown: "include", persistence: "connection-context" },
|
|
11
|
+
E2EEPassphrase: { markdown: "credentials", persistence: "passphrase" },
|
|
12
|
+
IdDerivationKey: { markdown: "credentials", persistence: "id-key" },
|
|
13
|
+
RuntimeOnly: { markdown: "omit", persistence: "omit" }
|
|
14
|
+
};
|
|
15
|
+
const SETTINGS_PROPERTY_POLICY = {
|
|
16
|
+
liveSync: SettingPolicies.Default,
|
|
17
|
+
syncOnSave: SettingPolicies.Default,
|
|
18
|
+
syncOnStart: SettingPolicies.Default,
|
|
19
|
+
syncOnFileOpen: SettingPolicies.Default,
|
|
20
|
+
syncOnEditorSave: SettingPolicies.Default,
|
|
21
|
+
keepReplicationActiveInBackground: SettingPolicies.Default,
|
|
22
|
+
allowSleepDuringSynchronisation: SettingPolicies.Default,
|
|
23
|
+
allowSleepDuringSynchronisationOnDesktop: SettingPolicies.Default,
|
|
24
|
+
syncMinimumInterval: SettingPolicies.Default,
|
|
25
|
+
showVerboseLog: SettingPolicies.Default,
|
|
26
|
+
lessInformationInLog: SettingPolicies.Default,
|
|
27
|
+
showLongerLogInsideEditor: SettingPolicies.Default,
|
|
28
|
+
showStatusOnEditor: SettingPolicies.Default,
|
|
29
|
+
showStatusOnStatusbar: SettingPolicies.Default,
|
|
30
|
+
showOnlyIconsOnEditor: SettingPolicies.Default,
|
|
31
|
+
hideFileWarningNotice: SettingPolicies.Default,
|
|
32
|
+
networkWarningStyle: SettingPolicies.Default,
|
|
33
|
+
displayLanguage: SettingPolicies.Default,
|
|
34
|
+
trashInsteadDelete: SettingPolicies.Default,
|
|
35
|
+
doNotDeleteFolder: SettingPolicies.Default,
|
|
36
|
+
batchSave: SettingPolicies.Default,
|
|
37
|
+
batchSaveMinimumDelay: SettingPolicies.Default,
|
|
38
|
+
batchSaveMaximumDelay: SettingPolicies.Default,
|
|
39
|
+
syncMaxSizeInMB: SettingPolicies.Default,
|
|
40
|
+
useIgnoreFiles: SettingPolicies.Default,
|
|
41
|
+
ignoreFiles: SettingPolicies.Default,
|
|
42
|
+
processSizeMismatchedFiles: SettingPolicies.Default,
|
|
43
|
+
syncOnlyRegEx: SettingPolicies.Default,
|
|
44
|
+
syncIgnoreRegEx: SettingPolicies.Default,
|
|
45
|
+
syncAfterMerge: SettingPolicies.Default,
|
|
46
|
+
resolveConflictsByNewerFile: SettingPolicies.Default,
|
|
47
|
+
writeDocumentsIfConflicted: SettingPolicies.Default,
|
|
48
|
+
disableMarkdownAutoMerge: SettingPolicies.Default,
|
|
49
|
+
configPassphraseStore: SettingPolicies.Default,
|
|
50
|
+
encryptedPassphrase: SettingPolicies.LocalOnly,
|
|
51
|
+
encryptedIdDerivationKey: SettingPolicies.LocalOnly,
|
|
52
|
+
encryptedCouchDBConnection: SettingPolicies.LocalOnly,
|
|
53
|
+
periodicReplication: SettingPolicies.Default,
|
|
54
|
+
periodicReplicationInterval: SettingPolicies.Default,
|
|
55
|
+
syncInternalFiles: SettingPolicies.Default,
|
|
56
|
+
syncInternalFilesBeforeReplication: SettingPolicies.Default,
|
|
57
|
+
syncInternalFilesInterval: SettingPolicies.Default,
|
|
58
|
+
syncInternalFilesIgnorePatterns: SettingPolicies.Default,
|
|
59
|
+
syncInternalFilesTargetPatterns: SettingPolicies.Default,
|
|
60
|
+
watchInternalFileChanges: SettingPolicies.Default,
|
|
61
|
+
suppressNotifyHiddenFilesChange: SettingPolicies.Default,
|
|
62
|
+
syncInternalFileOverwritePatterns: SettingPolicies.Default,
|
|
63
|
+
usePluginSync: SettingPolicies.Default,
|
|
64
|
+
usePluginSettings: SettingPolicies.Default,
|
|
65
|
+
showOwnPlugins: SettingPolicies.Default,
|
|
66
|
+
autoSweepPlugins: SettingPolicies.Default,
|
|
67
|
+
autoSweepPluginsPeriodic: SettingPolicies.Default,
|
|
68
|
+
notifyPluginOrSettingUpdated: SettingPolicies.Default,
|
|
69
|
+
deviceAndVaultName: SettingPolicies.DeviceLocal,
|
|
70
|
+
usePluginSyncV2: SettingPolicies.Default,
|
|
71
|
+
usePluginEtc: SettingPolicies.Default,
|
|
72
|
+
pluginSyncExtendedSetting: SettingPolicies.Default,
|
|
73
|
+
useAdvancedMode: SettingPolicies.Default,
|
|
74
|
+
usePowerUserMode: SettingPolicies.Default,
|
|
75
|
+
useEdgeCaseMode: SettingPolicies.Default,
|
|
76
|
+
notifyThresholdOfRemoteStorageSize: SettingPolicies.Default,
|
|
77
|
+
disableWorkerForGeneratingChunks: SettingPolicies.Default,
|
|
78
|
+
processSmallFilesInUIThread: SettingPolicies.Default,
|
|
79
|
+
savingDelay: SettingPolicies.Default,
|
|
80
|
+
gcDelay: SettingPolicies.Default,
|
|
81
|
+
skipOlderFilesOnSync: SettingPolicies.Default,
|
|
82
|
+
useIndexedDBAdapter: SettingPolicies.Default,
|
|
83
|
+
enableDebugTools: SettingPolicies.Default,
|
|
84
|
+
writeLogToTheFile: SettingPolicies.Default,
|
|
85
|
+
settingSyncFile: SettingPolicies.Default,
|
|
86
|
+
writeCredentialsForSettingSync: SettingPolicies.Default,
|
|
87
|
+
notifyAllSettingSyncFile: SettingPolicies.Default,
|
|
88
|
+
suspendFileWatching: SettingPolicies.Default,
|
|
89
|
+
suspendParseReplicationResult: SettingPolicies.Default,
|
|
90
|
+
doNotSuspendOnFetching: SettingPolicies.Default,
|
|
91
|
+
maxMTimeForReflectEvents: SettingPolicies.Default,
|
|
92
|
+
versionUpFlash: SettingPolicies.Default,
|
|
93
|
+
settingVersion: SettingPolicies.Default,
|
|
94
|
+
isConfigured: SettingPolicies.Default,
|
|
95
|
+
lastReadUpdates: SettingPolicies.Default,
|
|
96
|
+
doctorProcessedVersion: SettingPolicies.Default,
|
|
97
|
+
remoteConfigurations: SettingPolicies.RemoteProfiles,
|
|
98
|
+
activeConfigurationId: SettingPolicies.MarkdownCredentials,
|
|
99
|
+
P2P_ActiveRemoteConfigurationId: SettingPolicies.MarkdownCredentials,
|
|
100
|
+
couchDB_URI: SettingPolicies.LocalConnection,
|
|
101
|
+
couchDB_USER: SettingPolicies.ConnectionCredentials,
|
|
102
|
+
couchDB_PASSWORD: SettingPolicies.ConnectionCredentials,
|
|
103
|
+
couchDB_DBNAME: SettingPolicies.LocalConnection,
|
|
104
|
+
couchDB_CustomHeaders: SettingPolicies.ConnectionCredentials,
|
|
105
|
+
useJWT: SettingPolicies.Default,
|
|
106
|
+
jwtAlgorithm: SettingPolicies.Default,
|
|
107
|
+
jwtKey: SettingPolicies.ConnectionCredentials,
|
|
108
|
+
jwtKid: SettingPolicies.ConnectionCredentials,
|
|
109
|
+
jwtSub: SettingPolicies.ConnectionCredentials,
|
|
110
|
+
jwtExpDuration: SettingPolicies.Default,
|
|
111
|
+
useRequestAPI: SettingPolicies.Default,
|
|
112
|
+
accessKey: SettingPolicies.ConnectionCredentials,
|
|
113
|
+
secretKey: SettingPolicies.ConnectionCredentials,
|
|
114
|
+
bucket: SettingPolicies.LocalConnection,
|
|
115
|
+
region: SettingPolicies.ConnectionContext,
|
|
116
|
+
endpoint: SettingPolicies.LocalConnection,
|
|
117
|
+
useCustomRequestHandler: SettingPolicies.Default,
|
|
118
|
+
bucketCustomHeaders: SettingPolicies.ConnectionCredentials,
|
|
119
|
+
bucketPrefix: SettingPolicies.Default,
|
|
120
|
+
forcePathStyle: SettingPolicies.Default,
|
|
121
|
+
remoteType: SettingPolicies.Default,
|
|
122
|
+
encrypt: SettingPolicies.Default,
|
|
123
|
+
passphrase: SettingPolicies.E2EEPassphrase,
|
|
124
|
+
idDerivationVersion: SettingPolicies.MarkdownCredentials,
|
|
125
|
+
idDerivationKey: SettingPolicies.IdDerivationKey,
|
|
126
|
+
usePathObfuscation: SettingPolicies.Default,
|
|
127
|
+
encryptInternalMetadata: SettingPolicies.Default,
|
|
128
|
+
E2EEAlgorithm: SettingPolicies.Default,
|
|
129
|
+
hashAlg: SettingPolicies.Default,
|
|
130
|
+
minimumChunkSize: SettingPolicies.Default,
|
|
131
|
+
customChunkSize: SettingPolicies.Default,
|
|
132
|
+
longLineThreshold: SettingPolicies.Default,
|
|
133
|
+
useSegmenter: SettingPolicies.Default,
|
|
134
|
+
enableChunkSplitterV2: SettingPolicies.Default,
|
|
135
|
+
doNotUseFixedRevisionForChunks: SettingPolicies.Default,
|
|
136
|
+
chunkSplitterVersion: SettingPolicies.Default,
|
|
137
|
+
useEden: SettingPolicies.Default,
|
|
138
|
+
maxChunksInEden: SettingPolicies.Default,
|
|
139
|
+
maxTotalLengthInEden: SettingPolicies.Default,
|
|
140
|
+
maxAgeInEden: SettingPolicies.Default,
|
|
141
|
+
tweakModified: SettingPolicies.Default,
|
|
142
|
+
checkIntegrityOnSave: SettingPolicies.Default,
|
|
143
|
+
useHistory: SettingPolicies.Default,
|
|
144
|
+
disableRequestURI: SettingPolicies.Default,
|
|
145
|
+
sendChunksBulk: SettingPolicies.Default,
|
|
146
|
+
sendChunksBulkMaxSize: SettingPolicies.Default,
|
|
147
|
+
useDynamicIterationCount: SettingPolicies.Default,
|
|
148
|
+
doNotPaceReplication: SettingPolicies.Default,
|
|
149
|
+
readChunksOnline: SettingPolicies.Default,
|
|
150
|
+
useOnlyLocalChunk: SettingPolicies.Default,
|
|
151
|
+
concurrencyOfReadChunksOnline: SettingPolicies.Default,
|
|
152
|
+
minimumIntervalOfReadChunksOnline: SettingPolicies.Default,
|
|
153
|
+
enableCompression: SettingPolicies.Default,
|
|
154
|
+
batch_size: SettingPolicies.Default,
|
|
155
|
+
batches_limit: SettingPolicies.Default,
|
|
156
|
+
ignoreVersionCheck: SettingPolicies.Default,
|
|
157
|
+
disableCheckingConfigMismatch: SettingPolicies.Default,
|
|
158
|
+
autoAcceptCompatibleTweak: SettingPolicies.Default,
|
|
159
|
+
hashCacheMaxCount: SettingPolicies.Default,
|
|
160
|
+
hashCacheMaxAmount: SettingPolicies.Default,
|
|
161
|
+
permitEmptyPassphrase: SettingPolicies.Default,
|
|
162
|
+
handleFilenameCaseSensitive: SettingPolicies.Default,
|
|
163
|
+
checkConflictOnlyOnOpen: SettingPolicies.Default,
|
|
164
|
+
showMergeDialogOnlyOnActive: SettingPolicies.Default,
|
|
165
|
+
additionalSuffixOfDatabaseName: SettingPolicies.LocalOnly,
|
|
166
|
+
useTimeouts: SettingPolicies.Default,
|
|
167
|
+
deleteMetadataOfDeletedFiles: SettingPolicies.Default,
|
|
168
|
+
automaticallyDeleteMetadataOfDeletedFiles: SettingPolicies.Default,
|
|
169
|
+
P2P_AutoAccepting: SettingPolicies.Default,
|
|
170
|
+
P2P_AutoSyncPeers: SettingPolicies.Default,
|
|
171
|
+
P2P_AutoWatchPeers: SettingPolicies.Default,
|
|
172
|
+
P2P_SyncOnReplication: SettingPolicies.Default,
|
|
173
|
+
P2P_RebuildFrom: SettingPolicies.Default,
|
|
174
|
+
P2P_AutoAcceptingPeers: SettingPolicies.Default,
|
|
175
|
+
P2P_AutoDenyingPeers: SettingPolicies.Default,
|
|
176
|
+
P2P_IsHeadless: SettingPolicies.Default,
|
|
177
|
+
P2P_iceServers: SettingPolicies.RuntimeOnly,
|
|
178
|
+
P2P_iceServersExpiresAt: SettingPolicies.RuntimeOnly,
|
|
179
|
+
P2P_Enabled: SettingPolicies.Default,
|
|
180
|
+
P2P_relays: SettingPolicies.Default,
|
|
181
|
+
P2P_roomID: SettingPolicies.Default,
|
|
182
|
+
P2P_passphrase: SettingPolicies.MarkdownCredentials,
|
|
183
|
+
P2P_AppID: SettingPolicies.Default,
|
|
184
|
+
P2P_AutoStart: SettingPolicies.Default,
|
|
185
|
+
P2P_AutoBroadcast: SettingPolicies.Default,
|
|
186
|
+
P2P_DevicePeerName: SettingPolicies.DeviceLocal,
|
|
187
|
+
P2P_turnServers: SettingPolicies.Default,
|
|
188
|
+
P2P_turnUsername: SettingPolicies.MarkdownCredentials,
|
|
189
|
+
P2P_turnCredential: SettingPolicies.MarkdownCredentials,
|
|
190
|
+
P2P_managedType: SettingPolicies.RuntimeOnly,
|
|
191
|
+
P2P_managedId: SettingPolicies.RuntimeOnly,
|
|
192
|
+
P2P_managedToken: SettingPolicies.RuntimeOnly,
|
|
193
|
+
P2P_maxWirePayloadBytes: SettingPolicies.Default,
|
|
194
|
+
P2P_connectionPath: SettingPolicies.Default,
|
|
195
|
+
P2P_useDiagRTC: SettingPolicies.Default
|
|
196
|
+
};
|
|
197
|
+
const settingKeys = Object.keys(SETTINGS_PROPERTY_POLICY);
|
|
198
|
+
const protectedConnectionKeys = settingKeys.filter(
|
|
199
|
+
(key) => SETTINGS_PROPERTY_POLICY[key].persistence === "connection"
|
|
200
|
+
);
|
|
201
|
+
const connectionKeys = settingKeys.filter(
|
|
202
|
+
(key) => SETTINGS_PROPERTY_POLICY[key].persistence === "connection" || SETTINGS_PROPERTY_POLICY[key].persistence === "connection-context"
|
|
203
|
+
);
|
|
204
|
+
const omittedPersistenceKeys = settingKeys.filter((key) => SETTINGS_PROPERTY_POLICY[key].persistence === "omit");
|
|
205
|
+
function copySetting(target, source, key) {
|
|
206
|
+
if (key in source) target[key] = source[key];
|
|
207
|
+
else delete target[key];
|
|
208
|
+
}
|
|
209
|
+
function cloneProfiles(settings) {
|
|
210
|
+
const profiles = {};
|
|
211
|
+
for (const [id, profile] of Object.entries(settings.remoteConfigurations ?? {})) {
|
|
212
|
+
Object.defineProperty(profiles, id, {
|
|
213
|
+
value: { ...profile },
|
|
214
|
+
enumerable: true,
|
|
215
|
+
configurable: true,
|
|
216
|
+
writable: true
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return profiles;
|
|
220
|
+
}
|
|
221
|
+
function createMarkdownSettings(settings, includeCredentials = settings.writeCredentialsForSettingSync === true) {
|
|
222
|
+
const output = {};
|
|
223
|
+
for (const key of settingKeys) {
|
|
224
|
+
const action = SETTINGS_PROPERTY_POLICY[key].markdown;
|
|
225
|
+
if (action === "omit" || action === "credentials" && !includeCredentials) continue;
|
|
226
|
+
copySetting(output, settings, key);
|
|
227
|
+
}
|
|
228
|
+
if (output.remoteConfigurations) output.remoteConfigurations = cloneProfiles(output);
|
|
229
|
+
return output;
|
|
230
|
+
}
|
|
231
|
+
function mergeMarkdownSettings(incoming, current) {
|
|
232
|
+
const merged = { ...DEFAULT_SETTINGS, ...incoming };
|
|
233
|
+
for (const key of settingKeys) {
|
|
234
|
+
const action = SETTINGS_PROPERTY_POLICY[key].markdown;
|
|
235
|
+
if (action === "omit" || action === "credentials" && merged.writeCredentialsForSettingSync !== true) {
|
|
236
|
+
copySetting(merged, current, key);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
merged.remoteConfigurations = cloneProfiles(merged);
|
|
240
|
+
return merged;
|
|
241
|
+
}
|
|
242
|
+
function selectConnectionSettings(settings) {
|
|
243
|
+
const connection = {};
|
|
244
|
+
for (const key of connectionKeys) connection[key] = settings[key];
|
|
245
|
+
return connection;
|
|
246
|
+
}
|
|
247
|
+
function hasConnectionSettings(settings) {
|
|
248
|
+
return protectedConnectionKeys.some((key) => settings[key] !== "");
|
|
249
|
+
}
|
|
250
|
+
function clearConnectionSettings(settings) {
|
|
251
|
+
for (const key of connectionKeys) settings[key] = "";
|
|
252
|
+
}
|
|
253
|
+
function restoreConnectionSettings(settings, payload) {
|
|
254
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) return false;
|
|
255
|
+
const connection = payload;
|
|
256
|
+
if (connectionKeys.some((key) => key in connection && typeof connection[key] !== "string")) return false;
|
|
257
|
+
for (const key of connectionKeys) {
|
|
258
|
+
if (key in connection) settings[key] = connection[key];
|
|
259
|
+
}
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
function omitUnpersistedSettings(settings) {
|
|
263
|
+
for (const key of omittedPersistenceKeys) delete settings[key];
|
|
264
|
+
}
|
|
265
|
+
function requireConfigurationCiphertext(value) {
|
|
266
|
+
if (value === "") throw new Error("Failed to encrypt configuration. Settings were not saved.");
|
|
267
|
+
return value;
|
|
268
|
+
}
|
|
269
|
+
function prepareSettingsForPersistence(settings) {
|
|
270
|
+
if (hasConnectionSettings(settings)) throw new Error("Connection settings were not prepared for persistence.");
|
|
271
|
+
if (settings.encrypt && settings.passphrase !== "")
|
|
272
|
+
throw new Error("The passphrase was not prepared for persistence.");
|
|
273
|
+
if (settings.idDerivationVersion === 1 && settings.idDerivationKey !== "") {
|
|
274
|
+
throw new Error("The ID derivation key was not prepared for persistence.");
|
|
275
|
+
}
|
|
276
|
+
if (omittedPersistenceKeys.some((key) => key in settings)) {
|
|
277
|
+
throw new Error("Runtime settings were not removed before persistence.");
|
|
278
|
+
}
|
|
279
|
+
if (settings.configPassphraseStore !== "" && Object.values(settings.remoteConfigurations).some(
|
|
280
|
+
(profile) => profile.uri.trim() !== "" && !profile.isEncrypted
|
|
281
|
+
)) {
|
|
282
|
+
throw new Error("Remote configurations were not prepared for persistence.");
|
|
283
|
+
}
|
|
284
|
+
return settings;
|
|
285
|
+
}
|
|
286
|
+
export {
|
|
287
|
+
SETTINGS_PROPERTY_POLICY,
|
|
288
|
+
SettingPolicies,
|
|
289
|
+
clearConnectionSettings,
|
|
290
|
+
createMarkdownSettings,
|
|
291
|
+
hasConnectionSettings,
|
|
292
|
+
mergeMarkdownSettings,
|
|
293
|
+
omitUnpersistedSettings,
|
|
294
|
+
prepareSettingsForPersistence,
|
|
295
|
+
requireConfigurationCiphertext,
|
|
296
|
+
restoreConnectionSettings,
|
|
297
|
+
selectConnectionSettings
|
|
298
|
+
};
|
|
@@ -2,6 +2,17 @@ const MARK_OPERATOR = ``;
|
|
|
2
2
|
const MARK_DELETED = `${MARK_OPERATOR}__DELETED`;
|
|
3
3
|
const MARK_ISARRAY = `${MARK_OPERATOR}__ARRAY`;
|
|
4
4
|
const MARK_SWAPPED = `${MARK_OPERATOR}__SWAP`;
|
|
5
|
+
function hasOwnProperty(target, key) {
|
|
6
|
+
return Object.prototype.hasOwnProperty.call(target, key);
|
|
7
|
+
}
|
|
8
|
+
function setOwnProperty(target, key, value) {
|
|
9
|
+
Object.defineProperty(target, key, {
|
|
10
|
+
value,
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true
|
|
14
|
+
});
|
|
15
|
+
}
|
|
5
16
|
function unorderedArrayToObject(obj) {
|
|
6
17
|
return obj.map((e) => ({ [e.id]: e })).reduce((p, c) => ({ ...p, ...c }), {});
|
|
7
18
|
}
|
|
@@ -30,34 +41,34 @@ function generatePatchObj(from, to) {
|
|
|
30
41
|
const newEntries = Object.entries(to);
|
|
31
42
|
for (const [key, value] of newEntries) {
|
|
32
43
|
if (!tempMap.has(key)) {
|
|
33
|
-
ret
|
|
44
|
+
setOwnProperty(ret, key, value);
|
|
34
45
|
tempMap.delete(key);
|
|
35
46
|
} else {
|
|
36
47
|
const v = tempMap.get(key);
|
|
37
48
|
if (typeof v !== typeof value || Array.isArray(v) !== Array.isArray(value)) {
|
|
38
|
-
ret
|
|
49
|
+
setOwnProperty(ret, key, { [MARK_SWAPPED]: value });
|
|
39
50
|
} else {
|
|
40
51
|
if (v === null && value === null) {
|
|
41
52
|
} else if (v === null && value !== null) {
|
|
42
|
-
ret
|
|
53
|
+
setOwnProperty(ret, key, { [MARK_SWAPPED]: value });
|
|
43
54
|
} else if (v !== null && value === null) {
|
|
44
|
-
ret
|
|
55
|
+
setOwnProperty(ret, key, { [MARK_SWAPPED]: value });
|
|
45
56
|
} else if (typeof v == "object" && typeof value == "object" && !Array.isArray(v) && !Array.isArray(value)) {
|
|
46
57
|
const wk = generatePatchObj(
|
|
47
58
|
v,
|
|
48
59
|
value
|
|
49
60
|
);
|
|
50
|
-
if (Object.keys(wk).length > 0) ret
|
|
61
|
+
if (Object.keys(wk).length > 0) setOwnProperty(ret, key, wk);
|
|
51
62
|
} else if (typeof v == "object" && typeof value == "object" && Array.isArray(v) && Array.isArray(value)) {
|
|
52
63
|
const wk = generatePatchUnorderedArray(v, value);
|
|
53
|
-
if (Object.keys(wk).length > 0) ret
|
|
64
|
+
if (Object.keys(wk).length > 0) setOwnProperty(ret, key, wk);
|
|
54
65
|
} else if (typeof v != "object" && typeof value != "object") {
|
|
55
66
|
if (JSON.stringify(tempMap.get(key)) !== JSON.stringify(value)) {
|
|
56
|
-
ret
|
|
67
|
+
setOwnProperty(ret, key, value);
|
|
57
68
|
}
|
|
58
69
|
} else {
|
|
59
70
|
if (JSON.stringify(tempMap.get(key)) !== JSON.stringify(value)) {
|
|
60
|
-
ret
|
|
71
|
+
setOwnProperty(ret, key, { [MARK_SWAPPED]: value });
|
|
61
72
|
}
|
|
62
73
|
}
|
|
63
74
|
}
|
|
@@ -65,7 +76,7 @@ function generatePatchObj(from, to) {
|
|
|
65
76
|
}
|
|
66
77
|
}
|
|
67
78
|
for (const [key] of tempMap) {
|
|
68
|
-
ret
|
|
79
|
+
setOwnProperty(ret, key, MARK_DELETED);
|
|
69
80
|
}
|
|
70
81
|
return ret;
|
|
71
82
|
}
|
|
@@ -73,21 +84,21 @@ function applyPatch(from, patch) {
|
|
|
73
84
|
const ret = from;
|
|
74
85
|
const patches = Object.entries(patch);
|
|
75
86
|
for (const [key, value] of patches) {
|
|
76
|
-
if (value
|
|
87
|
+
if (value === MARK_DELETED) {
|
|
77
88
|
delete ret[key];
|
|
78
89
|
continue;
|
|
79
90
|
}
|
|
80
91
|
if (value === null) {
|
|
81
|
-
ret
|
|
92
|
+
setOwnProperty(ret, key, null);
|
|
82
93
|
continue;
|
|
83
94
|
}
|
|
84
95
|
if (typeof value == "object") {
|
|
85
|
-
if (MARK_SWAPPED
|
|
86
|
-
ret
|
|
96
|
+
if (hasOwnProperty(value, MARK_SWAPPED)) {
|
|
97
|
+
setOwnProperty(ret, key, value[MARK_SWAPPED]);
|
|
87
98
|
continue;
|
|
88
99
|
}
|
|
89
|
-
if (MARK_ISARRAY
|
|
90
|
-
if (!(key
|
|
100
|
+
if (hasOwnProperty(value, MARK_ISARRAY)) {
|
|
101
|
+
if (!hasOwnProperty(ret, key)) setOwnProperty(ret, key, []);
|
|
91
102
|
if (!Array.isArray(ret[key])) {
|
|
92
103
|
throw new Error("Patch target type is mismatched (array to something)");
|
|
93
104
|
}
|
|
@@ -97,19 +108,23 @@ function applyPatch(from, patch) {
|
|
|
97
108
|
value[MARK_ISARRAY]
|
|
98
109
|
);
|
|
99
110
|
const appliedArray = objectToUnorderedArray(appliedObject);
|
|
100
|
-
ret
|
|
111
|
+
setOwnProperty(ret, key, [...appliedArray]);
|
|
101
112
|
} else {
|
|
102
|
-
if (!(key
|
|
103
|
-
ret
|
|
113
|
+
if (!hasOwnProperty(ret, key)) {
|
|
114
|
+
setOwnProperty(ret, key, value);
|
|
104
115
|
continue;
|
|
105
116
|
}
|
|
106
|
-
|
|
107
|
-
ret
|
|
108
|
-
|
|
117
|
+
setOwnProperty(
|
|
118
|
+
ret,
|
|
119
|
+
key,
|
|
120
|
+
applyPatch(
|
|
121
|
+
ret[key],
|
|
122
|
+
value
|
|
123
|
+
)
|
|
109
124
|
);
|
|
110
125
|
}
|
|
111
126
|
} else {
|
|
112
|
-
ret
|
|
127
|
+
setOwnProperty(ret, key, value);
|
|
113
128
|
}
|
|
114
129
|
}
|
|
115
130
|
return ret;
|
|
@@ -121,24 +136,28 @@ function mergeObject(objA, objB) {
|
|
|
121
136
|
return objB;
|
|
122
137
|
}
|
|
123
138
|
for (const [key, v] of newEntries) {
|
|
124
|
-
if (key
|
|
139
|
+
if (hasOwnProperty(ret, key)) {
|
|
125
140
|
const value = ret[key];
|
|
126
141
|
if (typeof v !== typeof value || Array.isArray(v) !== Array.isArray(value)) {
|
|
127
|
-
ret
|
|
142
|
+
setOwnProperty(ret, key, v);
|
|
128
143
|
} else {
|
|
129
144
|
if (typeof v == "object" && typeof value == "object" && !Array.isArray(v) && !Array.isArray(value)) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
145
|
+
setOwnProperty(
|
|
146
|
+
ret,
|
|
147
|
+
key,
|
|
148
|
+
mergeObject(
|
|
149
|
+
v,
|
|
150
|
+
value
|
|
151
|
+
)
|
|
133
152
|
);
|
|
134
153
|
} else if (typeof v == "object" && typeof value == "object" && Array.isArray(v) && Array.isArray(value)) {
|
|
135
|
-
ret
|
|
154
|
+
setOwnProperty(ret, key, [.../* @__PURE__ */ new Set([...v, ...value])]);
|
|
136
155
|
} else {
|
|
137
|
-
ret
|
|
156
|
+
setOwnProperty(ret, key, v);
|
|
138
157
|
}
|
|
139
158
|
}
|
|
140
159
|
} else {
|
|
141
|
-
ret
|
|
160
|
+
setOwnProperty(ret, key, v);
|
|
142
161
|
}
|
|
143
162
|
}
|
|
144
163
|
const retSorted = Object.fromEntries(Object.entries(ret).sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
|
@@ -15,6 +15,13 @@ export declare class ChunkFetcher {
|
|
|
15
15
|
get chunkManager(): ChunkManager;
|
|
16
16
|
queue: DocumentID[];
|
|
17
17
|
private readonly pendingClaims;
|
|
18
|
+
private reportedPendingCount;
|
|
19
|
+
private reportedFetchCounts;
|
|
20
|
+
private requestTimer;
|
|
21
|
+
private requestTimerDueAt;
|
|
22
|
+
private finiteActivityWasActive;
|
|
23
|
+
private finiteCompletionVersion;
|
|
24
|
+
private readonly stopObservingDelivery;
|
|
18
25
|
private destroyed;
|
|
19
26
|
get interval(): number;
|
|
20
27
|
get concurrency(): number;
|
|
@@ -23,12 +30,20 @@ export declare class ChunkFetcher {
|
|
|
23
30
|
destroy(): void;
|
|
24
31
|
onEventHandler: (ids: DocumentID[]) => void;
|
|
25
32
|
onEvent(ids: DocumentID[]): void;
|
|
33
|
+
private clearRequestTimer;
|
|
34
|
+
private scheduleRequest;
|
|
26
35
|
private ensureClaims;
|
|
27
36
|
private removePendingDelivery;
|
|
37
|
+
private updatePendingCount;
|
|
28
38
|
private onClaimStalled;
|
|
29
39
|
private settleClaim;
|
|
40
|
+
private getActiveClaimIds;
|
|
30
41
|
private touchClaims;
|
|
31
42
|
private waitForActivityBoundary;
|
|
43
|
+
private waitBeforeRemoteRequest;
|
|
44
|
+
private resolveLocallyAvailableRetries;
|
|
45
|
+
private logFetchedChunks;
|
|
46
|
+
private applyMissingChunkResults;
|
|
32
47
|
/**
|
|
33
48
|
* Processing requests
|
|
34
49
|
*/
|
|
@@ -40,5 +55,6 @@ export declare class ChunkFetcher {
|
|
|
40
55
|
*/
|
|
41
56
|
previousRequestTime: number;
|
|
42
57
|
canRequestMore(): boolean;
|
|
58
|
+
private isReady;
|
|
43
59
|
requestMissingChunks(): Promise<void>;
|
|
44
60
|
}
|