hikoutei 0.3.2 → 0.3.3

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 (211) hide show
  1. package/README.md +12 -2
  2. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts +2 -0
  3. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts.map +1 -1
  4. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js +5 -0
  5. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js.map +1 -1
  6. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts +52 -0
  7. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.d.ts.map +1 -1
  8. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js +195 -13
  9. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPolling.js.map +1 -1
  10. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts +24 -0
  11. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.d.ts.map +1 -0
  12. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js +124 -0
  13. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingFastPath.js.map +1 -0
  14. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js +1 -1
  15. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingInspection.js.map +1 -1
  16. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts +15 -2
  17. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.d.ts.map +1 -1
  18. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js +27 -3
  19. package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmUserInputPollingPersistence.js.map +1 -1
  20. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +1 -0
  21. package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +1 -1
  22. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +1 -0
  23. package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +1 -1
  24. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +2 -0
  25. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -1
  26. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +1 -0
  27. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -1
  28. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +3 -1
  29. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +1 -1
  30. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +9 -0
  31. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +1 -1
  32. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +1 -1
  33. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +137 -20
  34. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +1 -1
  35. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +82 -34
  36. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +1 -1
  37. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +31 -0
  38. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +1 -0
  39. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +567 -0
  40. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +1 -0
  41. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +12 -17
  42. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +1 -1
  43. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +27 -213
  44. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +1 -1
  45. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +1 -1
  46. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +81 -8
  47. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +1 -1
  48. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +1 -6
  49. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -1
  50. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +15 -9
  51. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -1
  52. package/dist/application/orm/mapping/projection.js +1 -1
  53. package/dist/application/orm/mapping/projection.js.map +1 -1
  54. package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -1
  55. package/dist/application/orm/persistence/flush/flushCoordinator.js +1 -0
  56. package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -1
  57. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js +1 -1
  58. package/dist/application/orm/persistence/lifecycle/entityLifecycle.js.map +1 -1
  59. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts +3 -1
  60. package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +1 -1
  61. package/dist/application/sync/gateway/SyncGatewayBootstrap.js +3 -1
  62. package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +1 -1
  63. package/dist/application/sync/gateway/conflictProjection.d.ts +13 -0
  64. package/dist/application/sync/gateway/conflictProjection.d.ts.map +1 -0
  65. package/dist/application/sync/gateway/conflictProjection.js +58 -0
  66. package/dist/application/sync/gateway/conflictProjection.js.map +1 -0
  67. package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts +11 -0
  68. package/dist/application/sync/gateway/conflictProjectionRegistration.d.ts.map +1 -0
  69. package/dist/application/sync/gateway/conflictProjectionRegistration.js +70 -0
  70. package/dist/application/sync/gateway/conflictProjectionRegistration.js.map +1 -0
  71. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts +102 -0
  72. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.d.ts.map +1 -0
  73. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js +221 -0
  74. package/dist/application/sync/gateway/coordinator/CoordinatedSyncGateway.js.map +1 -0
  75. package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts +51 -0
  76. package/dist/application/sync/gateway/coordinator/asyncMutex.d.ts.map +1 -0
  77. package/dist/application/sync/gateway/coordinator/asyncMutex.js +65 -0
  78. package/dist/application/sync/gateway/coordinator/asyncMutex.js.map +1 -0
  79. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts +31 -0
  80. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.d.ts.map +1 -0
  81. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js +13 -0
  82. package/dist/application/sync/gateway/coordinator/coordinatorTelemetry.js.map +1 -0
  83. package/dist/application/sync/gateway/syncGateway.d.ts +26 -6
  84. package/dist/application/sync/gateway/syncGateway.d.ts.map +1 -1
  85. package/dist/application/sync/gateway/syncGateway.js +10 -2
  86. package/dist/application/sync/gateway/syncGateway.js.map +1 -1
  87. package/dist/application/sync/gateway/transportClassification.d.ts +62 -0
  88. package/dist/application/sync/gateway/transportClassification.d.ts.map +1 -0
  89. package/dist/application/sync/gateway/transportClassification.js +133 -0
  90. package/dist/application/sync/gateway/transportClassification.js.map +1 -0
  91. package/dist/application/sync/inbound/autoSystemConflictResolution.d.ts +26 -0
  92. package/dist/application/sync/inbound/autoSystemConflictResolution.d.ts.map +1 -0
  93. package/dist/application/sync/inbound/autoSystemConflictResolution.js +335 -0
  94. package/dist/application/sync/inbound/autoSystemConflictResolution.js.map +1 -0
  95. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +50 -0
  96. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -0
  97. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +97 -0
  98. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -0
  99. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +4 -1
  100. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
  101. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +35 -1
  102. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
  103. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +14 -2
  104. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
  105. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +190 -31
  106. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
  107. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +25 -2
  108. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
  109. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +25 -2
  110. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
  111. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +14 -7
  112. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
  113. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +118 -14
  114. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
  115. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +30 -9
  116. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
  117. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +102 -18
  118. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
  119. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -1
  120. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +49 -14
  121. package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -1
  122. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -1
  123. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +97 -17
  124. package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -1
  125. package/dist/application/sync/service/SyncServiceBootstrap.d.ts +17 -0
  126. package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
  127. package/dist/application/sync/service/SyncServiceBootstrap.js +125 -10
  128. package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
  129. package/dist/application/sync/service/contracts.d.ts +2 -0
  130. package/dist/application/sync/service/contracts.d.ts.map +1 -1
  131. package/dist/application/sync/telemetry/syncTiming.d.ts +6 -0
  132. package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -1
  133. package/dist/application/sync/telemetry/syncTiming.js +2 -0
  134. package/dist/application/sync/telemetry/syncTiming.js.map +1 -1
  135. package/dist/domain/conflict/index.d.ts +1 -1
  136. package/dist/domain/conflict/index.d.ts.map +1 -1
  137. package/dist/domain/conflict/index.js +1 -1
  138. package/dist/domain/conflict/index.js.map +1 -1
  139. package/dist/domain/conflict/transitions.d.ts +3 -0
  140. package/dist/domain/conflict/transitions.d.ts.map +1 -1
  141. package/dist/domain/conflict/transitions.js +3 -2
  142. package/dist/domain/conflict/transitions.js.map +1 -1
  143. package/dist/domain/model/constants.d.ts +1 -0
  144. package/dist/domain/model/constants.d.ts.map +1 -1
  145. package/dist/domain/model/constants.js +1 -0
  146. package/dist/domain/model/constants.js.map +1 -1
  147. package/dist/infrastructure/storage/index.d.ts +4 -2
  148. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  149. package/dist/infrastructure/storage/index.js +2 -1
  150. package/dist/infrastructure/storage/index.js.map +1 -1
  151. package/dist/infrastructure/storage/sqlite/migrateSchema.d.ts.map +1 -1
  152. package/dist/infrastructure/storage/sqlite/migrateSchema.js +59 -1
  153. package/dist/infrastructure/storage/sqlite/migrateSchema.js.map +1 -1
  154. package/dist/infrastructure/storage/sqlite/schema.d.ts +12 -1
  155. package/dist/infrastructure/storage/sqlite/schema.d.ts.map +1 -1
  156. package/dist/infrastructure/storage/sqlite/schema.js +47 -3
  157. package/dist/infrastructure/storage/sqlite/schema.js.map +1 -1
  158. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts +2 -2
  159. package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts.map +1 -1
  160. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js +1 -1
  161. package/dist/infrastructure/storage/state/canonical/canonicalCommit.js.map +1 -1
  162. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.d.ts +1 -0
  163. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.d.ts.map +1 -1
  164. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.js +1 -1
  165. package/dist/infrastructure/storage/state/mapped/mappedPersistenceSql.js.map +1 -1
  166. package/dist/infrastructure/storage/state/observation/observationAudit.js +5 -1
  167. package/dist/infrastructure/storage/state/observation/observationAudit.js.map +1 -1
  168. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts +10 -0
  169. package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts.map +1 -1
  170. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js +106 -20
  171. package/dist/infrastructure/storage/state/resolution/resolutionWriter.js.map +1 -1
  172. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts +9 -1
  173. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts.map +1 -1
  174. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js +3 -0
  175. package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js.map +1 -1
  176. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts +11 -0
  177. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts.map +1 -1
  178. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js +35 -0
  179. package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js.map +1 -1
  180. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +12 -4
  181. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
  182. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +46 -15
  183. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
  184. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +24 -0
  185. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -1
  186. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +1 -0
  187. package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -1
  188. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +9 -7
  189. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
  190. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +44 -8
  191. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
  192. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts +3 -1
  193. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts.map +1 -1
  194. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js +35 -2
  195. package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js.map +1 -1
  196. package/dist/infrastructure/storage/sync/outbound/reconciliationSql.js +1 -0
  197. package/dist/infrastructure/storage/sync/outbound/reconciliationSql.js.map +1 -1
  198. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.d.ts +31 -0
  199. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.d.ts.map +1 -0
  200. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.js +92 -0
  201. package/dist/infrastructure/storage/sync/shared/spreadsheetAuthority.js.map +1 -0
  202. package/dist/infrastructure/storage/sync/shared/writerLease.js +3 -1
  203. package/dist/infrastructure/storage/sync/shared/writerLease.js.map +1 -1
  204. package/docs/advanced-sheets-gateway-concurrency-problem.md +434 -0
  205. package/docs/architecture.md +53 -11
  206. package/docs/google-sheets-sync-scaling-strategy.md +459 -0
  207. package/docs/quick-start.md +15 -1
  208. package/docs/sync-bulk-write-benchmark.md +520 -0
  209. package/docs/sync-observability.md +39 -3
  210. package/docs/write-and-synchronization-flow.md +76 -17
  211. package/package.json +1 -1
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Structured classification of a Gateway transport outcome.
3
+ *
4
+ * The Apps Script transport can fail for three very different reasons that the
5
+ * effect worker must not treat the same way:
6
+ *
7
+ * - `success`: a decoded, valid envelope was returned.
8
+ * - `explicit_remote_failure`: the remote returned a structured rejection that
9
+ * proves no operation ran (e.g. a signed-envelope validation failure). The
10
+ * remote state is known, so the effect can transition to a terminal failure
11
+ * state.
12
+ * - `delivery_uncertain`: the transport gave no usable answer (timeout,
13
+ * network error, non-JSON/404 response, lost connection), or the Gateway
14
+ * failed during/after operation execution (`operation_failed`,
15
+ * `internal_error`). The remote may or may not have committed the write, so
16
+ * the effect must be recovered through a postcondition probe rather than
17
+ * immediately redriven. Per-effect guard/schema/identity rejections are not
18
+ * transport errors at all: they arrive as per-effect result statuses in a
19
+ * successful envelope and keep their existing terminal handling.
20
+ *
21
+ * This boundary lets future durable `delivery_uncertain` state and recovery
22
+ * barriers classify a thrown transport error without re-deriving the rules at
23
+ * every call site. It never weakens correctness: an uncertain outcome is never
24
+ * promoted to `success`, and a proven pre-mutation rejection is never
25
+ * reclassified as a retryable transport error.
26
+ */
27
+ import { AppsScriptSyncGatewayError } from "../../../adapter/sheets/providers/apps-script-gateway/errors.js";
28
+ import type { Presence } from "../../../shared/state/types.js";
29
+ export declare const TRANSPORT_OUTCOME_KINDS: {
30
+ readonly SUCCESS: "success";
31
+ readonly EXPLICIT_REMOTE_FAILURE: "explicit_remote_failure";
32
+ readonly DELIVERY_UNCERTAIN: "delivery_uncertain";
33
+ };
34
+ export type TransportOutcomeKind = (typeof TRANSPORT_OUTCOME_KINDS)[keyof typeof TRANSPORT_OUTCOME_KINDS];
35
+ /** A classified transport outcome with redacted, safe diagnostics. */
36
+ export interface TransportOutcome {
37
+ readonly kind: TransportOutcomeKind;
38
+ readonly httpStatus: Presence<number>;
39
+ /** Stable client/remote code without payload or secret material. */
40
+ readonly code: Presence<string>;
41
+ readonly message: string;
42
+ }
43
+ /**
44
+ * Classifies a value thrown by the Gateway transport.
45
+ *
46
+ * `undefined`/`null` means no error was observed and is classified as success;
47
+ * callers should normally pass a caught error. Any non-transport error is left
48
+ * as `delivery_uncertain` rather than `success` because the caller cannot prove
49
+ * the remote state either way.
50
+ */
51
+ export declare function classifyTransportOutcome(error: unknown): TransportOutcome;
52
+ /** Returns true when the remote state cannot be proven either way. */
53
+ export declare function isDeliveryUncertainOutcome(outcome: TransportOutcome): boolean;
54
+ /**
55
+ * Returns true when the Apps Script transport error implies an ambiguous
56
+ * delivery. Non-success HTTP responses are not proof that a mutating batch did
57
+ * not begin: Apps Script/proxy failures can be emitted after a partial remote
58
+ * write. Only a structured 2xx operation result can provide per-effect
59
+ * rejection evidence to the worker.
60
+ */
61
+ export declare function isDeliveryUncertain(error: AppsScriptSyncGatewayError): boolean;
62
+ //# sourceMappingURL=transportClassification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transportClassification.d.ts","sourceRoot":"","sources":["../../../../src/application/sync/gateway/transportClassification.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,0BAA0B,EAAmC,MAAM,iEAAiE,CAAC;AAE9I,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAE/D,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC;AAEX,MAAM,MAAM,oBAAoB,GAC9B,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,OAAO,uBAAuB,CAAC,CAAC;AAEzE,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACtC,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CA2BzE;AAED,sEAAsE;AACtE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAE7E;AA8BD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAwB9E"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Structured classification of a Gateway transport outcome.
3
+ *
4
+ * The Apps Script transport can fail for three very different reasons that the
5
+ * effect worker must not treat the same way:
6
+ *
7
+ * - `success`: a decoded, valid envelope was returned.
8
+ * - `explicit_remote_failure`: the remote returned a structured rejection that
9
+ * proves no operation ran (e.g. a signed-envelope validation failure). The
10
+ * remote state is known, so the effect can transition to a terminal failure
11
+ * state.
12
+ * - `delivery_uncertain`: the transport gave no usable answer (timeout,
13
+ * network error, non-JSON/404 response, lost connection), or the Gateway
14
+ * failed during/after operation execution (`operation_failed`,
15
+ * `internal_error`). The remote may or may not have committed the write, so
16
+ * the effect must be recovered through a postcondition probe rather than
17
+ * immediately redriven. Per-effect guard/schema/identity rejections are not
18
+ * transport errors at all: they arrive as per-effect result statuses in a
19
+ * successful envelope and keep their existing terminal handling.
20
+ *
21
+ * This boundary lets future durable `delivery_uncertain` state and recovery
22
+ * barriers classify a thrown transport error without re-deriving the rules at
23
+ * every call site. It never weakens correctness: an uncertain outcome is never
24
+ * promoted to `success`, and a proven pre-mutation rejection is never
25
+ * reclassified as a retryable transport error.
26
+ */
27
+ import { AppsScriptSyncGatewayError, SYNC_GATEWAY_CLIENT_ERROR_CODES } from "../../../adapter/sheets/providers/apps-script-gateway/errors.js";
28
+ import { PRESENCE_KINDS } from "../../../shared/state/index.js";
29
+ export const TRANSPORT_OUTCOME_KINDS = {
30
+ SUCCESS: "success",
31
+ EXPLICIT_REMOTE_FAILURE: "explicit_remote_failure",
32
+ DELIVERY_UNCERTAIN: "delivery_uncertain",
33
+ };
34
+ /**
35
+ * Classifies a value thrown by the Gateway transport.
36
+ *
37
+ * `undefined`/`null` means no error was observed and is classified as success;
38
+ * callers should normally pass a caught error. Any non-transport error is left
39
+ * as `delivery_uncertain` rather than `success` because the caller cannot prove
40
+ * the remote state either way.
41
+ */
42
+ export function classifyTransportOutcome(error) {
43
+ if (error === undefined || error === null) {
44
+ return {
45
+ kind: TRANSPORT_OUTCOME_KINDS.SUCCESS,
46
+ httpStatus: { kind: PRESENCE_KINDS.ABSENT },
47
+ code: { kind: PRESENCE_KINDS.ABSENT },
48
+ message: "",
49
+ };
50
+ }
51
+ if (error instanceof AppsScriptSyncGatewayError) {
52
+ const kind = isDeliveryUncertain(error)
53
+ ? TRANSPORT_OUTCOME_KINDS.DELIVERY_UNCERTAIN
54
+ : TRANSPORT_OUTCOME_KINDS.EXPLICIT_REMOTE_FAILURE;
55
+ return {
56
+ kind,
57
+ httpStatus: error.status,
58
+ code: error.remoteCode,
59
+ message: error.message,
60
+ };
61
+ }
62
+ // Unknown transport/Node error: assume the remote state is unverifiable.
63
+ return {
64
+ kind: TRANSPORT_OUTCOME_KINDS.DELIVERY_UNCERTAIN,
65
+ httpStatus: { kind: PRESENCE_KINDS.ABSENT },
66
+ code: { kind: PRESENCE_KINDS.ABSENT },
67
+ message: error instanceof Error ? error.message : "Unexpected transport failure",
68
+ };
69
+ }
70
+ /** Returns true when the remote state cannot be proven either way. */
71
+ export function isDeliveryUncertainOutcome(outcome) {
72
+ return outcome.kind === TRANSPORT_OUTCOME_KINDS.DELIVERY_UNCERTAIN;
73
+ }
74
+ /** Stable remote codes emitted by Code.gs that prove the request never mutated the Sheet. */
75
+ const PRE_MUTATION_REMOTE_CODES = new Set([
76
+ "method_not_allowed",
77
+ "invalid_request",
78
+ "invalid_json",
79
+ "unsupported_protocol",
80
+ "unsupported_operation",
81
+ "invalid_envelope",
82
+ "invalid_request_id",
83
+ "invalid_time",
84
+ "invalid_expiry",
85
+ "gateway_not_configured",
86
+ "sheet_not_allowlisted",
87
+ "unknown_key",
88
+ "invalid_payload",
89
+ "body_hash_mismatch",
90
+ "invalid_signature",
91
+ "sheet_open_failed",
92
+ ]);
93
+ /**
94
+ * Remote codes the Gateway emits only after an operation may have partially
95
+ * mutated the Sheet. `operation_failed` aborts the batch at the first throwing
96
+ * operation (writes from earlier phases can already be durable), and
97
+ * `internal_error` escapes the top-level handler after any number of phases.
98
+ */
99
+ const AMBIGUOUS_MUTATION_REMOTE_CODES = new Set(["operation_failed", "internal_error"]);
100
+ /**
101
+ * Returns true when the Apps Script transport error implies an ambiguous
102
+ * delivery. Non-success HTTP responses are not proof that a mutating batch did
103
+ * not begin: Apps Script/proxy failures can be emitted after a partial remote
104
+ * write. Only a structured 2xx operation result can provide per-effect
105
+ * rejection evidence to the worker.
106
+ */
107
+ export function isDeliveryUncertain(error) {
108
+ if (error.code === SYNC_GATEWAY_CLIENT_ERROR_CODES.TIMEOUT ||
109
+ error.code === SYNC_GATEWAY_CLIENT_ERROR_CODES.NETWORK_ERROR ||
110
+ error.code === SYNC_GATEWAY_CLIENT_ERROR_CODES.INVALID_RESPONSE ||
111
+ error.code === SYNC_GATEWAY_CLIENT_ERROR_CODES.INVALID_REDIRECT) {
112
+ return true;
113
+ }
114
+ if (error.code === SYNC_GATEWAY_CLIENT_ERROR_CODES.REMOTE_ERROR) {
115
+ // Batch-level failures emitted during or after operation execution can
116
+ // follow a partial remote mutation, so they must be probed instead of
117
+ // treated as terminal. Only codes the Gateway emits before any operation
118
+ // runs are provably non-mutating and may fail the batch explicitly.
119
+ if (error.remoteCode.kind === PRESENCE_KINDS.PRESENT) {
120
+ if (AMBIGUOUS_MUTATION_REMOTE_CODES.has(error.remoteCode.value))
121
+ return true;
122
+ if (PRE_MUTATION_REMOTE_CODES.has(error.remoteCode.value))
123
+ return false;
124
+ }
125
+ // An unrecognized structured failure cannot prove that no mutation began.
126
+ return true;
127
+ }
128
+ if (error.status.kind !== PRESENCE_KINDS.PRESENT)
129
+ return false;
130
+ const status = error.status.value;
131
+ return status === 404 || status === 408 || status === 429 || status >= 500;
132
+ }
133
+ //# sourceMappingURL=transportClassification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transportClassification.js","sourceRoot":"","sources":["../../../../src/application/sync/gateway/transportClassification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** Automatically resolves observed User_Input conflicts in favor of canonical SQLite state. */
2
+ import { type SyncConflict } from "../../../domain/index.js";
3
+ import { type TypedSheetsEntityMapping } from "../../orm/mapping/entityMapping.js";
4
+ import type { ResolvedWriterOptions } from "../../orm/persistence/support/contracts.js";
5
+ import type { PersistObservedRowInput } from "../../../infrastructure/storage/state/observation/observationTypes.js";
6
+ import { type FencingContext } from "../../../infrastructure/storage/index.js";
7
+ import type { SqlExecutor, SqlStorageAdapter } from "../../../adapter/persistence/contracts/sql.js";
8
+ /** Resolves existing unresolved conflicts before the sync supervisors start. */
9
+ export declare function autoResolveExistingMappedConflictsWithAdapter(storage: SqlStorageAdapter, mappings: readonly TypedSheetsEntityMapping[], writer: ResolvedWriterOptions): Promise<void>;
10
+ /** Renews the startup resolver fence without accepting a silent epoch takeover. */
11
+ export declare function renewAutomaticConflictResolutionLeaseWithSql(sql: SqlExecutor, fence: FencingContext, writer: ResolvedWriterOptions): Promise<FencingContext>;
12
+ /** Ensures one resolved conflict has an idempotent Sync_Conflicts audit effect. */
13
+ export declare function ensureMappedConflictAuditWithSql(sql: SqlExecutor, fence: FencingContext, writer: ResolvedWriterOptions, mapping: TypedSheetsEntityMapping, conflict: SyncConflict): Promise<void>;
14
+ /** Resolves newly persisted conflicts inside the caller's SQLite transaction. */
15
+ export declare function autoResolveMappedConflictsWithSql(sql: SqlExecutor, fence: FencingContext, writer: ResolvedWriterOptions, mapping: TypedSheetsEntityMapping, input: PersistObservedRowInput | undefined, conflictIds: readonly string[]): Promise<readonly string[]>;
16
+ /**
17
+ * Retries durable open conflicts after a later polling pass.
18
+ *
19
+ * A conflict deliberately remains OPEN while an older effect is processing so
20
+ * a late remote response cannot overwrite the system-wins decision. The open
21
+ * conflict row is the durable retry record; this pass re-reads it on every
22
+ * polling cycle and retries the same fenced resolution after the predecessor
23
+ * has become applied, superseded, or otherwise recoverable.
24
+ */
25
+ export declare function retryOpenMappedConflictsWithAdapter(storage: SqlStorageAdapter, mappings: readonly TypedSheetsEntityMapping[], writer: ResolvedWriterOptions, observedInputs?: readonly PersistObservedRowInput[]): Promise<number>;
26
+ //# sourceMappingURL=autoSystemConflictResolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoSystemConflictResolution.d.ts","sourceRoot":"","sources":["../../../../src/application/sync/inbound/autoSystemConflictResolution.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAK/F,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,0BAA0B,CAAC;AAkBlC,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,oCAAoC,CAAC;AAQ5C,OAAO,KAAK,EACV,qBAAqB,EACtB,MAAM,4CAA4C,CAAC;AAIpD,OAAO,KAAK,EACV,uBAAuB,EACxB,MAAM,uEAAuE,CAAC;AAmB/E,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAOpG,gFAAgF;AAChF,wBAAsB,6CAA6C,CACjE,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,SAAS,wBAAwB,EAAE,EAC7C,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAgDf;AAED,mFAAmF;AACnF,wBAAsB,4CAA4C,CAChE,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAwBzB;AAUD,mFAAmF;AACnF,wBAAsB,gCAAgC,CACpD,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAmCf;AAED,iFAAiF;AACjF,wBAAsB,iCAAiC,CACrD,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,wBAAwB,EACjC,KAAK,EAAE,uBAAuB,GAAG,SAAS,EAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CA4D5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,mCAAmC,CACvD,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,SAAS,wBAAwB,EAAE,EAC7C,MAAM,EAAE,qBAAqB,EAC7B,cAAc,GAAE,SAAS,uBAAuB,EAAO,GACtD,OAAO,CAAC,MAAM,CAAC,CA8EjB"}
@@ -0,0 +1,335 @@
1
+ /** Automatically resolves observed User_Input conflicts in favor of canonical SQLite state. */
2
+ import { candidateHash, } from "../../../domain/conflict/transitions.js";
3
+ import { CONFLICT_STATUSES, FIELD_OWNERSHIPS, LOOKUP_RESULT_KINDS, } from "../../../domain/index.js";
4
+ import { applicableValue, absentValue, notApplicableValue, presentValue, } from "../../../shared/state/index.js";
5
+ import { stableHash } from "../../../shared/encoding/stableEncode.js";
6
+ import { SYNC_GATEWAY_PROJECTIONS, } from "../gateway/constants.js";
7
+ import { syncConflictProjectionFields, } from "../gateway/conflictProjection.js";
8
+ import { createCandidateReconcileEffect, createResolutionProjectionEffect, } from "../outbound/projection/ProjectionEffectFactory.js";
9
+ import { requireTypedSheetsEntityProjection, } from "../../orm/mapping/entityMapping.js";
10
+ import { TYPED_SHEETS_ORM_ERROR_CODES, TypedSheetsOrmError, } from "../../orm/errors.js";
11
+ import { identifiedValue, } from "../../orm/persistence/support/helpers.js";
12
+ import { parseSyncProjectionEffectPayload, } from "../gateway/syncGateway.js";
13
+ import { appendResolutionEffectsWithSql, persistResolutionCommandWithSql, readConflictIdsWithSql, readConflictWithSql, readOpenConflictIdsWithSql, } from "../../../infrastructure/storage/state/resolution/resolutionWriter.js";
14
+ import { PERSIST_RESOLUTION_RESULT_KINDS } from "../../../infrastructure/storage/state/resolution/resolutionWriterContracts.js";
15
+ import { readMappedActiveCanonicalEntityWithSql, readMappedCanonicalFieldsWithSql, readMappedLatestProjectionEffectWithSql, readMappedRowBindingWithSql, readMappedVisibleProjectionStateWithSql, } from "../../../infrastructure/storage/state/mapped/mappedPersistenceSql.js";
16
+ import { requireRegisteredSyncSheetWithSql, } from "../../../infrastructure/storage/sync/shared/syncRegistry.js";
17
+ import { claimWriterLeaseWithSql, WRITER_LEASE_CLAIM_RESULT_KINDS, } from "../../../infrastructure/storage/index.js";
18
+ const RESOLUTION_ACTOR_ID = "sync:auto-system-wins";
19
+ const MAX_CONFLICTS_PER_LEASE_RENEWAL = 16;
20
+ const PROJECTION_ROW_TARGET_KIND = "projection_row";
21
+ const CONFLICT_TARGET_KIND = "conflict";
22
+ /** Resolves existing unresolved conflicts before the sync supervisors start. */
23
+ export async function autoResolveExistingMappedConflictsWithAdapter(storage, mappings, writer) {
24
+ await storage.transaction(async ({ sql }) => {
25
+ const initialNow = writer.now();
26
+ const claim = await claimWriterLeaseWithSql(sql, {
27
+ role: writer.role,
28
+ writerId: writer.writerId,
29
+ leaseDurationMs: writer.leaseDurationMs,
30
+ now: initialNow,
31
+ });
32
+ if (claim.kind !== WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED) {
33
+ throw new TypedSheetsOrmError(TYPED_SHEETS_ORM_ERROR_CODES.WRITER_LEASE_UNAVAILABLE, `automatic conflict resolver lease is unavailable: ${claim.reason}.`);
34
+ }
35
+ let fence = {
36
+ role: claim.lease.role,
37
+ writerEpoch: claim.lease.writerEpoch,
38
+ fencingToken: claim.lease.fencingToken,
39
+ now: initialNow,
40
+ };
41
+ for (const mapping of mappings) {
42
+ const conflictIds = await readOpenConflictIdsWithSql(sql, mapping.logicalSheetId);
43
+ const handledConflictIds = new Set(conflictIds);
44
+ for (const conflictBatch of chunkConflictIds(conflictIds)) {
45
+ fence = await renewAutomaticConflictResolutionLeaseWithSql(sql, fence, writer);
46
+ await autoResolveMappedConflictsWithSql(sql, fence, writer, mapping, undefined, conflictBatch);
47
+ }
48
+ const allConflictIds = await readConflictIdsWithSql(sql, mapping.logicalSheetId);
49
+ for (const conflictBatch of chunkConflictIds(allConflictIds)) {
50
+ fence = await renewAutomaticConflictResolutionLeaseWithSql(sql, fence, writer);
51
+ for (const conflictId of conflictBatch) {
52
+ if (handledConflictIds.has(conflictId))
53
+ continue;
54
+ const result = await readConflictWithSql(sql, mapping.logicalSheetId, conflictId);
55
+ if (result.kind === LOOKUP_RESULT_KINDS.FOUND && result.value.status === CONFLICT_STATUSES.RESOLVED) {
56
+ await ensureMappedConflictAuditWithSql(sql, fence, writer, mapping, result.value);
57
+ }
58
+ }
59
+ }
60
+ }
61
+ });
62
+ }
63
+ /** Renews the startup resolver fence without accepting a silent epoch takeover. */
64
+ export async function renewAutomaticConflictResolutionLeaseWithSql(sql, fence, writer) {
65
+ const now = Math.max(fence.now, writer.now());
66
+ const claim = await claimWriterLeaseWithSql(sql, {
67
+ role: writer.role,
68
+ writerId: writer.writerId,
69
+ leaseDurationMs: writer.leaseDurationMs,
70
+ now,
71
+ });
72
+ if (claim.kind !== WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED) {
73
+ throw new TypedSheetsOrmError(TYPED_SHEETS_ORM_ERROR_CODES.WRITER_LEASE_UNAVAILABLE, `automatic conflict resolver lease renewal is unavailable: ${claim.reason}.`);
74
+ }
75
+ if (claim.lease.writerEpoch !== fence.writerEpoch ||
76
+ claim.lease.fencingToken !== fence.fencingToken) {
77
+ throw new TypedSheetsOrmError(TYPED_SHEETS_ORM_ERROR_CODES.WRITER_LEASE_UNAVAILABLE, "automatic conflict resolver lease changed ownership while processing conflicts.");
78
+ }
79
+ return { ...fence, now };
80
+ }
81
+ function chunkConflictIds(conflictIds) {
82
+ const batches = [];
83
+ for (let index = 0; index < conflictIds.length; index += MAX_CONFLICTS_PER_LEASE_RENEWAL) {
84
+ batches.push(conflictIds.slice(index, index + MAX_CONFLICTS_PER_LEASE_RENEWAL));
85
+ }
86
+ return batches;
87
+ }
88
+ /** Ensures one resolved conflict has an idempotent Sync_Conflicts audit effect. */
89
+ export async function ensureMappedConflictAuditWithSql(sql, fence, writer, mapping, conflict) {
90
+ const conflictSheet = await requireRegisteredSyncSheetWithSql(sql, `${mapping.logicalSheetId}:sync_conflicts`);
91
+ const baseline = await nextEffectBaseline(sql, mapping.logicalSheetId, CONFLICT_TARGET_KIND, conflict.conflictId, 0, "", true, false);
92
+ const commitId = `audit:${conflict.conflictId}`;
93
+ const effect = createResolutionProjectionEffect({
94
+ effectId: identifiedValue("effect", writer),
95
+ commitId,
96
+ logicalSheetId: mapping.logicalSheetId,
97
+ physicalSheetId: conflictSheet.physicalSheetId,
98
+ sheetName: conflictSheet.tabName,
99
+ registeredRange: conflictSheet.registeredRange,
100
+ schemaVersion: mapping.schemaVersion,
101
+ targetId: conflict.conflictId,
102
+ rowBindingId: absentValue(),
103
+ conflictId: presentValue(conflict.conflictId),
104
+ targetAnchor: `conflict:${conflict.conflictId}`,
105
+ fields: syncConflictProjectionFields(conflict, "SYSTEM_WINS"),
106
+ createIfMissing: baseline.createIfMissing,
107
+ expectedVisibleRevision: baseline.expectedVisibleRevision,
108
+ expectedVisibleHash: baseline.expectedVisibleHash,
109
+ streamSequence: baseline.streamSequence,
110
+ });
111
+ await appendResolutionEffectsWithSql(sql, fence, [effect]);
112
+ }
113
+ /** Resolves newly persisted conflicts inside the caller's SQLite transaction. */
114
+ export async function autoResolveMappedConflictsWithSql(sql, fence, writer, mapping, input, conflictIds) {
115
+ if (conflictIds.length === 0)
116
+ return [];
117
+ const deferredConflictIds = [];
118
+ const userProjection = requireTypedSheetsEntityProjection(mapping, SYNC_GATEWAY_PROJECTIONS.USER_INPUT);
119
+ const userSheet = await requireRegisteredSyncSheetWithSql(sql, userProjection.physicalSheetId);
120
+ const conflictSheet = await requireRegisteredSyncSheetWithSql(sql, `${mapping.logicalSheetId}:sync_conflicts`);
121
+ for (const conflictId of conflictIds) {
122
+ const conflictResult = await readConflictWithSql(sql, mapping.logicalSheetId, conflictId);
123
+ if (conflictResult.kind !== LOOKUP_RESULT_KINDS.FOUND)
124
+ continue;
125
+ const conflict = conflictResult.value;
126
+ if (conflict.status === CONFLICT_STATUSES.RESOLVED)
127
+ continue;
128
+ const effects = await resolutionEffectsForConflict(sql, writer, mapping, input, conflict, userSheet, conflictSheet);
129
+ if (effects === undefined || effects.length === 0)
130
+ continue;
131
+ const commandId = `auto-system-wins:${conflict.conflictId}:${conflict.candidateEpoch}`;
132
+ const commitId = `auto-system-wins-commit:${conflict.conflictId}:${conflict.candidateEpoch}`;
133
+ const command = {
134
+ commandId,
135
+ requestKey: commandId,
136
+ action: "acknowledge_system",
137
+ actorId: RESOLUTION_ACTOR_ID,
138
+ role: "sync_operator",
139
+ targetConflictId: conflict.conflictId,
140
+ expectedRevision: conflict.currentCanonicalRevision,
141
+ activeCandidateHash: candidateHash(conflict),
142
+ expectedCandidateEpoch: conflict.candidateEpoch,
143
+ payloadHash: stableHash({
144
+ action: "acknowledge_system",
145
+ targetConflictId: conflict.conflictId,
146
+ expectedRevision: conflict.currentCanonicalRevision,
147
+ activeCandidateHash: candidateHash(conflict),
148
+ expectedCandidateEpoch: conflict.candidateEpoch,
149
+ }),
150
+ };
151
+ const resolutionResult = await persistResolutionCommandWithSql(sql, fence, {
152
+ logicalSheetId: mapping.logicalSheetId,
153
+ command,
154
+ commitId,
155
+ effects,
156
+ });
157
+ if (resolutionResult.kind === PERSIST_RESOLUTION_RESULT_KINDS.DEFERRED) {
158
+ deferredConflictIds.push(conflict.conflictId);
159
+ }
160
+ }
161
+ return deferredConflictIds;
162
+ }
163
+ /**
164
+ * Retries durable open conflicts after a later polling pass.
165
+ *
166
+ * A conflict deliberately remains OPEN while an older effect is processing so
167
+ * a late remote response cannot overwrite the system-wins decision. The open
168
+ * conflict row is the durable retry record; this pass re-reads it on every
169
+ * polling cycle and retries the same fenced resolution after the predecessor
170
+ * has become applied, superseded, or otherwise recoverable.
171
+ */
172
+ export async function retryOpenMappedConflictsWithAdapter(storage, mappings, writer, observedInputs = []) {
173
+ const candidates = await storage.read(async ({ sql }) => {
174
+ const result = [];
175
+ for (const mapping of mappings) {
176
+ if (!mapping.projections.some((projection) => projection.projection === SYNC_GATEWAY_PROJECTIONS.USER_INPUT)) {
177
+ continue;
178
+ }
179
+ const conflictIds = await readOpenConflictIdsWithSql(sql, mapping.logicalSheetId);
180
+ if (conflictIds.length > 0)
181
+ result.push({ mapping, conflictIds });
182
+ }
183
+ return result;
184
+ });
185
+ if (candidates.length === 0)
186
+ return 0;
187
+ const observedByBinding = new Map();
188
+ for (const observedInput of observedInputs) {
189
+ const row = observedInput.batch.rows[observedInput.rowIndex];
190
+ if (row === undefined)
191
+ continue;
192
+ observedByBinding.set(`${observedInput.physicalSheetId}:${row.rowBindingId}`, observedInput);
193
+ }
194
+ return storage.transaction(async ({ sql }) => {
195
+ const now = writer.now();
196
+ const claim = await claimWriterLeaseWithSql(sql, {
197
+ role: writer.role,
198
+ writerId: writer.writerId,
199
+ leaseDurationMs: writer.leaseDurationMs,
200
+ now,
201
+ });
202
+ // Another writer may be processing an observation. The next polling pass
203
+ // will retry the durable OPEN rows; do not turn a temporary lease race into
204
+ // a polling failure.
205
+ if (claim.kind !== WRITER_LEASE_CLAIM_RESULT_KINDS.CLAIMED)
206
+ return 0;
207
+ let fence = {
208
+ role: claim.lease.role,
209
+ writerEpoch: claim.lease.writerEpoch,
210
+ fencingToken: claim.lease.fencingToken,
211
+ now,
212
+ };
213
+ let attempted = 0;
214
+ for (const candidate of candidates) {
215
+ const currentIds = await readOpenConflictIdsWithSql(sql, candidate.mapping.logicalSheetId);
216
+ for (const conflictBatch of chunkConflictIds(currentIds)) {
217
+ fence = await renewAutomaticConflictResolutionLeaseWithSql(sql, fence, writer);
218
+ for (const conflictId of conflictBatch) {
219
+ const conflictResult = await readConflictWithSql(sql, candidate.mapping.logicalSheetId, conflictId);
220
+ if (conflictResult.kind !== LOOKUP_RESULT_KINDS.FOUND)
221
+ continue;
222
+ const userProjection = requireTypedSheetsEntityProjection(candidate.mapping, SYNC_GATEWAY_PROJECTIONS.USER_INPUT);
223
+ const observedInput = observedByBinding.get(`${userProjection.physicalSheetId}:${conflictResult.value.rowBindingId}`);
224
+ const deferred = await autoResolveMappedConflictsWithSql(sql, fence, writer, candidate.mapping, observedInput, [conflictId]);
225
+ attempted += deferred.length === 0 ? 1 : 0;
226
+ }
227
+ }
228
+ }
229
+ return attempted;
230
+ });
231
+ }
232
+ async function resolutionEffectsForConflict(sql, writer, mapping, input, conflict, userSheet, conflictSheet) {
233
+ const binding = await readMappedRowBindingWithSql(sql, conflict.rowBindingId);
234
+ if (binding === undefined || binding.entity_id === null)
235
+ return undefined;
236
+ const canonicalFields = await readMappedCanonicalFieldsWithSql(sql, conflict.entityId);
237
+ const userFields = {};
238
+ for (const field of mapping.fields) {
239
+ if (field.ownership !== FIELD_OWNERSHIPS.USER)
240
+ continue;
241
+ const value = canonicalFields[field.fieldName];
242
+ if (value === undefined)
243
+ return undefined;
244
+ userFields[field.fieldName] = value;
245
+ }
246
+ const visible = await readMappedVisibleProjectionStateWithSql(sql, userSheet.physicalSheetId, SYNC_GATEWAY_PROJECTIONS.USER_INPUT, conflict.rowBindingId);
247
+ const observed = input?.observedProjection;
248
+ const userVisibleRevision = observed?.visibleRevision ?? visible?.confirmed_visible_revision;
249
+ const userVisibleHash = observed?.visibleHash ?? visible?.confirmed_snapshot_hash;
250
+ if (userVisibleRevision === undefined || userVisibleHash === undefined)
251
+ return undefined;
252
+ const entity = await readMappedActiveCanonicalEntityWithSql(sql, conflict.entityId);
253
+ const userTargetId = `projection-row:${userSheet.physicalSheetId}:${conflict.rowBindingId}`;
254
+ const userBaseline = await nextEffectBaseline(sql, mapping.logicalSheetId, PROJECTION_ROW_TARGET_KIND, userTargetId, userVisibleRevision, userVisibleHash, false, true);
255
+ const conflictTargetId = conflict.conflictId;
256
+ const conflictBaseline = await nextEffectBaseline(sql, mapping.logicalSheetId, CONFLICT_TARGET_KIND, conflictTargetId, 0, "", true, false);
257
+ const resolvedConflict = {
258
+ ...conflict,
259
+ status: CONFLICT_STATUSES.RESOLVED,
260
+ resolutionCommandId: presentValue(`auto-system-wins:${conflict.conflictId}:${conflict.candidateEpoch}`),
261
+ };
262
+ const commitId = `auto-system-wins-commit:${conflict.conflictId}:${conflict.candidateEpoch}`;
263
+ const userEffect = createCandidateReconcileEffect({
264
+ effectId: identifiedValue("effect", writer),
265
+ commitId,
266
+ logicalSheetId: mapping.logicalSheetId,
267
+ physicalSheetId: userSheet.physicalSheetId,
268
+ sheetName: userSheet.tabName,
269
+ registeredRange: userSheet.registeredRange,
270
+ schemaVersion: mapping.schemaVersion,
271
+ targetKind: PROJECTION_ROW_TARGET_KIND,
272
+ targetId: userTargetId,
273
+ rowBindingId: presentValue(conflict.rowBindingId),
274
+ conflictId: absentValue(),
275
+ targetAnchor: binding.anchor_reference,
276
+ fields: userFields,
277
+ createIfMissing: false,
278
+ expectedVisibleRevision: userBaseline.expectedVisibleRevision,
279
+ expectedVisibleHash: userBaseline.expectedVisibleHash,
280
+ expectedCandidateHash: applicableValue(candidateHash(conflict)),
281
+ targetEntityRevision: entity === undefined
282
+ ? notApplicableValue()
283
+ : applicableValue(entity.entity_revision),
284
+ streamSequence: userBaseline.streamSequence,
285
+ });
286
+ const conflictEffect = createResolutionProjectionEffect({
287
+ effectId: identifiedValue("effect", writer),
288
+ commitId,
289
+ logicalSheetId: mapping.logicalSheetId,
290
+ physicalSheetId: conflictSheet.physicalSheetId,
291
+ sheetName: conflictSheet.tabName,
292
+ registeredRange: conflictSheet.registeredRange,
293
+ schemaVersion: mapping.schemaVersion,
294
+ targetId: conflictTargetId,
295
+ rowBindingId: absentValue(),
296
+ conflictId: presentValue(conflict.conflictId),
297
+ targetAnchor: `conflict:${conflict.conflictId}`,
298
+ fields: syncConflictProjectionFields(resolvedConflict, "SYSTEM_WINS"),
299
+ createIfMissing: conflictBaseline.createIfMissing,
300
+ expectedVisibleRevision: conflictBaseline.expectedVisibleRevision,
301
+ expectedVisibleHash: conflictBaseline.expectedVisibleHash,
302
+ streamSequence: conflictBaseline.streamSequence,
303
+ });
304
+ return [userEffect, conflictEffect];
305
+ }
306
+ async function nextEffectBaseline(sql, logicalSheetId, targetKind, targetId, fallbackVisibleRevision, fallbackVisibleHash, fallbackCreateIfMissing, preferFallbackForUnresolved) {
307
+ const latest = await readMappedLatestProjectionEffectWithSql(sql, logicalSheetId, targetKind, targetId);
308
+ if (latest === undefined) {
309
+ return {
310
+ expectedVisibleRevision: fallbackVisibleRevision,
311
+ expectedVisibleHash: fallbackVisibleHash,
312
+ createIfMissing: fallbackCreateIfMissing,
313
+ streamSequence: 1,
314
+ };
315
+ }
316
+ const payload = parseSyncProjectionEffectPayload(latest.payload_json);
317
+ const unresolved = latest.status !== "applied";
318
+ return {
319
+ expectedVisibleRevision: unresolved && preferFallbackForUnresolved
320
+ ? fallbackVisibleRevision
321
+ : unresolved
322
+ ? latest.expected_visible_revision
323
+ : latest.expected_visible_revision + 1,
324
+ expectedVisibleHash: unresolved && preferFallbackForUnresolved
325
+ ? fallbackVisibleHash
326
+ : unresolved
327
+ ? latest.expected_visible_hash
328
+ : payload.targetVisibleHash,
329
+ createIfMissing: unresolved
330
+ ? preferFallbackForUnresolved ? fallbackCreateIfMissing : payload.createIfMissing
331
+ : false,
332
+ streamSequence: latest.stream_sequence + 1,
333
+ };
334
+ }
335
+ //# sourceMappingURL=autoSystemConflictResolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autoSystemConflictResolution.js","sourceRoot":"","sources":["../../../../src/application/sync/inbound/autoSystemConflictResolution.ts"],"names":[],"mappings":"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"}