@recordtimelabel/core 0.1.5 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/package.json +1 -1
- package/src/index.js +53 -35
package/README.md
CHANGED
|
@@ -17,11 +17,13 @@ During local development an app can consume a sibling checkout with:
|
|
|
17
17
|
"@recordtimelabel/core": "file:../recordtimelabel-core"
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
For release builds, consume a fixed npm package, git tag, or private registry version so builds do not depend on a sibling folder path. The current release
|
|
20
|
+
For release builds, consume a fixed npm package, git tag, or private registry version so builds do not depend on a sibling folder path. The current published release is:
|
|
21
21
|
|
|
22
22
|
```json
|
|
23
|
-
"@recordtimelabel/core": "0.1.
|
|
23
|
+
"@recordtimelabel/core": "0.1.7"
|
|
24
24
|
```
|
|
25
|
+
|
|
26
|
+
If this checkout's `package.json` is ahead of the published version, publish the new package before updating consumers to that version.
|
|
25
27
|
|
|
26
28
|
## Public API
|
|
27
29
|
|
|
@@ -32,8 +34,8 @@ For release builds, consume a fixed npm package, git tag, or private registry ve
|
|
|
32
34
|
- `applyRecordTimeLabelOperation(state, operation)`
|
|
33
35
|
- `createSyncEngine({ storageAdapter, cloudAdapter, clientId, clock, logger })`
|
|
34
36
|
- `createRecordTimeLabelController({ storageAdapter, cloudAdapter, clientId, settingKeys, clock, logger })`
|
|
35
|
-
- `buildRecordTimeLabelSyncPayload({ data, previousCloudData, pendingOps, syncMode, clientId, now })`
|
|
36
|
-
- `buildSyncPayloadWithOperations({ data, previousCloudData, pendingOps, syncMode, clientId, now })`
|
|
37
|
+
- `buildRecordTimeLabelSyncPayload({ data, previousCloudData, pendingOps, syncMode, clientId, now, groupOrderNormalizer })`
|
|
38
|
+
- `buildSyncPayloadWithOperations({ data, previousCloudData, pendingOps, syncMode, clientId, now, groupOrderNormalizer })`
|
|
37
39
|
- `flushPendingOperations({ operations, storageAdapter, cloudAdapter, clientId, now })`
|
|
38
40
|
- `mergeRemoteStateIntoLocal({ localData, remoteData, pendingOps, settingKeys, clientId, now })`
|
|
39
41
|
- `buildLocalStateFromStorage(data, options)`
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -5,7 +5,7 @@ const REQUIRED_FOLDERS = [
|
|
|
5
5
|
{ id: DEFAULT_FOLDER_ID, name: 'Uncategorized' }
|
|
6
6
|
];
|
|
7
7
|
|
|
8
|
-
export const RECORD_TIMELABEL_CORE_VERSION = '0.1.
|
|
8
|
+
export const RECORD_TIMELABEL_CORE_VERSION = '0.1.8';
|
|
9
9
|
|
|
10
10
|
export const OPERATION_TYPES = Object.freeze({
|
|
11
11
|
RECORD_CREATE: 'record.create',
|
|
@@ -562,6 +562,10 @@ const buildOperationSyncMeta = (previousSyncMeta = {}, operation = {}, payload =
|
|
|
562
562
|
...(previousSyncMeta?.lastOrderOperationIdByType || {}),
|
|
563
563
|
[operation.type]: operation.id || null
|
|
564
564
|
};
|
|
565
|
+
nextSyncMeta.lastOrderClientIdByType = {
|
|
566
|
+
...(previousSyncMeta?.lastOrderClientIdByType || {}),
|
|
567
|
+
[operation.type]: operation.clientId || previousSyncMeta?.lastClientId || null
|
|
568
|
+
};
|
|
565
569
|
}
|
|
566
570
|
|
|
567
571
|
return nextSyncMeta;
|
|
@@ -1409,6 +1413,12 @@ const getOrderOperationAtByType = (data = {}, operationType) => toFiniteTimestam
|
|
|
1409
1413
|
data?.syncMeta?.lastOrderOperationAtByType?.[operationType]
|
|
1410
1414
|
);
|
|
1411
1415
|
|
|
1416
|
+
const getOrderClientIdByType = (data = {}, operationType) => String(
|
|
1417
|
+
data?.rtlSyncMeta?.lastOrderClientIdByType?.[operationType] ||
|
|
1418
|
+
data?.syncMeta?.lastOrderClientIdByType?.[operationType] ||
|
|
1419
|
+
''
|
|
1420
|
+
);
|
|
1421
|
+
|
|
1412
1422
|
const hasOperationMarker = (data = {}, operationType, operationTypeResolver = getLastRemoteOperationType) => {
|
|
1413
1423
|
const lastOperationId = String(data?.rtlSyncMeta?.lastOperationId || '');
|
|
1414
1424
|
const lastOperationType = operationTypeResolver(data);
|
|
@@ -1444,12 +1454,17 @@ const hasRecentLocalOperation = (localData = {}, remoteData = {}, operationType)
|
|
|
1444
1454
|
};
|
|
1445
1455
|
|
|
1446
1456
|
const hasRemoteOrderOperationFromDifferentClient = (localData = {}, remoteData = {}, operationType) => {
|
|
1447
|
-
|
|
1457
|
+
const remoteOrderOperationAt = getMarkedOrderOperationAt(remoteData, operationType, {
|
|
1458
|
+
operationTypeResolver: getLastRemoteOperationType,
|
|
1459
|
+
operationAtResolver: getLastRemoteOperationAt
|
|
1460
|
+
});
|
|
1461
|
+
if (!remoteOrderOperationAt) {
|
|
1448
1462
|
return false;
|
|
1449
1463
|
}
|
|
1450
1464
|
|
|
1451
|
-
const remoteClientId = getLastClientId(remoteData);
|
|
1452
|
-
|
|
1465
|
+
const remoteClientId = getOrderClientIdByType(remoteData, operationType) || getLastClientId(remoteData);
|
|
1466
|
+
const localClientId = getLastClientId(localData);
|
|
1467
|
+
return Boolean(remoteClientId) && (!localClientId || remoteClientId !== localClientId);
|
|
1453
1468
|
};
|
|
1454
1469
|
|
|
1455
1470
|
const shouldPreferRecentLocalOrder = (localData = {}, remoteData = {}, operationType) => {
|
|
@@ -1487,14 +1502,14 @@ const resolveMergedOrder = ({
|
|
|
1487
1502
|
return mergeOrderArrays(normalizer, remoteData?.[stateKey], localData?.[stateKey]);
|
|
1488
1503
|
};
|
|
1489
1504
|
|
|
1490
|
-
const buildSyncStateInput = (data = {}, operationTime) => ({
|
|
1491
|
-
folders: data?.folders || [],
|
|
1492
|
-
records: data?.records || {},
|
|
1493
|
-
settings: data?.settings || {},
|
|
1494
|
-
groupOrder: data?.groupOrder || [],
|
|
1495
|
-
folderOrder: data?.folderOrder || [],
|
|
1496
|
-
expandedGroups: data?.expandedGroups || [],
|
|
1497
|
-
rtlSyncMeta: data?.rtlSyncMeta || {},
|
|
1505
|
+
const buildSyncStateInput = (data = {}, operationTime, options = {}) => ({
|
|
1506
|
+
folders: data?.folders || [],
|
|
1507
|
+
records: data?.records || {},
|
|
1508
|
+
settings: data?.settings || {},
|
|
1509
|
+
groupOrder: normalizeGroupOrderForOption(data?.groupOrder || [], options.groupOrderNormalizer),
|
|
1510
|
+
folderOrder: data?.folderOrder || [],
|
|
1511
|
+
expandedGroups: data?.expandedGroups || [],
|
|
1512
|
+
rtlSyncMeta: data?.rtlSyncMeta || {},
|
|
1498
1513
|
deletedRecordTombstones: data?.deletedRecordTombstones || {},
|
|
1499
1514
|
deletedFolderTombstones: data?.deletedFolderTombstones || {},
|
|
1500
1515
|
lastModified: operationTime
|
|
@@ -1503,23 +1518,24 @@ const buildSyncStateInput = (data = {}, operationTime) => ({
|
|
|
1503
1518
|
export const buildRecordTimeLabelSyncPayload = ({
|
|
1504
1519
|
data,
|
|
1505
1520
|
previousCloudData,
|
|
1506
|
-
pendingOps = [],
|
|
1507
|
-
syncMode = RECORD_TIMELABEL_SYNC_MODES.FULL,
|
|
1508
|
-
clientId = 'recordtimelabel-client',
|
|
1509
|
-
now = Date.now()
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
const
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
const
|
|
1521
|
+
pendingOps = [],
|
|
1522
|
+
syncMode = RECORD_TIMELABEL_SYNC_MODES.FULL,
|
|
1523
|
+
clientId = 'recordtimelabel-client',
|
|
1524
|
+
now = Date.now(),
|
|
1525
|
+
groupOrderNormalizer
|
|
1526
|
+
} = {}) => {
|
|
1527
|
+
const operationTime = toFiniteTimestamp(data?.lastModified) || now;
|
|
1528
|
+
const payloadSource = syncMode === RECORD_TIMELABEL_SYNC_MODES.MERGE
|
|
1529
|
+
? mergeLocalRemote({
|
|
1530
|
+
localState: buildSyncStateInput(data || {}, operationTime, { groupOrderNormalizer }),
|
|
1531
|
+
remoteState: previousCloudData || {},
|
|
1532
|
+
pendingOps,
|
|
1533
|
+
clientId,
|
|
1534
|
+
now
|
|
1535
|
+
}).state
|
|
1536
|
+
: buildSyncStateInput(data || {}, operationTime, { groupOrderNormalizer });
|
|
1537
|
+
const sanitizedRecords = removeRecordSyncFlags(payloadSource.records || {});
|
|
1538
|
+
const deletionTombstones = buildDeletionTombstones({
|
|
1523
1539
|
previousState: previousCloudData,
|
|
1524
1540
|
nextRecords: sanitizedRecords,
|
|
1525
1541
|
nextFolders: payloadSource.folders || [],
|
|
@@ -1529,11 +1545,12 @@ export const buildRecordTimeLabelSyncPayload = ({
|
|
|
1529
1545
|
clientId
|
|
1530
1546
|
});
|
|
1531
1547
|
|
|
1532
|
-
return normalizeState({
|
|
1533
|
-
...payloadSource,
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1548
|
+
return normalizeState({
|
|
1549
|
+
...payloadSource,
|
|
1550
|
+
groupOrder: normalizeGroupOrderForOption(payloadSource.groupOrder, groupOrderNormalizer),
|
|
1551
|
+
records: sanitizedRecords,
|
|
1552
|
+
deletedRecordTombstones: deletionTombstones.deletedRecordTombstones,
|
|
1553
|
+
deletedFolderTombstones: deletionTombstones.deletedFolderTombstones,
|
|
1537
1554
|
lastModified: operationTime
|
|
1538
1555
|
});
|
|
1539
1556
|
};
|
|
@@ -1554,7 +1571,8 @@ export const buildSyncPayloadWithOperations = ({
|
|
|
1554
1571
|
pendingOps: [],
|
|
1555
1572
|
syncMode,
|
|
1556
1573
|
clientId,
|
|
1557
|
-
now
|
|
1574
|
+
now,
|
|
1575
|
+
groupOrderNormalizer
|
|
1558
1576
|
});
|
|
1559
1577
|
|
|
1560
1578
|
operations.forEach((operation) => {
|