hikoutei 0.3.3 → 0.3.5

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 (130) hide show
  1. package/README.md +88 -15
  2. package/apps-script/gateway/appsscript.json +17 -0
  3. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +9 -1
  4. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -1
  5. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +9 -1
  6. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -1
  7. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +1 -1
  8. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +1 -1
  9. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +18 -10
  10. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +1 -1
  11. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +157 -27
  12. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +1 -1
  13. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +4 -2
  14. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -1
  15. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +4 -2
  16. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -1
  17. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts +27 -0
  18. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts.map +1 -0
  19. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js +14 -0
  20. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js.map +1 -0
  21. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +156 -0
  22. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -0
  23. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +1138 -0
  24. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -0
  25. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts +87 -0
  26. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts.map +1 -0
  27. package/dist/adapter/sheets/providers/google-sheets-api/constants.js +97 -0
  28. package/dist/adapter/sheets/providers/google-sheets-api/constants.js.map +1 -0
  29. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts +53 -0
  30. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts.map +1 -0
  31. package/dist/adapter/sheets/providers/google-sheets-api/errors.js +61 -0
  32. package/dist/adapter/sheets/providers/google-sheets-api/errors.js.map +1 -0
  33. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts +18 -0
  34. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts.map +1 -0
  35. package/dist/adapter/sheets/providers/google-sheets-api/index.js +14 -0
  36. package/dist/adapter/sheets/providers/google-sheets-api/index.js.map +1 -0
  37. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +83 -0
  38. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -0
  39. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js +413 -0
  40. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -0
  41. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts +86 -0
  42. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -0
  43. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js +439 -0
  44. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js.map +1 -0
  45. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts +115 -0
  46. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -0
  47. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js +522 -0
  48. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js.map +1 -0
  49. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts +17 -0
  50. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -0
  51. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js +99 -0
  52. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -0
  53. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts +242 -0
  54. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts.map +1 -0
  55. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js +707 -0
  56. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js.map +1 -0
  57. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +16 -0
  58. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +1 -0
  59. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +29 -0
  60. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +1 -0
  61. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts +26 -0
  62. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts.map +1 -0
  63. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js +57 -0
  64. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js.map +1 -0
  65. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts +102 -0
  66. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts.map +1 -0
  67. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js +375 -0
  68. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js.map +1 -0
  69. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +168 -0
  70. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts.map +1 -0
  71. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +247 -0
  72. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -0
  73. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +47 -0
  74. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +1 -0
  75. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js +60 -0
  76. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +1 -0
  77. package/dist/application/sync/gateway/RoutedSyncGateway.d.ts +59 -0
  78. package/dist/application/sync/gateway/RoutedSyncGateway.d.ts.map +1 -0
  79. package/dist/application/sync/gateway/RoutedSyncGateway.js +86 -0
  80. package/dist/application/sync/gateway/RoutedSyncGateway.js.map +1 -0
  81. package/dist/application/sync/gateway/transportClassification.d.ts +12 -0
  82. package/dist/application/sync/gateway/transportClassification.d.ts.map +1 -1
  83. package/dist/application/sync/gateway/transportClassification.js +37 -0
  84. package/dist/application/sync/gateway/transportClassification.js.map +1 -1
  85. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +16 -0
  86. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -1
  87. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +26 -0
  88. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -1
  89. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
  90. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +23 -3
  91. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
  92. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +15 -0
  93. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
  94. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +61 -8
  95. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
  96. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +15 -0
  97. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
  98. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +15 -0
  99. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
  100. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +4 -0
  101. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
  102. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +16 -0
  103. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
  104. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +8 -0
  105. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
  106. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +22 -2
  107. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
  108. package/dist/application/sync/service/SyncServiceBootstrap.d.ts +23 -1
  109. package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
  110. package/dist/application/sync/service/SyncServiceBootstrap.js +162 -8
  111. package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
  112. package/dist/infrastructure/storage/index.d.ts +1 -1
  113. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  114. package/dist/infrastructure/storage/index.js +1 -1
  115. package/dist/infrastructure/storage/index.js.map +1 -1
  116. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +12 -0
  117. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
  118. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +22 -1
  119. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
  120. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +10 -0
  121. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
  122. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +38 -0
  123. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
  124. package/docs/architecture.md +57 -13
  125. package/docs/ci.md +47 -23
  126. package/docs/development.md +35 -5
  127. package/docs/quick-start.md +43 -11
  128. package/docs/sync-bulk-write-benchmark.md +561 -0
  129. package/docs/write-and-synchronization-flow.md +70 -14
  130. package/package.json +6 -3
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Narrow transport contract for the direct Google Sheets API provider.
3
+ *
4
+ * All Google SDK types stay behind this module: the rest of the provider
5
+ * works with a small discriminated union of write requests and treats every
6
+ * response as an untrusted `unknown` value that the preflight/reply modules
7
+ * validate with runtime guards. Tests implement the same interface with an
8
+ * in-memory spreadsheet model, so the planner and batch builder are exercised
9
+ * without credentials or network access.
10
+ */
11
+ import { GoogleAuth } from "google-auth-library";
12
+ import { sheets } from "@googleapis/sheets";
13
+ import { presentValue, absentValue } from "../../../../../shared/state/index.js";
14
+ import { GOOGLE_SHEETS_API_SCOPES } from "../constants.js";
15
+ import { GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES, GoogleSheetsApiTransportError, } from "../errors.js";
16
+ /**
17
+ * Real transport over the Google Sheets REST API.
18
+ *
19
+ * gaxios auto-retry is disabled for every call: retries are the durable
20
+ * worker/recovery path's job, and a retried mutating request could replay an
21
+ * already committed batch. All errors are mapped to
22
+ * `GoogleSheetsApiTransportError` before leaving this module.
23
+ */
24
+ export class GoogleSheetsApiHttpTransport {
25
+ client;
26
+ requestTimeoutMs;
27
+ constructor(options) {
28
+ // google-auth-library may resolve to a version nested under googleapis-common
29
+ // that differs from the top-level one; the boundary cast keeps the SDK
30
+ // version mismatch contained in this module.
31
+ const auth = options.auth ??
32
+ new GoogleAuth({ scopes: [...GOOGLE_SHEETS_API_SCOPES] });
33
+ // The sheets factory accepts GoogleAuth; the narrow wrapper below owns the
34
+ // SDK boundary so no other provider code touches the client type.
35
+ this.client = sheets({ version: "v4", auth });
36
+ this.requestTimeoutMs = options.requestTimeoutMs;
37
+ }
38
+ async getSpreadsheet(request) {
39
+ try {
40
+ const response = await this.client.spreadsheets.get({
41
+ spreadsheetId: request.spreadsheetId,
42
+ ranges: [...request.ranges],
43
+ fields: request.fields,
44
+ }, { timeout: request.timeoutMs ?? this.requestTimeoutMs, retry: false });
45
+ return response.data;
46
+ }
47
+ catch (error) {
48
+ throw classifyGoogleSheetsApiError(error);
49
+ }
50
+ }
51
+ async batchUpdate(request) {
52
+ try {
53
+ const response = await this.client.spreadsheets.batchUpdate({
54
+ spreadsheetId: request.spreadsheetId,
55
+ // The body comes from the same builder that
56
+ // `serializeBatchUpdateRequests` measures, so the batch builder's
57
+ // byte budget is exact for what gaxios sends on the wire.
58
+ requestBody: toSdkBatchUpdateBody(request.requests),
59
+ }, { timeout: this.requestTimeoutMs, retry: false });
60
+ return response.data;
61
+ }
62
+ catch (error) {
63
+ throw classifyGoogleSheetsApiError(error);
64
+ }
65
+ }
66
+ }
67
+ /**
68
+ * Maps a thrown SDK/gaxios/network error to the provider transport error.
69
+ *
70
+ * Exported separately so tests can exercise the mapping with shaped fixtures
71
+ * instead of real network failures. Any error without a proven HTTP status is
72
+ * classified conservatively as delivery-uncertain material (network/timeout),
73
+ * never as a proven pre-mutation rejection.
74
+ */
75
+ export function classifyGoogleSheetsApiError(error) {
76
+ const shape = extractGaxiosErrorShape(error);
77
+ if (shape.status !== undefined) {
78
+ const remoteCode = typeof shape.apiErrorStatus === "string" &&
79
+ shape.apiErrorStatus.length > 0
80
+ ? shape.apiErrorStatus
81
+ : String(shape.status);
82
+ return new GoogleSheetsApiTransportError(GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.HTTP_ERROR, "Google Sheets API request failed", presentValue(shape.status), presentValue(remoteCode));
83
+ }
84
+ if (isTimeoutError(error, shape.code)) {
85
+ return new GoogleSheetsApiTransportError(GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.TIMEOUT, "Google Sheets API request timed out", absentValue(), shape.code === undefined
86
+ ? absentValue()
87
+ : presentValue(shape.code));
88
+ }
89
+ return new GoogleSheetsApiTransportError(GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.NETWORK_ERROR, "Google Sheets API transport failed", absentValue(), shape.code === undefined
90
+ ? absentValue()
91
+ : presentValue(shape.code));
92
+ }
93
+ function extractGaxiosErrorShape(error) {
94
+ if (error === null || typeof error !== "object") {
95
+ return { code: undefined, status: undefined, apiErrorStatus: undefined };
96
+ }
97
+ const record = error;
98
+ const code = typeof record.code === "string" ? record.code : undefined;
99
+ const response = record.response;
100
+ const responseRecord = response !== null && typeof response === "object"
101
+ ? response
102
+ : undefined;
103
+ const rawStatus = responseRecord?.status;
104
+ const status = typeof rawStatus === "number" && Number.isInteger(rawStatus)
105
+ ? rawStatus
106
+ : typeof rawStatus === "string" && /^\d{3}$/.test(rawStatus)
107
+ ? Number(rawStatus)
108
+ : undefined;
109
+ let apiErrorStatus;
110
+ const data = responseRecord?.data;
111
+ const dataRecord = data !== null && typeof data === "object"
112
+ ? data
113
+ : undefined;
114
+ const errorBody = dataRecord?.error;
115
+ const errorRecord = errorBody !== null && typeof errorBody === "object"
116
+ ? errorBody
117
+ : undefined;
118
+ const rawApiStatus = errorRecord?.status;
119
+ if (typeof rawApiStatus === "string" && rawApiStatus.length > 0) {
120
+ apiErrorStatus = rawApiStatus;
121
+ }
122
+ return { code, status, apiErrorStatus };
123
+ }
124
+ function isTimeoutError(error, code) {
125
+ if (code !== undefined && /TIMEOUT|TIMEDOUT|DEADLINE|ABORTED|ETIMEDOUT/i.test(code)) {
126
+ return true;
127
+ }
128
+ return error instanceof Error && /timeout|timed out|deadline exceeded/i.test(error.message);
129
+ }
130
+ /**
131
+ * Builds the SDK batchUpdate body from provider write requests. The SDK
132
+ * request union is wider than the provider's narrow shapes; this boundary
133
+ * cast is the only place both types meet.
134
+ */
135
+ export function toSdkBatchUpdateBody(requests) {
136
+ return {
137
+ requests: requests.map(toSdkRequest),
138
+ };
139
+ }
140
+ /**
141
+ * Serializes the batchUpdate body exactly as the transport sends it, so the
142
+ * batch builder's byte budget measures the real wire bytes (SDK-wrapped
143
+ * request shapes, not the internal request union).
144
+ */
145
+ export function serializeBatchUpdateRequests(requests) {
146
+ return JSON.stringify(toSdkBatchUpdateBody(requests));
147
+ }
148
+ /** Maps one provider write request to the Google SDK request shape. */
149
+ function toSdkRequest(request) {
150
+ switch (request.kind) {
151
+ case "addSheet":
152
+ return { addSheet: { properties: { title: request.title, sheetId: request.sheetId } } };
153
+ case "updateSheetProperties":
154
+ return {
155
+ updateSheetProperties: {
156
+ properties: { sheetId: request.sheetId, hidden: request.hidden },
157
+ fields: "hidden",
158
+ },
159
+ };
160
+ case "updateCells":
161
+ return {
162
+ updateCells: {
163
+ start: {
164
+ sheetId: request.sheetId,
165
+ rowIndex: request.startRowIndex,
166
+ columnIndex: request.startColumnIndex,
167
+ },
168
+ rows: request.rows.map(toSdkRow),
169
+ fields: request.fields,
170
+ },
171
+ };
172
+ case "insertDimension":
173
+ return {
174
+ insertDimension: {
175
+ range: {
176
+ sheetId: request.sheetId,
177
+ dimension: request.dimension,
178
+ startIndex: request.startIndex,
179
+ endIndex: request.endIndex,
180
+ },
181
+ inheritFromBefore: request.inheritFromBefore,
182
+ },
183
+ };
184
+ case "deleteDimension":
185
+ return {
186
+ deleteDimension: {
187
+ range: {
188
+ sheetId: request.sheetId,
189
+ dimension: request.dimension,
190
+ startIndex: request.startIndex,
191
+ endIndex: request.endIndex,
192
+ },
193
+ },
194
+ };
195
+ case "setDataValidation":
196
+ return {
197
+ setDataValidation: {
198
+ range: {
199
+ sheetId: request.sheetId,
200
+ startRowIndex: request.startRowIndex,
201
+ endRowIndex: request.endRowIndex,
202
+ startColumnIndex: request.startColumnIndex,
203
+ endColumnIndex: request.endColumnIndex,
204
+ },
205
+ rule: {
206
+ condition: { type: "BOOLEAN" },
207
+ strict: request.strict,
208
+ },
209
+ },
210
+ };
211
+ case "createDeveloperMetadata":
212
+ return {
213
+ createDeveloperMetadata: {
214
+ developerMetadata: {
215
+ metadataKey: request.key,
216
+ metadataValue: request.value,
217
+ location: {
218
+ dimensionRange: {
219
+ sheetId: request.sheetId,
220
+ dimension: "ROWS",
221
+ startIndex: request.rowIndex,
222
+ endIndex: request.rowIndex + 1,
223
+ },
224
+ },
225
+ // DOCUMENT-scoped metadata is visible across Cloud projects, so
226
+ // anchors written by the service-account project stay findable by
227
+ // the Apps Script project (and vice versa) in mixed mode.
228
+ visibility: "DOCUMENT",
229
+ },
230
+ },
231
+ };
232
+ case "deleteSheet":
233
+ return { deleteSheet: { sheetId: request.sheetId } };
234
+ }
235
+ }
236
+ function toSdkRow(row) {
237
+ return { values: row.map(toSdkCell) };
238
+ }
239
+ function toSdkCell(cell) {
240
+ if (cell === null)
241
+ return {};
242
+ return {
243
+ ...(cell.userEnteredValue === undefined ? {} : { userEnteredValue: cell.userEnteredValue }),
244
+ ...(cell.userEnteredFormat === undefined ? {} : { userEnteredFormat: cell.userEnteredFormat }),
245
+ };
246
+ }
247
+ //# sourceMappingURL=googleSheetsApiTransport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"googleSheetsApiTransport.js","sourceRoot":"","sources":["../../../../../../src/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Request-start interval limiter used by the direct Sheets provider.
3
+ *
4
+ * Google Sheets quota windows are per 100 seconds, so bursty request starts
5
+ * can exhaust a class's budget before the worker's own latency/backoff reacts.
6
+ * The provider keeps two independent limiters (reads, writes) that only wait
7
+ * the time remaining since that class's last request START; an idle class is
8
+ * never throttled and concurrent classes never serialize against each other.
9
+ */
10
+ export interface RequestStartLimiterOptions {
11
+ /** Minimum interval between two request starts of this limiter class. */
12
+ readonly intervalMs: number;
13
+ /** Injectable clock for deterministic tests; defaults to Date.now. */
14
+ readonly now?: () => number;
15
+ /** Injectable sleep used while waiting for the next slot. */
16
+ readonly sleep?: (ms: number) => Promise<void>;
17
+ }
18
+ /**
19
+ * Waits only the remaining interval since the previous request start.
20
+ *
21
+ * Returns the number of milliseconds actually waited. A limiter with a zero
22
+ * interval never waits and records every start.
23
+ */
24
+ export declare class RequestStartLimiter {
25
+ private readonly intervalMs;
26
+ private readonly now;
27
+ private readonly sleep;
28
+ private lastStartAt;
29
+ constructor(options: RequestStartLimiterOptions);
30
+ /** Returns the last recorded request start, when one exists. */
31
+ lastStart(): number | undefined;
32
+ /**
33
+ * Waits for the next request-start slot and records the start time.
34
+ *
35
+ * Returns the number of milliseconds actually waited. A limiter with a zero
36
+ * interval never waits and records every start.
37
+ *
38
+ * The slot reservation happens SYNCHRONOUSLY before any await: each caller
39
+ * reserves the NEXT slot (`nextStart = max(now, lastStartAt + intervalMs)`)
40
+ * and records it immediately, so two concurrent waiters can never compute
41
+ * the same remaining time from the same `lastStartAt`, sleep together, and
42
+ * start at the same instant. A caller that arrives after its reserved slot
43
+ * has already passed waits zero (its reservation collapses to now).
44
+ */
45
+ waitForSlot(): Promise<number>;
46
+ }
47
+ //# sourceMappingURL=rateLimiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.d.ts","sourceRoot":"","sources":["../../../../../../src/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,WAAW,0BAA0B;IACzC,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;IACtD,OAAO,CAAC,WAAW,CAAqB;gBAErB,OAAO,EAAE,0BAA0B;IAStD,gEAAgE;IACzD,SAAS,IAAI,MAAM,GAAG,SAAS;IAItC;;;;;;;;;;;;OAYG;IACU,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;CAY5C"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Request-start interval limiter used by the direct Sheets provider.
3
+ *
4
+ * Google Sheets quota windows are per 100 seconds, so bursty request starts
5
+ * can exhaust a class's budget before the worker's own latency/backoff reacts.
6
+ * The provider keeps two independent limiters (reads, writes) that only wait
7
+ * the time remaining since that class's last request START; an idle class is
8
+ * never throttled and concurrent classes never serialize against each other.
9
+ */
10
+ const DEFAULT_SLEEP = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
11
+ /**
12
+ * Waits only the remaining interval since the previous request start.
13
+ *
14
+ * Returns the number of milliseconds actually waited. A limiter with a zero
15
+ * interval never waits and records every start.
16
+ */
17
+ export class RequestStartLimiter {
18
+ intervalMs;
19
+ now;
20
+ sleep;
21
+ lastStartAt;
22
+ constructor(options) {
23
+ if (!Number.isSafeInteger(options.intervalMs) || options.intervalMs < 0) {
24
+ throw new RangeError("request-start interval must be a non-negative safe integer");
25
+ }
26
+ this.intervalMs = options.intervalMs;
27
+ this.now = options.now ?? Date.now;
28
+ this.sleep = options.sleep ?? DEFAULT_SLEEP;
29
+ }
30
+ /** Returns the last recorded request start, when one exists. */
31
+ lastStart() {
32
+ return this.lastStartAt;
33
+ }
34
+ /**
35
+ * Waits for the next request-start slot and records the start time.
36
+ *
37
+ * Returns the number of milliseconds actually waited. A limiter with a zero
38
+ * interval never waits and records every start.
39
+ *
40
+ * The slot reservation happens SYNCHRONOUSLY before any await: each caller
41
+ * reserves the NEXT slot (`nextStart = max(now, lastStartAt + intervalMs)`)
42
+ * and records it immediately, so two concurrent waiters can never compute
43
+ * the same remaining time from the same `lastStartAt`, sleep together, and
44
+ * start at the same instant. A caller that arrives after its reserved slot
45
+ * has already passed waits zero (its reservation collapses to now).
46
+ */
47
+ async waitForSlot() {
48
+ const now = this.now();
49
+ const nextStart = this.lastStartAt === undefined
50
+ ? now
51
+ : Math.max(now, this.lastStartAt + this.intervalMs);
52
+ this.lastStartAt = nextStart;
53
+ const waited = Math.max(0, nextStart - now);
54
+ if (waited > 0) {
55
+ await this.sleep(waited);
56
+ }
57
+ return waited;
58
+ }
59
+ }
60
+ //# sourceMappingURL=rateLimiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rateLimiter.js","sourceRoot":"","sources":["../../../../../../src/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,aAAa,GAAG,CAAC,EAAU,EAAiB,EAAE,CAClD,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAW1D;;;;;GAKG;AACH,MAAM,OAAO,mBAAmB;IACb,UAAU,CAAS;IACnB,GAAG,CAAe;IAClB,KAAK,CAAgC;IAC9C,WAAW,CAAqB;IAExC,YAAmB,OAAmC;QACpD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;YACxE,MAAM,IAAI,UAAU,CAAC,4DAA4D,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;IAC9C,CAAC;IAED,gEAAgE;IACzD,SAAS;QACd,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,KAAK,CAAC,WAAW;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,KAAK,SAAS;YAC9C,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC,CAAC;QAC5C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Provider-neutral router composing a direct outbound provider with the
3
+ * observation/provisioning provider.
4
+ *
5
+ * The router implements the same gateway boundary the worker and polling
6
+ * already use, so no caller changes are required: outbound effect work
7
+ * (fast append, applyEffects, postcondition reads) goes to the direct Google
8
+ * Sheets provider, while anchor observation, snapshot/table reads, and
9
+ * provisioning stay on the Apps Script gateway (or an injected gateway +
10
+ * provisioner). The sync service bootstrap wraps the router in the
11
+ * per-spreadsheet mutation coordinator so direct writes and anchor
12
+ * observation share one in-process mutation lane.
13
+ */
14
+ import type { ApplySyncEffectsRequest, ApplySyncEffectsResult, EnsureSyncRowAnchorsRequest, EnsureSyncRowAnchorsResult, FastAppendRowsRequest, FastAppendRowsResult, ReadSyncEffectPostconditionsRequest, ReadSyncSnapshotRequest, ReadSyncTableRowsRequest, SyncEffectPostcondition, SyncEffectWorkerFullGateway, SyncGatewayEffect, SyncGatewayEffectPostconditionResult, SyncGatewaySnapshot, SyncObservedSnapshot, SyncSheetGateway, SyncSheetTableReaderGateway, SyncTableRowsResult } from "./syncGateway.js";
15
+ import type { SyncGatewayProvisioner, SyncGatewayProvisionRoute } from "./SyncGatewayBootstrap.js";
16
+ /** Delegates for the routed gateway. */
17
+ export interface RoutedSyncGatewayOptions {
18
+ /** Direct outbound provider: fast append, effects, postcondition reads. */
19
+ readonly outbound: SyncEffectWorkerFullGateway;
20
+ /** Observation provider: anchors, snapshots, table reads. */
21
+ readonly observation: SyncSheetGateway & SyncSheetTableReaderGateway;
22
+ /** Optional provisioning delegate; defaults to the observation provider. */
23
+ readonly provisioner?: SyncGatewayProvisioner;
24
+ }
25
+ /**
26
+ * @deprecated Legacy composition used only by the deprecated mixed
27
+ * `googleApiWorker` bootstrap mode. The preferred `googleSheetsApi` mode
28
+ * uses the full direct provider directly, so this router (and the Apps
29
+ * Script observation half it routes to) is no longer needed for new setups.
30
+ */
31
+ export declare class RoutedSyncGateway implements SyncSheetGateway, SyncSheetTableReaderGateway, SyncGatewayProvisioner {
32
+ private readonly outbound;
33
+ private readonly observation;
34
+ private readonly provisioner;
35
+ constructor(options: RoutedSyncGatewayOptions);
36
+ /** Sends append-only rows through the direct outbound provider. */
37
+ fastAppendRows(request: FastAppendRowsRequest): Promise<FastAppendRowsResult>;
38
+ /** Sends regular effect writes through the direct outbound provider. */
39
+ applyEffects(request: ApplySyncEffectsRequest): Promise<ApplySyncEffectsResult>;
40
+ /** Reads one effect postcondition through the direct outbound provider. */
41
+ readEffectPostcondition(effect: SyncGatewayEffect): Promise<SyncEffectPostcondition>;
42
+ /** Reads a batch of postconditions through the direct outbound provider. */
43
+ readEffectPostconditions(request: ReadSyncEffectPostconditionsRequest): Promise<readonly SyncGatewayEffectPostconditionResult[]>;
44
+ /** Ensures row anchors through the observation provider. */
45
+ ensureRowAnchors(request: EnsureSyncRowAnchorsRequest): Promise<EnsureSyncRowAnchorsResult>;
46
+ /** Reads snapshots through the observation provider. */
47
+ readSnapshot(request: ReadSyncSnapshotRequest): Promise<SyncGatewaySnapshot>;
48
+ /** Shares the observation provider's combined observation capability. */
49
+ observeSnapshot(request: ReadSyncSnapshotRequest): Promise<SyncObservedSnapshot>;
50
+ /** Shares one observation request across the supplied projections. */
51
+ observeSnapshots(requests: readonly ReadSyncSnapshotRequest[]): Promise<readonly SyncObservedSnapshot[]>;
52
+ /** Reads one registered table through the observation provider. */
53
+ readRows(request: ReadSyncTableRowsRequest): Promise<SyncTableRowsResult>;
54
+ /** Reads several registered tables through the observation provider. */
55
+ readRowsBatch(requests: readonly ReadSyncTableRowsRequest[]): Promise<readonly SyncTableRowsResult[]>;
56
+ /** Provisions the registered projections through the provisioning delegate. */
57
+ provisionRegistry(registrations: readonly SyncGatewayProvisionRoute[]): ReturnType<SyncGatewayProvisioner["provisionRegistry"]>;
58
+ }
59
+ //# sourceMappingURL=RoutedSyncGateway.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoutedSyncGateway.d.ts","sourceRoot":"","sources":["../../../../src/application/sync/gateway/RoutedSyncGateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,oBAAoB,EACpB,mCAAmC,EACnC,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,2BAA2B,EAC3B,iBAAiB,EACjB,oCAAoC,EACpC,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AAMnC,wCAAwC;AACxC,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;IAC/C,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,EAAE,gBAAgB,GAAG,2BAA2B,CAAC;IACrE,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,CAAC,EAAE,sBAAsB,CAAC;CAC/C;AAED;;;;;GAKG;AACH,qBAAa,iBACX,YAAW,gBAAgB,EAAE,2BAA2B,EAAE,sBAAsB;IAChF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiD;IAC7E,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyB;gBAElC,OAAO,EAAE,wBAAwB;IAapD,mEAAmE;IAC5D,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIpF,wEAAwE;IACjE,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAItF,2EAA2E;IACpE,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAI3F,4EAA4E;IACrE,wBAAwB,CAC7B,OAAO,EAAE,mCAAmC,GAC3C,OAAO,CAAC,SAAS,oCAAoC,EAAE,CAAC;IAI3D,4DAA4D;IACrD,gBAAgB,CACrB,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,0BAA0B,CAAC;IAItC,wDAAwD;IACjD,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAInF,yEAAyE;IAClE,eAAe,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAIvF,sEAAsE;IAC/D,gBAAgB,CACrB,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAC3C,OAAO,CAAC,SAAS,oBAAoB,EAAE,CAAC;IAI3C,mEAAmE;IAC5D,QAAQ,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIhF,wEAAwE;IACjE,aAAa,CAClB,QAAQ,EAAE,SAAS,wBAAwB,EAAE,GAC5C,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAI1C,+EAA+E;IACxE,iBAAiB,CACtB,aAAa,EAAE,SAAS,yBAAyB,EAAE,GAClD,UAAU,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;CAG3D"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Provider-neutral router composing a direct outbound provider with the
3
+ * observation/provisioning provider.
4
+ *
5
+ * The router implements the same gateway boundary the worker and polling
6
+ * already use, so no caller changes are required: outbound effect work
7
+ * (fast append, applyEffects, postcondition reads) goes to the direct Google
8
+ * Sheets provider, while anchor observation, snapshot/table reads, and
9
+ * provisioning stay on the Apps Script gateway (or an injected gateway +
10
+ * provisioner). The sync service bootstrap wraps the router in the
11
+ * per-spreadsheet mutation coordinator so direct writes and anchor
12
+ * observation share one in-process mutation lane.
13
+ */
14
+ import { observeSyncSnapshot, observeSyncSnapshots, } from "./syncGateway.js";
15
+ import { SYNC_GATEWAY_ERROR_CODES, SyncGatewayContractError, } from "./errors.js";
16
+ /**
17
+ * @deprecated Legacy composition used only by the deprecated mixed
18
+ * `googleApiWorker` bootstrap mode. The preferred `googleSheetsApi` mode
19
+ * uses the full direct provider directly, so this router (and the Apps
20
+ * Script observation half it routes to) is no longer needed for new setups.
21
+ */
22
+ export class RoutedSyncGateway {
23
+ outbound;
24
+ observation;
25
+ provisioner;
26
+ constructor(options) {
27
+ this.outbound = options.outbound;
28
+ this.observation = options.observation;
29
+ const provisioner = options.provisioner ?? asProvisioner(options.observation);
30
+ if (provisioner === undefined) {
31
+ throw new SyncGatewayContractError(SYNC_GATEWAY_ERROR_CODES.INVALID_PROVISIONING_DEFINITIONS, "the routed sync gateway needs a provisioning delegate");
32
+ }
33
+ this.provisioner = provisioner;
34
+ }
35
+ /** Sends append-only rows through the direct outbound provider. */
36
+ fastAppendRows(request) {
37
+ return this.outbound.fastAppendRows(request);
38
+ }
39
+ /** Sends regular effect writes through the direct outbound provider. */
40
+ applyEffects(request) {
41
+ return this.outbound.applyEffects(request);
42
+ }
43
+ /** Reads one effect postcondition through the direct outbound provider. */
44
+ readEffectPostcondition(effect) {
45
+ return this.outbound.readEffectPostcondition(effect);
46
+ }
47
+ /** Reads a batch of postconditions through the direct outbound provider. */
48
+ readEffectPostconditions(request) {
49
+ return this.outbound.readEffectPostconditions(request);
50
+ }
51
+ /** Ensures row anchors through the observation provider. */
52
+ ensureRowAnchors(request) {
53
+ return this.observation.ensureRowAnchors(request);
54
+ }
55
+ /** Reads snapshots through the observation provider. */
56
+ readSnapshot(request) {
57
+ return this.observation.readSnapshot(request);
58
+ }
59
+ /** Shares the observation provider's combined observation capability. */
60
+ observeSnapshot(request) {
61
+ return observeSyncSnapshot(this.observation, request);
62
+ }
63
+ /** Shares one observation request across the supplied projections. */
64
+ observeSnapshots(requests) {
65
+ return observeSyncSnapshots(this.observation, requests);
66
+ }
67
+ /** Reads one registered table through the observation provider. */
68
+ readRows(request) {
69
+ return this.observation.readRows(request);
70
+ }
71
+ /** Reads several registered tables through the observation provider. */
72
+ readRowsBatch(requests) {
73
+ return this.observation.readRowsBatch(requests);
74
+ }
75
+ /** Provisions the registered projections through the provisioning delegate. */
76
+ provisionRegistry(registrations) {
77
+ return this.provisioner.provisionRegistry(registrations);
78
+ }
79
+ }
80
+ /** Returns the observation provider itself when it can provision. */
81
+ function asProvisioner(value) {
82
+ return "provisionRegistry" in value && typeof value.provisionRegistry === "function"
83
+ ? value
84
+ : undefined;
85
+ }
86
+ //# sourceMappingURL=RoutedSyncGateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoutedSyncGateway.js","sourceRoot":"","sources":["../../../../src/application/sync/gateway/RoutedSyncGateway.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsBH,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,aAAa,CAAC;AAYrB;;;;;GAKG;AACH,MAAM,OAAO,iBAAiB;IAEX,QAAQ,CAA8B;IACtC,WAAW,CAAiD;IAC5D,WAAW,CAAyB;IAErD,YAAmB,OAAiC;QAClD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC9E,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,MAAM,IAAI,wBAAwB,CAChC,wBAAwB,CAAC,gCAAgC,EACzD,uDAAuD,CACxD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,mEAAmE;IAC5D,cAAc,CAAC,OAA8B;QAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,wEAAwE;IACjE,YAAY,CAAC,OAAgC;QAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,2EAA2E;IACpE,uBAAuB,CAAC,MAAyB;QACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,4EAA4E;IACrE,wBAAwB,CAC7B,OAA4C;QAE5C,OAAO,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;IAED,4DAA4D;IACrD,gBAAgB,CACrB,OAAoC;QAEpC,OAAO,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,wDAAwD;IACjD,YAAY,CAAC,OAAgC;QAClD,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,yEAAyE;IAClE,eAAe,CAAC,OAAgC;QACrD,OAAO,mBAAmB,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,sEAAsE;IAC/D,gBAAgB,CACrB,QAA4C;QAE5C,OAAO,oBAAoB,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;IAED,mEAAmE;IAC5D,QAAQ,CAAC,OAAiC;QAC/C,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,wEAAwE;IACjE,aAAa,CAClB,QAA6C;QAE7C,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,+EAA+E;IACxE,iBAAiB,CACtB,aAAmD;QAEnD,OAAO,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC3D,CAAC;CACF;AAED,qEAAqE;AACrE,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,mBAAmB,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,iBAAiB,KAAK,UAAU;QAClF,CAAC,CAAE,KAAgC;QACnC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC"}
@@ -25,6 +25,7 @@
25
25
  * reclassified as a retryable transport error.
