@mcmcjs/julia 0.11.3 → 0.13.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/index.cjs CHANGED
@@ -40,6 +40,7 @@ __export(index_exports, {
40
40
  runDoctor: () => runDoctor,
41
41
  runFit: () => runFit,
42
42
  runFitAuto: () => runFitAuto,
43
+ runLogLik: () => runLogLik,
43
44
  runMatrix: () => runMatrix,
44
45
  runPredict: () => runPredict,
45
46
  runSetup: () => runSetup,
@@ -287,10 +288,95 @@ async function runFit(spec, resolved, io) {
287
288
  return finalizeOkFit(spec, resolved, io, lastJsonLine(stdout), startedAt, elapsedMs);
288
289
  }
289
290
 
290
- // src/predict.ts
291
+ // src/loglik.ts
291
292
  var import_node_fs3 = require("fs");
292
293
  var import_node_path4 = require("path");
293
294
  var import_core2 = require("@mcmcjs/core");
295
+ async function runLogLik(spec, resolved, io) {
296
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
297
+ const start = performance.now();
298
+ const runtimeRequested = spec.backend.version;
299
+ const ownTmp = io.tmpDir === void 0;
300
+ const tmp = io.tmpDir ?? makeRequestDir("loglik");
301
+ const requestPath = (0, import_node_path4.join)(tmp, "request.json");
302
+ (0, import_node_fs3.writeFileSync)(
303
+ requestPath,
304
+ JSON.stringify({
305
+ mode: "loglik",
306
+ schema_version: spec.schema_version,
307
+ backend: { id: spec.backend.id },
308
+ model: { file: spec.modelPath, entry: spec.model.entry },
309
+ data: spec.data,
310
+ samples: io.samplesPath,
311
+ seed: spec.seed,
312
+ out: io.outPath
313
+ })
314
+ );
315
+ const args = [
316
+ ...resolved.args,
317
+ "--startup-file=no",
318
+ `--project=${io.projectDir}`,
319
+ driverPath(),
320
+ requestPath
321
+ ];
322
+ let stdout;
323
+ let stderr;
324
+ let code;
325
+ try {
326
+ ({ stdout, stderr, code } = await io.spawn(resolved.command, args));
327
+ } finally {
328
+ if (ownTmp) (0, import_node_fs3.rmSync)(tmp, { recursive: true, force: true });
329
+ }
330
+ const elapsedMs = Math.round(performance.now() - start);
331
+ if (code !== 0 || !(0, import_node_fs3.existsSync)(io.outPath)) {
332
+ const failure = lastJsonLine(stderr);
333
+ const error = failure?.error ?? stderr.trim().split("\n").pop() ?? `julia exited with code ${code}`;
334
+ return { status: "error", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };
335
+ }
336
+ try {
337
+ (0, import_core2.parseSamples)((0, import_node_fs3.readFileSync)(io.outPath, "utf8"));
338
+ } catch (error) {
339
+ return {
340
+ status: "error",
341
+ runtimeRequested,
342
+ elapsedMs,
343
+ stage: "write",
344
+ error: `log-likelihood file did not parse: ${error.message}`
345
+ };
346
+ }
347
+ const provenance = lastJsonLine(stdout);
348
+ const julia = provenance?.julia_version;
349
+ const record = {
350
+ schema_version: import_core2.RUN_RECORD_SCHEMA_VERSION,
351
+ spec_hash: spec.specHash,
352
+ seed: spec.seed,
353
+ backend: { id: spec.backend.id, runtime: spec.backend.runtime },
354
+ runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },
355
+ manifest_sha256: provenance?.manifest_sha256,
356
+ packages: provenance?.packages,
357
+ model_sha256: (0, import_node_fs3.existsSync)(spec.modelPath) ? sha256((0, import_node_fs3.readFileSync)(spec.modelPath, "utf8")) : void 0,
358
+ data_sha256: sha256((0, import_core2.canonicalJson)(spec.data)),
359
+ posterior_samples: io.samplesPath,
360
+ posterior_samples_sha256: (0, import_node_fs3.existsSync)(io.samplesPath) ? sha256((0, import_node_fs3.readFileSync)(io.samplesPath, "utf8")) : void 0,
361
+ samples_file: io.outPath,
362
+ started_at: startedAt,
363
+ elapsed_ms: elapsedMs
364
+ };
365
+ (0, import_node_fs3.writeFileSync)(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}
366
+ `);
367
+ return {
368
+ status: "ok",
369
+ samplesFile: io.outPath,
370
+ runtimeRequested,
371
+ runtimeActual: julia,
372
+ elapsedMs
373
+ };
374
+ }
375
+
376
+ // src/predict.ts
377
+ var import_node_fs4 = require("fs");
378
+ var import_node_path5 = require("path");
379
+ var import_core3 = require("@mcmcjs/core");
294
380
  function predictData(spec) {
295
381
  const predict = spec.predict;
296
382
  if (!predict) throw new Error("spec has no [predict] block");
@@ -308,8 +394,8 @@ async function runPredict(spec, resolved, io) {
308
394
  const data = predictData(spec);
309
395
  const ownTmp = io.tmpDir === void 0;
310
396
  const tmp = io.tmpDir ?? makeRequestDir("predict");
311
- const requestPath = (0, import_node_path4.join)(tmp, "request.json");
312
- (0, import_node_fs3.writeFileSync)(
397
+ const requestPath = (0, import_node_path5.join)(tmp, "request.json");
398
+ (0, import_node_fs4.writeFileSync)(
313
399
  requestPath,
314
400
  JSON.stringify({
315
401
  mode: "predict",
@@ -336,16 +422,16 @@ async function runPredict(spec, resolved, io) {
336
422
  try {
337
423
  ({ stdout, stderr, code } = await io.spawn(resolved.command, args));
338
424
  } finally {
339
- if (ownTmp) (0, import_node_fs3.rmSync)(tmp, { recursive: true, force: true });
425
+ if (ownTmp) (0, import_node_fs4.rmSync)(tmp, { recursive: true, force: true });
340
426
  }
341
427
  const elapsedMs = Math.round(performance.now() - start);
342
- if (code !== 0 || !(0, import_node_fs3.existsSync)(io.outPath)) {
428
+ if (code !== 0 || !(0, import_node_fs4.existsSync)(io.outPath)) {
343
429
  const failure = lastJsonLine(stderr);
344
430
  const error = failure?.error ?? stderr.trim().split("\n").pop() ?? `julia exited with code ${code}`;
345
431
  return { status: "error", runtimeRequested, elapsedMs, stage: toStage(failure?.stage), error };
346
432
  }
347
433
  try {
348
- (0, import_core2.parseSamples)((0, import_node_fs3.readFileSync)(io.outPath, "utf8"));
434
+ (0, import_core3.parseSamples)((0, import_node_fs4.readFileSync)(io.outPath, "utf8"));
349
435
  } catch (error) {
350
436
  return {
351
437
  status: "error",
@@ -358,22 +444,22 @@ async function runPredict(spec, resolved, io) {
358
444
  const provenance = lastJsonLine(stdout);
359
445
  const julia = provenance?.julia_version;
360
446
  const record = {
361
- schema_version: import_core2.RUN_RECORD_SCHEMA_VERSION,
447
+ schema_version: import_core3.RUN_RECORD_SCHEMA_VERSION,
362
448
  spec_hash: spec.specHash,
363
449
  seed: spec.seed,
364
450
  backend: { id: spec.backend.id, runtime: spec.backend.runtime },
365
451
  runtime: { requested: runtimeRequested, actual: julia, path: resolved.command },
366
452
  manifest_sha256: provenance?.manifest_sha256,
367
453
  packages: provenance?.packages,
368
- model_sha256: (0, import_node_fs3.existsSync)(spec.modelPath) ? sha256((0, import_node_fs3.readFileSync)(spec.modelPath, "utf8")) : void 0,
369
- data_sha256: sha256((0, import_core2.canonicalJson)(data)),
454
+ model_sha256: (0, import_node_fs4.existsSync)(spec.modelPath) ? sha256((0, import_node_fs4.readFileSync)(spec.modelPath, "utf8")) : void 0,
455
+ data_sha256: sha256((0, import_core3.canonicalJson)(data)),
370
456
  posterior_samples: io.samplesPath,
371
- posterior_samples_sha256: (0, import_node_fs3.existsSync)(io.samplesPath) ? sha256((0, import_node_fs3.readFileSync)(io.samplesPath, "utf8")) : void 0,
457
+ posterior_samples_sha256: (0, import_node_fs4.existsSync)(io.samplesPath) ? sha256((0, import_node_fs4.readFileSync)(io.samplesPath, "utf8")) : void 0,
372
458
  samples_file: io.outPath,
373
459
  started_at: startedAt,
374
460
  elapsed_ms: elapsedMs
375
461
  };
376
- (0, import_node_fs3.writeFileSync)(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}
462
+ (0, import_node_fs4.writeFileSync)(`${io.outPath}.run.json`, `${JSON.stringify(record, null, 2)}
377
463
  `);
378
464
  return {
379
465
  status: "ok",
@@ -385,10 +471,10 @@ async function runPredict(spec, resolved, io) {
385
471
  }
386
472
 
387
473
  // src/project.ts
388
- var import_node_fs4 = require("fs");
474
+ var import_node_fs5 = require("fs");
389
475
  var import_node_os3 = require("os");
390
- var import_node_path5 = require("path");
391
- var import_core3 = require("@mcmcjs/core");
476
+ var import_node_path6 = require("path");
477
+ var import_core4 = require("@mcmcjs/core");
392
478
  var import_engine3 = require("@mcmcjs/engine");
393
479
  var PACKAGES = [
394
480
  "Turing",
@@ -399,6 +485,7 @@ var PACKAGES = [
399
485
  "AdvancedHMC",
400
486
  "ForwardDiff",
401
487
  "Mooncake",
488
+ "ReverseDiff",
402
489
  "JSON",
403
490
  "StableRNGs",
404
491
  "StatsFuns"
@@ -425,19 +512,19 @@ function hasPins(pins) {
425
512
  return pins !== void 0 && Object.keys(pins).length > 0;
426
513
  }
427
514
  function managedProjectDir(version, pins) {
428
- const base = process.env.XDG_DATA_HOME || (0, import_node_path5.join)((0, import_node_os3.homedir)(), ".local", "share");
429
- const root = (0, import_node_path5.join)(base, "mcmcjs", "julia", "env");
515
+ const base = process.env.XDG_DATA_HOME || (0, import_node_path6.join)((0, import_node_os3.homedir)(), ".local", "share");
516
+ const root = (0, import_node_path6.join)(base, "mcmcjs", "julia", "env");
430
517
  if (!version && !hasPins(pins)) return root;
431
518
  let leaf = (version ?? "default").replace(/[^A-Za-z0-9._-]/g, "_");
432
- if (hasPins(pins)) leaf += `-${sha256((0, import_core3.canonicalJson)(pins)).slice(0, 8)}`;
433
- return (0, import_node_path5.join)(root, leaf);
519
+ if (hasPins(pins)) leaf += `-${sha256((0, import_core4.canonicalJson)(pins)).slice(0, 8)}`;
520
+ return (0, import_node_path6.join)(root, leaf);
434
521
  }
435
522
  function sentinelPath(dir) {
436
- return (0, import_node_path5.join)(dir, ".mcmcjs-packages.json");
523
+ return (0, import_node_path6.join)(dir, ".mcmcjs-packages.json");
437
524
  }
438
525
  var PROVISION_GENERATION = 1;
439
526
  function expectedSentinel(pins) {
440
- return (0, import_core3.canonicalJson)({
527
+ return (0, import_core4.canonicalJson)({
441
528
  gen: PROVISION_GENERATION,
442
529
  packages: [...PACKAGES].sort(),
443
530
  pins: pins ?? {}
@@ -445,13 +532,13 @@ function expectedSentinel(pins) {
445
532
  }
446
533
  function provisioned(dir, pins) {
447
534
  try {
448
- return (0, import_node_fs4.readFileSync)(sentinelPath(dir), "utf8").trim() === expectedSentinel(pins);
535
+ return (0, import_node_fs5.readFileSync)(sentinelPath(dir), "utf8").trim() === expectedSentinel(pins);
449
536
  } catch {
450
537
  return false;
451
538
  }
452
539
  }
453
540
  function managedProjectReady(dir = managedProjectDir(), pins) {
454
- return (0, import_node_fs4.existsSync)((0, import_node_path5.join)(dir, "Project.toml")) && provisioned(dir, pins);
541
+ return (0, import_node_fs5.existsSync)((0, import_node_path6.join)(dir, "Project.toml")) && provisioned(dir, pins);
455
542
  }
456
543
  function packageSpecsCode(pins) {
457
544
  const specs = PACKAGES.map((name) => {
@@ -461,15 +548,15 @@ function packageSpecsCode(pins) {
461
548
  return `[${specs.join(", ")}]`;
462
549
  }
463
550
  function usesPinnedEnv(version, pins) {
464
- return !hasPins(pins) && version === import_core3.DEFAULT_JULIA_CHANNEL && (0, import_node_fs4.existsSync)(pinnedEnvDir());
551
+ return !hasPins(pins) && version === import_core4.DEFAULT_JULIA_CHANNEL && (0, import_node_fs5.existsSync)(pinnedEnvDir());
465
552
  }
466
553
  async function ensureProject(juliaBin, run = (0, import_engine3.createRunner)(30 * 6e4), dir = managedProjectDir(), pins, opts) {
467
554
  validatePins(pins);
468
555
  if (managedProjectReady(dir, pins)) return dir;
469
- (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
556
+ (0, import_node_fs5.mkdirSync)(dir, { recursive: true });
470
557
  if (usesPinnedEnv(opts?.version, pins)) {
471
- (0, import_node_fs4.copyFileSync)((0, import_node_path5.join)(pinnedEnvDir(), "Project.toml"), (0, import_node_path5.join)(dir, "Project.toml"));
472
- (0, import_node_fs4.copyFileSync)((0, import_node_path5.join)(pinnedEnvDir(), "Manifest.toml"), (0, import_node_path5.join)(dir, "Manifest.toml"));
558
+ (0, import_node_fs5.copyFileSync)((0, import_node_path6.join)(pinnedEnvDir(), "Project.toml"), (0, import_node_path6.join)(dir, "Project.toml"));
559
+ (0, import_node_fs5.copyFileSync)((0, import_node_path6.join)(pinnedEnvDir(), "Manifest.toml"), (0, import_node_path6.join)(dir, "Manifest.toml"));
473
560
  await run(juliaBin, [
474
561
  "--startup-file=no",
475
562
  `--project=${dir}`,
@@ -480,12 +567,12 @@ async function ensureProject(juliaBin, run = (0, import_engine3.createRunner)(30
480
567
  const code = `using Pkg; Pkg.add(${packageSpecsCode(pins)}); Pkg.precompile()`;
481
568
  await run(juliaBin, ["--startup-file=no", `--project=${dir}`, "-e", code]);
482
569
  }
483
- (0, import_node_fs4.writeFileSync)(sentinelPath(dir), expectedSentinel(pins));
570
+ (0, import_node_fs5.writeFileSync)(sentinelPath(dir), expectedSentinel(pins));
484
571
  return dir;
485
572
  }
486
573
 
487
574
  // src/run-matrix.ts
488
- var import_node_path6 = require("path");
575
+ var import_node_path7 = require("path");
489
576
  async function runMatrix(spec, versions, io) {
490
577
  const entries = [];
491
578
  for (const version of versions) {
@@ -497,7 +584,7 @@ async function runMatrix(spec, versions, io) {
497
584
  const result = await runFit(versioned, resolved, {
498
585
  spawn: io.spawn,
499
586
  projectDir,
500
- outPath: (0, import_node_path6.join)(io.outDir, `${version}.samples.json`),
587
+ outPath: (0, import_node_path7.join)(io.outDir, `${version}.samples.json`),
501
588
  dataFile: io.dataFile,
502
589
  dataSha256: io.dataSha256
503
590
  });
@@ -524,7 +611,7 @@ async function runMatrix(spec, versions, io) {
524
611
  }
525
612
 
526
613
  // src/setup.ts
527
- var import_core4 = require("@mcmcjs/core");
614
+ var import_core5 = require("@mcmcjs/core");
528
615
  var JULIAUP_INSTALL_URL = "https://install.julialang.org";
529
616
  function juliaupInstallCommand(platform) {
530
617
  if (platform === "win32") {
@@ -534,20 +621,20 @@ function juliaupInstallCommand(platform) {
534
621
  command: "sh",
535
622
  args: [
536
623
  "-c",
537
- `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${import_core4.DEFAULT_JULIA_CHANNEL}`
624
+ `curl -fsSL ${JULIAUP_INSTALL_URL} | sh -s -- --yes --default-channel ${import_core5.DEFAULT_JULIA_CHANNEL}`
538
625
  ]
539
626
  };
540
627
  }
541
628
  function planSetup(report, platform) {
542
- if (report.julia.found && report.julia.version === import_core4.DEFAULT_JULIA_CHANNEL) return [];
629
+ if (report.julia.found && report.julia.version === import_core5.DEFAULT_JULIA_CHANNEL) return [];
543
630
  if (report.juliaup.found) {
544
631
  return [
545
632
  {
546
633
  tool: "julia",
547
- label: `install the pinned Julia ${import_core4.DEFAULT_JULIA_CHANNEL} via juliaup`,
634
+ label: `install the pinned Julia ${import_core5.DEFAULT_JULIA_CHANNEL} via juliaup`,
548
635
  command: {
549
636
  command: report.juliaup.path ?? "juliaup",
550
- args: ["add", import_core4.DEFAULT_JULIA_CHANNEL]
637
+ args: ["add", import_core5.DEFAULT_JULIA_CHANNEL]
551
638
  }
552
639
  }
553
640
  ];
@@ -555,7 +642,7 @@ function planSetup(report, platform) {
555
642
  return [
556
643
  {
557
644
  tool: "juliaup",
558
- label: `install juliaup with the pinned Julia ${import_core4.DEFAULT_JULIA_CHANNEL}`,
645
+ label: `install juliaup with the pinned Julia ${import_core5.DEFAULT_JULIA_CHANNEL}`,
559
646
  command: juliaupInstallCommand(platform)
560
647
  }
561
648
  ];
@@ -674,9 +761,9 @@ function assertVersionsInstalled(channels, installed) {
674
761
 
675
762
  // src/worker.ts
676
763
  var import_node_child_process = require("child_process");
677
- var import_node_fs5 = require("fs");
764
+ var import_node_fs6 = require("fs");
678
765
  var import_node_net = require("net");
679
- var import_node_path7 = require("path");
766
+ var import_node_path8 = require("path");
680
767
  var import_engine4 = require("@mcmcjs/engine");
681
768
  var START_WAIT_MS = 18e4;
682
769
  var CONNECT_TIMEOUT_MS = 1e3;
@@ -695,7 +782,7 @@ function workerPidPath(socket) {
695
782
  function killWorker(socket) {
696
783
  const pidPath = workerPidPath(socket);
697
784
  try {
698
- const pid = Number((0, import_node_fs5.readFileSync)(pidPath, "utf8").trim());
785
+ const pid = Number((0, import_node_fs6.readFileSync)(pidPath, "utf8").trim());
699
786
  if (Number.isInteger(pid) && pid > 0) {
700
787
  try {
701
788
  process.kill(-pid, "SIGKILL");
@@ -705,17 +792,17 @@ function killWorker(socket) {
705
792
  }
706
793
  } catch {
707
794
  }
708
- (0, import_node_fs5.rmSync)(socket, { force: true });
709
- (0, import_node_fs5.rmSync)(pidPath, { force: true });
795
+ (0, import_node_fs6.rmSync)(socket, { force: true });
796
+ (0, import_node_fs6.rmSync)(pidPath, { force: true });
710
797
  }
711
798
  function workersDir() {
712
799
  const runtime = process.env.XDG_RUNTIME_DIR;
713
- const dir = runtime ? (0, import_node_path7.join)(runtime, "mcmcjs") : (0, import_node_path7.join)(sharedTmpParent(), "workers");
714
- (0, import_node_fs5.mkdirSync)(dir, { recursive: true, mode: 448 });
800
+ const dir = runtime ? (0, import_node_path8.join)(runtime, "mcmcjs") : (0, import_node_path8.join)(sharedTmpParent(), "workers");
801
+ (0, import_node_fs6.mkdirSync)(dir, { recursive: true, mode: 448 });
715
802
  return dir;
716
803
  }
717
804
  function workerSocketPath(command, projectDir) {
718
- return (0, import_node_path7.join)(workersDir(), `worker-${sha256(`${command}
805
+ return (0, import_node_path8.join)(workersDir(), `worker-${sha256(`${command}
719
806
  ${projectDir}`).slice(0, 12)}.sock`);
720
807
  }
721
808
  function connectOnce(path) {
@@ -739,13 +826,13 @@ var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
739
826
  function acquireStartLock(socketPath) {
740
827
  const lock = `${socketPath}.start`;
741
828
  try {
742
- (0, import_node_fs5.mkdirSync)(lock);
829
+ (0, import_node_fs6.mkdirSync)(lock);
743
830
  return true;
744
831
  } catch {
745
832
  try {
746
- if (Date.now() - (0, import_node_fs5.statSync)(lock).mtimeMs > START_WAIT_MS) {
747
- (0, import_node_fs5.rmdirSync)(lock);
748
- (0, import_node_fs5.mkdirSync)(lock);
833
+ if (Date.now() - (0, import_node_fs6.statSync)(lock).mtimeMs > START_WAIT_MS) {
834
+ (0, import_node_fs6.rmdirSync)(lock);
835
+ (0, import_node_fs6.mkdirSync)(lock);
749
836
  return true;
750
837
  }
751
838
  } catch {
@@ -755,7 +842,7 @@ function acquireStartLock(socketPath) {
755
842
  }
756
843
  function releaseStartLock(socketPath) {
757
844
  try {
758
- (0, import_node_fs5.rmdirSync)(`${socketPath}.start`);
845
+ (0, import_node_fs6.rmdirSync)(`${socketPath}.start`);
759
846
  } catch {
760
847
  }
761
848
  }
@@ -770,7 +857,7 @@ async function ensureWorker(resolved, projectDir, notify, signal) {
770
857
  const startedHere = acquireStartLock(path);
771
858
  if (startedHere) {
772
859
  try {
773
- (0, import_node_fs5.rmSync)(path, { force: true });
860
+ (0, import_node_fs6.rmSync)(path, { force: true });
774
861
  notify?.("starting the Julia worker (first use loads Turing, can take a minute)...");
775
862
  const child = (0, import_node_child_process.spawn)(
776
863
  resolved.command,
@@ -962,10 +1049,10 @@ async function runFitAuto(spec, resolved, io) {
962
1049
  }
963
1050
  async function listWorkers() {
964
1051
  const dir = workersDir();
965
- const sockets = (0, import_node_fs5.readdirSync)(dir).filter((f) => f.startsWith("worker-") && f.endsWith(".sock"));
1052
+ const sockets = (0, import_node_fs6.readdirSync)(dir).filter((f) => f.startsWith("worker-") && f.endsWith(".sock"));
966
1053
  const statuses = [];
967
1054
  for (const name of sockets) {
968
- const socket = (0, import_node_path7.join)(dir, name);
1055
+ const socket = (0, import_node_path8.join)(dir, name);
969
1056
  let alive = false;
970
1057
  try {
971
1058
  const sock = await connectOnce(socket);
@@ -982,7 +1069,7 @@ async function stopWorker(socket) {
982
1069
  try {
983
1070
  sock = await connectOnce(socket);
984
1071
  } catch {
985
- (0, import_node_fs5.rmSync)(socket, { force: true });
1072
+ (0, import_node_fs6.rmSync)(socket, { force: true });
986
1073
  return "stale";
987
1074
  }
988
1075
  const acked = await new Promise((resolve) => {
@@ -998,7 +1085,7 @@ async function stopWorker(socket) {
998
1085
  });
999
1086
  sock.destroy();
1000
1087
  if (!acked) return "pending";
1001
- (0, import_node_fs5.rmSync)(socket, { force: true });
1088
+ (0, import_node_fs6.rmSync)(socket, { force: true });
1002
1089
  return "stopped";
1003
1090
  }
1004
1091
  // Annotate the CommonJS export names for ESM import in node:
@@ -1023,6 +1110,7 @@ async function stopWorker(socket) {
1023
1110
  runDoctor,
1024
1111
  runFit,
1025
1112
  runFitAuto,
1113
+ runLogLik,
1026
1114
  runMatrix,
1027
1115
  runPredict,
1028
1116
  runSetup,