tapimo 0.11.0 → 0.13.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/dist/App.d.ts +6396 -4575
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +39 -4
- package/dist/App.js.map +1 -1
- package/dist/Assets.d.ts +15 -0
- package/dist/Assets.d.ts.map +1 -1
- package/dist/Assets.js +7 -0
- package/dist/Assets.js.map +1 -1
- package/dist/Scope.d.ts +2 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +17 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +176 -78
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +84 -4
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/api-keys.js +54 -0
- package/dist/admin/apps/api-keys.js.map +1 -1
- package/dist/admin/apps/earn-vaults.d.ts +123 -9
- package/dist/admin/apps/earn-vaults.d.ts.map +1 -1
- package/dist/admin/apps/earn-vaults.js +60 -7
- package/dist/admin/apps/earn-vaults.js.map +1 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +4 -2
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +90 -90
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.js +71 -71
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/apps/Zones.d.ts +16 -16
- package/dist/apps/Zones.js +4 -4
- package/dist/apps/data/App.d.ts +1699 -749
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +58 -9
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/ZoneSelection.d.ts +62 -0
- package/dist/apps/data/ZoneSelection.d.ts.map +1 -0
- package/dist/apps/data/ZoneSelection.js +44 -0
- package/dist/apps/data/ZoneSelection.js.map +1 -0
- package/dist/apps/data/routes/activities.d.ts +2417 -50
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +1896 -1293
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +471 -340
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +12 -12
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +44 -17
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +42 -42
- package/dist/apps/data/routes/blocks.d.ts.map +1 -1
- package/dist/apps/data/routes/blocks.js +22 -12
- package/dist/apps/data/routes/blocks.js.map +1 -1
- package/dist/apps/data/routes/coingecko.d.ts +179 -179
- package/dist/apps/data/routes/earn.d.ts +144 -19
- package/dist/apps/data/routes/earn.d.ts.map +1 -1
- package/dist/apps/data/routes/earn.js +160 -28
- package/dist/apps/data/routes/earn.js.map +1 -1
- package/dist/apps/data/routes/exchanges.d.ts +719 -13
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +16 -13
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +2 -2
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +9 -11
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/indexer.d.ts +34 -34
- package/dist/apps/data/routes/receipts.d.ts +363 -263
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +29 -11
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/rpc.js +24 -10
- package/dist/apps/data/routes/rpc.js.map +1 -1
- package/dist/apps/data/routes/tokenlist.d.ts +13 -13
- package/dist/apps/data/routes/tokenlist.d.ts.map +1 -1
- package/dist/apps/data/routes/tokenlist.js +16 -15
- package/dist/apps/data/routes/tokenlist.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +112 -98
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +85 -35
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +7 -2
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +38 -18
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +1 -1
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +25 -21
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +1 -1
- package/dist/apps/data/routes/valuation.d.ts.map +1 -1
- package/dist/apps/data/routes/valuation.js +12 -7
- package/dist/apps/data/routes/valuation.js.map +1 -1
- package/dist/apps/data/routes/verified-tokens.d.ts +3 -3
- package/dist/apps/data/routes/webhooks.d.ts +15 -15
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +2 -2
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/data/routes/zones.d.ts +32 -32
- package/dist/apps/data/routes/zones.js +1 -1
- package/dist/apps/funding/App.d.ts +38 -27
- package/dist/apps/funding/App.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.d.ts.map +1 -1
- package/dist/apps/funding/routes/chains.js +5 -4
- package/dist/apps/funding/routes/chains.js.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.d.ts +16 -16
- package/dist/apps/funding/routes/deposit-addresses.d.ts.map +1 -1
- package/dist/apps/funding/routes/deposit-addresses.js +24 -19
- package/dist/apps/funding/routes/deposit-addresses.js.map +1 -1
- package/dist/apps/funding/routes/providers.d.ts +13 -13
- package/dist/apps/funding/routes/providers.d.ts.map +1 -1
- package/dist/apps/funding/routes/providers.js +3 -2
- package/dist/apps/funding/routes/providers.js.map +1 -1
- package/dist/apps/funding/routes/quotes.d.ts.map +1 -1
- package/dist/apps/funding/routes/quotes.js +2 -2
- package/dist/apps/funding/routes/quotes.js.map +1 -1
- package/dist/apps/funding/routes/transfers.d.ts +60 -48
- package/dist/apps/funding/routes/transfers.d.ts.map +1 -1
- package/dist/apps/funding/routes/transfers.js +27 -19
- package/dist/apps/funding/routes/transfers.js.map +1 -1
- package/dist/apps/management/App.d.ts +4558 -3700
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/Billing.d.ts.map +1 -1
- package/dist/apps/management/Billing.js +19 -6
- package/dist/apps/management/Billing.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +786 -175
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +312 -34
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +103 -30
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +91 -32
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +35 -35
- package/dist/apps/management/routes/faucet.d.ts.map +1 -1
- package/dist/apps/management/routes/faucet.js +23 -12
- package/dist/apps/management/routes/faucet.js.map +1 -1
- package/dist/apps/management/routes/invitations.d.ts +46 -13
- package/dist/apps/management/routes/invitations.d.ts.map +1 -1
- package/dist/apps/management/routes/invitations.js +79 -29
- package/dist/apps/management/routes/invitations.js.map +1 -1
- package/dist/apps/management/routes/invite-links.d.ts +120 -75
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +100 -41
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +5 -5
- package/dist/apps/management/routes/me.d.ts.map +1 -1
- package/dist/apps/management/routes/me.js +14 -10
- package/dist/apps/management/routes/me.js.map +1 -1
- package/dist/apps/management/routes/members.d.ts +99 -78
- package/dist/apps/management/routes/members.d.ts.map +1 -1
- package/dist/apps/management/routes/members.js +37 -18
- package/dist/apps/management/routes/members.js.map +1 -1
- package/dist/apps/management/routes/orgs.d.ts +48 -8
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +48 -19
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +108 -46
- package/dist/apps/management/routes/projects.d.ts.map +1 -1
- package/dist/apps/management/routes/projects.js +72 -21
- package/dist/apps/management/routes/projects.js.map +1 -1
- package/dist/apps/management/routes/scopes.d.ts.map +1 -1
- package/dist/apps/management/routes/scopes.js +8 -5
- package/dist/apps/management/routes/scopes.js.map +1 -1
- package/dist/apps/management/routes/usage.d.ts +82 -82
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +41 -31
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +35 -7
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.js +36 -17
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -1
- package/dist/apps/management/routes/webhooks.d.ts +200 -183
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/management/routes/webhooks.js +80 -35
- package/dist/apps/management/routes/webhooks.js.map +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts +1 -1
- package/dist/apps/mpp/internal/Adapter.d.ts.map +1 -1
- package/dist/apps/mpp/internal/Adapter.js +12 -0
- package/dist/apps/mpp/internal/Adapter.js.map +1 -1
- package/dist/db/Db.d.ts +2 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +52 -1
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +26 -3
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +24 -5
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earnVaults.d.ts +5 -1
- package/dist/db/tables/earnVaults.d.ts.map +1 -1
- package/dist/db/tables/earnVaults.js +5 -0
- package/dist/db/tables/earnVaults.js.map +1 -1
- package/dist/db/tables/fundingCatalog.d.ts +4 -2
- package/dist/db/tables/fundingCatalog.d.ts.map +1 -1
- package/dist/db/tables/fundingCatalog.js +5 -1
- package/dist/db/tables/fundingCatalog.js.map +1 -1
- package/dist/db/tables/webhookDeliveries.d.ts.map +1 -1
- package/dist/db/tables/webhookDeliveries.js +10 -0
- package/dist/db/tables/webhookDeliveries.js.map +1 -1
- package/dist/db/tables/webhookQueueCompletions.d.ts +15 -0
- package/dist/db/tables/webhookQueueCompletions.d.ts.map +1 -0
- package/dist/db/tables/webhookQueueCompletions.js +32 -0
- package/dist/db/tables/webhookQueueCompletions.js.map +1 -0
- package/dist/db/tables/webhookQueueEvents.d.ts +14 -20
- package/dist/db/tables/webhookQueueEvents.d.ts.map +1 -1
- package/dist/db/tables/webhookQueueEvents.js +68 -47
- package/dist/db/tables/webhookQueueEvents.js.map +1 -1
- package/dist/db/tables/webhookSubscriptions.d.ts +16 -5
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +29 -5
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +9 -0
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +19 -6
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/Cache.d.ts.map +1 -1
- package/dist/internal/Cache.js +11 -7
- package/dist/internal/Cache.js.map +1 -1
- package/dist/internal/EarnVaults.d.ts +43 -4
- package/dist/internal/EarnVaults.d.ts.map +1 -1
- package/dist/internal/EarnVaults.js +167 -0
- package/dist/internal/EarnVaults.js.map +1 -1
- package/dist/internal/Fetch.d.ts +23 -0
- package/dist/internal/Fetch.d.ts.map +1 -0
- package/dist/internal/Fetch.js +26 -0
- package/dist/internal/Fetch.js.map +1 -0
- package/dist/internal/Log.d.ts +3 -1
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +16 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +30 -24
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +140 -41
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +14 -9
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +16 -5
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +11 -10
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +14 -9
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Store.d.ts +28 -6
- package/dist/internal/Store.d.ts.map +1 -1
- package/dist/internal/Store.js +121 -25
- package/dist/internal/Store.js.map +1 -1
- package/dist/internal/Tidx.d.ts +2 -0
- package/dist/internal/Tidx.d.ts.map +1 -1
- package/dist/internal/Tidx.js +23 -6
- package/dist/internal/Tidx.js.map +1 -1
- package/dist/internal/Timeout.d.ts +36 -0
- package/dist/internal/Timeout.d.ts.map +1 -0
- package/dist/internal/Timeout.js +37 -0
- package/dist/internal/Timeout.js.map +1 -0
- package/dist/internal/Timing.d.ts +9 -0
- package/dist/internal/Timing.d.ts.map +1 -1
- package/dist/internal/Timing.js +7 -0
- package/dist/internal/Timing.js.map +1 -1
- package/dist/internal/WebhookDestination.d.ts.map +1 -1
- package/dist/internal/WebhookDestination.js +3 -0
- package/dist/internal/WebhookDestination.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +29 -12
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +37 -20
- package/dist/internal/Webhooks.js.map +1 -1
- package/dist/internal/funding/Action.d.ts +9 -0
- package/dist/internal/funding/Action.d.ts.map +1 -1
- package/dist/internal/funding/Action.js +16 -8
- package/dist/internal/funding/Action.js.map +1 -1
- package/dist/internal/funding/Catalog.d.ts +9 -2
- package/dist/internal/funding/Catalog.d.ts.map +1 -1
- package/dist/internal/funding/Catalog.js +19 -8
- package/dist/internal/funding/Catalog.js.map +1 -1
- package/dist/internal/funding/Deposit.d.ts +2 -2
- package/dist/internal/funding/Deposit.d.ts.map +1 -1
- package/dist/internal/funding/Deposit.js +9 -8
- package/dist/internal/funding/Deposit.js.map +1 -1
- package/dist/internal/funding/DepositAddress.d.ts +4 -4
- package/dist/internal/funding/DepositAddress.d.ts.map +1 -1
- package/dist/internal/funding/DepositAddress.js +9 -8
- package/dist/internal/funding/DepositAddress.js.map +1 -1
- package/dist/internal/funding/Provider.d.ts +68 -13
- package/dist/internal/funding/Provider.d.ts.map +1 -1
- package/dist/internal/funding/Provider.js +42 -20
- package/dist/internal/funding/Provider.js.map +1 -1
- package/dist/internal/funding/Transfer.d.ts +13 -12
- package/dist/internal/funding/Transfer.d.ts.map +1 -1
- package/dist/internal/funding/Transfer.js +23 -21
- package/dist/internal/funding/Transfer.js.map +1 -1
- package/dist/internal/funding/providers/stargate.d.ts +38 -0
- package/dist/internal/funding/providers/stargate.d.ts.map +1 -0
- package/dist/internal/funding/providers/stargate.js +277 -0
- package/dist/internal/funding/providers/stargate.js.map +1 -0
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +1 -0
- package/dist/internal/index.js.map +1 -1
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +3 -3
- package/src/App.test.ts +148 -0
- package/src/App.ts +45 -4
- package/src/Assets.test.ts +18 -0
- package/src/Assets.ts +22 -0
- package/src/Client.test-d.ts +311 -16
- package/src/Scope.test.ts +20 -0
- package/src/Scope.ts +16 -0
- package/src/admin/apps/api-keys.test.ts +75 -0
- package/src/admin/apps/api-keys.ts +64 -0
- package/src/admin/apps/earn-vaults.test.ts +143 -0
- package/src/admin/apps/earn-vaults.ts +84 -7
- package/src/admin/apps/organizations.ts +6 -2
- package/src/admin/ui/src/lib/api-keys.ts +19 -0
- package/src/admin/ui/src/routes/api-keys.tsx +125 -2
- package/src/admin/ui.generated.ts +71 -71
- package/src/apps/Zones.test.ts +4 -4
- package/src/apps/Zones.ts +4 -4
- package/src/apps/composition.test.ts +1 -1
- package/src/apps/data/App.test.ts +72 -0
- package/src/apps/data/App.ts +58 -10
- package/src/apps/data/ZoneSelection.test.ts +196 -0
- package/src/apps/data/ZoneSelection.ts +108 -0
- package/src/apps/data/routes/activities.test.ts +1843 -2
- package/src/apps/data/routes/activities.ts +2211 -1388
- package/src/apps/data/routes/balances.ts +134 -98
- package/src/apps/data/routes/blocks.test.ts +533 -0
- package/src/apps/data/routes/blocks.ts +36 -17
- package/src/apps/data/routes/earn.test.ts +187 -25
- package/src/apps/data/routes/earn.ts +228 -32
- package/src/apps/data/routes/earn.zone-access.test.ts +46 -0
- package/src/apps/data/routes/exchanges.test.ts +31 -1
- package/src/apps/data/routes/exchanges.ts +19 -15
- package/src/apps/data/routes/fee-amm.ts +18 -11
- package/src/apps/data/routes/receipts.ts +48 -17
- package/src/apps/data/routes/rpc.test.ts +75 -0
- package/src/apps/data/routes/rpc.ts +23 -9
- package/src/apps/data/routes/tokenlist.ts +21 -18
- package/src/apps/data/routes/tokens.test.ts +607 -0
- package/src/apps/data/routes/tokens.ts +312 -231
- package/src/apps/data/routes/transactions.ts +69 -30
- package/src/apps/data/routes/transfers.test.ts +424 -3
- package/src/apps/data/routes/transfers.ts +57 -36
- package/src/apps/data/routes/valuation.ts +94 -78
- package/src/apps/data/routes/webhooks.ts +6 -2
- package/src/apps/data/routes/zones.test.ts +21 -15
- package/src/apps/data/routes/zones.ts +1 -1
- package/src/apps/funding/routes/chains.test.ts +211 -7
- package/src/apps/funding/routes/chains.ts +19 -12
- package/src/apps/funding/routes/deposit-addresses.test.ts +416 -0
- package/src/apps/funding/routes/deposit-addresses.ts +101 -84
- package/src/apps/funding/routes/providers.ts +9 -5
- package/src/apps/funding/routes/quotes.test.ts +42 -0
- package/src/apps/funding/routes/quotes.ts +8 -5
- package/src/apps/funding/routes/transfers.test.ts +430 -40
- package/src/apps/funding/routes/transfers.ts +76 -59
- package/src/apps/management/Billing.test.ts +26 -0
- package/src/apps/management/Billing.ts +24 -7
- package/src/apps/management/routes/api-keys.test.ts +398 -0
- package/src/apps/management/routes/api-keys.ts +481 -145
- package/src/apps/management/routes/billing.test.ts +209 -0
- package/src/apps/management/routes/billing.ts +254 -177
- package/src/apps/management/routes/faucet.test.ts +39 -0
- package/src/apps/management/routes/faucet.ts +75 -41
- package/src/apps/management/routes/invitations.test.ts +216 -0
- package/src/apps/management/routes/invitations.ts +186 -109
- package/src/apps/management/routes/invite-links.test.ts +263 -1
- package/src/apps/management/routes/invite-links.ts +295 -214
- package/src/apps/management/routes/me.test.ts +49 -0
- package/src/apps/management/routes/me.ts +42 -32
- package/src/apps/management/routes/members.test.ts +124 -1
- package/src/apps/management/routes/members.ts +81 -51
- package/src/apps/management/routes/orgs.test.ts +176 -0
- package/src/apps/management/routes/orgs.ts +101 -59
- package/src/apps/management/routes/projects.test.ts +183 -0
- package/src/apps/management/routes/projects.ts +124 -60
- package/src/apps/management/routes/scopes.test.ts +44 -0
- package/src/apps/management/routes/scopes.ts +37 -28
- package/src/apps/management/routes/usage.test.ts +92 -0
- package/src/apps/management/routes/usage.ts +186 -151
- package/src/apps/management/routes/verified-token-requests.test.ts +114 -0
- package/src/apps/management/routes/verified-token-requests.ts +166 -133
- package/src/apps/management/routes/webhooks.test.ts +234 -0
- package/src/apps/management/routes/webhooks.ts +191 -78
- package/src/apps/mpp/internal/Adapter.ts +13 -1
- package/src/db/Db.test.ts +41 -0
- package/src/db/Db.ts +75 -1
- package/src/db/Schema.ts +33 -5
- package/src/db/tables/earnVaults.test.ts +22 -0
- package/src/db/tables/earnVaults.ts +11 -1
- package/src/db/tables/fundingCatalog.test.ts +16 -2
- package/src/db/tables/fundingCatalog.ts +9 -3
- package/src/db/tables/webhookDeliveries.ts +13 -0
- package/src/db/tables/webhookQueueCompletions.ts +55 -0
- package/src/db/tables/webhookQueueEvents.ts +95 -61
- package/src/db/tables/webhookSubscriptions.ts +45 -6
- package/src/handlers/internal/utils.test.ts +53 -0
- package/src/handlers/internal/utils.ts +15 -0
- package/src/internal/Auth.ts +35 -9
- package/src/internal/Cache.ts +14 -7
- package/src/internal/EarnVaults.capabilities.test.ts +33 -0
- package/src/internal/EarnVaults.test.ts +79 -0
- package/src/internal/EarnVaults.ts +277 -0
- package/src/internal/Fetch.test.ts +46 -0
- package/src/internal/Fetch.ts +56 -0
- package/src/internal/Log.test.ts +21 -0
- package/src/internal/Log.ts +20 -5
- package/src/internal/OpenApi.ts +177 -51
- package/src/internal/Response.test.ts +95 -0
- package/src/internal/Response.ts +41 -3
- package/src/internal/Schema.test.ts +18 -0
- package/src/internal/Schema.ts +19 -9
- package/src/internal/Store.test.ts +364 -0
- package/src/internal/Store.ts +153 -27
- package/src/internal/Tidx.test.ts +21 -1
- package/src/internal/Tidx.ts +23 -6
- package/src/internal/Timeout.test.ts +35 -0
- package/src/internal/Timeout.ts +73 -0
- package/src/internal/Timing.ts +16 -0
- package/src/internal/WebhookDestination.ts +3 -0
- package/src/internal/Webhooks.test.ts +122 -8
- package/src/internal/Webhooks.ts +59 -29
- package/src/internal/funding/Action.test.ts +41 -1
- package/src/internal/funding/Action.ts +69 -41
- package/src/internal/funding/Catalog.test.ts +34 -0
- package/src/internal/funding/Catalog.ts +28 -11
- package/src/internal/funding/Deposit.ts +71 -64
- package/src/internal/funding/DepositAddress.ts +50 -43
- package/src/internal/funding/Provider.test.ts +73 -0
- package/src/internal/funding/Provider.ts +246 -170
- package/src/internal/funding/Transfer.ts +133 -110
- package/src/internal/funding/providers/index.test.ts +22 -0
- package/src/internal/funding/providers/relay.test.ts +2 -2
- package/src/internal/funding/providers/stargate.test.ts +163 -0
- package/src/internal/funding/providers/stargate.ts +409 -0
- package/src/internal/index.test.ts +1 -0
- package/src/internal/index.ts +1 -0
- package/src/providers/index.test.ts +1 -0
- package/src/providers/index.ts +9 -0
package/src/internal/Response.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Context } from 'hono'
|
|
2
2
|
import type * as z from 'zod/mini'
|
|
3
3
|
|
|
4
|
+
import * as Tidx from './Tidx.js'
|
|
5
|
+
|
|
4
6
|
/** Creates a JSON error response. */
|
|
5
7
|
export function error<const status extends error.Status, const code extends string>(
|
|
6
8
|
c: Context,
|
|
@@ -39,14 +41,34 @@ export function unsupportedChainId(c: Context, chainId: number, supported: Itera
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
|
-
* Maps
|
|
44
|
+
* Maps upstream failures to 502, except TIDX query failures after the first positional page return 400.
|
|
43
45
|
* Preserves `Error` causes for reporting and rethrows non-`Error` causes.
|
|
44
46
|
*/
|
|
45
|
-
export function upstream(c: Context, cause: unknown)
|
|
47
|
+
export function upstream(c: Context, cause: unknown): upstream.Response
|
|
48
|
+
export function upstream(
|
|
49
|
+
c: Context,
|
|
50
|
+
cause: unknown,
|
|
51
|
+
options: upstream.Options,
|
|
52
|
+
): upstream.PageResponse
|
|
53
|
+
export function upstream(c: Context, cause: unknown, options?: upstream.Options) {
|
|
46
54
|
if (cause instanceof Error) {
|
|
47
55
|
// Preserve the original error for error-reporting middleware without
|
|
48
56
|
// exposing provider URLs, payloads, or credentials in the response.
|
|
49
57
|
c.error = cause
|
|
58
|
+
if (options?.page !== undefined && options.page > 1) {
|
|
59
|
+
if (Tidx.isQueryTimeout(cause))
|
|
60
|
+
return error(c, {
|
|
61
|
+
code: 'query_invalid',
|
|
62
|
+
message: 'The requested page timed out. Use cursor pagination for deep traversal.',
|
|
63
|
+
status: 400,
|
|
64
|
+
})
|
|
65
|
+
if (Tidx.isQueryRejection(cause))
|
|
66
|
+
return error(c, {
|
|
67
|
+
code: 'query_invalid',
|
|
68
|
+
message: 'The requested page was rejected. Use cursor pagination for deep traversal.',
|
|
69
|
+
status: 400,
|
|
70
|
+
})
|
|
71
|
+
}
|
|
50
72
|
return error(c, {
|
|
51
73
|
code: 'upstream_error',
|
|
52
74
|
message: 'Upstream service could not complete the request',
|
|
@@ -56,6 +78,22 @@ export function upstream(c: Context, cause: unknown) {
|
|
|
56
78
|
throw cause
|
|
57
79
|
}
|
|
58
80
|
|
|
81
|
+
export declare namespace upstream {
|
|
82
|
+
/** Pagination context for classifying a deep-page query failure. */
|
|
83
|
+
type Options = {
|
|
84
|
+
/** Validated positional page number, when requested. */
|
|
85
|
+
page: number | undefined
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Upstream response for routes that support positional pagination. */
|
|
89
|
+
type PageResponse =
|
|
90
|
+
| ReturnType<typeof error<400, 'query_invalid'>>
|
|
91
|
+
| ReturnType<typeof error<502, 'upstream_error'>>
|
|
92
|
+
|
|
93
|
+
/** Default upstream error response. */
|
|
94
|
+
type Response = ReturnType<typeof error<502, 'upstream_error'>>
|
|
95
|
+
}
|
|
96
|
+
|
|
59
97
|
/**
|
|
60
98
|
* Validates `value` against `schema`. Returns the parsed value on success or
|
|
61
99
|
* throws a generic upstream error so the public response body never leaks Zod
|
|
@@ -104,7 +142,7 @@ export declare namespace error {
|
|
|
104
142
|
}
|
|
105
143
|
|
|
106
144
|
/** HTTP status code accepted by the public error helper. */
|
|
107
|
-
type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503
|
|
145
|
+
type Status = 400 | 401 | 403 | 404 | 409 | 412 | 413 | 415 | 429 | 500 | 501 | 502 | 503 | 504
|
|
108
146
|
|
|
109
147
|
/** Options for creating a JSON error response. */
|
|
110
148
|
type Options<status extends Status = Status, code extends string = string> = {
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import * as z from 'zod/mini'
|
|
2
|
+
|
|
1
3
|
import * as Schema from './Schema.js'
|
|
2
4
|
|
|
3
5
|
describe('ChainId', () => {
|
|
4
6
|
test('resolves aliases to their chain id', () => {
|
|
5
7
|
expect(Schema.ChainId.parse('mainnet')).toMatchInlineSnapshot(`4217`)
|
|
6
8
|
expect(Schema.ChainId.parse('testnet')).toMatchInlineSnapshot(`42431`)
|
|
9
|
+
expect(Schema.ChainId.parse('1424310001')).toMatchInlineSnapshot(`1424310003`)
|
|
10
|
+
expect(Schema.ChainId.parse(1_424_310_001)).toMatchInlineSnapshot(`1424310003`)
|
|
7
11
|
})
|
|
8
12
|
|
|
9
13
|
test('accepts numeric chain ids as numbers or strings', () => {
|
|
@@ -51,6 +55,20 @@ describe('Limit', () => {
|
|
|
51
55
|
})
|
|
52
56
|
})
|
|
53
57
|
|
|
58
|
+
describe('pageChecks', () => {
|
|
59
|
+
const Query = z
|
|
60
|
+
.object({ cursor: Schema.Cursor, limit: Schema.Limit, page: Schema.Page })
|
|
61
|
+
.check(...Schema.pageChecks())
|
|
62
|
+
|
|
63
|
+
test('accepts positional pages through the 500-row window', () => {
|
|
64
|
+
expect(Query.safeParse({ limit: '10', page: '50' }).success).toMatchInlineSnapshot(`true`)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('rejects deeper positional pages', () => {
|
|
68
|
+
expect(Query.safeParse({ limit: '10', page: '51' }).success).toMatchInlineSnapshot(`false`)
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
54
72
|
describe('timestampBound', () => {
|
|
55
73
|
test('normalizes RFC 3339 offsets to UTC', () => {
|
|
56
74
|
const bound = Schema.timestampBound('swaps', 'from')
|
package/src/internal/Schema.ts
CHANGED
|
@@ -90,12 +90,19 @@ export function tokenAddress(example: core_Hex.Hex) {
|
|
|
90
90
|
)
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
/** Maps
|
|
93
|
+
/** Maps caller-facing chain aliases to their current Tempo chain id. */
|
|
94
94
|
export const chainIdAlias = {
|
|
95
|
+
// TODO: Remove this alias after clients migrate to chain 1424310003.
|
|
96
|
+
1_424_310_001: 1_424_310_003,
|
|
95
97
|
mainnet: 4217,
|
|
96
98
|
testnet: 42431,
|
|
97
99
|
} as const
|
|
98
100
|
|
|
101
|
+
/** Resolves a numeric chain id through the caller-facing alias map. */
|
|
102
|
+
export function resolveChainId(chainId: number): number {
|
|
103
|
+
return chainIdAlias[chainId as keyof typeof chainIdAlias] ?? chainId
|
|
104
|
+
}
|
|
105
|
+
|
|
99
106
|
/**
|
|
100
107
|
* Tempo chain id. Accepts a chain alias (`mainnet`/`testnet`) or any positive
|
|
101
108
|
* integer chain id (a number or numeric string), normalizing all forms to a
|
|
@@ -110,7 +117,10 @@ export const ChainId = z
|
|
|
110
117
|
z.enum(['mainnet', 'testnet']),
|
|
111
118
|
z.transform((alias) => chainIdAlias[alias]),
|
|
112
119
|
),
|
|
113
|
-
z.
|
|
120
|
+
z.pipe(
|
|
121
|
+
z.coerce.number(),
|
|
122
|
+
z.transform((chainId) => resolveChainId(chainId)),
|
|
123
|
+
),
|
|
114
124
|
]),
|
|
115
125
|
z.number().check(z.int(), z.positive()),
|
|
116
126
|
)
|
|
@@ -191,6 +201,8 @@ export const ErrorDetail = z
|
|
|
191
201
|
})
|
|
192
202
|
.check(z.describe('A single problem with the request.'))
|
|
193
203
|
|
|
204
|
+
z.globalRegistry.add(ErrorDetail, { ...z.globalRegistry.get(ErrorDetail), ref: 'ErrorDetail' })
|
|
205
|
+
|
|
194
206
|
/**
|
|
195
207
|
* Builds the global error envelope, optionally enumerating `error.code` to a
|
|
196
208
|
* fixed set of machine-readable codes. Pass the codes a given status can return
|
|
@@ -384,12 +396,10 @@ export const Cursor = z
|
|
|
384
396
|
|
|
385
397
|
/**
|
|
386
398
|
* Maximum page window (`page × limit` rows) accepted by positional pagination.
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* cap): shallow page-numbered access is served positionally, deep traversal
|
|
390
|
-
* must use cursors.
|
|
399
|
+
* Stays below the indexer's own 10k row ceiling so large offsets do not reach
|
|
400
|
+
* the indexer. Deeper traversal must use cursors.
|
|
391
401
|
*/
|
|
392
|
-
export const maxPageWindow =
|
|
402
|
+
export const maxPageWindow = 500
|
|
393
403
|
|
|
394
404
|
/**
|
|
395
405
|
* Page-number query parameter (1-indexed) shared by list endpoints that
|
|
@@ -443,8 +453,8 @@ export const NextCursor = z
|
|
|
443
453
|
* count is computed by a capped subquery (`… LIMIT countCap`) so it can't blow
|
|
444
454
|
* the indexer's execution budget on the 10⁹-plus row tables; when the bound is
|
|
445
455
|
* hit the count is a lower bound, signalled by `Meta.totalCountCapped`. Mirrors the
|
|
446
|
-
* indexer's own 10k row ceiling
|
|
447
|
-
*
|
|
456
|
+
* indexer's own 10k row ceiling and the capped-count conventions of comparable
|
|
457
|
+
* APIs (Stripe Search's 10k `total_count`,
|
|
448
458
|
* Elasticsearch `track_total_hits`, Shopify's `Count.precision`).
|
|
449
459
|
*/
|
|
450
460
|
export const countCap = 10_000
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { HonoRequest } from 'hono/request'
|
|
1
2
|
import { Store } from 'tapimo'
|
|
2
3
|
import * as TestStore from '../../test/Store.js'
|
|
4
|
+
import * as Timeout from './Timeout.js'
|
|
3
5
|
|
|
4
6
|
describe('from', () => {
|
|
5
7
|
const ops = {
|
|
@@ -754,6 +756,18 @@ describe('durableObject', () => {
|
|
|
754
756
|
})
|
|
755
757
|
})
|
|
756
758
|
|
|
759
|
+
describe('withRequest', () => {
|
|
760
|
+
test('preserves the source store contract', async () => {
|
|
761
|
+
const source = new ReceiverStore()
|
|
762
|
+
const store = Store.withRequest(source, new HonoRequest(new Request('https://api.tempo.xyz')))
|
|
763
|
+
|
|
764
|
+
await store.put('value', 'stored')
|
|
765
|
+
|
|
766
|
+
expect(store.type).toMatchInlineSnapshot(`"cache"`)
|
|
767
|
+
expect(await source.get('value')).toMatchInlineSnapshot(`"stored"`)
|
|
768
|
+
})
|
|
769
|
+
})
|
|
770
|
+
|
|
757
771
|
describe('memoize', () => {
|
|
758
772
|
test('coalesces concurrent cache misses for the same key', async () => {
|
|
759
773
|
const store = Store.memory()
|
|
@@ -795,6 +809,183 @@ describe('memoize', () => {
|
|
|
795
809
|
`)
|
|
796
810
|
})
|
|
797
811
|
|
|
812
|
+
test('hands cache persistence to waitUntil without retaining the resolved flight', async () => {
|
|
813
|
+
const pending = deferred<void>()
|
|
814
|
+
const waited: Promise<unknown>[] = []
|
|
815
|
+
const source = Store.memory()
|
|
816
|
+
const store = Store.withRequest(
|
|
817
|
+
Store.from({
|
|
818
|
+
...source,
|
|
819
|
+
put: () => pending.promise,
|
|
820
|
+
type: 'cache',
|
|
821
|
+
}),
|
|
822
|
+
new HonoRequest(new Request('https://api.tempo.xyz')),
|
|
823
|
+
{ waitUntil: (promise) => void waited.push(promise) },
|
|
824
|
+
)
|
|
825
|
+
let calls = 0
|
|
826
|
+
const options = { key: 'memo:stalled-write', store, ttl: 60_000 }
|
|
827
|
+
|
|
828
|
+
const first = await Store.memoize(async () => ({ value: ++calls }), options)
|
|
829
|
+
const second = await Store.memoize(async () => ({ value: ++calls }), options)
|
|
830
|
+
|
|
831
|
+
expect(first).toEqual({ value: 1 })
|
|
832
|
+
expect(second).toEqual({ value: 2 })
|
|
833
|
+
expect(calls).toBe(2)
|
|
834
|
+
expect(waited).toHaveLength(2)
|
|
835
|
+
|
|
836
|
+
pending.resolve()
|
|
837
|
+
await Promise.all(waited)
|
|
838
|
+
})
|
|
839
|
+
|
|
840
|
+
test('ignores cache persistence failures without waitUntil', async () => {
|
|
841
|
+
const store = Store.from({
|
|
842
|
+
...Store.memory(),
|
|
843
|
+
async put() {
|
|
844
|
+
throw new Error('cache unavailable')
|
|
845
|
+
},
|
|
846
|
+
type: 'cache',
|
|
847
|
+
})
|
|
848
|
+
|
|
849
|
+
await expect(
|
|
850
|
+
Store.memoize(async () => ({ value: 'fresh' }), {
|
|
851
|
+
key: 'memo:failed-write',
|
|
852
|
+
store,
|
|
853
|
+
ttl: 60_000,
|
|
854
|
+
}),
|
|
855
|
+
).resolves.toEqual({ value: 'fresh' })
|
|
856
|
+
})
|
|
857
|
+
|
|
858
|
+
test('releases a no-cache flight after deletion fails', async () => {
|
|
859
|
+
let deletes = 0
|
|
860
|
+
let fetches = 0
|
|
861
|
+
const source = Store.from({
|
|
862
|
+
...Store.memory(),
|
|
863
|
+
async delete() {
|
|
864
|
+
if (++deletes === 1) throw new Error('cache unavailable')
|
|
865
|
+
},
|
|
866
|
+
})
|
|
867
|
+
const store = Store.withRequest(
|
|
868
|
+
source,
|
|
869
|
+
new HonoRequest(
|
|
870
|
+
new Request('https://api.tempo.xyz', { headers: { 'cache-control': 'no-cache' } }),
|
|
871
|
+
),
|
|
872
|
+
)
|
|
873
|
+
const options = { key: 'memo:failed-delete', store, ttl: 60_000 }
|
|
874
|
+
|
|
875
|
+
await expect(Store.memoize(async () => ({ value: ++fetches }), options)).rejects.toThrow(
|
|
876
|
+
'cache unavailable',
|
|
877
|
+
)
|
|
878
|
+
await expect(Store.memoize(async () => ({ value: ++fetches }), options)).resolves.toEqual({
|
|
879
|
+
value: 1,
|
|
880
|
+
})
|
|
881
|
+
expect(deletes).toBe(2)
|
|
882
|
+
})
|
|
883
|
+
|
|
884
|
+
test('times out and evicts a stalled cache-miss flight', async () => {
|
|
885
|
+
vi.useFakeTimers()
|
|
886
|
+
try {
|
|
887
|
+
const store = Store.memory()
|
|
888
|
+
const stalled = deferred<{ value: string }>()
|
|
889
|
+
let calls = 0
|
|
890
|
+
let leaderSignal: AbortSignal | undefined
|
|
891
|
+
const options = {
|
|
892
|
+
flightTimeout: 100,
|
|
893
|
+
key: 'memo:test',
|
|
894
|
+
store,
|
|
895
|
+
ttl: 60_000,
|
|
896
|
+
}
|
|
897
|
+
const leader = Store.memoize(async (signal) => {
|
|
898
|
+
calls += 1
|
|
899
|
+
leaderSignal = signal
|
|
900
|
+
return stalled.promise
|
|
901
|
+
}, options)
|
|
902
|
+
await vi.advanceTimersByTimeAsync(0)
|
|
903
|
+
const follower = Store.memoize(async () => {
|
|
904
|
+
calls += 1
|
|
905
|
+
return { value: 'unexpected' }
|
|
906
|
+
}, options)
|
|
907
|
+
const failures = Promise.all([
|
|
908
|
+
expect(leader).rejects.toBeInstanceOf(Store.MemoizeTimeoutError),
|
|
909
|
+
expect(follower).rejects.toBeInstanceOf(Store.MemoizeTimeoutError),
|
|
910
|
+
])
|
|
911
|
+
|
|
912
|
+
await vi.advanceTimersByTimeAsync(100)
|
|
913
|
+
await failures
|
|
914
|
+
|
|
915
|
+
expect(calls).toBe(1)
|
|
916
|
+
expect(leaderSignal?.aborted).toBe(true)
|
|
917
|
+
expect(leaderSignal?.reason).toMatchObject({ name: 'TimeoutError' })
|
|
918
|
+
|
|
919
|
+
const recovered = await Store.memoize(async () => {
|
|
920
|
+
calls += 1
|
|
921
|
+
return { value: 'fresh' }
|
|
922
|
+
}, options)
|
|
923
|
+
stalled.resolve({ value: 'stale' })
|
|
924
|
+
await stalled.promise
|
|
925
|
+
await Promise.resolve()
|
|
926
|
+
|
|
927
|
+
expect(recovered).toEqual({ value: 'fresh' })
|
|
928
|
+
expect(calls).toBe(2)
|
|
929
|
+
expect(await store.get('memo:test')).toBe('tempo-api:store:json:v2:{"value":"fresh"}')
|
|
930
|
+
} finally {
|
|
931
|
+
vi.useRealTimers()
|
|
932
|
+
}
|
|
933
|
+
})
|
|
934
|
+
|
|
935
|
+
test('retains a timed-out flight until a cache mutation settles', async () => {
|
|
936
|
+
vi.useFakeTimers()
|
|
937
|
+
try {
|
|
938
|
+
const source = Store.memory()
|
|
939
|
+
const store = Store.withRequest(
|
|
940
|
+
source,
|
|
941
|
+
new HonoRequest(
|
|
942
|
+
new Request('https://api.tempo.xyz', {
|
|
943
|
+
headers: { 'cache-control': 'no-cache' },
|
|
944
|
+
}),
|
|
945
|
+
),
|
|
946
|
+
)
|
|
947
|
+
let calls = 0
|
|
948
|
+
const options = { flightTimeout: 100, key: 'memo:mutation', store, ttl: 60_000 }
|
|
949
|
+
const leader = Store.memoize(async () => ({ value: ++calls }), options)
|
|
950
|
+
const leaderFailure = expect(leader).rejects.toBeInstanceOf(Store.MemoizeTimeoutError)
|
|
951
|
+
|
|
952
|
+
// The first microtask enters the real in-memory store's async delete.
|
|
953
|
+
await Promise.resolve()
|
|
954
|
+
vi.advanceTimersByTime(100)
|
|
955
|
+
const followerFailure = expect(
|
|
956
|
+
Store.memoize(async () => ({ value: ++calls }), options),
|
|
957
|
+
).rejects.toBeInstanceOf(Store.MemoizeTimeoutError)
|
|
958
|
+
|
|
959
|
+
await Promise.all([leaderFailure, followerFailure])
|
|
960
|
+
expect(calls).toBe(0)
|
|
961
|
+
await expect(Store.memoize(async () => ({ value: ++calls }), options)).resolves.toEqual({
|
|
962
|
+
value: 1,
|
|
963
|
+
})
|
|
964
|
+
} finally {
|
|
965
|
+
vi.useRealTimers()
|
|
966
|
+
}
|
|
967
|
+
})
|
|
968
|
+
|
|
969
|
+
test('defaults cache-miss flights to the API deadline', async () => {
|
|
970
|
+
vi.useFakeTimers()
|
|
971
|
+
try {
|
|
972
|
+
const store = Store.memory()
|
|
973
|
+
const stalled = deferred<{ value: string }>()
|
|
974
|
+
const failure = expect(
|
|
975
|
+
Store.memoize(() => stalled.promise, {
|
|
976
|
+
key: 'memo:default-timeout',
|
|
977
|
+
store,
|
|
978
|
+
ttl: 60_000,
|
|
979
|
+
}),
|
|
980
|
+
).rejects.toBeInstanceOf(Store.MemoizeTimeoutError)
|
|
981
|
+
|
|
982
|
+
await vi.advanceTimersByTimeAsync(Timeout.duration)
|
|
983
|
+
await failure
|
|
984
|
+
} finally {
|
|
985
|
+
vi.useRealTimers()
|
|
986
|
+
}
|
|
987
|
+
})
|
|
988
|
+
|
|
798
989
|
test('returns cached JSON values until the entry expires', async () => {
|
|
799
990
|
const store = Store.memory()
|
|
800
991
|
let calls = 0
|
|
@@ -836,6 +1027,126 @@ describe('memoize', () => {
|
|
|
836
1027
|
`)
|
|
837
1028
|
})
|
|
838
1029
|
|
|
1030
|
+
test('refreshes the entry when request headers send no-cache', async () => {
|
|
1031
|
+
const store = Store.memory()
|
|
1032
|
+
let calls = 0
|
|
1033
|
+
const fetch = async () => ({ value: ++calls })
|
|
1034
|
+
|
|
1035
|
+
await Store.memoize(fetch, { key: 'memo:test', store, ttl: 60_000 })
|
|
1036
|
+
const refreshed = await Store.memoize(fetch, {
|
|
1037
|
+
key: 'memo:test',
|
|
1038
|
+
store: Store.withRequest(
|
|
1039
|
+
store,
|
|
1040
|
+
new HonoRequest(
|
|
1041
|
+
new Request('https://api.tempo.xyz', {
|
|
1042
|
+
headers: { 'cache-control': 'no-cache' },
|
|
1043
|
+
}),
|
|
1044
|
+
),
|
|
1045
|
+
),
|
|
1046
|
+
ttl: 60_000,
|
|
1047
|
+
})
|
|
1048
|
+
const after = await Store.memoize(fetch, { key: 'memo:test', store, ttl: 60_000 })
|
|
1049
|
+
|
|
1050
|
+
expect(calls).toMatchInlineSnapshot(`2`)
|
|
1051
|
+
expect(refreshed).toMatchInlineSnapshot(`
|
|
1052
|
+
{
|
|
1053
|
+
"value": 2,
|
|
1054
|
+
}
|
|
1055
|
+
`)
|
|
1056
|
+
expect(after).toEqual(refreshed)
|
|
1057
|
+
})
|
|
1058
|
+
|
|
1059
|
+
test('propagates no-cache through nested memoizers', async () => {
|
|
1060
|
+
const source = Store.memory()
|
|
1061
|
+
let calls = 0
|
|
1062
|
+
const fetch = async () => ({ value: ++calls })
|
|
1063
|
+
|
|
1064
|
+
await Store.memoize(fetch, { key: 'memo:inner', store: source, ttl: 60_000 })
|
|
1065
|
+
const store = Store.withRequest(
|
|
1066
|
+
source,
|
|
1067
|
+
new HonoRequest(
|
|
1068
|
+
new Request('https://api.tempo.xyz', {
|
|
1069
|
+
headers: { 'cache-control': 'no-cache' },
|
|
1070
|
+
}),
|
|
1071
|
+
),
|
|
1072
|
+
)
|
|
1073
|
+
const value = await Store.memoize(
|
|
1074
|
+
() => Store.memoize(fetch, { key: 'memo:inner', store, ttl: 60_000 }),
|
|
1075
|
+
{ key: 'memo:outer', store, ttl: 60_000 },
|
|
1076
|
+
)
|
|
1077
|
+
|
|
1078
|
+
expect(calls).toMatchInlineSnapshot(`2`)
|
|
1079
|
+
expect(value).toMatchInlineSnapshot(`
|
|
1080
|
+
{
|
|
1081
|
+
"value": 2,
|
|
1082
|
+
}
|
|
1083
|
+
`)
|
|
1084
|
+
})
|
|
1085
|
+
|
|
1086
|
+
test('bypasses without replacing the entry when request headers send no-store', async () => {
|
|
1087
|
+
const store = Store.memory()
|
|
1088
|
+
let calls = 0
|
|
1089
|
+
const fetch = async () => ({ value: ++calls })
|
|
1090
|
+
|
|
1091
|
+
const first = await Store.memoize(fetch, { key: 'memo:test', store, ttl: 60_000 })
|
|
1092
|
+
const bypassed = await Store.memoize(fetch, {
|
|
1093
|
+
key: 'memo:test',
|
|
1094
|
+
store: Store.withRequest(
|
|
1095
|
+
store,
|
|
1096
|
+
new HonoRequest(
|
|
1097
|
+
new Request('https://api.tempo.xyz', {
|
|
1098
|
+
headers: { 'cache-control': 'no-store' },
|
|
1099
|
+
}),
|
|
1100
|
+
),
|
|
1101
|
+
),
|
|
1102
|
+
ttl: 60_000,
|
|
1103
|
+
})
|
|
1104
|
+
const after = await Store.memoize(fetch, { key: 'memo:test', store, ttl: 60_000 })
|
|
1105
|
+
|
|
1106
|
+
expect(calls).toMatchInlineSnapshot(`2`)
|
|
1107
|
+
expect(bypassed).toMatchInlineSnapshot(`
|
|
1108
|
+
{
|
|
1109
|
+
"value": 2,
|
|
1110
|
+
}
|
|
1111
|
+
`)
|
|
1112
|
+
expect(after).toEqual(first)
|
|
1113
|
+
})
|
|
1114
|
+
|
|
1115
|
+
test('honors Pragma no-cache only without Cache-Control', async () => {
|
|
1116
|
+
const store = Store.memory()
|
|
1117
|
+
let calls = 0
|
|
1118
|
+
const fetch = async () => ({ value: ++calls })
|
|
1119
|
+
|
|
1120
|
+
await Store.memoize(fetch, { key: 'memo:test', store, ttl: 60_000 })
|
|
1121
|
+
await Store.memoize(fetch, {
|
|
1122
|
+
key: 'memo:test',
|
|
1123
|
+
store: Store.withRequest(
|
|
1124
|
+
store,
|
|
1125
|
+
new HonoRequest(new Request('https://api.tempo.xyz', { headers: { pragma: 'no-cache' } })),
|
|
1126
|
+
),
|
|
1127
|
+
ttl: 60_000,
|
|
1128
|
+
})
|
|
1129
|
+
const cached = await Store.memoize(fetch, {
|
|
1130
|
+
key: 'memo:test',
|
|
1131
|
+
store: Store.withRequest(
|
|
1132
|
+
store,
|
|
1133
|
+
new HonoRequest(
|
|
1134
|
+
new Request('https://api.tempo.xyz', {
|
|
1135
|
+
headers: { 'cache-control': 'max-age=0', pragma: 'no-cache' },
|
|
1136
|
+
}),
|
|
1137
|
+
),
|
|
1138
|
+
),
|
|
1139
|
+
ttl: 60_000,
|
|
1140
|
+
})
|
|
1141
|
+
|
|
1142
|
+
expect(calls).toMatchInlineSnapshot(`2`)
|
|
1143
|
+
expect(cached).toMatchInlineSnapshot(`
|
|
1144
|
+
{
|
|
1145
|
+
"value": 2,
|
|
1146
|
+
}
|
|
1147
|
+
`)
|
|
1148
|
+
})
|
|
1149
|
+
|
|
839
1150
|
test('preserves bigint values and collision-shaped strings on cache hits', async () => {
|
|
840
1151
|
const store = Store.memory()
|
|
841
1152
|
let calls = 0
|
|
@@ -877,6 +1188,34 @@ describe('memoize', () => {
|
|
|
877
1188
|
expect(calls).toBe(2)
|
|
878
1189
|
})
|
|
879
1190
|
|
|
1191
|
+
test('coalesces values excluded by the cache predicate without storing them', async () => {
|
|
1192
|
+
const store = Store.memory()
|
|
1193
|
+
const pending = deferred<void>()
|
|
1194
|
+
let calls = 0
|
|
1195
|
+
const fetch = async () => {
|
|
1196
|
+
calls += 1
|
|
1197
|
+
await pending.promise
|
|
1198
|
+
return { cacheable: false, value: 'fresh' }
|
|
1199
|
+
}
|
|
1200
|
+
const options = {
|
|
1201
|
+
key: 'memo:test',
|
|
1202
|
+
shouldCache: (value: Awaited<ReturnType<typeof fetch>>) => value.cacheable,
|
|
1203
|
+
store,
|
|
1204
|
+
ttl: 60_000,
|
|
1205
|
+
}
|
|
1206
|
+
const requests = [Store.memoize(fetch, options), Store.memoize(fetch, options)]
|
|
1207
|
+
|
|
1208
|
+
await Promise.resolve()
|
|
1209
|
+
pending.resolve()
|
|
1210
|
+
|
|
1211
|
+
expect(await Promise.all(requests)).toStrictEqual([
|
|
1212
|
+
{ cacheable: false, value: 'fresh' },
|
|
1213
|
+
{ cacheable: false, value: 'fresh' },
|
|
1214
|
+
])
|
|
1215
|
+
expect(await store.get('memo:test')).toBeNull()
|
|
1216
|
+
expect(calls).toBe(1)
|
|
1217
|
+
})
|
|
1218
|
+
|
|
880
1219
|
test('refreshes legacy untagged cache entries', async () => {
|
|
881
1220
|
const store = Store.memory({ entries: [['memo:test', '{"value":"123#__bigint"}']] })
|
|
882
1221
|
let calls = 0
|
|
@@ -945,3 +1284,28 @@ function durableObjectStorage(): Store.durableObject.Storage & { cells: Map<stri
|
|
|
945
1284
|
},
|
|
946
1285
|
}
|
|
947
1286
|
}
|
|
1287
|
+
|
|
1288
|
+
class ReceiverStore implements Store.Store {
|
|
1289
|
+
#cells = new Map<string, string>()
|
|
1290
|
+
type = 'cache' as const
|
|
1291
|
+
|
|
1292
|
+
async delete(key: string) {
|
|
1293
|
+
this.#cells.delete(key)
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
async get(key: string) {
|
|
1297
|
+
return this.#cells.get(key) ?? null
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
async list(options: { prefix?: string | undefined } = {}) {
|
|
1301
|
+
return {
|
|
1302
|
+
keys: [...this.#cells.keys()]
|
|
1303
|
+
.filter((key) => options.prefix === undefined || key.startsWith(options.prefix))
|
|
1304
|
+
.map((name) => ({ name })),
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
async put(key: string, value: string) {
|
|
1309
|
+
this.#cells.set(key, value)
|
|
1310
|
+
}
|
|
1311
|
+
}
|