Skip to content

Conversation

@mateuszJS
Copy link
Owner

@mateuszJS mateuszJS commented Jul 21, 2025

Summary by CodeRabbit

  • New Features

    • Added support for initializing projects from multiple images via a new file input.
    • Introduced a fallback "loading" texture to display while images are loading.
  • Improvements

    • Refined asset and texture loading for more reliable and asynchronous handling.
    • Enhanced pointer event handling, including proper processing when the pointer leaves the canvas.
    • Updated asset management APIs to work with URLs and improved asset ID generation.
    • Simplified file input handling and reset logic for image uploads.
  • Bug Fixes

    • Ensured consistent fallback rendering when textures are missing or still loading.
  • Tests

    • Added an end-to-end test to verify initial asset upload functionality.
  • Chores

    • Added "http-server" as a development dependency for local testing.
  • Documentation

    • Improved comments and type declarations for better clarity and maintainability.

@mateuszJS mateuszJS requested a review from Copilot July 21, 2025 11:05
@coderabbitai
Copy link

coderabbitai bot commented Jul 21, 2025

Walkthrough

This update refactors asset and texture loading logic, modifies asset ID handling, and adjusts API signatures for asset management in both TypeScript and Zig code. It introduces new types, improves asynchronous handling of assets, updates integration tests and HTML templates, adds a loading texture fallback, and enhances pointer event handling.

Changes

File(s) Change Summary
integration-tests/index.ts, integration-tests/init.ts, integration-tests/template.html Refactored asset upload logic, updated selectors, introduced new file input for bulk asset upload, and updated HTML UI.
integration-tests/tests/history.spec.ts Removed non-null assertion from Playwright locator calls for undo/redo buttons.
integration-tests/tests/initial-assets.spec.ts Added a new Playwright test for verifying initial asset upload functionality.
package.json, playwright.config.ts Added http-server as a dev dependency and updated Playwright web server command to remove explicit npx usage.
src/WebGPU/pick.ts Added a clarifying comment about event queue logic in pointer picking.
src/WebGPU/pointer.ts Improved pointer leave event handling, introduced OUTSIDE_CANVAS constant, and properly reset pointer state on leave.
src/index.ts Refactored and unified asset/texture loading, changed API signatures, improved async handling, and updated type names.
src/loadingTexture.ts Added function to create a fallback loading texture for rendering.
src/logic/index.d.ts, src/logic/index.zig Updated Zig logic: changed asset ID handling, made callback pointer nullable, updated function signatures, and added pointer leave logic.
src/run.ts Integrated loading texture fallback for rendering and picking operations.
src/utils/getDefaultPoints.ts Refactored to use numeric dimensions instead of DOM elements for default point calculation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant Creator
    participant Logic (Zig)
    participant GPU

    User->>UI: Selects images via #add-image or #start-project-from-images
    UI->>Creator: Calls addImage(url) or resetAssets([{url}, ...])
    Creator->>GPU: addTexture(url) (async image load)
    GPU-->>Creator: Texture ready (with dimensions)
    Creator->>Logic (Zig): add_asset(maybe_id, points, texture_id) or reset_assets([...], with_snapshot)
    Logic (Zig)->>Creator: on_asset_update_cb([...])
    Creator->>UI: Updates asset state/history
Loading

Estimated code review effort

4 (60–120 minutes)

Possibly related PRs

Suggested labels

released on @next

Poem

In fields of code where assets grow,
Rabbits hop and textures flow.
With loading screens and pointer leaves,
New logic blooms beneath the eaves.
IDs now sprout from Zig’s own hand—
A garden neat, so finely planned!
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-21T11_21_27_494Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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 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 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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes snapshot handling on initialization by implementing asynchronous asset loading with fallback textures to prevent race conditions during initialization.

  • Refactored parameter signatures to use primitive types instead of DOM elements for better separation of concerns
  • Implemented asynchronous texture loading with fallback "loading" textures to prevent rendering issues
  • Added proper snapshot control during asset initialization to avoid unwanted history entries

Reviewed Changes

Copilot reviewed 14 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/utils/getDefaultPoints.ts Refactored to accept primitive width/height parameters instead of DOM elements
src/run.ts Added loading texture fallback for unloaded textures
src/logic/index.zig Updated asset management to handle optional callbacks and snapshot control
src/loadingTexture.ts New file providing fallback texture for assets during loading
src/index.ts Refactored to handle asynchronous asset loading with proper timing control
src/WebGPU/pointer.ts Added mouse leave handling and pointer state management
src/WebGPU/pick.ts Added clarifying comment about pointer state timing
playwright.config.ts Simplified http-server command
package.json Added http-server dependency
integration-tests/ Updated tests to support new API and added initial assets test
Comments suppressed due to low confidence (1)

