Skip to content

608 run set up scripts before loading modules #638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

petermasking
Copy link
Member

@petermasking petermasking commented May 7, 2025

Fixes #608

Changes proposed in this pull request:

  • Moved loading segments, health checks and middleware from the server builder to their own managers.
  • Refactored the sourcing module for better supporting the loading from the managers.
  • Updated the server and services startup processes to first run the set up scripts before loading the segments, health checks and middleware.
  • Updated the Vite plugin to support he new startup process.
  • Renamed the construction example to resources to reflect its intend better.

@MaskingTechnology/jitar

Summary by CodeRabbit

  • New Features

    • Introduced dynamic loading and lifecycle management for health checks, middleware, and execution segments, allowing modules to be loaded and unloaded at runtime.
    • Added new ResourceManager for coordinated setup and teardown of resource scripts in server environments.
    • Added LocalSourcingManager and RemoteSourcingManager for simplified local and remote sourcing configuration.
  • Improvements

    • Refactored server and client startup/shutdown to coordinate initialization and cleanup of middleware, health checks, and resources.
    • Enhanced worker configuration with an option to control gateway registration.
    • Centralized and streamlined file and module management with new interfaces and manager classes.
    • Improved client build process with explicit start invocation.
    • Optimized server builder methods to be synchronous and streamlined resource script handling.
  • Bug Fixes

    • Improved error handling and reporting for unsupported remote file operations and module loading failures.
  • Chores

    • Updated package metadata and dependencies.
    • Consolidated and reorganized exports for easier imports and better maintainability.
    • Updated example projects and documentation to reflect resource usage focus.

@petermasking petermasking requested a review from basmasking May 7, 2025 07:40
@petermasking petermasking linked an issue May 7, 2025 that may be closed by this pull request
Copy link

coderabbitai bot commented May 7, 2025

## Walkthrough

This update introduces a new `ResourceManager` to manage setup and teardown scripts, restructures server and worker lifecycle management to coordinate resource initialization before loading modules, and refactors sourcing and file management into local and remote variants. Several new interfaces and classes are added for modularity, and the startup sequence is refactored to ensure resources are ready before module loading.

## Changes

| Files/Paths                                                                                           | Change Summary |
|-----------------------------------------------------------------------------------------------------|----------------|
| `packages/sourcing/src/files/LocalFileManager.ts`, `RemoteFileManager.ts`, `errors/RemoteFilesNotSupported.ts`, `index.ts`, `interfaces/FileReader.ts` | Added new file manager classes for local/remote files, a new error class, a file reader interface, and a file module index. |
| `packages/sourcing/src/modules/ImportManager.ts`, `LocalImportManager.ts`, `RemoteImportManager.ts`, `LocalModuleLocator.ts`, `RemoteModuleLocator.ts`, `interfaces/ModuleImporter.ts`, `interfaces/ModuleLocator.ts`, `index.ts` | Added new import manager and module locator classes for local/remote, new interfaces, and a module index. |
| `packages/sourcing/src/SourcingManager.ts`, `LocalSourcingManager.ts`, `RemoteSourcingManager.ts`, `index.ts` | Refactored sourcing manager to use injected file/import managers, added local/remote sourcing managers, and updated exports. |
| `packages/sourcing/src/files/FileManager.ts`                                                        | Refactored to require explicit file system injection and implement `FileReader`. |
| `packages/sourcing/test/fixtures/TestFileSystem.ts`                                                 | Updated import path for `LocalFileSystem`. |
| `packages/build/src/BuildManager.ts`, `packages/configuration/src/ConfigurationManager.ts`, `packages/cli/src/commands/StartServer.ts` | Switched to using `LocalFileManager` or `LocalSourcingManager` for file/sourcing management. |
| `packages/execution/package.json`                                                                   | Added dependency on `@jitar/sourcing`. |
| `packages/execution/src/ExecutionManager.ts`, `models/Application.ts`                               | Added lifecycle methods for segment loading/unloading and clearing segments. |
| `packages/health/src/HealthManager.ts`                                                              | Added dynamic health check loading/unloading and lifecycle methods. |
| `packages/middleware/src/MiddlewareManager.ts`                                                      | Added dynamic middleware loading/unloading and lifecycle methods. |
| `packages/plugin-vite/src/index.ts`                                                                 | Changed client bundle to explicitly start the client after build. |
| `packages/runtime/src/client/Client.ts`                                                             | Refactored startup/shutdown to coordinate worker and middleware manager, moving middleware setup to `start()`. |
| `packages/runtime/src/client/ClientBuilder.ts`                                                      | Refactored to inject `RemoteSourcingManager` into middleware and execution managers. |
| `packages/runtime/src/server/ResourceManager.ts`                                                    | Introduced `ResourceManager` to manage setup/teardown scripts. |
| `packages/runtime/src/server/Server.ts`                                                             | Refactored to use `ResourceManager` for resource lifecycle, changed startup order to start resources before loading modules. |
| `packages/runtime/src/server/ServerBuilder.ts`                                                      | Refactored to build and inject `ResourceManager`, removed async module loading from build steps. |
| `packages/services/src/worker/LocalWorker.ts`                                                       | Added `registerAtGateway` flag, refactored worker lifecycle to always start/stop execution manager, conditional gateway registration. |
| `packages/services/test/repository/fixtures/sourcingManager.fixture.ts`                              | Refactored fixture to use new sourcing manager structure and removed unused methods. |
| `examples/resources/package.json`                                                                   | Changed package name. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Server
    participant ResourceManager
    participant MiddlewareManager
    participant HealthManager
    participant ExecutionManager

    Server->>ResourceManager: start()
    ResourceManager->>ResourceManager: run setup scripts
    ResourceManager-->>Server: setup complete

    Server->>MiddlewareManager: start()
    Server->>HealthManager: start()
    Server->>ExecutionManager: start()
    MiddlewareManager-->>Server: ready
    HealthManager-->>Server: ready
    ExecutionManager-->>Server: ready

    Note over Server: Modules are loaded <br>after setup scripts complete

    Server->>ResourceManager: stop()
    ResourceManager->>ResourceManager: run teardown scripts
    ResourceManager-->>Server: teardown complete

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Run setup scripts before loading modules (#608)

Poem

Oh, the scripts now run before the code,
So resources are ready, in their proper mode!
Managers for files, modules, and more,
Start up in sequence, as rabbits adore.
With setup first and loading next,
This change leaves no bunny perplexed! 🐇✨


<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=MaskingTechnology/jitar&utm_content=638):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🧹 Nitpick comments (13)
packages/sourcing/src/files/interfaces/FileReader.ts (1)

