@femtomc/mu-core 26.2.68 → 26.2.70

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.
@@ -1,4 +1,4 @@
1
- export { appendJsonl, FsJsonlStore, readJsonl, streamJsonl, writeJsonl } from "./jsonl.js";
1
+ export { appendJsonl, FsJsonlStore, JsonlParseError, JsonlQueryValidationError, readJsonl, streamJsonl, writeJsonl, } from "./jsonl.js";
2
2
  export { currentRunId, runContext } from "./run_context.js";
3
3
  export type { StorePaths } from "./store.js";
4
4
  export { findRepoRoot, getStorePaths } from "./store.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAkB,MAAM,cAAc,CAAC;AAKxD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAEjE;AAED,cAAc,WAAW,CAAC;AAE1B,OAAO,EACN,aAAa,EACb,KAAK,aAAa,EAClB,QAAQ,EACR,KAAK,SAAS,EACd,cAAc,EACd,aAAa,EACb,KAAK,aAAa,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACxE,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,YAAY,EACZ,eAAe,EACf,yBAAyB,EACzB,SAAS,EACT,WAAW,EACX,UAAU,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,QAAQ,EAAkB,MAAM,cAAc,CAAC;AAKxD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAEjE;AAED,cAAc,WAAW,CAAC;AAE1B,OAAO,EACN,aAAa,EACb,KAAK,aAAa,EAClB,QAAQ,EACR,KAAK,SAAS,EACd,cAAc,EACd,aAAa,EACb,KAAK,aAAa,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACxE,cAAc,YAAY,CAAC"}
@@ -1,4 +1,4 @@
1
- export { appendJsonl, FsJsonlStore, readJsonl, streamJsonl, writeJsonl } from "./jsonl.js";
1
+ export { appendJsonl, FsJsonlStore, JsonlParseError, JsonlQueryValidationError, readJsonl, streamJsonl, writeJsonl, } from "./jsonl.js";
2
2
  export { currentRunId, runContext } from "./run_context.js";
3
3
  export { findRepoRoot, getStorePaths } from "./store.js";
4
4
  import { EventLog, JsonlEventSink } from "../events.js";
@@ -1,6 +1,24 @@
1
1
  import type { JsonlStore } from "../persistence.js";
2
+ export declare class JsonlParseError extends SyntaxError {
3
+ readonly filePath: string;
4
+ readonly lineNumber: number;
5
+ readonly rawLine: string;
6
+ constructor(opts: {
7
+ filePath: string;
8
+ lineNumber: number;
9
+ rawLine: string;
10
+ cause: unknown;
11
+ });
12
+ }
13
+ export declare class JsonlQueryValidationError extends TypeError {
14
+ constructor(message: string, opts?: {
15
+ cause?: unknown;
16
+ });
17
+ }
2
18
  export declare function streamJsonl(path: string): AsyncGenerator<unknown>;
3
- export declare function readJsonl(path: string): Promise<unknown[]>;
19
+ export declare function readJsonl(path: string, opts?: {
20
+ limit?: number | null;
21
+ }): Promise<unknown[]>;
4
22
  export declare function writeJsonl(path: string, rows: readonly unknown[]): Promise<void>;
5
23
  export declare function appendJsonl(path: string, row: unknown): Promise<void>;