src/logic/index.zig:81

  • [nitpick] The parameter 'maybe_id' is ambiguous. Consider renaming to 'id_or_zero' or 'provided_id' to clarify that 0 means generate a new ID.
pub fn add_asset(maybe_id: u32, points: [4]Types.PointUV, texture_id: u32) void {

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: 2

🧹 Nitpick comments (2)
src/WebGPU/pick.ts (1)

115-116: Good documentation of the design issue.

The comment accurately describes the synchronization problem where pointer coordinates are updated immediately while pick event processing is deferred. Consider addressing this architectural concern in a future refactor to ensure consistent event ordering.

src/index.ts (1)

172-177: Fix typos in the comment.

-            const textureId = addTexture(asset.url, (width, height) => {
-              // we wait to add iamge once poitns are known because otherwise
-              // if we add img first with "Default" point value and update
-              // it later ocne texture is loaded, we will get history snapshot with
-              // that "default" points
+            const textureId = addTexture(asset.url, (width, height) => {
+              // we wait to add image once points are known because otherwise
+              // if we add img first with "Default" point value and update
+              // it later once texture is loaded, we will get history snapshot with
+              // that "default" points
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fb4a261 and 0b66de7.

⛔ Files ignored due to path filters (2)
  • integration-tests/another-image-sample.jpg is excluded by !**/*.jpg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (15)
  • integration-tests/index.ts (2 hunks)
  • integration-tests/init.ts (1 hunks)
  • integration-tests/template.html (1 hunks)
  • integration-tests/tests/history.spec.ts (1 hunks)
  • integration-tests/tests/initial-assets.spec.ts (1 hunks)
  • package.json (1 hunks)
  • playwright.config.ts (1 hunks)
  • src/WebGPU/pick.ts (1 hunks)
  • src/WebGPU/pointer.ts (2 hunks)
  • src/index.ts (3 hunks)
  • src/loadingTexture.ts (1 hunks)
  • src/logic/index.d.ts (1 hunks)
  • src/logic/index.zig (8 hunks)
  • src/run.ts (2 hunks)
  • src/utils/getDefaultPoints.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/WebGPU/pointer.ts (1)
src/logic/index.d.ts (1)
  • on_pointer_leave (30-30)
integration-tests/index.ts (1)
src/index.ts (1)
  • SerializedOutputAsset (28-33)
src/run.ts (3)
src/loadingTexture.ts (1)
  • getLoadingTexture (1-32)
src/logic/index.d.ts (1)
  • connect_web_gpu_programs (32-38)
src/WebGPU/programs/initPrograms.ts (4)
  • drawTexture (18-18)
  • drawMSDF (21-21)
  • drawTriangle (12-12)
  • pickTexture (19-19)
src/utils/getDefaultPoints.ts (1)
src/utils/clamp.ts (1)
  • clamp (1-3)
🔇 Additional comments (24)
package.json (1)

41-41: http-server version ^14.1.1 is up-to-date

The http-server devDependency at version ^14.1.1 matches the latest stable release (14.1.1) and aligns with our Playwright test setup. Approved.

src/loadingTexture.ts (3)

1-6: LGTM! Clean function signature and well-defined constants.

The function signature is clear and the color constants provide good readability for the texture pattern definition.


8-16: Creative and readable texture data definition.

The approach of using color arrays and .flat() to create the texture data is both readable and maintainable. The yellow "F" pattern will serve as a good visual indicator for loading textures.


18-31: Proper GPU texture creation and data upload.

The texture creation uses appropriate format (rgba8unorm), correct usage flags, and proper data upload with correct layout parameters. The implementation follows WebGPU best practices.

integration-tests/init.ts (1)

68-68: Good improvement in selector specificity.

Changing from the generic input[type="file"] to the specific #add-image ID selector improves test reliability and aligns with the updated HTML template structure.

integration-tests/tests/history.spec.ts (1)

12-13: Good removal of non-null assertion operators.

Removing the ! operators allows Playwright's built-in error handling to work properly, making the tests more robust and idiomatic.

integration-tests/template.html (1)

33-34: Excellent UI and accessibility improvements.

The changes provide several benefits:

  • Proper labels improve accessibility and user experience
  • Semantic separation between single image addition and bulk project initialization
  • Clear IDs that align with test selectors
  • Multiple file support for project initialization

These changes enhance both usability and testability.

playwright.config.ts (1)

114-114: LGTM! Dependency management improvement.

Removing npx aligns with adding http-server as a direct dev dependency, which is a cleaner approach than relying on npx for package execution.

src/run.ts (5)

14-14: Excellent defensive programming pattern.

Adding the loading texture import enables robust fallback handling for missing textures during async loading.


34-34: Good initialization strategy.

Initializing the loading texture once and reusing it across all rendering calls is efficient and provides consistent fallback behavior.


37-43: Robust texture fallback implementation.

The nullish coalescing operator ensures draw_texture always receives a valid GPU texture, preventing runtime errors when textures haven't loaded yet.


44-51: Consistent fallback pattern for MSDF rendering.

The same robust fallback pattern applied to draw_msdf ensures consistent behavior across all texture rendering operations.


53-60: Proper fallback for picking operations.

Applying the loading texture fallback to pick_texture ensures picking operations work correctly even when assets are still loading, maintaining UI responsiveness.

integration-tests/tests/initial-assets.spec.ts (1)

8-27: Test image files verified

  • Confirmed that both integration-tests/image-sample.png and integration-tests/another-image-sample.jpg are present.

Integration test is approved as-is.

src/WebGPU/pointer.ts (4)

1-6: Good import organization.

Adding on_pointer_leave import expands the pointer event handling capabilities for better canvas boundary management.


8-8: Excellent sentinel value choice.

Using -1 as OUTSIDE_CANVAS is much better than 0 since (0,0) is a valid canvas coordinate. This clearly distinguishes between a valid position and "outside canvas" state.


25-26: Proper initialization with sentinel values.

Initializing pointer coordinates to OUTSIDE_CANVAS correctly represents the initial state where the pointer hasn't entered the canvas yet.


34-50: Robust mouseleave event handling.

The implementation correctly:

  • Follows the established deferred processing pattern for event queue consistency
  • Sets coordinates to the sentinel value when leaving canvas
  • Calls the appropriate logic callback
  • Maintains proper event ordering with other pointer operations

This ensures reliable pointer state management when the cursor exits the canvas area.

integration-tests/index.ts (1)

43-62: LGTM! Good handling of file inputs.

The implementation correctly:

  • Uses specific IDs for file inputs instead of generic selectors
  • Resets input values to allow re-uploading the same file
  • Properly creates object URLs from selected files
src/utils/getDefaultPoints.ts (1)

3-42: Good refactoring to decouple from DOM elements.

The change from DOM elements to numeric parameters improves:

  • Testability (easier to test with numeric values)
  • Reusability (can be used in non-DOM contexts)
  • Performance (avoids DOM property access)
src/logic/index.zig (3)

28-31: Good defensive programming with optional callback.

Making the callback optional and checking for null before invocation prevents potential crashes.


75-85: Well-implemented ID generation logic.

The ID generation function correctly uses wrapping addition to handle overflow, and the conditional ID assignment in add_asset properly handles both provided and generated IDs.


318-338: Clever callback suppression during reset.

The temporary nullification of the callback during reset prevents unwanted notifications, and the conditional notification based on with_snapshot provides fine-grained control over update behavior.

src/index.ts (1)

159-192: Well-implemented async asset reset with proper error handling.

The use of Promise.allSettled ensures that one failed asset doesn't block others from loading, and filtering for fulfilled results provides resilience against individual failures.

Comment on lines +88 to +114
function addTexture(url: string, callback?: (width: number, height: number) => void): number {
loadingTextures++
updateProcessing()

const textureId = textures.length
textures.push({ url })

const img = new Image()
img.src = url

img.onload = () => {
textures[textureId].texture = createTextureFromSource(device, img, { flipY: true })
callback?.(img.width, img.height)

loadingTextures--
updateProcessing()
}

img.onerror = () => {
console.error(`Failed to load image from ${url}`)

loadingTextures--
updateProcessing()
}

return textureId
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider improving error handling in texture loading.

The current implementation has potential issues:

  1. Failed textures remain in the array without a texture property, which could cause issues when rendering
  2. Errors are only logged to console without notifying the caller

Consider adding error state tracking or removing failed textures from the array.

🤖 Prompt for AI Agents
In src/index.ts between lines 88 and 114, the addTexture function currently adds
a texture object to the textures array before loading the image, but if the
image fails to load, the texture property is never set and the failed texture
remains in the array, which may cause rendering issues. To fix this, modify the
img.onerror handler to either remove the failed texture entry from the textures
array or mark it with an error state. Additionally, enhance error handling by
invoking the callback with an error indication or adding an optional error
callback parameter so the caller is notified of the failure instead of just
logging to the console.

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: 1

♻️ Duplicate comments (1)
src/index.ts (1)

88-114: Potential issue: Incomplete error handling in texture loading.

The current implementation has the same issues identified in previous reviews:

  1. Failed textures remain in the array without a texture property
  2. Only console logging without proper error propagation to callers

Consider enhancing error handling:

 img.onerror = () => {
   console.error(`Failed to load image from ${url}`)
+  // Mark the texture as failed or remove it from the array
+  textures[textureId] = { url, texture: null } // or similar error state
   
   loadingTextures--
   updateProcessing()
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 0b66de7 and 4624a86.

📒 Files selected for processing (4)
  • src/WebGPU/pick.ts (1 hunks)
  • src/index.ts (3 hunks)
  • src/logic/index.d.ts (1 hunks)
  • src/logic/index.zig (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/WebGPU/pick.ts
  • src/logic/index.d.ts
🔇 Additional comments (12)
src/logic/index.zig (8)

28-28: Good: Making callback pointer nullable improves robustness.

The change from a non-null pointer to an optional pointer allows for safer callback handling and prevents potential issues when the callback is not set.


75-79: Good: Proper ID generation with overflow handling.

The generate_id() function correctly uses wrapping addition (+%=) to handle potential overflow, which is appropriate for ID generation.


115-147: Good: Improved null safety in callback handling.

The early return pattern when the callback is null (const cb = on_asset_update_cb orelse return;) is a good defensive programming practice that prevents potential crashes.


192-196: Good: New pointer leave handler for better UX.

The on_pointer_leave() function properly resets the interaction state when the pointer leaves the canvas, which should improve user experience by preventing stuck states.


318-338: Good: Conditional snapshot behavior aligns with PR objective.

The addition of the with_snapshot parameter and conditional call to notify_about_assets_update() directly addresses the PR objective of fixing snapshots on initialization. This prevents unnecessary snapshot creation during asset reset.


345-345: Good: Proper state cleanup in destroy_state.

Resetting active_asset_id to 0 in destroy_state() ensures clean state management and prevents potential issues with stale asset references.


392-392: Good: Test updated to match new signature.

The test correctly passes false for the new with_snapshot parameter, maintaining the original test behavior while adapting to the new API.


81-85: All add_asset calls updated to the new signature; no further action required.

  • src/index.ts: add_asset(0 /* auto-generate ID */, points, textureId)
  • src/logic/index.zig: add_asset(asset.id, asset.points, asset.texture_id);
src/index.ts (4)

21-33: Good: Clear separation of input and output asset types.

The distinction between SerializedInputAsset (for loading) and SerializedOutputAsset (for callbacks) provides better type safety and clearer API contracts. The optional fields in the input type allow for flexible asset loading scenarios.


36-37: Good: Simplified API signature using URLs.

The change from HTMLImageElement to string (URL) in addImage and the addition of optional withSnapshot parameter in resetAssets make the API more flexible and align with the snapshot fix objective.


133-138: Good: Improved addImage implementation with async texture loading.

The refactored addImage function properly uses the new addTexture helper and generates default points based on actual image dimensions, which should provide better initial asset placement.


140-152: Good: Consistent texture loading for icons.

The icon loading has been properly refactored to use the new addTexture function with normalized coordinates calculation, maintaining consistency with the new texture loading approach.

Comment on lines +159 to 192
const resetAssets: CreatorAPI['resetAssets'] = async (assets, withSnapshot = false) => {
const results = await Promise.allSettled(
assets.map<Promise<AssetZig>>(
(asset) =>
new Promise((resolve, reject) => {
if (asset.points) {
return resolve({
points: asset.points,
texture_id: asset.textureId || addTexture(asset.url),
id: asset.id || 0,
})
}

const textureId = addTexture(asset.url, (width, height) => {
// we wait to add image once points are known because otherwise
// if we add img first with "Default" point value and update
// it later once texture is loaded, we will get history snapshot with
// that "default" points
return resolve({
points: getDefaultPoints(width, height, canvas.clientWidth, canvas.clientHeight),
texture_id: textureId, // if there is no points, then for sure there is no asset.textureId
id: 0,
})
})
})
)
)

const zigAssets = results
.filter((result) => result.status === 'fulfilled')
.map((result) => result.value)

reset_assets(zigAssets, withSnapshot)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Potential issue: Complex async logic with limited error handling.

While the Promise.allSettled approach is good for handling partial failures, there are potential concerns:

  1. No error logging for rejected promises
  2. Silent filtering of failed assets may confuse users
  3. Potential race condition if resetAssets is called multiple times rapidly

Consider adding error handling and user feedback:

 const results = await Promise.allSettled(
   assets.map<Promise<AssetZig>>(
     (asset) =>
       new Promise((resolve, reject) => {
         if (asset.points) {
           return resolve({
             points: asset.points,
             texture_id: asset.textureId || addTexture(asset.url),
             id: asset.id || 0,
           })
         }

         const textureId = addTexture(asset.url, (width, height) => {
+          try {
             return resolve({
               points: getDefaultPoints(width, height, canvas.clientWidth, canvas.clientHeight),
               texture_id: textureId,
               id: 0,
             })
+          } catch (error) {
+            reject(new Error(`Failed to generate points for ${asset.url}: ${error.message}`))
+          }
         })
       })
   )
 )

+// Log failed assets for debugging
+const failedAssets = results.filter(result => result.status === 'rejected')
+if (failedAssets.length > 0) {
+  console.warn(`Failed to load ${failedAssets.length} assets:`, failedAssets.map(r => r.reason))
+}
📝 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
const resetAssets: CreatorAPI['resetAssets'] = async (assets, withSnapshot = false) => {
const results = await Promise.allSettled(
assets.map<Promise<AssetZig>>(
(asset) =>
new Promise((resolve, reject) => {
if (asset.points) {
return resolve({
points: asset.points,
texture_id: asset.textureId || addTexture(asset.url),
id: asset.id || 0,
})
}
const textureId = addTexture(asset.url, (width, height) => {
// we wait to add image once points are known because otherwise
// if we add img first with "Default" point value and update
// it later once texture is loaded, we will get history snapshot with
// that "default" points
return resolve({
points: getDefaultPoints(width, height, canvas.clientWidth, canvas.clientHeight),
texture_id: textureId, // if there is no points, then for sure there is no asset.textureId
id: 0,
})
})
})
)
)
const zigAssets = results
.filter((result) => result.status === 'fulfilled')
.map((result) => result.value)
reset_assets(zigAssets, withSnapshot)
}
const resetAssets: CreatorAPI['resetAssets'] = async (assets, withSnapshot = false) => {
const results = await Promise.allSettled(
assets.map<Promise<AssetZig>>(
(asset) =>
new Promise((resolve, reject) => {
if (asset.points) {
return resolve({
points: asset.points,
texture_id: asset.textureId || addTexture(asset.url),
id: asset.id || 0,
})
}
const textureId = addTexture(asset.url, (width, height) => {
try {
return resolve({
points: getDefaultPoints(width, height, canvas.clientWidth, canvas.clientHeight),
texture_id: textureId,
id: 0,
})
} catch (error) {
reject(new Error(`Failed to generate points for ${asset.url}: ${error.message}`))
}
})
})
)
)
// Log failed assets for debugging
const failedAssets = results.filter(result => result.status === 'rejected')
if (failedAssets.length > 0) {
console.warn(`Failed to load ${failedAssets.length} assets:`, failedAssets.map(r => r.reason))
}
const zigAssets = results
.filter((result) => result.status === 'fulfilled')
.map((result) => result.value)
reset_assets(zigAssets, withSnapshot)
}
🤖 Prompt for AI Agents
In src/index.ts around lines 159 to 192, the async logic inside resetAssets uses
Promise.allSettled but does not handle or log errors from rejected promises, and
silently filters out failed assets which can confuse users. To fix this, add
error logging for any rejected promises after Promise.allSettled resolves, and
consider notifying the user about assets that failed to process. Additionally,
implement a mechanism to prevent race conditions if resetAssets is called
multiple times rapidly, such as debouncing calls or tracking ongoing executions
to avoid overlapping resets.

@mateuszJS mateuszJS merged commit 7fc7007 into next Jul 21, 2025
6 checks passed
@github-actions
Copy link

🎉 This PR is included in version 0.1.0-next.12 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants