@verdant-web/store 2.8.5 → 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 +37 -6
  15. package/dist/cjs/__tests__/documents.test.js.map +1 -1
  16. package/dist/cjs/__tests__/fixtures/testStorage.d.ts +2 -2
  17. package/dist/cjs/__tests__/fixtures/testStorage.js +2 -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 +8 -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 +5 -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 +37 -6
  142. package/dist/esm/__tests__/documents.test.js.map +1 -1
  143. package/dist/esm/__tests__/fixtures/testStorage.d.ts +2 -2
  144. package/dist/esm/__tests__/fixtures/testStorage.js +2 -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 +8 -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 +4 -2
  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 +44 -6
  265. package/src/__tests__/fixtures/testStorage.ts +3 -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 +8 -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 +6 -2
  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
@@ -7,10 +7,11 @@ import {
7
7
  getLegacyDotOidSubIdRange,
8
8
  } from '@verdant-web/common';
9
9
  import { IDBService } from '../IDBService.js';
10
+ import { Context } from '../context.js';
10
11
 
11
12
  export class BaselinesStore extends IDBService {
12
- constructor(db: IDBDatabase) {
13
- super(db);
13
+ constructor(db: IDBDatabase, opts: { log?: Context['log'] }) {
14
+ super(db, opts);
14
15
  }
15
16
 
16
17
  getAllForDocument = async (
@@ -61,8 +62,7 @@ export class BaselinesStore extends IDBService {
61
62
  // }
62
63
  },
63
64
  iterator,
64
- mode,
65
- transaction,
65
+ { mode, transaction },
66
66
  );
67
67
  };
68
68
 
@@ -84,8 +84,7 @@ export class BaselinesStore extends IDBService {
84
84
  ];
85
85
  },
86
86
  iterator,
87
- mode,
88
- transaction,
87
+ { mode, transaction },
89
88
  );
90
89
  };
91
90
 
@@ -115,7 +114,7 @@ export class BaselinesStore extends IDBService {
115
114
  // }
116
115
  });
117
116
  },
118
- mode,
117
+ { mode },
119
118
  );
120
119
  return result.flat();
121
120
  };
@@ -133,7 +132,7 @@ export class BaselinesStore extends IDBService {
133
132
  const index = store.index('timestamp');
134
133
  return index.getAll(range);
135
134
  },
136
- mode,
135
+ { mode },
137
136
  );
138
137
  };
139
138
 
@@ -144,24 +143,20 @@ export class BaselinesStore extends IDBService {
144
143
  mode = 'readonly',
145
144
  }: { transaction?: IDBTransaction; mode?: 'readwrite' | 'readonly' } = {},
146
145
  ) => {
147
- return this.run<DocumentBaseline>(
148
- 'baselines',
149
- (store) => store.get(oid),
146
+ return this.run<DocumentBaseline>('baselines', (store) => store.get(oid), {
150
147
  mode,
151
148
  transaction,
152
- );
149
+ });
153
150
  };
154
151
 
155
152
  set = async <T>(
156
153
  baseline: DocumentBaseline<T>,
157
154
  { transaction }: { transaction?: IDBTransaction } = {},
158
155
  ) => {
159
- await this.run(
160
- 'baselines',
161
- (store) => store.put(baseline),
162
- 'readwrite',
156
+ await this.run('baselines', (store) => store.put(baseline), {
157
+ mode: 'readwrite',
163
158
  transaction,
164
- );
159
+ });
165
160
  };
166
161
 
167
162
  setAll = async <T>(
@@ -173,8 +168,7 @@ export class BaselinesStore extends IDBService {
173
168
  (store) => {
174
169
  return baselines.map((baseline) => store.put(baseline));
175
170
  },
176
- 'readwrite',
177
- transaction,
171
+ { mode: 'readwrite', transaction },
178
172
  );
179
173
  };
180
174
 
