@cuboapp/crdt 1.0.15 → 1.0.16
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/package.json +2 -2
- package/src/client/index.ts +269 -57
- package/src/client/types/index.ts +19 -3
- package/src/client/types/store.ts +10 -1
- package/src/server/document/index.ts +18 -3
- package/src/server/index.ts +357 -81
- package/src/server/types/document.ts +10 -1
- package/src/server/types/index.ts +20 -1
- package/src/server/types/subscribe.ts +15 -2
- package/src/types/index.ts +24 -1
- package/src/utils/index.ts +24 -0
package/src/types/index.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
export type CuboCrdtKey<K, M> = K extends Extract<keyof M, string> ? M[K] : any
|
|
2
2
|
|
|
3
|
-
export type CuboCrdtAction = 'create' | 'upsert' | 'update' | 'delete' | 'awareness'
|
|
3
|
+
export type CuboCrdtAction = 'create' | 'upsert' | 'update' | 'delete' | 'awareness' | 'sync'
|
|
4
4
|
|
|
5
5
|
export type CuboCrdtExposeStrategy = 'all' | 'other' | 'subscribe' | 'client'
|
|
6
|
+
|
|
7
|
+
export type CuboCrdtListTotals = Record<string, number>
|
|
8
|
+
|
|
9
|
+
export type CuboCrdtSubscriptionStatus =
|
|
10
|
+
| 'idle'
|
|
11
|
+
| 'loading'
|
|
12
|
+
| 'ready'
|
|
13
|
+
| 'error'
|
|
14
|
+
|
|
15
|
+
export type CuboCrdtListSyncData = {
|
|
16
|
+
ids: number[]
|
|
17
|
+
totals: CuboCrdtListTotals
|
|
18
|
+
revision: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type CuboCrdtMutationAction = 'create' | 'update' | 'delete'
|
|
22
|
+
|
|
23
|
+
export type CuboCrdtMutation<T = any> = {
|
|
24
|
+
action: CuboCrdtMutationAction
|
|
25
|
+
row: T
|
|
26
|
+
previousRow?: T
|
|
27
|
+
changedKeys?: string[]
|
|
28
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -51,6 +51,18 @@ export function checkRowIsSutable(
|
|
|
51
51
|
if (!['limit', 'with'].includes(key)) {
|
|
52
52
|
if (customKeys?.[key]) {
|
|
53
53
|
sutable = customKeys[key](key, row, filters)
|
|
54
|
+
} else if (row && typeof row === 'object' && !(key in row)) {
|
|
55
|
+
// Виртуальный фильтр: поля с таким именем у строки нет, значит на бэкенде он
|
|
56
|
+
// разворачивается в условие запроса (join/exists/диапазон) и по одной строке
|
|
57
|
+
// не проверяется в принципе — например membership пользователя в компании.
|
|
58
|
+
//
|
|
59
|
+
// Раньше такой ключ молча не совпадал, и строка считалась выпавшей из подписки.
|
|
60
|
+
// Для update это фатально: рассылка подменяет action на delete (см. server),
|
|
61
|
+
// поэтому подписчик получал удаление вместо обновления — строка исчезала из
|
|
62
|
+
// списка при любой правке, а фоновые обновления постепенно вычищали его целиком.
|
|
63
|
+
//
|
|
64
|
+
// Пропускаем такой ключ. Если фильтр всё же должен влиять на live-раскатку,
|
|
65
|
+
// его семантику описывают в options.checkRowIsSutable или в customKeys.
|
|
54
66
|
} else {
|
|
55
67
|
const [formula, str] = `${value}`.split(':')
|
|
56
68
|
|
|
@@ -100,3 +112,15 @@ export function checkSubscribeIsSutable(origin: CuboCrdtServerDocumentOrigin, su
|
|
|
100
112
|
|
|
101
113
|
return noStrategyResolved || strategyOtherResolved || strategyClientResolved || strategySubscribeResolved
|
|
102
114
|
}
|
|
115
|
+
|
|
116
|
+
export function areCrdtListIdsEqual(left: number[], right: number[]) {
|
|
117
|
+
return left.length === right.length && left.every((id, index) => id === right[index])
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function areCrdtListTotalsEqual(
|
|
121
|
+
left: Record<string, number>,
|
|
122
|
+
right: Record<string, number>
|
|
123
|
+
) {
|
|
124
|
+
const keys = new Set([...Object.keys(left), ...Object.keys(right)])
|
|
125
|
+
return Array.from(keys).every((key) => left[key] === right[key])
|
|
126
|
+
}
|