hikoutei 0.2.0
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/LICENSE +21 -0
- package/README.ja.md +135 -0
- package/README.ko.md +138 -0
- package/README.md +143 -0
- package/apps-script/gateway/Code.gs +412 -0
- package/dist/adapter/persistence/contracts/index.d.ts +3 -0
- package/dist/adapter/persistence/contracts/index.d.ts.map +1 -0
- package/dist/adapter/persistence/contracts/index.js +3 -0
- package/dist/adapter/persistence/contracts/index.js.map +1 -0
- package/dist/adapter/persistence/contracts/sql.d.ts +50 -0
- package/dist/adapter/persistence/contracts/sql.d.ts.map +1 -0
- package/dist/adapter/persistence/contracts/sql.js +9 -0
- package/dist/adapter/persistence/contracts/sql.js.map +1 -0
- package/dist/adapter/persistence/index.d.ts +2 -0
- package/dist/adapter/persistence/index.d.ts.map +1 -0
- package/dist/adapter/persistence/index.js +2 -0
- package/dist/adapter/persistence/index.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.d.ts +53 -0
- package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.js +105 -0
- package/dist/adapter/persistence/providers/mikro-orm/api/MikroOrmTypedSheetsEntityManager.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts +39 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js +54 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmMappedTypedSheets.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.d.ts +38 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.js +55 -0
- package/dist/adapter/persistence/providers/mikro-orm/engine/MikroOrmTypedSheetsEngine.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/index.d.ts +16 -0
- package/dist/adapter/persistence/providers/mikro-orm/index.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/index.js +9 -0
- package/dist/adapter/persistence/providers/mikro-orm/index.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts +27 -0
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js +67 -0
- package/dist/adapter/persistence/providers/mikro-orm/observation/MikroOrmMappedObservation.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.d.ts +19 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.js +67 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmFlushChanges.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.d.ts +78 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.js +121 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteAdapter.js.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.d.ts +20 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.d.ts.map +1 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.js +125 -0
- package/dist/adapter/persistence/providers/mikro-orm/storage/MikroOrmSqliteSchema.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts +42 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.js +51 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/errors.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts +22 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/index.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js +12 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/index.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts +42 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js +161 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperation.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts +3 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js +692 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/effect/effectOperationScript.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts +29 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js +538 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/observation/observationOperation.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts +12 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js +190 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/read/tableReadOperation.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts +23 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js +166 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/operations/write/fastAppendOperation.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts +50 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js +60 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/codeGsProtocol.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts +44 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js +40 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/constants.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts +7 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js +47 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/syncProtocol.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts +5 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js +54 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/timing.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts +5 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js +2 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/types.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts +10 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js +35 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/protocol/validation.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts +67 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js +204 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationClient.js.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts +78 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.d.ts.map +1 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js +343 -0
- package/dist/adapter/sheets/providers/apps-script-gateway/transport/operationSyncGateway.js.map +1 -0
- package/dist/application/index.d.ts +4 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +4 -0
- package/dist/application/index.js.map +1 -0
- package/dist/application/orm/api/TypedSheetsOrm.d.ts +71 -0
- package/dist/application/orm/api/TypedSheetsOrm.d.ts.map +1 -0
- package/dist/application/orm/api/TypedSheetsOrm.js +116 -0
- package/dist/application/orm/api/TypedSheetsOrm.js.map +1 -0
- package/dist/application/orm/api/contracts.d.ts +118 -0
- package/dist/application/orm/api/contracts.d.ts.map +1 -0
- package/dist/application/orm/api/contracts.js +21 -0
- package/dist/application/orm/api/contracts.js.map +1 -0
- package/dist/application/orm/errors.d.ts +35 -0
- package/dist/application/orm/errors.d.ts.map +1 -0
- package/dist/application/orm/errors.js +35 -0
- package/dist/application/orm/errors.js.map +1 -0
- package/dist/application/orm/index.d.ts +13 -0
- package/dist/application/orm/index.d.ts.map +1 -0
- package/dist/application/orm/index.js +7 -0
- package/dist/application/orm/index.js.map +1 -0
- package/dist/application/orm/mapping/contracts.d.ts +113 -0
- package/dist/application/orm/mapping/contracts.d.ts.map +1 -0
- package/dist/application/orm/mapping/contracts.js +8 -0
- package/dist/application/orm/mapping/contracts.js.map +1 -0
- package/dist/application/orm/mapping/definition.d.ts +16 -0
- package/dist/application/orm/mapping/definition.d.ts.map +1 -0
- package/dist/application/orm/mapping/definition.js +145 -0
- package/dist/application/orm/mapping/definition.js.map +1 -0
- package/dist/application/orm/mapping/entityMapping.d.ts +13 -0
- package/dist/application/orm/mapping/entityMapping.d.ts.map +1 -0
- package/dist/application/orm/mapping/entityMapping.js +13 -0
- package/dist/application/orm/mapping/entityMapping.js.map +1 -0
- package/dist/application/orm/mapping/identity.d.ts +14 -0
- package/dist/application/orm/mapping/identity.d.ts.map +1 -0
- package/dist/application/orm/mapping/identity.js +37 -0
- package/dist/application/orm/mapping/identity.js.map +1 -0
- package/dist/application/orm/mapping/observationMapping.d.ts +42 -0
- package/dist/application/orm/mapping/observationMapping.d.ts.map +1 -0
- package/dist/application/orm/mapping/observationMapping.js +65 -0
- package/dist/application/orm/mapping/observationMapping.js.map +1 -0
- package/dist/application/orm/mapping/projection.d.ts +22 -0
- package/dist/application/orm/mapping/projection.d.ts.map +1 -0
- package/dist/application/orm/mapping/projection.js +74 -0
- package/dist/application/orm/mapping/projection.js.map +1 -0
- package/dist/application/orm/mapping/registry.d.ts +15 -0
- package/dist/application/orm/mapping/registry.d.ts.map +1 -0
- package/dist/application/orm/mapping/registry.js +38 -0
- package/dist/application/orm/mapping/registry.js.map +1 -0
- package/dist/application/orm/mapping/values.d.ts +17 -0
- package/dist/application/orm/mapping/values.d.ts.map +1 -0
- package/dist/application/orm/mapping/values.js +141 -0
- package/dist/application/orm/mapping/values.js.map +1 -0
- package/dist/application/orm/persistence/flush/flushCoordinator.d.ts +28 -0
- package/dist/application/orm/persistence/flush/flushCoordinator.d.ts.map +1 -0
- package/dist/application/orm/persistence/flush/flushCoordinator.js +170 -0
- package/dist/application/orm/persistence/flush/flushCoordinator.js.map +1 -0
- package/dist/application/orm/persistence/flush/mappedFlushCoordinator.d.ts +9 -0
- package/dist/application/orm/persistence/flush/mappedFlushCoordinator.d.ts.map +1 -0
- package/dist/application/orm/persistence/flush/mappedFlushCoordinator.js +8 -0
- package/dist/application/orm/persistence/flush/mappedFlushCoordinator.js.map +1 -0
- package/dist/application/orm/persistence/lifecycle/entityLifecycle.d.ts +12 -0
- package/dist/application/orm/persistence/lifecycle/entityLifecycle.d.ts.map +1 -0
- package/dist/application/orm/persistence/lifecycle/entityLifecycle.js +134 -0
- package/dist/application/orm/persistence/lifecycle/entityLifecycle.js.map +1 -0
- package/dist/application/orm/persistence/projection/projectionEffects.d.ts +21 -0
- package/dist/application/orm/persistence/projection/projectionEffects.d.ts.map +1 -0
- package/dist/application/orm/persistence/projection/projectionEffects.js +203 -0
- package/dist/application/orm/persistence/projection/projectionEffects.js.map +1 -0
- package/dist/application/orm/persistence/support/businessKeys.d.ts +17 -0
- package/dist/application/orm/persistence/support/businessKeys.d.ts.map +1 -0
- package/dist/application/orm/persistence/support/businessKeys.js +72 -0
- package/dist/application/orm/persistence/support/businessKeys.js.map +1 -0
- package/dist/application/orm/persistence/support/canonicalState.d.ts +22 -0
- package/dist/application/orm/persistence/support/canonicalState.d.ts.map +1 -0
- package/dist/application/orm/persistence/support/canonicalState.js +88 -0
- package/dist/application/orm/persistence/support/canonicalState.js.map +1 -0
- package/dist/application/orm/persistence/support/contracts.d.ts +139 -0
- package/dist/application/orm/persistence/support/contracts.d.ts.map +1 -0
- package/dist/application/orm/persistence/support/contracts.js +93 -0
- package/dist/application/orm/persistence/support/contracts.js.map +1 -0
- package/dist/application/orm/persistence/support/helpers.d.ts +32 -0
- package/dist/application/orm/persistence/support/helpers.d.ts.map +1 -0
- package/dist/application/orm/persistence/support/helpers.js +66 -0
- package/dist/application/orm/persistence/support/helpers.js.map +1 -0
- package/dist/application/orm/persistence/support/timing.d.ts +20 -0
- package/dist/application/orm/persistence/support/timing.d.ts.map +1 -0
- package/dist/application/orm/persistence/support/timing.js +55 -0
- package/dist/application/orm/persistence/support/timing.js.map +1 -0
- package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts +46 -0
- package/dist/application/sync/gateway/SyncGatewayBootstrap.d.ts.map +1 -0
- package/dist/application/sync/gateway/SyncGatewayBootstrap.js +93 -0
- package/dist/application/sync/gateway/SyncGatewayBootstrap.js.map +1 -0
- package/dist/application/sync/gateway/constants.d.ts +65 -0
- package/dist/application/sync/gateway/constants.d.ts.map +1 -0
- package/dist/application/sync/gateway/constants.js +57 -0
- package/dist/application/sync/gateway/constants.js.map +1 -0
- package/dist/application/sync/gateway/errors.d.ts +15 -0
- package/dist/application/sync/gateway/errors.d.ts.map +1 -0
- package/dist/application/sync/gateway/errors.js +16 -0
- package/dist/application/sync/gateway/errors.js.map +1 -0
- package/dist/application/sync/gateway/syncGateway.d.ts +313 -0
- package/dist/application/sync/gateway/syncGateway.d.ts.map +1 -0
- package/dist/application/sync/gateway/syncGateway.js +202 -0
- package/dist/application/sync/gateway/syncGateway.js.map +1 -0
- package/dist/application/sync/gateway/validation.d.ts +17 -0
- package/dist/application/sync/gateway/validation.d.ts.map +1 -0
- package/dist/application/sync/gateway/validation.js +60 -0
- package/dist/application/sync/gateway/validation.js.map +1 -0
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts +72 -0
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.d.ts.map +1 -0
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.js +272 -0
- package/dist/application/sync/inbound/polling/SimpleSheetPolling.js.map +1 -0
- package/dist/application/sync/index.d.ts +16 -0
- package/dist/application/sync/index.d.ts.map +1 -0
- package/dist/application/sync/index.js +9 -0
- package/dist/application/sync/index.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts +106 -0
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js +297 -0
- package/dist/application/sync/outbound/effects/SyncEffectSupervisor.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts +100 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorker.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js +345 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorker.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts +46 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js +63 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerConstants.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts +20 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js +102 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerDispatch.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.d.ts +19 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js +32 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerHelpers.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts +30 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js +202 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerRouting.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts +17 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js +80 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTiming.js.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts +13 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.d.ts.map +1 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js +205 -0
- package/dist/application/sync/outbound/effects/SyncEffectWorkerTransitions.js.map +1 -0
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts +81 -0
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.d.ts.map +1 -0
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js +245 -0
- package/dist/application/sync/outbound/projection/ProjectionEffectFactory.js.map +1 -0
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts +77 -0
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.d.ts.map +1 -0
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js +518 -0
- package/dist/application/sync/outbound/reconciliation/ReconciliationScanner.js.map +1 -0
- package/dist/application/sync/telemetry/syncTiming.d.ts +50 -0
- package/dist/application/sync/telemetry/syncTiming.d.ts.map +1 -0
- package/dist/application/sync/telemetry/syncTiming.js +22 -0
- package/dist/application/sync/telemetry/syncTiming.js.map +1 -0
- package/dist/domain/conflict/errors.d.ts +42 -0
- package/dist/domain/conflict/errors.d.ts.map +1 -0
- package/dist/domain/conflict/errors.js +36 -0
- package/dist/domain/conflict/errors.js.map +1 -0
- package/dist/domain/conflict/index.d.ts +5 -0
- package/dist/domain/conflict/index.d.ts.map +1 -0
- package/dist/domain/conflict/index.js +3 -0
- package/dist/domain/conflict/index.js.map +1 -0
- package/dist/domain/conflict/transitions.d.ts +52 -0
- package/dist/domain/conflict/transitions.d.ts.map +1 -0
- package/dist/domain/conflict/transitions.js +115 -0
- package/dist/domain/conflict/transitions.js.map +1 -0
- package/dist/domain/errors/evaluation.d.ts +13 -0
- package/dist/domain/errors/evaluation.d.ts.map +1 -0
- package/dist/domain/errors/evaluation.js +14 -0
- package/dist/domain/errors/evaluation.js.map +1 -0
- package/dist/domain/errors/identity.d.ts +12 -0
- package/dist/domain/errors/identity.d.ts.map +1 -0
- package/dist/domain/errors/identity.js +15 -0
- package/dist/domain/errors/identity.js.map +1 -0
- package/dist/domain/errors/index.d.ts +7 -0
- package/dist/domain/errors/index.d.ts.map +1 -0
- package/dist/domain/errors/index.js +5 -0
- package/dist/domain/errors/index.js.map +1 -0
- package/dist/domain/errors/stableEncoding.d.ts +7 -0
- package/dist/domain/errors/stableEncoding.d.ts.map +1 -0
- package/dist/domain/errors/stableEncoding.js +8 -0
- package/dist/domain/errors/stableEncoding.js.map +1 -0
- package/dist/domain/errors/types.d.ts +20 -0
- package/dist/domain/errors/types.d.ts.map +1 -0
- package/dist/domain/errors/types.js +18 -0
- package/dist/domain/errors/types.js.map +1 -0
- package/dist/domain/evaluate/constants.d.ts +55 -0
- package/dist/domain/evaluate/constants.d.ts.map +1 -0
- package/dist/domain/evaluate/constants.js +41 -0
- package/dist/domain/evaluate/constants.js.map +1 -0
- package/dist/domain/evaluate/contracts.d.ts +125 -0
- package/dist/domain/evaluate/contracts.d.ts.map +1 -0
- package/dist/domain/evaluate/contracts.js +8 -0
- package/dist/domain/evaluate/contracts.js.map +1 -0
- package/dist/domain/evaluate/evaluateBatch.d.ts +11 -0
- package/dist/domain/evaluate/evaluateBatch.d.ts.map +1 -0
- package/dist/domain/evaluate/evaluateBatch.js +91 -0
- package/dist/domain/evaluate/evaluateBatch.js.map +1 -0
- package/dist/domain/evaluate/fieldEvaluation.d.ts +14 -0
- package/dist/domain/evaluate/fieldEvaluation.d.ts.map +1 -0
- package/dist/domain/evaluate/fieldEvaluation.js +133 -0
- package/dist/domain/evaluate/fieldEvaluation.js.map +1 -0
- package/dist/domain/evaluate/identity.d.ts +21 -0
- package/dist/domain/evaluate/identity.d.ts.map +1 -0
- package/dist/domain/evaluate/identity.js +72 -0
- package/dist/domain/evaluate/identity.js.map +1 -0
- package/dist/domain/evaluate/index.d.ts +4 -0
- package/dist/domain/evaluate/index.d.ts.map +1 -0
- package/dist/domain/evaluate/index.js +3 -0
- package/dist/domain/evaluate/index.js.map +1 -0
- package/dist/domain/evaluate/preconditions.d.ts +30 -0
- package/dist/domain/evaluate/preconditions.d.ts.map +1 -0
- package/dist/domain/evaluate/preconditions.js +389 -0
- package/dist/domain/evaluate/preconditions.js.map +1 -0
- package/dist/domain/evaluate/quarantine.d.ts +15 -0
- package/dist/domain/evaluate/quarantine.d.ts.map +1 -0
- package/dist/domain/evaluate/quarantine.js +185 -0
- package/dist/domain/evaluate/quarantine.js.map +1 -0
- package/dist/domain/index.d.ts +7 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +7 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/model/constants.d.ts +73 -0
- package/dist/domain/model/constants.d.ts.map +1 -0
- package/dist/domain/model/constants.js +59 -0
- package/dist/domain/model/constants.js.map +1 -0
- package/dist/domain/model/index.d.ts +3 -0
- package/dist/domain/model/index.d.ts.map +1 -0
- package/dist/domain/model/index.js +2 -0
- package/dist/domain/model/index.js.map +1 -0
- package/dist/domain/model/types.d.ts +330 -0
- package/dist/domain/model/types.d.ts.map +1 -0
- package/dist/domain/model/types.js +8 -0
- package/dist/domain/model/types.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/index.d.ts +3 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +3 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/infrastructure/storage/constants.d.ts +4 -0
- package/dist/infrastructure/storage/constants.d.ts.map +1 -0
- package/dist/infrastructure/storage/constants.js +4 -0
- package/dist/infrastructure/storage/constants.js.map +1 -0
- package/dist/infrastructure/storage/errors.d.ts +55 -0
- package/dist/infrastructure/storage/errors.d.ts.map +1 -0
- package/dist/infrastructure/storage/errors.js +58 -0
- package/dist/infrastructure/storage/errors.js.map +1 -0
- package/dist/infrastructure/storage/index.d.ts +23 -0
- package/dist/infrastructure/storage/index.d.ts.map +1 -0
- package/dist/infrastructure/storage/index.js +13 -0
- package/dist/infrastructure/storage/index.js.map +1 -0
- package/dist/infrastructure/storage/recovery/restoreRecovery.d.ts +64 -0
- package/dist/infrastructure/storage/recovery/restoreRecovery.d.ts.map +1 -0
- package/dist/infrastructure/storage/recovery/restoreRecovery.js +148 -0
- package/dist/infrastructure/storage/recovery/restoreRecovery.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/schema.d.ts +49 -0
- package/dist/infrastructure/storage/sqlite/schema.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/schema.js +529 -0
- package/dist/infrastructure/storage/sqlite/schema.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts +5 -0
- package/dist/infrastructure/storage/sqlite/schemaTypes.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/schemaTypes.js +2 -0
- package/dist/infrastructure/storage/sqlite/schemaTypes.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlScript.d.ts +9 -0
- package/dist/infrastructure/storage/sqlite/sqlScript.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlScript.js +122 -0
- package/dist/infrastructure/storage/sqlite/sqlScript.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlState.d.ts +6 -0
- package/dist/infrastructure/storage/sqlite/sqlState.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlState.js +14 -0
- package/dist/infrastructure/storage/sqlite/sqlState.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlTransaction.d.ts +6 -0
- package/dist/infrastructure/storage/sqlite/sqlTransaction.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqlTransaction.js +24 -0
- package/dist/infrastructure/storage/sqlite/sqlTransaction.js.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqliteBridge.d.ts +44 -0
- package/dist/infrastructure/storage/sqlite/sqliteBridge.d.ts.map +1 -0
- package/dist/infrastructure/storage/sqlite/sqliteBridge.js +66 -0
- package/dist/infrastructure/storage/sqlite/sqliteBridge.js.map +1 -0
- package/dist/infrastructure/storage/state/canonical/canonicalCommit.d.ts +101 -0
- package/dist/infrastructure/storage/state/canonical/canonicalCommit.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/canonical/canonicalCommit.js +417 -0
- package/dist/infrastructure/storage/state/canonical/canonicalCommit.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationAudit.d.ts +16 -0
- package/dist/infrastructure/storage/state/observation/observationAudit.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationAudit.js +85 -0
- package/dist/infrastructure/storage/state/observation/observationAudit.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationCanonical.d.ts +31 -0
- package/dist/infrastructure/storage/state/observation/observationCanonical.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationCanonical.js +439 -0
- package/dist/infrastructure/storage/state/observation/observationCanonical.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationConstants.d.ts +53 -0
- package/dist/infrastructure/storage/state/observation/observationConstants.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationConstants.js +41 -0
- package/dist/infrastructure/storage/state/observation/observationConstants.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationLedger.d.ts +49 -0
- package/dist/infrastructure/storage/state/observation/observationLedger.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationLedger.js +537 -0
- package/dist/infrastructure/storage/state/observation/observationLedger.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationQuarantine.d.ts +15 -0
- package/dist/infrastructure/storage/state/observation/observationQuarantine.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationQuarantine.js +100 -0
- package/dist/infrastructure/storage/state/observation/observationQuarantine.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationTypes.d.ts +124 -0
- package/dist/infrastructure/storage/state/observation/observationTypes.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationTypes.js +13 -0
- package/dist/infrastructure/storage/state/observation/observationTypes.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationValidation.d.ts +28 -0
- package/dist/infrastructure/storage/state/observation/observationValidation.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationValidation.js +223 -0
- package/dist/infrastructure/storage/state/observation/observationValidation.js.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationWriter.d.ts +28 -0
- package/dist/infrastructure/storage/state/observation/observationWriter.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/observation/observationWriter.js +293 -0
- package/dist/infrastructure/storage/state/observation/observationWriter.js.map +1 -0
- package/dist/infrastructure/storage/state/readonly/readOnlyObservation.d.ts +58 -0
- package/dist/infrastructure/storage/state/readonly/readOnlyObservation.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/readonly/readOnlyObservation.js +195 -0
- package/dist/infrastructure/storage/state/readonly/readOnlyObservation.js.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts +31 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriter.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriter.js +563 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriter.js.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts +118 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js +18 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterContracts.js.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.d.ts +23 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.js +84 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterHelpers.js.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts +16 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.d.ts.map +1 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js +97 -0
- package/dist/infrastructure/storage/state/resolution/resolutionWriterSql.js.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts +137 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js +396 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutbox.js.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts +101 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js +9 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxContracts.js.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts +21 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js +184 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSql.js.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts +25 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js +158 -0
- package/dist/infrastructure/storage/sync/outbound/effectOutboxSupport.js.map +1 -0
- package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts +69 -0
- package/dist/infrastructure/storage/sync/shared/syncRegistry.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/shared/syncRegistry.js +272 -0
- package/dist/infrastructure/storage/sync/shared/syncRegistry.js.map +1 -0
- package/dist/infrastructure/storage/sync/shared/writerLease.d.ts +90 -0
- package/dist/infrastructure/storage/sync/shared/writerLease.d.ts.map +1 -0
- package/dist/infrastructure/storage/sync/shared/writerLease.js +282 -0
- package/dist/infrastructure/storage/sync/shared/writerLease.js.map +1 -0
- package/dist/shared/constants.d.ts +8 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +8 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/encoding/constants.d.ts +45 -0
- package/dist/shared/encoding/constants.d.ts.map +1 -0
- package/dist/shared/encoding/constants.js +37 -0
- package/dist/shared/encoding/constants.js.map +1 -0
- package/dist/shared/encoding/index.d.ts +6 -0
- package/dist/shared/encoding/index.d.ts.map +1 -0
- package/dist/shared/encoding/index.js +4 -0
- package/dist/shared/encoding/index.js.map +1 -0
- package/dist/shared/encoding/stableEncode.d.ts +34 -0
- package/dist/shared/encoding/stableEncode.d.ts.map +1 -0
- package/dist/shared/encoding/stableEncode.js +210 -0
- package/dist/shared/encoding/stableEncode.js.map +1 -0
- package/dist/shared/encoding/typeGuards.d.ts +15 -0
- package/dist/shared/encoding/typeGuards.d.ts.map +1 -0
- package/dist/shared/encoding/typeGuards.js +11 -0
- package/dist/shared/encoding/typeGuards.js.map +1 -0
- package/dist/shared/encoding/types.d.ts +52 -0
- package/dist/shared/encoding/types.d.ts.map +1 -0
- package/dist/shared/encoding/types.js +8 -0
- package/dist/shared/encoding/types.js.map +1 -0
- package/dist/shared/index.d.ts +6 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +6 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/state/constants.d.ts +16 -0
- package/dist/shared/state/constants.d.ts.map +1 -0
- package/dist/shared/state/constants.js +16 -0
- package/dist/shared/state/constants.js.map +1 -0
- package/dist/shared/state/index.d.ts +3 -0
- package/dist/shared/state/index.d.ts.map +1 -0
- package/dist/shared/state/index.js +2 -0
- package/dist/shared/state/index.js.map +1 -0
- package/dist/shared/state/types.d.ts +23 -0
- package/dist/shared/state/types.d.ts.map +1 -0
- package/dist/shared/state/types.js +2 -0
- package/dist/shared/state/types.js.map +1 -0
- package/dist/shared/validation.d.ts +9 -0
- package/dist/shared/validation.d.ts.map +1 -0
- package/dist/shared/validation.js +25 -0
- package/dist/shared/validation.js.map +1 -0
- package/docs/architecture.md +72 -0
- package/docs/code-guidelines.md +256 -0
- package/docs/development.md +48 -0
- package/docs/git-workflow.md +224 -0
- package/docs/mikro-orm-adapter-spike.md +248 -0
- package/docs/quick-start.md +102 -0
- package/docs/sql-layer-plan.md +59 -0
- package/docs/sync-bulk-write-benchmark.md +1036 -0
- package/docs/sync-observability.md +71 -0
- package/docs/task-queue-write-model.md +640 -0
- package/docs/typed-sheets-mvp-scope-2026-06-29.md +490 -0
- package/docs/typed-sheets-plan.md +417 -0
- package/docs/write-and-synchronization-flow.md +71 -0
- package/package.json +68 -0
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
# Task Queue Write Model
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Define the queued write model before implementing task queue operations in the
|
|
6
|
+
Apps Script gateway.
|
|
7
|
+
|
|
8
|
+
The queue is an internal write engine detail. The public API should continue to
|
|
9
|
+
move toward an entity lifecycle such as `findById()`, mutate, then
|
|
10
|
+
`save(entity)` or `remove(entity)`. Users should not need to understand queue
|
|
11
|
+
sheets during normal use.
|
|
12
|
+
|
|
13
|
+
## Non-Goals
|
|
14
|
+
|
|
15
|
+
- Do not replace the strict synchronous write path in the first queue branch.
|
|
16
|
+
- Do not expose a SQL queue API.
|
|
17
|
+
- Do not add Redis, Pub/Sub, or an external queue backend.
|
|
18
|
+
- Do not promise database transactions or MySQL/Postgres latency.
|
|
19
|
+
- Do not make queued writes the default until read-your-writes behavior and
|
|
20
|
+
failure reporting are designed.
|
|
21
|
+
|
|
22
|
+
## Sheets
|
|
23
|
+
|
|
24
|
+
The queued model separates system-owned data from user-facing spreadsheet
|
|
25
|
+
views. The system-owned canonical sheet is the source of truth for repository
|
|
26
|
+
reads, writes, queue processing, cache warmup, and version checks. The visible
|
|
27
|
+
user sheet is a projection that can be refreshed from the canonical sheet.
|
|
28
|
+
|
|
29
|
+
| Sheet | Purpose |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| `Users` or another user sheet | User-facing projection for viewing and light manual inspection. |
|
|
32
|
+
| `_typed_sheets_data_Users` or another canonical sheet | Hidden/protected system-owned canonical table. |
|
|
33
|
+
| `_typed_sheets_task_queue` | Durable append-only write task log. |
|
|
34
|
+
| `_typed_sheets_meta` | Processor cursor, schema metadata, and diagnostics. |
|
|
35
|
+
|
|
36
|
+
Internal sheets should be hidden when the gateway creates or initializes them.
|
|
37
|
+
Hidden sheets are still editable by spreadsheet owners, so the gateway must
|
|
38
|
+
validate queue rows before processing.
|
|
39
|
+
|
|
40
|
+
## Canonical and Projection Sheets
|
|
41
|
+
|
|
42
|
+
The canonical sheet is the only sheet the write processor trusts. User-facing
|
|
43
|
+
projection sheets are generated views of canonical state.
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
server write
|
|
47
|
+
-> _typed_sheets_task_queue
|
|
48
|
+
-> _typed_sheets_data_Users
|
|
49
|
+
-> optional Users projection sync
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This keeps manual edits to `Users` from corrupting the system-owned row state.
|
|
53
|
+
If a user manually inserts, updates, or deletes data in the visible projection,
|
|
54
|
+
the canonical sheet remains unchanged.
|
|
55
|
+
|
|
56
|
+
First implementation policy:
|
|
57
|
+
|
|
58
|
+
- queue processors read and write canonical sheets only
|
|
59
|
+
- repository reads should use canonical sheets when queued mode is enabled
|
|
60
|
+
- projection sync is optional and is not part of the current gateway processor
|
|
61
|
+
- visible sheet edits are not imported automatically
|
|
62
|
+
- a future projection sync may overwrite visible sheet edits
|
|
63
|
+
- `onEdit` import can be designed later as an explicit opt-in feature
|
|
64
|
+
|
|
65
|
+
This intentionally makes the visible sheet a projection, not the source of
|
|
66
|
+
truth. The naming in implementation should reflect that distinction:
|
|
67
|
+
|
|
68
|
+
- canonical sheet: an internal name recorded in metadata
|
|
69
|
+
- projection sheet: `<sheetName>`
|
|
70
|
+
- queue sheet: `_typed_sheets_task_queue`
|
|
71
|
+
|
|
72
|
+
Canonical sheet names must not be derived by direct prefixing alone. Direct
|
|
73
|
+
`_typed_sheets_data_<sheetName>` mapping can collide with an existing user
|
|
74
|
+
sheet, exceed Google Sheets title limits, or fail when a logical table name
|
|
75
|
+
contains characters that need escaping.
|
|
76
|
+
|
|
77
|
+
The gateway should store logical-to-physical sheet mappings in `_typed_sheets_meta`:
|
|
78
|
+
|
|
79
|
+
| Field | Meaning |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `logicalSheetName` | Public table name used by repository config and queue tasks. |
|
|
82
|
+
| `canonicalSheetName` | Actual hidden/protected sheet title used by the processor. |
|
|
83
|
+
| `projectionSheetName` | Visible user-facing sheet title. |
|
|
84
|
+
|
|
85
|
+
First implementation mapping policy:
|
|
86
|
+
|
|
87
|
+
- reserve `_typed_sheets_` as an internal prefix
|
|
88
|
+
- reject user-facing projection names that start with `_typed_sheets_`
|
|
89
|
+
- create canonical names with a short deterministic suffix such as
|
|
90
|
+
`_typed_sheets_data_<slug>_<hash>`
|
|
91
|
+
- truncate the slug so the final sheet title stays within Google Sheets limits
|
|
92
|
+
- resolve rare collisions by adding or extending the suffix, then persist the
|
|
93
|
+
chosen title in `_typed_sheets_meta`
|
|
94
|
+
- never recompute canonical names from logical names when a metadata mapping
|
|
95
|
+
already exists
|
|
96
|
+
|
|
97
|
+
The projection sync can start as a full rewrite for MVP-sized sheets. Later
|
|
98
|
+
versions can add incremental projection sync if full rewrites become too slow.
|
|
99
|
+
|
|
100
|
+
## `_typed_sheets_task_queue` Schema
|
|
101
|
+
|
|
102
|
+
Proposed header row:
|
|
103
|
+
|
|
104
|
+
| Column | Type | Description |
|
|
105
|
+
| --- | --- | --- |
|
|
106
|
+
| `taskId` | string | Unique id for idempotency and debugging. |
|
|
107
|
+
| `transactionId` | string | Groups tasks that must be applied together. |
|
|
108
|
+
| `transactionIndex` | number | Order inside the transaction. |
|
|
109
|
+
| `sequence` | number | Monotonic ordering value assigned by the gateway. |
|
|
110
|
+
| `status` | string | `pending`, `processing`, `done`, or `failed`. |
|
|
111
|
+
| `operation` | string | `insert`, `update`, or `delete`. |
|
|
112
|
+
| `sheetName` | string | Logical target table name, mapped to a canonical sheet during processing. |
|
|
113
|
+
| `keyHeader` | string | Repository key column name, usually `id`. |
|
|
114
|
+
| `keyValue` | string | Target key value. |
|
|
115
|
+
| `expectedVersion` | number or blank | Version fence for update/delete. |
|
|
116
|
+
| `payloadJson` | string | Serialized operation payload. |
|
|
117
|
+
| `attempts` | number | Number of processing attempts for the transaction. |
|
|
118
|
+
| `lastErrorCode` | string or blank | Last gateway error code. |
|
|
119
|
+
| `lastErrorMessage` | string or blank | Last gateway error message. |
|
|
120
|
+
| `createdAt` | ISO string | Task creation time. |
|
|
121
|
+
| `updatedAt` | ISO string | Last status update time. |
|
|
122
|
+
| `taskFingerprint` | string | Stable hash of the immutable enqueue request fields, retained after payload redaction for idempotency checks. |
|
|
123
|
+
|
|
124
|
+
The queue should be append-first. Updating `status`, `attempts`, and error
|
|
125
|
+
columns is allowed during processing.
|
|
126
|
+
|
|
127
|
+
When the queue schema gains `taskFingerprint`, the Apps Script template must
|
|
128
|
+
append that column to an existing legacy queue before processing or enqueueing.
|
|
129
|
+
Pending and non-redacted rows can be backfilled from their immutable fields.
|
|
130
|
+
Legacy `done` rows whose payload was already redacted cannot be reconstructed;
|
|
131
|
+
the migration keeps a task-id-only compatibility marker for replay and records
|
|
132
|
+
that limitation.
|
|
133
|
+
|
|
134
|
+
## Queue Transactions
|
|
135
|
+
|
|
136
|
+
A queue transaction is a group of tasks created by one repository write flush or
|
|
137
|
+
one explicit future unit of work. It is identified by `transactionId`.
|
|
138
|
+
|
|
139
|
+
This is not a database transaction across arbitrary Google Sheets operations.
|
|
140
|
+
It is a gateway processing contract:
|
|
141
|
+
|
|
142
|
+
- tasks with the same `transactionId` are claimed together
|
|
143
|
+
- tasks in the group are validated together
|
|
144
|
+
- materialization is attempted only after every task in the group is valid
|
|
145
|
+
- if one task in the group fails validation, no task in that group is applied
|
|
146
|
+
- every task in the group receives the same final outcome: `done` or `failed`
|
|
147
|
+
|
|
148
|
+
The first implementation should process one transaction group at a time under
|
|
149
|
+
the Apps Script document lock. For bulk processing, the processor should build
|
|
150
|
+
the next in-memory table state first, validate every task, then write the
|
|
151
|
+
canonical sheet. This gives the gateway a practical all-or-nothing boundary
|
|
152
|
+
before the sheet mutation call.
|
|
153
|
+
|
|
154
|
+
The document lock is the primary concurrency boundary. Google Sheets does not
|
|
155
|
+
provide row-level or sheet-level locks that fit this model, and every queued
|
|
156
|
+
write is already serialized through the task queue. The processor should
|
|
157
|
+
therefore use one document lock while claiming, validating, applying, and
|
|
158
|
+
marking transaction groups.
|
|
159
|
+
|
|
160
|
+
The lock protects against concurrent typed-sheets processors and server
|
|
161
|
+
requests. It does not make multiple SpreadsheetApp writes atomic, and it does
|
|
162
|
+
not prevent spreadsheet owners from manually editing visible projection sheets.
|
|
163
|
+
|
|
164
|
+
If Apps Script fails after mutating the canonical sheet but before marking
|
|
165
|
+
the transaction `done`, stale `processing` recovery must reconcile the whole
|
|
166
|
+
transaction as a group. If every task postcondition is visible, mark the entire
|
|
167
|
+
transaction `done`. If none of the task postconditions are visible and attempts
|
|
168
|
+
remain, move the entire transaction back to `pending`. If only part of the
|
|
169
|
+
group appears applied, mark the whole group `failed` with a `partial_apply`
|
|
170
|
+
error and require manual recovery.
|
|
171
|
+
|
|
172
|
+
## Status Values
|
|
173
|
+
|
|
174
|
+
| Status | Meaning |
|
|
175
|
+
| --- | --- |
|
|
176
|
+
| `pending` | Task is queued and has not been claimed. |
|
|
177
|
+
| `processing` | Gateway claimed the task under document lock. |
|
|
178
|
+
| `done` | Task was applied to the canonical sheet. |
|
|
179
|
+
| `failed` | Task could not be applied after validation or retry policy. |
|
|
180
|
+
|
|
181
|
+
The first processor can use a simple lock-based claim model:
|
|
182
|
+
|
|
183
|
+
1. Acquire Apps Script document lock.
|
|
184
|
+
2. Read a bounded window of complete `pending` transaction groups.
|
|
185
|
+
3. Hold any incomplete transaction group until a later processor pass.
|
|
186
|
+
4. Mark every task in each claimed transaction `processing`.
|
|
187
|
+
5. Apply transactions in `sequence` order.
|
|
188
|
+
6. Mark every task in a transaction with the same final status: `done` or
|
|
189
|
+
`failed`.
|
|
190
|
+
7. Release lock.
|
|
191
|
+
|
|
192
|
+
Because Apps Script can time out, the processor must handle stale
|
|
193
|
+
`processing` transactions in a later pass. A transaction with `processing`
|
|
194
|
+
status and an old `updatedAt` must not be blindly moved back to `pending`. The
|
|
195
|
+
processor first reconciles whether each task's intended effect is already
|
|
196
|
+
visible in the canonical sheet:
|
|
197
|
+
|
|
198
|
+
- insert is already applied when the key exists and the row matches the queued
|
|
199
|
+
row/version
|
|
200
|
+
- update is already applied when the key exists and the row matches
|
|
201
|
+
`rowToWrite` and the written `_version`
|
|
202
|
+
- delete is already applied when the key is absent and the task has enough
|
|
203
|
+
prior-version evidence to prove this delete removed it
|
|
204
|
+
|
|
205
|
+
If every task postcondition is already true, mark the transaction `done`. If no
|
|
206
|
+
task postconditions are true and the retry policy allows it, increment
|
|
207
|
+
`attempts` for every task in the transaction and move the transaction back to
|
|
208
|
+
`pending`. If only part of the transaction appears applied, mark the
|
|
209
|
+
transaction `failed` with `partial_apply`.
|
|
210
|
+
|
|
211
|
+
Stale recovery must happen before applying any later pending transaction. The
|
|
212
|
+
processor should scan from the lowest relevant `sequence` and reconcile stale
|
|
213
|
+
`processing` transaction groups before claiming higher-sequence `pending`
|
|
214
|
+
groups. This avoids misclassifying deletes or re-inserts. For example, if a
|
|
215
|
+
timed-out delete removed `u1`, a later pending insert for `u1` must not run
|
|
216
|
+
before the delete transaction is reconciled.
|
|
217
|
+
|
|
218
|
+
Delete recovery needs stronger evidence than key absence alone. A queued delete
|
|
219
|
+
should retain enough postcondition evidence to distinguish "the intended delete
|
|
220
|
+
already happened" from "the row is absent for another reason". First
|
|
221
|
+
implementation options are:
|
|
222
|
+
|
|
223
|
+
- keep the deleted row's previous key/version evidence until the transaction is
|
|
224
|
+
`done`
|
|
225
|
+
- record an apply marker in `_typed_sheets_meta` before or after the canonical
|
|
226
|
+
write
|
|
227
|
+
- mark ambiguous delete recovery as `partial_apply` instead of retrying blindly
|
|
228
|
+
|
|
229
|
+
## Task Payloads
|
|
230
|
+
|
|
231
|
+
`payloadJson` should contain only modeled repository data and metadata required
|
|
232
|
+
to apply the operation.
|
|
233
|
+
|
|
234
|
+
Insert payload:
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
{
|
|
238
|
+
"row": {
|
|
239
|
+
"id": "u1",
|
|
240
|
+
"email": "a@test.com",
|
|
241
|
+
"age": 20,
|
|
242
|
+
"active": true,
|
|
243
|
+
"_version": 1
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Update payload:
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"expectedVersion": 1,
|
|
253
|
+
"rowToWrite": {
|
|
254
|
+
"id": "u1",
|
|
255
|
+
"email": "a@test.com",
|
|
256
|
+
"age": 21,
|
|
257
|
+
"active": true,
|
|
258
|
+
"_version": 2
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Delete payload:
|
|
264
|
+
|
|
265
|
+
```json
|
|
266
|
+
{
|
|
267
|
+
"expectedVersion": 2,
|
|
268
|
+
"rowToDelete": {
|
|
269
|
+
"id": "u1",
|
|
270
|
+
"email": "a@test.com",
|
|
271
|
+
"age": 21,
|
|
272
|
+
"active": true,
|
|
273
|
+
"_version": 2
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
The queue row duplicates `operation`, `sheetName`, `keyHeader`, `keyValue`, and
|
|
279
|
+
`expectedVersion` outside the JSON payload so the processor can filter and
|
|
280
|
+
diagnose tasks without parsing every payload first.
|
|
281
|
+
|
|
282
|
+
## Repository Cache Policy
|
|
283
|
+
|
|
284
|
+
Queued writes split "accepted into the queue" from "applied to canonical data".
|
|
285
|
+
Repository cache entries must therefore represent confirmed canonical state
|
|
286
|
+
only. A queued write must not update the confirmed cache with the submitted
|
|
287
|
+
payload just because the task append succeeded.
|
|
288
|
+
|
|
289
|
+
Current implementation policy:
|
|
290
|
+
|
|
291
|
+
- queued repositories keep a repository-local confirmed snapshot cache with a
|
|
292
|
+
short configurable TTL; direct repositories do not use this cache
|
|
293
|
+
- queued write success means the task was durably appended, not that canonical
|
|
294
|
+
data changed
|
|
295
|
+
- before a queued write is materialized, invalidate the confirmed snapshot
|
|
296
|
+
instead of mutating it optimistically
|
|
297
|
+
- do not expose queued payload values as confirmed repository reads
|
|
298
|
+
- a later read should refresh from the canonical sheet after invalidation or
|
|
299
|
+
TTL expiry
|
|
300
|
+
- failed transactions must not require cache rollback because pending payloads
|
|
301
|
+
were never written into confirmed cache
|
|
302
|
+
|
|
303
|
+
The cache is process-local and does not coordinate multiple Node.js instances.
|
|
304
|
+
If the Apps Script processor runs outside the repository process, the TTL is
|
|
305
|
+
the upper bound for observing a previously cached canonical snapshot.
|
|
306
|
+
|
|
307
|
+
Future pending-aware APIs may keep a separate pending layer for user
|
|
308
|
+
experience, but that layer must stay distinct from confirmed canonical cache.
|
|
309
|
+
For example, `save(entity)` may report that a write was queued, while
|
|
310
|
+
`findById()` continues to return confirmed canonical data unless an explicit
|
|
311
|
+
pending-read mode is designed.
|
|
312
|
+
|
|
313
|
+
## Queue Data Retention and Redaction
|
|
314
|
+
|
|
315
|
+
Queue sheets are hidden internal sheets, but they are still part of the user's
|
|
316
|
+
spreadsheet and can contain sensitive application data. Treat
|
|
317
|
+
`_typed_sheets_task_queue` as part of the sensitive data surface.
|
|
318
|
+
|
|
319
|
+
Because `payloadJson` may contain full row data, including deleted values in
|
|
320
|
+
`rowToDelete`, the queue must not retain successful task payloads indefinitely.
|
|
321
|
+
|
|
322
|
+
First implementation retention policy:
|
|
323
|
+
|
|
324
|
+
- keep full `payloadJson` while a transaction is `pending` or `processing`
|
|
325
|
+
- after a transaction reaches `done`, replace `payloadJson` with a small
|
|
326
|
+
redacted summary such as `{"redacted":true}`
|
|
327
|
+
- keep `taskId`, `transactionId`, `sequence`, `status`, `operation`,
|
|
328
|
+
`sheetName`, `keyHeader`, `keyValue`, `expectedVersion`, timestamps, and
|
|
329
|
+
attempts for diagnostics
|
|
330
|
+
- keep full payloads for `failed` transactions only while they are needed for
|
|
331
|
+
debugging or manual recovery
|
|
332
|
+
- provide a future cleanup operation that can purge old `done` rows or redact
|
|
333
|
+
old `failed` payloads after a retention window
|
|
334
|
+
|
|
335
|
+
Error fields must also avoid leaking row contents. `lastErrorCode` should be a
|
|
336
|
+
stable code, and `lastErrorMessage` should be short, structured, and avoid
|
|
337
|
+
embedding full row values, secrets, credentials, or arbitrary payload JSON.
|
|
338
|
+
|
|
339
|
+
## Ordering
|
|
340
|
+
|
|
341
|
+
The gateway should assign `sequence` while holding the document lock. Processor
|
|
342
|
+
order is:
|
|
343
|
+
|
|
344
|
+
```text
|
|
345
|
+
sequence ascending
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
This preserves user intent for sequences such as:
|
|
349
|
+
|
|
350
|
+
```text
|
|
351
|
+
insert u1 -> update u1 -> delete u1 -> insert u1
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Within a transaction, `transactionIndex` preserves the caller's intended order.
|
|
355
|
+
Across transactions, `sequence` preserves enqueue order.
|
|
356
|
+
|
|
357
|
+
Cross-sheet transactions must be part of the first queue contract even if the
|
|
358
|
+
initial implementation keeps the public API small. A single `transactionId` may
|
|
359
|
+
contain tasks for multiple `sheetName` values, and the processor must never
|
|
360
|
+
split that transaction across processor runs.
|
|
361
|
+
|
|
362
|
+
Cross-sheet processor order:
|
|
363
|
+
|
|
364
|
+
1. Claim the complete transaction group under the document lock.
|
|
365
|
+
2. Read every affected canonical sheet.
|
|
366
|
+
3. Validate every affected sheet schema and every task precondition.
|
|
367
|
+
4. Build the next in-memory state for every affected sheet.
|
|
368
|
+
5. If any validation fails, mark the whole transaction `failed` without writing.
|
|
369
|
+
6. Write affected sheets in deterministic `sheetName` order.
|
|
370
|
+
7. Mark every task in the transaction `done` only after every affected sheet was
|
|
371
|
+
written successfully.
|
|
372
|
+
|
|
373
|
+
This is still not a true database transaction. Apps Script and SpreadsheetApp
|
|
374
|
+
do not provide an atomic multi-sheet commit. The queue contract is therefore:
|
|
375
|
+
|
|
376
|
+
- before the first sheet write, the transaction is all-or-fail
|
|
377
|
+
- after one or more sheet writes, recovery is based on postcondition
|
|
378
|
+
reconciliation
|
|
379
|
+
- if every affected sheet already reflects the queued result, mark the
|
|
380
|
+
transaction `done`
|
|
381
|
+
- if no affected sheet reflects the queued result and attempts remain, retry the
|
|
382
|
+
transaction
|
|
383
|
+
- if only some affected sheets reflect the queued result, mark the transaction
|
|
384
|
+
`failed` with `partial_apply`
|
|
385
|
+
|
|
386
|
+
This keeps future relationship-style operations possible without exposing
|
|
387
|
+
cross-sheet mechanics in the public repository API.
|
|
388
|
+
|
|
389
|
+
## Transaction Dependencies
|
|
390
|
+
|
|
391
|
+
Transactions are processed in `sequence` order, but one failed transaction can
|
|
392
|
+
still affect a later transaction because the later transaction may depend on
|
|
393
|
+
state the failed transaction was supposed to create.
|
|
394
|
+
|
|
395
|
+
Example:
|
|
396
|
+
|
|
397
|
+
```text
|
|
398
|
+
tx_001: insert order_1
|
|
399
|
+
tx_002: cancel order_1
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
If `tx_001` fails, `tx_002` should not be retried blindly. The processor should
|
|
403
|
+
evaluate `tx_002` against the current canonical sheet state. If `order_1` does
|
|
404
|
+
not exist, `tx_002` fails with `conflict`.
|
|
405
|
+
|
|
406
|
+
First implementation policy:
|
|
407
|
+
|
|
408
|
+
- failed transactions do not roll back already completed earlier transactions
|
|
409
|
+
- failed transactions do not automatically block every later transaction
|
|
410
|
+
- later transactions are validated against current canonical state
|
|
411
|
+
- if a later transaction's precondition is missing because an earlier
|
|
412
|
+
transaction failed, the later transaction fails with `conflict`
|
|
413
|
+
- `conflict` is not retried automatically
|
|
414
|
+
|
|
415
|
+
Later versions can add explicit dependency tracking:
|
|
416
|
+
|
|
417
|
+
```text
|
|
418
|
+
tx_002 dependsOnTransactionId = tx_001
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
With dependency tracking, a pending transaction could wait for its dependency,
|
|
422
|
+
or fail with `dependency_failed` if the dependency fails. That is a useful
|
|
423
|
+
future feature, but the first implementation should keep dependency handling
|
|
424
|
+
implicit through key/version preconditions.
|
|
425
|
+
|
|
426
|
+
## Idempotency
|
|
427
|
+
|
|
428
|
+
`taskId` is the idempotency key. It must be supplied by the client-side
|
|
429
|
+
repository executor or another deterministic internal caller before enqueue.
|
|
430
|
+
The gateway assigns `sequence`, not `taskId`. The queue stores a
|
|
431
|
+
`taskFingerprint` for the immutable enqueue request fields so it can compare a
|
|
432
|
+
replayed task after `payloadJson` has been redacted.
|
|
433
|
+
|
|
434
|
+
The gateway should reject duplicate `taskId` values on enqueue unless the
|
|
435
|
+
duplicate has the same task fingerprint. If a client retry replays the same
|
|
436
|
+
enqueue request after losing the first response, the gateway can return the
|
|
437
|
+
already queued task instead of appending another row. The client-side
|
|
438
|
+
repository transaction must reuse the original transaction/task IDs and
|
|
439
|
+
materialized payloads for that retry; generating new IDs would bypass this
|
|
440
|
+
idempotency check.
|
|
441
|
+
|
|
442
|
+
The public repository transaction API generates transaction identities
|
|
443
|
+
internally and does not expose queue task payloads. Queue materialization and
|
|
444
|
+
retry retention belong to the internal queue writer. Queue draining is a
|
|
445
|
+
separate processor operation:
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
await orders.transaction(async (tx) => {
|
|
449
|
+
const order = await tx.findById("o1");
|
|
450
|
+
if (order) {
|
|
451
|
+
order.status = "canceled";
|
|
452
|
+
tx.save(order);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
The queue writer keeps materialized task batches and task identities private to
|
|
458
|
+
the repository implementation. Callback failures clear pending work;
|
|
459
|
+
ambiguous enqueue failures remain an internal recovery state until a public
|
|
460
|
+
retry/status contract is introduced.
|
|
461
|
+
|
|
462
|
+
Processor idempotency rules:
|
|
463
|
+
|
|
464
|
+
- `done` transactions are never applied again.
|
|
465
|
+
- `failed` transactions are not retried unless explicitly reset.
|
|
466
|
+
- stale `processing` transactions are reconciled against all task
|
|
467
|
+
postconditions before retry.
|
|
468
|
+
- already-applied transactions are marked `done`.
|
|
469
|
+
- unapplied transactions can move back to `pending` as a group.
|
|
470
|
+
- partially applied transactions become `failed` with `partial_apply`.
|
|
471
|
+
|
|
472
|
+
## Apply Semantics
|
|
473
|
+
|
|
474
|
+
The processor applies tasks against the latest canonical sheet state under
|
|
475
|
+
the Apps Script document lock.
|
|
476
|
+
|
|
477
|
+
Insert:
|
|
478
|
+
|
|
479
|
+
- fail with `conflict` if the key already exists
|
|
480
|
+
- append or include in bulk rewrite if the key is new
|
|
481
|
+
- write `_version` from the payload
|
|
482
|
+
|
|
483
|
+
Update:
|
|
484
|
+
|
|
485
|
+
- fail with `conflict` if the key is missing
|
|
486
|
+
- fail with `conflict` if current `_version` is not `expectedVersion`
|
|
487
|
+
- preserve unknown sheet columns when possible
|
|
488
|
+
- write the full modeled row with `_version` incremented before enqueue
|
|
489
|
+
|
|
490
|
+
Delete:
|
|
491
|
+
|
|
492
|
+
- fail with `conflict` if the key is missing
|
|
493
|
+
- fail with `conflict` if current `_version` is not `expectedVersion`
|
|
494
|
+
- delete the canonical row or omit it from the bulk rewrite result
|
|
495
|
+
|
|
496
|
+
Duplicate keys in the canonical sheet are `schema_drift`.
|
|
497
|
+
|
|
498
|
+
## Failure and Retry
|
|
499
|
+
|
|
500
|
+
Error codes should stay small and stable:
|
|
501
|
+
|
|
502
|
+
| Code | Meaning |
|
|
503
|
+
| --- | --- |
|
|
504
|
+
| `invalid_task` | Queue row or payload is malformed. |
|
|
505
|
+
| `schema_drift` | Headers, key column, or duplicate keys make the sheet unsafe. |
|
|
506
|
+
| `conflict` | Expected key/version condition failed. |
|
|
507
|
+
| `partial_apply` | A transaction appears only partly applied after recovery. |
|
|
508
|
+
| `processor_timeout` | Processor exceeded its safe execution window. |
|
|
509
|
+
| `internal_error` | Unexpected Apps Script failure. |
|
|
510
|
+
|
|
511
|
+
Retry policy:
|
|
512
|
+
|
|
513
|
+
- `invalid_task` is not retried automatically.
|
|
514
|
+
- `schema_drift` is not retried automatically until the sheet is fixed.
|
|
515
|
+
- `conflict` is not retried automatically.
|
|
516
|
+
- `partial_apply` is not retried automatically.
|
|
517
|
+
- `internal_error` can retry until `attempts` reaches a configured maximum.
|
|
518
|
+
- retry decisions are made per transaction, not per row task.
|
|
519
|
+
- stale `processing` transactions run postcondition reconciliation before
|
|
520
|
+
retry.
|
|
521
|
+
|
|
522
|
+
Dead-letter policy:
|
|
523
|
+
|
|
524
|
+
- The first implementation can use `failed` as the dead-letter state for the
|
|
525
|
+
whole transaction.
|
|
526
|
+
- Later versions can add `_typed_sheets_dead_letter` only if the queue sheet
|
|
527
|
+
becomes hard to inspect.
|
|
528
|
+
|
|
529
|
+
## Read-Your-Writes
|
|
530
|
+
|
|
531
|
+
Queued writes change consistency. If `insert()` returns when a task is queued,
|
|
532
|
+
the canonical sheet and visible projection may not show the row yet.
|
|
533
|
+
|
|
534
|
+
Candidate strategies:
|
|
535
|
+
|
|
536
|
+
1. Explicit queue processing or status polling before strict reads.
|
|
537
|
+
2. In-memory cache that applies queued tasks immediately.
|
|
538
|
+
3. Pending-task overlay when reading from the canonical sheet.
|
|
539
|
+
4. Expose write operation status and let users choose when to wait.
|
|
540
|
+
|
|
541
|
+
The cache does not provide read-your-writes behavior. Expose queue processing as
|
|
542
|
+
an explicit operation and keep pending payloads separate from confirmed reads.
|
|
543
|
+
|
|
544
|
+
## Gateway Operations
|
|
545
|
+
|
|
546
|
+
Initial Apps Script operations:
|
|
547
|
+
|
|
548
|
+
| Operation | Purpose |
|
|
549
|
+
| --- | --- |
|
|
550
|
+
| `enqueueTasks` | Append one transaction worth of tasks with caller-supplied `taskId`/`transactionId` values and assign `sequence`. |
|
|
551
|
+
| `processTaskQueue` | Process a bounded queue window under lock. |
|
|
552
|
+
| `processTaskQueueBulk` | Process by rewriting affected canonical sheets in bulk. |
|
|
553
|
+
| `readTaskQueueStatus` | Return counts by status and recent failures. |
|
|
554
|
+
|
|
555
|
+
`processTaskQueueBulk` is the expected performance path. It should read the
|
|
556
|
+
affected canonical sheets once, apply all pending tasks in memory, and write
|
|
557
|
+
the resulting tables in as few SpreadsheetApp calls as possible.
|
|
558
|
+
|
|
559
|
+
## Apps Script Runtime Constraints
|
|
560
|
+
|
|
561
|
+
The queue processor must be designed around Apps Script quotas instead of
|
|
562
|
+
assuming a long-running worker. The most important constraints for this model
|
|
563
|
+
are:
|
|
564
|
+
|
|
565
|
+
- one Apps Script execution has a fixed maximum runtime window
|
|
566
|
+
- simultaneous executions can happen, but must be serialized with the document
|
|
567
|
+
lock before queue mutation
|
|
568
|
+
- installable triggers have a daily total runtime quota
|
|
569
|
+
- SpreadsheetApp calls and property reads/writes are not free and should be
|
|
570
|
+
minimized inside the lock
|
|
571
|
+
|
|
572
|
+
Because of this, queue processing must be resumable. `processTaskQueue` and
|
|
573
|
+
`processTaskQueueBulk` should accept bounded execution options:
|
|
574
|
+
|
|
575
|
+
```ts
|
|
576
|
+
interface ProcessTaskQueueOptions {
|
|
577
|
+
maxTransactions?: number;
|
|
578
|
+
maxRuntimeMs?: number;
|
|
579
|
+
}
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
The processor should check the elapsed runtime before starting each transaction
|
|
583
|
+
group. If the safe runtime budget is nearly exhausted, it should stop claiming
|
|
584
|
+
new transactions and return a partial progress response instead of risking an
|
|
585
|
+
Apps Script timeout.
|
|
586
|
+
|
|
587
|
+
Recommended first-pass behavior:
|
|
588
|
+
|
|
589
|
+
- claim only complete transaction groups
|
|
590
|
+
- process at most `maxTransactions` groups per call when provided
|
|
591
|
+
- stop before `maxRuntimeMs` is reached when provided
|
|
592
|
+
- leave unclaimed transactions in `pending`
|
|
593
|
+
- reconcile stale `processing` transactions in a later call
|
|
594
|
+
- expose counts for processed, remaining, failed, and stale transactions
|
|
595
|
+
|
|
596
|
+
This keeps queue processing compatible with manual button runs, time-based
|
|
597
|
+
triggers, and server-triggered gateway calls.
|
|
598
|
+
|
|
599
|
+
## Repository Integration Plan
|
|
600
|
+
|
|
601
|
+
Implementation should happen in separate branches:
|
|
602
|
+
|
|
603
|
+
1. Add gateway queue sheets and operations.
|
|
604
|
+
2. Add focused gateway adapter methods for enqueue/process/status.
|
|
605
|
+
3. Add cross-sheet transaction validation and recovery tests.
|
|
606
|
+
4. Add an internal queued write executor.
|
|
607
|
+
5. Group same-flush writes with one `transactionId`.
|
|
608
|
+
6. Add read-your-writes behavior.
|
|
609
|
+
7. Expose a documented opt-in repository mode.
|
|
610
|
+
|
|
611
|
+
The current synchronous executor remains the default until the queued mode has
|
|
612
|
+
clear consistency and failure behavior.
|
|
613
|
+
|
|
614
|
+
## Benchmark Requirements
|
|
615
|
+
|
|
616
|
+
Every queue benchmark must record:
|
|
617
|
+
|
|
618
|
+
- date and branch
|
|
619
|
+
- exact command or script
|
|
620
|
+
- dataset size and scenario steps
|
|
621
|
+
- backend details and Apps Script deployment URL type
|
|
622
|
+
- total time
|
|
623
|
+
- no-setup or steady-state time
|
|
624
|
+
- enqueue-only time
|
|
625
|
+
- processor-only time
|
|
626
|
+
- comparison with the previous synchronous benchmark
|
|
627
|
+
- caveats such as Apps Script latency and manual browser steps
|
|
628
|
+
|
|
629
|
+
Use the existing performance issue as the durable benchmark record.
|
|
630
|
+
|
|
631
|
+
## Open Questions
|
|
632
|
+
|
|
633
|
+
- Should task queue sheets be hidden by default or only by setup option?
|
|
634
|
+
- Should sequence be global or per target sheet?
|
|
635
|
+
- What should the first explicit unit-of-work API look like for generating
|
|
636
|
+
`transactionId` values?
|
|
637
|
+
- Should `enqueueTasks` optionally trigger processing immediately?
|
|
638
|
+
- How should server memory cache behave across multiple server instances?
|
|
639
|
+
- How much formatting and unknown-column preservation should bulk rewrite
|
|
640
|
+
guarantee?
|