6
24
  export declare class FsJsonlStore<T = unknown> implements JsonlStore<T> {
@@ -9,5 +27,6 @@ export declare class FsJsonlStore<T = unknown> implements JsonlStore<T> {
9
27
  read(): Promise<T[]>;
10
28
  write(rows: readonly T[]): Promise<void>;
11
29
  append(row: T): Promise<void>;
30
+ stream(): AsyncGenerator<T>;
12
31
  }
13
32
  //# sourceMappingURL=jsonl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../src/node/jsonl.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAmBpD,wBAAuB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAmBxE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAMhE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAC9D,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;IAIlB,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../../src/node/jsonl.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAoBpD,qBAAa,eAAgB,SAAQ,WAAW;IAC/C,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,OAAO,EAAE,MAAM,CAAC;gBAEb,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE;CAUlG;AAED,qBAAa,yBAA0B,SAAQ,SAAS;gBACpC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI9D;AAeD,wBAAuB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CA8BxE;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CA2BtG;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtF;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;IAC9D,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,MAAM;IAIlB,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5B,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC;CAKzC"}
@@ -4,7 +4,8 @@ import { dirname, join, parse as parsePath } from "node:path";
4
4
  import { createInterface } from "node:readline";
5
5
  function tmpPathFor(path) {
6
6
  const parsed = parsePath(path);
7
- return join(parsed.dir, `${parsed.name}.tmp`);
7
+ const nonce = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
8
+ return join(parsed.dir, `${parsed.base}.${nonce}.tmp`);
8
9
  }
9
10
  async function exists(path) {
10
11
  try {
@@ -18,19 +19,64 @@ async function exists(path) {
18
19
  throw err;
19
20
  }
20
21
  }
22
+ export class JsonlParseError extends SyntaxError {
23
+ filePath;
24
+ lineNumber;
25
+ rawLine;
26
+ constructor(opts) {
27
+ const causeMessage = opts.cause instanceof Error ? opts.cause.message : String(opts.cause);
28
+ super(`invalid jsonl row at ${opts.filePath}:${opts.lineNumber}: ${causeMessage}`, {
29
+ cause: opts.cause,
30
+ });
31
+ this.name = "JsonlParseError";
32
+ this.filePath = opts.filePath;
33
+ this.lineNumber = opts.lineNumber;
34
+ this.rawLine = opts.rawLine;
35
+ }
36
+ }
37
+ export class JsonlQueryValidationError extends TypeError {
38
+ constructor(message, opts) {
39
+ super(message, opts);
40
+ this.name = "JsonlQueryValidationError";
41
+ }
42
+ }
43
+ function normalizeReadLimit(limit) {
44
+ if (limit == null) {
45
+ return null;
46
+ }
47
+ if (typeof limit !== "number" || !Number.isFinite(limit) || !Number.isInteger(limit)) {
48
+ throw new JsonlQueryValidationError("invalid jsonl read limit: expected positive integer");
49
+ }
50
+ if (limit < 1) {
51
+ throw new JsonlQueryValidationError("invalid jsonl read limit: must be >= 1");
52
+ }
53
+ return limit;
54
+ }
21
55
  export async function* streamJsonl(path) {
22
56
  if (!(await exists(path))) {
23
57
  return;
24
58
  }
25
59
  const file = createReadStream(path, { encoding: "utf8" });
26
60
  const rl = createInterface({ input: file, crlfDelay: Number.POSITIVE_INFINITY });
61
+ let lineNumber = 0;
27
62
  try {
28
63
  for await (const line of rl) {
64
+ lineNumber += 1;
29
65
  const trimmed = line.trim();
30
66
  if (trimmed.length === 0) {
31
67
  continue;
32
68
  }
33
- yield JSON.parse(trimmed);
69
+ try {
70
+ yield JSON.parse(trimmed);
71
+ }
72
+ catch (error) {
73
+ throw new JsonlParseError({
74
+ filePath: path,
75
+ lineNumber,
76
+ rawLine: trimmed,
77
+ cause: error,
78
+ });
79
+ }
34
80
  }
35
81
  }
36
82
  finally {
@@ -38,12 +84,30 @@ export async function* streamJsonl(path) {
38
84
  file.close();
39
85
  }
40
86
  }
41
- export async function readJsonl(path) {
42
- const rows = [];
87
+ export async function readJsonl(path, opts = {}) {
88
+ const limit = normalizeReadLimit(opts.limit);
89
+ if (limit == null) {
90
+ const rows = [];
91
+ for await (const row of streamJsonl(path)) {
92
+ rows.push(row);
93
+ }
94
+ return rows;
95
+ }
96
+ const ring = new Array(limit);
97
+ let total = 0;
43
98
  for await (const row of streamJsonl(path)) {
44
- rows.push(row);
99
+ ring[total % limit] = row;
100
+ total += 1;
45
101
  }
46
- return rows;
102
+ if (total <= limit) {
103
+ return ring.slice(0, total);
104
+ }
105
+ const out = [];
106
+ const start = total % limit;
107
+ for (let i = 0; i < limit; i += 1) {
108
+ out.push(ring[(start + i) % limit]);
109
+ }
110
+ return out;
47
111
  }
48
112
  export async function writeJsonl(path, rows) {
49
113
  await mkdir(dirname(path), { recursive: true });
@@ -77,4 +141,9 @@ export class FsJsonlStore {
77
141
  async append(row) {
78
142
  await appendJsonl(this.path, row);
79
143
  }
144
+ async *stream() {
145
+ for await (const row of streamJsonl(this.path)) {
146
+ yield row;
147
+ }
148
+ }
80
149
  }
@@ -2,6 +2,7 @@ export type JsonlStore<T = unknown> = {
2
2
  read(): Promise<T[]>;
3
3
  write(rows: readonly T[]): Promise<void>;
4
4
  append(row: T): Promise<void>;
5
+ stream?(): AsyncGenerator<T>;
5
6
  };
6
7
  export declare class InMemoryJsonlStore<T = unknown> implements JsonlStore<T> {
7
8
  #private;
@@ -9,5 +10,6 @@ export declare class InMemoryJsonlStore<T = unknown> implements JsonlStore<T> {
9
10
  read(): Promise<T[]>;
10
11
  write(rows: readonly T[]): Promise<void>;
11
12
  append(row: T): Promise<void>;
13
+ stream(): AsyncGenerator<T>;
12
14
  }
13
15
  //# sourceMappingURL=persistence.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI;IACrC,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAEF,qBAAa,kBAAkB,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;;gBAGjD,OAAO,GAAE,SAAS,CAAC,EAAO;IAIhC,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI;IACrC,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC;IACrB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;CAC7B,CAAC;AAEF,qBAAa,kBAAkB,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,UAAU,CAAC,CAAC,CAAC;;gBAGjD,OAAO,GAAE,SAAS,CAAC,EAAO;IAIhC,IAAI,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpB,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5B,MAAM,IAAI,cAAc,CAAC,CAAC,CAAC;CAKzC"}
@@ -12,4 +12,9 @@ export class InMemoryJsonlStore {
12
12
  async append(row) {
13
13
  this.#rows.push(row);
14
14
  }
15
+ async *stream() {
16
+ for (const row of this.#rows) {
17
+ yield row;
18
+ }
19
+ }
15
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@femtomc/mu-core",
3
- "version": "26.2.68",
3
+ "version": "26.2.70",
4
4
  "description": "Core primitives for mu: IDs, events, DAG helpers, and persistence interfaces.",
5
5
  "keywords": [
6
6
  "mu",