@verdant-web/store 3.12.1 → 4.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 (279) hide show
  1. package/dist/bundle/index.js +11 -13
  2. package/dist/bundle/index.js.map +4 -4
  3. package/dist/esm/__tests__/batching.test.js +5 -5
  4. package/dist/esm/__tests__/batching.test.js.map +1 -1
  5. package/dist/esm/__tests__/entities.test.js +1 -1
  6. package/dist/esm/__tests__/entities.test.js.map +1 -1
  7. package/dist/esm/__tests__/fixtures/testStorage.d.ts +1 -3
  8. package/dist/esm/__tests__/fixtures/testStorage.js +3 -3
  9. package/dist/esm/__tests__/fixtures/testStorage.js.map +1 -1
  10. package/dist/esm/__tests__/queries.test.js.map +1 -1
  11. package/dist/esm/backup.d.ts +3 -4
  12. package/dist/esm/backup.js.map +1 -1
  13. package/dist/esm/client/Client.d.ts +28 -33
  14. package/dist/esm/client/Client.js +50 -161
  15. package/dist/esm/client/Client.js.map +1 -1
  16. package/dist/esm/client/ClientDescriptor.d.ts +8 -11
  17. package/dist/esm/client/ClientDescriptor.js +39 -141
  18. package/dist/esm/client/ClientDescriptor.js.map +1 -1
  19. package/dist/esm/context/Time.d.ts +13 -0
  20. package/dist/esm/context/Time.js +27 -0
  21. package/dist/esm/context/Time.js.map +1 -0
  22. package/dist/esm/context/context.d.ts +170 -0
  23. package/dist/esm/{context.js.map → context/context.js.map} +1 -1
  24. package/dist/esm/entities/DocumentManager.js.map +1 -1
  25. package/dist/esm/entities/Entity.d.ts +4 -5
  26. package/dist/esm/entities/Entity.js +5 -3
  27. package/dist/esm/entities/Entity.js.map +1 -1
  28. package/dist/esm/entities/Entity.test.js +4 -3
  29. package/dist/esm/entities/Entity.test.js.map +1 -1
  30. package/dist/esm/entities/EntityCache.d.ts +0 -3
  31. package/dist/esm/entities/EntityCache.js +0 -9
  32. package/dist/esm/entities/EntityCache.js.map +1 -1
  33. package/dist/esm/entities/EntityMetadata.d.ts +1 -1
  34. package/dist/esm/entities/EntityMetadata.js +6 -5
  35. package/dist/esm/entities/EntityMetadata.js.map +1 -1
  36. package/dist/esm/entities/EntityStore.d.ts +2 -6
  37. package/dist/esm/entities/EntityStore.js +22 -16
  38. package/dist/esm/entities/EntityStore.js.map +1 -1
  39. package/dist/esm/entities/OperationBatcher.d.ts +2 -5
  40. package/dist/esm/entities/OperationBatcher.js +9 -7
  41. package/dist/esm/entities/OperationBatcher.js.map +1 -1
  42. package/dist/esm/errors.d.ts +8 -0
  43. package/dist/esm/errors.js +12 -0
  44. package/dist/esm/errors.js.map +1 -0
  45. package/dist/esm/files/EntityFile.d.ts +6 -3
  46. package/dist/esm/files/EntityFile.js +22 -19
  47. package/dist/esm/files/EntityFile.js.map +1 -1
  48. package/dist/esm/files/FileManager.d.ts +8 -39
  49. package/dist/esm/files/FileManager.js +15 -170
  50. package/dist/esm/files/FileManager.js.map +1 -1
  51. package/dist/esm/files/utils.d.ts +0 -1
  52. package/dist/esm/files/utils.js +0 -14
  53. package/dist/esm/files/utils.js.map +1 -1
  54. package/dist/esm/index.d.ts +1 -2
  55. package/dist/esm/index.js +0 -1
  56. package/dist/esm/index.js.map +1 -1
  57. package/dist/esm/{metadata → persistence}/MessageCreator.d.ts +5 -6
  58. package/dist/esm/{metadata → persistence}/MessageCreator.js +31 -38
  59. package/dist/esm/persistence/MessageCreator.js.map +1 -0
  60. package/dist/esm/persistence/PersistenceFiles.d.ts +48 -0
  61. package/dist/esm/persistence/PersistenceFiles.js +160 -0
  62. package/dist/esm/persistence/PersistenceFiles.js.map +1 -0
  63. package/dist/esm/persistence/PersistenceMetadata.d.ts +69 -0
  64. package/dist/esm/persistence/PersistenceMetadata.js +302 -0
  65. package/dist/esm/persistence/PersistenceMetadata.js.map +1 -0
  66. package/dist/esm/persistence/PersistenceQueries.d.ts +34 -0
  67. package/dist/esm/persistence/PersistenceQueries.js +15 -0
  68. package/dist/esm/persistence/PersistenceQueries.js.map +1 -0
  69. package/dist/esm/persistence/PersistenceRebaser.d.ts +32 -0
  70. package/dist/esm/persistence/PersistenceRebaser.js +120 -0
  71. package/dist/esm/persistence/PersistenceRebaser.js.map +1 -0
  72. package/dist/esm/{IDBService.d.ts → persistence/idb/IdbService.d.ts} +9 -7
  73. package/dist/esm/{IDBService.js → persistence/idb/IdbService.js} +29 -8
  74. package/dist/esm/persistence/idb/IdbService.js.map +1 -0
  75. package/dist/esm/persistence/idb/files/IdbPersistenceFileDb.d.ts +58 -0
  76. package/dist/esm/{files/FileStorage.js → persistence/idb/files/IdbPersistenceFileDb.js} +85 -50
  77. package/dist/esm/persistence/idb/files/IdbPersistenceFileDb.js.map +1 -0
  78. package/dist/esm/persistence/idb/idbPersistence.d.ts +19 -0
  79. package/dist/esm/persistence/idb/idbPersistence.js +80 -0
  80. package/dist/esm/persistence/idb/idbPersistence.js.map +1 -0
  81. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.d.ts +72 -0
  82. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js +235 -0
  83. package/dist/esm/persistence/idb/metadata/IdbMetadataDb.js.map +1 -0
  84. package/dist/esm/{metadata → persistence/idb/metadata}/openMetadataDatabase.d.ts +3 -1
  85. package/dist/esm/{metadata → persistence/idb/metadata}/openMetadataDatabase.js +12 -3
  86. package/dist/esm/persistence/idb/metadata/openMetadataDatabase.js.map +1 -0
  87. package/dist/esm/persistence/idb/queries/IdbQueryDb.d.ts +41 -0
  88. package/dist/esm/persistence/idb/queries/IdbQueryDb.js +174 -0
  89. package/dist/esm/persistence/idb/queries/IdbQueryDb.js.map +1 -0
  90. package/dist/esm/{migration → persistence/idb/queries/migration}/db.d.ts +1 -1
  91. package/dist/esm/{migration → persistence/idb/queries/migration}/db.js +10 -48
  92. package/dist/esm/persistence/idb/queries/migration/db.js.map +1 -0
  93. package/dist/esm/persistence/idb/queries/migration/engine.d.ts +12 -0
  94. package/dist/esm/{migration → persistence/idb/queries/migration}/engine.js +29 -46
  95. package/dist/esm/persistence/idb/queries/migration/engine.js.map +1 -0
  96. package/dist/esm/{migration → persistence/idb/queries/migration}/migrations.d.ts +1 -3
  97. package/dist/esm/{migration → persistence/idb/queries/migration}/migrations.js +11 -10
  98. package/dist/esm/persistence/idb/queries/migration/migrations.js.map +1 -0
  99. package/dist/esm/{migration → persistence/idb/queries/migration}/openQueryDatabase.d.ts +1 -3
  100. package/dist/esm/{migration → persistence/idb/queries/migration}/openQueryDatabase.js +4 -7
  101. package/dist/esm/persistence/idb/queries/migration/openQueryDatabase.js.map +1 -0
  102. package/dist/esm/{migration → persistence/idb/queries/migration}/paths.js +2 -2
  103. package/dist/esm/persistence/idb/queries/migration/paths.js.map +1 -0
  104. package/dist/esm/persistence/idb/queries/migration/paths.test.js.map +1 -0
  105. package/dist/esm/persistence/idb/queries/migration/types.d.ts +6 -0
  106. package/dist/esm/persistence/idb/queries/migration/types.js.map +1 -0
  107. package/dist/esm/persistence/idb/queries/ranges.d.ts +2 -0
  108. package/dist/esm/persistence/idb/queries/ranges.js +66 -0
  109. package/dist/esm/persistence/idb/queries/ranges.js.map +1 -0
  110. package/dist/esm/{idb.d.ts → persistence/idb/util.d.ts} +11 -0
  111. package/dist/esm/{idb.js → persistence/idb/util.js} +58 -1
  112. package/dist/esm/persistence/idb/util.js.map +1 -0
  113. package/dist/esm/persistence/interfaces.d.ts +181 -0
  114. package/dist/esm/persistence/interfaces.js +2 -0
  115. package/dist/esm/persistence/interfaces.js.map +1 -0
  116. package/dist/esm/persistence/persistence.d.ts +4 -0
  117. package/dist/esm/persistence/persistence.js +126 -0
  118. package/dist/esm/persistence/persistence.js.map +1 -0
  119. package/dist/esm/queries/BaseQuery.d.ts +2 -1
  120. package/dist/esm/queries/BaseQuery.js +3 -0
  121. package/dist/esm/queries/BaseQuery.js.map +1 -1
  122. package/dist/esm/queries/CollectionQueries.d.ts +1 -1
  123. package/dist/esm/queries/FindAllQuery.js +1 -3
  124. package/dist/esm/queries/FindAllQuery.js.map +1 -1
  125. package/dist/esm/queries/FindInfiniteQuery.js +2 -5
  126. package/dist/esm/queries/FindInfiniteQuery.js.map +1 -1
  127. package/dist/esm/queries/FindOneQuery.js +1 -3
  128. package/dist/esm/queries/FindOneQuery.js.map +1 -1
  129. package/dist/esm/queries/FindPageQuery.js +1 -3
  130. package/dist/esm/queries/FindPageQuery.js.map +1 -1
  131. package/dist/esm/queries/QueryCache.d.ts +1 -1
  132. package/dist/esm/queries/QueryCache.js +4 -0
  133. package/dist/esm/queries/QueryCache.js.map +1 -1
  134. package/dist/esm/sync/FileSync.d.ts +23 -8
  135. package/dist/esm/sync/FileSync.js +76 -28
  136. package/dist/esm/sync/FileSync.js.map +1 -1
  137. package/dist/esm/sync/PresenceManager.d.ts +4 -3
  138. package/dist/esm/sync/PresenceManager.js +2 -2
  139. package/dist/esm/sync/PresenceManager.js.map +1 -1
  140. package/dist/esm/sync/PushPullSync.d.ts +4 -6
  141. package/dist/esm/sync/PushPullSync.js +13 -12
  142. package/dist/esm/sync/PushPullSync.js.map +1 -1
  143. package/dist/esm/sync/Sync.d.ts +9 -11
  144. package/dist/esm/sync/Sync.js +34 -29
  145. package/dist/esm/sync/Sync.js.map +1 -1
  146. package/dist/esm/sync/WebSocketSync.d.ts +4 -6
  147. package/dist/esm/sync/WebSocketSync.js +20 -22
  148. package/dist/esm/sync/WebSocketSync.js.map +1 -1
  149. package/dist/esm/utils/Disposable.d.ts +5 -2
  150. package/dist/esm/utils/Disposable.js +3 -2
  151. package/dist/esm/utils/Disposable.js.map +1 -1
  152. package/dist/esm/utils/wip.d.ts +2 -0
  153. package/dist/esm/utils/wip.js +5 -0
  154. package/dist/esm/utils/wip.js.map +1 -0
  155. package/package.json +2 -2
  156. package/src/__tests__/batching.test.ts +6 -6
  157. package/src/__tests__/entities.test.ts +1 -1
  158. package/src/__tests__/fixtures/testStorage.ts +2 -10
  159. package/src/__tests__/queries.test.ts +1 -1
  160. package/src/backup.ts +3 -4
  161. package/src/client/Client.ts +69 -226
  162. package/src/client/ClientDescriptor.ts +53 -184
  163. package/src/context/Time.ts +35 -0
  164. package/src/context/context.ts +200 -0
  165. package/src/entities/DocumentManager.ts +0 -3
  166. package/src/entities/Entity.test.ts +9 -9
  167. package/src/entities/Entity.ts +6 -12
  168. package/src/entities/EntityCache.ts +0 -9
  169. package/src/entities/EntityMetadata.ts +4 -4
  170. package/src/entities/EntityStore.ts +26 -29
  171. package/src/entities/OperationBatcher.ts +9 -11
  172. package/src/errors.ts +13 -0
  173. package/src/files/EntityFile.ts +16 -5
  174. package/src/files/FileManager.ts +18 -245
  175. package/src/files/utils.ts +0 -15
  176. package/src/index.ts +2 -1
  177. package/src/{metadata → persistence}/MessageCreator.ts +46 -36
  178. package/src/persistence/PersistenceFiles.ts +227 -0
  179. package/src/persistence/PersistenceMetadata.ts +425 -0
  180. package/src/persistence/PersistenceQueries.ts +22 -0
  181. package/src/persistence/PersistenceRebaser.ts +171 -0
  182. package/src/{IDBService.ts → persistence/idb/IdbService.ts} +45 -12
  183. package/src/{files/FileStorage.ts → persistence/idb/files/IdbPersistenceFileDb.ts} +128 -86
  184. package/src/persistence/idb/idbPersistence.ts +116 -0
  185. package/src/persistence/idb/metadata/IdbMetadataDb.ts +460 -0
  186. package/src/{metadata → persistence/idb/metadata}/openMetadataDatabase.ts +21 -4
  187. package/src/persistence/idb/queries/IdbQueryDb.ts +251 -0
  188. package/src/{migration → persistence/idb/queries/migration}/db.ts +18 -72
  189. package/src/{migration → persistence/idb/queries/migration}/engine.ts +39 -62
  190. package/src/{migration → persistence/idb/queries/migration}/migrations.ts +13 -18
  191. package/src/{migration → persistence/idb/queries/migration}/openQueryDatabase.ts +5 -14
  192. package/src/{migration → persistence/idb/queries/migration}/paths.ts +4 -3
  193. package/src/persistence/idb/queries/migration/types.ts +8 -0
  194. package/src/persistence/idb/queries/ranges.ts +107 -0
  195. package/src/{idb.ts → persistence/idb/util.ts} +75 -0
  196. package/src/persistence/interfaces.ts +240 -0
  197. package/src/persistence/persistence.ts +223 -0
  198. package/src/queries/BaseQuery.ts +5 -1
  199. package/src/queries/CollectionQueries.ts +2 -2
  200. package/src/queries/FindAllQuery.ts +1 -3
  201. package/src/queries/FindInfiniteQuery.ts +2 -5
  202. package/src/queries/FindOneQuery.ts +1 -3
  203. package/src/queries/FindPageQuery.ts +1 -3
  204. package/src/queries/QueryCache.ts +20 -1
  205. package/src/sync/FileSync.ts +93 -30
  206. package/src/sync/PresenceManager.ts +5 -7
  207. package/src/sync/PushPullSync.ts +23 -19
  208. package/src/sync/Sync.ts +45 -36
  209. package/src/sync/WebSocketSync.ts +41 -27
  210. package/src/utils/Disposable.ts +7 -4
  211. package/src/utils/wip.ts +5 -0
  212. package/dist/esm/IDBService.js.map +0 -1
  213. package/dist/esm/__tests__/legacyOids.test.d.ts +0 -1
  214. package/dist/esm/__tests__/legacyOids.test.js +0 -352
  215. package/dist/esm/__tests__/legacyOids.test.js.map +0 -1
  216. package/dist/esm/context.d.ts +0 -45
  217. package/dist/esm/files/FileStorage.d.ts +0 -47
  218. package/dist/esm/files/FileStorage.js.map +0 -1
  219. package/dist/esm/idb.js.map +0 -1
  220. package/dist/esm/metadata/AckInfoStore.d.ts +0 -10
  221. package/dist/esm/metadata/AckInfoStore.js +0 -22
  222. package/dist/esm/metadata/AckInfoStore.js.map +0 -1
  223. package/dist/esm/metadata/BaselinesStore.d.ts +0 -40
  224. package/dist/esm/metadata/BaselinesStore.js +0 -102
  225. package/dist/esm/metadata/BaselinesStore.js.map +0 -1
  226. package/dist/esm/metadata/LocalReplicaStore.d.ts +0 -19
  227. package/dist/esm/metadata/LocalReplicaStore.js +0 -56
  228. package/dist/esm/metadata/LocalReplicaStore.js.map +0 -1
  229. package/dist/esm/metadata/MessageCreator.js.map +0 -1
  230. package/dist/esm/metadata/Metadata.d.ts +0 -146
  231. package/dist/esm/metadata/Metadata.js +0 -452
  232. package/dist/esm/metadata/Metadata.js.map +0 -1
  233. package/dist/esm/metadata/OperationsStore.d.ts +0 -62
  234. package/dist/esm/metadata/OperationsStore.js +0 -175
  235. package/dist/esm/metadata/OperationsStore.js.map +0 -1
  236. package/dist/esm/metadata/SchemaStore.d.ts +0 -9
  237. package/dist/esm/metadata/SchemaStore.js +0 -35
  238. package/dist/esm/metadata/SchemaStore.js.map +0 -1
  239. package/dist/esm/metadata/openMetadataDatabase.js.map +0 -1
  240. package/dist/esm/migration/db.js.map +0 -1
  241. package/dist/esm/migration/engine.d.ts +0 -15
  242. package/dist/esm/migration/engine.js.map +0 -1
  243. package/dist/esm/migration/errors.d.ts +0 -5
  244. package/dist/esm/migration/errors.js +0 -8
  245. package/dist/esm/migration/errors.js.map +0 -1
  246. package/dist/esm/migration/migrations.js.map +0 -1
  247. package/dist/esm/migration/openQueryDatabase.js.map +0 -1
  248. package/dist/esm/migration/openWIPDatabase.d.ts +0 -11
  249. package/dist/esm/migration/openWIPDatabase.js +0 -65
  250. package/dist/esm/migration/openWIPDatabase.js.map +0 -1
  251. package/dist/esm/migration/paths.js.map +0 -1
  252. package/dist/esm/migration/paths.test.js.map +0 -1
  253. package/dist/esm/migration/types.d.ts +0 -3
  254. package/dist/esm/migration/types.js.map +0 -1
  255. package/dist/esm/queries/QueryableStorage.d.ts +0 -20
  256. package/dist/esm/queries/QueryableStorage.js +0 -90
  257. package/dist/esm/queries/QueryableStorage.js.map +0 -1
  258. package/dist/esm/queries/dbQueries.d.ts +0 -22
  259. package/dist/esm/queries/dbQueries.js +0 -130
  260. package/dist/esm/queries/dbQueries.js.map +0 -1
  261. package/src/__tests__/legacyOids.test.ts +0 -375
  262. package/src/context.ts +0 -55
  263. package/src/metadata/AckInfoStore.ts +0 -30
  264. package/src/metadata/BaselinesStore.ts +0 -188
  265. package/src/metadata/LocalReplicaStore.ts +0 -79
  266. package/src/metadata/Metadata.ts +0 -685
  267. package/src/metadata/OperationsStore.ts +0 -332
  268. package/src/metadata/SchemaStore.ts +0 -47
  269. package/src/migration/errors.ts +0 -7
  270. package/src/migration/openWIPDatabase.ts +0 -97
  271. package/src/migration/types.ts +0 -4
  272. package/src/queries/QueryableStorage.ts +0 -122
  273. package/src/queries/dbQueries.ts +0 -161
  274. /package/dist/esm/{context.js → context/context.js} +0 -0
  275. /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.d.ts +0 -0
  276. /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.test.d.ts +0 -0
  277. /package/dist/esm/{migration → persistence/idb/queries/migration}/paths.test.js +0 -0
  278. /package/dist/esm/{migration → persistence/idb/queries/migration}/types.js +0 -0
  279. /package/src/{migration → persistence/idb/queries/migration}/paths.test.ts +0 -0
