@powerhousedao/reactor 6.0.0-dev.69 → 6.0.0-dev.77

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 (240) hide show
  1. package/dist/src/index.d.ts +1 -1
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +19998 -62
  4. package/dist/src/sync/index.d.ts +1 -1
  5. package/dist/src/sync/index.d.ts.map +1 -1
  6. package/dist/src/sync/sync-manager.d.ts.map +1 -1
  7. package/dist/src/sync/types.d.ts +11 -0
  8. package/dist/src/sync/types.d.ts.map +1 -1
  9. package/package.json +17 -10
  10. package/dist/src/actions/index.js +0 -76
  11. package/dist/src/actions/index.js.map +0 -1
  12. package/dist/src/cache/buffer/ring-buffer.js +0 -69
  13. package/dist/src/cache/buffer/ring-buffer.js.map +0 -1
  14. package/dist/src/cache/collection-membership-cache.js +0 -33
  15. package/dist/src/cache/collection-membership-cache.js.map +0 -1
  16. package/dist/src/cache/document-meta-cache-types.js +0 -2
  17. package/dist/src/cache/document-meta-cache-types.js.map +0 -1
  18. package/dist/src/cache/document-meta-cache.js +0 -129
  19. package/dist/src/cache/document-meta-cache.js.map +0 -1
  20. package/dist/src/cache/index.js +0 -2
  21. package/dist/src/cache/index.js.map +0 -1
  22. package/dist/src/cache/kysely-operation-index.js +0 -345
  23. package/dist/src/cache/kysely-operation-index.js.map +0 -1
  24. package/dist/src/cache/kysely-write-cache.js +0 -411
  25. package/dist/src/cache/kysely-write-cache.js.map +0 -1
  26. package/dist/src/cache/lru/lru-tracker.js +0 -96
  27. package/dist/src/cache/lru/lru-tracker.js.map +0 -1
  28. package/dist/src/cache/operation-index-types.js +0 -4
  29. package/dist/src/cache/operation-index-types.js.map +0 -1
  30. package/dist/src/cache/write/interfaces.js +0 -2
  31. package/dist/src/cache/write/interfaces.js.map +0 -1
  32. package/dist/src/cache/write-cache-types.js +0 -2
  33. package/dist/src/cache/write-cache-types.js.map +0 -1
  34. package/dist/src/client/reactor-client.js +0 -497
  35. package/dist/src/client/reactor-client.js.map +0 -1
  36. package/dist/src/client/types.js +0 -14
  37. package/dist/src/client/types.js.map +0 -1
  38. package/dist/src/core/reactor-builder.js +0 -306
  39. package/dist/src/core/reactor-builder.js.map +0 -1
  40. package/dist/src/core/reactor-client-builder.js +0 -132
  41. package/dist/src/core/reactor-client-builder.js.map +0 -1
  42. package/dist/src/core/reactor.js +0 -640
  43. package/dist/src/core/reactor.js.map +0 -1
  44. package/dist/src/core/types.js +0 -2
  45. package/dist/src/core/types.js.map +0 -1
  46. package/dist/src/core/utils.js +0 -225
  47. package/dist/src/core/utils.js.map +0 -1
  48. package/dist/src/events/event-bus.js +0 -53
  49. package/dist/src/events/event-bus.js.map +0 -1
  50. package/dist/src/events/interfaces.js +0 -2
  51. package/dist/src/events/interfaces.js.map +0 -1
  52. package/dist/src/events/types.js +0 -30
  53. package/dist/src/events/types.js.map +0 -1
  54. package/dist/src/executor/document-action-handler.js +0 -356
  55. package/dist/src/executor/document-action-handler.js.map +0 -1
  56. package/dist/src/executor/interfaces.js +0 -2
  57. package/dist/src/executor/interfaces.js.map +0 -1
  58. package/dist/src/executor/signature-verifier.js +0 -70
  59. package/dist/src/executor/signature-verifier.js.map +0 -1
  60. package/dist/src/executor/simple-job-executor-manager.js +0 -345
  61. package/dist/src/executor/simple-job-executor-manager.js.map +0 -1
  62. package/dist/src/executor/simple-job-executor.js +0 -423
  63. package/dist/src/executor/simple-job-executor.js.map +0 -1
  64. package/dist/src/executor/types.js +0 -11
  65. package/dist/src/executor/types.js.map +0 -1
  66. package/dist/src/executor/util.js +0 -230
  67. package/dist/src/executor/util.js.map +0 -1
  68. package/dist/src/index.js.map +0 -1
  69. package/dist/src/job-tracker/in-memory-job-tracker.js +0 -114
  70. package/dist/src/job-tracker/in-memory-job-tracker.js.map +0 -1
  71. package/dist/src/job-tracker/index.js +0 -2
  72. package/dist/src/job-tracker/index.js.map +0 -1
  73. package/dist/src/job-tracker/interfaces.js +0 -2
  74. package/dist/src/job-tracker/interfaces.js.map +0 -1
  75. package/dist/src/logging/console.js +0 -2
  76. package/dist/src/logging/console.js.map +0 -1
  77. package/dist/src/logging/types.js +0 -2
  78. package/dist/src/logging/types.js.map +0 -1
  79. package/dist/src/processors/index.js +0 -2
  80. package/dist/src/processors/index.js.map +0 -1
  81. package/dist/src/processors/processor-manager.js +0 -165
  82. package/dist/src/processors/processor-manager.js.map +0 -1
  83. package/dist/src/processors/relational/types.js +0 -2
  84. package/dist/src/processors/relational/types.js.map +0 -1
  85. package/dist/src/processors/relational/utils.js +0 -2
  86. package/dist/src/processors/relational/utils.js.map +0 -1
  87. package/dist/src/processors/utils.js +0 -59
  88. package/dist/src/processors/utils.js.map +0 -1
  89. package/dist/src/queue/interfaces.js +0 -2
  90. package/dist/src/queue/interfaces.js.map +0 -1
  91. package/dist/src/queue/job-execution-handle.js +0 -71
  92. package/dist/src/queue/job-execution-handle.js.map +0 -1
  93. package/dist/src/queue/queue.js +0 -493
  94. package/dist/src/queue/queue.js.map +0 -1
  95. package/dist/src/queue/types.js +0 -19
  96. package/dist/src/queue/types.js.map +0 -1
  97. package/dist/src/read-models/base-read-model.js +0 -143
  98. package/dist/src/read-models/base-read-model.js.map +0 -1
  99. package/dist/src/read-models/coordinator.js +0 -72
  100. package/dist/src/read-models/coordinator.js.map +0 -1
  101. package/dist/src/read-models/document-view.js +0 -457
  102. package/dist/src/read-models/document-view.js.map +0 -1
  103. package/dist/src/read-models/interfaces.js +0 -2
  104. package/dist/src/read-models/interfaces.js.map +0 -1
  105. package/dist/src/read-models/types.js +0 -2
  106. package/dist/src/read-models/types.js.map +0 -1
  107. package/dist/src/registry/document-model-resolver.js +0 -81
  108. package/dist/src/registry/document-model-resolver.js.map +0 -1
  109. package/dist/src/registry/implementation.js +0 -226
  110. package/dist/src/registry/implementation.js.map +0 -1
  111. package/dist/src/registry/index.js +0 -3
  112. package/dist/src/registry/index.js.map +0 -1
  113. package/dist/src/registry/interfaces.js +0 -2
  114. package/dist/src/registry/interfaces.js.map +0 -1
  115. package/dist/src/shared/awaiter.js +0 -123
  116. package/dist/src/shared/awaiter.js.map +0 -1
  117. package/dist/src/shared/collect-all-pages.js +0 -17
  118. package/dist/src/shared/collect-all-pages.js.map +0 -1
  119. package/dist/src/shared/consistency-tracker.js +0 -123
  120. package/dist/src/shared/consistency-tracker.js.map +0 -1
  121. package/dist/src/shared/drive-url.js +0 -17
  122. package/dist/src/shared/drive-url.js.map +0 -1
  123. package/dist/src/shared/errors.js +0 -93
  124. package/dist/src/shared/errors.js.map +0 -1
  125. package/dist/src/shared/factories.js +0 -41
  126. package/dist/src/shared/factories.js.map +0 -1
  127. package/dist/src/shared/types.js +0 -38
  128. package/dist/src/shared/types.js.map +0 -1
  129. package/dist/src/shared/utils.js +0 -8
  130. package/dist/src/shared/utils.js.map +0 -1
  131. package/dist/src/signer/passthrough-signer.js +0 -17
  132. package/dist/src/signer/passthrough-signer.js.map +0 -1
  133. package/dist/src/signer/types.js +0 -2
  134. package/dist/src/signer/types.js.map +0 -1
  135. package/dist/src/storage/index.js +0 -3
  136. package/dist/src/storage/index.js.map +0 -1
  137. package/dist/src/storage/interfaces.js +0 -29
  138. package/dist/src/storage/interfaces.js.map +0 -1
  139. package/dist/src/storage/kysely/document-indexer.js +0 -421
  140. package/dist/src/storage/kysely/document-indexer.js.map +0 -1
  141. package/dist/src/storage/kysely/keyframe-store.js +0 -64
  142. package/dist/src/storage/kysely/keyframe-store.js.map +0 -1
  143. package/dist/src/storage/kysely/store.js +0 -264
  144. package/dist/src/storage/kysely/store.js.map +0 -1
  145. package/dist/src/storage/kysely/sync-cursor-storage.js +0 -97
  146. package/dist/src/storage/kysely/sync-cursor-storage.js.map +0 -1
  147. package/dist/src/storage/kysely/sync-dead-letter-storage.js +0 -110
  148. package/dist/src/storage/kysely/sync-dead-letter-storage.js.map +0 -1
  149. package/dist/src/storage/kysely/sync-remote-storage.js +0 -133
  150. package/dist/src/storage/kysely/sync-remote-storage.js.map +0 -1
  151. package/dist/src/storage/kysely/types.js +0 -2
  152. package/dist/src/storage/kysely/types.js.map +0 -1
  153. package/dist/src/storage/migrations/001_create_operation_table.js +0 -41
  154. package/dist/src/storage/migrations/001_create_operation_table.js.map +0 -1
  155. package/dist/src/storage/migrations/002_create_keyframe_table.js +0 -27
  156. package/dist/src/storage/migrations/002_create_keyframe_table.js.map +0 -1
  157. package/dist/src/storage/migrations/003_create_document_table.js +0 -10
  158. package/dist/src/storage/migrations/003_create_document_table.js.map +0 -1
  159. package/dist/src/storage/migrations/004_create_document_relationship_table.js +0 -35
  160. package/dist/src/storage/migrations/004_create_document_relationship_table.js.map +0 -1
  161. package/dist/src/storage/migrations/005_create_indexer_state_table.js +0 -10
  162. package/dist/src/storage/migrations/005_create_indexer_state_table.js.map +0 -1
  163. package/dist/src/storage/migrations/006_create_document_snapshot_table.js +0 -49
  164. package/dist/src/storage/migrations/006_create_document_snapshot_table.js.map +0 -1
  165. package/dist/src/storage/migrations/007_create_slug_mapping_table.js +0 -24
  166. package/dist/src/storage/migrations/007_create_slug_mapping_table.js.map +0 -1
  167. package/dist/src/storage/migrations/008_create_view_state_table.js +0 -10
  168. package/dist/src/storage/migrations/008_create_view_state_table.js.map +0 -1
  169. package/dist/src/storage/migrations/009_create_operation_index_tables.js +0 -50
  170. package/dist/src/storage/migrations/009_create_operation_index_tables.js.map +0 -1
  171. package/dist/src/storage/migrations/010_create_sync_tables.js +0 -43
  172. package/dist/src/storage/migrations/010_create_sync_tables.js.map +0 -1
  173. package/dist/src/storage/migrations/011_add_cursor_type_column.js +0 -29
  174. package/dist/src/storage/migrations/011_add_cursor_type_column.js.map +0 -1
  175. package/dist/src/storage/migrations/012_add_source_remote_column.js +0 -7
  176. package/dist/src/storage/migrations/012_add_source_remote_column.js.map +0 -1
  177. package/dist/src/storage/migrations/013_create_sync_dead_letters_table.js +0 -24
  178. package/dist/src/storage/migrations/013_create_sync_dead_letters_table.js.map +0 -1
  179. package/dist/src/storage/migrations/index.js +0 -3
  180. package/dist/src/storage/migrations/index.js.map +0 -1
  181. package/dist/src/storage/migrations/migrator.js +0 -84
  182. package/dist/src/storage/migrations/migrator.js.map +0 -1
  183. package/dist/src/storage/migrations/run-migrations.js +0 -58
  184. package/dist/src/storage/migrations/run-migrations.js.map +0 -1
  185. package/dist/src/storage/migrations/types.js +0 -2
  186. package/dist/src/storage/migrations/types.js.map +0 -1
  187. package/dist/src/storage/txn.js +0 -42
  188. package/dist/src/storage/txn.js.map +0 -1
  189. package/dist/src/subs/default-error-handler.js +0 -27
  190. package/dist/src/subs/default-error-handler.js.map +0 -1
  191. package/dist/src/subs/react-subscription-manager.js +0 -185
  192. package/dist/src/subs/react-subscription-manager.js.map +0 -1
  193. package/dist/src/subs/subscription-notification-read-model.js +0 -62
  194. package/dist/src/subs/subscription-notification-read-model.js.map +0 -1
  195. package/dist/src/subs/types.js +0 -2
  196. package/dist/src/subs/types.js.map +0 -1
  197. package/dist/src/sync/batch-aggregator.js +0 -94
  198. package/dist/src/sync/batch-aggregator.js.map +0 -1
  199. package/dist/src/sync/buffered-mailbox.js +0 -164
  200. package/dist/src/sync/buffered-mailbox.js.map +0 -1
  201. package/dist/src/sync/channels/gql-req-channel.js +0 -548
  202. package/dist/src/sync/channels/gql-req-channel.js.map +0 -1
  203. package/dist/src/sync/channels/gql-request-channel-factory.js +0 -105
  204. package/dist/src/sync/channels/gql-request-channel-factory.js.map +0 -1
  205. package/dist/src/sync/channels/gql-res-channel.js +0 -79
  206. package/dist/src/sync/channels/gql-res-channel.js.map +0 -1
  207. package/dist/src/sync/channels/gql-response-channel-factory.js +0 -14
  208. package/dist/src/sync/channels/gql-response-channel-factory.js.map +0 -1
  209. package/dist/src/sync/channels/index.js +0 -8
  210. package/dist/src/sync/channels/index.js.map +0 -1
  211. package/dist/src/sync/channels/interval-poll-timer.js +0 -123
  212. package/dist/src/sync/channels/interval-poll-timer.js.map +0 -1
  213. package/dist/src/sync/channels/poll-timer.js +0 -2
  214. package/dist/src/sync/channels/poll-timer.js.map +0 -1
  215. package/dist/src/sync/channels/utils.js +0 -161
  216. package/dist/src/sync/channels/utils.js.map +0 -1
  217. package/dist/src/sync/errors.js +0 -17
  218. package/dist/src/sync/errors.js.map +0 -1
  219. package/dist/src/sync/index.js +0 -11
  220. package/dist/src/sync/index.js.map +0 -1
  221. package/dist/src/sync/interfaces.js +0 -2
  222. package/dist/src/sync/interfaces.js.map +0 -1
  223. package/dist/src/sync/mailbox.js +0 -142
  224. package/dist/src/sync/mailbox.js.map +0 -1
  225. package/dist/src/sync/sync-awaiter.js +0 -124
  226. package/dist/src/sync/sync-awaiter.js.map +0 -1
  227. package/dist/src/sync/sync-builder.js +0 -52
  228. package/dist/src/sync/sync-builder.js.map +0 -1
  229. package/dist/src/sync/sync-manager.js +0 -447
  230. package/dist/src/sync/sync-manager.js.map +0 -1
  231. package/dist/src/sync/sync-operation.js +0 -70
  232. package/dist/src/sync/sync-operation.js.map +0 -1
  233. package/dist/src/sync/sync-status-tracker.js +0 -137
  234. package/dist/src/sync/sync-status-tracker.js.map +0 -1
  235. package/dist/src/sync/types.js +0 -31
  236. package/dist/src/sync/types.js.map +0 -1
  237. package/dist/src/sync/utils.js +0 -283
  238. package/dist/src/sync/utils.js.map +0 -1
  239. package/dist/src/utils/reshuffle.js +0 -91
  240. package/dist/src/utils/reshuffle.js.map +0 -1
