Fix initializedPromise never resolve in Zotero Reader - #171
Open
duanxianpi wants to merge 1 commit into
Open
Conversation
jamesbraza
added a commit
to jamesbraza/zotero-context
that referenced
this pull request
Jul 24, 2026
Grab mode's sentence snap booted slowly because whole-document Read Aloud segmentation only started at activation. Now (pref `warmOnOpen`, default on) each reader warms in the background at open: await `reader._initPromise` then the primary view's `initializedPromise` (the chain Zotero core itself relies on; after it the page count is guaranteed known, so no polling or retries), then fill the shared segment cache and precompute snap targets for the visible page ±1. Activation coalesces onto the same cached fetch. NEVER await `_internalReader.initializedPromise`: it is created but never resolved (zotero/reader#171) — see zotero-reader-initializedpromise-report.md. Also: per-page segment index replaces the O(all-segments) scan on every page hover, and `Intl.Segmenter` is now a lazy singleton instead of being rebuilt per paragraph. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jamesbraza
added a commit
to jamesbraza/zotero-context
that referenced
this pull request
Jul 24, 2026
Grab mode's sentence snap booted slowly because whole-document Read Aloud segmentation only started at activation. Now (pref `warmOnOpen`, default on) each reader warms in the background at open: await `reader._initPromise` then the primary view's `initializedPromise` (the chain Zotero core itself relies on; after it the page count is guaranteed known, so no polling or retries), then fill the shared segment cache and precompute snap targets for the visible page ±1. Activation coalesces onto the same cached fetch. NEVER await `_internalReader.initializedPromise`: it is created but never resolved (zotero/reader#171) — see zotero-reader-initializedpromise-report.md. Also: per-page segment index replaces the O(all-segments) scan on every page hover, and `Intl.Segmenter` is now a lazy singleton instead of being rebuilt per paragraph. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jamesbraza
added a commit
to jamesbraza/zotero-context
that referenced
this pull request
Jul 24, 2026
Grab mode's sentence snap booted slowly because whole-document Read Aloud segmentation only started at activation. Now (pref `warmOnOpen`, default on) each reader warms in the background at open: await `reader._initPromise` then the primary view's `initializedPromise` (the chain Zotero core itself relies on; after it the page count is guaranteed known, so no polling or retries), then fill the shared segment cache and precompute snap targets for the visible page ±1. Activation coalesces onto the same cached fetch. NEVER await `_internalReader.initializedPromise`: it is created but never resolved (zotero/reader#171) — see zotero-reader-initializedpromise-report.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jamesbraza
added a commit
to jamesbraza/zotero-context
that referenced
this pull request
Jul 24, 2026
* Grab-mode perf: shared Intl.Segmenter, per-page segment index Hover-time costs shrink: computing a page's sentence targets no longer scans ALL document segments (a per-page index, built once per segments array, replaces the O(total-segments) filter on every hovered page), and Intl.Segmenter is a lazy module singleton instead of being rebuilt for every paragraph segment. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Sentence snap warm-up: promise-driven segment prefetch at reader open Grab mode's sentence snap booted slowly because whole-document Read Aloud segmentation only started at activation. Now (pref `warmOnOpen`, default on) each reader warms in the background at open: await `reader._initPromise` then the primary view's `initializedPromise` (the chain Zotero core itself relies on; after it the page count is guaranteed known, so no polling or retries), then fill the shared segment cache and precompute snap targets for the visible page ±1. Activation coalesces onto the same cached fetch. NEVER await `_internalReader.initializedPromise`: it is created but never resolved (zotero/reader#171) — see zotero-reader-initializedpromise-report.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * MCP perf: lazy-load the SDK handler bundle zod + the MCP SDK were ~72% of the plugin bundle, parsed at every Zotero startup even with MCP disabled (the default). The SDK-bearing request core (handleRequest, dispatch, single-exchange transport, tools) now lives in a second esbuild entry (src/mcp-handler.ts) that the eager control layer loadSubScripts on first server start, publishing `addon.data.mcpHandler` into the plugin sandbox. Eager bundle: 1.6 MB → 91 KB. The load scope borrows web globals (console, AbortController, ...) from the app-lifetime hidden window: Zotero's plugin sandbox realm lacks them and the SDK needs them (its embedded Ajv reads `console` at construction). Session state (trail, paper infos) is injected into the tool server (`createMcpServer(deps)`): the lazy bundle carries its own copies of every module it imports, so a static grab-session import would have served a second, always-empty trail. Also: NetUtil resolves once instead of per request in the HTTP adapter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Build: minify release bundles NODE_ENV=production builds minify both esbuild entries (~3-4x fewer bytes for end users to parse); dev builds stay readable for debugging. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hello,
While working on a tool with the Zotero Reader, I noticed that the
initializedPromisewas never resolving. This caused any await calls on it to hang indefinitely.To address this, I added a call to
_resolveInitializedPromiseafter the primary view is initialized. I believe this is an appropriate place for it, but please let me know if there’s a better location or if you have any questions or concerns.Thanks!