@elaraai/e3-rack 0.0.0-bootstrap.0 → 1.0.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +407 -2
- package/dist/src/client/client.spec.d.ts +6 -0
- package/dist/src/client/client.spec.d.ts.map +1 -0
- package/dist/src/client/client.spec.js +150 -0
- package/dist/src/client/client.spec.js.map +1 -0
- package/dist/src/client/connect.d.ts +52 -0
- package/dist/src/client/connect.d.ts.map +1 -0
- package/dist/src/client/connect.js +112 -0
- package/dist/src/client/connect.js.map +1 -0
- package/dist/src/client/hub-client.d.ts +57 -0
- package/dist/src/client/hub-client.d.ts.map +1 -0
- package/dist/src/client/hub-client.js +87 -0
- package/dist/src/client/hub-client.js.map +1 -0
- package/dist/src/client/local-http.d.ts +78 -0
- package/dist/src/client/local-http.d.ts.map +1 -0
- package/dist/src/client/local-http.js +149 -0
- package/dist/src/client/local-http.js.map +1 -0
- package/dist/src/client/session-attempts.d.ts +20 -0
- package/dist/src/client/session-attempts.d.ts.map +1 -0
- package/dist/src/client/session-attempts.js +88 -0
- package/dist/src/client/session-attempts.js.map +1 -0
- package/dist/src/client/session-data-server.d.ts +37 -0
- package/dist/src/client/session-data-server.d.ts.map +1 -0
- package/dist/src/client/session-data-server.js +280 -0
- package/dist/src/client/session-data-server.js.map +1 -0
- package/dist/src/client/session-data-server.spec.d.ts +6 -0
- package/dist/src/client/session-data-server.spec.d.ts.map +1 -0
- package/dist/src/client/session-data-server.spec.js +192 -0
- package/dist/src/client/session-data-server.spec.js.map +1 -0
- package/dist/src/client/session.d.ts +119 -0
- package/dist/src/client/session.d.ts.map +1 -0
- package/dist/src/client/session.js +290 -0
- package/dist/src/client/session.js.map +1 -0
- package/dist/src/hub/config.d.ts +74 -0
- package/dist/src/hub/config.d.ts.map +1 -0
- package/dist/src/hub/config.js +159 -0
- package/dist/src/hub/config.js.map +1 -0
- package/dist/src/hub/fair-lease-store.d.ts +36 -0
- package/dist/src/hub/fair-lease-store.d.ts.map +1 -0
- package/dist/src/hub/fair-lease-store.js +73 -0
- package/dist/src/hub/fair-lease-store.js.map +1 -0
- package/dist/src/hub/hub.d.ts +91 -0
- package/dist/src/hub/hub.d.ts.map +1 -0
- package/dist/src/hub/hub.js +641 -0
- package/dist/src/hub/hub.js.map +1 -0
- package/dist/src/hub/hub.spec.d.ts +6 -0
- package/dist/src/hub/hub.spec.d.ts.map +1 -0
- package/dist/src/hub/hub.spec.js +363 -0
- package/dist/src/hub/hub.spec.js.map +1 -0
- package/dist/src/hub/infrastructure.spec.d.ts +6 -0
- package/dist/src/hub/infrastructure.spec.d.ts.map +1 -0
- package/dist/src/hub/infrastructure.spec.js +211 -0
- package/dist/src/hub/infrastructure.spec.js.map +1 -0
- package/dist/src/hub/lock.d.ts +62 -0
- package/dist/src/hub/lock.d.ts.map +1 -0
- package/dist/src/hub/lock.js +165 -0
- package/dist/src/hub/lock.js.map +1 -0
- package/dist/src/hub/main.d.ts +16 -0
- package/dist/src/hub/main.d.ts.map +1 -0
- package/dist/src/hub/main.js +56 -0
- package/dist/src/hub/main.js.map +1 -0
- package/dist/src/hub/session-bridge.d.ts +116 -0
- package/dist/src/hub/session-bridge.d.ts.map +1 -0
- package/dist/src/hub/session-bridge.js +336 -0
- package/dist/src/hub/session-bridge.js.map +1 -0
- package/dist/src/identity/file-identity-store.d.ts +18 -0
- package/dist/src/identity/file-identity-store.d.ts.map +1 -0
- package/dist/src/identity/file-identity-store.js +34 -0
- package/dist/src/identity/file-identity-store.js.map +1 -0
- package/dist/src/identity/file-identity-store.spec.d.ts +6 -0
- package/dist/src/identity/file-identity-store.spec.d.ts.map +1 -0
- package/dist/src/identity/file-identity-store.spec.js +59 -0
- package/dist/src/identity/file-identity-store.spec.js.map +1 -0
- package/dist/src/identity/in-memory-identity-store.d.ts +48 -0
- package/dist/src/identity/in-memory-identity-store.d.ts.map +1 -0
- package/dist/src/identity/in-memory-identity-store.js +102 -0
- package/dist/src/identity/in-memory-identity-store.js.map +1 -0
- package/dist/src/identity/machine-identity.d.ts +134 -0
- package/dist/src/identity/machine-identity.d.ts.map +1 -0
- package/dist/src/identity/machine-identity.js +65 -0
- package/dist/src/identity/machine-identity.js.map +1 -0
- package/dist/src/index.d.ts +34 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +34 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lease/closure.d.ts +96 -0
- package/dist/src/lease/closure.d.ts.map +1 -0
- package/dist/src/lease/closure.js +192 -0
- package/dist/src/lease/closure.js.map +1 -0
- package/dist/src/lease/closure.spec.d.ts +6 -0
- package/dist/src/lease/closure.spec.d.ts.map +1 -0
- package/dist/src/lease/closure.spec.js +35 -0
- package/dist/src/lease/closure.spec.js.map +1 -0
- package/dist/src/lease/coordinator.d.ts +34 -0
- package/dist/src/lease/coordinator.d.ts.map +1 -0
- package/dist/src/lease/coordinator.js +42 -0
- package/dist/src/lease/coordinator.js.map +1 -0
- package/dist/src/lease/in-memory-lease-store.d.ts +58 -0
- package/dist/src/lease/in-memory-lease-store.d.ts.map +1 -0
- package/dist/src/lease/in-memory-lease-store.js +132 -0
- package/dist/src/lease/in-memory-lease-store.js.map +1 -0
- package/dist/src/lease/lease-store.d.ts +169 -0
- package/dist/src/lease/lease-store.d.ts.map +1 -0
- package/dist/src/lease/lease-store.js +94 -0
- package/dist/src/lease/lease-store.js.map +1 -0
- package/dist/src/lease/lease-store.spec.d.ts +6 -0
- package/dist/src/lease/lease-store.spec.d.ts.map +1 -0
- package/dist/src/lease/lease-store.spec.js +8 -0
- package/dist/src/lease/lease-store.spec.js.map +1 -0
- package/dist/src/lease/rack-dispatch.d.ts +105 -0
- package/dist/src/lease/rack-dispatch.d.ts.map +1 -0
- package/dist/src/lease/rack-dispatch.js +6 -0
- package/dist/src/lease/rack-dispatch.js.map +1 -0
- package/dist/src/mutation-queue.d.ts +13 -0
- package/dist/src/mutation-queue.d.ts.map +1 -0
- package/dist/src/mutation-queue.js +17 -0
- package/dist/src/mutation-queue.js.map +1 -0
- package/dist/src/paths.d.ts +56 -0
- package/dist/src/paths.d.ts.map +1 -0
- package/dist/src/paths.js +82 -0
- package/dist/src/paths.js.map +1 -0
- package/dist/src/protocol/control.d.ts +295 -0
- package/dist/src/protocol/control.d.ts.map +1 -0
- package/dist/src/protocol/control.js +74 -0
- package/dist/src/protocol/control.js.map +1 -0
- package/dist/src/protocol/index.d.ts +9 -0
- package/dist/src/protocol/index.d.ts.map +1 -0
- package/dist/src/protocol/index.js +9 -0
- package/dist/src/protocol/index.js.map +1 -0
- package/dist/src/protocol/rack-wire.d.ts +357 -0
- package/dist/src/protocol/rack-wire.d.ts.map +1 -0
- package/dist/src/protocol/rack-wire.js +262 -0
- package/dist/src/protocol/rack-wire.js.map +1 -0
- package/dist/src/protocol/rack-wire.spec.d.ts +6 -0
- package/dist/src/protocol/rack-wire.spec.d.ts.map +1 -0
- package/dist/src/protocol/rack-wire.spec.js +14 -0
- package/dist/src/protocol/rack-wire.spec.js.map +1 -0
- package/dist/src/protocol/registration.d.ts +70 -0
- package/dist/src/protocol/registration.d.ts.map +1 -0
- package/dist/src/protocol/registration.js +67 -0
- package/dist/src/protocol/registration.js.map +1 -0
- package/dist/src/protocol/session-data.d.ts +69 -0
- package/dist/src/protocol/session-data.d.ts.map +1 -0
- package/dist/src/protocol/session-data.js +26 -0
- package/dist/src/protocol/session-data.js.map +1 -0
- package/dist/src/protocol/task-envelope.d.ts +198 -0
- package/dist/src/protocol/task-envelope.d.ts.map +1 -0
- package/dist/src/protocol/task-envelope.js +93 -0
- package/dist/src/protocol/task-envelope.js.map +1 -0
- package/dist/src/protocol/wire-golden.d.ts +8 -0
- package/dist/src/protocol/wire-golden.d.ts.map +1 -0
- package/dist/src/protocol/wire-golden.js +34 -0
- package/dist/src/protocol/wire-golden.js.map +1 -0
- package/dist/src/protocol/wire-samples.d.ts +11 -0
- package/dist/src/protocol/wire-samples.d.ts.map +1 -0
- package/dist/src/protocol/wire-samples.js +52 -0
- package/dist/src/protocol/wire-samples.js.map +1 -0
- package/dist/src/registry/file-rack-registry.d.ts +68 -0
- package/dist/src/registry/file-rack-registry.d.ts.map +1 -0
- package/dist/src/registry/file-rack-registry.js +138 -0
- package/dist/src/registry/file-rack-registry.js.map +1 -0
- package/dist/src/registry/file-rack-registry.spec.d.ts +6 -0
- package/dist/src/registry/file-rack-registry.spec.d.ts.map +1 -0
- package/dist/src/registry/file-rack-registry.spec.js +50 -0
- package/dist/src/registry/file-rack-registry.spec.js.map +1 -0
- package/dist/src/registry/rack-registry.d.ts +64 -0
- package/dist/src/registry/rack-registry.d.ts.map +1 -0
- package/dist/src/registry/rack-registry.js +65 -0
- package/dist/src/registry/rack-registry.js.map +1 -0
- package/dist/src/registry/rack-registry.spec.d.ts +6 -0
- package/dist/src/registry/rack-registry.spec.d.ts.map +1 -0
- package/dist/src/registry/rack-registry.spec.js +8 -0
- package/dist/src/registry/rack-registry.spec.js.map +1 -0
- package/dist/src/routing/eligibility.d.ts +38 -0
- package/dist/src/routing/eligibility.d.ts.map +1 -0
- package/dist/src/routing/eligibility.js +78 -0
- package/dist/src/routing/eligibility.js.map +1 -0
- package/dist/src/routing/host-coupling.d.ts +26 -0
- package/dist/src/routing/host-coupling.d.ts.map +1 -0
- package/dist/src/routing/host-coupling.js +62 -0
- package/dist/src/routing/host-coupling.js.map +1 -0
- package/dist/src/routing/policy.d.ts +188 -0
- package/dist/src/routing/policy.d.ts.map +1 -0
- package/dist/src/routing/policy.js +212 -0
- package/dist/src/routing/policy.js.map +1 -0
- package/dist/src/routing/routing.spec.d.ts +6 -0
- package/dist/src/routing/routing.spec.d.ts.map +1 -0
- package/dist/src/routing/routing.spec.js +100 -0
- package/dist/src/routing/routing.spec.js.map +1 -0
- package/dist/src/routing/tiers.d.ts +22 -0
- package/dist/src/routing/tiers.d.ts.map +1 -0
- package/dist/src/routing/tiers.js +26 -0
- package/dist/src/routing/tiers.js.map +1 -0
- package/dist/src/runner/api-server.d.ts +45 -0
- package/dist/src/runner/api-server.d.ts.map +1 -0
- package/dist/src/runner/api-server.js +21 -0
- package/dist/src/runner/api-server.js.map +1 -0
- package/dist/src/runner/capacity.d.ts +13 -0
- package/dist/src/runner/capacity.d.ts.map +1 -0
- package/dist/src/runner/capacity.js +18 -0
- package/dist/src/runner/capacity.js.map +1 -0
- package/dist/src/runner/rack-body.d.ts +43 -0
- package/dist/src/runner/rack-body.d.ts.map +1 -0
- package/dist/src/runner/rack-body.js +208 -0
- package/dist/src/runner/rack-body.js.map +1 -0
- package/dist/src/runner/rack-runner.d.ts +62 -0
- package/dist/src/runner/rack-runner.d.ts.map +1 -0
- package/dist/src/runner/rack-runner.js +75 -0
- package/dist/src/runner/rack-runner.js.map +1 -0
- package/dist/src/runner/rack-runner.spec.d.ts +6 -0
- package/dist/src/runner/rack-runner.spec.d.ts.map +1 -0
- package/dist/src/runner/rack-runner.spec.js +302 -0
- package/dist/src/runner/rack-runner.spec.js.map +1 -0
- package/dist/src/runner/split.spec.d.ts +6 -0
- package/dist/src/runner/split.spec.d.ts.map +1 -0
- package/dist/src/runner/split.spec.js +188 -0
- package/dist/src/runner/split.spec.js.map +1 -0
- package/dist/src/runner-event.d.ts +261 -0
- package/dist/src/runner-event.d.ts.map +1 -0
- package/dist/src/runner-event.js +332 -0
- package/dist/src/runner-event.js.map +1 -0
- package/dist/src/server/beast2.d.ts +19 -0
- package/dist/src/server/beast2.d.ts.map +1 -0
- package/dist/src/server/beast2.js +18 -0
- package/dist/src/server/beast2.js.map +1 -0
- package/dist/src/server/body-limit.d.ts +16 -0
- package/dist/src/server/body-limit.d.ts.map +1 -0
- package/dist/src/server/body-limit.js +53 -0
- package/dist/src/server/body-limit.js.map +1 -0
- package/dist/src/server/body-limit.spec.d.ts +2 -0
- package/dist/src/server/body-limit.spec.d.ts.map +1 -0
- package/dist/src/server/body-limit.spec.js +32 -0
- package/dist/src/server/body-limit.spec.js.map +1 -0
- package/dist/src/server/bounded.d.ts +16 -0
- package/dist/src/server/bounded.d.ts.map +1 -0
- package/dist/src/server/bounded.js +39 -0
- package/dist/src/server/bounded.js.map +1 -0
- package/dist/src/server/dispatch.d.ts +137 -0
- package/dist/src/server/dispatch.d.ts.map +1 -0
- package/dist/src/server/dispatch.js +267 -0
- package/dist/src/server/dispatch.js.map +1 -0
- package/dist/src/server/env-publication.d.ts +45 -0
- package/dist/src/server/env-publication.d.ts.map +1 -0
- package/dist/src/server/env-publication.js +10 -0
- package/dist/src/server/env-publication.js.map +1 -0
- package/dist/src/server/index.d.ts +16 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +17 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/protocol.spec.d.ts +6 -0
- package/dist/src/server/protocol.spec.d.ts.map +1 -0
- package/dist/src/server/protocol.spec.js +78 -0
- package/dist/src/server/protocol.spec.js.map +1 -0
- package/dist/src/server/rack-routes.d.ts +175 -0
- package/dist/src/server/rack-routes.d.ts.map +1 -0
- package/dist/src/server/rack-routes.js +755 -0
- package/dist/src/server/rack-routes.js.map +1 -0
- package/dist/src/server/rack-routes.spec.d.ts +6 -0
- package/dist/src/server/rack-routes.spec.d.ts.map +1 -0
- package/dist/src/server/rack-routes.spec.js +477 -0
- package/dist/src/server/rack-routes.spec.js.map +1 -0
- package/dist/src/server/storage-bridge.d.ts +140 -0
- package/dist/src/server/storage-bridge.d.ts.map +1 -0
- package/dist/src/server/storage-bridge.js +6 -0
- package/dist/src/server/storage-bridge.js.map +1 -0
- package/dist/src/state-file.d.ts +10 -0
- package/dist/src/state-file.d.ts.map +1 -0
- package/dist/src/state-file.js +38 -0
- package/dist/src/state-file.js.map +1 -0
- package/dist/src/testing/in-memory.d.ts +116 -0
- package/dist/src/testing/in-memory.d.ts.map +1 -0
- package/dist/src/testing/in-memory.js +193 -0
- package/dist/src/testing/in-memory.js.map +1 -0
- package/dist/src/testing/index.d.ts +14 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +14 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/testing/lease-store-contract.d.ts +14 -0
- package/dist/src/testing/lease-store-contract.d.ts.map +1 -0
- package/dist/src/testing/lease-store-contract.js +78 -0
- package/dist/src/testing/lease-store-contract.js.map +1 -0
- package/dist/src/testing/protocol-suite.d.ts +38 -0
- package/dist/src/testing/protocol-suite.d.ts.map +1 -0
- package/dist/src/testing/protocol-suite.js +207 -0
- package/dist/src/testing/protocol-suite.js.map +1 -0
- package/dist/src/testing/rack-registry-contract.d.ts +15 -0
- package/dist/src/testing/rack-registry-contract.d.ts.map +1 -0
- package/dist/src/testing/rack-registry-contract.js +106 -0
- package/dist/src/testing/rack-registry-contract.js.map +1 -0
- package/dist/src/testing/test-rack-agent.d.ts +121 -0
- package/dist/src/testing/test-rack-agent.d.ts.map +1 -0
- package/dist/src/testing/test-rack-agent.js +316 -0
- package/dist/src/testing/test-rack-agent.js.map +1 -0
- package/dist/src/tls/tls.d.ts +67 -0
- package/dist/src/tls/tls.d.ts.map +1 -0
- package/dist/src/tls/tls.js +200 -0
- package/dist/src/tls/tls.js.map +1 -0
- package/dist/src/tls/tls.spec.d.ts +6 -0
- package/dist/src/tls/tls.spec.d.ts.map +1 -0
- package/dist/src/tls/tls.spec.js +101 -0
- package/dist/src/tls/tls.spec.js.map +1 -0
- package/dist/src/version.d.ts +9 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +10 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +67 -7
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { encodeBeast2For, some, variant } from '@elaraai/east';
|
|
6
|
+
import * as wire from './rack-wire.js';
|
|
7
|
+
import * as registration from './registration.js';
|
|
8
|
+
const at = new Date(1_700_000_000_000);
|
|
9
|
+
const host = { label: 'rack', tiers: ['node', 'py'], capacity: 2n, agentVersion: '0.5.0+e3.1.0.85' };
|
|
10
|
+
const ref = { repo: 'repo', leaseId: 'lease' };
|
|
11
|
+
const size = { hash: 'a'.repeat(64), size: 4n };
|
|
12
|
+
const layer = { digest: 'sha256:abc', url: 'https://rack.invalid/layer', sizeBytes: 5n };
|
|
13
|
+
const target = variant('put', { url: 'https://rack.invalid/put', headers: new Map([['x-checksum', 'abc']]) });
|
|
14
|
+
/** A fully populated protocol value, with its encoder and name. @internal */
|
|
15
|
+
function sample(name, type, value) {
|
|
16
|
+
return { name, value, encode: () => encodeBeast2For(type)(value) };
|
|
17
|
+
}
|
|
18
|
+
/** Fixed samples used by this package and cloud adoption checks. @internal */
|
|
19
|
+
export const wireSamples = [
|
|
20
|
+
sample('RackHostInfoType', wire.RackHostInfoType, host),
|
|
21
|
+
sample('RackEnrollRequestType', wire.RackEnrollRequestType, { enrollmentToken: 'enroll', hostInfo: host }),
|
|
22
|
+
sample('RackEnrollResponseType', wire.RackEnrollResponseType, { rackId: 'rack', rackToken: 'token' }),
|
|
23
|
+
sample('RackLeaseRefType', wire.RackLeaseRefType, ref),
|
|
24
|
+
sample('RackLeaseRequestType', wire.RackLeaseRequestType, { tiers: ['node'], bootId: 'boot' }),
|
|
25
|
+
sample('RackLeaseGrantType', wire.RackLeaseGrantType, { ...ref, workspace: 'dev', tier: 'node', computeSize: 'large', eventJson: '{}', visibilityDeadline: at }),
|
|
26
|
+
sample('RackHeartbeatRequestType', wire.RackHeartbeatRequestType, { healthy: true, freeCapacity: 1n, runningLeases: [ref], agentVersion: host.agentVersion, bootId: 'boot', cacheBytes: 123n }),
|
|
27
|
+
sample('RackHeartbeatResponseType', wire.RackHeartbeatResponseType, { stop: [ref], rotatedToken: some('token'), pendingApproval: true }),
|
|
28
|
+
sample('RackExtendRequestType', wire.RackExtendRequestType, ref),
|
|
29
|
+
sample('RackWatchRequestType', wire.RackWatchRequestType, { runningLeases: [ref] }),
|
|
30
|
+
sample('RackWatchResponseType', wire.RackWatchResponseType, { stop: [ref] }),
|
|
31
|
+
sample('RackCompleteRequestType', wire.RackCompleteRequestType, { ...ref, resultJson: '{}', outputUploadId: some('upload'), inlineOutput: some(new Uint8Array([1, 2])) }),
|
|
32
|
+
sample('RackObjectSizeType', wire.RackObjectSizeType, size),
|
|
33
|
+
sample('RackObjectCommitType', wire.RackObjectCommitType, { ...size, version: 'receipt' }),
|
|
34
|
+
sample('RackStorageRequestType', wire.RackStorageRequestType, { ...ref, need: [size.hash], output: some(size), envManifest: some('env'), outputs: [size], commits: [{ ...size, version: 'receipt' }] }),
|
|
35
|
+
sample('RackObjectDescriptorType', wire.RackObjectDescriptorType, variant('inline', { hash: size.hash, data: new Uint8Array([1, 2]) })),
|
|
36
|
+
sample('RackEnvLayerType', wire.RackEnvLayerType, layer),
|
|
37
|
+
sample('RackWriteTargetType', wire.RackWriteTargetType, target),
|
|
38
|
+
sample('RackStorageResponseType', wire.RackStorageResponseType, {
|
|
39
|
+
objects: [variant('url', { hash: size.hash, url: 'https://rack.invalid/get' })],
|
|
40
|
+
output: some({ url: 'https://rack.invalid/put', uploadId: 'upload' }),
|
|
41
|
+
env: some({ manifestJson: '{}', layers: [layer] }),
|
|
42
|
+
targets: [{ hash: size.hash, target }, { hash: 'b'.repeat(64), target: variant('held', null) }],
|
|
43
|
+
committed: [{ hash: size.hash, committed: true }],
|
|
44
|
+
}),
|
|
45
|
+
sample('RackLogChunkType', wire.RackLogChunkType, { stream: variant('stdout', null), data: 'hello\n' }),
|
|
46
|
+
sample('RackLogsRequestType', wire.RackLogsRequestType, { ...ref, chunks: [{ stream: variant('stderr', null), data: 'error\n' }] }),
|
|
47
|
+
sample('RackCompleteResponseType', wire.RackCompleteResponseType, { disposition: variant('recorded', null) }),
|
|
48
|
+
sample('RackSecurityPolicyType', registration.RackSecurityPolicyType, { requireStartApproval: true }),
|
|
49
|
+
sample('RackRegistrationType', registration.RackRegistrationType, { rackId: 'rack', ...host, enrolledAt: at, lastSeenAt: at, healthy: true, lastBootId: some('boot'), approvedBootId: some('boot') }),
|
|
50
|
+
sample('RackActivityEntryType', registration.RackActivityEntryType, { repo: 'repo', workspace: 'dev', taskName: 'test', tier: 'node', status: 'completed', outcome: some('success'), error: some('message'), claimedAt: at, completedAt: some(at) }),
|
|
51
|
+
];
|
|
52
|
+
//# sourceMappingURL=wire-samples.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-samples.js","sourceRoot":"","sources":["../../../src/protocol/wire-samples.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { DictType, OptionType, StringType, StructType } from '@elaraai/east';
|
|
6
|
+
import { type RackRegistration, type RackSecurityPolicy } from '../protocol/registration.js';
|
|
7
|
+
import { type RackRegistry } from './rack-registry.js';
|
|
8
|
+
/** Stores the fleet and its security policy as one atomic value. */
|
|
9
|
+
export declare const RacksFileType: StructType<{
|
|
10
|
+
readonly racks: DictType<StringType, StructType<{
|
|
11
|
+
readonly rackId: StringType;
|
|
12
|
+
readonly label: StringType;
|
|
13
|
+
readonly enrolledAt: import("@elaraai/east").DateTimeType;
|
|
14
|
+
readonly tiers: import("@elaraai/east").ArrayType<StringType>;
|
|
15
|
+
readonly capacity: import("@elaraai/east").IntegerType;
|
|
16
|
+
readonly lastSeenAt: import("@elaraai/east").DateTimeType;
|
|
17
|
+
readonly agentVersion: StringType;
|
|
18
|
+
readonly healthy: import("@elaraai/east").BooleanType;
|
|
19
|
+
readonly lastBootId: OptionType<StringType>;
|
|
20
|
+
readonly approvedBootId: OptionType<StringType>;
|
|
21
|
+
}>>;
|
|
22
|
+
readonly security: OptionType<StructType<{
|
|
23
|
+
readonly requireStartApproval: import("@elaraai/east").BooleanType;
|
|
24
|
+
}>>;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Persists the registry, coalescing heartbeat-only changes for 30 seconds.
|
|
28
|
+
* Enrollment, revocation and security changes are durable before resolving.
|
|
29
|
+
* The hub is the sole writer and calls `flush` before releasing its lock.
|
|
30
|
+
* @example
|
|
31
|
+
* const registry = new FileRackRegistry(rackHome());
|
|
32
|
+
* await registry.putRack(registration);
|
|
33
|
+
* await registry.flush();
|
|
34
|
+
*/
|
|
35
|
+
export declare class FileRackRegistry implements RackRegistry {
|
|
36
|
+
private readonly now;
|
|
37
|
+
private readonly file;
|
|
38
|
+
private readonly queue;
|
|
39
|
+
private readonly ready;
|
|
40
|
+
private state;
|
|
41
|
+
private lastWrite;
|
|
42
|
+
private dirty;
|
|
43
|
+
private timer?;
|
|
44
|
+
private failure;
|
|
45
|
+
/**
|
|
46
|
+
* @param home - The private rack home owned by this hub
|
|
47
|
+
* @param now - Clock for coalescing (default: Date.now)
|
|
48
|
+
*/
|
|
49
|
+
constructor(home: string, now?: () => number);
|
|
50
|
+
private read;
|
|
51
|
+
listRacks(): Promise<RackRegistration[]>;
|
|
52
|
+
getRack(id: string): Promise<RackRegistration | null>;
|
|
53
|
+
putRack(registration: RackRegistration): Promise<void>;
|
|
54
|
+
/** {@inheritDoc RackRegistry.compareAndSetRack} */
|
|
55
|
+
compareAndSetRack(expected: RackRegistration, registration: RackRegistration): Promise<boolean>;
|
|
56
|
+
/** Applies a replacement under the mutation queue, preserving heartbeat coalescing. */
|
|
57
|
+
private replace;
|
|
58
|
+
deleteRack(id: string): Promise<boolean>;
|
|
59
|
+
getRackSecurityPolicy(): Promise<RackSecurityPolicy | null>;
|
|
60
|
+
putRackSecurityPolicy(policy: RackSecurityPolicy): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Flushes coalesced heartbeats and cancels their timer.
|
|
63
|
+
* @returns Once all preceding mutations are durable
|
|
64
|
+
*/
|
|
65
|
+
flush(): Promise<void>;
|
|
66
|
+
private write;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=file-rack-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-rack-registry.d.ts","sourceRoot":"","sources":["../../../src/registry/file-rack-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAA4E,MAAM,eAAe,CAAC;AACvJ,OAAO,EAAgD,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAG3I,OAAO,EAAkC,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvF,oEAAoE;AACpE,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;EAAkH,CAAC;AAM7I;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IAczB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAb9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAC,CAAgC;IAC9C,OAAO,CAAC,OAAO,CAAU;IAEzB;;;OAGG;gBACS,IAAI,EAAE,MAAM,EAAmB,GAAG,GAAE,MAAM,MAAiB;YAMzD,IAAI;IAEZ,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAM3D,OAAO,CAAC,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD,mDAAmD;IAC7C,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAarG,uFAAuF;YACzE,OAAO;IAiBrB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlC,qBAAqB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAKjE,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhE;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASR,KAAK;CASpB"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { DictType, OptionType, StringType, StructType, decodeBeast2For, encodeBeast2For, equalFor, none, some } from '@elaraai/east';
|
|
7
|
+
import { RackRegistrationType, RackSecurityPolicyType } from '../protocol/registration.js';
|
|
8
|
+
import { ensureRackHome, RACKS_FILE } from '../paths.js';
|
|
9
|
+
import { MutationQueue, readStateFile, writeStateFile } from '../state-file.js';
|
|
10
|
+
import { copyRegistration, copySecurity } from './rack-registry.js';
|
|
11
|
+
/** Stores the fleet and its security policy as one atomic value. */
|
|
12
|
+
export const RacksFileType = StructType({ racks: DictType(StringType, RackRegistrationType), security: OptionType(RackSecurityPolicyType) });
|
|
13
|
+
const encode = encodeBeast2For(RacksFileType);
|
|
14
|
+
const decode = decodeBeast2For(RacksFileType);
|
|
15
|
+
const equal = equalFor(RackRegistrationType);
|
|
16
|
+
/**
|
|
17
|
+
* Persists the registry, coalescing heartbeat-only changes for 30 seconds.
|
|
18
|
+
* Enrollment, revocation and security changes are durable before resolving.
|
|
19
|
+
* The hub is the sole writer and calls `flush` before releasing its lock.
|
|
20
|
+
* @example
|
|
21
|
+
* const registry = new FileRackRegistry(rackHome());
|
|
22
|
+
* await registry.putRack(registration);
|
|
23
|
+
* await registry.flush();
|
|
24
|
+
*/
|
|
25
|
+
export class FileRackRegistry {
|
|
26
|
+
now;
|
|
27
|
+
file;
|
|
28
|
+
queue = new MutationQueue();
|
|
29
|
+
ready;
|
|
30
|
+
state = { racks: new Map(), security: none };
|
|
31
|
+
lastWrite = -Infinity;
|
|
32
|
+
dirty = false;
|
|
33
|
+
timer;
|
|
34
|
+
failure;
|
|
35
|
+
/**
|
|
36
|
+
* @param home - The private rack home owned by this hub
|
|
37
|
+
* @param now - Clock for coalescing (default: Date.now)
|
|
38
|
+
*/
|
|
39
|
+
constructor(home, now = Date.now) {
|
|
40
|
+
this.now = now;
|
|
41
|
+
this.file = join(ensureRackHome(home), RACKS_FILE);
|
|
42
|
+
this.ready = readStateFile(this.file).then((bytes) => { if (bytes !== null)
|
|
43
|
+
this.state = decode(bytes); });
|
|
44
|
+
void this.ready.catch(() => undefined);
|
|
45
|
+
}
|
|
46
|
+
async read() { await this.ready; await this.queue.idle(); }
|
|
47
|
+
async listRacks() { await this.read(); return [...this.state.racks.values()].map(copyRegistration); }
|
|
48
|
+
async getRack(id) {
|
|
49
|
+
await this.read();
|
|
50
|
+
const rack = this.state.racks.get(id);
|
|
51
|
+
return rack === undefined ? null : copyRegistration(rack);
|
|
52
|
+
}
|
|
53
|
+
putRack(registration) {
|
|
54
|
+
const rack = copyRegistration(registration);
|
|
55
|
+
return this.queue.run(async () => {
|
|
56
|
+
await this.ready;
|
|
57
|
+
await this.replace(rack);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** {@inheritDoc RackRegistry.compareAndSetRack} */
|
|
61
|
+
async compareAndSetRack(expected, registration) {
|
|
62
|
+
if (expected.rackId !== registration.rackId)
|
|
63
|
+
throw new Error('Rack identity cannot change');
|
|
64
|
+
const before = copyRegistration(expected);
|
|
65
|
+
const rack = copyRegistration(registration);
|
|
66
|
+
return this.queue.run(async () => {
|
|
67
|
+
await this.ready;
|
|
68
|
+
const current = this.state.racks.get(before.rackId);
|
|
69
|
+
if (current === undefined || !equal(current, before))
|
|
70
|
+
return false;
|
|
71
|
+
await this.replace(rack);
|
|
72
|
+
return true;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/** Applies a replacement under the mutation queue, preserving heartbeat coalescing. */
|
|
76
|
+
async replace(rack) {
|
|
77
|
+
const old = this.state.racks.get(rack.rackId);
|
|
78
|
+
const heartbeatOnly = old !== undefined && equal(old, { ...rack, lastSeenAt: old.lastSeenAt, healthy: old.healthy, agentVersion: old.agentVersion });
|
|
79
|
+
const next = decode(encode(this.state));
|
|
80
|
+
next.racks.set(rack.rackId, rack);
|
|
81
|
+
if (!heartbeatOnly || this.now() - this.lastWrite >= 30_000)
|
|
82
|
+
await this.write(next);
|
|
83
|
+
else {
|
|
84
|
+
this.state = next;
|
|
85
|
+
this.dirty = true;
|
|
86
|
+
this.timer ??= setTimeout(() => {
|
|
87
|
+
this.timer = undefined;
|
|
88
|
+
void this.flush().catch((err) => { this.failure = err; });
|
|
89
|
+
}, Math.max(1, 30_000 - (this.now() - this.lastWrite)));
|
|
90
|
+
this.timer.unref();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
deleteRack(id) {
|
|
94
|
+
return this.queue.run(async () => {
|
|
95
|
+
await this.ready;
|
|
96
|
+
const next = decode(encode(this.state));
|
|
97
|
+
const existed = next.racks.delete(id);
|
|
98
|
+
await this.write(next);
|
|
99
|
+
return existed;
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async getRackSecurityPolicy() {
|
|
103
|
+
await this.read();
|
|
104
|
+
return this.state.security.type === 'some' ? copySecurity(this.state.security.value) : null;
|
|
105
|
+
}
|
|
106
|
+
putRackSecurityPolicy(policy) {
|
|
107
|
+
const security = some(copySecurity(policy));
|
|
108
|
+
return this.queue.run(async () => {
|
|
109
|
+
await this.ready;
|
|
110
|
+
await this.write({ ...this.state, security });
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Flushes coalesced heartbeats and cancels their timer.
|
|
115
|
+
* @returns Once all preceding mutations are durable
|
|
116
|
+
*/
|
|
117
|
+
flush() {
|
|
118
|
+
return this.queue.run(async () => {
|
|
119
|
+
await this.ready;
|
|
120
|
+
if (this.timer !== undefined)
|
|
121
|
+
clearTimeout(this.timer);
|
|
122
|
+
this.timer = undefined;
|
|
123
|
+
if (this.dirty || this.failure !== undefined)
|
|
124
|
+
await this.write(this.state);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async write(next) {
|
|
128
|
+
await writeStateFile(this.file, encode(next));
|
|
129
|
+
this.state = next;
|
|
130
|
+
this.lastWrite = this.now();
|
|
131
|
+
this.dirty = false;
|
|
132
|
+
this.failure = undefined;
|
|
133
|
+
if (this.timer !== undefined)
|
|
134
|
+
clearTimeout(this.timer);
|
|
135
|
+
this.timer = undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=file-rack-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-rack-registry.js","sourceRoot":"","sources":["../../../src/registry/file-rack-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-rack-registry.spec.d.ts","sourceRoot":"","sources":["../../../src/registry/file-rack-registry.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { it } from 'node:test';
|
|
6
|
+
import assert from 'node:assert/strict';
|
|
7
|
+
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
8
|
+
import { tmpdir } from 'node:os';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { equalFor, none, some } from '@elaraai/east';
|
|
11
|
+
import { RackRegistrationType } from '../protocol/registration.js';
|
|
12
|
+
import { FileRackRegistry } from './file-rack-registry.js';
|
|
13
|
+
import { rackRegistryContract } from '../testing/rack-registry-contract.js';
|
|
14
|
+
rackRegistryContract('file', async (t) => {
|
|
15
|
+
const home = await mkdtemp(join(tmpdir(), 'e3r-registry-'));
|
|
16
|
+
const registry = new FileRackRegistry(home);
|
|
17
|
+
t.after(async () => { await registry.flush(); await rm(home, { recursive: true, force: true }); });
|
|
18
|
+
return registry;
|
|
19
|
+
});
|
|
20
|
+
it('persists enrollment and revocation immediately and coalesces only heartbeat fields', async (t) => {
|
|
21
|
+
const home = await mkdtemp(join(tmpdir(), 'e3r-'));
|
|
22
|
+
let now = Date.now();
|
|
23
|
+
const registry = new FileRackRegistry(home, () => now);
|
|
24
|
+
t.after(async () => { await registry.flush(); await rm(home, { recursive: true, force: true }); });
|
|
25
|
+
const rack = {
|
|
26
|
+
rackId: 'rack', label: 'local', enrolledAt: new Date(now), tiers: ['node'], capacity: 2n,
|
|
27
|
+
lastSeenAt: new Date(now), agentVersion: '0.5.0', healthy: true, lastBootId: none, approvedBootId: none,
|
|
28
|
+
};
|
|
29
|
+
await registry.putRack(rack);
|
|
30
|
+
assert.ok(equalFor(RackRegistrationType)((await new FileRackRegistry(home).getRack('rack')), rack));
|
|
31
|
+
const file = join(home, 'racks.beast2');
|
|
32
|
+
const before = await readFile(file);
|
|
33
|
+
for (let i = 0; i < 8; i++) {
|
|
34
|
+
now += 1000;
|
|
35
|
+
const before = (await registry.getRack('rack'));
|
|
36
|
+
assert.equal(await registry.compareAndSetRack(before, { ...before, lastSeenAt: new Date(now), agentVersion: '0.5.1', healthy: false }), true);
|
|
37
|
+
}
|
|
38
|
+
assert.deepEqual(await readFile(file), before);
|
|
39
|
+
assert.equal((await registry.getRack('rack'))?.healthy, false);
|
|
40
|
+
now += 30_000;
|
|
41
|
+
await registry.putRack({ ...rack, lastSeenAt: new Date(now) });
|
|
42
|
+
assert.notDeepEqual(await readFile(file), before);
|
|
43
|
+
await registry.putRack({ ...rack, approvedBootId: some('boot'), lastBootId: some('boot') });
|
|
44
|
+
assert.deepEqual((await new FileRackRegistry(home).getRack('rack'))?.approvedBootId, some('boot'));
|
|
45
|
+
await registry.putRackSecurityPolicy({ requireStartApproval: true });
|
|
46
|
+
assert.deepEqual(await new FileRackRegistry(home).getRackSecurityPolicy(), { requireStartApproval: true });
|
|
47
|
+
assert.equal(await registry.deleteRack('rack'), true);
|
|
48
|
+
assert.equal(await new FileRackRegistry(home).getRack('rack'), null);
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=file-rack-registry.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-rack-registry.spec.js","sourceRoot":"","sources":["../../../src/registry/file-rack-registry.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { type RackRegistration, type RackSecurityPolicy } from '../protocol/registration.js';
|
|
6
|
+
/** The rack subset of the cloud's DeploymentSettingsStore, structurally compatible. */
|
|
7
|
+
export interface RackRegistry {
|
|
8
|
+
/** Lists enrolled racks. */
|
|
9
|
+
listRacks(): Promise<RackRegistration[]>;
|
|
10
|
+
/** Reads a registration, or null if deregistered. */
|
|
11
|
+
getRack(rackId: string): Promise<RackRegistration | null>;
|
|
12
|
+
/** Persists a registration or heartbeat. */
|
|
13
|
+
putRack(registration: RackRegistration): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Replaces exactly the observed registration atomically, without recreating
|
|
16
|
+
* a revoked identity. Both values name the same rack.
|
|
17
|
+
* @param expected - Independently read registration
|
|
18
|
+
* @param registration - Replacement for that exact value
|
|
19
|
+
* @returns Whether the conditional replacement succeeded
|
|
20
|
+
* @throws {Error} If the replacement changes the rack identity
|
|
21
|
+
*/
|
|
22
|
+
compareAndSetRack(expected: RackRegistration, registration: RackRegistration): Promise<boolean>;
|
|
23
|
+
/** Deregisters a rack, revoking its credential; returns whether it existed. */
|
|
24
|
+
deleteRack(rackId: string): Promise<boolean>;
|
|
25
|
+
/** Reads the security policy, or null for its defaults. */
|
|
26
|
+
getRackSecurityPolicy(): Promise<RackSecurityPolicy | null>;
|
|
27
|
+
/** Persists a security policy before resolving. */
|
|
28
|
+
putRackSecurityPolicy(policy: RackSecurityPolicy): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
/** Makes an independent East value, preserving variants and options. @internal */
|
|
31
|
+
export declare const copyRegistration: (value: RackRegistration) => RackRegistration;
|
|
32
|
+
/** Makes an independent security policy. @internal */
|
|
33
|
+
export declare const copySecurity: (value: RackSecurityPolicy) => RackSecurityPolicy;
|
|
34
|
+
/**
|
|
35
|
+
* Patches the latest registration without losing concurrent updates or revocation.
|
|
36
|
+
* Recomputes a pure patch after contention; does not recreate a missing rack.
|
|
37
|
+
* @param store - Registration persistence with conditional replacement
|
|
38
|
+
* @param rackId - Identity being updated
|
|
39
|
+
* @param patch - Pure patch computed from the latest registration
|
|
40
|
+
* @returns The committed value, or null after revocation
|
|
41
|
+
* @throws {Error} After repeated contention or a storage failure
|
|
42
|
+
* @example
|
|
43
|
+
* await updateRack(registry, rackId, () => ({ healthy: false, capacity: 0n }));
|
|
44
|
+
*/
|
|
45
|
+
export declare function updateRack(store: Pick<RackRegistry, 'getRack' | 'compareAndSetRack'>, rackId: string, patch: (current: RackRegistration) => Partial<RackRegistration>): Promise<RackRegistration | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Keeps the rack registry in memory, returning independent copies.
|
|
48
|
+
* @example
|
|
49
|
+
* const registry = new InMemoryRackRegistry();
|
|
50
|
+
* await registry.putRack(registration);
|
|
51
|
+
*/
|
|
52
|
+
export declare class InMemoryRackRegistry implements RackRegistry {
|
|
53
|
+
private readonly racks;
|
|
54
|
+
private security;
|
|
55
|
+
listRacks(): Promise<RackRegistration[]>;
|
|
56
|
+
getRack(id: string): Promise<RackRegistration | null>;
|
|
57
|
+
putRack(registration: RackRegistration): Promise<void>;
|
|
58
|
+
/** {@inheritDoc RackRegistry.compareAndSetRack} */
|
|
59
|
+
compareAndSetRack(expected: RackRegistration, registration: RackRegistration): Promise<boolean>;
|
|
60
|
+
deleteRack(id: string): Promise<boolean>;
|
|
61
|
+
getRackSecurityPolicy(): Promise<RackSecurityPolicy | null>;
|
|
62
|
+
putRackSecurityPolicy(policy: RackSecurityPolicy): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=rack-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-registry.d.ts","sourceRoot":"","sources":["../../../src/registry/rack-registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAgD,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAE3I,uFAAuF;AACvF,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACzC,qDAAqD;IACrD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC1D,4CAA4C;IAC5C,OAAO,CAAC,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;;;;OAOG;IACH,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAChG,+EAA+E;IAC/E,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,2DAA2D;IAC3D,qBAAqB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC5D,mDAAmD;IACnD,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,GAAI,OAAO,gBAAgB,KAAG,gBAAuG,CAAC;AACnK,sDAAsD;AACtD,eAAO,MAAM,YAAY,GAAI,OAAO,kBAAkB,KAAG,kBAA6G,CAAC;AAEvK;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,mBAAmB,CAAC,EAC1D,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAC9D,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQlC;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAC7D,OAAO,CAAC,QAAQ,CAAmC;IAEnD,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IACxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAIrD,OAAO,CAAC,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,mDAAmD;IACnD,iBAAiB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAO/F,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IACxC,qBAAqB,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAC3D,qBAAqB,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;CACjE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { decodeBeast2For, encodeBeast2For, equalFor } from '@elaraai/east';
|
|
6
|
+
import { RackRegistrationType, RackSecurityPolicyType } from '../protocol/registration.js';
|
|
7
|
+
/** Makes an independent East value, preserving variants and options. @internal */
|
|
8
|
+
export const copyRegistration = (value) => decodeBeast2For(RackRegistrationType)(encodeBeast2For(RackRegistrationType)(value));
|
|
9
|
+
/** Makes an independent security policy. @internal */
|
|
10
|
+
export const copySecurity = (value) => decodeBeast2For(RackSecurityPolicyType)(encodeBeast2For(RackSecurityPolicyType)(value));
|
|
11
|
+
/**
|
|
12
|
+
* Patches the latest registration without losing concurrent updates or revocation.
|
|
13
|
+
* Recomputes a pure patch after contention; does not recreate a missing rack.
|
|
14
|
+
* @param store - Registration persistence with conditional replacement
|
|
15
|
+
* @param rackId - Identity being updated
|
|
16
|
+
* @param patch - Pure patch computed from the latest registration
|
|
17
|
+
* @returns The committed value, or null after revocation
|
|
18
|
+
* @throws {Error} After repeated contention or a storage failure
|
|
19
|
+
* @example
|
|
20
|
+
* await updateRack(registry, rackId, () => ({ healthy: false, capacity: 0n }));
|
|
21
|
+
*/
|
|
22
|
+
export async function updateRack(store, rackId, patch) {
|
|
23
|
+
for (let attempt = 0; attempt < 8; attempt++) {
|
|
24
|
+
const current = await store.getRack(rackId);
|
|
25
|
+
if (current === null)
|
|
26
|
+
return null;
|
|
27
|
+
const updated = { ...current, ...patch(current) };
|
|
28
|
+
if (await store.compareAndSetRack(current, updated))
|
|
29
|
+
return updated;
|
|
30
|
+
}
|
|
31
|
+
throw new Error('Rack registration changed repeatedly; retry the request');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Keeps the rack registry in memory, returning independent copies.
|
|
35
|
+
* @example
|
|
36
|
+
* const registry = new InMemoryRackRegistry();
|
|
37
|
+
* await registry.putRack(registration);
|
|
38
|
+
*/
|
|
39
|
+
export class InMemoryRackRegistry {
|
|
40
|
+
racks = new Map();
|
|
41
|
+
security = null;
|
|
42
|
+
listRacks() { return Promise.resolve([...this.racks.values()].map(copyRegistration)); }
|
|
43
|
+
getRack(id) {
|
|
44
|
+
const rack = this.racks.get(id);
|
|
45
|
+
return Promise.resolve(rack === undefined ? null : copyRegistration(rack));
|
|
46
|
+
}
|
|
47
|
+
putRack(registration) {
|
|
48
|
+
this.racks.set(registration.rackId, copyRegistration(registration));
|
|
49
|
+
return Promise.resolve();
|
|
50
|
+
}
|
|
51
|
+
/** {@inheritDoc RackRegistry.compareAndSetRack} */
|
|
52
|
+
compareAndSetRack(expected, registration) {
|
|
53
|
+
if (expected.rackId !== registration.rackId)
|
|
54
|
+
return Promise.reject(new Error('Rack identity cannot change'));
|
|
55
|
+
const current = this.racks.get(expected.rackId);
|
|
56
|
+
if (current === undefined || !equalFor(RackRegistrationType)(current, expected))
|
|
57
|
+
return Promise.resolve(false);
|
|
58
|
+
this.racks.set(registration.rackId, copyRegistration(registration));
|
|
59
|
+
return Promise.resolve(true);
|
|
60
|
+
}
|
|
61
|
+
deleteRack(id) { return Promise.resolve(this.racks.delete(id)); }
|
|
62
|
+
getRackSecurityPolicy() { return Promise.resolve(this.security === null ? null : copySecurity(this.security)); }
|
|
63
|
+
putRackSecurityPolicy(policy) { this.security = copySecurity(policy); return Promise.resolve(); }
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=rack-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-registry.js","sourceRoot":"","sources":["../../../src/registry/rack-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-registry.spec.d.ts","sourceRoot":"","sources":["../../../src/registry/rack-registry.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import { InMemoryRackRegistry } from './rack-registry.js';
|
|
6
|
+
import { rackRegistryContract } from '../testing/rack-registry-contract.js';
|
|
7
|
+
rackRegistryContract('memory', () => new InMemoryRackRegistry());
|
|
8
|
+
//# sourceMappingURL=rack-registry.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rack-registry.spec.js","sourceRoot":"","sources":["../../../src/registry/rack-registry.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E,oBAAoB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
import type { TaskBodyRequest } from '@elaraai/e3-core';
|
|
6
|
+
import { type RackPolicy } from './policy.js';
|
|
7
|
+
import { type IneligibleReason, type RackTier } from './tiers.js';
|
|
8
|
+
/** A request's rack destination, or why it remains local. */
|
|
9
|
+
export type Eligibility = {
|
|
10
|
+
eligible: true;
|
|
11
|
+
tier: RackTier;
|
|
12
|
+
size: string;
|
|
13
|
+
timeoutMinutes: number;
|
|
14
|
+
} | {
|
|
15
|
+
eligible: false;
|
|
16
|
+
reason: IneligibleReason;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Evaluates routing once per logical task and graph name for a run.
|
|
20
|
+
* The program and output reducer are task-object references, so a merge that
|
|
21
|
+
* arrives before any map (cached maps) receives the same complete scan.
|
|
22
|
+
* @example
|
|
23
|
+
* const eligibility = await new EligibilityEvaluator(policy).evaluate(request);
|
|
24
|
+
*/
|
|
25
|
+
export declare class EligibilityEvaluator {
|
|
26
|
+
private readonly policy;
|
|
27
|
+
private readonly verdicts;
|
|
28
|
+
/** @param policy - The policy snapshot for this run */
|
|
29
|
+
constructor(policy: RackPolicy);
|
|
30
|
+
/**
|
|
31
|
+
* Checks selection, runtime, environment and every executable IR bundle.
|
|
32
|
+
* @param request - A task or split unit after its cache miss
|
|
33
|
+
* @returns Its eligibility, with a deterministic reason on refusal
|
|
34
|
+
*/
|
|
35
|
+
evaluate(request: TaskBodyRequest): Promise<Eligibility>;
|
|
36
|
+
private check;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=eligibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../../src/routing/eligibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAe,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG/E,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAElD;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAInB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IAEpE,uDAAuD;gBAC1B,MAAM,EAAE,UAAU;IAE/C;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;YAc1C,KAAK;CAyBpB"}
|