@@ -1,143 +0,0 @@
1
- /**
2
- * Base class for read models that provides catch-up/rewind functionality.
3
- * Handles initialization, state tracking via ViewState table, and consistency tracking.
4
- * Subclasses should override indexOperations() with their specific indexing logic.
5
- */
6
- export class BaseReadModel {
7
- db;
8
- operationIndex;
9
- writeCache;
10
- consistencyTracker;
11
- readModelId;
12
- lastOrdinal = 0;
13
- constructor(db, operationIndex, writeCache, consistencyTracker, readModelId) {
14
- this.db = db;
15
- this.operationIndex = operationIndex;
16
- this.writeCache = writeCache;
17
- this.consistencyTracker = consistencyTracker;
18
- this.readModelId = readModelId;
19
- }
20
- /**
21
- * Initializes the read model by loading state and catching up on missed operations.
22
- */
23
- async init() {
24
- const viewState = await this.loadState();
25
- if (viewState !== undefined) {
26
- this.lastOrdinal = viewState;
27
- const missedOperations = await this.operationIndex.getSinceOrdinal(this.lastOrdinal);
28
- if (missedOperations.results.length > 0) {
29
- const opsWithState = await this.rebuildStateForOperations(missedOperations.results);
30
- await this.indexOperations(opsWithState);
31
- }
32
- }
33
- else {
34
- await this.initializeState();
35
- const allOperations = await this.operationIndex.getSinceOrdinal(0);
36
- if (allOperations.results.length > 0) {
37
- const opsWithState = await this.rebuildStateForOperations(allOperations.results);
38
- await this.indexOperations(opsWithState);
39
- }
40
- }
41
- }
42
- /**
43
- * Indexes operations into the read model.
44
- * Subclasses should override this method to implement their specific indexing logic.
45
- * The overriding method should call saveState() and updateConsistencyTracker() at the end.
46
- */
47
- async indexOperations(items) {
48
- if (items.length === 0)
49
- return;
50
- await this.db.transaction().execute(async (trx) => {
51
- await this.saveState(trx, items);
52
- });
53
- this.updateConsistencyTracker(items);
54
- }
55
- /**
56
- * Waits for the read model to reach the specified consistency level.
57
- */
58
- async waitForConsistency(token, timeoutMs, signal) {
59
- if (token.coordinates.length === 0) {
60
- return;
61
- }
62
- await this.consistencyTracker.waitFor(token.coordinates, timeoutMs, signal);
63
- }
64
- /**
65
- * Rebuilds document state for each operation using the write cache.
66
- */
67
- async rebuildStateForOperations(operations) {
68
- const result = [];
69
- for (const op of operations) {
70
- const { documentId, scope, branch } = op.context;
71
- const targetRevision = op.operation.index;
72
- const document = await this.writeCache.getState(documentId, scope, branch, targetRevision);
73
- result.push({
74
- operation: op.operation,
75
- context: {
76
- ...op.context,
77
- resultingState: JSON.stringify(document),
78
- },
79
- });
80
- }
81
- return result;
82
- }
83
- /**
84
- * Loads the last processed ordinal from the ViewState table.
85
- * Returns undefined if no state exists for this read model.
86
- */
87
- async loadState() {
88
- const viewStateDb = this.db;
89
- const row = await viewStateDb
90
- .selectFrom("ViewState")
91
- .select("lastOrdinal")
92
- .where("readModelId", "=", this.readModelId)
93
- .executeTakeFirst();
94
- return row?.lastOrdinal;
95
- }
96
- /**
97
- * Initializes the ViewState row for this read model.
98
- */
99
- async initializeState() {
100
- const viewStateDb = this.db;
101
- await viewStateDb
102
- .insertInto("ViewState")
103
- .values({
104
- readModelId: this.readModelId,
105
- lastOrdinal: 0,
106
- })
107
- .execute();
108
- }
109
- /**
110
- * Saves the last processed ordinal to the ViewState table.
111
- * Should be called at the end of indexOperations() within a transaction.
112
- */
113
- async saveState(trx, items) {
114
- const maxOrdinal = Math.max(...items.map((item) => item.context.ordinal));
115
- this.lastOrdinal = maxOrdinal;
116
- await trx
117
- .updateTable("ViewState")
118
- .set({
119
- lastOrdinal: maxOrdinal,
120
- lastOperationTimestamp: new Date(),
121
- })
122
- .where("readModelId", "=", this.readModelId)
123
- .execute();
124
- }
125
- /**
126
- * Updates the consistency tracker with the processed operations.
127
- * Should be called at the end of indexOperations() after the transaction commits.
128
- */
129
- updateConsistencyTracker(items) {
130
- const coordinates = [];
131
- for (let i = 0; i < items.length; i++) {
132
- const item = items[i];
133
- coordinates.push({
134
- documentId: item.context.documentId,
135
- scope: item.context.scope,
136
- branch: item.context.branch,
137
- operationIndex: item.operation.index,
138
- });
139
- }
140
- this.consistencyTracker.update(coordinates);
141
- }
142
- }
143
- //# sourceMappingURL=base-read-model.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"base-read-model.js","sourceRoot":"","sources":["../../../src/read-models/base-read-model.ts"],"names":[],"mappings":"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"}
@@ -1,72 +0,0 @@
1
- import { ReactorEventTypes, } from "../events/types.js";
2
- /**
3
- * Coordinates read model synchronization by listening to operation write events
4
- * and updating all registered read models in parallel.
5
- *
6
- * This coordinator is responsible for:
7
- * - Subscribing to OPERATION_WRITTEN events from the event bus
8
- * - Distributing operation updates to all registered read models
9
- * - Managing the lifecycle of read model subscriptions
10
- *
11
- * Read models are updated asynchronously and in parallel to avoid blocking
12
- * the write path. Errors in read model updates are propagated through the
13
- * event bus but do not affect the write operation success.
14
- */
15
- export class ReadModelCoordinator {
16
- eventBus;
17
- preReady;
18
- postReady;
19
- unsubscribe;
20
- isRunning = false;
21
- constructor(eventBus, preReady, postReady) {
22
- this.eventBus = eventBus;
23
- this.preReady = preReady;
24
- this.postReady = postReady;
25
- //
26
- }
27
- /**
28
- * Start listening for operation events and updating read models.
29
- * Can be called multiple times safely (subsequent calls are no-ops).
30
- */
31
- start() {
32
- if (this.isRunning) {
33
- return;
34
- }
35
- // Subscribe to WRITE_READY events
36
- this.unsubscribe = this.eventBus.subscribe(ReactorEventTypes.JOB_WRITE_READY, async (type, event) => {
37
- await this.handleWriteReady(event);
38
- });
39
- this.isRunning = true;
40
- }
41
- /**
42
- * Stop listening and clean up subscriptions.
43
- * Can be called multiple times safely (subsequent calls are no-ops).
44
- */
45
- stop() {
46
- if (!this.isRunning) {
47
- return;
48
- }
49
- if (this.unsubscribe) {
50
- this.unsubscribe();
51
- this.unsubscribe = undefined;
52
- }
53
- this.isRunning = false;
54
- }
55
- /**
56
- * Handle write ready events by updating all read models in parallel.
57
- * Errors from individual read models are collected and re-thrown as an aggregate.
58
- */
59
- async handleWriteReady(event) {
60
- // Index into pre-ready read models in parallel
61
- await Promise.all(this.preReady.map((readModel) => readModel.indexOperations(event.operations)));
62
- // Emit READ_READY event after all pre-ready read models have completed
63
- const readyEvent = {
64
- jobId: event.jobId,
65
- operations: event.operations,
66
- };
67
- await this.eventBus.emit(ReactorEventTypes.JOB_READ_READY, readyEvent);
68
- // Process post-ready read models (e.g., subscription notifications)
69
- await Promise.all(this.postReady.map((readModel) => readModel.indexOperations(event.operations)));
70
- }
71
- }
72
- //# sourceMappingURL=coordinator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"coordinator.js","sourceRoot":"","sources":["../../../src/read-models/coordinator.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,GAIlB,MAAM,oBAAoB,CAAC;AAG5B;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAoB;IAKrB;IACQ;IACA;IANV,WAAW,CAAe;IAC1B,SAAS,GAAG,KAAK,CAAC;IAE1B,YACU,QAAmB,EACX,QAAsB,EACtB,SAAuB;QAF/B,aAAQ,GAAR,QAAQ,CAAW;QACX,aAAQ,GAAR,QAAQ,CAAc;QACtB,cAAS,GAAT,SAAS,CAAc;QAEvC,EAAE;IACJ,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CACxC,iBAAiB,CAAC,eAAe,EACjC,KAAK,EAAE,IAAI,EAAE,KAAyB,EAAE,EAAE;YACxC,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC,CACF,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,gBAAgB,CAAC,KAAyB;QACtD,+CAA+C;QAC/C,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAC9B,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,CAC5C,CACF,CAAC;QAEF,uEAAuE;QACvE,MAAM,UAAU,GAAsB;YACpC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,UAAU,EAAE,KAAK,CAAC,UAAU;SAC7B,CAAC;QACF,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;QAEvE,oEAAoE;QACpE,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAC/B,SAAS,CAAC,eAAe,CAAC,KAAK,CAAC,UAAU,CAAC,CAC5C,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -1,457 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { BaseReadModel } from "./base-read-model.js";
3
- export class KyselyDocumentView extends BaseReadModel {
4
- operationStore;
5
- _db;
6
- constructor(db, operationStore, operationIndex, writeCache, consistencyTracker) {
7
- super(db, operationIndex, writeCache, consistencyTracker, "document-view");
8
- this.operationStore = operationStore;
9
- this._db = db;
10
- }
11
- async indexOperations(items) {
12
- if (items.length === 0)
13
- return;
14
- await this._db.transaction().execute(async (trx) => {
15
- for (const item of items) {
16
- const { operation, context } = item;
17
- const { documentId, scope, branch, documentType, resultingState } = context;
18
- const { index, hash } = operation;
19
- if (!resultingState) {
20
- throw new Error(`Missing resultingState in context for operation ${operation.id || "unknown"}. ` +
21
- `IDocumentView requires resultingState from upstream - it does not rebuild documents.`);
22
- }
23
- let fullState = {};
24
- try {
25
- fullState = JSON.parse(resultingState);
26
- }
27
- catch (error) {
28
- throw new Error(`Failed to parse resultingState for operation ${operation.id || "unknown"}: ${error instanceof Error ? error.message : String(error)}`);
29
- }
30
- const operationType = operation.action.type;
31
- let scopesToIndex;
32
- if (operationType === "CREATE_DOCUMENT") {
33
- scopesToIndex = Object.entries(fullState).filter(([key]) => key === "header" || key === "document" || key === "auth");
34
- }
35
- else if (operationType === "UPGRADE_DOCUMENT") {
36
- const scopeStatesToIndex = [];
37
- for (const [scopeName, scopeState] of Object.entries(fullState)) {
38
- if (scopeName === "header") {
39
- scopeStatesToIndex.push([scopeName, scopeState]);
40
- continue;
41
- }
42
- if (scopeName === scope) {
43
- scopeStatesToIndex.push([scopeName, scopeState]);
44
- continue;
45
- }
46
- const existingSnapshot = await trx
47
- .selectFrom("DocumentSnapshot")
48
- .select("scope")
49
- .where("documentId", "=", documentId)
50
- .where("scope", "=", scopeName)
51
- .where("branch", "=", branch)
52
- .executeTakeFirst();
53
- if (!existingSnapshot) {
54
- scopeStatesToIndex.push([scopeName, scopeState]);
55
- }
56
- }
57
- scopesToIndex = scopeStatesToIndex;
58
- }
59
- else {
60
- scopesToIndex = [];
61
- if (fullState.header !== undefined) {
62
- scopesToIndex.push(["header", fullState.header]);
63
- }
64
- if (fullState[scope] !== undefined) {
65
- scopesToIndex.push([scope, fullState[scope]]);
66
- }
67
- else {
68
- scopesToIndex.push([scope, {}]);
69
- }
70
- }
71
- for (const [scopeName, scopeState] of scopesToIndex) {
72
- const existingSnapshot = await trx
73
- .selectFrom("DocumentSnapshot")
74
- .selectAll()
75
- .where("documentId", "=", documentId)
76
- .where("scope", "=", scopeName)
77
- .where("branch", "=", branch)
78
- .executeTakeFirst();
79
- const newState = typeof scopeState === "object" && scopeState !== null
80
- ? scopeState
81
- : {};
82
- let slug = existingSnapshot?.slug ?? null;
83
- let name = existingSnapshot?.name ?? null;
84
- if (scopeName === "header") {
85
- const headerSlug = newState.slug;
86
- const headerName = newState.name;
87
- if (typeof headerSlug === "string") {
88
- slug = headerSlug;
89
- }
90
- if (typeof headerName === "string") {
91
- name = headerName;
92
- }
93
- if (slug && slug !== documentId) {
94
- await trx
95
- .insertInto("SlugMapping")
96
- .values({
97
- slug,
98
- documentId,
99
- scope: scopeName,
100
- branch,
101
- })
102
- .onConflict((oc) => oc.column("slug").doUpdateSet({
103
- documentId,
104
- scope: scopeName,
105
- branch,
106
- }))
107
- .execute();
108
- }
109
- }
110
- if (existingSnapshot) {
111
- await trx
112
- .updateTable("DocumentSnapshot")
113
- .set({
114
- lastOperationIndex: index,
115
- lastOperationHash: hash,
116
- lastUpdatedAt: new Date(),
117
- snapshotVersion: existingSnapshot.snapshotVersion + 1,
118
- content: newState,
119
- slug,
120
- name,
121
- })
122
- .where("documentId", "=", documentId)
123
- .where("scope", "=", scopeName)
124
- .where("branch", "=", branch)
125
- .execute();
126
- }
127
- else {
128
- const snapshot = {
129
- id: uuidv4(),
130
- documentId,
131
- slug,
132
- name,
133
- scope: scopeName,
134
- branch,
135
- content: newState,
136
- documentType,
137
- lastOperationIndex: index,
138
- lastOperationHash: hash,
139
- identifiers: null,
140
- metadata: null,
141
- deletedAt: null,
142
- };
143
- await trx.insertInto("DocumentSnapshot").values(snapshot).execute();
144
- }
145
- }
146
- }
147
- await this.saveState(trx, items);
148
- });
149
- this.updateConsistencyTracker(items);
150
- }
151
- async exists(documentIds, consistencyToken, signal) {
152
- if (consistencyToken) {
153
- await this.waitForConsistency(consistencyToken, undefined, signal);
154
- }
155
- if (signal?.aborted) {
156
- throw new Error("Operation aborted");
157
- }
158
- if (documentIds.length === 0) {
159
- return [];
160
- }
161
- const snapshots = await this._db
162
- .selectFrom("DocumentSnapshot")
163
- .select(["documentId"])
164
- .where("documentId", "in", documentIds)
165
- .where("isDeleted", "=", false)
166
- .distinct()
167
- .execute();
168
- const existingIds = new Set(snapshots.map((s) => s.documentId));
169
- return documentIds.map((id) => existingIds.has(id));
170
- }
171
- async get(documentId, view, consistencyToken, signal) {
172
- if (consistencyToken) {
173
- await this.waitForConsistency(consistencyToken, undefined, signal);
174
- }
175
- if (signal?.aborted) {
176
- throw new Error("Operation aborted");
177
- }
178
- const branch = view?.branch || "main";
179
- let scopesToQuery;
180
- if (view?.scopes && view.scopes.length > 0) {
181
- scopesToQuery = [...new Set(["header", "document", ...view.scopes])];
182
- }
183
- else {
184
- scopesToQuery = [];
185
- }
186
- let query = this._db
187
- .selectFrom("DocumentSnapshot")
188
- .selectAll()
189
- .where("documentId", "=", documentId)
190
- .where("branch", "=", branch)
191
- .where("isDeleted", "=", false);
192
- if (scopesToQuery.length > 0) {
193
- query = query.where("scope", "in", scopesToQuery);
194
- }
195
- const snapshots = await query.execute();
196
- if (snapshots.length === 0) {
197
- throw new Error(`Document not found: ${documentId}`);
198
- }
199
- if (signal?.aborted) {
200
- throw new Error("Operation aborted");
201
- }
202
- const headerSnapshot = snapshots.find((s) => s.scope === "header");
203
- if (!headerSnapshot) {
204
- throw new Error(`Document header not found: ${documentId}`);
205
- }
206
- const header = headerSnapshot.content;
207
- const revisions = await this.operationStore.getRevisions(documentId, branch, signal);
208
- header.revision = revisions.revision;
209
- header.lastModifiedAtUtcIso = revisions.latestTimestamp;
210
- const state = {};
211
- for (const snapshot of snapshots) {
212
- if (snapshot.scope === "header") {
213
- continue;
214
- }
215
- state[snapshot.scope] = snapshot.content;
216
- }
217
- const document = {
218
- header,
219
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
220
- state: state,
221
- operations: {},
222
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
223
- initialState: state,
224
- clipboard: [],
225
- };
226
- return document;
227
- }
228
- async getMany(documentIds, view, consistencyToken, signal) {
229
- if (documentIds.length === 0) {
230
- return [];
231
- }
232
- if (consistencyToken) {
233
- await this.waitForConsistency(consistencyToken, undefined, signal);
234
- }
235
- if (signal?.aborted) {
236
- throw new Error("Operation aborted");
237
- }
238
- const branch = view?.branch || "main";
239
- let scopesToQuery;
240
- if (view?.scopes && view.scopes.length > 0) {
241
- scopesToQuery = [...new Set(["header", "document", ...view.scopes])];
242
- }
243
- else {
244
- scopesToQuery = [];
245
- }
246
- let query = this._db
247
- .selectFrom("DocumentSnapshot")
248
- .selectAll()
249
- .where("documentId", "in", documentIds)
250
- .where("branch", "=", branch)
251
- .where("isDeleted", "=", false);
252
- if (scopesToQuery.length > 0) {
253
- query = query.where("scope", "in", scopesToQuery);
254
- }
255
- const allSnapshots = await query.execute();
256
- if (signal?.aborted) {
257
- throw new Error("Operation aborted");
258
- }
259
- const snapshotsByDocId = new Map();
260
- for (const snapshot of allSnapshots) {
261
- const existing = snapshotsByDocId.get(snapshot.documentId) || [];
262
- existing.push(snapshot);
263
- snapshotsByDocId.set(snapshot.documentId, existing);
264
- }
265
- const foundDocumentIds = [...snapshotsByDocId.keys()];
266
- const revisionResults = await Promise.all(foundDocumentIds.map((docId) => this.operationStore.getRevisions(docId, branch, signal)));
267
- const revisionsByDocId = new Map();
268
- for (let i = 0; i < foundDocumentIds.length; i++) {
269
- revisionsByDocId.set(foundDocumentIds[i], revisionResults[i]);
270
- }
271
- if (signal?.aborted) {
272
- throw new Error("Operation aborted");
273
- }
274
- const documents = [];
275
- for (const documentId of documentIds) {
276
- const snapshots = snapshotsByDocId.get(documentId);
277
- if (!snapshots || snapshots.length === 0) {
278
- continue;
279
- }
280
- const headerSnapshot = snapshots.find((s) => s.scope === "header");
281
- if (!headerSnapshot) {
282
- continue;
283
- }
284
- const header = headerSnapshot.content;
285
- const revisions = revisionsByDocId.get(documentId);
286
- if (revisions) {
287
- header.revision = revisions.revision;
288
- header.lastModifiedAtUtcIso = revisions.latestTimestamp;
289
- }
290
- const state = {};
291
- for (const snapshot of snapshots) {
292
- if (snapshot.scope === "header") {
293
- continue;
294
- }
295
- state[snapshot.scope] = snapshot.content;
296
- }
297
- const document = {
298
- header,
299
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
300
- state: state,
301
- operations: {},
302
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
303
- initialState: state,
304
- clipboard: [],
305
- };
306
- documents.push(document);
307
- }
308
- return documents;
309
- }
310
- async getByIdOrSlug(identifier, view, consistencyToken, signal) {
311
- const documentId = await this.resolveIdOrSlug(identifier, view, consistencyToken, signal);
312
- return this.get(documentId, view, undefined, signal);
313
- }
314
- async findByType(type, view, paging, consistencyToken, signal) {
315
- if (consistencyToken) {
316
- await this.waitForConsistency(consistencyToken, undefined, signal);
317
- }
318
- if (signal?.aborted) {
319
- throw new Error("Operation aborted");
320
- }
321
- const branch = view?.branch || "main";
322
- const startIndex = paging?.cursor ? parseInt(paging.cursor) : 0;
323
- const limit = paging?.limit || 100;
324
- const documents = [];
325
- const processedDocumentIds = new Set();
326
- const allDocumentIds = [];
327
- const snapshots = await this._db
328
- .selectFrom("DocumentSnapshot")
329
- .selectAll()
330
- .where("documentType", "=", type)
331
- .where("branch", "=", branch)
332
- .where("isDeleted", "=", false)
333
- .orderBy("lastUpdatedAt", "desc")
334
- .execute();
335
- if (signal?.aborted) {
336
- throw new Error("Operation aborted");
337
- }
338
- for (const snapshot of snapshots) {
339
- if (processedDocumentIds.has(snapshot.documentId)) {
340
- continue;
341
- }
342
- processedDocumentIds.add(snapshot.documentId);
343
- allDocumentIds.push(snapshot.documentId);
344
- }
345
- const docsToFetch = allDocumentIds.slice(startIndex, startIndex + limit);
346
- for (const documentId of docsToFetch) {
347
- if (signal?.aborted) {
348
- throw new Error("Operation aborted");
349
- }
350
- try {
351
- const document = await this.get(documentId, view, undefined, signal);
352
- documents.push(document);
353
- }
354
- catch {
355
- continue;
356
- }
357
- }
358
- const hasMore = allDocumentIds.length > startIndex + limit;
359
- const nextCursor = hasMore ? String(startIndex + limit) : undefined;
360
- return {
361
- results: documents,
362
- options: paging || { cursor: "0", limit: 100 },
363
- nextCursor,
364
- totalCount: allDocumentIds.length,
365
- next: hasMore
366
- ? () => this.findByType(type, view, { cursor: nextCursor, limit }, consistencyToken, signal)
367
- : undefined,
368
- };
369
- }
370
- async resolveSlug(slug,
371
- // TODO: this should only be branch
372
- view, consistencyToken, signal) {
373
- if (consistencyToken) {
374
- await this.waitForConsistency(consistencyToken, undefined, signal);
375
- }
376
- if (signal?.aborted) {
377
- throw new Error("Operation aborted");
378
- }
379
- const branch = view?.branch || "main";
380
- const mapping = await this._db
381
- .selectFrom("SlugMapping")
382
- .select("documentId")
383
- .where("slug", "=", slug)
384
- .where("branch", "=", branch)
385
- .executeTakeFirst();
386
- if (!mapping) {
387
- return undefined;
388
- }
389
- if (signal?.aborted) {
390
- throw new Error("Operation aborted");
391
- }
392
- if (view?.scopes && view.scopes.length > 0) {
393
- const scopeCheck = await this._db
394
- .selectFrom("DocumentSnapshot")
395
- .select("scope")
396
- .where("documentId", "=", mapping.documentId)
397
- .where("branch", "=", branch)
398
- .where("scope", "in", view.scopes)
399
- .where("isDeleted", "=", false)
400
- .executeTakeFirst();
401
- if (!scopeCheck) {
402
- return undefined;
403
- }
404
- }
405
- return mapping.documentId;
406
- }
407
- // TODO: fix
408
- async resolveSlugs(slugs,
409
- // TODO: this should only be branch
410
- view, consistencyToken, signal) {
411
- const ids = await Promise.all(slugs.map((slug) => this.resolveSlug(slug, view, consistencyToken, signal)));
412
- return ids.filter((id) => id !== undefined);
413
- }
414
- async resolveIdOrSlug(identifier,
415
- // TODO: this should only be branch
416
- view, consistencyToken, signal) {
417
- if (consistencyToken) {
418
- await this.waitForConsistency(consistencyToken, undefined, signal);
419
- }
420
- if (signal?.aborted) {
421
- throw new Error("Operation aborted");
422
- }
423
- const branch = view?.branch || "main";
424
- const idCheckPromise = this._db
425
- .selectFrom("DocumentSnapshot")
426
- .select("documentId")
427
- .where("documentId", "=", identifier)
428
- .where("branch", "=", branch)
429
- .where("isDeleted", "=", false)
430
- .executeTakeFirst();
431
- const slugCheckPromise = this._db
432
- .selectFrom("SlugMapping")
433
- .select("documentId")
434
- .where("slug", "=", identifier)
435
- .where("branch", "=", branch)
436
- .executeTakeFirst();
437
- const [idMatch, slugMatch] = await Promise.all([
438
- idCheckPromise,
439
- slugCheckPromise,
440
- ]);
441
- if (signal?.aborted) {
442
- throw new Error("Operation aborted");
443
- }
444
- const idMatchDocId = idMatch?.documentId;
445
- const slugMatchDocId = slugMatch?.documentId;
446
- if (idMatchDocId && slugMatchDocId && idMatchDocId !== slugMatchDocId) {
447
- throw new Error(`Ambiguous identifier "${identifier}": matches both document ID "${idMatchDocId}" and slug for document ID "${slugMatchDocId}". ` +
448
- `Please use get() for ID or resolveSlug() + get() for slug to be explicit.`);
449
- }
450
- const resolvedDocumentId = idMatchDocId || slugMatchDocId;
451
- if (!resolvedDocumentId) {
452
- throw new Error(`Document not found: ${identifier}`);
453
- }
454
- return resolvedDocumentId;
455
- }
456
- }
457
- //# sourceMappingURL=document-view.js.map