@@ -10,7 +10,7 @@ import {
10
10
  compareTimestampSchemaVersions,
11
11
  getWallClockTime,
12
12
  } from '@verdant-web/common';
13
- import { Context } from '../context.js';
13
+ import { Context } from '../context/context.js';
14
14
  import { EntityChange } from './types.js';
15
15
 
16
16
  export type EntityMetadataView = {
@@ -118,7 +118,7 @@ export class EntityMetadata {
118
118
  !!confirmedResult.latestTimestamp &&
119
119
  compareTimestampSchemaVersions(
120
120
  confirmedResult.latestTimestamp,
121
- this.ctx.getNow(),
121
+ this.ctx.time.now,
122
122
  ) < 0;
123
123
 
124
124
  const empty =
@@ -142,7 +142,6 @@ export class EntityMetadata {
142
142
  'warn',
143
143
  `Entity ${this.oid} has no view, no deleted flag, and not empty`,
144
144
  );
145
- debugger;
146
145
  }
147
146
 
148
147
  return {
@@ -227,7 +226,7 @@ export class EntityMetadata {
227
226
  let futureSeen: string | undefined = undefined;
228
227
  let authz: string | undefined = undefined;
229
228
 
230
- const now = this.ctx.getNow();
229
+ const now = this.ctx.time.now;
231
230
  for (const op of operations) {
232
231
  // ignore ops before our after cutoff
233
232
  if (after && op.timestamp <= after) {
@@ -323,6 +322,7 @@ export class EntityFamilyMetadata {
323
322
  );
324
323
  }
325
324
  this.get(baseline.oid).addBaseline(baseline);
325
+ changes[baseline.oid] ??= { oid: baseline.oid, isLocal };
326
326
  }
327
327
  for (const [oid, ops] of Object.entries(operations)) {
328
328
  if (!areOidsRelated(this.rootOid, oid)) {
@@ -2,7 +2,6 @@ import {
2
2
  DocumentBaseline,
3
3
  ObjectIdentifier,
4
4
  Operation,
5
- StorageFieldsSchema,
6
5
  StorageObjectFieldSchema,
7
6
  assert,
8
7
  assignOid,
@@ -15,14 +14,12 @@ import {
15
14
  removeOidsFromAllSubObjects,
16
15
  AuthorizationKey,
17
16
  } from '@verdant-web/common';
18
- import { Context } from '../context.js';
19
- import { Metadata } from '../metadata/Metadata.js';
17
+ import { Context } from '../context/context.js';
20
18
  import { Entity } from './Entity.js';
21
19
  import { Disposable } from '../utils/Disposable.js';
22
20
  import { EntityFamilyMetadata } from './EntityMetadata.js';
23
21
  import { FileManager } from '../files/FileManager.js';
24
22
  import { OperationBatcher } from './OperationBatcher.js';
25
- import { QueryableStorage } from '../queries/QueryableStorage.js';
26
23
  import { WeakEvent } from 'weak-event';
27
24
  import { processValueFiles } from '../files/utils.js';
28
25
 
@@ -57,10 +54,8 @@ export interface EntityCreateOptions {
57
54
 
58
55
  export class EntityStore extends Disposable {
59
56
  private ctx;
60
- private meta;
61
57
  private files;
62
58
  private batcher;
63
- private queryableStorage;
64
59
  private events: EntityStoreEvents = {
65
60
  add: new WeakEvent(),
66
61
  replace: new WeakEvent(),
@@ -80,26 +75,18 @@ export class EntityStore extends Disposable {
80
75
  },
81
76
  );
82
77
 
83
- constructor({
84
- ctx,
85
- meta,
86
- files,
87
- }: {
88
- ctx: Context;
89
- meta: Metadata;
90
- files: FileManager;
91
- }) {
78
+ constructor({ ctx, files }: { ctx: Context; files: FileManager }) {
92
79
  super();
93
80
 
94
81
  this.ctx = ctx;
95
- this.meta = meta;
96
82
  this.files = files;
97
- this.queryableStorage = new QueryableStorage({ ctx });
98
83
  this.batcher = new OperationBatcher({
99
84
  ctx,
100
- meta,
101
85
  entities: this,
102
86
  });
87
+ this.addDispose(
88
+ this.ctx.internalEvents.subscribe('persistenceReset', this.clearCache),
89
+ );
103
90
  }
104
91
 
105
92
  // expose batch APIs
@@ -145,7 +132,7 @@ export class EntityStore extends Disposable {
145
132
  };
146
133
 
147
134
  empty = async () => {
148
- await this.queryableStorage.reset();
135
+ await this.ctx.queries.reset();
149
136
  this.events.resetAll.invoke(this);
150
137
  this.cache.clear();
151
138
  };
@@ -155,8 +142,8 @@ export class EntityStore extends Disposable {
155
142
  this.ctx.log('warn', 'EntityStore is disposed, not resetting local data');
156
143
  return;
157
144
  }
158
- await this.meta.reset();
159
- await this.queryableStorage.reset();
145
+ await this.ctx.meta.reset();
146
+ await this.ctx.queries.reset();
160
147
  this.events.resetAll.invoke(this);
161
148
  };
162
149
 
@@ -172,6 +159,11 @@ export class EntityStore extends Disposable {
172
159
  const baselines = data?.baselines ?? [];
173
160
  const operations = data?.operations ?? [];
174
161
 
162
+ if (baselines.length === 0 && operations.length === 0) {
163
+ this.ctx.log('debug', 'No data to process');
164
+ return;
165
+ }
166
+
175
167
  this.ctx.log('debug', 'Processing incoming data', {
176
168
  operations: operations.length,
177
169
  baselines: baselines.length,
@@ -200,6 +192,7 @@ export class EntityStore extends Disposable {
200
192
  const event = data.reset ? this.events.replace : this.events.add;
201
193
  const hydrationPromise = this.pendingEntityPromises.get(oid);
202
194
  if (hydrationPromise) {
195
+ this.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);
203
196
  hydrationPromise.then(() => {
204
197
  event.invoke(this, {
205
198
  oid,
@@ -209,6 +202,7 @@ export class EntityStore extends Disposable {
209
202
  });
210
203
  });
211
204
  } else {
205
+ this.ctx.log('debug', 'Applying data to entity', oid);
212
206
  event.invoke(this, {
213
207
  oid,
214
208
  baselines,
@@ -227,7 +221,7 @@ export class EntityStore extends Disposable {
227
221
  // TODO: could messages be sent to sync before storage,
228
222
  // so that realtime is lower latency? What would happen
229
223
  // if the storage failed?
230
- await this.meta.insertData(data, abortOptions);
224
+ await this.ctx.meta.insertData(data, abortOptions);
231
225
 
232
226
  // recompute all affected documents for querying
233
227
  const entities = await Promise.all(
@@ -246,7 +240,7 @@ export class EntityStore extends Disposable {
246
240
  }),
247
241
  );
248
242
  try {
249
- await this.queryableStorage.saveEntities(entities, abortOptions);
243
+ await this.ctx.queries.saveEntities(entities, abortOptions);
250
244
  } catch (err) {
251
245
  if (this.disposed) {
252
246
  this.ctx.log(
@@ -275,14 +269,16 @@ export class EntityStore extends Disposable {
275
269
  }
276
270
 
277
271
  if (this.cache.has(oid)) {
278
- this.ctx.log('debug', 'Hydrating entity from cache', oid);
279
272
  const cached = this.cache.get(oid);
280
273
  if (cached) {
281
274
  const entity = cached.deref();
282
275
  if (entity) {
283
276
  if (entity.deleted) {
277
+ this.ctx.log('debug', 'Hydrated entity is deleted', oid);
278
+ // debugger;
284
279
  return null;
285
280
  }
281
+ this.ctx.log('debug', 'Hydrating entity from cache', oid);
286
282
  return entity;
287
283
  } else {
288
284
  this.ctx.log('debug', "Removing GC'd entity from cache", oid);
@@ -299,6 +295,7 @@ export class EntityStore extends Disposable {
299
295
  this.ctx.log('debug', 'Hydrating entity from storage', oid);
300
296
  const entity = this.constructEntity(oid);
301
297
  if (!entity) {
298
+ this.ctx.log('warn', 'Entity schema not found, cannot construct', oid);
302
299
  return null;
303
300
  }
304
301
  const pendingPromise = this.loadEntity(entity, opts);
@@ -308,7 +305,7 @@ export class EntityStore extends Disposable {
308
305
  this.pendingEntityPromises.set(oid, pendingPromise);
309
306
  return pendingPromise;
310
307
  } else {
311
- this.ctx.log('debug', 'Waiting for entity hydration', oid);
308
+ this.ctx.log('debug', 'Waiting for ongoing entity hydration', oid);
312
309
  return pendingPromise;
313
310
  }
314
311
  };
@@ -345,7 +342,7 @@ export class EntityStore extends Disposable {
345
342
  );
346
343
  }
347
344
 
348
- const operations = this.meta.patchCreator.createInitialize(processed, oid);
345
+ const operations = this.ctx.patchCreator.createInitialize(processed, oid);
349
346
  if (access) {
350
347
  operations.forEach((op) => {
351
348
  op.authz = access;
@@ -396,7 +393,7 @@ export class EntityStore extends Disposable {
396
393
  for (const entity of entities) {
397
394
  if (entity) {
398
395
  const oids = entity.__getFamilyOids__();
399
- const deletes = this.meta.patchCreator.createDeleteAll(oids);
396
+ const deletes = this.ctx.patchCreator.createDeleteAll(oids);
400
397
  for (const op of deletes) {
401
398
  op.authz = entity.access;
402
399
  }
@@ -468,7 +465,6 @@ export class EntityStore extends Disposable {
468
465
  readonlyKeys,
469
466
  files: this.files,
470
467
  metadataFamily: metadataFamily,
471
- patchCreator: this.meta.patchCreator,
472
468
  storeEvents: this.events,
473
469
  deleteSelf: this.delete.bind(this, oid),
474
470
  });
@@ -504,7 +500,7 @@ export class EntityStore extends Disposable {
504
500
  entity: Entity,
505
501
  opts?: { abort: AbortSignal },
506
502
  ) => {
507
- const { operations, baselines } = await this.meta.getDocumentData(
503
+ const { operations, baselines } = await this.ctx.meta.getDocumentData(
508
504
  entity.oid,
509
505
  opts,
510
506
  );
@@ -531,6 +527,7 @@ export class EntityStore extends Disposable {
531
527
  * referenced will go 'dead'...
532
528
  */
533
529
  clearCache = () => {
530
+ this.ctx.log('debug', 'Emptying entity cache');
534
531
  this.cache.clear();
535
532
  };
536
533
  }
@@ -10,8 +10,7 @@ import {
10
10
  isSuperseded,
11
11
  operationSupersedes,
12
12
  } from '@verdant-web/common';
13
- import { Metadata } from '../metadata/Metadata.js';
14
- import { Context } from '../context.js';
13
+ import { Context } from '../context/context.js';
15
14
  import type { EntityStore } from './EntityStore.js';
16
15
  import { Entity } from './Entity.js';
17
16
 
@@ -29,22 +28,18 @@ export class OperationBatcher {
29
28
  private batcher;
30
29
  private currentBatchKey = DEFAULT_BATCH_KEY;
31
30
  private defaultBatchTimeout: number;
32
- private meta;
33
31
  private ctx;
34
32
  private entities;
35
33
 
36
34
  constructor({
37
35
  batchTimeout = 200,
38
- meta,
39
36
  ctx,
40
37
  entities,
41
38
  }: {
42
39
  batchTimeout?: number;
43
- meta: Metadata;
44
40
  ctx: Context;
45
41
  entities: EntityStore;
46
42
  }) {
47
- this.meta = meta;
48
43
  this.ctx = ctx;
49
44
  this.entities = entities;
50
45
  this.defaultBatchTimeout = batchTimeout;
@@ -69,6 +64,7 @@ export class OperationBatcher {
69
64
  batchKey: string,
70
65
  meta: { undoable?: boolean },
71
66
  ) => {
67
+ if (!operations.length) return;
72
68
  this.ctx.log(
73
69
  'debug',
74
70
  'Flushing',
@@ -77,7 +73,6 @@ export class OperationBatcher {
77
73
  batchKey,
78
74
  'to storage / sync',
79
75
  );
80
- if (!operations.length) return;
81
76
 
82
77
  // next block of logic computes superseding rules to eliminate
83
78
  // operations which are 'overshadowed' by later ones on the same
@@ -129,7 +124,7 @@ export class OperationBatcher {
129
124
  // cannot be done in reversed loop above or timestamps would be
130
125
  // in reverse order.
131
126
  for (const op of committed) {
132
- op.timestamp = this.meta.now;
127
+ op.timestamp = this.ctx.time.now;
133
128
  }
134
129
  await this.commitOperations(committed, meta);
135
130
  };
@@ -257,7 +252,10 @@ export class OperationBatcher {
257
252
  return externalApi;
258
253
  };
259
254
 
260
- flushAll = () => Promise.all(this.batcher.flushAll());
255
+ flushAll = () => {
256
+ this.ctx.log('debug', 'Flushing all operations');
257
+ return Promise.all(this.batcher.flushAll());
258
+ };
261
259
 
262
260
  private createUndo = async (data: { ops: Operation[]; source?: Entity }) => {
263
261
  // this can't be done on-demand because we rely on the current
@@ -273,7 +271,7 @@ export class OperationBatcher {
273
271
  });
274
272
  // set time to now for all undo operations, they're happening now.
275
273
  for (const op of inverseOps) {
276
- op.timestamp = this.meta.now;
274
+ op.timestamp = this.ctx.time.now;
277
275
  }
278
276
  await this.commitOperations(
279
277
  inverseOps,
@@ -293,7 +291,7 @@ export class OperationBatcher {
293
291
  }) => {
294
292
  const grouped = groupPatchesByOid(ops);
295
293
  const inverseOps: Operation[] = [];
296
- const getNow = () => this.meta.now;
294
+ const getNow = () => this.ctx.time.now;
297
295
  await Promise.all(
298
296
  Object.entries(grouped).map(async ([oid, patches]): Promise<void> => {
299
297
  const entity = source ?? (await this.entities.hydrate(getOidRoot(oid)));
package/src/errors.ts ADDED
@@ -0,0 +1,13 @@
1
+ export enum VerdantErrorCode {
2
+ MigrationPathNotFound = 50001,
3
+ }
4
+
5
+ export class VerdantError extends Error {
6
+ static Code = VerdantErrorCode;
7
+ constructor(
8
+ public code: VerdantErrorCode,
9
+ message: string,
10
+ ) {
11
+ super(message);
12
+ }
13
+ }
@@ -1,4 +1,5 @@
1
1
  import { EventSubscriber, FileData } from '@verdant-web/common';
2
+ import { Context } from '../context/context.js';
2
3
 
3
4
  export type EntityFileEvents = {
4
5
  change: () => void;
@@ -6,7 +7,6 @@ export type EntityFileEvents = {
6
7
 
7
8
  export const UPDATE = Symbol('entity-file-update');
8
9
  export const MARK_FAILED = Symbol('entity-file-mark-failed');
9
- export const MARK_UPLOADED = Symbol('entity-file-mark-uploaded');
10
10
 
11
11
  export type EntityFileSnapshot = {
12
12
  id: string;
@@ -24,17 +24,26 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
24
24
  private _loading = true;
25
25
  private _failed = false;
26
26
  private _downloadRemote = false;
27
+ private ctx: Context;
28
+ private unsubscribes: (() => void)[] = [];
27
29
 
28
30
  constructor(
29
31
  public readonly id: string,
30
32
  {
31
33
  downloadRemote = false,
34
+ ctx,
32
35
  }: {
33
36
  downloadRemote?: boolean;
34
- } = {},
37
+ ctx: Context;
38
+ },
35
39
  ) {
36
40
  super();
41
+ this.ctx = ctx;
37
42
  this._downloadRemote = downloadRemote;
43
+
44
+ this.unsubscribes.push(
45
+ this.ctx.internalEvents.subscribe(`fileUploaded:${id}`, this.onUploaded),
46
+ );
38
47
  }
39
48
 
40
49
  get downloadRemote() {
@@ -48,6 +57,7 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
48
57
  }
49
58
 
50
59
  [UPDATE] = (fileData: FileData) => {
60
+ this.ctx.log('debug', 'EntityFile updated', this.id, fileData);
51
61
  this._loading = false;
52
62
  this._failed = false;
53
63
  this._fileData = fileData;
@@ -55,6 +65,7 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
55
65
  if (this._objectUrl) {
56
66
  URL.revokeObjectURL(this._objectUrl);
57
67
  }
68
+ this.ctx.log('debug', 'Creating object URL for file', this.id);
58
69
  this._objectUrl = URL.createObjectURL(fileData.file);
59
70
  }
60
71
  this.emit('change');
@@ -66,7 +77,7 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
66
77
  this.emit('change');
67
78
  };
68
79
 
69
- [MARK_UPLOADED] = () => {
80
+ private onUploaded = () => {
70
81
  if (!this._fileData) return;
71
82
  this._fileData!.remote = true;
72
83
  this.emit('change');
@@ -102,13 +113,13 @@ export class EntityFile extends EventSubscriber<EntityFileEvents> {
102
113
  };
103
114
 
104
115
  getSnapshot(): FileData {
105
- if (this._fileData) return this._fileData;
106
116
  return {
107
117
  id: this.id,
108
- url: this._objectUrl ?? undefined,
118
+ url: this._objectUrl ?? this._fileData?.url ?? undefined,
109
119
  name: this.name ?? 'unknown-file',
110
120
  remote: false,
111
121
  type: this.type ?? '',
122
+ file: this._fileData?.file,
112
123
  };
113
124
  }
114
125
  }