4-11: Consider adding JSDoc comments to the interface methods

The FileReader interface is well-defined with clear method signatures, but adding JSDoc comments would improve the documentation and make the interface more self-explanatory for developers.

 interface FileReader
 {
+    /**
+     * Filters files based on the provided patterns.
+     * @param patterns - Glob patterns to match files against
+     * @returns Promise resolving to an array of matching filenames
+     */
     filter(...patterns: string[]): Promise<string[]>;
     
+    /**
+     * Checks if a file exists at the specified path.
+     * @param filename - Path to the file to check
+     * @returns Promise resolving to a boolean indicating if the file exists
+     */
     exists(filename: string): Promise<boolean>;

+    /**
+     * Reads the content of a file.
+     * @param filename - Path to the file to read
+     * @returns Promise resolving to a File object containing the file contents
+     */
     read(filename: string): Promise<File>;
 }
packages/sourcing/src/modules/ImportManager.ts (2)

22-23: Consider expanding the comment to explain why awaiting is necessary.

The comment correctly indicates that awaiting is necessary to catch errors, but it could be more educational by explaining the alternative behavior (errors propagating up the call stack) if await wasn't used here.


16-32: Consider adding more granular error handling.

The current error handling wraps all import errors into a ModuleNotLoaded error with the original message. You might want to distinguish between different types of errors (e.g., syntax errors, module not found, network errors for remote imports) to provide more specific error messages or handling strategies.

packages/sourcing/src/modules/index.ts (1)

10-11: Add newline at the end of the file.

The file is missing a newline at the end, which is considered a best practice for text files and is enforced by many linters.

 export { default as LocalImportManager } from './LocalImportManager';
 export { default as RemoteImportManager } from './RemoteImportManager';
+
packages/sourcing/src/files/index.ts (1)

13-14: Add newline at the end of the file.

The file is missing a newline at the end, which is considered a best practice for text files and is enforced by many linters.

 export { default as LocalFileManager } from './LocalFileManager';
 export { default as RemoteFileManager } from './RemoteFileManager';
+
packages/runtime/src/server/ResourceManager.ts (2)

17-25: Consider adding script execution status reporting.

The start and stop methods could benefit from reporting the execution status of each script. This would be helpful for debugging and monitoring purposes, especially in production environments.


37-40: Consider sequential execution option for scripts.

Currently, all scripts are executed in parallel using Promise.all. For some scenarios, sequential execution might be preferred to ensure one script completes before the next begins. Consider adding an option to run scripts sequentially if ordered execution is important.

packages/sourcing/src/files/RemoteFileSystem.ts (2)

14-68: Consistent error handling for unsupported operations

Most methods appropriately throw a RemoteFilesNotSupported error to clearly indicate that remote file operations are not currently supported.

However, there's an inconsistency with the filter() method returning an empty array instead of throwing an error. Consider whether this should be consistent with other methods.

-    async filter(location: string, pattern: string): Promise<string[]>
-    {
-        return [];
-    }
+    filter(location: string, pattern: string): Promise<string[]>
+    {
+        throw new RemoteFilesNotSupported();
+    }

Alternatively, if there's a specific reason for filter() to return an empty array instead of throwing, consider adding a comment explaining this decision.


49-53: Consider documenting resolve() method's behavior

The resolve() method returns the input location unchanged, unlike most other methods that throw exceptions. Consider adding a comment explaining why this method has different behavior.

    resolve(location: string): string
    {
+       // This method doesn't throw an error because it's needed for basic path handling
+       // even when remote file operations are not supported
        return location;
    }
packages/runtime/src/server/Server.ts (2)

237-250: Startup sequence may miss ProcedureRunner initialisation

middlewareManager.start() is awaited before ProcedureRunner is created and added.
If the manager performs one-off initialisation (e.g. building a chain of middlewares) the newly added ProcedureRunner will not be part of that setup.

