Skip to content

Add host sessions - #485

Merged
alex-rawlings-yyc merged 6 commits into
mainfrom
440-host-sessions
Oct 23, 2026
Merged

alex-rawlings-yyc merged 6 commits into
mainfrom
440-host-sessions

Conversation

@alex-rawlings-yyc

@alex-rawlings-yyc alex-rawlings-yyc commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Closes #440. Part of #426. Stacked on #469.

Summary

Sessions in the host, over a source project's draft, a draft paired with its interlinear project, or a Paratext 9 import, read-only. The WebView doesn't call them yet.

interlinearizer.openSession(sourceProjectId, interlinearProjectId?) -> { sessionId, readOnly, hasFreeTranslations }
interlinearizer.closeSession(sessionId)
interlinearizer.setAnalysisLanguage(sessionId, analysisLanguage)
  • Read-only capability. AnalysisRepository.capabilities.readOnly. Pt9ImportRepository serves an import through the seam and refuses replaceAll and markClean. The conformance suite runs over both repositories and checks the refusal.
  • One session per source. Opening another closes the earlier one and loads afresh from storage. A session runs its commands one at a time; runEdit refuses them on a read-only session.
  • hasFreeTranslations uses the loader's own check, moved into analysisHasFreeTranslations.
  • Draft calls share one queue. getDraft and saveDraft go through openDraftRepository, the queued handle sessions use, so the two never overlap. The handle counts its writes for Save, as saveDraft did.

Evidence

  • Unit suite at 100% coverage; lint and tsc clean.
  • setAnalysisLanguage passes a parity test against the reducer.
  • Seven mutations of the session lifecycle (replacing, closing, queueing) each fail a test.

Decisions with a strong alternative

  • setAnalysisLanguage stores nothing, and works on an import's session. Alternative: write the draft's analysis languages. Why not: the reducer only changes the store's working language, and the import view switches languages too.
  • The scope type lives at the session (SessionScope). exportAll and replaceAll keep the draft's shape. Alternative: a repository-level record pairing the draft with its project. Why not: 4c removes the whole-draft calls, and Move Save and Save As into the host #475's host Save already owns the project half.
  • Closing a WebView closes no session. Alternative: close on onDidCloseWebView. Why not: no WebView opens a session yet, so none belongs to a view. A save that lands after a close still loses nothing, since a released repository loads the stored draft before its first save. Reopening reloads, so perf seeding still sees what it wrote.
  • A session starts on the draft's first analysis language, else the platform's first interface language, else und, as the loader falls back.

Merge Danger

Door: two-way

Nothing calls the new commands. The draft load and save path now runs through the queued handle, with the same behavior apart from one extra read: a repository that hasn't loaded the draft loads it before its first save.

Blast Radius: draft load and save in projectStorage; the loader's free-translation check

🤖 Generated with Claude Code


This change is Reviewable

Summary by CodeRabbit

  • New Features
    • Added session commands for opening and closing analysis sessions and choosing an analysis language.
    • Sessions can work with a draft, optionally paired with an interlinear project, or with a Paratext 9 import in read-only mode.
    • Opening a new session for a source replaces its existing session. Read-only sessions reject edits.
    • Analysis language defaults to the first available analysis language, then the first interface language, or an undetermined value.

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: aebf4059-a015-450e-abce-79abab6d04da
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@alex-rawlings-yyc alex-rawlings-yyc self-assigned this Oct 22, 2026
Base automatically changed from 432-repository-conformance-suite to main October 22, 2026 18:23
@alex-rawlings-yyc
alex-rawlings-yyc marked this pull request as ready for review October 22, 2026 18:42
coderabbitai[bot]

This comment was marked as resolved.

imnasnainaec

This comment was marked as resolved.

@alex-rawlings-yyc
alex-rawlings-yyc force-pushed the 440-host-sessions branch 2 times, most recently from 1436214 to 5d5d1cf Compare October 22, 2026 19:54
imnasnainaec

This comment was marked as resolved.

@alex-rawlings-yyc alex-rawlings-yyc left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alex-rawlings-yyc made 2 comments and resolved 2 discussions.
Reviewable status: 11 of 22 files reviewed, 14 unresolved discussions (waiting on alex-rawlings-yyc and imnasnainaec).


src/__tests__/analysis-repository-conformance.ts line 703 at r3 (raw file):

Previously, imnasnainaec (D. Ror.) wrote…

⛏️ /** The analysis that

Done.


src/__tests__/types/read-only-analysis-error.test.ts at r3 (raw file):

Previously, imnasnainaec (D. Ror.) wrote…

❓ Is this types test worth adding?

Removed: type files don't need their own suite.

imnasnainaec

This comment was marked as resolved.

@alex-rawlings-yyc alex-rawlings-yyc left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alex-rawlings-yyc made 2 comments and resolved 2 discussions.
Reviewable status: 20 of 22 files reviewed, all discussions resolved (waiting on alex-rawlings-yyc).


src/__tests__/services/pt9ImportRepository.test.ts line 22 at r4 (raw file):

Previously, imnasnainaec (D. Ror.) wrote…

⛏️ readProject is documented to read afresh, but this returns the same object on every call. A copy keeps the fake to that contract:

  return new Pt9ImportRepository(
    'import-id',
    async () => project && (JSON.parse(JSON.stringify(project)) as InterlinearProject),
  );

Done, without the cast, which the repo's no-type-assertion rule forbids; the constructor's parameter type already types the result. The fake in analysisSessions.test.ts also handed back a shared object, so it now copies the project on every read too.


src/services/pt9ImportRepository.ts line 24 at r4 (raw file):

Previously, imnasnainaec (D. Ror.) wrote…

⛏️ When #487 caches an index, a shared object would let an exported draft alias the index's records. Spelling out that the read returns a new object:

   * @param readProject - Reads the project stored under that id afresh, as a new object the
   *   repository may hand out, resolving `undefined` when none is stored.

Done.

@imnasnainaec imnasnainaec left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imnasnainaec reviewed 3 files and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on imnasnainaec).

@imnasnainaec imnasnainaec left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@imnasnainaec reviewed 1 file and all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on alex-rawlings-yyc).

@alex-rawlings-yyc
alex-rawlings-yyc merged commit 81e40cf into main Oct 23, 2026
10 checks passed
@alex-rawlings-yyc
alex-rawlings-yyc deleted the 440-host-sessions branch October 23, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[3a] Add host sessions

2 participants