Importing Core, et al, via ES module for runtime

WebViewer Version: 10.9.0 and 11.5.0

Do you have an issue with a specific file(s)? No
Can you reproduce using one of our samples or online demos? Yes
Are you using the WebViewer server? No
Does the issue only happen on certain browsers? No
Is your issue related to a front-end framework? No
Is your issue related to annotations? No

Please give a brief summary of your issue:
(Think of this as an email subject)
Core is defined at build/compile time. Undefined at runtime.

Please describe your issue and provide steps to reproduce it:
(The more descriptive your answer, the faster we are able to help you)
I’m wresting with the fact that your package only imports the types for your classes such as Core.Math.Quad. While I can use these for Typescript type annotations as expected, the values are not available at runtime so it’s getting a bit tedious to instantiate new objects. Wondering what the best approach is from your point of view.

I’ll illustrate with a couple examples. Let’s consider the following that defines a React component in Typescript, instantiating a Webviewer.

import WebViewer, { WebViewerInstance } from "@pdftron/webviewer";
import { useEffect, useRef } from "react";

export default function Page() {
  const viewerRef = useRef<HTMLDivElement>(null);
  const instanceRef = useRef<WebViewerInstance>(null);
  
  useEffect(() => {
    const opts = {
      // fullAPI, licenseKey, path, etc.
    }

    WebViewer(opts, viewerRef.current)
      .then((instance) => {
        instanceRef.current = instance;
        const quad = new instance.Core.Math.Quad(2, 4, 6, 8, 1, 3, 5, 7);
        // ...
      })
      .catch((err: unknown) => {
        // handle the error      
      });
  }, []);

  return <div ref={viewerRef} />
}

Most of this is not very different from one of your examples in your docs. However, it’s instantiating a new Quad by accessing the class within the Core.Math namespace. Importantly, this is through the value of type WebViewerInstance provided by WebViewer.

However, if I want to create my own set of helpers that instantiate new Quads, this isn’t possible by just importing Core from your package since it only imports types.

// In a separate file
import { Core } from "@pdftron/webviewer";

type Quad = Core.Math.Quad;

export function makeSpecialQuad(): Quad {
  return new Quad(1, 3, 5, 7, 2, 4, 6, 8); // Quad only refers to a type, but is being used as a value here.
}

Is Core.Math.Quad class (and others) only available through the WebViewerInstance? I guess I can make makeSpecialQuad accept a Quad from a WebViewerInstance as an argument to instantiate new quads with. But that would also entail changing our app’s architecture to start managing the WebViewerInstance value in a wider scope. ie. as a ref, state, context, etc.

Another workaround I’ve found was that by loading the core library as noted in your doc for building our own UI. Now I can access Quad from the global window and instantiate new objects with it.

import { Core } from "@pdftron/webviewer";

type WindowWithCore = Window & {
  Core: typeof Core;
};

const _window = (window as unknown as WindowWithCore);

function makeSpecialQuad(): Core.Math.Quad {
  return new _window.Core.Math.Quad(1, 3, 5, 7, 2, 4, 6, 8);
}

Quite a bit of boilerplate, but this technically works. Though, I’m not sure of the implications from mixing the usage of the WebViewerInstance and the “global Core” from loading the Core library. My guess is that it’s fine but noting here anyway.

In summary, is there a more standard approach to getting my hands on Core.Math.Quad at runtime other than through a WebViewerInstance, or are the two approaches mentioned above my only options?

Please provide a link to a minimal sample where the issue is reproducible:
See above.

1 Like

Hello, I’m AiRon, an automated tech support bot :robot:
While you wait for one of our customer support representatives, I can help you with your question.


It seems like you’re trying to instantiate objects from the Core namespace of WebViewer at runtime, but are encountering issues because the classes are only available through the WebViewerInstance. This is a common scenario when using TypeScript, where type information is available at compile time, but you need the actual runtime objects.

Some things you can try:

  • Continue using the WebViewerInstance to access the Core classes. This is the most straightforward method as it ensures you are using the correct context and version of the library.

  • Consider managing the WebViewerInstance at a higher scope if you need to access it in multiple places. You can use React’s context or state management tools to pass the instance around.

  • If you choose to use the global Core from the window object, ensure that it is loaded before you try to access it. This can work, but be cautious about potential conflicts or version mismatches.



Here are some resources that might help you:

  • Getting Started with WebViewer in React: This guide will help you understand how to set up WebViewer in a React environment, which can provide insights into managing the WebViewerInstance.

  • Advanced Customization: Learn more about customizing and extending WebViewer, which could help you with managing instances and accessing the Core library.

  • UI Setup and Customization: This documentation might help you understand how to integrate and manage the WebViewer UI, which could be useful if you’re handling multiple instances or contexts.

  • Annotations Guide: Although not directly related to your issue, understanding annotations might help if you’re planning to manipulate or create complex objects like Quad.



Hopefully, this helps you solve your problem while you wait for a human to get back to you.

1 Like

Looks like the AI is suggesting the exact solutions I posted. Hopefully a human expert will chime in eventually. My team will continue to stick with our current plans for now.

1 Like

Hello James,

I’m looking into your question and will update you soon.

1 Like

Hello James,

I spoke with the development team and unfortunately we do not have a way to directly import the Quad currently. What the AI suggested is correct, you can access from the global Core object just like your workaround. However, I can submit a feature request for an easier way to access these classes if you would like.

Best Regards,
Darian

1 Like

Thanks Darian. I appreciate the consult with the dev team. For now, we’ve come up with a somewhat manageable solution around an imperative handle that wraps the WebViewerInstance. We’ll plan on sticking with this approach.

I used the Quad class as an example here because it just happens to be what we’ve been working with a lot recently. But we’re also instantiating a couple other classes directly, such as Core.Annotations.Color and Core.Annotations.TextHighlightAnnotation. So if the dev team can figure this out in a future release that’s a nice-to-have. But really not a dire emergency or anything like that, at least on our end.

1 Like