@astrale-os/kernel-client 0.6.0-beta.8 → 0.6.0-beta.80
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/auth/auth.d.ts +25 -10
- package/dist/auth/auth.js +5 -7
- package/dist/auth/authorization.d.ts +6 -4
- package/dist/auth/authorization.js +25 -6
- package/dist/auth/credential.d.ts +11 -2
- package/dist/auth/credential.js +6 -3
- package/dist/auth/identity.d.ts +6 -9
- package/dist/auth/identity.js +0 -1
- package/dist/auth/index.d.ts +4 -5
- package/dist/auth/index.js +2 -4
- package/dist/auth/register.d.ts +24 -0
- package/dist/auth/register.js +10 -0
- package/dist/client/admission.d.ts +4 -2
- package/dist/client/admission.js +8 -2
- package/dist/client/client.d.ts +4 -3
- package/dist/client/client.js +13 -3
- package/dist/client/credential.d.ts +4 -3
- package/dist/client/credential.js +7 -3
- package/dist/client/index.d.ts +1 -2
- package/dist/client/index.js +1 -2
- package/dist/client/request.d.ts +10 -4
- package/dist/client/request.js +33 -6
- package/dist/client/result.d.ts +3 -4
- package/dist/client/result.js +3 -1
- package/dist/client/routing-control.d.ts +0 -1
- package/dist/client/routing-control.js +0 -1
- package/dist/errors/client-error.d.ts +0 -1
- package/dist/errors/client-error.js +2 -1
- package/dist/errors/exchange-error.d.ts +19 -0
- package/dist/errors/exchange-error.js +9 -0
- package/dist/errors/index.d.ts +8 -7
- package/dist/errors/index.js +8 -7
- package/dist/errors/miss-error.d.ts +0 -1
- package/dist/errors/miss-error.js +0 -1
- package/dist/errors/protocol-error.d.ts +0 -1
- package/dist/errors/protocol-error.js +0 -1
- package/dist/errors/response-error.d.ts +0 -1
- package/dist/errors/response-error.js +0 -1
- package/dist/errors/session-error.d.ts +9 -0
- package/dist/errors/session-error.js +9 -0
- package/dist/errors/stale-route-error.d.ts +0 -1
- package/dist/errors/stale-route-error.js +0 -1
- package/dist/errors/transport-error.d.ts +18 -6
- package/dist/errors/transport-error.js +11 -7
- package/dist/graph/domain/binding.d.ts +22 -0
- package/dist/graph/domain/binding.js +123 -0
- package/dist/graph/domain/domain.typecheck.d.ts +1 -0
- package/dist/graph/domain/domain.typecheck.js +147 -0
- package/dist/graph/domain/index.d.ts +3 -0
- package/dist/graph/domain/index.js +1 -0
- package/dist/graph/domain/model.d.ts +18 -0
- package/dist/graph/domain/model.js +1 -0
- package/dist/graph/domain/page.d.ts +23 -0
- package/dist/graph/domain/page.js +42 -0
- package/dist/graph/domain/project.d.ts +8 -0
- package/dist/graph/domain/project.js +124 -0
- package/dist/graph/domain/provenance.d.ts +6 -0
- package/dist/graph/domain/provenance.js +11 -0
- package/dist/graph/errors.d.ts +2 -3
- package/dist/graph/errors.js +1 -2
- package/dist/graph/expectation.d.ts +3 -0
- package/dist/graph/expectation.js +6 -0
- package/dist/graph/graph.d.ts +12 -8
- package/dist/graph/graph.js +0 -1
- package/dist/graph/index.d.ts +2 -2
- package/dist/graph/index.js +1 -1
- package/dist/graph/mutation.d.ts +2 -4
- package/dist/graph/mutation.js +10 -2
- package/dist/graph/page/index.d.ts +0 -1
- package/dist/graph/page/index.js +0 -1
- package/dist/graph/page/neighbors.d.ts +4 -5
- package/dist/graph/page/neighbors.js +7 -7
- package/dist/graph/page/page.d.ts +5 -2
- package/dist/graph/page/page.js +0 -1
- package/dist/graph/page-contract.d.ts +1 -2
- package/dist/graph/page-contract.js +0 -1
- package/dist/graph/provenance.d.ts +14 -0
- package/dist/graph/provenance.js +42 -0
- package/dist/graph/query.d.ts +3 -1
- package/dist/graph/query.js +33 -13
- package/dist/graph/read.d.ts +3 -4
- package/dist/graph/read.js +6 -5
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/pacer/batcher/batcher.d.ts +0 -1
- package/dist/pacer/batcher/batcher.js +0 -1
- package/dist/pacer/batcher/defaults.d.ts +0 -1
- package/dist/pacer/batcher/defaults.js +0 -1
- package/dist/pacer/batcher/index.d.ts +0 -1
- package/dist/pacer/batcher/index.js +0 -1
- package/dist/pacer/index.d.ts +0 -1
- package/dist/pacer/index.js +0 -1
- package/dist/pacer/limiter/defaults.d.ts +0 -1
- package/dist/pacer/limiter/defaults.js +0 -1
- package/dist/pacer/limiter/index.d.ts +0 -1
- package/dist/pacer/limiter/index.js +0 -1
- package/dist/pacer/limiter/limiter.d.ts +0 -1
- package/dist/pacer/limiter/limiter.js +0 -1
- package/dist/pacer/queue/defaults.d.ts +0 -1
- package/dist/pacer/queue/defaults.js +0 -1
- package/dist/pacer/queue/index.d.ts +0 -1
- package/dist/pacer/queue/index.js +0 -1
- package/dist/pacer/queue/queue.d.ts +0 -1
- package/dist/pacer/queue/queue.js +0 -1
- package/dist/pacer/retry/defaults.d.ts +0 -1
- package/dist/pacer/retry/defaults.js +0 -1
- package/dist/pacer/retry/index.d.ts +0 -1
- package/dist/pacer/retry/index.js +0 -1
- package/dist/pacer/retry/retry.d.ts +0 -1
- package/dist/pacer/retry/retry.js +0 -1
- package/dist/pool/index.d.ts +0 -1
- package/dist/pool/index.js +0 -1
- package/dist/pool/pool.d.ts +0 -1
- package/dist/pool/pool.js +0 -1
- package/dist/pool/target.d.ts +0 -1
- package/dist/pool/target.js +0 -1
- package/dist/schema/admission.d.ts +1 -2
- package/dist/schema/admission.js +0 -1
- package/dist/schema/contracts.d.ts +6 -16
- package/dist/schema/contracts.js +0 -1
- package/dist/schema/index.d.ts +2 -3
- package/dist/schema/index.js +1 -2
- package/dist/schema/introspection.d.ts +1 -2
- package/dist/schema/introspection.js +9 -2
- package/dist/schema/operation.d.ts +0 -1
- package/dist/schema/operation.js +2 -3
- package/dist/schema/schema.d.ts +13 -10
- package/dist/schema/schema.js +83 -11
- package/dist/session/admission.d.ts +6 -0
- package/dist/session/admission.js +59 -0
- package/dist/session/bound.d.ts +48 -0
- package/dist/session/bound.js +110 -0
- package/dist/session/content.d.ts +27 -0
- package/dist/session/content.js +158 -0
- package/dist/session/context/control.d.ts +0 -1
- package/dist/session/context/control.js +0 -1
- package/dist/session/context/index.d.ts +0 -1
- package/dist/session/context/index.js +0 -1
- package/dist/session/context/limits.d.ts +0 -1
- package/dist/session/context/limits.js +0 -1
- package/dist/session/context/operation.d.ts +5 -2
- package/dist/session/context/operation.js +19 -17
- package/dist/session/context/policy.d.ts +0 -1
- package/dist/session/context/policy.js +0 -1
- package/dist/session/credential/index.d.ts +1 -0
- package/dist/session/credential/index.js +1 -0
- package/dist/session/credential/limits.d.ts +12 -0
- package/dist/session/credential/limits.js +12 -0
- package/dist/session/credential/provider.d.ts +56 -0
- package/dist/session/credential/provider.js +236 -0
- package/dist/session/discovery/bundle.d.ts +5 -2
- package/dist/session/discovery/bundle.js +34 -15
- package/dist/session/discovery/discovery.d.ts +4 -2
- package/dist/session/discovery/discovery.js +34 -6
- package/dist/session/discovery/index.d.ts +3 -1
- package/dist/session/discovery/index.js +1 -1
- package/dist/session/discovery/publication.d.ts +0 -1
- package/dist/session/discovery/publication.js +4 -4
- package/dist/session/discovery/snapshot.d.ts +0 -1
- package/dist/session/discovery/snapshot.js +0 -1
- package/dist/session/discovery/transport.d.ts +6 -0
- package/dist/session/discovery/transport.js +13 -0
- package/dist/session/exchange/domain.d.ts +27 -0
- package/dist/session/exchange/domain.js +63 -0
- package/dist/session/exchange/exchange.d.ts +54 -0
- package/dist/session/exchange/exchange.js +58 -0
- package/dist/session/exchange/index.d.ts +5 -0
- package/dist/session/exchange/index.js +5 -0
- package/dist/session/exchange/issuer.d.ts +18 -0
- package/dist/session/exchange/issuer.js +149 -0
- package/dist/session/exchange/limits.d.ts +10 -0
- package/dist/session/exchange/limits.js +10 -0
- package/dist/session/exchange/options.d.ts +29 -0
- package/dist/session/exchange/options.js +57 -0
- package/dist/session/exchange/presentation.d.ts +18 -0
- package/dist/session/exchange/presentation.js +73 -0
- package/dist/session/exchange/source.d.ts +32 -0
- package/dist/session/exchange/source.js +78 -0
- package/dist/session/execution.d.ts +65 -0
- package/dist/session/execution.js +34 -0
- package/dist/session/index.d.ts +9 -4
- package/dist/session/index.js +4 -1
- package/dist/session/reference.d.ts +40 -12
- package/dist/session/reference.js +56 -14
- package/dist/session/routing/auth.d.ts +10 -1
- package/dist/session/routing/auth.js +8 -2
- package/dist/session/routing/cache.d.ts +27 -8
- package/dist/session/routing/cache.js +218 -25
- package/dist/session/routing/dispatch.d.ts +15 -8
- package/dist/session/routing/dispatch.js +121 -48
- package/dist/session/routing/envelope.d.ts +2 -1
- package/dist/session/routing/envelope.js +14 -10
- package/dist/session/routing/index.d.ts +3 -5
- package/dist/session/routing/index.js +2 -3
- package/dist/session/routing/request.d.ts +9 -1
- package/dist/session/routing/request.js +17 -1
- package/dist/session/session.d.ts +41 -8
- package/dist/session/session.js +129 -41
- package/dist/session/session.typecheck.d.ts +0 -1
- package/dist/session/session.typecheck.js +172 -3
- package/dist/session/views/catalog.d.ts +0 -1
- package/dist/session/views/catalog.js +14 -5
- package/dist/session/views/index.d.ts +0 -1
- package/dist/session/views/index.js +0 -1
- package/dist/session/views/resolve.d.ts +0 -1
- package/dist/session/views/resolve.js +0 -1
- package/dist/store/entity-index.d.ts +0 -1
- package/dist/store/entity-index.js +0 -1
- package/dist/store/index.d.ts +0 -1
- package/dist/store/index.js +0 -1
- package/dist/store/memory.d.ts +2 -2
- package/dist/store/memory.js +38 -15
- package/dist/store/mutation.d.ts +1 -2
- package/dist/store/mutation.js +6 -4
- package/dist/store/observe.d.ts +0 -1
- package/dist/store/observe.js +0 -1
- package/dist/store/optimistic.d.ts +0 -1
- package/dist/store/optimistic.js +0 -1
- package/dist/store/query-key.d.ts +2 -2
- package/dist/store/query-key.js +7 -3
- package/dist/store/shape.d.ts +4 -2
- package/dist/store/shape.js +4 -2
- package/dist/store/store.d.ts +2 -4
- package/dist/store/store.js +6 -5
- package/dist/store/store.typecheck.d.ts +0 -1
- package/dist/store/store.typecheck.js +3 -9
- package/dist/transport/auto/decision.d.ts +0 -1
- package/dist/transport/auto/decision.js +0 -1
- package/dist/transport/auto/fallback.d.ts +2 -2
- package/dist/transport/auto/fallback.js +10 -11
- package/dist/transport/auto/index.d.ts +0 -1
- package/dist/transport/auto/index.js +0 -1
- package/dist/transport/auto/transport.d.ts +0 -1
- package/dist/transport/auto/transport.js +5 -6
- package/dist/transport/auto/warning.d.ts +0 -1
- package/dist/transport/auto/warning.js +5 -3
- package/dist/transport/deadline.d.ts +0 -1
- package/dist/transport/deadline.js +0 -1
- package/dist/transport/failure.d.ts +7 -0
- package/dist/transport/failure.js +9 -0
- package/dist/transport/http/byte-stream.d.ts +18 -0
- package/dist/transport/http/byte-stream.js +94 -0
- package/dist/transport/http/index.d.ts +0 -1
- package/dist/transport/http/index.js +0 -1
- package/dist/transport/http/response.d.ts +0 -1
- package/dist/transport/http/response.js +0 -1
- package/dist/transport/http/stream.d.ts +0 -1
- package/dist/transport/http/stream.js +7 -7
- package/dist/transport/http/transport.d.ts +3 -1
- package/dist/transport/http/transport.js +87 -30
- package/dist/transport/index.d.ts +0 -1
- package/dist/transport/index.js +0 -1
- package/dist/transport/transport.d.ts +0 -1
- package/dist/transport/transport.js +0 -1
- package/dist/transport/websocket/connection.d.ts +0 -1
- package/dist/transport/websocket/connection.js +16 -26
- package/dist/transport/websocket/exchange.d.ts +0 -1
- package/dist/transport/websocket/exchange.js +5 -9
- package/dist/transport/websocket/index.d.ts +0 -1
- package/dist/transport/websocket/index.js +0 -1
- package/dist/transport/websocket/transport.d.ts +0 -1
- package/dist/transport/websocket/transport.js +7 -20
- package/package.json +12 -14
- package/dist/auth/auth.d.ts.map +0 -1
- package/dist/auth/auth.js.map +0 -1
- package/dist/auth/authorization.d.ts.map +0 -1
- package/dist/auth/authorization.js.map +0 -1
- package/dist/auth/credential.d.ts.map +0 -1
- package/dist/auth/credential.js.map +0 -1
- package/dist/auth/identity.d.ts.map +0 -1
- package/dist/auth/identity.js.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/provision.d.ts +0 -9
- package/dist/auth/provision.d.ts.map +0 -1
- package/dist/auth/provision.js +0 -11
- package/dist/auth/provision.js.map +0 -1
- package/dist/client/admission.d.ts.map +0 -1
- package/dist/client/admission.js.map +0 -1
- package/dist/client/client.d.ts.map +0 -1
- package/dist/client/client.js.map +0 -1
- package/dist/client/credential.d.ts.map +0 -1
- package/dist/client/credential.js.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/client/request.d.ts.map +0 -1
- package/dist/client/request.js.map +0 -1
- package/dist/client/result.d.ts.map +0 -1
- package/dist/client/result.js.map +0 -1
- package/dist/client/routing-control.d.ts.map +0 -1
- package/dist/client/routing-control.js.map +0 -1
- package/dist/errors/client-error.d.ts.map +0 -1
- package/dist/errors/client-error.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/miss-error.d.ts.map +0 -1
- package/dist/errors/miss-error.js.map +0 -1
- package/dist/errors/protocol-error.d.ts.map +0 -1
- package/dist/errors/protocol-error.js.map +0 -1
- package/dist/errors/response-error.d.ts.map +0 -1
- package/dist/errors/response-error.js.map +0 -1
- package/dist/errors/stale-route-error.d.ts.map +0 -1
- package/dist/errors/stale-route-error.js.map +0 -1
- package/dist/errors/transport-error.d.ts.map +0 -1
- package/dist/errors/transport-error.js.map +0 -1
- package/dist/graph/errors.d.ts.map +0 -1
- package/dist/graph/errors.js.map +0 -1
- package/dist/graph/graph.d.ts.map +0 -1
- package/dist/graph/graph.js.map +0 -1
- package/dist/graph/index.d.ts.map +0 -1
- package/dist/graph/index.js.map +0 -1
- package/dist/graph/mutation.d.ts.map +0 -1
- package/dist/graph/mutation.js.map +0 -1
- package/dist/graph/page/index.d.ts.map +0 -1
- package/dist/graph/page/index.js.map +0 -1
- package/dist/graph/page/neighbors.d.ts.map +0 -1
- package/dist/graph/page/neighbors.js.map +0 -1
- package/dist/graph/page/page.d.ts.map +0 -1
- package/dist/graph/page/page.js.map +0 -1
- package/dist/graph/page-contract.d.ts.map +0 -1
- package/dist/graph/page-contract.js.map +0 -1
- package/dist/graph/query.d.ts.map +0 -1
- package/dist/graph/query.js.map +0 -1
- package/dist/graph/read.d.ts.map +0 -1
- package/dist/graph/read.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/pacer/batcher/batcher.d.ts.map +0 -1
- package/dist/pacer/batcher/batcher.js.map +0 -1
- package/dist/pacer/batcher/defaults.d.ts.map +0 -1
- package/dist/pacer/batcher/defaults.js.map +0 -1
- package/dist/pacer/batcher/index.d.ts.map +0 -1
- package/dist/pacer/batcher/index.js.map +0 -1
- package/dist/pacer/index.d.ts.map +0 -1
- package/dist/pacer/index.js.map +0 -1
- package/dist/pacer/limiter/defaults.d.ts.map +0 -1
- package/dist/pacer/limiter/defaults.js.map +0 -1
- package/dist/pacer/limiter/index.d.ts.map +0 -1
- package/dist/pacer/limiter/index.js.map +0 -1
- package/dist/pacer/limiter/limiter.d.ts.map +0 -1
- package/dist/pacer/limiter/limiter.js.map +0 -1
- package/dist/pacer/queue/defaults.d.ts.map +0 -1
- package/dist/pacer/queue/defaults.js.map +0 -1
- package/dist/pacer/queue/index.d.ts.map +0 -1
- package/dist/pacer/queue/index.js.map +0 -1
- package/dist/pacer/queue/queue.d.ts.map +0 -1
- package/dist/pacer/queue/queue.js.map +0 -1
- package/dist/pacer/retry/defaults.d.ts.map +0 -1
- package/dist/pacer/retry/defaults.js.map +0 -1
- package/dist/pacer/retry/index.d.ts.map +0 -1
- package/dist/pacer/retry/index.js.map +0 -1
- package/dist/pacer/retry/retry.d.ts.map +0 -1
- package/dist/pacer/retry/retry.js.map +0 -1
- package/dist/pool/index.d.ts.map +0 -1
- package/dist/pool/index.js.map +0 -1
- package/dist/pool/pool.d.ts.map +0 -1
- package/dist/pool/pool.js.map +0 -1
- package/dist/pool/target.d.ts.map +0 -1
- package/dist/pool/target.js.map +0 -1
- package/dist/schema/admission.d.ts.map +0 -1
- package/dist/schema/admission.js.map +0 -1
- package/dist/schema/contracts.d.ts.map +0 -1
- package/dist/schema/contracts.js.map +0 -1
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js.map +0 -1
- package/dist/schema/introspection.d.ts.map +0 -1
- package/dist/schema/introspection.js.map +0 -1
- package/dist/schema/operation.d.ts.map +0 -1
- package/dist/schema/operation.js.map +0 -1
- package/dist/schema/schema.d.ts.map +0 -1
- package/dist/schema/schema.js.map +0 -1
- package/dist/session/context/control.d.ts.map +0 -1
- package/dist/session/context/control.js.map +0 -1
- package/dist/session/context/index.d.ts.map +0 -1
- package/dist/session/context/index.js.map +0 -1
- package/dist/session/context/limits.d.ts.map +0 -1
- package/dist/session/context/limits.js.map +0 -1
- package/dist/session/context/operation.d.ts.map +0 -1
- package/dist/session/context/operation.js.map +0 -1
- package/dist/session/context/policy.d.ts.map +0 -1
- package/dist/session/context/policy.js.map +0 -1
- package/dist/session/discovery/bundle.d.ts.map +0 -1
- package/dist/session/discovery/bundle.js.map +0 -1
- package/dist/session/discovery/discovery.d.ts.map +0 -1
- package/dist/session/discovery/discovery.js.map +0 -1
- package/dist/session/discovery/index.d.ts.map +0 -1
- package/dist/session/discovery/index.js.map +0 -1
- package/dist/session/discovery/publication.d.ts.map +0 -1
- package/dist/session/discovery/publication.js.map +0 -1
- package/dist/session/discovery/snapshot.d.ts.map +0 -1
- package/dist/session/discovery/snapshot.js.map +0 -1
- package/dist/session/index.d.ts.map +0 -1
- package/dist/session/index.js.map +0 -1
- package/dist/session/reference.d.ts.map +0 -1
- package/dist/session/reference.js.map +0 -1
- package/dist/session/routing/auth.d.ts.map +0 -1
- package/dist/session/routing/auth.js.map +0 -1
- package/dist/session/routing/cache.d.ts.map +0 -1
- package/dist/session/routing/cache.js.map +0 -1
- package/dist/session/routing/dispatch.d.ts.map +0 -1
- package/dist/session/routing/dispatch.js.map +0 -1
- package/dist/session/routing/envelope.d.ts.map +0 -1
- package/dist/session/routing/envelope.js.map +0 -1
- package/dist/session/routing/expectation.d.ts +0 -7
- package/dist/session/routing/expectation.d.ts.map +0 -1
- package/dist/session/routing/expectation.js +0 -2
- package/dist/session/routing/expectation.js.map +0 -1
- package/dist/session/routing/index.d.ts.map +0 -1
- package/dist/session/routing/index.js.map +0 -1
- package/dist/session/routing/request.d.ts.map +0 -1
- package/dist/session/routing/request.js.map +0 -1
- package/dist/session/session.d.ts.map +0 -1
- package/dist/session/session.js.map +0 -1
- package/dist/session/session.typecheck.d.ts.map +0 -1
- package/dist/session/session.typecheck.js.map +0 -1
- package/dist/session/views/catalog.d.ts.map +0 -1
- package/dist/session/views/catalog.js.map +0 -1
- package/dist/session/views/index.d.ts.map +0 -1
- package/dist/session/views/index.js.map +0 -1
- package/dist/session/views/resolve.d.ts.map +0 -1
- package/dist/session/views/resolve.js.map +0 -1
- package/dist/store/entity-index.d.ts.map +0 -1
- package/dist/store/entity-index.js.map +0 -1
- package/dist/store/index.d.ts.map +0 -1
- package/dist/store/index.js.map +0 -1
- package/dist/store/memory.d.ts.map +0 -1
- package/dist/store/memory.js.map +0 -1
- package/dist/store/mutation.d.ts.map +0 -1
- package/dist/store/mutation.js.map +0 -1
- package/dist/store/observe.d.ts.map +0 -1
- package/dist/store/observe.js.map +0 -1
- package/dist/store/optimistic.d.ts.map +0 -1
- package/dist/store/optimistic.js.map +0 -1
- package/dist/store/query-key.d.ts.map +0 -1
- package/dist/store/query-key.js.map +0 -1
- package/dist/store/shape.d.ts.map +0 -1
- package/dist/store/shape.js.map +0 -1
- package/dist/store/store.d.ts.map +0 -1
- package/dist/store/store.js.map +0 -1
- package/dist/store/store.typecheck.d.ts.map +0 -1
- package/dist/store/store.typecheck.js.map +0 -1
- package/dist/transport/auto/decision.d.ts.map +0 -1
- package/dist/transport/auto/decision.js.map +0 -1
- package/dist/transport/auto/fallback.d.ts.map +0 -1
- package/dist/transport/auto/fallback.js.map +0 -1
- package/dist/transport/auto/index.d.ts.map +0 -1
- package/dist/transport/auto/index.js.map +0 -1
- package/dist/transport/auto/transport.d.ts.map +0 -1
- package/dist/transport/auto/transport.js.map +0 -1
- package/dist/transport/auto/warning.d.ts.map +0 -1
- package/dist/transport/auto/warning.js.map +0 -1
- package/dist/transport/deadline.d.ts.map +0 -1
- package/dist/transport/deadline.js.map +0 -1
- package/dist/transport/http/index.d.ts.map +0 -1
- package/dist/transport/http/index.js.map +0 -1
- package/dist/transport/http/response.d.ts.map +0 -1
- package/dist/transport/http/response.js.map +0 -1
- package/dist/transport/http/stream.d.ts.map +0 -1
- package/dist/transport/http/stream.js.map +0 -1
- package/dist/transport/http/transport.d.ts.map +0 -1
- package/dist/transport/http/transport.js.map +0 -1
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/transport.d.ts.map +0 -1
- package/dist/transport/transport.js.map +0 -1
- package/dist/transport/websocket/connection.d.ts.map +0 -1
- package/dist/transport/websocket/connection.js.map +0 -1
- package/dist/transport/websocket/exchange.d.ts.map +0 -1
- package/dist/transport/websocket/exchange.js.map +0 -1
- package/dist/transport/websocket/index.d.ts.map +0 -1
- package/dist/transport/websocket/index.js.map +0 -1
- package/dist/transport/websocket/transport.d.ts.map +0 -1
- package/dist/transport/websocket/transport.js.map +0 -1
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { ClientError } from '../../errors/index.js';
|
|
2
|
+
import { BACKOFF_MS, MINT_TIMEOUT_MS, RETRY_INTERVAL_MS, SETTLEMENT_SKEW_MS } from './limits.js';
|
|
3
|
+
/**
|
|
4
|
+
* Remaining lifetime a credential must exceed to carry a delegation of `ttlSeconds`: the TTL itself
|
|
5
|
+
* plus the settlement skew, so it cannot expire between admission and delivery.
|
|
6
|
+
*/
|
|
7
|
+
export function delegationCoverageMs(ttlSeconds) {
|
|
8
|
+
return ttlSeconds * 1_000 + SETTLEMENT_SKEW_MS;
|
|
9
|
+
}
|
|
10
|
+
export function createSessionCredentialProvider(options) {
|
|
11
|
+
if (options === null || typeof options !== 'object') {
|
|
12
|
+
throw new TypeError('Session credential provider options are invalid.');
|
|
13
|
+
}
|
|
14
|
+
if (typeof options.mint !== 'function') {
|
|
15
|
+
throw new TypeError('Session credential mint capability is invalid.');
|
|
16
|
+
}
|
|
17
|
+
if (!Number.isSafeInteger(options.ttlSeconds) || options.ttlSeconds < 1) {
|
|
18
|
+
throw new TypeError('Session credential ttlSeconds must be a positive safe integer.');
|
|
19
|
+
}
|
|
20
|
+
if (options.onChange !== undefined && typeof options.onChange !== 'function') {
|
|
21
|
+
throw new TypeError('Session credential change observer is invalid.');
|
|
22
|
+
}
|
|
23
|
+
const { ttlSeconds } = options;
|
|
24
|
+
const mint = options.mint.bind(options);
|
|
25
|
+
const notify = options.onChange?.bind(options);
|
|
26
|
+
// The threshold is the coverage the caller already declared, never a separate guessed constant.
|
|
27
|
+
const marginMs = delegationCoverageMs(ttlSeconds);
|
|
28
|
+
let current = options.initial === undefined ? undefined : admitInitial(options.initial);
|
|
29
|
+
let state = Object.freeze(current === undefined
|
|
30
|
+
? { status: 'empty' }
|
|
31
|
+
: { status: 'valid', credential: current });
|
|
32
|
+
let inflight;
|
|
33
|
+
let controller;
|
|
34
|
+
let waiting = 0;
|
|
35
|
+
let anticipating = false;
|
|
36
|
+
let refreshTimer;
|
|
37
|
+
let expiryTimer;
|
|
38
|
+
let attempt = 0;
|
|
39
|
+
return Object.freeze({
|
|
40
|
+
ttlSeconds,
|
|
41
|
+
state: () => state,
|
|
42
|
+
acquire,
|
|
43
|
+
refresh,
|
|
44
|
+
start,
|
|
45
|
+
stop,
|
|
46
|
+
resolve,
|
|
47
|
+
});
|
|
48
|
+
async function resolve(_call, signal) {
|
|
49
|
+
return { credential: (await acquire(signal)).credential };
|
|
50
|
+
}
|
|
51
|
+
function acquire(signal) {
|
|
52
|
+
if (current !== undefined && covers(current))
|
|
53
|
+
return Promise.resolve(current);
|
|
54
|
+
return share(signal);
|
|
55
|
+
}
|
|
56
|
+
function refresh(signal) {
|
|
57
|
+
return share(signal);
|
|
58
|
+
}
|
|
59
|
+
function start() {
|
|
60
|
+
anticipating = true;
|
|
61
|
+
attempt = 0;
|
|
62
|
+
schedule();
|
|
63
|
+
}
|
|
64
|
+
function stop() {
|
|
65
|
+
anticipating = false;
|
|
66
|
+
clearTimers();
|
|
67
|
+
}
|
|
68
|
+
/** Join the mint in flight, or begin one, while following only this caller's cancellation. */
|
|
69
|
+
function share(signal) {
|
|
70
|
+
if (signal?.aborted === true)
|
|
71
|
+
return Promise.reject(signal.reason);
|
|
72
|
+
const pending = inflight ?? begin();
|
|
73
|
+
if (signal === undefined)
|
|
74
|
+
return pending;
|
|
75
|
+
waiting += 1;
|
|
76
|
+
let settled = false;
|
|
77
|
+
return new Promise((complete, fail) => {
|
|
78
|
+
const leave = () => {
|
|
79
|
+
if (settled)
|
|
80
|
+
return;
|
|
81
|
+
settled = true;
|
|
82
|
+
waiting -= 1;
|
|
83
|
+
signal.removeEventListener('abort', cancel);
|
|
84
|
+
// Nobody is waiting and nobody is anticipating: the mint has no beneficiary left.
|
|
85
|
+
if (waiting === 0 && !anticipating)
|
|
86
|
+
controller?.abort(signal.reason);
|
|
87
|
+
};
|
|
88
|
+
const cancel = () => {
|
|
89
|
+
const reason = signal.reason;
|
|
90
|
+
leave();
|
|
91
|
+
fail(reason);
|
|
92
|
+
};
|
|
93
|
+
signal.addEventListener('abort', cancel, { once: true });
|
|
94
|
+
pending.then((credential) => {
|
|
95
|
+
if (settled)
|
|
96
|
+
return;
|
|
97
|
+
settled = true;
|
|
98
|
+
waiting -= 1;
|
|
99
|
+
signal.removeEventListener('abort', cancel);
|
|
100
|
+
complete(credential);
|
|
101
|
+
}, (error) => {
|
|
102
|
+
if (settled)
|
|
103
|
+
return;
|
|
104
|
+
settled = true;
|
|
105
|
+
waiting -= 1;
|
|
106
|
+
signal.removeEventListener('abort', cancel);
|
|
107
|
+
fail(error);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function begin() {
|
|
112
|
+
publish({ status: 'refreshing', ...(current === undefined ? {} : { credential: current }) });
|
|
113
|
+
const owned = new AbortController();
|
|
114
|
+
controller = owned;
|
|
115
|
+
const signal = AbortSignal.any([owned.signal, AbortSignal.timeout(MINT_TIMEOUT_MS)]);
|
|
116
|
+
const pending = (async () => {
|
|
117
|
+
try {
|
|
118
|
+
const minted = admitMinted(await mint(signal));
|
|
119
|
+
current = minted;
|
|
120
|
+
attempt = 0;
|
|
121
|
+
publish({ status: 'valid', credential: minted });
|
|
122
|
+
if (anticipating)
|
|
123
|
+
schedule();
|
|
124
|
+
return minted;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
settleFailure(error);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
inflight = undefined;
|
|
132
|
+
controller = undefined;
|
|
133
|
+
}
|
|
134
|
+
})();
|
|
135
|
+
inflight = pending;
|
|
136
|
+
// A rejection reaches every waiter; keep an unattached one from surfacing as unhandled.
|
|
137
|
+
pending.catch(() => undefined);
|
|
138
|
+
return pending;
|
|
139
|
+
}
|
|
140
|
+
function settleFailure(error) {
|
|
141
|
+
if (current !== undefined && current.expiresAt > Date.now()) {
|
|
142
|
+
publish({ status: 'degraded', credential: current, error });
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
current = undefined;
|
|
146
|
+
publish({ status: 'expired', error });
|
|
147
|
+
}
|
|
148
|
+
if (anticipating)
|
|
149
|
+
retry();
|
|
150
|
+
}
|
|
151
|
+
/** Arm the threshold refresh and the expiry watchdog for the credential now held. */
|
|
152
|
+
function schedule() {
|
|
153
|
+
clearTimers();
|
|
154
|
+
if (!anticipating)
|
|
155
|
+
return;
|
|
156
|
+
if (current === undefined) {
|
|
157
|
+
void share().catch(() => undefined);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
// The threshold itself, with no extra lead: chained providers sharing this rule must not
|
|
161
|
+
// cascade into a mint loop, and the settlement skew already covers the round trip.
|
|
162
|
+
armRefresh(clamp(current.expiresAt - marginMs - Date.now()));
|
|
163
|
+
armExpiry(current);
|
|
164
|
+
}
|
|
165
|
+
function retry() {
|
|
166
|
+
if (refreshTimer !== undefined)
|
|
167
|
+
return;
|
|
168
|
+
const backoff = BACKOFF_MS[attempt];
|
|
169
|
+
attempt = Math.min(attempt + 1, BACKOFF_MS.length);
|
|
170
|
+
armRefresh(backoff ?? RETRY_INTERVAL_MS);
|
|
171
|
+
if (current !== undefined)
|
|
172
|
+
armExpiry(current);
|
|
173
|
+
}
|
|
174
|
+
function armRefresh(delay) {
|
|
175
|
+
refreshTimer = setTimeout(() => {
|
|
176
|
+
refreshTimer = undefined;
|
|
177
|
+
void share().catch(() => undefined);
|
|
178
|
+
}, delay);
|
|
179
|
+
}
|
|
180
|
+
function armExpiry(credential) {
|
|
181
|
+
if (expiryTimer !== undefined)
|
|
182
|
+
clearTimeout(expiryTimer);
|
|
183
|
+
expiryTimer = setTimeout(() => {
|
|
184
|
+
expiryTimer = undefined;
|
|
185
|
+
if (!anticipating || current !== credential)
|
|
186
|
+
return;
|
|
187
|
+
current = undefined;
|
|
188
|
+
publish({ status: 'expired', error: new ClientError('Session credential expired.') });
|
|
189
|
+
}, clamp(credential.expiresAt - Date.now()));
|
|
190
|
+
}
|
|
191
|
+
function clearTimers() {
|
|
192
|
+
if (refreshTimer !== undefined)
|
|
193
|
+
clearTimeout(refreshTimer);
|
|
194
|
+
if (expiryTimer !== undefined)
|
|
195
|
+
clearTimeout(expiryTimer);
|
|
196
|
+
refreshTimer = undefined;
|
|
197
|
+
expiryTimer = undefined;
|
|
198
|
+
}
|
|
199
|
+
function covers(credential) {
|
|
200
|
+
return credential.expiresAt - Date.now() > marginMs;
|
|
201
|
+
}
|
|
202
|
+
function publish(next) {
|
|
203
|
+
state = Object.freeze(next);
|
|
204
|
+
notify?.(state);
|
|
205
|
+
}
|
|
206
|
+
function admitMinted(input) {
|
|
207
|
+
const credential = admitShape(input);
|
|
208
|
+
if (credential === undefined)
|
|
209
|
+
throw new ClientError('Minted session credential is invalid.');
|
|
210
|
+
if (!covers(credential)) {
|
|
211
|
+
throw new ClientError('Minted session credential cannot cover the delegation TTL.');
|
|
212
|
+
}
|
|
213
|
+
return credential;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function admitInitial(input) {
|
|
217
|
+
const credential = admitShape(input);
|
|
218
|
+
if (credential === undefined || credential.expiresAt <= Date.now()) {
|
|
219
|
+
throw new TypeError('Initial session credential is invalid.');
|
|
220
|
+
}
|
|
221
|
+
return credential;
|
|
222
|
+
}
|
|
223
|
+
function admitShape(input) {
|
|
224
|
+
if (input === null ||
|
|
225
|
+
typeof input !== 'object' ||
|
|
226
|
+
typeof input.credential !== 'string' ||
|
|
227
|
+
input.credential.length === 0 ||
|
|
228
|
+
!Number.isSafeInteger(input.expiresAt)) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
return Object.freeze({ credential: input.credential, expiresAt: input.expiresAt });
|
|
232
|
+
}
|
|
233
|
+
/** Keep every scheduled delay inside the platform timer range. */
|
|
234
|
+
function clamp(delay) {
|
|
235
|
+
return Math.min(Math.max(delay, 0), 2_147_483_647);
|
|
236
|
+
}
|
|
@@ -2,17 +2,20 @@ import type { bundle } from '@astrale-os/kernel-dsl/v1';
|
|
|
2
2
|
import type { publication } from '@astrale-os/kernel-protocol';
|
|
3
3
|
import type { Fetch } from '../../transport/http/index.js';
|
|
4
4
|
import type { SessionOperation, SessionPolicy } from '../context/index.js';
|
|
5
|
+
import { ClientError } from '../../errors/index.js';
|
|
5
6
|
export interface BundleDiscoveryOptions {
|
|
6
7
|
readonly fetch: Fetch;
|
|
7
8
|
readonly policy: Readonly<SessionPolicy>;
|
|
8
9
|
readonly maximumBytes: number;
|
|
9
10
|
}
|
|
11
|
+
/** Internal evidence that a selected immutable artifact is no longer served. */
|
|
12
|
+
export declare class BundleUnavailableError extends ClientError {
|
|
13
|
+
}
|
|
10
14
|
export declare class BundleDiscovery {
|
|
11
15
|
private readonly options;
|
|
12
|
-
private
|
|
16
|
+
private retained?;
|
|
13
17
|
constructor(options: BundleDiscoveryOptions);
|
|
14
18
|
get(publication: publication.Publication, operation: SessionOperation): Promise<bundle.Bundle>;
|
|
15
19
|
clear(): void;
|
|
16
20
|
private fetch;
|
|
17
21
|
}
|
|
18
|
-
//# sourceMappingURL=bundle.d.ts.map
|
|
@@ -1,38 +1,49 @@
|
|
|
1
|
+
import { bundleUrl } from '@astrale-os/kernel-protocol/publication';
|
|
1
2
|
import { decodeBundleValue } from '@astrale-os/kernel-protocol/publication/bundle';
|
|
2
3
|
import { ClientError } from '../../errors/index.js';
|
|
3
|
-
import { allowEndpoint
|
|
4
|
+
import { allowEndpoint } from '../context/index.js';
|
|
4
5
|
import { boundedResponse, requireExactResponse } from './publication.js';
|
|
6
|
+
import { runAcquisition } from './transport.js';
|
|
7
|
+
/** Internal evidence that a selected immutable artifact is no longer served. */
|
|
8
|
+
export class BundleUnavailableError extends ClientError {
|
|
9
|
+
}
|
|
5
10
|
export class BundleDiscovery {
|
|
6
11
|
options;
|
|
7
|
-
|
|
12
|
+
retained;
|
|
8
13
|
constructor(options) {
|
|
9
14
|
this.options = options;
|
|
10
15
|
}
|
|
11
16
|
async get(publication, operation) {
|
|
12
17
|
const key = bundleKey(publication);
|
|
13
|
-
|
|
14
|
-
if (
|
|
15
|
-
return
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return retained;
|
|
18
|
+
allowEndpoint(publication.schema.bundle.href, this.options.policy);
|
|
19
|
+
if (this.retained?.key === key)
|
|
20
|
+
return this.retained.value;
|
|
21
|
+
const value = await this.fetch(publication, operation);
|
|
22
|
+
this.retained = { key, value };
|
|
23
|
+
return value;
|
|
20
24
|
}
|
|
21
25
|
clear() {
|
|
22
|
-
this.
|
|
26
|
+
this.retained = undefined;
|
|
23
27
|
}
|
|
24
28
|
async fetch(publication, operation) {
|
|
25
29
|
if (publication.schema.bundle.ref.size > this.options.maximumBytes) {
|
|
26
30
|
throw new ClientError('Bundle artifact exceeds its byte limit.');
|
|
27
31
|
}
|
|
28
32
|
const href = publication.schema.bundle.href;
|
|
29
|
-
|
|
30
|
-
const response = await
|
|
33
|
+
const immutable = href === bundleUrl(publication.identity.issuer, publication.schema.bundle.ref);
|
|
34
|
+
const response = await runAcquisition(operation, 'bundle', 'unknown', 'Kernel bundle could not be retrieved.', (signal) => this.options.fetch(href, {
|
|
31
35
|
headers: { accept: publication.schema.bundle.ref.mediaType },
|
|
36
|
+
// Omitting `cache` is the browser default; Workers reject the DOM-only 'default' mode.
|
|
37
|
+
cache: immutable ? undefined : 'no-cache',
|
|
32
38
|
redirect: 'manual',
|
|
33
39
|
signal,
|
|
34
40
|
}));
|
|
35
41
|
requireExactResponse(response, href, 'Bundle retrieval');
|
|
42
|
+
if (immutable && (response.status === 404 || response.status === 410)) {
|
|
43
|
+
// Cleanup must not hold discovery open on an injected body cancellation.
|
|
44
|
+
void response.body?.cancel().catch(() => undefined);
|
|
45
|
+
throw new BundleUnavailableError(`Bundle retrieval returned HTTP ${response.status}.`);
|
|
46
|
+
}
|
|
36
47
|
if (!response.ok)
|
|
37
48
|
throw new ClientError(`Bundle retrieval returned HTTP ${response.status}.`);
|
|
38
49
|
if (response.headers.get('content-type') !== publication.schema.bundle.ref.mediaType) {
|
|
@@ -42,7 +53,7 @@ export class BundleDiscovery {
|
|
|
42
53
|
if (etag !== null && etag !== `"${publication.schema.bundle.ref.digest}"`) {
|
|
43
54
|
throw new ClientError('Bundle response ETag differs from its descriptor.');
|
|
44
55
|
}
|
|
45
|
-
const bytes = await
|
|
56
|
+
const bytes = await runAcquisition(operation, 'bundle', 'receive', 'Kernel bundle response could not be read.', (signal) => boundedResponse(response, publication.schema.bundle.ref.size, signal));
|
|
46
57
|
if (bytes.byteLength !== publication.schema.bundle.ref.size) {
|
|
47
58
|
throw new ClientError('Bundle artifact size differs from its descriptor.');
|
|
48
59
|
}
|
|
@@ -50,6 +61,14 @@ export class BundleDiscovery {
|
|
|
50
61
|
}
|
|
51
62
|
}
|
|
52
63
|
function bundleKey(publication) {
|
|
53
|
-
|
|
64
|
+
const { href, ref } = publication.schema.bundle;
|
|
65
|
+
return JSON.stringify([
|
|
66
|
+
publication.identity.issuer,
|
|
67
|
+
new URL(href).origin,
|
|
68
|
+
publication.origin,
|
|
69
|
+
publication.schema.revision,
|
|
70
|
+
ref.digest,
|
|
71
|
+
ref.mediaType,
|
|
72
|
+
ref.size,
|
|
73
|
+
]);
|
|
54
74
|
}
|
|
55
|
-
//# sourceMappingURL=bundle.js.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
|
|
2
|
+
import type { publication } from '@astrale-os/kernel-protocol';
|
|
2
3
|
import type { SessionOperation, SessionPolicy } from '../context/index.js';
|
|
3
|
-
import type { BundleDiscovery } from './bundle.js';
|
|
4
4
|
import type { PublicationDiscovery } from './publication.js';
|
|
5
5
|
import type { SessionSnapshot } from './snapshot.js';
|
|
6
|
+
import { type BundleDiscovery } from './bundle.js';
|
|
6
7
|
export declare class SessionDiscovery {
|
|
7
8
|
readonly kernel: IssuerId;
|
|
8
9
|
private readonly policy;
|
|
@@ -12,9 +13,10 @@ export declare class SessionDiscovery {
|
|
|
12
13
|
private readonly acquisitionOperation;
|
|
13
14
|
private retained?;
|
|
14
15
|
private flight?;
|
|
16
|
+
private publicationFlight?;
|
|
15
17
|
constructor(kernel: IssuerId, policy: Readonly<SessionPolicy>, publications: PublicationDiscovery, bundles: BundleDiscovery, requireOpen: () => void, acquisitionOperation: () => SessionOperation);
|
|
18
|
+
publication(operation: SessionOperation): Promise<publication.Publication>;
|
|
16
19
|
snapshot(operation: SessionOperation): Promise<SessionSnapshot>;
|
|
17
20
|
clear(): void;
|
|
18
21
|
private acquireSnapshot;
|
|
19
22
|
}
|
|
20
|
-
//# sourceMappingURL=discovery.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { runSessionOperation } from '../context/index.js';
|
|
2
2
|
import { rootViewCatalog } from '../views/index.js';
|
|
3
|
+
import { BundleUnavailableError } from './bundle.js';
|
|
3
4
|
import { createSessionSnapshot } from './snapshot.js';
|
|
4
5
|
export class SessionDiscovery {
|
|
5
6
|
kernel;
|
|
@@ -10,6 +11,7 @@ export class SessionDiscovery {
|
|
|
10
11
|
acquisitionOperation;
|
|
11
12
|
retained;
|
|
12
13
|
flight;
|
|
14
|
+
publicationFlight;
|
|
13
15
|
constructor(kernel, policy, publications, bundles, requireOpen, acquisitionOperation) {
|
|
14
16
|
this.kernel = kernel;
|
|
15
17
|
this.policy = policy;
|
|
@@ -18,6 +20,24 @@ export class SessionDiscovery {
|
|
|
18
20
|
this.requireOpen = requireOpen;
|
|
19
21
|
this.acquisitionOperation = acquisitionOperation;
|
|
20
22
|
}
|
|
23
|
+
publication(operation) {
|
|
24
|
+
this.requireOpen();
|
|
25
|
+
const current = this.publicationFlight;
|
|
26
|
+
if (current !== undefined)
|
|
27
|
+
return runSessionOperation(operation, () => current);
|
|
28
|
+
const flight = this.publications.revalidate(this.acquisitionOperation()).then((value) => {
|
|
29
|
+
this.requireOpen();
|
|
30
|
+
return value;
|
|
31
|
+
});
|
|
32
|
+
this.publicationFlight = flight;
|
|
33
|
+
void flight
|
|
34
|
+
.finally(() => {
|
|
35
|
+
if (this.publicationFlight === flight)
|
|
36
|
+
this.publicationFlight = undefined;
|
|
37
|
+
})
|
|
38
|
+
.catch(() => undefined);
|
|
39
|
+
return runSessionOperation(operation, () => flight);
|
|
40
|
+
}
|
|
21
41
|
snapshot(operation) {
|
|
22
42
|
this.requireOpen();
|
|
23
43
|
const current = this.flight;
|
|
@@ -39,11 +59,20 @@ export class SessionDiscovery {
|
|
|
39
59
|
this.retained = undefined;
|
|
40
60
|
}
|
|
41
61
|
async acquireSnapshot(operation) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.bundles.
|
|
46
|
-
|
|
62
|
+
let publication = await this.publication(operation);
|
|
63
|
+
let artifact;
|
|
64
|
+
try {
|
|
65
|
+
artifact = await this.bundles.get(publication, operation);
|
|
66
|
+
}
|
|
67
|
+
catch (cause) {
|
|
68
|
+
if (!(cause instanceof BundleUnavailableError))
|
|
69
|
+
throw cause;
|
|
70
|
+
const current = await this.publication(operation);
|
|
71
|
+
if (current.etag === publication.etag)
|
|
72
|
+
throw cause;
|
|
73
|
+
publication = current;
|
|
74
|
+
artifact = await this.bundles.get(publication, operation);
|
|
75
|
+
}
|
|
47
76
|
this.requireOpen();
|
|
48
77
|
if (this.retained?.publication.etag === publication.etag)
|
|
49
78
|
return this.retained;
|
|
@@ -53,4 +82,3 @@ export class SessionDiscovery {
|
|
|
53
82
|
return snapshot;
|
|
54
83
|
}
|
|
55
84
|
}
|
|
56
|
-
//# sourceMappingURL=discovery.js.map
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
|
|
2
|
+
import type { publication } from '@astrale-os/kernel-protocol';
|
|
2
3
|
import type { Fetch } from '../../transport/http/index.js';
|
|
3
4
|
import type { SessionOperation, SessionPolicy } from '../context/index.js';
|
|
4
5
|
import type { SessionSnapshot } from './snapshot.js';
|
|
5
6
|
export type { SessionSnapshot } from './snapshot.js';
|
|
7
|
+
export { boundedResponse, requireExactResponse } from './publication.js';
|
|
6
8
|
export interface SessionDiscovery {
|
|
7
9
|
readonly kernel: IssuerId;
|
|
10
|
+
publication(operation: SessionOperation): Promise<publication.Publication>;
|
|
8
11
|
snapshot(operation: SessionOperation): Promise<SessionSnapshot>;
|
|
9
12
|
clear(): void;
|
|
10
13
|
}
|
|
@@ -18,4 +21,3 @@ export interface SessionDiscoveryOptions {
|
|
|
18
21
|
readonly acquisitionOperation: () => SessionOperation;
|
|
19
22
|
}
|
|
20
23
|
export declare function createSessionDiscovery(options: SessionDiscoveryOptions): SessionDiscovery;
|
|
21
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BundleDiscovery } from './bundle.js';
|
|
2
2
|
import { SessionDiscovery as SessionDiscoveryImplementation } from './discovery.js';
|
|
3
3
|
import { PublicationDiscovery } from './publication.js';
|
|
4
|
+
export { boundedResponse, requireExactResponse } from './publication.js';
|
|
4
5
|
export function createSessionDiscovery(options) {
|
|
5
6
|
return new SessionDiscoveryImplementation(options.kernel, options.policy, new PublicationDiscovery({
|
|
6
7
|
kernel: options.kernel,
|
|
@@ -13,4 +14,3 @@ export function createSessionDiscovery(options) {
|
|
|
13
14
|
maximumBytes: options.maximumBundleBytes,
|
|
14
15
|
}), options.requireOpen, options.acquisitionOperation);
|
|
15
16
|
}
|
|
16
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -21,4 +21,3 @@ export declare class PublicationDiscovery {
|
|
|
21
21
|
}
|
|
22
22
|
export declare function boundedResponse(response: Response, maximum: number, signal: AbortSignal): Promise<Uint8Array>;
|
|
23
23
|
export declare function requireExactResponse(response: Response, expected: string, label: string): void;
|
|
24
|
-
//# sourceMappingURL=publication.d.ts.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as codecs from '@astrale-os/kernel-protocol/codecs';
|
|
2
2
|
import * as publicationCodec from '@astrale-os/kernel-protocol/publication/publication';
|
|
3
3
|
import { ClientError } from '../../errors/index.js';
|
|
4
|
-
import { allowEndpoint
|
|
4
|
+
import { allowEndpoint } from '../context/index.js';
|
|
5
|
+
import { runAcquisition } from './transport.js';
|
|
5
6
|
export class PublicationDiscovery {
|
|
6
7
|
options;
|
|
7
8
|
publication;
|
|
@@ -29,7 +30,7 @@ export class PublicationDiscovery {
|
|
|
29
30
|
async fetch(operation, previous) {
|
|
30
31
|
const url = publicationCodec.url(this.options.kernel);
|
|
31
32
|
allowEndpoint(url, this.options.policy);
|
|
32
|
-
const response = await
|
|
33
|
+
const response = await runAcquisition(operation, 'publication', 'unknown', 'Kernel Publication could not be retrieved.', (signal) => this.options.fetch(url, {
|
|
33
34
|
headers: {
|
|
34
35
|
accept: 'application/json',
|
|
35
36
|
...(previous === undefined ? {} : { 'if-none-match': `"${previous.etag}"` }),
|
|
@@ -51,7 +52,7 @@ export class PublicationDiscovery {
|
|
|
51
52
|
if (!response.ok) {
|
|
52
53
|
throw new ClientError(`Publication discovery returned HTTP ${response.status}.`);
|
|
53
54
|
}
|
|
54
|
-
const body = await
|
|
55
|
+
const body = await runAcquisition(operation, 'publication', 'receive', 'Kernel Publication response could not be read.', (signal) => boundedResponse(response, this.options.maximumBytes, signal));
|
|
55
56
|
const admitted = publicationCodec.accept(codecs.json.decode(body));
|
|
56
57
|
if (admitted.identity.issuer !== this.options.kernel) {
|
|
57
58
|
throw new ClientError('Publication issuer differs from the requested Kernel issuer.');
|
|
@@ -120,4 +121,3 @@ function join(parts, length) {
|
|
|
120
121
|
}
|
|
121
122
|
return output;
|
|
122
123
|
}
|
|
123
|
-
//# sourceMappingURL=publication.js.map
|
|
@@ -10,4 +10,3 @@ export interface SessionSnapshot {
|
|
|
10
10
|
readonly views: ViewCatalog;
|
|
11
11
|
}
|
|
12
12
|
export declare function createSessionSnapshot(kernel: IssuerId, publication: publication.Publication, artifact: bundle.Bundle, views: ViewCatalog): SessionSnapshot;
|
|
13
|
-
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TransportPhase } from '../../errors/index.js';
|
|
2
|
+
import type { SessionOperation } from '../context/index.js';
|
|
3
|
+
type AcquisitionResource = 'publication' | 'bundle';
|
|
4
|
+
/** Normalize only unknown failures from one injected acquisition capability. */
|
|
5
|
+
export declare function runAcquisition<Result>(operation: SessionOperation, resource: AcquisitionResource, phase: Extract<TransportPhase, 'receive' | 'unknown'>, message: string, task: (signal: AbortSignal) => Result | PromiseLike<Result>): Promise<Result>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ClientError, TransportError } from '../../errors/index.js';
|
|
2
|
+
import { runSessionOperation } from '../context/index.js';
|
|
3
|
+
/** Normalize only unknown failures from one injected acquisition capability. */
|
|
4
|
+
export async function runAcquisition(operation, resource, phase, message, task) {
|
|
5
|
+
try {
|
|
6
|
+
return await runSessionOperation(operation, task);
|
|
7
|
+
}
|
|
8
|
+
catch (cause) {
|
|
9
|
+
if (cause instanceof ClientError)
|
|
10
|
+
throw cause;
|
|
11
|
+
throw TransportError.acquisition(message, { cause, phase, resource });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IssuerId } from '@astrale-os/kernel-core/auth/issuer';
|
|
2
|
+
import type { invocation } from '@astrale-os/kernel-protocol';
|
|
3
|
+
import { Path } from '@astrale-os/kernel-core/path';
|
|
4
|
+
import { Key } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
5
|
+
import type { SessionOperation } from '../context/index.js';
|
|
6
|
+
import type { EffectiveAuth } from '../routing/index.js';
|
|
7
|
+
import type { ExchangeDependencies } from './exchange.js';
|
|
8
|
+
/** Installed issuers of the Domains one Session reaches. */
|
|
9
|
+
export interface Installations {
|
|
10
|
+
issuerOf(origin: Key.Origin, source: EffectiveAuth, operation: SessionOperation): Promise<IssuerId | undefined>;
|
|
11
|
+
clear(): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The origin of the Domain whose declaration a Call executes, or undefined when the target names no
|
|
15
|
+
* Domain. An instance Method belongs to its qualified Class, never to its receiver's Domain.
|
|
16
|
+
*/
|
|
17
|
+
export declare function declaringOrigin(target: invocation.Call['target']): Key.Origin | undefined;
|
|
18
|
+
export declare function callableOrigin(path: Path): Key.Origin | undefined;
|
|
19
|
+
export declare function isKernelOrigin(origin: Key.Origin): boolean;
|
|
20
|
+
/** The installed remote issuer of one Domain, read as the source caller; undefined when local. */
|
|
21
|
+
export declare function installedIssuer(dependencies: Pick<ExchangeDependencies, 'kernel' | 'source' | 'limits'>, origin: Key.Origin, source: EffectiveAuth, operation: SessionOperation): Promise<IssuerId | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Remember each origin's installed issuer for the Session route age. The issuer is installation
|
|
24
|
+
* state, not authority, so one inspection serves every source credential; concurrent readers share
|
|
25
|
+
* it while each keeps its own cancellation and deadline.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createInstallations(dependencies: ExchangeDependencies): Installations;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { targetPath } from '@astrale-os/kernel-core/callable';
|
|
2
|
+
import { Path } from '@astrale-os/kernel-core/path';
|
|
3
|
+
import { identity } from '@astrale-os/kernel-core/schema/kernel/syscalls/references';
|
|
4
|
+
import { Key } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
5
|
+
import { createSchema } from '../../schema/index.js';
|
|
6
|
+
import { runSessionOperation } from '../context/index.js';
|
|
7
|
+
import { sourceCaller } from './source.js';
|
|
8
|
+
const KERNEL_ORIGIN = identity.whoami.owner.origin;
|
|
9
|
+
/**
|
|
10
|
+
* The origin of the Domain whose declaration a Call executes, or undefined when the target names no
|
|
11
|
+
* Domain. An instance Method belongs to its qualified Class, never to its receiver's Domain.
|
|
12
|
+
*/
|
|
13
|
+
export function declaringOrigin(target) {
|
|
14
|
+
return callableOrigin(Path.parse(targetPath(target)));
|
|
15
|
+
}
|
|
16
|
+
export function callableOrigin(path) {
|
|
17
|
+
const last = path.ast.steps.at(-1);
|
|
18
|
+
if (last?.kind === 'method' && last.dispatch === 'instance')
|
|
19
|
+
return Key.origin(last.class);
|
|
20
|
+
return path.ast.anchor.kind === 'domain' ? path.ast.anchor.origin : undefined;
|
|
21
|
+
}
|
|
22
|
+
export function isKernelOrigin(origin) {
|
|
23
|
+
return origin === KERNEL_ORIGIN;
|
|
24
|
+
}
|
|
25
|
+
/** The installed remote issuer of one Domain, read as the source caller; undefined when local. */
|
|
26
|
+
export async function installedIssuer(dependencies, origin, source, operation) {
|
|
27
|
+
const caller = sourceCaller(dependencies, source, operation);
|
|
28
|
+
const domain = await createSchema(caller.dispatch, dependencies.limits).inspect(origin);
|
|
29
|
+
const remote = domain.publication;
|
|
30
|
+
return remote === null || remote.identity.issuer === dependencies.kernel
|
|
31
|
+
? undefined
|
|
32
|
+
: remote.identity.issuer;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Remember each origin's installed issuer for the Session route age. The issuer is installation
|
|
36
|
+
* state, not authority, so one inspection serves every source credential; concurrent readers share
|
|
37
|
+
* it while each keeps its own cancellation and deadline.
|
|
38
|
+
*/
|
|
39
|
+
export function createInstallations(dependencies) {
|
|
40
|
+
/** An inspection in flight never expires; a settled one lives for the route age. */
|
|
41
|
+
const entries = new Map();
|
|
42
|
+
return Object.freeze({
|
|
43
|
+
issuerOf(origin, source, operation) {
|
|
44
|
+
const held = entries.get(origin);
|
|
45
|
+
const { issuer } = held === undefined || held.expiresAt <= Date.now() ? inspect(origin, source) : held;
|
|
46
|
+
return runSessionOperation(operation, () => issuer);
|
|
47
|
+
},
|
|
48
|
+
clear: () => entries.clear(),
|
|
49
|
+
});
|
|
50
|
+
function inspect(origin, source) {
|
|
51
|
+
const issuer = installedIssuer(dependencies, origin, source, dependencies.operation());
|
|
52
|
+
const entry = { issuer, expiresAt: Infinity };
|
|
53
|
+
entries.set(origin, entry);
|
|
54
|
+
// Both reactions are attached, so a rejection that reaches no waiter is never unhandled.
|
|
55
|
+
issuer.then(() => {
|
|
56
|
+
entry.expiresAt = Date.now() + dependencies.policy.maximumRouteAgeMs;
|
|
57
|
+
}, () => {
|
|
58
|
+
if (entries.get(origin) === entry)
|
|
59
|
+
entries.delete(origin);
|
|
60
|
+
});
|
|
61
|
+
return entry;
|
|
62
|
+
}
|
|
63
|
+
}
|