@osdk/react-devtools 0.13.0 → 0.14.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @osdk/react-devtools
2
2
 
3
+ ## 0.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - df15011: Detect actions and resolve memo component names in the component tree, and clarify the components and cache-hit-rate copy
8
+
3
9
  ## 0.13.0
4
10
 
5
11
  ### Minor Changes
@@ -95,7 +95,7 @@ export function OverviewTab({
95
95
  value: formatMetric(metrics.optimisticCoverage)
96
96
  }), /*#__PURE__*/React.createElement(Metric, {
97
97
  title: "Cache hit rate",
98
- help: /*#__PURE__*/React.createElement(React.Fragment, null, "Share of object reads served from the normalized cache instead of the network.", /*#__PURE__*/React.createElement(MetricLegend, {
98
+ help: /*#__PURE__*/React.createElement(React.Fragment, null, "How often object reads come from the cache instead of the network. Averaged over all reads since devtools started; blank until at least 20 reads.", /*#__PURE__*/React.createElement(MetricLegend, {
99
99
  entries: [{
100
100
  swatch: "success",
101
101
  label: "≥ 70%"
@@ -1 +1 @@
1
- {"version":3,"file":"OverviewTab.js","names":["AnchorButton","Classes","Icon","NonIdealState","classNames","React","useMemo","useClientMetrics","useComponentOntology","useConsoleLogs","useUnusedFieldAnalysis","formatMetric","Metric","MetricLegend","Metrics","OverviewSection","RecommendationsList","styles","OSDK_DOCS_URL","POSITIVE_IS_PROBLEM_LEGEND","swatch","label","OverviewTab","monitorStore","onNavigateToTab","metrics","useOverviewMetrics","isOntologyEmpty","objectTypeCount","actionTypeCount","linkCount","createElement","className","overviewTab","title","icon","description","action","href","target","rel","intent","endIcon","columns","value","help","requestsSaved","optimisticCoverage","Fragment","entries","cacheHitRate","footer","type","metricLink","TEXT_MUTED","onClick","size","avgResponseMs","errorWarningCount","overfetchingCount","clientMetrics","report","logs","filter","l","level","length","facets","objectTypes","actions","links","inefficientComponents"],"sources":["OverviewTab.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AnchorButton, Classes, Icon, NonIdealState } from \"@blueprintjs/core\";\nimport classNames from \"classnames\";\nimport React, { useMemo } from \"react\";\n\nimport { useClientMetrics } from \"../hooks/useClientMetrics.js\";\nimport { useComponentOntology } from \"../hooks/useComponentOntology.js\";\nimport { useConsoleLogs } from \"../hooks/useConsoleLogs.js\";\nimport { useUnusedFieldAnalysis } from \"../hooks/useUnusedFieldAnalysis.js\";\nimport { formatMetric } from \"../metrics/clientMetrics.js\";\nimport type { MonitorStore } from \"../store/MonitorStore.js\";\nimport type { DevtoolsTabId } from \"./components/devtoolsTabId.js\";\nimport { Metric } from \"./Metric.js\";\nimport { MetricLegend } from \"./MetricLegend.js\";\nimport type { MetricLegendEntry } from \"./MetricLegend.js\";\nimport { Metrics } from \"./Metrics.js\";\nimport { OverviewSection } from \"./OverviewSection.js\";\nimport { RecommendationsList } from \"./RecommendationsList.js\";\n\nimport styles from \"./OverviewTab.module.scss\";\n\n/**\n * Link to the osdk/react pages instead of the public docs since they contain more examples\n */\nconst OSDK_DOCS_URL = \"https://palantir.github.io/osdk-ts/\";\n\nexport interface OverviewTabProps {\n monitorStore: MonitorStore;\n /**\n * Switches the panel's active tab.\n */\n onNavigateToTab: (tab: DevtoolsTabId) => void;\n}\n\n/**\n * Color key shared by the count metrics where any occurrence is a problem — a\n * positive value is flagged `danger`; zero / no data reads as muted.\n */\nconst POSITIVE_IS_PROBLEM_LEGEND: readonly MetricLegendEntry[] = [\n { swatch: \"danger\", label: \"> 0\" },\n { swatch: \"none\", label: \"0 / no data\" },\n];\n\n/**\n * The Overview tab — an at-a-glance summary of the monitored client's value,\n * health, and ontology usage.\n */\nexport function OverviewTab({\n monitorStore,\n onNavigateToTab,\n}: OverviewTabProps): React.JSX.Element {\n const metrics = useOverviewMetrics(monitorStore);\n const isOntologyEmpty =\n metrics.objectTypeCount + metrics.actionTypeCount + metrics.linkCount === 0;\n\n return (\n <div className={styles.overviewTab}>\n <OverviewSection title=\"Ontology\">\n {isOntologyEmpty ? (\n <NonIdealState\n icon=\"cube\"\n title=\"No Ontology usage detected\"\n description=\"None of this app's components use the Ontology yet. Add an @osdk/react hook to a component to read objects or call actions.\"\n action={\n <AnchorButton\n href={OSDK_DOCS_URL}\n target=\"_blank\"\n rel=\"noreferrer\"\n intent=\"primary\"\n endIcon=\"share\"\n >\n View documentation\n </AnchorButton>\n }\n />\n ) : (\n <Metrics columns={3}>\n <Metric title=\"Object types\" value={metrics.objectTypeCount} />\n <Metric title=\"Action types\" value={metrics.actionTypeCount} />\n <Metric title=\"Links\" value={metrics.linkCount} />\n </Metrics>\n )}\n </OverviewSection>\n <OverviewSection title=\"Metrics\">\n <Metrics columns={2}>\n <Metric\n title=\"Requests saved\"\n help=\"Requests served from cache, revalidations, and deduplicated fetches that never hit the network.\"\n value={formatMetric(metrics.requestsSaved)}\n />\n <Metric\n title=\"Optimistic coverage\"\n help=\"Share of actions that update the UI right away, before the server confirms.\"\n value={formatMetric(metrics.optimisticCoverage)}\n />\n <Metric\n title=\"Cache hit rate\"\n help={\n <>\n Share of object reads served from the normalized cache instead\n of the network.\n <MetricLegend\n entries={[\n { swatch: \"success\", label: \"≥ 70%\" },\n { swatch: \"warning\", label: \"40–70%\" },\n { swatch: \"danger\", label: \"< 40%\" },\n ]}\n />\n </>\n }\n value={formatMetric(metrics.cacheHitRate)}\n intent={\n metrics.cacheHitRate.value == null\n ? \"none\"\n : metrics.cacheHitRate.value > 0.7\n ? \"success\"\n : metrics.cacheHitRate.value > 0.4\n ? \"warning\"\n : \"danger\"\n }\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"cache\")}\n >\n View in Cache\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n\n <Metric\n title=\"Avg response time\"\n help=\"Average response time across requests. Cache reads are typically under 1ms; network reads dominate.\"\n value={formatMetric(metrics.avgResponseMs)}\n />\n <Metric\n title=\"Errors & warnings\"\n help={\n <>\n Uncaught errors and console warnings captured from @osdk/react\n hooks and your render tree this session.\n <MetricLegend entries={POSITIVE_IS_PROBLEM_LEGEND} />\n </>\n }\n value={metrics.errorWarningCount}\n intent={metrics.errorWarningCount > 0 ? \"danger\" : \"none\"}\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"console\")}\n >\n View in Console\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n <Metric\n title=\"Overfetching\"\n help={\n <>\n Components whose hooks fetch fields that no descendant ever\n reads.\n <MetricLegend entries={POSITIVE_IS_PROBLEM_LEGEND} />\n </>\n }\n value={metrics.overfetchingCount}\n intent={\n metrics.overfetchingCount != null && metrics.overfetchingCount > 0\n ? \"danger\"\n : \"none\"\n }\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"components\")}\n >\n View in Components\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n </Metrics>\n </OverviewSection>\n <OverviewSection title=\"Recommendations\">\n <RecommendationsList monitorStore={monitorStore} />\n </OverviewSection>\n </div>\n );\n}\n\nfunction useOverviewMetrics(monitorStore: MonitorStore) {\n const clientMetrics = useClientMetrics(monitorStore);\n const { report } = useUnusedFieldAnalysis(monitorStore);\n const logs = useConsoleLogs(monitorStore);\n const errorWarningCount = useMemo(\n () =>\n logs.entries.filter((l) => l.level === \"error\" || l.level === \"warn\")\n .length,\n [logs.entries]\n );\n const { facets } = useComponentOntology(monitorStore);\n\n return {\n cacheHitRate: clientMetrics.cacheHitRate,\n requestsSaved: clientMetrics.requestsSaved,\n optimisticCoverage: clientMetrics.optimisticCoverage,\n avgResponseMs: clientMetrics.avgResponseMs,\n objectTypeCount: facets.objectTypes.length,\n actionTypeCount: facets.actions.length,\n linkCount: facets.links.length,\n overfetchingCount: report != null ? report.inefficientComponents : null,\n errorWarningCount,\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"OverviewTab.js","names":["AnchorButton","Classes","Icon","NonIdealState","classNames","React","useMemo","useClientMetrics","useComponentOntology","useConsoleLogs","useUnusedFieldAnalysis","formatMetric","Metric","MetricLegend","Metrics","OverviewSection","RecommendationsList","styles","OSDK_DOCS_URL","POSITIVE_IS_PROBLEM_LEGEND","swatch","label","OverviewTab","monitorStore","onNavigateToTab","metrics","useOverviewMetrics","isOntologyEmpty","objectTypeCount","actionTypeCount","linkCount","createElement","className","overviewTab","title","icon","description","action","href","target","rel","intent","endIcon","columns","value","help","requestsSaved","optimisticCoverage","Fragment","entries","cacheHitRate","footer","type","metricLink","TEXT_MUTED","onClick","size","avgResponseMs","errorWarningCount","overfetchingCount","clientMetrics","report","logs","filter","l","level","length","facets","objectTypes","actions","links","inefficientComponents"],"sources":["OverviewTab.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AnchorButton, Classes, Icon, NonIdealState } from \"@blueprintjs/core\";\nimport classNames from \"classnames\";\nimport React, { useMemo } from \"react\";\n\nimport { useClientMetrics } from \"../hooks/useClientMetrics.js\";\nimport { useComponentOntology } from \"../hooks/useComponentOntology.js\";\nimport { useConsoleLogs } from \"../hooks/useConsoleLogs.js\";\nimport { useUnusedFieldAnalysis } from \"../hooks/useUnusedFieldAnalysis.js\";\nimport { formatMetric } from \"../metrics/clientMetrics.js\";\nimport type { MonitorStore } from \"../store/MonitorStore.js\";\nimport type { DevtoolsTabId } from \"./components/devtoolsTabId.js\";\nimport { Metric } from \"./Metric.js\";\nimport { MetricLegend } from \"./MetricLegend.js\";\nimport type { MetricLegendEntry } from \"./MetricLegend.js\";\nimport { Metrics } from \"./Metrics.js\";\nimport { OverviewSection } from \"./OverviewSection.js\";\nimport { RecommendationsList } from \"./RecommendationsList.js\";\n\nimport styles from \"./OverviewTab.module.scss\";\n\n/**\n * Link to the osdk/react pages instead of the public docs since they contain more examples\n */\nconst OSDK_DOCS_URL = \"https://palantir.github.io/osdk-ts/\";\n\nexport interface OverviewTabProps {\n monitorStore: MonitorStore;\n /**\n * Switches the panel's active tab.\n */\n onNavigateToTab: (tab: DevtoolsTabId) => void;\n}\n\n/**\n * Color key shared by the count metrics where any occurrence is a problem — a\n * positive value is flagged `danger`; zero / no data reads as muted.\n */\nconst POSITIVE_IS_PROBLEM_LEGEND: readonly MetricLegendEntry[] = [\n { swatch: \"danger\", label: \"> 0\" },\n { swatch: \"none\", label: \"0 / no data\" },\n];\n\n/**\n * The Overview tab — an at-a-glance summary of the monitored client's value,\n * health, and ontology usage.\n */\nexport function OverviewTab({\n monitorStore,\n onNavigateToTab,\n}: OverviewTabProps): React.JSX.Element {\n const metrics = useOverviewMetrics(monitorStore);\n const isOntologyEmpty =\n metrics.objectTypeCount + metrics.actionTypeCount + metrics.linkCount === 0;\n\n return (\n <div className={styles.overviewTab}>\n <OverviewSection title=\"Ontology\">\n {isOntologyEmpty ? (\n <NonIdealState\n icon=\"cube\"\n title=\"No Ontology usage detected\"\n description=\"None of this app's components use the Ontology yet. Add an @osdk/react hook to a component to read objects or call actions.\"\n action={\n <AnchorButton\n href={OSDK_DOCS_URL}\n target=\"_blank\"\n rel=\"noreferrer\"\n intent=\"primary\"\n endIcon=\"share\"\n >\n View documentation\n </AnchorButton>\n }\n />\n ) : (\n <Metrics columns={3}>\n <Metric title=\"Object types\" value={metrics.objectTypeCount} />\n <Metric title=\"Action types\" value={metrics.actionTypeCount} />\n <Metric title=\"Links\" value={metrics.linkCount} />\n </Metrics>\n )}\n </OverviewSection>\n <OverviewSection title=\"Metrics\">\n <Metrics columns={2}>\n <Metric\n title=\"Requests saved\"\n help=\"Requests served from cache, revalidations, and deduplicated fetches that never hit the network.\"\n value={formatMetric(metrics.requestsSaved)}\n />\n <Metric\n title=\"Optimistic coverage\"\n help=\"Share of actions that update the UI right away, before the server confirms.\"\n value={formatMetric(metrics.optimisticCoverage)}\n />\n <Metric\n title=\"Cache hit rate\"\n help={\n <>\n How often object reads come from the cache instead of the\n network. Averaged over all reads since devtools started; blank\n until at least 20 reads.\n <MetricLegend\n entries={[\n { swatch: \"success\", label: \"≥ 70%\" },\n { swatch: \"warning\", label: \"40–70%\" },\n { swatch: \"danger\", label: \"< 40%\" },\n ]}\n />\n </>\n }\n value={formatMetric(metrics.cacheHitRate)}\n intent={\n metrics.cacheHitRate.value == null\n ? \"none\"\n : metrics.cacheHitRate.value > 0.7\n ? \"success\"\n : metrics.cacheHitRate.value > 0.4\n ? \"warning\"\n : \"danger\"\n }\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"cache\")}\n >\n View in Cache\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n\n <Metric\n title=\"Avg response time\"\n help=\"Average response time across requests. Cache reads are typically under 1ms; network reads dominate.\"\n value={formatMetric(metrics.avgResponseMs)}\n />\n <Metric\n title=\"Errors & warnings\"\n help={\n <>\n Uncaught errors and console warnings captured from @osdk/react\n hooks and your render tree this session.\n <MetricLegend entries={POSITIVE_IS_PROBLEM_LEGEND} />\n </>\n }\n value={metrics.errorWarningCount}\n intent={metrics.errorWarningCount > 0 ? \"danger\" : \"none\"}\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"console\")}\n >\n View in Console\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n <Metric\n title=\"Overfetching\"\n help={\n <>\n Components whose hooks fetch fields that no descendant ever\n reads.\n <MetricLegend entries={POSITIVE_IS_PROBLEM_LEGEND} />\n </>\n }\n value={metrics.overfetchingCount}\n intent={\n metrics.overfetchingCount != null && metrics.overfetchingCount > 0\n ? \"danger\"\n : \"none\"\n }\n footer={\n <button\n type=\"button\"\n className={classNames(styles.metricLink, Classes.TEXT_MUTED)}\n onClick={() => onNavigateToTab(\"components\")}\n >\n View in Components\n <Icon icon=\"arrow-right\" size={14} />\n </button>\n }\n />\n </Metrics>\n </OverviewSection>\n <OverviewSection title=\"Recommendations\">\n <RecommendationsList monitorStore={monitorStore} />\n </OverviewSection>\n </div>\n );\n}\n\nfunction useOverviewMetrics(monitorStore: MonitorStore) {\n const clientMetrics = useClientMetrics(monitorStore);\n const { report } = useUnusedFieldAnalysis(monitorStore);\n const logs = useConsoleLogs(monitorStore);\n const errorWarningCount = useMemo(\n () =>\n logs.entries.filter((l) => l.level === \"error\" || l.level === \"warn\")\n .length,\n [logs.entries]\n );\n const { facets } = useComponentOntology(monitorStore);\n\n return {\n cacheHitRate: clientMetrics.cacheHitRate,\n requestsSaved: clientMetrics.requestsSaved,\n optimisticCoverage: clientMetrics.optimisticCoverage,\n avgResponseMs: clientMetrics.avgResponseMs,\n objectTypeCount: facets.objectTypes.length,\n actionTypeCount: facets.actions.length,\n linkCount: facets.links.length,\n overfetchingCount: report != null ? report.inefficientComponents : null,\n errorWarningCount,\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -14,11 +14,13 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { Icon, Tooltip } from "@blueprintjs/core";
17
18
  import React from "react";
18
19
  import styles from "./ComponentsPanel.module.scss.js";
19
20
  function plural(count, noun) {
20
21
  return `${count} ${noun}${count === 1 ? "" : "s"}`;
21
22
  }
23
+ const SCOPE_EXPLANATION = `Only components that call an @osdk/react hook (useOsdkObject, useOsdkObjects, …) show up here. If a component only renders an OSDK-aware child like ObjectTable or ActionForm, or gets its objects through props, it won't appear. Look for the child that owns the hook instead.`;
22
24
  export const ComponentsHeader = ({
23
25
  componentCount,
24
26
  objectTypeCount,
@@ -34,6 +36,15 @@ export const ComponentsHeader = ({
34
36
  className: styles.summaryDot
35
37
  }, "\u2022"), /*#__PURE__*/React.createElement("span", null, plural(objectTypeCount, "object type")), /*#__PURE__*/React.createElement("span", {
36
38
  className: styles.summaryDot
37
- }, "\u2022"), /*#__PURE__*/React.createElement("span", null, plural(actionTypeCount, "action type"))));
39
+ }, "\u2022"), /*#__PURE__*/React.createElement("span", null, plural(actionTypeCount, "action type"))), /*#__PURE__*/React.createElement(Tooltip, {
40
+ compact: true,
41
+ content: /*#__PURE__*/React.createElement("span", {
42
+ className: styles.infoContent
43
+ }, SCOPE_EXPLANATION)
44
+ }, /*#__PURE__*/React.createElement(Icon, {
45
+ className: styles.infoIcon,
46
+ icon: "info-sign",
47
+ size: 12
48
+ })));
38
49
  };
39
50
  //# sourceMappingURL=ComponentsHeader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentsHeader.js","names":["React","styles","plural","count","noun","ComponentsHeader","componentCount","objectTypeCount","actionTypeCount","createElement","className","summary","summaryText","summaryStrong","summaryDot"],"sources":["ComponentsHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from \"react\";\n\nimport styles from \"./ComponentsPanel.module.scss\";\n\ninterface ComponentsHeaderProps {\n componentCount: number;\n objectTypeCount: number;\n actionTypeCount: number;\n}\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\nexport const ComponentsHeader: React.FC<ComponentsHeaderProps> = ({\n componentCount,\n objectTypeCount,\n actionTypeCount,\n}) => {\n return (\n <div className={styles.summary}>\n <span className={styles.summaryText}>\n <span className={styles.summaryStrong}>\n {plural(componentCount, \"component\")}\n </span>\n <span className={styles.summaryDot}>•</span>\n <span>{plural(objectTypeCount, \"object type\")}</span>\n <span className={styles.summaryDot}>•</span>\n <span>{plural(actionTypeCount, \"action type\")}</span>\n </span>\n </div>\n );\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,KAAK,MAAM,OAAO;AAEzB,OAAOC,MAAM,MAAM,+BAA+B;AAQlD,SAASC,MAAMA,CAACC,KAAa,EAAEC,IAAY,EAAU;EACnD,OAAO,GAAGD,KAAK,IAAIC,IAAI,GAAGD,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;AACpD;AAEA,OAAO,MAAME,gBAAiD,GAAGA,CAAC;EAChEC,cAAc;EACdC,eAAe;EACfC;AACF,CAAC,KAAK;EACJ,oBACER,KAAA,CAAAS,aAAA;IAAKC,SAAS,EAAET,MAAM,CAACU;EAAQ,gBAC7BX,KAAA,CAAAS,aAAA;IAAMC,SAAS,EAAET,MAAM,CAACW;EAAY,gBAClCZ,KAAA,CAAAS,aAAA;IAAMC,SAAS,EAAET,MAAM,CAACY;EAAc,GACnCX,MAAM,CAACI,cAAc,EAAE,WAAW,CAC/B,CAAC,eACPN,KAAA,CAAAS,aAAA;IAAMC,SAAS,EAAET,MAAM,CAACa;EAAW,GAAC,QAAO,CAAC,eAC5Cd,KAAA,CAAAS,aAAA,eAAOP,MAAM,CAACK,eAAe,EAAE,aAAa,CAAQ,CAAC,eACrDP,KAAA,CAAAS,aAAA;IAAMC,SAAS,EAAET,MAAM,CAACa;EAAW,GAAC,QAAO,CAAC,eAC5Cd,KAAA,CAAAS,aAAA,eAAOP,MAAM,CAACM,eAAe,EAAE,aAAa,CAAQ,CAChD,CACH,CAAC;AAEV,CAAC","ignoreList":[]}
1
+ {"version":3,"file":"ComponentsHeader.js","names":["Icon","Tooltip","React","styles","plural","count","noun","SCOPE_EXPLANATION","ComponentsHeader","componentCount","objectTypeCount","actionTypeCount","createElement","className","summary","summaryText","summaryStrong","summaryDot","compact","content","infoContent","infoIcon","icon","size"],"sources":["ComponentsHeader.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Icon, Tooltip } from \"@blueprintjs/core\";\nimport React from \"react\";\n\nimport styles from \"./ComponentsPanel.module.scss\";\n\ninterface ComponentsHeaderProps {\n componentCount: number;\n objectTypeCount: number;\n actionTypeCount: number;\n}\n\nfunction plural(count: number, noun: string): string {\n return `${count} ${noun}${count === 1 ? \"\" : \"s\"}`;\n}\n\nconst SCOPE_EXPLANATION = `Only components that call an @osdk/react hook (useOsdkObject, useOsdkObjects, …) show up here. If a component only renders an OSDK-aware child like ObjectTable or ActionForm, or gets its objects through props, it won't appear. Look for the child that owns the hook instead.`;\n\nexport const ComponentsHeader: React.FC<ComponentsHeaderProps> = ({\n componentCount,\n objectTypeCount,\n actionTypeCount,\n}) => {\n return (\n <div className={styles.summary}>\n <span className={styles.summaryText}>\n <span className={styles.summaryStrong}>\n {plural(componentCount, \"component\")}\n </span>\n <span className={styles.summaryDot}>•</span>\n <span>{plural(objectTypeCount, \"object type\")}</span>\n <span className={styles.summaryDot}>•</span>\n <span>{plural(actionTypeCount, \"action type\")}</span>\n </span>\n <Tooltip\n compact={true}\n content={\n <span className={styles.infoContent}>{SCOPE_EXPLANATION}</span>\n }\n >\n <Icon className={styles.infoIcon} icon=\"info-sign\" size={12} />\n </Tooltip>\n </div>\n );\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,IAAI,EAAEC,OAAO,QAAQ,mBAAmB;AACjD,OAAOC,KAAK,MAAM,OAAO;AAEzB,OAAOC,MAAM,MAAM,+BAA+B;AAQlD,SAASC,MAAMA,CAACC,KAAa,EAAEC,IAAY,EAAU;EACnD,OAAO,GAAGD,KAAK,IAAIC,IAAI,GAAGD,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE;AACpD;AAEA,MAAME,iBAAiB,GAAG,mRAAmR;AAE7S,OAAO,MAAMC,gBAAiD,GAAGA,CAAC;EAChEC,cAAc;EACdC,eAAe;EACfC;AACF,CAAC,KAAK;EACJ,oBACET,KAAA,CAAAU,aAAA;IAAKC,SAAS,EAAEV,MAAM,CAACW;EAAQ,gBAC7BZ,KAAA,CAAAU,aAAA;IAAMC,SAAS,EAAEV,MAAM,CAACY;EAAY,gBAClCb,KAAA,CAAAU,aAAA;IAAMC,SAAS,EAAEV,MAAM,CAACa;EAAc,GACnCZ,MAAM,CAACK,cAAc,EAAE,WAAW,CAC/B,CAAC,eACPP,KAAA,CAAAU,aAAA;IAAMC,SAAS,EAAEV,MAAM,CAACc;EAAW,GAAC,QAAO,CAAC,eAC5Cf,KAAA,CAAAU,aAAA,eAAOR,MAAM,CAACM,eAAe,EAAE,aAAa,CAAQ,CAAC,eACrDR,KAAA,CAAAU,aAAA;IAAMC,SAAS,EAAEV,MAAM,CAACc;EAAW,GAAC,QAAO,CAAC,eAC5Cf,KAAA,CAAAU,aAAA,eAAOR,MAAM,CAACO,eAAe,EAAE,aAAa,CAAQ,CAChD,CAAC,eACPT,KAAA,CAAAU,aAAA,CAACX,OAAO;IACNiB,OAAO,EAAE,IAAK;IACdC,OAAO,eACLjB,KAAA,CAAAU,aAAA;MAAMC,SAAS,EAAEV,MAAM,CAACiB;IAAY,GAAEb,iBAAwB;EAC/D,gBAEDL,KAAA,CAAAU,aAAA,CAACZ,IAAI;IAACa,SAAS,EAAEV,MAAM,CAACkB,QAAS;IAACC,IAAI,EAAC,WAAW;IAACC,IAAI,EAAE;EAAG,CAAE,CACvD,CACN,CAAC;AAEV,CAAC","ignoreList":[]}
@@ -6,6 +6,8 @@ const styles = {
6
6
  "summaryText": "ComponentsPanel-module__summaryText___LKZ3NQ1S",
7
7
  "summaryStrong": "ComponentsPanel-module__summaryStrong___29XjzvZH",
8
8
  "summaryDot": "ComponentsPanel-module__summaryDot___r3jhOWrk",
9
+ "infoIcon": "ComponentsPanel-module__infoIcon___LG4ul8dX",
10
+ "infoContent": "ComponentsPanel-module__infoContent___hy6X7-Fa",
9
11
  "filters": "ComponentsPanel-module__filters___uqN0ijBU",
10
12
  "chip": "ComponentsPanel-module__chip___8Crfzjsk",
11
13
  "chipActive": "ComponentsPanel-module__chipActive___Twf2iI7E",
@@ -175,6 +175,26 @@ const VALID_HOOK_TYPES = new Set(["useOsdkAction", "useOsdkObjects", "useOsdkObj
175
175
  function isValidHookType(value) {
176
176
  return VALID_HOOK_TYPES.has(value);
177
177
  }
178
+
179
+ /**
180
+ * The lightweight `useDevToolsMetadata` (useRef) marker stores a hook's
181
+ * identifying name under `key`, not the typed name fields. `useOsdkAction` uses
182
+ * this path with `key === actionDef.apiName`, so map it onto `actionName`;
183
+ * otherwise downstream consumers see `undefined` → "Unknown" and drop it.
184
+ */
185
+ function normalizeRefMetadata(meta) {
186
+ if (meta.hookType === "useOsdkAction" && meta.actionName == null) {
187
+ const key = meta.key;
188
+ if (typeof key === "string") {
189
+ return {
190
+ ...meta,
191
+ [OSDK_HOOK_METADATA]: true,
192
+ actionName: key
193
+ };
194
+ }
195
+ }
196
+ return meta;
197
+ }
178
198
  export function extractOsdkMetadataFromFiber(fiber) {
179
199
  return safeFiberOperation(() => {
180
200
  const results = [];
@@ -184,7 +204,7 @@ export function extractOsdkMetadataFromFiber(fiber) {
184
204
 
185
205
  // useRef check: state is { current: OsdkHookMetadata }
186
206
  if (isRefStorage(state) && isOsdkHookMetadata(state.current)) {
187
- results.push(state.current);
207
+ results.push(normalizeRefMetadata(state.current));
188
208
  }
189
209
 
190
210
  // useMemo check: state is [memoizedValue, deps]
@@ -1 +1 @@
1
- {"version":3,"file":"HookStateInspector.js","names":["getComponentId","getComponentName","getProps","safeFiberOperation","traverseAllFibers","walkFiberTree","OSDK_HOOK_METADATA","Symbol","for","isOsdkContextConsumer","fiber","fibersToCheck","alternate","filter","Boolean","f","dependencies","firstContext","ctx","value","memoizedValue","next","fallback","feature","getSourceBasedId","name","source","_debugSource","shortPath","fileName","split","slice","join","lineNumber","getFiberSourceLocation","buildConsumerInfo","componentName","sourceLocation","sourceBasedId","isOsdkFunctionComponent","type","findOsdkConsumersInAncestors","maxDepth","node","undefined","map","hasOsdkConsumerInTree","current","depth","return","createSearchBudget","scope","nodesVisited","resultsFound","maxNodes","maxAncestorLevels","maxChildDepth","maxSiblingsPerLevel","maxResults","maxTotalResults","isBudgetExhausted","budget","DEFAULT_SEARCH_SCOPE","findOsdkConsumersInSiblings","consumers","visited","Set","ancestorPath","pathFiber","add","currentAncestor","ancestorLevel","child","siblingCount","has","remaining","subtreeMatches","match","push","sibling","findOsdkConsumersInDescendants","length","matches","isOsdkHookMetadata","isRefStorage","Object","keys","VALID_HOOK_TYPES","isValidHookType","extractOsdkMetadataFromFiber","results","memoizedState","state","Array","isArray","memoValue","meta","hookType","validated","actionName","objectType","primaryKey","sourceObjectType","linkName","where","orderBy","pageSize","aggregate","MAX_PROP_KEYS","MAX_PROP_VALUE_LEN","summarizePropValue","text","JSON","stringify","String","record","$apiName","summarizeProps","raw","key","summary","discoverOsdkComponentsFromRoot","fiberRoot","components","Map","rootFiber","metadata","componentId","set","hooks","props"],"sources":["HookStateInspector.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n getComponentId,\n getComponentName,\n getProps,\n} from \"./FiberInspection.js\";\nimport { safeFiberOperation } from \"./SafeFiberOperation.js\";\nimport { traverseAllFibers, walkFiberTree } from \"./traverseFiber.js\";\nimport type {\n ContextDependency,\n Fiber,\n FiberRoot,\n MemoizedState,\n} from \"./types.js\";\n\nconst OSDK_HOOK_METADATA = Symbol.for(\"__OSDK_HOOK_METADATA__\");\n\nexport interface OsdkHookMetadata {\n readonly [key: symbol]: true;\n readonly hookType:\n | \"useOsdkAction\"\n | \"useOsdkObjects\"\n | \"useOsdkObject\"\n | \"useLinks\"\n | \"useOsdkAggregation\"\n | \"useOsdkFunction\"\n | \"useObjectSet\";\n readonly actionName?: string;\n readonly objectType?: string;\n readonly primaryKey?: string;\n readonly sourceObjectType?: string;\n readonly linkName?: string;\n readonly where?: unknown;\n readonly orderBy?: unknown;\n readonly pageSize?: number;\n readonly aggregate?: unknown;\n}\n\nexport interface OsdkConsumerFiber {\n fiber: Fiber;\n componentName: string;\n sourceLocation: { fileName?: string; lineNumber?: number } | null;\n sourceBasedId: string | null;\n}\n\nfunction isOsdkContextConsumer(fiber: Fiber): boolean {\n return safeFiberOperation(\n () => {\n const fibersToCheck = [fiber, fiber.alternate].filter(Boolean) as Fiber[];\n\n for (const f of fibersToCheck) {\n if (!f.dependencies?.firstContext) {\n continue;\n }\n\n let ctx: ContextDependency | null = f.dependencies.firstContext;\n while (ctx) {\n const value = ctx.memoizedValue;\n if (\n value != null &&\n typeof value === \"object\" &&\n \"observableClient\" in value &&\n \"client\" in value\n ) {\n return true;\n }\n ctx = ctx.next;\n }\n }\n return false;\n },\n { fallback: false, feature: \"hook-discovery\" }\n );\n}\n\nfunction getSourceBasedId(fiber: Fiber): string | null {\n const name = getComponentName(fiber);\n const source = fiber._debugSource;\n if (!source) {\n return null;\n }\n\n const shortPath =\n source.fileName?.split(\"/\").slice(-2).join(\"/\") || \"unknown\";\n return `fiber-${name}-${shortPath}-${source.lineNumber || 0}`;\n}\n\nfunction getFiberSourceLocation(fiber: Fiber): {\n fileName?: string;\n lineNumber?: number;\n} | null {\n if (!fiber._debugSource) {\n return null;\n }\n return {\n fileName: fiber._debugSource.fileName,\n lineNumber: fiber._debugSource.lineNumber,\n };\n}\n\nfunction buildConsumerInfo(fiber: Fiber): OsdkConsumerFiber {\n return {\n fiber,\n componentName: getComponentName(fiber),\n sourceLocation: getFiberSourceLocation(fiber),\n sourceBasedId: getSourceBasedId(fiber),\n };\n}\n\nfunction isOsdkFunctionComponent(fiber: Fiber): boolean {\n return typeof fiber.type === \"function\" && isOsdkContextConsumer(fiber);\n}\n\nexport function findOsdkConsumersInAncestors(\n fiber: Fiber,\n maxDepth = 50\n): OsdkConsumerFiber[] {\n return traverseAllFibers(\n fiber,\n (node) => isOsdkFunctionComponent(node),\n /* ascending */ true,\n /* maxResults */ undefined,\n maxDepth\n ).map(buildConsumerInfo);\n}\n\nexport function hasOsdkConsumerInTree(fiber: Fiber, maxDepth = 50): boolean {\n let current: Fiber | null = fiber;\n let depth = 0;\n\n while (current && depth < maxDepth) {\n if (typeof current.type === \"function\" && isOsdkContextConsumer(current)) {\n return true;\n }\n current = current.return;\n depth++;\n }\n\n return false;\n}\n\ninterface SearchScope {\n maxAncestorLevels: number;\n maxChildDepth: number;\n maxTotalResults: number;\n maxSiblingsPerLevel: number;\n}\n\ninterface SearchBudget {\n nodesVisited: number;\n resultsFound: number;\n readonly maxNodes: number;\n readonly maxResults: number;\n}\n\nfunction createSearchBudget(scope: SearchScope): SearchBudget {\n return {\n nodesVisited: 0,\n resultsFound: 0,\n maxNodes:\n scope.maxAncestorLevels * scope.maxChildDepth * scope.maxSiblingsPerLevel,\n maxResults: scope.maxTotalResults,\n };\n}\n\nfunction isBudgetExhausted(budget: SearchBudget): boolean {\n return (\n budget.nodesVisited >= budget.maxNodes ||\n budget.resultsFound >= budget.maxResults\n );\n}\n\nconst DEFAULT_SEARCH_SCOPE: SearchScope = {\n maxAncestorLevels: 10,\n maxChildDepth: 10,\n maxTotalResults: 10,\n maxSiblingsPerLevel: 20,\n};\n\nexport function findOsdkConsumersInSiblings(\n fiber: Fiber,\n scope: SearchScope = DEFAULT_SEARCH_SCOPE\n): OsdkConsumerFiber[] {\n return safeFiberOperation(\n () => {\n const consumers: OsdkConsumerFiber[] = [];\n const visited = new Set<Fiber>();\n const ancestorPath = new Set<Fiber>();\n const budget = createSearchBudget(scope);\n\n let pathFiber: Fiber | null = fiber;\n while (pathFiber) {\n ancestorPath.add(pathFiber);\n pathFiber = pathFiber.return;\n }\n\n let currentAncestor: Fiber | null = fiber.return;\n let ancestorLevel = 0;\n\n while (\n currentAncestor &&\n ancestorLevel < scope.maxAncestorLevels &&\n !isBudgetExhausted(budget)\n ) {\n let child: Fiber | null = currentAncestor.child;\n let siblingCount = 0;\n while (\n child &&\n siblingCount < scope.maxSiblingsPerLevel &&\n !isBudgetExhausted(budget)\n ) {\n if (!ancestorPath.has(child)) {\n const remaining = budget.maxResults - budget.resultsFound;\n const subtreeMatches = traverseAllFibers(\n child,\n (node) => {\n if (visited.has(node)) {\n return false;\n }\n visited.add(node);\n budget.nodesVisited++;\n return isOsdkFunctionComponent(node);\n },\n /* ascending */ false,\n /* maxResults */ remaining,\n scope.maxChildDepth\n );\n\n for (const match of subtreeMatches) {\n consumers.push(buildConsumerInfo(match));\n budget.resultsFound++;\n }\n }\n child = child.sibling;\n siblingCount++;\n }\n\n currentAncestor = currentAncestor.return;\n ancestorLevel++;\n }\n\n return consumers;\n },\n { fallback: [], feature: \"hook-discovery\" }\n );\n}\n\nexport function findOsdkConsumersInDescendants(\n fiber: Fiber,\n scope: SearchScope = DEFAULT_SEARCH_SCOPE\n): OsdkConsumerFiber[] {\n return safeFiberOperation(\n () => {\n const consumers: OsdkConsumerFiber[] = [];\n\n let child: Fiber | null = fiber.child;\n let siblingCount = 0;\n while (\n child &&\n siblingCount < scope.maxSiblingsPerLevel &&\n consumers.length < scope.maxTotalResults\n ) {\n const remaining = scope.maxTotalResults - consumers.length;\n const matches = traverseAllFibers(\n child,\n (node) => isOsdkFunctionComponent(node),\n /* ascending */ false,\n remaining,\n scope.maxChildDepth\n );\n for (const match of matches) {\n consumers.push(buildConsumerInfo(match));\n }\n child = child.sibling;\n siblingCount++;\n }\n\n return consumers;\n },\n { fallback: [], feature: \"hook-discovery\" }\n );\n}\n\nfunction isOsdkHookMetadata(value: unknown): value is OsdkHookMetadata {\n return (\n value != null &&\n typeof value === \"object\" &&\n OSDK_HOOK_METADATA in value &&\n (value as Record<symbol, unknown>)[OSDK_HOOK_METADATA] === true\n );\n}\n\nfunction isRefStorage(value: unknown): value is { current: unknown } {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"current\" in value &&\n Object.keys(value as object).length <= 2\n );\n}\n\nconst VALID_HOOK_TYPES = new Set<OsdkHookMetadata[\"hookType\"]>([\n \"useOsdkAction\",\n \"useOsdkObjects\",\n \"useOsdkObject\",\n \"useLinks\",\n \"useOsdkAggregation\",\n \"useOsdkFunction\",\n \"useObjectSet\",\n]);\n\nfunction isValidHookType(value: string): value is OsdkHookMetadata[\"hookType\"] {\n return VALID_HOOK_TYPES.has(value as OsdkHookMetadata[\"hookType\"]);\n}\n\nexport function extractOsdkMetadataFromFiber(fiber: Fiber): OsdkHookMetadata[] {\n return safeFiberOperation(\n () => {\n const results: OsdkHookMetadata[] = [];\n let current: MemoizedState | null = fiber.memoizedState;\n\n while (current) {\n const state = current.memoizedState;\n\n // useRef check: state is { current: OsdkHookMetadata }\n if (isRefStorage(state) && isOsdkHookMetadata(state.current)) {\n results.push(state.current);\n }\n\n // useMemo check: state is [memoizedValue, deps]\n // The memoizedValue is the makeExternalStore return object\n // which has OSDK_HOOK_METADATA as a non-enumerable symbol property\n if (\n Array.isArray(state) &&\n state[0] != null &&\n typeof state[0] === \"object\"\n ) {\n const memoValue = state[0];\n if (OSDK_HOOK_METADATA in memoValue) {\n // `in` validates the key exists; TS can't narrow symbol keys\n const meta = (memoValue as Record<symbol, unknown>)[\n OSDK_HOOK_METADATA\n ];\n if (\n meta != null &&\n typeof meta === \"object\" &&\n \"hookType\" in meta &&\n typeof (meta as { hookType: unknown }).hookType === \"string\" &&\n isValidHookType((meta as { hookType: string }).hookType)\n ) {\n const validated = meta as {\n hookType: OsdkHookMetadata[\"hookType\"];\n [key: string]: unknown;\n };\n results.push({\n [OSDK_HOOK_METADATA]: true,\n hookType: validated.hookType,\n actionName:\n typeof validated.actionName === \"string\"\n ? validated.actionName\n : undefined,\n objectType:\n typeof validated.objectType === \"string\"\n ? validated.objectType\n : undefined,\n primaryKey:\n typeof validated.primaryKey === \"string\"\n ? validated.primaryKey\n : undefined,\n sourceObjectType:\n typeof validated.sourceObjectType === \"string\"\n ? validated.sourceObjectType\n : undefined,\n linkName:\n typeof validated.linkName === \"string\"\n ? validated.linkName\n : undefined,\n where: validated.where,\n orderBy: validated.orderBy,\n pageSize:\n typeof validated.pageSize === \"number\"\n ? validated.pageSize\n : undefined,\n aggregate: validated.aggregate,\n });\n }\n }\n }\n\n current = current.next;\n }\n\n return results;\n },\n { fallback: [], feature: \"metadata-extraction\" }\n );\n}\n\nexport interface DiscoveredComponent {\n componentId: string;\n componentName: string;\n hooks: OsdkHookMetadata[];\n sourceLocation: { fileName?: string; lineNumber?: number } | null;\n props?: Record<string, string>;\n}\n\nconst MAX_PROP_KEYS = 12;\n// Longest a prop-value preview may be before it's truncated, in characters.\n// TODO: preserve the untruncated value alongside this preview so the inspector\n// can show the full value in a tooltip on hover.\nconst MAX_PROP_VALUE_LEN = 80;\n\nfunction summarizePropValue(value: unknown): string {\n if (value == null) {\n return \"null\";\n }\n switch (typeof value) {\n case \"undefined\": {\n return \"undefined\";\n }\n case \"string\": {\n const text =\n value.length > MAX_PROP_VALUE_LEN\n ? `${value.slice(0, MAX_PROP_VALUE_LEN)}…`\n : value;\n return JSON.stringify(text);\n }\n case \"number\":\n case \"boolean\":\n case \"bigint\": {\n return String(value);\n }\n case \"function\": {\n return \"ƒ\";\n }\n case \"object\": {\n if (Array.isArray(value)) {\n return `Array(${value.length})`;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.$apiName === \"string\") {\n return `<${record.$apiName}>`;\n }\n return \"{…}\";\n }\n default: {\n return String(value);\n }\n }\n}\n\nfunction summarizeProps(fiber: Fiber): Record<string, string> | undefined {\n const raw = getProps(fiber);\n const keys = Object.keys(raw).filter((key) => key !== \"children\");\n if (keys.length === 0) {\n return undefined;\n }\n const summary: Record<string, string> = {};\n for (const key of keys.slice(0, MAX_PROP_KEYS)) {\n summary[key] = summarizePropValue(raw[key]);\n }\n return summary;\n}\n\nexport function discoverOsdkComponentsFromRoot(\n fiberRoot: FiberRoot\n): Map<string, DiscoveredComponent> {\n return safeFiberOperation(\n () => {\n const components = new Map<string, DiscoveredComponent>();\n const rootFiber = fiberRoot.current;\n\n if (!rootFiber) {\n return components;\n }\n\n walkFiberTree(rootFiber, (fiber) => {\n if (typeof fiber.type !== \"function\") {\n return;\n }\n\n const metadata = extractOsdkMetadataFromFiber(fiber);\n if (metadata.length > 0) {\n const componentId = getComponentId(fiber);\n const componentName = getComponentName(fiber);\n const sourceLocation = getFiberSourceLocation(fiber);\n\n components.set(componentId, {\n componentId,\n componentName,\n hooks: metadata,\n sourceLocation,\n props: summarizeProps(fiber),\n });\n }\n });\n\n return components;\n },\n { fallback: new Map(), feature: \"fiber-discovery\" }\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"HookStateInspector.js","names":["getComponentId","getComponentName","getProps","safeFiberOperation","traverseAllFibers","walkFiberTree","OSDK_HOOK_METADATA","Symbol","for","isOsdkContextConsumer","fiber","fibersToCheck","alternate","filter","Boolean","f","dependencies","firstContext","ctx","value","memoizedValue","next","fallback","feature","getSourceBasedId","name","source","_debugSource","shortPath","fileName","split","slice","join","lineNumber","getFiberSourceLocation","buildConsumerInfo","componentName","sourceLocation","sourceBasedId","isOsdkFunctionComponent","type","findOsdkConsumersInAncestors","maxDepth","node","undefined","map","hasOsdkConsumerInTree","current","depth","return","createSearchBudget","scope","nodesVisited","resultsFound","maxNodes","maxAncestorLevels","maxChildDepth","maxSiblingsPerLevel","maxResults","maxTotalResults","isBudgetExhausted","budget","DEFAULT_SEARCH_SCOPE","findOsdkConsumersInSiblings","consumers","visited","Set","ancestorPath","pathFiber","add","currentAncestor","ancestorLevel","child","siblingCount","has","remaining","subtreeMatches","match","push","sibling","findOsdkConsumersInDescendants","length","matches","isOsdkHookMetadata","isRefStorage","Object","keys","VALID_HOOK_TYPES","isValidHookType","normalizeRefMetadata","meta","hookType","actionName","key","extractOsdkMetadataFromFiber","results","memoizedState","state","Array","isArray","memoValue","validated","objectType","primaryKey","sourceObjectType","linkName","where","orderBy","pageSize","aggregate","MAX_PROP_KEYS","MAX_PROP_VALUE_LEN","summarizePropValue","text","JSON","stringify","String","record","$apiName","summarizeProps","raw","summary","discoverOsdkComponentsFromRoot","fiberRoot","components","Map","rootFiber","metadata","componentId","set","hooks","props"],"sources":["HookStateInspector.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n getComponentId,\n getComponentName,\n getProps,\n} from \"./FiberInspection.js\";\nimport { safeFiberOperation } from \"./SafeFiberOperation.js\";\nimport { traverseAllFibers, walkFiberTree } from \"./traverseFiber.js\";\nimport type {\n ContextDependency,\n Fiber,\n FiberRoot,\n MemoizedState,\n} from \"./types.js\";\n\nconst OSDK_HOOK_METADATA = Symbol.for(\"__OSDK_HOOK_METADATA__\");\n\nexport interface OsdkHookMetadata {\n readonly [key: symbol]: true;\n readonly hookType:\n | \"useOsdkAction\"\n | \"useOsdkObjects\"\n | \"useOsdkObject\"\n | \"useLinks\"\n | \"useOsdkAggregation\"\n | \"useOsdkFunction\"\n | \"useObjectSet\";\n readonly actionName?: string;\n readonly objectType?: string;\n readonly primaryKey?: string;\n readonly sourceObjectType?: string;\n readonly linkName?: string;\n readonly where?: unknown;\n readonly orderBy?: unknown;\n readonly pageSize?: number;\n readonly aggregate?: unknown;\n}\n\nexport interface OsdkConsumerFiber {\n fiber: Fiber;\n componentName: string;\n sourceLocation: { fileName?: string; lineNumber?: number } | null;\n sourceBasedId: string | null;\n}\n\nfunction isOsdkContextConsumer(fiber: Fiber): boolean {\n return safeFiberOperation(\n () => {\n const fibersToCheck = [fiber, fiber.alternate].filter(Boolean) as Fiber[];\n\n for (const f of fibersToCheck) {\n if (!f.dependencies?.firstContext) {\n continue;\n }\n\n let ctx: ContextDependency | null = f.dependencies.firstContext;\n while (ctx) {\n const value = ctx.memoizedValue;\n if (\n value != null &&\n typeof value === \"object\" &&\n \"observableClient\" in value &&\n \"client\" in value\n ) {\n return true;\n }\n ctx = ctx.next;\n }\n }\n return false;\n },\n { fallback: false, feature: \"hook-discovery\" }\n );\n}\n\nfunction getSourceBasedId(fiber: Fiber): string | null {\n const name = getComponentName(fiber);\n const source = fiber._debugSource;\n if (!source) {\n return null;\n }\n\n const shortPath =\n source.fileName?.split(\"/\").slice(-2).join(\"/\") || \"unknown\";\n return `fiber-${name}-${shortPath}-${source.lineNumber || 0}`;\n}\n\nfunction getFiberSourceLocation(fiber: Fiber): {\n fileName?: string;\n lineNumber?: number;\n} | null {\n if (!fiber._debugSource) {\n return null;\n }\n return {\n fileName: fiber._debugSource.fileName,\n lineNumber: fiber._debugSource.lineNumber,\n };\n}\n\nfunction buildConsumerInfo(fiber: Fiber): OsdkConsumerFiber {\n return {\n fiber,\n componentName: getComponentName(fiber),\n sourceLocation: getFiberSourceLocation(fiber),\n sourceBasedId: getSourceBasedId(fiber),\n };\n}\n\nfunction isOsdkFunctionComponent(fiber: Fiber): boolean {\n return typeof fiber.type === \"function\" && isOsdkContextConsumer(fiber);\n}\n\nexport function findOsdkConsumersInAncestors(\n fiber: Fiber,\n maxDepth = 50\n): OsdkConsumerFiber[] {\n return traverseAllFibers(\n fiber,\n (node) => isOsdkFunctionComponent(node),\n /* ascending */ true,\n /* maxResults */ undefined,\n maxDepth\n ).map(buildConsumerInfo);\n}\n\nexport function hasOsdkConsumerInTree(fiber: Fiber, maxDepth = 50): boolean {\n let current: Fiber | null = fiber;\n let depth = 0;\n\n while (current && depth < maxDepth) {\n if (typeof current.type === \"function\" && isOsdkContextConsumer(current)) {\n return true;\n }\n current = current.return;\n depth++;\n }\n\n return false;\n}\n\ninterface SearchScope {\n maxAncestorLevels: number;\n maxChildDepth: number;\n maxTotalResults: number;\n maxSiblingsPerLevel: number;\n}\n\ninterface SearchBudget {\n nodesVisited: number;\n resultsFound: number;\n readonly maxNodes: number;\n readonly maxResults: number;\n}\n\nfunction createSearchBudget(scope: SearchScope): SearchBudget {\n return {\n nodesVisited: 0,\n resultsFound: 0,\n maxNodes:\n scope.maxAncestorLevels * scope.maxChildDepth * scope.maxSiblingsPerLevel,\n maxResults: scope.maxTotalResults,\n };\n}\n\nfunction isBudgetExhausted(budget: SearchBudget): boolean {\n return (\n budget.nodesVisited >= budget.maxNodes ||\n budget.resultsFound >= budget.maxResults\n );\n}\n\nconst DEFAULT_SEARCH_SCOPE: SearchScope = {\n maxAncestorLevels: 10,\n maxChildDepth: 10,\n maxTotalResults: 10,\n maxSiblingsPerLevel: 20,\n};\n\nexport function findOsdkConsumersInSiblings(\n fiber: Fiber,\n scope: SearchScope = DEFAULT_SEARCH_SCOPE\n): OsdkConsumerFiber[] {\n return safeFiberOperation(\n () => {\n const consumers: OsdkConsumerFiber[] = [];\n const visited = new Set<Fiber>();\n const ancestorPath = new Set<Fiber>();\n const budget = createSearchBudget(scope);\n\n let pathFiber: Fiber | null = fiber;\n while (pathFiber) {\n ancestorPath.add(pathFiber);\n pathFiber = pathFiber.return;\n }\n\n let currentAncestor: Fiber | null = fiber.return;\n let ancestorLevel = 0;\n\n while (\n currentAncestor &&\n ancestorLevel < scope.maxAncestorLevels &&\n !isBudgetExhausted(budget)\n ) {\n let child: Fiber | null = currentAncestor.child;\n let siblingCount = 0;\n while (\n child &&\n siblingCount < scope.maxSiblingsPerLevel &&\n !isBudgetExhausted(budget)\n ) {\n if (!ancestorPath.has(child)) {\n const remaining = budget.maxResults - budget.resultsFound;\n const subtreeMatches = traverseAllFibers(\n child,\n (node) => {\n if (visited.has(node)) {\n return false;\n }\n visited.add(node);\n budget.nodesVisited++;\n return isOsdkFunctionComponent(node);\n },\n /* ascending */ false,\n /* maxResults */ remaining,\n scope.maxChildDepth\n );\n\n for (const match of subtreeMatches) {\n consumers.push(buildConsumerInfo(match));\n budget.resultsFound++;\n }\n }\n child = child.sibling;\n siblingCount++;\n }\n\n currentAncestor = currentAncestor.return;\n ancestorLevel++;\n }\n\n return consumers;\n },\n { fallback: [], feature: \"hook-discovery\" }\n );\n}\n\nexport function findOsdkConsumersInDescendants(\n fiber: Fiber,\n scope: SearchScope = DEFAULT_SEARCH_SCOPE\n): OsdkConsumerFiber[] {\n return safeFiberOperation(\n () => {\n const consumers: OsdkConsumerFiber[] = [];\n\n let child: Fiber | null = fiber.child;\n let siblingCount = 0;\n while (\n child &&\n siblingCount < scope.maxSiblingsPerLevel &&\n consumers.length < scope.maxTotalResults\n ) {\n const remaining = scope.maxTotalResults - consumers.length;\n const matches = traverseAllFibers(\n child,\n (node) => isOsdkFunctionComponent(node),\n /* ascending */ false,\n remaining,\n scope.maxChildDepth\n );\n for (const match of matches) {\n consumers.push(buildConsumerInfo(match));\n }\n child = child.sibling;\n siblingCount++;\n }\n\n return consumers;\n },\n { fallback: [], feature: \"hook-discovery\" }\n );\n}\n\nfunction isOsdkHookMetadata(value: unknown): value is OsdkHookMetadata {\n return (\n value != null &&\n typeof value === \"object\" &&\n OSDK_HOOK_METADATA in value &&\n (value as Record<symbol, unknown>)[OSDK_HOOK_METADATA] === true\n );\n}\n\nfunction isRefStorage(value: unknown): value is { current: unknown } {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"current\" in value &&\n Object.keys(value as object).length <= 2\n );\n}\n\nconst VALID_HOOK_TYPES = new Set<OsdkHookMetadata[\"hookType\"]>([\n \"useOsdkAction\",\n \"useOsdkObjects\",\n \"useOsdkObject\",\n \"useLinks\",\n \"useOsdkAggregation\",\n \"useOsdkFunction\",\n \"useObjectSet\",\n]);\n\nfunction isValidHookType(value: string): value is OsdkHookMetadata[\"hookType\"] {\n return VALID_HOOK_TYPES.has(value as OsdkHookMetadata[\"hookType\"]);\n}\n\n/**\n * The lightweight `useDevToolsMetadata` (useRef) marker stores a hook's\n * identifying name under `key`, not the typed name fields. `useOsdkAction` uses\n * this path with `key === actionDef.apiName`, so map it onto `actionName`;\n * otherwise downstream consumers see `undefined` → \"Unknown\" and drop it.\n */\nfunction normalizeRefMetadata(meta: OsdkHookMetadata): OsdkHookMetadata {\n if (meta.hookType === \"useOsdkAction\" && meta.actionName == null) {\n const key = (meta as { key?: unknown }).key;\n if (typeof key === \"string\") {\n return { ...meta, [OSDK_HOOK_METADATA]: true, actionName: key };\n }\n }\n return meta;\n}\n\nexport function extractOsdkMetadataFromFiber(fiber: Fiber): OsdkHookMetadata[] {\n return safeFiberOperation(\n () => {\n const results: OsdkHookMetadata[] = [];\n let current: MemoizedState | null = fiber.memoizedState;\n\n while (current) {\n const state = current.memoizedState;\n\n // useRef check: state is { current: OsdkHookMetadata }\n if (isRefStorage(state) && isOsdkHookMetadata(state.current)) {\n results.push(normalizeRefMetadata(state.current));\n }\n\n // useMemo check: state is [memoizedValue, deps]\n // The memoizedValue is the makeExternalStore return object\n // which has OSDK_HOOK_METADATA as a non-enumerable symbol property\n if (\n Array.isArray(state) &&\n state[0] != null &&\n typeof state[0] === \"object\"\n ) {\n const memoValue = state[0];\n if (OSDK_HOOK_METADATA in memoValue) {\n // `in` validates the key exists; TS can't narrow symbol keys\n const meta = (memoValue as Record<symbol, unknown>)[\n OSDK_HOOK_METADATA\n ];\n if (\n meta != null &&\n typeof meta === \"object\" &&\n \"hookType\" in meta &&\n typeof (meta as { hookType: unknown }).hookType === \"string\" &&\n isValidHookType((meta as { hookType: string }).hookType)\n ) {\n const validated = meta as {\n hookType: OsdkHookMetadata[\"hookType\"];\n [key: string]: unknown;\n };\n results.push({\n [OSDK_HOOK_METADATA]: true,\n hookType: validated.hookType,\n actionName:\n typeof validated.actionName === \"string\"\n ? validated.actionName\n : undefined,\n objectType:\n typeof validated.objectType === \"string\"\n ? validated.objectType\n : undefined,\n primaryKey:\n typeof validated.primaryKey === \"string\"\n ? validated.primaryKey\n : undefined,\n sourceObjectType:\n typeof validated.sourceObjectType === \"string\"\n ? validated.sourceObjectType\n : undefined,\n linkName:\n typeof validated.linkName === \"string\"\n ? validated.linkName\n : undefined,\n where: validated.where,\n orderBy: validated.orderBy,\n pageSize:\n typeof validated.pageSize === \"number\"\n ? validated.pageSize\n : undefined,\n aggregate: validated.aggregate,\n });\n }\n }\n }\n\n current = current.next;\n }\n\n return results;\n },\n { fallback: [], feature: \"metadata-extraction\" }\n );\n}\n\nexport interface DiscoveredComponent {\n componentId: string;\n componentName: string;\n hooks: OsdkHookMetadata[];\n sourceLocation: { fileName?: string; lineNumber?: number } | null;\n props?: Record<string, string>;\n}\n\nconst MAX_PROP_KEYS = 12;\n// Longest a prop-value preview may be before it's truncated, in characters.\n// TODO: preserve the untruncated value alongside this preview so the inspector\n// can show the full value in a tooltip on hover.\nconst MAX_PROP_VALUE_LEN = 80;\n\nfunction summarizePropValue(value: unknown): string {\n if (value == null) {\n return \"null\";\n }\n switch (typeof value) {\n case \"undefined\": {\n return \"undefined\";\n }\n case \"string\": {\n const text =\n value.length > MAX_PROP_VALUE_LEN\n ? `${value.slice(0, MAX_PROP_VALUE_LEN)}…`\n : value;\n return JSON.stringify(text);\n }\n case \"number\":\n case \"boolean\":\n case \"bigint\": {\n return String(value);\n }\n case \"function\": {\n return \"ƒ\";\n }\n case \"object\": {\n if (Array.isArray(value)) {\n return `Array(${value.length})`;\n }\n const record = value as Record<string, unknown>;\n if (typeof record.$apiName === \"string\") {\n return `<${record.$apiName}>`;\n }\n return \"{…}\";\n }\n default: {\n return String(value);\n }\n }\n}\n\nfunction summarizeProps(fiber: Fiber): Record<string, string> | undefined {\n const raw = getProps(fiber);\n const keys = Object.keys(raw).filter((key) => key !== \"children\");\n if (keys.length === 0) {\n return undefined;\n }\n const summary: Record<string, string> = {};\n for (const key of keys.slice(0, MAX_PROP_KEYS)) {\n summary[key] = summarizePropValue(raw[key]);\n }\n return summary;\n}\n\nexport function discoverOsdkComponentsFromRoot(\n fiberRoot: FiberRoot\n): Map<string, DiscoveredComponent> {\n return safeFiberOperation(\n () => {\n const components = new Map<string, DiscoveredComponent>();\n const rootFiber = fiberRoot.current;\n\n if (!rootFiber) {\n return components;\n }\n\n walkFiberTree(rootFiber, (fiber) => {\n if (typeof fiber.type !== \"function\") {\n return;\n }\n\n const metadata = extractOsdkMetadataFromFiber(fiber);\n if (metadata.length > 0) {\n const componentId = getComponentId(fiber);\n const componentName = getComponentName(fiber);\n const sourceLocation = getFiberSourceLocation(fiber);\n\n components.set(componentId, {\n componentId,\n componentName,\n hooks: metadata,\n sourceLocation,\n props: summarizeProps(fiber),\n });\n }\n });\n\n return components;\n },\n { fallback: new Map(), feature: \"fiber-discovery\" }\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -141,7 +141,7 @@ function getCallerLocation() {
141
141
  * its real source, since our wrapper sits on top of installHook's.
142
142
  */
143
143
  function isReactDevtoolsFrame(source) {
144
- return source.startsWith("installHook.js") || source.startsWith("react_devtools") || source.startsWith("react-devtools");
144
+ return source.startsWith("installHook.js") || source.includes("react_devtools") || source.includes("react-devtools") || source.includes("react-router-dom");
145
145
  }
146
146
  function capEntrySize(args) {
147
147
  let totalSize = 0;
@@ -252,7 +252,6 @@ export class ConsoleLogStore extends SubscribableStore {
252
252
  const original = this.originals.get(level);
253
253
  const ourWrapper = this.wrappers.get(level);
254
254
  if (original && ourWrapper && console[level] === ourWrapper) {
255
- // eslint-disable-line no-console
256
255
  console[level] = original; // eslint-disable-line no-console
257
256
  }
258
257
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ConsoleLogStore.js","names":["CircularBuffer","SubscribableStore","CONSOLE_LEVELS","entryCounter","nextId","Date","now","MAX_DEPTH","MAX_STRING_SIZE","MAX_TOTAL_SIZE","INTERNAL_FRAME_PATTERN","BROWSER_LOGGER_CSS","isBrowserLoggerCall","args","startsWith","includes","CHROME_FRAME_REGEX_PAREN","CHROME_FRAME_REGEX_BARE","FIREFOX_FRAME_REGEX","serializeValue","value","depth","seen","String","type","description","name","obj","Node","tagName","Error","stack","message","has","Array","isArray","length","add","items","i","push","join","entries","key","Object","keys","val","delete","serializeArg","arg","WeakSet","result","slice","getCallerLocation","err","undefined","lines","split","line","test","match","exec","filePath","lineNum","fileName","pop","isReactDevtoolsFrame","source","capEntrySize","totalSize","longestIndex","longestLength","replacement","ConsoleLogStore","cachedEntries","originals","Map","wrappers","installed","suppressed","capturing","notifyScheduled","constructor","capacity","install","level","original","console","set","store","wrapper","skipCapture","skip","Function","prototype","apply","call","queueMicrotask","serializedArgs","map","entry","id","timestamp","scheduleNotify","uninstall","get","ourWrapper","clear","suppress","unsuppress","getEntries","toArray","getSize","notifySubscribers","dispose","clearSubscribers"],"sources":["ConsoleLogStore.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CircularBuffer } from \"../utils/CircularBuffer.js\";\nimport { SubscribableStore } from \"./SubscribableStore.js\";\n\nexport type ConsoleLogLevel = \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n\nconst CONSOLE_LEVELS: readonly ConsoleLogLevel[] = [\n \"log\",\n \"warn\",\n \"error\",\n \"info\",\n \"debug\",\n] as const;\n\nexport interface ConsoleLogEntry {\n readonly id: string;\n readonly level: ConsoleLogLevel;\n readonly args: readonly string[];\n readonly timestamp: number;\n readonly source?: string;\n}\n\nlet entryCounter = 0;\n\nfunction nextId(): string {\n return `console-${++entryCounter}-${Date.now()}`;\n}\n\nconst MAX_DEPTH = 3;\nconst MAX_STRING_SIZE = 10240; // 10KB\nconst MAX_TOTAL_SIZE = 10240; // 10KB\n\nconst INTERNAL_FRAME_PATTERN =\n /ConsoleLogStore|serializeArg|serializeValue|getCallerLocation|capEntrySize|osdkConsoleWrapper/u;\n\n// BrowserLogger formats calls with %c CSS styling and a \"border: 1px solid\"\n// pattern from its createStyle(). We filter these from the devtools console\n// because devtools monitors the same operations through its own instrumentation.\nconst BROWSER_LOGGER_CSS = \"border: 1px solid\";\nfunction isBrowserLoggerCall(args: unknown[]): boolean {\n return (\n typeof args[0] === \"string\" &&\n args[0].startsWith(\"%c\") &&\n typeof args[1] === \"string\" &&\n args[1].includes(BROWSER_LOGGER_CSS)\n );\n}\n\nconst CHROME_FRAME_REGEX_PAREN = /at\\s+.*?\\((.*?):(\\d+):\\d+\\)/u;\nconst CHROME_FRAME_REGEX_BARE = /at\\s+(.*?):(\\d+):\\d+/u;\nconst FIREFOX_FRAME_REGEX = /@(.*?):(\\d+):\\d+/u;\n\nfunction serializeValue(\n value: unknown,\n depth: number,\n seen: WeakSet<object>\n): string {\n if (value == null) {\n return String(value);\n }\n\n const type = typeof value;\n\n if (type === \"string\") {\n if (depth === 0) {\n return value as string;\n }\n return `\"${value as string}\"`;\n }\n if (type === \"number\" || type === \"boolean\") {\n return String(value);\n }\n if (type === \"bigint\") {\n return `BigInt(${String(value)})`;\n }\n if (type === \"symbol\") {\n return `Symbol(${(value as symbol).description ?? \"\"})`;\n }\n if (type === \"function\") {\n return `[Function: ${\n (value as (...args: readonly unknown[]) => unknown).name || \"anonymous\"\n }]`;\n }\n\n const obj = value as object;\n\n if (typeof Node !== \"undefined\" && obj instanceof Node) {\n const el = obj as { tagName?: string };\n return `[HTMLElement: ${el.tagName ?? \"unknown\"}]`;\n }\n\n if (obj instanceof Error) {\n return obj.stack ?? obj.message;\n }\n\n if (seen.has(obj)) {\n return \"[Circular]\";\n }\n\n if (depth >= MAX_DEPTH) {\n if (Array.isArray(obj)) {\n return `[Array(${obj.length})]`;\n }\n return \"[Object]\";\n }\n\n seen.add(obj);\n try {\n if (Array.isArray(obj)) {\n const items: string[] = [];\n for (let i = 0; i < obj.length; i++) {\n items.push(serializeValue(obj[i], depth + 1, seen));\n }\n return `[${items.join(\",\")}]`;\n }\n\n const entries: string[] = [];\n for (const key of Object.keys(obj)) {\n const val = serializeValue(\n (obj as Record<string, unknown>)[key],\n depth + 1,\n seen\n );\n entries.push(`\"${key}\":${val}`);\n }\n return `{${entries.join(\",\")}}`;\n } catch {\n return String(obj);\n } finally {\n seen.delete(obj);\n }\n}\n\nfunction serializeArg(arg: unknown): string {\n const seen = new WeakSet<object>();\n const result = serializeValue(arg, 0, seen);\n if (result.length > MAX_STRING_SIZE) {\n return `${result.slice(0, MAX_STRING_SIZE)}...truncated`;\n }\n return result;\n}\n\nfunction getCallerLocation(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) {\n return undefined;\n }\n\n const lines = stack.split(\"\\n\");\n\n for (const line of lines) {\n if (INTERNAL_FRAME_PATTERN.test(line)) {\n continue;\n }\n\n let match = CHROME_FRAME_REGEX_PAREN.exec(line);\n if (!match) {\n match = CHROME_FRAME_REGEX_BARE.exec(line);\n }\n if (!match) {\n match = FIREFOX_FRAME_REGEX.exec(line);\n }\n\n if (match) {\n const filePath = match[1];\n const lineNum = match[2];\n const fileName = filePath.split(\"/\").pop() ?? filePath;\n return `${fileName}:${lineNum}`;\n }\n }\n\n return undefined;\n}\n\n/**\n * React DevTools' installHook re-emits console.error/warn (to append the React\n * component stack) through our wrapper, which surfaces as a duplicate entry\n * whose resolved source is installHook.js. Recognize those frames so the\n * re-emission can be dropped — the app's own call is captured separately with\n * its real source, since our wrapper sits on top of installHook's.\n */\nfunction isReactDevtoolsFrame(source: string): boolean {\n return (\n source.startsWith(\"installHook.js\") ||\n source.startsWith(\"react_devtools\") ||\n source.startsWith(\"react-devtools\")\n );\n}\n\nfunction capEntrySize(args: string[]): string[] {\n let totalSize = 0;\n for (const arg of args) {\n totalSize += arg.length;\n }\n\n if (totalSize <= MAX_TOTAL_SIZE) {\n return args;\n }\n\n const result = [...args];\n while (totalSize > MAX_TOTAL_SIZE) {\n let longestIndex = 0;\n let longestLength = 0;\n for (let i = 0; i < result.length; i++) {\n if (result[i].length > longestLength) {\n longestLength = result[i].length;\n longestIndex = i;\n }\n }\n if (longestLength <= 40) {\n break;\n }\n const replacement = `...truncated (${longestLength} bytes)`;\n totalSize += replacement.length - longestLength;\n result[longestIndex] = replacement;\n }\n return result;\n}\n\nexport class ConsoleLogStore extends SubscribableStore {\n private readonly entries: CircularBuffer<ConsoleLogEntry>;\n private cachedEntries: readonly ConsoleLogEntry[] | null = null;\n private readonly originals = new Map<\n ConsoleLogLevel,\n (...args: unknown[]) => void\n >();\n private readonly wrappers = new Map<\n ConsoleLogLevel,\n (...args: unknown[]) => void\n >();\n private installed = false;\n private suppressed = false;\n private capturing = false;\n private notifyScheduled = false;\n\n constructor(capacity: number = 1000) {\n super();\n this.entries = new CircularBuffer(capacity);\n }\n\n install(): void {\n if (this.installed) {\n return;\n }\n\n for (const level of CONSOLE_LEVELS) {\n const original = console[level]; // eslint-disable-line no-console\n this.originals.set(level, original);\n\n const store = this;\n const wrapper = function osdkConsoleWrapper(\n this: Console,\n ...args: unknown[]\n ) {\n // Capture the source synchronously, before any async boundary, so the\n // user's frame is still on the stack. The in-panel `entry.source` is\n // canonical and accurate — verified by ConsoleLogStore.test.ts.\n //\n // Browser DevTools source-link attribution (the clickable link beside\n // each console row) is decided by V8 and follows wherever the original\n // method was *called*. Routing the call through Function.prototype.apply\n // is best-effort; in practice the link may still resolve to the wrapper\n // file in some Chromium versions. There is no fully-portable JS-level\n // mitigation; if needed, prefer the panel-side source field.\n //\n // Reentrancy note: capture work runs in queueMicrotask, so `capturing`\n // resets between the wrapper microtask and any nested microtask. A\n // getter that calls console.log during serialization may therefore be\n // captured (one extra entry, no infinite loop). Strict synchronous\n // reentrancy guarding is incompatible with the microtask deferral that\n // makes the source attribution improvement possible.\n const skipCapture =\n store.suppressed || store.capturing || isBrowserLoggerCall(args);\n const source = skipCapture ? undefined : getCallerLocation();\n const skip =\n skipCapture || (source !== undefined && isReactDevtoolsFrame(source));\n\n Function.prototype.apply.call(original, this ?? console, args);\n\n if (skip) {\n return;\n }\n\n queueMicrotask(() => {\n if (store.capturing) {\n return;\n }\n store.capturing = true;\n try {\n const serializedArgs = capEntrySize(args.map(serializeArg));\n const entry: ConsoleLogEntry = {\n id: nextId(),\n level,\n args: serializedArgs,\n timestamp: Date.now(),\n ...(source !== undefined ? { source } : {}),\n };\n\n store.entries.push(entry);\n store.cachedEntries = null;\n store.scheduleNotify();\n } catch {\n } finally {\n store.capturing = false;\n }\n });\n };\n\n console[level] = wrapper; // eslint-disable-line no-console\n this.wrappers.set(level, wrapper);\n }\n\n this.installed = true;\n }\n\n uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n for (const level of CONSOLE_LEVELS) {\n const original = this.originals.get(level);\n const ourWrapper = this.wrappers.get(level);\n if (original && ourWrapper && console[level] === ourWrapper) {\n // eslint-disable-line no-console\n console[level] = original; // eslint-disable-line no-console\n }\n }\n\n this.originals.clear();\n this.wrappers.clear();\n this.installed = false;\n }\n\n suppress(): void {\n this.suppressed = true;\n }\n\n unsuppress(): void {\n this.suppressed = false;\n }\n\n getEntries(): readonly ConsoleLogEntry[] {\n if (this.cachedEntries != null) {\n return this.cachedEntries;\n }\n this.cachedEntries = this.entries.toArray();\n return this.cachedEntries;\n }\n\n getSize(): number {\n return this.entries.getSize();\n }\n\n clear(): void {\n this.entries.clear();\n this.cachedEntries = null;\n this.notifySubscribers();\n }\n\n dispose(): void {\n this.uninstall();\n this.entries.clear();\n this.cachedEntries = null;\n this.clearSubscribers();\n }\n\n private scheduleNotify(): void {\n if (this.notifyScheduled) {\n return;\n }\n this.notifyScheduled = true;\n queueMicrotask(() => {\n this.notifyScheduled = false;\n this.notifySubscribers();\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ConsoleLogStore.js","names":["CircularBuffer","SubscribableStore","CONSOLE_LEVELS","entryCounter","nextId","Date","now","MAX_DEPTH","MAX_STRING_SIZE","MAX_TOTAL_SIZE","INTERNAL_FRAME_PATTERN","BROWSER_LOGGER_CSS","isBrowserLoggerCall","args","startsWith","includes","CHROME_FRAME_REGEX_PAREN","CHROME_FRAME_REGEX_BARE","FIREFOX_FRAME_REGEX","serializeValue","value","depth","seen","String","type","description","name","obj","Node","tagName","Error","stack","message","has","Array","isArray","length","add","items","i","push","join","entries","key","Object","keys","val","delete","serializeArg","arg","WeakSet","result","slice","getCallerLocation","err","undefined","lines","split","line","test","match","exec","filePath","lineNum","fileName","pop","isReactDevtoolsFrame","source","capEntrySize","totalSize","longestIndex","longestLength","replacement","ConsoleLogStore","cachedEntries","originals","Map","wrappers","installed","suppressed","capturing","notifyScheduled","constructor","capacity","install","level","original","console","set","store","wrapper","skipCapture","skip","Function","prototype","apply","call","queueMicrotask","serializedArgs","map","entry","id","timestamp","scheduleNotify","uninstall","get","ourWrapper","clear","suppress","unsuppress","getEntries","toArray","getSize","notifySubscribers","dispose","clearSubscribers"],"sources":["ConsoleLogStore.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CircularBuffer } from \"../utils/CircularBuffer.js\";\nimport { SubscribableStore } from \"./SubscribableStore.js\";\n\nexport type ConsoleLogLevel = \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n\nconst CONSOLE_LEVELS: readonly ConsoleLogLevel[] = [\n \"log\",\n \"warn\",\n \"error\",\n \"info\",\n \"debug\",\n] as const;\n\nexport interface ConsoleLogEntry {\n readonly id: string;\n readonly level: ConsoleLogLevel;\n readonly args: readonly string[];\n readonly timestamp: number;\n readonly source?: string;\n}\n\nlet entryCounter = 0;\n\nfunction nextId(): string {\n return `console-${++entryCounter}-${Date.now()}`;\n}\n\nconst MAX_DEPTH = 3;\nconst MAX_STRING_SIZE = 10240; // 10KB\nconst MAX_TOTAL_SIZE = 10240; // 10KB\n\nconst INTERNAL_FRAME_PATTERN =\n /ConsoleLogStore|serializeArg|serializeValue|getCallerLocation|capEntrySize|osdkConsoleWrapper/u;\n\n// BrowserLogger formats calls with %c CSS styling and a \"border: 1px solid\"\n// pattern from its createStyle(). We filter these from the devtools console\n// because devtools monitors the same operations through its own instrumentation.\nconst BROWSER_LOGGER_CSS = \"border: 1px solid\";\nfunction isBrowserLoggerCall(args: unknown[]): boolean {\n return (\n typeof args[0] === \"string\" &&\n args[0].startsWith(\"%c\") &&\n typeof args[1] === \"string\" &&\n args[1].includes(BROWSER_LOGGER_CSS)\n );\n}\n\nconst CHROME_FRAME_REGEX_PAREN = /at\\s+.*?\\((.*?):(\\d+):\\d+\\)/u;\nconst CHROME_FRAME_REGEX_BARE = /at\\s+(.*?):(\\d+):\\d+/u;\nconst FIREFOX_FRAME_REGEX = /@(.*?):(\\d+):\\d+/u;\n\nfunction serializeValue(\n value: unknown,\n depth: number,\n seen: WeakSet<object>\n): string {\n if (value == null) {\n return String(value);\n }\n\n const type = typeof value;\n\n if (type === \"string\") {\n if (depth === 0) {\n return value as string;\n }\n return `\"${value as string}\"`;\n }\n if (type === \"number\" || type === \"boolean\") {\n return String(value);\n }\n if (type === \"bigint\") {\n return `BigInt(${String(value)})`;\n }\n if (type === \"symbol\") {\n return `Symbol(${(value as symbol).description ?? \"\"})`;\n }\n if (type === \"function\") {\n return `[Function: ${\n (value as (...args: readonly unknown[]) => unknown).name || \"anonymous\"\n }]`;\n }\n\n const obj = value as object;\n\n if (typeof Node !== \"undefined\" && obj instanceof Node) {\n const el = obj as { tagName?: string };\n return `[HTMLElement: ${el.tagName ?? \"unknown\"}]`;\n }\n\n if (obj instanceof Error) {\n return obj.stack ?? obj.message;\n }\n\n if (seen.has(obj)) {\n return \"[Circular]\";\n }\n\n if (depth >= MAX_DEPTH) {\n if (Array.isArray(obj)) {\n return `[Array(${obj.length})]`;\n }\n return \"[Object]\";\n }\n\n seen.add(obj);\n try {\n if (Array.isArray(obj)) {\n const items: string[] = [];\n for (let i = 0; i < obj.length; i++) {\n items.push(serializeValue(obj[i], depth + 1, seen));\n }\n return `[${items.join(\",\")}]`;\n }\n\n const entries: string[] = [];\n for (const key of Object.keys(obj)) {\n const val = serializeValue(\n (obj as Record<string, unknown>)[key],\n depth + 1,\n seen\n );\n entries.push(`\"${key}\":${val}`);\n }\n return `{${entries.join(\",\")}}`;\n } catch {\n return String(obj);\n } finally {\n seen.delete(obj);\n }\n}\n\nfunction serializeArg(arg: unknown): string {\n const seen = new WeakSet<object>();\n const result = serializeValue(arg, 0, seen);\n if (result.length > MAX_STRING_SIZE) {\n return `${result.slice(0, MAX_STRING_SIZE)}...truncated`;\n }\n return result;\n}\n\nfunction getCallerLocation(): string | undefined {\n const err = new Error();\n const stack = err.stack;\n if (!stack) {\n return undefined;\n }\n\n const lines = stack.split(\"\\n\");\n\n for (const line of lines) {\n if (INTERNAL_FRAME_PATTERN.test(line)) {\n continue;\n }\n\n let match = CHROME_FRAME_REGEX_PAREN.exec(line);\n if (!match) {\n match = CHROME_FRAME_REGEX_BARE.exec(line);\n }\n if (!match) {\n match = FIREFOX_FRAME_REGEX.exec(line);\n }\n\n if (match) {\n const filePath = match[1];\n const lineNum = match[2];\n const fileName = filePath.split(\"/\").pop() ?? filePath;\n return `${fileName}:${lineNum}`;\n }\n }\n\n return undefined;\n}\n\n/**\n * React DevTools' installHook re-emits console.error/warn (to append the React\n * component stack) through our wrapper, which surfaces as a duplicate entry\n * whose resolved source is installHook.js. Recognize those frames so the\n * re-emission can be dropped — the app's own call is captured separately with\n * its real source, since our wrapper sits on top of installHook's.\n */\nfunction isReactDevtoolsFrame(source: string): boolean {\n return (\n source.startsWith(\"installHook.js\") ||\n source.includes(\"react_devtools\") ||\n source.includes(\"react-devtools\") ||\n source.includes(\"react-router-dom\")\n );\n}\n\nfunction capEntrySize(args: string[]): string[] {\n let totalSize = 0;\n for (const arg of args) {\n totalSize += arg.length;\n }\n\n if (totalSize <= MAX_TOTAL_SIZE) {\n return args;\n }\n\n const result = [...args];\n while (totalSize > MAX_TOTAL_SIZE) {\n let longestIndex = 0;\n let longestLength = 0;\n for (let i = 0; i < result.length; i++) {\n if (result[i].length > longestLength) {\n longestLength = result[i].length;\n longestIndex = i;\n }\n }\n if (longestLength <= 40) {\n break;\n }\n const replacement = `...truncated (${longestLength} bytes)`;\n totalSize += replacement.length - longestLength;\n result[longestIndex] = replacement;\n }\n return result;\n}\n\nexport class ConsoleLogStore extends SubscribableStore {\n private readonly entries: CircularBuffer<ConsoleLogEntry>;\n private cachedEntries: readonly ConsoleLogEntry[] | null = null;\n private readonly originals = new Map<\n ConsoleLogLevel,\n (...args: unknown[]) => void\n >();\n private readonly wrappers = new Map<\n ConsoleLogLevel,\n (...args: unknown[]) => void\n >();\n private installed = false;\n private suppressed = false;\n private capturing = false;\n private notifyScheduled = false;\n\n constructor(capacity: number = 1000) {\n super();\n this.entries = new CircularBuffer(capacity);\n }\n\n install(): void {\n if (this.installed) {\n return;\n }\n\n for (const level of CONSOLE_LEVELS) {\n const original = console[level]; // eslint-disable-line no-console\n this.originals.set(level, original);\n\n const store = this;\n const wrapper = function osdkConsoleWrapper(\n this: Console,\n ...args: unknown[]\n ) {\n // Capture the source synchronously, before any async boundary, so the\n // user's frame is still on the stack. The in-panel `entry.source` is\n // canonical and accurate — verified by ConsoleLogStore.test.ts.\n //\n // Browser DevTools source-link attribution (the clickable link beside\n // each console row) is decided by V8 and follows wherever the original\n // method was *called*. Routing the call through Function.prototype.apply\n // is best-effort; in practice the link may still resolve to the wrapper\n // file in some Chromium versions. There is no fully-portable JS-level\n // mitigation; if needed, prefer the panel-side source field.\n //\n // Reentrancy note: capture work runs in queueMicrotask, so `capturing`\n // resets between the wrapper microtask and any nested microtask. A\n // getter that calls console.log during serialization may therefore be\n // captured (one extra entry, no infinite loop). Strict synchronous\n // reentrancy guarding is incompatible with the microtask deferral that\n // makes the source attribution improvement possible.\n const skipCapture =\n store.suppressed || store.capturing || isBrowserLoggerCall(args);\n const source = skipCapture ? undefined : getCallerLocation();\n const skip =\n skipCapture || (source !== undefined && isReactDevtoolsFrame(source));\n\n Function.prototype.apply.call(original, this ?? console, args);\n\n if (skip) {\n return;\n }\n\n queueMicrotask(() => {\n if (store.capturing) {\n return;\n }\n store.capturing = true;\n try {\n const serializedArgs = capEntrySize(args.map(serializeArg));\n const entry: ConsoleLogEntry = {\n id: nextId(),\n level,\n args: serializedArgs,\n timestamp: Date.now(),\n ...(source !== undefined ? { source } : {}),\n };\n\n store.entries.push(entry);\n store.cachedEntries = null;\n store.scheduleNotify();\n } catch {\n } finally {\n store.capturing = false;\n }\n });\n };\n\n console[level] = wrapper; // eslint-disable-line no-console\n this.wrappers.set(level, wrapper);\n }\n\n this.installed = true;\n }\n\n uninstall(): void {\n if (!this.installed) {\n return;\n }\n\n for (const level of CONSOLE_LEVELS) {\n const original = this.originals.get(level);\n const ourWrapper = this.wrappers.get(level);\n if (original && ourWrapper && console[level] === ourWrapper) {\n console[level] = original; // eslint-disable-line no-console\n }\n }\n\n this.originals.clear();\n this.wrappers.clear();\n this.installed = false;\n }\n\n suppress(): void {\n this.suppressed = true;\n }\n\n unsuppress(): void {\n this.suppressed = false;\n }\n\n getEntries(): readonly ConsoleLogEntry[] {\n if (this.cachedEntries != null) {\n return this.cachedEntries;\n }\n this.cachedEntries = this.entries.toArray();\n return this.cachedEntries;\n }\n\n getSize(): number {\n return this.entries.getSize();\n }\n\n clear(): void {\n this.entries.clear();\n this.cachedEntries = null;\n this.notifySubscribers();\n }\n\n dispose(): void {\n this.uninstall();\n this.entries.clear();\n this.cachedEntries = null;\n this.clearSubscribers();\n }\n\n private scheduleNotify(): void {\n if (this.notifyScheduled) {\n return;\n }\n this.notifyScheduled = true;\n queueMicrotask(() => {\n this.notifyScheduled = false;\n this.notifySubscribers();\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -19866,6 +19866,7 @@ a > .bp6-dark .bp6-tooltip .bp6-running-text code{
19866
19866
  gap: 8px;
19867
19867
  padding: 7px 12px;
19868
19868
  border-bottom: 1px solid var(--dt-border-default);
19869
+ align-items: center;
19869
19870
  }
19870
19871
 
19871
19872
  .ComponentsPanel-module__summaryText___LKZ3NQ1S {
@@ -19883,6 +19884,16 @@ a > .bp6-dark .bp6-tooltip .bp6-running-text code{
19883
19884
  color: var(--dt-text-tertiary);
19884
19885
  }
19885
19886
 
19887
+ .ComponentsPanel-module__infoIcon___LG4ul8dX {
19888
+ color: var(--dt-text-tertiary);
19889
+ cursor: help;
19890
+ }
19891
+
19892
+ .ComponentsPanel-module__infoContent___hy6X7-Fa {
19893
+ display: inline-block;
19894
+ max-width: 260px;
19895
+ }
19896
+
19886
19897
  .ComponentsPanel-module__filters___uqN0ijBU {
19887
19898
  display: flex;
19888
19899
  flex-wrap: wrap;