hikoutei 0.3.4 → 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.
- package/README.md +88 -15
- package/apps-script/gateway/appsscript.json +17 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +9 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js +9 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +18 -10
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +157 -27
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +4 -2
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -1
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +4 -2
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -1
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts +27 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js +14 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +156 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +1138 -0
- package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts +87 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.js +97 -0
- package/dist/adapter/sheets/providers/google-sheets-api/constants.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts +53 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.js +61 -0
- package/dist/adapter/sheets/providers/google-sheets-api/errors.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts +18 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.js +14 -0
- package/dist/adapter/sheets/providers/google-sheets-api/index.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +83 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js +413 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts +86 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js +439 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts +115 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js +522 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts +17 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js +99 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts +242 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js +707 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +16 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +29 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts +26 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js +57 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts +102 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js +375 -0
- package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +168 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +247 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +47 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js +60 -0
- package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +1 -0
- package/dist/application/sync/gateway/RoutedSyncGateway.d.ts +59 -0
- package/dist/application/sync/gateway/RoutedSyncGateway.d.ts.map +1 -0
- package/dist/application/sync/gateway/RoutedSyncGateway.js +86 -0
- package/dist/application/sync/gateway/RoutedSyncGateway.js.map +1 -0
- package/dist/application/sync/gateway/transportClassification.d.ts +12 -0
- package/dist/application/sync/gateway/transportClassification.d.ts.map +1 -1
- package/dist/application/sync/gateway/transportClassification.js +37 -0
- package/dist/application/sync/gateway/transportClassification.js.map +1 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +16 -0
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +26 -0
- package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +23 -3
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +15 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js +61 -8
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +15 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +15 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +4 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +16 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +8 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +22 -2
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.d.ts +23 -1
- package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
- package/dist/application/sync/service/SyncServiceBootstrap.js +162 -8
- package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
- package/dist/infrastructure/storage/index.d.ts +1 -1
- package/dist/infrastructure/storage/index.d.ts.map +1 -1
- package/dist/infrastructure/storage/index.js +1 -1
- package/dist/infrastructure/storage/index.js.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +12 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +22 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +10 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +38 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
- package/docs/architecture.md +57 -13
- package/docs/ci.md +16 -9
- package/docs/development.md +35 -5
- package/docs/quick-start.md +43 -11
- package/docs/sync-bulk-write-benchmark.md +561 -0
- package/docs/write-and-synchronization-flow.md +70 -14
- package/package.json +6 -3
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic batch builder for the direct Sheets provider.
|
|
3
|
+
*
|
|
4
|
+
* All applicable target mutations (appends, scattered field updates, physical
|
|
5
|
+
* row deletes) and their receipt writes are combined into ONE
|
|
6
|
+
* `spreadsheets.batchUpdate`, which is atomic: any invalid request aborts the
|
|
7
|
+
* whole batch. The builder also owns the transport byte budget: a batch that
|
|
8
|
+
* would exceed the budget is trimmed to the largest order-preserving effect
|
|
9
|
+
* prefix, and an effect that alone exceeds the budget becomes a schema_error
|
|
10
|
+
* result instead of a mutation.
|
|
11
|
+
*/
|
|
12
|
+
import { PRESENCE_KINDS } from "../../../../../shared/state/index.js";
|
|
13
|
+
import { GOOGLE_SHEETS_API_ANCHOR_KEY, GOOGLE_SHEETS_API_DATE_NUMBER_FORMAT_OBJECT, GOOGLE_SHEETS_API_RECEIPT_HEADERS, } from "../constants.js";
|
|
14
|
+
import { invalidProviderState } from "../errors.js";
|
|
15
|
+
import { serializeBatchUpdateRequests } from "../transport/googleSheetsApiTransport.js";
|
|
16
|
+
import { toApiUserEnteredValue } from "./valueNormalization.js";
|
|
17
|
+
import { allocateSheetId } from "./sheetIdAllocator.js";
|
|
18
|
+
/**
|
|
19
|
+
* Resolves how many leading effects fit in one atomic batch.
|
|
20
|
+
*
|
|
21
|
+
* The byte budget is measured on the phase-ordered request list serialized
|
|
22
|
+
* exactly as the transport sends it (SDK-wrapped request shapes), so the
|
|
23
|
+
* check is exact for the bytes that would actually hit the wire. When the
|
|
24
|
+
* very first effect alone exceeds the budget it becomes a schema_error
|
|
25
|
+
* result and the remaining effects are re-tried, so a single pathological
|
|
26
|
+
* payload cannot block the rest of the batch.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveApplyBatchBudget(context, plans, options) {
|
|
29
|
+
const total = plans.length;
|
|
30
|
+
let cursor = 0;
|
|
31
|
+
const schemaErrorIndices = [];
|
|
32
|
+
while (cursor < total) {
|
|
33
|
+
const fitting = largestFittingPrefix(plans, context, options, cursor, total);
|
|
34
|
+
if (fitting > cursor) {
|
|
35
|
+
return {
|
|
36
|
+
includeCount: fitting,
|
|
37
|
+
schemaErrorIndices,
|
|
38
|
+
hasMore: fitting < total,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
schemaErrorIndices.push(cursor);
|
|
42
|
+
cursor += 1;
|
|
43
|
+
}
|
|
44
|
+
return { includeCount: 0, schemaErrorIndices, hasMore: false };
|
|
45
|
+
}
|
|
46
|
+
function largestFittingPrefix(plans, context, options, start, end) {
|
|
47
|
+
let low = start;
|
|
48
|
+
let high = end;
|
|
49
|
+
while (low < high) {
|
|
50
|
+
const mid = Math.ceil((low + high) / 2);
|
|
51
|
+
const built = buildApplyBatchRequests(context, plans.slice(start, mid), {
|
|
52
|
+
updatedAt: options.updatedAt,
|
|
53
|
+
includeReceipts: options.includeReceipts,
|
|
54
|
+
});
|
|
55
|
+
if (built.bytes <= options.maxBatchBytes) {
|
|
56
|
+
low = mid;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
high = mid - 1;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return low;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Builds one atomic batchUpdate request list for a prefix of the plan.
|
|
66
|
+
*
|
|
67
|
+
* Requests are emitted in phase order: receipt-tab creation, append row
|
|
68
|
+
* inserts/values/anchors, scattered field updates, physical deletes (in
|
|
69
|
+
* descending row order so an earlier delete never shifts a later target),
|
|
70
|
+
* then receipt rows. Appended rows are written with their full header cells
|
|
71
|
+
* (all effects that touched a created row merge into one write); date cells
|
|
72
|
+
* keep the canonical number format through a separate format-masked request.
|
|
73
|
+
*/
|
|
74
|
+
export function buildApplyBatchRequests(context, plans, options) {
|
|
75
|
+
const requests = [];
|
|
76
|
+
const appended = [];
|
|
77
|
+
const updated = [];
|
|
78
|
+
const deleted = [];
|
|
79
|
+
for (const plan of plans) {
|
|
80
|
+
if (plan.mutation !== undefined)
|
|
81
|
+
collectMutation(plan.mutation, appended, updated, deleted);
|
|
82
|
+
}
|
|
83
|
+
const receipts = collectBatchReceipts(plans, context, options.includeReceipts);
|
|
84
|
+
let createdReceiptSheetId;
|
|
85
|
+
if (receipts.length > 0 && context.receiptSheetId.kind === PRESENCE_KINDS.ABSENT) {
|
|
86
|
+
createdReceiptSheetId = pushReceiptSheetCreation(requests, context);
|
|
87
|
+
}
|
|
88
|
+
if (appended.length > 0) {
|
|
89
|
+
pushAppendWrites(requests, context, appended);
|
|
90
|
+
}
|
|
91
|
+
for (const row of updated) {
|
|
92
|
+
pushUpdateWrites(requests, context, row);
|
|
93
|
+
}
|
|
94
|
+
// Descending physical row order: deleting a row never shifts a later target.
|
|
95
|
+
for (const row of [...deleted].sort((left, right) => right.rowNumber - left.rowNumber)) {
|
|
96
|
+
requests.push({
|
|
97
|
+
kind: "deleteDimension",
|
|
98
|
+
sheetId: context.sheetId,
|
|
99
|
+
dimension: "ROWS",
|
|
100
|
+
startIndex: row.rowNumber - 1,
|
|
101
|
+
endIndex: row.rowNumber,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (receipts.length > 0) {
|
|
105
|
+
pushReceiptWrites(requests, context, receipts, options.updatedAt, createdReceiptSheetId);
|
|
106
|
+
}
|
|
107
|
+
return { requests, bytes: measureRequestBytes(requests) };
|
|
108
|
+
}
|
|
109
|
+
/** Measures the serialized batchUpdate body with the transport serializer. */
|
|
110
|
+
export function measureRequestBytes(requests) {
|
|
111
|
+
return new TextEncoder().encode(serializeBatchUpdateRequests(requests)).byteLength;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Collects one batch's receipts, deduplicated by effectId (queueReceipt_
|
|
115
|
+
* semantics): receipts already stored in the sheet belong to replays and are
|
|
116
|
+
* never rewritten, and a receipt planned twice inside one request (a
|
|
117
|
+
* same-request effect-id replay) is written once.
|
|
118
|
+
*/
|
|
119
|
+
function collectBatchReceipts(plans, context, includeReceipts) {
|
|
120
|
+
if (!includeReceipts)
|
|
121
|
+
return [];
|
|
122
|
+
const queued = new Set();
|
|
123
|
+
const receipts = [];
|
|
124
|
+
for (const plan of plans) {
|
|
125
|
+
const receipt = plan.receipt;
|
|
126
|
+
if (receipt === undefined)
|
|
127
|
+
continue;
|
|
128
|
+
if (context.receipts.has(receipt.effectId))
|
|
129
|
+
continue;
|
|
130
|
+
if (queued.has(receipt.effectId))
|
|
131
|
+
continue;
|
|
132
|
+
queued.add(receipt.effectId);
|
|
133
|
+
receipts.push(receipt);
|
|
134
|
+
}
|
|
135
|
+
return receipts;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Resolves the append row prefix for one fast-append request.
|
|
139
|
+
*
|
|
140
|
+
* Unlike regular effects there is no per-row schema_error status, so a single
|
|
141
|
+
* row that alone exceeds the budget is still included: the API's own limits
|
|
142
|
+
* reject it deterministically (a proven explicit failure) instead of leaving
|
|
143
|
+
* the effect in an infinite defer loop.
|
|
144
|
+
*/
|
|
145
|
+
export function resolveAppendBudget(rows, build, maxBatchBytes) {
|
|
146
|
+
if (rows.length === 0)
|
|
147
|
+
return { includeCount: 0, hasMore: false };
|
|
148
|
+
let low = 1;
|
|
149
|
+
let high = rows.length;
|
|
150
|
+
// The first row is always included (documented above).
|
|
151
|
+
while (low < high) {
|
|
152
|
+
const mid = Math.ceil((low + high) / 2);
|
|
153
|
+
if (build(mid).bytes <= maxBatchBytes) {
|
|
154
|
+
low = mid;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
high = mid - 1;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return { includeCount: low, hasMore: low < rows.length };
|
|
161
|
+
}
|
|
162
|
+
/** Builds one atomic fast-append batch for a prefix of pending rows. */
|
|
163
|
+
export function buildAppendBatchRequests(context, rows, receipts, options) {
|
|
164
|
+
const requests = [];
|
|
165
|
+
const uniqueReceipts = dedupeReceipts(receipts, context);
|
|
166
|
+
let createdReceiptSheetId;
|
|
167
|
+
if (uniqueReceipts.length > 0 && context.receiptSheetId.kind === PRESENCE_KINDS.ABSENT) {
|
|
168
|
+
createdReceiptSheetId = pushReceiptSheetCreation(requests, context);
|
|
169
|
+
}
|
|
170
|
+
if (rows.length > 0) {
|
|
171
|
+
pushAppendWrites(requests, context, rows);
|
|
172
|
+
}
|
|
173
|
+
if (uniqueReceipts.length > 0) {
|
|
174
|
+
pushReceiptWrites(requests, context, uniqueReceipts, options.updatedAt, createdReceiptSheetId);
|
|
175
|
+
}
|
|
176
|
+
return { requests, bytes: measureRequestBytes(requests) };
|
|
177
|
+
}
|
|
178
|
+
/** Deduplicates pre-planned receipts by effectId for one append batch. */
|
|
179
|
+
function dedupeReceipts(receipts, context) {
|
|
180
|
+
const queued = new Set();
|
|
181
|
+
const unique = [];
|
|
182
|
+
for (const receipt of receipts) {
|
|
183
|
+
if (context.receipts.has(receipt.effectId))
|
|
184
|
+
continue;
|
|
185
|
+
if (queued.has(receipt.effectId))
|
|
186
|
+
continue;
|
|
187
|
+
queued.add(receipt.effectId);
|
|
188
|
+
unique.push(receipt);
|
|
189
|
+
}
|
|
190
|
+
return unique;
|
|
191
|
+
}
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
// Phase builders
|
|
194
|
+
// ---------------------------------------------------------------------------
|
|
195
|
+
function collectMutation(mutation, appended, updated, deleted) {
|
|
196
|
+
switch (mutation.kind) {
|
|
197
|
+
case "append":
|
|
198
|
+
appended.push(mutation.row);
|
|
199
|
+
break;
|
|
200
|
+
case "update":
|
|
201
|
+
updated.push(mutation.row);
|
|
202
|
+
break;
|
|
203
|
+
case "delete":
|
|
204
|
+
deleted.push(mutation.row);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/** Inserts the appended rows, writes their values/anchors, formats, checkboxes. */
|
|
209
|
+
function pushAppendWrites(requests, context, rows) {
|
|
210
|
+
const ordered = [...rows].sort((left, right) => left.rowNumber - right.rowNumber);
|
|
211
|
+
const first = ordered[0];
|
|
212
|
+
const last = ordered[ordered.length - 1];
|
|
213
|
+
if (first === undefined || last === undefined)
|
|
214
|
+
return;
|
|
215
|
+
const sheetId = context.sheetId;
|
|
216
|
+
const startColumn = context.startColumn - 1;
|
|
217
|
+
const columnCount = context.headers.length;
|
|
218
|
+
// Reserve the target rows before writing values so a concurrent human
|
|
219
|
+
// append is shifted rather than overwritten (insertRowsAfter equivalent).
|
|
220
|
+
requests.push({
|
|
221
|
+
kind: "insertDimension",
|
|
222
|
+
sheetId,
|
|
223
|
+
dimension: "ROWS",
|
|
224
|
+
startIndex: first.rowNumber - 1,
|
|
225
|
+
endIndex: first.rowNumber - 1 + ordered.length,
|
|
226
|
+
inheritFromBefore: false,
|
|
227
|
+
});
|
|
228
|
+
const values = ordered.map((row) => context.headers.map((header) => toApiCell(row.cells[header] ?? null)));
|
|
229
|
+
requests.push({
|
|
230
|
+
kind: "updateCells",
|
|
231
|
+
sheetId,
|
|
232
|
+
startRowIndex: first.rowNumber - 1,
|
|
233
|
+
startColumnIndex: startColumn,
|
|
234
|
+
rows: values,
|
|
235
|
+
fields: "userEnteredValue",
|
|
236
|
+
});
|
|
237
|
+
// Developer-metadata anchors keep created rows findable by anchor on the
|
|
238
|
+
// next apply/probe, matching the Apps Script effect-operation create path.
|
|
239
|
+
for (const row of ordered) {
|
|
240
|
+
if (row.anchor.kind === PRESENCE_KINDS.PRESENT) {
|
|
241
|
+
requests.push({
|
|
242
|
+
kind: "createDeveloperMetadata",
|
|
243
|
+
sheetId,
|
|
244
|
+
rowIndex: row.rowNumber - 1,
|
|
245
|
+
key: GOOGLE_SHEETS_API_ANCHOR_KEY,
|
|
246
|
+
value: row.anchor.value,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// A column is formatted as dates only when every appended cell in it is a
|
|
251
|
+
// date or blank (the Apps Script setDateNumberFormats_ rule).
|
|
252
|
+
context.headers.forEach((header, columnIndex) => {
|
|
253
|
+
const isDateColumn = ordered.every((row) => {
|
|
254
|
+
const cell = row.cells[header] ?? null;
|
|
255
|
+
return cell === null || cell.kind === "date";
|
|
256
|
+
});
|
|
257
|
+
if (!isDateColumn)
|
|
258
|
+
return;
|
|
259
|
+
requests.push({
|
|
260
|
+
kind: "updateCells",
|
|
261
|
+
sheetId,
|
|
262
|
+
startRowIndex: first.rowNumber - 1,
|
|
263
|
+
startColumnIndex: startColumn + columnIndex,
|
|
264
|
+
rows: ordered.map(() => [{ userEnteredFormat: { numberFormat: GOOGLE_SHEETS_API_DATE_NUMBER_FORMAT_OBJECT } }]),
|
|
265
|
+
fields: "userEnteredFormat.numberFormat",
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
for (const checkboxHeader of context.checkboxHeaders) {
|
|
269
|
+
const columnIndex = context.positions.get(checkboxHeader);
|
|
270
|
+
if (columnIndex === undefined) {
|
|
271
|
+
invalidProviderState(`checkbox header is not registered: ${checkboxHeader}`);
|
|
272
|
+
}
|
|
273
|
+
requests.push({
|
|
274
|
+
kind: "setDataValidation",
|
|
275
|
+
sheetId,
|
|
276
|
+
startRowIndex: first.rowNumber - 1,
|
|
277
|
+
endRowIndex: last.rowNumber,
|
|
278
|
+
startColumnIndex: startColumn + columnIndex,
|
|
279
|
+
endColumnIndex: startColumn + columnIndex + 1,
|
|
280
|
+
strict: true,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Writes one updated row's changed field runs.
|
|
286
|
+
*
|
|
287
|
+
* Runs are contiguous field spans (the Apps Script writeFieldRun_ grouping),
|
|
288
|
+
* so the values arrays never need empty placeholder cells that would clear a
|
|
289
|
+
* neighboring cell. Date cells get the canonical number format through a
|
|
290
|
+
* separate format-masked request so the value write never resets formats.
|
|
291
|
+
*/
|
|
292
|
+
function pushUpdateWrites(requests, context, row) {
|
|
293
|
+
const sheetId = context.sheetId;
|
|
294
|
+
const startColumn = context.startColumn - 1;
|
|
295
|
+
const changed = Object.entries(row.writeFields)
|
|
296
|
+
.map(([fieldName, cell]) => {
|
|
297
|
+
const columnIndex = context.positions.get(fieldName);
|
|
298
|
+
if (columnIndex === undefined) {
|
|
299
|
+
invalidProviderState(`effect field is not a registered header: ${fieldName}`);
|
|
300
|
+
}
|
|
301
|
+
return { fieldName, columnIndex, cell };
|
|
302
|
+
})
|
|
303
|
+
.sort((left, right) => left.columnIndex - right.columnIndex);
|
|
304
|
+
let runStart = 0;
|
|
305
|
+
for (let index = 1; index <= changed.length; index += 1) {
|
|
306
|
+
const previous = changed[index - 1];
|
|
307
|
+
const current = changed[index];
|
|
308
|
+
if (previous !== undefined &&
|
|
309
|
+
(current === undefined || current.columnIndex !== previous.columnIndex + 1)) {
|
|
310
|
+
pushUpdateRun(requests, sheetId, row, changed.slice(runStart, index), startColumn);
|
|
311
|
+
runStart = index;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function pushUpdateRun(requests, sheetId, row, run, startColumn) {
|
|
316
|
+
const first = run[0];
|
|
317
|
+
if (first === undefined)
|
|
318
|
+
return;
|
|
319
|
+
const firstColumn = startColumn + first.columnIndex;
|
|
320
|
+
const cells = run.map((entry) => toApiCell(entry.cell));
|
|
321
|
+
requests.push({
|
|
322
|
+
kind: "updateCells",
|
|
323
|
+
sheetId,
|
|
324
|
+
startRowIndex: row.rowNumber - 1,
|
|
325
|
+
startColumnIndex: firstColumn,
|
|
326
|
+
rows: [cells],
|
|
327
|
+
fields: "userEnteredValue",
|
|
328
|
+
});
|
|
329
|
+
// Date cells need the canonical format so read-back normalizes the serial
|
|
330
|
+
// as a date; without it the visible hash would never match.
|
|
331
|
+
run.forEach((entry, offset) => {
|
|
332
|
+
if (entry.cell !== null && entry.cell.kind === "date") {
|
|
333
|
+
requests.push({
|
|
334
|
+
kind: "updateCells",
|
|
335
|
+
sheetId,
|
|
336
|
+
startRowIndex: row.rowNumber - 1,
|
|
337
|
+
startColumnIndex: firstColumn + offset,
|
|
338
|
+
rows: [[{ userEnteredFormat: { numberFormat: GOOGLE_SHEETS_API_DATE_NUMBER_FORMAT_OBJECT } }]],
|
|
339
|
+
fields: "userEnteredFormat.numberFormat",
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
/** Creates the hidden receipt tab and its header row in the same batch. */
|
|
345
|
+
function pushReceiptSheetCreation(requests, context) {
|
|
346
|
+
// A deterministic, collision-free 31-bit positive sheetId (never the old
|
|
347
|
+
// random pick): the allocator scans the enumeration's existing ids so a
|
|
348
|
+
// repeated attempt after a lost response picks the same id.
|
|
349
|
+
const receiptSheetId = allocateSheetId(context.existingSheetIds);
|
|
350
|
+
requests.push({
|
|
351
|
+
kind: "addSheet",
|
|
352
|
+
title: "__typed_sheets_internal_effect_receipts",
|
|
353
|
+
sheetId: receiptSheetId,
|
|
354
|
+
});
|
|
355
|
+
requests.push({
|
|
356
|
+
kind: "updateSheetProperties",
|
|
357
|
+
sheetId: receiptSheetId,
|
|
358
|
+
hidden: true,
|
|
359
|
+
});
|
|
360
|
+
requests.push({
|
|
361
|
+
kind: "updateCells",
|
|
362
|
+
sheetId: receiptSheetId,
|
|
363
|
+
startRowIndex: 0,
|
|
364
|
+
startColumnIndex: 0,
|
|
365
|
+
rows: [GOOGLE_SHEETS_API_RECEIPT_HEADERS.map((header) => ({
|
|
366
|
+
userEnteredValue: { stringValue: header },
|
|
367
|
+
}))],
|
|
368
|
+
fields: "userEnteredValue",
|
|
369
|
+
});
|
|
370
|
+
return receiptSheetId;
|
|
371
|
+
}
|
|
372
|
+
/** Appends receipt rows after the receipt tab's last content row. */
|
|
373
|
+
function pushReceiptWrites(requests, context, receipts, updatedAt, createdReceiptSheetId) {
|
|
374
|
+
let sheetId;
|
|
375
|
+
if (createdReceiptSheetId !== undefined) {
|
|
376
|
+
sheetId = createdReceiptSheetId;
|
|
377
|
+
}
|
|
378
|
+
else if (context.receiptSheetId.kind === PRESENCE_KINDS.PRESENT) {
|
|
379
|
+
sheetId = context.receiptSheetId.value;
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
invalidProviderState("receipt sheet id is unavailable for receipt writes");
|
|
383
|
+
}
|
|
384
|
+
const startRow = Math.max(context.receiptLastRow + 1, 2);
|
|
385
|
+
requests.push({
|
|
386
|
+
kind: "insertDimension",
|
|
387
|
+
sheetId,
|
|
388
|
+
dimension: "ROWS",
|
|
389
|
+
startIndex: startRow - 1,
|
|
390
|
+
endIndex: startRow - 1 + receipts.length,
|
|
391
|
+
inheritFromBefore: false,
|
|
392
|
+
});
|
|
393
|
+
requests.push({
|
|
394
|
+
kind: "updateCells",
|
|
395
|
+
sheetId,
|
|
396
|
+
startRowIndex: startRow - 1,
|
|
397
|
+
startColumnIndex: 0,
|
|
398
|
+
rows: receipts.map((receipt) => [
|
|
399
|
+
{ userEnteredValue: { stringValue: receipt.effectId } },
|
|
400
|
+
{ userEnteredValue: { stringValue: receipt.payloadHash } },
|
|
401
|
+
{ userEnteredValue: { stringValue: receipt.status } },
|
|
402
|
+
{ userEnteredValue: { stringValue: receipt.visibleHash } },
|
|
403
|
+
{ userEnteredValue: { numberValue: receipt.visibleRevision } },
|
|
404
|
+
{ userEnteredValue: { stringValue: updatedAt } },
|
|
405
|
+
]),
|
|
406
|
+
fields: "userEnteredValue",
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/** Converts a normalized cell to the API cell shape (dates as serials). */
|
|
410
|
+
function toApiCell(cell) {
|
|
411
|
+
return toApiUserEnteredValue(cell);
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=batchBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchBuilder.js","sourceRoot":"","sources":["../../../../../../src/adapter/sheets/providers/google-sheets-api/model/batchBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observation model: row-anchor planning and full snapshot building.
|
|
3
|
+
*
|
|
4
|
+
* These helpers port the Apps Script observation operation's semantics to
|
|
5
|
+
* the REST wire shapes: nonblank rows are detected with the checkbox rule,
|
|
6
|
+
* anchors come from row-level developer metadata, and every cell is
|
|
7
|
+
* classified merged / error / formula / literal / blank with the same
|
|
8
|
+
* precedence and the same stableHash evidence as the Apps Script source, so
|
|
9
|
+
* snapshot hashes are byte-compatible across providers.
|
|
10
|
+
*
|
|
11
|
+
* Every untrusted SDK payload is validated by the preflight guards before it
|
|
12
|
+
* reaches this module; all functions here fail closed on drift (header
|
|
13
|
+
* mismatch, duplicate anchors, multi-anchor rows) exactly like the Apps
|
|
14
|
+
* Script source throws.
|
|
15
|
+
*/
|
|
16
|
+
import { type SyncGatewaySnapshotReadMode } from "../../../../../application/sync/gateway/constants.js";
|
|
17
|
+
import type { SyncGatewaySnapshot } from "../../../../../application/sync/gateway/syncGateway.js";
|
|
18
|
+
import type { GoogleSheetsApiTransport } from "../transport/googleSheetsApiTransport.js";
|
|
19
|
+
import { type ParsedGridData, type ParsedMergedCell } from "./preflight.js";
|
|
20
|
+
/** One tab requested by an observation/table-read batch. */
|
|
21
|
+
export interface ObservationGridTarget {
|
|
22
|
+
readonly sheetName: string;
|
|
23
|
+
readonly registeredRange: string;
|
|
24
|
+
}
|
|
25
|
+
/** Validated grid plus sheet identity for one observed tab. */
|
|
26
|
+
export interface ObservedTab {
|
|
27
|
+
readonly sheetId: number;
|
|
28
|
+
readonly title: string;
|
|
29
|
+
readonly grid: ParsedGridData;
|
|
30
|
+
/** Merged regions of this tab (sheet-level `merges` GridRange entries). */
|
|
31
|
+
readonly merges: readonly ParsedMergedCell[];
|
|
32
|
+
}
|
|
33
|
+
/** Anchor planning inputs shared by ensureRowAnchors and observation. */
|
|
34
|
+
export interface AnchorPlanningTarget {
|
|
35
|
+
readonly registeredRange: string;
|
|
36
|
+
readonly headers: readonly string[];
|
|
37
|
+
readonly checkboxHeaders: readonly string[];
|
|
38
|
+
}
|
|
39
|
+
/** One anchor write planned for a missing anchor. */
|
|
40
|
+
export interface PlannedAnchorWrite {
|
|
41
|
+
/** 0-based row index for the createDeveloperMetadata request. */
|
|
42
|
+
readonly rowIndex: number;
|
|
43
|
+
readonly anchor: string;
|
|
44
|
+
}
|
|
45
|
+
/** Result of one anchor-planning pass over a tab grid. */
|
|
46
|
+
export interface AnchorPlanResult {
|
|
47
|
+
readonly assigned: number;
|
|
48
|
+
readonly existing: number;
|
|
49
|
+
readonly duplicateAnchors: readonly {
|
|
50
|
+
readonly anchor: string;
|
|
51
|
+
readonly rowNumbers: readonly number[];
|
|
52
|
+
}[];
|
|
53
|
+
readonly planned: readonly PlannedAnchorWrite[];
|
|
54
|
+
}
|
|
55
|
+
/** Full snapshot inputs; the projection and schemaVersion are wire fields. */
|
|
56
|
+
export interface SnapshotBuildTarget extends AnchorPlanningTarget {
|
|
57
|
+
readonly sheetName: string;
|
|
58
|
+
readonly projection: string;
|
|
59
|
+
readonly schemaVersion: number;
|
|
60
|
+
readonly readMode: SyncGatewaySnapshotReadMode;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Reads the grids of several registered tabs in ONE `spreadsheets.get`
|
|
64
|
+
* call. Every requested tab must exist and return grid data; the result is
|
|
65
|
+
* keyed by tab name. The `fields` mask decides which metadata comes back
|
|
66
|
+
* (full observation mask or the lighter user_input mask); `timeoutMs`
|
|
67
|
+
* overrides the transport's per-request timeout for read calls.
|
|
68
|
+
*/
|
|
69
|
+
export declare function readTabGrids(transport: GoogleSheetsApiTransport, spreadsheetId: string, targets: readonly ObservationGridTarget[], fields?: string, timeoutMs?: number): Promise<ReadonlyMap<string, ObservedTab>>;
|
|
70
|
+
/**
|
|
71
|
+
* Plans anchors for every nonblank data row of one tab grid. Rows with more
|
|
72
|
+
* than one anchor fail closed; missing anchors get a fresh
|
|
73
|
+
* `sync-anchor:<uuid>` value; duplicate anchors across rows are reported as
|
|
74
|
+
* evidence (never rewritten). Blank rows are skipped, matching the Apps
|
|
75
|
+
* Script ensureAnchorsFromValues_ behavior.
|
|
76
|
+
*/
|
|
77
|
+
export declare function planRowAnchors(tab: ObservedTab, target: AnchorPlanningTarget): AnchorPlanResult;
|
|
78
|
+
/**
|
|
79
|
+
* Builds one full snapshot from a validated tab grid with EXACT parity to
|
|
80
|
+
* the Apps Script observation source: per-cell precedence merged -> error ->
|
|
81
|
+
* formula -> literal/blank, stableHash evidence (including stableHash(null)
|
|
82
|
+
* for blank cells), and a snapshotHash over the wire-shaped snapshot object
|
|
83
|
+
* with presence fields serialized as null.
|
|
84
|
+
*/
|
|
85
|
+
export declare function buildSnapshotFromTab(tab: ObservedTab, target: SnapshotBuildTarget): SyncGatewaySnapshot;
|
|
86
|
+
//# sourceMappingURL=observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../../../../../src/adapter/sheets/providers/google-sheets-api/model/observation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,sDAAsD,CAAC;AAC9D,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,wDAAwD,CAAC;AAEhE,OAAO,KAAK,EACV,wBAAwB,EAEzB,MAAM,0CAA0C,CAAC;AAMlD,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAEtB,MAAM,gBAAgB,CAAC;AAOxB,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC9C;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAED,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,0DAA0D;AAC1D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,SAAS;QAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;KACxC,EAAE,CAAC;IACJ,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACjD;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAoB,SAAQ,oBAAoB;IAC/D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;CAChD;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,wBAAwB,EACnC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,SAAS,qBAAqB,EAAE,EACzC,MAAM,GAAE,MAA6C,EACrD,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CA8B3C;AASD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,oBAAoB,GAC3B,gBAAgB,CAsClB;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC1B,mBAAmB,CA8DrB"}
|