hikoutei 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (535) hide show
  1. package/LICENSE +21 -0
  2. package/README.ja.md +135 -0
  3. package/README.ko.md +138 -0
  4. package/README.md +143 -0
  5. package/apps-script/gateway/Code.gs +412 -0
  6. package/dist/adapter/persistence/contracts/index.d.ts +3 -0
  7. package/dist/adapter/persistence/contracts/index.d.ts.map +1 -0
  8. package/dist/adapter/persistence/contracts/index.js +3 -0
  9. package/dist/adapter/persistence/contracts/index.js.map +1 -0
  10. package/dist/adapter/persistence/contracts/sql.d.ts +50 -0
  11. package/dist/adapter/persistence/contracts/sql.d.ts.map +1 -0
  12. package/dist/adapter/persistence/contracts/sql.js +9 -0
  13. package/dist/adapter/persistence/contracts/sql.js.map +1 -0
  14. package/dist/adapter/persistence/index.d.ts +2 -0
  15. package/dist/adapter/persistence/index.d.ts.map +1 -0
  16. package/dist/adapter/persistence/index.js +2 -0
  17. package/dist/adapter/persistence/index.js.map +1 -0
  18. package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.d.ts +53 -0
  19. package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.d.ts.map +1 -0
  20. package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.js +105 -0
  21. package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.js.map +1 -0
  22. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts +39 -0
  23. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts.map +1 -0
  24. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js +54 -0
  25. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js.map +1 -0
  26. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.d.ts +38 -0
  27. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.d.ts.map +1 -0
  28. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.js +55 -0
  29. package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.js.map +1 -0
  30. package/dist/adapter/persistence/providers/mikro-orm/index.d.ts +16 -0
  31. package/dist/adapter/persistence/providers/mikro-orm/index.d.ts.map +1 -0
  32. package/dist/adapter/persistence/providers/mikro-orm/index.js +9 -0
  33. package/dist/adapter/persistence/providers/mikro-orm/index.js.map +1 -0
  34. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts +27 -0
  35. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts.map +1 -0
  36. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js +67 -0
  37. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js.map +1 -0
  38. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.d.ts +19 -0
  39. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.d.ts.map +1 -0
  40. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.js +67 -0
  41. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.js.map +1 -0
  42. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.d.ts +78 -0
  43. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.d.ts.map +1 -0
  44. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.js +121 -0
  45. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.js.map +1 -0
  46. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.d.ts +20 -0
  47. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.d.ts.map +1 -0
  48. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.js +125 -0
  49. package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.js.map +1 -0
  50. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +42 -0
  51. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +1 -0
  52. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +51 -0
  53. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +1 -0
  54. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +22 -0
  55. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -0
  56. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +12 -0
  57. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -0
  58. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +42 -0
  59. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +1 -0
  60. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +161 -0
  61. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +1 -0
  62. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts +3 -0
  63. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +1 -0
  64. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +692 -0
  65. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +1 -0
  66. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts +29 -0
  67. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts.map +1 -0
  68. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +538 -0
  69. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +1 -0
  70. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts +12 -0
  71. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts.map +1 -0
  72. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js +190 -0
  73. package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js.map +1 -0
  74. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +23 -0
  75. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +1 -0
  76. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +166 -0
  77. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +1 -0
  78. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts +50 -0
  79. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts.map +1 -0
  80. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js +60 -0
  81. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js.map +1 -0
  82. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts +44 -0
  83. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts.map +1 -0
  84. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js +40 -0
  85. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js.map +1 -0
  86. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts +7 -0
  87. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts.map +1 -0
  88. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js +47 -0
  89. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js.map +1 -0
  90. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts +5 -0
  91. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts.map +1 -0
  92. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js +54 -0
  93. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js.map +1 -0
  94. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts +5 -0
  95. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts.map +1 -0
  96. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js +2 -0
  97. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js.map +1 -0
  98. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts +10 -0
  99. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts.map +1 -0
  100. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js +35 -0
  101. package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js.map +1 -0
  102. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts +67 -0
  103. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +1 -0
  104. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +204 -0
  105. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +1 -0
  106. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +78 -0
  107. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -0
  108. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +343 -0
  109. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -0
  110. package/dist/application/index.d.ts +4 -0
  111. package/dist/application/index.d.ts.map +1 -0
  112. package/dist/application/index.js +4 -0
  113. package/dist/application/index.js.map +1 -0
  114. package/dist/application/orm/api/TypedSheetsOrm.d.ts +71 -0
  115. package/dist/application/orm/api/TypedSheetsOrm.d.ts.map +1 -0
  116. package/dist/application/orm/api/TypedSheetsOrm.js +116 -0
  117. package/dist/application/orm/api/TypedSheetsOrm.js.map +1 -0
  118. package/dist/application/orm/api/contracts.d.ts +118 -0
  119. package/dist/application/orm/api/contracts.d.ts.map +1 -0
  120. package/dist/application/orm/api/contracts.js +21 -0
  121. package/dist/application/orm/api/contracts.js.map +1 -0
  122. package/dist/application/orm/errors.d.ts +35 -0
  123. package/dist/application/orm/errors.d.ts.map +1 -0
  124. package/dist/application/orm/errors.js +35 -0
  125. package/dist/application/orm/errors.js.map +1 -0
  126. package/dist/application/orm/index.d.ts +13 -0
  127. package/dist/application/orm/index.d.ts.map +1 -0
  128. package/dist/application/orm/index.js +7 -0
  129. package/dist/application/orm/index.js.map +1 -0
  130. package/dist/application/orm/mapping/contracts.d.ts +113 -0
  131. package/dist/application/orm/mapping/contracts.d.ts.map +1 -0
  132. package/dist/application/orm/mapping/contracts.js +8 -0
  133. package/dist/application/orm/mapping/contracts.js.map +1 -0
  134. package/dist/application/orm/mapping/definition.d.ts +16 -0
  135. package/dist/application/orm/mapping/definition.d.ts.map +1 -0
  136. package/dist/application/orm/mapping/definition.js +145 -0
  137. package/dist/application/orm/mapping/definition.js.map +1 -0
  138. package/dist/application/orm/mapping/entityMapping.d.ts +13 -0
  139. package/dist/application/orm/mapping/entityMapping.d.ts.map +1 -0
  140. package/dist/application/orm/mapping/entityMapping.js +13 -0
  141. package/dist/application/orm/mapping/entityMapping.js.map +1 -0
  142. package/dist/application/orm/mapping/identity.d.ts +14 -0
  143. package/dist/application/orm/mapping/identity.d.ts.map +1 -0
  144. package/dist/application/orm/mapping/identity.js +37 -0
  145. package/dist/application/orm/mapping/identity.js.map +1 -0
  146. package/dist/application/orm/mapping/observationMapping.d.ts +42 -0
  147. package/dist/application/orm/mapping/observationMapping.d.ts.map +1 -0
  148. package/dist/application/orm/mapping/observationMapping.js +65 -0
  149. package/dist/application/orm/mapping/observationMapping.js.map +1 -0
  150. package/dist/application/orm/mapping/projection.d.ts +22 -0
  151. package/dist/application/orm/mapping/projection.d.ts.map +1 -0
  152. package/dist/application/orm/mapping/projection.js +74 -0
  153. package/dist/application/orm/mapping/projection.js.map +1 -0
  154. package/dist/application/orm/mapping/registry.d.ts +15 -0
  155. package/dist/application/orm/mapping/registry.d.ts.map +1 -0
  156. package/dist/application/orm/mapping/registry.js +38 -0
  157. package/dist/application/orm/mapping/registry.js.map +1 -0
  158. package/dist/application/orm/mapping/values.d.ts +17 -0
  159. package/dist/application/orm/mapping/values.d.ts.map +1 -0
  160. package/dist/application/orm/mapping/values.js +141 -0
  161. package/dist/application/orm/mapping/values.js.map +1 -0
  162. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts +28 -0
  163. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -0
  164. package/dist/application/orm/persistence/flush/flushCoordinator.js +170 -0
  165. package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -0
  166. package/dist/application/orm/persistence/flush/mappedFlushCoordinator.d.ts +9 -0
  167. package/dist/application/orm/persistence/flush/mappedFlushCoordinator.d.ts.map +1 -0
  168. package/dist/application/orm/persistence/flush/mappedFlushCoordinator.js +8 -0
  169. package/dist/application/orm/persistence/flush/mappedFlushCoordinator.js.map +1 -0
  170. package/dist/application/orm/persistence/lifecycle/entityLifecycle.d.ts +12 -0
  171. package/dist/application/orm/persistence/lifecycle/entityLifecycle.d.ts.map +1 -0
  172. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js +134 -0
  173. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js.map +1 -0
  174. package/dist/application/orm/persistence/projection/projectionEffects.d.ts +21 -0
  175. package/dist/application/orm/persistence/projection/projectionEffects.d.ts.map +1 -0
  176. package/dist/application/orm/persistence/projection/projectionEffects.js +203 -0
  177. package/dist/application/orm/persistence/projection/projectionEffects.js.map +1 -0
  178. package/dist/application/orm/persistence/support/businessKeys.d.ts +17 -0
  179. package/dist/application/orm/persistence/support/businessKeys.d.ts.map +1 -0
  180. package/dist/application/orm/persistence/support/businessKeys.js +72 -0
  181. package/dist/application/orm/persistence/support/businessKeys.js.map +1 -0
  182. package/dist/application/orm/persistence/support/canonicalState.d.ts +22 -0
  183. package/dist/application/orm/persistence/support/canonicalState.d.ts.map +1 -0
  184. package/dist/application/orm/persistence/support/canonicalState.js +88 -0
  185. package/dist/application/orm/persistence/support/canonicalState.js.map +1 -0
  186. package/dist/application/orm/persistence/support/contracts.d.ts +139 -0
  187. package/dist/application/orm/persistence/support/contracts.d.ts.map +1 -0
  188. package/dist/application/orm/persistence/support/contracts.js +93 -0
  189. package/dist/application/orm/persistence/support/contracts.js.map +1 -0
  190. package/dist/application/orm/persistence/support/helpers.d.ts +32 -0
  191. package/dist/application/orm/persistence/support/helpers.d.ts.map +1 -0
  192. package/dist/application/orm/persistence/support/helpers.js +66 -0
  193. package/dist/application/orm/persistence/support/helpers.js.map +1 -0
  194. package/dist/application/orm/persistence/support/timing.d.ts +20 -0
  195. package/dist/application/orm/persistence/support/timing.d.ts.map +1 -0
  196. package/dist/application/orm/persistence/support/timing.js +55 -0
  197. package/dist/application/orm/persistence/support/timing.js.map +1 -0
  198. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts +46 -0
  199. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +1 -0
  200. package/dist/application/sync/gateway/SyncGatewayBootstrap.js +93 -0
  201. package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +1 -0
  202. package/dist/application/sync/gateway/constants.d.ts +65 -0
  203. package/dist/application/sync/gateway/constants.d.ts.map +1 -0
  204. package/dist/application/sync/gateway/constants.js +57 -0
  205. package/dist/application/sync/gateway/constants.js.map +1 -0
  206. package/dist/application/sync/gateway/errors.d.ts +15 -0
  207. package/dist/application/sync/gateway/errors.d.ts.map +1 -0
  208. package/dist/application/sync/gateway/errors.js +16 -0
  209. package/dist/application/sync/gateway/errors.js.map +1 -0
  210. package/dist/application/sync/gateway/syncGateway.d.ts +313 -0
  211. package/dist/application/sync/gateway/syncGateway.d.ts.map +1 -0
  212. package/dist/application/sync/gateway/syncGateway.js +202 -0
  213. package/dist/application/sync/gateway/syncGateway.js.map +1 -0
  214. package/dist/application/sync/gateway/validation.d.ts +17 -0
  215. package/dist/application/sync/gateway/validation.d.ts.map +1 -0
  216. package/dist/application/sync/gateway/validation.js +60 -0
  217. package/dist/application/sync/gateway/validation.js.map +1 -0
  218. package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts +72 -0
  219. package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts.map +1 -0
  220. package/dist/application/sync/inbound/polling/SimpleSheetPolling.js +272 -0
  221. package/dist/application/sync/inbound/polling/SimpleSheetPolling.js.map +1 -0
  222. package/dist/application/sync/index.d.ts +16 -0
  223. package/dist/application/sync/index.d.ts.map +1 -0
  224. package/dist/application/sync/index.js +9 -0
  225. package/dist/application/sync/index.js.map +1 -0
  226. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +106 -0
  227. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -0
  228. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +297 -0
  229. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -0
  230. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +100 -0
  231. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -0
  232. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +345 -0
  233. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -0
  234. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +46 -0
  235. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -0
  236. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +63 -0
  237. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -0
  238. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +20 -0
  239. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -0
  240. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +102 -0
  241. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -0
  242. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.d.ts +19 -0
  243. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.d.ts.map +1 -0
  244. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js +32 -0
  245. package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js.map +1 -0
  246. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +30 -0
  247. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -0
  248. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +202 -0
  249. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -0
  250. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts +17 -0
  251. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts.map +1 -0
  252. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js +80 -0
  253. package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js.map +1 -0
  254. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts +13 -0
  255. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -0
  256. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +205 -0
  257. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -0
  258. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts +81 -0
  259. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts.map +1 -0
  260. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js +245 -0
  261. package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js.map +1 -0
  262. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts +77 -0
  263. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -0
  264. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +518 -0
  265. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -0
  266. package/dist/application/sync/telemetry/syncTiming.d.ts +50 -0
  267. package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -0
  268. package/dist/application/sync/telemetry/syncTiming.js +22 -0
  269. package/dist/application/sync/telemetry/syncTiming.js.map +1 -0
  270. package/dist/domain/conflict/errors.d.ts +42 -0
  271. package/dist/domain/conflict/errors.d.ts.map +1 -0
  272. package/dist/domain/conflict/errors.js +36 -0
  273. package/dist/domain/conflict/errors.js.map +1 -0
  274. package/dist/domain/conflict/index.d.ts +5 -0
  275. package/dist/domain/conflict/index.d.ts.map +1 -0
  276. package/dist/domain/conflict/index.js +3 -0
  277. package/dist/domain/conflict/index.js.map +1 -0
  278. package/dist/domain/conflict/transitions.d.ts +52 -0
  279. package/dist/domain/conflict/transitions.d.ts.map +1 -0
  280. package/dist/domain/conflict/transitions.js +115 -0
  281. package/dist/domain/conflict/transitions.js.map +1 -0
  282. package/dist/domain/errors/evaluation.d.ts +13 -0
  283. package/dist/domain/errors/evaluation.d.ts.map +1 -0
  284. package/dist/domain/errors/evaluation.js +14 -0
  285. package/dist/domain/errors/evaluation.js.map +1 -0
  286. package/dist/domain/errors/identity.d.ts +12 -0
  287. package/dist/domain/errors/identity.d.ts.map +1 -0
  288. package/dist/domain/errors/identity.js +15 -0
  289. package/dist/domain/errors/identity.js.map +1 -0
  290. package/dist/domain/errors/index.d.ts +7 -0
  291. package/dist/domain/errors/index.d.ts.map +1 -0
  292. package/dist/domain/errors/index.js +5 -0
  293. package/dist/domain/errors/index.js.map +1 -0
  294. package/dist/domain/errors/stableEncoding.d.ts +7 -0
  295. package/dist/domain/errors/stableEncoding.d.ts.map +1 -0
  296. package/dist/domain/errors/stableEncoding.js +8 -0
  297. package/dist/domain/errors/stableEncoding.js.map +1 -0
  298. package/dist/domain/errors/types.d.ts +20 -0
  299. package/dist/domain/errors/types.d.ts.map +1 -0
  300. package/dist/domain/errors/types.js +18 -0
  301. package/dist/domain/errors/types.js.map +1 -0
  302. package/dist/domain/evaluate/constants.d.ts +55 -0
  303. package/dist/domain/evaluate/constants.d.ts.map +1 -0
  304. package/dist/domain/evaluate/constants.js +41 -0
  305. package/dist/domain/evaluate/constants.js.map +1 -0
  306. package/dist/domain/evaluate/contracts.d.ts +125 -0
  307. package/dist/domain/evaluate/contracts.d.ts.map +1 -0
  308. package/dist/domain/evaluate/contracts.js +8 -0
  309. package/dist/domain/evaluate/contracts.js.map +1 -0
  310. package/dist/domain/evaluate/evaluateBatch.d.ts +11 -0
  311. package/dist/domain/evaluate/evaluateBatch.d.ts.map +1 -0
  312. package/dist/domain/evaluate/evaluateBatch.js +91 -0
  313. package/dist/domain/evaluate/evaluateBatch.js.map +1 -0
  314. package/dist/domain/evaluate/fieldEvaluation.d.ts +14 -0
  315. package/dist/domain/evaluate/fieldEvaluation.d.ts.map +1 -0
  316. package/dist/domain/evaluate/fieldEvaluation.js +133 -0
  317. package/dist/domain/evaluate/fieldEvaluation.js.map +1 -0
  318. package/dist/domain/evaluate/identity.d.ts +21 -0
  319. package/dist/domain/evaluate/identity.d.ts.map +1 -0
  320. package/dist/domain/evaluate/identity.js +72 -0
  321. package/dist/domain/evaluate/identity.js.map +1 -0
  322. package/dist/domain/evaluate/index.d.ts +4 -0
  323. package/dist/domain/evaluate/index.d.ts.map +1 -0
  324. package/dist/domain/evaluate/index.js +3 -0
  325. package/dist/domain/evaluate/index.js.map +1 -0
  326. package/dist/domain/evaluate/preconditions.d.ts +30 -0
  327. package/dist/domain/evaluate/preconditions.d.ts.map +1 -0
  328. package/dist/domain/evaluate/preconditions.js +389 -0
  329. package/dist/domain/evaluate/preconditions.js.map +1 -0
  330. package/dist/domain/evaluate/quarantine.d.ts +15 -0
  331. package/dist/domain/evaluate/quarantine.d.ts.map +1 -0
  332. package/dist/domain/evaluate/quarantine.js +185 -0
  333. package/dist/domain/evaluate/quarantine.js.map +1 -0
  334. package/dist/domain/index.d.ts +7 -0
  335. package/dist/domain/index.d.ts.map +1 -0
  336. package/dist/domain/index.js +7 -0
  337. package/dist/domain/index.js.map +1 -0
  338. package/dist/domain/model/constants.d.ts +73 -0
  339. package/dist/domain/model/constants.d.ts.map +1 -0
  340. package/dist/domain/model/constants.js +59 -0
  341. package/dist/domain/model/constants.js.map +1 -0
  342. package/dist/domain/model/index.d.ts +3 -0
  343. package/dist/domain/model/index.d.ts.map +1 -0
  344. package/dist/domain/model/index.js +2 -0
  345. package/dist/domain/model/index.js.map +1 -0
  346. package/dist/domain/model/types.d.ts +330 -0
  347. package/dist/domain/model/types.d.ts.map +1 -0
  348. package/dist/domain/model/types.js +8 -0
  349. package/dist/domain/model/types.js.map +1 -0
  350. package/dist/index.d.ts +17 -0
  351. package/dist/index.d.ts.map +1 -0
  352. package/dist/index.js +11 -0
  353. package/dist/index.js.map +1 -0
  354. package/dist/infrastructure/index.d.ts +3 -0
  355. package/dist/infrastructure/index.d.ts.map +1 -0
  356. package/dist/infrastructure/index.js +3 -0
  357. package/dist/infrastructure/index.js.map +1 -0
  358. package/dist/infrastructure/storage/constants.d.ts +4 -0
  359. package/dist/infrastructure/storage/constants.d.ts.map +1 -0
  360. package/dist/infrastructure/storage/constants.js +4 -0
  361. package/dist/infrastructure/storage/constants.js.map +1 -0
  362. package/dist/infrastructure/storage/errors.d.ts +55 -0
  363. package/dist/infrastructure/storage/errors.d.ts.map +1 -0
  364. package/dist/infrastructure/storage/errors.js +58 -0
  365. package/dist/infrastructure/storage/errors.js.map +1 -0
  366. package/dist/infrastructure/storage/index.d.ts +23 -0
  367. package/dist/infrastructure/storage/index.d.ts.map +1 -0
  368. package/dist/infrastructure/storage/index.js +13 -0
  369. package/dist/infrastructure/storage/index.js.map +1 -0
  370. package/dist/infrastructure/storage/recovery/restoreRecovery.d.ts +64 -0
  371. package/dist/infrastructure/storage/recovery/restoreRecovery.d.ts.map +1 -0
  372. package/dist/infrastructure/storage/recovery/restoreRecovery.js +148 -0
  373. package/dist/infrastructure/storage/recovery/restoreRecovery.js.map +1 -0
  374. package/dist/infrastructure/storage/sqlite/schema.d.ts +49 -0
  375. package/dist/infrastructure/storage/sqlite/schema.d.ts.map +1 -0
  376. package/dist/infrastructure/storage/sqlite/schema.js +529 -0
  377. package/dist/infrastructure/storage/sqlite/schema.js.map +1 -0
  378. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts +5 -0
  379. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts.map +1 -0
  380. package/dist/infrastructure/storage/sqlite/schemaTypes.js +2 -0
  381. package/dist/infrastructure/storage/sqlite/schemaTypes.js.map +1 -0
  382. package/dist/infrastructure/storage/sqlite/sqlScript.d.ts +9 -0
  383. package/dist/infrastructure/storage/sqlite/sqlScript.d.ts.map +1 -0
  384. package/dist/infrastructure/storage/sqlite/sqlScript.js +122 -0
  385. package/dist/infrastructure/storage/sqlite/sqlScript.js.map +1 -0
  386. package/dist/infrastructure/storage/sqlite/sqlState.d.ts +6 -0
  387. package/dist/infrastructure/storage/sqlite/sqlState.d.ts.map +1 -0
  388. package/dist/infrastructure/storage/sqlite/sqlState.js +14 -0
  389. package/dist/infrastructure/storage/sqlite/sqlState.js.map +1 -0
  390. package/dist/infrastructure/storage/sqlite/sqlTransaction.d.ts +6 -0
  391. package/dist/infrastructure/storage/sqlite/sqlTransaction.d.ts.map +1 -0
  392. package/dist/infrastructure/storage/sqlite/sqlTransaction.js +24 -0
  393. package/dist/infrastructure/storage/sqlite/sqlTransaction.js.map +1 -0
  394. package/dist/infrastructure/storage/sqlite/sqliteBridge.d.ts +44 -0
  395. package/dist/infrastructure/storage/sqlite/sqliteBridge.d.ts.map +1 -0
  396. package/dist/infrastructure/storage/sqlite/sqliteBridge.js +66 -0
  397. package/dist/infrastructure/storage/sqlite/sqliteBridge.js.map +1 -0
  398. package/dist/infrastructure/storage/state/canonical/canonicalCommit.d.ts +101 -0
  399. package/dist/infrastructure/storage/state/canonical/canonicalCommit.d.ts.map +1 -0
  400. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js +417 -0
  401. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js.map +1 -0
  402. package/dist/infrastructure/storage/state/observation/observationAudit.d.ts +16 -0
  403. package/dist/infrastructure/storage/state/observation/observationAudit.d.ts.map +1 -0
  404. package/dist/infrastructure/storage/state/observation/observationAudit.js +85 -0
  405. package/dist/infrastructure/storage/state/observation/observationAudit.js.map +1 -0
  406. package/dist/infrastructure/storage/state/observation/observationCanonical.d.ts +31 -0
  407. package/dist/infrastructure/storage/state/observation/observationCanonical.d.ts.map +1 -0
  408. package/dist/infrastructure/storage/state/observation/observationCanonical.js +439 -0
  409. package/dist/infrastructure/storage/state/observation/observationCanonical.js.map +1 -0
  410. package/dist/infrastructure/storage/state/observation/observationConstants.d.ts +53 -0
  411. package/dist/infrastructure/storage/state/observation/observationConstants.d.ts.map +1 -0
  412. package/dist/infrastructure/storage/state/observation/observationConstants.js +41 -0
  413. package/dist/infrastructure/storage/state/observation/observationConstants.js.map +1 -0
  414. package/dist/infrastructure/storage/state/observation/observationLedger.d.ts +49 -0
  415. package/dist/infrastructure/storage/state/observation/observationLedger.d.ts.map +1 -0
  416. package/dist/infrastructure/storage/state/observation/observationLedger.js +537 -0
  417. package/dist/infrastructure/storage/state/observation/observationLedger.js.map +1 -0
  418. package/dist/infrastructure/storage/state/observation/observationQuarantine.d.ts +15 -0
  419. package/dist/infrastructure/storage/state/observation/observationQuarantine.d.ts.map +1 -0
  420. package/dist/infrastructure/storage/state/observation/observationQuarantine.js +100 -0
  421. package/dist/infrastructure/storage/state/observation/observationQuarantine.js.map +1 -0
  422. package/dist/infrastructure/storage/state/observation/observationTypes.d.ts +124 -0
  423. package/dist/infrastructure/storage/state/observation/observationTypes.d.ts.map +1 -0
  424. package/dist/infrastructure/storage/state/observation/observationTypes.js +13 -0
  425. package/dist/infrastructure/storage/state/observation/observationTypes.js.map +1 -0
  426. package/dist/infrastructure/storage/state/observation/observationValidation.d.ts +28 -0
  427. package/dist/infrastructure/storage/state/observation/observationValidation.d.ts.map +1 -0
  428. package/dist/infrastructure/storage/state/observation/observationValidation.js +223 -0
  429. package/dist/infrastructure/storage/state/observation/observationValidation.js.map +1 -0
  430. package/dist/infrastructure/storage/state/observation/observationWriter.d.ts +28 -0
  431. package/dist/infrastructure/storage/state/observation/observationWriter.d.ts.map +1 -0
  432. package/dist/infrastructure/storage/state/observation/observationWriter.js +293 -0
  433. package/dist/infrastructure/storage/state/observation/observationWriter.js.map +1 -0
  434. package/dist/infrastructure/storage/state/readonly/readOnlyObservation.d.ts +58 -0
  435. package/dist/infrastructure/storage/state/readonly/readOnlyObservation.d.ts.map +1 -0
  436. package/dist/infrastructure/storage/state/readonly/readOnlyObservation.js +195 -0
  437. package/dist/infrastructure/storage/state/readonly/readOnlyObservation.js.map +1 -0
  438. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts +31 -0
  439. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts.map +1 -0
  440. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js +563 -0
  441. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js.map +1 -0
  442. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts +118 -0
  443. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts.map +1 -0
  444. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js +18 -0
  445. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js.map +1 -0
  446. package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.d.ts +23 -0
  447. package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.d.ts.map +1 -0
  448. package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.js +84 -0
  449. package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.js.map +1 -0
  450. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts +16 -0
  451. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts.map +1 -0
  452. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js +97 -0
  453. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js.map +1 -0
  454. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +137 -0
  455. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -0
  456. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +396 -0
  457. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -0
  458. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +101 -0
  459. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -0
  460. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +9 -0
  461. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -0
  462. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +21 -0
  463. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -0
  464. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +184 -0
  465. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -0
  466. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts +25 -0
  467. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts.map +1 -0
  468. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js +158 -0
  469. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js.map +1 -0
  470. package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts +69 -0
  471. package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts.map +1 -0
  472. package/dist/infrastructure/storage/sync/shared/syncRegistry.js +272 -0
  473. package/dist/infrastructure/storage/sync/shared/syncRegistry.js.map +1 -0
  474. package/dist/infrastructure/storage/sync/shared/writerLease.d.ts +90 -0
  475. package/dist/infrastructure/storage/sync/shared/writerLease.d.ts.map +1 -0
  476. package/dist/infrastructure/storage/sync/shared/writerLease.js +282 -0
  477. package/dist/infrastructure/storage/sync/shared/writerLease.js.map +1 -0
  478. package/dist/shared/constants.d.ts +8 -0
  479. package/dist/shared/constants.d.ts.map +1 -0
  480. package/dist/shared/constants.js +8 -0
  481. package/dist/shared/constants.js.map +1 -0
  482. package/dist/shared/encoding/constants.d.ts +45 -0
  483. package/dist/shared/encoding/constants.d.ts.map +1 -0
  484. package/dist/shared/encoding/constants.js +37 -0
  485. package/dist/shared/encoding/constants.js.map +1 -0
  486. package/dist/shared/encoding/index.d.ts +6 -0
  487. package/dist/shared/encoding/index.d.ts.map +1 -0
  488. package/dist/shared/encoding/index.js +4 -0
  489. package/dist/shared/encoding/index.js.map +1 -0
  490. package/dist/shared/encoding/stableEncode.d.ts +34 -0
  491. package/dist/shared/encoding/stableEncode.d.ts.map +1 -0
  492. package/dist/shared/encoding/stableEncode.js +210 -0
  493. package/dist/shared/encoding/stableEncode.js.map +1 -0
  494. package/dist/shared/encoding/typeGuards.d.ts +15 -0
  495. package/dist/shared/encoding/typeGuards.d.ts.map +1 -0
  496. package/dist/shared/encoding/typeGuards.js +11 -0
  497. package/dist/shared/encoding/typeGuards.js.map +1 -0
  498. package/dist/shared/encoding/types.d.ts +52 -0
  499. package/dist/shared/encoding/types.d.ts.map +1 -0
  500. package/dist/shared/encoding/types.js +8 -0
  501. package/dist/shared/encoding/types.js.map +1 -0
  502. package/dist/shared/index.d.ts +6 -0
  503. package/dist/shared/index.d.ts.map +1 -0
  504. package/dist/shared/index.js +6 -0
  505. package/dist/shared/index.js.map +1 -0
  506. package/dist/shared/state/constants.d.ts +16 -0
  507. package/dist/shared/state/constants.d.ts.map +1 -0
  508. package/dist/shared/state/constants.js +16 -0
  509. package/dist/shared/state/constants.js.map +1 -0
  510. package/dist/shared/state/index.d.ts +3 -0
  511. package/dist/shared/state/index.d.ts.map +1 -0
  512. package/dist/shared/state/index.js +2 -0
  513. package/dist/shared/state/index.js.map +1 -0
  514. package/dist/shared/state/types.d.ts +23 -0
  515. package/dist/shared/state/types.d.ts.map +1 -0
  516. package/dist/shared/state/types.js +2 -0
  517. package/dist/shared/state/types.js.map +1 -0
  518. package/dist/shared/validation.d.ts +9 -0
  519. package/dist/shared/validation.d.ts.map +1 -0
  520. package/dist/shared/validation.js +25 -0
  521. package/dist/shared/validation.js.map +1 -0
  522. package/docs/architecture.md +72 -0
  523. package/docs/code-guidelines.md +256 -0
  524. package/docs/development.md +48 -0
  525. package/docs/git-workflow.md +224 -0
  526. package/docs/mikro-orm-adapter-spike.md +248 -0
  527. package/docs/quick-start.md +102 -0
  528. package/docs/sql-layer-plan.md +59 -0
  529. package/docs/sync-bulk-write-benchmark.md +1036 -0
  530. package/docs/sync-observability.md +71 -0
  531. package/docs/task-queue-write-model.md +640 -0
  532. package/docs/typed-sheets-mvp-scope-2026-06-29.md +490 -0
  533. package/docs/typed-sheets-plan.md +417 -0
  534. package/docs/write-and-synchronization-flow.md +71 -0
  535. package/package.json +68 -0