-        await Promise.all(
-        [
-            this.#proxy.start(),
-            this.#healthManager.start(),
-            this.#middlewareManager.start()
-        ]);
-
-        const procedureRunner = new ProcedureRunner(this.#proxy);
-        this.#middlewareManager.addMiddleware(procedureRunner);
+        const procedureRunner = new ProcedureRunner(this.#proxy);
+        this.#middlewareManager.addMiddleware(procedureRunner);
+
+        await Promise.all([
+            this.#proxy.start(),
+            this.#healthManager.start(),
+            this.#middlewareManager.start()
+        ]);

Placing the ProcedureRunner in the chain before the manager starts ensures consistent middleware ordering and avoids a second explicit “reload”.


252-262: Graceful rollback on partial start / stop failures

#setUp() and #tearDown() execute several async tasks in parallel without a surrounding try/catch.
If one task fails, the server may end up in a half-started (or half-stopped) state, leaking resources.

Consider:

  1. Wrapping the whole block in try/catch.
  2. Implementing a best-effort rollback (e.g. stop already-started components).
  3. Logging the partial failure so that operators know which piece failed.

This will make the server startup sequence more resilient in production.

packages/runtime/src/server/ServerBuilder.ts (2)

137-157: DRY: Extract common “ensure .js” mapping

#buildResourceManager, #buildHealthManager, and #buildMiddlewareManager repeat identical logic. A tiny helper keeps this file shorter and future-proof.

+#translateFilenames(filenames: string[] = []): string[] {
+    return filenames.map(this.#assureExtension.bind(this));
+}
 
 const translatedSetUp = this.#translateFilenames(setUp);
 const translatedTearDown = this.#translateFilenames(tearDown);
 ...
 const translatedFilenames = this.#translateFilenames(filenames);

Not urgent, but worthwhile as more managers appear.


25-42: Optional: rename local variable proxy for clarity

With the earlier aliasing of ServiceProxy, the local proxy instance remains, but the name duplicates the concept.
Consider serviceProxy to slightly improve readability:

-const proxy = await this.#buildService(configuration);
+const serviceProxy = await this.#buildService(configuration);
 ...
-return new Server({ proxy, sourcingManager, remoteBuilder, resourceManager, middlewareManager, healthManager, logger });
+return new Server({ proxy: serviceProxy, sourcingManager, remoteBuilder, resourceManager, middlewareManager, healthManager, logger });

Purely a readability nitpick—feel free to skip.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a01079 and fe8ff93.

📒 Files selected for processing (37)
  • examples/resources/package.json (1 hunks)
  • packages/build/src/BuildManager.ts (2 hunks)
  • packages/cli/src/commands/StartServer.ts (2 hunks)
  • packages/configuration/src/ConfigurationManager.ts (2 hunks)
  • packages/execution/package.json (1 hunks)
  • packages/execution/src/ExecutionManager.ts (3 hunks)
  • packages/execution/src/models/Application.ts (1 hunks)
  • packages/health/src/HealthManager.ts (3 hunks)
  • packages/middleware/src/MiddlewareManager.ts (2 hunks)
  • packages/plugin-vite/src/index.ts (1 hunks)
  • packages/runtime/src/client/Client.ts (2 hunks)
  • packages/runtime/src/client/ClientBuilder.ts (2 hunks)
  • packages/runtime/src/server/ResourceManager.ts (1 hunks)
  • packages/runtime/src/server/Server.ts (3 hunks)
  • packages/runtime/src/server/ServerBuilder.ts (6 hunks)
  • packages/services/src/worker/LocalWorker.ts (4 hunks)
  • packages/services/test/repository/fixtures/sourcingManager.fixture.ts (2 hunks)
  • packages/sourcing/src/LocalSourcingManager.ts (1 hunks)
  • packages/sourcing/src/RemoteSourcingManager.ts (1 hunks)
  • packages/sourcing/src/SourcingManager.ts (2 hunks)
  • packages/sourcing/src/files/FileManager.ts (1 hunks)
  • packages/sourcing/src/files/LocalFileManager.ts (1 hunks)
  • packages/sourcing/src/files/RemoteFileManager.ts (1 hunks)
  • packages/sourcing/src/files/RemoteFileSystem.ts (1 hunks)
  • packages/sourcing/src/files/errors/RemoteFilesNotSupported.ts (1 hunks)
  • packages/sourcing/src/files/index.ts (1 hunks)
  • packages/sourcing/src/files/interfaces/FileReader.ts (1 hunks)
  • packages/sourcing/src/index.ts (1 hunks)
  • packages/sourcing/src/modules/ImportManager.ts (1 hunks)
  • packages/sourcing/src/modules/LocalImportManager.ts (1 hunks)
  • packages/sourcing/src/modules/LocalModuleLocator.ts (1 hunks)
  • packages/sourcing/src/modules/RemoteImportManager.ts (1 hunks)
  • packages/sourcing/src/modules/RemoteModuleLocator.ts (1 hunks)
  • packages/sourcing/src/modules/index.ts (1 hunks)
  • packages/sourcing/src/modules/interfaces/ModuleImporter.ts (1 hunks)
  • packages/sourcing/src/modules/interfaces/ModuleLocator.ts (1 hunks)
  • packages/sourcing/test/fixtures/TestFileSystem.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (10)
packages/configuration/src/ConfigurationManager.ts (1)
packages/sourcing/src/files/LocalFileManager.ts (1)
  • LocalFileManager (5-11)
packages/sourcing/src/modules/RemoteImportManager.ts (3)
packages/sourcing/src/modules/LocalImportManager.ts (1)
  • LocalImportManager (7-13)
packages/sourcing/src/modules/ImportManager.ts (1)
  • ImportManager (7-33)
packages/sourcing/src/modules/RemoteModuleLocator.ts (1)
  • RemoteModuleLocator (5-18)
packages/sourcing/src/files/interfaces/FileReader.ts (2)
packages/runtime/src/server/ServerBuilder.ts (2)
  • patterns (166-173)
  • filename (175-180)
packages/sourcing/src/files/models/File.ts (1)
  • File (2-22)
packages/build/src/BuildManager.ts (1)
packages/sourcing/src/files/LocalFileManager.ts (1)
  • LocalFileManager (5-11)
packages/sourcing/src/files/RemoteFileSystem.ts (1)
packages/sourcing/src/files/errors/RemoteFilesNotSupported.ts (1)
  • RemoteFilesNotSupported (2-8)
packages/sourcing/src/SourcingManager.ts (4)
packages/sourcing/src/index.ts (6)
  • FileReader (2-2)
  • ModuleImporter (5-5)
  • FileManager (3-3)
  • ImportManager (6-6)
  • File (3-3)
  • Module (5-5)
packages/sourcing/src/files/FileManager.ts (1)
  • FileManager (12-129)
packages/sourcing/src/modules/ImportManager.ts (1)
  • ImportManager (7-33)
packages/sourcing/src/files/models/File.ts (1)
  • File (2-22)
packages/plugin-vite/src/index.ts (2)
packages/runtime/src/client/ClientBuilder.ts (1)
  • build (25-37)
packages/runtime/src/client/Client.ts (1)
  • start (40-43)
packages/runtime/src/client/Client.ts (1)
packages/runtime/src/ProcedureRunner.ts (1)
  • ProcedureRunner (5-19)
packages/middleware/src/MiddlewareManager.ts (1)
packages/sourcing/src/index.ts (1)
  • ModuleImporter (5-5)
packages/services/test/repository/fixtures/sourcingManager.fixture.ts (1)
packages/sourcing/src/LocalSourcingManager.ts (1)
  • LocalSourcingManager (7-16)
🪛 Biome (1.9.4)
packages/sourcing/src/modules/RemoteModuleLocator.ts

[error] 8-12: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

packages/runtime/src/server/ServerBuilder.ts

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (60)
examples/resources/package.json (1)

2-2: Approve example package rename

The package name has been correctly updated to "jitar-resources-example" to reflect the new example purpose.

packages/sourcing/test/fixtures/TestFileSystem.ts (1)

4-4: Update import path to reflect new file structure

The LocalFileSystem import has been updated to the new src/files directory structure, aligning this test fixture with the refactored code organization in the sourcing package.

packages/execution/package.json (1)

19-20: Add dependency on @jitar/sourcing

The new dependency on @jitar/sourcing supports dynamic segment and resource loading in the execution package. Using "*" for internal packages is consistent with the monorepo’s versioning strategy.

packages/configuration/src/ConfigurationManager.ts (2)

3-3: Import LocalFileManager instead of generic FileManager

Switched to LocalFileManager to leverage the specialized local file system implementation, matching the updated sourcing architecture.


21-21: Instantiate LocalFileManager with root path

Replaced the generic FileManager instantiation with LocalFileManager, ensuring the correct subclass is used for all local file operations in configuration management.

packages/build/src/BuildManager.ts (2)

4-4: Import LocalFileManager from sourcing

Replaced the previous FileManager import with LocalFileManager to use the new specialized manager for local file handling within the build workflow.


23-26: Instantiate LocalFileManager for each project path

All file manager instances (source, target, resources, segments) now use LocalFileManager, aligning with the sourcing package’s updated API and ensuring consistent local file handling.

packages/execution/src/models/Application.ts (1)

15-18: LGTM: Clean implementation of the clearSegments method

This new method provides a clean way to remove all segments from the application, which is important for the enhanced lifecycle management introduced elsewhere in the codebase.

packages/sourcing/src/modules/interfaces/ModuleLocator.ts (1)

2-7: Well-defined interface for module location resolution

Clean, focused interface that establishes a clear contract for resolving module locations. This is a good abstraction to support both local and remote module loading strategies.

packages/cli/src/commands/StartServer.ts (1)

6-6: Code simplification with LocalSourcingManager

Good refactoring to use the consolidated LocalSourcingManager instead of separate managers. This change aligns with the broader refactoring effort in the sourcing package and simplifies the server building process.

Also applies to: 52-52

packages/sourcing/src/modules/interfaces/ModuleImporter.ts (1)

2-9: Clean interface for asynchronous module importing

Well-designed interface that establishes a clear contract for module importing functionality. The Promise return type correctly handles the asynchronous nature of module loading operations.

packages/sourcing/src/files/errors/RemoteFilesNotSupported.ts (1)

2-8: Clean implementation of an error class

The error class is straightforward and follows best practices with a descriptive error message that clearly indicates the unsupported operation.

packages/sourcing/src/files/RemoteFileManager.ts (1)

2-10: Implementation follows class hierarchy design pattern

The RemoteFileManager correctly extends the FileManager base class and injects the RemoteFileSystem implementation. This follows good object-oriented design principles by using inheritance and dependency injection.

packages/sourcing/src/files/LocalFileManager.ts (1)

2-10: Implementation follows class hierarchy design pattern

The LocalFileManager correctly extends the FileManager base class and injects the LocalFileSystem implementation. This follows good object-oriented design principles by using inheritance and dependency injection.

packages/sourcing/src/modules/LocalImportManager.ts (1)

7-13: Well-structured class with clear responsibility.

The implementation follows good OOP principles by extending the base ImportManager with specific local functionality. The composition with LocalModuleLocator is appropriate for the separation of concerns between importing and locating modules.

packages/sourcing/src/files/FileManager.ts (2)

5-5: Good implementation of the FileReader interface.

Explicitly implementing the FileReader interface enforces a formal contract for file reading capabilities, which improves type safety and makes the API more clear.

Also applies to: 12-12


18-18: Improved constructor with explicit dependency injection.

Requiring a FileSystem parameter without defaults is a good practice that makes dependencies explicit and supports the separation of local and remote file management strategies.

packages/sourcing/src/modules/RemoteModuleLocator.ts (2)

7-12: Security-focused implementation with clear documentation.

The empty constructor with explanatory comments about security restrictions is a good practice. While static analysis suggests removing it as "unnecessary," keeping it maintains API consistency with other ModuleLocator implementations and provides a place for important security documentation.

🧰 Tools
🪛 Biome (1.9.4)

[error] 8-12: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


14-17: Good security practice for remote module loading.

Explicitly throwing an error with a clear message when attempting to load remote modules is an excellent security practice that prevents potential vulnerabilities.

packages/sourcing/src/RemoteSourcingManager.ts (1)

7-15: Clean implementation with good separation of concerns.

The RemoteSourcingManager properly extends SourcingManager and initializes the appropriate remote-specific components. The class composition follows good object-oriented design principles by delegating specialized behavior to RemoteFileManager and RemoteImportManager.

packages/plugin-vite/src/index.ts (1)

201-203: Client startup sequence updated for lifecycle management compatibility

The changes to explicitly create a client variable and call client.start() align with the broader lifecycle management improvements in the runtime components. This ensures proper initialization of the client according to the new lifecycle management approach.

packages/sourcing/src/LocalSourcingManager.ts (1)

7-16: Implementation looks good

The LocalSourcingManager correctly extends the SourcingManager base class and provides appropriate local implementations of file and import managers. This implementation follows good object-oriented design principles by composing the necessary dependencies and delegating to the parent class.

packages/sourcing/src/modules/LocalModuleLocator.ts (1)

6-24: Path handling logic looks good

The LocalModuleLocator correctly implements the ModuleLocator interface and handles the conversion of absolute paths to relative paths before resolving them. The code is clear and the comment explains the purpose of the conversion.

packages/sourcing/src/modules/ImportManager.ts (1)

1-33: Well-designed module import abstraction with good error handling.

The ImportManager class provides a clean abstraction for module importing with proper error handling and follows the dependency injection pattern by accepting a ModuleLocator. This separation of concerns will make testing and extending the import functionality easier.

packages/sourcing/src/modules/index.ts (1)

1-11: Clear and concise barrel file.

This well-organized barrel file provides a clean interface for importing module-related components. The exports are organized by type (errors, interfaces, types, and implementation classes).

packages/sourcing/src/files/index.ts (1)

1-14: Well-structured file exports.

This barrel file provides a clean and organized way to export file-related components, making imports elsewhere in the codebase more concise and maintainable.

packages/runtime/src/server/ResourceManager.ts (1)

1-41: Good implementation of resource lifecycle management.

The ResourceManager class cleanly encapsulates the responsibility of running setup and teardown scripts, following the single responsibility principle. The use of private methods and fields makes the interface clean and implementation details hidden.

packages/runtime/src/client/Client.ts (3)

40-43: Improved lifecycle management with asynchronous operations

The delegation to private async methods for start/stop operations provides a cleaner interface while allowing for proper orchestration of asynchronous initialization and cleanup.

Also applies to: 45-48


64-75: Well-structured startup sequence with concurrent operations

The implementation properly coordinates the startup sequence by:

  1. Starting both worker and middleware manager concurrently for better performance
  2. Adding the ProcedureRunner middleware only after both components are initialized

This approach ensures all dependencies are properly initialized before they're used.


77-84: Proper shutdown sequence with concurrent operations

The teardown method properly stops both the middleware manager and worker concurrently, providing efficient resource cleanup.

packages/sourcing/src/SourcingManager.ts (3)

3-6: Good implementation of interfaces and improved import organization

The SourcingManager now explicitly implements the FileReader and ModuleImporter interfaces, making its capabilities clear. The consolidated imports from './files' and './modules' improve code organization.


9-15: Better dependency injection pattern

Adding the ImportManager parameter to the constructor follows the dependency injection pattern, making the class more modular and testable.


24-37: Improved method implementations with clear delegation

The methods have been simplified by:

  1. Removing unnecessary async keywords where direct delegation is used
  2. Delegating module importing entirely to the specialized ImportManager instance

This follows the single responsibility principle by letting specialized components handle their specific tasks.

packages/runtime/src/client/ClientBuilder.ts (3)

5-5: Good import of new dependency

The RemoteSourcingManager import is properly added to support the new sourcing capabilities.


27-34: Well-structured build process with clear dependencies

The build process now:

  1. Explicitly extracts configuration fields for clarity
  2. Creates a RemoteSourcingManager instance with the provided remoteUrl
  3. Passes the sourcing manager to both middleware and execution managers

This ensures proper integration of sourcing capabilities throughout the system.


39-55: Updated method signatures with proper dependency injection

Both private build methods now accept the sourcingManager as their first parameter and create their respective managers with it. This properly links sourcing capabilities to middleware and execution management.

packages/sourcing/src/files/RemoteFileSystem.ts (1)

5-13: Clear placeholder implementation with good documentation

The class is well-documented as a placeholder for remote file systems, with clear comments explaining its current role and future directions.

packages/execution/src/ExecutionManager.ts (6)

2-3: Clean module import for ModuleImporter

The addition of the ModuleImporter import from @jitar/sourcing aligns with the dynamic loading capabilities being added to this class.


27-29: Appropriate private fields for module management

These private readonly fields properly encapsulate the module importer and segment files, following TypeScript best practices.


34-38: Well-structured constructor

The constructor properly initializes the module importer and segment files, with a sensible default empty array for segmentFiles.


40-48: Clear lifecycle methods implementation

The start() and stop() methods provide a clean lifecycle management approach, delegating to private methods for actual implementation. This pattern is consistent with other managers in the codebase.


50-55: Effective segment loading implementation

The loadSegment method correctly awaits the module import and adds the segment to the application. The casting of module.default to Segment is appropriate here.


116-124: Well-implemented private helper methods

The private methods effectively handle the loading and clearing of segments. The loadSegments method correctly uses Promise.all for parallel loading, while clearSegments delegates to the application's clearSegments method.

packages/middleware/src/MiddlewareManager.ts (6)

3-3: Appropriate import for ModuleImporter

The addition of the ModuleImporter import from @jitar/sourcing aligns with the dynamic loading capabilities being added to this class.


11-13: Well-defined private fields

These private readonly fields properly encapsulate the module importer and middleware files, following TypeScript best practices.


16-20: Clear constructor implementation

The constructor properly initializes the module importer and middleware files, with a sensible default empty array for middlewareFiles.


22-30: Consistent lifecycle methods

The start() and stop() methods provide a clean lifecycle management approach, delegating to private methods for implementation. This follows the same pattern used in ExecutionManager.


32-37: Effective middleware loading implementation

The loadMiddleware method correctly awaits the module import and adds the middleware to the application. The casting of module.default to Middleware is appropriate here.


68-71: Well-implemented loadMiddlewares method

This private method correctly uses Promise.all for parallel loading of all middleware files, which is an efficient approach.

packages/sourcing/src/index.ts (3)

2-3: Clean export organization for file-related components

The reorganization of exports for file-related types and classes improves the module's structure and makes the API clearer.


5-6: Well-structured module-related exports

The clear separation of module-related types and exports improves code organization and makes dependencies more explicit.


9-10: Good addition of sourcing managers exports

The export of LocalSourcingManager and RemoteSourcingManager aligns with the refactoring goals and provides a clear API for consumers.

packages/services/src/worker/LocalWorker.ts (7)

20-20: Good addition of registerAtGateway configuration option

The optional registerAtGateway flag provides better control over the worker's behavior with respect to the gateway.


30-30: Appropriate private field for registration flag

The private readonly field properly encapsulates the registration flag, following TypeScript best practices.


39-39: Clear initialization of registerAtGateway

The boolean conversion ensures the field is always a boolean value, avoiding potential undefined issues.


57-58: Important lifecycle sequence improvement

Starting the ExecutionManager before gateway operations ensures modules are loaded and ready before worker registration, which is a correct dependency ordering.


63-66: Conditional gateway registration

The conditional registration based on the registerAtGateway flag provides flexibility in controlling worker behavior, which can be useful in various deployment scenarios.


72-77: Improved worker deregistration logic

The worker now only attempts to remove itself from the gateway if it has been assigned an ID, which prevents unnecessary calls.


81-82: Proper execution manager shutdown

The ExecutionManager is now properly stopped after gateway operations, ensuring a clean shutdown sequence. The explicit await is important for proper async operation.

packages/health/src/HealthManager.ts (1)

36-41: Missing validation of default export when loading a health check

loadHealthCheck() assumes that the imported module exposes a default export that is a valid HealthCheck.
If a file is mis-configured (e.g. export const foo = …) this will silently add undefined, breaking the manager later.

Consider guarding against this:

const module = await this.#moduleImporter.import(filename);
const healthCheck = module.default;

if (healthCheck === undefined) {
    throw new InvalidHealthCheck();   // or a dedicated error
}

this.addHealthCheck(healthCheck as HealthCheck);

Comment on lines +37 to +40
async #runScripts(scripts: string[]): Promise<void>
{
await Promise.all(scripts.map(script => this.#sourcingManager.import(script)));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for script execution failures.

The #runScripts method currently has no error handling. If any script fails to import or execute, the Promise.all will reject with the first error encountered, potentially leaving the system in an inconsistent state. Consider adding try/catch blocks and a more graceful failure mechanism.

 async #runScripts(scripts: string[]): Promise<void>
 {
-    await Promise.all(scripts.map(script => this.#sourcingManager.import(script)));
+    try {
+        await Promise.all(scripts.map(async script => {
+            try {
+                await this.#sourcingManager.import(script);
+            } catch (error) {
+                console.error(`Failed to run script ${script}:`, error);
+                // Consider whether to rethrow or continue with other scripts
+                throw error;
+            }
+        }));
+    } catch (error) {
+        console.error('Error running scripts:', error);
+        throw error; // Rethrow to notify caller of failure
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async #runScripts(scripts: string[]): Promise<void>
{
await Promise.all(scripts.map(script => this.#sourcingManager.import(script)));
}
async #runScripts(scripts: string[]): Promise<void>
{
try {
await Promise.all(scripts.map(async script => {
try {
await this.#sourcingManager.import(script);
} catch (error) {
console.error(`Failed to run script ${script}:`, error);
// Consider whether to rethrow or continue with other scripts
throw error;
}
}));
} catch (error) {
console.error('Error running scripts:', error);
throw error; // Rethrow to notify caller of failure
}
}

Comment on lines 73 to 76
#clearMiddlewares(): void
{
this.#middlewares.slice();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug in clearMiddlewares implementation

The current implementation doesn't actually clear the middlewares array. The slice() method returns a new array but doesn't modify the original.

Apply this fix:

#clearMiddlewares(): void
{
-    this.#middlewares.slice();
+    this.clearMiddlewares();
}

Or alternatively:

#clearMiddlewares(): void
{
-    this.#middlewares.slice();
+    this.#middlewares = [];
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#clearMiddlewares(): void
{
this.#middlewares.slice();
}
#clearMiddlewares(): void
{
- this.#middlewares.slice();
+ this.#middlewares = [];
}

Comment on lines 7 to 8
import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
import { SourcingManager } from '@jitar/sourcing';
Copy link

@coderabbitai coderabbitai bot May 7, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid shadowing the built-in Proxy global

Importing Proxy without an alias makes every subsequent reference (e.g. new Proxy({ … })) easy to confuse with the built-in Proxy constructor that wraps objects in ECMAScript. Static-analysis is already warning about this.

-import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
+import {
+  DummyProvider,
+  DummyRunner,
+  LocalGateway,
+  LocalRepository,
+  LocalWorker,
+  Proxy as ServiceProxy,
+  RemoteBuilder,
+  RemoteGateway,
+  RemoteRepository
+} from '@jitar/services';

and update all occurrences of new Proxy(new ServiceProxy( within this file (≈7 places).

This tiny rename removes ambiguity and prevents accidental usage of the wrong Proxy.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
import { SourcingManager } from '@jitar/sourcing';
import {
DummyProvider,
DummyRunner,
LocalGateway,
LocalRepository,
LocalWorker,
Proxy as ServiceProxy,
RemoteBuilder,
RemoteGateway,
RemoteRepository
} from '@jitar/services';
import { SourcingManager } from '@jitar/sourcing';
🧰 Tools
🪛 Biome (1.9.4)

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

Copy link
Member

Choose a reason for hiding this comment

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

After a short discussion we decided to rename the Proxy to LocalProxy to prevent confusion with the ECMAScript Proxy Object

Copy link

Choose a reason for hiding this comment

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

@basmasking Thanks for the update! That's a great decision to rename it to LocalProxy – it clearly indicates its purpose while avoiding any confusion with JavaScript's built-in Proxy object.


✏️ Learnings added
Learnt from: basmasking
PR: MaskingTechnology/jitar#638
File: packages/runtime/src/server/ServerBuilder.ts:7-8
Timestamp: 2025-05-13T18:15:31.378Z
Learning: In the Jitar codebase, always import the `Proxy` class from `@jitar/services` as `LocalProxy` to avoid shadowing the built-in JavaScript `Proxy` global object.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines 94 to 102
#buildLocalWorker(url: string, configuration: WorkerConfiguration): LocalWorker
{
const trustKey = configuration.trustKey;
const gateway = configuration.gateway ? this.#buildRemoteGateway(configuration.gateway) : undefined;
const executionManager = await this.#buildExecutionManager(configuration.segments);
const registerAtGateway = gateway !== undefined;
const executionManager = this.#buildExecutionManager(configuration.segments);

return new LocalWorker({ url, trustKey, gateway, executionManager });
return new LocalWorker({ url, trustKey, gateway, registerAtGateway, executionManager });
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Guard against segments being undefined

WorkerConfiguration.segments is forwarded straight into #buildExecutionManager, which immediately calls .map (line 161).
If the field is missing/optional the server will crash with TypeError: Cannot read properties of undefined (reading 'map').

-const executionManager = this.#buildExecutionManager(configuration.segments);
+const segmentNames = configuration.segments ?? [];
+const executionManager = this.#buildExecutionManager(segmentNames);

Equally, change the signature of #buildExecutionManager to accept an optional array (see next comment).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#buildLocalWorker(url: string, configuration: WorkerConfiguration): LocalWorker
{
const trustKey = configuration.trustKey;
const gateway = configuration.gateway ? this.#buildRemoteGateway(configuration.gateway) : undefined;
const executionManager = await this.#buildExecutionManager(configuration.segments);
const registerAtGateway = gateway !== undefined;
const executionManager = this.#buildExecutionManager(configuration.segments);
return new LocalWorker({ url, trustKey, gateway, executionManager });
return new LocalWorker({ url, trustKey, gateway, registerAtGateway, executionManager });
}
#buildLocalWorker(url: string, configuration: WorkerConfiguration): LocalWorker
{
const trustKey = configuration.trustKey;
const gateway = configuration.gateway ? this.#buildRemoteGateway(configuration.gateway) : undefined;
const registerAtGateway = gateway !== undefined;
const segmentNames = configuration.segments ?? [];
const executionManager = this.#buildExecutionManager(segmentNames);
return new LocalWorker({ url, trustKey, gateway, registerAtGateway, executionManager });
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/runtime/src/server/ServerBuilder.ts (1)

7-7: ⚠️ Potential issue

Rename Proxy import to avoid shadowing the built-in global

The Proxy import shadows JavaScript's built-in Proxy class, which can cause confusion and potential bugs. This issue is also flagged by static analysis tools.

-import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
+import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy as ServiceProxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';

Then update all occurrences of new Proxy in the file to new ServiceProxy.

🧰 Tools
🪛 Biome (1.9.4)

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🧹 Nitpick comments (5)
packages/sourcing/src/modules/RemoteImportManager.ts (1)

5-11: Consider adding documentation about security implications

This class indirectly enforces security restrictions by using the RemoteModuleLocator, which throws an error for all locate attempts. Consider adding a class-level comment that explains this security behavior for better discoverability and maintainability.

+/**
+ * Manages imports for remote modules. Currently prevents all remote module loading
+ * for security reasons by using RemoteModuleLocator which throws ModuleNotLoaded errors.
+ */
export default class RemoteImportManager extends ImportManager
{
    constructor(location: string)
    {
        super(new RemoteModuleLocator(location));
    }
}
packages/services/test/repository/fixtures/sourcingManager.fixture.ts (3)

11-14: Consider documenting why filter throws NotImplemented.

While throwing NotImplemented is appropriate for a test fixture that doesn't need this functionality, adding a brief comment explaining why it's intentionally not implemented would improve code clarity.


16-20: Consider documenting why exists throws NotImplemented.

Similar to filter, adding a brief comment explaining the design decision to not implement this method would help future developers understand the test fixture's intentions.


32-36: Consider documenting why delete throws NotImplemented.

As with the other unimplemented methods, adding a brief comment would improve code clarity.

packages/runtime/src/server/ServerBuilder.ts (1)

98-99: Consider adding a documentation comment for registerAtGateway

The new registerAtGateway flag is derived from the presence of a gateway, but its purpose and implications aren't immediately clear from the code.

 const gateway = configuration.gateway ? this.#buildRemoteGateway(configuration.gateway) : undefined;
+// If gateway is defined, the worker should register itself with the gateway
 const registerAtGateway = gateway !== undefined;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fe8ff93 and 0f40a03.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • examples/README.md (1 hunks)
  • examples/resources/README.md (1 hunks)
  • packages/health/src/HealthManager.ts (3 hunks)
  • packages/middleware/src/MiddlewareManager.ts (2 hunks)
  • packages/runtime/src/server/ServerBuilder.ts (6 hunks)
  • packages/services/test/repository/fixtures/sourcingManager.fixture.ts (2 hunks)
  • packages/sourcing/src/modules/RemoteImportManager.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • examples/README.md
  • examples/resources/README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/health/src/HealthManager.ts
  • packages/middleware/src/MiddlewareManager.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/sourcing/src/modules/RemoteImportManager.ts (2)
packages/sourcing/src/modules/ImportManager.ts (1)
  • ImportManager (7-33)
packages/sourcing/src/modules/RemoteModuleLocator.ts (1)
  • RemoteModuleLocator (5-18)
packages/services/test/repository/fixtures/sourcingManager.fixture.ts (1)
packages/sourcing/src/LocalSourcingManager.ts (1)
  • LocalSourcingManager (7-16)
🪛 Biome (1.9.4)
packages/runtime/src/server/ServerBuilder.ts

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (11)
packages/sourcing/src/modules/RemoteImportManager.ts (1)

1-11: LGTM - Fixed naming inconsistency

The implementation correctly addresses the previous naming inconsistency by correctly using RemoteImportManager as the class name, which properly aligns with:

  1. The file name RemoteImportManager.ts
  2. The use of RemoteModuleLocator internally
  3. The overall pattern of "Remote" prefix for remote operations

The class appropriately extends ImportManager and delegates to RemoteModuleLocator for security handling.

packages/services/test/repository/fixtures/sourcingManager.fixture.ts (4)

3-3: Updated imports align with new architecture.

The addition of LocalSourcingManager reflects the architectural changes in the sourcing system.


8-8: Good refactoring to extend LocalSourcingManager.

Changing from implementing FileManager to extending LocalSourcingManager is a significant improvement. This properly aligns with the new sourcing architecture and eliminates the need to reimplement common functionality.

Most importantly, this change implicitly resolves the previous issue with the import() method by inheriting a working implementation from LocalSourcingManager instead of overriding it with one that throws.


22-30: LGTM!

The implementation of read correctly handles the test fixture cases and throws an appropriate error for unknown filenames.


39-39: LGTM!

Exporting a new instance with an empty string location is appropriate for a test fixture.

packages/runtime/src/server/ServerBuilder.ts (6)

27-28: Clean restructuring of setup and teardown scripts

Extracting the setup and teardown scripts from the configuration and delegating their management to a dedicated ResourceManager is a good architectural decision, improving separation of concerns.

Also applies to: 35-35


35-37: Improved server composition with dedicated managers

The synchronous instantiation of resource, middleware, and health managers streamlines the server build process and aligns with the PR objectives of moving loading responsibilities into dedicated managers.

Also applies to: 41-41


58-58: Successfully refactored service methods from async to sync

Converting the gateway and worker builder methods from async to sync improves code clarity and performance by removing unnecessary asynchronous operations.

Also applies to: 66-66, 79-79, 94-102


137-143: Well-structured ResourceManager implementation

The #buildResourceManager method properly transforms input filenames and creates a new ResourceManager instance with appropriate parameters, supporting the PR's objective of running setup scripts before loading modules.


145-157: Clean implementation of manager builders with default parameters

The #buildHealthManager and #buildMiddlewareManager methods properly handle default values and filename transformations, making them more robust against undefined inputs.


159-164: Fixed potential undefined segments issue

By using a default empty array parameter, the code now correctly handles undefined segment configurations, addressing the previous review comment about guarding against undefined segments.

Copy link

sonarqubecloud bot commented May 7, 2025

Quality Gate Passed Quality Gate passed

Issues
0 New issues
1 Accepted issue

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
packages/runtime/src/server/ServerBuilder.ts (1)

7-7: Address static analysis warning about shadowing the global Proxy

The static analysis tool still flags the imported Proxy as shadowing the global Proxy property. This was noted in a previous review comment and should be addressed for clarity and to avoid potential bugs. Rename the imported Proxy to ServiceProxy or similar.

-import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
+import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy as ServiceProxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';

Remember to update all occurrences of Proxy in the code to use the renamed import.

🧰 Tools
🪛 Biome (1.9.4)

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🧹 Nitpick comments (1)
packages/sourcing/src/modules/RemoteModuleLocator.ts (1)

7-16: Consider keeping the constructor despite static analysis warning.

The static analysis tool flags the constructor as unnecessary, but I agree with your implementation choice. The constructor with its explanatory comments serves an important documentation purpose, making it clear that this is intentionally designed for future extensibility.

If you want to make the intent even clearer to static analyzers, you could add a @ts-ignore comment or configure your linter to ignore this specific instance.

🧰 Tools
🪛 Biome (1.9.4)

[error] 11-16: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f40a03 and 71beb8e.

📒 Files selected for processing (6)
  • packages/runtime/src/server/ServerBuilder.ts (6 hunks)
  • packages/services/test/repository/fixtures/sourcingManager.fixture.ts (2 hunks)
  • packages/sourcing/src/files/LocalFileSystem.ts (1 hunks)
  • packages/sourcing/src/modules/ImportManager.ts (1 hunks)
  • packages/sourcing/src/modules/RemoteImportManager.ts (1 hunks)
  • packages/sourcing/src/modules/RemoteModuleLocator.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/sourcing/src/files/LocalFileSystem.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/sourcing/src/modules/RemoteImportManager.ts
  • packages/sourcing/src/modules/ImportManager.ts
  • packages/services/test/repository/fixtures/sourcingManager.fixture.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/runtime/src/server/ServerBuilder.ts

[error] 7-7: Do not shadow the global "Proxy" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

packages/sourcing/src/modules/RemoteModuleLocator.ts

[error] 11-16: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)

🔇 Additional comments (7)
packages/sourcing/src/modules/RemoteModuleLocator.ts (2)

5-22: Well-designed security boundary preventing remote module loading.

This class effectively implements a security boundary by blocking remote module loading, which is a good practice for preventing security vulnerabilities. The clear error message and explanatory comments help future developers understand the design intent.

🧰 Tools
🪛 Biome (1.9.4)

[error] 11-16: This constructor is unnecessary.

Unsafe fix: Remove the unnecessary constructor.

(lint/complexity/noUselessConstructor)


18-21: The error handling is clear and informative.

The locate method appropriately throws a ModuleNotLoaded error with a descriptive message explaining why remote module loading is disallowed. This provides good feedback to developers who might attempt to use this functionality.

packages/runtime/src/server/ServerBuilder.ts (5)

35-37: Good refactoring to use synchronous manager building methods

The refactoring to use synchronous manager building methods improves code readability and maintainability. This approach of directly instantiating manager classes aligns well with the PR objective of moving loading into dedicated managers.


94-102: Good addition of the registerAtGateway flag

Adding the registerAtGateway flag improves the clarity of worker-gateway interactions. This approach explicitly documents when a worker should register with a gateway based on the presence of a gateway configuration, making the code more maintainable and less error-prone.


137-143: Well-designed ResourceManager integration

The new ResourceManager implementation efficiently handles setup and teardown scripts. The translation of filenames to ensure proper extensions is a good practice. This change nicely centralizes resource management, which aligns with the PR objectives.


145-157: Consistent pattern for manager instantiation

The implementation of #buildHealthManager and #buildMiddlewareManager follows a consistent pattern, making the code more maintainable. The use of default empty arrays for parameters is a good defensive coding practice that prevents null/undefined errors.


159-164: Good implementation of default parameters

The updated #buildExecutionManager now correctly handles the case when no segments are provided by using a default empty array. This addresses a previous comment and prevents potential runtime errors when segments is undefined.

{
filter(...patterns: string[]): Promise<string[]>;

exists(filename: string): Promise<boolean>;
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: alphabetical order

Comment on lines 7 to 8
import { DummyProvider, DummyRunner, LocalGateway, LocalRepository, LocalWorker, Proxy, RemoteBuilder, RemoteGateway, RemoteRepository } from '@jitar/services';
import { SourcingManager } from '@jitar/sourcing';
Copy link
Member

Choose a reason for hiding this comment

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

After a short discussion we decided to rename the Proxy to LocalProxy to prevent confusion with the ECMAScript Proxy Object

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.

Run set up scripts before loading modules
2 participants