hikoutei 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +47 -23
- 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
|
@@ -38,12 +38,12 @@ SQLite transaction
|
|
|
38
38
|
▼
|
|
39
39
|
internal effect supervisor
|
|
40
40
|
├─ claim with a lease
|
|
41
|
-
├─ send a signed operation batch
|
|
41
|
+
├─ send a signed operation batch (gateway) or a direct REST batch
|
|
42
42
|
├─ persist uncertain delivery and schedule a durable postcondition probe
|
|
43
43
|
└─ mark the effect applied, terminally failed, or recoverably pending
|
|
44
44
|
│
|
|
45
45
|
▼
|
|
46
|
-
Apps Script gateway ──▶ Google Sheets
|
|
46
|
+
full direct provider / legacy Apps Script gateway ──▶ Google Sheets
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
A successful `flush()` means that SQLite accepted the local change and queued
|
|
@@ -60,6 +60,40 @@ so one gateway call returns a complete result set instead of a partial prefix.
|
|
|
60
60
|
These operation types are implementation details and are not methods on the
|
|
61
61
|
public EntityManager.
|
|
62
62
|
|
|
63
|
+
### Outbound providers
|
|
64
|
+
|
|
65
|
+
The outbound half of the worker can run through one of three interchangeable
|
|
66
|
+
providers behind the same `SyncEffectWorkerFullGateway` contract:
|
|
67
|
+
|
|
68
|
+
- **Full direct Google Sheets API (preferred, `googleSheetsApi`):** ONE
|
|
69
|
+
service-account provider owns provisioning, outbound effects, table reads,
|
|
70
|
+
row anchors, and User_Input observation with no Apps Script at all.
|
|
71
|
+
- **Apps Script gateway (legacy):** every fast append, guarded effect, and
|
|
72
|
+
recovery probe is a signed operation executed by the deployed `Code.gs`.
|
|
73
|
+
It remains supported but is deprecated; new setups should use the full
|
|
74
|
+
direct provider.
|
|
75
|
+
- **Direct outbound worker (deprecated, `googleApiWorker`):** the worker
|
|
76
|
+
talks to the Sheets REST API directly with a service account (Application
|
|
77
|
+
Default Credentials) while Apps Script (or an injected gateway) still owns
|
|
78
|
+
provisioning and User_Input observation. Superseded by `googleSheetsApi`,
|
|
79
|
+
which moves provisioning and observation into the direct provider as well.
|
|
80
|
+
|
|
81
|
+
The direct provider ports the Apps Script semantics to TypeScript: bulk
|
|
82
|
+
preflight with fail-closed validation (headers, anchors, identities,
|
|
83
|
+
receipts), receipt replay/idempotency, visible/candidate/repair guards,
|
|
84
|
+
full-row deletion guards, one atomic `spreadsheets.batchUpdate` per
|
|
85
|
+
applicable target mutation + receipt write, and receipt-backed postcondition
|
|
86
|
+
recovery. It disables SDK auto-retry (the durable worker owns retries),
|
|
87
|
+
spaces request starts at 1,100 ms per class (reads and writes separately),
|
|
88
|
+
and trims a serialized batch over ~2 MB to an order-preserving prefix with
|
|
89
|
+
`hasMore`. Transport outcomes are classified by the shared
|
|
90
|
+
`classifyTransportOutcome` boundary: pre-mutation 4xx rejections are explicit
|
|
91
|
+
remote failures; timeouts, network errors, 408/429/5xx, and malformed 2xx
|
|
92
|
+
replies stay delivery-uncertain and are probed like Apps Script response loss.
|
|
93
|
+
This mode is not a performance claim; the raw-transport experiments under
|
|
94
|
+
`scripts/bench/` measure the unguarded API path without receipts or
|
|
95
|
+
compare-and-set.
|
|
96
|
+
|
|
63
97
|
## Inbound User_Input flow
|
|
64
98
|
|
|
65
99
|
The internal service polls registered `User_Input` projections on a bounded
|
|
@@ -110,23 +144,32 @@ Projection provisioning is an internal service-start operation. The bootstrap
|
|
|
110
144
|
generates route registrations and headers for the required System_State,
|
|
111
145
|
User_Input, and Sync_Conflicts projections, verifies remote schema drift, and
|
|
112
146
|
starts workers only after provisioning and unresolved-conflict backfill succeed.
|
|
113
|
-
|
|
147
|
+
In the preferred `googleSheetsApi` mode the full direct provider provisions
|
|
148
|
+
the tabs itself — creating missing tabs, initializing truly-empty tabs, and
|
|
149
|
+
failing closed on header drift — with no Apps Script involved. In the legacy
|
|
150
|
+
Apps Script mode the gateway remains intentionally thin:
|
|
114
151
|
|
|
115
152
|
1. verify the signed operation envelope
|
|
116
153
|
2. validate the operation contract
|
|
117
154
|
3. execute the signed operation source, whose contract validates the registered Sheet operation
|
|
118
155
|
4. return a structured result to the internal worker
|
|
119
156
|
|
|
120
|
-
The
|
|
157
|
+
The gateway contract is a single deployable file:
|
|
121
158
|
`apps-script/gateway/Code.gs`. A user copies it into a spreadsheet-bound Apps
|
|
122
159
|
Script project, deploys it as a Web App, pastes the deployed `/exec` URL into
|
|
123
160
|
the `TYPED_SHEETS_GATEWAY_URL` constant, and runs `setupSyncGateway()` from the
|
|
124
161
|
editor. That setup writes the bound spreadsheet ID and a generated shared
|
|
125
|
-
secret into Script Properties and logs a copyable local `.env` block.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
162
|
+
secret into Script Properties and logs a copyable local `.env` block. The
|
|
163
|
+
current fast-append implementation unconditionally writes append target rows
|
|
164
|
+
through the Apps Script Advanced Sheets Service; there is no runtime
|
|
165
|
+
enablement switch, so the bundled `appsscript.json` manifest (Sheets v4
|
|
166
|
+
advanced service enabled) and Google Cloud Sheets API activation in the
|
|
167
|
+
script's Cloud project are mandatory for the current temporary append path.
|
|
168
|
+
A legacy deployment that runs only on the built-in `SpreadsheetApp`,
|
|
169
|
+
`LockService`, and `PropertiesService` services must first restore the
|
|
170
|
+
commented rollback block in `batchAppendOperation.ts`, which reverts the
|
|
171
|
+
append target write to the built-in services path. No service account is
|
|
172
|
+
required. The signed gateway secret is a code-execution trust boundary;
|
|
130
173
|
keep it private and rotate the previously exposed value before production
|
|
131
174
|
deployment.
|
|
132
175
|
|
|
@@ -139,13 +182,26 @@ effect is recognized as already applied and never double-materialized), the
|
|
|
139
182
|
SQLite durable outbox (effects survive restarts and are delivered
|
|
140
183
|
at-least-once), fencing (spreadsheet authority epoch/token and worker/effect
|
|
141
184
|
leases reject stale writers), and postcondition recovery (uncertain deliveries
|
|
142
|
-
are probed until receipt-backed visible evidence matches).
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
185
|
+
are probed until receipt-backed visible evidence matches). The temporary
|
|
186
|
+
test-batch append operation writes a whole bulk append batch in one RAW
|
|
187
|
+
ValueRange through the Apps Script Advanced Sheets Service; that call is
|
|
188
|
+
unconditional in the current implementation, so the only way back to the
|
|
189
|
+
built-in services write is restoring the commented rollback block in
|
|
190
|
+
`batchAppendOperation.ts`, while the rest of the gateway runs on built-in
|
|
191
|
+
services.
|
|
146
192
|
|
|
147
193
|
Applications do not import or call the gateway client, protocol, operation
|
|
148
|
-
builders, polling functions, or
|
|
194
|
+
builders, polling functions, provisioning interfaces, or the direct Sheets
|
|
195
|
+
API provider.
|
|
196
|
+
|
|
197
|
+
In direct mode the same spreadsheet must be reachable by the service account
|
|
198
|
+
(the full provider owns provisioning, outbound writes, and observation): one
|
|
199
|
+
SQLite runtime is the single authoritative writer for the whole spreadsheet.
|
|
200
|
+
The tracked live scenario
|
|
201
|
+
(`scripts/ci/run-api-scenario.mjs --backend live --outbound direct`) verifies
|
|
202
|
+
provisioning from an empty spreadsheet, append/update/delete delivery, mapped
|
|
203
|
+
User_Input polling, stale-edit CAS guards, anchor evidence, and cleanup
|
|
204
|
+
without any Apps Script deployment.
|
|
149
205
|
|
|
150
206
|
## Failure model
|
|
151
207
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hikoutei",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Hikoutei — typed repository and safe write layer for Google Sheets-backed MVPs.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
24
24
|
"docs",
|
|
25
|
-
"apps-script/gateway/Code.gs"
|
|
25
|
+
"apps-script/gateway/Code.gs",
|
|
26
|
+
"apps-script/gateway/appsscript.json"
|
|
26
27
|
],
|
|
27
28
|
"scripts": {
|
|
28
29
|
"clean": "node scripts/clean-dist.mjs",
|
|
@@ -39,7 +40,9 @@
|
|
|
39
40
|
],
|
|
40
41
|
"license": "MIT",
|
|
41
42
|
"dependencies": {
|
|
42
|
-
"@
|
|
43
|
+
"@googleapis/sheets": "^14.0.0",
|
|
44
|
+
"@hikoutei/kohkai": "0.1.0",
|
|
45
|
+
"google-auth-library": "^11.0.0"
|
|
43
46
|
},
|
|
44
47
|
"devDependencies": {
|
|
45
48
|
"@mikro-orm/core": "7.1.7",
|