@ai-ecoverse/slicc-kernel 1.174.1 → 1.174.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/dist/index.js +33 -0
- package/dist/index.js.map +3 -3
- package/dist/kernel-worker.js +216 -70
- package/dist/kernel-worker.js.map +4 -4
- package/dist/node-process-worker.cjs +1 -1
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +217 -70
- package/dist/node.js.map +4 -4
- package/dist/process-worker.js +1 -1
- package/dist/testing.js +4 -2
- package/dist/testing.js.map +2 -2
- package/dist/types/cron/clock.d.ts +3 -1
- package/dist/types/cron/schedule.d.ts +5 -3
- package/dist/types/cron/service.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/launcher.d.ts +3 -1
- package/dist/types/node.d.ts +2 -1
- package/dist/types/serve.d.ts +1 -0
- package/dist/types/time-zone.d.ts +11 -0
- package/package.json +1 -1
package/dist/kernel-worker.js
CHANGED
|
@@ -8740,7 +8740,7 @@ function satisfies(version, range2) {
|
|
|
8740
8740
|
}
|
|
8741
8741
|
|
|
8742
8742
|
// src/version.ts
|
|
8743
|
-
var KERNEL_VERSION = true ? "1.174.
|
|
8743
|
+
var KERNEL_VERSION = true ? "1.174.2" : "0.0.0-dev";
|
|
8744
8744
|
var OS_RELEASE = "6.0.0-slicc";
|
|
8745
8745
|
function procVersion() {
|
|
8746
8746
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -9152,6 +9152,27 @@ function binfmtOf(binfmts, path) {
|
|
|
9152
9152
|
return best === void 0 ? void 0 : binfmts.get(best);
|
|
9153
9153
|
}
|
|
9154
9154
|
|
|
9155
|
+
// src/cron/clock.ts
|
|
9156
|
+
function clockZone(clock) {
|
|
9157
|
+
return clock?.timeZone ?? (clock?.utc === true ? "UTC" : void 0);
|
|
9158
|
+
}
|
|
9159
|
+
var systemCronClock = {
|
|
9160
|
+
now: () => Date.now(),
|
|
9161
|
+
sleep(until2, signal) {
|
|
9162
|
+
if (signal.aborted) return Promise.resolve();
|
|
9163
|
+
return new Promise((resolve2) => {
|
|
9164
|
+
const done5 = () => {
|
|
9165
|
+
clearTimeout(timer);
|
|
9166
|
+
signal.removeEventListener("abort", done5);
|
|
9167
|
+
resolve2();
|
|
9168
|
+
};
|
|
9169
|
+
const timer = setTimeout(done5, Math.max(0, until2 - Date.now()));
|
|
9170
|
+
timer.unref?.();
|
|
9171
|
+
signal.addEventListener("abort", done5, { once: true });
|
|
9172
|
+
});
|
|
9173
|
+
}
|
|
9174
|
+
};
|
|
9175
|
+
|
|
9155
9176
|
// src/cron/command.ts
|
|
9156
9177
|
var CRONTAB_PATH = "/usr/bin/crontab";
|
|
9157
9178
|
var CRONTAB_COMMAND = {
|
|
@@ -9263,6 +9284,94 @@ var CRONTAB_SOURCE = `export default async function crontab(ctx) {
|
|
|
9263
9284
|
}
|
|
9264
9285
|
`;
|
|
9265
9286
|
|
|
9287
|
+
// src/time-zone.ts
|
|
9288
|
+
var MINUTE_MS = 6e4;
|
|
9289
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
9290
|
+
var BUCKET_MS = 15 * MINUTE_MS;
|
|
9291
|
+
var CACHE_MAX = 4096;
|
|
9292
|
+
var ZERO = /* @__PURE__ */ new Set(["UTC", "Etc/UTC", "Etc/GMT", "GMT", "Etc/Universal", "Etc/Zulu"]);
|
|
9293
|
+
function canonicalZone(name2) {
|
|
9294
|
+
if (typeof name2 !== "string" || name2 === "" || name2.length > 64) return void 0;
|
|
9295
|
+
try {
|
|
9296
|
+
return new Intl.DateTimeFormat("en-US", { timeZone: name2 }).resolvedOptions().timeZone;
|
|
9297
|
+
} catch {
|
|
9298
|
+
return void 0;
|
|
9299
|
+
}
|
|
9300
|
+
}
|
|
9301
|
+
function hostTimeZone() {
|
|
9302
|
+
let name2;
|
|
9303
|
+
try {
|
|
9304
|
+
name2 = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
9305
|
+
} catch {
|
|
9306
|
+
name2 = void 0;
|
|
9307
|
+
}
|
|
9308
|
+
return canonicalZone(name2) ?? "UTC";
|
|
9309
|
+
}
|
|
9310
|
+
function systemTimeZone(given, fallback) {
|
|
9311
|
+
if (given !== void 0) {
|
|
9312
|
+
const zone = canonicalZone(given);
|
|
9313
|
+
if (zone === void 0) throw new Error(`not a time zone: ${String(given)}`);
|
|
9314
|
+
return zone;
|
|
9315
|
+
}
|
|
9316
|
+
return canonicalZone(fallback) ?? hostTimeZone();
|
|
9317
|
+
}
|
|
9318
|
+
var utcZone = { name: "UTC", offset: () => 0 };
|
|
9319
|
+
function hostZone(name2) {
|
|
9320
|
+
return { name: name2, offset: (at) => -new Date(at).getTimezoneOffset() * MINUTE_MS };
|
|
9321
|
+
}
|
|
9322
|
+
function intlZone(name2) {
|
|
9323
|
+
const format = new Intl.DateTimeFormat("en-US", {
|
|
9324
|
+
timeZone: name2,
|
|
9325
|
+
hourCycle: "h23",
|
|
9326
|
+
year: "numeric",
|
|
9327
|
+
month: "numeric",
|
|
9328
|
+
day: "numeric",
|
|
9329
|
+
hour: "numeric",
|
|
9330
|
+
minute: "numeric",
|
|
9331
|
+
second: "numeric"
|
|
9332
|
+
});
|
|
9333
|
+
const exact = (at) => {
|
|
9334
|
+
const parts2 = {};
|
|
9335
|
+
for (const part of format.formatToParts(at)) parts2[part.type] = Number(part.value);
|
|
9336
|
+
const wall = Date.UTC(
|
|
9337
|
+
parts2.year,
|
|
9338
|
+
parts2.month - 1,
|
|
9339
|
+
parts2.day,
|
|
9340
|
+
parts2.hour,
|
|
9341
|
+
parts2.minute,
|
|
9342
|
+
parts2.second
|
|
9343
|
+
);
|
|
9344
|
+
return wall - Math.floor(at / 1e3) * 1e3;
|
|
9345
|
+
};
|
|
9346
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
9347
|
+
return {
|
|
9348
|
+
name: name2,
|
|
9349
|
+
offset(at) {
|
|
9350
|
+
const bucket = Math.floor(at / BUCKET_MS);
|
|
9351
|
+
let known = buckets.get(bucket);
|
|
9352
|
+
if (known === void 0) {
|
|
9353
|
+
const start2 = exact(bucket * BUCKET_MS);
|
|
9354
|
+
known = start2 === exact(bucket * BUCKET_MS + BUCKET_MS - MINUTE_MS) ? start2 : null;
|
|
9355
|
+
if (buckets.size >= CACHE_MAX) buckets.clear();
|
|
9356
|
+
buckets.set(bucket, known);
|
|
9357
|
+
}
|
|
9358
|
+
return known ?? exact(at);
|
|
9359
|
+
}
|
|
9360
|
+
};
|
|
9361
|
+
}
|
|
9362
|
+
var zones = /* @__PURE__ */ new Map();
|
|
9363
|
+
function zoneOf(name2) {
|
|
9364
|
+
if (ZERO.has(name2)) return utcZone;
|
|
9365
|
+
if (name2 === hostTimeZone()) return hostZone(name2);
|
|
9366
|
+
let zone = zones.get(name2);
|
|
9367
|
+
if (!zone) {
|
|
9368
|
+
zone = intlZone(name2);
|
|
9369
|
+
zones.set(name2, zone);
|
|
9370
|
+
}
|
|
9371
|
+
return zone;
|
|
9372
|
+
}
|
|
9373
|
+
var MAX_SHIFT_MS = 3 * HOUR_MS;
|
|
9374
|
+
|
|
9266
9375
|
// src/cron/schedule.ts
|
|
9267
9376
|
var MISSED_CAP = 1e5;
|
|
9268
9377
|
var MACROS = {
|
|
@@ -9334,6 +9443,7 @@ function parseSchedule(expression) {
|
|
|
9334
9443
|
);
|
|
9335
9444
|
if (weekdays.delete(7)) weekdays.add(0);
|
|
9336
9445
|
return {
|
|
9446
|
+
fixed: !parts2[0].startsWith("*") && !parts2[1].startsWith("*"),
|
|
9337
9447
|
minutes,
|
|
9338
9448
|
hours,
|
|
9339
9449
|
days,
|
|
@@ -9347,18 +9457,6 @@ function parseWhen(expression) {
|
|
|
9347
9457
|
if (expression.trim().toLowerCase() === "@reboot") return { reboot: true };
|
|
9348
9458
|
return { reboot: false, schedule: parseSchedule(expression) };
|
|
9349
9459
|
}
|
|
9350
|
-
var LOCAL = {
|
|
9351
|
-
year: (d) => d.getFullYear(),
|
|
9352
|
-
month: (d) => d.getMonth(),
|
|
9353
|
-
date: (d) => d.getDate(),
|
|
9354
|
-
day: (d) => d.getDay(),
|
|
9355
|
-
hours: (d) => d.getHours(),
|
|
9356
|
-
minutes: (d) => d.getMinutes(),
|
|
9357
|
-
setMonth: (d, month) => d.setMonth(month, 1),
|
|
9358
|
-
setDate: (d, date) => d.setDate(date),
|
|
9359
|
-
setHours: (d, hours) => d.setHours(hours, 0, 0, 0),
|
|
9360
|
-
setMinutes: (d, minutes) => d.setMinutes(minutes, 0, 0)
|
|
9361
|
-
};
|
|
9362
9460
|
var UTC = {
|
|
9363
9461
|
year: (d) => d.getUTCFullYear(),
|
|
9364
9462
|
month: (d) => d.getUTCMonth(),
|
|
@@ -9371,60 +9469,112 @@ var UTC = {
|
|
|
9371
9469
|
setHours: (d, hours) => d.setUTCHours(hours, 0, 0, 0),
|
|
9372
9470
|
setMinutes: (d, minutes) => d.setUTCMinutes(minutes, 0, 0)
|
|
9373
9471
|
};
|
|
9374
|
-
function dayMatches(schedule,
|
|
9375
|
-
const day = schedule.days.has(
|
|
9376
|
-
const weekday = schedule.weekdays.has(
|
|
9472
|
+
function dayMatches(schedule, date) {
|
|
9473
|
+
const day = schedule.days.has(UTC.date(date));
|
|
9474
|
+
const weekday = schedule.weekdays.has(UTC.day(date));
|
|
9377
9475
|
if (schedule.anyDay || schedule.anyWeekday) return day && weekday;
|
|
9378
9476
|
return day || weekday;
|
|
9379
9477
|
}
|
|
9380
9478
|
var LIMIT_YEARS = 8;
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
const
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9479
|
+
var LIMIT_MS = (LIMIT_YEARS + 1) * 366 * 24 * 60 * MINUTE_MS;
|
|
9480
|
+
var SCAN_MS = 6 * 60 * MINUTE_MS;
|
|
9481
|
+
function nextWall(schedule, from) {
|
|
9482
|
+
const date = new Date(Math.ceil(from / MINUTE_MS) * MINUTE_MS);
|
|
9483
|
+
const limit = UTC.year(date) + LIMIT_YEARS;
|
|
9484
|
+
while (UTC.year(date) <= limit) {
|
|
9485
|
+
if (!schedule.months.has(UTC.month(date) + 1)) {
|
|
9486
|
+
UTC.setMonth(date, UTC.month(date) + 1);
|
|
9487
|
+
UTC.setHours(date, 0);
|
|
9488
|
+
} else if (!dayMatches(schedule, date)) {
|
|
9489
|
+
UTC.setDate(date, UTC.date(date) + 1);
|
|
9490
|
+
UTC.setHours(date, 0);
|
|
9491
|
+
} else if (!schedule.hours.has(UTC.hours(date))) {
|
|
9492
|
+
UTC.setHours(date, UTC.hours(date) + 1);
|
|
9493
|
+
} else if (!schedule.minutes.has(UTC.minutes(date))) {
|
|
9494
|
+
UTC.setMinutes(date, UTC.minutes(date) + 1);
|
|
9396
9495
|
} else return date.getTime();
|
|
9397
9496
|
}
|
|
9398
9497
|
return null;
|
|
9399
9498
|
}
|
|
9400
|
-
function
|
|
9499
|
+
function firstChange(zone, from, to, offset) {
|
|
9500
|
+
let lo = from;
|
|
9501
|
+
let hi = to;
|
|
9502
|
+
for (let at = from + SCAN_MS; at < to; at += SCAN_MS) {
|
|
9503
|
+
if (zone.offset(at) !== offset) {
|
|
9504
|
+
hi = at;
|
|
9505
|
+
break;
|
|
9506
|
+
}
|
|
9507
|
+
lo = at;
|
|
9508
|
+
}
|
|
9509
|
+
while (hi - lo > MINUTE_MS) {
|
|
9510
|
+
const mid = lo + Math.floor((hi - lo) / 2 / MINUTE_MS) * MINUTE_MS;
|
|
9511
|
+
if (zone.offset(mid) === offset) lo = mid;
|
|
9512
|
+
else hi = mid;
|
|
9513
|
+
}
|
|
9514
|
+
return hi;
|
|
9515
|
+
}
|
|
9516
|
+
function afterRepeat(zone, at) {
|
|
9517
|
+
const offset = zone.offset(at);
|
|
9518
|
+
const earlier = zone.offset(at - MAX_SHIFT_MS);
|
|
9519
|
+
if (earlier <= offset) return at;
|
|
9520
|
+
const shift = firstChange(zone, at - MAX_SHIFT_MS, at, earlier);
|
|
9521
|
+
const end = shift + (earlier - zone.offset(shift));
|
|
9522
|
+
return Math.max(at, end);
|
|
9523
|
+
}
|
|
9524
|
+
function nextFire(schedule, after, zone = utcZone) {
|
|
9525
|
+
let at = Math.floor(after / MINUTE_MS) * MINUTE_MS + MINUTE_MS;
|
|
9526
|
+
const limit = at + LIMIT_MS;
|
|
9527
|
+
while (at <= limit) {
|
|
9528
|
+
if (schedule.fixed) {
|
|
9529
|
+
const end = afterRepeat(zone, at);
|
|
9530
|
+
if (end > at) {
|
|
9531
|
+
at = end;
|
|
9532
|
+
continue;
|
|
9533
|
+
}
|
|
9534
|
+
}
|
|
9535
|
+
const offset = zone.offset(at);
|
|
9536
|
+
const before = zone.offset(at - MINUTE_MS);
|
|
9537
|
+
if (schedule.fixed && before < offset && offset - before <= MAX_SHIFT_MS) {
|
|
9538
|
+
const skipped = nextWall(schedule, at + before);
|
|
9539
|
+
if (skipped !== null && skipped < at + offset) return at;
|
|
9540
|
+
}
|
|
9541
|
+
const wall = nextWall(schedule, at + offset);
|
|
9542
|
+
if (wall === null) return null;
|
|
9543
|
+
const found = at + (wall - (at + offset));
|
|
9544
|
+
const change = firstChange(zone, at, found, offset);
|
|
9545
|
+
if (change >= found && zone.offset(found) === offset) return found;
|
|
9546
|
+
at = change;
|
|
9547
|
+
}
|
|
9548
|
+
return null;
|
|
9549
|
+
}
|
|
9550
|
+
function missedFires(schedule, from, until2, zone = utcZone, cap = MISSED_CAP) {
|
|
9401
9551
|
let count2 = 0;
|
|
9402
9552
|
let last = null;
|
|
9403
9553
|
let at = from;
|
|
9404
9554
|
while (count2 < cap) {
|
|
9405
|
-
at = nextFire(schedule, at,
|
|
9555
|
+
at = nextFire(schedule, at, zone);
|
|
9406
9556
|
if (at === null || at > until2) return { count: count2, last, more: false };
|
|
9407
9557
|
last = at;
|
|
9408
9558
|
count2++;
|
|
9409
9559
|
}
|
|
9410
|
-
const next3 = nextFire(schedule, last,
|
|
9560
|
+
const next3 = nextFire(schedule, last, zone);
|
|
9411
9561
|
if (next3 === null || next3 > until2) return { count: count2, last, more: false };
|
|
9412
|
-
return { count: count2, last: latestFire(schedule, last, until2,
|
|
9562
|
+
return { count: count2, last: latestFire(schedule, last, until2, zone), more: true };
|
|
9413
9563
|
}
|
|
9414
|
-
function latestFire(schedule, from, until2,
|
|
9564
|
+
function latestFire(schedule, from, until2, zone = utcZone) {
|
|
9415
9565
|
let found = from;
|
|
9416
9566
|
for (let span = 6e4; ; span *= 2) {
|
|
9417
9567
|
const start2 = Math.max(from, until2 - span);
|
|
9418
|
-
const first = nextFire(schedule, start2,
|
|
9568
|
+
const first = nextFire(schedule, start2, zone);
|
|
9419
9569
|
if (first !== null && first <= until2) {
|
|
9420
9570
|
found = first;
|
|
9421
9571
|
break;
|
|
9422
9572
|
}
|
|
9423
9573
|
if (start2 === from) return from;
|
|
9424
9574
|
}
|
|
9425
|
-
for (let at = nextFire(schedule, found,
|
|
9575
|
+
for (let at = nextFire(schedule, found, zone); at !== null && at <= until2; ) {
|
|
9426
9576
|
found = at;
|
|
9427
|
-
at = nextFire(schedule, at,
|
|
9577
|
+
at = nextFire(schedule, at, zone);
|
|
9428
9578
|
}
|
|
9429
9579
|
return found;
|
|
9430
9580
|
}
|
|
@@ -9465,13 +9615,16 @@ function split2(text, count2) {
|
|
|
9465
9615
|
}
|
|
9466
9616
|
return [words2, rest2.trim()];
|
|
9467
9617
|
}
|
|
9468
|
-
function jobOf(content, pending, ctx) {
|
|
9618
|
+
function jobOf(content, pending, ctx, env) {
|
|
9469
9619
|
const fields = content.startsWith("@") ? 1 : 5;
|
|
9470
9620
|
const parts2 = split2(content, fields + (ctx.system ? 1 : 0));
|
|
9471
9621
|
if (!parts2 || parts2[1] === "") throw new Error("no command");
|
|
9472
9622
|
const [words2, command] = parts2;
|
|
9473
9623
|
const schedule = words2.slice(0, fields).join(" ");
|
|
9474
9624
|
const when = parseWhen(schedule);
|
|
9625
|
+
const zone = env.CRON_TZ;
|
|
9626
|
+
if (zone && !when.reboot && canonicalZone(zone) === void 0)
|
|
9627
|
+
throw new Error(`CRON_TZ: unknown time zone "${zone}"`);
|
|
9475
9628
|
const user = ctx.system ? words2[fields] : void 0;
|
|
9476
9629
|
if (user !== void 0 && !USER_NAME.test(user)) throw new Error(`bad user name ${user}`);
|
|
9477
9630
|
if (pending !== void 0 && !JOB_NAME.test(pending))
|
|
@@ -9517,7 +9670,7 @@ function parseCrontab(text, path, system = false) {
|
|
|
9517
9670
|
continue;
|
|
9518
9671
|
}
|
|
9519
9672
|
try {
|
|
9520
|
-
jobs.push({ line, ...jobOf(content, pending, ctx), env: { ...env } });
|
|
9673
|
+
jobs.push({ line, ...jobOf(content, pending, ctx, env), env: { ...env } });
|
|
9521
9674
|
} catch (err) {
|
|
9522
9675
|
errors.push({ line, message: err.message });
|
|
9523
9676
|
}
|
|
@@ -10304,24 +10457,6 @@ var UnlinkedKeeper = class {
|
|
|
10304
10457
|
}
|
|
10305
10458
|
};
|
|
10306
10459
|
|
|
10307
|
-
// src/cron/clock.ts
|
|
10308
|
-
var systemCronClock = {
|
|
10309
|
-
now: () => Date.now(),
|
|
10310
|
-
sleep(until2, signal) {
|
|
10311
|
-
if (signal.aborted) return Promise.resolve();
|
|
10312
|
-
return new Promise((resolve2) => {
|
|
10313
|
-
const done5 = () => {
|
|
10314
|
-
clearTimeout(timer);
|
|
10315
|
-
signal.removeEventListener("abort", done5);
|
|
10316
|
-
resolve2();
|
|
10317
|
-
};
|
|
10318
|
-
const timer = setTimeout(done5, Math.max(0, until2 - Date.now()));
|
|
10319
|
-
timer.unref?.();
|
|
10320
|
-
signal.addEventListener("abort", done5, { once: true });
|
|
10321
|
-
});
|
|
10322
|
-
}
|
|
10323
|
-
};
|
|
10324
|
-
|
|
10325
10460
|
// src/cron/service.ts
|
|
10326
10461
|
var CRON_DIR = "/var/spool/cron";
|
|
10327
10462
|
var STAMP_PATH = `${CRON_DIR}/stamp`;
|
|
@@ -10333,9 +10468,10 @@ var WAKE_MS = 6e4;
|
|
|
10333
10468
|
var BACK_JUMP_MS = 12e4;
|
|
10334
10469
|
var DEFAULT_SHELL = "/bin/bash";
|
|
10335
10470
|
var encoder = new TextEncoder();
|
|
10336
|
-
var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {} });
|
|
10471
|
+
var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {}, when: {} });
|
|
10337
10472
|
var messageOf = (err) => err?.message ?? String(err);
|
|
10338
10473
|
var keyOf2 = ({ source, job }) => `${source} ${job.id}`;
|
|
10474
|
+
var whenOf = ({ job }) => `${job.schedule} ${job.env.CRON_TZ ?? ""}`;
|
|
10339
10475
|
function tail(bytes, cap = LOG_CAP) {
|
|
10340
10476
|
return bytes.length > cap ? bytes.slice(bytes.length - cap) : bytes;
|
|
10341
10477
|
}
|
|
@@ -10369,9 +10505,10 @@ function readStamp(text) {
|
|
|
10369
10505
|
const parsed2 = JSON.parse(text ?? "");
|
|
10370
10506
|
const jobs = parsed2.jobs && typeof parsed2.jobs === "object" ? parsed2.jobs : {};
|
|
10371
10507
|
const reboot = parsed2.reboot && typeof parsed2.reboot === "object" ? parsed2.reboot : {};
|
|
10372
|
-
|
|
10508
|
+
const when = parsed2.when && typeof parsed2.when === "object" ? parsed2.when : {};
|
|
10509
|
+
return { jobs: { ...jobs }, reboot: { ...reboot }, when: { ...when } };
|
|
10373
10510
|
} catch {
|
|
10374
|
-
return { jobs: {}, reboot: {} };
|
|
10511
|
+
return { jobs: {}, reboot: {}, when: {} };
|
|
10375
10512
|
}
|
|
10376
10513
|
}
|
|
10377
10514
|
var CronService = class {
|
|
@@ -10446,7 +10583,7 @@ var CronService = class {
|
|
|
10446
10583
|
const loaded = await this.load();
|
|
10447
10584
|
const stamp = readStamp(await fs.readFile(STAMP_PATH).catch(() => void 0));
|
|
10448
10585
|
const now = this.clock.now();
|
|
10449
|
-
const
|
|
10586
|
+
const system = this.host.timeZone;
|
|
10450
10587
|
const due2 = [];
|
|
10451
10588
|
const keys = /* @__PURE__ */ new Set();
|
|
10452
10589
|
let next3 = now + WAKE_MS;
|
|
@@ -10460,20 +10597,24 @@ var CronService = class {
|
|
|
10460
10597
|
due2.push({ entry, due: now, missed: 0 });
|
|
10461
10598
|
continue;
|
|
10462
10599
|
}
|
|
10600
|
+
const zone = zoneOf(entry.job.env.CRON_TZ || system);
|
|
10463
10601
|
const last = stamp.jobs[key];
|
|
10464
|
-
|
|
10602
|
+
const was = stamp.when[key];
|
|
10603
|
+
stamp.when[key] = whenOf(entry);
|
|
10604
|
+
const changed = was !== void 0 && was !== stamp.when[key];
|
|
10605
|
+
if (typeof last !== "number" || changed || last > now + BACK_JUMP_MS) stamp.jobs[key] = now;
|
|
10465
10606
|
else {
|
|
10466
|
-
const missed = missedFires(when.schedule, last, now,
|
|
10607
|
+
const missed = missedFires(when.schedule, last, now, zone);
|
|
10467
10608
|
if (missed.last !== null) {
|
|
10468
10609
|
stamp.jobs[key] = now;
|
|
10469
10610
|
due2.push({ entry, due: missed.last, missed: missed.count - 1 });
|
|
10470
10611
|
}
|
|
10471
10612
|
}
|
|
10472
|
-
const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]),
|
|
10613
|
+
const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]), zone);
|
|
10473
10614
|
if (coming !== null && coming < next3) next3 = coming;
|
|
10474
10615
|
}
|
|
10475
10616
|
this.rebooted = true;
|
|
10476
|
-
for (const map of [stamp.jobs, stamp.reboot])
|
|
10617
|
+
for (const map of [stamp.jobs, stamp.reboot, stamp.when])
|
|
10477
10618
|
for (const key of Object.keys(map)) if (!keys.has(key)) delete map[key];
|
|
10478
10619
|
await this.writeStamp(stamp);
|
|
10479
10620
|
for (const each of due2) void this.spawn(each);
|
|
@@ -16212,14 +16353,14 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
16212
16353
|
|
|
16213
16354
|
// src/kernel/cpu-clock.ts
|
|
16214
16355
|
var SYS_CAP_US = 2e4;
|
|
16215
|
-
var
|
|
16356
|
+
var LOCAL = SAB_CLOCK_OFFSET;
|
|
16216
16357
|
var BLOCKED = 0;
|
|
16217
16358
|
var IDLE = 1;
|
|
16218
16359
|
function epochMicros() {
|
|
16219
16360
|
return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
|
|
16220
16361
|
}
|
|
16221
16362
|
function slots(sab) {
|
|
16222
|
-
return new BigInt64Array(sab,
|
|
16363
|
+
return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
|
|
16223
16364
|
}
|
|
16224
16365
|
var rawWait = Atomics.wait.bind(Atomics);
|
|
16225
16366
|
function localIdle(sab, now) {
|
|
@@ -33068,6 +33209,7 @@ var Launcher = class {
|
|
|
33068
33209
|
routes;
|
|
33069
33210
|
resolver;
|
|
33070
33211
|
hostname;
|
|
33212
|
+
timeZone;
|
|
33071
33213
|
watchers = new FsWatchers();
|
|
33072
33214
|
changes = new FileChanges();
|
|
33073
33215
|
peerHeldPaths = /* @__PURE__ */ new Set();
|
|
@@ -33183,9 +33325,11 @@ var Launcher = class {
|
|
|
33183
33325
|
const hostname = options.hostname ?? DEFAULT_HOSTNAME;
|
|
33184
33326
|
if (!isHostname(hostname)) throw new Error(`not a host name: ${String(hostname)}`);
|
|
33185
33327
|
this.hostname = hostname;
|
|
33328
|
+
this.timeZone = systemTimeZone(options.timeZone, clockZone(options.cron?.clock));
|
|
33186
33329
|
this.env = {
|
|
33187
33330
|
...networkEnv(hostname),
|
|
33188
33331
|
HOSTNAME: hostname,
|
|
33332
|
+
TZ: this.timeZone,
|
|
33189
33333
|
SLICC_CDP_URL: this.cdp.url,
|
|
33190
33334
|
...this.facades.env(),
|
|
33191
33335
|
...options.env
|
|
@@ -33295,6 +33439,7 @@ var Launcher = class {
|
|
|
33295
33439
|
owners: this.owners,
|
|
33296
33440
|
lock: options.lock ?? "slicc-kernel-cron",
|
|
33297
33441
|
bootId: this.bootId,
|
|
33442
|
+
timeZone: this.timeZone,
|
|
33298
33443
|
...options.clock ? { clock: options.clock } : {},
|
|
33299
33444
|
locks: cronLocks(),
|
|
33300
33445
|
ready: () => this.fstab,
|
|
@@ -35314,7 +35459,7 @@ var Launcher = class {
|
|
|
35314
35459
|
}
|
|
35315
35460
|
environment(cwd, extra, account, login2 = false) {
|
|
35316
35461
|
const env = {
|
|
35317
|
-
...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname } : this.env,
|
|
35462
|
+
...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname, TZ: this.timeZone } : this.env,
|
|
35318
35463
|
...userEnv(account, this.pnpmHome),
|
|
35319
35464
|
PWD: cwd,
|
|
35320
35465
|
...extra
|
|
@@ -36167,6 +36312,7 @@ function hostOptions(req, port, sealed, sealedFetch, clipboard, lookup2, request
|
|
|
36167
36312
|
return {
|
|
36168
36313
|
cron: { lock: `slicc-kernel-cron:${req.metadata ?? META_DB}` },
|
|
36169
36314
|
...req.hostname !== void 0 ? { hostname: req.hostname } : {},
|
|
36315
|
+
...req.timeZone !== void 0 ? { timeZone: req.timeZone } : {},
|
|
36170
36316
|
...req.doh !== void 0 ? { doh: req.doh } : {},
|
|
36171
36317
|
...req.users !== void 0 ? { users: req.users } : {},
|
|
36172
36318
|
...req.denials ? { onDenial: (denial) => port.postMessage({ denial }) } : {},
|