26
26
  */
27
27
  import { AppsScriptSyncGatewayError } from "../../../adapter/sheets/providers/apps-script-gateway/errors.js";
28
+ import { GoogleSheetsApiTransportError } from "../../../adapter/sheets/providers/google-sheets-api/errors.js";
28
29
  import type { Presence } from "../../../shared/state/types.js";
29
30
  export declare const TRANSPORT_OUTCOME_KINDS: {
30
31
  readonly SUCCESS: "success";
@@ -59,4 +60,15 @@ export declare function isDeliveryUncertainOutcome(outcome: TransportOutcome): b
59
60
  * rejection evidence to the worker.
60
61
  */
61
62
  export declare function isDeliveryUncertain(error: AppsScriptSyncGatewayError): boolean;
63
+ /**
64
+ * Returns true when the direct Sheets transport error implies an ambiguous
65
+ * delivery.
66
+ *
67
+ * Google API non-2xx responses prove the batch did not execute only for the
68
+ * pre-mutation rejection statuses below; timeouts, network failures, and
69
+ * proxy-emitted 408/429/5xx responses can follow a committed write, and a
70
+ * malformed 2xx reply cannot prove what was applied. Those are recovered
71
+ * through the postcondition probe path, never closed as success.
72
+ */
73
+ export declare function isGoogleSheetsApiDeliveryUncertain(error: GoogleSheetsApiTransportError): boolean;
62
74
  //# sourceMappingURL=transportClassification.d.ts.map
@@ -1 +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"}
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;AAC9I,OAAO,EAAE,6BAA6B,EAA2C,MAAM,+DAA+D,CAAC;AAEvJ,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,CAsCzE;AAED,sEAAsE;AACtE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAE7E;AA8BD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAwB9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAeT"}
@@ -25,6 +25,7 @@
25
25
  * reclassified as a retryable transport error.
26
26
  */
27
27
  import { AppsScriptSyncGatewayError, SYNC_GATEWAY_CLIENT_ERROR_CODES } from "../../../adapter/sheets/providers/apps-script-gateway/errors.js";
28
+ import { GoogleSheetsApiTransportError, GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES } from "../../../adapter/sheets/providers/google-sheets-api/errors.js";
28
29
  import { PRESENCE_KINDS } from "../../../shared/state/index.js";
29
30
  export const TRANSPORT_OUTCOME_KINDS = {
30
31
  SUCCESS: "success",
@@ -59,6 +60,17 @@ export function classifyTransportOutcome(error) {
59
60
  message: error.message,
60
61
  };
61
62
  }
63
+ if (error instanceof GoogleSheetsApiTransportError) {
64
+ const kind = isGoogleSheetsApiDeliveryUncertain(error)
65
+ ? TRANSPORT_OUTCOME_KINDS.DELIVERY_UNCERTAIN
66
+ : TRANSPORT_OUTCOME_KINDS.EXPLICIT_REMOTE_FAILURE;
67
+ return {
68
+ kind,
69
+ httpStatus: error.status,
70
+ code: error.remoteCode,
71
+ message: error.message,
72
+ };
73
+ }
62
74
  // Unknown transport/Node error: assume the remote state is unverifiable.
63
75
  return {
64
76
  kind: TRANSPORT_OUTCOME_KINDS.DELIVERY_UNCERTAIN,
@@ -130,4 +142,29 @@ export function isDeliveryUncertain(error) {
130
142
  const status = error.status.value;
131
143
  return status === 404 || status === 408 || status === 429 || status >= 500;
132
144
  }
145
+ /**
146
+ * Returns true when the direct Sheets transport error implies an ambiguous
147
+ * delivery.
148
+ *
149
+ * Google API non-2xx responses prove the batch did not execute only for the
150
+ * pre-mutation rejection statuses below; timeouts, network failures, and
151
+ * proxy-emitted 408/429/5xx responses can follow a committed write, and a
152
+ * malformed 2xx reply cannot prove what was applied. Those are recovered
153
+ * through the postcondition probe path, never closed as success.
154
+ */
155
+ export function isGoogleSheetsApiDeliveryUncertain(error) {
156
+ if (error.code === GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.TIMEOUT ||
157
+ error.code === GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.NETWORK_ERROR ||
158
+ error.code === GOOGLE_SHEETS_API_TRANSPORT_ERROR_CODES.INVALID_RESPONSE) {
159
+ return true;
160
+ }
161
+ if (error.status.kind !== PRESENCE_KINDS.PRESENT)
162
+ return true;
163
+ const status = error.status.value;
164
+ if (status === 400 || status === 401 || status === 403 || status === 404) {
165
+ // The API rejected the request before executing any part of the batch.
166
+ return false;
167
+ }
168
+ return true;
169
+ }
133
170
  //# sourceMappingURL=transportClassification.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transportClassification.js","sourceRoot":"","sources":["../../../../src/application/sync/gateway/transportClassification.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transportClassification.js","sourceRoot":"","sources":["../../../../src/application/sync/gateway/transportClassification.ts"],"names":[],"mappings":"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"}