@hypequery/deployment 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,209 @@
1
+ import { createProtocolSchemaValueParser, ProtocolSchemaValueError, ProtocolValueError, validateProtocolDeploymentContract, } from '@hypequery/protocol';
2
+ import { resolveDeploymentDataPlaneLimits, } from './data-plane-limits.js';
3
+ export class DeploymentDataPlaneError extends Error {
4
+ code;
5
+ path;
6
+ constructor(code, message, options = {}) {
7
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
8
+ this.name = 'DeploymentDataPlaneError';
9
+ this.code = code;
10
+ this.path = options.path;
11
+ }
12
+ }
13
+ function dataPlaneError(code, message, cause, path) {
14
+ return new DeploymentDataPlaneError(code, message, { cause, path });
15
+ }
16
+ function throwIfAborted(signal) {
17
+ if (signal?.aborted) {
18
+ throw dataPlaneError('HQ_DATA_PLANE_ABORTED', 'The data-plane request was aborted.', signal.reason);
19
+ }
20
+ }
21
+ function frozenRecord(entries) {
22
+ return Object.freeze(Object.assign(Object.create(null), entries));
23
+ }
24
+ function valueAtPath(input, path) {
25
+ let value = input;
26
+ for (const segment of path.split('.')) {
27
+ if (typeof value !== 'object' || value === null || Array.isArray(value)
28
+ || !Object.hasOwn(value, segment))
29
+ return undefined;
30
+ value = value[segment];
31
+ }
32
+ return value;
33
+ }
34
+ function sqlParameters(query, input, tenant) {
35
+ if (query.implementation.kind !== 'compiled-sql')
36
+ return Object.freeze({});
37
+ const values = Object.create(null);
38
+ for (const parameter of query.implementation.parameters) {
39
+ const value = parameter.source.kind === 'tenant'
40
+ ? tenant
41
+ : valueAtPath(input, parameter.source.path);
42
+ if (value === undefined) {
43
+ throw dataPlaneError('HQ_DATA_PLANE_INPUT_INVALID', 'A required compiled SQL binding is missing.', undefined, parameter.source.kind === 'input' ? `$.${parameter.source.path}` : '$.tenant');
44
+ }
45
+ values[parameter.name] = value;
46
+ }
47
+ return frozenRecord(values);
48
+ }
49
+ function routeTable(deployment, limits) {
50
+ const routes = new Map();
51
+ for (const query of deployment.queries) {
52
+ routes.set(`${query.endpoint.method}\0${query.endpoint.path}`, Object.freeze({
53
+ query,
54
+ input: createProtocolSchemaValueParser(query.input, { limits }),
55
+ output: createProtocolSchemaValueParser(query.output, { limits }),
56
+ }));
57
+ }
58
+ return routes;
59
+ }
60
+ function missing(values, actual) {
61
+ const available = new Set(actual ?? []);
62
+ return values.filter(value => !available.has(value));
63
+ }
64
+ export function createDeploymentDataPlane(options) {
65
+ let deployment;
66
+ try {
67
+ deployment = validateProtocolDeploymentContract(options.deployment);
68
+ }
69
+ catch (error) {
70
+ throw dataPlaneError('HQ_DATA_PLANE_CONFIGURATION', 'The deployment data plane requires a valid deployment contract.', error);
71
+ }
72
+ const limits = resolveDeploymentDataPlaneLimits(options.limits);
73
+ const routes = routeTable(deployment, limits);
74
+ const paths = new Set(deployment.queries.map(query => query.endpoint.path));
75
+ async function execute(request, json) {
76
+ throwIfAborted(request.signal);
77
+ const route = routes.get(`${request.method}\0${request.path}`);
78
+ if (!route) {
79
+ if (paths.has(request.path)) {
80
+ throw dataPlaneError('HQ_DATA_PLANE_METHOD_NOT_ALLOWED', 'The deployment route does not support this method.');
81
+ }
82
+ throw dataPlaneError('HQ_DATA_PLANE_ROUTE_NOT_FOUND', 'The deployment route was not found.');
83
+ }
84
+ const { query } = route;
85
+ let principal = null;
86
+ if (query.endpoint.access.kind === 'authenticated' && !options.authenticate) {
87
+ throw dataPlaneError('HQ_DATA_PLANE_CONFIGURATION', 'An authenticator is required for this deployment route.');
88
+ }
89
+ if (options.authenticate
90
+ && (query.endpoint.access.kind === 'authenticated' || request.credentials !== undefined)) {
91
+ try {
92
+ principal = await options.authenticate({ credentials: request.credentials, request, query });
93
+ }
94
+ catch (error) {
95
+ throw dataPlaneError('HQ_DATA_PLANE_UNAUTHENTICATED', 'Authentication failed.', error);
96
+ }
97
+ }
98
+ throwIfAborted(request.signal);
99
+ if (query.endpoint.access.kind === 'authenticated') {
100
+ if (!principal) {
101
+ throw dataPlaneError('HQ_DATA_PLANE_UNAUTHENTICATED', 'Authentication is required.');
102
+ }
103
+ if (missing(query.endpoint.access.roles, principal.roles).length > 0
104
+ || missing(query.endpoint.access.scopes, principal.scopes).length > 0) {
105
+ throw dataPlaneError('HQ_DATA_PLANE_FORBIDDEN', 'The principal lacks required access.');
106
+ }
107
+ }
108
+ let tenant;
109
+ if (query.endpoint.tenant.kind !== 'not-required') {
110
+ if (!options.resolveTenant) {
111
+ if (query.endpoint.tenant.kind === 'required') {
112
+ throw dataPlaneError('HQ_DATA_PLANE_CONFIGURATION', 'A tenant resolver is required for this deployment route.');
113
+ }
114
+ }
115
+ else {
116
+ try {
117
+ tenant = await options.resolveTenant({ principal, request, query });
118
+ }
119
+ catch (error) {
120
+ throw dataPlaneError('HQ_DATA_PLANE_FORBIDDEN', 'Tenant resolution failed.', error);
121
+ }
122
+ }
123
+ if (query.endpoint.tenant.kind === 'required' && (tenant === undefined || tenant === null)) {
124
+ throw dataPlaneError('HQ_DATA_PLANE_TENANT_REQUIRED', 'Tenant context is required.');
125
+ }
126
+ }
127
+ throwIfAborted(request.signal);
128
+ let input;
129
+ try {
130
+ if (json && request.input !== undefined) {
131
+ if (typeof route.input.parseJson !== 'function')
132
+ throw dataPlaneError('HQ_DATA_PLANE_CONFIGURATION', 'The route input parser does not support JSON request bodies.');
133
+ input = route.input.parseJson(request.input);
134
+ }
135
+ else {
136
+ input = route.input.parse(request.input);
137
+ }
138
+ }
139
+ catch (error) {
140
+ if (error instanceof ProtocolSchemaValueError || error instanceof ProtocolValueError) {
141
+ throw dataPlaneError('HQ_DATA_PLANE_INPUT_INVALID', 'The request input does not match the deployment schema.', error, error.path);
142
+ }
143
+ throw error;
144
+ }
145
+ const common = { query, input, principal, tenant, request, signal: request.signal };
146
+ let output;
147
+ try {
148
+ switch (query.implementation.kind) {
149
+ case 'semantic-plan':
150
+ if (!options.executeSemanticPlan)
151
+ throw dataPlaneError('HQ_DATA_PLANE_EXECUTOR_UNAVAILABLE', 'No semantic-plan executor is configured.');
152
+ output = await options.executeSemanticPlan({
153
+ ...common,
154
+ implementation: query.implementation,
155
+ deployment,
156
+ });
157
+ break;
158
+ case 'compiled-sql':
159
+ if (!options.executeCompiledSql)
160
+ throw dataPlaneError('HQ_DATA_PLANE_EXECUTOR_UNAVAILABLE', 'No compiled SQL executor is configured.');
161
+ output = await options.executeCompiledSql({
162
+ ...common,
163
+ implementation: query.implementation,
164
+ parameters: sqlParameters(query, input, tenant),
165
+ });
166
+ break;
167
+ case 'runtime-reference':
168
+ if (!options.executeRuntimeReference)
169
+ throw dataPlaneError('HQ_DATA_PLANE_EXECUTOR_UNAVAILABLE', 'No runtime-reference executor is configured.');
170
+ output = await options.executeRuntimeReference({
171
+ ...common,
172
+ implementation: query.implementation,
173
+ });
174
+ break;
175
+ }
176
+ }
177
+ catch (error) {
178
+ if (error instanceof DeploymentDataPlaneError)
179
+ throw error;
180
+ if (request.signal?.aborted) {
181
+ throw dataPlaneError('HQ_DATA_PLANE_ABORTED', 'The data-plane request was aborted.', error);
182
+ }
183
+ throw dataPlaneError('HQ_DATA_PLANE_EXECUTION_FAILED', 'Deployment query execution failed.', error);
184
+ }
185
+ try {
186
+ output = route.output.parse(output);
187
+ }
188
+ catch (error) {
189
+ if (error instanceof ProtocolSchemaValueError) {
190
+ throw dataPlaneError('HQ_DATA_PLANE_OUTPUT_INVALID', 'The query output does not match the deployment schema.', error, error.path);
191
+ }
192
+ throw error;
193
+ }
194
+ const publicCacheTtlMs = query.endpoint.access.kind === 'public'
195
+ && query.endpoint.tenant.kind === 'not-required'
196
+ && principal === null
197
+ ? query.endpoint.cacheTtlMs
198
+ : undefined;
199
+ return Object.freeze({
200
+ query: query.name,
201
+ output,
202
+ ...(publicCacheTtlMs === undefined ? {} : { cacheTtlMs: publicCacheTtlMs }),
203
+ });
204
+ }
205
+ return Object.freeze({
206
+ execute: (request) => execute(request, false),
207
+ executeJson: (request) => execute(request, true),
208
+ });
209
+ }
@@ -0,0 +1,51 @@
1
+ import type { ProtocolDeploymentReleaseTarget } from '@hypequery/protocol';
2
+ import { type DeploymentActivationRegistry } from './activation.js';
3
+ import { type DeploymentControlPlane, type DeploymentControlPlaneAuthorizer } from './control-plane.js';
4
+ import type { DeploymentControlPlaneLimits } from './control-plane-limits.js';
5
+ import { type FileSystemDeploymentSubmissionStore } from './filesystem-store.js';
6
+ import { type DeploymentHost, type DeploymentHostDataPlaneConfiguration, type DeploymentHostDataPlaneInput } from './host.js';
7
+ import type { DeploymentIntakeLimits } from './limits.js';
8
+ import { type NodeDeploymentRuntimeFactoryOptions } from './node-runtime-factory.js';
9
+ import { type DeploymentRuntimeMaterializer } from './runtime-materialization.js';
10
+ import { type DeploymentRuntimeFactory, type DeploymentRuntimeSupervisor } from './runtime-supervisor.js';
11
+ import type { DeploymentAuthenticator, DeploymentAuthorizer, DeploymentIntake } from './types.js';
12
+ export interface FileSystemDeploymentHostOptions<SubmissionPrincipal, ControlPrincipal> {
13
+ readonly directory: string;
14
+ readonly targets: readonly ProtocolDeploymentReleaseTarget[];
15
+ readonly intake: {
16
+ readonly authenticator: DeploymentAuthenticator<SubmissionPrincipal>;
17
+ readonly authorizer: DeploymentAuthorizer<SubmissionPrincipal>;
18
+ readonly limits?: Partial<DeploymentIntakeLimits>;
19
+ readonly temporaryDirectory?: string;
20
+ };
21
+ readonly controlPlane: {
22
+ readonly authenticator: DeploymentAuthenticator<ControlPrincipal>;
23
+ readonly authorizer: DeploymentControlPlaneAuthorizer<ControlPrincipal>;
24
+ readonly limits?: Partial<DeploymentControlPlaneLimits>;
25
+ };
26
+ readonly configureDataPlane: (input: DeploymentHostDataPlaneInput) => DeploymentHostDataPlaneConfiguration | Promise<DeploymentHostDataPlaneConfiguration>;
27
+ /** Defaults to the reference Node worker runtime factory. */
28
+ readonly runtimeFactory?: DeploymentRuntimeFactory;
29
+ readonly nodeRuntime?: NodeDeploymentRuntimeFactoryOptions;
30
+ readonly activationClock?: () => Date;
31
+ readonly maxMaterializationAttempts?: number;
32
+ readonly drainTimeoutMs?: number;
33
+ readonly maxReconcileAttempts?: number;
34
+ readonly maxHostStabilityAttempts?: number;
35
+ readonly onBackgroundError?: (error: unknown) => void;
36
+ }
37
+ export interface FileSystemDeploymentHost<SubmissionPrincipal> {
38
+ readonly store: FileSystemDeploymentSubmissionStore<SubmissionPrincipal>;
39
+ readonly activations: DeploymentActivationRegistry;
40
+ readonly intake: DeploymentIntake;
41
+ readonly controlPlane: DeploymentControlPlane;
42
+ readonly materializer: DeploymentRuntimeMaterializer;
43
+ readonly supervisor: DeploymentRuntimeSupervisor;
44
+ readonly host: DeploymentHost;
45
+ start(options?: {
46
+ readonly signal?: AbortSignal;
47
+ }): Promise<void>;
48
+ close(): Promise<void>;
49
+ }
50
+ export declare function createFileSystemDeploymentHost<SubmissionPrincipal, ControlPrincipal>(options: FileSystemDeploymentHostOptions<SubmissionPrincipal, ControlPrincipal>): FileSystemDeploymentHost<SubmissionPrincipal>;
51
+ //# sourceMappingURL=filesystem-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filesystem-host.d.ts","sourceRoot":"","sources":["../src/filesystem-host.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { createFileSystemDeploymentActivationRegistry, } from './activation.js';
2
+ import { createDeploymentControlPlane, } from './control-plane.js';
3
+ import { createFileSystemDeploymentSubmissionStore, } from './filesystem-store.js';
4
+ import { createDeploymentHost, } from './host.js';
5
+ import { createDeploymentIntake } from './intake.js';
6
+ import { createNodeWorkerDeploymentRuntimeFactory, } from './node-runtime-factory.js';
7
+ import { createDeploymentRuntimeMaterializer, } from './runtime-materialization.js';
8
+ import { createDeploymentRuntimeSupervisor, } from './runtime-supervisor.js';
9
+ export function createFileSystemDeploymentHost(options) {
10
+ if (options.runtimeFactory !== undefined && options.nodeRuntime !== undefined) {
11
+ throw new TypeError('runtimeFactory and nodeRuntime cannot both be configured.');
12
+ }
13
+ const targets = Object.freeze([...options.targets]);
14
+ const store = createFileSystemDeploymentSubmissionStore({
15
+ directory: options.directory,
16
+ });
17
+ const activations = createFileSystemDeploymentActivationRegistry({
18
+ directory: options.directory,
19
+ releases: store,
20
+ clock: options.activationClock,
21
+ });
22
+ const intake = createDeploymentIntake({
23
+ ...options.intake,
24
+ store,
25
+ });
26
+ const materializer = createDeploymentRuntimeMaterializer({
27
+ activations,
28
+ releases: store,
29
+ maxStabilityAttempts: options.maxMaterializationAttempts,
30
+ });
31
+ const runtimeFactory = options.runtimeFactory
32
+ ?? createNodeWorkerDeploymentRuntimeFactory(options.nodeRuntime);
33
+ const supervisor = createDeploymentRuntimeSupervisor({
34
+ materializer,
35
+ factory: runtimeFactory,
36
+ drainTimeoutMs: options.drainTimeoutMs,
37
+ maxReconcileAttempts: options.maxReconcileAttempts,
38
+ onBackgroundError: options.onBackgroundError,
39
+ });
40
+ const host = createDeploymentHost({
41
+ supervisor,
42
+ configureDataPlane: options.configureDataPlane,
43
+ maxStabilityAttempts: options.maxHostStabilityAttempts,
44
+ onBackgroundError: options.onBackgroundError,
45
+ });
46
+ const controlPlane = createDeploymentControlPlane({
47
+ intake,
48
+ activations,
49
+ ...options.controlPlane,
50
+ onActivation: activation => host.scheduleReconcile(activation.target),
51
+ onBackgroundError: options.onBackgroundError,
52
+ });
53
+ let startPromise;
54
+ const result = {
55
+ store,
56
+ activations,
57
+ intake,
58
+ controlPlane,
59
+ materializer,
60
+ supervisor,
61
+ host,
62
+ start(startOptions = {}) {
63
+ const pending = startPromise ??= host.start(targets, startOptions).then(() => undefined);
64
+ void pending.catch(() => {
65
+ if (startPromise === pending)
66
+ startPromise = undefined;
67
+ });
68
+ return pending;
69
+ },
70
+ close: () => host.close(),
71
+ };
72
+ return Object.freeze(result);
73
+ }
package/dist/host.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { type ProtocolDeploymentContract, type ProtocolDeploymentReleaseTarget } from '@hypequery/protocol';
2
+ import { type DeploymentDataPlane, type DeploymentDataPlaneOptions, type DeploymentDataPlaneRequest, type DeploymentDataPlaneResult, type DeploymentRuntimeReferenceExecutionInput } from './data-plane.js';
3
+ import type { DeploymentRuntimeReconcileResult, DeploymentRuntimeStatus, DeploymentRuntimeSupervisor } from './runtime-supervisor.js';
4
+ export type DeploymentHostErrorCode = 'HQ_DEPLOYMENT_HOST_CONFIGURATION' | 'HQ_DEPLOYMENT_HOST_CLOSED' | 'HQ_DEPLOYMENT_HOST_NOT_READY' | 'HQ_DEPLOYMENT_HOST_RECONCILE_FAILED' | 'HQ_DEPLOYMENT_HOST_RECONCILE_UNSTABLE';
5
+ export declare class DeploymentHostError extends Error {
6
+ readonly code: DeploymentHostErrorCode;
7
+ constructor(code: DeploymentHostErrorCode, message: string, options?: {
8
+ readonly cause?: unknown;
9
+ });
10
+ }
11
+ export interface DeploymentHostDataPlaneInput {
12
+ readonly target: ProtocolDeploymentReleaseTarget;
13
+ readonly status: DeploymentRuntimeStatus;
14
+ readonly deployment: ProtocolDeploymentContract;
15
+ }
16
+ export type DeploymentHostDataPlaneConfiguration = Omit<DeploymentDataPlaneOptions, 'deployment' | 'executeRuntimeReference'> & {
17
+ readonly runtimeArgument: (input: DeploymentRuntimeReferenceExecutionInput) => unknown;
18
+ };
19
+ export interface DeploymentHostOptions {
20
+ readonly supervisor: DeploymentRuntimeSupervisor;
21
+ readonly configureDataPlane: (input: DeploymentHostDataPlaneInput) => DeploymentHostDataPlaneConfiguration | Promise<DeploymentHostDataPlaneConfiguration>;
22
+ /** Generation-stability attempts from 1 through 16. */
23
+ readonly maxStabilityAttempts?: number;
24
+ readonly onBackgroundError?: (error: unknown) => void;
25
+ }
26
+ export interface DeploymentHost {
27
+ start(targets: readonly ProtocolDeploymentReleaseTarget[], options?: {
28
+ readonly signal?: AbortSignal;
29
+ }): Promise<readonly DeploymentRuntimeReconcileResult[]>;
30
+ reconcile(target: ProtocolDeploymentReleaseTarget, options?: {
31
+ readonly signal?: AbortSignal;
32
+ }): Promise<DeploymentRuntimeReconcileResult>;
33
+ scheduleReconcile(target: ProtocolDeploymentReleaseTarget): void;
34
+ execute(target: ProtocolDeploymentReleaseTarget, request: DeploymentDataPlaneRequest): Promise<DeploymentDataPlaneResult>;
35
+ dataPlane(target: ProtocolDeploymentReleaseTarget): DeploymentDataPlane;
36
+ status(target: ProtocolDeploymentReleaseTarget): DeploymentRuntimeStatus | undefined;
37
+ close(): Promise<void>;
38
+ }
39
+ export declare function createDeploymentHost(options: DeploymentHostOptions): DeploymentHost;
40
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,0BAA0B,EAC/B,KAAK,+BAA+B,EACrC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,mBAAmB,EAExB,KAAK,0BAA0B,EAC/B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,wCAAwC,EAC9C,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAEV,gCAAgC,EAChC,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,yBAAyB,CAAC;AAKjC,MAAM,MAAM,uBAAuB,GAC/B,kCAAkC,GAClC,2BAA2B,GAC3B,8BAA8B,GAC9B,qCAAqC,GACrC,uCAAuC,CAAC;AAE5C,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;gBAGrC,IAAI,EAAE,uBAAuB,EAC7B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAM7C;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,MAAM,EAAE,+BAA+B,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,0BAA0B,CAAC;CACjD;AAED,MAAM,MAAM,oCAAoC,GAAG,IAAI,CACrD,0BAA0B,EAC1B,YAAY,GAAG,yBAAyB,CACzC,GAAG;IACF,QAAQ,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,wCAAwC,KAAK,OAAO,CAAC;CACxF,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,UAAU,EAAE,2BAA2B,CAAC;IACjD,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,KAAK,EAAE,4BAA4B,KAChC,oCAAoC,GAAG,OAAO,CAAC,oCAAoC,CAAC,CAAC;IAC1F,uDAAuD;IACvD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CACH,OAAO,EAAE,SAAS,+BAA+B,EAAE,EACnD,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,SAAS,gCAAgC,EAAE,CAAC,CAAC;IACxD,SAAS,CACP,MAAM,EAAE,+BAA+B,EACvC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC1C,OAAO,CAAC,gCAAgC,CAAC,CAAC;IAC7C,iBAAiB,CAAC,MAAM,EAAE,+BAA+B,GAAG,IAAI,CAAC;IACjE,OAAO,CACL,MAAM,EAAE,+BAA+B,EACvC,OAAO,EAAE,0BAA0B,GAClC,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtC,SAAS,CAAC,MAAM,EAAE,+BAA+B,GAAG,mBAAmB,CAAC;IACxE,MAAM,CAAC,MAAM,EAAE,+BAA+B,GAAG,uBAAuB,GAAG,SAAS,CAAC;IACrF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAiDD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CAmLnF"}
package/dist/host.js ADDED
@@ -0,0 +1,183 @@
1
+ import { validateProtocolDeploymentReleaseTarget, } from '@hypequery/protocol';
2
+ import { createDeploymentDataPlane, } from './data-plane.js';
3
+ import { createDeploymentRuntimeSupervisorExecutor } from './data-plane-runtime.js';
4
+ const DEFAULT_STABILITY_ATTEMPTS = 4;
5
+ const MAX_STABILITY_ATTEMPTS = 16;
6
+ export class DeploymentHostError extends Error {
7
+ code;
8
+ constructor(code, message, options = {}) {
9
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
10
+ this.name = 'DeploymentHostError';
11
+ this.code = code;
12
+ }
13
+ }
14
+ function hostError(code, message, cause) {
15
+ return new DeploymentHostError(code, message, { cause });
16
+ }
17
+ function targetKey(target) {
18
+ return JSON.stringify([target.project, target.environment]);
19
+ }
20
+ function target(input) {
21
+ try {
22
+ return validateProtocolDeploymentReleaseTarget(input);
23
+ }
24
+ catch (error) {
25
+ throw hostError('HQ_DEPLOYMENT_HOST_CONFIGURATION', 'The deployment host target is invalid.', error);
26
+ }
27
+ }
28
+ function stabilityAttempts(input) {
29
+ const value = input ?? DEFAULT_STABILITY_ATTEMPTS;
30
+ if (!Number.isSafeInteger(value) || value < 1 || value > MAX_STABILITY_ATTEMPTS) {
31
+ throw hostError('HQ_DEPLOYMENT_HOST_CONFIGURATION', `maxStabilityAttempts must be between 1 and ${MAX_STABILITY_ATTEMPTS}.`);
32
+ }
33
+ return value;
34
+ }
35
+ function sameGeneration(left, right) {
36
+ return left?.status.activationRevision === right?.status.activationRevision;
37
+ }
38
+ export function createDeploymentHost(options) {
39
+ if (!options.supervisor || typeof options.configureDataPlane !== 'function') {
40
+ throw hostError('HQ_DEPLOYMENT_HOST_CONFIGURATION', 'A runtime supervisor and data-plane configurator are required.');
41
+ }
42
+ const maximumAttempts = stabilityAttempts(options.maxStabilityAttempts);
43
+ const active = new Map();
44
+ const updates = new Map();
45
+ const background = new Set();
46
+ let closed = false;
47
+ let closePromise;
48
+ function ensureOpen() {
49
+ if (closed)
50
+ throw hostError('HQ_DEPLOYMENT_HOST_CLOSED', 'The deployment host is closed.');
51
+ }
52
+ function serialize(key, operation) {
53
+ const previous = updates.get(key) ?? Promise.resolve();
54
+ const current = previous.catch(() => undefined).then(operation);
55
+ const tracked = current.finally(() => {
56
+ if (updates.get(key) === tracked)
57
+ updates.delete(key);
58
+ });
59
+ updates.set(key, tracked);
60
+ return tracked;
61
+ }
62
+ async function install(desiredTarget, signal) {
63
+ for (let attempt = 0; attempt < maximumAttempts; attempt += 1) {
64
+ ensureOpen();
65
+ const result = await options.supervisor.reconcile(desiredTarget, { signal });
66
+ ensureOpen();
67
+ if (result.status === 'deactivated' || result.status === 'no-active-release') {
68
+ active.delete(targetKey(desiredTarget));
69
+ return result;
70
+ }
71
+ const generation = options.supervisor.generation(desiredTarget);
72
+ if (!generation
73
+ || generation.status.activationRevision !== result.runtime.activationRevision) {
74
+ continue;
75
+ }
76
+ let configuration;
77
+ try {
78
+ configuration = await options.configureDataPlane(Object.freeze({
79
+ target: desiredTarget,
80
+ status: generation.status,
81
+ deployment: generation.deployment,
82
+ }));
83
+ }
84
+ catch (error) {
85
+ throw hostError('HQ_DEPLOYMENT_HOST_RECONCILE_FAILED', 'The active deployment data plane could not be configured.', error);
86
+ }
87
+ ensureOpen();
88
+ let dataPlane;
89
+ try {
90
+ dataPlane = createDeploymentDataPlane({
91
+ ...configuration,
92
+ deployment: generation.deployment,
93
+ executeRuntimeReference: createDeploymentRuntimeSupervisorExecutor({
94
+ supervisor: options.supervisor,
95
+ target: desiredTarget,
96
+ activationRevision: generation.status.activationRevision,
97
+ argument: configuration.runtimeArgument,
98
+ }),
99
+ });
100
+ }
101
+ catch (error) {
102
+ throw hostError('HQ_DEPLOYMENT_HOST_RECONCILE_FAILED', 'The active deployment data plane could not be constructed.', error);
103
+ }
104
+ const confirmed = options.supervisor.generation(desiredTarget);
105
+ if (!sameGeneration(generation, confirmed))
106
+ continue;
107
+ active.set(targetKey(desiredTarget), Object.freeze({ generation, dataPlane }));
108
+ return result;
109
+ }
110
+ throw hostError('HQ_DEPLOYMENT_HOST_RECONCILE_UNSTABLE', 'The active deployment generation changed repeatedly during host reconciliation.');
111
+ }
112
+ const host = {
113
+ async start(targets, startOptions = {}) {
114
+ ensureOpen();
115
+ const validated = targets.map(target);
116
+ const keys = validated.map(targetKey);
117
+ if (new Set(keys).size !== keys.length) {
118
+ throw hostError('HQ_DEPLOYMENT_HOST_CONFIGURATION', 'Deployment host startup targets must be unique.');
119
+ }
120
+ return Object.freeze(await Promise.all(validated.map(candidate => (host.reconcile(candidate, startOptions)))));
121
+ },
122
+ reconcile(input, reconcileOptions = {}) {
123
+ ensureOpen();
124
+ const desiredTarget = target(input);
125
+ return serialize(targetKey(desiredTarget), () => install(desiredTarget, reconcileOptions.signal));
126
+ },
127
+ scheduleReconcile(input) {
128
+ ensureOpen();
129
+ const operation = host.reconcile(input).then(() => undefined).catch(error => {
130
+ try {
131
+ options.onBackgroundError?.(error);
132
+ }
133
+ catch {
134
+ // A diagnostic callback cannot make reconciliation an unhandled rejection.
135
+ }
136
+ });
137
+ background.add(operation);
138
+ void operation.finally(() => background.delete(operation)).catch(() => undefined);
139
+ },
140
+ async execute(input, request) {
141
+ ensureOpen();
142
+ const desiredTarget = target(input);
143
+ const hosted = active.get(targetKey(desiredTarget));
144
+ if (!hosted) {
145
+ throw hostError('HQ_DEPLOYMENT_HOST_NOT_READY', 'No deployment data plane is ready for target.');
146
+ }
147
+ return await hosted.dataPlane.execute(request);
148
+ },
149
+ dataPlane(input) {
150
+ ensureOpen();
151
+ const desiredTarget = target(input);
152
+ return Object.freeze({
153
+ execute: (request) => host.execute(desiredTarget, request),
154
+ executeJson: (request) => {
155
+ ensureOpen();
156
+ const hosted = active.get(targetKey(desiredTarget));
157
+ if (!hosted) {
158
+ throw hostError('HQ_DEPLOYMENT_HOST_NOT_READY', 'No deployment data plane is ready for target.');
159
+ }
160
+ return hosted.dataPlane.executeJson(request);
161
+ },
162
+ });
163
+ },
164
+ status(input) {
165
+ ensureOpen();
166
+ const desiredTarget = target(input);
167
+ return active.get(targetKey(desiredTarget))?.generation.status;
168
+ },
169
+ close() {
170
+ if (closePromise)
171
+ return closePromise;
172
+ closed = true;
173
+ closePromise = (async () => {
174
+ await Promise.allSettled([...updates.values()]);
175
+ await Promise.allSettled([...background]);
176
+ active.clear();
177
+ await options.supervisor.close();
178
+ })();
179
+ return closePromise;
180
+ },
181
+ };
182
+ return Object.freeze(host);
183
+ }
package/dist/index.d.ts CHANGED
@@ -20,6 +20,18 @@ export type { NodeDeploymentRuntimeErrorCode, NodeDeploymentRuntimeFactoryOption
20
20
  export { createDeploymentRuntimeMaterializer, DeploymentRuntimeMaterializationError, } from './runtime-materialization.js';
21
21
  export type { DeploymentRuntimeArtifactSnapshot, DeploymentRuntimeMaterializationErrorCode, DeploymentRuntimeMaterializer, DeploymentRuntimeMaterializerOptions, DeploymentRuntimeQueryBinding, DeploymentRuntimeRelease, DeploymentRuntimeReleaseReader, DeploymentRuntimeSnapshot, } from './runtime-materialization.js';
22
22
  export { createDeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorError, } from './runtime-supervisor.js';
23
- export type { DeploymentRuntimeFactory, DeploymentRuntimeInstance, DeploymentRuntimeInstanceInvocation, DeploymentRuntimeInvocation, DeploymentRuntimeReconcileResult, DeploymentRuntimeStatus, DeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorErrorCode, DeploymentRuntimeSupervisorOptions, } from './runtime-supervisor.js';
23
+ export type { DeploymentRuntimeFactory, DeploymentRuntimeGeneration, DeploymentRuntimeInstance, DeploymentRuntimeInstanceInvocation, DeploymentRuntimeInvocation, DeploymentRuntimeReconcileResult, DeploymentRuntimeStatus, DeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorErrorCode, DeploymentRuntimeSupervisorOptions, } from './runtime-supervisor.js';
24
24
  export type { DeploymentAuthenticationInput, DeploymentAuthenticator, DeploymentAuthorizationInput, DeploymentAuthorizer, DeploymentIntake, DeploymentIntakeOptions, DeploymentIntakeRequest, DeploymentIntakeResponse, DeploymentSubmissionResponse, DeploymentSubmissionStore, VerifiedDeploymentSubmission, } from './types.js';
25
+ export { createDeploymentDataPlane, DeploymentDataPlaneError, } from './data-plane.js';
26
+ export type { DeploymentCompiledSqlExecutionInput, DeploymentDataPlane, DeploymentDataPlaneAuthenticationInput, DeploymentDataPlaneErrorCode, DeploymentDataPlaneExecutionInput, DeploymentDataPlaneJsonRequest, DeploymentDataPlaneOptions, DeploymentDataPlanePrincipal, DeploymentDataPlaneRequest, DeploymentDataPlaneResult, DeploymentDataPlaneTenantInput, DeploymentRuntimeReferenceExecutionInput, DeploymentSemanticPlanExecutionInput, } from './data-plane.js';
27
+ export { DEFAULT_DEPLOYMENT_DATA_PLANE_LIMITS, resolveDeploymentDataPlaneLimits, } from './data-plane-limits.js';
28
+ export type { DeploymentDataPlaneLimits } from './data-plane-limits.js';
29
+ export { createDeploymentRuntimeSupervisorExecutor } from './data-plane-runtime.js';
30
+ export type { DeploymentRuntimeSupervisorExecutorOptions } from './data-plane-runtime.js';
31
+ export { createDeploymentDataPlaneFetchHandler, createDeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
32
+ export type { DeploymentDataPlaneAdapterOptions, DeploymentDataPlaneAdapterRequest, DeploymentDataPlaneFetchHandler, DeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
33
+ export { createDeploymentHost, DeploymentHostError, } from './host.js';
34
+ export { createFileSystemDeploymentHost } from './filesystem-host.js';
35
+ export type { FileSystemDeploymentHost, FileSystemDeploymentHostOptions, } from './filesystem-host.js';
36
+ export type { DeploymentHost, DeploymentHostDataPlaneConfiguration, DeploymentHostDataPlaneInput, DeploymentHostErrorCode, DeploymentHostOptions, } from './host.js';
25
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4CAA4C,EAC5C,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,gCAAgC,EAChC,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,6CAA6C,GAC9C,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,yCAAyC,EACzC,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,kCAAkC,EAClC,mCAAmC,EACnC,0CAA0C,EAC1C,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,wCAAwC,EACxC,gCAAgC,EAChC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,uCAAuC,EACvC,mCAAmC,GACpC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACL,wCAAwC,EACxC,0BAA0B,GAC3B,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,8BAA8B,EAC9B,mCAAmC,GACpC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,mCAAmC,EACnC,qCAAqC,GACtC,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,iCAAiC,EACjC,yCAAyC,EACzC,6BAA6B,EAC7B,oCAAoC,EACpC,6BAA6B,EAC7B,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,iCAAiC,EACjC,gCAAgC,GACjC,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,mCAAmC,EACnC,2BAA2B,EAC3B,gCAAgC,EAChC,uBAAuB,EACvB,2BAA2B,EAC3B,oCAAoC,EACpC,kCAAkC,GACnC,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -10,3 +10,9 @@ export { DEFAULT_DEPLOYMENT_INTAKE_LIMITS, resolveDeploymentIntakeLimits, } from
10
10
  export { createNodeWorkerDeploymentRuntimeFactory, NodeDeploymentRuntimeError, } from './node-runtime-factory.js';
11
11
  export { createDeploymentRuntimeMaterializer, DeploymentRuntimeMaterializationError, } from './runtime-materialization.js';
12
12
  export { createDeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorError, } from './runtime-supervisor.js';
13
+ export { createDeploymentDataPlane, DeploymentDataPlaneError, } from './data-plane.js';
14
+ export { DEFAULT_DEPLOYMENT_DATA_PLANE_LIMITS, resolveDeploymentDataPlaneLimits, } from './data-plane-limits.js';
15
+ export { createDeploymentRuntimeSupervisorExecutor } from './data-plane-runtime.js';
16
+ export { createDeploymentDataPlaneFetchHandler, createDeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
17
+ export { createDeploymentHost, DeploymentHostError, } from './host.js';
18
+ export { createFileSystemDeploymentHost } from './filesystem-host.js';
@@ -1,4 +1,4 @@
1
- import type { ProtocolDeploymentReleaseTarget } from '@hypequery/protocol';
1
+ import type { ProtocolDeploymentContract, ProtocolDeploymentReleaseTarget } from '@hypequery/protocol';
2
2
  import type { DeploymentRuntimeMaterializer, DeploymentRuntimeQueryBinding, DeploymentRuntimeSnapshot } from './runtime-materialization.js';
3
3
  export type DeploymentRuntimeSupervisorErrorCode = 'HQ_RUNTIME_SUPERVISOR_CONFIGURATION' | 'HQ_RUNTIME_SUPERVISOR_CLOSED' | 'HQ_RUNTIME_NOT_READY' | 'HQ_RUNTIME_QUERY_NOT_FOUND' | 'HQ_RUNTIME_QUERY_NOT_EXECUTABLE' | 'HQ_RUNTIME_START_FAILED' | 'HQ_RUNTIME_HEALTH_FAILED' | 'HQ_RUNTIME_INVOCATION_FAILED' | 'HQ_RUNTIME_RECONCILE_UNSTABLE' | 'HQ_RUNTIME_ABORTED';
4
4
  export declare class DeploymentRuntimeSupervisorError extends Error {
@@ -27,6 +27,8 @@ export interface DeploymentRuntimeFactory {
27
27
  }
28
28
  export interface DeploymentRuntimeInvocation {
29
29
  readonly target: ProtocolDeploymentReleaseTarget;
30
+ /** Reject the invocation unless this exact activation generation is active. */
31
+ readonly activationRevision?: string;
30
32
  readonly query: string;
31
33
  readonly argument: unknown;
32
34
  readonly signal?: AbortSignal;
@@ -37,6 +39,10 @@ export interface DeploymentRuntimeStatus {
37
39
  readonly releaseIdentity: string;
38
40
  readonly bundleIdentity: string;
39
41
  }
42
+ export interface DeploymentRuntimeGeneration {
43
+ readonly status: DeploymentRuntimeStatus;
44
+ readonly deployment: ProtocolDeploymentContract;
45
+ }
40
46
  export type DeploymentRuntimeReconcileResult = {
41
47
  readonly status: 'activated';
42
48
  readonly runtime: DeploymentRuntimeStatus;
@@ -55,6 +61,7 @@ export interface DeploymentRuntimeSupervisor {
55
61
  }): Promise<DeploymentRuntimeReconcileResult>;
56
62
  invoke(input: DeploymentRuntimeInvocation): Promise<unknown>;
57
63
  status(target: ProtocolDeploymentReleaseTarget): DeploymentRuntimeStatus | undefined;
64
+ generation(target: ProtocolDeploymentReleaseTarget): DeploymentRuntimeGeneration | undefined;
58
65
  close(): Promise<void>;
59
66
  }
60
67
  export interface DeploymentRuntimeSupervisorOptions {