hikoutei 0.10.1-dev → 0.10.3-dev
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/dist/composition/localRuntime.js +2 -2
- package/dist/composition/localRuntime.js.map +1 -1
- package/dist/contracts/domain/model/constants.d.ts +15 -0
- package/dist/contracts/domain/model/constants.d.ts.map +1 -1
- package/dist/contracts/domain/model/constants.js +13 -0
- package/dist/contracts/domain/model/constants.js.map +1 -1
- package/dist/contracts/shared/observability/internalLog.d.ts.map +1 -0
- package/dist/contracts/shared/observability/internalLog.js.map +1 -0
- package/dist/contracts/shared/observability/logEvents.d.ts.map +1 -0
- package/dist/contracts/shared/observability/logEvents.js.map +1 -0
- package/dist/contracts/sheets/mutationCoordinator/CoordinatedSheetsProvider.js +1 -1
- package/dist/contracts/sheets/mutationCoordinator/CoordinatedSheetsProvider.js.map +1 -1
- package/dist/contracts/sheets/mutationCoordinator/laneTelemetry.d.ts +1 -1
- package/dist/contracts/sheets/mutationCoordinator/laneTelemetry.d.ts.map +1 -1
- package/dist/contracts/sheets/mutationCoordinator/laneTelemetry.js +1 -1
- package/dist/contracts/sheets/mutationCoordinator/laneTelemetry.js.map +1 -1
- package/dist/contracts/sheets/timing.d.ts +4 -37
- package/dist/contracts/sheets/timing.d.ts.map +1 -1
- package/dist/contracts/sheets/timing.js +4 -18
- package/dist/contracts/sheets/timing.js.map +1 -1
- package/dist/internal/syncStatus.d.ts.map +1 -1
- package/dist/internal/syncStatus.js +1 -2
- package/dist/internal/syncStatus.js.map +1 -1
- package/dist/orm/persistence/projection/projectionEffects.d.ts.map +1 -1
- package/dist/orm/persistence/projection/projectionEffects.js +2 -2
- package/dist/orm/persistence/projection/projectionEffects.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +2 -0
- package/dist/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +21 -4
- package/dist/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/constants.d.ts +13 -2
- package/dist/sheets/providers/google-sheets-api/constants.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/constants.js +17 -2
- package/dist/sheets/providers/google-sheets-api/constants.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/errors.js +2 -2
- package/dist/sheets/providers/google-sheets-api/errors.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/index.d.ts +1 -1
- package/dist/sheets/providers/google-sheets-api/index.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/index.js +1 -1
- package/dist/sheets/providers/google-sheets-api/index.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js +7 -7
- package/dist/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/observation.d.ts +3 -3
- package/dist/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/observation.js +11 -8
- package/dist/sheets/providers/google-sheets-api/model/observation.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/plannerReceipt.d.ts +6 -5
- package/dist/sheets/providers/google-sheets-api/model/plannerReceipt.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/plannerReceipt.js +97 -43
- package/dist/sheets/providers/google-sheets-api/model/plannerReceipt.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/postcondition.d.ts +8 -5
- package/dist/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/postcondition.js +50 -60
- package/dist/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/preflightContext.d.ts +5 -6
- package/dist/sheets/providers/google-sheets-api/model/preflightContext.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/preflightContext.js +22 -15
- package/dist/sheets/providers/google-sheets-api/model/preflightContext.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/preflightVerify.d.ts +2 -2
- package/dist/sheets/providers/google-sheets-api/model/preflightVerify.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/model/preflightVerify.js +10 -7
- package/dist/sheets/providers/google-sheets-api/model/preflightVerify.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/applyEffects.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/applyEffects.js +2 -3
- package/dist/sheets/providers/google-sheets-api/operations/applyEffects.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js +2 -3
- package/dist/sheets/providers/google-sheets-api/operations/fastAppend.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/preflightOp.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/preflightOp.js +2 -2
- package/dist/sheets/providers/google-sheets-api/operations/preflightOp.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/provisioning.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/provisioning.js +2 -2
- package/dist/sheets/providers/google-sheets-api/operations/provisioning.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/readRows.js +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/readRows.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/rowChecks.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js +9 -7
- package/dist/sheets/providers/google-sheets-api/operations/rowChecks.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/shared.d.ts +119 -58
- package/dist/sheets/providers/google-sheets-api/operations/shared.d.ts.map +1 -1
- package/dist/sheets/providers/google-sheets-api/operations/shared.js +168 -153
- package/dist/sheets/providers/google-sheets-api/operations/shared.js.map +1 -1
- package/dist/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +1 -1
- package/dist/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +4 -4
- package/dist/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -1
- package/dist/storage/sqlite/migrateSchema.d.ts.map +1 -1
- package/dist/storage/sqlite/migrateSchema.js +36 -3
- package/dist/storage/sqlite/migrateSchema.js.map +1 -1
- package/dist/storage/sqlite/schema.d.ts +3 -1
- package/dist/storage/sqlite/schema.d.ts.map +1 -1
- package/dist/storage/sqlite/schema.js +6 -2
- package/dist/storage/sqlite/schema.js.map +1 -1
- package/dist/storage/sqlite/schemaTypes.d.ts +1 -1
- package/dist/storage/sqlite/schemaTypes.d.ts.map +1 -1
- package/dist/sync/outbound/projection/ProjectionEffectFactory.d.ts +19 -0
- package/dist/sync/outbound/projection/ProjectionEffectFactory.d.ts.map +1 -1
- package/dist/sync/outbound/projection/ProjectionEffectFactory.js +35 -0
- package/dist/sync/outbound/projection/ProjectionEffectFactory.js.map +1 -1
- package/dist/sync-engine/api/hikouteiCore.js +2 -2
- package/dist/sync-engine/api/hikouteiCore.js.map +1 -1
- package/dist/sync-engine/api/internalEntityManager.js +2 -2
- package/dist/sync-engine/api/internalEntityManager.js.map +1 -1
- package/dist/sync-engine/sync/outbound/SheetsEffectDispatcher.d.ts +13 -2
- package/dist/sync-engine/sync/outbound/SheetsEffectDispatcher.d.ts.map +1 -1
- package/dist/sync-engine/sync/outbound/SheetsEffectDispatcher.js +37 -5
- package/dist/sync-engine/sync/outbound/SheetsEffectDispatcher.js.map +1 -1
- package/dist/sync-engine/sync/outbound/dispatcherSupport.d.ts +4 -7
- package/dist/sync-engine/sync/outbound/dispatcherSupport.d.ts.map +1 -1
- package/dist/sync-engine/sync/outbound/dispatcherSupport.js +4 -14
- package/dist/sync-engine/sync/outbound/dispatcherSupport.js.map +1 -1
- package/dist/sync-engine/sync/service/SyncServiceBootstrap.js +2 -2
- package/dist/sync-engine/sync/service/SyncServiceBootstrap.js.map +1 -1
- package/dist/sync-engine/sync/service/adopt/adoptionSeeding.js +1 -1
- package/dist/sync-engine/sync/service/adopt/adoptionSeeding.js.map +1 -1
- package/dist/sync-engine/sync/service/effectSupervisor.js +2 -2
- package/dist/sync-engine/sync/service/effectSupervisor.js.map +1 -1
- package/dist/sync-engine/sync/service/pollingSupervisor.js +2 -2
- package/dist/sync-engine/sync/service/pollingSupervisor.js.map +1 -1
- package/dist/sync-engine/sync/service/requestTelemetry.js +2 -2
- package/dist/sync-engine/sync/service/requestTelemetry.js.map +1 -1
- package/dist/sync-engine/sync/service/shutdown.js +1 -1
- package/dist/sync-engine/sync/service/shutdown.js.map +1 -1
- package/dist/sync-engine/sync/service/syncAutoStart.js +2 -2
- package/dist/sync-engine/sync/service/syncAutoStart.js.map +1 -1
- package/dist/sync-engine/sync/sheetsContract/conflictProjectionRegistration.js +1 -1
- package/dist/sync-engine/sync/sheetsContract/conflictProjectionRegistration.js.map +1 -1
- package/package.json +2 -2
- package/dist/contracts/sheets/transportOutcome.d.ts +0 -90
- package/dist/contracts/sheets/transportOutcome.d.ts.map +0 -1
- package/dist/contracts/sheets/transportOutcome.js +0 -191
- package/dist/contracts/sheets/transportOutcome.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/readPlan.d.ts +0 -168
- package/dist/sheets/providers/google-sheets-api/model/readPlan.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/readPlan.js +0 -184
- package/dist/sheets/providers/google-sheets-api/model/readPlan.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/receiptCursor.d.ts +0 -102
- package/dist/sheets/providers/google-sheets-api/model/receiptCursor.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/receiptCursor.js +0 -132
- package/dist/sheets/providers/google-sheets-api/model/receiptCursor.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/rowCheckFormula.d.ts +0 -35
- package/dist/sheets/providers/google-sheets-api/model/rowCheckFormula.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/rowCheckFormula.js +0 -57
- package/dist/sheets/providers/google-sheets-api/model/rowCheckFormula.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +0 -16
- package/dist/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +0 -29
- package/dist/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/operations/readEngine.d.ts +0 -50
- package/dist/sheets/providers/google-sheets-api/operations/readEngine.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/operations/readEngine.js +0 -124
- package/dist/sheets/providers/google-sheets-api/operations/readEngine.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/operations/writeEngine.d.ts +0 -90
- package/dist/sheets/providers/google-sheets-api/operations/writeEngine.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/operations/writeEngine.js +0 -112
- package/dist/sheets/providers/google-sheets-api/operations/writeEngine.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/quotaGovernor.d.ts +0 -229
- package/dist/sheets/providers/google-sheets-api/transport/quotaGovernor.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/quotaGovernor.js +0 -299
- package/dist/sheets/providers/google-sheets-api/transport/quotaGovernor.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +0 -185
- package/dist/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/rateLimiter.js +0 -248
- package/dist/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/rawErrorSchemas.d.ts +0 -7
- package/dist/sheets/providers/google-sheets-api/transport/rawErrorSchemas.d.ts.map +0 -1
- package/dist/sheets/providers/google-sheets-api/transport/rawErrorSchemas.js +0 -26
- package/dist/sheets/providers/google-sheets-api/transport/rawErrorSchemas.js.map +0 -1
- package/dist/sync-engine/shared/observability/internalLog.d.ts.map +0 -1
- package/dist/sync-engine/shared/observability/internalLog.js.map +0 -1
- package/dist/sync-engine/shared/observability/logEvents.d.ts.map +0 -1
- package/dist/sync-engine/shared/observability/logEvents.js.map +0 -1
- /package/dist/{sync-engine → contracts}/shared/observability/internalLog.d.ts +0 -0
- /package/dist/{sync-engine → contracts}/shared/observability/internalLog.js +0 -0
- /package/dist/{sync-engine → contracts}/shared/observability/logEvents.d.ts +0 -0
- /package/dist/{sync-engine → contracts}/shared/observability/logEvents.js +0 -0
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure read planning for the unified read engine (design/unified-read-engine.md).
|
|
3
|
-
*
|
|
4
|
-
* Every read lane (polling observation, preflight base, verification/probe)
|
|
5
|
-
* historically built its own A1 ranges with unbounded row extent
|
|
6
|
-
* (`X2:X1048576`), so each lane's largest single request grew with the
|
|
7
|
-
* accumulated data and the 30k-row burst stress pushed all three lanes into
|
|
8
|
-
* the 10 s read timeout at once. This module is the SINGLE planner those
|
|
9
|
-
* lanes route through: given an authoritative committed row bound
|
|
10
|
-
* (`gridProperties.rowCount` from the sheet's own enumeration), a column
|
|
11
|
-
* span, and an evidence class, it emits row bands that never exceed the
|
|
12
|
-
* shared per-range cell cap or the per-request byte estimate, and packs the
|
|
13
|
-
* bands into at most `MAX_READ_RANGES_PER_REQUEST` ranges per request.
|
|
14
|
-
*
|
|
15
|
-
* Safety rules baked into the planning contract:
|
|
16
|
-
* - The bound is an upper bound on what a read can return (content ≤ grid
|
|
17
|
-
* rows always holds at snapshot time); a too-low cached bound can never
|
|
18
|
-
* truncate coverage because the LAST band of every banded column stays
|
|
19
|
-
* open-ended (`<start>:<end>1048576`) unless the caller proves the row
|
|
20
|
-
* * extent itself (explicit row sets and the verification spans, which are
|
|
21
|
-
* bounded by their own maximum row number).
|
|
22
|
-
* - Byte estimates are deliberately conservative (each class constant is
|
|
23
|
-
* ≥ 2× the measured live average) and a per-class telemetry-calibrated
|
|
24
|
-
* multiplier only ever GROWS them: a mispredict shrinks the next pass's
|
|
25
|
-
* bands, it never loops or grows one request.
|
|
26
|
-
* - Small tabs collapse to exactly one open-ended band per column, i.e. the
|
|
27
|
-
* byte-identical historical ranges; chunking activates only when the
|
|
28
|
-
* authoritative bound exceeds one chunk.
|
|
29
|
-
*/
|
|
30
|
-
/** Current hard grid limit of a real spreadsheet (1-based). */
|
|
31
|
-
export const SHEET_MAX_ROW = 1_048_576;
|
|
32
|
-
/**
|
|
33
|
-
* Hard cap on cells per requested range, shared by EVERY lane (the API's
|
|
34
|
-
* ~10 000-cell request-shape limit with margin; previously only the
|
|
35
|
-
* verification lane enforced it).
|
|
36
|
-
*/
|
|
37
|
-
export const MAX_READ_CELLS_PER_RANGE = 9_500;
|
|
38
|
-
/**
|
|
39
|
-
* Hard cap on ranges per `spreadsheets.get`, shared by every lane (unifies
|
|
40
|
-
* the former `MAX_OBSERVATION_BAND_RANGES` / `MAX_VERIFY_RANGES_PER_REQUEST`).
|
|
41
|
-
*/
|
|
42
|
-
export const MAX_READ_RANGES_PER_REQUEST = 40;
|
|
43
|
-
/**
|
|
44
|
-
* Per-BAND ESTIMATE target in bytes: one band plans to at most this many
|
|
45
|
-
* estimated bytes (the chunking gate). A planning threshold, not a transport
|
|
46
|
-
* guarantee: the constants below are conservative and the calibration
|
|
47
|
-
* multiplier shrinks future bands whenever measured bytes/cell exceed the
|
|
48
|
-
* estimate.
|
|
49
|
-
*/
|
|
50
|
-
export const READ_SOFT_TARGET_BYTES = 3_000_000;
|
|
51
|
-
/**
|
|
52
|
-
* Per-request ESTIMATE ceiling: packed requests add bands until the summed
|
|
53
|
-
* estimate would exceed this (each individual band is already ≤ the soft
|
|
54
|
-
* target, so a request holds 1-2 near-maximal bands). With the ≥ 2× safety
|
|
55
|
-
* margin baked into BYTES_PER_CELL the REAL response lands well under the
|
|
56
|
-
* figure that streamed past the 10 s budget at the observed average.
|
|
57
|
-
*/
|
|
58
|
-
export const READ_HARD_MAX_BYTES = 5_000_000;
|
|
59
|
-
/**
|
|
60
|
-
* Cell-evidence classes → conservative per-cell JSON byte estimates.
|
|
61
|
-
* Each value is ≥ 2× the measured live `responseBytes ÷ cellsRequested`
|
|
62
|
-
* average for its wire mask (~107–210 B/cell preflight/observation classes,
|
|
63
|
-
* ~163 B/cell-band row-checks).
|
|
64
|
-
* ponytail: fixture-scale calibration; recalibrate from live telemetry if
|
|
65
|
-
* planning mispredicts > 2×.
|
|
66
|
-
*/
|
|
67
|
-
export const READ_BYTES_PER_CELL = {
|
|
68
|
-
"values-only": 120,
|
|
69
|
-
"row-checks": 400,
|
|
70
|
-
"values+formats": 400,
|
|
71
|
-
"rendering-complete": 450,
|
|
72
|
-
};
|
|
73
|
-
/** Safety margin applied to the observed bytes/cell ratio. */
|
|
74
|
-
const CALIBRATION_SAFETY = 1.5;
|
|
75
|
-
/** Ceiling for one class's multiplier (bounds a pathological sample's damage). */
|
|
76
|
-
const CALIBRATION_MAX_RATIO = 20;
|
|
77
|
-
/** Builds a fresh provider-instance calibration tracker. */
|
|
78
|
-
export function createReadCalibration() {
|
|
79
|
-
const ratios = new Map();
|
|
80
|
-
return {
|
|
81
|
-
ratioFor: (evidence) => ratios.get(evidence) ?? 1,
|
|
82
|
-
observe: (evidence, cellsRequested, responseBytes) => {
|
|
83
|
-
if (cellsRequested <= 0 || responseBytes <= 0)
|
|
84
|
-
return;
|
|
85
|
-
const observed = responseBytes / cellsRequested / READ_BYTES_PER_CELL[evidence];
|
|
86
|
-
const next = Math.min(CALIBRATION_MAX_RATIO, Math.max(ratios.get(evidence) ?? 1, observed * CALIBRATION_SAFETY));
|
|
87
|
-
ratios.set(evidence, next);
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
/** Estimated bytes for one planned band under the current calibration. */
|
|
92
|
-
export function estimatedRangeBytes(item, evidence, calibration) {
|
|
93
|
-
return item.cells * READ_BYTES_PER_CELL[evidence] * calibration.ratioFor(evidence);
|
|
94
|
-
}
|
|
95
|
-
/** Rows one band of `columnCount` columns may request under both caps. */
|
|
96
|
-
export function rowsPerBand(columnCount, evidence, calibration) {
|
|
97
|
-
const cellBudget = Math.floor(READ_SOFT_TARGET_BYTES /
|
|
98
|
-
(READ_BYTES_PER_CELL[evidence] * calibration.ratioFor(evidence)));
|
|
99
|
-
return Math.max(1, Math.floor(Math.min(MAX_READ_CELLS_PER_RANGE, cellBudget) / Math.max(1, columnCount)));
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Plans the row bands for one column span: contiguous chunks of at most
|
|
103
|
-
* `rowsPerBand` rows and `MAX_READ_CELLS_PER_RANGE` cells each. The final
|
|
104
|
-
* band stays OPEN (`:1048576`) so a stale-low bound can never truncate
|
|
105
|
-
* coverage — unless the caller proved the extent via `exactLastRow`. A span
|
|
106
|
-
* that fits one chunk collapses to the byte-identical historical single
|
|
107
|
-
* open-ended range.
|
|
108
|
-
*/
|
|
109
|
-
export function planRowBands(plan) {
|
|
110
|
-
const { quote, firstLetter, lastLetter, columnCount, fromRow, rowBound, exactLastRow, evidence, calibration } = plan;
|
|
111
|
-
const lastRow = exactLastRow ?? rowBound;
|
|
112
|
-
if (lastRow === undefined || lastRow < fromRow) {
|
|
113
|
-
// No bound (legacy/unenumerated transport) or nothing to read: the
|
|
114
|
-
// historical single open band; cells 0 keeps it out of byte packing
|
|
115
|
-
// (it was never chunkable without a bound anyway).
|
|
116
|
-
return [{
|
|
117
|
-
range: `${quote}${firstLetter}${fromRow}:${lastLetter}${SHEET_MAX_ROW}`,
|
|
118
|
-
cells: rowBound !== undefined && rowBound >= fromRow
|
|
119
|
-
? (Math.min(rowBound, lastRow ?? rowBound) - fromRow + 1) * columnCount
|
|
120
|
-
: 0,
|
|
121
|
-
}];
|
|
122
|
-
}
|
|
123
|
-
const rows = rowsPerBand(columnCount, evidence, calibration);
|
|
124
|
-
const items = [];
|
|
125
|
-
let start = fromRow;
|
|
126
|
-
while (start + rows - 1 < lastRow) {
|
|
127
|
-
const end = start + rows - 1;
|
|
128
|
-
items.push({
|
|
129
|
-
range: `${quote}${firstLetter}${start}:${lastLetter}${end}`,
|
|
130
|
-
cells: rows * columnCount,
|
|
131
|
-
});
|
|
132
|
-
start = end + 1;
|
|
133
|
-
}
|
|
134
|
-
const remainingRows = lastRow - start + 1;
|
|
135
|
-
const openEnded = exactLastRow === undefined;
|
|
136
|
-
items.push({
|
|
137
|
-
range: `${quote}${firstLetter}${start}:${lastLetter}${openEnded ? SHEET_MAX_ROW : lastRow}`,
|
|
138
|
-
cells: remainingRows * columnCount,
|
|
139
|
-
});
|
|
140
|
-
return items;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Greedily packs planned bands into paced requests: each request holds at
|
|
144
|
-
* most `MAX_READ_RANGES_PER_REQUEST` ranges and stays within the
|
|
145
|
-
* `READ_HARD_MAX_BYTES` estimate (individual bands are chunked to the
|
|
146
|
-
* softer 3 MB target, so one oversized tab spreads across requests while
|
|
147
|
-
* small tabs of one logical read still share a single request — the
|
|
148
|
-
* historical single-request shape).
|
|
149
|
-
*/
|
|
150
|
-
export function packReadRequests(items, evidence, calibration) {
|
|
151
|
-
const requests = [];
|
|
152
|
-
let current = [];
|
|
153
|
-
let currentBytes = 0;
|
|
154
|
-
for (const item of items) {
|
|
155
|
-
const bytes = estimatedRangeBytes(item, evidence, calibration);
|
|
156
|
-
if (current.length > 0 &&
|
|
157
|
-
(current.length + 1 > MAX_READ_RANGES_PER_REQUEST ||
|
|
158
|
-
currentBytes + bytes > READ_HARD_MAX_BYTES)) {
|
|
159
|
-
requests.push(current);
|
|
160
|
-
current = [];
|
|
161
|
-
currentBytes = 0;
|
|
162
|
-
}
|
|
163
|
-
current.push(item);
|
|
164
|
-
currentBytes += bytes;
|
|
165
|
-
}
|
|
166
|
-
if (current.length > 0)
|
|
167
|
-
requests.push(current);
|
|
168
|
-
return requests;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Resolves one title's authoritative row bound from an enumeration (the
|
|
172
|
-
* committed `gridProperties.rowCount`, exact) falling back to the
|
|
173
|
-
* provider-instance bounds cache (refreshed by every engine response), so
|
|
174
|
-
* lanes that enumerated never pay for a second metadata call.
|
|
175
|
-
*/
|
|
176
|
-
export function authoritativeRowBound(sheets, boundsCache, title) {
|
|
177
|
-
for (const sheet of sheets) {
|
|
178
|
-
if (sheet.title === title) {
|
|
179
|
-
return sheet.gridProperties?.rowCount ?? boundsCache.get(title);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return boundsCache.get(title);
|
|
183
|
-
}
|
|
184
|
-
//# sourceMappingURL=readPlan.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"readPlan.js","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/readPlan.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-provider receipt READ cursor plus cumulative receipt memo.
|
|
3
|
-
*
|
|
4
|
-
* The hidden receipt tab is append-only machine data (each write batch appends
|
|
5
|
-
* its receipt rows at the tab tail; humans never edit it), so a dispatch does
|
|
6
|
-
* not need to re-read the whole tab to decide idempotency: it needs only the
|
|
7
|
-
* receipts appended since the last verified coverage. This cursor records the
|
|
8
|
-
* LAST receipt row this provider instance has verified as covered — either by
|
|
9
|
-
* parsing it in a previous receipt read, or by writing it in a batch that got
|
|
10
|
-
* a valid `batchUpdate` reply — so the next dispatch reads only the tail band
|
|
11
|
-
* starting AT that row (the row doubles as a sentinel proving the cursor is
|
|
12
|
-
* still inside the tab).
|
|
13
|
-
*
|
|
14
|
-
* Because the cursor advances on every successful read, a band alone cannot
|
|
15
|
-
* answer idempotency for effects that have not been re-dispatched for several
|
|
16
|
-
* batches: their receipt rows fall BELOW the next cursor. The cursor
|
|
17
|
-
* therefore also owns a cumulative memo — every receipt row this instance has
|
|
18
|
-
* ever parsed (bands and full reads alike) — and preflight contexts expose
|
|
19
|
-
* the memo, not just the current band, as their `receipts` view. Receipt
|
|
20
|
-
* lookups never depend on where the cursor happens to sit.
|
|
21
|
-
*
|
|
22
|
-
* Safety contract:
|
|
23
|
-
* - The cursor advances ONLY from a successful receipt READ, to the tail row
|
|
24
|
-
* that read parsed. It is never advanced from a write: receipts appended
|
|
25
|
-
* after the previous read therefore stay inside the next band, are merged
|
|
26
|
-
* into the memo there, and remain replay-recognizable for as long as this
|
|
27
|
-
* instance lives.
|
|
28
|
-
* - Every row at or below the cursor was parsed by this instance since the
|
|
29
|
-
* last reset (append-only tab + snapshot-atomic reads), so memo coverage
|
|
30
|
-
* is exactly "everything the cursor has passed". A concurrent or
|
|
31
|
-
* cross-process append can only grow the tab at the tail, which the next
|
|
32
|
-
* band (starting AT the cursor sentinel) re-reads.
|
|
33
|
-
* - A kill -9 loses the whole cursor AND the memo (instance memory): the next
|
|
34
|
-
* process starts with no cursor and performs the historical FULL
|
|
35
|
-
* `A1:F1048576` receipt read, byte-identical to the pre-cursor behavior.
|
|
36
|
-
* - Cursor missing (< 2), sentinel blank (tab truncated/cleared), or a
|
|
37
|
-
* clipped grid → reset (cursor + memo dropped together) and fall back to
|
|
38
|
-
* one full receipt read, which re-establishes both.
|
|
39
|
-
* - Memo growth is bounded: past `MAX_MEMO_RECEIPTS` the cursor resets, so
|
|
40
|
-
* the instance degrades to the pre-cursor full-read behavior instead of
|
|
41
|
-
* growing unbounded memory.
|
|
42
|
-
*
|
|
43
|
-
* Why instance memory instead of a SQLite column under the writer fence:
|
|
44
|
-
* durable-then-ack coupling only buys savings across a process restart (one
|
|
45
|
-
* full receipt read paid once per restart), while every multi-process and
|
|
46
|
-
* crash-desync case above is already proven safe by the append-only +
|
|
47
|
-
* shift-not-overwrite invariants plus the probe rule that a live cursor
|
|
48
|
-
* after the base read proves complete memo coverage (a receipt miss is then
|
|
49
|
-
* provable and decides `unapplied` from the band), while any coverage the
|
|
50
|
-
* read itself invalidated falls back to one full receipt read (see
|
|
51
|
-
* `readEffectPostconditions`). Keeping the cursor
|
|
52
|
-
* inside the provider also keeps the Sheets adapter free of storage-schema
|
|
53
|
-
* ownership (a fence-coupled cursor would require outbox-kernel, contracts,
|
|
54
|
-
* and storage API changes far outside this optimization's scope).
|
|
55
|
-
*/
|
|
56
|
-
import type { PreflightReceipt } from "./preflightContext.js";
|
|
57
|
-
/**
|
|
58
|
-
* Ceiling for the cumulative receipt memo. Beyond it the cursor resets and
|
|
59
|
-
* the instance falls back to the historical per-dispatch full receipt read.
|
|
60
|
-
* ponytail: 200k receipts ≈ tens of MB of small records; upgrade path if a
|
|
61
|
-
* real deployment exceeds this is an acknowledged-effect watermark in
|
|
62
|
-
* SQLite (durable cursor + durable coverage).
|
|
63
|
-
*/
|
|
64
|
-
export declare const MAX_MEMO_RECEIPTS = 200000;
|
|
65
|
-
export declare class ReceiptReadCursor {
|
|
66
|
-
/** Last receipt row (1-based) verified as covered; 0 means "no cursor". */
|
|
67
|
-
private lastVerifiedRow;
|
|
68
|
-
/** Every receipt parsed by this instance since the last reset. */
|
|
69
|
-
private readonly memo;
|
|
70
|
-
/**
|
|
71
|
-
* Row (1-based) to START a banded receipt read at, or `undefined` when a
|
|
72
|
-
* full read is required (no usable cursor yet). The band starts AT the
|
|
73
|
-
* cursor row so the known-applied receipt there acts as a sentinel against
|
|
74
|
-
* tab truncation; row 1 is the header, so a cursor below 2 can never prove
|
|
75
|
-
* coverage of a data row and the full read stays.
|
|
76
|
-
*/
|
|
77
|
-
bandStartRow(): number | undefined;
|
|
78
|
-
/** Monotonic advance; understating the verified tail is always safe. */
|
|
79
|
-
advanceTo(verifiedRow: number): void;
|
|
80
|
-
/**
|
|
81
|
-
* Merges one parsed read's receipts into the cumulative memo. Re-parsing
|
|
82
|
-
* the same row (the band sentinel is read again every dispatch) is a no-op
|
|
83
|
-
* when the values agree; a different value under an already-covered
|
|
84
|
-
* effectId means the append-only tab was rewritten from under this
|
|
85
|
-
* instance and fails closed exactly like an in-band duplicate.
|
|
86
|
-
*/
|
|
87
|
-
mergeParsed(receipts: ReadonlyMap<string, PreflightReceipt>): boolean;
|
|
88
|
-
/** True when the memo has grown past its ceiling (caller must reset). */
|
|
89
|
-
isOverCapacity(): boolean;
|
|
90
|
-
/** True when the next merge could only exceed the ceiling: force a full read. */
|
|
91
|
-
isAtCapacity(): boolean;
|
|
92
|
-
/** True when this instance has covered no receipt row yet. */
|
|
93
|
-
isEmpty(): boolean;
|
|
94
|
-
/** The cumulative receipt coverage every scoped/full read's context exposes. */
|
|
95
|
-
memoView(): ReadonlyMap<string, PreflightReceipt>;
|
|
96
|
-
/**
|
|
97
|
-
* Drops the cursor AND the memo together so the next read performs the
|
|
98
|
-
* historical full receipt read; coverage and cursor must never disagree.
|
|
99
|
-
*/
|
|
100
|
-
reset(): void;
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=receiptCursor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"receiptCursor.d.ts","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/receiptCursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,SAAU,CAAC;AAEzC,qBAAa,iBAAiB;IAC5B,2EAA2E;IAC3E,OAAO,CAAC,eAAe,CAAK;IAC5B,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuC;IAE5D;;;;;;OAMG;IACI,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC,wEAAwE;IACjE,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,OAAO;IAgB5E,yEAAyE;IAClE,cAAc,IAAI,OAAO;IAIhC,iFAAiF;IAC1E,YAAY,IAAI,OAAO;IAI9B,8DAA8D;IACvD,OAAO,IAAI,OAAO;IAIzB,gFAAgF;IACzE,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIxD;;;OAGG;IACI,KAAK,IAAI,IAAI;CAIrB"}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Per-provider receipt READ cursor plus cumulative receipt memo.
|
|
3
|
-
*
|
|
4
|
-
* The hidden receipt tab is append-only machine data (each write batch appends
|
|
5
|
-
* its receipt rows at the tab tail; humans never edit it), so a dispatch does
|
|
6
|
-
* not need to re-read the whole tab to decide idempotency: it needs only the
|
|
7
|
-
* receipts appended since the last verified coverage. This cursor records the
|
|
8
|
-
* LAST receipt row this provider instance has verified as covered — either by
|
|
9
|
-
* parsing it in a previous receipt read, or by writing it in a batch that got
|
|
10
|
-
* a valid `batchUpdate` reply — so the next dispatch reads only the tail band
|
|
11
|
-
* starting AT that row (the row doubles as a sentinel proving the cursor is
|
|
12
|
-
* still inside the tab).
|
|
13
|
-
*
|
|
14
|
-
* Because the cursor advances on every successful read, a band alone cannot
|
|
15
|
-
* answer idempotency for effects that have not been re-dispatched for several
|
|
16
|
-
* batches: their receipt rows fall BELOW the next cursor. The cursor
|
|
17
|
-
* therefore also owns a cumulative memo — every receipt row this instance has
|
|
18
|
-
* ever parsed (bands and full reads alike) — and preflight contexts expose
|
|
19
|
-
* the memo, not just the current band, as their `receipts` view. Receipt
|
|
20
|
-
* lookups never depend on where the cursor happens to sit.
|
|
21
|
-
*
|
|
22
|
-
* Safety contract:
|
|
23
|
-
* - The cursor advances ONLY from a successful receipt READ, to the tail row
|
|
24
|
-
* that read parsed. It is never advanced from a write: receipts appended
|
|
25
|
-
* after the previous read therefore stay inside the next band, are merged
|
|
26
|
-
* into the memo there, and remain replay-recognizable for as long as this
|
|
27
|
-
* instance lives.
|
|
28
|
-
* - Every row at or below the cursor was parsed by this instance since the
|
|
29
|
-
* last reset (append-only tab + snapshot-atomic reads), so memo coverage
|
|
30
|
-
* is exactly "everything the cursor has passed". A concurrent or
|
|
31
|
-
* cross-process append can only grow the tab at the tail, which the next
|
|
32
|
-
* band (starting AT the cursor sentinel) re-reads.
|
|
33
|
-
* - A kill -9 loses the whole cursor AND the memo (instance memory): the next
|
|
34
|
-
* process starts with no cursor and performs the historical FULL
|
|
35
|
-
* `A1:F1048576` receipt read, byte-identical to the pre-cursor behavior.
|
|
36
|
-
* - Cursor missing (< 2), sentinel blank (tab truncated/cleared), or a
|
|
37
|
-
* clipped grid → reset (cursor + memo dropped together) and fall back to
|
|
38
|
-
* one full receipt read, which re-establishes both.
|
|
39
|
-
* - Memo growth is bounded: past `MAX_MEMO_RECEIPTS` the cursor resets, so
|
|
40
|
-
* the instance degrades to the pre-cursor full-read behavior instead of
|
|
41
|
-
* growing unbounded memory.
|
|
42
|
-
*
|
|
43
|
-
* Why instance memory instead of a SQLite column under the writer fence:
|
|
44
|
-
* durable-then-ack coupling only buys savings across a process restart (one
|
|
45
|
-
* full receipt read paid once per restart), while every multi-process and
|
|
46
|
-
* crash-desync case above is already proven safe by the append-only +
|
|
47
|
-
* shift-not-overwrite invariants plus the probe rule that a live cursor
|
|
48
|
-
* after the base read proves complete memo coverage (a receipt miss is then
|
|
49
|
-
* provable and decides `unapplied` from the band), while any coverage the
|
|
50
|
-
* read itself invalidated falls back to one full receipt read (see
|
|
51
|
-
* `readEffectPostconditions`). Keeping the cursor
|
|
52
|
-
* inside the provider also keeps the Sheets adapter free of storage-schema
|
|
53
|
-
* ownership (a fence-coupled cursor would require outbox-kernel, contracts,
|
|
54
|
-
* and storage API changes far outside this optimization's scope).
|
|
55
|
-
*/
|
|
56
|
-
/**
|
|
57
|
-
* Ceiling for the cumulative receipt memo. Beyond it the cursor resets and
|
|
58
|
-
* the instance falls back to the historical per-dispatch full receipt read.
|
|
59
|
-
* ponytail: 200k receipts ≈ tens of MB of small records; upgrade path if a
|
|
60
|
-
* real deployment exceeds this is an acknowledged-effect watermark in
|
|
61
|
-
* SQLite (durable cursor + durable coverage).
|
|
62
|
-
*/
|
|
63
|
-
export const MAX_MEMO_RECEIPTS = 200_000;
|
|
64
|
-
export class ReceiptReadCursor {
|
|
65
|
-
/** Last receipt row (1-based) verified as covered; 0 means "no cursor". */
|
|
66
|
-
lastVerifiedRow = 0;
|
|
67
|
-
/** Every receipt parsed by this instance since the last reset. */
|
|
68
|
-
memo = new Map();
|
|
69
|
-
/**
|
|
70
|
-
* Row (1-based) to START a banded receipt read at, or `undefined` when a
|
|
71
|
-
* full read is required (no usable cursor yet). The band starts AT the
|
|
72
|
-
* cursor row so the known-applied receipt there acts as a sentinel against
|
|
73
|
-
* tab truncation; row 1 is the header, so a cursor below 2 can never prove
|
|
74
|
-
* coverage of a data row and the full read stays.
|
|
75
|
-
*/
|
|
76
|
-
bandStartRow() {
|
|
77
|
-
return this.lastVerifiedRow >= 2 ? this.lastVerifiedRow : undefined;
|
|
78
|
-
}
|
|
79
|
-
/** Monotonic advance; understating the verified tail is always safe. */
|
|
80
|
-
advanceTo(verifiedRow) {
|
|
81
|
-
if (Number.isSafeInteger(verifiedRow) && verifiedRow > this.lastVerifiedRow) {
|
|
82
|
-
this.lastVerifiedRow = verifiedRow;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Merges one parsed read's receipts into the cumulative memo. Re-parsing
|
|
87
|
-
* the same row (the band sentinel is read again every dispatch) is a no-op
|
|
88
|
-
* when the values agree; a different value under an already-covered
|
|
89
|
-
* effectId means the append-only tab was rewritten from under this
|
|
90
|
-
* instance and fails closed exactly like an in-band duplicate.
|
|
91
|
-
*/
|
|
92
|
-
mergeParsed(receipts) {
|
|
93
|
-
for (const [effectId, receipt] of receipts) {
|
|
94
|
-
const known = this.memo.get(effectId);
|
|
95
|
-
if (known !== undefined) {
|
|
96
|
-
if (known.payloadHash !== receipt.payloadHash ||
|
|
97
|
-
known.visibleHash !== receipt.visibleHash ||
|
|
98
|
-
known.visibleRevision !== receipt.visibleRevision) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
this.memo.set(effectId, receipt);
|
|
104
|
-
}
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
/** True when the memo has grown past its ceiling (caller must reset). */
|
|
108
|
-
isOverCapacity() {
|
|
109
|
-
return this.memo.size > MAX_MEMO_RECEIPTS;
|
|
110
|
-
}
|
|
111
|
-
/** True when the next merge could only exceed the ceiling: force a full read. */
|
|
112
|
-
isAtCapacity() {
|
|
113
|
-
return this.memo.size >= MAX_MEMO_RECEIPTS;
|
|
114
|
-
}
|
|
115
|
-
/** True when this instance has covered no receipt row yet. */
|
|
116
|
-
isEmpty() {
|
|
117
|
-
return this.memo.size === 0;
|
|
118
|
-
}
|
|
119
|
-
/** The cumulative receipt coverage every scoped/full read's context exposes. */
|
|
120
|
-
memoView() {
|
|
121
|
-
return this.memo;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Drops the cursor AND the memo together so the next read performs the
|
|
125
|
-
* historical full receipt read; coverage and cursor must never disagree.
|
|
126
|
-
*/
|
|
127
|
-
reset() {
|
|
128
|
-
this.lastVerifiedRow = 0;
|
|
129
|
-
this.memo.clear();
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=receiptCursor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"receiptCursor.js","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/receiptCursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAIH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAEzC,MAAM,OAAO,iBAAiB;IAC5B,2EAA2E;IACnE,eAAe,GAAG,CAAC,CAAC;IAC5B,kEAAkE;IACjD,IAAI,GAAG,IAAI,GAAG,EAA4B,CAAC;IAE5D;;;;;;OAMG;IACI,YAAY;QACjB,OAAO,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC;IACtE,CAAC;IAED,wEAAwE;IACjE,SAAS,CAAC,WAAmB;QAClC,IAAI,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5E,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,WAAW,CAAC,QAA+C;QAChE,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,IAAI,KAAK,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW;oBACzC,KAAK,CAAC,WAAW,KAAK,OAAO,CAAC,WAAW;oBACzC,KAAK,CAAC,eAAe,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC;oBACtD,OAAO,KAAK,CAAC;gBACf,CAAC;gBACD,SAAS;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yEAAyE;IAClE,cAAc;QACnB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAC5C,CAAC;IAED,iFAAiF;IAC1E,YAAY;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,iBAAiB,CAAC;IAC7C,CAAC;IAED,8DAA8D;IACvD,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,gFAAgF;IACzE,QAAQ;QACb,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,IAAI,CAAC,eAAe,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Row-check formula builder for the User_Input check column.
|
|
3
|
-
*
|
|
4
|
-
* The provider writes ONE deterministic formula per created row into the
|
|
5
|
-
* check column (the column directly after the registered range): a `&`
|
|
6
|
-
* concatenation of one length-prefixed, type-tagged TOKEN term per user
|
|
7
|
-
* data column of the row, joined by the shared delimiter. Each term is
|
|
8
|
-
* `IF(ISNUMBER(ref),"n",IF(ISLOGICAL(ref),"b","s"))&LEN(ref)&":"&ref`,
|
|
9
|
-
* mirroring the contracts leaf (`sheets/rowCheck.ts` →
|
|
10
|
-
* {@link renderRowCheckCell}) token-for-token, so the computed string is
|
|
11
|
-
* injective over the row's data vector (delimiter collisions and blank
|
|
12
|
-
* permutations are encoded by the length prefix, not skipped) while the
|
|
13
|
-
* formula stays compact enough that the narrow polling read keeps its
|
|
14
|
-
* payload advantage.
|
|
15
|
-
*
|
|
16
|
-
* The Sheet's recalculation engine maintains the cell afterwards, so any
|
|
17
|
-
* human edit to a data column of that row changes the visible check string
|
|
18
|
-
* without a system write, and every system `updateCells` write to the row
|
|
19
|
-
* (which preserves neighboring formulas — proven) recalcs on the next read.
|
|
20
|
-
* The polling gate compares that computed string against the value derived
|
|
21
|
-
* from canonical SQLite state (contracts `sheets/rowCheck.ts`) and only
|
|
22
|
-
* escalates mismatched rows to targeted full-field reads.
|
|
23
|
-
*
|
|
24
|
-
* Branch equivalences the renderer mirrors: a blank or empty-string cell
|
|
25
|
-
* concatenates to "" with LEN 0 under the `s` tag (`s0:`); a date cell
|
|
26
|
-
* ISNUMBER-concatenates its bare serial; a boolean concatenates to
|
|
27
|
-
* TRUE/FALSE under the `b` tag; an error or an unsupported render propagates
|
|
28
|
-
* (or disagrees) as a MISMATCH — the safe direction. `ponytail`: ~70
|
|
29
|
-
* formula chars per column; a Sheet's ~10k formula cap ceilings this at
|
|
30
|
-
* roughly 140 data columns — beyond that, hash the row server-side instead
|
|
31
|
-
* of encoding it.
|
|
32
|
-
*/
|
|
33
|
-
/** Returns the row-check formula text (with leading `=`) for one row. */
|
|
34
|
-
export declare function buildRowCheckFormula(firstDataColumn: number, lastDataColumn: number, rowNumber: number): string;
|
|
35
|
-
//# sourceMappingURL=rowCheckFormula.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rowCheckFormula.d.ts","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/rowCheckFormula.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AASH,yEAAyE;AACzE,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,GAChB,MAAM,CAMR"}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Row-check formula builder for the User_Input check column.
|
|
3
|
-
*
|
|
4
|
-
* The provider writes ONE deterministic formula per created row into the
|
|
5
|
-
* check column (the column directly after the registered range): a `&`
|
|
6
|
-
* concatenation of one length-prefixed, type-tagged TOKEN term per user
|
|
7
|
-
* data column of the row, joined by the shared delimiter. Each term is
|
|
8
|
-
* `IF(ISNUMBER(ref),"n",IF(ISLOGICAL(ref),"b","s"))&LEN(ref)&":"&ref`,
|
|
9
|
-
* mirroring the contracts leaf (`sheets/rowCheck.ts` →
|
|
10
|
-
* {@link renderRowCheckCell}) token-for-token, so the computed string is
|
|
11
|
-
* injective over the row's data vector (delimiter collisions and blank
|
|
12
|
-
* permutations are encoded by the length prefix, not skipped) while the
|
|
13
|
-
* formula stays compact enough that the narrow polling read keeps its
|
|
14
|
-
* payload advantage.
|
|
15
|
-
*
|
|
16
|
-
* The Sheet's recalculation engine maintains the cell afterwards, so any
|
|
17
|
-
* human edit to a data column of that row changes the visible check string
|
|
18
|
-
* without a system write, and every system `updateCells` write to the row
|
|
19
|
-
* (which preserves neighboring formulas — proven) recalcs on the next read.
|
|
20
|
-
* The polling gate compares that computed string against the value derived
|
|
21
|
-
* from canonical SQLite state (contracts `sheets/rowCheck.ts`) and only
|
|
22
|
-
* escalates mismatched rows to targeted full-field reads.
|
|
23
|
-
*
|
|
24
|
-
* Branch equivalences the renderer mirrors: a blank or empty-string cell
|
|
25
|
-
* concatenates to "" with LEN 0 under the `s` tag (`s0:`); a date cell
|
|
26
|
-
* ISNUMBER-concatenates its bare serial; a boolean concatenates to
|
|
27
|
-
* TRUE/FALSE under the `b` tag; an error or an unsupported render propagates
|
|
28
|
-
* (or disagrees) as a MISMATCH — the safe direction. `ponytail`: ~70
|
|
29
|
-
* formula chars per column; a Sheet's ~10k formula cap ceilings this at
|
|
30
|
-
* roughly 140 data columns — beyond that, hash the row server-side instead
|
|
31
|
-
* of encoding it.
|
|
32
|
-
*/
|
|
33
|
-
import { SYNC_ROW_CHECK_DELIMITER, SYNC_ROW_CHECK_LENGTH_SEPARATOR, SYNC_ROW_CHECK_TOKEN_TAGS, } from "../../../../contracts/sheets/rowCheck.js";
|
|
34
|
-
import { columnLetters } from "./valueNormalization.js";
|
|
35
|
-
/** Returns the row-check formula text (with leading `=`) for one row. */
|
|
36
|
-
export function buildRowCheckFormula(firstDataColumn, lastDataColumn, rowNumber) {
|
|
37
|
-
const terms = [];
|
|
38
|
-
for (let column = firstDataColumn; column <= lastDataColumn; column += 1) {
|
|
39
|
-
terms.push(buildRowCheckTerm(`${columnLetters(column)}${rowNumber}`));
|
|
40
|
-
}
|
|
41
|
-
return `=${terms.join(`&"${SYNC_ROW_CHECK_DELIMITER}"&`)}`;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* One column's token term for cell `ref`, generated from the shared
|
|
45
|
-
* delimiter/tag constants so the formula and the SQLite-side renderer can
|
|
46
|
-
* never drift apart silently. Text is the fallback tag (a blank or
|
|
47
|
-
* empty-string cell renders exactly like the renderer's zero-length `s`
|
|
48
|
-
* token); errors propagate through LEN/concatenation.
|
|
49
|
-
*/
|
|
50
|
-
function buildRowCheckTerm(ref) {
|
|
51
|
-
const text = SYNC_ROW_CHECK_TOKEN_TAGS.STRING;
|
|
52
|
-
const number = SYNC_ROW_CHECK_TOKEN_TAGS.NUMBER;
|
|
53
|
-
const bool = SYNC_ROW_CHECK_TOKEN_TAGS.BOOLEAN;
|
|
54
|
-
return `IF(ISNUMBER(${ref}),"${number}",IF(ISLOGICAL(${ref}),"${bool}","${text}"))`
|
|
55
|
-
+ `&LEN(${ref})&"${SYNC_ROW_CHECK_LENGTH_SEPARATOR}"&${ref}`;
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=rowCheckFormula.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rowCheckFormula.js","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/rowCheckFormula.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EACL,wBAAwB,EACxB,+BAA+B,EAC/B,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD,yEAAyE;AACzE,MAAM,UAAU,oBAAoB,CAClC,eAAuB,EACvB,cAAsB,EACtB,SAAiB;IAEjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,IAAI,MAAM,GAAG,eAAe,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QACzE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,wBAAwB,IAAI,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC;IAC9C,MAAM,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC;IAChD,MAAM,IAAI,GAAG,yBAAyB,CAAC,OAAO,CAAC;IAC/C,OAAO,eAAe,GAAG,MAAM,MAAM,kBAAkB,GAAG,MAAM,IAAI,MAAM,IAAI,KAAK;UAC/E,QAAQ,GAAG,MAAM,+BAA+B,KAAK,GAAG,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deterministic sheet-id allocation for the direct Sheets provider.
|
|
3
|
-
*
|
|
4
|
-
* The provider self-assigns numeric sheet ids when it creates tabs (the
|
|
5
|
-
* provisioned projection tabs and the hidden receipt tab). The allocator is
|
|
6
|
-
* deterministic and fail-closed: it picks the smallest positive 31-bit id
|
|
7
|
-
* not already used by any tab, so repeated provision attempts against the
|
|
8
|
-
* same spreadsheet never drift and a colliding id can never be emitted.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Returns the smallest positive 31-bit sheet id that collides with none of
|
|
12
|
-
* the supplied ids. Fails closed when no free id remains (unreachable for
|
|
13
|
-
* any real spreadsheet, but the contract must not invent an invalid id).
|
|
14
|
-
*/
|
|
15
|
-
export declare function allocateSheetId(existing: ReadonlySet<number> | readonly number[]): number;
|
|
16
|
-
//# sourceMappingURL=sheetIdAllocator.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sheetIdAllocator.d.ts","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/sheetIdAllocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,MAAM,EAAE,GAChD,MAAM,CAQR"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Deterministic sheet-id allocation for the direct Sheets provider.
|
|
3
|
-
*
|
|
4
|
-
* The provider self-assigns numeric sheet ids when it creates tabs (the
|
|
5
|
-
* provisioned projection tabs and the hidden receipt tab). The allocator is
|
|
6
|
-
* deterministic and fail-closed: it picks the smallest positive 31-bit id
|
|
7
|
-
* not already used by any tab, so repeated provision attempts against the
|
|
8
|
-
* same spreadsheet never drift and a colliding id can never be emitted.
|
|
9
|
-
*/
|
|
10
|
-
import { invalidProviderState } from "../errors.js";
|
|
11
|
-
/** Smallest positive 31-bit signed integer accepted by the Sheets API. */
|
|
12
|
-
const MIN_SHEET_ID = 1;
|
|
13
|
-
const MAX_SHEET_ID = 0x7fffffff;
|
|
14
|
-
/**
|
|
15
|
-
* Returns the smallest positive 31-bit sheet id that collides with none of
|
|
16
|
-
* the supplied ids. Fails closed when no free id remains (unreachable for
|
|
17
|
-
* any real spreadsheet, but the contract must not invent an invalid id).
|
|
18
|
-
*/
|
|
19
|
-
export function allocateSheetId(existing) {
|
|
20
|
-
const used = existing instanceof Set
|
|
21
|
-
? existing
|
|
22
|
-
: new Set(existing);
|
|
23
|
-
for (let candidate = MIN_SHEET_ID; candidate <= MAX_SHEET_ID; candidate += 1) {
|
|
24
|
-
if (!used.has(candidate))
|
|
25
|
-
return candidate;
|
|
26
|
-
}
|
|
27
|
-
invalidProviderState("no free sheet id remains for tab creation");
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=sheetIdAllocator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sheetIdAllocator.js","sourceRoot":"","sources":["../../../../../../../../src/sheets/providers/google-sheets-api/model/sheetIdAllocator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,0EAA0E;AAC1E,MAAM,YAAY,GAAG,CAAC,CAAC;AACvB,MAAM,YAAY,GAAG,UAAU,CAAC;AAEhC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAiD;IAEjD,MAAM,IAAI,GAAG,QAAQ,YAAY,GAAG;QAClC,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,KAAK,IAAI,SAAS,GAAG,YAAY,EAAE,SAAS,IAAI,YAAY,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QAC7E,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;IAC7C,CAAC;IACD,oBAAoB,CAAC,2CAA2C,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unified read engine executor (design/unified-read-engine.md §3).
|
|
3
|
-
*
|
|
4
|
-
* Runs an already-packed band plan as SEQUENTIAL paced `spreadsheets.get`
|
|
5
|
-
* requests on the lane's request-start class and reassembles the replies
|
|
6
|
-
* into one logical document: every requested range's GridData in request
|
|
7
|
-
* order, concatenated per sheet id, so lanes consume band replies through
|
|
8
|
-
* the SAME accessors (`resolveGridCell`, `synthesizeScopedTargetGrid`,
|
|
9
|
-
* `pickRegisteredGrid`) that serve today's multi-range replies. Each band
|
|
10
|
-
* is one server snapshot and consumes exactly one `runRead` slot, so:
|
|
11
|
-
* - telemetry emits ONE event per band with the RAW-document `responseBytes`
|
|
12
|
-
* (sink-gated exactly like the historical reads) — per-lane, per-band
|
|
13
|
-
* bytes are observable without any extra plumbing;
|
|
14
|
-
* - a timeout or rejection fails ONE band with the existing
|
|
15
|
-
* delivery-uncertain classification instead of an all-or-nothing
|
|
16
|
-
* multi-megabyte single request;
|
|
17
|
-
* - every response's `sheets.properties.gridProperties.rowCount` refreshes
|
|
18
|
-
* the provider-instance authoritative bounds cache (a ranged GET returns
|
|
19
|
-
* properties for the intersecting sheets), and `responseBytes ÷
|
|
20
|
-
* cellsRequested` feeds the per-evidence calibration multiplier, so a
|
|
21
|
-
* mispredicted band size shrinks the NEXT pass's bands.
|
|
22
|
-
*/
|
|
23
|
-
import type { BandedGet, EngineRuntime, ReadEvidence } from "../model/readPlan.js";
|
|
24
|
-
import { type GoogleSheetsApiProviderDeps, type RequestStartPacing } from "./shared.js";
|
|
25
|
-
/**
|
|
26
|
-
* Builds the executor for ONE logical read: fixed field mask, evidence
|
|
27
|
-
* class, pacing lane, and telemetry label. The returned closure owns no
|
|
28
|
-
* state — bounds/calibration updates land on the shared `deps` carriers.
|
|
29
|
-
*/
|
|
30
|
-
export declare function createBandedGet(deps: GoogleSheetsApiProviderDeps, pacing: RequestStartPacing, fields: string, evidence: ReadEvidence, label: string): BandedGet;
|
|
31
|
-
/**
|
|
32
|
-
* Builds the model-facing engine runtime for one logical read on one lane:
|
|
33
|
-
* the fields/evidence → executor factory plus the shared bounds cache and
|
|
34
|
-
* calibration tracker. Model functions receive this instead of a raw
|
|
35
|
-
* transport, which is what lets a single logical read expand into
|
|
36
|
-
* sequential paced band requests WITHOUT the model layer importing the
|
|
37
|
-
* operations layer.
|
|
38
|
-
*/
|
|
39
|
-
export declare function createEngineRuntime(deps: GoogleSheetsApiProviderDeps, pacing: RequestStartPacing, label: string): EngineRuntime;
|
|
40
|
-
/**
|
|
41
|
-
* Ensures every listed tab has an authoritative row bound in the
|
|
42
|
-
* provider-instance cache, settling cold titles with ONE range-less
|
|
43
|
-
* metadata enumeration (`gridProperties.rowCount` is metadata-only). The
|
|
44
|
-
* cache is refreshed by every subsequent engine response's sheet
|
|
45
|
-
* properties, so the enumeration is a once-per-title-per-instance cost —
|
|
46
|
-
* the polling lane has no per-dispatch enumeration of its own and this is
|
|
47
|
-
* where its committed upper bound comes from.
|
|
48
|
-
*/
|
|
49
|
-
export declare function ensureSheetRowBounds(deps: GoogleSheetsApiProviderDeps, pacing: RequestStartPacing, titles: readonly string[]): Promise<void>;
|
|
50
|
-
//# sourceMappingURL=readEngine.d.ts.map
|