@powerhousedao/reactor 6.0.0-dev.7 → 6.0.0-dev.78

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 (376) hide show
  1. package/dist/src/cache/collection-membership-cache.d.ts +13 -0
  2. package/dist/src/cache/collection-membership-cache.d.ts.map +1 -0
  3. package/dist/src/cache/document-meta-cache.d.ts.map +1 -1
  4. package/dist/src/cache/kysely-operation-index.d.ts +6 -1
  5. package/dist/src/cache/kysely-operation-index.d.ts.map +1 -1
  6. package/dist/src/cache/kysely-write-cache.d.ts +9 -2
  7. package/dist/src/cache/kysely-write-cache.d.ts.map +1 -1
  8. package/dist/src/cache/operation-index-types.d.ts +16 -2
  9. package/dist/src/cache/operation-index-types.d.ts.map +1 -1
  10. package/dist/src/cache/write/interfaces.d.ts +7 -2
  11. package/dist/src/cache/write/interfaces.d.ts.map +1 -1
  12. package/dist/src/client/reactor-client.d.ts +13 -10
  13. package/dist/src/client/reactor-client.d.ts.map +1 -1
  14. package/dist/src/client/types.d.ts +25 -6
  15. package/dist/src/client/types.d.ts.map +1 -1
  16. package/dist/src/core/reactor-builder.d.ts +23 -10
  17. package/dist/src/core/reactor-builder.d.ts.map +1 -1
  18. package/dist/src/core/reactor-client-builder.d.ts +5 -4
  19. package/dist/src/core/reactor-client-builder.d.ts.map +1 -1
  20. package/dist/src/core/reactor.d.ts +20 -80
  21. package/dist/src/core/reactor.d.ts.map +1 -1
  22. package/dist/src/core/types.d.ts +64 -28
  23. package/dist/src/core/types.d.ts.map +1 -1
  24. package/dist/src/core/utils.d.ts +39 -3
  25. package/dist/src/core/utils.d.ts.map +1 -1
  26. package/dist/src/events/types.d.ts +35 -10
  27. package/dist/src/events/types.d.ts.map +1 -1
  28. package/dist/src/executor/document-action-handler.d.ts +37 -0
  29. package/dist/src/executor/document-action-handler.d.ts.map +1 -0
  30. package/dist/src/executor/signature-verifier.d.ts +9 -0
  31. package/dist/src/executor/signature-verifier.d.ts.map +1 -0
  32. package/dist/src/executor/simple-job-executor-manager.d.ts +6 -1
  33. package/dist/src/executor/simple-job-executor-manager.d.ts.map +1 -1
  34. package/dist/src/executor/simple-job-executor.d.ts +6 -46
  35. package/dist/src/executor/simple-job-executor.d.ts.map +1 -1
  36. package/dist/src/executor/types.d.ts +1 -3
  37. package/dist/src/executor/types.d.ts.map +1 -1
  38. package/dist/src/executor/util.d.ts +12 -2
  39. package/dist/src/executor/util.d.ts.map +1 -1
  40. package/dist/src/index.d.ts +11 -9
  41. package/dist/src/index.d.ts.map +1 -1
  42. package/dist/src/index.js +20208 -61
  43. package/dist/src/job-tracker/in-memory-job-tracker.d.ts +4 -3
  44. package/dist/src/job-tracker/in-memory-job-tracker.d.ts.map +1 -1
  45. package/dist/src/job-tracker/interfaces.d.ts +3 -1
  46. package/dist/src/job-tracker/interfaces.d.ts.map +1 -1
  47. package/dist/src/logging/console.d.ts +1 -22
  48. package/dist/src/logging/console.d.ts.map +1 -1
  49. package/dist/src/logging/types.d.ts +1 -11
  50. package/dist/src/logging/types.d.ts.map +1 -1
  51. package/dist/src/processors/index.d.ts +1 -1
  52. package/dist/src/processors/index.d.ts.map +1 -1
  53. package/dist/src/processors/processor-manager.d.ts +19 -6
  54. package/dist/src/processors/processor-manager.d.ts.map +1 -1
  55. package/dist/src/processors/relational/types.d.ts +2 -0
  56. package/dist/src/processors/relational/types.d.ts.map +1 -0
  57. package/dist/src/processors/relational/utils.d.ts +2 -0
  58. package/dist/src/processors/relational/utils.d.ts.map +1 -0
  59. package/dist/src/processors/utils.d.ts +3 -2
  60. package/dist/src/processors/utils.d.ts.map +1 -1
  61. package/dist/src/queue/job-execution-handle.d.ts +3 -0
  62. package/dist/src/queue/job-execution-handle.d.ts.map +1 -1
  63. package/dist/src/queue/queue.d.ts +30 -1
  64. package/dist/src/queue/queue.d.ts.map +1 -1
  65. package/dist/src/queue/types.d.ts +4 -3
  66. package/dist/src/queue/types.d.ts.map +1 -1
  67. package/dist/src/read-models/base-read-model.d.ts +11 -9
  68. package/dist/src/read-models/base-read-model.d.ts.map +1 -1
  69. package/dist/src/read-models/coordinator.d.ts +2 -2
  70. package/dist/src/read-models/coordinator.d.ts.map +1 -1
  71. package/dist/src/read-models/document-view.d.ts +7 -4
  72. package/dist/src/read-models/document-view.d.ts.map +1 -1
  73. package/dist/src/read-models/interfaces.d.ts +1 -1
  74. package/dist/src/read-models/interfaces.d.ts.map +1 -1
  75. package/dist/src/read-models/types.d.ts +16 -0
  76. package/dist/src/read-models/types.d.ts.map +1 -1
  77. package/dist/src/registry/document-model-resolver.d.ts +29 -0
  78. package/dist/src/registry/document-model-resolver.d.ts.map +1 -0
  79. package/dist/src/registry/implementation.d.ts +4 -0
  80. package/dist/src/registry/implementation.d.ts.map +1 -1
  81. package/dist/src/registry/index.d.ts +3 -1
  82. package/dist/src/registry/index.d.ts.map +1 -1
  83. package/dist/src/registry/interfaces.d.ts +8 -0
  84. package/dist/src/registry/interfaces.d.ts.map +1 -1
  85. package/dist/src/shared/awaiter.d.ts +2 -2
  86. package/dist/src/shared/awaiter.d.ts.map +1 -1
  87. package/dist/src/shared/collect-all-pages.d.ts +7 -0
  88. package/dist/src/shared/collect-all-pages.d.ts.map +1 -0
  89. package/dist/src/shared/drive-url.d.ts +15 -0
  90. package/dist/src/shared/drive-url.d.ts.map +1 -0
  91. package/dist/src/shared/errors.d.ts +9 -0
  92. package/dist/src/shared/errors.d.ts.map +1 -1
  93. package/dist/src/shared/factories.d.ts +6 -2
  94. package/dist/src/shared/factories.d.ts.map +1 -1
  95. package/dist/src/shared/types.d.ts +32 -6
  96. package/dist/src/shared/types.d.ts.map +1 -1
  97. package/dist/src/signer/passthrough-signer.d.ts +1 -1
  98. package/dist/src/signer/passthrough-signer.d.ts.map +1 -1
  99. package/dist/src/storage/interfaces.d.ts +238 -124
  100. package/dist/src/storage/interfaces.d.ts.map +1 -1
  101. package/dist/src/storage/kysely/document-indexer.d.ts +17 -18
  102. package/dist/src/storage/kysely/document-indexer.d.ts.map +1 -1
  103. package/dist/src/storage/kysely/store.d.ts +5 -4
  104. package/dist/src/storage/kysely/store.d.ts.map +1 -1
  105. package/dist/src/storage/kysely/sync-cursor-storage.d.ts +1 -1
  106. package/dist/src/storage/kysely/sync-cursor-storage.d.ts.map +1 -1
  107. package/dist/src/storage/kysely/sync-dead-letter-storage.d.ts +17 -0
  108. package/dist/src/storage/kysely/sync-dead-letter-storage.d.ts.map +1 -0
  109. package/dist/src/storage/kysely/types.d.ts +22 -0
  110. package/dist/src/storage/kysely/types.d.ts.map +1 -1
  111. package/dist/src/storage/migrations/011_add_cursor_type_column.d.ts +3 -0
  112. package/dist/src/storage/migrations/011_add_cursor_type_column.d.ts.map +1 -0
  113. package/dist/src/storage/migrations/012_add_source_remote_column.d.ts +3 -0
  114. package/dist/src/storage/migrations/012_add_source_remote_column.d.ts.map +1 -0
  115. package/dist/src/storage/migrations/013_create_sync_dead_letters_table.d.ts +3 -0
  116. package/dist/src/storage/migrations/013_create_sync_dead_letters_table.d.ts.map +1 -0
  117. package/dist/src/storage/migrations/014_create_processor_cursor_table.d.ts +3 -0
  118. package/dist/src/storage/migrations/014_create_processor_cursor_table.d.ts.map +1 -0
  119. package/dist/src/storage/migrations/migrator.d.ts.map +1 -1
  120. package/dist/src/subs/default-error-handler.d.ts.map +1 -1
  121. package/dist/src/subs/subscription-notification-read-model.d.ts +3 -2
  122. package/dist/src/subs/subscription-notification-read-model.d.ts.map +1 -1
  123. package/dist/src/sync/batch-aggregator.d.ts +25 -0
  124. package/dist/src/sync/batch-aggregator.d.ts.map +1 -0
  125. package/dist/src/sync/buffered-mailbox.d.ts +36 -0
  126. package/dist/src/sync/buffered-mailbox.d.ts.map +1 -0
  127. package/dist/src/sync/channels/gql-req-channel.d.ts +121 -0
  128. package/dist/src/sync/channels/gql-req-channel.d.ts.map +1 -0
  129. package/dist/src/sync/channels/gql-request-channel-factory.d.ts +32 -0
  130. package/dist/src/sync/channels/gql-request-channel-factory.d.ts.map +1 -0
  131. package/dist/src/sync/channels/gql-res-channel.d.ts +31 -0
  132. package/dist/src/sync/channels/gql-res-channel.d.ts.map +1 -0
  133. package/dist/src/sync/channels/gql-response-channel-factory.d.ts +13 -0
  134. package/dist/src/sync/channels/gql-response-channel-factory.d.ts.map +1 -0
  135. package/dist/src/sync/channels/index.d.ts +6 -4
  136. package/dist/src/sync/channels/index.d.ts.map +1 -1
  137. package/dist/src/sync/channels/interval-poll-timer.d.ts +40 -0
  138. package/dist/src/sync/channels/interval-poll-timer.d.ts.map +1 -0
  139. package/dist/src/sync/channels/poll-timer.d.ts +14 -0
  140. package/dist/src/sync/channels/poll-timer.d.ts.map +1 -0
  141. package/dist/src/sync/channels/utils.d.ts +15 -1
  142. package/dist/src/sync/channels/utils.d.ts.map +1 -1
  143. package/dist/src/sync/index.d.ts +11 -7
  144. package/dist/src/sync/index.d.ts.map +1 -1
  145. package/dist/src/sync/interfaces.d.ts +42 -19
  146. package/dist/src/sync/interfaces.d.ts.map +1 -1
  147. package/dist/src/sync/mailbox.d.ts +51 -12
  148. package/dist/src/sync/mailbox.d.ts.map +1 -1
  149. package/dist/src/sync/sync-awaiter.d.ts +34 -0
  150. package/dist/src/sync/sync-awaiter.d.ts.map +1 -0
  151. package/dist/src/sync/sync-builder.d.ts +5 -1
  152. package/dist/src/sync/sync-builder.d.ts.map +1 -1
  153. package/dist/src/sync/sync-manager.d.ts +22 -8
  154. package/dist/src/sync/sync-manager.d.ts.map +1 -1
  155. package/dist/src/sync/sync-operation.d.ts +4 -2
  156. package/dist/src/sync/sync-operation.d.ts.map +1 -1
  157. package/dist/src/sync/sync-status-tracker.d.ts +31 -0
  158. package/dist/src/sync/sync-status-tracker.d.ts.map +1 -0
  159. package/dist/src/sync/types.d.ts +107 -2
  160. package/dist/src/sync/types.d.ts.map +1 -1
  161. package/dist/src/sync/utils.d.ts +37 -2
  162. package/dist/src/sync/utils.d.ts.map +1 -1
  163. package/dist/src/utils/reshuffle.d.ts +22 -5
  164. package/dist/src/utils/reshuffle.d.ts.map +1 -1
  165. package/package.json +24 -20
  166. package/dist/src/actions/index.js +0 -76
  167. package/dist/src/actions/index.js.map +0 -1
  168. package/dist/src/cache/buffer/ring-buffer.js +0 -69
  169. package/dist/src/cache/buffer/ring-buffer.js.map +0 -1
  170. package/dist/src/cache/document-meta-cache-types.js +0 -2
  171. package/dist/src/cache/document-meta-cache-types.js.map +0 -1
  172. package/dist/src/cache/document-meta-cache.js +0 -128
  173. package/dist/src/cache/document-meta-cache.js.map +0 -1
  174. package/dist/src/cache/index.js +0 -2
  175. package/dist/src/cache/index.js.map +0 -1
  176. package/dist/src/cache/kysely-operation-index.js +0 -250
  177. package/dist/src/cache/kysely-operation-index.js.map +0 -1
  178. package/dist/src/cache/kysely-write-cache.js +0 -388
  179. package/dist/src/cache/kysely-write-cache.js.map +0 -1
  180. package/dist/src/cache/lru/lru-tracker.js +0 -96
  181. package/dist/src/cache/lru/lru-tracker.js.map +0 -1
  182. package/dist/src/cache/operation-index-types.js +0 -4
  183. package/dist/src/cache/operation-index-types.js.map +0 -1
  184. package/dist/src/cache/write/interfaces.js +0 -2
  185. package/dist/src/cache/write/interfaces.js.map +0 -1
  186. package/dist/src/cache/write-cache-types.js +0 -2
  187. package/dist/src/cache/write-cache-types.js.map +0 -1
  188. package/dist/src/client/reactor-client.js +0 -406
  189. package/dist/src/client/reactor-client.js.map +0 -1
  190. package/dist/src/client/types.js +0 -14
  191. package/dist/src/client/types.js.map +0 -1
  192. package/dist/src/core/reactor-builder.js +0 -231
  193. package/dist/src/core/reactor-builder.js.map +0 -1
  194. package/dist/src/core/reactor-client-builder.js +0 -123
  195. package/dist/src/core/reactor-client-builder.js.map +0 -1
  196. package/dist/src/core/reactor.js +0 -981
  197. package/dist/src/core/reactor.js.map +0 -1
  198. package/dist/src/core/types.js +0 -2
  199. package/dist/src/core/types.js.map +0 -1
  200. package/dist/src/core/utils.js +0 -171
  201. package/dist/src/core/utils.js.map +0 -1
  202. package/dist/src/events/event-bus.js +0 -53
  203. package/dist/src/events/event-bus.js.map +0 -1
  204. package/dist/src/events/interfaces.js +0 -2
  205. package/dist/src/events/interfaces.js.map +0 -1
  206. package/dist/src/events/types.js +0 -28
  207. package/dist/src/events/types.js.map +0 -1
  208. package/dist/src/executor/interfaces.js +0 -2
  209. package/dist/src/executor/interfaces.js.map +0 -1
  210. package/dist/src/executor/simple-job-executor-manager.js +0 -233
  211. package/dist/src/executor/simple-job-executor-manager.js.map +0 -1
  212. package/dist/src/executor/simple-job-executor.js +0 -898
  213. package/dist/src/executor/simple-job-executor.js.map +0 -1
  214. package/dist/src/executor/types.js +0 -11
  215. package/dist/src/executor/types.js.map +0 -1
  216. package/dist/src/executor/util.js +0 -184
  217. package/dist/src/executor/util.js.map +0 -1
  218. package/dist/src/index.js.map +0 -1
  219. package/dist/src/job-tracker/in-memory-job-tracker.js +0 -112
  220. package/dist/src/job-tracker/in-memory-job-tracker.js.map +0 -1
  221. package/dist/src/job-tracker/index.js +0 -2
  222. package/dist/src/job-tracker/index.js.map +0 -1
  223. package/dist/src/job-tracker/interfaces.js +0 -2
  224. package/dist/src/job-tracker/interfaces.js.map +0 -1
  225. package/dist/src/logging/console.js +0 -108
  226. package/dist/src/logging/console.js.map +0 -1
  227. package/dist/src/logging/types.js +0 -2
  228. package/dist/src/logging/types.js.map +0 -1
  229. package/dist/src/processors/index.js +0 -2
  230. package/dist/src/processors/index.js.map +0 -1
  231. package/dist/src/processors/processor-manager.js +0 -165
  232. package/dist/src/processors/processor-manager.js.map +0 -1
  233. package/dist/src/processors/types.d.ts +0 -63
  234. package/dist/src/processors/types.d.ts.map +0 -1
  235. package/dist/src/processors/types.js +0 -2
  236. package/dist/src/processors/types.js.map +0 -1
  237. package/dist/src/processors/utils.js +0 -58
  238. package/dist/src/processors/utils.js.map +0 -1
  239. package/dist/src/queue/interfaces.js +0 -2
  240. package/dist/src/queue/interfaces.js.map +0 -1
  241. package/dist/src/queue/job-execution-handle.js +0 -62
  242. package/dist/src/queue/job-execution-handle.js.map +0 -1
  243. package/dist/src/queue/queue.js +0 -384
  244. package/dist/src/queue/queue.js.map +0 -1
  245. package/dist/src/queue/types.js +0 -19
  246. package/dist/src/queue/types.js.map +0 -1
  247. package/dist/src/read-models/base-read-model.js +0 -143
  248. package/dist/src/read-models/base-read-model.js.map +0 -1
  249. package/dist/src/read-models/coordinator.js +0 -72
  250. package/dist/src/read-models/coordinator.js.map +0 -1
  251. package/dist/src/read-models/document-view.js +0 -375
  252. package/dist/src/read-models/document-view.js.map +0 -1
  253. package/dist/src/read-models/interfaces.js +0 -2
  254. package/dist/src/read-models/interfaces.js.map +0 -1
  255. package/dist/src/read-models/types.js +0 -2
  256. package/dist/src/read-models/types.js.map +0 -1
  257. package/dist/src/registry/implementation.js +0 -216
  258. package/dist/src/registry/implementation.js.map +0 -1
  259. package/dist/src/registry/index.js +0 -2
  260. package/dist/src/registry/index.js.map +0 -1
  261. package/dist/src/registry/interfaces.js +0 -2
  262. package/dist/src/registry/interfaces.js.map +0 -1
  263. package/dist/src/shared/awaiter.js +0 -123
  264. package/dist/src/shared/awaiter.js.map +0 -1
  265. package/dist/src/shared/consistency-tracker.js +0 -123
  266. package/dist/src/shared/consistency-tracker.js.map +0 -1
  267. package/dist/src/shared/errors.js +0 -75
  268. package/dist/src/shared/errors.js.map +0 -1
  269. package/dist/src/shared/factories.js +0 -33
  270. package/dist/src/shared/factories.js.map +0 -1
  271. package/dist/src/shared/types.js +0 -38
  272. package/dist/src/shared/types.js.map +0 -1
  273. package/dist/src/shared/utils.js +0 -8
  274. package/dist/src/shared/utils.js.map +0 -1
  275. package/dist/src/signer/passthrough-signer.js +0 -19
  276. package/dist/src/signer/passthrough-signer.js.map +0 -1
  277. package/dist/src/signer/types.js +0 -2
  278. package/dist/src/signer/types.js.map +0 -1
  279. package/dist/src/storage/consistency-aware-legacy-storage.d.ts +0 -33
  280. package/dist/src/storage/consistency-aware-legacy-storage.d.ts.map +0 -1
  281. package/dist/src/storage/consistency-aware-legacy-storage.js +0 -65
  282. package/dist/src/storage/consistency-aware-legacy-storage.js.map +0 -1
  283. package/dist/src/storage/index.js +0 -3
  284. package/dist/src/storage/index.js.map +0 -1
  285. package/dist/src/storage/interfaces.js +0 -19
  286. package/dist/src/storage/interfaces.js.map +0 -1
  287. package/dist/src/storage/kysely/document-indexer.js +0 -350
  288. package/dist/src/storage/kysely/document-indexer.js.map +0 -1
  289. package/dist/src/storage/kysely/keyframe-store.js +0 -64
  290. package/dist/src/storage/kysely/keyframe-store.js.map +0 -1
  291. package/dist/src/storage/kysely/store.js +0 -233
  292. package/dist/src/storage/kysely/store.js.map +0 -1
  293. package/dist/src/storage/kysely/sync-cursor-storage.js +0 -93
  294. package/dist/src/storage/kysely/sync-cursor-storage.js.map +0 -1
  295. package/dist/src/storage/kysely/sync-remote-storage.js +0 -133
  296. package/dist/src/storage/kysely/sync-remote-storage.js.map +0 -1
  297. package/dist/src/storage/kysely/types.js +0 -2
  298. package/dist/src/storage/kysely/types.js.map +0 -1
  299. package/dist/src/storage/migrations/001_create_operation_table.js +0 -41
  300. package/dist/src/storage/migrations/001_create_operation_table.js.map +0 -1
  301. package/dist/src/storage/migrations/002_create_keyframe_table.js +0 -27
  302. package/dist/src/storage/migrations/002_create_keyframe_table.js.map +0 -1
  303. package/dist/src/storage/migrations/003_create_document_table.js +0 -10
  304. package/dist/src/storage/migrations/003_create_document_table.js.map +0 -1
  305. package/dist/src/storage/migrations/004_create_document_relationship_table.js +0 -35
  306. package/dist/src/storage/migrations/004_create_document_relationship_table.js.map +0 -1
  307. package/dist/src/storage/migrations/005_create_indexer_state_table.js +0 -10
  308. package/dist/src/storage/migrations/005_create_indexer_state_table.js.map +0 -1
  309. package/dist/src/storage/migrations/006_create_document_snapshot_table.js +0 -49
  310. package/dist/src/storage/migrations/006_create_document_snapshot_table.js.map +0 -1
  311. package/dist/src/storage/migrations/007_create_slug_mapping_table.js +0 -24
  312. package/dist/src/storage/migrations/007_create_slug_mapping_table.js.map +0 -1
  313. package/dist/src/storage/migrations/008_create_view_state_table.js +0 -10
  314. package/dist/src/storage/migrations/008_create_view_state_table.js.map +0 -1
  315. package/dist/src/storage/migrations/009_create_operation_index_tables.js +0 -50
  316. package/dist/src/storage/migrations/009_create_operation_index_tables.js.map +0 -1
  317. package/dist/src/storage/migrations/010_create_sync_tables.js +0 -43
  318. package/dist/src/storage/migrations/010_create_sync_tables.js.map +0 -1
  319. package/dist/src/storage/migrations/index.js +0 -3
  320. package/dist/src/storage/migrations/index.js.map +0 -1
  321. package/dist/src/storage/migrations/migrator.js +0 -78
  322. package/dist/src/storage/migrations/migrator.js.map +0 -1
  323. package/dist/src/storage/migrations/run-migrations.js +0 -58
  324. package/dist/src/storage/migrations/run-migrations.js.map +0 -1
  325. package/dist/src/storage/migrations/types.js +0 -2
  326. package/dist/src/storage/migrations/types.js.map +0 -1
  327. package/dist/src/storage/txn.js +0 -42
  328. package/dist/src/storage/txn.js.map +0 -1
  329. package/dist/src/subs/default-error-handler.js +0 -27
  330. package/dist/src/subs/default-error-handler.js.map +0 -1
  331. package/dist/src/subs/react-subscription-manager.js +0 -185
  332. package/dist/src/subs/react-subscription-manager.js.map +0 -1
  333. package/dist/src/subs/subscription-notification-read-model.js +0 -62
  334. package/dist/src/subs/subscription-notification-read-model.js.map +0 -1
  335. package/dist/src/subs/types.js +0 -2
  336. package/dist/src/subs/types.js.map +0 -1
  337. package/dist/src/sync/channels/composite-channel-factory.d.ts +0 -30
  338. package/dist/src/sync/channels/composite-channel-factory.d.ts.map +0 -1
  339. package/dist/src/sync/channels/composite-channel-factory.js +0 -87
  340. package/dist/src/sync/channels/composite-channel-factory.js.map +0 -1
  341. package/dist/src/sync/channels/gql-channel-factory.d.ts +0 -25
  342. package/dist/src/sync/channels/gql-channel-factory.d.ts.map +0 -1
  343. package/dist/src/sync/channels/gql-channel-factory.js +0 -76
  344. package/dist/src/sync/channels/gql-channel-factory.js.map +0 -1
  345. package/dist/src/sync/channels/gql-channel.d.ts +0 -118
  346. package/dist/src/sync/channels/gql-channel.d.ts.map +0 -1
  347. package/dist/src/sync/channels/gql-channel.js +0 -423
  348. package/dist/src/sync/channels/gql-channel.js.map +0 -1
  349. package/dist/src/sync/channels/index.js +0 -6
  350. package/dist/src/sync/channels/index.js.map +0 -1
  351. package/dist/src/sync/channels/polling-channel.d.ts +0 -39
  352. package/dist/src/sync/channels/polling-channel.d.ts.map +0 -1
  353. package/dist/src/sync/channels/polling-channel.js +0 -72
  354. package/dist/src/sync/channels/polling-channel.js.map +0 -1
  355. package/dist/src/sync/channels/utils.js +0 -96
  356. package/dist/src/sync/channels/utils.js.map +0 -1
  357. package/dist/src/sync/errors.js +0 -17
  358. package/dist/src/sync/errors.js.map +0 -1
  359. package/dist/src/sync/index.js +0 -9
  360. package/dist/src/sync/index.js.map +0 -1
  361. package/dist/src/sync/interfaces.js +0 -2
  362. package/dist/src/sync/interfaces.js.map +0 -1
  363. package/dist/src/sync/mailbox.js +0 -59
  364. package/dist/src/sync/mailbox.js.map +0 -1
  365. package/dist/src/sync/sync-builder.js +0 -39
  366. package/dist/src/sync/sync-builder.js.map +0 -1
  367. package/dist/src/sync/sync-manager.js +0 -266
  368. package/dist/src/sync/sync-manager.js.map +0 -1
  369. package/dist/src/sync/sync-operation.js +0 -63
  370. package/dist/src/sync/sync-operation.js.map +0 -1
  371. package/dist/src/sync/types.js +0 -16
  372. package/dist/src/sync/types.js.map +0 -1
  373. package/dist/src/sync/utils.js +0 -78
  374. package/dist/src/sync/utils.js.map +0 -1
  375. package/dist/src/utils/reshuffle.js +0 -47
  376. package/dist/src/utils/reshuffle.js.map +0 -1
