@wix/ditto-codegen-public 1.0.441 → 1.0.442
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/out.js +454 -49
- package/package.json +2 -2
package/dist/out.js
CHANGED
|
@@ -544,7 +544,15 @@ var require_context = __commonJS({
|
|
|
544
544
|
var types_1 = require_types_impl();
|
|
545
545
|
var dotenv_1 = __importDefault2(require_main());
|
|
546
546
|
var path_12 = __importDefault2(require("path"));
|
|
547
|
+
var provisioned = {
|
|
548
|
+
CODEGEN_JOB_DELIVERY: process.env.CODEGEN_JOB_DELIVERY,
|
|
549
|
+
CODEGEN_JOB_FETCH_PORT: process.env.CODEGEN_JOB_FETCH_PORT
|
|
550
|
+
};
|
|
547
551
|
dotenv_1.default.config({ path: path_12.default.join(__dirname, "../.env"), override: true });
|
|
552
|
+
for (const [key, value] of Object.entries(provisioned)) {
|
|
553
|
+
if (value?.trim())
|
|
554
|
+
process.env[key] = value;
|
|
555
|
+
}
|
|
548
556
|
var HistoryManager = class {
|
|
549
557
|
constructor() {
|
|
550
558
|
this.history = [];
|
|
@@ -11032,7 +11040,7 @@ var require_CodeGenService = __commonJS({
|
|
|
11032
11040
|
"dist/services/CodeGenService.js"(exports2) {
|
|
11033
11041
|
"use strict";
|
|
11034
11042
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
11035
|
-
exports2.CodeGenService = exports2.JobsSortOrder = exports2.TaskKind = exports2.Status = void 0;
|
|
11043
|
+
exports2.CodeGenService = exports2.FETCH_TIMEOUT_MS = exports2.REQUEST_TIMEOUT_MS = exports2.JobsSortOrder = exports2.TaskKind = exports2.Status = void 0;
|
|
11036
11044
|
exports2.createCodeGenErrorHandler = createCodeGenErrorHandler;
|
|
11037
11045
|
var http_client_1 = require_index_node();
|
|
11038
11046
|
var http_1 = require_http_impl();
|
|
@@ -11116,6 +11124,14 @@ var require_CodeGenService = __commonJS({
|
|
|
11116
11124
|
}
|
|
11117
11125
|
};
|
|
11118
11126
|
}
|
|
11127
|
+
exports2.REQUEST_TIMEOUT_MS = 12e4;
|
|
11128
|
+
exports2.FETCH_TIMEOUT_MS = 3e4;
|
|
11129
|
+
function isNotFound(error) {
|
|
11130
|
+
return http_client_1.HttpClient.isHttpError(error) && error.response?.status === 404;
|
|
11131
|
+
}
|
|
11132
|
+
function mapRequest(req, fn) {
|
|
11133
|
+
return typeof req === "function" ? (ctx) => fn(req(ctx)) : fn(req);
|
|
11134
|
+
}
|
|
11119
11135
|
var CodeGenService = class {
|
|
11120
11136
|
constructor(projectId, httpClient) {
|
|
11121
11137
|
this.projectId = projectId;
|
|
@@ -11126,15 +11142,16 @@ var require_CodeGenService = __commonJS({
|
|
|
11126
11142
|
this.setAccessToken(token);
|
|
11127
11143
|
return token;
|
|
11128
11144
|
};
|
|
11129
|
-
this.request = async (req) => {
|
|
11145
|
+
this.request = async (req, timeout) => {
|
|
11146
|
+
const build = () => this.withTimeout(this.withAuth(req), timeout);
|
|
11130
11147
|
try {
|
|
11131
|
-
return await this.httpClient.request(
|
|
11148
|
+
return await this.httpClient.request(build());
|
|
11132
11149
|
} catch (err) {
|
|
11133
11150
|
if (!this.isUnauthorized(err))
|
|
11134
11151
|
throw err;
|
|
11135
11152
|
logger_12.logger.warn("[CodeGenService] 401 received, refreshing token and retrying once");
|
|
11136
11153
|
await this.refreshAccessToken();
|
|
11137
|
-
return await this.httpClient.request(
|
|
11154
|
+
return await this.httpClient.request(build());
|
|
11138
11155
|
}
|
|
11139
11156
|
};
|
|
11140
11157
|
this.fetchPendingJobs = async () => {
|
|
@@ -11145,10 +11162,19 @@ var require_CodeGenService = __commonJS({
|
|
|
11145
11162
|
paging: { limit: 1 },
|
|
11146
11163
|
sortOrder: types_1.JobsSortOrder.CREATED_AT_ASC
|
|
11147
11164
|
} : void 0;
|
|
11148
|
-
const resp = await this.request((0, http_1.listProjectJobs)(filtered ?? { projectId: this.projectId }));
|
|
11165
|
+
const resp = await this.request((0, http_1.listProjectJobs)(filtered ?? { projectId: this.projectId }), exports2.FETCH_TIMEOUT_MS);
|
|
11149
11166
|
const jobs = resp.data?.jobs ?? [];
|
|
11150
11167
|
return filtered ? jobs : jobs.filter(this.shouldProcessJob);
|
|
11151
11168
|
};
|
|
11169
|
+
this.findJob = async (jobId) => {
|
|
11170
|
+
try {
|
|
11171
|
+
return await this.getJob(jobId, exports2.FETCH_TIMEOUT_MS);
|
|
11172
|
+
} catch (error) {
|
|
11173
|
+
if (isNotFound(error))
|
|
11174
|
+
return null;
|
|
11175
|
+
throw error;
|
|
11176
|
+
}
|
|
11177
|
+
};
|
|
11152
11178
|
this.shouldProcessJob = (job) => {
|
|
11153
11179
|
if (job.status !== types_1.Status.PENDING)
|
|
11154
11180
|
return false;
|
|
@@ -11279,11 +11305,11 @@ var require_CodeGenService = __commonJS({
|
|
|
11279
11305
|
}
|
|
11280
11306
|
}));
|
|
11281
11307
|
};
|
|
11282
|
-
this.getJob = async (jobId) => {
|
|
11308
|
+
this.getJob = async (jobId, timeout) => {
|
|
11283
11309
|
const resp = await this.request((0, http_1.getJob)({
|
|
11284
11310
|
projectId: this.projectId,
|
|
11285
11311
|
jobId
|
|
11286
|
-
}));
|
|
11312
|
+
}), timeout);
|
|
11287
11313
|
return resp.data?.job ?? null;
|
|
11288
11314
|
};
|
|
11289
11315
|
this.runContext = (ctx) => ({
|
|
@@ -11329,6 +11355,7 @@ var require_CodeGenService = __commonJS({
|
|
|
11329
11355
|
const serverUrl = process.env.CODEGEN_SERVER_BASE_URL || "https://manage.wix.com";
|
|
11330
11356
|
this.httpClient = (0, http_client_1.createHttpClient)({
|
|
11331
11357
|
baseURL: serverUrl,
|
|
11358
|
+
timeout: exports2.REQUEST_TIMEOUT_MS,
|
|
11332
11359
|
errorHandler: createCodeGenErrorHandler(() => this.httpClient)
|
|
11333
11360
|
});
|
|
11334
11361
|
}
|
|
@@ -11346,14 +11373,16 @@ var require_CodeGenService = __commonJS({
|
|
|
11346
11373
|
return error.response?.status === 401;
|
|
11347
11374
|
}
|
|
11348
11375
|
withAuth(req) {
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
}
|
|
11355
|
-
}
|
|
11356
|
-
|
|
11376
|
+
return mapRequest(req, (r) => ({
|
|
11377
|
+
...r,
|
|
11378
|
+
headers: {
|
|
11379
|
+
...r.headers ?? {},
|
|
11380
|
+
authorization: `Bearer ${this.accessToken}`
|
|
11381
|
+
}
|
|
11382
|
+
}));
|
|
11383
|
+
}
|
|
11384
|
+
withTimeout(req, timeout) {
|
|
11385
|
+
return timeout === void 0 ? req : mapRequest(req, (r) => ({ ...r, timeout }));
|
|
11357
11386
|
}
|
|
11358
11387
|
};
|
|
11359
11388
|
exports2.CodeGenService = CodeGenService;
|
|
@@ -16508,11 +16537,13 @@ var require_utils9 = __commonJS({
|
|
|
16508
16537
|
"dist/utils.js"(exports2) {
|
|
16509
16538
|
"use strict";
|
|
16510
16539
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
16511
|
-
exports2.errorStack = void 0;
|
|
16540
|
+
exports2.errorStack = exports2.delay = void 0;
|
|
16512
16541
|
exports2.serializeError = serializeError;
|
|
16513
16542
|
exports2.updateAllRunningTasks = updateAllRunningTasks;
|
|
16514
16543
|
var types_1 = require_types_impl();
|
|
16515
16544
|
var codeGenerationService_12 = require_codeGenerationService();
|
|
16545
|
+
var delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
16546
|
+
exports2.delay = delay;
|
|
16516
16547
|
var errorStack = (error) => error instanceof Error ? error.stack ?? error.message : String(error);
|
|
16517
16548
|
exports2.errorStack = errorStack;
|
|
16518
16549
|
function serializeError(error) {
|
|
@@ -23760,7 +23791,7 @@ var require_skills_installer = __commonJS({
|
|
|
23760
23791
|
const nested = discoverSkills((0, path_12.join)(packageRoot, "skills"));
|
|
23761
23792
|
return nested.length > 0 ? nested : discoverSkills(packageRoot);
|
|
23762
23793
|
}
|
|
23763
|
-
var
|
|
23794
|
+
var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
23764
23795
|
async function applySkillsOverride(outputPath, log) {
|
|
23765
23796
|
const skillsOverride = process.env.SKILLS_OVERRIDE_BRANCH;
|
|
23766
23797
|
if (!skillsOverride) {
|
|
@@ -23806,7 +23837,7 @@ var require_skills_installer = __commonJS({
|
|
|
23806
23837
|
});
|
|
23807
23838
|
const deadline = Date.now() + timeoutMs;
|
|
23808
23839
|
while (Date.now() < deadline) {
|
|
23809
|
-
await
|
|
23840
|
+
await delay(intervalMs);
|
|
23810
23841
|
state = inspect(state.candidates);
|
|
23811
23842
|
if (state.ready) {
|
|
23812
23843
|
log.info("[Skills] Skills became available", { present: state.present });
|
|
@@ -24213,6 +24244,367 @@ var require_plugin_artifacts = __commonJS({
|
|
|
24213
24244
|
}
|
|
24214
24245
|
});
|
|
24215
24246
|
|
|
24247
|
+
// dist/fetch-scheduler.js
|
|
24248
|
+
var require_fetch_scheduler = __commonJS({
|
|
24249
|
+
"dist/fetch-scheduler.js"(exports2) {
|
|
24250
|
+
"use strict";
|
|
24251
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
24252
|
+
exports2.FetchScheduler = exports2.MAX_AWAITED_JOB_IDS = exports2.MAX_MISSING_JOB_RECHECKS = exports2.ERROR_BACKOFF_MS = exports2.POST_JOB_INTERVAL_MS = exports2.MIN_FETCH_INTERVAL_MS = void 0;
|
|
24253
|
+
var logger_12 = require_logger();
|
|
24254
|
+
var utils_12 = require_utils9();
|
|
24255
|
+
exports2.MIN_FETCH_INTERVAL_MS = 1e3;
|
|
24256
|
+
exports2.POST_JOB_INTERVAL_MS = 3e3;
|
|
24257
|
+
exports2.ERROR_BACKOFF_MS = 5e3;
|
|
24258
|
+
exports2.MAX_MISSING_JOB_RECHECKS = 3;
|
|
24259
|
+
exports2.MAX_AWAITED_JOB_IDS = 4;
|
|
24260
|
+
var FetchScheduler = class {
|
|
24261
|
+
constructor(deps) {
|
|
24262
|
+
this.deps = deps;
|
|
24263
|
+
this.cycle = null;
|
|
24264
|
+
this.checkAgain = false;
|
|
24265
|
+
this.stopped = false;
|
|
24266
|
+
this.nextFetchNotBefore = 0;
|
|
24267
|
+
this.interval = 0;
|
|
24268
|
+
this.awaitedJobIds = /* @__PURE__ */ new Map();
|
|
24269
|
+
}
|
|
24270
|
+
start() {
|
|
24271
|
+
this.stopped = false;
|
|
24272
|
+
}
|
|
24273
|
+
/** A cycle already inside runJob is NOT awaited. A caller that needs exclusivity must
|
|
24274
|
+
* not start another runner until that cycle settles. */
|
|
24275
|
+
stop() {
|
|
24276
|
+
this.stopped = true;
|
|
24277
|
+
}
|
|
24278
|
+
/** Records the nudge and makes sure a cycle is running. It does not wait for the
|
|
24279
|
+
* fetch. A caller held on a slow socket times out and reads that as "machine down",
|
|
24280
|
+
* so retrying is ours to do, not theirs. */
|
|
24281
|
+
nudge(jobId) {
|
|
24282
|
+
if (this.stopped)
|
|
24283
|
+
return;
|
|
24284
|
+
if (jobId) {
|
|
24285
|
+
this.awaitedJobIds.delete(jobId);
|
|
24286
|
+
if (this.awaitedJobIds.size >= exports2.MAX_AWAITED_JOB_IDS) {
|
|
24287
|
+
this.awaitedJobIds.delete(this.awaitedJobIds.keys().next().value);
|
|
24288
|
+
}
|
|
24289
|
+
this.awaitedJobIds.set(jobId, exports2.MAX_MISSING_JOB_RECHECKS);
|
|
24290
|
+
}
|
|
24291
|
+
if (this.cycle) {
|
|
24292
|
+
this.checkAgain = true;
|
|
24293
|
+
return;
|
|
24294
|
+
}
|
|
24295
|
+
this.cycle = this.runUntilIdle().catch((error) => logger_12.logger.error("[JobFetch] Cycle aborted", { error: (0, utils_12.errorStack)(error) }));
|
|
24296
|
+
}
|
|
24297
|
+
async runUntilIdle() {
|
|
24298
|
+
try {
|
|
24299
|
+
do {
|
|
24300
|
+
await this.runSingleJobCycle();
|
|
24301
|
+
} while (this.checkAgain && !this.stopped);
|
|
24302
|
+
} finally {
|
|
24303
|
+
this.cycle = null;
|
|
24304
|
+
}
|
|
24305
|
+
}
|
|
24306
|
+
async runSingleJobCycle() {
|
|
24307
|
+
await this.throttle();
|
|
24308
|
+
if (this.stopped)
|
|
24309
|
+
return;
|
|
24310
|
+
this.checkAgain = false;
|
|
24311
|
+
const due = await this.findRunnableJob();
|
|
24312
|
+
if (!due)
|
|
24313
|
+
return;
|
|
24314
|
+
this.checkAgain = true;
|
|
24315
|
+
if (this.stopped)
|
|
24316
|
+
return;
|
|
24317
|
+
await this.attemptJob(due);
|
|
24318
|
+
}
|
|
24319
|
+
async findRunnableJob() {
|
|
24320
|
+
let jobs;
|
|
24321
|
+
try {
|
|
24322
|
+
jobs = await this.deps.fetchPendingJobs();
|
|
24323
|
+
} catch (error) {
|
|
24324
|
+
this.recordDebt("Fetch failed", error);
|
|
24325
|
+
return null;
|
|
24326
|
+
}
|
|
24327
|
+
this.schedule(exports2.MIN_FETCH_INTERVAL_MS);
|
|
24328
|
+
logger_12.logger.info("[JobFetch] Fetched pending jobs", { count: jobs.length });
|
|
24329
|
+
for (const job of jobs) {
|
|
24330
|
+
if (job.id)
|
|
24331
|
+
this.awaitedJobIds.delete(job.id);
|
|
24332
|
+
}
|
|
24333
|
+
if (jobs.length > 0)
|
|
24334
|
+
return jobs[0];
|
|
24335
|
+
if (this.awaitedJobIds.size === 0)
|
|
24336
|
+
return null;
|
|
24337
|
+
try {
|
|
24338
|
+
return await this.claimNudgedJob();
|
|
24339
|
+
} catch (error) {
|
|
24340
|
+
this.recordDebt("Nudged job lookup failed", error);
|
|
24341
|
+
return null;
|
|
24342
|
+
}
|
|
24343
|
+
}
|
|
24344
|
+
async attemptJob(job) {
|
|
24345
|
+
try {
|
|
24346
|
+
await this.deps.runJob(job);
|
|
24347
|
+
this.schedule(exports2.POST_JOB_INTERVAL_MS);
|
|
24348
|
+
} catch (error) {
|
|
24349
|
+
this.recordDebt("Job run failed", error);
|
|
24350
|
+
}
|
|
24351
|
+
}
|
|
24352
|
+
/** A nudged job the list did not return. Read it by key, which does not wait on the
|
|
24353
|
+
* index. A key read is still a replica read, so a job the server does not know about
|
|
24354
|
+
* yet keeps a small budget of re-checks instead of one answer settling it. */
|
|
24355
|
+
async claimNudgedJob() {
|
|
24356
|
+
for (const jobId of [...this.awaitedJobIds.keys()]) {
|
|
24357
|
+
if (this.stopped)
|
|
24358
|
+
return null;
|
|
24359
|
+
const job = await this.deps.findJob(jobId);
|
|
24360
|
+
if (job) {
|
|
24361
|
+
this.awaitedJobIds.delete(jobId);
|
|
24362
|
+
if (this.deps.canRunJob(job))
|
|
24363
|
+
return job;
|
|
24364
|
+
continue;
|
|
24365
|
+
}
|
|
24366
|
+
const rechecksLeft = this.awaitedJobIds.get(jobId);
|
|
24367
|
+
if (rechecksLeft === void 0)
|
|
24368
|
+
continue;
|
|
24369
|
+
if (rechecksLeft > 0) {
|
|
24370
|
+
this.awaitedJobIds.set(jobId, rechecksLeft - 1);
|
|
24371
|
+
this.checkAgain = true;
|
|
24372
|
+
} else {
|
|
24373
|
+
this.awaitedJobIds.delete(jobId);
|
|
24374
|
+
logger_12.logger.warn("[JobFetch] Nudged job does not exist", { jobId });
|
|
24375
|
+
}
|
|
24376
|
+
}
|
|
24377
|
+
return null;
|
|
24378
|
+
}
|
|
24379
|
+
schedule(intervalMs) {
|
|
24380
|
+
this.interval = intervalMs;
|
|
24381
|
+
this.nextFetchNotBefore = Date.now() + intervalMs;
|
|
24382
|
+
}
|
|
24383
|
+
/** Nobody else will retry. We already answered the caller 200. */
|
|
24384
|
+
recordDebt(what, error) {
|
|
24385
|
+
logger_12.logger.error(`[JobFetch] ${what}`, { error: (0, utils_12.errorStack)(error) });
|
|
24386
|
+
this.checkAgain = true;
|
|
24387
|
+
this.schedule(exports2.ERROR_BACKOFF_MS);
|
|
24388
|
+
}
|
|
24389
|
+
async throttle() {
|
|
24390
|
+
const wait = Math.min(this.nextFetchNotBefore - Date.now(), this.interval);
|
|
24391
|
+
if (wait > 0)
|
|
24392
|
+
await (0, utils_12.delay)(wait);
|
|
24393
|
+
}
|
|
24394
|
+
};
|
|
24395
|
+
exports2.FetchScheduler = FetchScheduler;
|
|
24396
|
+
}
|
|
24397
|
+
});
|
|
24398
|
+
|
|
24399
|
+
// dist/nudge-listener-server.js
|
|
24400
|
+
var require_nudge_listener_server = __commonJS({
|
|
24401
|
+
"dist/nudge-listener-server.js"(exports2) {
|
|
24402
|
+
"use strict";
|
|
24403
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
24404
|
+
exports2.NudgeListenerServer = exports2.BIND_RETRY_DELAY_MS = exports2.BIND_RETRIES = exports2.MAX_LOGGED_PATH_LENGTH = exports2.JOB_ID_PATTERN = exports2.JOB_FETCH_PATH = exports2.JOB_FETCH_PORT = void 0;
|
|
24405
|
+
var node_http_1 = require("node:http");
|
|
24406
|
+
var logger_12 = require_logger();
|
|
24407
|
+
var utils_12 = require_utils9();
|
|
24408
|
+
var fetch_scheduler_1 = require_fetch_scheduler();
|
|
24409
|
+
exports2.JOB_FETCH_PORT = 52402;
|
|
24410
|
+
exports2.JOB_FETCH_PATH = "/_wix/codegen/fetch-jobs";
|
|
24411
|
+
exports2.JOB_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
24412
|
+
exports2.MAX_LOGGED_PATH_LENGTH = 128;
|
|
24413
|
+
exports2.BIND_RETRIES = 5;
|
|
24414
|
+
exports2.BIND_RETRY_DELAY_MS = 300;
|
|
24415
|
+
var NudgeListenerServer = class {
|
|
24416
|
+
constructor(deps, port = exports2.JOB_FETCH_PORT) {
|
|
24417
|
+
this.port = port;
|
|
24418
|
+
this.server = null;
|
|
24419
|
+
this.stopped = false;
|
|
24420
|
+
this.scheduler = new fetch_scheduler_1.FetchScheduler(deps);
|
|
24421
|
+
}
|
|
24422
|
+
async start() {
|
|
24423
|
+
this.stopped = false;
|
|
24424
|
+
this.scheduler.start();
|
|
24425
|
+
await this.listen();
|
|
24426
|
+
if (this.stopped) {
|
|
24427
|
+
await this.stop();
|
|
24428
|
+
throw new Error("Nudge listener was stopped while binding");
|
|
24429
|
+
}
|
|
24430
|
+
logger_12.logger.info("[JobFetch] Endpoint listening", {
|
|
24431
|
+
port: this.boundPort(),
|
|
24432
|
+
path: exports2.JOB_FETCH_PATH
|
|
24433
|
+
});
|
|
24434
|
+
this.scheduler.nudge();
|
|
24435
|
+
}
|
|
24436
|
+
/** Closes the socket and stops the scheduler; a cycle already inside runJob is NOT
|
|
24437
|
+
* awaited. A caller that needs exclusivity must not start another runner until that
|
|
24438
|
+
* cycle settles. */
|
|
24439
|
+
async stop() {
|
|
24440
|
+
this.stopped = true;
|
|
24441
|
+
this.scheduler.stop();
|
|
24442
|
+
const server = this.server;
|
|
24443
|
+
if (!server)
|
|
24444
|
+
return;
|
|
24445
|
+
this.server = null;
|
|
24446
|
+
server.removeAllListeners("error");
|
|
24447
|
+
server.on("error", (error) => logger_12.logger.warn("[JobFetch] Endpoint error while closing", {
|
|
24448
|
+
error: (0, utils_12.errorStack)(error)
|
|
24449
|
+
}));
|
|
24450
|
+
server.closeAllConnections();
|
|
24451
|
+
await new Promise((resolve) => server.close(() => resolve()));
|
|
24452
|
+
}
|
|
24453
|
+
boundPort() {
|
|
24454
|
+
const address = this.server?.address();
|
|
24455
|
+
return address && typeof address === "object" ? address.port : null;
|
|
24456
|
+
}
|
|
24457
|
+
/** The agent is restarted in a tight `while true` loop, so a bind can land before
|
|
24458
|
+
* the previous process has released the port. Falling straight back to poll there
|
|
24459
|
+
* would strand the machine on the slow path for the whole session. */
|
|
24460
|
+
async listen() {
|
|
24461
|
+
for (let attempt = 0; ; attempt++) {
|
|
24462
|
+
try {
|
|
24463
|
+
return await this.listenOnce();
|
|
24464
|
+
} catch (error) {
|
|
24465
|
+
const inUse = error?.code === "EADDRINUSE" && attempt < exports2.BIND_RETRIES;
|
|
24466
|
+
if (!inUse)
|
|
24467
|
+
throw error;
|
|
24468
|
+
await (0, utils_12.delay)(exports2.BIND_RETRY_DELAY_MS);
|
|
24469
|
+
}
|
|
24470
|
+
}
|
|
24471
|
+
}
|
|
24472
|
+
listenOnce() {
|
|
24473
|
+
return new Promise((resolve, reject) => {
|
|
24474
|
+
const server = (0, node_http_1.createServer)((req, res) => {
|
|
24475
|
+
try {
|
|
24476
|
+
this.handleRequest(req, res);
|
|
24477
|
+
} catch (error) {
|
|
24478
|
+
logger_12.logger.error("[JobFetch] Request handler failed", {
|
|
24479
|
+
error: (0, utils_12.errorStack)(error)
|
|
24480
|
+
});
|
|
24481
|
+
if (res.headersSent)
|
|
24482
|
+
res.destroy();
|
|
24483
|
+
else
|
|
24484
|
+
this.respond(res, 500, { error: "request failed" });
|
|
24485
|
+
}
|
|
24486
|
+
});
|
|
24487
|
+
server.once("error", reject);
|
|
24488
|
+
server.listen(this.port, "0.0.0.0", () => {
|
|
24489
|
+
server.removeListener("error", reject);
|
|
24490
|
+
server.on("error", (error) => {
|
|
24491
|
+
logger_12.logger.error("[JobFetch] Endpoint failed after binding, exiting", {
|
|
24492
|
+
error: (0, utils_12.errorStack)(error)
|
|
24493
|
+
});
|
|
24494
|
+
process.exit(1);
|
|
24495
|
+
});
|
|
24496
|
+
this.server = server;
|
|
24497
|
+
resolve();
|
|
24498
|
+
});
|
|
24499
|
+
});
|
|
24500
|
+
}
|
|
24501
|
+
handleRequest(req, res) {
|
|
24502
|
+
const url = new URL((req.url ?? "").replace(/^\/+/, "/"), "http://localhost");
|
|
24503
|
+
const path = url.pathname.replace(/\/+$/, "");
|
|
24504
|
+
if (req.method !== "GET" || path !== exports2.JOB_FETCH_PATH) {
|
|
24505
|
+
logger_12.logger.warn("[JobFetch] Rejected request", {
|
|
24506
|
+
method: req.method,
|
|
24507
|
+
path: url.pathname.slice(0, exports2.MAX_LOGGED_PATH_LENGTH)
|
|
24508
|
+
});
|
|
24509
|
+
this.respond(res, 404, { error: "not found" });
|
|
24510
|
+
return;
|
|
24511
|
+
}
|
|
24512
|
+
const nudgedId = url.searchParams.get("jobId");
|
|
24513
|
+
const usable = nudgedId === null || exports2.JOB_ID_PATTERN.test(nudgedId);
|
|
24514
|
+
if (!usable) {
|
|
24515
|
+
logger_12.logger.warn("[JobFetch] Nudge carried an unusable jobId", {
|
|
24516
|
+
length: nudgedId.length
|
|
24517
|
+
});
|
|
24518
|
+
}
|
|
24519
|
+
const jobId = usable ? nudgedId ?? void 0 : void 0;
|
|
24520
|
+
this.scheduler.nudge(jobId);
|
|
24521
|
+
logger_12.logger.info("[JobFetch] Nudge accepted", { jobId });
|
|
24522
|
+
this.respond(res, 200, { accepted: true });
|
|
24523
|
+
}
|
|
24524
|
+
respond(res, status, body) {
|
|
24525
|
+
res.writeHead(status, {
|
|
24526
|
+
"Content-Type": "application/json",
|
|
24527
|
+
// A cached response would turn every nudge into a no-op.
|
|
24528
|
+
"Cache-Control": "no-store"
|
|
24529
|
+
});
|
|
24530
|
+
res.end(JSON.stringify(body));
|
|
24531
|
+
}
|
|
24532
|
+
};
|
|
24533
|
+
exports2.NudgeListenerServer = NudgeListenerServer;
|
|
24534
|
+
}
|
|
24535
|
+
});
|
|
24536
|
+
|
|
24537
|
+
// dist/job-fetching.js
|
|
24538
|
+
var require_job_fetching = __commonJS({
|
|
24539
|
+
"dist/job-fetching.js"(exports2) {
|
|
24540
|
+
"use strict";
|
|
24541
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
24542
|
+
exports2.JobDeliveryMode = void 0;
|
|
24543
|
+
exports2.getJobDeliveryMode = getJobDeliveryMode;
|
|
24544
|
+
exports2.getJobFetchPort = getJobFetchPort;
|
|
24545
|
+
exports2.startJobFetching = startJobFetching;
|
|
24546
|
+
var nudge_listener_server_12 = require_nudge_listener_server();
|
|
24547
|
+
var logger_12 = require_logger();
|
|
24548
|
+
var utils_12 = require_utils9();
|
|
24549
|
+
var JobDeliveryMode;
|
|
24550
|
+
(function(JobDeliveryMode2) {
|
|
24551
|
+
JobDeliveryMode2["POLL"] = "poll";
|
|
24552
|
+
JobDeliveryMode2["PUSH"] = "push";
|
|
24553
|
+
})(JobDeliveryMode || (exports2.JobDeliveryMode = JobDeliveryMode = {}));
|
|
24554
|
+
var DEFAULT_MODE = JobDeliveryMode.POLL;
|
|
24555
|
+
function getJobDeliveryMode() {
|
|
24556
|
+
const mode = process.env.CODEGEN_JOB_DELIVERY?.trim().toLowerCase();
|
|
24557
|
+
const supported = Object.values(JobDeliveryMode).find((candidate) => candidate === mode);
|
|
24558
|
+
if (supported)
|
|
24559
|
+
return supported;
|
|
24560
|
+
if (mode) {
|
|
24561
|
+
logger_12.logger.warn("[Startup] Unrecognized CODEGEN_JOB_DELIVERY, using default", {
|
|
24562
|
+
mode,
|
|
24563
|
+
default: DEFAULT_MODE
|
|
24564
|
+
});
|
|
24565
|
+
}
|
|
24566
|
+
return DEFAULT_MODE;
|
|
24567
|
+
}
|
|
24568
|
+
var MIN_PORT = 1;
|
|
24569
|
+
var MAX_PORT = 65535;
|
|
24570
|
+
function getJobFetchPort() {
|
|
24571
|
+
const configured = process.env.CODEGEN_JOB_FETCH_PORT;
|
|
24572
|
+
if (configured === void 0)
|
|
24573
|
+
return nudge_listener_server_12.JOB_FETCH_PORT;
|
|
24574
|
+
const port = /^\s*\d+\s*$/.test(configured) ? Number(configured) : NaN;
|
|
24575
|
+
if (Number.isInteger(port) && port >= MIN_PORT && port <= MAX_PORT)
|
|
24576
|
+
return port;
|
|
24577
|
+
logger_12.logger.warn("[Startup] Unusable CODEGEN_JOB_FETCH_PORT, using default", {
|
|
24578
|
+
port: configured,
|
|
24579
|
+
default: nudge_listener_server_12.JOB_FETCH_PORT
|
|
24580
|
+
});
|
|
24581
|
+
return nudge_listener_server_12.JOB_FETCH_PORT;
|
|
24582
|
+
}
|
|
24583
|
+
async function startJobFetching(deps) {
|
|
24584
|
+
const mode = getJobDeliveryMode();
|
|
24585
|
+
logger_12.logger.info("[Startup] Job delivery mode", { mode });
|
|
24586
|
+
if (mode === JobDeliveryMode.POLL) {
|
|
24587
|
+
return deps.runPollLoop();
|
|
24588
|
+
}
|
|
24589
|
+
try {
|
|
24590
|
+
await deps.nudgeListenerServer.start();
|
|
24591
|
+
} catch (error) {
|
|
24592
|
+
try {
|
|
24593
|
+
await deps.nudgeListenerServer.stop();
|
|
24594
|
+
} catch (stopError) {
|
|
24595
|
+
logger_12.logger.error("[Startup] Closing the half-started listener failed", {
|
|
24596
|
+
error: (0, utils_12.errorStack)(stopError)
|
|
24597
|
+
});
|
|
24598
|
+
}
|
|
24599
|
+
logger_12.logger.error("[Startup] Push delivery unavailable, falling back to poll", {
|
|
24600
|
+
error: (0, utils_12.errorStack)(error)
|
|
24601
|
+
});
|
|
24602
|
+
return deps.runPollLoop();
|
|
24603
|
+
}
|
|
24604
|
+
}
|
|
24605
|
+
}
|
|
24606
|
+
});
|
|
24607
|
+
|
|
24216
24608
|
// dist/index.js
|
|
24217
24609
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24218
24610
|
exports.processJob = processJob;
|
|
@@ -24241,61 +24633,67 @@ var subagent_tool_logger_1 = require_subagent_tool_logger();
|
|
|
24241
24633
|
var plugin_artifacts_1 = require_plugin_artifacts();
|
|
24242
24634
|
var config_1 = require_config();
|
|
24243
24635
|
var environments_1 = require_environments();
|
|
24244
|
-
var plugin_host_1 = require_plugin_host();
|
|
24245
24636
|
var utils_1 = require_utils9();
|
|
24637
|
+
var job_fetching_1 = require_job_fetching();
|
|
24638
|
+
var nudge_listener_server_1 = require_nudge_listener_server();
|
|
24639
|
+
var plugin_host_1 = require_plugin_host();
|
|
24640
|
+
var utils_2 = require_utils9();
|
|
24246
24641
|
var sessionId = process.env.CODEGEN_SESSION_ID || (0, crypto_1.randomUUID)();
|
|
24247
24642
|
process.env.CODEGEN_SESSION_ID = sessionId;
|
|
24248
24643
|
(0, logger_1.initLogger)(sessionId);
|
|
24249
24644
|
var jobCancellationMonitor = new job_cancellation_monitor_1.JobCancellationMonitor(codeGenerationService_1.codeGenerationService);
|
|
24250
24645
|
var jobTimeoutMonitor = new job_timeout_monitor_1.JobTimeoutMonitor(codeGenerationService_1.codeGenerationService);
|
|
24251
|
-
var
|
|
24646
|
+
var POLL_LOG_PREFIX = "[Loop]";
|
|
24647
|
+
var PUSH_LOG_PREFIX = "[JobFetch]";
|
|
24252
24648
|
var ACTIVE_JOB_SLEEP_MS = 1e3;
|
|
24253
24649
|
var NO_JOBS_SLEEP_MS = 5e3;
|
|
24254
24650
|
var POST_JOB_SLEEP_MS = 3e3;
|
|
24651
|
+
var runPendingJob = async (job, logPrefix) => {
|
|
24652
|
+
const redactAgentData = (payload) => payload?.agentData ? { ...payload, agentData: Object.keys(payload.agentData) } : payload;
|
|
24653
|
+
logger_1.logger.info("Job details", {
|
|
24654
|
+
job: {
|
|
24655
|
+
...job,
|
|
24656
|
+
tasks: job.tasks?.map((task) => ({
|
|
24657
|
+
...task,
|
|
24658
|
+
input: redactAgentData(task.input),
|
|
24659
|
+
payload: redactAgentData(task.payload)
|
|
24660
|
+
}))
|
|
24661
|
+
}
|
|
24662
|
+
});
|
|
24663
|
+
if (!job.id) {
|
|
24664
|
+
throw new ditto_codegen_types_1.MissingJobIdError();
|
|
24665
|
+
}
|
|
24666
|
+
const jobId = job.id;
|
|
24667
|
+
logger_1.logger.info(`${logPrefix} Selected job`, { jobId });
|
|
24668
|
+
const freshToken = await codeGenerationService_1.codeGenerationService.refreshAccessToken();
|
|
24669
|
+
(0, config_1.setCurrentAccessToken)(freshToken);
|
|
24670
|
+
await codeGenerationService_1.codeGenerationService.markJobAsRuninng(jobId);
|
|
24671
|
+
await processJob(job);
|
|
24672
|
+
await codeGenerationService_1.codeGenerationService.markJobAsCompleted(jobId);
|
|
24673
|
+
logger_1.logger.info(`${logPrefix} Processed job`, { jobId });
|
|
24674
|
+
};
|
|
24255
24675
|
var alwaysOnLoop = async () => {
|
|
24256
24676
|
while (true) {
|
|
24257
24677
|
try {
|
|
24258
24678
|
if (context_1.ctx.hasActiveJobs()) {
|
|
24259
24679
|
console.log(`[Loop] Local active job in progress. Sleeping ${ACTIVE_JOB_SLEEP_MS}ms`);
|
|
24260
|
-
await delay(ACTIVE_JOB_SLEEP_MS);
|
|
24680
|
+
await (0, utils_1.delay)(ACTIVE_JOB_SLEEP_MS);
|
|
24261
24681
|
continue;
|
|
24262
24682
|
}
|
|
24263
24683
|
const jobs = await codeGenerationService_1.codeGenerationService.fetchPendingJobs();
|
|
24264
24684
|
console.log("[Loop] Fetched pending jobs", { count: jobs.length });
|
|
24265
24685
|
if (jobs.length === 0) {
|
|
24266
24686
|
console.log("[Loop] No pending jobs, sleeping");
|
|
24267
|
-
await delay(NO_JOBS_SLEEP_MS);
|
|
24687
|
+
await (0, utils_1.delay)(NO_JOBS_SLEEP_MS);
|
|
24268
24688
|
continue;
|
|
24269
24689
|
}
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
logger_1.logger.info("Job details", {
|
|
24273
|
-
job: {
|
|
24274
|
-
...job,
|
|
24275
|
-
tasks: job.tasks?.map((task) => ({
|
|
24276
|
-
...task,
|
|
24277
|
-
input: redactAgentData(task.input),
|
|
24278
|
-
payload: redactAgentData(task.payload)
|
|
24279
|
-
}))
|
|
24280
|
-
}
|
|
24281
|
-
});
|
|
24282
|
-
if (!job.id) {
|
|
24283
|
-
throw new ditto_codegen_types_1.MissingJobIdError();
|
|
24284
|
-
}
|
|
24285
|
-
const jobId = job.id;
|
|
24286
|
-
logger_1.logger.info("[Loop] Selected job", { jobId });
|
|
24287
|
-
const freshToken = await codeGenerationService_1.codeGenerationService.refreshAccessToken();
|
|
24288
|
-
(0, config_1.setCurrentAccessToken)(freshToken);
|
|
24289
|
-
await codeGenerationService_1.codeGenerationService.markJobAsRuninng(jobId);
|
|
24290
|
-
await processJob(job);
|
|
24291
|
-
await codeGenerationService_1.codeGenerationService.markJobAsCompleted(jobId);
|
|
24292
|
-
logger_1.logger.info("[Loop] Processed job", { jobId });
|
|
24293
|
-
await delay(POST_JOB_SLEEP_MS);
|
|
24690
|
+
await runPendingJob(jobs[0], POLL_LOG_PREFIX);
|
|
24691
|
+
await (0, utils_1.delay)(POST_JOB_SLEEP_MS);
|
|
24294
24692
|
} catch (loopError) {
|
|
24295
24693
|
logger_1.logger.error("Polling loop encountered an error. Will continue after backoff:", {
|
|
24296
24694
|
error: loopError instanceof Error ? loopError.message : String(loopError)
|
|
24297
24695
|
});
|
|
24298
|
-
await delay(NO_JOBS_SLEEP_MS);
|
|
24696
|
+
await (0, utils_1.delay)(NO_JOBS_SLEEP_MS);
|
|
24299
24697
|
}
|
|
24300
24698
|
context_1.ctx.resetJobs();
|
|
24301
24699
|
}
|
|
@@ -24333,7 +24731,13 @@ async function main(ctx) {
|
|
|
24333
24731
|
metasiteId: ctx.metasiteId
|
|
24334
24732
|
});
|
|
24335
24733
|
await initOpenCode();
|
|
24336
|
-
|
|
24734
|
+
const nudgeListenerServer = new nudge_listener_server_1.NudgeListenerServer({
|
|
24735
|
+
fetchPendingJobs: () => codeGenerationService_1.codeGenerationService.fetchPendingJobs(),
|
|
24736
|
+
findJob: (jobId) => codeGenerationService_1.codeGenerationService.findJob(jobId),
|
|
24737
|
+
canRunJob: (job) => codeGenerationService_1.codeGenerationService.shouldProcessJob(job),
|
|
24738
|
+
runJob: (job) => runPendingJob(job, PUSH_LOG_PREFIX)
|
|
24739
|
+
}, (0, job_fetching_1.getJobFetchPort)());
|
|
24740
|
+
await (0, job_fetching_1.startJobFetching)({ runPollLoop: alwaysOnLoop, nudgeListenerServer });
|
|
24337
24741
|
}
|
|
24338
24742
|
var getFirstTask = (job) => {
|
|
24339
24743
|
return job.tasks?.[0];
|
|
@@ -24377,7 +24781,7 @@ async function reportPreDispatchFailure(jobId, error) {
|
|
|
24377
24781
|
});
|
|
24378
24782
|
try {
|
|
24379
24783
|
await codeGenerationService_1.codeGenerationService.markJobAsFailed(jobId, codegenError);
|
|
24380
|
-
await (0,
|
|
24784
|
+
await (0, utils_2.updateAllRunningTasks)(jobId, CodeGenService_1.Status.FAILED, codegenError);
|
|
24381
24785
|
} catch (reportError) {
|
|
24382
24786
|
logger_1.logger.error("[Job] Could not mark the job failed", {
|
|
24383
24787
|
jobId,
|
|
@@ -24444,6 +24848,7 @@ async function processJob(job) {
|
|
|
24444
24848
|
} finally {
|
|
24445
24849
|
jobCancellationMonitor.stop();
|
|
24446
24850
|
jobTimeoutMonitor.stop();
|
|
24851
|
+
context_1.ctx.resetJobs();
|
|
24447
24852
|
}
|
|
24448
24853
|
});
|
|
24449
24854
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/ditto-codegen-public",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.442",
|
|
4
4
|
"description": "AI-powered Wix CLI app generator - standalone executable",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "node build.mjs",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"esbuild": "^0.27.2",
|
|
30
30
|
"vitest": "^4.0.16"
|
|
31
31
|
},
|
|
32
|
-
"falconPackageHash": "
|
|
32
|
+
"falconPackageHash": "19c7b1e106b5b7a1aa3bc62b9fc8ebae4ce01f8641d5971c6e7138c3"
|
|
33
33
|
}
|