@yishiguji/tokenarena 0.16.3 → 0.16.4

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.js CHANGED
@@ -645,13 +645,15 @@ function readRollout(path) {
645
645
  let latestTimestampOrder = 0n;
646
646
  let minLineTimestampOrder = null;
647
647
  let line = 0;
648
- let lineCount = 0;
648
+ let maxOrdinal = null;
649
649
  for (const text of content.split("\n")) {
650
650
  line++;
651
651
  if (!text.trim()) continue;
652
- lineCount++;
653
652
  try {
654
653
  const event = JSON.parse(text);
654
+ if (typeof event.ordinal === "number" && Number.isSafeInteger(event.ordinal) && event.ordinal >= 0 && (maxOrdinal === null || event.ordinal > maxOrdinal)) {
655
+ maxOrdinal = event.ordinal;
656
+ }
655
657
  const timestamp = readTimestamp(event.timestamp);
656
658
  const order = timestampOrder(event.timestamp, timestamp);
657
659
  if (order !== null) {
@@ -702,7 +704,7 @@ function readRollout(path) {
702
704
  forkedFrom && spawnedFrom && forkedFrom !== spawnedFrom
703
705
  ),
704
706
  forkOrdinalExclusive: typeof meta?.forked_from_ordinal_exclusive === "number" && Number.isSafeInteger(meta.forked_from_ordinal_exclusive) && meta.forked_from_ordinal_exclusive > 0 ? meta.forked_from_ordinal_exclusive : null,
705
- lineCount,
707
+ maxOrdinal,
706
708
  rootTimestampOrder: timestampOrder(
707
709
  rootMeta?.timestamp,
708
710
  readTimestamp(rootMeta?.timestamp)
@@ -809,13 +811,11 @@ var CodexParser = class {
809
811
  if (file.parentConflict || file.parentId) {
810
812
  const parent = file.parentId ? threadIndex.get(file.parentId) : void 0;
811
813
  const cutoff = file.rootTimestampOrder;
812
- const coverageOk = parent ? file.forkOrdinalExclusive !== null ? (
813
- // 多文件父线程按最新文件(通常就是产生该 fork 的 rollout)
814
- // 的行数核验;其余文件属于同一线程的历史分段。
815
- parent.files.some(
816
- (rollout) => rollout.lineCount >= (file.forkOrdinalExclusive ?? 0)
817
- )
818
- ) : cutoff !== null && // 父最大时间戳落后不超过 1 秒,或父内容完全早于截止点
814
+ const parentMaxOrdinal = parent ? parent.files.reduce(
815
+ (max, rollout) => rollout.maxOrdinal !== null && (max === null || rollout.maxOrdinal > max) ? rollout.maxOrdinal : max,
816
+ null
817
+ ) : null;
818
+ const coverageOk = parent ? file.forkOrdinalExclusive !== null && parentMaxOrdinal !== null ? parentMaxOrdinal >= file.forkOrdinalExclusive - 1 : cutoff !== null && // 父最大时间戳落后不超过 1 秒,或父内容完全早于截止点
819
819
  // 且父最早行时间戳也早于截止点(父在截止前已停止写入)。
820
820
  (parent.latestTimestampOrder >= cutoff - 1000000n || parent.minLineTimestampOrder !== null && parent.minLineTimestampOrder < cutoff) : false;
821
821
  if (file.parentConflict || !parent || parent === thread || cutoff === null || !processThread(parent) || parent.invalidTokenTimestamp || !coverageOk) {
@@ -1282,7 +1282,15 @@ import { dirname, join as join6 } from "path";
1282
1282
  import { execFileSync } from "child_process";
1283
1283
  import { statSync } from "fs";
1284
1284
  import { pathToFileURL } from "url";
1285
- function withSuppressedSqliteWarning(fn) {
1285
+ var warningScope = Promise.resolve();
1286
+ async function withSuppressedSqliteWarning(fn) {
1287
+ const previousScope = warningScope;
1288
+ let releaseScope = () => {
1289
+ };
1290
+ warningScope = new Promise((resolve5) => {
1291
+ releaseScope = resolve5;
1292
+ });
1293
+ await previousScope;
1286
1294
  const originalEmitWarning = process.emitWarning;
1287
1295
  process.emitWarning = ((warning, ...args) => {
1288
1296
  const warningName = typeof warning === "string" ? typeof args[0] === "string" ? args[0] : "" : warning.name;
@@ -1292,9 +1300,12 @@ function withSuppressedSqliteWarning(fn) {
1292
1300
  }
1293
1301
  originalEmitWarning.call(process, warning, ...args);
1294
1302
  });
1295
- return fn().finally(() => {
1303
+ try {
1304
+ return await fn();
1305
+ } finally {
1296
1306
  process.emitWarning = originalEmitWarning;
1297
- });
1307
+ releaseScope();
1308
+ }
1298
1309
  }
1299
1310
  function warnWhenWalSkipped(dbPath) {
1300
1311
  try {
@@ -2375,25 +2386,9 @@ function getOpenCodeDataDirs(env = process.env) {
2375
2386
  ].filter((value) => Boolean(value));
2376
2387
  return Array.from(new Set(dirs));
2377
2388
  }
2378
- async function withSuppressedSqliteWarning2(fn) {
2379
- const originalEmitWarning = process.emitWarning;
2380
- process.emitWarning = ((warning, ...args) => {
2381
- const warningName = typeof warning === "string" ? typeof args[0] === "string" ? args[0] : "" : warning.name;
2382
- const warningMessage = typeof warning === "string" ? warning : warning.message;
2383
- if (warningName === "ExperimentalWarning" && warningMessage.includes("SQLite")) {
2384
- return;
2385
- }
2386
- originalEmitWarning.call(process, warning, ...args);
2387
- });
2388
- try {
2389
- return await fn();
2390
- } finally {
2391
- process.emitWarning = originalEmitWarning;
2392
- }
2393
- }
2394
2389
  async function readSqliteRowsWithBuiltin2(dbPath, query) {
2395
2390
  try {
2396
- return await withSuppressedSqliteWarning2(async () => {
2391
+ return await withSuppressedSqliteWarning(async () => {
2397
2392
  const sqliteModuleId = "node:sqlite";
2398
2393
  const sqlite = await import(sqliteModuleId);
2399
2394
  const db = new sqlite.DatabaseSync(dbPath);
@@ -7421,13 +7416,13 @@ function saveCachedParseResult(toolId, fingerprint2, result) {
7421
7416
  // src/services/parser-service.ts
7422
7417
  var PARSER_CONCURRENCY = 8;
7423
7418
  async function parseWithCache(parser) {
7424
- const files = parser.listSourceFiles?.();
7425
- const fingerprint2 = files ? computeScanFingerprint(files) : null;
7426
- const cached = loadCachedParseResult(parser.tool.id, fingerprint2);
7427
- if (cached) {
7428
- return { status: "ok", result: cached, cached: true };
7429
- }
7430
7419
  try {
7420
+ const files = parser.listSourceFiles?.();
7421
+ const fingerprint2 = files ? computeScanFingerprint(files) : null;
7422
+ const cached = loadCachedParseResult(parser.tool.id, fingerprint2);
7423
+ if (cached) {
7424
+ return { status: "ok", result: cached, cached: true };
7425
+ }
7431
7426
  const result = await parser.parse();
7432
7427
  saveCachedParseResult(parser.tool.id, fingerprint2, result);
7433
7428
  return { status: "ok", result, cached: false };
@@ -7564,14 +7559,28 @@ function toDeviceMetadata(config) {
7564
7559
  hostname: hostname7().replace(/\.local$/, "")
7565
7560
  };
7566
7561
  }
7567
- function toUploadBuckets(buckets, settings, device) {
7562
+ function createProjectIdentityResolver(settings) {
7563
+ const identities = /* @__PURE__ */ new Map();
7564
+ return (project) => {
7565
+ const name = project || "unknown";
7566
+ let identity = identities.get(name);
7567
+ if (!identity) {
7568
+ identity = toProjectIdentity({
7569
+ project: name,
7570
+ mode: settings.projectMode,
7571
+ salt: settings.projectHashSalt
7572
+ });
7573
+ identities.set(name, identity);
7574
+ }
7575
+ return identity;
7576
+ };
7577
+ }
7578
+ function toUploadBuckets(buckets, settings, device, resolveProject = createProjectIdentityResolver(
7579
+ settings
7580
+ )) {
7568
7581
  const aggregated = /* @__PURE__ */ new Map();
7569
7582
  for (const bucket of buckets) {
7570
- const project = toProjectIdentity({
7571
- project: bucket.project || "unknown",
7572
- mode: settings.projectMode,
7573
- salt: settings.projectHashSalt
7574
- });
7583
+ const project = resolveProject(bucket.project);
7575
7584
  const key = [
7576
7585
  bucket.source,
7577
7586
  bucket.model,
@@ -7607,13 +7616,11 @@ function toUploadBuckets(buckets, settings, device) {
7607
7616
  }
7608
7617
  return Array.from(aggregated.values());
7609
7618
  }
7610
- function toUploadSessions(sessions, settings, device) {
7619
+ function toUploadSessions(sessions, settings, device, resolveProject = createProjectIdentityResolver(
7620
+ settings
7621
+ )) {
7611
7622
  return sessions.map((session) => {
7612
- const project = toProjectIdentity({
7613
- project: session.project || "unknown",
7614
- mode: settings.projectMode,
7615
- salt: settings.projectHashSalt
7616
- });
7623
+ const project = resolveProject(session.project);
7617
7624
  return {
7618
7625
  source: session.source,
7619
7626
  projectKey: project.projectKey,
@@ -7792,8 +7799,19 @@ async function runSync(config, opts = {}) {
7792
7799
  deviceId: device.deviceId,
7793
7800
  settings
7794
7801
  });
7795
- const uploadBuckets = toUploadBuckets(allBuckets, settings, device);
7796
- const uploadSessions = toUploadSessions(allSessions, settings, device);
7802
+ const resolveProject = createProjectIdentityResolver(settings);
7803
+ const uploadBuckets = toUploadBuckets(
7804
+ allBuckets,
7805
+ settings,
7806
+ device,
7807
+ resolveProject
7808
+ );
7809
+ const uploadSessions = toUploadSessions(
7810
+ allSessions,
7811
+ settings,
7812
+ device,
7813
+ resolveProject
7814
+ );
7797
7815
  const previousManifest = loadUploadManifest();
7798
7816
  const uploadDiff = diffUploadManifest({
7799
7817
  buckets: uploadBuckets,
@@ -7846,7 +7864,9 @@ async function runSync(config, opts = {}) {
7846
7864
  skippedParts.length > 0 ? `No new or updated usage data to upload. Skipped ${skippedParts.join(" + ")}.` : "No new or updated usage data to upload."
7847
7865
  );
7848
7866
  }
7849
- persistUploadManifest(uploadDiff.nextManifest, quiet);
7867
+ if (uploadDiff.removedBuckets > 0 || uploadDiff.removedSessions > 0) {
7868
+ persistUploadManifest(uploadDiff.nextManifest, quiet);
7869
+ }
7850
7870
  markSyncSucceeded(source, { buckets: 0, sessions: 0 });
7851
7871
  return { buckets: 0, sessions: 0 };
7852
7872
  }