@verdant-web/store 2.8.4 → 3.0.0-next.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.
Files changed (307) hide show
  1. package/dist/bundle/index.js +9 -10
  2. package/dist/bundle/index.js.map +4 -4
  3. package/dist/cjs/DocumentManager.d.ts +6 -5
  4. package/dist/cjs/DocumentManager.js +2 -2
  5. package/dist/cjs/DocumentManager.js.map +1 -1
  6. package/dist/cjs/IDBService.d.ts +28 -7
  7. package/dist/cjs/IDBService.js +50 -13
  8. package/dist/cjs/IDBService.js.map +1 -1
  9. package/dist/cjs/UndoHistory.d.ts +1 -1
  10. package/dist/cjs/UndoHistory.js +6 -2
  11. package/dist/cjs/UndoHistory.js.map +1 -1
  12. package/dist/cjs/__tests__/batching.test.js +3 -1
  13. package/dist/cjs/__tests__/batching.test.js.map +1 -1
  14. package/dist/cjs/__tests__/documents.test.js +54 -6
  15. package/dist/cjs/__tests__/documents.test.js.map +1 -1
  16. package/dist/cjs/__tests__/fixtures/testStorage.d.ts +8 -2
  17. package/dist/cjs/__tests__/fixtures/testStorage.js +8 -1
  18. package/dist/cjs/__tests__/fixtures/testStorage.js.map +1 -1
  19. package/dist/cjs/__tests__/legacyOids.test.js +50 -17
  20. package/dist/cjs/__tests__/legacyOids.test.js.map +1 -1
  21. package/dist/cjs/__tests__/mutations.test.js +9 -3
  22. package/dist/cjs/__tests__/mutations.test.js.map +1 -1
  23. package/dist/cjs/__tests__/queries.test.js +6 -2
  24. package/dist/cjs/__tests__/queries.test.js.map +1 -1
  25. package/dist/cjs/__tests__/setup/indexedDB.d.ts +1 -1
  26. package/dist/cjs/__tests__/setup/indexedDB.js +13 -1
  27. package/dist/cjs/__tests__/setup/indexedDB.js.map +1 -1
  28. package/dist/cjs/__tests__/undo.test.js +16 -9
  29. package/dist/cjs/__tests__/undo.test.js.map +1 -1
  30. package/dist/cjs/client/Client.d.ts +2 -3
  31. package/dist/cjs/client/Client.js +8 -4
  32. package/dist/cjs/client/Client.js.map +1 -1
  33. package/dist/cjs/client/ClientDescriptor.js +21 -6
  34. package/dist/cjs/client/ClientDescriptor.js.map +1 -1
  35. package/dist/cjs/context.d.ts +10 -1
  36. package/dist/cjs/entities/2/Entity.d.ts +148 -0
  37. package/dist/cjs/entities/2/Entity.js +711 -0
  38. package/dist/cjs/entities/2/Entity.js.map +1 -0
  39. package/dist/cjs/entities/2/Entity.test.d.ts +1 -0
  40. package/dist/cjs/entities/2/Entity.test.js +194 -0
  41. package/dist/cjs/entities/2/Entity.test.js.map +1 -0
  42. package/dist/cjs/entities/2/EntityCache.d.ts +15 -0
  43. package/dist/cjs/entities/2/EntityCache.js +39 -0
  44. package/dist/cjs/entities/2/EntityCache.js.map +1 -0
  45. package/dist/cjs/entities/2/EntityMetadata.d.ts +68 -0
  46. package/dist/cjs/entities/2/EntityMetadata.js +261 -0
  47. package/dist/cjs/entities/2/EntityMetadata.js.map +1 -0
  48. package/dist/cjs/entities/2/EntityStore.d.ts +78 -0
  49. package/dist/cjs/entities/2/EntityStore.js +352 -0
  50. package/dist/cjs/entities/2/EntityStore.js.map +1 -0
  51. package/dist/cjs/entities/2/OperationBatcher.d.ts +52 -0
  52. package/dist/cjs/entities/2/OperationBatcher.js +165 -0
  53. package/dist/cjs/entities/2/OperationBatcher.js.map +1 -0
  54. package/dist/cjs/entities/2/types.d.ts +84 -0
  55. package/dist/cjs/entities/2/types.js +3 -0
  56. package/dist/cjs/entities/2/types.js.map +1 -0
  57. package/dist/cjs/entities/Entity.d.ts +0 -7
  58. package/dist/cjs/entities/Entity.js +7 -0
  59. package/dist/cjs/entities/Entity.js.map +1 -1
  60. package/dist/cjs/entities/EntityStore.js +4 -20
  61. package/dist/cjs/entities/EntityStore.js.map +1 -1
  62. package/dist/cjs/entities/FakeWeakRef.d.ts +11 -0
  63. package/dist/cjs/entities/FakeWeakRef.js +19 -0
  64. package/dist/cjs/entities/FakeWeakRef.js.map +1 -0
  65. package/dist/cjs/files/EntityFile.d.ts +5 -2
  66. package/dist/cjs/files/EntityFile.js +8 -4
  67. package/dist/cjs/files/EntityFile.js.map +1 -1
  68. package/dist/cjs/files/FileManager.d.ts +3 -1
  69. package/dist/cjs/files/FileManager.js +5 -3
  70. package/dist/cjs/files/FileManager.js.map +1 -1
  71. package/dist/cjs/files/FileStorage.js +7 -7
  72. package/dist/cjs/files/FileStorage.js.map +1 -1
  73. package/dist/cjs/files/utils.d.ts +2 -0
  74. package/dist/cjs/files/utils.js +8 -2
  75. package/dist/cjs/files/utils.js.map +1 -1
  76. package/dist/cjs/idb.d.ts +2 -0
  77. package/dist/cjs/idb.js +50 -4
  78. package/dist/cjs/idb.js.map +1 -1
  79. package/dist/cjs/index.d.ts +2 -2
  80. package/dist/cjs/index.js +1 -1
  81. package/dist/cjs/index.js.map +1 -1
  82. package/dist/cjs/indexes.d.ts +3 -0
  83. package/dist/cjs/indexes.js +20 -0
  84. package/dist/cjs/indexes.js.map +1 -0
  85. package/dist/cjs/metadata/AckInfoStore.js +1 -1
  86. package/dist/cjs/metadata/AckInfoStore.js.map +1 -1
  87. package/dist/cjs/metadata/BaselinesStore.d.ts +4 -1
  88. package/dist/cjs/metadata/BaselinesStore.js +19 -10
  89. package/dist/cjs/metadata/BaselinesStore.js.map +1 -1
  90. package/dist/cjs/metadata/LocalReplicaStore.d.ts +1 -1
  91. package/dist/cjs/metadata/LocalReplicaStore.js +11 -5
  92. package/dist/cjs/metadata/LocalReplicaStore.js.map +1 -1
  93. package/dist/cjs/metadata/Metadata.d.ts +26 -5
  94. package/dist/cjs/metadata/Metadata.js +55 -18
  95. package/dist/cjs/metadata/Metadata.js.map +1 -1
  96. package/dist/cjs/metadata/OperationsStore.d.ts +3 -0
  97. package/dist/cjs/metadata/OperationsStore.js +35 -15
  98. package/dist/cjs/metadata/OperationsStore.js.map +1 -1
  99. package/dist/cjs/migration/openDatabase.js +31 -10
  100. package/dist/cjs/migration/openDatabase.js.map +1 -1
  101. package/dist/cjs/queries/BaseQuery.js +14 -2
  102. package/dist/cjs/queries/BaseQuery.js.map +1 -1
  103. package/dist/cjs/queries/CollectionQueries.d.ts +2 -4
  104. package/dist/cjs/queries/CollectionQueries.js +1 -1
  105. package/dist/cjs/queries/CollectionQueries.js.map +1 -1
  106. package/dist/cjs/queries/FindAllQuery.js +1 -0
  107. package/dist/cjs/queries/FindAllQuery.js.map +1 -1
  108. package/dist/cjs/queries/QueryCache.d.ts +1 -0
  109. package/dist/cjs/queries/QueryCache.js +4 -0
  110. package/dist/cjs/queries/QueryCache.js.map +1 -1
  111. package/dist/cjs/queries/QueryableStorage.d.ts +20 -0
  112. package/dist/cjs/queries/QueryableStorage.js +84 -0
  113. package/dist/cjs/queries/QueryableStorage.js.map +1 -0
  114. package/dist/cjs/queries/dbQueries.js +13 -3
  115. package/dist/cjs/queries/dbQueries.js.map +1 -1
  116. package/dist/cjs/queries/utils.js +1 -1
  117. package/dist/cjs/queries/utils.js.map +1 -1
  118. package/dist/cjs/sync/FileSync.d.ts +1 -0
  119. package/dist/cjs/sync/FileSync.js +1 -0
  120. package/dist/cjs/sync/FileSync.js.map +1 -1
  121. package/dist/cjs/sync/PushPullSync.d.ts +2 -1
  122. package/dist/cjs/sync/PushPullSync.js +7 -1
  123. package/dist/cjs/sync/PushPullSync.js.map +1 -1
  124. package/dist/cjs/sync/Sync.d.ts +6 -3
  125. package/dist/cjs/sync/Sync.js +9 -4
  126. package/dist/cjs/sync/Sync.js.map +1 -1
  127. package/dist/cjs/sync/WebSocketSync.d.ts +4 -1
  128. package/dist/cjs/sync/WebSocketSync.js +41 -11
  129. package/dist/cjs/sync/WebSocketSync.js.map +1 -1
  130. package/dist/esm/DocumentManager.d.ts +6 -5
  131. package/dist/esm/DocumentManager.js +2 -2
  132. package/dist/esm/DocumentManager.js.map +1 -1
  133. package/dist/esm/IDBService.d.ts +28 -7
  134. package/dist/esm/IDBService.js +51 -14
  135. package/dist/esm/IDBService.js.map +1 -1
  136. package/dist/esm/UndoHistory.d.ts +1 -1
  137. package/dist/esm/UndoHistory.js +6 -2
  138. package/dist/esm/UndoHistory.js.map +1 -1
  139. package/dist/esm/__tests__/batching.test.js +3 -1
  140. package/dist/esm/__tests__/batching.test.js.map +1 -1
  141. package/dist/esm/__tests__/documents.test.js +54 -6
  142. package/dist/esm/__tests__/documents.test.js.map +1 -1
  143. package/dist/esm/__tests__/fixtures/testStorage.d.ts +8 -2
  144. package/dist/esm/__tests__/fixtures/testStorage.js +8 -1
  145. package/dist/esm/__tests__/fixtures/testStorage.js.map +1 -1
  146. package/dist/esm/__tests__/legacyOids.test.js +50 -17
  147. package/dist/esm/__tests__/legacyOids.test.js.map +1 -1
  148. package/dist/esm/__tests__/mutations.test.js +9 -3
  149. package/dist/esm/__tests__/mutations.test.js.map +1 -1
  150. package/dist/esm/__tests__/queries.test.js +6 -2
  151. package/dist/esm/__tests__/queries.test.js.map +1 -1
  152. package/dist/esm/__tests__/setup/indexedDB.d.ts +1 -1
  153. package/dist/esm/__tests__/setup/indexedDB.js +13 -1
  154. package/dist/esm/__tests__/setup/indexedDB.js.map +1 -1
  155. package/dist/esm/__tests__/undo.test.js +16 -9
  156. package/dist/esm/__tests__/undo.test.js.map +1 -1
  157. package/dist/esm/client/Client.d.ts +2 -3
  158. package/dist/esm/client/Client.js +8 -4
  159. package/dist/esm/client/Client.js.map +1 -1
  160. package/dist/esm/client/ClientDescriptor.js +21 -6
  161. package/dist/esm/client/ClientDescriptor.js.map +1 -1
  162. package/dist/esm/context.d.ts +10 -1
  163. package/dist/esm/entities/2/Entity.d.ts +148 -0
  164. package/dist/esm/entities/2/Entity.js +707 -0
  165. package/dist/esm/entities/2/Entity.js.map +1 -0
  166. package/dist/esm/entities/2/Entity.test.d.ts +1 -0
  167. package/dist/esm/entities/2/Entity.test.js +192 -0
  168. package/dist/esm/entities/2/Entity.test.js.map +1 -0
  169. package/dist/esm/entities/2/EntityCache.d.ts +15 -0
  170. package/dist/esm/entities/2/EntityCache.js +35 -0
  171. package/dist/esm/entities/2/EntityCache.js.map +1 -0
  172. package/dist/esm/entities/2/EntityMetadata.d.ts +68 -0
  173. package/dist/esm/entities/2/EntityMetadata.js +256 -0
  174. package/dist/esm/entities/2/EntityMetadata.js.map +1 -0
  175. package/dist/esm/entities/2/EntityStore.d.ts +78 -0
  176. package/dist/esm/entities/2/EntityStore.js +348 -0
  177. package/dist/esm/entities/2/EntityStore.js.map +1 -0
  178. package/dist/esm/entities/2/OperationBatcher.d.ts +52 -0
  179. package/dist/esm/entities/2/OperationBatcher.js +161 -0
  180. package/dist/esm/entities/2/OperationBatcher.js.map +1 -0
  181. package/dist/esm/entities/2/types.d.ts +84 -0
  182. package/dist/esm/entities/2/types.js +2 -0
  183. package/dist/esm/entities/2/types.js.map +1 -0
  184. package/dist/esm/entities/Entity.d.ts +0 -7
  185. package/dist/esm/entities/Entity.js +7 -0
  186. package/dist/esm/entities/Entity.js.map +1 -1
  187. package/dist/esm/entities/EntityStore.js +4 -20
  188. package/dist/esm/entities/EntityStore.js.map +1 -1
  189. package/dist/esm/entities/FakeWeakRef.d.ts +11 -0
  190. package/dist/esm/entities/FakeWeakRef.js +15 -0
  191. package/dist/esm/entities/FakeWeakRef.js.map +1 -0
  192. package/dist/esm/files/EntityFile.d.ts +5 -2
  193. package/dist/esm/files/EntityFile.js +8 -4
  194. package/dist/esm/files/EntityFile.js.map +1 -1
  195. package/dist/esm/files/FileManager.d.ts +3 -1
  196. package/dist/esm/files/FileManager.js +5 -3
  197. package/dist/esm/files/FileManager.js.map +1 -1
  198. package/dist/esm/files/FileStorage.js +7 -7
  199. package/dist/esm/files/FileStorage.js.map +1 -1
  200. package/dist/esm/files/utils.d.ts +2 -0
  201. package/dist/esm/files/utils.js +6 -1
  202. package/dist/esm/files/utils.js.map +1 -1
  203. package/dist/esm/idb.d.ts +2 -0
  204. package/dist/esm/idb.js +47 -3
  205. package/dist/esm/idb.js.map +1 -1
  206. package/dist/esm/index.d.ts +2 -2
  207. package/dist/esm/index.js +1 -1
  208. package/dist/esm/index.js.map +1 -1
  209. package/dist/esm/indexes.d.ts +3 -0
  210. package/dist/esm/indexes.js +15 -0
  211. package/dist/esm/indexes.js.map +1 -0
  212. package/dist/esm/metadata/AckInfoStore.js +1 -1
  213. package/dist/esm/metadata/AckInfoStore.js.map +1 -1
  214. package/dist/esm/metadata/BaselinesStore.d.ts +4 -1
  215. package/dist/esm/metadata/BaselinesStore.js +19 -10
  216. package/dist/esm/metadata/BaselinesStore.js.map +1 -1
  217. package/dist/esm/metadata/LocalReplicaStore.d.ts +1 -1
  218. package/dist/esm/metadata/LocalReplicaStore.js +11 -5
  219. package/dist/esm/metadata/LocalReplicaStore.js.map +1 -1
  220. package/dist/esm/metadata/Metadata.d.ts +26 -5
  221. package/dist/esm/metadata/Metadata.js +56 -19
  222. package/dist/esm/metadata/Metadata.js.map +1 -1
  223. package/dist/esm/metadata/OperationsStore.d.ts +3 -0
  224. package/dist/esm/metadata/OperationsStore.js +35 -15
  225. package/dist/esm/metadata/OperationsStore.js.map +1 -1
  226. package/dist/esm/migration/openDatabase.js +32 -11
  227. package/dist/esm/migration/openDatabase.js.map +1 -1
  228. package/dist/esm/queries/BaseQuery.js +14 -2
  229. package/dist/esm/queries/BaseQuery.js.map +1 -1
  230. package/dist/esm/queries/CollectionQueries.d.ts +2 -4
  231. package/dist/esm/queries/CollectionQueries.js +1 -1
  232. package/dist/esm/queries/CollectionQueries.js.map +1 -1
  233. package/dist/esm/queries/FindAllQuery.js +1 -0
  234. package/dist/esm/queries/FindAllQuery.js.map +1 -1
  235. package/dist/esm/queries/QueryCache.d.ts +1 -0
  236. package/dist/esm/queries/QueryCache.js +4 -0
  237. package/dist/esm/queries/QueryCache.js.map +1 -1
  238. package/dist/esm/queries/QueryableStorage.d.ts +20 -0
  239. package/dist/esm/queries/QueryableStorage.js +80 -0
  240. package/dist/esm/queries/QueryableStorage.js.map +1 -0
  241. package/dist/esm/queries/dbQueries.js +13 -3
  242. package/dist/esm/queries/dbQueries.js.map +1 -1
  243. package/dist/esm/queries/utils.js +1 -1
  244. package/dist/esm/queries/utils.js.map +1 -1
  245. package/dist/esm/sync/FileSync.d.ts +1 -0
  246. package/dist/esm/sync/FileSync.js +1 -0
  247. package/dist/esm/sync/FileSync.js.map +1 -1
  248. package/dist/esm/sync/PushPullSync.d.ts +2 -1
  249. package/dist/esm/sync/PushPullSync.js +7 -1
  250. package/dist/esm/sync/PushPullSync.js.map +1 -1
  251. package/dist/esm/sync/Sync.d.ts +6 -3
  252. package/dist/esm/sync/Sync.js +9 -4
  253. package/dist/esm/sync/Sync.js.map +1 -1
  254. package/dist/esm/sync/WebSocketSync.d.ts +4 -1
  255. package/dist/esm/sync/WebSocketSync.js +41 -11
  256. package/dist/esm/sync/WebSocketSync.js.map +1 -1
  257. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  258. package/dist/tsconfig.tsbuildinfo +1 -1
  259. package/package.json +8 -7
  260. package/src/DocumentManager.ts +3 -7
  261. package/src/IDBService.ts +78 -17
  262. package/src/UndoHistory.ts +5 -3
  263. package/src/__tests__/batching.test.ts +5 -2
  264. package/src/__tests__/documents.test.ts +66 -6
  265. package/src/__tests__/fixtures/testStorage.ts +9 -0
  266. package/src/__tests__/legacyOids.test.ts +53 -17
  267. package/src/__tests__/mutations.test.ts +9 -3
  268. package/src/__tests__/queries.test.ts +6 -2
  269. package/src/__tests__/setup/indexedDB.ts +14 -1
  270. package/src/__tests__/undo.test.ts +17 -9
  271. package/src/client/Client.ts +8 -4
  272. package/src/client/ClientDescriptor.ts +24 -8
  273. package/src/context.ts +16 -1
  274. package/src/entities/2/Entity.test.ts +218 -0
  275. package/src/entities/2/Entity.ts +954 -0
  276. package/src/entities/2/EntityCache.ts +41 -0
  277. package/src/entities/2/EntityMetadata.ts +364 -0
  278. package/src/entities/2/EntityStore.ts +490 -0
  279. package/src/entities/2/NOTES.md +22 -0
  280. package/src/entities/2/OperationBatcher.ts +251 -0
  281. package/src/entities/2/types.ts +154 -0
  282. package/src/files/EntityFile.ts +9 -4
  283. package/src/files/FileManager.ts +5 -3
  284. package/src/files/FileStorage.ts +7 -13
  285. package/src/files/utils.ts +9 -1
  286. package/src/idb.ts +51 -3
  287. package/src/index.ts +2 -2
  288. package/src/metadata/AckInfoStore.ts +1 -1
  289. package/src/metadata/BaselinesStore.ts +16 -24
  290. package/src/metadata/LocalReplicaStore.ts +13 -6
  291. package/src/metadata/Metadata.ts +109 -24
  292. package/src/metadata/OperationsStore.ts +37 -16
  293. package/src/migration/openDatabase.ts +32 -10
  294. package/src/queries/BaseQuery.ts +15 -2
  295. package/src/queries/CollectionQueries.ts +3 -3
  296. package/src/queries/FindAllQuery.ts +4 -0
  297. package/src/queries/QueryCache.ts +5 -0
  298. package/src/queries/QueryableStorage.ts +107 -0
  299. package/src/queries/dbQueries.ts +10 -3
  300. package/src/queries/utils.ts +1 -1
  301. package/src/sync/FileSync.ts +2 -0
  302. package/src/sync/PushPullSync.ts +8 -1
  303. package/src/sync/Sync.ts +14 -6
  304. package/src/sync/WebSocketSync.ts +47 -10
  305. package/src/entities/DocumentFamiliyCache.ts +0 -426
  306. package/src/entities/Entity.ts +0 -874
  307. package/src/entities/EntityStore.ts +0 -731
