@stim-cli/metro 1.0.0-rc.9 → 1.1.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Optional Metro integration for Stim. It exports a transform cache shared across
4
4
  worktrees and an NDJSON reporter for structured Metro and client logs.
5
5
 
6
- If Stim is not installed globally, replace `stim` with `npx stim-cli`.
6
+ If Stim is not installed globally, replace `stim` with `npx stim`.
7
7
 
8
8
  ```bash
9
9
  npm install --save-dev @stim-cli/metro
@@ -36,7 +36,8 @@ blocking Metro. Provider failures are misses.
36
36
  ```
37
37
 
38
38
  Under `stim start` the supervisor passes the resolved selection to Metro. A
39
- Metro process outside Stim reads the nearest committed `.stim.json`. See
39
+ Metro process outside Stim reads `.stim.json` only from its app working directory;
40
+ it does not inherit a monorepo-root provider. See
40
41
  [`@stim-cli/cache`](https://www.npmjs.com/package/@stim-cli/cache) for the
41
42
  provider contract. `clear()` only clears the local tier.
42
43
 
@@ -55,5 +56,5 @@ The reporter must be attached to the config passed directly to
55
56
  Stim supplies this integration automatically for Stim-managed servers. Add the
56
57
  package directly only for Metro processes that run outside Stim.
57
58
 
58
- See the [cache package documentation](https://appandflow.github.io/stim/docs/cache-packages)
59
+ See the [cache package documentation](https://stim.appandflow.com/docs/cache-packages)
59
60
  for current usage and cleanup guidance.
package/dist/index.d.mts CHANGED
@@ -18,7 +18,8 @@ interface MetroEvent {
18
18
  level?: unknown;
19
19
  data?: unknown;
20
20
  error?: unknown;
21
- stack?: string;
21
+ stack?: unknown;
22
+ codeFrame?: unknown;
22
23
  buildID?: string;
23
24
  bundleDetails?: {
24
25
  platform?: string | null;
package/dist/index.mjs CHANGED
@@ -22,37 +22,22 @@ function registerOnce(dir, replaces = []) {
22
22
  function isPlainObject(value) {
23
23
  return value !== null && typeof value === "object" && !Array.isArray(value);
24
24
  }
25
- function repositoryRoot(startDir) {
26
- let dir = startDir;
27
- for (;;) {
28
- if (fs.existsSync(path.join(dir, ".git"))) return dir;
29
- const parent = path.dirname(dir);
30
- if (parent === dir) return null;
31
- dir = parent;
32
- }
33
- }
34
25
  function committedProviderConfig(startDir) {
35
- const start = path.resolve(startDir);
36
- const stop = repositoryRoot(start) ?? start;
37
- let dir = start;
38
- for (;;) {
39
- let parsed;
40
- try {
41
- parsed = JSON.parse(fs.readFileSync(path.join(dir, ".stim.json"), "utf-8"));
42
- } catch {
43
- parsed = null;
44
- }
45
- const cache = isPlainObject(parsed) && isPlainObject(parsed.cache) ? parsed.cache : null;
46
- const reference = cache?.provider;
47
- if (typeof reference === "string" && reference.trim() !== "") return {
48
- provider: reference.trim(),
49
- options: isPlainObject(cache?.options) ? cache.options : {},
50
- baseDir: dir
51
- };
52
- const parent = path.dirname(dir);
53
- if (dir === stop || parent === dir) return null;
54
- dir = parent;
26
+ let dir;
27
+ let parsed;
28
+ try {
29
+ dir = fs.realpathSync(startDir);
30
+ parsed = JSON.parse(fs.readFileSync(path.join(dir, ".stim.json"), "utf-8"));
31
+ } catch {
32
+ return null;
55
33
  }
34
+ const cache = isPlainObject(parsed) && isPlainObject(parsed.cache) ? parsed.cache : null;
35
+ const reference = cache?.provider;
36
+ return typeof reference === "string" && reference.trim() !== "" ? {
37
+ provider: reference.trim(),
38
+ options: isPlainObject(cache?.options) ? cache.options : {},
39
+ baseDir: dir
40
+ } : null;
56
41
  }
57
42
  function warnToStderr(_code, message) {
58
43
  process.stderr.write(`warning: ${message}\n`);
@@ -129,6 +114,23 @@ function errorMessage(error) {
129
114
  if (typeof error.message === "string" && error.message) return error.message;
130
115
  return formatValue(error);
131
116
  }
117
+ function symbolicationMessage(codeFrame) {
118
+ if (!isPlainObject(codeFrame) || typeof codeFrame.content !== "string") return "Call Stack";
119
+ const fileName = typeof codeFrame.fileName === "string" ? codeFrame.fileName : "unknown source";
120
+ const location = isPlainObject(codeFrame.location) ? codeFrame.location : null;
121
+ return `Code: ${fileName}${typeof location?.row === "number" ? `:${location.row}` : ""}${typeof location?.column === "number" ? `:${location.column}` : ""}\n${codeFrame.content}\nCall Stack`;
122
+ }
123
+ function symbolicationStack(stack) {
124
+ if (!Array.isArray(stack)) return [];
125
+ return stack.filter((frame) => isPlainObject(frame) && frame.collapse !== true).map((frame) => {
126
+ const normalized = {};
127
+ if (typeof frame.file === "string") normalized.file = frame.file;
128
+ if (typeof frame.lineNumber === "number") normalized.line = frame.lineNumber;
129
+ if (typeof frame.column === "number") normalized.column = frame.column;
130
+ if (typeof frame.methodName === "string") normalized.fn = frame.methodName;
131
+ return normalized;
132
+ }).filter((frame) => Object.keys(frame).length > 0);
133
+ }
132
134
  function ndjsonReporter({ dir } = {}) {
133
135
  const logDir = dir || workspaceLogDir(process.cwd());
134
136
  let ensured = false;
@@ -185,6 +187,16 @@ function ndjsonReporter({ dir } = {}) {
185
187
  write("client.ndjson", record);
186
188
  return;
187
189
  }
190
+ if (type === "client_symbolication") {
191
+ const stack = symbolicationStack(event.stack);
192
+ if (!(isPlainObject(event.codeFrame) && typeof event.codeFrame.content === "string") && stack.length === 0) return;
193
+ record.src = "client";
194
+ record.level = "info";
195
+ record.msg = symbolicationMessage(event.codeFrame);
196
+ if (stack.length > 0) record.stack = stack;
197
+ write("client.ndjson", record);
198
+ return;
199
+ }
188
200
  if (type === "bundling_error" || type === "transformer_error") {
189
201
  record.level = "error";
190
202
  record.msg = errorMessage(event.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stim-cli/metro",
3
- "version": "1.0.0-rc.9",
3
+ "version": "1.1.0",
4
4
  "description": "Metro integration for Stim: shared transforms across worktrees and structured logs.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -24,8 +24,8 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@stim-cli/cache": "^1.0.0-rc.9",
28
- "@stim-cli/core": "^1.0.0-rc.9"
27
+ "@stim-cli/cache": "^1.1.0",
28
+ "@stim-cli/core": "^1.1.0"
29
29
  },
30
30
  "peerDependencies": {
31
31
  "metro-cache": "*"