Compare commits

..

100 Commits

Author SHA1 Message Date
Saul-Mirone
22924c767c fix(editor): onChange notification for flat model (#10589)
The primary purpose of this PR appears to be:
1. Simplifying the change notification API by removing the redundant value parameter from callbacks
2. Improving the reactive system's handling of specialized types (Text and Boxed) in flat data
3. Adding better test coverage for text handling in the flat data model
2025-03-04 05:57:06 +00:00
doodlewind
c418e89fb9 chore(editor): add feature flag entry for testing turbo renderer (#10581)
The debug pane will be displayed once the `enable_turbo_renderer` feature flag is enabled.

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/lEGcysB4lFTEbCwZ8jMv/c1ba558a-2d84-403c-aa81-864b0338c861.png)
2025-03-04 05:38:44 +00:00
doouding
1c29d0e269 feat: optimize edgeless alignment (#10435)
### Changed
- alignment line style
- threshold of snapping
- optimize alignment checking performance
2025-03-04 03:03:31 +00:00
akumatus
321247a2fa fix(core): add ai 7 day trial hint (#10587)
Fix issue [BS-2739](https://linear.app/affine-design/issue/BS-2739).
2025-03-03 15:10:16 +00:00
pengx17
8e5d7858c4 fix(core): only enable attachment preview for pdf (#10584) 2025-03-03 11:07:13 +00:00
L-Sun
37fbfbcf3e fix(editor): zindex of frame child not updated (#10580)
Close [BS-2689](https://linear.app/affine-design/issue/BS-2689/[bug]-%E5%BD%93%E5%B1%82%E7%BA%A7%E4%BD%8E%E4%BA%8E-frame-%E7%9A%84yuan%E7%B4%A0%E8%A2%AB%E6%8B%96%E5%85%A5-frame-%E6%97%B6%E5%B1%82%E7%BA%A7%E5%BA%94%E8%AF%A5%E8%A2%AB%E8%87%AA%E5%8A%A8%E6%8B%89%E9%AB%98%E5%B5%8C%E5%85%A5-frame)
2025-03-03 10:51:27 +00:00
liuyi
889625cdaa fix(server): reschedule busy doc merging (#10583) 2025-03-03 18:51:09 +08:00
Saul-Mirone
4c3c953a36 chore(editor): merge clamp functions (#10577)
Closes: [BS-2625](https://linear.app/affine-design/issue/BS-2625/合并clamp函数)
2025-03-03 10:33:38 +00:00
Brooooooklyn
899a957fab fix(native): do not crash on bootstrap if API is not available (#10582) 2025-03-03 10:15:42 +00:00
L-Sun
2cd83be621 fix(editor): code block toolbar float offset (#10579)
Close [BS-2736](https://linear.app/affine-design/issue/BS-2736/代码块工具栏偏移太大), [BS-1974](https://linear.app/affine-design/issue/BS-1974/code-block-浮标歪)

## Before

https://github.com/user-attachments/assets/f4ec4d7d-8c18-43ea-9464-c18e8b8dce60

https://github.com/user-attachments/assets/76f89ce6-bd89-49d6-a987-e9e5d5f9842a

### After

https://github.com/user-attachments/assets/dac919b9-d19c-4fb3-99bf-be02a460ad8c

https://github.com/user-attachments/assets/e5329f84-f1cf-4776-a789-8d12bea17ece
2025-03-03 09:56:13 +00:00
donteatfriedrice
170066050e feat(core): support latex in ai text renderer (#10576) 2025-03-03 09:19:31 +00:00
liuyi
abad289783 fix(server): limit max batch pulled doc updates (#10578) 2025-03-03 09:19:17 +00:00
Flrande
5d3c365d97 fix(editor): format text in code block (#10575)
Closes: [BS-2724](https://linear.app/affine-design/issue/BS-2724/code-block%E9%87%8C%E4%B8%8D%E5%BA%94%E8%AF%A5%E6%98%BE%E7%A4%BAtoolbar)
2025-03-03 08:52:38 +00:00
doodlewind
86c449319b chore(editor): remove redundant fields in viewport (#10569) 2025-03-03 07:49:08 +00:00
fengmk2
0e24ea3ac5 fix(server): throw s3 store error directly (#10572)
close CLOUD-154
2025-03-03 07:09:54 +00:00
fengmk2
0e26498e6a refactor(server): reduce server resource requests (#10568)
close CLOUD-149
2025-03-03 06:33:07 +00:00
Saul-Mirone
a587abca85 feat(editor): add block meta service (#10561) 2025-03-03 06:13:06 +00:00
zzj3720
3711e13e0e fix(editor): database block create new row when group by rich-text (#10564) 2025-03-03 05:58:07 +00:00
Brooooooklyn
18bdf830b4 ci: fix native server build (#10554) 2025-03-03 05:44:00 +00:00
Brooooooklyn
73fa04e249 chore: unify Cargo deps versions (#10553) 2025-03-03 03:30:59 +00:00
Saul-Mirone
4eae3cc66a feat(editor): add user list services (#10555) 2025-03-03 03:15:00 +00:00
pengx17
629aea48df fix(electron): app menu about action (#10445)
fix AF-2268
2025-03-03 03:00:17 +00:00
doodlewind
bd1b26a230 feat(editor): support zooming placeholder in turbo renderer (#10504)
[Screen Recording 2025-02-28 at 4.32.20 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/lEGcysB4lFTEbCwZ8jMv/6c08b827-8428-42f3-aa7a-a2366756bd16.mov" />](https://app.graphite.dev/media/video/lEGcysB4lFTEbCwZ8jMv/6c08b827-8428-42f3-aa7a-a2366756bd16.mov)

This prevents painting task backlog during zooming by adding a fast placeholder painter, with a `zooming` state in renderer state machine.
2025-03-03 02:07:46 +00:00
Saul-Mirone
fdde818ddd feat(editor): add block meta feature flag (#10548) 2025-03-03 01:45:33 +00:00
Saul-Mirone
f23f29610c refactor(editor): remove stable feature flags (#10547) 2025-03-02 08:41:12 +00:00
Saul-Mirone
6353e72078 feat(editor): add embed option config extension (#10540)
This PR implements a significant refactoring of the embed block services across multiple components (Figma, GitHub, Loom, and YouTube) in the BlockSuite codebase. Here are the key changes:

1. **Architecture Change**:
   - Moves from a dynamic registration pattern to a more declarative configuration approach
   - Replaces `EmbedOptionProvider.registerEmbedBlockOptions()` calls with a new `EmbedOptionConfig` factory function

2. **Service Refactoring**:
   - For each embed block type (Figma, GitHub, Loom, YouTube):
     - Separates configuration from service logic
     - Creates new `EmbedBlockOptionConfig` constants using the new `EmbedOptionConfig` factory
     - Removes the `mounted()` lifecycle hook from services where it was only used for registration

3. **Core Changes**:
   - In `embed-option-service.ts`:
     - Introduces new `EmbedOptionConfigIdentifier` for dependency injection
     - Adds `EmbedOptionConfig` factory function for creating embed configurations
     - Updates `EmbedOptionService` constructor to automatically register configurations
     - Modifies DI setup to include `StdIdentifier` dependency

4. **Spec Updates**:
   - Updates all block specs to include the new configuration objects
   - Maintains existing functionality while using the new pattern

The main benefit of this refactoring is:
- More declarative configuration approach
- Better separation of concerns
- Reduced runtime registration code
- More predictable initialization of embed options
2025-03-01 16:40:18 +00:00
Saul-Mirone
7527d36547 feat: prevent cycle emit in slot (#10539) 2025-03-01 08:10:41 +00:00
renovate
2b0c91b58b chore: bump up sonner version to v2 (#10535)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [sonner](https://sonner.emilkowal.ski/) ([source](https://redirect.github.com/emilkowalski/sonner)) | [`^1.7.1` -> `^2.0.0`](https://renovatebot.com/diffs/npm/sonner/1.7.4/2.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/sonner/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/sonner/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/sonner/1.7.4/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/sonner/1.7.4/2.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>emilkowalski/sonner (sonner)</summary>

### [`v2.0.1`](https://redirect.github.com/emilkowalski/sonner/releases/tag/v2.0.1)

[Compare Source](https://redirect.github.com/emilkowalski/sonner/compare/v2.0.0...v2.0.1)

##### What's Changed

-   fix: flush sync error by [@&#8203;emilkowalski](https://redirect.github.com/emilkowalski) in [https://github.com/emilkowalski/sonner/pull/586](https://redirect.github.com/emilkowalski/sonner/pull/586)
-   fix: allow users to select text after swipe gesture by [@&#8203;emilkowalski](https://redirect.github.com/emilkowalski) in [https://github.com/emilkowalski/sonner/pull/587](https://redirect.github.com/emilkowalski/sonner/pull/587)

**Full Changelog**: https://github.com/emilkowalski/sonner/compare/v2.0.0...v2.0.1

### [`v2.0.0`](https://redirect.github.com/emilkowalski/sonner/releases/tag/v2.0.0)

[Compare Source](8665072d34...v2.0.0)

Mostly bug fixes, see more at https://sonner.emilkowal.ski/getting-started.

##### What's Changed

-   sonner v2.0 by [@&#8203;emilkowalski](https://redirect.github.com/emilkowalski) in [https://github.com/emilkowalski/sonner/pull/558](https://redirect.github.com/emilkowalski/sonner/pull/558)

**Full Changelog**: https://github.com/emilkowalski/sonner/compare/v.2.0.0-beta.1...v2.0.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-03-01 03:28:11 +00:00
renovate
b05315c6fa chore: bump up shiki version to v3 (#10534)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [shiki](https://redirect.github.com/shikijs/shiki) ([source](https://redirect.github.com/shikijs/shiki/tree/HEAD/packages/shiki)) | [`^2.0.0` -> `^3.0.0`](https://renovatebot.com/diffs/npm/shiki/2.5.0/3.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/shiki/3.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/shiki/3.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/shiki/2.5.0/3.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/shiki/2.5.0/3.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>shikijs/shiki (shiki)</summary>

### [`v3.1.0`](https://redirect.github.com/shikijs/shiki/releases/tag/v3.1.0)

[Compare Source](https://redirect.github.com/shikijs/shiki/compare/v3.0.0...v3.1.0)

#####    🚀 Features

-   **engine-js**: Bump deps to work around Safari bug with some grammars  -  by [@&#8203;slevithan](https://redirect.github.com/slevithan) in [https://github.com/shikijs/shiki/issues/941](https://redirect.github.com/shikijs/shiki/issues/941) [<samp>(47205)</samp>](https://redirect.github.com/shikijs/shiki/commit/4720501b)
-   **twoslash**: Upgrade twoslash v0.3, require typescript v5.5+, close [#&#8203;950](https://redirect.github.com/shikijs/shiki/issues/950), close [#&#8203;951](https://redirect.github.com/shikijs/shiki/issues/951)  -  by [@&#8203;antfu](https://redirect.github.com/antfu) in [https://github.com/shikijs/shiki/issues/950](https://redirect.github.com/shikijs/shiki/issues/950) and [https://github.com/shikijs/shiki/issues/951](https://redirect.github.com/shikijs/shiki/issues/951) [<samp>(5c6f9)</samp>](https://redirect.github.com/shikijs/shiki/commit/5c6f9e92)

#####    🐞 Bug Fixes

-   **monaco**: Handle missing settings in textmate theme func  -  by [@&#8203;felipetodev](https://redirect.github.com/felipetodev) in [https://github.com/shikijs/shiki/issues/939](https://redirect.github.com/shikijs/shiki/issues/939) [<samp>(19f75)</samp>](https://redirect.github.com/shikijs/shiki/commit/19f75f66)

#####     [View changes on GitHub](https://redirect.github.com/shikijs/shiki/compare/v3.0.0...v3.1.0)

### [`v3.0.0`](https://redirect.github.com/shikijs/shiki/releases/tag/v3.0.0)

[Compare Source](https://redirect.github.com/shikijs/shiki/compare/v2.5.0...v3.0.0)

#####    🚨 Breaking Changes

-   Remove deprecated apis for v3.0  -  by [@&#8203;antfu](https://redirect.github.com/antfu) in [https://github.com/shikijs/shiki/issues/900](https://redirect.github.com/shikijs/shiki/issues/900) [<samp>(55c15)</samp>](https://redirect.github.com/shikijs/shiki/commit/55c1554b)
-   Remove `node10` typescript resolution support  -  by [@&#8203;userquin](https://redirect.github.com/userquin) in [https://github.com/shikijs/shiki/issues/923](https://redirect.github.com/shikijs/shiki/issues/923) [<samp>(ccb58)</samp>](https://redirect.github.com/shikijs/shiki/commit/ccb5856b)
-   **twoslash**: Make default `moduleResolution` to `bundler`  -  by [@&#8203;antfu](https://redirect.github.com/antfu) in [https://github.com/shikijs/shiki/issues/936](https://redirect.github.com/shikijs/shiki/issues/936) [<samp>(e924d)</samp>](https://redirect.github.com/shikijs/shiki/commit/e924d4b1)

#####    🐞 Bug Fixes

-   **transformers**:
    -   Also remove extra newline token, fix [#&#8203;915](https://redirect.github.com/shikijs/shiki/issues/915)  -  by [@&#8203;antfu](https://redirect.github.com/antfu) in [https://github.com/shikijs/shiki/issues/915](https://redirect.github.com/shikijs/shiki/issues/915) [<samp>(cc591)</samp>](https://redirect.github.com/shikijs/shiki/commit/cc5913eb)
    -   Support matching comments in comments, fix [#&#8203;934](https://redirect.github.com/shikijs/shiki/issues/934)  -  by [@&#8203;antfu](https://redirect.github.com/antfu) in [https://github.com/shikijs/shiki/issues/934](https://redirect.github.com/shikijs/shiki/issues/934) [<samp>(6efc8)</samp>](https://redirect.github.com/shikijs/shiki/commit/6efc8979)
    -   Fix matching indices for word-highlight  -  by [@&#8203;artt](https://redirect.github.com/artt) in [https://github.com/shikijs/shiki/issues/909](https://redirect.github.com/shikijs/shiki/issues/909) [<samp>(57a09)</samp>](https://redirect.github.com/shikijs/shiki/commit/57a09ade)

#####     [View changes on GitHub](https://redirect.github.com/shikijs/shiki/compare/v2.5.0...v3.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-03-01 02:33:49 +00:00
renovate
0f66f9dff1 chore: bump up fast-xml-parser version to v5 (#10531)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [fast-xml-parser](https://redirect.github.com/NaturalIntelligence/fast-xml-parser) | [`^4.5.0` -> `^5.0.0`](https://renovatebot.com/diffs/npm/fast-xml-parser/4.5.3/5.0.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/fast-xml-parser/5.0.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/fast-xml-parser/5.0.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/fast-xml-parser/4.5.3/5.0.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fast-xml-parser/4.5.3/5.0.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>NaturalIntelligence/fast-xml-parser (fast-xml-parser)</summary>

### [`v5.0.8`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.7...d167cb085d1fc3b9cfa40bded295135e9d91809d)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.7...v5.0.8)

### [`v5.0.7`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.6...v5.0.7)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.6...v5.0.7)

### [`v5.0.6`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.5...v5.0.6)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.5...v5.0.6)

### [`v5.0.5`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.4...v5.0.5)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.4...v5.0.5)

### [`v5.0.4`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.3...v5.0.4)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.3...v5.0.4)

### [`v5.0.3`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.2...v5.0.3)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.2...v5.0.3)

### [`v5.0.2`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.1...v5.0.2)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.1...v5.0.2)

### [`v5.0.1`](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.0...v5.0.1)

[Compare Source](https://redirect.github.com/NaturalIntelligence/fast-xml-parser/compare/v5.0.0...v5.0.1)

### [`v5.0.0`](ab00cdc49c...v5.0.0)

[Compare Source](ab00cdc49c...v5.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 15:58:06 +00:00
renovate
87ca6b1981 chore: bump up react-markdown version to v10 (#10532)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [react-markdown](https://redirect.github.com/remarkjs/react-markdown) | [`^9.0.3` -> `^10.0.0`](https://renovatebot.com/diffs/npm/react-markdown/9.1.0/10.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/react-markdown/10.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/react-markdown/10.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/react-markdown/9.1.0/10.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-markdown/9.1.0/10.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>remarkjs/react-markdown (react-markdown)</summary>

### [`v10.0.0`](https://redirect.github.com/remarkjs/react-markdown/blob/HEAD/changelog.md#1000---2025-02-20)

[Compare Source](https://redirect.github.com/remarkjs/react-markdown/compare/9.1.0...10.0.0)

-   [`aaaa40b`](https://redirect.github.com/remarkjs/react-markdown/commit/aaaa40b)
    Remove support for `className` prop
    **migrate**: see “Remove `className`” below

##### Remove `className`

The `className` prop was removed.
If you want to add classes to some element that wraps the markdown
you can explicitly write that element and add the class to it.
You can then choose yourself which tag name to use and whether to add other
props.

Before:

```js
<Markdown className="markdown-body">{markdown}</Markdown>
```

After:

```js
<div className="markdown-body">
  <Markdown>{markdown}</Markdown>
</div>
```

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 15:43:07 +00:00
renovate
815b437025 chore: bump up nestjs (#10212)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@nestjs-cls/transactional](https://papooch.github.io/nestjs-cls/) ([source](https://redirect.github.com/Papooch/nestjs-cls)) | [`2.4.12` -> `2.5.0`](https://renovatebot.com/diffs/npm/@nestjs-cls%2ftransactional/2.4.12/2.5.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs-cls%2ftransactional/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs-cls%2ftransactional/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs-cls%2ftransactional/2.4.12/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs-cls%2ftransactional/2.4.12/2.5.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |
| [@nestjs-cls/transactional-adapter-prisma](https://papooch.github.io/nestjs-cls/) ([source](https://redirect.github.com/Papooch/nestjs-cls)) | [`1.2.15` -> `1.2.16`](https://renovatebot.com/diffs/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.15/1.2.16) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.15/1.2.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@nestjs-cls%2ftransactional-adapter-prisma/1.2.15/1.2.16?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>Papooch/nestjs-cls (@&#8203;nestjs-cls/transactional)</summary>

### [`v2.5.0`](https://redirect.github.com/Papooch/nestjs-cls/releases/tag/%40nestjs-cls/transactional%402.5.0)

[Compare Source](https://redirect.github.com/Papooch/nestjs-cls/compare/@nestjs-cls/transactional@2.4.12...@nestjs-cls/transactional@2.5.0)

##### Features

-   **transactional**: adds supports propagation mode ([#&#8203;219](https://redirect.github.com/Papooch/nestjs-cls/issues/219)) ([95b1fdb](https://redirect.github.com/Papooch/nestjs-cls/commits/95b1fdb))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 15:28:10 +00:00
renovate
9ca8fc895a chore: bump up Rust crate thiserror to v2 (#10529)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [thiserror](https://redirect.github.com/dtolnay/thiserror) | dependencies | major | `1` -> `2` |

---

### Release Notes

<details>
<summary>dtolnay/thiserror (thiserror)</summary>

### [`v2.0.11`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.11)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.10...2.0.11)

-   Add feature gate to tests that use std ([#&#8203;409](https://redirect.github.com/dtolnay/thiserror/issues/409), [#&#8203;410](https://redirect.github.com/dtolnay/thiserror/issues/410), thanks [@&#8203;Maytha8](https://redirect.github.com/Maytha8))

### [`v2.0.10`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.10)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.9...2.0.10)

-   Support errors containing a generic type parameter's associated type in a field ([#&#8203;408](https://redirect.github.com/dtolnay/thiserror/issues/408))

### [`v2.0.9`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.9)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.8...2.0.9)

-   Work around `missing_inline_in_public_items` clippy restriction being triggered in macro-generated code ([#&#8203;404](https://redirect.github.com/dtolnay/thiserror/issues/404))

### [`v2.0.8`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.8)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.7...2.0.8)

-   Improve support for macro-generated `derive(Error)` call sites ([#&#8203;399](https://redirect.github.com/dtolnay/thiserror/issues/399))

### [`v2.0.7`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.7)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.6...2.0.7)

-   Work around conflict with #\[deny(clippy::allow_attributes)] ([#&#8203;397](https://redirect.github.com/dtolnay/thiserror/issues/397), thanks [@&#8203;zertosh](https://redirect.github.com/zertosh))

### [`v2.0.6`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.6)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.5...2.0.6)

-   Suppress deprecation warning on generated From impls ([#&#8203;396](https://redirect.github.com/dtolnay/thiserror/issues/396))

### [`v2.0.5`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.5)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.4...2.0.5)

-   Prevent deprecation warning on generated impl for deprecated type ([#&#8203;394](https://redirect.github.com/dtolnay/thiserror/issues/394))

### [`v2.0.4`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.4)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.3...2.0.4)

-   Eliminate needless_lifetimes clippy lint in generated `From` impls ([#&#8203;391](https://redirect.github.com/dtolnay/thiserror/issues/391), thanks [@&#8203;matt-phylum](https://redirect.github.com/matt-phylum))

### [`v2.0.3`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.3)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.2...2.0.3)

-   Support the same Path field being repeated in both Debug and Display representation in error message ([#&#8203;383](https://redirect.github.com/dtolnay/thiserror/issues/383))
-   Improve error message when a format trait used in error message is not implemented by some field ([#&#8203;384](https://redirect.github.com/dtolnay/thiserror/issues/384))

### [`v2.0.2`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.2)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.1...2.0.2)

-   Fix hang on invalid input inside #\[error(...)] attribute ([#&#8203;382](https://redirect.github.com/dtolnay/thiserror/issues/382))

### [`v2.0.1`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.1)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/2.0.0...2.0.1)

-   Support errors that contain a dynamically sized final field ([#&#8203;375](https://redirect.github.com/dtolnay/thiserror/issues/375))
-   Improve inference of trait bounds for fields that are interpolated multiple times in an error message ([#&#8203;377](https://redirect.github.com/dtolnay/thiserror/issues/377))

### [`v2.0.0`](https://redirect.github.com/dtolnay/thiserror/releases/tag/2.0.0)

[Compare Source](https://redirect.github.com/dtolnay/thiserror/compare/1.0.69...2.0.0)

#### Breaking changes

-   Referencing keyword-named fields by a raw identifier like `{r#type}` inside a format string is no longer accepted; simply use the unraw name like `{type}` ([#&#8203;347](https://redirect.github.com/dtolnay/thiserror/issues/347))

    This aligns thiserror with the standard library's formatting macros, which gained support for implicit argument capture later than the release of this feature in thiserror 1.x.

    ```rust
    #[derive(Error, Debug)]
    #[error("... {type} ...")]  // Before: {r#type}
    pub struct Error {
        pub r#type: Type,
    }
    ```

-   Trait bounds are no longer inferred on fields whose value is shadowed by an explicit named argument in a format message ([#&#8203;345](https://redirect.github.com/dtolnay/thiserror/issues/345))

    ```rust
    // Before: impl<T: Octal> Display for Error<T>
    // After: impl<T> Display for Error<T>
    #[derive(Error, Debug)]
    #[error("{thing:o}", thing = "...")]
    pub struct Error<T> {
        thing: T,
    }
    ```

-   Tuple structs and tuple variants can no longer use numerical `{0}` `{1}` access at the same time as supplying extra positional arguments for a format message, as this makes it ambiguous whether the number refers to a tuple field vs a different positional arg ([#&#8203;354](https://redirect.github.com/dtolnay/thiserror/issues/354))

    ```rust
    #[derive(Error, Debug)]
    #[error("ambiguous: {0} {}", $N)]
    //                  ^^^ Not allowed, use #[error("... {0} {n}", n = $N)]
    pub struct TupleError(i32);
    ```

-   Code containing invocations of thiserror's `derive(Error)` must now have a direct dependency on the `thiserror` crate regardless of the error data structure's contents ([#&#8203;368](https://redirect.github.com/dtolnay/thiserror/issues/368), [#&#8203;369](https://redirect.github.com/dtolnay/thiserror/issues/369), [#&#8203;370](https://redirect.github.com/dtolnay/thiserror/issues/370), [#&#8203;372](https://redirect.github.com/dtolnay/thiserror/issues/372))

#### Features

-   Support disabling thiserror's standard library dependency by disabling the default "std" Cargo feature: `thiserror = { version = "2", default-features = false }` ([#&#8203;373](https://redirect.github.com/dtolnay/thiserror/issues/373))

-   Support using `r#source` as field name to opt out of a field named "source" being treated as an error's `Error::source()` ([#&#8203;350](https://redirect.github.com/dtolnay/thiserror/issues/350))

    ```rust
    #[derive(Error, Debug)]
    #[error("{source} ==> {destination}")]
    pub struct Error {
        r#source: char,
        destination: char,
    }

    let error = Error { source: 'S', destination: 'D' };
    ```

-   Infinite recursion in a generated Display impl now produces an `unconditional_recursion` warning ([#&#8203;359](https://redirect.github.com/dtolnay/thiserror/issues/359))

    ```rust
    #[derive(Error, Debug)]
    #[error("??? {self}")]
    pub struct Error;
    ```

-   A new attribute `#[error(fmt = path::to::myfmt)]` can be used to write formatting logic for an enum variant out-of-line ([#&#8203;367](https://redirect.github.com/dtolnay/thiserror/issues/367))

    ```rust
    #[derive(Error, Debug)]
    pub enum Error {
        #[error(fmt = demo_fmt)]
        Demo { code: u16, message: Option<String> },
    }

    fn demo_fmt(code: &u16, message: &Option<String>, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{code}")?;
        if let Some(msg) = message {
            write!(formatter, " - {msg}")?;
        }
        Ok(())
    }
    ```

-   Enums with an enum-level format message are now able to have individual variants that are `transparent` to supersede the enum-level message ([#&#8203;366](https://redirect.github.com/dtolnay/thiserror/issues/366))

    ```rust
    #[derive(Error, Debug)]
    #[error("my error {0}")]
    pub enum Error {
        Json(#[from] serde_json::Error),
        Yaml(#[from] serde_yaml::Error),
        #[error(transparent)]
        Other(#[from] anyhow::Error),
    }
    ```

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 15:13:05 +00:00
renovate
54bf4b05f4 chore: bump up copy-webpack-plugin version to v13 (#10530)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [copy-webpack-plugin](https://redirect.github.com/webpack-contrib/copy-webpack-plugin) | [`^12.0.2` -> `^13.0.0`](https://renovatebot.com/diffs/npm/copy-webpack-plugin/12.0.2/13.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/copy-webpack-plugin/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/copy-webpack-plugin/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/copy-webpack-plugin/12.0.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/copy-webpack-plugin/12.0.2/13.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>webpack-contrib/copy-webpack-plugin (copy-webpack-plugin)</summary>

### [`v13.0.0`](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/blob/HEAD/CHANGELOG.md#1300-2025-02-27)

[Compare Source](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/compare/v12.0.2...v13.0.0)

##### ⚠ BREAKING CHANGES

-   switch from `globby` and `fast-glob` to `tinyglobby` ([#&#8203;795](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/issues/795)) ([19fd937](19fd937705))

For more information please visit [`tinyglobby`](https://redirect.github.com/SuperchupuDev/tinyglobby).

The breaking change only affects the developer who used these options - [`gitignore`](https://redirect.github.com/sindresorhus/globby#gitignore) and [`ignoreFiles`](https://redirect.github.com/sindresorhus/globby#gitignore) in the `globOptions` option.

Please migrate to the [`ignore`](https://redirect.github.com/SuperchupuDev/tinyglobby#options) option.

##### Bug Fixes

-   concurrency option is limited to files now ([#&#8203;796](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/issues/796)) ([d42469c](d42469cfdc))
-   the order of patterns provided by the developer is respected

##### [12.0.2](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/compare/v12.0.1...v12.0.2) (2024-01-17)

##### Bug Fixes

-   improve perf ([#&#8203;764](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/issues/764)) ([a7379a9](a7379a9907))

##### [12.0.1](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/compare/v12.0.0...v12.0.1) (2024-01-11)

##### Bug Fixes

-   improve perf ([#&#8203;760](https://redirect.github.com/webpack-contrib/copy-webpack-plugin/issues/760)) ([55036ab](55036ab503))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 14:48:52 +00:00
renovate
4012732058 chore: bump up Rust crate criterion2 to v3 (#10527)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [criterion2](https://bheisler.github.io/criterion.rs/book/index.html) ([source](https://redirect.github.com/Boshen/criterion2.rs)) | workspace.dependencies | major | `2` -> `3` |

---

### Release Notes

<details>
<summary>Boshen/criterion2.rs (criterion2)</summary>

### [`v3.0.0`](https://redirect.github.com/Boshen/criterion2.rs/releases/tag/v3.0.0)

[Compare Source](https://redirect.github.com/Boshen/criterion2.rs/compare/v2.0.0...v3.0.0)

##### Other

-   Make filters to look for a substring unless exact is given ([#&#8203;65](https://redirect.github.com/Boshen/criterion2.rs/pull/65))
-   *(deps)* update rust crates ([#&#8203;64](https://redirect.github.com/Boshen/criterion2.rs/pull/64))
-   *(deps)* update rust crate serde_json to 1.0.132 ([#&#8203;63](https://redirect.github.com/Boshen/criterion2.rs/pull/63))
-   *(deps)* update dependency rust to v1.82.0 ([#&#8203;62](https://redirect.github.com/Boshen/criterion2.rs/pull/62))
-   *(deps)* update rust crate bpaf to 0.9.15 ([#&#8203;61](https://redirect.github.com/Boshen/criterion2.rs/pull/61))
-   *(deps)* update rust crate futures to 0.3.31 ([#&#8203;60](https://redirect.github.com/Boshen/criterion2.rs/pull/60))
-   *(deps)* update rust crate tempfile to 3.13.0 ([#&#8203;59](https://redirect.github.com/Boshen/criterion2.rs/pull/59))
-   *(deps)* update rust crates ([#&#8203;57](https://redirect.github.com/Boshen/criterion2.rs/pull/57))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 14:31:57 +00:00
renovate
5c16b803b7 chore: bump up @sentry/react version to v9 (#10064)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@sentry/react](https://redirect.github.com/getsentry/sentry-javascript/tree/master/packages/react) ([source](https://redirect.github.com/getsentry/sentry-javascript)) | [`^8.44.0` -> `^9.0.0`](https://renovatebot.com/diffs/npm/@sentry%2freact/8.54.0/9.0.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sentry%2freact/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sentry%2freact/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sentry%2freact/8.54.0/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sentry%2freact/8.54.0/9.0.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>getsentry/sentry-javascript (@&#8203;sentry/react)</summary>

### [`v9.0.1`](https://redirect.github.com/getsentry/sentry-javascript/releases/tag/9.0.1)

[Compare Source](https://redirect.github.com/getsentry/sentry-javascript/compare/9.0.0...9.0.1)

-   ref(flags): rename unleash integration param ([#&#8203;15343](https://redirect.github.com/getsentry/sentry-javascript/pull/15343))

##### Bundle size 📦

| Path                                                             | Size              |
| ---------------------------------------------------------------- | ----------------- |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser)                                                  | 22.9 KB   |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) - with treeshaking flags                         | 22.69 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Tracing)                                  | 35.77 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Tracing, Replay)                          | 72.65 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Tracing, Replay) - with treeshaking flags | 66.13 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Tracing, Replay with Canvas)              | 76.9 KB   |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Tracing, Replay, Feedback)                | 89.64 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. Feedback)                                 | 39.86 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. sendFeedback)                             | 27.53 KB  |
| [@&#8203;sentry/browser](https://redirect.github.com/sentry/browser) (incl. FeedbackAsync)                            | 32.31 KB  |
| [@&#8203;sentry/react](https://redirect.github.com/sentry/react)                                                    | 24.74 KB  |
| [@&#8203;sentry/react](https://redirect.github.com/sentry/react) (incl. Tracing)                                    | 37.67 KB  |
| [@&#8203;sentry/vue](https://redirect.github.com/sentry/vue)                                                      | 27.09 KB  |
| [@&#8203;sentry/vue](https://redirect.github.com/sentry/vue) (incl. Tracing)                                      | 37.47 KB  |
| [@&#8203;sentry/svelte](https://redirect.github.com/sentry/svelte)                                                   | 22.94 KB  |
| CDN Bundle                                                       | 24.13 KB  |
| CDN Bundle (incl. Tracing)                                       | 35.84 KB  |
| CDN Bundle (incl. Tracing, Replay)                               | 70.55 KB  |
| CDN Bundle (incl. Tracing, Replay, Feedback)                     | 75.69 KB  |
| CDN Bundle - uncompressed                                        | 70.59 KB  |
| CDN Bundle (incl. Tracing) - uncompressed                        | 106.46 KB |
| CDN Bundle (incl. Tracing, Replay) - uncompressed                | 217.52 KB |
| CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed      | 230.09 KB |
| [@&#8203;sentry/nextjs](https://redirect.github.com/sentry/nextjs) (client)                                          | 38.63 KB  |
| [@&#8203;sentry/sveltekit](https://redirect.github.com/sentry/sveltekit) (client)                                       | 36.2 KB   |
| [@&#8203;sentry/node](https://redirect.github.com/sentry/node)                                                     | 156.33 KB |
| [@&#8203;sentry/node](https://redirect.github.com/sentry/node) - without tracing                                   | 97.31 KB  |
| [@&#8203;sentry/aws-serverless](https://redirect.github.com/sentry/aws-serverless)                                           | 106.82 KB |

### [`v9.0.0`](https://redirect.github.com/getsentry/sentry-javascript/blob/HEAD/CHANGELOG.md#900)

[Compare Source](https://redirect.github.com/getsentry/sentry-javascript/compare/8.54.0...9.0.0)

Version `9.0.0` marks a release of the Sentry JavaScript SDKs that contains breaking changes.
The goal of this release is to trim down on unused and potentially confusing APIs, prepare the SDKs for future framework versions to build deeper instrumentation, and remove old polyfills to reduce the packages' size.

##### How To Upgrade

Please carefully read through the migration guide in the Sentry docs on how to upgrade from version 8 to version 9.
Make sure to select your specific platform/framework in the top left corner: https://docs.sentry.io/platforms/javascript/migration/v8-to-v9/

A comprehensive migration guide outlining all changes for all the frameworks can be found within the Sentry JavaScript SDK Repository: https://github.com/getsentry/sentry-javascript/blob/develop/MIGRATION.md

##### Breaking Changes

-   doc(deno)!: Make Deno v2 the minimum supported version ([#&#8203;15085](https://redirect.github.com/getsentry/sentry-javascript/issues/15085))
-   feat!: Bump typescript to `~5.0.0` ([#&#8203;14758](https://redirect.github.com/getsentry/sentry-javascript/issues/14758))
-   feat!: Drop `nitro-utils` package ([#&#8203;14998](https://redirect.github.com/getsentry/sentry-javascript/issues/14998))
-   feat!: Only collect ip addresses with `sendDefaultPii: true` ([#&#8203;15084](https://redirect.github.com/getsentry/sentry-javascript/issues/15084))
-   feat!: Remove `autoSessionTracking` option ([#&#8203;14802](https://redirect.github.com/getsentry/sentry-javascript/issues/14802))
-   feat!: Remove `enableTracing` ([#&#8203;15078](https://redirect.github.com/getsentry/sentry-javascript/issues/15078))
-   feat!: Remove `getCurrentHub()`, `Hub`, and `getCurrentHubShim()` ([#&#8203;15122](https://redirect.github.com/getsentry/sentry-javascript/issues/15122))
-   feat!: Remove `spanId` from propagation context ([#&#8203;14733](https://redirect.github.com/getsentry/sentry-javascript/issues/14733))
-   feat!: Remove deprecated and unused code ([#&#8203;15077](https://redirect.github.com/getsentry/sentry-javascript/issues/15077))
-   feat!: Remove metrics API from the JS SDK ([#&#8203;14745](https://redirect.github.com/getsentry/sentry-javascript/issues/14745))
-   feat!: Require Node `>=18` as minimum supported version ([#&#8203;14749](https://redirect.github.com/getsentry/sentry-javascript/issues/14749))
-   feat(astro)!: Respect user-specified source map setting ([#&#8203;14941](https://redirect.github.com/getsentry/sentry-javascript/issues/14941))
-   feat(browser)!: Remove `captureUserFeedback` method ([#&#8203;14820](https://redirect.github.com/getsentry/sentry-javascript/issues/14820))
-   feat(build)!: Drop pre-ES2020 polyfills ([#&#8203;14882](https://redirect.github.com/getsentry/sentry-javascript/issues/14882))
-   feat(core)!: Add `normalizedRequest` to `samplingContext` ([#&#8203;14902](https://redirect.github.com/getsentry/sentry-javascript/issues/14902))
-   feat(core)!: Always use session from isolation scope ([#&#8203;14860](https://redirect.github.com/getsentry/sentry-javascript/issues/14860))
-   feat(core)!: Pass root spans to `beforeSendSpan` and disallow returning `null` ([#&#8203;14831](https://redirect.github.com/getsentry/sentry-javascript/issues/14831))
-   feat(core)!: Remove `BAGGAGE_HEADER_NAME` export ([#&#8203;14785](https://redirect.github.com/getsentry/sentry-javascript/issues/14785))
-   feat(core)!: Remove `TransactionNamingScheme` type ([#&#8203;14865](https://redirect.github.com/getsentry/sentry-javascript/issues/14865))
-   feat(core)!: Remove `addOpenTelemetryInstrumentation` method ([#&#8203;14792](https://redirect.github.com/getsentry/sentry-javascript/issues/14792))
-   feat(core)!: Remove `arrayify` method ([#&#8203;14782](https://redirect.github.com/getsentry/sentry-javascript/issues/14782))
-   feat(core)!: Remove `debugIntegration` and `sessionTimingIntegration` ([#&#8203;14747](https://redirect.github.com/getsentry/sentry-javascript/issues/14747))
-   feat(core)!: Remove `flatten` method ([#&#8203;14784](https://redirect.github.com/getsentry/sentry-javascript/issues/14784))
-   feat(core)!: Remove `getDomElement` method ([#&#8203;14797](https://redirect.github.com/getsentry/sentry-javascript/issues/14797))
-   feat(core)!: Remove `makeFifoCache` method ([#&#8203;14786](https://redirect.github.com/getsentry/sentry-javascript/issues/14786))
-   feat(core)!: Remove `memoBuilder` export & `WeakSet` fallback ([#&#8203;14859](https://redirect.github.com/getsentry/sentry-javascript/issues/14859))
-   feat(core)!: Remove `transactionContext` from `samplingContext` ([#&#8203;14904](https://redirect.github.com/getsentry/sentry-javascript/issues/14904))
-   feat(core)!: Remove `urlEncode` method ([#&#8203;14783](https://redirect.github.com/getsentry/sentry-javascript/issues/14783))
-   feat(core)!: Remove deprecated `Request` type ([#&#8203;14858](https://redirect.github.com/getsentry/sentry-javascript/issues/14858))
-   feat(core)!: Remove deprecated request data methods ([#&#8203;14896](https://redirect.github.com/getsentry/sentry-javascript/issues/14896))
-   feat(core)!: Remove standalone `Client` interface & deprecate `BaseClient` ([#&#8203;14800](https://redirect.github.com/getsentry/sentry-javascript/issues/14800))
-   feat(core)!: Remove validSeverityLevels export ([#&#8203;14765](https://redirect.github.com/getsentry/sentry-javascript/issues/14765))
-   feat(core)!: Stop accepting `event` as argument for `recordDroppedEvent` ([#&#8203;14999](https://redirect.github.com/getsentry/sentry-javascript/issues/14999))
-   feat(core)!: Stop setting user in `requestDataIntegration` ([#&#8203;14898](https://redirect.github.com/getsentry/sentry-javascript/issues/14898))
-   feat(core)!: Type sdkProcessingMetadata more strictly ([#&#8203;14855](https://redirect.github.com/getsentry/sentry-javascript/issues/14855))
-   feat(core)!: Update `hasTracingEnabled` to consider empty trace config ([#&#8203;14857](https://redirect.github.com/getsentry/sentry-javascript/issues/14857))
-   feat(core)!: Update `requestDataIntegration` handling ([#&#8203;14806](https://redirect.github.com/getsentry/sentry-javascript/issues/14806))
-   feat(deno)!: Remove deno prepack ([#&#8203;14829](https://redirect.github.com/getsentry/sentry-javascript/issues/14829))
-   feat(ember)!: Officially drop support for ember `<=3.x` ([#&#8203;15032](https://redirect.github.com/getsentry/sentry-javascript/issues/15032))
-   feat(nestjs)!: Move `nestIntegration` into nest sdk and remove `setupNestErrorHandler` ([#&#8203;14751](https://redirect.github.com/getsentry/sentry-javascript/issues/14751))
-   feat(nestjs)!: Remove `@WithSentry` decorator ([#&#8203;14762](https://redirect.github.com/getsentry/sentry-javascript/issues/14762))
-   feat(nestjs)!: Remove `SentryService` ([#&#8203;14759](https://redirect.github.com/getsentry/sentry-javascript/issues/14759))
-   feat(nextjs)!: Don't rely on Next.js Build ID for release names ([#&#8203;14939](https://redirect.github.com/getsentry/sentry-javascript/issues/14939))
-   feat(nextjs)!: Remove `experimental_captureRequestError` ([#&#8203;14607](https://redirect.github.com/getsentry/sentry-javascript/issues/14607))
-   feat(nextjs)!: Respect user-provided source map generation settings ([#&#8203;14956](https://redirect.github.com/getsentry/sentry-javascript/issues/14956))
-   feat(node)!: Add support for Prisma v6 and drop v5 support ([#&#8203;15120](https://redirect.github.com/getsentry/sentry-javascript/issues/15120))
-   feat(node)!: Avoid http spans by default for custom OTEL setups ([#&#8203;14678](https://redirect.github.com/getsentry/sentry-javascript/issues/14678))
-   feat(node)!: Collect request sessions via HTTP instrumentation ([#&#8203;14658](https://redirect.github.com/getsentry/sentry-javascript/issues/14658))
-   feat(node)!: Remove `processThreadBreadcrumbIntegration` ([#&#8203;14666](https://redirect.github.com/getsentry/sentry-javascript/issues/14666))
-   feat(node)!: Remove fine grained `registerEsmLoaderHooks` ([#&#8203;15002](https://redirect.github.com/getsentry/sentry-javascript/issues/15002))
-   feat(opentelemetry)!: Exclusively pass root spans through sampling pipeline ([#&#8203;14951](https://redirect.github.com/getsentry/sentry-javascript/issues/14951))
-   feat(pinia)!: Include state of all stores in breadcrumb ([#&#8203;15312](https://redirect.github.com/getsentry/sentry-javascript/issues/15312))
-   feat(react)!: Raise minimum supported TanStack Router version to `1.63.0` ([#&#8203;15030](https://redirect.github.com/getsentry/sentry-javascript/issues/15030))
-   feat(react)!: Remove deprecated `getNumberOfUrlSegments` method ([#&#8203;14744](https://redirect.github.com/getsentry/sentry-javascript/issues/14744))
-   feat(react)!: Remove deprecated react router methods ([#&#8203;14743](https://redirect.github.com/getsentry/sentry-javascript/issues/14743))
-   feat(react)!: Update `ErrorBoundary` `componentStack` type ([#&#8203;14742](https://redirect.github.com/getsentry/sentry-javascript/issues/14742))
-   feat(remix)!: Drop support for Remix v1 ([#&#8203;14988](https://redirect.github.com/getsentry/sentry-javascript/issues/14988))
-   feat(remix)!: Remove `autoInstrumentRemix` option ([#&#8203;15074](https://redirect.github.com/getsentry/sentry-javascript/issues/15074))
-   feat(solidstart)!: Default to `--import` setup and add `autoInjectServerSentry` ([#&#8203;14862](https://redirect.github.com/getsentry/sentry-javascript/issues/14862))
-   feat(solidstart)!: No longer export `sentrySolidStartVite` ([#&#8203;15143](https://redirect.github.com/getsentry/sentry-javascript/issues/15143))
-   feat(solidstart)!: Respect user-provided source map setting ([#&#8203;14979](https://redirect.github.com/getsentry/sentry-javascript/issues/14979))
-   feat(svelte)!: Disable component update tracking by default ([#&#8203;15265](https://redirect.github.com/getsentry/sentry-javascript/issues/15265))
-   feat(sveltekit)!: Drop support for SvelteKit [@&#8203;1](https://redirect.github.com/1).x ([#&#8203;15037](https://redirect.github.com/getsentry/sentry-javascript/issues/15037))
-   feat(sveltekit)!: Remove `fetchProxyScriptNonce` option ([#&#8203;15123](https://redirect.github.com/getsentry/sentry-javascript/issues/15123))
-   feat(sveltekit)!: Respect user-provided source map generation settings ([#&#8203;14886](https://redirect.github.com/getsentry/sentry-javascript/issues/14886))
-   feat(utils)!: Remove `@sentry/utils` package ([#&#8203;14830](https://redirect.github.com/getsentry/sentry-javascript/issues/14830))
-   feat(vue)!: Remove configuring Vue tracing options anywhere else other than through the `vueIntegration`'s `tracingOptions` option ([#&#8203;14856](https://redirect.github.com/getsentry/sentry-javascript/issues/14856))
-   feat(vue/nuxt)!: No longer create `"update"` spans for component tracking by default ([#&#8203;14602](https://redirect.github.com/getsentry/sentry-javascript/issues/14602))
-   fix(node)!: Fix name of `vercelAIIntegration` to `VercelAI` ([#&#8203;15298](https://redirect.github.com/getsentry/sentry-javascript/issues/15298))
-   fix(vue)!: Remove `logError` from `vueIntegration` ([#&#8203;14958](https://redirect.github.com/getsentry/sentry-javascript/issues/14958))
-   ref!: Don't polyfill optional chaining and nullish coalescing ([#&#8203;14603](https://redirect.github.com/getsentry/sentry-javascript/issues/14603))
-   ref(core)!: Cleanup internal types, including `ReportDialogOptions` ([#&#8203;14861](https://redirect.github.com/getsentry/sentry-javascript/issues/14861))
-   ref(core)!: Mark exceptions from `captureConsoleIntegration` as `handled: true` by default ([#&#8203;14734](https://redirect.github.com/getsentry/sentry-javascript/issues/14734))
-   ref(core)!: Move `shutdownTimeout` option type from core to node ([#&#8203;15217](https://redirect.github.com/getsentry/sentry-javascript/issues/15217))
-   ref(core)!: Remove `Scope` type interface in favor of using `Scope` class ([#&#8203;14721](https://redirect.github.com/getsentry/sentry-javascript/issues/14721))
-   ref(core)!: Remove backwards compatible SentryCarrier type ([#&#8203;14697](https://redirect.github.com/getsentry/sentry-javascript/issues/14697))

##### Other Changes

-   chore(browser): Export ipAddress helpers for use in other SDKs ([#&#8203;15079](https://redirect.github.com/getsentry/sentry-javascript/issues/15079))
-   deps(node): Bump `import-in-the-middle` to `1.12.0` ([#&#8203;14796](https://redirect.github.com/getsentry/sentry-javascript/issues/14796))
-   feat(aws): Rename AWS lambda layer name to `SentryNodeServerlessSDKv9` ([#&#8203;14927](https://redirect.github.com/getsentry/sentry-javascript/issues/14927))
-   feat(aws-serverless): Upgrade OTEL deps ([#&#8203;15091](https://redirect.github.com/getsentry/sentry-javascript/issues/15091))
-   feat(browser): Set `user.ip_address` explicitly to `{{auto}}` ([#&#8203;15008](https://redirect.github.com/getsentry/sentry-javascript/issues/15008))
-   feat(core): Add `inheritOrSampleWith` helper to `traceSampler` ([#&#8203;15277](https://redirect.github.com/getsentry/sentry-javascript/issues/15277))
-   feat(core): Emit client reports for unsampled root spans on span start ([#&#8203;14936](https://redirect.github.com/getsentry/sentry-javascript/issues/14936))
-   feat(core): Rename `hasTracingEnabled` to `hasSpansEnabled` ([#&#8203;15309](https://redirect.github.com/getsentry/sentry-javascript/issues/15309))
-   feat(core): Streamline `SpanJSON` type ([#&#8203;14693](https://redirect.github.com/getsentry/sentry-javascript/issues/14693))
-   feat(deno): Don't bundle `@sentry/deno` ([#&#8203;15014](https://redirect.github.com/getsentry/sentry-javascript/issues/15014))
-   feat(deno): Don't publish to `deno.land` ([#&#8203;15016](https://redirect.github.com/getsentry/sentry-javascript/issues/15016))
-   feat(deno): Stop inlining types from core ([#&#8203;14729](https://redirect.github.com/getsentry/sentry-javascript/issues/14729))
-   feat(deps): Bump [@&#8203;opentelemetry/instrumentation-amqplib](https://redirect.github.com/opentelemetry/instrumentation-amqplib) from 0.45.0 to 0.46.0 ([#&#8203;14835](https://redirect.github.com/getsentry/sentry-javascript/issues/14835))
-   feat(deps): Bump [@&#8203;opentelemetry/instrumentation-aws-lambda](https://redirect.github.com/opentelemetry/instrumentation-aws-lambda) from 0.49.0 to 0.50.0 ([#&#8203;14833](https://redirect.github.com/getsentry/sentry-javascript/issues/14833))
-   feat(deps): Bump [@&#8203;opentelemetry/instrumentation-express](https://redirect.github.com/opentelemetry/instrumentation-express) from 0.46.0 to 0.47.0 ([#&#8203;14834](https://redirect.github.com/getsentry/sentry-javascript/issues/14834))
-   feat(deps): Bump [@&#8203;opentelemetry/instrumentation-mysql2](https://redirect.github.com/opentelemetry/instrumentation-mysql2) from 0.44.0 to 0.45.0 ([#&#8203;14836](https://redirect.github.com/getsentry/sentry-javascript/issues/14836))
-   feat(deps): Bump [@&#8203;opentelemetry/propagation-utils](https://redirect.github.com/opentelemetry/propagation-utils) from 0.30.14 to 0.30.15 ([#&#8203;14832](https://redirect.github.com/getsentry/sentry-javascript/issues/14832))
-   feat(deps): bump [@&#8203;opentelemetry/context-async-hooks](https://redirect.github.com/opentelemetry/context-async-hooks) from 1.29.0 to 1.30.0 ([#&#8203;14869](https://redirect.github.com/getsentry/sentry-javascript/issues/14869))
-   feat(deps): bump [@&#8203;opentelemetry/instrumentation-generic-pool](https://redirect.github.com/opentelemetry/instrumentation-generic-pool) from 0.42.0 to 0.43.0 ([#&#8203;14870](https://redirect.github.com/getsentry/sentry-javascript/issues/14870))
-   feat(deps): bump [@&#8203;opentelemetry/instrumentation-knex](https://redirect.github.com/opentelemetry/instrumentation-knex) from 0.43.0 to 0.44.0 ([#&#8203;14872](https://redirect.github.com/getsentry/sentry-javascript/issues/14872))
-   feat(deps): bump [@&#8203;opentelemetry/instrumentation-mongodb](https://redirect.github.com/opentelemetry/instrumentation-mongodb) from 0.50.0 to 0.51.0 ([#&#8203;14871](https://redirect.github.com/getsentry/sentry-javascript/issues/14871))
-   feat(deps): bump [@&#8203;opentelemetry/instrumentation-tedious](https://redirect.github.com/opentelemetry/instrumentation-tedious) from 0.17.0 to 0.18.0 ([#&#8203;14868](https://redirect.github.com/getsentry/sentry-javascript/issues/14868))
-   feat(deps): bump [@&#8203;sentry/cli](https://redirect.github.com/sentry/cli) from 2.39.1 to 2.41.1 ([#&#8203;15173](https://redirect.github.com/getsentry/sentry-javascript/issues/15173))
-   feat(flags): Add Statsig browser integration ([#&#8203;15319](https://redirect.github.com/getsentry/sentry-javascript/issues/15319))
-   feat(gatsby): Preserve user-provided source map settings ([#&#8203;15006](https://redirect.github.com/getsentry/sentry-javascript/issues/15006))
-   feat(nestjs): Remove `SentryTracingInterceptor`, `SentryGlobalGraphQLFilter`, `SentryGlobalGenericFilter` ([#&#8203;14761](https://redirect.github.com/getsentry/sentry-javascript/issues/14761))
-   feat(nextjs): Directly forward `sourcemaps.disable` to webpack plugin ([#&#8203;15109](https://redirect.github.com/getsentry/sentry-javascript/issues/15109))
-   feat(node): Add `processSessionIntegration` ([#&#8203;15081](https://redirect.github.com/getsentry/sentry-javascript/issues/15081))
-   feat(node): Add missing `vercelAIIntegration` export ([#&#8203;15318](https://redirect.github.com/getsentry/sentry-javascript/issues/15318))
-   feat(node): Capture exceptions from `worker_threads` ([#&#8203;15105](https://redirect.github.com/getsentry/sentry-javascript/issues/15105))
-   feat(nuxt): Add enabled to disable Sentry module ([#&#8203;15337](https://redirect.github.com/getsentry/sentry-javascript/issues/15337))
-   feat(nuxt): add `silent`, `errorHandler`, `release` to `SourceMapsOptions` ([#&#8203;15246](https://redirect.github.com/getsentry/sentry-javascript/issues/15246))
-   feat(profiling-node): Use `@sentry-internal/node-cpu-profiler` ([#&#8203;15208](https://redirect.github.com/getsentry/sentry-javascript/issues/15208))
-   feat(replay): Update fflate to 0.8.2 ([#&#8203;14867](https://redirect.github.com/getsentry/sentry-javascript/issues/14867))
-   feat(solidstart): Add `autoInjectServerSentry: 'experimental_dynamic-import` ([#&#8203;14863](https://redirect.github.com/getsentry/sentry-javascript/issues/14863))
-   feat(sveltekit): Only inject fetch proxy script for SvelteKit < 2.16.0 ([#&#8203;15126](https://redirect.github.com/getsentry/sentry-javascript/issues/15126))
-   feat(user feedback): Adds draw tool for UF screenshot annotations ([#&#8203;15062](https://redirect.github.com/getsentry/sentry-javascript/issues/15062))
-   feat(user feedback): Adds toolbar for cropping and annotating ([#&#8203;15282](https://redirect.github.com/getsentry/sentry-javascript/issues/15282))
-   feat: Avoid class fields all-together ([#&#8203;14887](https://redirect.github.com/getsentry/sentry-javascript/issues/14887))
-   feat: Only emit `__esModule` properties in CJS modules when there is a default export ([#&#8203;15018](https://redirect.github.com/getsentry/sentry-javascript/issues/15018))
-   feat: Pass `parentSampleRate` to `tracesSampler` ([#&#8203;15024](https://redirect.github.com/getsentry/sentry-javascript/issues/15024))
-   feat: Propagate and use a sampling random ([#&#8203;14989](https://redirect.github.com/getsentry/sentry-javascript/issues/14989))
-   fix(browser): Remove `browserPerformanceTimeOrigin` side-effects ([#&#8203;14025](https://redirect.github.com/getsentry/sentry-javascript/issues/14025))
-   fix(core): Ensure debugIds are applied to all exceptions in an event ([#&#8203;14881](https://redirect.github.com/getsentry/sentry-javascript/issues/14881))
-   fix(core): Fork scope if custom scope is passed to `startSpanManual` ([#&#8203;14901](https://redirect.github.com/getsentry/sentry-javascript/issues/14901))
-   fix(core): Fork scope if custom scope is passed to `startSpan` ([#&#8203;14900](https://redirect.github.com/getsentry/sentry-javascript/issues/14900))
-   fix(core): Only fall back to `sendDefaultPii` for IP collection in `requestDataIntegration` ([#&#8203;15125](https://redirect.github.com/getsentry/sentry-javascript/issues/15125))
-   fix(nextjs): Flush with `waitUntil` in `captureRequestError` ([#&#8203;15146](https://redirect.github.com/getsentry/sentry-javascript/issues/15146))
-   fix(nextjs): Use batched devserver symbolication endpoint ([#&#8203;15335](https://redirect.github.com/getsentry/sentry-javascript/issues/15335))
-   fix(node): Don't leak `__span` property into breadcrumbs ([#&#8203;14798](https://redirect.github.com/getsentry/sentry-javascript/issues/14798))
-   fix(node): Ensure `httpIntegration` propagates traces ([#&#8203;15233](https://redirect.github.com/getsentry/sentry-javascript/issues/15233))
-   fix(node): Fix sample rand propagation for negative sampling decisions ([#&#8203;15045](https://redirect.github.com/getsentry/sentry-javascript/issues/15045))
-   fix(node): Missing `release` from ANR sessions ([#&#8203;15138](https://redirect.github.com/getsentry/sentry-javascript/issues/15138))
-   fix(node): Set the correct fallback URL fields for outgoing https requests if they are not defined ([#&#8203;15316](https://redirect.github.com/getsentry/sentry-javascript/issues/15316))
-   fix(nuxt): Detect Azure Function runtime for flushing with timeout ([#&#8203;15288](https://redirect.github.com/getsentry/sentry-javascript/issues/15288))
-   fix(react): From location can be undefined in Tanstack Router Instrumentation ([#&#8203;15235](https://redirect.github.com/getsentry/sentry-javascript/issues/15235))
-   fix(react): Import default for hoistNonReactStatics ([#&#8203;15238](https://redirect.github.com/getsentry/sentry-javascript/issues/15238))
-   fix(react): Support lazy-loaded routes and components. ([#&#8203;15039](https://redirect.github.com/getsentry/sentry-javascript/issues/15039))
-   fix(solidstart): Do not copy release-injection map file ([#&#8203;15302](https://redirect.github.com/getsentry/sentry-javascript/issues/15302))
-   ref(browser): Improve active span handling for `browserTracingIntegration` ([#&#8203;14959](https://redirect.github.com/getsentry/sentry-javascript/issues/14959))
-   ref(browser): Improve setting of propagation scope for navigation spans ([#&#8203;15108](https://redirect.github.com/getsentry/sentry-javascript/issues/15108))
-   ref(browser): Skip browser extension warning in non-debug builds ([#&#8203;15310](https://redirect.github.com/getsentry/sentry-javascript/issues/15310))
-   ref(browser): Update `supportsHistory` check & history usage ([#&#8203;14696](https://redirect.github.com/getsentry/sentry-javascript/issues/14696))
-   ref(core): Ensure non-recording root spans have frozen DSC ([#&#8203;14964](https://redirect.github.com/getsentry/sentry-javascript/issues/14964))
-   ref(core): Log debug message when capturing error events ([#&#8203;14701](https://redirect.github.com/getsentry/sentry-javascript/issues/14701))
-   ref(core): Move log message about invalid sample rate ([#&#8203;15215](https://redirect.github.com/getsentry/sentry-javascript/issues/15215))
-   ref(node): Streamline check for adding performance integrations ([#&#8203;15021](https://redirect.github.com/getsentry/sentry-javascript/issues/15021))
-   ref(react): Adapt tanstack router type ([#&#8203;15241](https://redirect.github.com/getsentry/sentry-javascript/issues/15241))
-   ref(svelte): Remove SvelteKit detection ([#&#8203;15313](https://redirect.github.com/getsentry/sentry-javascript/issues/15313))
-   ref(sveltekit): Clean up sub-request check ([#&#8203;15251](https://redirect.github.com/getsentry/sentry-javascript/issues/15251))

Work in this release was contributed by [@&#8203;aloisklink](https://redirect.github.com/aloisklink), [@&#8203;arturovt](https://redirect.github.com/arturovt), [@&#8203;aryanvdesh](https://redirect.github.com/aryanvdesh), [@&#8203;benjick](https://redirect.github.com/benjick), [@&#8203;chris-basebone](https://redirect.github.com/chris-basebone), [@&#8203;davidturissini](https://redirect.github.com/davidturissini), [@&#8203;GrizliK1988](https://redirect.github.com/GrizliK1988), [@&#8203;jahands](https://redirect.github.com/jahands), [@&#8203;jrandolf](https://redirect.github.com/jrandolf), [@&#8203;kunal-511](https://redirect.github.com/kunal-511), [@&#8203;maximepvrt](https://redirect.github.com/maximepvrt), [@&#8203;maxmaxme](https://redirect.github.com/maxmaxme), [@&#8203;mstrokin](https://redirect.github.com/mstrokin), [@&#8203;nathankleyn](https://redirect.github.com/nathankleyn), [@&#8203;nwalters512](https://redirect.github.com/nwalters512), [@&#8203;tannerlinsley](https://redirect.github.com/tannerlinsley), [@&#8203;tjhiggins](https://redirect.github.com/tjhiggins), and [@&#8203;Zen-cronic](https://redirect.github.com/Zen-cronic). Thank you for your contributions!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjQuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE2NC4xIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 14:09:36 +00:00
renovate
91e00f08d0 chore: bump up rustc version to v1.85.0 (#10515)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rustc](https://redirect.github.com/rust-lang/rust) | minor | `1.84.1` -> `1.85.0` |

---

### Release Notes

<details>
<summary>rust-lang/rust (rustc)</summary>

### [`v1.85.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1850-2025-02-20)

[Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.84.1...1.85.0)

\==========================

<a id="1.85.0-Language"></a>

## Language

-   [The 2024 Edition is now stable.](https://redirect.github.com/rust-lang/rust/pull/133349)
    See [the edition guide](https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html) for more details.
-   [Stabilize async closures](https://redirect.github.com/rust-lang/rust/pull/132706)
    See [RFC 3668](https://rust-lang.github.io/rfcs/3668-async-closures.html) for more details.
-   [Stabilize `#[diagnostic::do_not_recommend]`](https://redirect.github.com/rust-lang/rust/pull/132056)
-   [Add `unpredictable_function_pointer_comparisons` lint to warn against function pointer comparisons](https://redirect.github.com/rust-lang/rust/pull/118833)
-   [Lint on combining `#[no_mangle]` and `#[export_name]` attributes.](https://redirect.github.com/rust-lang/rust/pull/131558)

<a id="1.85.0-Compiler"></a>

## Compiler

-   [The unstable flag `-Zpolymorphize` has been removed](https://redirect.github.com/rust-lang/rust/pull/133883), see [https://github.com/rust-lang/compiler-team/issues/810](https://redirect.github.com/rust-lang/compiler-team/issues/810) for some background.

<a id="1.85.0-Platform-Support"></a>

## Platform Support

-   [Promote `powerpc64le-unknown-linux-musl` to tier 2 with host tools](https://redirect.github.com/rust-lang/rust/pull/133801)

Refer to Rust's \[platform support page]\[platform-support-doc]
for more information on Rust's tiered platform support.

<a id="1.85.0-Libraries"></a>

## Libraries

-   [Panics in the standard library now have a leading `library/` in their path](https://redirect.github.com/rust-lang/rust/pull/132390)
-   [`std::env::home_dir()` on Windows now ignores the non-standard `$HOME` environment variable](https://redirect.github.com/rust-lang/rust/pull/132515)

    It will be un-deprecated in a subsequent release.
-   [Add `AsyncFn*` to the prelude in all editions.](https://redirect.github.com/rust-lang/rust/pull/132611)

<a id="1.85.0-Stabilized-APIs"></a>

## Stabilized APIs

-   [`BuildHasherDefault::new`](https://doc.rust-lang.org/stable/std/hash/struct.BuildHasherDefault.html#method.new)
-   [`ptr::fn_addr_eq`](https://doc.rust-lang.org/std/ptr/fn.fn_addr_eq.html)
-   [`io::ErrorKind::QuotaExceeded`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.QuotaExceeded)
-   [`io::ErrorKind::CrossesDevices`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.CrossesDevices)
-   [`{float}::midpoint`](https://doc.rust-lang.org/core/primitive.f32.html#method.midpoint)
-   [Unsigned `{integer}::midpoint`](https://doc.rust-lang.org/std/primitive.u64.html#method.midpoint)
-   [`NonZeroU*::midpoint`](https://doc.rust-lang.org/std/num/type.NonZeroU32.html#method.midpoint)
-   [impl `std::iter::Extend` for tuples with arity 1 through 12](https://doc.rust-lang.org/stable/std/iter/trait.Extend.html#impl-Extend%3C\(A,\)%3E-for-\(EA,\))
-   [`FromIterator<(A, ...)>` for tuples with arity 1 through 12](https://doc.rust-lang.org/stable/std/iter/trait.FromIterator.html#impl-FromIterator%3C\(EA,\)%3E-for-\(A,\))
-   [`std::task::Waker::noop`](https://doc.rust-lang.org/stable/std/task/struct.Waker.html#method.noop)

These APIs are now stable in const contexts:

-   [`mem::size_of_val`](https://doc.rust-lang.org/stable/std/mem/fn.size_of_val.html)
-   [`mem::align_of_val`](https://doc.rust-lang.org/stable/std/mem/fn.align_of_val.html)
-   [`Layout::for_value`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.for_value)
-   [`Layout::align_to`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align_to)
-   [`Layout::pad_to_align`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.pad_to_align)
-   [`Layout::extend`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.extend)
-   [`Layout::array`](https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.array)
-   [`std::mem::swap`](https://doc.rust-lang.org/stable/std/mem/fn.swap.html)
-   [`std::ptr::swap`](https://doc.rust-lang.org/stable/std/ptr/fn.swap.html)
-   [`NonNull::new`](https://doc.rust-lang.org/stable/std/ptr/struct.NonNull.html#method.new)
-   [`HashMap::with_hasher`](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html#method.with_hasher)
-   [`HashSet::with_hasher`](https://doc.rust-lang.org/stable/std/collections/struct.HashSet.html#method.with_hasher)
-   [`BuildHasherDefault::new`](https://doc.rust-lang.org/stable/std/hash/struct.BuildHasherDefault.html#method.new)
-   [`<float>::recip`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.recip)
-   [`<float>::to_degrees`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.to_degrees)
-   [`<float>::to_radians`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.to_radians)
-   [`<float>::max`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.max)
-   [`<float>::min`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.min)
-   [`<float>::clamp`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.clamp)
-   [`<float>::abs`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.abs)
-   [`<float>::signum`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.signum)
-   [`<float>::copysign`](https://doc.rust-lang.org/stable/std/primitive.f32.html#method.copysign)
-   [`MaybeUninit::write`](https://doc.rust-lang.org/stable/std/mem/union.MaybeUninit.html#method.write)

<a id="1.85.0-Cargo"></a>

## Cargo

-   [Add future-incompatibility warning against keywords in cfgs and add raw-idents](https://redirect.github.com/rust-lang/cargo/pull/14671/)
-   [Stabilize higher precedence trailing flags](https://redirect.github.com/rust-lang/cargo/pull/14900/)
-   [Pass `CARGO_CFG_FEATURE` to build scripts](https://redirect.github.com/rust-lang/cargo/pull/14902/)

<a id="1.85.0-Rustdoc"></a>

## Rustdoc

-   [Doc comment on impl blocks shows the first line, even when the impl block is collapsed](https://redirect.github.com/rust-lang/rust/pull/132155)

<a id="1.85.0-Compatibility-Notes"></a>

## Compatibility Notes

-   [`rustc` no longer treats the `test` cfg as a well known check-cfg](https://redirect.github.com/rust-lang/rust/pull/131729), instead it is up to the build systems and users of `--check-cfg`\[^check-cfg] to set it as a well known cfg using `--check-cfg=cfg(test)`.

    This is done to enable build systems like Cargo to set it conditionally, as not all source files are suitable for unit tests.
    [Cargo (for now) unconditionally sets the `test` cfg as a well known cfg](https://redirect.github.com/rust-lang/cargo/pull/14963).
    \[^check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
-   [Disable potentially incorrect type inference if there are trivial and non-trivial where-clauses](https://redirect.github.com/rust-lang/rust/pull/132325)
-   `std::env::home_dir()` has been deprecated for years, because it can give surprising results in some Windows configurations if the `HOME` environment variable is set (which is not the normal configuration on Windows). We had previously avoided changing its behavior, out of concern for compatibility with code depending on this non-standard configuration. Given how long this function has been deprecated, we're now fixing its behavior as a bugfix. A subsequent release will remove the deprecation for this function.
-   [Make `core::ffi::c_char` signedness more closely match that of the platform-default `char`](https://redirect.github.com/rust-lang/rust/pull/132975)

    This changed `c_char` from an `i8` to `u8` or vice versa on many Tier 2 and 3
    targets (mostly Arm and RISC-V embedded targets). The new definition may
    result in compilation failures but fixes compatibility issues with C.

    The `libc` crate matches this change as of its 0.2.169 release.
-   [When compiling a nested `macro_rules` macro from an external crate, the content of the inner `macro_rules` is now built with the edition of the external crate, not the local crate.](https://redirect.github.com/rust-lang/rust/pull/133274)
-   [Increase `sparcv9-sun-solaris` and `x86_64-pc-solaris` Solaris baseline to 11.4.](https://redirect.github.com/rust-lang/rust/pull/133293)
-   [Show `abi_unsupported_vector_types` lint in future breakage reports](https://redirect.github.com/rust-lang/rust/pull/133374)
-   [Error if multiple super-trait instantiations of `dyn Trait` need associated types to be specified but only one is provided](https://redirect.github.com/rust-lang/rust/pull/133392)
-   [Change `powerpc64-ibm-aix` default `codemodel` to large](https://redirect.github.com/rust-lang/rust/pull/133811)

<a id="1.85.0-Internal-Changes"></a>

## Internal Changes

These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.

-   [Build `x86_64-unknown-linux-gnu` with LTO for C/C++ code (e.g., `jemalloc`)](https://redirect.github.com/rust-lang/rust/pull/134690)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 13:39:39 +00:00
pengx17
bab4a07c9f fix(native): expose tapped audio stats (#10524)
Need to encode the audio based on the sample's sample rate & channels.
Also fixed that global audio tap not receiving any samples at all.
2025-02-28 13:24:02 +00:00
L-Sun
61541a2d15 fix(editor): patch android backspace key binding with beforeInput (#10523)
Close [BS-1869](https://linear.app/affine-design/issue/BS-1869/[bug]-android-chrome-%E8%BE%93%E5%85%A5%E9%94%99%E8%AF%AF)

## Problem
On Android devices, keyboard events do not properly capture key information, causing the backspace key and other keyboard functionalities to malfunction. This is due to the specific behavior of Android platform, as discussed in:
- https://stackoverflow.com/a/68188679
- https://stackoverflow.com/a/66724830

## Solution
1. Added special handling for Android platform in `KeyboardControl` class by using `beforeInput` event instead of `keyDown` event
2. Implemented `androidBindKeymapPatch` function to handle special key events on Android platform
3. Updated event handling logic in related components, including:
   - CodeBlock
   - ListKeymap
   - ParagraphKeymap
   - PageKeyboardManager

## Changes
- Added `androidBindKeymapPatch` function for handling key events on Android platform
- Modified `KeyboardControl.bindHotkey` method to add `beforeInput` event handling for Android
- Unified event object access using `ctx.get('defaultState').event` instead of `keyboardState.raw`
- Updated key event handling logic in multiple components

## Before

https://github.com/user-attachments/assets/e8602de4-d584-4adf-816f-369f38312022

## After

https://github.com/user-attachments/assets/f9e1680e-28ff-4d52-bdab-7683cdcb6f82
2025-02-28 13:03:00 +00:00
fengmk2
b59f60c60b feat(server): add workspace avatar support in doc reader (#10390) 2025-02-28 12:41:26 +00:00
akumatus
008fdfc234 feat(core): disable ai if value of sever copilot config is false (#10520)
Fix issue [AF-2224](https://linear.app/affine-design/issue/AF-2224).
2025-02-28 12:24:58 +00:00
zzj3720
5c5c9f8dcd fix(editor): insertion position of new rows and columns is incorrect in table block (#10516)
fix: BS-2714
2025-02-28 12:06:28 +00:00
doodlewind
12acf7e4a0 fix(editor): range IndexSizeError on firefox (#10519)
This is a Firefox compat issue, I've manually confirmed this implementation works in latest Firefox build.
2025-02-28 11:50:56 +00:00
renovate
82dffcbf67 chore: bump up @blocksuite/icons version to v2.2.4 (#10517)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@blocksuite/icons](https://redirect.github.com/toeverything/icons) | [`2.2.3` -> `2.2.4`](https://renovatebot.com/diffs/npm/@blocksuite%2ficons/2.2.3/2.2.4) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@blocksuite%2ficons/2.2.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@blocksuite%2ficons/2.2.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@blocksuite%2ficons/2.2.3/2.2.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@blocksuite%2ficons/2.2.3/2.2.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>toeverything/icons (@&#8203;blocksuite/icons)</summary>

### [`v2.2.4`](fa7773d6f0...4686040920)

[Compare Source](fa7773d6f0...4686040920)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 11:37:06 +00:00
renovate
04b1239a25 chore: bump up @googleapis/androidpublisher version to v24 (#10518)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [@googleapis/androidpublisher](https://redirect.github.com/googleapis/google-api-nodejs-client) | [`^22.0.0` -> `^24.0.0`](https://renovatebot.com/diffs/npm/@googleapis%2fandroidpublisher/22.0.0/24.0.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@googleapis%2fandroidpublisher/24.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@googleapis%2fandroidpublisher/24.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@googleapis%2fandroidpublisher/22.0.0/24.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@googleapis%2fandroidpublisher/22.0.0/24.0.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>googleapis/google-api-nodejs-client (@&#8203;googleapis/androidpublisher)</summary>

### [`v24.0.0`](https://redirect.github.com/googleapis/google-api-nodejs-client/blob/HEAD/CHANGELOG.md#12400-2023-08-09)

##### ⚠ BREAKING CHANGES

-   **youtube:** This release has breaking changes.
-   **workloadmanager:** This release has breaking changes.
-   **smartdevicemanagement:** This release has breaking changes.
-   **serviceusage:** This release has breaking changes.
-   **servicedirectory:** This release has breaking changes.
-   **retail:** This release has breaking changes.
-   **networkconnectivity:** This release has breaking changes.
-   **monitoring:** This release has breaking changes.
-   **gkeonprem:** This release has breaking changes.
-   **gkehub:** This release has breaking changes.
-   **contentwarehouse:** This release has breaking changes.
-   **contactcenteraiplatform:** This release has breaking changes.
-   **compute:** This release has breaking changes.
-   **checks:** This release has breaking changes.
-   **bigtableadmin:** This release has breaking changes.
-   **bigquery:** This release has breaking changes.
-   **assuredworkloads:** This release has breaking changes.
-   **androidmanagement:** This release has breaking changes.
-   **analyticsadmin:** This release has breaking changes.
-   migate to Node 14

##### Features

-   **admin:** update the API ([1bc7f53](1bc7f53857))
-   **analyticsadmin:** update the API ([8f479e1](8f479e1550))
-   **analyticshub:** update the API ([427f865](427f8657bc))
-   **androidmanagement:** update the API ([d885722](d885722fa7))
-   **artifactregistry:** update the API ([d70a33e](d70a33e42e))
-   **assuredworkloads:** update the API ([321cff7](321cff70dc))
-   **beyondcorp:** update the API ([ad95808](ad95808585))
-   **bigquerydatatransfer:** update the API ([b290e4a](b290e4a24d))
-   **bigquery:** update the API ([3a1ca66](3a1ca661f4))
-   **bigtableadmin:** update the API ([4f1fb0c](4f1fb0cac0))
-   **chat:** update the API ([c594a3b](c594a3b012))
-   **checks:** update the API ([b9c4657](b9c46572eb))
-   **cloudbuild:** update the API ([1d791a8](1d791a8bc5))
-   **clouddeploy:** update the API ([c733347](c7333472fd))
-   **cloudfunctions:** update the API ([0255d75](0255d75e4b))
-   **compute:** update the API ([0237e76](0237e76d5b))
-   **connectors:** update the API ([cc40ccb](cc40ccbdeb))
-   **contactcenteraiplatform:** update the API ([6778c8d](6778c8ddfa))
-   **containeranalysis:** update the API ([a74b5e3](a74b5e3e99))
-   **container:** update the API ([1f06a76](1f06a76ec8))
-   **content:** update the API ([b5af676](b5af676bbb))
-   **contentwarehouse:** update the API ([ac9b754](ac9b7543ce))
-   **datacatalog:** update the API ([747a4af](747a4af6ff))
-   **dataflow:** update the API ([a62940f](a62940fdc1))
-   **dataform:** update the API ([d1a0a72](d1a0a72df8))
-   **datamigration:** update the API ([5037d65](5037d6562b))
-   **dataplex:** update the API ([ef7bc25](ef7bc250fb))
-   **dataproc:** update the API ([1c699db](1c699db9ce))
-   **datastore:** update the API ([80a30a0](80a30a04e2))
-   **datastream:** update the API ([2c1c784](2c1c784b89))
-   **dialogflow:** update the API ([bac62ef](bac62ef9ff))
-   **discoveryengine:** update the API ([d8debb8](d8debb8863))
-   **discovery:** update the API ([c82eebd](c82eebd5f1))
-   **displayvideo:** update the API ([bbc4d65](bbc4d65427))
-   **documentai:** update the API ([8ac40a0](8ac40a004e))
-   **drivelabels:** update the API ([5ef5d03](5ef5d030b1))
-   **drive:** update the API ([2432651](243265177f))
-   **firebaseappcheck:** update the API ([7c4888c](7c4888c182))
-   **firebase:** update the API ([fdafcaa](fdafcaa969))
-   **firestore:** update the API ([7a14283](7a14283031))
-   **games:** update the API ([55fed7d](55fed7d4ec))
-   **gkebackup:** update the API ([8d1ac26](8d1ac26eb6))
-   **gkehub:** update the API ([81d36c9](81d36c9368))
-   **gkeonprem:** update the API ([7412e91](7412e91ccd))
-   **healthcare:** update the API ([1d0354c](1d0354c855))
-   **migrationcenter:** update the API ([f4cb381](f4cb38184d))
-   **monitoring:** update the API ([f5bf72c](f5bf72c5a7))
-   **networkconnectivity:** update the API ([23894c5](23894c5f96))
-   **networksecurity:** update the API ([d9f4f91](d9f4f9174f))
-   **notebooks:** update the API ([9498d86](9498d86aaf))
-   **ondemandscanning:** update the API ([0ec83f3](0ec83f316b))
-   **osconfig:** update the API ([e1ca8d0](e1ca8d031e))
-   **oslogin:** update the API ([cf32530](cf32530418))
-   **policysimulator:** update the API ([7c67951](7c6795150e))
-   **pubsub:** update the API ([27c5439](27c5439336))
-   regenerate index files ([7e6a0e5](7e6a0e582b))
-   **retail:** update the API ([4dcd52b](4dcd52b6a7))
-   **securitycenter:** update the API ([82cf038](82cf0380c5))
-   **serviceconsumermanagement:** update the API ([da52b7e](da52b7ef38))
-   **servicecontrol:** update the API ([d246968](d24696820f))
-   **servicedirectory:** update the API ([70389d9](70389d96ea))
-   **servicemanagement:** update the API ([6fdca08](6fdca087b3))
-   **servicenetworking:** update the API ([d4784d0](d4784d07dd))
-   **serviceusage:** update the API ([cf72cfd](cf72cfd02b))
-   **smartdevicemanagement:** update the API ([cc5c86e](cc5c86e758))
-   **sqladmin:** update the API ([0c9f7b6](0c9f7b666d))
-   **tagmanager:** update the API ([42c3b97](42c3b97d78))
-   **toolresults:** update the API ([d07c878](d07c8782d3))
-   **tpu:** update the API ([6109722](61097227dc))
-   **trafficdirector:** update the API ([d07ac95](d07ac95641))
-   **vault:** update the API ([e1d2dc4](e1d2dc4ca3))
-   **verifiedaccess:** update the API ([d8e2234](d8e22343e2))
-   **videointelligence:** update the API ([158ae35](158ae35e73))
-   **vmmigration:** update the API ([3adbd55](3adbd5557e))
-   **workloadmanager:** update the API ([2f089aa](2f089aa056))
-   **youtube:** update the API ([83aac2f](83aac2f393))

##### Bug Fixes

-   **abusiveexperiencereport:** update the API ([51e5811](51e581179d))
-   **acceleratedmobilepageurl:** update the API ([a6a2a06](a6a2a06ff1))
-   **accessapproval:** update the API ([5194181](519418151e))
-   **accesscontextmanager:** update the API ([28aebba](28aebba030))
-   **acmedns:** update the API ([c6b1bcb](c6b1bcb8c3))
-   add headers to tests ([d88a219](d88a2193ee))
-   **adexchangebuyer2:** update the API ([436e422](436e422f45))
-   **adexchangebuyer:** update the API ([de73406](de73406cfe))
-   **adexperiencereport:** update the API ([3363255](3363255135))
-   **admob:** update the API ([d249550](d249550bd5))
-   **adsensehost:** update the API ([0a088ff](0a088ff891))
-   **adsense:** update the API ([e1f10f6](e1f10f6ecf))
-   **advisorynotifications:** update the API ([d8350ff](d8350ff286))
-   **aiplatform:** update the API ([7feb2e8](7feb2e8bf0))
-   **alertcenter:** update the API ([a073124](a07312469e))
-   **analyticsdata:** update the API ([43bedd1](43bedd114a))
-   **analyticsreporting:** update the API ([2d68b5a](2d68b5aa54))
-   **analytics:** update the API ([64c4b07](64c4b07238))
-   **androiddeviceprovisioning:** update the API ([ba02075](ba02075615))
-   **androidenterprise:** update the API ([93f7c0c](93f7c0c999))
-   **androidpublisher:** update the API ([8d35576](8d35576047))
-   **apigateway:** update the API ([fc58d33](fc58d331a6))
-   **apigeeregistry:** update the API ([b57542e](b57542e40b))
-   **apikeys:** update the API ([18e475b](18e475be06))
-   **appengine:** update the API ([67a3448](67a3448d66))
-   **appsactivity:** update the API ([f8ba6ee](f8ba6ee70c))
-   **area120tables:** update the API ([6ae8d8d](6ae8d8d8be))
-   **authorizedbuyersmarketplace:** update the API ([61d943b](61d943be06))
-   **baremetalsolution:** update the API ([269dae8](269dae821f))
-   **batch:** update the API ([7aa7cc7](7aa7cc702d))
-   **bigqueryconnection:** update the API ([bb288b1](bb288b1195))
-   **bigqueryreservation:** update the API ([4e77b1d](4e77b1d162))
-   **billingbudgets:** update the API ([0f799e6](0f799e65a5))
-   **binaryauthorization:** update the API ([deb6c10](deb6c10db6))
-   **blockchainnodeengine:** update the API ([b6bd10a](b6bd10a35c))
-   **blogger:** update the API ([975da3e](975da3e0ed))
-   **books:** update the API ([4bef344](4bef344a07))
-   **businessprofileperformance:** update the API ([5b313f4](5b313f4920))
-   **calendar:** update the API ([006efbc](006efbc7fa))
-   **certificatemanager:** update the API ([7d91857](7d91857b20))
-   **chromemanagement:** update the API ([fd29c85](fd29c85f37))
-   **chromepolicy:** update the API ([f51e0db](f51e0db2dc))
-   **chromeuxreport:** update the API ([fd7db9e](fd7db9edc4))
-   **civicinfo:** update the API ([a1f55b2](a1f55b245d))
-   **classroom:** update the API ([7603333](7603333575))
-   **cloudasset:** update the API ([1ffdfc2](1ffdfc2b30))
-   **cloudbilling:** update the API ([46cbf0e](46cbf0ef91))
-   **cloudchannel:** update the API ([e563d83](e563d832be))
-   **clouddebugger:** update the API ([faad469](faad4698e5))
-   **clouderrorreporting:** update the API ([afa4dec](afa4dec030))
-   **cloudidentity:** update the API ([2610c07](2610c07173))
-   **cloudiot:** update the API ([49105a6](49105a65ea))
-   **cloudkms:** update the API ([208f1da](208f1daac6))
-   **cloudprofiler:** update the API ([25cdd90](25cdd90c33))
-   **cloudresourcemanager:** update the API ([493ac8c](493ac8ce90))
-   **cloudscheduler:** update the API ([58070d7](58070d75a2))
-   **cloudsearch:** update the API ([d732a80](d732a80357))
-   **cloudshell:** update the API ([f098eb8](f098eb8765))
-   **cloudsupport:** update the API ([16514b9](16514b97fc))
-   **cloudtasks:** update the API ([12a7fe1](12a7fe1b93))
-   **cloudtrace:** update the API ([85adc52](85adc52814))
-   **composer:** update the API ([746d876](746d876c78))
-   **contactcenterinsights:** update the API ([03a34b1](03a34b14b6))
-   **customsearch:** update the API ([13ef993](13ef993800))
-   **datafusion:** update the API ([d74fb78](d74fb78629))
-   **datalabeling:** update the API ([ed7e0cb](ed7e0cb989))
-   **datalineage:** update the API ([7be88ab](7be88abd11))
-   **datapipelines:** update the API ([68131e2](68131e2960))
-   **deploymentmanager:** update the API ([7a36c72](7a36c726f7))
-   **dfareporting:** update the API ([f9c9934](f9c9934688))
-   **digitalassetlinks:** update the API ([ef3f085](ef3f0859be))
-   **dlp:** update the API ([75eb667](75eb6671c3))
-   **dns:** update the API ([6e63b36](6e63b36afb))
-   **docs:** update the API ([9cdab2d](9cdab2d96b))
-   **domainsrdap:** update the API ([13b01b1](13b01b1767))
-   **domains:** update the API ([884519b](884519bf3a))
-   **doubleclickbidmanager:** update the API ([73d0bed](73d0bedb16))
-   **doubleclicksearch:** update the API ([fa8cb1f](fa8cb1f4aa))
-   **driveactivity:** update the API ([13487f9](13487f9ce2))
-   **essentialcontacts:** update the API ([5fab60a](5fab60a961))
-   **eventarc:** update the API ([d615c48](d615c48812))
-   **factchecktools:** update the API ([6f372f1](6f372f19cc))
-   **fcmdata:** update the API ([3b19295](3b192956b2))
-   **fcm:** update the API ([e099c42](e099c42993))
-   **file:** update the API ([9bbf034](9bbf0348a0))
-   **firebaseappdistribution:** update the API ([8da0eb4](8da0eb460f))
-   **firebasedatabase:** update the API ([4032b62](4032b62921))
-   **firebasedynamiclinks:** update the API ([9d96aea](9d96aeafe1))
-   **firebasehosting:** update the API ([c23f76b](c23f76bf5e))
-   **firebaseml:** update the API ([048c48e](048c48e88b))
-   **firebaserules:** update the API ([5e24b10](5e24b105f7))
-   **firebasestorage:** update the API ([ea95e22](ea95e22fb2))
-   **fitness:** update the API ([7c544ff](7c544ffc24))
-   **forms:** update the API ([8ba614a](8ba614a2aa))
-   **gamesConfiguration:** update the API ([8d46262](8d46262831))
-   **gameservices:** update the API ([900a2fa](900a2fac5c))
-   **gamesManagement:** update the API ([7997150](799715027a))
-   **genomics:** update the API ([c64bc84](c64bc848cb))
-   **gmailpostmastertools:** update the API ([3b25276](3b25276be0))
-   **gmail:** update the API ([6ee8730](6ee873005b))
-   **groupsmigration:** update the API ([e0c396e](e0c396e9d0))
-   **groupssettings:** update the API ([8400a0e](8400a0e998))
-   **homegraph:** update the API ([c77f44b](c77f44b726))
-   **iamcredentials:** update the API ([b806bd9](b806bd9fb9))
-   **iam:** update the API ([6ad470f](6ad470ffbb))
-   **iap:** update the API ([8b998a0](8b998a0914))
-   **ideahub:** update the API ([1540d50](1540d50df9))
-   **identitytoolkit:** update the API ([4d7a874](4d7a874025))
-   **ids:** update the API ([428dc29](428dc29375))
-   **indexing:** update the API ([782806a](782806a470))
-   **integrations:** update the API ([96dd8fd](96dd8fd2c1))
-   **jobs:** update the API ([10826fa](10826fa6de))
-   **kgsearch:** update the API ([9cee192](9cee192c08))
-   **kmsinventory:** update the API ([9492458](9492458165))
-   **language:** update the API ([585690a](585690a033))
-   **libraryagent:** update the API ([9251716](9251716a73))
-   **licensing:** update the API ([c5271b5](c5271b559e))
-   **lifesciences:** update the API ([145d7ce](145d7ce4d4))
-   **localservices:** update the API ([db5b627](db5b6271a4))
-   **logging:** update the API ([df73435](df73435d7d))
-   **managedidentities:** update the API ([1814dfa](1814dfa9e3))
-   **manufacturers:** update the API ([c6c1398](c6c1398806))
-   **memcache:** update the API ([05013bb](05013bb4d2))
-   **metastore:** update the API ([45b0b5d](45b0b5d84f))
-   **ml:** update the API ([9e1be4a](9e1be4aed4))
-   **mybusinessaccountmanagement:** update the API ([6bc90e9](6bc90e9575))
-   **mybusinessbusinesscalls:** update the API ([13ec9e0](13ec9e001a))
-   **mybusinessbusinessinformation:** update the API ([565b3fa](565b3fa86b))
-   **mybusinesslodging:** update the API ([006bd5a](006bd5a42d))
-   **mybusinessnotifications:** update the API ([78e33ee](78e33ee568))
-   **mybusinessplaceactions:** update the API ([bc8e5c7](bc8e5c7259))
-   **mybusinessqanda:** update the API ([0ca91b1](0ca91b1e04))
-   **mybusinessverifications:** update the API ([d5de2b9](d5de2b9692))
-   **networkmanagement:** update the API ([533642b](533642ba85))
-   **networkservices:** update the API ([8133c74](8133c7471e))
-   **oauth2:** update the API ([5097e00](5097e00e9b))
-   **orgpolicy:** update the API ([4f1d852](4f1d85203a))
-   **pagespeedonline:** update the API ([fb574b4](fb574b4740))
-   **paymentsresellersubscription:** update the API ([ecff656](ecff6566f2))
-   **people:** update the API ([abebf9f](abebf9f738))
-   **places:** update the API ([1582524](1582524f23))
-   **playablelocations:** update the API ([711c349](711c349182))
-   **playcustomapp:** update the API ([d96f5b2](d96f5b2af3))
-   **playdeveloperreporting:** update the API ([e05bcaf](e05bcaf6c0))
-   **playintegrity:** update the API ([7c9edd3](7c9edd37f9))
-   **plus:** update the API ([ecac7a8](ecac7a88cd))
-   **policyanalyzer:** update the API ([98148bf](98148bf5d9))
-   **policytroubleshooter:** update the API ([36a5273](36a52733f6))
-   **poly:** update the API ([807484d](807484d57a))
-   **privateca:** update the API ([b654769](b654769dd2))
-   **prod_tt_sasportal:** update the API ([b8c3705](b8c3705040))
-   **publicca:** update the API ([f3361e6](f3361e6e1d))
-   **pubsublite:** update the API ([87e148d](87e148d025))
-   **readerrevenuesubscriptionlinking:** update the API ([6eb57e9](6eb57e9d2f))
-   **realtimebidding:** update the API ([dbcfad2](dbcfad26ca))
-   **recaptchaenterprise:** update the API ([3af6e62](3af6e62c11))
-   **recommendationengine:** update the API ([b5323d8](b5323d877e))
-   **recommender:** update the API ([bf6eed9](bf6eed9745))
-   **redis:** update the API ([6879c13](6879c133e0))
-   **remotebuildexecution:** update the API ([911cd0a](911cd0a68e))
-   **reseller:** update the API ([e7ec5d3](e7ec5d33b9))
-   **resourcesettings:** update the API ([c2c0c9e](c2c0c9ecd6))
-   **runtimeconfig:** update the API ([7866c3a](7866c3a9b9))
-   **run:** update the API ([2ed76fe](2ed76fe355))
-   **safebrowsing:** update the API ([fe23d83](fe23d83559))
-   **sasportal:** update the API ([ca33e9c](ca33e9c71f))
-   **script:** update the API ([207587b](207587b2b7))
-   **searchads360:** update the API ([8ed1df1](8ed1df140b))
-   **searchconsole:** update the API ([208d0a5](208d0a5dc7))
-   **secretmanager:** update the API ([426f146](426f146ac7))
-   **sheets:** update the API ([3333f83](3333f83473))
-   **siteVerification:** update the API ([760447c](760447c313))
-   **slides:** update the API ([5e4d08c](5e4d08cfae))
-   **sourcerepo:** update the API ([f803061](f803061d79))
-   **spanner:** update the API ([8fe5e93](8fe5e9303a))
-   **speech:** update the API ([34b7185](34b7185e75))
-   **sql:** update the API ([b29a348](b29a34873e))
-   **storagetransfer:** update the API ([d4e4820](d4e48203dd))
-   **storage:** update the API ([20860bc](20860bc1ab))
-   **streetviewpublish:** update the API ([1c6bb94](1c6bb94e2e))
-   **sts:** update the API ([5765d2a](5765d2a4a1))
-   **tasks:** update the API ([0eac80e](0eac80eb8e))
-   **testing:** update the API ([fd787ed](fd787ed8f2))
-   **texttospeech:** update the API ([9981feb](9981feb93e))
-   **transcoder:** update the API ([851586c](851586c418))
-   **translate:** update the API ([e11cc5e](e11cc5eea6))
-   **travelimpactmodel:** update the API ([75a5352](75a5352631))
-   **vectortile:** update the API ([4d94932](4d949325d9))
-   **versionhistory:** update the API ([bb2ceec](bb2ceec5dd))
-   **vision:** update the API ([afea669](afea6697bc))
-   **vpcaccess:** update the API ([da58970](da5897041f))
-   **webfonts:** update the API ([f0a4421](f0a4421760))
-   **webmasters:** update the API ([d4143d6](d4143d6ab0))
-   **webrisk:** update the API ([d4cc69b](d4cc69bca7))
-   **websecurityscanner:** update the API ([9960a3a](9960a3aff2))
-   **workflowexecutions:** update the API ([b3488ab](b3488abe18))
-   **workflows:** update the API ([0b82237](0b82237e45))
-   **workstations:** update the API ([a5f5488](a5f5488c31))
-   **youtubeAnalytics:** update the API ([203afe6](203afe652d))
-   **youtubereporting:** update the API ([48b6016](48b6016a38))

##### Miscellaneous Chores

-   migate to Node 14 ([0967781](09677817aa))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNzYuMiIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 11:21:58 +00:00
darkskygit
6b76037e39 fix(server): better copilot error handle (#10509) 2025-02-28 11:01:58 +00:00
renovate
7227b7f8f6 chore: bump up oxlint version to v0.15.12 (#10206)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [oxlint](https://oxc.rs) ([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint)) | [`0.15.10` -> `0.15.12`](https://renovatebot.com/diffs/npm/oxlint/0.15.10/0.15.12) | [![age](https://developer.mend.io/api/mc/badges/age/npm/oxlint/0.15.12?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/oxlint/0.15.12?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/oxlint/0.15.10/0.15.12?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/oxlint/0.15.10/0.15.12?slim=true)](https://docs.renovatebot.com/merge-confidence/) |

---

### Release Notes

<details>
<summary>oxc-project/oxc (oxlint)</summary>

### [`v0.15.12`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.15.12): oxlint v0.15.12

[Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.15.11...oxlint_v0.15.12)

#### \[0.15.12] - 2025-02-24

##### Features

-   [`914dd46`](https://redirect.github.com/oxc-project/oxc/commit/914dd46) linter: Add eslint/max-depth ([#&#8203;9173](https://redirect.github.com/oxc-project/oxc/issues/9173)) (ikkz)
-   [`0b08159`](https://redirect.github.com/oxc-project/oxc/commit/0b08159) linter: Add eslint/max-lines-per-function ([#&#8203;9161](https://redirect.github.com/oxc-project/oxc/issues/9161)) (ikkz)
-   [`cc8dd48`](https://redirect.github.com/oxc-project/oxc/commit/cc8dd48) linter: Add unicorn/no-invalid-fetch-options rule ([#&#8203;9212](https://redirect.github.com/oxc-project/oxc/issues/9212)) (Mikhail Baev)
-   [`af13b1b`](https://redirect.github.com/oxc-project/oxc/commit/af13b1b) linter: Promote `eslint/no-eval` to `correctness` ([#&#8203;9231](https://redirect.github.com/oxc-project/oxc/issues/9231)) (dalaoshu)
-   [`542bbd7`](https://redirect.github.com/oxc-project/oxc/commit/542bbd7) linter: Support `import-x` plugin name ([#&#8203;9074](https://redirect.github.com/oxc-project/oxc/issues/9074)) (Sysix)
-   [`d266c29`](https://redirect.github.com/oxc-project/oxc/commit/d266c29) linter: Add eslint/max-nested-callbacks ([#&#8203;9172](https://redirect.github.com/oxc-project/oxc/issues/9172)) (ikkz)
-   [`86795d0`](https://redirect.github.com/oxc-project/oxc/commit/86795d0) linter: Implement grouped-accessor-pairs ([#&#8203;9065](https://redirect.github.com/oxc-project/oxc/issues/9065)) (yefan)
-   [`d70bad3`](https://redirect.github.com/oxc-project/oxc/commit/d70bad3) linter: Add eslint/no-unneeded-ternary rule ([#&#8203;9160](https://redirect.github.com/oxc-project/oxc/issues/9160)) (Cédric DIRAND)
-   [`4bd86e6`](https://redirect.github.com/oxc-project/oxc/commit/4bd86e6) linter: Add `fixer` for `unicorn/catch-error-name` ([#&#8203;9165](https://redirect.github.com/oxc-project/oxc/issues/9165)) (dalaoshu)

##### Bug Fixes

-   [`94bd2d8`](https://redirect.github.com/oxc-project/oxc/commit/94bd2d8) language_server: Fix `clippy::significant_drop_in_scrutinee` warning ([#&#8203;9234](https://redirect.github.com/oxc-project/oxc/issues/9234)) (Boshen)
-   [`69091c0`](https://redirect.github.com/oxc-project/oxc/commit/69091c0) linter: Correct default for `eslint/no-eval` ([#&#8203;9312](https://redirect.github.com/oxc-project/oxc/issues/9312)) (dalaoshu)
-   [`3031845`](https://redirect.github.com/oxc-project/oxc/commit/3031845) linter: Add option "allowTypeImports" for rule "no-restricted-imports" ([#&#8203;7894](https://redirect.github.com/oxc-project/oxc/issues/7894)) (Alexander S.)

##### Documentation

-   [`6c0f006`](https://redirect.github.com/oxc-project/oxc/commit/6c0f006) linter: Improve the documentation of eslint/no-useless-concat ([#&#8203;9179](https://redirect.github.com/oxc-project/oxc/issues/9179)) (Tom)
-   [`3414824`](https://redirect.github.com/oxc-project/oxc/commit/3414824) oxc: Enable `clippy::too_long_first_doc_paragraph` ([#&#8203;9237](https://redirect.github.com/oxc-project/oxc/issues/9237)) (Boshen)

##### Refactor

-   [`fb7df52`](https://redirect.github.com/oxc-project/oxc/commit/fb7df52) linter: Allow indirect `eval` by default for `eslint/no-eval` ([#&#8203;9302](https://redirect.github.com/oxc-project/oxc/issues/9302)) (dalaoshu)
-   [`b6fc0f6`](https://redirect.github.com/oxc-project/oxc/commit/b6fc0f6) linter: Improve `unicorn/consistent-function-scoping` ([#&#8203;9163](https://redirect.github.com/oxc-project/oxc/issues/9163)) (dalaoshu)

### [`v0.15.11`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#01511---2025-02-16)

[Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.15.10...oxlint_v0.15.11)

##### Features

-   [`5d508a4`](https://redirect.github.com/oxc-project/oxc/commit/5d508a4) linter: Support `env` and `globals` in `overrides` configuration ([#&#8203;8915](https://redirect.github.com/oxc-project/oxc/issues/8915)) (Sysix)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjcuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 10:43:57 +00:00
doodlewind
22191caa82 fix(editor): safari compat for lit host (#10514)
Fixed this white screen crash on mobile safari:

<img src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/lEGcysB4lFTEbCwZ8jMv/00bffd51-8e06-4d37-88d4-6f5020cd503d.png" width="500">
2025-02-28 10:26:59 +00:00
renovate
b9b3c0db66 chore: Lock file maintenance (#10041)
This PR contains the following updates:

| Update | Change |
|---|---|
| lockFileMaintenance | All locks refreshed |

🔧 This Pull Request updates lock files to use the latest dependency versions.

---

### Configuration

📅 **Schedule**: Branch creation - "* 0-3 * * 1" (UTC), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjQuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE3Ni4yIiwidGFyZ2V0QnJhbmNoIjoiY2FuYXJ5IiwibGFiZWxzIjpbImRlcGVuZGVuY2llcyJdfQ==-->
2025-02-28 10:06:25 +00:00
renovate
27518e1fb1 chore: bump up all non-major dependencies (#10363)
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence | Type | Update |
|---|---|---|---|---|---|---|---|
| [@aws-sdk/client-s3](https://redirect.github.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3) ([source](https://redirect.github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3)) | [`3.750.0` -> `3.758.0`](https://renovatebot.com/diffs/npm/@aws-sdk%2fclient-s3/3.750.0/3.758.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@aws-sdk%2fclient-s3/3.758.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@aws-sdk%2fclient-s3/3.758.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@aws-sdk%2fclient-s3/3.750.0/3.758.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@aws-sdk%2fclient-s3/3.750.0/3.758.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [@capgo/inappbrowser](https://redirect.github.com/Cap-go/capacitor-inappbrowser) | [`7.2.16` -> `7.2.18`](https://renovatebot.com/diffs/npm/@capgo%2finappbrowser/7.2.16/7.2.18) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@capgo%2finappbrowser/7.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@capgo%2finappbrowser/7.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@capgo%2finappbrowser/7.2.16/7.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@capgo%2finappbrowser/7.2.16/7.2.18?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@chromatic-com/storybook](https://redirect.github.com/chromaui/addon-visual-tests) | [`3.2.4` -> `3.2.5`](https://renovatebot.com/diffs/npm/@chromatic-com%2fstorybook/3.2.4/3.2.5) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@chromatic-com%2fstorybook/3.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@chromatic-com%2fstorybook/3.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@chromatic-com%2fstorybook/3.2.4/3.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@chromatic-com%2fstorybook/3.2.4/3.2.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@electron-forge/cli](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fcli/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fcli/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fcli/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fcli/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fcli/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/core](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fcore/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fcore/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fcore/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fcore/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fcore/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/core-utils](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fcore-utils/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fcore-utils/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fcore-utils/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fcore-utils/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fcore-utils/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/maker-deb](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fmaker-deb/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fmaker-deb/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fmaker-deb/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fmaker-deb/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fmaker-deb/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/maker-dmg](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fmaker-dmg/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fmaker-dmg/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fmaker-dmg/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fmaker-dmg/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fmaker-dmg/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/maker-flatpak](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fmaker-flatpak/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fmaker-flatpak/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fmaker-flatpak/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fmaker-flatpak/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fmaker-flatpak/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/maker-squirrel](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fmaker-squirrel/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fmaker-squirrel/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fmaker-squirrel/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fmaker-squirrel/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fmaker-squirrel/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/maker-zip](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fmaker-zip/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fmaker-zip/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fmaker-zip/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fmaker-zip/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fmaker-zip/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/plugin-auto-unpack-natives](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fplugin-auto-unpack-natives/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fplugin-auto-unpack-natives/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fplugin-auto-unpack-natives/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fplugin-auto-unpack-natives/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fplugin-auto-unpack-natives/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@electron-forge/shared-types](https://redirect.github.com/electron/forge) | [`7.6.1` -> `7.7.0`](https://renovatebot.com/diffs/npm/@electron-forge%2fshared-types/7.6.1/7.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@electron-forge%2fshared-types/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@electron-forge%2fshared-types/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@electron-forge%2fshared-types/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@electron-forge%2fshared-types/7.6.1/7.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@eslint/js](https://eslint.org) ([source](https://redirect.github.com/eslint/eslint/tree/HEAD/packages/js)) | [`9.20.0` -> `9.21.0`](https://renovatebot.com/diffs/npm/@eslint%2fjs/9.20.0/9.21.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@eslint%2fjs/9.21.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@eslint%2fjs/9.21.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@eslint%2fjs/9.20.0/9.21.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@eslint%2fjs/9.20.0/9.21.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@google/generative-ai](https://redirect.github.com/google/generative-ai-js) | [`^0.21.0` -> `^0.22.0`](https://renovatebot.com/diffs/npm/@google%2fgenerative-ai/0.21.0/0.22.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@google%2fgenerative-ai/0.22.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@google%2fgenerative-ai/0.22.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@google%2fgenerative-ai/0.21.0/0.22.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@google%2fgenerative-ai/0.21.0/0.22.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [@graphql-codegen/typescript](https://redirect.github.com/dotansimha/graphql-code-generator) ([source](https://redirect.github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/plugins/typescript/typescript)) | [`4.1.3` -> `4.1.5`](https://renovatebot.com/diffs/npm/@graphql-codegen%2ftypescript/4.1.3/4.1.5) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@graphql-codegen%2ftypescript/4.1.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@graphql-codegen%2ftypescript/4.1.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@graphql-codegen%2ftypescript/4.1.3/4.1.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@graphql-codegen%2ftypescript/4.1.3/4.1.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@graphql-codegen/typescript-operations](https://redirect.github.com/dotansimha/graphql-code-generator) ([source](https://redirect.github.com/dotansimha/graphql-code-generator/tree/HEAD/packages/plugins/typescript/operations)) | [`4.4.1` -> `4.5.1`](https://renovatebot.com/diffs/npm/@graphql-codegen%2ftypescript-operations/4.4.1/4.5.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@graphql-codegen%2ftypescript-operations/4.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@graphql-codegen%2ftypescript-operations/4.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@graphql-codegen%2ftypescript-operations/4.4.1/4.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@graphql-codegen%2ftypescript-operations/4.4.1/4.5.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@opentelemetry/instrumentation-graphql](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-graphql#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib)) | [`0.47.0` -> `0.47.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-graphql/0.47.0/0.47.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-graphql/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation-graphql/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation-graphql/0.47.0/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-graphql/0.47.0/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@opentelemetry/instrumentation-ioredis](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-ioredis#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib)) | [`0.47.0` -> `0.47.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-ioredis/0.47.0/0.47.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-ioredis/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation-ioredis/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation-ioredis/0.47.0/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-ioredis/0.47.0/0.47.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@opentelemetry/instrumentation-nestjs-core](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-nestjs-core#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib)) | [`0.44.0` -> `0.44.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-nestjs-core/0.44.0/0.44.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-nestjs-core/0.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation-nestjs-core/0.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation-nestjs-core/0.44.0/0.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-nestjs-core/0.44.0/0.44.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@opentelemetry/instrumentation-socket.io](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/instrumentation-socket.io#readme) ([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib)) | [`0.46.0` -> `0.46.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-socket.io/0.46.0/0.46.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-socket.io/0.46.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@opentelemetry%2finstrumentation-socket.io/0.46.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@opentelemetry%2finstrumentation-socket.io/0.46.0/0.46.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-socket.io/0.46.0/0.46.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@sentry/esbuild-plugin](https://redirect.github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/esbuild-plugin) ([source](https://redirect.github.com/getsentry/sentry-javascript-bundler-plugins)) | [`3.1.2` -> `3.2.1`](https://renovatebot.com/diffs/npm/@sentry%2fesbuild-plugin/3.1.2/3.2.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sentry%2fesbuild-plugin/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sentry%2fesbuild-plugin/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sentry%2fesbuild-plugin/3.1.2/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sentry%2fesbuild-plugin/3.1.2/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@sentry/webpack-plugin](https://redirect.github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/webpack-plugin) ([source](https://redirect.github.com/getsentry/sentry-javascript-bundler-plugins)) | [`3.1.2` -> `3.2.1`](https://renovatebot.com/diffs/npm/@sentry%2fwebpack-plugin/3.1.2/3.2.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@sentry%2fwebpack-plugin/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@sentry%2fwebpack-plugin/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@sentry%2fwebpack-plugin/3.1.2/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@sentry%2fwebpack-plugin/3.1.2/3.2.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [@storybook/addon-essentials](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/essentials) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/essentials)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2faddon-essentials/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-essentials/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-essentials/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-essentials/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-essentials/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/addon-interactions](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/interactions) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/interactions)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2faddon-interactions/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-interactions/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-interactions/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-interactions/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-interactions/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/addon-links](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/links) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/links)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2faddon-links/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-links/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-links/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-links/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-links/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/addon-mdx-gfm](https://redirect.github.com/storybookjs/storybook/tree/next/code/addons/gfm) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/addons/gfm)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2faddon-mdx-gfm/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2faddon-mdx-gfm/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2faddon-mdx-gfm/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2faddon-mdx-gfm/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2faddon-mdx-gfm/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/react](https://redirect.github.com/storybookjs/storybook/tree/next/code/renderers/react) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/renderers/react)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2freact/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2freact/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2freact/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2freact/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2freact/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@storybook/react-vite](https://redirect.github.com/storybookjs/storybook/tree/next/code/frameworks/react-vite) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/@storybook%2freact-vite/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@storybook%2freact-vite/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@storybook%2freact-vite/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@storybook%2freact-vite/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@storybook%2freact-vite/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@swc/core](https://swc.rs) ([source](https://redirect.github.com/swc-project/swc)) | [`1.10.17` -> `1.11.4`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.10.17/1.11.4) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@swc%2fcore/1.11.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@swc%2fcore/1.11.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@swc%2fcore/1.10.17/1.11.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@swc%2fcore/1.10.17/1.11.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [@tailwindcss/postcss](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)) | [`4.0.6` -> `4.0.9`](https://renovatebot.com/diffs/npm/@tailwindcss%2fpostcss/4.0.6/4.0.9) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@tailwindcss%2fpostcss/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@tailwindcss%2fpostcss/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@tailwindcss%2fpostcss/4.0.6/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@tailwindcss%2fpostcss/4.0.6/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@tailwindcss/vite](https://tailwindcss.com) ([source](https://redirect.github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)) | [`4.0.6` -> `4.0.9`](https://renovatebot.com/diffs/npm/@tailwindcss%2fvite/4.0.6/4.0.9) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@tailwindcss%2fvite/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@tailwindcss%2fvite/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@tailwindcss%2fvite/4.0.6/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@tailwindcss%2fvite/4.0.6/4.0.9?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`22.13.4` -> `22.13.5`](https://renovatebot.com/diffs/npm/@types%2fnode/22.13.4/22.13.5) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/22.13.4/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/22.13.4/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [@types/node](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | [`22.13.4` -> `22.13.5`](https://renovatebot.com/diffs/npm/@types%2fnode/22.13.4/22.13.5) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fnode/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fnode/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fnode/22.13.4/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fnode/22.13.4/22.13.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@types/sinon](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/sinon) ([source](https://redirect.github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/sinon)) | [`17.0.3` -> `17.0.4`](https://renovatebot.com/diffs/npm/@types%2fsinon/17.0.3/17.0.4) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@types%2fsinon/17.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@types%2fsinon/17.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@types%2fsinon/17.0.3/17.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@types%2fsinon/17.0.3/17.0.4?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@vitest/browser](https://redirect.github.com/vitest-dev/vitest/tree/main/packages/browser#readme) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/browser)) | [`3.0.6` -> `3.0.7`](https://renovatebot.com/diffs/npm/@vitest%2fbrowser/3.0.6/3.0.7) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fbrowser/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fbrowser/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fbrowser/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fbrowser/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@vitest/coverage-istanbul](https://redirect.github.com/vitest-dev/vitest/tree/main/packages/coverage-istanbul#readme) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-istanbul)) | [`3.0.6` -> `3.0.7`](https://renovatebot.com/diffs/npm/@vitest%2fcoverage-istanbul/3.0.6/3.0.7) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fcoverage-istanbul/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fcoverage-istanbul/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fcoverage-istanbul/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fcoverage-istanbul/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [@vitest/ui](https://redirect.github.com/vitest-dev/vitest/tree/main/packages/ui#readme) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/ui)) | [`3.0.6` -> `3.0.7`](https://renovatebot.com/diffs/npm/@vitest%2fui/3.0.6/3.0.7) | [![age](https://developer.mend.io/api/mc/badges/age/npm/@vitest%2fui/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/@vitest%2fui/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/@vitest%2fui/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@vitest%2fui/3.0.6/3.0.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [anyhow](https://redirect.github.com/dtolnay/anyhow) | `1.0.95` -> `1.0.96` | [![age](https://developer.mend.io/api/mc/badges/age/crate/anyhow/1.0.96?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/anyhow/1.0.96?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/anyhow/1.0.95/1.0.96?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/anyhow/1.0.95/1.0.96?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch |
| [apollographql/apollo-ios](https://redirect.github.com/apollographql/apollo-ios) | `from: "1.17.0"` -> `from: "1.18.0"` | [![age](https://developer.mend.io/api/mc/badges/age/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios.git/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios.git/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios.git/1.17.0/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios.git/1.17.0/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |  | minor |
| [apollographql/apollo-ios](https://redirect.github.com/apollographql/apollo-ios) | `1.17.0` -> `1.18.0` | [![age](https://developer.mend.io/api/mc/badges/age/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios/1.17.0/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/git-tags/https:%2f%2fgithub.com%2fapollographql%2fapollo-ios/1.17.0/1.18.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) |  | minor |
| [bullmq](https://bullmq.io/) ([source](https://redirect.github.com/taskforcesh/bullmq)) | [`5.41.2` -> `5.41.7`](https://renovatebot.com/diffs/npm/bullmq/5.41.2/5.41.7) | [![age](https://developer.mend.io/api/mc/badges/age/npm/bullmq/5.41.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/bullmq/5.41.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/bullmq/5.41.2/5.41.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/bullmq/5.41.2/5.41.7?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [cc](https://redirect.github.com/rust-lang/cc-rs) | `1.2.12` -> `1.2.15` | [![age](https://developer.mend.io/api/mc/badges/age/crate/cc/1.2.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/cc/1.2.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/cc/1.2.12/1.2.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/cc/1.2.12/1.2.15?slim=true)](https://docs.renovatebot.com/merge-confidence/) | build-dependencies | patch |
| [chrono](https://redirect.github.com/chronotope/chrono) | `0.4.39` -> `0.4.40` | [![age](https://developer.mend.io/api/mc/badges/age/crate/chrono/0.4.40?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/chrono/0.4.40?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/chrono/0.4.39/0.4.40?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/chrono/0.4.39/0.4.40?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch |
| [electron](https://redirect.github.com/electron/electron) | [`34.2.0` -> `34.3.0`](https://renovatebot.com/diffs/npm/electron/34.2.0/34.3.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/electron/34.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/electron/34.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/electron/34.2.0/34.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/electron/34.2.0/34.3.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [fast-xml-parser](https://redirect.github.com/NaturalIntelligence/fast-xml-parser) | [`4.5.2` -> `4.5.3`](https://renovatebot.com/diffs/npm/fast-xml-parser/4.5.2/4.5.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/fast-xml-parser/4.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/fast-xml-parser/4.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/fast-xml-parser/4.5.2/4.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/fast-xml-parser/4.5.2/4.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [file-type](https://redirect.github.com/sindresorhus/file-type) | [`20.1.0` -> `20.4.0`](https://renovatebot.com/diffs/npm/file-type/20.1.0/20.4.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/file-type/20.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/file-type/20.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/file-type/20.1.0/20.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/file-type/20.1.0/20.4.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [gradle](https://gradle.org) ([source](https://redirect.github.com/gradle/gradle)) | `8.12.1` -> `8.13` | [![age](https://developer.mend.io/api/mc/badges/age/gradle-version/gradle/8.13?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/gradle-version/gradle/8.13?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/gradle-version/gradle/8.12.1/8.13?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/gradle-version/gradle/8.12.1/8.13?slim=true)](https://docs.renovatebot.com/merge-confidence/) |  | minor |
| [happy-dom](https://redirect.github.com/capricorn86/happy-dom) | [`17.1.0` -> `17.1.8`](https://renovatebot.com/diffs/npm/happy-dom/17.1.0/17.1.8) | [![age](https://developer.mend.io/api/mc/badges/age/npm/happy-dom/17.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/happy-dom/17.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/happy-dom/17.1.0/17.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/happy-dom/17.1.0/17.1.8?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [html-validate](https://html-validate.org) ([source](https://gitlab.com/html-validate/html-validate)) | [`9.3.0` -> `9.4.1`](https://renovatebot.com/diffs/npm/html-validate/9.3.0/9.4.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/html-validate/9.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/html-validate/9.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/html-validate/9.3.0/9.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/html-validate/9.3.0/9.4.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [libc](https://redirect.github.com/rust-lang/libc) | `0.2.169` -> `0.2.170` | [![age](https://developer.mend.io/api/mc/badges/age/crate/libc/0.2.170?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/libc/0.2.170?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/libc/0.2.169/0.2.170?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/libc/0.2.169/0.2.170?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch |
| [lucide-react](https://lucide.dev) ([source](https://redirect.github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react)) | [`^0.475.0` -> `^0.476.0`](https://renovatebot.com/diffs/npm/lucide-react/0.475.0/0.476.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/lucide-react/0.476.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/lucide-react/0.476.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/lucide-react/0.475.0/0.476.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/lucide-react/0.475.0/0.476.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [msw](https://mswjs.io) ([source](https://redirect.github.com/mswjs/msw)) | [`2.7.0` -> `2.7.3`](https://renovatebot.com/diffs/npm/msw/2.7.0/2.7.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/msw/2.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/msw/2.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/msw/2.7.0/2.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/msw/2.7.0/2.7.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [nanoid](https://redirect.github.com/ai/nanoid) | [`5.1.0` -> `5.1.2`](https://renovatebot.com/diffs/npm/nanoid/5.1.0/5.1.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/nanoid/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nanoid/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nanoid/5.1.0/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nanoid/5.1.0/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [nanoid](https://redirect.github.com/ai/nanoid) | [`5.1.0` -> `5.1.2`](https://renovatebot.com/diffs/npm/nanoid/5.1.0/5.1.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/nanoid/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/nanoid/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/nanoid/5.1.0/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nanoid/5.1.0/5.1.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [openai](https://redirect.github.com/openai/openai-node) | [`4.85.1` -> `4.86.1`](https://renovatebot.com/diffs/npm/openai/4.85.1/4.86.1) | [![age](https://developer.mend.io/api/mc/badges/age/npm/openai/4.86.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/openai/4.86.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/openai/4.85.1/4.86.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/openai/4.85.1/4.86.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [postcss](https://postcss.org/) ([source](https://redirect.github.com/postcss/postcss)) | [`8.5.2` -> `8.5.3`](https://renovatebot.com/diffs/npm/postcss/8.5.2/8.5.3) | [![age](https://developer.mend.io/api/mc/badges/age/npm/postcss/8.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/postcss/8.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/postcss/8.5.2/8.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/postcss/8.5.2/8.5.3?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [prettier](https://prettier.io) ([source](https://redirect.github.com/prettier/prettier)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/prettier/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/prettier/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/prettier/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/prettier/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/prettier/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [prettier](https://prettier.io) ([source](https://redirect.github.com/prettier/prettier)) | [`3.5.1` -> `3.5.2`](https://renovatebot.com/diffs/npm/prettier/3.5.1/3.5.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/prettier/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/prettier/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/prettier/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/prettier/3.5.1/3.5.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [react-markdown](https://redirect.github.com/remarkjs/react-markdown) | [`9.0.3` -> `9.1.0`](https://renovatebot.com/diffs/npm/react-markdown/9.0.3/9.1.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/react-markdown/9.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/react-markdown/9.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/react-markdown/9.0.3/9.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-markdown/9.0.3/9.1.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [react-router-dom](https://redirect.github.com/remix-run/react-router) ([source](https://redirect.github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom)) | [`6.29.0` -> `6.30.0`](https://renovatebot.com/diffs/npm/react-router-dom/6.29.0/6.30.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/react-router-dom/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/react-router-dom/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/react-router-dom/6.29.0/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/react-router-dom/6.29.0/6.30.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [rxjs](https://rxjs.dev) ([source](https://redirect.github.com/reactivex/rxjs)) | [`7.8.1` -> `7.8.2`](https://renovatebot.com/diffs/npm/rxjs/7.8.1/7.8.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/rxjs/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/rxjs/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/rxjs/7.8.1/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/rxjs/7.8.1/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [rxjs](https://rxjs.dev) ([source](https://redirect.github.com/reactivex/rxjs)) | [`7.8.1` -> `7.8.2`](https://renovatebot.com/diffs/npm/rxjs/7.8.1/7.8.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/rxjs/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/rxjs/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/rxjs/7.8.1/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/rxjs/7.8.1/7.8.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [serde](https://serde.rs) ([source](https://redirect.github.com/serde-rs/serde)) | `1.0.217` -> `1.0.218` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde/1.0.218?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde/1.0.218?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde/1.0.217/1.0.218?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde/1.0.217/1.0.218?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch |
| [serde_json](https://redirect.github.com/serde-rs/json) | `1.0.138` -> `1.0.139` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde_json/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde_json/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde_json/1.0.138/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde_json/1.0.138/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | patch |
| [serde_json](https://redirect.github.com/serde-rs/json) | `1.0.138` -> `1.0.139` | [![age](https://developer.mend.io/api/mc/badges/age/crate/serde_json/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/crate/serde_json/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/crate/serde_json/1.0.138/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/serde_json/1.0.138/1.0.139?slim=true)](https://docs.renovatebot.com/merge-confidence/) | workspace.dependencies | patch |
| [shadcn-ui](https://redirect.github.com/shadcn/ui) ([source](https://redirect.github.com/shadcn/ui/tree/HEAD/packages/cli)) | [`0.9.4` -> `0.9.5`](https://renovatebot.com/diffs/npm/shadcn-ui/0.9.4/0.9.5) | [![age](https://developer.mend.io/api/mc/badges/age/npm/shadcn-ui/0.9.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/shadcn-ui/0.9.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/shadcn-ui/0.9.4/0.9.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/shadcn-ui/0.9.4/0.9.5?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | patch |
| [storybook](https://redirect.github.com/storybookjs/storybook/tree/next/code/lib/cli) ([source](https://redirect.github.com/storybookjs/storybook/tree/HEAD/code/lib/cli)) | [`8.5.6` -> `8.6.2`](https://renovatebot.com/diffs/npm/storybook/8.5.6/8.6.2) | [![age](https://developer.mend.io/api/mc/badges/age/npm/storybook/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/storybook/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/storybook/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/storybook/8.5.6/8.6.2?slim=true)](https://docs.renovatebot.com/merge-confidence/) | devDependencies | minor |
| [stripe](https://redirect.github.com/stripe/stripe-node) | [`17.6.0` -> `17.7.0`](https://renovatebot.com/diffs/npm/stripe/17.6.0/17.7.0) | [![age](https://developer.mend.io/api/mc/badges/age/npm/stripe/17.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/stripe/17.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/stripe/17.6.0/17.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/stripe/17.6.0/17.7.0?slim=true)](https://docs.renovatebot.com/merge-confidence/) | dependencies | minor |
| [strum_macros](https://redirect.github.com/Peternator7/strum) | `0.26.2` -> `0.27.0` | [![age](https://developer.mend.io/api/mc/badges/age/crate/strum_macros/0.27.1?slim=true)](https://docs.renovatebot.com/merge-confidence/) | [!
2025-02-28 09:07:27 +00:00
L-Sun
d476d3b1df fix(editor): android keyboard can not be opened (#10502)
Close [BS-2674](https://linear.app/affine-design/issue/BS-2674/[android]-%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%8C%BA%E5%9F%9F%E7%82%B9%E5%87%BB%E5%90%8E%E6%97%A0%E6%B3%95%E6%BF%80%E6%B4%BB%E9%94%AE%E7%9B%98) [BS-2609](https://linear.app/affine-design/issue/BS-2609/[android]-%E8%BE%93%E5%85%A5%E7%9A%84-toolbar-%E6%B2%A1%E6%9C%89%E4%BA%86)
2025-02-28 08:23:26 +00:00
doodlewind
f1df774188 fix(editor): invalidate turbo renderer on selection update (#10499) 2025-02-28 08:08:28 +00:00
L-Sun
90b37ce65c fix(core): editor blur unexpectedly when clicking blank area (#10501)
### Before

https://github.com/user-attachments/assets/3c4b20e1-6d89-4dc7-a51f-04b6e9a89486

### After

https://github.com/user-attachments/assets/86b93403-597e-4dbb-ab65-90908342c230
2025-02-28 07:05:06 +00:00
L-Sun
27fc4afc35 chore(core): remove capacitor from frontend/core (#10500) 2025-02-28 07:05:05 +00:00
Saul-Mirone
e90c00c3b7 refactor(editor): perf optimization of flat data (#10494)
The new code should be more efficient as it:
- Avoids unnecessary iterations when objects aren't empty
- Has clearer path management
- Reduces redundant object traversals
2025-02-28 04:51:54 +00:00
Saul-Mirone
1d865ad883 test(editor): collab table test (#10506)
1. **Table UI Enhancements - Test IDs Added**
   - Added `data-testid` attributes to several table components for better testability:
     - `add-column-button` for the column addition button
     - `add-row-button` for the row addition button
     - `drag-column-handle` for column drag handles
     - `drag-row-handle` for row drag handles

2. **New Test Infrastructure**
   - Added new testing utilities in `tests/kit/src/bs/`:
     - `misc.ts`: Added `waitNextFrame` utility function for handling animation frame timing in tests
     - `table.ts`: Added comprehensive table testing utilities including:
       - `createTable`: Creates a new table with initial cells
       - `getCellText`: Retrieves text from a specific table cell
       - `inputToCell`: Inputs text into a specific table cell
       - `clickDeleteButtonInTableMenu`: Handles table deletion operations

3. **New Collaboration Test**
   - Added a new test file `tests/affine-local/e2e/blocksuite/table/collab.spec.ts` that tests table collaboration features:
     - Tests synchronization between two pages (A and B)
     - Verifies table operations sync correctly:
       - Adding columns and rows
       - Inputting cell content
       - Deleting columns and rows
     - Validates cell content consistency across both pages
     - Tests the complete table manipulation workflow in a collaborative setting

4. **Package Configuration Update**
   - Modified `tests/kit/package.json` to expose new test utilities:
     - Added new export mapping: `"./bs/*": "./src/bs/*.ts"` to make the new table testing utilities accessible

This PR primarily focuses on improving table testing infrastructure and adding comprehensive collaboration tests for the table functionality, while also enhancing component testability through data-test-ids.
2025-02-28 04:37:12 +00:00
pengx17
cd0bec5d31 fix(core): at menu ux (#10485)
fix AF-2285

1. loading icon will be rendered to the group name
2. make the focused item more stable
2025-02-28 02:34:29 +00:00
pengx17
59526080d4 fix(electron): hide tray for now (#10498) 2025-02-28 02:13:10 +00:00
pengx17
9e0cae58d7 fix(native): split application & tappable application (#10491)
A listening tappable app's info should inherit from its group process's name/icon. However the group process may not be listed as a tappable application.
2025-02-27 15:02:38 +00:00
Brooooooklyn
c50184bee6 chore(server-native): cleanup unused test (#10493) 2025-02-27 14:20:36 +00:00
Brooooooklyn
d7d33868d4 feat(native): decode audio and mp3 encoder (#10490) 2025-02-27 12:57:28 +00:00
Saul-Mirone
b19c1df43e fix: table collab (#10489)
[Screen Recording 2025-02-27 at 20.24.15.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/EUhyG5TOGVlHZ0Suk1wH/b3ac681f-a14d-483a-820c-53c584f0fb44.mov" />](https://app.graphite.dev/media/video/EUhyG5TOGVlHZ0Suk1wH/b3ac681f-a14d-483a-820c-53c584f0fb44.mov)
2025-02-27 12:37:57 +00:00
darkskygit
985906aa13 feat(server): copilot session prompt query (#10479) 2025-02-27 11:25:52 +00:00
forehalo
d50860eee2 fix(server): use updowncounter by default (#10482) 2025-02-27 10:15:13 +00:00
L-Sun
b995b4f965 chore(editor): update page block telemetry (#10487)
Close [BS-2711](https://linear.app/affine-design/issue/BS-2711/page-block埋点更新)
2025-02-27 09:58:58 +00:00
akumatus
1bb5dd0eda fix(core): always update session prompt before chat (#10483)
Why make this fix?
The network search flag is saved locally. If the user opens multiple clients, the local status and server status may be inconsistent.
2025-02-27 09:44:19 +00:00
LongYinan
fc4a716ef1 fix: add missing annotation to apps serviceAccount (#10484) 2025-02-27 17:34:00 +08:00
Saul-Mirone
4c736bc190 feat(editor): type safe draft model and transformer (#10486) 2025-02-27 09:19:49 +00:00
donteatfriedrice
272d41e32d chore: remove unused component imports and styles from text-renderer (#10478) 2025-02-27 08:54:15 +00:00
Saul-Mirone
d57ef5c5b3 fix(editor): transform to draftmodel first when get snapshot (#10477) 2025-02-27 07:52:18 +00:00
darkskygit
1fd3d618be feat(server): update search model (#10475)
fix AF-2283
2025-02-27 07:24:53 +00:00
donteatfriedrice
7c8ba13aad fix(core): extract a scrollable text renderer fot ai panel (#10469) 2025-02-27 07:00:16 +00:00
liuyi
b3821ad619 fix(server): avoid global rejection when event handler errors (#10467) 2025-02-27 06:25:46 +00:00
fundon
caa4dfedfc fix(editor): adjust black and white in shape text color palettes to pure black and pure white (#10450)
Closes: [BS-2697](https://linear.app/affine-design/issue/BS-2697/检查shape-text-color黑白不映射的pr合并状态)

https://github.com/user-attachments/assets/732612e9-5e43-453f-aef2-5f32f5a08614
2025-02-27 06:05:42 +00:00
zzj3720
18dfad28d7 fix(editor): toDraftModal supports flat data structures (#10466)
fix: PD-2374
fix: BS-2703
2025-02-27 05:16:10 +00:00
akumatus
f43a848e18 feat(core): convert ai think tag to markdown divider (#10459)
Support issue [AF-2282](https://linear.app/affine-design/issue/AF-2282).
2025-02-27 04:43:11 +00:00
doodlewind
8cec22cc64 fix(editor): handle resize in turbo renderer (#10465) 2025-02-27 04:18:37 +00:00
pengx17
be94f3fc17 fix(native): potential sharablecontent icon/name crash (#10464) 2025-02-27 03:19:52 +00:00
Yifeng Wang
e9484e8e15 refactor(editor): remove non null asserts in turbo renderer (#10454) 2025-02-27 10:47:26 +08:00
pengx17
f25266ec88 fix(editor): ai chat panel textarea selection issue (#10461)
fix AF-2244
2025-02-27 02:26:57 +00:00
doodlewind
3252dd7a31 feat(editor): automatically hide canvas optimized blocks (#10451)
Qualified DOM blocks can now be optimized away automatically.

<img alt="image.png" width="500" src="https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/lEGcysB4lFTEbCwZ8jMv/102bf813-154a-4816-9eb0-2c9c0ce01fe7.png">

Since this is under development, verifying state correctness is more important than rendering details.

This won't affect current production version since the passive APIs added to `GfxViewportElement` are disabled by the `enableOptimization = false` config.
2025-02-27 02:10:49 +00:00
akumatus
903d260880 fix(core): ai chat panel scrolling dizziness problem (#10458)
Fix issue [AF-2281](https://linear.app/affine-design/issue/AF-2281).

### What Changed?
- During the re-rendering process of the rich-text editor, the container height is always expanded.
- If the user manually scrolls the chat panel, immediately stop automatically scrolling

[录屏2025-02-27 07.30.08.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/sJGviKxfE3Ap685cl5bj/624ea4fa-b8dd-4cf2-a9be-6997bdabc97b.mov" />](https://app.graphite.dev/media/video/sJGviKxfE3Ap685cl5bj/624ea4fa-b8dd-4cf2-a9be-6997bdabc97b.mov)
2025-02-26 23:59:12 +00:00
Saul-Mirone
2c79d7229f refactor(editor): remove legacy service watcher (#10455)
The main changes in this PR involve replacing the deprecated `BlockServiceWatcher` with the new `LifeCycleWatcher` across multiple files. Here's a detailed breakdown:

1. **Core Architectural Change:**
   - Removed `BlockServiceWatcher` class completely (deleted file)
   - Migrated to `LifeCycleWatcher` as the new standard for watching component lifecycle events

2. **Key Changes in Implementation:**
   - Changed from using `blockService.specSlots` events to using `view.viewUpdated` events
   - Replaced `flavour` static property with `key` static property
   - Updated event handling to use more specific payload type checking

3. **Major File Changes:**
   - Modified multiple block components:
     - Embed synced doc block
     - Frame preview
     - Edgeless root spec
     - AI-related components (code, image, paragraph, etc.)
     - Quick search service
     - Edgeless clipboard

4. **Pattern of Changes:**
   The migration follows a consistent pattern:
   ```typescript
   // Old pattern
   class SomeWatcher extends BlockServiceWatcher {
     static override readonly flavour = 'some:flavour';
     mounted() {
       this.blockService.specSlots.viewConnected.on(...)
     }
   }

   // New pattern
   class SomeWatcher extends LifeCycleWatcher {
     static override key = 'some-watcher';
     mounted() {
       const { view } = this.std;
       view.viewUpdated.on(payload => {
         if (payload.type !== 'block' || payload.method !== 'add') return;
         // Handle event
       });
     }
   }
   ```

5. **Benefits:**
   - More explicit and type-safe event handling
   - Cleaner architecture by removing deprecated code
   - More consistent approach to lifecycle management
   - Better separation of concerns

This appears to be a significant architectural improvement that modernizes the codebase by removing deprecated patterns and standardizing on a more robust lifecycle management system.
2025-02-26 15:15:45 +00:00
Saul-Mirone
fd6d96a38e refactor(editor): use transformer from store when possible (#10453) 2025-02-26 14:15:04 +00:00
Saul-Mirone
1c5e360d7e feat(editor): add widget in viewUpdated slot (#10452) 2025-02-26 13:24:32 +00:00
doodlewind
589622043c fix(editor): list toggle position offset (#10448)
Before:

![image](https://github.com/user-attachments/assets/fbddc396-1078-4c1e-8e2c-c26c6e4a6d61)

After:

<img width="579" alt="image" src="https://github.com/user-attachments/assets/7b049b53-269b-484e-ba76-fa6f46a2004c" />

This centering approach won't affect heading blocks:

<img width="267" alt="image" src="https://github.com/user-attachments/assets/3f3217e3-7e23-43fc-a7e5-33b6eadccc88" />
2025-02-26 12:09:00 +00:00
Saul-Mirone
ce87dcf58e feat(editor): schema extension (#10447)
1. **Major Architectural Change: Schema Management**
   - Moved from `workspace.schema` to `store.schema` throughout the codebase
   - Removed schema property from Workspace and Doc interfaces
   - Added `BlockSchemaExtension` pattern across multiple block types

2. **Block Schema Extensions Added**
   - Added new `BlockSchemaExtension` to numerous block types including:
     - DataView, Surface, Attachment, Bookmark, Code
     - Database, Divider, EdgelessText, Embed blocks (Figma, Github, HTML, etc.)
     - Frame, Image, Latex, List, Note, Paragraph
     - Root, Surface Reference, Table blocks

3. **Import/Export System Updates**
   - Updated import functions to accept `schema` parameter:
     - `importHTMLToDoc`
     - `importHTMLZip`
     - `importMarkdownToDoc`
     - `importMarkdownZip`
     - `importNotionZip`
   - Modified export functions to use new schema pattern

4. **Test Infrastructure Updates**
   - Updated test files to use new schema extensions
   - Modified test document creation to include schema extensions
   - Removed direct schema registration in favor of extensions

5. **Service Layer Changes**
   - Updated various services to use `getAFFiNEWorkspaceSchema()`
   - Modified transformer initialization to use document schema
   - Updated collection initialization patterns

6. **Version Management**
   - Removed version-related properties and methods from:
     - `WorkspaceMetaImpl`
     - `TestMeta`
     - `DocImpl`
   - Removed `blockVersions` and `workspaceVersion/pageVersion`

7. **Store and Extension Updates**
   - Added new store extensions and adapters
   - Updated store initialization patterns
   - Added new schema-related functionality in store extension

This PR represents a significant architectural shift in how schemas are managed, moving from a workspace-centric to a store-centric approach, while introducing a more extensible block schema system through `BlockSchemaExtension`. The changes touch multiple layers of the application including core functionality, services, testing infrastructure, and import/export capabilities.
2025-02-26 11:31:29 +00:00
L-Sun
2732b96d00 fix(editor): overflow of embed github card in edgeless note (#10442)
This PR fixes the overflow of the `embed-github-card` inside edgeless notes.

https://github.com/user-attachments/assets/21775d0f-e4c8-4fcc-86d8-aafb27033358
2025-02-26 09:33:57 +00:00
doodlewind
0f8c837fbe refactor(editor): simplify renderer state (#10441)
The redundant `monitoring` state has been removed. The new `ready` state is used for querying if DOM elements can be safely optimized away.
2025-02-26 08:39:58 +00:00
fundon
c058f94e15 chore(editor): improve color formatting tests (#10429) 2025-02-26 08:19:54 +00:00
darkskygit
d25b216311 feat(server): adapt doc loader for server native (#9942) 2025-02-26 08:05:20 +00:00
CatsJuice
e1fd8f5d80 fix(core): correctly toggle visibility of starter-bar based on doc.isEmpty (#10439) 2025-02-26 07:49:51 +00:00
fundon
866b096304 fix(core): fix doc url parsing with custom domain names (#10444)
Closes: [AF-2279](https://affine-pro.slack.com/archives/C06CTBH5L4R/p1740552397245649?thread_ts=1740547457.278239&cid=C06CTBH5L4R)
2025-02-26 07:35:25 +00:00
doodlewind
e38e59d4e5 refactor(editor): request refresh after finding stale bitmap (#10438)
This ensures a bitmap will be eventually generated after tile got invalidated.
2025-02-26 06:49:09 +00:00
EYHN
7dbc1e300d fix(ios): fix magic link sign in (#10436) 2025-02-26 06:32:16 +00:00
zzj3720
1a9bfeaa2c fix(editor): table block supports parsing rich text (#10430)
fix: BS-2685
2025-02-26 04:56:55 +00:00
doodlewind
97cc814a22 fix(editor): remote cursor color inconsistency (#10437)
Fixed:

![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/lEGcysB4lFTEbCwZ8jMv/c2db021e-6ee9-4022-913c-84b84953d36e.png)
2025-02-26 04:42:05 +00:00
donteatfriedrice
d63f16da5e fix(editor): affine preview root style (#10420)
Fix [BS-2677](https://linear.app/affine-design/issue/BS-2677/linked-doc-embed-view样式错误)

1. Only show the border of embed synced doc block (in note) when hover.
2. Fix affine preview root padding style, set padding only when affine preview root in embed synced doc block (in surface).
3. Only add the footnote config extension to the chat panel and chat block center peek. For footnotes in other page preview scenarios, such as footnote nodes within embed synced doc blocks or embed linked doc blocks, the hover effect should be maintained.
2025-02-26 04:25:24 +00:00
zzj3720
0e4a79959f fix(editor): improve string conversion logic for checkbox property (#10433)
fix: BS-2465

- Add a FALSE_VALUES set containing various falsy string representations

- Support Chinese negation terms like "否", "不", "错", etc.

- Optimize the implementation of cellFromString method
2025-02-25 23:23:00 +00:00
doodlewind
f3911b1b5e fix(editor): discard stale layout bitmap in turbo renderer (#10427)
Fixes this bug caused by stale bitmap:

[Screen Recording 2025-02-24 at 6.10.19 PM.mov <span class="graphite__hidden">(uploaded via Graphite)</span> <img class="graphite__hidden" src="https://app.graphite.dev/api/v1/graphite/video/thumbnail/lEGcysB4lFTEbCwZ8jMv/3e24f4b7-6f95-4c7c-a79a-b8e4ffdb3b10.mov" />](https://app.graphite.dev/media/video/lEGcysB4lFTEbCwZ8jMv/3e24f4b7-6f95-4c7c-a79a-b8e4ffdb3b10.mov)
2025-02-25 10:51:55 +00:00
463 changed files with 9763 additions and 7991 deletions

View File

@@ -44,12 +44,14 @@ runs:
RUSTUP_HOME: ${{ env.DEV_DRIVE }}/.rustup
- name: Set CC
if: ${{ contains(inputs.target, 'linux') && inputs.package != '@affine/native' && inputs.no-build != 'true' }}
if: ${{ contains(inputs.target, 'linux') && inputs.no-build != 'true' }}
working-directory: ${{ env.DEV_DRIVE_WORKSPACE || github.workspace }}
shell: bash
# https://github.com/tree-sitter/tree-sitter/issues/4186
# pass -D_BSD_SOURCE to clang to fix the tree-sitter build issue
run: |
echo "CC=clang" >> "$GITHUB_ENV"
echo "TARGET_CC=clang" >> "$GITHUB_ENV"
echo "CC=clang -D_BSD_SOURCE" >> "$GITHUB_ENV"
echo "TARGET_CC=clang -D_BSD_SOURCE" >> "$GITHUB_ENV"
- name: Cache cargo
uses: Swatinem/rust-cache@v2
@@ -82,7 +84,7 @@ runs:
shell: bash
if: ${{ runner.os == 'Windows' && inputs.no-build != 'true' }}
run: |
yarn workspace ${{ inputs.package }} build --target ${{ inputs.target }} --use-napi-cross
yarn workspace ${{ inputs.package }} build --target ${{ inputs.target }}
env:
DEBUG: 'napi:*'
CARGO_HOME: ${{ env.DEV_DRIVE }}/.cargo

View File

@@ -25,6 +25,7 @@ const {
AFFINE_GOOGLE_CLIENT_ID,
AFFINE_GOOGLE_CLIENT_SECRET,
CLOUD_SQL_IAM_ACCOUNT,
APP_IAM_ACCOUNT,
GCLOUD_CONNECTION_NAME,
GCLOUD_CLOUD_SQL_INTERNAL_ENDPOINT,
REDIS_HOST,
@@ -99,16 +100,22 @@ const createHelmCommand = ({ isDryRun }) => {
`--set-string global.redis.password="${REDIS_PASSWORD}"`,
]
: [];
const serviceAnnotations =
const serviceAnnotations = [
`--set-json web.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
`--set-json graphql.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
`--set-json sync.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
`--set-json doc.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${APP_IAM_ACCOUNT}\\" }"`,
].concat(
isProduction || isBeta || isInternal
? [
`--set-json web.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
`--set-json graphql.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
`--set-json sync.service.annotations=\"{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }\"`,
`--set-json cloud-sql-proxy.serviceAccount.annotations=\"{ \\"iam.gke.io/gcp-service-account\\": \\"${CLOUD_SQL_IAM_ACCOUNT}\\" }\"`,
`--set-json cloud-sql-proxy.nodeSelector=\"{ \\"iam.gke.io/gke-metadata-server-enabled\\": \\"true\\" }\"`,
`--set-json web.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
`--set-json graphql.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
`--set-json sync.service.annotations="{ \\"cloud.google.com/neg\\": \\"{\\\\\\"ingress\\\\\\": true}\\" }"`,
`--set-json cloud-sql-proxy.serviceAccount.annotations="{ \\"iam.gke.io/gcp-service-account\\": \\"${CLOUD_SQL_IAM_ACCOUNT}\\" }"`,
`--set-json cloud-sql-proxy.nodeSelector="{ \\"iam.gke.io/gke-metadata-server-enabled\\": \\"true\\" }"`,
]
: [];
: []
);
const cpu = cpuConfig[buildType];
const resources = cpu
@@ -136,7 +143,7 @@ const createHelmCommand = ({ isDryRun }) => {
`--namespace ${namespace}`,
`--set-string global.app.buildType="${buildType}"`,
`--set global.ingress.enabled=true`,
`--set-json global.ingress.annotations=\"{ \\"kubernetes.io/ingress.class\\": \\"gce\\", \\"kubernetes.io/ingress.allow-http\\": \\"true\\", \\"kubernetes.io/ingress.global-static-ip-name\\": \\"${STATIC_IP_NAME}\\" }\"`,
`--set-json global.ingress.annotations="{ \\"kubernetes.io/ingress.class\\": \\"gce\\", \\"kubernetes.io/ingress.allow-http\\": \\"true\\", \\"kubernetes.io/ingress.global-static-ip-name\\": \\"${STATIC_IP_NAME}\\" }"`,
`--set-string global.ingress.host="${host}"`,
`--set global.objectStorage.r2.enabled=true`,
`--set-string global.objectStorage.r2.accountId="${R2_ACCOUNT_ID}"`,

View File

@@ -26,7 +26,7 @@ podSecurityContext:
resources:
requests:
cpu: '2'
cpu: '1'
memory: 4Gi
probe:

View File

@@ -36,7 +36,7 @@ spec:
- name: NODE_ENV
value: "{{ .Values.env }}"
- name: NODE_OPTIONS
value: "--max-old-space-size=4096"
value: "--max-old-space-size=2048"
- name: NO_COLOR
value: "1"
- name: DEPLOYMENT_TYPE

View File

@@ -71,8 +71,8 @@ podSecurityContext:
resources:
requests:
cpu: '4'
memory: 4Gi
cpu: '2'
memory: 2Gi
probe:
initialDelaySeconds: 20

View File

@@ -36,7 +36,7 @@ spec:
- name: NODE_ENV
value: "{{ .Values.env }}"
- name: NODE_OPTIONS
value: "--max-old-space-size=4096"
value: "--max-old-space-size=2048"
- name: NO_COLOR
value: "1"
- name: DEPLOYMENT_TYPE

View File

@@ -27,8 +27,8 @@ podSecurityContext:
resources:
requests:
cpu: '4'
memory: 4Gi
cpu: '1'
memory: 2Gi
probe:
initialDelaySeconds: 20

View File

@@ -24,11 +24,11 @@ podSecurityContext:
resources:
limits:
cpu: '4'
memory: 8Gi
requests:
cpu: '2'
memory: 4Gi
requests:
cpu: '1'
memory: 2Gi
probe:
initialDelaySeconds: 20

View File

@@ -309,6 +309,10 @@ jobs:
with:
workspace-copy: true
drive-size: 8GB
drive-format: NTFS
env-mapping: |
CARGO_HOME,{{ DEV_DRIVE }}/.cargo
RUSTUP_HOME,{{ DEV_DRIVE }}/.rustup
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
@@ -387,6 +391,28 @@ jobs:
path: dist.tar.gz
if-no-files-found: error
native-unit-test:
name: Native Unit Test
runs-on: ubuntu-latest
needs:
- optimize_ci
- build-native
if: needs.optimize_ci.outputs.skip == 'false'
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
extra-flags: workspaces focus @affine-tools/cli @affine/monorepo @affine/native
electron-install: false
- name: Download affine.linux-x64-gnu.node
uses: actions/download-artifact@v4
with:
name: affine.linux-x64-gnu.node
path: ./packages/frontend/native
- name: Unit Test
run: yarn affine @affine/native test
server-test:
name: Server Test
runs-on: ubuntu-latest
@@ -897,6 +923,7 @@ jobs:
- build-native
- build-server-native
- build-electron-renderer
- native-unit-test
- server-test
- rust-test
- copilot-api-test

View File

@@ -116,6 +116,7 @@ jobs:
REDIS_HOST: ${{ secrets.REDIS_HOST }}
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD }}
CLOUD_SQL_IAM_ACCOUNT: ${{ secrets.CLOUD_SQL_IAM_ACCOUNT }}
APP_IAM_ACCOUNT: ${{ secrets.APP_IAM_ACCOUNT }}
STRIPE_API_KEY: ${{ secrets.STRIPE_API_KEY }}
STRIPE_WEBHOOK_KEY: ${{ secrets.STRIPE_WEBHOOK_KEY }}
STATIC_IP_NAME: ${{ secrets.STATIC_IP_NAME }}

View File

@@ -53,7 +53,7 @@ jobs:
uses: actions/checkout@v4
with:
ref: l10n_crowdin_translations
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:

View File

@@ -1,7 +1,7 @@
# we will make this file shared by prettier|eslint|oxlint
**/node_modules
.yarn
.github
.github/helm
.vscode
.yarnrc.yml
.docker

445
Cargo.lock generated
View File

@@ -44,7 +44,7 @@ dependencies = [
"sha3",
"strum_macros",
"text-splitter",
"thiserror 1.0.69",
"thiserror 2.0.11",
"tiktoken-rs",
"tree-sitter",
"tree-sitter-c",
@@ -69,6 +69,8 @@ dependencies = [
"core-foundation",
"coreaudio-rs",
"dispatch2",
"libc",
"mp3lame-encoder",
"napi",
"napi-build",
"napi-derive",
@@ -76,6 +78,7 @@ dependencies = [
"objc2-foundation",
"rubato",
"screencapturekit",
"symphonia",
"thiserror 2.0.11",
"uuid",
]
@@ -273,9 +276,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.95"
version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4"
[[package]]
name = "arbitrary"
@@ -286,6 +289,12 @@ dependencies = [
"derive_arbitrary",
]
[[package]]
name = "arrayvec"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "async-compat"
version = "0.2.4"
@@ -338,6 +347,15 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "autotools"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef941527c41b0fc0dd48511a8154cd5fc7e29200a0ff8b7203c5d777dbc795cf"
dependencies = [
"cc",
]
[[package]]
name = "backtrace"
version = "0.3.74"
@@ -500,6 +518,12 @@ version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
version = "1.5.0"
@@ -552,9 +576,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.2.12"
version = "1.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "755717a7de9ec452bf7f3f1a3099085deabd7f2962b861dae91ecd7a365903d2"
checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
dependencies = [
"shlex",
]
@@ -608,16 +632,16 @@ dependencies = [
[[package]]
name = "chrono"
version = "0.4.39"
version = "0.4.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.6",
"windows-link",
]
[[package]]
@@ -660,9 +684,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.28"
version = "4.5.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff"
checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767"
dependencies = [
"clap_builder",
"clap_derive",
@@ -670,9 +694,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.27"
version = "4.5.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863"
dependencies = [
"anstream",
"anstyle",
@@ -885,9 +909,9 @@ dependencies = [
[[package]]
name = "criterion2"
version = "2.0.0"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09db22066fd79bd628faf416dac96e44054deb00531601bcc20c6d12506b3701"
checksum = "7b43b9cdbf592c78d882f2a3b9e6ebe8aedc749ef84915103a0248802ce2f6b3"
dependencies = [
"anes",
"bpaf",
@@ -952,9 +976,18 @@ dependencies = [
[[package]]
name = "ctor"
version = "0.3.0"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f06b1425736ba96096116f063c9d10be2352a7cde0cbea829a717008e114aec9"
checksum = "21d960ecacd0a1bf55e73144b72de745e7bf275c7952c50e36e8af0a0cb7ab1f"
dependencies = [
"ctor-proc-macro",
]
[[package]]
name = "ctor-proc-macro"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c426d2ba3e525b39c1f0a9ba41b9fe61878dee11fa4e4a76b6ab440f46c5db5d"
[[package]]
name = "dashmap"
@@ -1099,9 +1132,9 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "either"
version = "1.13.0"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d"
dependencies = [
"serde",
]
@@ -1117,9 +1150,9 @@ dependencies = [
[[package]]
name = "equivalent"
version = "1.0.1"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
@@ -1173,6 +1206,12 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "extended"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af9673d8203fcb076b19dfd17e38b3d4ae9f44959416ea532ce72415a6020365"
[[package]]
name = "fancy-regex"
version = "0.13.0"
@@ -1198,9 +1237,9 @@ checksum = "e7ef3d5e8ae27277c8285ac43ed153158178ef0f79567f32024ca8140a0c7cd8"
[[package]]
name = "flate2"
version = "1.0.35"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -1874,9 +1913,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.169"
version = "0.2.170"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
[[package]]
name = "libloading"
@@ -1923,9 +1962,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "litemap"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
[[package]]
name = "lock_api"
@@ -1939,9 +1978,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.25"
version = "0.4.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
[[package]]
name = "loom"
@@ -2075,9 +2114,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.3"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8402cab7aefae129c6977bb0ff1b8fd9a04eb5b51efc50a70bea51cda0c7924"
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
dependencies = [
"adler2",
]
@@ -2093,6 +2132,27 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "mp3lame-encoder"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc8c8b5cdbe788ccd1098c3d3635298a011cffdebdd3460c9ca5060a7551557b"
dependencies = [
"libc",
"mp3lame-sys",
]
[[package]]
name = "mp3lame-sys"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acaec8842b2ebd61692a6c8c2b9f3edbf5c36e5e5c4677b5911430eaf859377c"
dependencies = [
"autotools",
"cc",
"libc",
]
[[package]]
name = "nanoid"
version = "0.4.0"
@@ -2104,9 +2164,9 @@ dependencies = [
[[package]]
name = "napi"
version = "3.0.0-alpha.28"
version = "3.0.0-alpha.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dd957e2cc4bd62b730b10ff1f35775f8a81dac84a3bfac273b0ec4336f53ab8"
checksum = "b1911b4f0d33fbcb5f46ff68319ec053ab8a655f3a17440eae1246a23ba2ad78"
dependencies = [
"anyhow",
"bitflags 2.8.0",
@@ -2120,15 +2180,15 @@ dependencies = [
[[package]]
name = "napi-build"
version = "2.1.4"
version = "2.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db836caddef23662b94e16bf1f26c40eceb09d6aee5d5b06a7ac199320b69b19"
checksum = "40685973218af4aa4b42486652692c294c44b5a67e4b2202df721c9063f2e51c"
[[package]]
name = "napi-derive"
version = "3.0.0-alpha.26"
version = "3.0.0-alpha.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0f0b6f3f77925d8fd2030855af659ce428a7bb6e10e94852e226f509186ba7c"
checksum = "c8097918a9af1976700eac6944b120b65ad17bf6d38906703d2b68e17ee89256"
dependencies = [
"convert_case 0.7.1",
"napi-derive-backend",
@@ -2139,9 +2199,9 @@ dependencies = [
[[package]]
name = "napi-derive-backend"
version = "2.0.0-alpha.26"
version = "2.0.0-alpha.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c694bb49a2fa84dd9542d51eece39a57519f9cf1fc2deefa9d119ab8181e374d"
checksum = "8e5adc92fcdec3aa09f591bd2b139d7c669399f34b8211fe653641b52d40d3b3"
dependencies = [
"convert_case 0.7.1",
"proc-macro2",
@@ -2629,9 +2689,9 @@ dependencies = [
[[package]]
name = "pulldown-cmark"
version = "0.12.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f86ba2052aebccc42cbbb3ed234b8b13ce76f75c3551a303cb2bcffcff12bb14"
checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0"
dependencies = [
"bitflags 2.8.0",
"memchr",
@@ -2671,8 +2731,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.0",
"zerocopy 0.8.16",
"rand_core 0.9.2",
"zerocopy 0.8.21",
]
[[package]]
@@ -2692,7 +2752,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.0",
"rand_core 0.9.2",
]
[[package]]
@@ -2706,12 +2766,12 @@ dependencies = [
[[package]]
name = "rand_core"
version = "0.9.0"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c"
dependencies = [
"getrandom 0.3.1",
"zerocopy 0.8.16",
"zerocopy 0.8.21",
]
[[package]]
@@ -2774,9 +2834,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.8"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f"
dependencies = [
"bitflags 2.8.0",
]
@@ -2827,15 +2887,14 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "ring"
version = "0.17.8"
version = "0.17.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.15",
"libc",
"spin",
"untrusted",
"windows-sys 0.52.0",
]
@@ -2968,9 +3027,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.22"
version = "0.23.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7"
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
dependencies = [
"once_cell",
"ring",
@@ -3086,18 +3145,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.217"
version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.217"
version = "1.0.218"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b"
dependencies = [
"proc-macro2",
"quote",
@@ -3106,9 +3165,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.138"
version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6"
dependencies = [
"indexmap",
"itoa",
@@ -3218,9 +3277,9 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.13.2"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
dependencies = [
"serde",
]
@@ -3503,9 +3562,9 @@ dependencies = [
[[package]]
name = "string_cache_codegen"
version = "0.5.3"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244292f3441c89febe5b5bdfbb6863aeaf4f64da810ea3050fd927b27b8d92ce"
checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
dependencies = [
"phf_generator 0.11.3",
"phf_shared 0.11.3",
@@ -3532,18 +3591,18 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.26.3"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.26.4"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8"
dependencies = [
"heck",
"proc-macro2",
@@ -3558,6 +3617,202 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "symphonia"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "815c942ae7ee74737bb00f965fa5b5a2ac2ce7b6c01c0cc169bbeaf7abd5f5a9"
dependencies = [
"lazy_static",
"symphonia-bundle-flac",
"symphonia-bundle-mp3",
"symphonia-codec-aac",
"symphonia-codec-adpcm",
"symphonia-codec-alac",
"symphonia-codec-pcm",
"symphonia-codec-vorbis",
"symphonia-core",
"symphonia-format-caf",
"symphonia-format-isomp4",
"symphonia-format-mkv",
"symphonia-format-ogg",
"symphonia-format-riff",
"symphonia-metadata",
]
[[package]]
name = "symphonia-bundle-flac"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72e34f34298a7308d4397a6c7fbf5b84c5d491231ce3dd379707ba673ab3bd97"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-bundle-mp3"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c01c2aae70f0f1fb096b6f0ff112a930b1fb3626178fba3ae68b09dce71706d4"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "symphonia-codec-aac"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdbf25b545ad0d3ee3e891ea643ad115aff4ca92f6aec472086b957a58522f70"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-adpcm"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c94e1feac3327cd616e973d5be69ad36b3945f16b06f19c6773fc3ac0b426a0f"
dependencies = [
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-alac"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d8a6666649a08412906476a8b0efd9b9733e241180189e9f92b09c08d0e38f3"
dependencies = [
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-pcm"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f395a67057c2ebc5e84d7bb1be71cce1a7ba99f64e0f0f0e303a03f79116f89b"
dependencies = [
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-codec-vorbis"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a98765fb46a0a6732b007f7e2870c2129b6f78d87db7987e6533c8f164a9f30"
dependencies = [
"log",
"symphonia-core",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-core"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "798306779e3dc7d5231bd5691f5a813496dc79d3f56bf82e25789f2094e022c3"
dependencies = [
"arrayvec",
"bitflags 1.3.2",
"bytemuck",
"lazy_static",
"log",
"rustfft",
]
[[package]]
name = "symphonia-format-caf"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e43c99c696a388295a29fe71b133079f5d8b18041cf734c5459c35ad9097af50"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "symphonia-format-isomp4"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abfdf178d697e50ce1e5d9b982ba1b94c47218e03ec35022d9f0e071a16dc844"
dependencies = [
"encoding_rs",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-format-mkv"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bb43471a100f7882dc9937395bd5ebee8329298e766250b15b3875652fe3d6f"
dependencies = [
"lazy_static",
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-format-ogg"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ada3505789516bcf00fc1157c67729eded428b455c27ca370e41f4d785bfa931"
dependencies = [
"log",
"symphonia-core",
"symphonia-metadata",
"symphonia-utils-xiph",
]
[[package]]
name = "symphonia-format-riff"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f7be232f962f937f4b7115cbe62c330929345434c834359425e043bfd15f50"
dependencies = [
"extended",
"log",
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "symphonia-metadata"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc622b9841a10089c5b18e99eb904f4341615d5aa55bbf4eedde1be721a4023c"
dependencies = [
"encoding_rs",
"lazy_static",
"log",
"symphonia-core",
]
[[package]]
name = "symphonia-utils-xiph"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "484472580fa49991afda5f6550ece662237b00c6f562c7d9638d1b086ed010fe"
dependencies = [
"symphonia-core",
"symphonia-metadata",
]
[[package]]
name = "syn"
version = "1.0.109"
@@ -3599,9 +3854,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.16.0"
version = "3.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
dependencies = [
"cfg-if",
"fastrand",
@@ -3624,9 +3879,9 @@ dependencies = [
[[package]]
name = "text-splitter"
version = "0.22.0"
version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5cb76f2930deed7b89fd345fff5361813fb8feb7b6f0b80d26c4aba391819dd"
checksum = "698b22fc8ce5bef13475143a43e87df82440e66b2a18d7655d1425dd36580a53"
dependencies = [
"ahash",
"auto_enums",
@@ -3912,9 +4167,9 @@ dependencies = [
[[package]]
name = "tree-sitter"
version = "0.25.1"
version = "0.25.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a802c93485fb6781d27e27cb5927f6b00ff8d26b56c70af87267be7e99def97"
checksum = "5168a515fe492af54c5cc8800ff8c840be09fa5168de45838afaecd3e008bce4"
dependencies = [
"cc",
"regex",
@@ -3996,9 +4251,9 @@ dependencies = [
[[package]]
name = "tree-sitter-language"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38eee4db33814de3d004de9d8d825627ed3320d0989cce0dea30efaf5be4736c"
checksum = "c4013970217383f67b18aef68f6fb2e8d409bc5755227092d32efb0422ba24b8"
[[package]]
name = "tree-sitter-python"
@@ -4051,9 +4306,9 @@ dependencies = [
[[package]]
name = "typenum"
version = "1.17.0"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unicase"
@@ -4069,9 +4324,9 @@ checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"
[[package]]
name = "unicode-ident"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
[[package]]
name = "unicode-normalization"
@@ -4251,9 +4506,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.13.1"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
dependencies = [
"getrandom 0.3.1",
]
@@ -4546,6 +4801,12 @@ dependencies = [
"syn 2.0.98",
]
[[package]]
name = "windows-link"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
[[package]]
name = "windows-result"
version = "0.1.2"
@@ -4724,9 +4985,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.2"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603"
checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
dependencies = [
"memchr",
]
@@ -4839,11 +5100,11 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.16"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b8c07a70861ce02bad1607b5753ecb2501f67847b9f9ada7c160fff0ec6300c"
checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478"
dependencies = [
"zerocopy-derive 0.8.16",
"zerocopy-derive 0.8.21",
]
[[package]]
@@ -4859,9 +5120,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.8.16"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5226bc9a9a9836e7428936cde76bb6b22feea1a8bfdbc0d241136e4d13417e25"
checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2"
dependencies = [
"proc-macro2",
"quote",
@@ -4870,18 +5131,18 @@ dependencies = [
[[package]]
name = "zerofrom"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
dependencies = [
"zerofrom-derive",
]
[[package]]
name = "zerofrom-derive"
version = "0.1.5"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -8,46 +8,72 @@ members = [
"./packages/frontend/native/schema",
"./packages/frontend/native/sqlite_v1",
]
resolver = "2"
resolver = "3"
[workspace.package]
edition = "2024"
[workspace.dependencies]
affine_common = { path = "./packages/common/native" }
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
anyhow = "1"
base64-simd = "0.8"
block2 = "0.6"
chrono = "0.4"
core-foundation = "0.10"
coreaudio-rs = "0.12"
criterion2 = { version = "2", default-features = false }
dispatch2 = "0.2"
dotenvy = "0.15"
file-format = { version = "0.26", features = ["reader"] }
homedir = "0.3"
mimalloc = "0.1"
napi = { version = "3.0.0-alpha.12", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
napi-build = { version = "2" }
napi-derive = { version = "3.0.0-alpha.12" }
notify = { version = "8", features = ["serde"] }
objc2 = "0.6"
objc2-foundation = "0.3"
once_cell = "1"
parking_lot = "0.12"
rand = "0.9"
rayon = "1.10"
rubato = "0.16"
screencapturekit = "0.3"
serde = "1"
serde_json = "1"
sha3 = "0.10"
sqlx = { version = "0.8", default-features = false, features = ["chrono", "macros", "migrate", "runtime-tokio", "sqlite", "tls-rustls"] }
thiserror = "2"
tiktoken-rs = "0.6"
tokio = "1.37"
uniffi = "0.29"
uuid = "1.8"
v_htmlescape = "0.15"
y-octo = { git = "https://github.com/y-crdt/y-octo.git", branch = "main" }
affine_common = { path = "./packages/common/native" }
affine_nbstore = { path = "./packages/frontend/native/nbstore" }
anyhow = "1"
base64-simd = "0.8"
block2 = "0.6"
chrono = "0.4"
core-foundation = "0.10"
coreaudio-rs = "0.12"
criterion2 = { version = "3", default-features = false }
dispatch2 = "0.2"
docx-parser = { git = "https://github.com/toeverything/docx-parser" }
dotenvy = "0.15"
file-format = { version = "0.26", features = ["reader"] }
homedir = "0.3"
infer = { version = "0.19.0" }
libc = "0.2"
mimalloc = "0.1"
mp3lame-encoder = "0.2"
napi = { version = "3.0.0-alpha.31", features = ["async", "chrono_date", "error_anyhow", "napi9", "serde"] }
napi-build = { version = "2" }
napi-derive = { version = "3.0.0-alpha.28" }
notify = { version = "8", features = ["serde"] }
objc2 = "0.6"
objc2-foundation = "0.3"
once_cell = "1"
parking_lot = "0.12"
path-ext = "0.1.1"
pdf-extract = "0.8.2"
rand = "0.9"
rayon = "1.10"
readability = { version = "0.3.0", default-features = false }
rubato = "0.16"
screencapturekit = "0.3"
serde = "1"
serde_json = "1"
sha3 = "0.10"
sqlx = { version = "0.8", default-features = false, features = ["chrono", "macros", "migrate", "runtime-tokio", "sqlite", "tls-rustls"] }
strum_macros = "0.27.0"
symphonia = { version = "0.5", features = ["all", "opt-simd"] }
text-splitter = "0.24"
thiserror = "2"
tiktoken-rs = "0.6"
tokio = "1.37"
tree-sitter = { version = "0.25" }
tree-sitter-c = { version = "0.23" }
tree-sitter-c-sharp = { version = "0.23" }
tree-sitter-cpp = { version = "0.23" }
tree-sitter-go = { version = "0.23" }
tree-sitter-java = { version = "0.23" }
tree-sitter-javascript = { version = "0.23" }
tree-sitter-kotlin-ng = { version = "1.1" }
tree-sitter-python = { version = "0.23" }
tree-sitter-rust = { version = "0.23" }
tree-sitter-scala = { version = "0.23" }
tree-sitter-typescript = { version = "0.23" }
uniffi = "0.29"
url = { version = "2.5" }
uuid = "1.8"
v_htmlescape = "0.15"
y-octo = { git = "https://github.com/y-crdt/y-octo.git", branch = "main" }
[profile.dev.package.sqlx-macros]
opt-level = 3

View File

@@ -160,6 +160,7 @@ We would also like to give thanks to open-source projects that make AFFiNE possi
- [Jotai](https://github.com/pmndrs/jotai) - Primitive and flexible state management for React.
- [async-call-rpc](https://github.com/Jack-Works/async-call-rpc) - A lightweight JSON RPC client & server.
- [Vite](https://github.com/vitejs/vite) - Next generation frontend tooling.
- [lame](https://lame.sourceforge.io/) - High quality MPEG Audio Layer III (MP3) encoder.
- Other upstream [dependencies](https://github.com/toeverything/AFFiNE/network/dependencies).
Thanks a lot to the community for providing such powerful and simple libraries, so that we can focus more on the implementation of the product logic, and we hope that in the future our projects will also provide a more easy-to-use knowledge base for everyone.

View File

@@ -30,7 +30,11 @@ import { AttachmentEmbedProvider } from './embed.js';
import { styles } from './styles.js';
import { checkAttachmentBlob, downloadAttachmentBlob } from './utils.js';
@Peekable()
@Peekable({
enableOn: ({ model }: AttachmentBlockComponent) => {
return model.type.endsWith('pdf');
},
})
export class AttachmentBlockComponent extends CaptionedBlockComponent<AttachmentBlockModel> {
static override styles = styles;

View File

@@ -28,7 +28,7 @@
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"shiki": "^2.0.0",
"shiki": "^3.0.0",
"zod": "^3.23.8"
},
"exports": {

View File

@@ -182,17 +182,17 @@ export class CodeBlockComponent extends CaptionedBlockComponent<
// TODO: move to service for better performance
this.bindHotKey({
Backspace: ctx => {
const state = ctx.get('keyboardState');
const event = ctx.get('defaultState').event;
const textSelection = selectionManager.find(TextSelection);
if (!textSelection) {
state.raw.preventDefault();
event.preventDefault();
return;
}
const from = textSelection.from;
if (from.index === 0 && from.length === 0) {
state.raw.preventDefault();
event.preventDefault();
selectionManager.setGroup('note', [
selectionManager.create(BlockSelection, { blockId: this.blockId }),
]);
@@ -215,7 +215,7 @@ export class CodeBlockComponent extends CaptionedBlockComponent<
index: index,
length: 0,
});
state.raw.preventDefault();
event.preventDefault();
return true;
}

View File

@@ -8,7 +8,6 @@ import {
getMoreMenuConfig,
} from '@blocksuite/affine-components/toolbar';
import type { CodeBlockModel } from '@blocksuite/affine-model';
import { PAGE_HEADER_HEIGHT } from '@blocksuite/affine-shared/consts';
import {
BlockSelection,
TextSelection,
@@ -92,7 +91,6 @@ export class AffineCodeToolbarWidget extends WidgetComponent<
shift({
crossAxis: true,
padding: {
top: PAGE_HEADER_HEIGHT + 12,
bottom: 12,
right: 12,
},

View File

@@ -1,3 +1,4 @@
import { affineTextStyles } from '@blocksuite/affine-components/rich-text';
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
import { ShadowlessElement } from '@blocksuite/block-std';
import { type DeltaInsert, ZERO_WIDTH_SPACE } from '@blocksuite/inline';
@@ -16,7 +17,25 @@ export class AffineCodeUnit extends ShadowlessElement {
}
override render() {
const plainContent = html`<span
if (this.delta.attributes?.link && this.codeBlock) {
return html`<affine-link
.std=${this.codeBlock.std}
.delta=${this.delta}
></affine-link>`;
}
let style = this.delta.attributes
? affineTextStyles(this.delta.attributes)
: {};
if (this.delta.attributes?.code) {
style = {
...style,
'font-size': 'calc(var(--affine-font-base) - 3px)',
padding: '0px 4px 2px',
};
}
const plainContent = html`<span style=${styleMap(style)}
><v-text .str=${this.delta.insert}></v-text
></span>`;
@@ -53,12 +72,13 @@ export class AffineCodeUnit extends ShadowlessElement {
endOffset - token.offset
);
return html`<v-text
.str=${content}
return html`<span
style=${styleMap({
color: token.color,
...style,
})}
></v-text>`;
><v-text .str=${content}></v-text
></span>`;
} else {
const firstToken = includedTokens[0];
const lastToken = includedTokens[includedTokens.length - 1];
@@ -79,6 +99,7 @@ export class AffineCodeUnit extends ShadowlessElement {
.str=${token.content}
style=${styleMap({
color: token.color,
...style,
})}
></v-text>`;
});

View File

@@ -1,10 +1,6 @@
import { css } from 'lit';
export const codeBlockStyles = css`
affine-code {
position: relative;
}
.affine-code-block-container {
font-size: var(--affine-font-xs);
line-height: var(--affine-line-height);

View File

@@ -5,7 +5,11 @@ import {
type InsertToPosition,
} from '@blocksuite/affine-shared/utils';
import type { DataViewDataType } from '@blocksuite/data-view';
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
import {
BlockModel,
BlockSchemaExtension,
defineBlockSchema,
} from '@blocksuite/store';
type Props = {
title: string;
@@ -93,3 +97,6 @@ export const DataViewBlockSchema = defineBlockSchema({
return new DataViewBlockModel();
},
});
export const DataViewBlockSchemaExtension =
BlockSchemaExtension(DataViewBlockSchema);

View File

@@ -1,4 +1,3 @@
import { clamp } from '@blocksuite/affine-shared/utils';
import {
createPropertyConvert,
getTagColor,
@@ -6,6 +5,7 @@ import {
} from '@blocksuite/data-view';
import { presetPropertyConverts } from '@blocksuite/data-view/property-presets';
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
import { clamp } from '@blocksuite/global/utils';
import { nanoid, Text } from '@blocksuite/store';
import { richTextPropertyModelConfig } from './rich-text/define.js';

View File

@@ -32,7 +32,7 @@
"zod": "^3.23.8"
},
"devDependencies": {
"vitest": "3.0.6"
"vitest": "3.0.7"
},
"exports": {
".": "./src/index.ts",

View File

@@ -9,6 +9,7 @@ import {
EMBED_CARD_WIDTH,
} from '@blocksuite/affine-shared/consts';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { findAncestorModel } from '@blocksuite/affine-shared/utils';
import type { BlockService } from '@blocksuite/block-std';
import type { GfxCompatibleProps } from '@blocksuite/block-std/gfx';
import type { BlockModel } from '@blocksuite/store';
@@ -57,7 +58,15 @@ export class EmbedBlockComponent<
) {
this.style.display = 'block';
if (this.std.get(DocModeProvider).getEditorMode() === 'edgeless') {
const insideNote = findAncestorModel(
this.model,
m => m.flavour === 'affine:note'
);
if (
!insideNote &&
this.std.get(DocModeProvider).getEditorMode() === 'edgeless'
) {
this.style.minWidth = `${EMBED_CARD_MIN_WIDTH}px`;
}
}

View File

@@ -304,11 +304,12 @@ export function getDocContentWithMaxLength(doc: Store, maxlength = 500) {
export function getTitleFromSelectedModels(selectedModels: DraftModel[]) {
const firstBlock = selectedModels[0];
if (
matchModels(firstBlock, [ParagraphBlockModel]) &&
firstBlock.type.startsWith('h')
) {
return firstBlock.text.toString();
const isParagraph = (
model: DraftModel
): model is DraftModel<ParagraphBlockModel> =>
model.flavour === 'affine:paragraph';
if (isParagraph(firstBlock) && firstBlock.type.startsWith('h')) {
return firstBlock.text?.toString();
}
return undefined;
}
@@ -394,7 +395,7 @@ export async function convertSelectedBlocksToLinkedDoc(
'before'
);
// delete selected elements
models.forEach(model => doc.deleteBlock(model));
models.forEach(model => doc.deleteBlock(model.id));
return linkedDoc;
}

View File

@@ -10,13 +10,9 @@ import { classMap } from 'lit/directives/class-map.js';
import { styleMap } from 'lit/directives/style-map.js';
import { EmbedBlockComponent } from '../common/embed-block-element.js';
import type { EmbedFigmaBlockService } from './embed-figma-service.js';
import { FigmaIcon, styles } from './styles.js';
export class EmbedFigmaBlockComponent extends EmbedBlockComponent<
EmbedFigmaModel,
EmbedFigmaBlockService
> {
export class EmbedFigmaBlockComponent extends EmbedBlockComponent<EmbedFigmaModel> {
static override styles = styles;
override _cardStyle: (typeof EmbedFigmaStyles)[number] = 'figma';

View File

@@ -2,22 +2,13 @@ import {
EmbedFigmaBlockSchema,
EmbedFigmaStyles,
} from '@blocksuite/affine-model';
import { EmbedOptionProvider } from '@blocksuite/affine-shared/services';
import { BlockService } from '@blocksuite/block-std';
import { EmbedOptionConfig } from '@blocksuite/affine-shared/services';
import { figmaUrlRegex } from './embed-figma-model.js';
export class EmbedFigmaBlockService extends BlockService {
static override readonly flavour = EmbedFigmaBlockSchema.model.flavour;
override mounted() {
super.mounted();
this.std.get(EmbedOptionProvider).registerEmbedBlockOptions({
flavour: this.flavour,
urlRegex: figmaUrlRegex,
styles: EmbedFigmaStyles,
viewType: 'embed',
});
}
}
export const EmbedFigmaBlockOptionConfig = EmbedOptionConfig({
flavour: EmbedFigmaBlockSchema.model.flavour,
urlRegex: figmaUrlRegex,
styles: EmbedFigmaStyles,
viewType: 'embed',
});

View File

@@ -3,15 +3,15 @@ import type { ExtensionType } from '@blocksuite/store';
import { literal } from 'lit/static-html.js';
import { EmbedFigmaBlockAdapterExtensions } from './adapters/extension.js';
import { EmbedFigmaBlockService } from './embed-figma-service.js';
import { EmbedFigmaBlockOptionConfig } from './embed-figma-service.js';
export const EmbedFigmaBlockSpec: ExtensionType[] = [
FlavourExtension('affine:embed-figma'),
EmbedFigmaBlockService,
BlockViewExtension('affine:embed-figma', model => {
return model.parent?.flavour === 'affine:surface'
? literal`affine-embed-edgeless-figma-block`
: literal`affine-embed-figma-block`;
}),
EmbedFigmaBlockAdapterExtensions,
EmbedFigmaBlockOptionConfig,
].flat();

View File

@@ -4,7 +4,7 @@ import {
EmbedGithubStyles,
} from '@blocksuite/affine-model';
import {
EmbedOptionProvider,
EmbedOptionConfig,
LinkPreviewerService,
} from '@blocksuite/affine-shared/services';
import { BlockService } from '@blocksuite/block-std';
@@ -26,15 +26,11 @@ export class EmbedGithubBlockService extends BlockService {
signal
);
};
override mounted() {
super.mounted();
this.std.get(EmbedOptionProvider).registerEmbedBlockOptions({
flavour: this.flavour,
urlRegex: githubUrlRegex,
styles: EmbedGithubStyles,
viewType: 'card',
});
}
}
export const EmbedGithubBlockOptionConfig = EmbedOptionConfig({
flavour: EmbedGithubBlockSchema.model.flavour,
urlRegex: githubUrlRegex,
styles: EmbedGithubStyles,
viewType: 'card',
});

View File

@@ -3,7 +3,10 @@ import type { ExtensionType } from '@blocksuite/store';
import { literal } from 'lit/static-html.js';
import { EmbedGithubBlockAdapterExtensions } from './adapters/extension.js';
import { EmbedGithubBlockService } from './embed-github-service.js';
import {
EmbedGithubBlockOptionConfig,
EmbedGithubBlockService,
} from './embed-github-service.js';
export const EmbedGithubBlockSpec: ExtensionType[] = [
FlavourExtension('affine:embed-github'),
@@ -14,4 +17,5 @@ export const EmbedGithubBlockSpec: ExtensionType[] = [
: literal`affine-embed-github-block`;
}),
EmbedGithubBlockAdapterExtensions,
EmbedGithubBlockOptionConfig,
].flat();

View File

@@ -2,6 +2,7 @@ import { css, html } from 'lit';
export const styles = css`
.affine-embed-github-block {
container: affine-embed-github-block / inline-size;
box-sizing: border-box;
display: flex;
width: 100%;
@@ -24,6 +25,7 @@ export const styles = css`
padding: 12px;
border-radius: var(--1, 0px);
opacity: var(--add, 1);
overflow: hidden;
}
.affine-embed-github-content-title {
@@ -376,6 +378,15 @@ export const styles = css`
display: none;
}
}
@container affine-embed-github-block (width < 375px) {
.affine-embed-github-content {
width: 100%;
}
.affine-embed-github-banner {
display: none;
}
}
`;
export const GithubIcon = html`<svg

View File

@@ -6,7 +6,6 @@ import {
EMBED_CARD_HEIGHT,
EMBED_CARD_WIDTH,
} from '@blocksuite/affine-shared/consts';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import {
cloneReferenceInfoWithoutAliases,
isNewTabTrigger,
@@ -23,14 +22,6 @@ export class EmbedEdgelessLinkedDocBlockComponent extends toEdgelessEmbedBlock(
override convertToEmbed = () => {
const { id, doc, caption, xywh } = this.model;
// synced doc entry controlled by flag
const isSyncedDocEnabled = doc
.get(FeatureFlagService)
.getFlag('enable_synced_doc_block');
if (!isSyncedDocEnabled) {
return;
}
const style = 'syncedDoc';
const bound = Bound.deserialize(xywh);
bound.w = EMBED_CARD_WIDTH[style];

View File

@@ -14,7 +14,6 @@ import {
import {
DocDisplayMetaProvider,
DocModeProvider,
FeatureFlagService,
OpenDocExtensionIdentifier,
type OpenDocMode,
ThemeProvider,
@@ -131,14 +130,6 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const { doc, caption } = this.model;
// synced doc entry controlled by flag
const isSyncedDocEnabled = doc
.get(FeatureFlagService)
.getFlag('enable_synced_doc_block');
if (!isSyncedDocEnabled) {
return;
}
const parent = doc.getParent(this.model);
if (!parent) {
return;

View File

@@ -3,7 +3,7 @@ import {
type EmbedLoomModel,
EmbedLoomStyles,
} from '@blocksuite/affine-model';
import { EmbedOptionProvider } from '@blocksuite/affine-shared/services';
import { EmbedOptionConfig } from '@blocksuite/affine-shared/services';
import { BlockService } from '@blocksuite/block-std';
import { loomUrlRegex } from './embed-loom-model.js';
@@ -15,15 +15,11 @@ export class EmbedLoomBlockService extends BlockService {
queryUrlData = (embedLoomModel: EmbedLoomModel, signal?: AbortSignal) => {
return queryEmbedLoomData(embedLoomModel, signal);
};
override mounted() {
super.mounted();
this.std.get(EmbedOptionProvider).registerEmbedBlockOptions({
flavour: this.flavour,
urlRegex: loomUrlRegex,
styles: EmbedLoomStyles,
viewType: 'embed',
});
}
}
export const EmbedLoomBlockOptionConfig = EmbedOptionConfig({
flavour: EmbedLoomBlockSchema.model.flavour,
urlRegex: loomUrlRegex,
styles: EmbedLoomStyles,
viewType: 'embed',
});

View File

@@ -3,7 +3,10 @@ import type { ExtensionType } from '@blocksuite/store';
import { literal } from 'lit/static-html.js';
import { EmbedLoomBlockAdapterExtensions } from './adapters/extension.js';
import { EmbedLoomBlockService } from './embed-loom-service.js';
import {
EmbedLoomBlockOptionConfig,
EmbedLoomBlockService,
} from './embed-loom-service.js';
export const EmbedLoomBlockSpec: ExtensionType[] = [
FlavourExtension('affine:embed-loom'),
@@ -14,4 +17,5 @@ export const EmbedLoomBlockSpec: ExtensionType[] = [
: literal`affine-embed-loom-block`;
}),
EmbedLoomBlockAdapterExtensions,
EmbedLoomBlockOptionConfig,
].flat();

View File

@@ -26,9 +26,9 @@ import {
} from '@blocksuite/affine-shared/utils';
import {
BlockSelection,
BlockServiceWatcher,
BlockStdScope,
type EditorHost,
LifeCycleWatcher,
} from '@blocksuite/block-std';
import {
GfxControllerIdentifier,
@@ -124,27 +124,31 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this.std.getOptional(EditorSettingProvider) ??
signal(GeneralSettingSchema.parse({}));
class EmbedSyncedDocWatcher extends BlockServiceWatcher {
static override readonly flavour = 'affine:embed-synced-doc';
class EmbedSyncedDocWatcher extends LifeCycleWatcher {
static override key = 'embed-synced-doc-watcher';
override mounted() {
const disposableGroup = this.blockService.disposables;
const slots = this.blockService.specSlots;
disposableGroup.add(
slots.viewConnected.on(({ component }) => {
const nextComponent = component as EmbedSyncedDocBlockComponent;
override mounted(): void {
const { view } = this.std;
view.viewUpdated.on(payload => {
if (
payload.type !== 'block' ||
payload.view.model.flavour !== 'affine:embed-synced-doc'
) {
return;
}
const nextComponent = payload.view as EmbedSyncedDocBlockComponent;
if (payload.method === 'add') {
nextComponent.depth = nextDepth;
currentDisposables.add(() => {
nextComponent.depth = 0;
});
})
);
disposableGroup.add(
slots.viewDisconnected.on(({ component }) => {
const nextComponent = component as EmbedSyncedDocBlockComponent;
return;
}
if (payload.method === 'delete') {
nextComponent.depth = 0;
})
);
return;
}
});
}
}
@@ -231,6 +235,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
[theme]: true,
surface: false,
selected: this.selected$.value,
'show-hover-border': true,
})}
@click=${this._handleClick}
style=${containerStyleMap}

View File

@@ -57,10 +57,13 @@ export const blockStyles = css`
}
.affine-embed-synced-doc-container {
border: 1px solid var(--affine-border-color);
border: 1px solid transparent;
border-radius: 8px;
overflow: hidden;
}
.affine-embed-synced-doc-container.show-hover-border:hover {
border-color: var(--affine-border-color);
}
.affine-embed-synced-doc-container.page {
display: block;
width: 100%;
@@ -151,7 +154,12 @@ export const blockStyles = css`
}
.affine-embed-synced-doc-container.surface {
border-color: var(--affine-border-color);
background: var(--affine-background-primary-color);
affine-preview-root {
padding: 0 24px;
}
}
.affine-embed-synced-doc-container

View File

@@ -4,7 +4,7 @@ import {
EmbedYoutubeStyles,
} from '@blocksuite/affine-model';
import {
EmbedOptionProvider,
EmbedOptionConfig,
LinkPreviewerService,
} from '@blocksuite/affine-shared/services';
import { BlockService } from '@blocksuite/block-std';
@@ -25,15 +25,11 @@ export class EmbedYoutubeBlockService extends BlockService {
signal
);
};
override mounted() {
super.mounted();
this.std.get(EmbedOptionProvider).registerEmbedBlockOptions({
flavour: this.flavour,
urlRegex: youtubeUrlRegex,
styles: EmbedYoutubeStyles,
viewType: 'embed',
});
}
}
export const EmbedYoutubeBlockOptionConfig = EmbedOptionConfig({
flavour: EmbedYoutubeBlockSchema.model.flavour,
urlRegex: youtubeUrlRegex,
styles: EmbedYoutubeStyles,
viewType: 'embed',
});

View File

@@ -3,7 +3,10 @@ import type { ExtensionType } from '@blocksuite/store';
import { literal } from 'lit/static-html.js';
import { EmbedYoutubeBlockAdapterExtensions } from './adapters/extension.js';
import { EmbedYoutubeBlockService } from './embed-youtube-service.js';
import {
EmbedYoutubeBlockOptionConfig,
EmbedYoutubeBlockService,
} from './embed-youtube-service.js';
export const EmbedYoutubeBlockSpec: ExtensionType[] = [
FlavourExtension('affine:embed-youtube'),
@@ -14,4 +17,5 @@ export const EmbedYoutubeBlockSpec: ExtensionType[] = [
: literal`affine-embed-youtube-block`;
}),
EmbedYoutubeBlockAdapterExtensions,
EmbedYoutubeBlockOptionConfig,
].flat();

View File

@@ -30,7 +30,7 @@
"zod": "^3.23.8"
},
"devDependencies": {
"vitest": "3.0.6"
"vitest": "3.0.7"
},
"exports": {
".": "./src/index.ts",

View File

@@ -105,7 +105,7 @@ export const ListKeymapExtension = KeymapExtension(
const isStart = isCollapsed && text.from.index === 0;
if (!isStart) return false;
ctx.get('keyboardState').raw.preventDefault();
ctx.get('defaultState').event.preventDefault();
std.command
.chain()
.pipe(listToParagraphCommand, {

View File

@@ -4,14 +4,23 @@ import {
TextSelection,
} from '@blocksuite/block-std';
/**
* Focus the end of the block
* @param focusBlock - The block to focus
* @param force - If set to true, the selection will be cleared.
* It is useful when the selection is same.
*/
export const focusBlockEnd: Command<{
focusBlock?: BlockComponent;
force?: boolean;
}> = (ctx, next) => {
const { focusBlock, std } = ctx;
const { focusBlock, force, std } = ctx;
if (!focusBlock || !focusBlock.model.text) return;
const { selection } = std;
if (force) selection.clear();
selection.setGroup('note', [
selection.create(TextSelection, {
from: {

View File

@@ -2,10 +2,11 @@ import { EdgelessLegacySlotIdentifier } from '@blocksuite/affine-block-surface';
import type { DocTitle } from '@blocksuite/affine-components/doc-title';
import { NoteDisplayMode } from '@blocksuite/affine-model';
import { EDGELESS_BLOCK_CHILD_PADDING } from '@blocksuite/affine-shared/consts';
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
import { stopPropagation } from '@blocksuite/affine-shared/utils';
import { toGfxBlockComponent } from '@blocksuite/block-std';
import { Bound } from '@blocksuite/global/utils';
import { html, nothing } from 'lit';
import { html, nothing, type PropertyValues } from 'lit';
import { query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { ifDefined } from 'lit/directives/if-defined.js';
@@ -173,6 +174,15 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
}
}
override updated(changedProperties: PropertyValues) {
if (changedProperties.has('_editing') && this._editing) {
this.std.getOptional(TelemetryProvider)?.track('EdgelessNoteEditing', {
page: 'edgeless',
segment: this.model.isPageBlock() ? 'page' : 'note',
});
}
}
override getRenderingRect() {
const { xywh, edgeless } = this.model;
const { collapse, scale = 1 } = edgeless;

View File

@@ -9,6 +9,7 @@ import {
getSelectedModelsCommand,
} from '@blocksuite/affine-shared/commands';
import type { BlockStdScope } from '@blocksuite/block-std';
import { toDraftModel } from '@blocksuite/store';
export interface QuickActionConfig {
id: string;
@@ -45,7 +46,9 @@ export const quickActionConfig: QuickActionConfig[] = [
std.selection.clear();
const doc = std.store;
const autofill = getTitleFromSelectedModels(selectedModels);
const autofill = getTitleFromSelectedModels(
selectedModels.map(toDraftModel)
);
promptDocTitle(std, autofill)
.then(title => {
if (title === null) return;

View File

@@ -42,7 +42,7 @@ export const ParagraphKeymapExtension = KeymapExtension(
const model = store.getBlock(text.from.blockId)?.model;
if (!model || !matchModels(model, [ParagraphBlockModel])) return;
const event = ctx.get('keyboardState').raw;
const event = ctx.get('defaultState').event;
event.preventDefault();
// When deleting at line start of a paragraph block,

View File

@@ -64,7 +64,6 @@ import {
BlockSnapshotSchema,
fromJSON,
type SliceSnapshot,
Transformer,
} from '@blocksuite/store';
import DOMPurify from 'dompurify';
import * as Y from 'yjs';
@@ -373,15 +372,7 @@ export class EdgelessClipboardController extends PageClipboard {
if (mayBeSurfaceDataJson !== undefined) {
const elementsRawData = JSON.parse(mayBeSurfaceDataJson);
const { snapshot, blobs } = elementsRawData;
const job = new Transformer({
schema: this.std.workspace.schema,
blobCRUD: this.std.workspace.blobSync,
docCRUD: {
create: (id: string) => this.std.workspace.createDoc({ id }),
get: (id: string) => this.std.workspace.getDoc(id),
delete: (id: string) => this.std.workspace.removeDoc(id),
},
});
const job = this.std.store.getTransformer();
const map = job.assetsManager.getAssets();
decodeClipboardBlobs(blobs, map);
for (const blobId of map.keys()) {
@@ -1377,15 +1368,7 @@ export async function prepareClipboardData(
selectedAll: GfxModel[],
std: BlockStdScope
) {
const job = new Transformer({
schema: std.workspace.schema,
blobCRUD: std.workspace.blobSync,
docCRUD: {
create: (id: string) => std.workspace.createDoc({ id }),
get: (id: string) => std.workspace.getDoc(id),
delete: (id: string) => std.workspace.removeDoc(id),
},
});
const job = std.store.getTransformer();
const selected = await Promise.all(
selectedAll.map(async selected => {
const data = serializeElement(selected, selectedAll, job);

View File

@@ -1,9 +1,9 @@
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import {
BlockServiceWatcher,
BlockStdScope,
type EditorHost,
LifeCycleWatcher,
ShadowlessElement,
} from '@blocksuite/block-std';
import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
@@ -117,22 +117,26 @@ export class FramePreview extends WithDisposable(ShadowlessElement) {
private _initSpec() {
const refreshViewport = this._refreshViewport.bind(this);
class FramePreviewWatcher extends BlockServiceWatcher {
static override readonly flavour = 'affine:page';
class FramePreviewWatcher extends LifeCycleWatcher {
static override key = 'frame-preview-watcher';
override mounted() {
const blockService = this.blockService;
blockService.disposables.add(
blockService.specSlots.viewConnected.on(({ component }) => {
const edgelessBlock =
component as EdgelessRootPreviewBlockComponent;
edgelessBlock.editorViewportSelector = 'frame-preview-viewport';
edgelessBlock.service.viewport.sizeUpdated.once(() => {
refreshViewport();
});
})
);
const { view } = this.std;
view.viewUpdated.on(payload => {
if (
payload.type !== 'block' ||
payload.method !== 'add' ||
payload.view.model.flavour !== 'affine:page'
) {
return;
}
const edgelessBlock =
payload.view as EdgelessRootPreviewBlockComponent;
edgelessBlock.editorViewportSelector = 'frame-preview-viewport';
edgelessBlock.service.viewport.sizeUpdated.once(() => {
refreshViewport();
});
});
}
}
this._previewSpec.extend([FramePreviewWatcher]);

View File

@@ -1,5 +1,9 @@
import type { Color, ColorScheme, Palette } from '@blocksuite/affine-model';
import { isTransparent, resolveColor } from '@blocksuite/affine-model';
import {
DefaultTheme,
isTransparent,
resolveColor,
} from '@blocksuite/affine-model';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { ColorEvent } from '@blocksuite/affine-shared/utils';
import { css, html, LitElement, nothing, svg, type TemplateResult } from 'lit';
@@ -253,7 +257,7 @@ export class EdgelessColorPanel extends LitElement {
accessor openColorPicker!: (e: MouseEvent) => void;
@property({ type: Array })
accessor palettes: readonly Palette[] = [];
accessor palettes: readonly Palette[] = DefaultTheme.Palettes;
@property({ attribute: false })
accessor theme!: ColorScheme;

View File

@@ -1,9 +1,10 @@
import { LINE_WIDTHS, LineWidth } from '@blocksuite/affine-model';
import { clamp, on, once } from '@blocksuite/affine-shared/utils';
import { on, once } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, LitElement, nothing, type PropertyValues } from 'lit';
import { property, query } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import clamp from 'lodash-es/clamp';
interface Config {
width: number;

View File

@@ -1,7 +1,8 @@
import { clamp, stopPropagation } from '@blocksuite/affine-shared/utils';
import { stopPropagation } from '@blocksuite/affine-shared/utils';
import { css, html, LitElement } from 'lit';
import { property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import clamp from 'lodash-es/clamp';
const MIN_SCALE = 0;
const MAX_SCALE = 400;

View File

@@ -1,8 +1,9 @@
import { clamp, stopPropagation } from '@blocksuite/affine-shared/utils';
import { stopPropagation } from '@blocksuite/affine-shared/utils';
import { DoneIcon } from '@blocksuite/icons/lit';
import { css, html, LitElement, nothing } from 'lit';
import { property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import clamp from 'lodash-es/clamp';
const MIN_SIZE = 1;
const MAX_SIZE = 200;

View File

@@ -1,8 +1,4 @@
import {
type ColorScheme,
DefaultTheme,
type StrokeStyle,
} from '@blocksuite/affine-model';
import { type ColorScheme, type StrokeStyle } from '@blocksuite/affine-model';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils';
import { css, html, LitElement } from 'lit';
@@ -44,7 +40,6 @@ export class StrokeStylePanel extends WithDisposable(LitElement) {
aria-label="Border colors"
.value=${this.strokeColor}
.theme=${this.theme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${this.hollowCircle}
@select=${(e: ColorEvent) => this.setStrokeColor(e)}
>

View File

@@ -35,7 +35,6 @@ import {
import { EMBED_CARD_HEIGHT } from '@blocksuite/affine-shared/consts';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import {
clamp,
getElementsWithoutGroup,
getSelectedRect,
requestThrottledConnectedFrame,
@@ -68,6 +67,7 @@ import { css, html, nothing } from 'lit';
import { state } from 'lit/decorators.js';
import { ifDefined } from 'lit/directives/if-defined.js';
import { styleMap } from 'lit/directives/style-map.js';
import clamp from 'lodash-es/clamp';
import type { EdgelessRootBlockComponent } from '../../edgeless-root-block.js';
import {

View File

@@ -65,7 +65,7 @@ export class EdgelessBrushMenu extends EdgelessToolbarToolMixin(
class="one-way"
.value=${this._props$.value.color}
.theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
.palettes=${DefaultTheme.StrokeColorShortPalettes}
.hasTransparent=${!this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker')}

View File

@@ -133,7 +133,7 @@ export class EdgelessConnectorMenu extends EdgelessToolbarToolMixin(
class="one-way"
.value=${stroke}
.theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
.palettes=${DefaultTheme.StrokeColorShortPalettes}
.hasTransparent=${!this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker')}

View File

@@ -75,9 +75,10 @@ export class EdgelessShapeMenu extends SignalWatcher(
const filled = !isTransparent(value);
const fillColor = value;
const strokeColor = filled
? DefaultTheme.StrokeColorPalettes.find(palette => palette.key === key)
?.value
: DefaultTheme.StrokeColorMap.Grey;
? DefaultTheme.StrokeColorShortPalettes.find(
palette => palette.key === key
)?.value
: DefaultTheme.StrokeColorShortMap.Grey;
const { shapeName } = this._props$.value;
this.edgeless.std
@@ -173,7 +174,7 @@ export class EdgelessShapeMenu extends SignalWatcher(
class="one-way"
.value=${fillColor}
.theme=${this._theme$.value}
.palettes=${DefaultTheme.FillColorPalettes}
.palettes=${DefaultTheme.FillColorShortPalettes}
.hasTransparent=${!this.edgeless.doc
.get(FeatureFlagService)
.getFlag('enable_color_picker')}

View File

@@ -33,7 +33,7 @@ export class EdgelessTextMenu extends EdgelessToolbarToolMixin(LitElement) {
class="one-way"
.value=${this.color}
.theme=${this._theme$.value}
.palettes=${DefaultTheme.StrokeColorPalettes}
.palettes=${DefaultTheme.StrokeColorShortPalettes}
@select=${(e: ColorEvent) => this.onChange({ color: e.detail })}
></edgeless-color-panel>
</div>

View File

@@ -21,7 +21,7 @@ import { ShapeTool } from './gfx-tool/shape-tool.js';
import { TemplateTool } from './gfx-tool/template-tool.js';
import { TextTool } from './gfx-tool/text-tool.js';
import { EditPropsMiddlewareBuilder } from './middlewares/base.js';
import { EdgelessSnapManager } from './utils/snap-manager.js';
import { SnapManager } from './utils/snap-manager.js';
export const EdgelessToolExtension: ExtensionType[] = [
DefaultTool,
@@ -43,7 +43,7 @@ export const EdgelessBuiltInManager: ExtensionType[] = [
ConnectionOverlay,
FrameOverlay,
MindMapIndicatorOverlay,
EdgelessSnapManager,
SnapManager,
EdgelessFrameManager,
EditPropsMiddlewareBuilder,
];

View File

@@ -447,7 +447,7 @@ export class EdgelessRootBlockComponent extends BlockComponent<
);
const zoom = normalizeWheelDeltaY(e.deltaY, viewport.zoom);
viewport.setZoom(zoom, new Point(baseX, baseY));
viewport.setZoom(zoom, new Point(baseX, baseY), true);
e.stopPropagation();
}
// pan

View File

@@ -14,7 +14,6 @@ import {
MindmapElementModel,
RootBlockSchema,
} from '@blocksuite/affine-model';
import { clamp } from '@blocksuite/affine-shared/utils';
import type { BlockStdScope } from '@blocksuite/block-std';
import type {
GfxController,
@@ -35,6 +34,7 @@ import {
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { Bound, getCommonBound } from '@blocksuite/global/utils';
import { effect } from '@preact/signals-core';
import clamp from 'lodash-es/clamp';
import { RootService } from '../root-service.js';
import { TemplateJob } from './services/template.js';

View File

@@ -2,11 +2,14 @@ import { autoConnectWidget } from '@blocksuite/affine-widget-edgeless-auto-conne
import { frameTitleWidget } from '@blocksuite/affine-widget-frame-title';
import { edgelessRemoteSelectionWidget } from '@blocksuite/affine-widget-remote-selection';
import {
BlockServiceWatcher,
BlockViewExtension,
LifeCycleWatcher,
WidgetViewExtension,
} from '@blocksuite/block-std';
import { ToolController } from '@blocksuite/block-std/gfx';
import {
GfxControllerIdentifier,
ToolController,
} from '@blocksuite/block-std/gfx';
import type { ExtensionType } from '@blocksuite/store';
import { literal, unsafeStatic } from 'lit/static-html.js';
@@ -56,17 +59,12 @@ export const edgelessToolbarWidget = WidgetViewExtension(
literal`${unsafeStatic(EDGELESS_TOOLBAR_WIDGET)}`
);
class EdgelessLocker extends BlockServiceWatcher {
static override readonly flavour = 'affine:page';
class EdgelessLocker extends LifeCycleWatcher {
static override key = 'edgeless-locker';
override mounted() {
const service = this.blockService;
service.disposables.add(
service.specSlots.viewConnected.on(({ service }) => {
// Does not allow the user to move and zoom.
(service as EdgelessRootService).locked = true;
})
);
const { viewport } = this.std.get(GfxControllerIdentifier);
viewport.locked = true;
}
}

View File

@@ -27,7 +27,6 @@ import {
TelemetryProvider,
} from '@blocksuite/affine-shared/services';
import {
clamp,
handleNativeRangeAtPoint,
resetNativeSelection,
} from '@blocksuite/affine-shared/utils';
@@ -52,13 +51,14 @@ import {
Vec,
} from '@blocksuite/global/utils';
import { effect } from '@preact/signals-core';
import clamp from 'lodash-es/clamp';
import type { EdgelessRootBlockComponent } from '../edgeless-root-block.js';
import { prepareCloneData } from '../utils/clone-utils.js';
import { isSingleMindMapNode } from '../utils/mindmap.js';
import { calPanDelta } from '../utils/panning-utils.js';
import { isCanvasElement, isEdgelessTextBlock } from '../utils/query.js';
import type { EdgelessSnapManager } from '../utils/snap-manager.js';
import type { SnapManager } from '../utils/snap-manager.js';
import {
addText,
mountConnectorLabelEditor,
@@ -277,9 +277,7 @@ export class DefaultTool extends BaseTool {
}
get snapOverlay() {
return this.std.get(
OverlayIdentifier('snap-manager')
) as EdgelessSnapManager;
return this.std.get(OverlayIdentifier('snap-manager')) as SnapManager;
}
private _addEmptyParagraphBlock(
@@ -580,7 +578,7 @@ export class DefaultTool extends BaseTool {
) {
const mindmap = this._toBeMoved[0].group as MindmapElementModel;
this._alignBound = this.snapOverlay.setupAlignables(this._toBeMoved, [
this._alignBound = this.snapOverlay.setMovingElements(this._toBeMoved, [
mindmap,
...(mindmap?.childElements || []),
]);
@@ -640,7 +638,7 @@ export class DefaultTool extends BaseTool {
);
}
this._alignBound = this.snapOverlay.setupAlignables(
this._alignBound = this.snapOverlay.setMovingElements(
this._toBeMoved
);
@@ -882,7 +880,7 @@ export class DefaultTool extends BaseTool {
if (this.edgelessSelectionManager.editing) return;
this._selectedBounds = [];
this.snapOverlay.cleanupAlignables();
this.snapOverlay.clear();
this.frameOverlay.clear();
this._toBeMoved = [];
this._selectedConnector = null;

View File

@@ -16,7 +16,7 @@ import {
type DocSnapshot,
DocSnapshotSchema,
type SnapshotNode,
Transformer,
type Transformer,
} from '@blocksuite/store';
import type * as Y from 'yjs';
/**
@@ -90,16 +90,7 @@ export class TemplateJob {
type: TemplateType;
constructor({ model, type, middlewares }: TemplateJobConfig) {
this.job = new Transformer({
schema: model.doc.workspace.schema,
blobCRUD: model.doc.workspace.blobSync,
docCRUD: {
create: (id: string) => model.doc.workspace.createDoc({ id }),
get: (id: string) => model.doc.workspace.getDoc(id),
delete: (id: string) => model.doc.workspace.removeDoc(id),
},
middlewares: [],
});
this.job = model.doc.getTransformer();
this.model = model;
this.type = TEMPLATE_TYPES.includes(type as TemplateType)
? (type as TemplateType)
@@ -320,8 +311,7 @@ export class TemplateJob {
from: Record<string, Record<string, unknown>>,
to: Y.Map<Y.Map<unknown>>
) {
const schema =
this.model.doc.workspace.schema.flavourSchemaMap.get('affine:surface');
const schema = this.model.doc.schema.get('affine:surface');
const surfaceTransformer = schema?.transformer?.(
new Map()
) as SurfaceBlockTransformer;

View File

@@ -19,7 +19,7 @@ import {
isGfxGroupCompatibleModel,
type SerializedElement,
} from '@blocksuite/block-std/gfx';
import { type BlockSnapshot, Transformer } from '@blocksuite/store';
import type { BlockSnapshot, Transformer } from '@blocksuite/store';
/**
* return all elements in the tree of the elements
@@ -40,15 +40,7 @@ export function getSortedCloneElements(elements: GfxModel[]) {
export function prepareCloneData(elements: GfxModel[], std: BlockStdScope) {
elements = sortEdgelessElements(elements);
const job = new Transformer({
schema: std.workspace.schema,
blobCRUD: std.workspace.blobSync,
docCRUD: {
create: (id: string) => std.workspace.createDoc({ id }),
get: (id: string) => std.workspace.getDoc(id),
delete: (id: string) => std.workspace.removeDoc(id),
},
});
const job = std.store.getTransformer();
const res = elements.map(element => {
const data = serializeElement(element, elements, job);
return data;

View File

@@ -1,30 +1,49 @@
import type {
SurfaceBlockComponent,
SurfaceBlockModel,
} from '@blocksuite/affine-block-surface';
import { getSurfaceBlock, Overlay } from '@blocksuite/affine-block-surface';
import type { ConnectorElementModel } from '@blocksuite/affine-model';
import type { GfxController, GfxModel } from '@blocksuite/block-std/gfx';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { Bound, Point } from '@blocksuite/global/utils';
import { isConnectable } from '../utils/query.js';
import { Overlay } from '@blocksuite/affine-block-surface';
import { ConnectorElementModel } from '@blocksuite/affine-model';
import type { GfxModel } from '@blocksuite/block-std/gfx';
import { almostEqual, Bound, Point } from '@blocksuite/global/utils';
interface Distance {
absXDistance: number;
absYDistance: number;
xDistance: number;
yDistance: number;
indexX: number;
indexY: number;
horiz?: {
/**
* the minimum x moving distance to align with other bound
*/
distance: number;
/**
* the indices of the align position
*/
alignPositionIndices: number[];
};
vert?: {
/**
* the minimum y moving distance to align with other bound
*/
distance: number;
/**
* the indices of the align position
*/
alignPositionIndices: number[];
};
}
const ALIGN_THRESHOLD = 5;
const ALIGN_THRESHOLD = 8;
const DISTRIBUTION_LINE_OFFSET = 1;
export class EdgelessSnapManager extends Overlay {
export class SnapManager extends Overlay {
static override overlayName: string = 'snap-manager';
private _alignableBounds: Bound[] = [];
private _referenceBounds: {
vertical: Bound[];
horizontal: Bound[];
all: Bound[];
} = {
vertical: [],
horizontal: [],
all: [],
};
/**
* This variable contains reference lines that are
@@ -44,28 +63,16 @@ export class EdgelessSnapManager extends Overlay {
*/
private _intraGraphicAlignLines: [Point, Point][] = [];
cleanupAlignables = () => {
this._alignableBounds = [];
override clear() {
super.clear();
this._referenceBounds = {
vertical: [],
horizontal: [],
all: [],
};
this._intraGraphicAlignLines = [];
this._distributedAlignLines = [];
// FIXME: not sure why renderer can be undefined sometimes
this._surface.renderer?.removeOverlay(this);
};
private get _surface() {
const surfaceModel = getSurfaceBlock(this.gfx.doc);
if (!surfaceModel) {
throw new BlockSuiteError(
ErrorCode.ValueNotExists,
'Surface block not found in doc when creating snap manager'
);
}
return this.gfx.std.view.getBlock(surfaceModel.id) as SurfaceBlockComponent;
}
constructor(gfx: GfxController) {
super(gfx);
}
private _alignDistributeHorizontally(
@@ -75,31 +82,52 @@ export class EdgelessSnapManager extends Overlay {
viewport: { zoom: number }
) {
const wBoxes: Bound[] = [];
this._alignableBounds.forEach(box => {
this._referenceBounds.horizontal.forEach(box => {
if (box.isHorizontalCross(bound)) {
wBoxes.push(box);
}
});
wBoxes.sort((a, b) => a.center[0] - b.center[0]);
let dif = Infinity;
let min = Infinity;
let aveDis = Number.MAX_SAFE_INTEGER;
let curBound!: {
leftIdx: number;
rightIdx: number;
spacing: number;
points: [Point, Point][];
};
for (let i = 0; i < wBoxes.length; i++) {
for (let j = i + 1; j < wBoxes.length; j++) {
let lb = wBoxes[i],
rb = wBoxes[j];
// it means these bound need to be horizontally across
if (!lb.isHorizontalCross(rb)) continue;
if (lb.isIntersectWithBound(rb)) continue;
if (!lb.isHorizontalCross(rb) || lb.isIntersectWithBound(rb)) continue;
let switchFlag = false;
// exchange lb and rb to make sure lb is on the left of rb
if (rb.maxX < lb.minX) {
const temp = rb;
rb = lb;
lb = temp;
switchFlag = true;
}
/** align middle */
let _centerX = 0;
const updateDif = () => {
dif = Math.abs(bound.center[0] - _centerX);
if (dif <= threshold && dif < min) {
const curAveDis =
(Math.abs(lb.center[0] - bound.center[0]) +
Math.abs(rb.center[0] - bound.center[0])) /
2;
if (
dif <= threshold &&
(dif < min || (almostEqual(dif, min) && curAveDis < aveDis))
) {
min = dif;
aveDis = curAveDis;
rst.dx = _centerX - bound.center[0];
/**
* calculate points to draw
@@ -108,37 +136,102 @@ export class EdgelessSnapManager extends Overlay {
(a, b) => a - b
);
const y = (ys[1] + ys[2]) / 2;
const offset = 2 / viewport.zoom;
const offset = DISTRIBUTION_LINE_OFFSET / viewport.zoom;
const xs = [
_centerX - bound.w / 2 - offset,
_centerX + bound.w / 2 + offset,
_centerX - bound.w / 2,
_centerX + bound.w / 2,
rb.minX,
rb.maxX,
lb.minX,
lb.maxX,
].sort((a, b) => a - b);
this._distributedAlignLines[0] = [
new Point(xs[1], y),
new Point(xs[2], y),
];
this._distributedAlignLines[1] = [
new Point(xs[3], y),
new Point(xs[4], y),
];
curBound = {
leftIdx: switchFlag ? j : i,
rightIdx: switchFlag ? i : j,
spacing: xs[2] - xs[1],
points: [
[new Point(xs[1] + offset, y), new Point(xs[2] - offset, y)],
[new Point(xs[3] + offset, y), new Point(xs[4] - offset, y)],
],
};
}
};
/**
* align between left and right bound
*/
if (lb.horizontalDistance(rb) > bound.w) {
_centerX = (lb.maxX + rb.minX) / 2;
updateDif();
}
/** align left */
/**
* align to the left bounds
*/
_centerX = lb.minX - (rb.minX - lb.maxX) - bound.w / 2;
updateDif();
/** align right */
_centerX = rb.minX - lb.maxX + rb.maxX + bound.w / 2;
updateDif();
}
}
// find the boxes that has same spacing
if (curBound) {
const { leftIdx, rightIdx, spacing, points } = curBound;
this._distributedAlignLines.push(...points);
{
let curLeftBound = wBoxes[leftIdx];
for (let i = leftIdx - 1; i >= 0; i--) {
if (almostEqual(wBoxes[i].maxX, curLeftBound.minX - spacing)) {
const targetBound = wBoxes[i];
const ys = [
targetBound.minY,
targetBound.maxY,
curLeftBound.minY,
curLeftBound.maxY,
].sort((a, b) => a - b);
const y = (ys[1] + ys[2]) / 2;
this._distributedAlignLines.push([
new Point(wBoxes[i].maxX, y),
new Point(curLeftBound.minX, y),
]);
curLeftBound = wBoxes[i];
}
}
}
{
let curRightBound = wBoxes[rightIdx];
for (let i = rightIdx + 1; i < wBoxes.length; i++) {
if (almostEqual(wBoxes[i].minX, curRightBound.maxX + spacing)) {
const targetBound = wBoxes[i];
const ys = [
targetBound.minY,
targetBound.maxY,
curRightBound.minY,
curRightBound.maxY,
].sort((a, b) => a - b);
const y = (ys[1] + ys[2]) / 2;
this._distributedAlignLines.push([
new Point(curRightBound.maxX, y),
new Point(wBoxes[i].minX, y),
]);
curRightBound = wBoxes[i];
}
}
}
}
}
private _alignDistributeVertically(
@@ -148,29 +241,50 @@ export class EdgelessSnapManager extends Overlay {
viewport: { zoom: number }
) {
const hBoxes: Bound[] = [];
this._alignableBounds.forEach(box => {
this._referenceBounds.vertical.forEach(box => {
if (box.isVerticalCross(bound)) {
hBoxes.push(box);
}
});
hBoxes.sort((a, b) => a.center[0] - b.center[0]);
let dif = Infinity;
let min = Infinity;
let aveDis = Number.MAX_SAFE_INTEGER;
let curBound!: {
upperIdx: number;
lowerIdx: number;
spacing: number;
points: [Point, Point][];
};
for (let i = 0; i < hBoxes.length; i++) {
for (let j = i + 1; j < hBoxes.length; j++) {
let ub = hBoxes[i],
db = hBoxes[j];
if (!ub.isVerticalCross(db)) continue;
if (ub.isIntersectWithBound(db)) continue;
if (!ub.isVerticalCross(db) || ub.isIntersectWithBound(db)) continue;
let switchFlag = false;
if (db.maxY < ub.minX) {
const temp = ub;
ub = db;
db = temp;
switchFlag = true;
}
/** align middle */
let _centerY = 0;
const updateDiff = () => {
dif = Math.abs(bound.center[1] - _centerY);
if (dif <= threshold && dif < min) {
const curAveDis =
(Math.abs(ub.center[1] - bound.center[1]) +
Math.abs(db.center[1] - bound.center[1])) /
2;
if (
dif <= threshold &&
(dif < min || (almostEqual(dif, min) && curAveDis < aveDis))
) {
min = dif;
rst.dy = _centerY - bound.center[1];
/**
@@ -180,29 +294,33 @@ export class EdgelessSnapManager extends Overlay {
(a, b) => a - b
);
const x = (xs[1] + xs[2]) / 2;
const offset = 2 / viewport.zoom;
const offset = DISTRIBUTION_LINE_OFFSET / viewport.zoom;
const ys = [
_centerY - bound.h / 2 - offset,
_centerY + bound.h / 2 + offset,
_centerY - bound.h / 2,
_centerY + bound.h / 2,
db.minY,
db.maxY,
ub.minY,
ub.maxY,
].sort((a, b) => a - b);
this._distributedAlignLines[3] = [
new Point(x, ys[1]),
new Point(x, ys[2]),
];
this._distributedAlignLines[4] = [
new Point(x, ys[3]),
new Point(x, ys[4]),
];
curBound = {
upperIdx: switchFlag ? j : i,
lowerIdx: switchFlag ? i : j,
spacing: ys[2] - ys[1],
points: [
[new Point(x, ys[1] + offset), new Point(x, ys[2] - offset)],
[new Point(x, ys[3] + offset), new Point(x, ys[4] - offset)],
],
};
}
};
if (ub.verticalDistance(db) > bound.h) {
_centerY = (ub.maxY + db.minY) / 2;
updateDiff();
}
/** align upper */
_centerY = ub.minY - (db.minY - ub.maxY) - bound.h / 2;
updateDiff();
@@ -211,6 +329,61 @@ export class EdgelessSnapManager extends Overlay {
updateDiff();
}
}
// find the boxes that has same spacing
if (curBound) {
const { upperIdx, lowerIdx, spacing, points } = curBound;
this._distributedAlignLines.push(...points);
{
let curUpperBound = hBoxes[upperIdx];
for (let i = upperIdx - 1; i >= 0; i--) {
if (almostEqual(hBoxes[i].maxY, curUpperBound.minY - spacing)) {
const targetBound = hBoxes[i];
const xs = [
targetBound.minX,
targetBound.maxX,
curUpperBound.minX,
curUpperBound.maxX,
].sort((a, b) => a - b);
const x = (xs[1] + xs[2]) / 2;
this._distributedAlignLines.push([
new Point(x, hBoxes[i].maxY),
new Point(x, curUpperBound.minY),
]);
curUpperBound = hBoxes[i];
}
}
}
{
let curLowerBound = hBoxes[lowerIdx];
for (let i = lowerIdx + 1; i < hBoxes.length; i++) {
if (almostEqual(hBoxes[i].minY, curLowerBound.maxY + spacing)) {
const targetBound = hBoxes[i];
const xs = [
targetBound.minX,
targetBound.maxX,
curLowerBound.minX,
curLowerBound.maxX,
].sort((a, b) => a - b);
const x = (xs[1] + xs[2]) / 2;
this._distributedAlignLines.push([
new Point(x, curLowerBound.maxY),
new Point(x, hBoxes[i].minY),
]);
curLowerBound = hBoxes[i];
}
}
}
}
}
private _calculateClosestDistances(bound: Bound, other: Bound): Distance {
@@ -263,94 +436,150 @@ export class EdgelessSnapManager extends Overlay {
const closestX = Math.min(...xDistancesAbs);
const closestY = Math.min(...yDistancesAbs);
const indexX = xDistancesAbs.indexOf(closestX);
const indexY = yDistancesAbs.indexOf(closestY);
const threshold = ALIGN_THRESHOLD / this.gfx.viewport.zoom;
// the x and y distances will be useful for locating the align point
return {
absXDistance: closestX,
absYDistance: closestY,
xDistance: xDistances[indexX],
yDistance: yDistances[indexY],
indexX,
indexY,
horiz:
closestX <= threshold
? {
distance: xDistances[xDistancesAbs.indexOf(closestX)],
get alignPositionIndices() {
const indices: number[] = [];
xDistancesAbs.forEach(
(val, idx) => almostEqual(val, closestX) && indices.push(idx)
);
return indices;
},
}
: undefined,
vert:
closestY <= threshold
? {
distance: yDistances[yDistancesAbs.indexOf(closestY)],
get alignPositionIndices() {
const indices: number[] = [];
yDistancesAbs.forEach(
(val, idx) => almostEqual(val, closestY) && indices.push(idx)
);
return indices;
},
}
: undefined,
};
}
private _draw() {
this._surface.refresh();
}
// Update X align point
/**
* Update horizontal moving distance `rst.dx` to align with other bound.
* Also, update the align points to draw.
* @param rst
* @param bound
* @param other
* @param distance
*/
private _updateXAlignPoint(
rst: { dx: number; dy: number },
bound: Bound,
other: Bound,
distance: Distance
) {
const index = distance.indexX;
rst.dx = distance.xDistance;
const alignPointX = [
if (!distance.horiz) return;
const { distance: dx, alignPositionIndices: distanceIndices } =
distance.horiz;
const alignXPosition = [
other.center[0],
other.minX,
other.maxX,
bound.minX + rst.dx,
bound.minX + rst.dx,
bound.maxX + rst.dx,
bound.maxX + rst.dx,
][index];
this._intraGraphicAlignLines[0] = [
new Point(alignPointX, bound.center[1]),
new Point(alignPointX, other.center[1]),
bound.minX + dx,
bound.minX + dx,
bound.maxX + dx,
bound.maxX + dx,
];
rst.dx = dx;
const dy = distance.vert?.distance ?? 0;
const top = Math.min(bound.minY + dy, other.minY);
const down = Math.max(bound.maxY + dy, other.maxY);
this._intraGraphicAlignLines.push(
...distanceIndices.map(
idx =>
[
new Point(alignXPosition[idx], top),
new Point(alignXPosition[idx], down),
] as [Point, Point]
)
);
}
// Update Y align point
/**
* Update vertical moving distance `rst.dy` to align with other bound.
* Also, update the align points to draw.
* @param rst
* @param bound
* @param other
* @param distance
*/
private _updateYAlignPoint(
rst: { dx: number; dy: number },
bound: Bound,
other: Bound,
distance: Distance
) {
const index = distance.indexY;
rst.dy = distance.yDistance;
const alignPointY = [
if (!distance.vert) return;
const { distance: dy, alignPositionIndices } = distance.vert;
const alignXPosition = [
other.center[1],
other.minY,
other.maxY,
bound.minY + rst.dy,
bound.minY + rst.dy,
bound.maxY + rst.dy,
bound.maxY + rst.dy,
][index];
this._intraGraphicAlignLines[1] = [
new Point(bound.center[0], alignPointY),
new Point(other.center[0], alignPointY),
bound.minY + dy,
bound.minY + dy,
bound.maxY + dy,
bound.maxY + dy,
];
rst.dy = dy;
const dx = distance.horiz?.distance ?? 0;
const left = Math.min(bound.minX + dx, other.minX);
const right = Math.max(bound.maxX + dx, other.maxX);
this._intraGraphicAlignLines.push(
...alignPositionIndices.map(
idx =>
[
new Point(left, alignXPosition[idx]),
new Point(right, alignXPosition[idx]),
] as [Point, Point]
)
);
}
align(bound: Bound): { dx: number; dy: number } {
const rst = { dx: 0, dy: 0 };
const threshold = ALIGN_THRESHOLD;
const threshold = ALIGN_THRESHOLD / this.gfx.viewport.zoom;
const { viewport } = this.gfx;
this._intraGraphicAlignLines = [];
this._distributedAlignLines = [];
for (const other of this._alignableBounds) {
for (const other of this._referenceBounds.all) {
const closestDistances = this._calculateClosestDistances(bound, other);
if (closestDistances.absXDistance < threshold) {
if (closestDistances.horiz) {
this._updateXAlignPoint(rst, bound, other, closestDistances);
}
if (closestDistances.absYDistance < threshold) {
if (closestDistances.vert) {
this._updateYAlignPoint(rst, bound, other, closestDistances);
}
}
// point align prority is higher than distribute align
// point align priority is higher than distribute align
if (rst.dx === 0) {
this._alignDistributeHorizontally(rst, bound, threshold, viewport);
}
@@ -358,7 +587,9 @@ export class EdgelessSnapManager extends Overlay {
if (rst.dy === 0) {
this._alignDistributeVertically(rst, bound, threshold, viewport);
}
this._draw();
this._renderer?.refresh();
return rst;
}
@@ -369,9 +600,9 @@ export class EdgelessSnapManager extends Overlay {
)
return;
const { viewport } = this.gfx;
const strokeWidth = 1 / viewport.zoom;
const offset = 5 / viewport.zoom;
ctx.strokeStyle = '#1672F3';
const strokeWidth = 2 / viewport.zoom;
ctx.strokeStyle = '#8B5CF6';
ctx.lineWidth = strokeWidth;
ctx.beginPath();
@@ -381,30 +612,31 @@ export class EdgelessSnapManager extends Overlay {
const x = line[0].x;
const minY = Math.min(line[0].y, line[1].y);
const maxY = Math.max(line[0].y, line[1].y);
d = `M${x},${minY - offset}L${x},${maxY}`;
d = `M${x},${minY}L${x},${maxY}`;
} else {
const y = line[0].y;
const minX = Math.min(line[0].x, line[1].x);
const maxX = Math.max(line[0].x, line[1].x);
d = `M${minX - offset},${y}L${maxX + offset},${y}`;
d = `M${minX},${y}L${maxX},${y}`;
}
ctx.stroke(new Path2D(d));
});
ctx.strokeStyle = '#CC4187';
this._distributedAlignLines.forEach(line => {
const bar = 10 / viewport.zoom;
let d = '';
if (line[0].x === line[1].x) {
const x = line[0].x;
const minY = Math.min(line[0].y, line[1].y) + offset;
const maxY = Math.max(line[0].y, line[1].y) - offset;
const minY = Math.min(line[0].y, line[1].y);
const maxY = Math.max(line[0].y, line[1].y);
d = `M${x},${minY}L${x},${maxY}
M${x - bar},${minY}L${x + bar},${minY}
M${x - bar},${maxY}L${x + bar},${maxY} `;
} else {
const y = line[0].y;
const minX = Math.min(line[0].x, line[1].x) + offset;
const maxX = Math.max(line[0].x, line[1].x) - offset;
const minX = Math.min(line[0].x, line[1].x);
const maxX = Math.max(line[0].x, line[1].x);
d = `M${minX},${y}L${maxX},${y}
M${minX},${y - bar}L${minX},${y + bar}
M${maxX},${y - bar}L${maxX},${y + bar}`;
@@ -413,42 +645,68 @@ export class EdgelessSnapManager extends Overlay {
});
}
setupAlignables(alignables: GfxModel[], exclude: GfxModel[] = []): Bound {
if (alignables.length === 0) return new Bound();
setMovingElements(
movingElements: GfxModel[],
excludes: GfxModel[] = []
): Bound {
if (movingElements.length === 0) return new Bound();
const connectors = alignables.filter(isConnectable).reduce((prev, el) => {
const connectors = (this.gfx.surface as SurfaceBlockModel).getConnectors(
el.id
);
const skipped = new Set(movingElements);
excludes.forEach(e => skipped.add(e));
if (connectors.length > 0) {
prev = prev.concat(connectors);
}
return prev;
}, [] as ConnectorElementModel[]);
const { viewport } = this.gfx;
const viewportBounds = Bound.from(viewport.viewportBounds);
this._surface.renderer.addOverlay(this);
const canvasElements = this.gfx.layer.canvasElements;
const excludes = new Set([...alignables, ...exclude, ...connectors]);
this._alignableBounds = [];
([...this.gfx.layer.blocks, ...canvasElements] as GfxModel[]).forEach(
alignable => {
const bounds = alignable.elementBound;
if (
viewportBounds.isOverlapWithBound(bounds) &&
!excludes.has(alignable)
) {
this._alignableBounds.push(bounds);
}
}
const viewportBound = this.gfx.viewport.viewportBounds;
const movingBound = movingElements
.reduce(
(prev, element) => prev.unite(element.elementBound),
movingElements[0].elementBound
)
.expand(ALIGN_THRESHOLD * this.gfx.viewport.zoom);
const horizAreaBound = new Bound(
Math.min(movingBound.x, viewportBound.x),
movingBound.y,
Math.max(movingBound.w, viewportBound.w),
movingBound.h
);
const vertAreaBound = new Bound(
movingBound.x,
Math.min(movingBound.y, viewportBound.y),
movingBound.w,
Math.max(movingBound.h, viewportBound.h)
);
return alignables.reduce((prev, element) => {
const bounds = element.elementBound;
return prev.unite(bounds);
}, Bound.deserialize(alignables[0].xywh));
const vertCandidates = this.gfx.grid.search(vertAreaBound, {
useSet: true,
});
const horizCandidates = this.gfx.grid.search(horizAreaBound, {
useSet: true,
});
const verticalBounds: Bound[] = [];
const horizBounds: Bound[] = [];
const allBounds: Bound[] = [];
vertCandidates.forEach(candidate => {
if (skipped.has(candidate) || candidate instanceof ConnectorElementModel)
return;
verticalBounds.push(candidate.elementBound);
allBounds.push(candidate.elementBound);
});
horizCandidates.forEach(candidate => {
if (skipped.has(candidate) || candidate instanceof ConnectorElementModel)
return;
horizBounds.push(candidate.elementBound);
allBounds.push(candidate.elementBound);
});
this._referenceBounds = {
horizontal: horizBounds,
vertical: verticalBounds,
all: allBounds,
};
return movingElements.reduce(
(prev, element) => prev.unite(element.elementBound),
Bound.deserialize(movingElements[0].xywh)
);
}
}

View File

@@ -17,10 +17,11 @@ import {
type UIEventHandler,
} from '@blocksuite/block-std';
import { IS_MAC, IS_WINDOWS } from '@blocksuite/global/env';
import { toDraftModel } from '@blocksuite/store';
export class PageKeyboardManager {
private readonly _handleDelete: UIEventHandler = ctx => {
const event = ctx.get('keyboardState').raw;
const event = ctx.get('defaultState').event;
const blockSelections = this._currentSelection.filter(sel =>
sel.is(BlockSelection)
);
@@ -143,7 +144,9 @@ export class PageKeyboardManager {
}
const doc = rootComponent.host.doc;
const autofill = getTitleFromSelectedModels(selectedModels);
const autofill = getTitleFromSelectedModels(
selectedModels.map(toDraftModel)
);
promptDocTitle(rootComponent.std, autofill)
.then(title => {
if (title === null) return;

View File

@@ -10,7 +10,6 @@ export class PreviewRootBlockComponent extends BlockComponent {
static override styles = css`
affine-preview-root {
display: block;
padding: 0 24px;
}
`;

View File

@@ -8,19 +8,21 @@ import {
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils';
import type { Store, Workspace } from '@blocksuite/store';
import type { Schema, Store, Workspace } from '@blocksuite/store';
import { extMimeMap, Transformer } from '@blocksuite/store';
import { createAssetsArchive, download, Unzip } from './utils.js';
type ImportHTMLToDocOptions = {
collection: Workspace;
schema: Schema;
html: string;
fileName?: string;
};
type ImportHTMLZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
};
@@ -41,19 +43,10 @@ function getProvider() {
*/
async function exportDoc(doc: Store) {
const provider = getProvider();
const job = new Transformer({
schema: doc.schema,
blobCRUD: doc.blobSync,
docCRUD: {
create: (id: string) => doc.workspace.createDoc({ id }),
get: (id: string) => doc.workspace.getDoc(id),
delete: (id: string) => doc.workspace.removeDoc(id),
},
middlewares: [
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
],
});
const job = doc.getTransformer([
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
]);
const snapshot = job.docToSnapshot(doc);
const adapter = new HtmlAdapter(job, provider);
if (!snapshot) {
@@ -87,18 +80,20 @@ async function exportDoc(doc: Store) {
*
* @param options - The import options.
* @param options.collection - The target doc collection.
* @param options.schema - The schema of the target doc collection.
* @param options.html - The HTML content to import.
* @param options.fileName - Optional filename for the imported doc.
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails.
*/
async function importHTMLToDoc({
collection,
schema,
html,
fileName,
}: ImportHTMLToDocOptions) {
const provider = getProvider();
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),
@@ -127,10 +122,15 @@ async function importHTMLToDoc({
*
* @param options - The import options.
* @param options.collection - The target doc collection.
* @param options.schema - The schema of the target doc collection.
* @param options.imported - The zip file as a Blob.
* @returns A Promise that resolves to an array of IDs of the newly created docs.
*/
async function importHTMLZip({ collection, imported }: ImportHTMLZipOptions) {
async function importHTMLZip({
collection,
schema,
imported,
}: ImportHTMLZipOptions) {
const provider = getProvider();
const unzip = new Unzip();
await unzip.load(imported);
@@ -161,7 +161,7 @@ async function importHTMLZip({ collection, imported }: ImportHTMLZipOptions) {
htmlBlobs.map(async ([fileName, blob]) => {
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),

View File

@@ -9,7 +9,7 @@ import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { assertExists, sha } from '@blocksuite/global/utils';
import type { Store, Workspace } from '@blocksuite/store';
import type { Schema, Store, Workspace } from '@blocksuite/store';
import { extMimeMap, Transformer } from '@blocksuite/store';
import { createAssetsArchive, download, Unzip } from './utils.js';
@@ -31,12 +31,14 @@ type ImportMarkdownToBlockOptions = {
type ImportMarkdownToDocOptions = {
collection: Workspace;
schema: Schema;
markdown: string;
fileName?: string;
};
type ImportMarkdownZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
};
@@ -47,19 +49,10 @@ type ImportMarkdownZipOptions = {
*/
async function exportDoc(doc: Store) {
const provider = getProvider();
const job = new Transformer({
schema: doc.schema,
blobCRUD: doc.blobSync,
docCRUD: {
create: (id: string) => doc.workspace.createDoc({ id }),
get: (id: string) => doc.workspace.getDoc(id),
delete: (id: string) => doc.workspace.removeDoc(id),
},
middlewares: [
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
],
});
const job = doc.getTransformer([
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
]);
const snapshot = job.docToSnapshot(doc);
const adapter = new MarkdownAdapter(job, provider);
@@ -107,19 +100,10 @@ async function importMarkdownToBlock({
blockId,
}: ImportMarkdownToBlockOptions) {
const provider = getProvider();
const job = new Transformer({
schema: doc.schema,
blobCRUD: doc.blobSync,
docCRUD: {
create: (id: string) => doc.workspace.createDoc({ id }),
get: (id: string) => doc.workspace.getDoc(id),
delete: (id: string) => doc.workspace.removeDoc(id),
},
middlewares: [
defaultImageProxyMiddleware,
docLinkBaseURLMiddleware(doc.workspace.id),
],
});
const job = doc.getTransformer([
defaultImageProxyMiddleware,
docLinkBaseURLMiddleware(doc.workspace.id),
]);
const adapter = new MarkdownAdapter(job, provider);
const snapshot = await adapter.toSliceSnapshot({
file: markdown,
@@ -143,18 +127,20 @@ async function importMarkdownToBlock({
* Imports Markdown content into a new doc within a collection.
* @param options Object containing import options
* @param options.collection The target doc collection
* @param options.schema The schema of the target doc collection
* @param options.markdown The Markdown content to import
* @param options.fileName Optional filename for the imported doc
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails
*/
async function importMarkdownToDoc({
collection,
schema,
markdown,
fileName,
}: ImportMarkdownToDocOptions) {
const provider = getProvider();
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),
@@ -182,11 +168,13 @@ async function importMarkdownToDoc({
* Imports a zip file containing Markdown files and assets into a collection.
* @param options Object containing import options
* @param options.collection The target doc collection
* @param options.schema The schema of the target doc collection
* @param options.imported The zip file as a Blob
* @returns A Promise that resolves to an array of IDs of the newly created docs
*/
async function importMarkdownZip({
collection,
schema,
imported,
}: ImportMarkdownZipOptions) {
const provider = getProvider();
@@ -219,7 +207,7 @@ async function importMarkdownZip({
markdownBlobs.map(async ([fileName, blob]) => {
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),

View File

@@ -3,12 +3,18 @@ import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils';
import { extMimeMap, Transformer, type Workspace } from '@blocksuite/store';
import {
extMimeMap,
type Schema,
Transformer,
type Workspace,
} from '@blocksuite/store';
import { Unzip } from './utils.js';
type ImportNotionZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
};
@@ -26,6 +32,7 @@ function getProvider() {
*
* @param options - The options for importing.
* @param options.collection - The BlockSuite document collection.
* @param options.schema - The schema of the BlockSuite document collection.
* @param options.imported - The imported zip file as a Blob.
*
* @returns A promise that resolves to an object containing:
@@ -36,6 +43,7 @@ function getProvider() {
*/
async function importNotionZip({
collection,
schema,
imported,
}: ImportNotionZipOptions) {
const provider = getProvider();
@@ -117,7 +125,7 @@ async function importNotionZip({
}
const pagePromises = Array.from(pagePaths).map(async path => {
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),

View File

@@ -3,15 +3,19 @@ import {
titleMiddleware,
} from '@blocksuite/affine-shared/adapters';
import { sha } from '@blocksuite/global/utils';
import type { DocSnapshot, Store, Workspace } from '@blocksuite/store';
import type { DocSnapshot, Schema, Store, Workspace } from '@blocksuite/store';
import { extMimeMap, getAssetName, Transformer } from '@blocksuite/store';
import { download, Unzip, Zip } from '../transformers/utils.js';
async function exportDocs(collection: Workspace, docs: Store[]) {
async function exportDocs(
collection: Workspace,
schema: Schema,
docs: Store[]
) {
const zip = new Zip();
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),
@@ -70,7 +74,11 @@ async function exportDocs(collection: Workspace, docs: Store[]) {
return download(downloadBlob, `${collection.id}.bs.zip`);
}
async function importDocs(collection: Workspace, imported: Blob) {
async function importDocs(
collection: Workspace,
schema: Schema,
imported: Blob
) {
const unzip = new Unzip();
await unzip.load(imported);
@@ -98,7 +106,7 @@ async function importDocs(collection: Workspace, imported: Blob) {
}
const job = new Transformer({
schema: collection.schema,
schema,
blobCRUD: collection.blobSync,
docCRUD: {
create: (id: string) => collection.createDoc({ id }),

View File

@@ -1,4 +1,4 @@
import { clamp } from '@blocksuite/affine-shared/utils';
import clamp from 'lodash-es/clamp';
type CollisionBox = {
/**

View File

@@ -134,13 +134,12 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
return html`
<edgeless-color-picker-button
class="color"
.label=${'Color'}
.label="${'Color'}"
.pick=${this.pickColor}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
>
</edgeless-color-picker-button>
`;
@@ -159,7 +158,6 @@ export class EdgelessChangeBrushButton extends WithDisposable(LitElement) {
<edgeless-color-panel
.value=${selectedColor}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
@select=${this._setBrushColor}
>
</edgeless-color-panel>

View File

@@ -373,13 +373,12 @@ export class EdgelessChangeConnectorButton extends WithDisposable(LitElement) {
return html`
<edgeless-color-picker-button
class="stroke-color"
.label=${'Stroke style'}
.label="${'Stroke style'}"
.pick=${this.pickColor}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${true}
>
<div

View File

@@ -43,7 +43,6 @@ import {
import {
EmbedOptionProvider,
type EmbedOptions,
FeatureFlagService,
GenerateDocUrlProvider,
type GenerateDocUrlService,
type LinkEventType,
@@ -419,16 +418,6 @@ export class EdgelessChangeEmbedCardButton extends WithDisposable(LitElement) {
private get _canConvertToEmbedView() {
const block = this._blockComponent;
// synced doc entry controlled by awareness flag
if (!!block && isEmbedLinkedDocBlock(block.model)) {
const isSyncedDocEnabled = block.doc
.get(FeatureFlagService)
.getFlag('enable_synced_doc_block');
if (!isSyncedDocEnabled) {
return false;
}
}
return (
(block && 'convertToEmbed' in block) ||
this._embedOptions?.viewType === 'embed'

View File

@@ -13,7 +13,6 @@ import { renderToolbarSeparator } from '@blocksuite/affine-components/toolbar';
import {
type ColorScheme,
DEFAULT_NOTE_HEIGHT,
DefaultTheme,
type FrameBlockModel,
NoteBlockModel,
NoteDisplayMode,
@@ -201,13 +200,12 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
return html`
<edgeless-color-picker-button
class="background"
.label=${'Background'}
.label="${'Background'}"
.pick=${this.pickColor}
.color=${background}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
>
</edgeless-color-picker-button>
`;
@@ -229,7 +227,6 @@ export class EdgelessChangeFrameButton extends WithDisposable(LitElement) {
<edgeless-color-panel
.value=${background}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
@select=${this._setFrameBackground}
>
</edgeless-color-panel>

View File

@@ -338,7 +338,6 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
>
</edgeless-color-picker-button>
`;
@@ -362,7 +361,6 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
aria-label="Fill colors"
.value=${selectedFillColor}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
@select=${this._setShapeFillColor}
>
</edgeless-color-panel>
@@ -390,7 +388,6 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.hollowCircle=${true}
>
<div
@@ -453,8 +450,8 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
() => html`
<editor-icon-button
aria-label="Add text"
.tooltip=${'Add text'}
.iconSize=${'20px'}
.tooltip="${'Add text'}"
.iconSize="${'20px'}"
@click=${this._addText}
>
${AddTextIcon()}
@@ -465,7 +462,7 @@ export class EdgelessChangeShapeButton extends WithDisposable(LitElement) {
'menu',
() => html`
<edgeless-change-text-menu
.elementType=${'shape'}
.elementType="${'shape'}"
.elements=${elements}
.edgeless=${this.edgeless}
></edgeless-change-text-menu>

View File

@@ -344,6 +344,10 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
matchFontFaces.length === 1 &&
matchFontFaces[0].style === selectedFontStyle &&
matchFontFaces[0].weight === selectedFontWeight;
const palettes =
this.elementType === 'shape'
? DefaultTheme.ShapeTextColorPalettes
: DefaultTheme.Palettes;
return join(
[
@@ -389,14 +393,14 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
return html`
<edgeless-color-picker-button
class="text-color"
.label=${'Text color'}
.label="${'Text color'}"
.pick=${this.pickColor}
.isText=${true}
.color=${selectedColor}
.colors=${colors}
.colorType=${type}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.palettes=${palettes}
>
</edgeless-color-picker-button>
`;
@@ -418,7 +422,7 @@ export class EdgelessChangeTextMenu extends WithDisposable(LitElement) {
<edgeless-color-panel
.value=${selectedColor}
.theme=${colorScheme}
.palettes=${DefaultTheme.Palettes}
.palettes=${palettes}
@select=${this._setTextColor}
></edgeless-color-panel>
</editor-menu-button>

View File

@@ -44,7 +44,6 @@ import {
import {
EmbedOptionProvider,
type EmbedOptions,
FeatureFlagService,
GenerateDocUrlProvider,
type GenerateDocUrlService,
type LinkEventType,
@@ -236,16 +235,6 @@ export class EmbedCardToolbar extends WidgetComponent<
cloneGroups(BUILT_IN_GROUPS);
private get _canConvertToEmbedView() {
// synced doc entry controlled by awareness flag
if (this.focusModel && isEmbedLinkedDocBlock(this.focusModel)) {
const isSyncedDocEnabled = this.doc
.get(FeatureFlagService)
.getFlag('enable_synced_doc_block');
if (!isSyncedDocEnabled) {
return false;
}
}
if (!this.focusBlock) return false;
return (

View File

@@ -64,7 +64,7 @@ import type {
import { tableViewMeta } from '@blocksuite/data-view/view-presets';
import { assertExists } from '@blocksuite/global/utils';
import { MoreVerticalIcon } from '@blocksuite/icons/lit';
import { Slice } from '@blocksuite/store';
import { Slice, toDraftModel } from '@blocksuite/store';
import { html, type TemplateResult } from 'lit';
import { FormatBarContext } from './context.js';
@@ -230,7 +230,9 @@ export function toolbarDefaultConfig(toolbar: AffineFormatBarWidget) {
host.selection.clear();
const doc = host.doc;
const autofill = getTitleFromSelectedModels(selectedModels);
const autofill = getTitleFromSelectedModels(
selectedModels.map(toDraftModel)
);
promptDocTitle(std, autofill)
.then(async title => {
if (title === null) return;

View File

@@ -113,12 +113,6 @@ import {
export type KeyboardToolbarConfig = {
items: KeyboardToolbarItem[];
/**
* @description Whether to use the screen height as the keyboard height when the virtual keyboard API is not supported.
* It is useful when the app is running in a webview and the keyboard is not overlaid on the content.
* @default false
*/
useScreenHeight?: boolean;
};
export type KeyboardToolbarItem =
@@ -1106,5 +1100,4 @@ export const defaultKeyboardToolbarConfig: KeyboardToolbarConfig = {
},
},
],
useScreenHeight: false,
};

View File

@@ -1,8 +1,8 @@
import { getDocTitleByEditorHost } from '@blocksuite/affine-components/doc-title';
import type { RootBlockModel } from '@blocksuite/affine-model';
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
import { WidgetComponent } from '@blocksuite/block-std';
import { IS_MOBILE } from '@blocksuite/global/env';
import { assertType } from '@blocksuite/global/utils';
import { signal } from '@preact/signals-core';
import { html, nothing } from 'lit';
@@ -20,10 +20,10 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
> {
private readonly _close = (blur: boolean) => {
if (blur) {
if (document.activeElement === this._docTitle) {
this._docTitle?.blur();
if (document.activeElement === this._docTitle?.inlineEditorContainer) {
this._docTitle?.inlineEditor?.setInlineRange(null);
} else if (document.activeElement === this.block.rootComponent) {
this.block.rootComponent?.blur();
this.std.selection.clear();
}
}
this._show$.value = false;
@@ -31,12 +31,8 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
private readonly _show$ = signal(false);
private get _docTitle(): HTMLDivElement | null {
const docTitle = this.std.host
.closest('.affine-page-viewport')
?.querySelector('doc-title rich-text .inline-editor');
assertType<HTMLDivElement | null>(docTitle);
return docTitle;
private get _docTitle() {
return getDocTitleByEditorHost(this.std.host);
}
get config() {
@@ -61,10 +57,11 @@ export class AffineKeyboardToolbarWidget extends WidgetComponent<
}
if (this._docTitle) {
this.disposables.addFromEvent(this._docTitle, 'focus', () => {
const { inlineEditorContainer } = this._docTitle;
this.disposables.addFromEvent(inlineEditorContainer, 'focus', () => {
this._show$.value = true;
});
this.disposables.addFromEvent(this._docTitle, 'blur', () => {
this.disposables.addFromEvent(inlineEditorContainer, 'blur', () => {
this._show$.value = false;
});
}

View File

@@ -1,8 +1,5 @@
import {
VirtualKeyboardController,
type VirtualKeyboardControllerConfig,
} from '@blocksuite/affine-components/virtual-keyboard';
import { getSelectedModelsCommand } from '@blocksuite/affine-shared/commands';
import { VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
import {
PropTypes,
requiredProperties,
@@ -17,20 +14,21 @@ import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
import { when } from 'lit/directives/when.js';
import { PageRootBlockComponent } from '../../page/page-root-block.js';
import { PageRootBlockComponent } from '../../page/page-root-block';
import type {
KeyboardIconType,
KeyboardToolbarConfig,
KeyboardToolbarContext,
KeyboardToolbarItem,
KeyboardToolPanelConfig,
} from './config.js';
import { keyboardToolbarStyles, TOOLBAR_HEIGHT } from './styles.js';
} from './config';
import { PositionController } from './position-controller';
import { keyboardToolbarStyles } from './styles';
import {
isKeyboardSubToolBarConfig,
isKeyboardToolBarActionItem,
isKeyboardToolPanelConfig,
} from './utils.js';
} from './utils';
export const AFFINE_KEYBOARD_TOOLBAR = 'affine-keyboard-toolbar';
@@ -43,11 +41,28 @@ export class AffineKeyboardToolbar extends SignalWatcher(
) {
static override styles = keyboardToolbarStyles;
/** This field records the panel static height same as the virtual keyboard height */
panelHeight$ = signal(0);
positionController = new PositionController(this);
get std() {
return this.rootComponent.std;
}
get keyboard() {
return this._context.std.get(VirtualKeyboardProvider);
}
get panelOpened() {
return this._currentPanelIndex$.value !== -1;
}
private readonly _closeToolPanel = () => {
if (!this._isPanelOpened) return;
if (!this.panelOpened) return;
this._currentPanelIndex$.value = -1;
this._keyboardController.show();
this.keyboard.show();
};
private readonly _currentPanelIndex$ = signal(-1);
@@ -55,7 +70,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
private readonly _goPrevToolbar = () => {
if (!this._isSubToolbarOpened) return;
if (this._isPanelOpened) this._closeToolPanel();
if (this.panelOpened) this._closeToolPanel();
this._path$.value = this._path$.value.slice(0, -1);
};
@@ -75,31 +90,25 @@ export class AffineKeyboardToolbar extends SignalWatcher(
this._closeToolPanel();
} else {
this._currentPanelIndex$.value = index;
this._keyboardController.hide();
this.scrollCurrentBlockIntoView();
this.keyboard.hide();
this._scrollCurrentBlockIntoView();
}
}
this._lastActiveItem$.value = item;
};
private readonly _keyboardController = new VirtualKeyboardController(this);
private readonly _lastActiveItem$ = signal<KeyboardToolbarItem | null>(null);
/** This field records the panel static height, which dose not aim to control the panel opening */
private readonly _panelHeight$ = signal(0);
private readonly _path$ = signal<number[]>([]);
private readonly scrollCurrentBlockIntoView = () => {
const { std } = this.rootComponent;
std.command
private readonly _scrollCurrentBlockIntoView = () => {
this.std.command
.chain()
.pipe(getSelectedModelsCommand)
.pipe(({ selectedModels }) => {
if (!selectedModels?.length) return;
const block = std.view.getBlock(selectedModels[0].id);
const block = this.std.view.getBlock(selectedModels[0].id);
if (!block) return;
const { y: y1 } = this.getBoundingClientRect();
@@ -118,7 +127,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
private get _context(): KeyboardToolbarContext {
return {
std: this.rootComponent.std,
std: this.std,
rootComponent: this.rootComponent,
closeToolbar: (blur = false) => {
this.close(blur);
@@ -130,7 +139,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
}
private get _currentPanelConfig(): KeyboardToolPanelConfig | null {
if (!this._isPanelOpened) return null;
if (!this.panelOpened) return null;
const result = this._currentToolbarItems[this._currentPanelIndex$.value];
@@ -139,9 +148,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
private get _currentToolbarItems(): KeyboardToolbarItem[] {
let items = this.config.items;
// eslint-disable-next-line @typescript-eslint/prefer-for-of
for (let i = 0; i < this._path$.value.length; i++) {
const index = this._path$.value[i];
for (const index of this._path$.value) {
if (isKeyboardSubToolBarConfig(items[index])) {
items = items[index].items;
} else {
@@ -156,21 +163,10 @@ export class AffineKeyboardToolbar extends SignalWatcher(
);
}
private get _isPanelOpened() {
return this._currentPanelIndex$.value !== -1;
}
private get _isSubToolbarOpened() {
return this._path$.value.length > 0;
}
get virtualKeyboardControllerConfig(): VirtualKeyboardControllerConfig {
return {
useScreenHeight: this.config.useScreenHeight ?? false,
inputElement: this.rootComponent,
};
}
private _renderIcon(icon: KeyboardIconType) {
return typeof icon === 'function' ? icon(this._context) : icon;
}
@@ -252,35 +248,13 @@ export class AffineKeyboardToolbar extends SignalWatcher(
e.preventDefault();
});
this.disposables.add(
effect(() => {
if (this._keyboardController.opened) {
this._panelHeight$.value = this._keyboardController.keyboardHeight;
} else if (this._isPanelOpened && this._panelHeight$.peek() === 0) {
this._panelHeight$.value = 260;
}
})
);
this.disposables.add(
effect(() => {
if (this._keyboardController.opened && !this.config.useScreenHeight) {
document.body.style.paddingBottom = `${this._keyboardController.keyboardHeight + TOOLBAR_HEIGHT}px`;
} else if (this._isPanelOpened) {
document.body.style.paddingBottom = `${this._panelHeight$.value + TOOLBAR_HEIGHT}px`;
} else {
document.body.style.paddingBottom = '';
}
})
);
this.disposables.add(
effect(() => {
const std = this.rootComponent.std;
std.selection.value;
// wait cursor updated
requestAnimationFrame(() => {
this.scrollCurrentBlockIntoView();
this._scrollCurrentBlockIntoView();
});
})
);
@@ -328,24 +302,14 @@ export class AffineKeyboardToolbar extends SignalWatcher(
);
}
override disconnectedCallback() {
super.disconnectedCallback();
document.body.style.paddingBottom = '';
}
override firstUpdated() {
// workaround for the virtual keyboard showing transition animation
setTimeout(() => {
this.scrollCurrentBlockIntoView();
this._scrollCurrentBlockIntoView();
}, 700);
}
override render() {
this.style.bottom =
this.config.useScreenHeight && this._keyboardController.opened
? `${-this._panelHeight$.value}px`
: '0px';
return html`
<div class="keyboard-toolbar">
${this._renderItems()}
@@ -355,7 +319,7 @@ export class AffineKeyboardToolbar extends SignalWatcher(
<affine-keyboard-tool-panel
.config=${this._currentPanelConfig}
.context=${this._context}
height=${this._panelHeight$.value}
height=${this.panelHeight$.value}
></affine-keyboard-tool-panel>
`;
}

View File

@@ -0,0 +1,58 @@
import { type VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
import type { BlockStdScope, ShadowlessElement } from '@blocksuite/block-std';
import { DisposableGroup } from '@blocksuite/global/utils';
import { effect, type Signal } from '@preact/signals-core';
import type { ReactiveController, ReactiveControllerHost } from 'lit';
import { TOOLBAR_HEIGHT } from './styles';
/**
* This controller is used to control the keyboard toolbar position
*/
export class PositionController implements ReactiveController {
private readonly _disposables = new DisposableGroup();
host: ReactiveControllerHost &
ShadowlessElement & {
std: BlockStdScope;
panelHeight$: Signal<number>;
keyboard: VirtualKeyboardProvider;
panelOpened: boolean;
};
constructor(host: PositionController['host']) {
(this.host = host).addController(this);
}
hostConnected() {
const { keyboard, panelOpened } = this.host;
this._disposables.add(
effect(() => {
if (keyboard.visible$.value) {
this.host.panelHeight$.value = keyboard.height$.value;
}
})
);
this.host.style.bottom = '0px';
this._disposables.add(
effect(() => {
if (keyboard.visible$.value) {
document.body.style.paddingBottom = `${keyboard.height$.value + TOOLBAR_HEIGHT}px`;
} else if (panelOpened) {
document.body.style.paddingBottom = `${this.host.panelHeight$.peek() + TOOLBAR_HEIGHT}px`;
} else {
document.body.style.paddingBottom = '';
}
})
);
this._disposables.add(() => {
document.body.style.paddingBottom = '';
});
}
hostDisconnected() {
this._disposables.dispose();
}
}

View File

@@ -55,15 +55,15 @@ export interface LinkedWidgetConfig {
*
* If the return value is not null, no action will be taken.
*/
autoFocusedItem?: (
autoFocusedItemKey?: (
menus: LinkedMenuGroup[],
query: string,
currentActiveKey: string | null,
editorHost: EditorHost,
inlineEditor: AffineInlineEditor
) => LinkedMenuItem | null;
) => string | null;
mobile: {
useScreenHeight?: boolean;
/**
* The linked doc menu widget will scroll the container to make sure the input cursor is visible in viewport.
* It accepts a selector string, HTMLElement or Window
@@ -101,8 +101,6 @@ export type LinkedMenuGroup = {
loading?: boolean | Signal<boolean>;
// copywriting when display quantity exceeds
overflowText?: string | Signal<string>;
// loading text
loadingText?: string | Signal<string>;
};
export type LinkedDocContext = {
@@ -233,6 +231,7 @@ export function createNewDocMenuGroup(
};
showImportModal({
collection: doc.workspace,
schema: doc.schema,
onSuccess,
onFail,
});

View File

@@ -8,7 +8,7 @@ import {
} from '@blocksuite/affine-components/icons';
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils';
import type { Workspace } from '@blocksuite/store';
import type { Schema, Workspace } from '@blocksuite/store';
import { html, LitElement, type PropertyValues } from 'lit';
import { query, state } from 'lit/decorators.js';
@@ -31,6 +31,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
constructor(
private readonly collection: Workspace,
private readonly schema: Schema,
private readonly onSuccess?: OnSuccessHandler,
private readonly onFail?: OnFailHandler,
private readonly abortController = new AbortController()
@@ -63,6 +64,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
}
const pageId = await HtmlTransformer.importHTMLToDoc({
collection: this.collection,
schema: this.schema,
html: text,
fileName,
});
@@ -93,6 +95,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
}
const pageId = await MarkdownTransformer.importMarkdownToDoc({
collection: this.collection,
schema: this.schema,
markdown: text,
fileName,
});
@@ -117,6 +120,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
const { entryId, pageIds, isWorkspaceFile, hasMarkdown } =
await NotionHtmlTransformer.importNotionZip({
collection: this.collection,
schema: this.schema,
imported: file,
});
needLoading && this.abortController.abort();

View File

@@ -1,4 +1,4 @@
import type { Workspace } from '@blocksuite/store';
import type { Schema, Workspace } from '@blocksuite/store';
import {
ImportDoc,
@@ -7,12 +7,14 @@ import {
} from './import-doc.js';
export function showImportModal({
schema,
collection,
onSuccess,
onFail,
container = document.body,
abortController = new AbortController(),
}: {
schema: Schema;
collection: Workspace;
onSuccess?: OnSuccessHandler;
onFail?: OnFailHandler;
@@ -22,6 +24,7 @@ export function showImportModal({
}) {
const importDoc = new ImportDoc(
collection,
schema,
onSuccess,
onFail,
abortController

View File

@@ -20,10 +20,8 @@ import { choose } from 'lit/directives/choose.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
import {
type PageRootBlockComponent,
RootBlockConfigExtension,
} from '../../index.js';
import type { PageRootBlockComponent } from '../../page/page-root-block.js';
import { RootBlockConfigExtension } from '../../root-config.js';
import {
type AFFINE_LINKED_DOC_WIDGET,
getMenus,
@@ -216,7 +214,6 @@ export class AffineLinkedDocWidget extends WidgetComponent<
convertTriggerKey: true,
getMenus,
mobile: {
useScreenHeight: false,
scrollContainer: getViewportElement(this.std.host) ?? window,
scrollTopOffset: 46,
},

View File

@@ -75,23 +75,33 @@ export class LinkedDocPopover extends SignalWatcher(
// need to rebind the effect because this._linkedDocGroup has changed.
this._menusItemsEffectCleanup = effect(() => {
this._updateAutoFocusedItem();
// wait for the next tick to ensure the items are rendered to DOM
setTimeout(() => {
this.scrollToFocusedItem();
});
});
};
private readonly _updateAutoFocusedItem = () => {
if (!this._query) {
return;
}
const autoFocusedItem = this.context.config.autoFocusedItem?.(
// Get the auto-focused item key from the config
const autoFocusedItemKey = this.context.config.autoFocusedItemKey?.(
this._linkedDocGroup,
this._query,
this._query || '',
this._activatedItemKey,
this.context.std.host,
this.context.inlineEditor
);
if (autoFocusedItem) {
this._activatedItemIndex = this._flattenActionList.findIndex(
item => item.key === autoFocusedItem.key
);
if (autoFocusedItemKey) {
this._activatedItemKey = autoFocusedItemKey;
return;
}
// If no auto-focused item key is returned from the config and no item is currently focused,
// focus the first item in the flattened action list
if (!this._activatedItemKey && this._flattenActionList.length > 0) {
this._activatedItemKey = this._flattenActionList[0].key;
}
};
@@ -126,19 +136,9 @@ export class LinkedDocPopover extends SignalWatcher(
let items = resolveSignal(group.items);
const isOverflow = !!group.maxDisplay && items.length > group.maxDisplay;
const isLoading = resolveSignal(group.loading);
items = isExpanded ? items : items.slice(0, group.maxDisplay);
if (isLoading) {
items = items.concat({
key: 'loading',
name: resolveSignal(group.loadingText) || 'loading',
icon: LoadingIcon,
action: () => {},
});
}
if (isOverflow && !isExpanded && group.maxDisplay) {
items = items.concat({
key: `${group.name} More`,
@@ -183,7 +183,6 @@ export class LinkedDocPopover extends SignalWatcher(
target: eventSource,
signal: keydownObserverAbortController.signal,
onInput: isComposition => {
this._activatedItemIndex = 0;
if (isComposition) {
this._updateLinkedDocGroup().catch(console.error);
} else {
@@ -193,7 +192,6 @@ export class LinkedDocPopover extends SignalWatcher(
}
},
onPaste: () => {
this._activatedItemIndex = 0;
setTimeout(() => {
this._updateLinkedDocGroup().catch(console.error);
}, 50);
@@ -206,33 +204,18 @@ export class LinkedDocPopover extends SignalWatcher(
if (curRange.index < this.context.startRange.index) {
this.context.close();
}
this._activatedItemIndex = 0;
this.context.inlineEditor.slots.renderComplete.once(
this._updateLinkedDocGroup
);
},
onMove: step => {
const itemLen = this._flattenActionList.length;
this._activatedItemIndex =
(itemLen + this._activatedItemIndex + step) % itemLen;
// Scroll to the active item
const item = this._flattenActionList[this._activatedItemIndex];
const shadowRoot = this.shadowRoot;
if (!shadowRoot) {
console.warn('Failed to find the shadow root!', this);
return;
const nextIndex = (itemLen + this._activatedItemIndex + step) % itemLen;
const item = this._flattenActionList[nextIndex];
if (item) {
this._activatedItemKey = item.key;
}
const ele = shadowRoot.querySelector(
`icon-button[data-id="${item.key}"]`
);
if (!ele) {
console.warn('Failed to find the active item!', item);
return;
}
ele.scrollIntoView({
block: 'nearest',
});
this.scrollToFocusedItem();
},
onConfirm: () => {
this._flattenActionList[this._activatedItemIndex]
@@ -261,19 +244,29 @@ export class LinkedDocPopover extends SignalWatcher(
visibility: 'hidden',
});
// XXX This is a side effect
let accIdx = 0;
const actionGroups = this._actionGroup.map(group => {
// Check if the group is loading
const isLoading = resolveSignal(group.loading);
return {
...group,
isLoading,
};
});
return html`<div class="linked-doc-popover" style="${style}">
${this._actionGroup
.filter(group => group.items.length)
${actionGroups
.filter(group => group.items.length || group.isLoading)
.map((group, idx) => {
return html`
<div class="divider" ?hidden=${idx === 0}></div>
<div class="group-title">${group.name}</div>
<div class="group-title">
${group.name}
${group.isLoading
? html`<span class="loading-icon">${LoadingIcon}</span>`
: nothing}
</div>
<div class="group" style=${group.styles ?? ''}>
${group.items.map(({ key, name, icon, action }) => {
accIdx++;
const curIdx = accIdx - 1;
const tooltip = this._showTooltip
? html`<affine-tooltip
tip-position=${'right'}
@@ -290,13 +283,13 @@ export class LinkedDocPopover extends SignalWatcher(
height="30px"
data-id=${key}
.text=${name}
hover=${this._activatedItemIndex === curIdx}
hover=${this._activatedItemKey === key}
@click=${() => {
action()?.catch(console.error);
}}
@mousemove=${() => {
// Use `mousemove` instead of `mouseover` to avoid navigate conflict with keyboard
this._activatedItemIndex = curIdx;
this._activatedItemKey = key;
// show tooltip whether text length overflows
for (const button of this.iconButtons.values()) {
if (button.dataset.id == key && button.textElement) {
@@ -348,8 +341,40 @@ export class LinkedDocPopover extends SignalWatcher(
}
}
private scrollToFocusedItem() {
const shadowRoot = this.shadowRoot;
if (!shadowRoot) {
return;
}
// If there's no active item key, don't try to scroll
if (!this._activatedItemKey) {
return;
}
const ele = shadowRoot.querySelector(
`icon-button[data-id="${this._activatedItemKey}"]`
);
// If the element doesn't exist, don't log a warning
if (!ele) {
return;
}
ele.scrollIntoView({
block: 'nearest',
});
}
get _activatedItemIndex() {
const index = this._flattenActionList.findIndex(
item => item.key === this._activatedItemKey
);
return index === -1 ? 0 : index;
}
@state()
private accessor _activatedItemIndex = 0;
private accessor _activatedItemKey: string | null = null;
@state()
private accessor _linkedDocGroup: LinkedMenuGroup[] = [];

View File

@@ -2,10 +2,7 @@ import {
cleanSpecifiedTail,
getTextContentFromInlineRange,
} from '@blocksuite/affine-components/rich-text';
import {
VirtualKeyboardController,
type VirtualKeyboardControllerConfig,
} from '@blocksuite/affine-components/virtual-keyboard';
import { VirtualKeyboardProvider } from '@blocksuite/affine-shared/services';
import {
createKeydownObserver,
getViewportElement,
@@ -43,8 +40,6 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
private _firstActionItem: LinkedMenuItem | null = null;
private readonly _keyboardController = new VirtualKeyboardController(this);
private readonly _linkedDocGroup$ = signal<LinkedMenuGroup[]>([]);
private readonly _renderGroup = (group: LinkedMenuGroup) => {
@@ -159,11 +154,8 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
);
}
get virtualKeyboardControllerConfig(): VirtualKeyboardControllerConfig {
return {
useScreenHeight: this.context.config.mobile.useScreenHeight ?? false,
inputElement: this.rootComponent,
};
get keyboard() {
return this.context.std.get(VirtualKeyboardProvider);
}
override connectedCallback() {
@@ -230,8 +222,8 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
}
override firstUpdated() {
if (!this._keyboardController.opened) {
this._keyboardController.show();
if (!this.keyboard.visible$.value) {
this.keyboard.show();
}
this._scrollInputToTop();
}
@@ -244,11 +236,7 @@ export class AffineMobileLinkedDocMenu extends SignalWatcher(
this._firstActionItem = resolveSignal(groups[0].items)[0];
this.style.bottom =
this.context.config.mobile.useScreenHeight &&
this._keyboardController.opened
? '0px'
: `max(0px, ${this._keyboardController.keyboardHeight}px)`;
this.style.bottom = `${this.keyboard.height$.value}px`;
return html`
${join(groups.map(this._renderGroup), html`<div class="divider"></div>`)}

View File

@@ -51,6 +51,18 @@ export const linkedDocPopoverStyles = css`
align-items: center;
flex-shrink: 0;
font-weight: 500;
justify-content: space-between;
}
.linked-doc-popover .group-title .loading-icon {
display: flex;
align-items: center;
margin-left: 8px;
}
.linked-doc-popover .group-title .loading-icon svg {
width: 20px;
height: 20px;
}
.linked-doc-popover .divider {

View File

@@ -423,8 +423,9 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
override mounted() {
const disposable = this.std.view.viewUpdated.on(payload => {
if (payload.type !== 'block') return;
if (
payload.type === 'add' &&
payload.method === 'add' &&
matchModels(payload.view.model, [RootBlockModel])
) {
disposable.dispose();

View File

@@ -34,7 +34,7 @@
},
"devDependencies": {
"@types/lodash.chunk": "^4.2.9",
"vitest": "3.0.6"
"vitest": "3.0.7"
},
"exports": {
".": "./src/index.ts",

View File

@@ -50,7 +50,11 @@ export {
} from './adapters/index.js';
export type { SurfaceContext } from './surface-block.js';
export { SurfaceBlockComponent } from './surface-block.js';
export { SurfaceBlockModel, SurfaceBlockSchema } from './surface-model.js';
export {
SurfaceBlockModel,
SurfaceBlockSchema,
SurfaceBlockSchemaExtension,
} from './surface-model.js';
export type { SurfaceBlockService } from './surface-service.js';
export {
EdgelessSurfaceBlockSpec,

View File

@@ -5,7 +5,7 @@ import type {
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
import { DisposableGroup } from '@blocksuite/global/utils';
import { defineBlockSchema } from '@blocksuite/store';
import { BlockSchemaExtension, defineBlockSchema } from '@blocksuite/store';
import * as Y from 'yjs';
import { elementsCtorMap } from './element-model/index.js';
@@ -36,6 +36,9 @@ export const SurfaceBlockSchema = defineBlockSchema({
toModel: () => new SurfaceBlockModel(),
});
export const SurfaceBlockSchemaExtension =
BlockSchemaExtension(SurfaceBlockSchema);
export type SurfaceMiddleware = (surface: SurfaceBlockModel) => () => void;
export class SurfaceBlockModel extends BaseSurfaceModel {

View File

@@ -246,6 +246,7 @@ export class AddButton extends SignalWatcher(
this.hoverColumnIndex$.value === this.columns$.value.length - 1;
const dragging = this.columnDragging$.value;
return html` <div
data-testid="add-column-button"
class="${classMap({
[addColumnButtonStyle]: true,
active: dragging,
@@ -269,6 +270,7 @@ export class AddButton extends SignalWatcher(
const hovered = this.hoverRowIndex$.value === this.rows$.value.length - 1;
const dragging = this.rowDragging$.value;
return html` <div
data-testid="add-row-button"
class="${classMap({
[addRowButtonStyle]: true,
active: dragging,

View File

@@ -180,14 +180,16 @@ export class TableCell extends SignalWatcher(
name: 'Insert Left',
prefix: InsertLeftIcon(),
select: () => {
this.dataManager.insertColumn(columnIndex - 1);
this.dataManager.insertColumn(
columnIndex > 0 ? columnIndex - 1 : undefined
);
},
}),
menu.action({
name: 'Insert Right',
prefix: InsertRightIcon(),
select: () => {
this.dataManager.insertColumn(columnIndex + 1);
this.dataManager.insertColumn(columnIndex);
},
}),
menu.action({
@@ -304,14 +306,16 @@ export class TableCell extends SignalWatcher(
name: 'Insert Above',
prefix: InsertAboveIcon(),
select: () => {
this.dataManager.insertRow(rowIndex - 1);
this.dataManager.insertRow(
rowIndex > 0 ? rowIndex - 1 : undefined
);
},
}),
menu.action({
name: 'Insert Below',
prefix: InsertBelowIcon(),
select: () => {
this.dataManager.insertRow(rowIndex + 1);
this.dataManager.insertRow(rowIndex);
},
}),
menu.action({
@@ -454,6 +458,7 @@ export class TableCell extends SignalWatcher(
};
return html`<div class=${columnOptionsCellStyle}>
<div
data-testid="drag-column-handle"
data-drag-column-id=${column.columnId}
class=${classMap({
[columnOptionsStyle]: true,
@@ -478,6 +483,7 @@ export class TableCell extends SignalWatcher(
};
return html`<div class=${rowOptionsCellStyle}>
<div
data-testid="drag-row-handle"
data-drag-row-id=${row.rowId}
class=${classMap({
[rowOptionsStyle]: true,

View File

@@ -34,7 +34,7 @@
"lit-html": "^3.2.1",
"lodash.clonedeep": "^4.5.0",
"remark-math": "^6.0.0",
"shiki": "^2.0.0",
"shiki": "^3.0.0",
"yjs": "^13.6.21",
"zod": "^3.23.8"
},
@@ -55,7 +55,6 @@
"./date-picker": "./src/date-picker/index.ts",
"./drop-indicator": "./src/drop-indicator/index.ts",
"./filterable-list": "./src/filterable-list/index.ts",
"./virtual-keyboard": "./src/virtual-keyboard/index.ts",
"./toggle-button": "./src/toggle-button/index.ts",
"./toggle-switch": "./src/toggle-switch/index.ts",
"./notification": "./src/notification/index.ts",

View File

@@ -1,5 +1,5 @@
import type { ColorScheme, Palette } from '@blocksuite/affine-model';
import { resolveColor } from '@blocksuite/affine-model';
import { DefaultTheme, resolveColor } from '@blocksuite/affine-model';
import type { ColorEvent } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils';
import { html, LitElement } from 'lit';
@@ -188,7 +188,7 @@ export class EdgelessColorPickerButton extends WithDisposable(LitElement) {
accessor menuButton!: EditorMenuButton;
@property({ attribute: false })
accessor palettes: Palette[] = [];
accessor palettes: Palette[] = DefaultTheme.Palettes;
@property({ attribute: false })
accessor pick!: (event: PickColorEvent) => void;

Some files were not shown because too many files have changed in this diff Show More