@@ -0,0 +1,78 @@
1
+ import { DocumentBaseline, ObjectIdentifier, Operation } from '@verdant-web/common';
2
+ import { Context } from '../../context.js';
3
+ import { Metadata } from '../../metadata/Metadata.js';
4
+ import { Entity } from './Entity.js';
5
+ import { Disposable } from '../../utils/Disposable.js';
6
+ import { FileManager } from '../../files/FileManager.js';
7
+ import { WeakEvent } from 'weak-event';
8
+ import { abort } from 'process';
9
+ export type EntityStoreEventData = {
10
+ oid: ObjectIdentifier;
11
+ operations?: Record<string, Operation[]>;
12
+ baselines?: DocumentBaseline[];
13
+ isLocal: boolean;
14
+ };
15
+ export type EntityStoreEvents = {
16
+ add: WeakEvent<EntityStore, EntityStoreEventData>;
17
+ replace: WeakEvent<EntityStore, EntityStoreEventData>;
18
+ resetAll: WeakEvent<EntityStore, void>;
19
+ };
20
+ type IncomingData = {
21
+ operations?: Operation[];
22
+ baselines?: DocumentBaseline[];
23
+ reset?: boolean;
24
+ isLocal?: boolean;
25
+ };
26
+ export declare class EntityStore extends Disposable {
27
+ private ctx;
28
+ private meta;
29
+ private files;
30
+ private batcher;
31
+ private queryableStorage;
32
+ private events;
33
+ private cache;
34
+ private pendingEntityPromises;
35
+ private abortDataQueueController;
36
+ private ongoingResetPromise;
37
+ private entityFinalizationRegistry;
38
+ constructor({ ctx, meta, files, }: {
39
+ ctx: Context;
40
+ meta: Metadata;
41
+ files: FileManager;
42
+ });
43
+ get batch(): ({ undoable, batchName, max, timeout, }?: {
44
+ undoable?: boolean | undefined;
45
+ batchName?: string | undefined;
46
+ max?: number | null | undefined;
47
+ timeout?: number | null | undefined;
48
+ }) => import("./OperationBatcher.js").OperationBatch;
49
+ get flushAllBatches(): () => Promise<any[]>;
50
+ addData: (data: IncomingData) => Promise<void>;
51
+ private resetData;
52
+ private processData;
53
+ hydrate: (oid: string, opts?: {
54
+ abort: AbortSignal;
55
+ }) => Promise<Entity | null>;
56
+ destroy: () => Promise<void>;
57
+ /**
58
+ * Creates a new Entity with the given initial data.
59
+ */
60
+ create: (initial: any, oid: ObjectIdentifier) => Promise<Entity<any, any, any>>;
61
+ deleteAll: (oids: ObjectIdentifier[], options?: {
62
+ undoable?: boolean;
63
+ }) => Promise<void>;
64
+ delete: (oid: ObjectIdentifier, options?: {
65
+ undoable?: boolean;
66
+ }) => Promise<void>;
67
+ private getCollectionSchema;
68
+ /**
69
+ * Constructs an entity from an OID, but does not load it.
70
+ */
71
+ private constructEntity;
72
+ private onPendingOperations;
73
+ /**
74
+ * Loads initial Entity data from storage
75
+ */
76
+ private loadEntity;
77
+ }
78
+ export {};
@@ -0,0 +1,348 @@
1
+ import { assert, assignOid, decomposeOid, getOidRoot, groupBaselinesByRootOid, groupPatchesByOid, groupPatchesByRootOid, isRootOid, removeOidsFromAllSubObjects, } from '@verdant-web/common';
2
+ import { Entity } from './Entity.js';
3
+ import { Disposable } from '../../utils/Disposable.js';
4
+ import { EntityFamilyMetadata } from './EntityMetadata.js';
5
+ import { OperationBatcher } from './OperationBatcher.js';
6
+ import { QueryableStorage } from '../../queries/QueryableStorage.js';
7
+ import { WeakEvent } from 'weak-event';
8
+ import { processValueFiles } from '../../files/utils.js';
9
+ var AbortReason;
10
+ (function (AbortReason) {
11
+ AbortReason[AbortReason["Reset"] = 0] = "Reset";
12
+ })(AbortReason || (AbortReason = {}));
13
+ export class EntityStore extends Disposable {
14
+ constructor({ ctx, meta, files, }) {
15
+ super();
16
+ this.events = {
17
+ add: new WeakEvent(),
18
+ replace: new WeakEvent(),
19
+ resetAll: new WeakEvent(),
20
+ };
21
+ this.cache = new Map();
22
+ this.pendingEntityPromises = new Map();
23
+ // halts the current data queue processing
24
+ this.abortDataQueueController = new AbortController();
25
+ this.ongoingResetPromise = null;
26
+ this.entityFinalizationRegistry = new FinalizationRegistry((oid) => {
27
+ this.ctx.log('debug', 'Entity GC', oid);
28
+ });
29
+ // internal-ish API to load remote / stored data
30
+ this.addData = async (data) => {
31
+ if (this.disposed) {
32
+ this.ctx.log('warn', 'EntityStore is disposed, not adding incoming data');
33
+ return;
34
+ }
35
+ // for resets - abort any other changes, reset everything,
36
+ // then proceed
37
+ if (data.reset) {
38
+ this.ctx.log('info', 'Resetting local store to replicate remote synced data - dropping any current transactions');
39
+ // cancel any other ongoing data - it will all
40
+ // be replaced by the reset
41
+ this.abortDataQueueController.abort(AbortReason.Reset);
42
+ this.abortDataQueueController = new AbortController();
43
+ this.ongoingResetPromise = this.resetData().finally(() => {
44
+ this.ongoingResetPromise = null;
45
+ });
46
+ }
47
+ // await either the reset we just started, or any that was
48
+ // in progress when this data came in.
49
+ if (this.ongoingResetPromise) {
50
+ this.ctx.log('debug', 'Waiting for ongoing reset to complete');
51
+ await this.ongoingResetPromise;
52
+ this.ctx.log('debug', 'Ongoing reset complete');
53
+ }
54
+ await this.processData(data);
55
+ };
56
+ this.resetData = async () => {
57
+ if (this.disposed) {
58
+ this.ctx.log('warn', 'EntityStore is disposed, not resetting local data');
59
+ return;
60
+ }
61
+ await this.meta.reset();
62
+ await this.queryableStorage.reset();
63
+ this.events.resetAll.invoke(this);
64
+ };
65
+ this.processData = async (data) => {
66
+ var _a, _b, _c;
67
+ if (this.disposed) {
68
+ this.ctx.log('warn', 'EntityStore is disposed, not processing incoming data');
69
+ return;
70
+ }
71
+ const baselines = (_a = data === null || data === void 0 ? void 0 : data.baselines) !== null && _a !== void 0 ? _a : [];
72
+ const operations = (_b = data === null || data === void 0 ? void 0 : data.operations) !== null && _b !== void 0 ? _b : [];
73
+ this.ctx.log('debug', 'Processing incoming data', {
74
+ operations: operations.length,
75
+ baselines: baselines.length,
76
+ reset: !!data.reset,
77
+ });
78
+ const allDocumentOids = Array.from(new Set(baselines
79
+ .map((b) => getOidRoot(b.oid))
80
+ .concat(operations.map((o) => getOidRoot(o.oid)))));
81
+ const baselinesGroupedByOid = groupBaselinesByRootOid(baselines);
82
+ const operationsGroupedByOid = groupPatchesByRootOid(operations);
83
+ this.ctx.log('debug', 'Applying data to live entities');
84
+ // synchronously add/replace data in any open entities via eventing
85
+ for (const oid of allDocumentOids) {
86
+ const baselines = baselinesGroupedByOid[oid];
87
+ const operations = (_c = operationsGroupedByOid[oid]) !== null && _c !== void 0 ? _c : [];
88
+ const groupedOperations = groupPatchesByOid(operations);
89
+ // what happens if an entity is being hydrated
90
+ // while this is happening? - we wait for the hydration promise
91
+ // to complete, then invoke the event
92
+ const event = data.reset ? this.events.replace : this.events.add;
93
+ const hydrationPromise = this.pendingEntityPromises.get(oid);
94
+ if (hydrationPromise) {
95
+ hydrationPromise.then(() => {
96
+ event.invoke(this, {
97
+ oid,
98
+ baselines,
99
+ operations: groupedOperations,
100
+ isLocal: false,
101
+ });
102
+ });
103
+ }
104
+ else {
105
+ if (this.cache.has(oid)) {
106
+ this.ctx.log('debug', 'Cache has', oid, ', an event should follow.');
107
+ }
108
+ event.invoke(this, {
109
+ oid,
110
+ baselines,
111
+ operations: groupedOperations,
112
+ isLocal: false,
113
+ });
114
+ }
115
+ }
116
+ const abortOptions = {
117
+ abort: this.abortDataQueueController.signal,
118
+ };
119
+ // then, asynchronously add to the database
120
+ await this.meta.insertData(data, abortOptions);
121
+ // FIXME: entities hydrated here are not seeing
122
+ // the operations just inserted above!!
123
+ // IDEA: can we coordinate here with hydrate promises
124
+ // based on affected OIDs?
125
+ // recompute all affected documents for querying
126
+ const entities = await Promise.all(allDocumentOids.map(async (oid) => {
127
+ const entity = await this.hydrate(oid, abortOptions);
128
+ // if the entity is not found, we return a stub that
129
+ // indicates it's deleted and should be cleared
130
+ return (entity !== null && entity !== void 0 ? entity : {
131
+ oid,
132
+ getSnapshot() {
133
+ return null;
134
+ },
135
+ });
136
+ }));
137
+ try {
138
+ await this.queryableStorage.saveEntities(entities, abortOptions);
139
+ }
140
+ catch (err) {
141
+ if (this.disposed) {
142
+ this.ctx.log('warn', 'Error saving entities to queryable storage - EntityStore is disposed', err);
143
+ }
144
+ else {
145
+ this.ctx.log('error', 'Error saving entities to queryable storage', err);
146
+ }
147
+ }
148
+ };
149
+ // internal-ish API for creating Entities from OIDs
150
+ // when query results come in
151
+ this.hydrate = async (oid, opts) => {
152
+ if (!isRootOid(oid)) {
153
+ throw new Error('Cannot hydrate non-root entity');
154
+ }
155
+ if (this.cache.has(oid)) {
156
+ this.ctx.log('debug', 'Hydrating entity from cache', oid);
157
+ const cached = this.cache.get(oid);
158
+ if (cached) {
159
+ const entity = cached.deref();
160
+ if (entity) {
161
+ if (entity.deleted) {
162
+ return null;
163
+ }
164
+ return entity;
165
+ }
166
+ else {
167
+ this.ctx.log('debug', "Removing GC'd entity from cache", oid);
168
+ this.cache.delete(oid);
169
+ }
170
+ }
171
+ }
172
+ // we don't want to hydrate two entities in parallel, so
173
+ // we use a promise to ensure that only one is ever
174
+ // constructed at a time
175
+ const pendingPromise = this.pendingEntityPromises.get(oid);
176
+ if (!pendingPromise) {
177
+ this.ctx.log('debug', 'Hydrating entity from storage', oid);
178
+ const entity = this.constructEntity(oid);
179
+ if (!entity) {
180
+ return null;
181
+ }
182
+ const pendingPromise = this.loadEntity(entity, opts);
183
+ pendingPromise.finally(() => {
184
+ this.pendingEntityPromises.delete(oid);
185
+ });
186
+ this.pendingEntityPromises.set(oid, pendingPromise);
187
+ return pendingPromise;
188
+ }
189
+ else {
190
+ this.ctx.log('debug', 'Waiting for entity hydration', oid);
191
+ return pendingPromise;
192
+ }
193
+ };
194
+ this.destroy = async () => {
195
+ this.dispose();
196
+ await this.batcher.flushAll();
197
+ };
198
+ // public APIs for manipulating entities
199
+ /**
200
+ * Creates a new Entity with the given initial data.
201
+ */
202
+ this.create = async (initial, oid) => {
203
+ this.ctx.log('debug', 'Creating new entity', oid);
204
+ const { collection } = decomposeOid(oid);
205
+ // remove any OID associations from the initial data
206
+ removeOidsFromAllSubObjects(initial);
207
+ // grab files and replace them with refs
208
+ const processed = processValueFiles(initial, this.files.add);
209
+ assignOid(processed, oid);
210
+ // creating a new Entity with no data, then preloading the operations
211
+ const entity = this.constructEntity(oid);
212
+ if (!entity) {
213
+ throw new Error(`Could not put new document: no schema exists for collection ${collection}`);
214
+ }
215
+ const operations = this.meta.patchCreator.createInitialize(processed, oid);
216
+ await this.batcher.commitOperations(operations, {
217
+ undoable: true,
218
+ source: entity,
219
+ });
220
+ // TODO: what happens if you create an entity with an OID that already
221
+ // exists?
222
+ // we still need to synchronously add the initial operations to the Entity
223
+ // even though they are flowing through the system
224
+ // TODO: this could be better aligned to avoid grouping here
225
+ const operationsGroupedByOid = groupPatchesByOid(operations);
226
+ this.events.add.invoke(this, {
227
+ operations: operationsGroupedByOid,
228
+ isLocal: true,
229
+ oid,
230
+ });
231
+ this.cache.set(oid, this.ctx.weakRef(entity));
232
+ return entity;
233
+ };
234
+ this.deleteAll = async (oids, options) => {
235
+ this.ctx.log('info', 'Deleting documents', oids);
236
+ assert(oids.every((oid) => oid === getOidRoot(oid)), 'Only root documents may be deleted via client methods');
237
+ const allOids = await Promise.all(oids.flatMap(async (oid) => {
238
+ var _a;
239
+ const entity = await this.hydrate(oid);
240
+ return (_a = entity === null || entity === void 0 ? void 0 : entity.__getFamilyOids__()) !== null && _a !== void 0 ? _a : [];
241
+ }));
242
+ // remove the entities from cache
243
+ oids.forEach((oid) => {
244
+ this.cache.delete(oid);
245
+ this.ctx.log('debug', 'Deleted document from cache', oid);
246
+ });
247
+ // create the delete patches and wait for them to be applied
248
+ const operations = this.meta.patchCreator.createDeleteAll(allOids.flat());
249
+ await this.batcher.commitOperations(operations, {
250
+ undoable: (options === null || options === void 0 ? void 0 : options.undoable) === undefined ? true : options.undoable,
251
+ });
252
+ };
253
+ this.delete = async (oid, options) => {
254
+ return this.deleteAll([oid], options);
255
+ };
256
+ this.getCollectionSchema = (collectionName) => {
257
+ const schema = this.ctx.schema.collections[collectionName];
258
+ if (!schema) {
259
+ this.ctx.log('warn', `Missing schema for collection: ${collectionName}`);
260
+ return {
261
+ schema: null,
262
+ readonlyKeys: [],
263
+ };
264
+ }
265
+ return {
266
+ // convert to object schema for compatibility
267
+ schema: {
268
+ type: 'object',
269
+ nullable: false,
270
+ properties: schema.fields,
271
+ },
272
+ readonlyKeys: [schema.primaryKey],
273
+ };
274
+ };
275
+ /**
276
+ * Constructs an entity from an OID, but does not load it.
277
+ */
278
+ this.constructEntity = (oid) => {
279
+ const { collection } = decomposeOid(oid);
280
+ const { schema, readonlyKeys } = this.getCollectionSchema(collection);
281
+ if (!schema) {
282
+ return null;
283
+ }
284
+ if (this.disposed) {
285
+ throw new Error('Cannot hydrate entity after store has been disposed');
286
+ }
287
+ const metadataFamily = new EntityFamilyMetadata({
288
+ ctx: this.ctx,
289
+ onPendingOperations: this.onPendingOperations,
290
+ rootOid: oid,
291
+ });
292
+ // this is created synchronously so it's immediately available
293
+ // to begin capturing incoming data.
294
+ return new Entity({
295
+ ctx: this.ctx,
296
+ oid,
297
+ schema,
298
+ readonlyKeys,
299
+ files: this.files,
300
+ metadataFamily: metadataFamily,
301
+ patchCreator: this.meta.patchCreator,
302
+ events: this.events,
303
+ });
304
+ };
305
+ this.onPendingOperations = (operations) => {
306
+ this.batcher.addOperations(operations);
307
+ };
308
+ /**
309
+ * Loads initial Entity data from storage
310
+ */
311
+ this.loadEntity = async (entity, opts) => {
312
+ const { operations, baselines } = await this.meta.getDocumentData(entity.oid, opts);
313
+ if (!baselines.length && !Object.keys(operations).length) {
314
+ this.ctx.log('debug', 'No data found for entity', entity.oid);
315
+ return null;
316
+ }
317
+ this.ctx.log('debug', 'Loaded entity from storage', entity.oid);
318
+ this.events.replace.invoke(this, {
319
+ oid: entity.oid,
320
+ baselines,
321
+ operations,
322
+ isLocal: false,
323
+ });
324
+ // only set the cache after loading.
325
+ // TODO: is this cache/promise stuff redundant?
326
+ this.cache.set(entity.oid, this.ctx.weakRef(entity));
327
+ this.entityFinalizationRegistry.register(entity, entity.oid);
328
+ return entity;
329
+ };
330
+ this.ctx = ctx;
331
+ this.meta = meta;
332
+ this.files = files;
333
+ this.queryableStorage = new QueryableStorage({ ctx });
334
+ this.batcher = new OperationBatcher({
335
+ ctx,
336
+ meta,
337
+ entities: this,
338
+ });
339
+ }
340
+ // expose batch APIs
341
+ get batch() {
342
+ return this.batcher.batch;
343
+ }
344
+ get flushAllBatches() {
345
+ return this.batcher.flushAll;
346
+ }
347
+ }
348
+ //# sourceMappingURL=EntityStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityStore.js","sourceRoot":"","sources":["../../../../src/entities/2/EntityStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { Operation } from '@verdant-web/common';
2
+ import { Metadata } from '../../metadata/Metadata.js';
3
+ import { Context } from '../../context.js';
4
+ import type { EntityStore } from './EntityStore.js';
5
+ import { Entity } from './Entity.js';
6
+ export interface OperationBatch {
7
+ run: (fn: () => void) => this;
8
+ /** @deprecated - use commit() */
9
+ flush: () => Promise<void>;
10
+ commit: () => Promise<void>;
11
+ discard: () => void;
12
+ }
13
+ export declare class OperationBatcher {
14
+ private batcher;
15
+ private currentBatchKey;
16
+ private defaultBatchTimeout;
17
+ private meta;
18
+ private ctx;
19
+ private entities;
20
+ constructor({ batchTimeout, meta, ctx, entities, }: {
21
+ batchTimeout?: number;
22
+ meta: Metadata;
23
+ ctx: Context;
24
+ entities: EntityStore;
25
+ });
26
+ get isDefaultBatch(): boolean;
27
+ private flushOperations;
28
+ /**
29
+ * Immediately flushes operations to storage / sync.
30
+ * Providing source to second arg skips hydrating related
31
+ * Entity from storage, which is useful when that Entity
32
+ * isn't in storage (i.e. still creating) or just to speed
33
+ * up the commit.
34
+ */
35
+ commitOperations: (operations: Operation[], meta: {
36
+ undoable?: boolean;
37
+ source?: Entity;
38
+ }) => Promise<void>;
39
+ /**
40
+ * Adds operations to the active batch.
41
+ */
42
+ addOperations: (operations: Operation[]) => void;
43
+ batch: ({ undoable, batchName, max, timeout, }?: {
44
+ undoable?: boolean | undefined;
45
+ batchName?: string | undefined;
46
+ max?: number | null | undefined;
47
+ timeout?: number | null | undefined;
48
+ }) => OperationBatch;
49
+ flushAll: () => Promise<any[]>;
50
+ private createUndo;
51
+ private getInverseOperations;
52
+ }
@@ -0,0 +1,161 @@
1
+ import { Batcher, generateId, getOidRoot, getUndoOperations, groupPatchesByOid, } from '@verdant-web/common';
2
+ const DEFAULT_BATCH_KEY = '@@default';
3
+ export class OperationBatcher {
4
+ constructor({ batchTimeout = 200, meta, ctx, entities, }) {
5
+ this.currentBatchKey = DEFAULT_BATCH_KEY;
6
+ this.flushOperations = async (operations, batchKey, meta) => {
7
+ this.ctx.log('debug', 'Flushing', operations.length, 'operations from batch', batchKey, 'to storage / sync');
8
+ if (!operations.length)
9
+ return;
10
+ // rewrite timestamps of all operations to now - this preserves
11
+ // the linear history of operations which are sent to the server.
12
+ // even if multiple batches are spun up in parallel and flushed
13
+ // after delay, the final operations in each one should reflect
14
+ // when the batch flushed, not when the changes were made.
15
+ // This also corresponds to user-observed behavior, since unconfirmed
16
+ // operations are applied universally after confirmed operations locally,
17
+ // so even operations which were made before a remote operation but
18
+ // have not been confirmed yet will appear to come after the remote one
19
+ // despite the provisional timestamp being earlier
20
+ // NOTE: this MUST be mutating the original operation object! this timestamp
21
+ // also serves as a unique ID for deduplication later.
22
+ for (const op of operations) {
23
+ op.timestamp = this.meta.now;
24
+ }
25
+ await this.commitOperations(operations, meta);
26
+ };
27
+ /**
28
+ * Immediately flushes operations to storage / sync.
29
+ * Providing source to second arg skips hydrating related
30
+ * Entity from storage, which is useful when that Entity
31
+ * isn't in storage (i.e. still creating) or just to speed
32
+ * up the commit.
33
+ */
34
+ this.commitOperations = async (operations, meta) => {
35
+ if (!operations.length)
36
+ return;
37
+ // now is the time to decide on what the undo operations will
38
+ // look like, based on the confirmed view of the related entities.
39
+ if (meta.undoable) {
40
+ const undo = await this.createUndo({
41
+ ops: operations,
42
+ source: meta.source,
43
+ });
44
+ if (undo)
45
+ this.ctx.undoHistory.addUndo(undo);
46
+ }
47
+ // ship it out to EntityStore to compute final snapshots
48
+ // write to storage and refresh entities and queries
49
+ await this.entities.addData({
50
+ operations,
51
+ baselines: [],
52
+ isLocal: true,
53
+ });
54
+ };
55
+ /**
56
+ * Adds operations to the active batch.
57
+ */
58
+ this.addOperations = (operations) => {
59
+ if (!operations.length)
60
+ return;
61
+ this.batcher.add({
62
+ key: this.currentBatchKey,
63
+ items: operations,
64
+ });
65
+ this.ctx.log(`debug`, 'added', operations.length, 'ops to batch', this.currentBatchKey, ', size = ', this.batcher.getSize(this.currentBatchKey));
66
+ };
67
+ this.batch = ({ undoable = true, batchName = generateId(), max = null, timeout = this.defaultBatchTimeout, } = {}) => {
68
+ const internalBatch = this.batcher.add({
69
+ key: batchName,
70
+ max,
71
+ timeout,
72
+ items: [],
73
+ userData: { undoable },
74
+ });
75
+ const externalApi = {
76
+ run: (fn) => {
77
+ // while the provided function runs, operations are forwarded
78
+ // to the new batch instead of default. this relies on the function
79
+ // being synchronous.
80
+ this.currentBatchKey = batchName;
81
+ fn();
82
+ this.currentBatchKey = DEFAULT_BATCH_KEY;
83
+ return externalApi;
84
+ },
85
+ commit: async () => {
86
+ // before running a batch, the default operations must be flushed
87
+ // this better preserves undo history behavior...
88
+ // if we left the default batch open while flushing a named batch,
89
+ // then the default batch would be flushed after the named batch,
90
+ // and the default batch could contain operations both prior and
91
+ // after the named batch. this would result in a confusing undo
92
+ // history where the first undo might reverse changes before and
93
+ // after a set of other changes.
94
+ await this.batcher.flush(DEFAULT_BATCH_KEY);
95
+ return internalBatch.flush();
96
+ },
97
+ flush: () => externalApi.commit(),
98
+ discard: () => {
99
+ this.batcher.discard(batchName);
100
+ },
101
+ };
102
+ return externalApi;
103
+ };
104
+ this.flushAll = () => Promise.all(this.batcher.flushAll());
105
+ this.createUndo = async (data) => {
106
+ // this can't be done on-demand because we rely on the current
107
+ // state of the entities to calculate the inverse operations.
108
+ const inverseOps = await this.getInverseOperations(data);
109
+ if (!inverseOps.length)
110
+ return null;
111
+ return async () => {
112
+ const redo = await this.createUndo({
113
+ ops: inverseOps,
114
+ source: data.source,
115
+ });
116
+ // set time to now for all undo operations, they're happening now.
117
+ for (const op of inverseOps) {
118
+ op.timestamp = this.meta.now;
119
+ }
120
+ await this.commitOperations(inverseOps,
121
+ // undos should not generate their own undo operations
122
+ // since they already calculate redo as the inverse.
123
+ { undoable: false });
124
+ return redo;
125
+ };
126
+ };
127
+ this.getInverseOperations = async ({ ops, source, }) => {
128
+ const grouped = groupPatchesByOid(ops);
129
+ const inverseOps = [];
130
+ const getNow = () => this.meta.now;
131
+ await Promise.all(Object.entries(grouped).map(async ([oid, patches]) => {
132
+ const entity = source !== null && source !== void 0 ? source : (await this.entities.hydrate(getOidRoot(oid)));
133
+ // TODO: this is getting the rebased baseline? how? are ops being submitted early?
134
+ const viewData = entity === null || entity === void 0 ? void 0 : entity.__getViewData__(oid, 'confirmed');
135
+ if (!viewData) {
136
+ this.ctx.log('warn', 'could not find entity', oid, 'for undo operation', ops);
137
+ return;
138
+ }
139
+ const inverse = getUndoOperations(oid, viewData.view, patches, getNow);
140
+ inverseOps.unshift(...inverse);
141
+ }));
142
+ return inverseOps;
143
+ };
144
+ this.meta = meta;
145
+ this.ctx = ctx;
146
+ this.entities = entities;
147
+ this.defaultBatchTimeout = batchTimeout;
148
+ this.batcher = new Batcher(this.flushOperations);
149
+ this.batcher.add({
150
+ key: DEFAULT_BATCH_KEY,
151
+ items: [],
152
+ max: 100,
153
+ timeout: batchTimeout,
154
+ userData: { undoable: true },
155
+ });
156
+ }
157
+ get isDefaultBatch() {
158
+ return this.currentBatchKey === DEFAULT_BATCH_KEY;
159
+ }
160
+ }
161
+ //# sourceMappingURL=OperationBatcher.js.map