@supacloud/compiler 0.31.1 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +129 -17
- package/dist/delivery-bundle-protocol.d.ts +34 -0
- package/dist/delivery-bundle-worker.js +71 -4
- package/dist/index.js +156 -44
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -15283,6 +15283,65 @@ var init_application_development2 = __esm(() => {
|
|
|
15283
15283
|
};
|
|
15284
15284
|
});
|
|
15285
15285
|
|
|
15286
|
+
// node_modules/@supacloud/delivery/src/worker-execution.ts
|
|
15287
|
+
function parseWorkerExecutionGroup(value) {
|
|
15288
|
+
if (!Check2(WorkerExecutionGroupSchema, value) || value.replicas > value.maxReplicas || !value.queue.endsWith(`_v${value.definitionVersion}`) || value.lifecycle.visibilityTimeoutSeconds < value.lifecycle.executionTimeoutSeconds + value.lifecycle.shutdownGraceSeconds + 30) {
|
|
15289
|
+
throw new Error("WORKER_EXECUTION_INVALID");
|
|
15290
|
+
}
|
|
15291
|
+
return structuredClone(value);
|
|
15292
|
+
}
|
|
15293
|
+
function validateWorkerExecution(groups) {
|
|
15294
|
+
const names = new Set, targets = new Set, queues = new Set, routes = new Set;
|
|
15295
|
+
for (const candidate of groups) {
|
|
15296
|
+
const group = parseWorkerExecutionGroup(candidate);
|
|
15297
|
+
const route = `${group.taskKey}:${group.definitionVersion}`;
|
|
15298
|
+
if (names.has(group.name) || targets.has(group.target) || queues.has(group.queue) || routes.has(route)) {
|
|
15299
|
+
throw new Error("WORKER_EXECUTION_CONFLICT");
|
|
15300
|
+
}
|
|
15301
|
+
names.add(group.name);
|
|
15302
|
+
targets.add(group.target);
|
|
15303
|
+
queues.add(group.queue);
|
|
15304
|
+
routes.add(route);
|
|
15305
|
+
}
|
|
15306
|
+
}
|
|
15307
|
+
var closed3, positive = (maximum) => Integer({ minimum: 1, maximum }), WorkerExecutionGroupSchema, WorkerExecutionSchema;
|
|
15308
|
+
var init_worker_execution = __esm(() => {
|
|
15309
|
+
init_build();
|
|
15310
|
+
init_value2();
|
|
15311
|
+
closed3 = { additionalProperties: false };
|
|
15312
|
+
WorkerExecutionGroupSchema = _Object_({
|
|
15313
|
+
name: String2({ pattern: "^[a-z][a-z0-9-]{0,47}$" }),
|
|
15314
|
+
target: String2({ pattern: "^[a-z][a-z0-9-]{0,53}$" }),
|
|
15315
|
+
workloadClass: Union([Literal("interactive"), Literal("batch")]),
|
|
15316
|
+
executor: Literal("pgflow-queue"),
|
|
15317
|
+
runtime: Literal("bun"),
|
|
15318
|
+
queue: String2({ pattern: "^scw_[a-z0-9_]{1,40}$" }),
|
|
15319
|
+
taskKey: String2({ pattern: "^[a-z][a-z0-9_.-]{0,99}$" }),
|
|
15320
|
+
definitionVersion: String2({ pattern: "^[1-9][0-9]{0,8}$" }),
|
|
15321
|
+
replicas: positive(16),
|
|
15322
|
+
maxReplicas: positive(16),
|
|
15323
|
+
concurrencyPerReplica: positive(32),
|
|
15324
|
+
resources: _Object_({
|
|
15325
|
+
cpuLimit: Number2({ minimum: 0.1, maximum: 64, multipleOf: 0.1 }),
|
|
15326
|
+
memoryLimitMiB: Integer({ minimum: 64, maximum: 262144 })
|
|
15327
|
+
}, closed3),
|
|
15328
|
+
database: _Object_({
|
|
15329
|
+
engineConnectionsPerReplica: positive(16),
|
|
15330
|
+
handlerConnectionsPerReplica: positive(16)
|
|
15331
|
+
}, closed3),
|
|
15332
|
+
lifecycle: _Object_({
|
|
15333
|
+
executionTimeoutSeconds: positive(3500),
|
|
15334
|
+
visibilityTimeoutSeconds: Integer({ minimum: 15, maximum: 3600 }),
|
|
15335
|
+
shutdownGraceSeconds: positive(300)
|
|
15336
|
+
}, closed3),
|
|
15337
|
+
retry: _Object_({ maxAttempts: Integer({ minimum: 1, maximum: 10 }) }, closed3),
|
|
15338
|
+
admission: _Object_({ maxOutstandingOperations: positive(1e6) }, closed3)
|
|
15339
|
+
}, closed3);
|
|
15340
|
+
WorkerExecutionSchema = _Object_({
|
|
15341
|
+
groups: _Array_(WorkerExecutionGroupSchema, { minItems: 1, maxItems: 32 })
|
|
15342
|
+
}, closed3);
|
|
15343
|
+
});
|
|
15344
|
+
|
|
15286
15345
|
// node_modules/@supacloud/delivery/src/delivery-schema.ts
|
|
15287
15346
|
function parseDeliveryOptions(value) {
|
|
15288
15347
|
if (value === undefined)
|
|
@@ -15290,6 +15349,11 @@ function parseDeliveryOptions(value) {
|
|
|
15290
15349
|
if (!Check2(DeliveryOptionsSchema, value))
|
|
15291
15350
|
throw new DeliveryConfigurationError;
|
|
15292
15351
|
const migrations = value.build?.migrations ?? [];
|
|
15352
|
+
try {
|
|
15353
|
+
validateWorkerExecution(value.execution?.groups ?? []);
|
|
15354
|
+
} catch {
|
|
15355
|
+
throw new DeliveryConfigurationError;
|
|
15356
|
+
}
|
|
15293
15357
|
if (new Set(migrations.map((item) => item.version)).size !== migrations.length || new Set(migrations.map((item) => item.source)).size !== migrations.length || migrations.some((item) => BigInt(item.version) > 9223372036854775807n || !/\.sql$/i.test(item.source) || item.source.split("/").includes("node_modules"))) {
|
|
15294
15358
|
throw new DeliveryConfigurationError;
|
|
15295
15359
|
}
|
|
@@ -15304,6 +15368,7 @@ var objectOptions, reference2, references, kind2, isolation, DeliveryFilePathSch
|
|
|
15304
15368
|
var init_delivery_schema = __esm(() => {
|
|
15305
15369
|
init_build();
|
|
15306
15370
|
init_value2();
|
|
15371
|
+
init_worker_execution();
|
|
15307
15372
|
objectOptions = { additionalProperties: false };
|
|
15308
15373
|
reference2 = String2({ minLength: 1, maxLength: 128, pattern: "^[A-Za-z][A-Za-z0-9_.:/-]*$" });
|
|
15309
15374
|
references = _Array_(reference2, { uniqueItems: true });
|
|
@@ -15315,6 +15380,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
15315
15380
|
});
|
|
15316
15381
|
DeliveryOptionsSchema = _Object_({
|
|
15317
15382
|
version: Literal(1),
|
|
15383
|
+
execution: Optional(WorkerExecutionSchema),
|
|
15318
15384
|
targets: Optional(_Array_(_Object_({
|
|
15319
15385
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
15320
15386
|
kind: kind2,
|
|
@@ -15387,6 +15453,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
15387
15453
|
name: String2(),
|
|
15388
15454
|
kind: kind2,
|
|
15389
15455
|
isolation,
|
|
15456
|
+
execution: Optional(WorkerExecutionGroupSchema),
|
|
15390
15457
|
roots: _Array_(String2()),
|
|
15391
15458
|
modules: _Array_(_Object_({
|
|
15392
15459
|
name: String2(),
|
|
@@ -15602,6 +15669,12 @@ function deliveryObjectDigest(object) {
|
|
|
15602
15669
|
function parseDeliveryBuildManifest(value) {
|
|
15603
15670
|
if (!Check2(DeliveryBuildManifestSchema, value))
|
|
15604
15671
|
throw new Error("Invalid delivery build manifest.");
|
|
15672
|
+
validateWorkerExecution(value.plan.targets.flatMap((target) => target.execution ? [target.execution] : []));
|
|
15673
|
+
for (const target of value.plan.targets) {
|
|
15674
|
+
if (target.execution && (target.kind !== "jobs" || target.isolation !== "process" || target.execution.target !== target.name || target.jobs.length !== 1 || target.jobs[0]?.name !== target.execution.taskKey || value.objects.find((object) => object.name === target.name)?.entryKind !== "bun-worker-application")) {
|
|
15675
|
+
throw new Error("Invalid delivery execution binding.");
|
|
15676
|
+
}
|
|
15677
|
+
}
|
|
15605
15678
|
if (new Set(value.objects.map((item) => item.name)).size !== value.objects.length) {
|
|
15606
15679
|
throw new Error("Duplicate delivery object owner.");
|
|
15607
15680
|
}
|
|
@@ -15631,13 +15704,14 @@ function parseDeliveryBuildResult(value) {
|
|
|
15631
15704
|
parseDeliveryBuildManifest(value.manifest);
|
|
15632
15705
|
return value;
|
|
15633
15706
|
}
|
|
15634
|
-
var
|
|
15707
|
+
var closed4, digest2, DeliveryObjectSchema, DeliveryBuildManifestSchema, resultFields, DeliveryBuildResultSchema;
|
|
15635
15708
|
var init_delivery_build_schema = __esm(() => {
|
|
15636
15709
|
init_build();
|
|
15637
15710
|
init_value2();
|
|
15638
15711
|
init_delivery_schema();
|
|
15639
15712
|
init_delivery_files();
|
|
15640
|
-
|
|
15713
|
+
init_worker_execution();
|
|
15714
|
+
closed4 = { additionalProperties: false };
|
|
15641
15715
|
digest2 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
15642
15716
|
DeliveryObjectSchema = _Object_({
|
|
15643
15717
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
@@ -15654,8 +15728,8 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
15654
15728
|
path: DeliveryFilePathSchema,
|
|
15655
15729
|
sha256: digest2,
|
|
15656
15730
|
bytes: Integer({ minimum: 0 })
|
|
15657
|
-
},
|
|
15658
|
-
},
|
|
15731
|
+
}, closed4), { minItems: 1 })
|
|
15732
|
+
}, closed4);
|
|
15659
15733
|
DeliveryBuildManifestSchema = _Object_({
|
|
15660
15734
|
schemaVersion: Literal(1),
|
|
15661
15735
|
producer: Literal("@supacloud/compiler/delivery-build-v1"),
|
|
@@ -15666,9 +15740,9 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
15666
15740
|
method: String2(),
|
|
15667
15741
|
path: String2(),
|
|
15668
15742
|
target: String2()
|
|
15669
|
-
},
|
|
15670
|
-
jobs: _Array_(_Object_({ name: String2(), target: String2() },
|
|
15671
|
-
},
|
|
15743
|
+
}, closed4)),
|
|
15744
|
+
jobs: _Array_(_Object_({ name: String2(), target: String2() }, closed4))
|
|
15745
|
+
}, closed4);
|
|
15672
15746
|
resultFields = {
|
|
15673
15747
|
diagnostics: _Array_(DeliveryDiagnosticSchema),
|
|
15674
15748
|
written: _Array_(String2()),
|
|
@@ -15682,13 +15756,13 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
15682
15756
|
changedTargets: _Array_(String2()),
|
|
15683
15757
|
unchangedTargets: _Array_(String2()),
|
|
15684
15758
|
removedTargets: _Array_(String2())
|
|
15685
|
-
},
|
|
15759
|
+
}, closed4),
|
|
15686
15760
|
_Object_({
|
|
15687
15761
|
...resultFields,
|
|
15688
15762
|
written: _Array_(String2(), { maxItems: 0 }),
|
|
15689
15763
|
ok: Literal(false),
|
|
15690
15764
|
manifest: Null()
|
|
15691
|
-
},
|
|
15765
|
+
}, closed4)
|
|
15692
15766
|
]);
|
|
15693
15767
|
});
|
|
15694
15768
|
|
|
@@ -16063,6 +16137,7 @@ var init_application_release = __esm(() => {
|
|
|
16063
16137
|
init_build();
|
|
16064
16138
|
init_value2();
|
|
16065
16139
|
init_delivery_files();
|
|
16140
|
+
init_worker_execution();
|
|
16066
16141
|
ApplicationIdSchema = String2({ pattern: "^[A-Za-z0-9_-]{1,64}$" });
|
|
16067
16142
|
ApplicationReleaseIdSchema = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
16068
16143
|
ApplicationReleaseRecordSchema = _Object_({
|
|
@@ -16076,7 +16151,8 @@ var init_application_release = __esm(() => {
|
|
|
16076
16151
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
16077
16152
|
object_id: ApplicationReleaseIdSchema,
|
|
16078
16153
|
kind: Union([Literal("http"), Literal("worker")]),
|
|
16079
|
-
entrypoint: Literal("bundle/index.js")
|
|
16154
|
+
entrypoint: Literal("bundle/index.js"),
|
|
16155
|
+
execution: Optional(WorkerExecutionGroupSchema)
|
|
16080
16156
|
}, { additionalProperties: false }), { minItems: 1, maxItems: 32 })
|
|
16081
16157
|
}, { additionalProperties: false });
|
|
16082
16158
|
});
|
|
@@ -16140,7 +16216,9 @@ var init_application_configuration = __esm(() => {
|
|
|
16140
16216
|
"SUPACLOUD_ACTIVATION_ID",
|
|
16141
16217
|
"SUPACLOUD_ENVIRONMENT_ID",
|
|
16142
16218
|
"SUPACLOUD_TARGET",
|
|
16143
|
-
"SUPACLOUD_OBJECT_ID"
|
|
16219
|
+
"SUPACLOUD_OBJECT_ID",
|
|
16220
|
+
"SUPACLOUD_WORKER_EXECUTION",
|
|
16221
|
+
"SUPACLOUD_WORKER_REPLICA"
|
|
16144
16222
|
]);
|
|
16145
16223
|
});
|
|
16146
16224
|
|
|
@@ -16292,6 +16370,7 @@ var init_delivery_migration_plan = () => {};
|
|
|
16292
16370
|
// node_modules/@supacloud/delivery/src/index.ts
|
|
16293
16371
|
var init_src = __esm(() => {
|
|
16294
16372
|
init_delivery_artifact();
|
|
16373
|
+
init_worker_execution();
|
|
16295
16374
|
init_application_activation();
|
|
16296
16375
|
init_application_release();
|
|
16297
16376
|
init_application_configuration();
|
|
@@ -21352,6 +21431,17 @@ function createDeliveryPlan(graph, input) {
|
|
|
21352
21431
|
}
|
|
21353
21432
|
}
|
|
21354
21433
|
}
|
|
21434
|
+
for (const group of options.execution?.groups ?? []) {
|
|
21435
|
+
const target = targets.get(group.target);
|
|
21436
|
+
if (!target || target.kind !== "jobs" || target.isolation !== "process" || target.jobs.length !== 1 || target.jobs[0]?.name !== group.taskKey || !options.build?.workerApplications?.some((item) => item.target === group.target)) {
|
|
21437
|
+
fail("delivery-execution-binding-invalid", `Execution group "${group.name}" requires one matching compiled Job and a Worker host.`, "Bind one versioned queue/task to one process-isolated jobs target with build.workerApplications.");
|
|
21438
|
+
} else {
|
|
21439
|
+
target.execution = group;
|
|
21440
|
+
}
|
|
21441
|
+
}
|
|
21442
|
+
if ([...targets.values()].reduce((count, target) => count + (target.execution?.replicas ?? 1), 0) > 32) {
|
|
21443
|
+
fail("delivery-execution-replica-limit", "A release supports at most 32 runtime targets including replicas.", "Reduce the replica count or split independent applications.");
|
|
21444
|
+
}
|
|
21355
21445
|
const canonicalDiagnostics = [...new Map(diagnostics.map((item) => [JSON.stringify(item), item])).values()].sort((a, b) => compare2(JSON.stringify(a), JSON.stringify(b)));
|
|
21356
21446
|
if (canonicalDiagnostics.some((item) => item.severity === "error")) {
|
|
21357
21447
|
return parseDeliveryPlanResult({ ok: false, plan: null, diagnostics: canonicalDiagnostics, written: [] });
|
|
@@ -21531,7 +21621,7 @@ function staticDeliveryImports(path, contents) {
|
|
|
21531
21621
|
// src/delivery-bundle-protocol.ts
|
|
21532
21622
|
init_build();
|
|
21533
21623
|
init_value2();
|
|
21534
|
-
var
|
|
21624
|
+
var closed5 = { additionalProperties: false };
|
|
21535
21625
|
var requestSchema = _Object_({
|
|
21536
21626
|
parentPid: Integer({ minimum: 1 }),
|
|
21537
21627
|
name: String2(),
|
|
@@ -21539,15 +21629,15 @@ var requestSchema = _Object_({
|
|
|
21539
21629
|
project: String2(),
|
|
21540
21630
|
generatedDirectory: String2(),
|
|
21541
21631
|
options: DeliveryOptionsSchema
|
|
21542
|
-
},
|
|
21632
|
+
}, closed5);
|
|
21543
21633
|
var responseSchema = Union([
|
|
21544
21634
|
_Object_({
|
|
21545
21635
|
ok: Literal(true),
|
|
21546
21636
|
files: _Array_(Tuple([DeliveryFilePathSchema, String2({ pattern: "^[A-Za-z0-9+/]*={0,2}$" })])),
|
|
21547
21637
|
inputs: _Array_(Tuple([String2(), String2({ pattern: "^[a-f0-9]{64}$" })])),
|
|
21548
21638
|
runtimeImports: _Array_(String2())
|
|
21549
|
-
},
|
|
21550
|
-
_Object_({ ok: Literal(false) },
|
|
21639
|
+
}, closed5),
|
|
21640
|
+
_Object_({ ok: Literal(false) }, closed5)
|
|
21551
21641
|
]);
|
|
21552
21642
|
function parseDeliveryBundleRequest(input) {
|
|
21553
21643
|
if (!Check2(requestSchema, input))
|
|
@@ -21863,6 +21953,7 @@ function renderDeliveryWorkerEntry(generatedDirectory, hostPath) {
|
|
|
21863
21953
|
const specifier = relativeImportPath(generatedDirectory, hostPath);
|
|
21864
21954
|
return `
|
|
21865
21955
|
import deliveryProcess from "node:process";
|
|
21956
|
+
import { isDeepStrictEqual as deliveryPolicyEqual } from "node:util";
|
|
21866
21957
|
import { createDeliveryWorker } from ${JSON.stringify(specifier)};
|
|
21867
21958
|
${renderDeliveryRuntimeIdentity()}
|
|
21868
21959
|
|
|
@@ -21870,6 +21961,8 @@ interface DeliveryWorkerHost {
|
|
|
21870
21961
|
start(): void | Promise<void>;
|
|
21871
21962
|
close(): void | Promise<void>;
|
|
21872
21963
|
failure?: Promise<never>;
|
|
21964
|
+
execution?: unknown;
|
|
21965
|
+
health?(): Promise<{ ready: boolean; active: number; completed: number; failed: number; timedOut: number }>;
|
|
21873
21966
|
}
|
|
21874
21967
|
|
|
21875
21968
|
{
|
|
@@ -21881,6 +21974,7 @@ interface DeliveryWorkerHost {
|
|
|
21881
21974
|
let closing: Promise<void> | undefined;
|
|
21882
21975
|
let deadline: ReturnType<typeof setTimeout> | undefined;
|
|
21883
21976
|
let keepAlive: ReturnType<typeof setInterval> | undefined;
|
|
21977
|
+
let healthPending = false;
|
|
21884
21978
|
const finish = (failed: boolean) => {
|
|
21885
21979
|
clearTimeout(deadline);
|
|
21886
21980
|
clearInterval(keepAlive);
|
|
@@ -21941,6 +22035,13 @@ interface DeliveryWorkerHost {
|
|
|
21941
22035
|
const candidate = await createHost(createCompiledModules(), { signal: lifecycle.signal });
|
|
21942
22036
|
if (!candidate || typeof candidate.close !== "function") throw new Error("Invalid delivery worker host.");
|
|
21943
22037
|
host = candidate;
|
|
22038
|
+
const execution = deliveryProcess.env.SUPACLOUD_WORKER_EXECUTION;
|
|
22039
|
+
if (execution) {
|
|
22040
|
+
const expected: unknown = JSON.parse(Buffer.from(execution, "base64").toString("utf8"));
|
|
22041
|
+
if (!deliveryPolicyEqual(host.execution, expected) || typeof host.health !== "function" || !host.failure) {
|
|
22042
|
+
throw new Error("Delivery worker execution policy was not adopted.");
|
|
22043
|
+
}
|
|
22044
|
+
}
|
|
21944
22045
|
if (typeof host.start !== "function") throw new Error("Invalid delivery worker host.");
|
|
21945
22046
|
if (host.failure !== undefined) {
|
|
21946
22047
|
if (!host.failure || typeof host.failure.then !== "function") throw new Error("Invalid worker failure signal.");
|
|
@@ -21952,7 +22053,18 @@ interface DeliveryWorkerHost {
|
|
|
21952
22053
|
await finishShutdown();
|
|
21953
22054
|
} else {
|
|
21954
22055
|
running = true;
|
|
21955
|
-
|
|
22056
|
+
const health = async () => {
|
|
22057
|
+
if (!execution || !host?.health || healthPending || lifecycle.signal.aborted) return;
|
|
22058
|
+
healthPending = true;
|
|
22059
|
+
try {
|
|
22060
|
+
const status = await host.health();
|
|
22061
|
+
console.log(JSON.stringify({ event: "delivery-worker-health", identity, observedAt: new Date().toISOString(), ...status }));
|
|
22062
|
+
} catch {
|
|
22063
|
+
console.log(JSON.stringify({ event: "delivery-worker-health", identity, observedAt: new Date().toISOString(), ready: false }));
|
|
22064
|
+
} finally { healthPending = false; }
|
|
22065
|
+
};
|
|
22066
|
+
keepAlive = setInterval(() => { void health(); }, execution ? 5000 : 1000);
|
|
22067
|
+
await health();
|
|
21956
22068
|
console.log(JSON.stringify({ event: "delivery-worker-started", ...(identity ? { identity } : {}) }));
|
|
21957
22069
|
}
|
|
21958
22070
|
} catch {
|
|
@@ -22342,7 +22454,7 @@ function compilerVersion() {
|
|
|
22342
22454
|
}
|
|
22343
22455
|
function migrationDependencies() {
|
|
22344
22456
|
return {
|
|
22345
|
-
"@supacloud/app": "0.
|
|
22457
|
+
"@supacloud/app": "0.22.0",
|
|
22346
22458
|
"@supacloud/compiler": compilerVersion(),
|
|
22347
22459
|
"@supacloud/elysia": "0.23.1",
|
|
22348
22460
|
elysia: "2.0.0-beta.19",
|
|
@@ -7,6 +7,40 @@ declare const requestSchema: Type.TObject<{
|
|
|
7
7
|
generatedDirectory: Type.TString;
|
|
8
8
|
options: Type.TObject<{
|
|
9
9
|
version: Type.TLiteral<1>;
|
|
10
|
+
execution: Type.TOptional<Type.TObject<{
|
|
11
|
+
groups: Type.TArray<Type.TObject<{
|
|
12
|
+
name: Type.TString;
|
|
13
|
+
target: Type.TString;
|
|
14
|
+
workloadClass: Type.TUnion<[Type.TLiteral<"interactive">, Type.TLiteral<"batch">]>;
|
|
15
|
+
executor: Type.TLiteral<"pgflow-queue">;
|
|
16
|
+
runtime: Type.TLiteral<"bun">;
|
|
17
|
+
queue: Type.TString;
|
|
18
|
+
taskKey: Type.TString;
|
|
19
|
+
definitionVersion: Type.TString;
|
|
20
|
+
replicas: Type.TInteger;
|
|
21
|
+
maxReplicas: Type.TInteger;
|
|
22
|
+
concurrencyPerReplica: Type.TInteger;
|
|
23
|
+
resources: Type.TObject<{
|
|
24
|
+
cpuLimit: Type.TNumber;
|
|
25
|
+
memoryLimitMiB: Type.TInteger;
|
|
26
|
+
}>;
|
|
27
|
+
database: Type.TObject<{
|
|
28
|
+
engineConnectionsPerReplica: Type.TInteger;
|
|
29
|
+
handlerConnectionsPerReplica: Type.TInteger;
|
|
30
|
+
}>;
|
|
31
|
+
lifecycle: Type.TObject<{
|
|
32
|
+
executionTimeoutSeconds: Type.TInteger;
|
|
33
|
+
visibilityTimeoutSeconds: Type.TInteger;
|
|
34
|
+
shutdownGraceSeconds: Type.TInteger;
|
|
35
|
+
}>;
|
|
36
|
+
retry: Type.TObject<{
|
|
37
|
+
maxAttempts: Type.TInteger;
|
|
38
|
+
}>;
|
|
39
|
+
admission: Type.TObject<{
|
|
40
|
+
maxOutstandingOperations: Type.TInteger;
|
|
41
|
+
}>;
|
|
42
|
+
}>>;
|
|
43
|
+
}>>;
|
|
10
44
|
targets: Type.TOptional<Type.TArray<Type.TObject<{
|
|
11
45
|
name: Type.TString;
|
|
12
46
|
kind: Type.TUnion<[Type.TLiteral<"api">, Type.TLiteral<"jobs">, Type.TLiteral<"webhook">]>;
|
|
@@ -9980,6 +9980,65 @@ var init_build2 = __esm(() => {
|
|
|
9980
9980
|
init_types2();
|
|
9981
9981
|
});
|
|
9982
9982
|
|
|
9983
|
+
// node_modules/@supacloud/delivery/src/worker-execution.ts
|
|
9984
|
+
function parseWorkerExecutionGroup(value) {
|
|
9985
|
+
if (!Check2(WorkerExecutionGroupSchema, value) || value.replicas > value.maxReplicas || !value.queue.endsWith(`_v${value.definitionVersion}`) || value.lifecycle.visibilityTimeoutSeconds < value.lifecycle.executionTimeoutSeconds + value.lifecycle.shutdownGraceSeconds + 30) {
|
|
9986
|
+
throw new Error("WORKER_EXECUTION_INVALID");
|
|
9987
|
+
}
|
|
9988
|
+
return structuredClone(value);
|
|
9989
|
+
}
|
|
9990
|
+
function validateWorkerExecution(groups) {
|
|
9991
|
+
const names = new Set, targets = new Set, queues = new Set, routes = new Set;
|
|
9992
|
+
for (const candidate of groups) {
|
|
9993
|
+
const group = parseWorkerExecutionGroup(candidate);
|
|
9994
|
+
const route = `${group.taskKey}:${group.definitionVersion}`;
|
|
9995
|
+
if (names.has(group.name) || targets.has(group.target) || queues.has(group.queue) || routes.has(route)) {
|
|
9996
|
+
throw new Error("WORKER_EXECUTION_CONFLICT");
|
|
9997
|
+
}
|
|
9998
|
+
names.add(group.name);
|
|
9999
|
+
targets.add(group.target);
|
|
10000
|
+
queues.add(group.queue);
|
|
10001
|
+
routes.add(route);
|
|
10002
|
+
}
|
|
10003
|
+
}
|
|
10004
|
+
var closed, positive = (maximum) => Integer({ minimum: 1, maximum }), WorkerExecutionGroupSchema, WorkerExecutionSchema;
|
|
10005
|
+
var init_worker_execution = __esm(() => {
|
|
10006
|
+
init_build2();
|
|
10007
|
+
init_value2();
|
|
10008
|
+
closed = { additionalProperties: false };
|
|
10009
|
+
WorkerExecutionGroupSchema = _Object_({
|
|
10010
|
+
name: String2({ pattern: "^[a-z][a-z0-9-]{0,47}$" }),
|
|
10011
|
+
target: String2({ pattern: "^[a-z][a-z0-9-]{0,53}$" }),
|
|
10012
|
+
workloadClass: Union([Literal("interactive"), Literal("batch")]),
|
|
10013
|
+
executor: Literal("pgflow-queue"),
|
|
10014
|
+
runtime: Literal("bun"),
|
|
10015
|
+
queue: String2({ pattern: "^scw_[a-z0-9_]{1,40}$" }),
|
|
10016
|
+
taskKey: String2({ pattern: "^[a-z][a-z0-9_.-]{0,99}$" }),
|
|
10017
|
+
definitionVersion: String2({ pattern: "^[1-9][0-9]{0,8}$" }),
|
|
10018
|
+
replicas: positive(16),
|
|
10019
|
+
maxReplicas: positive(16),
|
|
10020
|
+
concurrencyPerReplica: positive(32),
|
|
10021
|
+
resources: _Object_({
|
|
10022
|
+
cpuLimit: Number2({ minimum: 0.1, maximum: 64, multipleOf: 0.1 }),
|
|
10023
|
+
memoryLimitMiB: Integer({ minimum: 64, maximum: 262144 })
|
|
10024
|
+
}, closed),
|
|
10025
|
+
database: _Object_({
|
|
10026
|
+
engineConnectionsPerReplica: positive(16),
|
|
10027
|
+
handlerConnectionsPerReplica: positive(16)
|
|
10028
|
+
}, closed),
|
|
10029
|
+
lifecycle: _Object_({
|
|
10030
|
+
executionTimeoutSeconds: positive(3500),
|
|
10031
|
+
visibilityTimeoutSeconds: Integer({ minimum: 15, maximum: 3600 }),
|
|
10032
|
+
shutdownGraceSeconds: positive(300)
|
|
10033
|
+
}, closed),
|
|
10034
|
+
retry: _Object_({ maxAttempts: Integer({ minimum: 1, maximum: 10 }) }, closed),
|
|
10035
|
+
admission: _Object_({ maxOutstandingOperations: positive(1e6) }, closed)
|
|
10036
|
+
}, closed);
|
|
10037
|
+
WorkerExecutionSchema = _Object_({
|
|
10038
|
+
groups: _Array_(WorkerExecutionGroupSchema, { minItems: 1, maxItems: 32 })
|
|
10039
|
+
}, closed);
|
|
10040
|
+
});
|
|
10041
|
+
|
|
9983
10042
|
// node_modules/@supacloud/delivery/src/delivery-schema.ts
|
|
9984
10043
|
function parseDeliveryOptions(value) {
|
|
9985
10044
|
if (value === undefined)
|
|
@@ -9987,6 +10046,11 @@ function parseDeliveryOptions(value) {
|
|
|
9987
10046
|
if (!Check2(DeliveryOptionsSchema, value))
|
|
9988
10047
|
throw new DeliveryConfigurationError;
|
|
9989
10048
|
const migrations = value.build?.migrations ?? [];
|
|
10049
|
+
try {
|
|
10050
|
+
validateWorkerExecution(value.execution?.groups ?? []);
|
|
10051
|
+
} catch {
|
|
10052
|
+
throw new DeliveryConfigurationError;
|
|
10053
|
+
}
|
|
9990
10054
|
if (new Set(migrations.map((item) => item.version)).size !== migrations.length || new Set(migrations.map((item) => item.source)).size !== migrations.length || migrations.some((item) => BigInt(item.version) > 9223372036854775807n || !/\.sql$/i.test(item.source) || item.source.split("/").includes("node_modules"))) {
|
|
9991
10055
|
throw new DeliveryConfigurationError;
|
|
9992
10056
|
}
|
|
@@ -10001,6 +10065,7 @@ var objectOptions, reference, references, kind, isolation, DeliveryFilePathSchem
|
|
|
10001
10065
|
var init_delivery_schema = __esm(() => {
|
|
10002
10066
|
init_build2();
|
|
10003
10067
|
init_value2();
|
|
10068
|
+
init_worker_execution();
|
|
10004
10069
|
objectOptions = { additionalProperties: false };
|
|
10005
10070
|
reference = String2({ minLength: 1, maxLength: 128, pattern: "^[A-Za-z][A-Za-z0-9_.:/-]*$" });
|
|
10006
10071
|
references = _Array_(reference, { uniqueItems: true });
|
|
@@ -10012,6 +10077,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
10012
10077
|
});
|
|
10013
10078
|
DeliveryOptionsSchema = _Object_({
|
|
10014
10079
|
version: Literal(1),
|
|
10080
|
+
execution: Optional(WorkerExecutionSchema),
|
|
10015
10081
|
targets: Optional(_Array_(_Object_({
|
|
10016
10082
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
10017
10083
|
kind,
|
|
@@ -10084,6 +10150,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
10084
10150
|
name: String2(),
|
|
10085
10151
|
kind,
|
|
10086
10152
|
isolation,
|
|
10153
|
+
execution: Optional(WorkerExecutionGroupSchema),
|
|
10087
10154
|
roots: _Array_(String2()),
|
|
10088
10155
|
modules: _Array_(_Object_({
|
|
10089
10156
|
name: String2(),
|
|
@@ -10391,7 +10458,7 @@ init_value2();
|
|
|
10391
10458
|
init_delivery_schema();
|
|
10392
10459
|
|
|
10393
10460
|
// src/delivery-bundle-protocol.ts
|
|
10394
|
-
var
|
|
10461
|
+
var closed2 = { additionalProperties: false };
|
|
10395
10462
|
var requestSchema = _Object_({
|
|
10396
10463
|
parentPid: Integer({ minimum: 1 }),
|
|
10397
10464
|
name: String2(),
|
|
@@ -10399,15 +10466,15 @@ var requestSchema = _Object_({
|
|
|
10399
10466
|
project: String2(),
|
|
10400
10467
|
generatedDirectory: String2(),
|
|
10401
10468
|
options: DeliveryOptionsSchema
|
|
10402
|
-
},
|
|
10469
|
+
}, closed2);
|
|
10403
10470
|
var responseSchema = Union([
|
|
10404
10471
|
_Object_({
|
|
10405
10472
|
ok: Literal(true),
|
|
10406
10473
|
files: _Array_(Tuple([DeliveryFilePathSchema, String2({ pattern: "^[A-Za-z0-9+/]*={0,2}$" })])),
|
|
10407
10474
|
inputs: _Array_(Tuple([String2(), String2({ pattern: "^[a-f0-9]{64}$" })])),
|
|
10408
10475
|
runtimeImports: _Array_(String2())
|
|
10409
|
-
},
|
|
10410
|
-
_Object_({ ok: Literal(false) },
|
|
10476
|
+
}, closed2),
|
|
10477
|
+
_Object_({ ok: Literal(false) }, closed2)
|
|
10411
10478
|
]);
|
|
10412
10479
|
function parseDeliveryBundleRequest(input) {
|
|
10413
10480
|
if (!Check2(requestSchema, input))
|
package/dist/index.js
CHANGED
|
@@ -14164,6 +14164,65 @@ var init_value2 = __esm(() => {
|
|
|
14164
14164
|
init_shared();
|
|
14165
14165
|
});
|
|
14166
14166
|
|
|
14167
|
+
// node_modules/@supacloud/delivery/src/worker-execution.ts
|
|
14168
|
+
function parseWorkerExecutionGroup(value) {
|
|
14169
|
+
if (!Check2(WorkerExecutionGroupSchema, value) || value.replicas > value.maxReplicas || !value.queue.endsWith(`_v${value.definitionVersion}`) || value.lifecycle.visibilityTimeoutSeconds < value.lifecycle.executionTimeoutSeconds + value.lifecycle.shutdownGraceSeconds + 30) {
|
|
14170
|
+
throw new Error("WORKER_EXECUTION_INVALID");
|
|
14171
|
+
}
|
|
14172
|
+
return structuredClone(value);
|
|
14173
|
+
}
|
|
14174
|
+
function validateWorkerExecution(groups) {
|
|
14175
|
+
const names = new Set, targets = new Set, queues = new Set, routes = new Set;
|
|
14176
|
+
for (const candidate of groups) {
|
|
14177
|
+
const group = parseWorkerExecutionGroup(candidate);
|
|
14178
|
+
const route = `${group.taskKey}:${group.definitionVersion}`;
|
|
14179
|
+
if (names.has(group.name) || targets.has(group.target) || queues.has(group.queue) || routes.has(route)) {
|
|
14180
|
+
throw new Error("WORKER_EXECUTION_CONFLICT");
|
|
14181
|
+
}
|
|
14182
|
+
names.add(group.name);
|
|
14183
|
+
targets.add(group.target);
|
|
14184
|
+
queues.add(group.queue);
|
|
14185
|
+
routes.add(route);
|
|
14186
|
+
}
|
|
14187
|
+
}
|
|
14188
|
+
var closed, positive = (maximum) => Integer({ minimum: 1, maximum }), WorkerExecutionGroupSchema, WorkerExecutionSchema;
|
|
14189
|
+
var init_worker_execution = __esm(() => {
|
|
14190
|
+
init_build();
|
|
14191
|
+
init_value2();
|
|
14192
|
+
closed = { additionalProperties: false };
|
|
14193
|
+
WorkerExecutionGroupSchema = _Object_({
|
|
14194
|
+
name: String2({ pattern: "^[a-z][a-z0-9-]{0,47}$" }),
|
|
14195
|
+
target: String2({ pattern: "^[a-z][a-z0-9-]{0,53}$" }),
|
|
14196
|
+
workloadClass: Union([Literal("interactive"), Literal("batch")]),
|
|
14197
|
+
executor: Literal("pgflow-queue"),
|
|
14198
|
+
runtime: Literal("bun"),
|
|
14199
|
+
queue: String2({ pattern: "^scw_[a-z0-9_]{1,40}$" }),
|
|
14200
|
+
taskKey: String2({ pattern: "^[a-z][a-z0-9_.-]{0,99}$" }),
|
|
14201
|
+
definitionVersion: String2({ pattern: "^[1-9][0-9]{0,8}$" }),
|
|
14202
|
+
replicas: positive(16),
|
|
14203
|
+
maxReplicas: positive(16),
|
|
14204
|
+
concurrencyPerReplica: positive(32),
|
|
14205
|
+
resources: _Object_({
|
|
14206
|
+
cpuLimit: Number2({ minimum: 0.1, maximum: 64, multipleOf: 0.1 }),
|
|
14207
|
+
memoryLimitMiB: Integer({ minimum: 64, maximum: 262144 })
|
|
14208
|
+
}, closed),
|
|
14209
|
+
database: _Object_({
|
|
14210
|
+
engineConnectionsPerReplica: positive(16),
|
|
14211
|
+
handlerConnectionsPerReplica: positive(16)
|
|
14212
|
+
}, closed),
|
|
14213
|
+
lifecycle: _Object_({
|
|
14214
|
+
executionTimeoutSeconds: positive(3500),
|
|
14215
|
+
visibilityTimeoutSeconds: Integer({ minimum: 15, maximum: 3600 }),
|
|
14216
|
+
shutdownGraceSeconds: positive(300)
|
|
14217
|
+
}, closed),
|
|
14218
|
+
retry: _Object_({ maxAttempts: Integer({ minimum: 1, maximum: 10 }) }, closed),
|
|
14219
|
+
admission: _Object_({ maxOutstandingOperations: positive(1e6) }, closed)
|
|
14220
|
+
}, closed);
|
|
14221
|
+
WorkerExecutionSchema = _Object_({
|
|
14222
|
+
groups: _Array_(WorkerExecutionGroupSchema, { minItems: 1, maxItems: 32 })
|
|
14223
|
+
}, closed);
|
|
14224
|
+
});
|
|
14225
|
+
|
|
14167
14226
|
// node_modules/@supacloud/delivery/src/delivery-schema.ts
|
|
14168
14227
|
function parseDeliveryOptions(value) {
|
|
14169
14228
|
if (value === undefined)
|
|
@@ -14171,6 +14230,11 @@ function parseDeliveryOptions(value) {
|
|
|
14171
14230
|
if (!Check2(DeliveryOptionsSchema, value))
|
|
14172
14231
|
throw new DeliveryConfigurationError;
|
|
14173
14232
|
const migrations = value.build?.migrations ?? [];
|
|
14233
|
+
try {
|
|
14234
|
+
validateWorkerExecution(value.execution?.groups ?? []);
|
|
14235
|
+
} catch {
|
|
14236
|
+
throw new DeliveryConfigurationError;
|
|
14237
|
+
}
|
|
14174
14238
|
if (new Set(migrations.map((item) => item.version)).size !== migrations.length || new Set(migrations.map((item) => item.source)).size !== migrations.length || migrations.some((item) => BigInt(item.version) > 9223372036854775807n || !/\.sql$/i.test(item.source) || item.source.split("/").includes("node_modules"))) {
|
|
14175
14239
|
throw new DeliveryConfigurationError;
|
|
14176
14240
|
}
|
|
@@ -14185,6 +14249,7 @@ var objectOptions, reference, references, kind, isolation, DeliveryFilePathSchem
|
|
|
14185
14249
|
var init_delivery_schema = __esm(() => {
|
|
14186
14250
|
init_build();
|
|
14187
14251
|
init_value2();
|
|
14252
|
+
init_worker_execution();
|
|
14188
14253
|
objectOptions = { additionalProperties: false };
|
|
14189
14254
|
reference = String2({ minLength: 1, maxLength: 128, pattern: "^[A-Za-z][A-Za-z0-9_.:/-]*$" });
|
|
14190
14255
|
references = _Array_(reference, { uniqueItems: true });
|
|
@@ -14196,6 +14261,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
14196
14261
|
});
|
|
14197
14262
|
DeliveryOptionsSchema = _Object_({
|
|
14198
14263
|
version: Literal(1),
|
|
14264
|
+
execution: Optional(WorkerExecutionSchema),
|
|
14199
14265
|
targets: Optional(_Array_(_Object_({
|
|
14200
14266
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
14201
14267
|
kind,
|
|
@@ -14268,6 +14334,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
14268
14334
|
name: String2(),
|
|
14269
14335
|
kind,
|
|
14270
14336
|
isolation,
|
|
14337
|
+
execution: Optional(WorkerExecutionGroupSchema),
|
|
14271
14338
|
roots: _Array_(String2()),
|
|
14272
14339
|
modules: _Array_(_Object_({
|
|
14273
14340
|
name: String2(),
|
|
@@ -14483,6 +14550,12 @@ function deliveryObjectDigest(object) {
|
|
|
14483
14550
|
function parseDeliveryBuildManifest(value) {
|
|
14484
14551
|
if (!Check2(DeliveryBuildManifestSchema, value))
|
|
14485
14552
|
throw new Error("Invalid delivery build manifest.");
|
|
14553
|
+
validateWorkerExecution(value.plan.targets.flatMap((target) => target.execution ? [target.execution] : []));
|
|
14554
|
+
for (const target of value.plan.targets) {
|
|
14555
|
+
if (target.execution && (target.kind !== "jobs" || target.isolation !== "process" || target.execution.target !== target.name || target.jobs.length !== 1 || target.jobs[0]?.name !== target.execution.taskKey || value.objects.find((object) => object.name === target.name)?.entryKind !== "bun-worker-application")) {
|
|
14556
|
+
throw new Error("Invalid delivery execution binding.");
|
|
14557
|
+
}
|
|
14558
|
+
}
|
|
14486
14559
|
if (new Set(value.objects.map((item) => item.name)).size !== value.objects.length) {
|
|
14487
14560
|
throw new Error("Duplicate delivery object owner.");
|
|
14488
14561
|
}
|
|
@@ -14512,13 +14585,14 @@ function parseDeliveryBuildResult(value) {
|
|
|
14512
14585
|
parseDeliveryBuildManifest(value.manifest);
|
|
14513
14586
|
return value;
|
|
14514
14587
|
}
|
|
14515
|
-
var
|
|
14588
|
+
var closed2, digest2, DeliveryObjectSchema, DeliveryBuildManifestSchema, resultFields, DeliveryBuildResultSchema;
|
|
14516
14589
|
var init_delivery_build_schema = __esm(() => {
|
|
14517
14590
|
init_build();
|
|
14518
14591
|
init_value2();
|
|
14519
14592
|
init_delivery_schema();
|
|
14520
14593
|
init_delivery_files();
|
|
14521
|
-
|
|
14594
|
+
init_worker_execution();
|
|
14595
|
+
closed2 = { additionalProperties: false };
|
|
14522
14596
|
digest2 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
14523
14597
|
DeliveryObjectSchema = _Object_({
|
|
14524
14598
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
@@ -14535,8 +14609,8 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
14535
14609
|
path: DeliveryFilePathSchema,
|
|
14536
14610
|
sha256: digest2,
|
|
14537
14611
|
bytes: Integer({ minimum: 0 })
|
|
14538
|
-
},
|
|
14539
|
-
},
|
|
14612
|
+
}, closed2), { minItems: 1 })
|
|
14613
|
+
}, closed2);
|
|
14540
14614
|
DeliveryBuildManifestSchema = _Object_({
|
|
14541
14615
|
schemaVersion: Literal(1),
|
|
14542
14616
|
producer: Literal("@supacloud/compiler/delivery-build-v1"),
|
|
@@ -14547,9 +14621,9 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
14547
14621
|
method: String2(),
|
|
14548
14622
|
path: String2(),
|
|
14549
14623
|
target: String2()
|
|
14550
|
-
},
|
|
14551
|
-
jobs: _Array_(_Object_({ name: String2(), target: String2() },
|
|
14552
|
-
},
|
|
14624
|
+
}, closed2)),
|
|
14625
|
+
jobs: _Array_(_Object_({ name: String2(), target: String2() }, closed2))
|
|
14626
|
+
}, closed2);
|
|
14553
14627
|
resultFields = {
|
|
14554
14628
|
diagnostics: _Array_(DeliveryDiagnosticSchema),
|
|
14555
14629
|
written: _Array_(String2()),
|
|
@@ -14563,13 +14637,13 @@ var init_delivery_build_schema = __esm(() => {
|
|
|
14563
14637
|
changedTargets: _Array_(String2()),
|
|
14564
14638
|
unchangedTargets: _Array_(String2()),
|
|
14565
14639
|
removedTargets: _Array_(String2())
|
|
14566
|
-
},
|
|
14640
|
+
}, closed2),
|
|
14567
14641
|
_Object_({
|
|
14568
14642
|
...resultFields,
|
|
14569
14643
|
written: _Array_(String2(), { maxItems: 0 }),
|
|
14570
14644
|
ok: Literal(false),
|
|
14571
14645
|
manifest: Null()
|
|
14572
|
-
},
|
|
14646
|
+
}, closed2)
|
|
14573
14647
|
]);
|
|
14574
14648
|
});
|
|
14575
14649
|
|
|
@@ -15037,12 +15111,12 @@ function serializedExecutionSnapshot(graph) {
|
|
|
15037
15111
|
parseExecutionSnapshot(wire);
|
|
15038
15112
|
return json;
|
|
15039
15113
|
}
|
|
15040
|
-
var
|
|
15114
|
+
var closed3, text, kind2, SnapshotSchema, EXECUTION_SNAPSHOT_MAX_BYTES = 1048576, indices, WireSnapshotSchema;
|
|
15041
15115
|
var init_execution_snapshot = __esm(() => {
|
|
15042
15116
|
init_build();
|
|
15043
15117
|
init_value2();
|
|
15044
15118
|
init_inspect();
|
|
15045
|
-
|
|
15119
|
+
closed3 = { additionalProperties: false };
|
|
15046
15120
|
text = String2({ minLength: 1, maxLength: 512, pattern: "^[^\\u0000-\\u001f\\u007f]+$" });
|
|
15047
15121
|
kind2 = Union([Literal("route"), Literal("command"), Literal("job")]);
|
|
15048
15122
|
SnapshotSchema = _Object_({
|
|
@@ -15053,12 +15127,12 @@ var init_execution_snapshot = __esm(() => {
|
|
|
15053
15127
|
name: text,
|
|
15054
15128
|
command: Optional(text),
|
|
15055
15129
|
stages: _Array_(text)
|
|
15056
|
-
},
|
|
15057
|
-
commandAliases: _Array_(_Object_({ module: text, name: text, alias: text },
|
|
15130
|
+
}, closed3)),
|
|
15131
|
+
commandAliases: _Array_(_Object_({ module: text, name: text, alias: text }, closed3)),
|
|
15058
15132
|
contexts: _Array_(_Object_({
|
|
15059
15133
|
subject: text,
|
|
15060
15134
|
aliases: _Array_(text),
|
|
15061
|
-
modules: _Array_(_Object_({ name: text, file: Optional(text) },
|
|
15135
|
+
modules: _Array_(_Object_({ name: text, file: Optional(text) }, closed3)),
|
|
15062
15136
|
files: _Array_(text),
|
|
15063
15137
|
diagnostics: _Array_(_Object_({
|
|
15064
15138
|
code: text,
|
|
@@ -15068,10 +15142,10 @@ var init_execution_snapshot = __esm(() => {
|
|
|
15068
15142
|
repair: Optional(_Object_({
|
|
15069
15143
|
type: text,
|
|
15070
15144
|
readiness: Union([Literal("preview"), Literal("input-required"), Literal("manual")])
|
|
15071
|
-
},
|
|
15072
|
-
},
|
|
15073
|
-
},
|
|
15074
|
-
},
|
|
15145
|
+
}, closed3))
|
|
15146
|
+
}, closed3))
|
|
15147
|
+
}, closed3))
|
|
15148
|
+
}, closed3);
|
|
15075
15149
|
indices = _Array_(Integer({ minimum: 0 }));
|
|
15076
15150
|
WireSnapshotSchema = _Object_({
|
|
15077
15151
|
version: Literal(1),
|
|
@@ -15086,8 +15160,8 @@ var init_execution_snapshot = __esm(() => {
|
|
|
15086
15160
|
modules: indices,
|
|
15087
15161
|
files: indices,
|
|
15088
15162
|
diagnostics: indices
|
|
15089
|
-
},
|
|
15090
|
-
},
|
|
15163
|
+
}, closed3))
|
|
15164
|
+
}, closed3);
|
|
15091
15165
|
});
|
|
15092
15166
|
|
|
15093
15167
|
// node_modules/@supacloud/delivery/src/application-development.ts
|
|
@@ -15121,7 +15195,7 @@ function parseDevelopmentContext(input) {
|
|
|
15121
15195
|
throw invalid();
|
|
15122
15196
|
}
|
|
15123
15197
|
}
|
|
15124
|
-
var APPLICATION_DEVELOPMENT_SCHEMA = "supacloud.application-development.v1", APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES = 524288, APPLICATION_DEVELOPMENT_LIMITS, DevelopmentContractError,
|
|
15198
|
+
var APPLICATION_DEVELOPMENT_SCHEMA = "supacloud.application-development.v1", APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES = 524288, APPLICATION_DEVELOPMENT_LIMITS, DevelopmentContractError, closed4, text2, texts, count, mode, operations2, resourceUse, schemaKind, stage, ContextSchema;
|
|
15125
15199
|
var init_application_development = __esm(() => {
|
|
15126
15200
|
init_build();
|
|
15127
15201
|
init_value2();
|
|
@@ -15145,13 +15219,13 @@ var init_application_development = __esm(() => {
|
|
|
15145
15219
|
this.name = "DevelopmentContractError";
|
|
15146
15220
|
}
|
|
15147
15221
|
};
|
|
15148
|
-
|
|
15222
|
+
closed4 = { additionalProperties: false };
|
|
15149
15223
|
text2 = String2({ minLength: 1, maxLength: 512, pattern: "^[^\\u0000-\\u001f\\u007f]+$" });
|
|
15150
15224
|
texts = _Array_(text2);
|
|
15151
15225
|
count = Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER });
|
|
15152
15226
|
mode = Union([Literal("required"), Literal("none")]);
|
|
15153
15227
|
operations2 = _Array_(Union([Literal("read"), Literal("write"), Literal("publish"), Literal("consume")]));
|
|
15154
|
-
resourceUse = _Object_({ resource: text2, operations: operations2 },
|
|
15228
|
+
resourceUse = _Object_({ resource: text2, operations: operations2 }, closed4);
|
|
15155
15229
|
schemaKind = Optional(Union([Literal("opaque"), Literal("declared")]));
|
|
15156
15230
|
stage = Union([
|
|
15157
15231
|
Union([Literal("commandExecutor"), Literal("jobExecutor"), Literal("authorize"), Literal("idempotency"), Literal("transaction"), Literal("handler"), Literal("audit")]),
|
|
@@ -15176,7 +15250,7 @@ var init_application_development = __esm(() => {
|
|
|
15176
15250
|
jobs: texts,
|
|
15177
15251
|
queries: texts,
|
|
15178
15252
|
resources: texts
|
|
15179
|
-
},
|
|
15253
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.modules }),
|
|
15180
15254
|
routes: _Array_(_Object_({
|
|
15181
15255
|
module: text2,
|
|
15182
15256
|
method: Union([Literal("GET"), Literal("POST"), Literal("PUT"), Literal("PATCH"), Literal("DELETE"), Literal("HEAD"), Literal("OPTIONS")]),
|
|
@@ -15192,8 +15266,8 @@ var init_application_development = __esm(() => {
|
|
|
15192
15266
|
headers: schemaKind,
|
|
15193
15267
|
cookie: schemaKind,
|
|
15194
15268
|
response: schemaKind
|
|
15195
|
-
},
|
|
15196
|
-
},
|
|
15269
|
+
}, closed4))
|
|
15270
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.routes }),
|
|
15197
15271
|
commands: _Array_(_Object_({
|
|
15198
15272
|
module: text2,
|
|
15199
15273
|
name: text2,
|
|
@@ -15202,28 +15276,28 @@ var init_application_development = __esm(() => {
|
|
|
15202
15276
|
idempotency: mode,
|
|
15203
15277
|
audit: Optional(text2),
|
|
15204
15278
|
resources: _Array_(resourceUse)
|
|
15205
|
-
},
|
|
15279
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.commands }),
|
|
15206
15280
|
jobs: _Array_(_Object_({
|
|
15207
15281
|
module: text2,
|
|
15208
15282
|
name: text2,
|
|
15209
15283
|
mode: Optional(Union([Literal("task"), Literal("workflow")])),
|
|
15210
15284
|
resources: _Array_(resourceUse)
|
|
15211
|
-
},
|
|
15212
|
-
resources: _Array_(_Object_({ name: text2, kind: Union([Literal("database"), Literal("bucket"), Literal("queue"), Literal("config"), Literal("secret")]) },
|
|
15285
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.jobs }),
|
|
15286
|
+
resources: _Array_(_Object_({ name: text2, kind: Union([Literal("database"), Literal("bucket"), Literal("queue"), Literal("config"), Literal("secret")]) }, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.resources }),
|
|
15213
15287
|
resourceUses: _Array_(_Object_({
|
|
15214
15288
|
module: text2,
|
|
15215
15289
|
owner: text2,
|
|
15216
15290
|
ownerKind: Union([Literal("command"), Literal("job")]),
|
|
15217
15291
|
resource: text2,
|
|
15218
15292
|
operations: operations2
|
|
15219
|
-
},
|
|
15293
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.resourceUses }),
|
|
15220
15294
|
executionPlans: _Array_(_Object_({
|
|
15221
15295
|
module: text2,
|
|
15222
15296
|
kind: Union([Literal("route"), Literal("command"), Literal("job")]),
|
|
15223
15297
|
name: text2,
|
|
15224
15298
|
command: Optional(text2),
|
|
15225
15299
|
stages: _Array_(stage)
|
|
15226
|
-
},
|
|
15300
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.plans }),
|
|
15227
15301
|
diagnostics: _Array_(_Object_({
|
|
15228
15302
|
code: text2,
|
|
15229
15303
|
severity: Union([Literal("error"), Literal("warn")]),
|
|
@@ -15232,8 +15306,8 @@ var init_application_development = __esm(() => {
|
|
|
15232
15306
|
repair: Optional(_Object_({
|
|
15233
15307
|
type: Union([Literal("set_command_mode"), Literal("add_module_import"), Literal("add_provider"), Literal("mark_optional_dependency"), Literal("change_provider_scope"), Literal("add_command_permission"), Literal("add_route_parameter_binding"), Literal("remove_route_body_binding")]),
|
|
15234
15308
|
readiness: Union([Literal("preview"), Literal("input-required"), Literal("manual")])
|
|
15235
|
-
},
|
|
15236
|
-
},
|
|
15309
|
+
}, closed4))
|
|
15310
|
+
}, closed4), { maxItems: APPLICATION_DEVELOPMENT_LIMITS.diagnostics }),
|
|
15237
15311
|
omitted: _Object_({
|
|
15238
15312
|
modules: count,
|
|
15239
15313
|
providers: count,
|
|
@@ -15244,7 +15318,7 @@ var init_application_development = __esm(() => {
|
|
|
15244
15318
|
resourceUses: count,
|
|
15245
15319
|
plans: count,
|
|
15246
15320
|
diagnostics: count
|
|
15247
|
-
},
|
|
15321
|
+
}, closed4),
|
|
15248
15322
|
limits: _Object_({
|
|
15249
15323
|
outputBytes: Literal(APPLICATION_DEVELOPMENT_LIMITS.outputBytes),
|
|
15250
15324
|
modules: Literal(APPLICATION_DEVELOPMENT_LIMITS.modules),
|
|
@@ -15256,8 +15330,8 @@ var init_application_development = __esm(() => {
|
|
|
15256
15330
|
resourceUses: Literal(APPLICATION_DEVELOPMENT_LIMITS.resourceUses),
|
|
15257
15331
|
plans: Literal(APPLICATION_DEVELOPMENT_LIMITS.plans),
|
|
15258
15332
|
diagnostics: Literal(APPLICATION_DEVELOPMENT_LIMITS.diagnostics)
|
|
15259
|
-
},
|
|
15260
|
-
},
|
|
15333
|
+
}, closed4)
|
|
15334
|
+
}, closed4);
|
|
15261
15335
|
});
|
|
15262
15336
|
|
|
15263
15337
|
// src/application-development.ts
|
|
@@ -15514,6 +15588,7 @@ var init_application_release = __esm(() => {
|
|
|
15514
15588
|
init_build();
|
|
15515
15589
|
init_value2();
|
|
15516
15590
|
init_delivery_files();
|
|
15591
|
+
init_worker_execution();
|
|
15517
15592
|
ApplicationIdSchema = String2({ pattern: "^[A-Za-z0-9_-]{1,64}$" });
|
|
15518
15593
|
ApplicationReleaseIdSchema = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
15519
15594
|
ApplicationReleaseRecordSchema = _Object_({
|
|
@@ -15527,7 +15602,8 @@ var init_application_release = __esm(() => {
|
|
|
15527
15602
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
15528
15603
|
object_id: ApplicationReleaseIdSchema,
|
|
15529
15604
|
kind: Union([Literal("http"), Literal("worker")]),
|
|
15530
|
-
entrypoint: Literal("bundle/index.js")
|
|
15605
|
+
entrypoint: Literal("bundle/index.js"),
|
|
15606
|
+
execution: Optional(WorkerExecutionGroupSchema)
|
|
15531
15607
|
}, { additionalProperties: false }), { minItems: 1, maxItems: 32 })
|
|
15532
15608
|
}, { additionalProperties: false });
|
|
15533
15609
|
});
|
|
@@ -15591,7 +15667,9 @@ var init_application_configuration = __esm(() => {
|
|
|
15591
15667
|
"SUPACLOUD_ACTIVATION_ID",
|
|
15592
15668
|
"SUPACLOUD_ENVIRONMENT_ID",
|
|
15593
15669
|
"SUPACLOUD_TARGET",
|
|
15594
|
-
"SUPACLOUD_OBJECT_ID"
|
|
15670
|
+
"SUPACLOUD_OBJECT_ID",
|
|
15671
|
+
"SUPACLOUD_WORKER_EXECUTION",
|
|
15672
|
+
"SUPACLOUD_WORKER_REPLICA"
|
|
15595
15673
|
]);
|
|
15596
15674
|
});
|
|
15597
15675
|
|
|
@@ -15743,6 +15821,7 @@ var init_delivery_migration_plan = () => {};
|
|
|
15743
15821
|
// node_modules/@supacloud/delivery/src/index.ts
|
|
15744
15822
|
var init_src = __esm(() => {
|
|
15745
15823
|
init_delivery_artifact();
|
|
15824
|
+
init_worker_execution();
|
|
15746
15825
|
init_application_activation();
|
|
15747
15826
|
init_application_release();
|
|
15748
15827
|
init_application_configuration();
|
|
@@ -20412,6 +20491,17 @@ function createDeliveryPlan(graph, input) {
|
|
|
20412
20491
|
}
|
|
20413
20492
|
}
|
|
20414
20493
|
}
|
|
20494
|
+
for (const group of options.execution?.groups ?? []) {
|
|
20495
|
+
const target = targets.get(group.target);
|
|
20496
|
+
if (!target || target.kind !== "jobs" || target.isolation !== "process" || target.jobs.length !== 1 || target.jobs[0]?.name !== group.taskKey || !options.build?.workerApplications?.some((item) => item.target === group.target)) {
|
|
20497
|
+
fail("delivery-execution-binding-invalid", `Execution group "${group.name}" requires one matching compiled Job and a Worker host.`, "Bind one versioned queue/task to one process-isolated jobs target with build.workerApplications.");
|
|
20498
|
+
} else {
|
|
20499
|
+
target.execution = group;
|
|
20500
|
+
}
|
|
20501
|
+
}
|
|
20502
|
+
if ([...targets.values()].reduce((count, target) => count + (target.execution?.replicas ?? 1), 0) > 32) {
|
|
20503
|
+
fail("delivery-execution-replica-limit", "A release supports at most 32 runtime targets including replicas.", "Reduce the replica count or split independent applications.");
|
|
20504
|
+
}
|
|
20415
20505
|
const canonicalDiagnostics = [...new Map(diagnostics.map((item) => [JSON.stringify(item), item])).values()].sort((a, b) => compare2(JSON.stringify(a), JSON.stringify(b)));
|
|
20416
20506
|
if (canonicalDiagnostics.some((item) => item.severity === "error")) {
|
|
20417
20507
|
return parseDeliveryPlanResult({ ok: false, plan: null, diagnostics: canonicalDiagnostics, written: [] });
|
|
@@ -20590,7 +20680,7 @@ function staticDeliveryImports(path, contents) {
|
|
|
20590
20680
|
// src/delivery-bundle-protocol.ts
|
|
20591
20681
|
init_build();
|
|
20592
20682
|
init_value2();
|
|
20593
|
-
var
|
|
20683
|
+
var closed5 = { additionalProperties: false };
|
|
20594
20684
|
var requestSchema = _Object_({
|
|
20595
20685
|
parentPid: Integer({ minimum: 1 }),
|
|
20596
20686
|
name: String2(),
|
|
@@ -20598,15 +20688,15 @@ var requestSchema = _Object_({
|
|
|
20598
20688
|
project: String2(),
|
|
20599
20689
|
generatedDirectory: String2(),
|
|
20600
20690
|
options: DeliveryOptionsSchema
|
|
20601
|
-
},
|
|
20691
|
+
}, closed5);
|
|
20602
20692
|
var responseSchema = Union([
|
|
20603
20693
|
_Object_({
|
|
20604
20694
|
ok: Literal(true),
|
|
20605
20695
|
files: _Array_(Tuple([DeliveryFilePathSchema, String2({ pattern: "^[A-Za-z0-9+/]*={0,2}$" })])),
|
|
20606
20696
|
inputs: _Array_(Tuple([String2(), String2({ pattern: "^[a-f0-9]{64}$" })])),
|
|
20607
20697
|
runtimeImports: _Array_(String2())
|
|
20608
|
-
},
|
|
20609
|
-
_Object_({ ok: Literal(false) },
|
|
20698
|
+
}, closed5),
|
|
20699
|
+
_Object_({ ok: Literal(false) }, closed5)
|
|
20610
20700
|
]);
|
|
20611
20701
|
function parseDeliveryBundleRequest(input) {
|
|
20612
20702
|
if (!Check2(requestSchema, input))
|
|
@@ -20922,6 +21012,7 @@ function renderDeliveryWorkerEntry(generatedDirectory, hostPath) {
|
|
|
20922
21012
|
const specifier = relativeImportPath(generatedDirectory, hostPath);
|
|
20923
21013
|
return `
|
|
20924
21014
|
import deliveryProcess from "node:process";
|
|
21015
|
+
import { isDeepStrictEqual as deliveryPolicyEqual } from "node:util";
|
|
20925
21016
|
import { createDeliveryWorker } from ${JSON.stringify(specifier)};
|
|
20926
21017
|
${renderDeliveryRuntimeIdentity()}
|
|
20927
21018
|
|
|
@@ -20929,6 +21020,8 @@ interface DeliveryWorkerHost {
|
|
|
20929
21020
|
start(): void | Promise<void>;
|
|
20930
21021
|
close(): void | Promise<void>;
|
|
20931
21022
|
failure?: Promise<never>;
|
|
21023
|
+
execution?: unknown;
|
|
21024
|
+
health?(): Promise<{ ready: boolean; active: number; completed: number; failed: number; timedOut: number }>;
|
|
20932
21025
|
}
|
|
20933
21026
|
|
|
20934
21027
|
{
|
|
@@ -20940,6 +21033,7 @@ interface DeliveryWorkerHost {
|
|
|
20940
21033
|
let closing: Promise<void> | undefined;
|
|
20941
21034
|
let deadline: ReturnType<typeof setTimeout> | undefined;
|
|
20942
21035
|
let keepAlive: ReturnType<typeof setInterval> | undefined;
|
|
21036
|
+
let healthPending = false;
|
|
20943
21037
|
const finish = (failed: boolean) => {
|
|
20944
21038
|
clearTimeout(deadline);
|
|
20945
21039
|
clearInterval(keepAlive);
|
|
@@ -21000,6 +21094,13 @@ interface DeliveryWorkerHost {
|
|
|
21000
21094
|
const candidate = await createHost(createCompiledModules(), { signal: lifecycle.signal });
|
|
21001
21095
|
if (!candidate || typeof candidate.close !== "function") throw new Error("Invalid delivery worker host.");
|
|
21002
21096
|
host = candidate;
|
|
21097
|
+
const execution = deliveryProcess.env.SUPACLOUD_WORKER_EXECUTION;
|
|
21098
|
+
if (execution) {
|
|
21099
|
+
const expected: unknown = JSON.parse(Buffer.from(execution, "base64").toString("utf8"));
|
|
21100
|
+
if (!deliveryPolicyEqual(host.execution, expected) || typeof host.health !== "function" || !host.failure) {
|
|
21101
|
+
throw new Error("Delivery worker execution policy was not adopted.");
|
|
21102
|
+
}
|
|
21103
|
+
}
|
|
21003
21104
|
if (typeof host.start !== "function") throw new Error("Invalid delivery worker host.");
|
|
21004
21105
|
if (host.failure !== undefined) {
|
|
21005
21106
|
if (!host.failure || typeof host.failure.then !== "function") throw new Error("Invalid worker failure signal.");
|
|
@@ -21011,7 +21112,18 @@ interface DeliveryWorkerHost {
|
|
|
21011
21112
|
await finishShutdown();
|
|
21012
21113
|
} else {
|
|
21013
21114
|
running = true;
|
|
21014
|
-
|
|
21115
|
+
const health = async () => {
|
|
21116
|
+
if (!execution || !host?.health || healthPending || lifecycle.signal.aborted) return;
|
|
21117
|
+
healthPending = true;
|
|
21118
|
+
try {
|
|
21119
|
+
const status = await host.health();
|
|
21120
|
+
console.log(JSON.stringify({ event: "delivery-worker-health", identity, observedAt: new Date().toISOString(), ...status }));
|
|
21121
|
+
} catch {
|
|
21122
|
+
console.log(JSON.stringify({ event: "delivery-worker-health", identity, observedAt: new Date().toISOString(), ready: false }));
|
|
21123
|
+
} finally { healthPending = false; }
|
|
21124
|
+
};
|
|
21125
|
+
keepAlive = setInterval(() => { void health(); }, execution ? 5000 : 1000);
|
|
21126
|
+
await health();
|
|
21015
21127
|
console.log(JSON.stringify({ event: "delivery-worker-started", ...(identity ? { identity } : {}) }));
|
|
21016
21128
|
}
|
|
21017
21129
|
} catch {
|
|
@@ -22075,7 +22187,7 @@ function compilerVersion() {
|
|
|
22075
22187
|
}
|
|
22076
22188
|
function migrationDependencies() {
|
|
22077
22189
|
return {
|
|
22078
|
-
"@supacloud/app": "0.
|
|
22190
|
+
"@supacloud/app": "0.22.0",
|
|
22079
22191
|
"@supacloud/compiler": compilerVersion(),
|
|
22080
22192
|
"@supacloud/elysia": "0.23.1",
|
|
22081
22193
|
elysia: "2.0.0-beta.19",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Static compiler for @supacloud/app metadata: builds the application graph from AST, validates it, and generates reflection-free factory code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"directory": "packages/compiler"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@supacloud/delivery": "0.
|
|
57
|
+
"@supacloud/delivery": "0.5.0",
|
|
58
58
|
"typebox": "1.3.34",
|
|
59
59
|
"@graphql-codegen/core": "^6.2.0",
|
|
60
60
|
"@graphql-codegen/typed-document-node": "^7.1.0",
|