@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.
@@ -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
+ }
@@ -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
+ }