hikoutei 0.3.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/README.md +88 -15
  2. package/apps-script/gateway/appsscript.json +17 -0
  3. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +9 -1
  4. package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -1
  5. package/dist/adapter/sheets/providers/apps-script-gateway/index.js +9 -1
  6. package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -1
  7. package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +1 -1
  8. package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +1 -1
  9. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts +18 -10
  10. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.d.ts.map +1 -1
  11. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js +157 -27
  12. package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/batchAppendOperation.js.map +1 -1
  13. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +4 -2
  14. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -1
  15. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +4 -2
  16. package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -1
  17. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts +27 -0
  18. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.d.ts.map +1 -0
  19. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js +14 -0
  20. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiEffectGateway.js.map +1 -0
  21. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts +156 -0
  22. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.d.ts.map +1 -0
  23. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js +1138 -0
  24. package/dist/adapter/sheets/providers/google-sheets-api/GoogleSheetsApiSyncProvider.js.map +1 -0
  25. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts +87 -0
  26. package/dist/adapter/sheets/providers/google-sheets-api/constants.d.ts.map +1 -0
  27. package/dist/adapter/sheets/providers/google-sheets-api/constants.js +97 -0
  28. package/dist/adapter/sheets/providers/google-sheets-api/constants.js.map +1 -0
  29. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts +53 -0
  30. package/dist/adapter/sheets/providers/google-sheets-api/errors.d.ts.map +1 -0
  31. package/dist/adapter/sheets/providers/google-sheets-api/errors.js +61 -0
  32. package/dist/adapter/sheets/providers/google-sheets-api/errors.js.map +1 -0
  33. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts +18 -0
  34. package/dist/adapter/sheets/providers/google-sheets-api/index.d.ts.map +1 -0
  35. package/dist/adapter/sheets/providers/google-sheets-api/index.js +14 -0
  36. package/dist/adapter/sheets/providers/google-sheets-api/index.js.map +1 -0
  37. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts +83 -0
  38. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.d.ts.map +1 -0
  39. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js +413 -0
  40. package/dist/adapter/sheets/providers/google-sheets-api/model/batchBuilder.js.map +1 -0
  41. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts +86 -0
  42. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.d.ts.map +1 -0
  43. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js +439 -0
  44. package/dist/adapter/sheets/providers/google-sheets-api/model/observation.js.map +1 -0
  45. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts +115 -0
  46. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.d.ts.map +1 -0
  47. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js +522 -0
  48. package/dist/adapter/sheets/providers/google-sheets-api/model/planner.js.map +1 -0
  49. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts +17 -0
  50. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.d.ts.map +1 -0
  51. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js +99 -0
  52. package/dist/adapter/sheets/providers/google-sheets-api/model/postcondition.js.map +1 -0
  53. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts +242 -0
  54. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.d.ts.map +1 -0
  55. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js +707 -0
  56. package/dist/adapter/sheets/providers/google-sheets-api/model/preflight.js.map +1 -0
  57. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts +16 -0
  58. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.d.ts.map +1 -0
  59. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js +29 -0
  60. package/dist/adapter/sheets/providers/google-sheets-api/model/sheetIdAllocator.js.map +1 -0
  61. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts +26 -0
  62. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.d.ts.map +1 -0
  63. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js +57 -0
  64. package/dist/adapter/sheets/providers/google-sheets-api/model/tableRead.js.map +1 -0
  65. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts +102 -0
  66. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.d.ts.map +1 -0
  67. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js +375 -0
  68. package/dist/adapter/sheets/providers/google-sheets-api/model/valueNormalization.js.map +1 -0
  69. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts +168 -0
  70. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.d.ts.map +1 -0
  71. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js +247 -0
  72. package/dist/adapter/sheets/providers/google-sheets-api/transport/googleSheetsApiTransport.js.map +1 -0
  73. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts +47 -0
  74. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.d.ts.map +1 -0
  75. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js +60 -0
  76. package/dist/adapter/sheets/providers/google-sheets-api/transport/rateLimiter.js.map +1 -0
  77. package/dist/application/sync/gateway/RoutedSyncGateway.d.ts +59 -0
  78. package/dist/application/sync/gateway/RoutedSyncGateway.d.ts.map +1 -0
  79. package/dist/application/sync/gateway/RoutedSyncGateway.js +86 -0
  80. package/dist/application/sync/gateway/RoutedSyncGateway.js.map +1 -0
  81. package/dist/application/sync/gateway/transportClassification.d.ts +12 -0
  82. package/dist/application/sync/gateway/transportClassification.d.ts.map +1 -1
  83. package/dist/application/sync/gateway/transportClassification.js +37 -0
  84. package/dist/application/sync/gateway/transportClassification.js.map +1 -1
  85. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts +16 -0
  86. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.d.ts.map +1 -1
  87. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js +26 -0
  88. package/dist/application/sync/outbound/effects/AdaptiveEffectBatchController.js.map +1 -1
  89. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -1
  90. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +23 -3
  91. package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -1
  92. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +15 -0
  93. package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -1
  94. package/dist/application/sync/outbound/effects/SyncEffectWorker.js +61 -8
  95. package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -1
  96. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +15 -0
  97. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -1
  98. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +15 -0
  99. package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -1
  100. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +4 -0
  101. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -1
  102. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +16 -0
  103. package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -1
  104. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +8 -0
  105. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -1
  106. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +22 -2
  107. package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -1
  108. package/dist/application/sync/service/SyncServiceBootstrap.d.ts +23 -1
  109. package/dist/application/sync/service/SyncServiceBootstrap.d.ts.map +1 -1
  110. package/dist/application/sync/service/SyncServiceBootstrap.js +162 -8
  111. package/dist/application/sync/service/SyncServiceBootstrap.js.map +1 -1
  112. package/dist/infrastructure/storage/index.d.ts +1 -1
  113. package/dist/infrastructure/storage/index.d.ts.map +1 -1
  114. package/dist/infrastructure/storage/index.js +1 -1
  115. package/dist/infrastructure/storage/index.js.map +1 -1
  116. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +12 -0
  117. package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -1
  118. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +22 -1
  119. package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -1
  120. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +10 -0
  121. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -1
  122. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +38 -0
  123. package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -1
  124. package/docs/architecture.md +57 -13
  125. package/docs/ci.md +47 -23
  126. package/docs/development.md +35 -5
  127. package/docs/quick-start.md +43 -11
  128. package/docs/sync-bulk-write-benchmark.md +561 -0
  129. package/docs/write-and-synchronization-flow.md +70 -14
  130. package/package.json +6 -3
@@ -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
- The Apps Script gateway remains intentionally thin:
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 MVP gateway contract is a single deployable file:
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. This path
126
- requires no `appsscript.json` manifest, no Apps Script Advanced Sheets Service,
127
- no Google Cloud Sheets API activation, and no service account; the gateway runs
128
- on the built-in `SpreadsheetApp`, `LockService`, and `PropertiesService`
129
- services only. The signed gateway secret is a code-execution trust boundary;
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). A batch-append
143
- operation source that would use the Apps Script Advanced Sheets Service and an
144
- `appsscript.json` manifest exists only as an out-of-MVP performance experiment;
145
- it is not part of the default installation.
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 provisioning interfaces.
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",
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
- "@hikoutei/kohkai": "0.1.0"
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",