@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
|
@@ -7514,7 +7514,7 @@ var init_version = __esm({
|
|
|
7514
7514
|
"src/version.ts"() {
|
|
7515
7515
|
"use strict";
|
|
7516
7516
|
init_captured_globals();
|
|
7517
|
-
KERNEL_VERSION = true ? "1.174.
|
|
7517
|
+
KERNEL_VERSION = true ? "1.174.2" : "0.0.0-dev";
|
|
7518
7518
|
OS_RELEASE = "6.0.0-slicc";
|
|
7519
7519
|
}
|
|
7520
7520
|
});
|
|
@@ -7513,7 +7513,7 @@ var init_version = __esm({
|
|
|
7513
7513
|
"src/version.ts"() {
|
|
7514
7514
|
"use strict";
|
|
7515
7515
|
init_captured_globals();
|
|
7516
|
-
KERNEL_VERSION = true ? "1.174.
|
|
7516
|
+
KERNEL_VERSION = true ? "1.174.2" : "0.0.0-dev";
|
|
7517
7517
|
OS_RELEASE = "6.0.0-slicc";
|
|
7518
7518
|
}
|
|
7519
7519
|
});
|
package/dist/node.js
CHANGED
|
@@ -3702,7 +3702,7 @@ function satisfies(version, range2) {
|
|
|
3702
3702
|
}
|
|
3703
3703
|
|
|
3704
3704
|
// src/version.ts
|
|
3705
|
-
var KERNEL_VERSION = true ? "1.174.
|
|
3705
|
+
var KERNEL_VERSION = true ? "1.174.2" : "0.0.0-dev";
|
|
3706
3706
|
var OS_RELEASE = "6.0.0-slicc";
|
|
3707
3707
|
function procVersion() {
|
|
3708
3708
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -4114,6 +4114,27 @@ function binfmtOf(binfmts, path) {
|
|
|
4114
4114
|
return best === void 0 ? void 0 : binfmts.get(best);
|
|
4115
4115
|
}
|
|
4116
4116
|
|
|
4117
|
+
// src/cron/clock.ts
|
|
4118
|
+
function clockZone(clock) {
|
|
4119
|
+
return clock?.timeZone ?? (clock?.utc === true ? "UTC" : void 0);
|
|
4120
|
+
}
|
|
4121
|
+
var systemCronClock = {
|
|
4122
|
+
now: () => Date.now(),
|
|
4123
|
+
sleep(until2, signal) {
|
|
4124
|
+
if (signal.aborted) return Promise.resolve();
|
|
4125
|
+
return new Promise((resolve2) => {
|
|
4126
|
+
const done4 = () => {
|
|
4127
|
+
clearTimeout(timer);
|
|
4128
|
+
signal.removeEventListener("abort", done4);
|
|
4129
|
+
resolve2();
|
|
4130
|
+
};
|
|
4131
|
+
const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
|
|
4132
|
+
timer.unref?.();
|
|
4133
|
+
signal.addEventListener("abort", done4, { once: true });
|
|
4134
|
+
});
|
|
4135
|
+
}
|
|
4136
|
+
};
|
|
4137
|
+
|
|
4117
4138
|
// src/cron/command.ts
|
|
4118
4139
|
var CRONTAB_PATH = "/usr/bin/crontab";
|
|
4119
4140
|
var CRONTAB_COMMAND = {
|
|
@@ -4225,6 +4246,94 @@ var CRONTAB_SOURCE = `export default async function crontab(ctx) {
|
|
|
4225
4246
|
}
|
|
4226
4247
|
`;
|
|
4227
4248
|
|
|
4249
|
+
// src/time-zone.ts
|
|
4250
|
+
var MINUTE_MS = 6e4;
|
|
4251
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
4252
|
+
var BUCKET_MS = 15 * MINUTE_MS;
|
|
4253
|
+
var CACHE_MAX = 4096;
|
|
4254
|
+
var ZERO = /* @__PURE__ */ new Set(["UTC", "Etc/UTC", "Etc/GMT", "GMT", "Etc/Universal", "Etc/Zulu"]);
|
|
4255
|
+
function canonicalZone(name2) {
|
|
4256
|
+
if (typeof name2 !== "string" || name2 === "" || name2.length > 64) return void 0;
|
|
4257
|
+
try {
|
|
4258
|
+
return new Intl.DateTimeFormat("en-US", { timeZone: name2 }).resolvedOptions().timeZone;
|
|
4259
|
+
} catch {
|
|
4260
|
+
return void 0;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
function hostTimeZone() {
|
|
4264
|
+
let name2;
|
|
4265
|
+
try {
|
|
4266
|
+
name2 = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
4267
|
+
} catch {
|
|
4268
|
+
name2 = void 0;
|
|
4269
|
+
}
|
|
4270
|
+
return canonicalZone(name2) ?? "UTC";
|
|
4271
|
+
}
|
|
4272
|
+
function systemTimeZone(given, fallback) {
|
|
4273
|
+
if (given !== void 0) {
|
|
4274
|
+
const zone = canonicalZone(given);
|
|
4275
|
+
if (zone === void 0) throw new Error(`not a time zone: ${String(given)}`);
|
|
4276
|
+
return zone;
|
|
4277
|
+
}
|
|
4278
|
+
return canonicalZone(fallback) ?? hostTimeZone();
|
|
4279
|
+
}
|
|
4280
|
+
var utcZone = { name: "UTC", offset: () => 0 };
|
|
4281
|
+
function hostZone(name2) {
|
|
4282
|
+
return { name: name2, offset: (at) => -new Date(at).getTimezoneOffset() * MINUTE_MS };
|
|
4283
|
+
}
|
|
4284
|
+
function intlZone(name2) {
|
|
4285
|
+
const format = new Intl.DateTimeFormat("en-US", {
|
|
4286
|
+
timeZone: name2,
|
|
4287
|
+
hourCycle: "h23",
|
|
4288
|
+
year: "numeric",
|
|
4289
|
+
month: "numeric",
|
|
4290
|
+
day: "numeric",
|
|
4291
|
+
hour: "numeric",
|
|
4292
|
+
minute: "numeric",
|
|
4293
|
+
second: "numeric"
|
|
4294
|
+
});
|
|
4295
|
+
const exact = (at) => {
|
|
4296
|
+
const parts2 = {};
|
|
4297
|
+
for (const part of format.formatToParts(at)) parts2[part.type] = Number(part.value);
|
|
4298
|
+
const wall = Date.UTC(
|
|
4299
|
+
parts2.year,
|
|
4300
|
+
parts2.month - 1,
|
|
4301
|
+
parts2.day,
|
|
4302
|
+
parts2.hour,
|
|
4303
|
+
parts2.minute,
|
|
4304
|
+
parts2.second
|
|
4305
|
+
);
|
|
4306
|
+
return wall - Math.floor(at / 1e3) * 1e3;
|
|
4307
|
+
};
|
|
4308
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
4309
|
+
return {
|
|
4310
|
+
name: name2,
|
|
4311
|
+
offset(at) {
|
|
4312
|
+
const bucket = Math.floor(at / BUCKET_MS);
|
|
4313
|
+
let known = buckets.get(bucket);
|
|
4314
|
+
if (known === void 0) {
|
|
4315
|
+
const start2 = exact(bucket * BUCKET_MS);
|
|
4316
|
+
known = start2 === exact(bucket * BUCKET_MS + BUCKET_MS - MINUTE_MS) ? start2 : null;
|
|
4317
|
+
if (buckets.size >= CACHE_MAX) buckets.clear();
|
|
4318
|
+
buckets.set(bucket, known);
|
|
4319
|
+
}
|
|
4320
|
+
return known ?? exact(at);
|
|
4321
|
+
}
|
|
4322
|
+
};
|
|
4323
|
+
}
|
|
4324
|
+
var zones = /* @__PURE__ */ new Map();
|
|
4325
|
+
function zoneOf(name2) {
|
|
4326
|
+
if (ZERO.has(name2)) return utcZone;
|
|
4327
|
+
if (name2 === hostTimeZone()) return hostZone(name2);
|
|
4328
|
+
let zone = zones.get(name2);
|
|
4329
|
+
if (!zone) {
|
|
4330
|
+
zone = intlZone(name2);
|
|
4331
|
+
zones.set(name2, zone);
|
|
4332
|
+
}
|
|
4333
|
+
return zone;
|
|
4334
|
+
}
|
|
4335
|
+
var MAX_SHIFT_MS = 3 * HOUR_MS;
|
|
4336
|
+
|
|
4228
4337
|
// src/cron/schedule.ts
|
|
4229
4338
|
var MISSED_CAP = 1e5;
|
|
4230
4339
|
var MACROS = {
|
|
@@ -4296,6 +4405,7 @@ function parseSchedule(expression) {
|
|
|
4296
4405
|
);
|
|
4297
4406
|
if (weekdays.delete(7)) weekdays.add(0);
|
|
4298
4407
|
return {
|
|
4408
|
+
fixed: !parts2[0].startsWith("*") && !parts2[1].startsWith("*"),
|
|
4299
4409
|
minutes,
|
|
4300
4410
|
hours,
|
|
4301
4411
|
days,
|
|
@@ -4309,18 +4419,6 @@ function parseWhen(expression) {
|
|
|
4309
4419
|
if (expression.trim().toLowerCase() === "@reboot") return { reboot: true };
|
|
4310
4420
|
return { reboot: false, schedule: parseSchedule(expression) };
|
|
4311
4421
|
}
|
|
4312
|
-
var LOCAL = {
|
|
4313
|
-
year: (d) => d.getFullYear(),
|
|
4314
|
-
month: (d) => d.getMonth(),
|
|
4315
|
-
date: (d) => d.getDate(),
|
|
4316
|
-
day: (d) => d.getDay(),
|
|
4317
|
-
hours: (d) => d.getHours(),
|
|
4318
|
-
minutes: (d) => d.getMinutes(),
|
|
4319
|
-
setMonth: (d, month) => d.setMonth(month, 1),
|
|
4320
|
-
setDate: (d, date) => d.setDate(date),
|
|
4321
|
-
setHours: (d, hours) => d.setHours(hours, 0, 0, 0),
|
|
4322
|
-
setMinutes: (d, minutes) => d.setMinutes(minutes, 0, 0)
|
|
4323
|
-
};
|
|
4324
4422
|
var UTC = {
|
|
4325
4423
|
year: (d) => d.getUTCFullYear(),
|
|
4326
4424
|
month: (d) => d.getUTCMonth(),
|
|
@@ -4333,60 +4431,112 @@ var UTC = {
|
|
|
4333
4431
|
setHours: (d, hours) => d.setUTCHours(hours, 0, 0, 0),
|
|
4334
4432
|
setMinutes: (d, minutes) => d.setUTCMinutes(minutes, 0, 0)
|
|
4335
4433
|
};
|
|
4336
|
-
function dayMatches(schedule,
|
|
4337
|
-
const day = schedule.days.has(
|
|
4338
|
-
const weekday = schedule.weekdays.has(
|
|
4434
|
+
function dayMatches(schedule, date) {
|
|
4435
|
+
const day = schedule.days.has(UTC.date(date));
|
|
4436
|
+
const weekday = schedule.weekdays.has(UTC.day(date));
|
|
4339
4437
|
if (schedule.anyDay || schedule.anyWeekday) return day && weekday;
|
|
4340
4438
|
return day || weekday;
|
|
4341
4439
|
}
|
|
4342
4440
|
var LIMIT_YEARS = 8;
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
const
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4441
|
+
var LIMIT_MS = (LIMIT_YEARS + 1) * 366 * 24 * 60 * MINUTE_MS;
|
|
4442
|
+
var SCAN_MS = 6 * 60 * MINUTE_MS;
|
|
4443
|
+
function nextWall(schedule, from) {
|
|
4444
|
+
const date = new Date(Math.ceil(from / MINUTE_MS) * MINUTE_MS);
|
|
4445
|
+
const limit = UTC.year(date) + LIMIT_YEARS;
|
|
4446
|
+
while (UTC.year(date) <= limit) {
|
|
4447
|
+
if (!schedule.months.has(UTC.month(date) + 1)) {
|
|
4448
|
+
UTC.setMonth(date, UTC.month(date) + 1);
|
|
4449
|
+
UTC.setHours(date, 0);
|
|
4450
|
+
} else if (!dayMatches(schedule, date)) {
|
|
4451
|
+
UTC.setDate(date, UTC.date(date) + 1);
|
|
4452
|
+
UTC.setHours(date, 0);
|
|
4453
|
+
} else if (!schedule.hours.has(UTC.hours(date))) {
|
|
4454
|
+
UTC.setHours(date, UTC.hours(date) + 1);
|
|
4455
|
+
} else if (!schedule.minutes.has(UTC.minutes(date))) {
|
|
4456
|
+
UTC.setMinutes(date, UTC.minutes(date) + 1);
|
|
4358
4457
|
} else return date.getTime();
|
|
4359
4458
|
}
|
|
4360
4459
|
return null;
|
|
4361
4460
|
}
|
|
4362
|
-
function
|
|
4461
|
+
function firstChange(zone, from, to, offset) {
|
|
4462
|
+
let lo = from;
|
|
4463
|
+
let hi = to;
|
|
4464
|
+
for (let at = from + SCAN_MS; at < to; at += SCAN_MS) {
|
|
4465
|
+
if (zone.offset(at) !== offset) {
|
|
4466
|
+
hi = at;
|
|
4467
|
+
break;
|
|
4468
|
+
}
|
|
4469
|
+
lo = at;
|
|
4470
|
+
}
|
|
4471
|
+
while (hi - lo > MINUTE_MS) {
|
|
4472
|
+
const mid = lo + Math.floor((hi - lo) / 2 / MINUTE_MS) * MINUTE_MS;
|
|
4473
|
+
if (zone.offset(mid) === offset) lo = mid;
|
|
4474
|
+
else hi = mid;
|
|
4475
|
+
}
|
|
4476
|
+
return hi;
|
|
4477
|
+
}
|
|
4478
|
+
function afterRepeat(zone, at) {
|
|
4479
|
+
const offset = zone.offset(at);
|
|
4480
|
+
const earlier = zone.offset(at - MAX_SHIFT_MS);
|
|
4481
|
+
if (earlier <= offset) return at;
|
|
4482
|
+
const shift = firstChange(zone, at - MAX_SHIFT_MS, at, earlier);
|
|
4483
|
+
const end = shift + (earlier - zone.offset(shift));
|
|
4484
|
+
return Math.max(at, end);
|
|
4485
|
+
}
|
|
4486
|
+
function nextFire(schedule, after, zone = utcZone) {
|
|
4487
|
+
let at = Math.floor(after / MINUTE_MS) * MINUTE_MS + MINUTE_MS;
|
|
4488
|
+
const limit = at + LIMIT_MS;
|
|
4489
|
+
while (at <= limit) {
|
|
4490
|
+
if (schedule.fixed) {
|
|
4491
|
+
const end = afterRepeat(zone, at);
|
|
4492
|
+
if (end > at) {
|
|
4493
|
+
at = end;
|
|
4494
|
+
continue;
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4497
|
+
const offset = zone.offset(at);
|
|
4498
|
+
const before = zone.offset(at - MINUTE_MS);
|
|
4499
|
+
if (schedule.fixed && before < offset && offset - before <= MAX_SHIFT_MS) {
|
|
4500
|
+
const skipped = nextWall(schedule, at + before);
|
|
4501
|
+
if (skipped !== null && skipped < at + offset) return at;
|
|
4502
|
+
}
|
|
4503
|
+
const wall = nextWall(schedule, at + offset);
|
|
4504
|
+
if (wall === null) return null;
|
|
4505
|
+
const found = at + (wall - (at + offset));
|
|
4506
|
+
const change = firstChange(zone, at, found, offset);
|
|
4507
|
+
if (change >= found && zone.offset(found) === offset) return found;
|
|
4508
|
+
at = change;
|
|
4509
|
+
}
|
|
4510
|
+
return null;
|
|
4511
|
+
}
|
|
4512
|
+
function missedFires(schedule, from, until2, zone = utcZone, cap = MISSED_CAP) {
|
|
4363
4513
|
let count2 = 0;
|
|
4364
4514
|
let last = null;
|
|
4365
4515
|
let at = from;
|
|
4366
4516
|
while (count2 < cap) {
|
|
4367
|
-
at = nextFire(schedule, at,
|
|
4517
|
+
at = nextFire(schedule, at, zone);
|
|
4368
4518
|
if (at === null || at > until2) return { count: count2, last, more: false };
|
|
4369
4519
|
last = at;
|
|
4370
4520
|
count2++;
|
|
4371
4521
|
}
|
|
4372
|
-
const next3 = nextFire(schedule, last,
|
|
4522
|
+
const next3 = nextFire(schedule, last, zone);
|
|
4373
4523
|
if (next3 === null || next3 > until2) return { count: count2, last, more: false };
|
|
4374
|
-
return { count: count2, last: latestFire(schedule, last, until2,
|
|
4524
|
+
return { count: count2, last: latestFire(schedule, last, until2, zone), more: true };
|
|
4375
4525
|
}
|
|
4376
|
-
function latestFire(schedule, from, until2,
|
|
4526
|
+
function latestFire(schedule, from, until2, zone = utcZone) {
|
|
4377
4527
|
let found = from;
|
|
4378
4528
|
for (let span = 6e4; ; span *= 2) {
|
|
4379
4529
|
const start2 = Math.max(from, until2 - span);
|
|
4380
|
-
const first = nextFire(schedule, start2,
|
|
4530
|
+
const first = nextFire(schedule, start2, zone);
|
|
4381
4531
|
if (first !== null && first <= until2) {
|
|
4382
4532
|
found = first;
|
|
4383
4533
|
break;
|
|
4384
4534
|
}
|
|
4385
4535
|
if (start2 === from) return from;
|
|
4386
4536
|
}
|
|
4387
|
-
for (let at = nextFire(schedule, found,
|
|
4537
|
+
for (let at = nextFire(schedule, found, zone); at !== null && at <= until2; ) {
|
|
4388
4538
|
found = at;
|
|
4389
|
-
at = nextFire(schedule, at,
|
|
4539
|
+
at = nextFire(schedule, at, zone);
|
|
4390
4540
|
}
|
|
4391
4541
|
return found;
|
|
4392
4542
|
}
|
|
@@ -4427,13 +4577,16 @@ function split(text, count2) {
|
|
|
4427
4577
|
}
|
|
4428
4578
|
return [words2, rest2.trim()];
|
|
4429
4579
|
}
|
|
4430
|
-
function jobOf(content, pending, ctx) {
|
|
4580
|
+
function jobOf(content, pending, ctx, env) {
|
|
4431
4581
|
const fields = content.startsWith("@") ? 1 : 5;
|
|
4432
4582
|
const parts2 = split(content, fields + (ctx.system ? 1 : 0));
|
|
4433
4583
|
if (!parts2 || parts2[1] === "") throw new Error("no command");
|
|
4434
4584
|
const [words2, command] = parts2;
|
|
4435
4585
|
const schedule = words2.slice(0, fields).join(" ");
|
|
4436
4586
|
const when = parseWhen(schedule);
|
|
4587
|
+
const zone = env.CRON_TZ;
|
|
4588
|
+
if (zone && !when.reboot && canonicalZone(zone) === void 0)
|
|
4589
|
+
throw new Error(`CRON_TZ: unknown time zone "${zone}"`);
|
|
4437
4590
|
const user = ctx.system ? words2[fields] : void 0;
|
|
4438
4591
|
if (user !== void 0 && !USER_NAME.test(user)) throw new Error(`bad user name ${user}`);
|
|
4439
4592
|
if (pending !== void 0 && !JOB_NAME.test(pending))
|
|
@@ -4479,7 +4632,7 @@ function parseCrontab(text, path, system = false) {
|
|
|
4479
4632
|
continue;
|
|
4480
4633
|
}
|
|
4481
4634
|
try {
|
|
4482
|
-
jobs.push({ line, ...jobOf(content, pending, ctx), env: { ...env } });
|
|
4635
|
+
jobs.push({ line, ...jobOf(content, pending, ctx, env), env: { ...env } });
|
|
4483
4636
|
} catch (err) {
|
|
4484
4637
|
errors.push({ line, message: err.message });
|
|
4485
4638
|
}
|
|
@@ -5279,24 +5432,6 @@ var UnlinkedKeeper = class {
|
|
|
5279
5432
|
}
|
|
5280
5433
|
};
|
|
5281
5434
|
|
|
5282
|
-
// src/cron/clock.ts
|
|
5283
|
-
var systemCronClock = {
|
|
5284
|
-
now: () => Date.now(),
|
|
5285
|
-
sleep(until2, signal) {
|
|
5286
|
-
if (signal.aborted) return Promise.resolve();
|
|
5287
|
-
return new Promise((resolve2) => {
|
|
5288
|
-
const done4 = () => {
|
|
5289
|
-
clearTimeout(timer);
|
|
5290
|
-
signal.removeEventListener("abort", done4);
|
|
5291
|
-
resolve2();
|
|
5292
|
-
};
|
|
5293
|
-
const timer = setTimeout(done4, Math.max(0, until2 - Date.now()));
|
|
5294
|
-
timer.unref?.();
|
|
5295
|
-
signal.addEventListener("abort", done4, { once: true });
|
|
5296
|
-
});
|
|
5297
|
-
}
|
|
5298
|
-
};
|
|
5299
|
-
|
|
5300
5435
|
// src/cron/service.ts
|
|
5301
5436
|
var CRON_DIR = "/var/spool/cron";
|
|
5302
5437
|
var STAMP_PATH = `${CRON_DIR}/stamp`;
|
|
@@ -5308,9 +5443,10 @@ var WAKE_MS = 6e4;
|
|
|
5308
5443
|
var BACK_JUMP_MS = 12e4;
|
|
5309
5444
|
var DEFAULT_SHELL = "/bin/bash";
|
|
5310
5445
|
var encoder = new TextEncoder();
|
|
5311
|
-
var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {} });
|
|
5446
|
+
var EMPTY_STAMP = JSON.stringify({ jobs: {}, reboot: {}, when: {} });
|
|
5312
5447
|
var messageOf = (err) => err?.message ?? String(err);
|
|
5313
5448
|
var keyOf2 = ({ source, job }) => `${source} ${job.id}`;
|
|
5449
|
+
var whenOf = ({ job }) => `${job.schedule} ${job.env.CRON_TZ ?? ""}`;
|
|
5314
5450
|
function tail(bytes, cap = LOG_CAP) {
|
|
5315
5451
|
return bytes.length > cap ? bytes.slice(bytes.length - cap) : bytes;
|
|
5316
5452
|
}
|
|
@@ -5344,9 +5480,10 @@ function readStamp(text) {
|
|
|
5344
5480
|
const parsed2 = JSON.parse(text ?? "");
|
|
5345
5481
|
const jobs = parsed2.jobs && typeof parsed2.jobs === "object" ? parsed2.jobs : {};
|
|
5346
5482
|
const reboot = parsed2.reboot && typeof parsed2.reboot === "object" ? parsed2.reboot : {};
|
|
5347
|
-
|
|
5483
|
+
const when = parsed2.when && typeof parsed2.when === "object" ? parsed2.when : {};
|
|
5484
|
+
return { jobs: { ...jobs }, reboot: { ...reboot }, when: { ...when } };
|
|
5348
5485
|
} catch {
|
|
5349
|
-
return { jobs: {}, reboot: {} };
|
|
5486
|
+
return { jobs: {}, reboot: {}, when: {} };
|
|
5350
5487
|
}
|
|
5351
5488
|
}
|
|
5352
5489
|
var CronService = class {
|
|
@@ -5421,7 +5558,7 @@ var CronService = class {
|
|
|
5421
5558
|
const loaded = await this.load();
|
|
5422
5559
|
const stamp = readStamp(await fs.readFile(STAMP_PATH).catch(() => void 0));
|
|
5423
5560
|
const now = this.clock.now();
|
|
5424
|
-
const
|
|
5561
|
+
const system = this.host.timeZone;
|
|
5425
5562
|
const due2 = [];
|
|
5426
5563
|
const keys = /* @__PURE__ */ new Set();
|
|
5427
5564
|
let next3 = now + WAKE_MS;
|
|
@@ -5435,20 +5572,24 @@ var CronService = class {
|
|
|
5435
5572
|
due2.push({ entry, due: now, missed: 0 });
|
|
5436
5573
|
continue;
|
|
5437
5574
|
}
|
|
5575
|
+
const zone = zoneOf(entry.job.env.CRON_TZ || system);
|
|
5438
5576
|
const last = stamp.jobs[key];
|
|
5439
|
-
|
|
5577
|
+
const was = stamp.when[key];
|
|
5578
|
+
stamp.when[key] = whenOf(entry);
|
|
5579
|
+
const changed = was !== void 0 && was !== stamp.when[key];
|
|
5580
|
+
if (typeof last !== "number" || changed || last > now + BACK_JUMP_MS) stamp.jobs[key] = now;
|
|
5440
5581
|
else {
|
|
5441
|
-
const missed = missedFires(when.schedule, last, now,
|
|
5582
|
+
const missed = missedFires(when.schedule, last, now, zone);
|
|
5442
5583
|
if (missed.last !== null) {
|
|
5443
5584
|
stamp.jobs[key] = now;
|
|
5444
5585
|
due2.push({ entry, due: missed.last, missed: missed.count - 1 });
|
|
5445
5586
|
}
|
|
5446
5587
|
}
|
|
5447
|
-
const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]),
|
|
5588
|
+
const coming = nextFire(when.schedule, Math.max(now, stamp.jobs[key]), zone);
|
|
5448
5589
|
if (coming !== null && coming < next3) next3 = coming;
|
|
5449
5590
|
}
|
|
5450
5591
|
this.rebooted = true;
|
|
5451
|
-
for (const map of [stamp.jobs, stamp.reboot])
|
|
5592
|
+
for (const map of [stamp.jobs, stamp.reboot, stamp.when])
|
|
5452
5593
|
for (const key of Object.keys(map)) if (!keys.has(key)) delete map[key];
|
|
5453
5594
|
await this.writeStamp(stamp);
|
|
5454
5595
|
for (const each of due2) void this.spawn(each);
|
|
@@ -11925,14 +12066,14 @@ function attachSyncSabResponder(port, sab, token, opts) {
|
|
|
11925
12066
|
|
|
11926
12067
|
// src/kernel/cpu-clock.ts
|
|
11927
12068
|
var SYS_CAP_US = 2e4;
|
|
11928
|
-
var
|
|
12069
|
+
var LOCAL = SAB_CLOCK_OFFSET;
|
|
11929
12070
|
var BLOCKED = 0;
|
|
11930
12071
|
var IDLE = 1;
|
|
11931
12072
|
function epochMicros() {
|
|
11932
12073
|
return Math.floor((performance.timeOrigin + performance.now()) * 1e3);
|
|
11933
12074
|
}
|
|
11934
12075
|
function slots(sab) {
|
|
11935
|
-
return new BigInt64Array(sab,
|
|
12076
|
+
return new BigInt64Array(sab, LOCAL, SAB_CLOCK_I64);
|
|
11936
12077
|
}
|
|
11937
12078
|
var rawWait = Atomics.wait.bind(Atomics);
|
|
11938
12079
|
function localIdle(sab, now) {
|
|
@@ -31964,6 +32105,7 @@ var Launcher = class {
|
|
|
31964
32105
|
routes;
|
|
31965
32106
|
resolver;
|
|
31966
32107
|
hostname;
|
|
32108
|
+
timeZone;
|
|
31967
32109
|
watchers = new FsWatchers();
|
|
31968
32110
|
changes = new FileChanges();
|
|
31969
32111
|
peerHeldPaths = /* @__PURE__ */ new Set();
|
|
@@ -32079,9 +32221,11 @@ var Launcher = class {
|
|
|
32079
32221
|
const hostname = options.hostname ?? DEFAULT_HOSTNAME;
|
|
32080
32222
|
if (!isHostname(hostname)) throw new Error(`not a host name: ${String(hostname)}`);
|
|
32081
32223
|
this.hostname = hostname;
|
|
32224
|
+
this.timeZone = systemTimeZone(options.timeZone, clockZone(options.cron?.clock));
|
|
32082
32225
|
this.env = {
|
|
32083
32226
|
...networkEnv(hostname),
|
|
32084
32227
|
HOSTNAME: hostname,
|
|
32228
|
+
TZ: this.timeZone,
|
|
32085
32229
|
SLICC_CDP_URL: this.cdp.url,
|
|
32086
32230
|
...this.facades.env(),
|
|
32087
32231
|
...options.env
|
|
@@ -32191,6 +32335,7 @@ var Launcher = class {
|
|
|
32191
32335
|
owners: this.owners,
|
|
32192
32336
|
lock: options.lock ?? "slicc-kernel-cron",
|
|
32193
32337
|
bootId: this.bootId,
|
|
32338
|
+
timeZone: this.timeZone,
|
|
32194
32339
|
...options.clock ? { clock: options.clock } : {},
|
|
32195
32340
|
locks: cronLocks(),
|
|
32196
32341
|
ready: () => this.fstab,
|
|
@@ -34210,7 +34355,7 @@ var Launcher = class {
|
|
|
34210
34355
|
}
|
|
34211
34356
|
environment(cwd, extra, account, login2 = false) {
|
|
34212
34357
|
const env = {
|
|
34213
|
-
...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname } : this.env,
|
|
34358
|
+
...login2 ? { ...networkEnv(this.hostname), HOSTNAME: this.hostname, TZ: this.timeZone } : this.env,
|
|
34214
34359
|
...userEnv(account, this.pnpmHome),
|
|
34215
34360
|
PWD: cwd,
|
|
34216
34361
|
...extra
|
|
@@ -37199,6 +37344,7 @@ function checkedRequests(hook) {
|
|
|
37199
37344
|
}
|
|
37200
37345
|
async function createNodeKernel(options = {}) {
|
|
37201
37346
|
const hooks = sealedHooks(options.sealed);
|
|
37347
|
+
const timeZone = systemTimeZone(options.timeZone, clockZone(options.cron?.clock));
|
|
37202
37348
|
const root = options.root ?? memoryRoot();
|
|
37203
37349
|
const fs = new OpfsFs(root, void 0, void 0, { ranged: isMemoryRoot(root) });
|
|
37204
37350
|
await fs.reconcile();
|
|
@@ -37234,6 +37380,7 @@ async function createNodeKernel(options = {}) {
|
|
|
37234
37380
|
...options.cdp ? { cdp: options.cdp } : {},
|
|
37235
37381
|
...options.facades ? { facades: options.facades } : {},
|
|
37236
37382
|
...options.hostname !== void 0 ? { hostname: options.hostname } : {},
|
|
37383
|
+
timeZone,
|
|
37237
37384
|
users: options.users === void 0 ? DEFAULT_USERS : options.users,
|
|
37238
37385
|
...options.onDenial ? { onDenial: options.onDenial } : {},
|
|
37239
37386
|
...options.protect ? { protect: options.protect } : {},
|