@@ -186,11 +180,9 @@ export class BaselinesStore extends IDBService {
186
180
  oid: ObjectIdentifier,
187
181
  { transaction }: { transaction?: IDBTransaction },
188
182
  ) => {
189
- await this.run(
190
- 'baselines',
191
- (store) => store.delete(oid),
192
- 'readwrite',
183
+ await this.run('baselines', (store) => store.delete(oid), {
184
+ mode: 'readwrite',
193
185
  transaction,
194
- );
186
+ });
195
187
  };
196
188
  }
@@ -12,7 +12,9 @@ export class LocalReplicaStore extends IDBService {
12
12
  private _creating: Promise<void> | undefined;
13
13
  private cached: LocalReplicaInfo | undefined;
14
14
 
15
- get = async ({ transaction }: { transaction?: IDBTransaction } = {}): Promise<LocalReplicaInfo> => {
15
+ get = async ({
16
+ transaction,
17
+ }: { transaction?: IDBTransaction } = {}): Promise<LocalReplicaInfo> => {
16
18
  if (this.cached) {
17
19
  return this.cached;
18
20
  }
@@ -20,8 +22,7 @@ export class LocalReplicaStore extends IDBService {
20
22
  const lookup = await this.run<LocalReplicaInfo>(
21
23
  'info',
22
24
  (store) => store.get('localReplicaInfo'),
23
- undefined,
24
- transaction,
25
+ { transaction },
25
26
  );
26
27
 
27
28
  // not cached, not in db, create it
@@ -38,7 +39,9 @@ export class LocalReplicaStore extends IDBService {
38
39
  ackedLogicalTime: null,
39
40
  lastSyncedLogicalTime: null,
40
41
  };
41
- await this.run('info', (store) => store.put(replicaInfo), 'readwrite');
42
+ await this.run('info', (store) => store.put(replicaInfo), {
43
+ mode: 'readwrite',
44
+ });
42
45
  this.cached = replicaInfo;
43
46
  })();
44
47
  }
@@ -57,7 +60,9 @@ export class LocalReplicaStore extends IDBService {
57
60
  ) => {
58
61
  const localReplicaInfo = await this.get({ transaction });
59
62
  Object.assign(localReplicaInfo, data);
60
- await this.run('info', (store) => store.put(localReplicaInfo), 'readwrite');
63
+ await this.run('info', (store) => store.put(localReplicaInfo), {
64
+ mode: 'readwrite',
65
+ });
61
66
  this.cached = localReplicaInfo;
62
67
  };
63
68
 
@@ -65,6 +70,8 @@ export class LocalReplicaStore extends IDBService {
65
70
  const localInfo = await this.get();
66
71
  localInfo.ackedLogicalTime = null;
67
72
  localInfo.lastSyncedLogicalTime = null;
68
- await this.run('info', (store) => store.put(localInfo), 'readwrite');
73
+ await this.run('info', (store) => store.put(localInfo), {
74
+ mode: 'readwrite',
75
+ });
69
76
  };
70
77
  }
