Skip to content

Store-layout-in-extension-api#2

Merged
mdroidian merged 4 commits intomainfrom
store-layout-in-extension-api
Feb 10, 2026
Merged

Store-layout-in-extension-api#2
mdroidian merged 4 commits intomainfrom
store-layout-in-extension-api

Conversation

@mdroidian
Copy link
Copy Markdown
Contributor

@mdroidian mdroidian commented Feb 10, 2026

  • Updated getPageUid to use the pull method for fetching the page UID, enhancing efficiency.
  • Simplified the return logic to handle null cases more gracefully.

Open with Devin

Summary by CodeRabbit

  • Refactor
    • Layout persistence migrated from local storage to extension settings for more reliable, consistent saving and loading of note layouts.
  • New Features
    • Layout persistence now initializes on startup and updates automatically; tools to read current layout settings exposed for diagnostics.

- Introduced OnloadArgs type for better extension settings handling.
- Updated getLayouts and setLayouts functions to utilize extension settings API.
- Enhanced layout normalization and ensured consistent formatting.
- Improved event handling for sticky note dragging, ensuring layout persistence on drag end.
- Refactored createStickyNoteElement to streamline layout updates and interactions.
- Updated getPageUid to use the pull method for fetching the page UID, enhancing efficiency.
- Simplified the return logic to handle null cases more gracefully.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 10, 2026

Warning

Rate limit exceeded

@mdroidian has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

Layout persistence was moved from localStorage to the extension settings API. getLayouts now reads and normalizes layouts from extensionSettings (returning an empty object for missing/invalid data). setLayouts writes layouts to extensionSettings. createStickyNoteElement’s public signature was expanded to accept persistLayouts and readLayoutsSetting; initialization was updated to derive layouts via getLayouts({ extensionSettings }) and expose a persistLayouts helper used in place of prior setLayouts calls. Minor formatting and trailing-comma adjustments were applied.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Store-layout-in-extension-api' is directly related to the main changes in the PR, which migrate layout persistence from localStorage to extension settings API.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch store-layout-in-extension-api

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

❤️ Share

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

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown

@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

🤖 Fix all issues with AI agents
In `@src/index.ts`:
- Around line 478-479: Remove the diagnostic console.log and the auxiliary
readLayoutsSetting parameter from the public API: delete the
console.log("[sticky-note] drag end settings", readLayoutsSetting()) call after
persistLayouts(), remove the readLayoutsSetting parameter from the
createStickyNoteElement function signature and all places that call
createStickyNoteElement (and any intermediate forwarding), and update any
references inside createStickyNoteElement that only existed to support that
debug log; ensure persistLayouts() remains called and no other behavior is
changed.
🧹 Nitpick comments (2)
src/index.ts (2)

82-88: Unsafe cast — normalizeLayout only validates rotation.

JSON.parse(raw) as StickyNoteLayouts trusts that all layout fields (x, y, width, height, minimized) are present and correctly typed. If stored data is ever partially corrupt (e.g., after a failed write or schema change), notes could render at NaN/undefined positions. Consider either validating all fields in normalizeLayout or adding a guard that drops invalid entries.


467-480: Cancel the pending debounce timer on drag end to avoid a redundant persist.

stopDragging calls persistLayouts() immediately (line 478), but a pending resizePersistTimeout from scheduleLayoutPersistence (set during onPointerMove) may still fire ~250ms later, causing a redundant write.

Proposed fix
   const stopDragging = (): void => {
     if (!isDragging) {
       return;
     }
     isDragging = false;
+    if (resizePersistTimeout) {
+      window.clearTimeout(resizePersistTimeout);
+      resizePersistTimeout = null;
+    }
     note.classList.remove(NOTE_DRAGGING_CLASS);

@mdroidian mdroidian merged commit 35ff85a into main Feb 10, 2026
1 check passed
@mdroidian mdroidian deleted the store-layout-in-extension-api branch February 10, 2026 05:17
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 7 additional findings in Devin Review.

Open in Devin Review

Comment on lines +100 to 102
}): void => {
extensionSettings.set(STORAGE_KEY, JSON.stringify(layouts));
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Unhandled Promise from async extensionSettings.set in setLayouts

The setLayouts function calls extensionSettings.set() without awaiting or catching the returned Promise, causing silent failures and unhandled promise rejections.

Root Cause

The old code used synchronous localStorage.setItem which would throw synchronously on failure (e.g. quota exceeded), but the new code at src/index.ts:101 calls extensionSettings.set(STORAGE_KEY, JSON.stringify(layouts)) which returns Promise<void> (per the type definition at node_modules/roamjs-components/types/native.d.ts:393: set: (k: string, v: unknown) => Promise<void>). Since the return type of setLayouts is void, this Promise is silently discarded.

This means:

  • If extensionSettings.set rejects, the error is completely lost—no logging, no user feedback.
  • This produces unhandled promise rejections in the runtime, which may be reported as errors in the console or could crash the extension in strict environments.
  • Every callsite that invokes persistLayouts() (lines 451, 482, 513, 558, 781, 805, 830) is affected since persistLayouts at line 751 delegates directly to setLayouts.

Impact: Layout changes (drag, resize, minimize, delete) may silently fail to persist without any indication to the user, and unhandled rejections are produced.

Suggested change
}): void => {
extensionSettings.set(STORAGE_KEY, JSON.stringify(layouts));
};
}): void => {
void extensionSettings.set(STORAGE_KEY, JSON.stringify(layouts)).catch((err) => {
console.error("[sticky-note] Failed to persist layouts", err);
});
};
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

1 participant