@@ -1,898 +0,0 @@
1
- import { deriveOperationId, isUndoRedo } from "document-model/core";
2
- import { driveCollectionId } from "../cache/operation-index-types.js";
3
- import { OperationEventTypes, } from "../events/types.js";
4
- import { DocumentDeletedError, InvalidSignatureError, } from "../shared/errors.js";
5
- import { reshuffleByTimestamp } from "../utils/reshuffle.js";
6
- import { applyDeleteDocumentAction, applyUpgradeDocumentAction, createDocumentFromAction, getNextIndexForScope, } from "./util.js";
7
- const MAX_SKIP_THRESHOLD = 100;
8
- const documentScopeActions = [
9
- "CREATE_DOCUMENT",
10
- "DELETE_DOCUMENT",
11
- "UPGRADE_DOCUMENT",
12
- "ADD_RELATIONSHIP",
13
- "REMOVE_RELATIONSHIP",
14
- ];
15
- /**
16
- * Simple job executor that processes a job by applying actions through document model reducers.
17
- *
18
- * @see docs/planning/Storage/IOperationStore.md for storage schema
19
- * @see docs/planning/Operations/index.md for operation structure
20
- * @see docs/planning/Jobs/reshuffle.md for skip mechanism details
21
- */
22
- export class SimpleJobExecutor {
23
- logger;
24
- registry;
25
- documentStorage;
26
- operationStorage;
27
- operationStore;
28
- eventBus;
29
- writeCache;
30
- operationIndex;
31
- documentMetaCache;
32
- signatureVerifier;
33
- config;
34
- constructor(logger, registry, documentStorage, operationStorage, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, config, signatureVerifier) {
35
- this.logger = logger;
36
- this.registry = registry;
37
- this.documentStorage = documentStorage;
38
- this.operationStorage = operationStorage;
39
- this.operationStore = operationStore;
40
- this.eventBus = eventBus;
41
- this.writeCache = writeCache;
42
- this.operationIndex = operationIndex;
43
- this.documentMetaCache = documentMetaCache;
44
- this.signatureVerifier = signatureVerifier;
45
- this.config = {
46
- maxSkipThreshold: config.maxSkipThreshold ?? MAX_SKIP_THRESHOLD,
47
- maxConcurrency: config.maxConcurrency ?? 1,
48
- jobTimeoutMs: config.jobTimeoutMs ?? 30000,
49
- retryBaseDelayMs: config.retryBaseDelayMs ?? 100,
50
- retryMaxDelayMs: config.retryMaxDelayMs ?? 5000,
51
- legacyStorageEnabled: config.legacyStorageEnabled ?? true,
52
- };
53
- }
54
- /**
55
- * Execute a single job by applying all its actions through the appropriate reducers.
56
- * Actions are processed sequentially in order.
57
- */
58
- async executeJob(job) {
59
- const startTime = Date.now();
60
- const indexTxn = this.operationIndex.start();
61
- if (job.kind === "load") {
62
- const result = await this.executeLoadJob(job, startTime, indexTxn);
63
- if (result.success && result.operationsWithContext) {
64
- const ordinals = await this.operationIndex.commit(indexTxn);
65
- for (let i = 0; i < result.operationsWithContext.length; i++) {
66
- result.operationsWithContext[i].context.ordinal = ordinals[i];
67
- }
68
- if (result.operationsWithContext.length > 0) {
69
- const event = {
70
- jobId: job.id,
71
- operations: result.operationsWithContext,
72
- jobMeta: job.meta,
73
- };
74
- this.eventBus
75
- .emit(OperationEventTypes.OPERATION_WRITTEN, event)
76
- .catch(() => {
77
- // TODO: Log error
78
- });
79
- }
80
- }
81
- return result;
82
- }
83
- const result = await this.processActions(job, job.actions, startTime, indexTxn);
84
- if (!result.success) {
85
- return {
86
- job,
87
- success: false,
88
- error: result.error,
89
- duration: Date.now() - startTime,
90
- };
91
- }
92
- const ordinals = await this.operationIndex.commit(indexTxn);
93
- if (result.operationsWithContext.length > 0) {
94
- for (let i = 0; i < result.operationsWithContext.length; i++) {
95
- result.operationsWithContext[i].context.ordinal = ordinals[i];
96
- }
97
- const event = {
98
- jobId: job.id,
99
- operations: result.operationsWithContext,
100
- jobMeta: job.meta,
101
- };
102
- this.eventBus
103
- .emit(OperationEventTypes.OPERATION_WRITTEN, event)
104
- .catch(() => {
105
- // TODO: Log error
106
- });
107
- }
108
- return {
109
- job,
110
- success: true,
111
- operations: result.generatedOperations,
112
- operationsWithContext: result.operationsWithContext,
113
- duration: Date.now() - startTime,
114
- };
115
- }
116
- async processActions(job, actions, startTime, indexTxn, skipValues, sourceOperations) {
117
- const generatedOperations = [];
118
- const operationsWithContext = [];
119
- try {
120
- await this.verifyActionSignatures(job, actions);
121
- }
122
- catch (error) {
123
- return {
124
- success: false,
125
- generatedOperations,
126
- operationsWithContext,
127
- error: error instanceof Error ? error : new Error(String(error)),
128
- };
129
- }
130
- for (let actionIndex = 0; actionIndex < actions.length; actionIndex++) {
131
- const action = actions[actionIndex];
132
- const skip = skipValues?.[actionIndex] ?? 0;
133
- const sourceOperation = sourceOperations?.[actionIndex];
134
- const isDocumentAction = documentScopeActions.includes(action.type);
135
- const result = isDocumentAction
136
- ? await this.executeDocumentAction(job, action, startTime, indexTxn, skip)
137
- : await this.executeRegularAction(job, action, startTime, indexTxn, skip, sourceOperation);
138
- const error = this.accumulateResultOrReturnError(result, generatedOperations, operationsWithContext);
139
- if (error !== null) {
140
- return {
141
- success: false,
142
- generatedOperations,
143
- operationsWithContext,
144
- error: error.error,
145
- };
146
- }
147
- }
148
- return {
149
- success: true,
150
- generatedOperations,
151
- operationsWithContext,
152
- };
153
- }
154
- /**
155
- * Execute a document scope action (CREATE_DOCUMENT, DELETE_DOCUMENT, UPGRADE_DOCUMENT,
156
- * ADD_RELATIONSHIP, REMOVE_RELATIONSHIP) by dispatching to the appropriate handler.
157
- */
158
- async executeDocumentAction(job, action, startTime, indexTxn, skip = 0) {
159
- switch (action.type) {
160
- case "CREATE_DOCUMENT":
161
- return this.executeCreateDocumentAction(job, action, startTime, indexTxn, skip);
162
- case "DELETE_DOCUMENT":
163
- return this.executeDeleteDocumentAction(job, action, startTime, indexTxn);
164
- case "UPGRADE_DOCUMENT":
165
- return this.executeUpgradeDocumentAction(job, action, startTime, indexTxn, skip);
166
- case "ADD_RELATIONSHIP":
167
- return this.executeAddRelationshipAction(job, action, startTime, indexTxn);
168
- case "REMOVE_RELATIONSHIP":
169
- return this.executeRemoveRelationshipAction(job, action, startTime, indexTxn);
170
- default:
171
- return this.buildErrorResult(job, new Error(`Unknown document action type: ${action.type}`), startTime);
172
- }
173
- }
174
- /**
175
- * Execute a CREATE_DOCUMENT system action.
176
- * This creates a new document in storage along with its initial operation.
177
- * For a new document, the operation index is always 0.
178
- */
179
- async executeCreateDocumentAction(job, action, startTime, indexTxn, skip = 0) {
180
- if (job.scope !== "document") {
181
- return {
182
- job,
183
- success: false,
184
- error: new Error(`CREATE_DOCUMENT must be in "document" scope, got "${job.scope}"`),
185
- duration: Date.now() - startTime,
186
- };
187
- }
188
- const document = createDocumentFromAction(action);
189
- // Legacy: Store the document in storage
190
- if (this.config.legacyStorageEnabled) {
191
- try {
192
- await this.documentStorage.create(document);
193
- }
194
- catch (error) {
195
- return this.buildErrorResult(job, new Error(`Failed to create document in storage: ${error instanceof Error ? error.message : String(error)}`), startTime);
196
- }
197
- }
198
- const operation = this.createOperation(action, 0, skip, {
199
- documentId: document.header.id,
200
- scope: job.scope,
201
- branch: job.branch,
202
- });
203
- // Legacy: Write the CREATE_DOCUMENT operation to legacy storage
204
- if (this.config.legacyStorageEnabled) {
205
- try {
206
- await this.operationStorage.addDocumentOperations(document.header.id, [operation], document);
207
- }
208
- catch (error) {
209
- return this.buildErrorResult(job, new Error(`Failed to write CREATE_DOCUMENT operation to legacy storage: ${error instanceof Error ? error.message : String(error)}`), startTime);
210
- }
211
- }
212
- // Compute resultingState for passing via context (not persisted)
213
- // Include header and all scopes present in the document state (auth, document, etc.)
214
- // but not global/local which aren't initialized by CREATE_DOCUMENT
215
- const resultingStateObj = {
216
- header: document.header,
217
- ...document.state,
218
- };
219
- const resultingState = JSON.stringify(resultingStateObj);
220
- const writeError = await this.writeOperationToStore(document.header.id, document.header.documentType, job.scope, job.branch, operation, job, startTime);
221
- if (writeError !== null) {
222
- return writeError;
223
- }
224
- this.updateDocumentRevision(document, job.scope, operation.index);
225
- this.writeCacheState(document.header.id, job.scope, job.branch, operation.index, document);
226
- indexTxn.write([
227
- {
228
- ...operation,
229
- documentId: document.header.id,
230
- documentType: document.header.documentType,
231
- branch: job.branch,
232
- scope: job.scope,
233
- },
234
- ]);
235
- // collection membership has to be _after_ the write, as it requires the
236
- // ordinal of the operation to be set
237
- if (document.header.documentType === "powerhouse/document-drive") {
238
- const collectionId = driveCollectionId(job.branch, document.header.id);
239
- indexTxn.createCollection(collectionId);
240
- indexTxn.addToCollection(collectionId, document.header.id);
241
- }
242
- this.documentMetaCache.putDocumentMeta(document.header.id, job.branch, {
243
- state: document.state.document,
244
- documentType: document.header.documentType,
245
- documentScopeRevision: 1,
246
- });
247
- return this.buildSuccessResult(job, operation, document.header.id, document.header.documentType, resultingState, startTime);
248
- }
249
- /**
250
- * Execute a DELETE_DOCUMENT system action.
251
- * This deletes a document from legacy storage and writes the operation to IOperationStore.
252
- * The operation index is determined from the document's current operation count.
253
- */
254
- async executeDeleteDocumentAction(job, action, startTime, indexTxn) {
255
- const input = action.input;
256
- if (!input.documentId) {
257
- return this.buildErrorResult(job, new Error("DELETE_DOCUMENT action requires a documentId in input"), startTime);
258
- }
259
- const documentId = input.documentId;
260
- let document;
261
- try {
262
- document = await this.writeCache.getState(documentId, job.scope, job.branch);
263
- }
264
- catch (error) {
265
- return this.buildErrorResult(job, new Error(`Failed to fetch document before deletion: ${error instanceof Error ? error.message : String(error)}`), startTime);
266
- }
267
- // Check if document is already deleted
268
- const documentState = document.state.document;
269
- if (documentState.isDeleted) {
270
- return this.buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);
271
- }
272
- const nextIndex = getNextIndexForScope(document, job.scope);
273
- const operation = this.createOperation(action, nextIndex, 0, {
274
- documentId,
275
- scope: job.scope,
276
- branch: job.branch,
277
- });
278
- if (this.config.legacyStorageEnabled) {
279
- try {
280
- await this.documentStorage.delete(documentId);
281
- }
282
- catch (error) {
283
- return this.buildErrorResult(job, new Error(`Failed to delete document from legacy storage: ${error instanceof Error ? error.message : String(error)}`), startTime);
284
- }
285
- }
286
- // Mark the document as deleted in the state for read model indexing
287
- applyDeleteDocumentAction(document, action);
288
- // Compute resultingState for passing via context (not persisted)
289
- // DELETE_DOCUMENT only affects header and document scopes
290
- const resultingStateObj = {
291
- header: document.header,
292
- document: document.state.document,
293
- };
294
- const resultingState = JSON.stringify(resultingStateObj);
295
- const writeError = await this.writeOperationToStore(documentId, document.header.documentType, job.scope, job.branch, operation, job, startTime);
296
- if (writeError !== null) {
297
- return writeError;
298
- }
299
- indexTxn.write([
300
- {
301
- ...operation,
302
- documentId: documentId,
303
- documentType: document.header.documentType,
304
- branch: job.branch,
305
- scope: job.scope,
306
- },
307
- ]);
308
- this.documentMetaCache.putDocumentMeta(documentId, job.branch, {
309
- state: document.state.document,
310
- documentType: document.header.documentType,
311
- documentScopeRevision: operation.index + 1,
312
- });
313
- return this.buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);
314
- }
315
- /**
316
- * Execute an UPGRADE_DOCUMENT system action.
317
- * Handles initial upgrades (version 0 to N), same-version no-ops, and multi-step upgrade chains.
318
- * The operation index is determined from the document's current operation count.
319
- */
320
- async executeUpgradeDocumentAction(job, action, startTime, indexTxn, skip = 0) {
321
- const input = action.input;
322
- if (!input.documentId) {
323
- return this.buildErrorResult(job, new Error("UPGRADE_DOCUMENT action requires a documentId in input"), startTime);
324
- }
325
- const documentId = input.documentId;
326
- const fromVersion = input.fromVersion;
327
- const toVersion = input.toVersion;
328
- let document;
329
- try {
330
- document = await this.writeCache.getState(documentId, job.scope, job.branch);
331
- }
332
- catch (error) {
333
- return this.buildErrorResult(job, new Error(`Failed to fetch document for upgrade: ${error instanceof Error ? error.message : String(error)}`), startTime);
334
- }
335
- const documentState = document.state.document;
336
- if (documentState.isDeleted) {
337
- return this.buildErrorResult(job, new DocumentDeletedError(documentId, documentState.deletedAtUtcIso), startTime);
338
- }
339
- const nextIndex = getNextIndexForScope(document, job.scope);
340
- let upgradePath;
341
- if (fromVersion > 0 && fromVersion < toVersion) {
342
- try {
343
- upgradePath = this.registry.computeUpgradePath(document.header.documentType, fromVersion, toVersion);
344
- }
345
- catch (error) {
346
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
347
- }
348
- }
349
- if (fromVersion === toVersion && fromVersion > 0) {
350
- return {
351
- job,
352
- success: true,
353
- operations: [],
354
- operationsWithContext: [],
355
- duration: Date.now() - startTime,
356
- };
357
- }
358
- try {
359
- document = applyUpgradeDocumentAction(document, action, upgradePath);
360
- }
361
- catch (error) {
362
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
363
- }
364
- const operation = this.createOperation(action, nextIndex, skip, {
365
- documentId,
366
- scope: job.scope,
367
- branch: job.branch,
368
- });
369
- // Write the updated document to legacy storage
370
- if (this.config.legacyStorageEnabled) {
371
- try {
372
- await this.operationStorage.addDocumentOperations(documentId, [operation], document);
373
- }
374
- catch (error) {
375
- return this.buildErrorResult(job, new Error(`Failed to write UPGRADE_DOCUMENT operation to legacy storage: ${error instanceof Error ? error.message : String(error)}`), startTime);
376
- }
377
- }
378
- // Compute resultingState for passing via context (not persisted)
379
- const resultingStateObj = {
380
- header: document.header,
381
- ...document.state,
382
- };
383
- const resultingState = JSON.stringify(resultingStateObj);
384
- const writeError = await this.writeOperationToStore(documentId, document.header.documentType, job.scope, job.branch, operation, job, startTime);
385
- if (writeError !== null) {
386
- return writeError;
387
- }
388
- this.updateDocumentRevision(document, job.scope, operation.index);
389
- this.writeCacheState(documentId, job.scope, job.branch, operation.index, document);
390
- indexTxn.write([
391
- {
392
- ...operation,
393
- documentId: documentId,
394
- documentType: document.header.documentType,
395
- branch: job.branch,
396
- scope: job.scope,
397
- },
398
- ]);
399
- this.documentMetaCache.putDocumentMeta(documentId, job.branch, {
400
- state: document.state.document,
401
- documentType: document.header.documentType,
402
- documentScopeRevision: operation.index + 1,
403
- });
404
- return this.buildSuccessResult(job, operation, documentId, document.header.documentType, resultingState, startTime);
405
- }
406
- async executeAddRelationshipAction(job, action, startTime, indexTxn) {
407
- if (job.scope !== "document") {
408
- return this.buildErrorResult(job, new Error(`ADD_RELATIONSHIP must be in "document" scope, got "${job.scope}"`), startTime);
409
- }
410
- const input = action.input;
411
- if (!input.sourceId || !input.targetId || !input.relationshipType) {
412
- return this.buildErrorResult(job, new Error("ADD_RELATIONSHIP action requires sourceId, targetId, and relationshipType in input"), startTime);
413
- }
414
- if (input.sourceId === input.targetId) {
415
- return this.buildErrorResult(job, new Error("ADD_RELATIONSHIP: sourceId and targetId cannot be the same (self-relationships not allowed)"), startTime);
416
- }
417
- let sourceDoc;
418
- try {
419
- sourceDoc = await this.writeCache.getState(input.sourceId, "document", job.branch);
420
- }
421
- catch (error) {
422
- return this.buildErrorResult(job, new Error(`ADD_RELATIONSHIP: source document ${input.sourceId} not found: ${error instanceof Error ? error.message : String(error)}`), startTime);
423
- }
424
- const nextIndex = getNextIndexForScope(sourceDoc, job.scope);
425
- const operation = this.createOperation(action, nextIndex, 0, {
426
- documentId: input.sourceId,
427
- scope: job.scope,
428
- branch: job.branch,
429
- });
430
- const writeError = await this.writeOperationToStore(input.sourceId, sourceDoc.header.documentType, job.scope, job.branch, operation, job, startTime);
431
- if (writeError !== null) {
432
- return writeError;
433
- }
434
- sourceDoc.header.lastModifiedAtUtcIso =
435
- operation.timestampUtcMs || new Date().toISOString();
436
- this.updateDocumentRevision(sourceDoc, job.scope, operation.index);
437
- sourceDoc.operations = {
438
- ...sourceDoc.operations,
439
- [job.scope]: [...(sourceDoc.operations[job.scope] ?? []), operation],
440
- };
441
- const scopeState = sourceDoc.state[job.scope];
442
- const resultingStateObj = {
443
- header: structuredClone(sourceDoc.header),
444
- [job.scope]: scopeState === undefined ? {} : structuredClone(scopeState),
445
- };
446
- const resultingState = JSON.stringify(resultingStateObj);
447
- this.writeCacheState(input.sourceId, job.scope, job.branch, operation.index, sourceDoc);
448
- indexTxn.write([
449
- {
450
- ...operation,
451
- documentId: input.sourceId,
452
- documentType: sourceDoc.header.documentType,
453
- branch: job.branch,
454
- scope: job.scope,
455
- },
456
- ]);
457
- // collection membership has to be _after_ the write, as it requires the
458
- // ordinal of the operation to be set
459
- if (sourceDoc.header.documentType === "powerhouse/document-drive") {
460
- const collectionId = driveCollectionId(job.branch, input.sourceId);
461
- indexTxn.addToCollection(collectionId, input.targetId);
462
- }
463
- this.documentMetaCache.putDocumentMeta(input.sourceId, job.branch, {
464
- state: sourceDoc.state.document,
465
- documentType: sourceDoc.header.documentType,
466
- documentScopeRevision: operation.index + 1,
467
- });
468
- return this.buildSuccessResult(job, operation, input.sourceId, sourceDoc.header.documentType, resultingState, startTime);
469
- }
470
- async executeRemoveRelationshipAction(job, action, startTime, indexTxn) {
471
- if (job.scope !== "document") {
472
- return this.buildErrorResult(job, new Error(`REMOVE_RELATIONSHIP must be in "document" scope, got "${job.scope}"`), startTime);
473
- }
474
- const input = action.input;
475
- if (!input.sourceId || !input.targetId || !input.relationshipType) {
476
- return this.buildErrorResult(job, new Error("REMOVE_RELATIONSHIP action requires sourceId, targetId, and relationshipType in input"), startTime);
477
- }
478
- let sourceDoc;
479
- try {
480
- sourceDoc = await this.writeCache.getState(input.sourceId, "document", job.branch);
481
- }
482
- catch (error) {
483
- return this.buildErrorResult(job, new Error(`REMOVE_RELATIONSHIP: source document ${input.sourceId} not found: ${error instanceof Error ? error.message : String(error)}`), startTime);
484
- }
485
- const nextIndex = getNextIndexForScope(sourceDoc, job.scope);
486
- const operation = this.createOperation(action, nextIndex, 0, {
487
- documentId: input.sourceId,
488
- scope: job.scope,
489
- branch: job.branch,
490
- });
491
- const writeError = await this.writeOperationToStore(input.sourceId, sourceDoc.header.documentType, job.scope, job.branch, operation, job, startTime);
492
- if (writeError !== null) {
493
- return writeError;
494
- }
495
- sourceDoc.header.lastModifiedAtUtcIso =
496
- operation.timestampUtcMs || new Date().toISOString();
497
- this.updateDocumentRevision(sourceDoc, job.scope, operation.index);
498
- sourceDoc.operations = {
499
- ...sourceDoc.operations,
500
- [job.scope]: [...(sourceDoc.operations[job.scope] ?? []), operation],
501
- };
502
- const scopeState = sourceDoc.state[job.scope];
503
- const resultingStateObj = {
504
- header: structuredClone(sourceDoc.header),
505
- [job.scope]: scopeState === undefined ? {} : structuredClone(scopeState),
506
- };
507
- const resultingState = JSON.stringify(resultingStateObj);
508
- this.writeCacheState(input.sourceId, job.scope, job.branch, operation.index, sourceDoc);
509
- indexTxn.write([
510
- {
511
- ...operation,
512
- documentId: input.sourceId,
513
- documentType: sourceDoc.header.documentType,
514
- branch: job.branch,
515
- scope: job.scope,
516
- },
517
- ]);
518
- // collection membership has to be _after_ the write, as it requires the
519
- // ordinal of the operation to be set
520
- if (sourceDoc.header.documentType === "powerhouse/document-drive") {
521
- const collectionId = driveCollectionId(job.branch, input.sourceId);
522
- indexTxn.removeFromCollection(collectionId, input.targetId);
523
- }
524
- this.documentMetaCache.putDocumentMeta(input.sourceId, job.branch, {
525
- state: sourceDoc.state.document,
526
- documentType: sourceDoc.header.documentType,
527
- documentScopeRevision: operation.index + 1,
528
- });
529
- return this.buildSuccessResult(job, operation, input.sourceId, sourceDoc.header.documentType, resultingState, startTime);
530
- }
531
- /**
532
- * Execute a regular document action by applying it through the document model reducer.
533
- * If sourceOperation is provided (for load jobs), its id and timestamp are preserved.
534
- */
535
- async executeRegularAction(job, action, startTime, indexTxn, skip = 0, sourceOperation) {
536
- let docMeta;
537
- try {
538
- docMeta = await this.documentMetaCache.getDocumentMeta(job.documentId, job.branch);
539
- }
540
- catch (error) {
541
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
542
- }
543
- if (docMeta.state.isDeleted) {
544
- return this.buildErrorResult(job, new DocumentDeletedError(job.documentId, docMeta.state.deletedAtUtcIso), startTime);
545
- }
546
- let document;
547
- try {
548
- document = await this.writeCache.getState(job.documentId, job.scope, job.branch);
549
- }
550
- catch (error) {
551
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
552
- }
553
- let module;
554
- try {
555
- // Use document version to get the correct module
556
- // Version 0 means not yet upgraded - use latest version
557
- const moduleVersion = docMeta.state.version === 0 ? undefined : docMeta.state.version;
558
- module = this.registry.getModule(document.header.documentType, moduleVersion);
559
- }
560
- catch (error) {
561
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
562
- }
563
- let updatedDocument;
564
- try {
565
- const protocolVersion = document.header.protocolVersions?.["base-reducer"] ?? 1;
566
- const reducerOptions = sourceOperation
567
- ? {
568
- skip,
569
- branch: job.branch,
570
- replayOptions: { operation: sourceOperation },
571
- protocolVersion,
572
- }
573
- : { skip, branch: job.branch, protocolVersion };
574
- updatedDocument = module.reducer(document, action, undefined, reducerOptions);
575
- }
576
- catch (error) {
577
- const contextMessage = `Failed to apply action to document:\n Action type: ${action.type}\n Document ID: ${job.documentId}\n Document type: ${document.header.documentType}\n Scope: ${job.scope}\n Original error: ${error instanceof Error ? error.message : String(error)}`;
578
- const enhancedError = new Error(contextMessage);
579
- if (error instanceof Error && error.stack) {
580
- enhancedError.stack = `${contextMessage}\n\nOriginal stack trace:\n${error.stack}`;
581
- }
582
- return this.buildErrorResult(job, enhancedError, startTime);
583
- }
584
- const scope = job.scope;
585
- const operations = updatedDocument.operations[scope];
586
- if (operations.length === 0) {
587
- return this.buildErrorResult(job, new Error("No operation generated from action"), startTime);
588
- }
589
- const newOperation = operations[operations.length - 1];
590
- if (!isUndoRedo(action)) {
591
- newOperation.skip = skip;
592
- }
593
- if (this.config.legacyStorageEnabled) {
594
- try {
595
- await this.operationStorage.addDocumentOperations(job.documentId, [newOperation], updatedDocument);
596
- }
597
- catch (error) {
598
- return this.buildErrorResult(job, error instanceof Error ? error : new Error(String(error)), startTime);
599
- }
600
- }
601
- const resultingState = JSON.stringify({
602
- ...updatedDocument.state,
603
- header: updatedDocument.header,
604
- });
605
- const writeFailResult = await this.writeOperationToStore(job.documentId, document.header.documentType, scope, job.branch, newOperation, job, startTime);
606
- if (writeFailResult !== null) {
607
- return writeFailResult;
608
- }
609
- updatedDocument.header.revision = {
610
- ...updatedDocument.header.revision,
611
- [scope]: newOperation.index + 1,
612
- };
613
- this.writeCache.putState(job.documentId, scope, job.branch, newOperation.index, updatedDocument);
614
- indexTxn.write([
615
- {
616
- ...newOperation,
617
- documentId: job.documentId,
618
- documentType: document.header.documentType,
619
- branch: job.branch,
620
- scope,
621
- },
622
- ]);
623
- return {
624
- job,
625
- success: true,
626
- operations: [newOperation],
627
- operationsWithContext: [
628
- {
629
- operation: newOperation,
630
- context: {
631
- documentId: job.documentId,
632
- scope,
633
- branch: job.branch,
634
- documentType: document.header.documentType,
635
- resultingState,
636
- ordinal: 0,
637
- },
638
- },
639
- ],
640
- duration: Date.now() - startTime,
641
- };
642
- }
643
- createOperation(action, index, skip = 0, context) {
644
- const id = deriveOperationId(context.documentId, context.scope, context.branch, action.id);
645
- return {
646
- id,
647
- index: index,
648
- timestampUtcMs: action.timestampUtcMs || new Date().toISOString(),
649
- hash: "",
650
- skip: skip,
651
- action: action,
652
- };
653
- }
654
- async executeLoadJob(job, startTime, indexTxn) {
655
- if (job.operations.length === 0) {
656
- return this.buildErrorResult(job, new Error("Load job must include at least one operation"), startTime);
657
- }
658
- const scope = job.scope;
659
- let latestRevision = 0;
660
- try {
661
- const revisions = await this.operationStore.getRevisions(job.documentId, job.branch);
662
- latestRevision = revisions.revision[scope] ?? 0;
663
- }
664
- catch {
665
- latestRevision = 0;
666
- }
667
- let minIncomingIndex = Number.POSITIVE_INFINITY;
668
- let minIncomingTimestamp = job.operations[0]?.timestampUtcMs || "";
669
- for (const operation of job.operations) {
670
- minIncomingIndex = Math.min(minIncomingIndex, operation.index);
671
- const ts = operation.timestampUtcMs || "";
672
- if (ts < minIncomingTimestamp) {
673
- minIncomingTimestamp = ts;
674
- }
675
- }
676
- let conflictingOps = [];
677
- try {
678
- const conflictingResult = await this.operationStore.getConflicting(job.documentId, scope, job.branch, minIncomingTimestamp, { limit: this.config.maxSkipThreshold + 1 });
679
- if (conflictingResult.hasMore) {
680
- return {
681
- job,
682
- success: false,
683
- error: new Error(`Excessive reshuffle detected: more than ${this.config.maxSkipThreshold} conflicting operations found. ` +
684
- `This indicates a significant divergence between local and incoming operations.`),
685
- duration: Date.now() - startTime,
686
- };
687
- }
688
- conflictingOps = conflictingResult.items;
689
- }
690
- catch {
691
- conflictingOps = [];
692
- }
693
- // Filter out operations that have been superseded by later operations with skip values.
694
- // An operation at index N is superseded if there exists an operation at index M > N
695
- // where (M - skip_M) <= N, meaning the later operation's logical index covers N.
696
- const nonSupersededOps = conflictingOps.filter((op) => {
697
- for (const laterOp of conflictingOps) {
698
- if (laterOp.index > op.index && laterOp.skip > 0) {
699
- const logicalIndex = laterOp.index - laterOp.skip;
700
- if (logicalIndex <= op.index) {
701
- return false;
702
- }
703
- }
704
- }
705
- return true;
706
- });
707
- // All non-superseded conflicting operations need to be reshuffled
708
- const existingOpsToReshuffle = nonSupersededOps;
709
- // Skip count is the number of existing operations that need to be rewound
710
- const skipCount = existingOpsToReshuffle.length;
711
- if (skipCount > this.config.maxSkipThreshold) {
712
- return {
713
- job,
714
- success: false,
715
- error: new Error(`Excessive reshuffle detected: skip count of ${skipCount} exceeds threshold of ${this.config.maxSkipThreshold}. ` +
716
- `This indicates a significant divergence between local and incoming operations.`),
717
- duration: Date.now() - startTime,
718
- };
719
- }
720
- // Filter out incoming operations that are duplicates (action already exists locally
721
- // or appears multiple times in incoming)
722
- const existingActionIds = new Set(nonSupersededOps.map((op) => op.action.id));
723
- const seenIncomingActionIds = new Set();
724
- const incomingOpsToApply = job.operations.filter((op) => {
725
- if (existingActionIds.has(op.action.id))
726
- return false;
727
- if (seenIncomingActionIds.has(op.action.id))
728
- return false;
729
- seenIncomingActionIds.add(op.action.id);
730
- return true;
731
- });
732
- const reshuffledOperations = reshuffleByTimestamp({
733
- index: latestRevision,
734
- skip: skipCount,
735
- }, existingOpsToReshuffle, incomingOpsToApply.map((operation) => ({
736
- ...operation,
737
- id: operation.id,
738
- })));
739
- // For v2, all NOOPs have skip=1 - consecutive NOOPs are handled during state rebuild
740
- for (const operation of reshuffledOperations) {
741
- if (operation.action.type === "NOOP") {
742
- operation.skip = 1;
743
- }
744
- }
745
- const actions = reshuffledOperations.map((operation) => operation.action);
746
- const skipValues = reshuffledOperations.map((operation) => operation.skip);
747
- const result = await this.processActions(job, actions, startTime, indexTxn, skipValues, reshuffledOperations);
748
- if (!result.success) {
749
- return {
750
- job,
751
- success: false,
752
- error: result.error,
753
- duration: Date.now() - startTime,
754
- };
755
- }
756
- this.writeCache.invalidate(job.documentId, scope, job.branch);
757
- if (scope === "document") {
758
- this.documentMetaCache.invalidate(job.documentId, job.branch);
759
- }
760
- return {
761
- job,
762
- success: true,
763
- operations: result.generatedOperations,
764
- operationsWithContext: result.operationsWithContext,
765
- duration: Date.now() - startTime,
766
- };
767
- }
768
- async writeOperationToStore(documentId, documentType, scope, branch, operation, job, startTime) {
769
- try {
770
- await this.operationStore.apply(documentId, documentType, scope, branch, operation.index, (txn) => {
771
- txn.addOperations(operation);
772
- });
773
- return null;
774
- }
775
- catch (error) {
776
- this.logger.error("Error writing @Operation to IOperationStore: @Error", operation, error);
777
- this.writeCache.invalidate(documentId, scope, branch);
778
- return {
779
- job,
780
- success: false,
781
- error: new Error(`Failed to write operation to IOperationStore: ${error instanceof Error ? error.message : String(error)}`),
782
- duration: Date.now() - startTime,
783
- };
784
- }
785
- }
786
- updateDocumentRevision(document, scope, operationIndex) {
787
- document.header.revision = {
788
- ...document.header.revision,
789
- [scope]: operationIndex + 1,
790
- };
791
- }
792
- writeCacheState(documentId, scope, branch, operationIndex, document) {
793
- this.writeCache.putState(documentId, scope, branch, operationIndex, document);
794
- }
795
- buildSuccessResult(job, operation, documentId, documentType, resultingState, startTime) {
796
- return {
797
- job,
798
- success: true,
799
- operations: [operation],
800
- operationsWithContext: [
801
- {
802
- operation,
803
- context: {
804
- documentId: documentId,
805
- scope: job.scope,
806
- branch: job.branch,
807
- documentType: documentType,
808
- resultingState,
809
- ordinal: 0,
810
- },
811
- },
812
- ],
813
- duration: Date.now() - startTime,
814
- };
815
- }
816
- buildErrorResult(job, error, startTime) {
817
- return {
818
- job,
819
- success: false,
820
- error: error,
821
- duration: Date.now() - startTime,
822
- };
823
- }
824
- async verifyOperationSignatures(job, operations) {
825
- if (!this.signatureVerifier) {
826
- return;
827
- }
828
- for (let i = 0; i < operations.length; i++) {
829
- const operation = operations[i];
830
- const signer = operation.action.context?.signer;
831
- if (!signer) {
832
- continue;
833
- }
834
- if (signer.signatures.length === 0) {
835
- throw new InvalidSignatureError(job.documentId, `Operation ${operation.id} at index ${operation.index} has signer but no signatures`);
836
- }
837
- const publicKey = signer.app.key;
838
- let isValid = false;
839
- try {
840
- isValid = await this.signatureVerifier(operation, publicKey);
841
- }
842
- catch (error) {
843
- const errorMessage = error instanceof Error ? error.message : String(error);
844
- throw new InvalidSignatureError(job.documentId, `Operation ${operation.id} at index ${operation.index} verification failed: ${errorMessage}`);
845
- }
846
- if (!isValid) {
847
- throw new InvalidSignatureError(job.documentId, `Operation ${operation.id} at index ${operation.index} signature verification returned false`);
848
- }
849
- }
850
- }
851
- async verifyActionSignatures(job, actions) {
852
- if (!this.signatureVerifier) {
853
- return;
854
- }
855
- for (const action of actions) {
856
- const signer = action.context?.signer;
857
- if (!signer) {
858
- continue;
859
- }
860
- if (signer.signatures.length === 0) {
861
- throw new InvalidSignatureError(job.documentId, `Action ${action.id} has signer but no signatures`);
862
- }
863
- const publicKey = signer.app.key;
864
- let isValid = false;
865
- try {
866
- const tempOperation = {
867
- id: deriveOperationId(job.documentId, action.scope, job.branch, action.id),
868
- index: 0,
869
- timestampUtcMs: action.timestampUtcMs || new Date().toISOString(),
870
- hash: "",
871
- skip: 0,
872
- action: action,
873
- };
874
- isValid = await this.signatureVerifier(tempOperation, publicKey);
875
- }
876
- catch (error) {
877
- const errorMessage = error instanceof Error ? error.message : String(error);
878
- throw new InvalidSignatureError(job.documentId, `Action ${action.id} verification failed: ${errorMessage}`);
879
- }
880
- if (!isValid) {
881
- throw new InvalidSignatureError(job.documentId, `Action ${action.id} signature verification returned false`);
882
- }
883
- }
884
- }
885
- accumulateResultOrReturnError(result, generatedOperations, operationsWithContext) {
886
- if (!result.success) {
887
- return result;
888
- }
889
- if (result.operations && result.operations.length > 0) {
890
- generatedOperations.push(...result.operations);
891
- }
892
- if (result.operationsWithContext) {
893
- operationsWithContext.push(...result.operationsWithContext);
894
- }
895
- return null;
896
- }
897
- }
898
- //# sourceMappingURL=simple-job-executor.js.map