@@ -19,6 +19,7 @@ import {
19
19
  import { AckInfoStore } from './AckInfoStore.js';
20
20
  import { BaselinesStore } from './BaselinesStore.js';
21
21
  import {
22
+ createAbortableTransaction,
22
23
  getAllFromObjectStores,
23
24
  getSizeOfObjectStore,
24
25
  storeRequestPromise,
@@ -57,20 +58,20 @@ export class Metadata extends EventSubscriber<{
57
58
  */
58
59
  private _closing = false;
59
60
 
60
- private context: Omit<Context, 'documentDb'>;
61
+ private context: Omit<Context, 'documentDb' | 'getNow'>;
61
62
 
62
63
  constructor({
63
64
  disableRebasing,
64
65
  context,
65
66
  }: {
66
67
  disableRebasing?: boolean;
67
- context: Omit<Context, 'documentDb'>;
68
+ context: Omit<Context, 'documentDb' | 'getNow'>;
68
69
  }) {
69
70
  super();
70
71
  this.context = context;
71
72
  this.schema = new SchemaStore(context.metaDb, context.schema.version);
72
- this.operations = new OperationsStore(this.db);
73
- this.baselines = new BaselinesStore(this.db);
73
+ this.operations = new OperationsStore(this.db, { log: context.log });
74
+ this.baselines = new BaselinesStore(this.db, { log: context.log });
74
75
  this.localReplica = new LocalReplicaStore(this.db);
75
76
  this.ackInfo = new AckInfoStore(this.db);
76
77
  this.messageCreator = new MessageCreator(this);
@@ -102,8 +103,19 @@ export class Metadata extends EventSubscriber<{
102
103
  * Methods for accessing data
103
104
  */
104
105
 
105
- createTransaction = (stores: ('operations' | 'baselines')[]) => {
106
- return this.db.transaction(stores, 'readwrite');
106
+ createTransaction = (
107
+ stores: ('operations' | 'baselines')[],
108
+ opts: {
109
+ abort?: AbortSignal;
110
+ } = {},
111
+ ) => {
112
+ return createAbortableTransaction(
113
+ this.db,
114
+ stores,
115
+ 'readwrite',
116
+ opts.abort,
117
+ this.context.log,
118
+ );
107
119
  };
108
120
 
109
121
  /**
@@ -117,10 +129,7 @@ export class Metadata extends EventSubscriber<{
117
129
  assert(documentOid === oid, 'Must be root document OID');
118
130
  oids.add(documentOid);
119
131
  // readwrite mode to block on other write transactions
120
- const transaction = this.db.transaction(
121
- ['baselines', 'operations'],
122
- 'readwrite',
123
- );
132
+ const transaction = this.createTransaction(['baselines', 'operations']);
124
133
  await Promise.all([
125
134
  this.baselines.iterateOverAllForDocument(
126
135
  documentOid,
@@ -210,6 +219,43 @@ export class Metadata extends EventSubscriber<{
210
219
  return root;
211
220
  };
212
221
 
222
+ getDocumentData = async (
223
+ oid: ObjectIdentifier,
224
+ opts?: {
225
+ abort?: AbortSignal;
226
+ },
227
+ ) => {
228
+ const transaction = this.createTransaction(
229
+ ['baselines', 'operations'],
230
+ opts,
231
+ );
232
+ const baselines: DocumentBaseline[] = [];
233
+ const operations: Record<ObjectIdentifier, Operation[]> = {};
234
+ await Promise.all([
235
+ this.baselines.iterateOverAllForDocument(
236
+ oid,
237
+ (baseline) => {
238
+ baselines.push(baseline);
239
+ },
240
+ {
241
+ transaction,
242
+ },
243
+ ),
244
+ this.operations.iterateOverAllOperationsForDocument(
245
+ oid,
246
+ (op) => {
247
+ operations[op.oid] ??= [];
248
+ operations[op.oid].push(op);
249
+ },
250
+ { transaction },
251
+ ),
252
+ ]);
253
+ return {
254
+ baselines,
255
+ operations,
256
+ };
257
+ };
258
+
213
259
  /**
214
260
  * Methods for writing data
215
261
  */
@@ -242,16 +288,23 @@ export class Metadata extends EventSubscriber<{
242
288
  * Applies a patch to the document and stores it in the database.
243
289
  * @returns the oldest local history timestamp
244
290
  */
245
- insertLocalOperation = async (operations: Operation[]) => {
291
+ insertLocalOperations = async (
292
+ operations: Operation[],
293
+ opts?: { transaction?: IDBTransaction },
294
+ ) => {
246
295
  if (operations.length === 0) return;
247
296
  // await this.rebaseLock;
248
- this.log(`Inserting ${operations.length} local operations`);
297
+ this.log(
298
+ 'debug',
299
+ `Inserting ${operations.length} local operations`,
300
+ operations,
301
+ );
249
302
 
250
303
  // add local flag, in place.
251
304
  for (const operation of operations) {
252
305
  (operation as ClientOperation).isLocal = true;
253
306
  }
254
- await this.operations.addOperations(operations as ClientOperation[]);
307
+ await this.operations.addOperations(operations as ClientOperation[], opts);
255
308
 
256
309
  const message = await this.messageCreator.createOperation({ operations });
257
310
  this.emit('message', message);
@@ -264,16 +317,24 @@ export class Metadata extends EventSubscriber<{
264
317
  * Inserts remote operations. This does not affect local history.
265
318
  * @returns a list of affected document OIDs
266
319
  */
267
- insertRemoteOperations = async (operations: Operation[]) => {
320
+ insertRemoteOperations = async (
321
+ operations: Operation[],
322
+ opts?: { transaction?: IDBTransaction },
323
+ ) => {
268
324
  if (operations.length === 0) return [];
269
325
  // await this.rebaseLock;
270
- this.log(`Inserting ${operations.length} remote operations`);
326
+ this.log(
327
+ 'debug',
328
+ `Inserting ${operations.length} remote operations`,
329
+ operations,
330
+ );
271
331
 
272
332
  const affectedDocumentOids = await this.operations.addOperations(
273
333
  operations.map((patch) => ({
274
334
  ...patch,
275
335
  isLocal: false,
276
336
  })),
337
+ opts,
277
338
  );
278
339
 
279
340
  this.ack(operations[operations.length - 1].timestamp);
@@ -281,11 +342,14 @@ export class Metadata extends EventSubscriber<{
281
342
  return affectedDocumentOids;
282
343
  };
283
344
 
284
- insertRemoteBaselines = async (baselines: DocumentBaseline[]) => {
345
+ insertRemoteBaselines = async (
346
+ baselines: DocumentBaseline[],
347
+ opts?: { transaction?: IDBTransaction },
348
+ ) => {
285
349
  if (baselines.length === 0) return [];
286
350
  this.log(`Inserting ${baselines.length} remote baselines`);
287
351
 
288
- await this.baselines.setAll(baselines);
352
+ await this.baselines.setAll(baselines, opts);
289
353
 
290
354
  // this.ack(baselines[baselines.length - 1].timestamp);
291
355
 
@@ -297,6 +361,31 @@ export class Metadata extends EventSubscriber<{
297
361
  return Array.from(affectedOidSet);
298
362
  };
299
363
 
364
+ insertData = async (
365
+ data: {
366
+ baselines?: DocumentBaseline[];
367
+ operations?: Operation[];
368
+ isLocal?: boolean;
369
+ },
370
+ opts?: { abort: AbortSignal },
371
+ ) => {
372
+ const transaction = this.createTransaction(
373
+ ['baselines', 'operations'],
374
+ opts,
375
+ );
376
+ if (data.baselines) {
377
+ await this.insertRemoteBaselines(data.baselines, { transaction });
378
+ }
379
+ if (opts?.abort?.aborted) return;
380
+ if (data.operations) {
381
+ if (data.isLocal) {
382
+ await this.insertLocalOperations(data.operations, { transaction });
383
+ } else {
384
+ await this.insertRemoteOperations(data.operations, { transaction });
385
+ }
386
+ }
387
+ };
388
+
300
389
  updateLastSynced = async (timestamp: string) => {
301
390
  if (this._closing) return;
302
391
 
@@ -331,10 +420,7 @@ export class Metadata extends EventSubscriber<{
331
420
  // find all operations before the global ack
332
421
  let lastTimestamp;
333
422
  const toRebase = new Set<ObjectIdentifier>();
334
- const transaction = this.db.transaction(
335
- ['baselines', 'operations'],
336
- 'readwrite',
337
- );
423
+ const transaction = this.createTransaction(['baselines', 'operations']);
338
424
  let operationCount = 0;
339
425
  await this.operations.iterateOverAllOperations(
340
426
  (patch) => {
@@ -349,7 +435,6 @@ export class Metadata extends EventSubscriber<{
349
435
  );
350
436
 
351
437
  if (!toRebase.size) {
352
- this.log('Cannot rebase, no operations prior to', globalAckTimestamp);
353
438
  return;
354
439
  }
355
440
 
@@ -381,8 +466,7 @@ export class Metadata extends EventSubscriber<{
381
466
 
382
467
  this.log('[', replicaId, ']', 'Rebasing', oid, 'up to', upTo);
383
468
  const transaction =
384
- providedTx ||
385
- this.db.transaction(['operations', 'baselines'], 'readwrite');
469
+ providedTx || this.createTransaction(['operations', 'baselines']);
386
470
  const baseline = await this.baselines.get(oid, { transaction });
387
471
  let current: any = baseline?.snapshot || undefined;
388
472
  let operationsApplied = 0;
@@ -419,6 +503,7 @@ export class Metadata extends EventSubscriber<{
419
503
  }
420
504
 
421
505
  this.log(
506
+ 'debug',
422
507
  'successfully rebased',
423
508
  oid,
424
509
  'up to',
@@ -8,6 +8,7 @@ import {
8
8
  assert,
9
9
  } from '@verdant-web/common';
10
10
  import { IDBService } from '../IDBService.js';
11
+ import { isAbortError } from '../idb.js';
11
12
 
12
13
  export type ClientOperation = Operation & {
13
14
  isLocal: boolean;
@@ -20,6 +21,9 @@ export type StoredClientOperation = ClientOperation & {
20
21
  };
21
22
 
22
23
  export class OperationsStore extends IDBService {
24
+ constructor(db: IDBDatabase, opts: { log?: (...args: any[]) => void }) {
25
+ super(db, opts);
26
+ }
23
27
  /**
24
28
  * Iterates over every patch for the root and every sub-object
25
29
  * of a given document. Optionally limit by timestamp.
@@ -41,7 +45,11 @@ export class OperationsStore extends IDBService {
41
45
  transaction?: IDBTransaction;
42
46
  } = {},
43
47
  ): Promise<void> => {
44
- const transaction = providedTx || this.db.transaction('operations', mode);
48
+ const transaction =
49
+ providedTx ||
50
+ this.createTransaction(['operations'], {
51
+ mode,
52
+ });
45
53
  const store = transaction.objectStore('operations');
46
54
  const index = store.index('d_t');
47
55
 
@@ -77,7 +85,12 @@ export class OperationsStore extends IDBService {
77
85
  }
78
86
  };
79
87
  request.onerror = (event) => {
80
- reject(event);
88
+ if (isAbortError(request.error)) {
89
+ resolve();
90
+ return;
91
+ } else {
92
+ reject(request.error);
93
+ }
81
94
  };
82
95
  });
83
96
  };
@@ -97,7 +110,8 @@ export class OperationsStore extends IDBService {
97
110
  transaction?: IDBTransaction;
98
111
  },
99
112
  ): Promise<void> => {
100
- const transaction = providedTx || this.db.transaction('operations', mode);
113
+ const transaction =
114
+ providedTx || this.createTransaction(['operations'], { mode });
101
115
  const store = transaction.objectStore('operations');
102
116
 
103
117
  const start = after
@@ -131,7 +145,11 @@ export class OperationsStore extends IDBService {
131
145
  }
132
146
  };
133
147
  request.onerror = (event) => {
134
- reject(event);
148
+ if (isAbortError(request.error)) {
149
+ resolve();
150
+ } else {
151
+ reject(request.error);
152
+ }
135
153
  };
136
154
  });
137
155
  };
@@ -151,7 +169,8 @@ export class OperationsStore extends IDBService {
151
169
  transaction?: IDBTransaction;
152
170
  },
153
171
  ): Promise<void> => {
154
- const transaction = providedTx || this.db.transaction('operations', mode);
172
+ const transaction =
173
+ providedTx || this.createTransaction(['operations'], { mode });
155
174
 
156
175
  return this.iterate(
157
176
  'operations',
@@ -162,8 +181,7 @@ export class OperationsStore extends IDBService {
162
181
  );
163
182
  },
164
183
  iterator,
165
- mode,
166
- transaction,
184
+ { mode, transaction },
167
185
  );
168
186
  };
169
187
 
@@ -181,7 +199,8 @@ export class OperationsStore extends IDBService {
181
199
  transaction?: IDBTransaction;
182
200
  },
183
201
  ): Promise<void> => {
184
- const transaction = providedTx || this.db.transaction('operations', mode);
202
+ const transaction =
203
+ providedTx || this.createTransaction(['operations'], { mode });
185
204
  const store = transaction.objectStore('operations');
186
205
  const index = store.index('l_t');
187
206
 
@@ -215,7 +234,11 @@ export class OperationsStore extends IDBService {
215
234
  }
216
235
  };
217
236
  request.onerror = (event) => {
218
- reject(event);
237
+ if (isAbortError(request.error)) {
238
+ resolve();
239
+ } else {
240
+ reject(request.error);
241
+ }
219
242
  };
220
243
  });
221
244
  };
@@ -244,18 +267,17 @@ export class OperationsStore extends IDBService {
244
267
 
245
268
  const range =
246
269
  start && end
247
- ? IDBKeyRange.bound(start, end, false, true)
270
+ ? window.IDBKeyRange.bound(start, end, false, true)
248
271
  : start
249
- ? IDBKeyRange.lowerBound(start, false)
272
+ ? window.IDBKeyRange.lowerBound(start, false)
250
273
  : end
251
- ? IDBKeyRange.upperBound(end, true)
274
+ ? window.IDBKeyRange.upperBound(end, true)
252
275
  : undefined;
253
276
  const index = store.index('timestamp');
254
277
  return index.openCursor(range, 'next');
255
278
  },
256
279
  iterator,
257
- mode,
258
- transaction,
280
+ { mode, transaction },
259
281
  );
260
282
  };
261
283
 
@@ -299,8 +321,7 @@ export class OperationsStore extends IDBService {
299
321
  affected.add(getOidRoot(op.oid));
300
322
  return store.put(op);
301
323
  }),
302
- 'readwrite',
303
- transaction,
324
+ { mode: 'readwrite', transaction },
304
325
  );
305
326
  return Array.from(affected);
306
327
  };
@@ -14,6 +14,7 @@ import {
14
14
  decomposeOid,
15
15
  diffToPatches,
16
16
  getIndexValues,
17
+ getOid,
17
18
  getOidRoot,
18
19
  hasOid,
19
20
  initialToPatches,
@@ -258,7 +259,11 @@ async function runMigrations({
258
259
  `Migration failed (${migration.oldSchema.version} -> ${migration.newSchema.version})`,
259
260
  err,
260
261
  );
261
- throw err;
262
+ if (err instanceof Error) {
263
+ throw err;
264
+ } else {
265
+ throw new Error('Unknown error during migration');
266
+ }
262
267
  }
263
268
 
264
269
  // now we have to open the database again with the next version and
@@ -356,6 +361,25 @@ async function runMigrations({
356
361
  }),
357
362
  );
358
363
 
364
+ // add 'touch' operations to all root OIDs of all documents.
365
+ // this marks documents which have undergone a migration
366
+ // so that other clients know when they're working
367
+ // with unmigrated data - by seeing that there are no
368
+ // existing operations or baselines with a timestamp
369
+ // that matches the current version.
370
+ // UPDATE: no longer necessary now that pruning is a thing.
371
+ // await Promise.all(
372
+ // oids.map((oid) =>
373
+ // meta.insertLocalOperations([
374
+ // {
375
+ // oid,
376
+ // timestamp: meta.time.zero(migration.version),
377
+ // data: { op: 'touch' },
378
+ // },
379
+ // ]),
380
+ // ),
381
+ // );
382
+
359
383
  const snapshots = await Promise.all(
360
384
  oids.map(async (oid) => {
361
385
  try {
@@ -396,10 +420,7 @@ async function runMigrations({
396
420
  await Promise.all(
397
421
  views.map(([oid, view]) => {
398
422
  if (view) {
399
- return putView(writeStore, view).catch((err) => {
400
- view;
401
- throw err;
402
- });
423
+ return putView(writeStore, view);
403
424
  } else {
404
425
  const { id } = decomposeOid(oid);
405
426
  return deleteView(writeStore, id);
@@ -453,7 +474,7 @@ function getMigrationMutations({
453
474
  doc[migration.newSchema.collections[collectionName].primaryKey];
454
475
  const oid = createOid(collectionName, primaryKey);
455
476
  newOids.push(oid);
456
- await meta.insertLocalOperation(
477
+ await meta.insertLocalOperations(
457
478
  initialToPatches(doc, oid, getMigrationNow),
458
479
  );
459
480
  return doc;
@@ -461,7 +482,7 @@ function getMigrationMutations({
461
482
  delete: async (id: string) => {
462
483
  const rootOid = createOid(collectionName, id);
463
484
  const allOids = await meta.getAllDocumentRelatedOids(rootOid);
464
- return meta.insertLocalOperation(
485
+ return meta.insertLocalOperations(
465
486
  allOids.map((oid) => ({
466
487
  oid,
467
488
  timestamp: getMigrationNow(),
@@ -556,7 +577,7 @@ function getMigrationEngine({
556
577
  });
557
578
  const deleteCollection = async (collection: string) => {
558
579
  const allOids = await meta.getAllCollectionRelatedOids(collection);
559
- return meta.insertLocalOperation(
580
+ return meta.insertLocalOperations(
560
581
  allOids.map((oid) => ({
561
582
  oid,
562
583
  timestamp: getMigrationNow(),
@@ -574,8 +595,9 @@ function getMigrationEngine({
574
595
 
575
596
  await Promise.all(
576
597
  docs.filter(Boolean).map(async (doc: any) => {
598
+ const rootOid = getOid(doc);
577
599
  assert(
578
- hasOid(doc),
600
+ !!rootOid,
579
601
  `Document is missing an OID: ${JSON.stringify(doc)}`,
580
602
  );
581
603
  const original = cloneDeep(doc);
@@ -599,7 +621,7 @@ function getMigrationEngine({
599
621
  },
600
622
  );
601
623
  if (patches.length > 0) {
602
- await meta.insertLocalOperation(patches);
624
+ await meta.insertLocalOperations(patches);
603
625
  }
604
626
  }
605
627
  }),
@@ -1,6 +1,6 @@
1
1
  import { EventSubscriber } from '@verdant-web/common';
2
2
  import { Context } from '../context.js';
3
- import { Entity } from '../entities/Entity.js';
3
+ import { Entity } from '../entities/2/Entity.js';
4
4
  import { Disposable } from '../utils/Disposable.js';
5
5
  import { filterResultSet } from './utils.js';
6
6
 
@@ -70,11 +70,15 @@ export abstract class BaseQuery<T> extends Disposable {
70
70
  (collections) => {
71
71
  if (shouldUpdateFn(collections)) {
72
72
  this.context.log('info', 'Updating query', this.key);
73
+ // immediately refilter the result set - deleted
74
+ // entities will already be nulled out
75
+ // this.refreshValue();
73
76
  this.execute();
74
77
  }
75
78
  },
76
79
  ),
77
80
  );
81
+ // TODO: subscribe to document changes and update if necessary.
78
82
  }
79
83
 
80
84
  get current() {
@@ -135,6 +139,13 @@ export abstract class BaseQuery<T> extends Disposable {
135
139
  this._rawValue = value;
136
140
  this.subscribeToDeleteAndRestore(this._rawValue);
137
141
  this._value = filterResultSet(value);
142
+ // validate the value
143
+ if (
144
+ Array.isArray(this._value) &&
145
+ this._value.some((v) => v.getSnapshot() === null)
146
+ ) {
147
+ debugger;
148
+ }
138
149
  this._status = 'ready';
139
150
  this._events.emit('change', this._value);
140
151
  };
@@ -193,8 +204,10 @@ export abstract class BaseQuery<T> extends Disposable {
193
204
  // possibly accessing db while it's closed. not much we can do.
194
205
  return this._value;
195
206
  }
207
+ throw err;
208
+ } else {
209
+ throw new Error('Unknown error executing query');
196
210
  }
197
- throw err;
198
211
  });
199
212
  return this._executionPromise;
200
213
  };