@@ -0,0 +1,272 @@
1
+ /**
2
+ * SQLite registry/allowlist operations for the sync gateway.
3
+ *
4
+ * The local registry is the source of truth used to choose a gateway range.
5
+ * A caller cannot turn an arbitrary tab name into a sync target by merely
6
+ * passing it to the gateway client.
7
+ */
8
+ import { withImmediateTransaction } from "../../sqlite/sqliteBridge.js";
9
+ import { STORAGE_ERROR_CODES, StorageError } from "../../errors.js";
10
+ import { withSqlSavepoint } from "../../sqlite/sqlTransaction.js";
11
+ import { isFencingValid, isFencingValidWithSql, } from "./writerLease.js";
12
+ const READ_LOGICAL_SHEET_REGISTRATION_SQL = `
13
+ SELECT schema_version, ownership_manifest_json, business_key_field, anchor_mode, enabled
14
+ FROM sheet_registry
15
+ WHERE sheet_id = ?
16
+ `;
17
+ const INSERT_LOGICAL_SHEET_REGISTRATION_SQL = `
18
+ INSERT INTO sheet_registry (
19
+ sheet_id, schema_version, ownership_manifest_json, business_key_field, anchor_mode, enabled
20
+ ) VALUES (?, ?, ?, ?, ?, 1)
21
+ `;
22
+ const READ_PHYSICAL_SHEET_REGISTRATION_SQL = `
23
+ SELECT logical_sheet_id, spreadsheet_id, tab_name, registered_range, projection,
24
+ schema_version, anchor_mode, enabled
25
+ FROM physical_sheet_registry
26
+ WHERE physical_sheet_id = ?
27
+ `;
28
+ const INSERT_PHYSICAL_SHEET_REGISTRATION_SQL = `
29
+ INSERT INTO physical_sheet_registry (
30
+ physical_sheet_id, logical_sheet_id, spreadsheet_id, tab_name,
31
+ registered_range, projection, schema_version, anchor_mode, enabled
32
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1)
33
+ `;
34
+ const READ_REGISTERED_SYNC_SHEET_SQL = `
35
+ SELECT physical.logical_sheet_id, physical.physical_sheet_id, physical.spreadsheet_id,
36
+ physical.tab_name, physical.registered_range, physical.projection,
37
+ physical.schema_version, physical.anchor_mode, physical.enabled AS physical_enabled,
38
+ logical.ownership_manifest_json, logical.business_key_field, logical.enabled AS logical_enabled
39
+ FROM physical_sheet_registry AS physical
40
+ JOIN sheet_registry AS logical ON logical.sheet_id = physical.logical_sheet_id
41
+ WHERE physical.physical_sheet_id = ?
42
+ `;
43
+ /**
44
+ * Registers one logical sheet/projection pair under the current writer fence.
45
+ *
46
+ * Repeating an identical registration is idempotent. Any attempt to reuse a
47
+ * logical or physical ID with different immutable routing data fails closed.
48
+ */
49
+ export function registerSyncSheet(db, fence, input) {
50
+ const normalizedInput = normalizeRegistrationInput(input);
51
+ validateRegistration(normalizedInput);
52
+ if (!isFencingValid(db, fence))
53
+ return { kind: "fenced_out" };
54
+ return withImmediateTransaction(db, () => {
55
+ if (!isFencingValid(db, fence))
56
+ return { kind: "fenced_out" };
57
+ const logical = db.prepare(READ_LOGICAL_SHEET_REGISTRATION_SQL)
58
+ .get(normalizedInput.logicalSheetId);
59
+ if (logical === undefined) {
60
+ const inserted = db.prepare(INSERT_LOGICAL_SHEET_REGISTRATION_SQL).run(normalizedInput.logicalSheetId, normalizedInput.schemaVersion, normalizedInput.ownershipManifestJson, normalizedInput.businessKeyField, normalizedInput.anchorMode ?? "developer_metadata");
61
+ if (inserted.changes !== 1) {
62
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_WRITE_FAILED, "could not register logical sheet");
63
+ }
64
+ }
65
+ else if (!sameLogicalRegistration(logical, normalizedInput)) {
66
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_CONFLICT, "logical sync sheet registration does not match the existing allowlist");
67
+ }
68
+ const physical = db.prepare(READ_PHYSICAL_SHEET_REGISTRATION_SQL)
69
+ .get(normalizedInput.physicalSheetId);
70
+ if (physical === undefined) {
71
+ const inserted = db.prepare(INSERT_PHYSICAL_SHEET_REGISTRATION_SQL).run(normalizedInput.physicalSheetId, normalizedInput.logicalSheetId, normalizedInput.spreadsheetId, normalizedInput.tabName, normalizedInput.registeredRange, normalizedInput.projection, normalizedInput.schemaVersion, normalizedInput.anchorMode ?? "developer_metadata");
72
+ if (inserted.changes !== 1) {
73
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_WRITE_FAILED, "could not register physical sheet");
74
+ }
75
+ }
76
+ else if (!samePhysicalRegistration(physical, normalizedInput)) {
77
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_CONFLICT, "physical sync sheet registration does not match the existing allowlist");
78
+ }
79
+ return {
80
+ kind: "registered",
81
+ sheet: requireRegisteredSyncSheet(db, normalizedInput.physicalSheetId),
82
+ };
83
+ });
84
+ }
85
+ /**
86
+ * Registers one logical sheet/projection pair through an active async SQL context.
87
+ *
88
+ * Call this from the same MikroORM transaction as any related setup state. The
89
+ * registration and its writer-fence check then use the ORM-owned connection
90
+ * instead of opening a second SQLite connection.
91
+ */
92
+ export async function registerSyncSheetWithSql(sql, fence, input) {
93
+ const normalizedInput = normalizeRegistrationInput(input);
94
+ validateRegistration(normalizedInput);
95
+ if (!(await isFencingValidWithSql(sql, fence)))
96
+ return { kind: "fenced_out" };
97
+ return withSqlSavepoint(sql, "register_sync_sheet", async () => {
98
+ if (!(await isFencingValidWithSql(sql, fence)))
99
+ return { kind: "fenced_out" };
100
+ const logical = await sql.get(READ_LOGICAL_SHEET_REGISTRATION_SQL, [
101
+ normalizedInput.logicalSheetId,
102
+ ]);
103
+ if (logical === undefined) {
104
+ const inserted = await sql.run(INSERT_LOGICAL_SHEET_REGISTRATION_SQL, [
105
+ normalizedInput.logicalSheetId,
106
+ normalizedInput.schemaVersion,
107
+ normalizedInput.ownershipManifestJson,
108
+ normalizedInput.businessKeyField,
109
+ normalizedInput.anchorMode ?? "developer_metadata",
110
+ ]);
111
+ if (inserted.changes !== 1) {
112
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_WRITE_FAILED, "could not register logical sheet");
113
+ }
114
+ }
115
+ else if (!sameLogicalRegistration(logical, normalizedInput)) {
116
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_CONFLICT, "logical sync sheet registration does not match the existing allowlist");
117
+ }
118
+ const physical = await sql.get(READ_PHYSICAL_SHEET_REGISTRATION_SQL, [
119
+ normalizedInput.physicalSheetId,
120
+ ]);
121
+ if (physical === undefined) {
122
+ const inserted = await sql.run(INSERT_PHYSICAL_SHEET_REGISTRATION_SQL, [
123
+ normalizedInput.physicalSheetId,
124
+ normalizedInput.logicalSheetId,
125
+ normalizedInput.spreadsheetId,
126
+ normalizedInput.tabName,
127
+ normalizedInput.registeredRange,
128
+ normalizedInput.projection,
129
+ normalizedInput.schemaVersion,
130
+ normalizedInput.anchorMode ?? "developer_metadata",
131
+ ]);
132
+ if (inserted.changes !== 1) {
133
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_WRITE_FAILED, "could not register physical sheet");
134
+ }
135
+ }
136
+ else if (!samePhysicalRegistration(physical, normalizedInput)) {
137
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRATION_CONFLICT, "physical sync sheet registration does not match the existing allowlist");
138
+ }
139
+ return {
140
+ kind: "registered",
141
+ sheet: await requireRegisteredSyncSheetWithSql(sql, normalizedInput.physicalSheetId),
142
+ };
143
+ });
144
+ }
145
+ /** Registers one projection in an adapter-owned MikroORM transaction. */
146
+ export async function registerSyncSheetWithAdapter(storage, fence, input) {
147
+ return storage.transaction(({ sql }) => registerSyncSheetWithSql(sql, fence, input));
148
+ }
149
+ /** Reads one enabled physical registry entry or rejects any unregistered target. */
150
+ export function requireRegisteredSyncSheet(db, physicalSheetId) {
151
+ if (physicalSheetId.length === 0) {
152
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "physical sheet ID is required");
153
+ }
154
+ const row = db.prepare(READ_REGISTERED_SYNC_SHEET_SQL)
155
+ .get(physicalSheetId);
156
+ return registeredSyncSheetFromRow(row);
157
+ }
158
+ /** Reads one enabled physical registry entry through an active async SQL context. */
159
+ export async function requireRegisteredSyncSheetWithSql(sql, physicalSheetId) {
160
+ if (physicalSheetId.length === 0) {
161
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "physical sheet ID is required");
162
+ }
163
+ const row = await sql.get(READ_REGISTERED_SYNC_SHEET_SQL, [physicalSheetId]);
164
+ return registeredSyncSheetFromRow(row);
165
+ }
166
+ /** Reads one enabled physical registry entry through a fresh adapter read context. */
167
+ export async function requireRegisteredSyncSheetWithAdapter(storage, physicalSheetId) {
168
+ return storage.read(({ sql }) => requireRegisteredSyncSheetWithSql(sql, physicalSheetId));
169
+ }
170
+ function validateRegistration(input) {
171
+ for (const [label, value] of [
172
+ ["logical sheet ID", input.logicalSheetId],
173
+ ["physical sheet ID", input.physicalSheetId],
174
+ ["spreadsheet ID", input.spreadsheetId],
175
+ ["tab name", input.tabName],
176
+ ["registered range", input.registeredRange],
177
+ ["ownership manifest", input.ownershipManifestJson],
178
+ ["business key field", input.businessKeyField],
179
+ ]) {
180
+ if (value.length === 0) {
181
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, label + " is required");
182
+ }
183
+ }
184
+ if (!Number.isSafeInteger(input.schemaVersion) || input.schemaVersion < 1) {
185
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "schema version must be a positive safe integer");
186
+ }
187
+ if (!isRegisteredProjection(input.projection)) {
188
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "unsupported sync projection");
189
+ }
190
+ if (input.anchorMode !== undefined && input.anchorMode !== "developer_metadata") {
191
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "v1 sync registry requires developer_metadata anchors");
192
+ }
193
+ try {
194
+ JSON.parse(input.ownershipManifestJson);
195
+ }
196
+ catch {
197
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION, "ownership manifest must be valid JSON");
198
+ }
199
+ }
200
+ function normalizeRegistrationInput(input) {
201
+ return {
202
+ ...input,
203
+ registeredRange: normalizeRegisteredRange(input.registeredRange, STORAGE_ERROR_CODES.INVALID_SYNC_REGISTRATION),
204
+ };
205
+ }
206
+ function sameLogicalRegistration(existing, input) {
207
+ return existing.schema_version === input.schemaVersion &&
208
+ existing.ownership_manifest_json === input.ownershipManifestJson &&
209
+ existing.business_key_field === input.businessKeyField &&
210
+ existing.anchor_mode === (input.anchorMode ?? "developer_metadata") &&
211
+ existing.enabled === 1;
212
+ }
213
+ function samePhysicalRegistration(existing, input) {
214
+ return existing.logical_sheet_id === input.logicalSheetId &&
215
+ existing.spreadsheet_id === input.spreadsheetId &&
216
+ existing.tab_name === input.tabName &&
217
+ existing.registered_range === input.registeredRange &&
218
+ existing.projection === input.projection &&
219
+ existing.schema_version === input.schemaVersion &&
220
+ existing.anchor_mode === (input.anchorMode ?? "developer_metadata") &&
221
+ existing.enabled === 1;
222
+ }
223
+ function registeredSyncSheetFromRow(row) {
224
+ if (row === undefined || row.physical_enabled !== 1 || row.logical_enabled !== 1) {
225
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRY_TARGET_UNAVAILABLE, "physical sheet is not an enabled sync registry target");
226
+ }
227
+ if (!isRegisteredProjection(row.projection) || row.anchor_mode !== "developer_metadata") {
228
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRY_TARGET_UNAVAILABLE, "physical sheet registry has an unsupported projection or anchor mode");
229
+ }
230
+ const registeredRange = normalizeRegisteredRange(row.registered_range, STORAGE_ERROR_CODES.SYNC_REGISTRY_TARGET_UNAVAILABLE);
231
+ if (registeredRange !== row.registered_range) {
232
+ throw new StorageError(STORAGE_ERROR_CODES.SYNC_REGISTRY_TARGET_UNAVAILABLE, "physical sheet registry range is not in canonical whole-column form");
233
+ }
234
+ return {
235
+ logicalSheetId: row.logical_sheet_id,
236
+ physicalSheetId: row.physical_sheet_id,
237
+ spreadsheetId: row.spreadsheet_id,
238
+ tabName: row.tab_name,
239
+ registeredRange,
240
+ projection: row.projection,
241
+ schemaVersion: row.schema_version,
242
+ ownershipManifestJson: row.ownership_manifest_json,
243
+ businessKeyField: row.business_key_field,
244
+ anchorMode: "developer_metadata",
245
+ };
246
+ }
247
+ function isRegisteredProjection(value) {
248
+ return value === "user_input" || value === "system_state" || value === "sync_conflicts";
249
+ }
250
+ /** Normalizes the v1 whole-column gateway boundary to the form accepted by Apps Script. */
251
+ function normalizeRegisteredRange(value, errorCode) {
252
+ const normalized = value.trim().toUpperCase();
253
+ const match = /^([A-Z]+):([A-Z]+)$/.exec(normalized);
254
+ if (match === null || match[1] === undefined || match[2] === undefined) {
255
+ throw new StorageError(errorCode, "registered range must be a whole-column range such as A:Z");
256
+ }
257
+ if (sheetColumnNumber(match[2], errorCode) < sheetColumnNumber(match[1], errorCode)) {
258
+ throw new StorageError(errorCode, "registered range must be a whole-column range such as A:Z");
259
+ }
260
+ return normalized;
261
+ }
262
+ function sheetColumnNumber(letters, errorCode) {
263
+ let result = 0;
264
+ for (const letter of letters) {
265
+ result = result * 26 + letter.charCodeAt(0) - 64;
266
+ if (!Number.isSafeInteger(result)) {
267
+ throw new StorageError(errorCode, "registered range column is out of range");
268
+ }
269
+ }
270
+ return result;
271
+ }
272
+ //# sourceMappingURL=syncRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncRegistry.js","sourceRoot":"","sources":["../../../../../src/infrastructure/storage/sync/shared/syncRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * SQLite writer lease and fencing token management.
3
+ *
4
+ * Per design concurrency/writer-rpc.md:
5
+ * - Single writer owns all canonical/outbox mutations.
6
+ * - Every mutation CAS-checks the current fencing token.
7
+ * - Lease takeover increments epoch + fencing token.
8
+ * - Stale fencing tokens are rejected even if the affected row hasn't changed.
9
+ */
10
+ import type { DatabaseSyncLike } from "../../sqlite/sqliteBridge.js";
11
+ import type { LookupResult } from "../../../../shared/state/types.js";
12
+ import type { SqlExecutor, SqlStorageAdapter } from "../../../../adapter/persistence/contracts/sql.js";
13
+ export interface WriterLease {
14
+ readonly role: string;
15
+ readonly writerId: string;
16
+ readonly writerEpoch: number;
17
+ readonly fencingToken: string;
18
+ readonly leaseUntil: number;
19
+ }
20
+ /** Runtime values for the two observable writer-lease claim outcomes. */
21
+ export declare const WRITER_LEASE_CLAIM_RESULT_KINDS: {
22
+ readonly CLAIMED: "claimed";
23
+ readonly NOT_CLAIMED: "not_claimed";
24
+ };
25
+ /** Closed set of writer-lease claim outcome kinds. */
26
+ export type WriterLeaseClaimResultKind = (typeof WRITER_LEASE_CLAIM_RESULT_KINDS)[keyof typeof WRITER_LEASE_CLAIM_RESULT_KINDS];
27
+ /** Runtime values explaining why a writer-lease claim did not succeed. */
28
+ export declare const WRITER_LEASE_CLAIM_FAILURE_REASONS: {
29
+ readonly ACTIVE_WRITER: "active_writer";
30
+ readonly INITIAL_CLAIM_NOT_APPLIED: "initial_claim_not_applied";
31
+ readonly RENEWAL_RACE_LOST: "renewal_race_lost";
32
+ readonly TAKEOVER_RACE_LOST: "takeover_race_lost";
33
+ };
34
+ /** Closed set of writer-lease claim failure reasons. */
35
+ export type WriterLeaseClaimFailureReason = (typeof WRITER_LEASE_CLAIM_FAILURE_REASONS)[keyof typeof WRITER_LEASE_CLAIM_FAILURE_REASONS];
36
+ export type WriterLeaseClaimResult = {
37
+ readonly kind: typeof WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED;
38
+ readonly lease: WriterLease;
39
+ } | {
40
+ readonly kind: typeof WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED;
41
+ readonly reason: WriterLeaseClaimFailureReason;
42
+ };
43
+ export interface ClaimLeaseOptions {
44
+ readonly role: string;
45
+ readonly writerId: string;
46
+ readonly leaseDurationMs: number;
47
+ readonly now: number;
48
+ }
49
+ /** The current lease identity required for a fenced storage mutation. */
50
+ export interface FencingContext {
51
+ readonly role: string;
52
+ readonly writerEpoch: number;
53
+ readonly fencingToken: string;
54
+ readonly now: number;
55
+ }
56
+ /**
57
+ * Claims or renews the writer lease for a role.
58
+ *
59
+ * If no lease exists, creates one with epoch 1.
60
+ * If the current lease belongs to this writer, renews it.
61
+ * If the current lease has expired, takes over with incremented epoch + new fencing token.
62
+ * If the current lease is held by another active writer, returns a typed failure.
63
+ */
64
+ export declare function claimWriterLease(db: DatabaseSyncLike, options: ClaimLeaseOptions): WriterLeaseClaimResult;
65
+ /**
66
+ * Claims or renews a writer lease inside an already-active async SQL context.
67
+ *
68
+ * This is the MikroORM-compatible counterpart of `claimWriterLease()`. Call
69
+ * it from a broader adapter transaction when the lease claim must be atomic
70
+ * with an entity, canonical-state, or outbox mutation.
71
+ */
72
+ export declare function claimWriterLeaseWithSql(sql: SqlExecutor, options: ClaimLeaseOptions): Promise<WriterLeaseClaimResult>;
73
+ /** Claims or renews a writer lease in one adapter-owned transaction. */
74
+ export declare function claimWriterLeaseWithAdapter(storage: SqlStorageAdapter, options: ClaimLeaseOptions): Promise<WriterLeaseClaimResult>;
75
+ /** Reads the current lease for a role with an explicit not-found state. */
76
+ export declare function readWriterLease(db: DatabaseSyncLike, role: string): LookupResult<WriterLease>;
77
+ /** Reads a writer lease through an already-active async SQL context. */
78
+ export declare function readWriterLeaseWithSql(sql: SqlExecutor, role: string): Promise<LookupResult<WriterLease>>;
79
+ /** Reads a writer lease through a fresh adapter read context. */
80
+ export declare function readWriterLeaseWithAdapter(storage: SqlStorageAdapter, role: string): Promise<LookupResult<WriterLease>>;
81
+ /**
82
+ * Checks whether the given epoch + fencing token match the current lease.
83
+ * Used by effect workers to verify their claim is still valid before applying results.
84
+ */
85
+ export declare function isFencingValid(db: DatabaseSyncLike, fence: FencingContext): boolean;
86
+ /** Checks a fencing token inside an already-active async SQL context. */
87
+ export declare function isFencingValidWithSql(sql: SqlExecutor, fence: FencingContext): Promise<boolean>;
88
+ /** Checks a fencing token through a fresh adapter read context. */
89
+ export declare function isFencingValidWithAdapter(storage: SqlStorageAdapter, fence: FencingContext): Promise<boolean>;
90
+ //# sourceMappingURL=writerLease.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writerLease.d.ts","sourceRoot":"","sources":["../../../../../src/infrastructure/storage/sync/shared/writerLease.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,282 @@
1
+ /**
2
+ * SQLite writer lease and fencing token management.
3
+ *
4
+ * Per design concurrency/writer-rpc.md:
5
+ * - Single writer owns all canonical/outbox mutations.
6
+ * - Every mutation CAS-checks the current fencing token.
7
+ * - Lease takeover increments epoch + fencing token.
8
+ * - Stale fencing tokens are rejected even if the affected row hasn't changed.
9
+ */
10
+ import { STORAGE_ERROR_CODES, StorageError } from "../../errors.js";
11
+ import { LOOKUP_RESULT_KINDS } from "../../../../shared/state/constants.js";
12
+ import { withSqlSavepoint } from "../../sqlite/sqlTransaction.js";
13
+ const READ_WRITER_LEASE_SQL = "SELECT role, writer_id, writer_epoch, fencing_token, lease_until FROM writer_lease WHERE role = ?";
14
+ const INSERT_WRITER_LEASE_SQL = `
15
+ INSERT INTO writer_lease (role, writer_id, writer_epoch, fencing_token, lease_until)
16
+ VALUES (?, ?, ?, ?, ?)
17
+ `;
18
+ const RENEW_WRITER_LEASE_SQL = `
19
+ UPDATE writer_lease
20
+ SET lease_until = ?
21
+ WHERE role = ? AND writer_id = ? AND writer_epoch = ?
22
+ AND fencing_token = ? AND lease_until > ?
23
+ `;
24
+ const TAKEOVER_WRITER_LEASE_SQL = `
25
+ UPDATE writer_lease
26
+ SET writer_id = ?, writer_epoch = ?, fencing_token = ?, lease_until = ?
27
+ WHERE role = ? AND writer_epoch = ? AND fencing_token = ? AND lease_until <= ?
28
+ `;
29
+ /** Runtime values for the two observable writer-lease claim outcomes. */
30
+ export const WRITER_LEASE_CLAIM_RESULT_KINDS = {
31
+ CLAIMED: "claimed",
32
+ NOT_CLAIMED: "not_claimed",
33
+ };
34
+ /** Runtime values explaining why a writer-lease claim did not succeed. */
35
+ export const WRITER_LEASE_CLAIM_FAILURE_REASONS = {
36
+ ACTIVE_WRITER: "active_writer",
37
+ INITIAL_CLAIM_NOT_APPLIED: "initial_claim_not_applied",
38
+ RENEWAL_RACE_LOST: "renewal_race_lost",
39
+ TAKEOVER_RACE_LOST: "takeover_race_lost",
40
+ };
41
+ /**
42
+ * Claims or renews the writer lease for a role.
43
+ *
44
+ * If no lease exists, creates one with epoch 1.
45
+ * If the current lease belongs to this writer, renews it.
46
+ * If the current lease has expired, takes over with incremented epoch + new fencing token.
47
+ * If the current lease is held by another active writer, returns a typed failure.
48
+ */
49
+ export function claimWriterLease(db, options) {
50
+ validateClaimOptions(options);
51
+ return withSavepoint(db, "claim_writer_lease", () => {
52
+ const existing = readLeaseRow(db, options.role);
53
+ const newLeaseUntil = options.now + options.leaseDurationMs;
54
+ if (existing === undefined) {
55
+ const lease = makeLease(options.role, options.writerId, 1, newLeaseUntil);
56
+ const result = db.prepare(INSERT_WRITER_LEASE_SQL).run(lease.role, lease.writerId, lease.writerEpoch, lease.fencingToken, lease.leaseUntil);
57
+ return result.changes === 1
58
+ ? { kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED, lease }
59
+ : {
60
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
61
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.INITIAL_CLAIM_NOT_APPLIED,
62
+ };
63
+ }
64
+ if (existing.writer_id === options.writerId && existing.lease_until > options.now) {
65
+ const result = db.prepare(RENEW_WRITER_LEASE_SQL).run(newLeaseUntil, options.role, options.writerId, existing.writer_epoch, existing.fencing_token, options.now);
66
+ return result.changes === 1
67
+ ? {
68
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED,
69
+ lease: {
70
+ role: existing.role,
71
+ writerId: existing.writer_id,
72
+ writerEpoch: existing.writer_epoch,
73
+ fencingToken: existing.fencing_token,
74
+ leaseUntil: newLeaseUntil,
75
+ },
76
+ }
77
+ : {
78
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
79
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.RENEWAL_RACE_LOST,
80
+ };
81
+ }
82
+ if (existing.lease_until > options.now) {
83
+ return {
84
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
85
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.ACTIVE_WRITER,
86
+ };
87
+ }
88
+ // An expired owner, including the same process, must take a new epoch.
89
+ // Reusing its old fence would allow delayed work to look current again.
90
+ const takeover = makeLease(options.role, options.writerId, existing.writer_epoch + 1, newLeaseUntil);
91
+ const result = db.prepare(TAKEOVER_WRITER_LEASE_SQL).run(takeover.writerId, takeover.writerEpoch, takeover.fencingToken, takeover.leaseUntil, options.role, existing.writer_epoch, existing.fencing_token, options.now);
92
+ return result.changes === 1
93
+ ? { kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED, lease: takeover }
94
+ : {
95
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
96
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.TAKEOVER_RACE_LOST,
97
+ };
98
+ });
99
+ }
100
+ /**
101
+ * Claims or renews a writer lease inside an already-active async SQL context.
102
+ *
103
+ * This is the MikroORM-compatible counterpart of `claimWriterLease()`. Call
104
+ * it from a broader adapter transaction when the lease claim must be atomic
105
+ * with an entity, canonical-state, or outbox mutation.
106
+ */
107
+ export async function claimWriterLeaseWithSql(sql, options) {
108
+ validateClaimOptions(options);
109
+ return withSqlSavepoint(sql, "claim_writer_lease", async () => {
110
+ const existing = await readLeaseRowWithSql(sql, options.role);
111
+ const newLeaseUntil = options.now + options.leaseDurationMs;
112
+ if (existing === undefined) {
113
+ const lease = makeLease(options.role, options.writerId, 1, newLeaseUntil);
114
+ const result = await sql.run(INSERT_WRITER_LEASE_SQL, [
115
+ lease.role,
116
+ lease.writerId,
117
+ lease.writerEpoch,
118
+ lease.fencingToken,
119
+ lease.leaseUntil,
120
+ ]);
121
+ return result.changes === 1
122
+ ? { kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED, lease }
123
+ : {
124
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
125
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.INITIAL_CLAIM_NOT_APPLIED,
126
+ };
127
+ }
128
+ if (existing.writer_id === options.writerId && existing.lease_until > options.now) {
129
+ const result = await sql.run(RENEW_WRITER_LEASE_SQL, [
130
+ newLeaseUntil,
131
+ options.role,
132
+ options.writerId,
133
+ existing.writer_epoch,
134
+ existing.fencing_token,
135
+ options.now,
136
+ ]);
137
+ return result.changes === 1
138
+ ? {
139
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED,
140
+ lease: {
141
+ role: existing.role,
142
+ writerId: existing.writer_id,
143
+ writerEpoch: existing.writer_epoch,
144
+ fencingToken: existing.fencing_token,
145
+ leaseUntil: newLeaseUntil,
146
+ },
147
+ }
148
+ : {
149
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
150
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.RENEWAL_RACE_LOST,
151
+ };
152
+ }
153
+ if (existing.lease_until > options.now) {
154
+ return {
155
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
156
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.ACTIVE_WRITER,
157
+ };
158
+ }
159
+ const takeover = makeLease(options.role, options.writerId, existing.writer_epoch + 1, newLeaseUntil);
160
+ const result = await sql.run(TAKEOVER_WRITER_LEASE_SQL, [
161
+ takeover.writerId,
162
+ takeover.writerEpoch,
163
+ takeover.fencingToken,
164
+ takeover.leaseUntil,
165
+ options.role,
166
+ existing.writer_epoch,
167
+ existing.fencing_token,
168
+ options.now,
169
+ ]);
170
+ return result.changes === 1
171
+ ? { kind: WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED, lease: takeover }
172
+ : {
173
+ kind: WRITER_LEASE_CLAIM_RESULT_KINDS.NOT_CLAIMED,
174
+ reason: WRITER_LEASE_CLAIM_FAILURE_REASONS.TAKEOVER_RACE_LOST,
175
+ };
176
+ });
177
+ }
178
+ /** Claims or renews a writer lease in one adapter-owned transaction. */
179
+ export async function claimWriterLeaseWithAdapter(storage, options) {
180
+ return storage.transaction(({ sql }) => claimWriterLeaseWithSql(sql, options));
181
+ }
182
+ /** Reads the current lease for a role with an explicit not-found state. */
183
+ export function readWriterLease(db, role) {
184
+ const row = readLeaseRow(db, role);
185
+ return row === undefined
186
+ ? { kind: LOOKUP_RESULT_KINDS.NOT_FOUND }
187
+ : {
188
+ kind: LOOKUP_RESULT_KINDS.FOUND,
189
+ value: {
190
+ role: row.role,
191
+ writerId: row.writer_id,
192
+ writerEpoch: row.writer_epoch,
193
+ fencingToken: row.fencing_token,
194
+ leaseUntil: row.lease_until,
195
+ },
196
+ };
197
+ }
198
+ /** Reads a writer lease through an already-active async SQL context. */
199
+ export async function readWriterLeaseWithSql(sql, role) {
200
+ const row = await readLeaseRowWithSql(sql, role);
201
+ return row === undefined
202
+ ? { kind: LOOKUP_RESULT_KINDS.NOT_FOUND }
203
+ : {
204
+ kind: LOOKUP_RESULT_KINDS.FOUND,
205
+ value: {
206
+ role: row.role,
207
+ writerId: row.writer_id,
208
+ writerEpoch: row.writer_epoch,
209
+ fencingToken: row.fencing_token,
210
+ leaseUntil: row.lease_until,
211
+ },
212
+ };
213
+ }
214
+ /** Reads a writer lease through a fresh adapter read context. */
215
+ export async function readWriterLeaseWithAdapter(storage, role) {
216
+ return storage.read(({ sql }) => readWriterLeaseWithSql(sql, role));
217
+ }
218
+ /**
219
+ * Checks whether the given epoch + fencing token match the current lease.
220
+ * Used by effect workers to verify their claim is still valid before applying results.
221
+ */
222
+ export function isFencingValid(db, fence) {
223
+ const lease = readWriterLease(db, fence.role);
224
+ if (lease.kind === LOOKUP_RESULT_KINDS.NOT_FOUND)
225
+ return false;
226
+ return (lease.value.writerEpoch === fence.writerEpoch &&
227
+ lease.value.fencingToken === fence.fencingToken &&
228
+ lease.value.leaseUntil > fence.now);
229
+ }
230
+ /** Checks a fencing token inside an already-active async SQL context. */
231
+ export async function isFencingValidWithSql(sql, fence) {
232
+ const lease = await readWriterLeaseWithSql(sql, fence.role);
233
+ if (lease.kind === LOOKUP_RESULT_KINDS.NOT_FOUND)
234
+ return false;
235
+ return (lease.value.writerEpoch === fence.writerEpoch &&
236
+ lease.value.fencingToken === fence.fencingToken &&
237
+ lease.value.leaseUntil > fence.now);
238
+ }
239
+ /** Checks a fencing token through a fresh adapter read context. */
240
+ export async function isFencingValidWithAdapter(storage, fence) {
241
+ return storage.read(({ sql }) => isFencingValidWithSql(sql, fence));
242
+ }
243
+ function readLeaseRow(db, role) {
244
+ return db.prepare(READ_WRITER_LEASE_SQL).get(role);
245
+ }
246
+ function readLeaseRowWithSql(sql, role) {
247
+ return sql.get(READ_WRITER_LEASE_SQL, [role]);
248
+ }
249
+ function makeLease(role, writerId, writerEpoch, leaseUntil) {
250
+ return {
251
+ role,
252
+ writerId,
253
+ writerEpoch,
254
+ fencingToken: `fence-${writerEpoch}`,
255
+ leaseUntil,
256
+ };
257
+ }
258
+ function validateClaimOptions(options) {
259
+ if (!Number.isSafeInteger(options.now) || options.now < 0) {
260
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_WRITER_LEASE_OPTIONS, "writer lease now must be a non-negative safe integer");
261
+ }
262
+ if (!Number.isSafeInteger(options.leaseDurationMs) || options.leaseDurationMs <= 0) {
263
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_WRITER_LEASE_OPTIONS, "writer lease duration must be a positive safe integer");
264
+ }
265
+ if (options.role.length === 0 || options.writerId.length === 0) {
266
+ throw new StorageError(STORAGE_ERROR_CODES.INVALID_WRITER_LEASE_OPTIONS, "writer lease role and writer ID are required");
267
+ }
268
+ }
269
+ function withSavepoint(db, name, operation) {
270
+ db.exec(`SAVEPOINT ${name}`);
271
+ try {
272
+ const value = operation();
273
+ db.exec(`RELEASE ${name}`);
274
+ return value;
275
+ }
276
+ catch (error) {
277
+ db.exec(`ROLLBACK TO ${name}`);
278
+ db.exec(`RELEASE ${name}`);
279
+ throw error;
280
+ }
281
+ }
282
+ //# sourceMappingURL=writerLease.js.map