Compare commits

..

31 Commits

Author SHA1 Message Date
DarkSky
f373e08583 feat: refactor doc write in native (#14272) 2026-01-18 16:31:12 +08:00
Gabriele
753b11deeb fix: resolve navbar overlay issue on sign-in page (#14274)
This pr fixes #14273.

I have implemented two minor CSS adjustments to resolve the navbar
interaction issue on the sign-in page:

- Removed position: relative and z-index: 1 from signInPageContainer.
- Set z-index: 1 on the SignInPanel div (prevent SignInBackgroundArts
from overlapping the SignInPanel)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
  * Adjusted z-index layering for the sign-in page component.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-17 17:32:42 +00:00
Heera Rana
17f2ebc4de feat: render document header image from document metadata (#14255)
### What
Adds support for rendering an optional image above the document title
using document metadata.

### Why
Provides a visual identifier for documents and improves readability for
users who rely on visual cues.

### How
- Reads `headerImage` from document metadata (if present)
- Renders the image above the editor when present
- Fully optional and non-breaking
- No BlockSuite or data model changes

### Related
fix #14240


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Documents can now display header images in the page editor. When a
header image is available, it appears above the editor content,
enhancing visual presentation and providing better context for your
documents.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-16 14:18:59 +00:00
realies
0da91e406e feat(server): add document write tools for mcp (#14245)
## Summary

This PR adds write capabilities to AFFiNE's MCP (Model Context Protocol)
integration, enabling external tools (Claude, GPT, etc.) to create and
modify documents programmatically.

**New MCP Tools:**
- `create_document` - Create new documents from markdown content
- `update_document` - Update document content using structural diffing
for minimal changes (preserves document history and enables real-time
collaboration)

**Implementation:**
- `markdown_to_ydoc.rs` - Converts markdown to AFFiNE-compatible y-octo
binary format
- `markdown_utils.rs` - Shared markdown parsing utilities (used by both
ydoc-to-md and md-to-ydoc)
- `update_ydoc.rs` - Structural diffing implementation for updating
existing documents
- `DocWriter` service - TypeScript service for document operations
- Exposes `markdownToDocBinary` and `updateDocBinary` via napi bindings

**Supported Markdown Elements:**
- Headings (H1-H6)
- Paragraphs
- Bullet lists and numbered lists
- Code blocks (with language detection)
- Blockquotes
- Horizontal dividers
- Todo items (checkboxes)

**y-octo Changes:**
This PR reverts the y-octo sync (ca2462f, a5b60cf) which introduced a
concurrency bug causing hangs when creating documents with many nested
block structures. It also ports the improved `get_node_index` binary
search fix from upstream that prevents divide-by-zero panics when
decoding documents.

## Test Results 

### Unit Tests (47/47 passing)

| Test Suite | Tests | Status |
|------------|-------|--------|
| markdown_to_ydoc | 16/16 |  Pass |
| markdown_utils | 11/11 |  Pass |
| update_ydoc | 13/13 |  Pass |
| delta_markdown | 2/2 |  Pass |
| affine (doc parser) | 5/5 |  Pass |

### End-to-End MCP Testing 

Tested against local AFFiNE server with real MCP client requests:

| Tool | Result | Notes |
|------|--------|-------|
| `tools/list` |  Pass | Returns all 5 tools with correct schemas |
| `create_document` |  Pass | Successfully created test documents |
| `update_document` |  Pass | Successfully updated documents with
structural diffing |
| `read_document` |  Pass | Existing tool, works correctly |
| `keyword_search` |  Pass | Existing tool, works correctly |

**E2E Test Details:**
- Started local AFFiNE server with PostgreSQL, Redis, and Manticore
- Created test user and workspace via seed/GraphQL
- Verified MCP endpoint at `/api/workspaces/:workspaceId/mcp`
- Tested JSON-RPC calls with proper SSE streaming
- Confirmed documents are stored and indexed correctly (verified via
server logs)

## Test Plan
- [x] All Rust unit tests pass (47 tests)
- [x] Native bindings build successfully (release mode)
- [x] Document creation via MCP works end-to-end
- [x] Document update via MCP works end-to-end
- [x] CodeRabbit feedback addressed
- [ ] Integration testing with Claude/GPT MCP clients

Closes #14161

---

**Requested by:** @realies  
**Key guidance from:** @darkskygit (use y-octo instead of yjs for memory
efficiency)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Create documents from Markdown: generate new documents directly from
Markdown content with automatic title extraction
* Update documents with Markdown: modify existing documents using
Markdown as the source with automatic diff calculation for efficient
updates
* Copilot integration: new tools for document creation and updates
through Copilot's interface

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-16 20:57:24 +08:00
DarkSky
2c5559ed0b fix: missing session fields 2026-01-16 17:26:05 +08:00
DarkSky
924d58603f chore: improve event flow (#14266) 2026-01-16 16:07:27 +08:00
DarkSky
d4581b839a chore: add tools 2026-01-16 10:53:13 +08:00
DarkSky
8d14607c2b feat: improve indexer perf 2026-01-15 19:27:41 +08:00
DarkSky
00a458543f feat: cleanup chat panel (#14258)
#### PR Dependency Tree


* **PR #14258** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **Removed Features**
* Web search functionality has been removed from AI chat and related AI
features. Users will no longer see network search options or toggles in
chat preferences and panels.
  * AI chat requests no longer support external web search capabilities.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #14258** 👈
  * **PR #14259**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
2026-01-15 19:20:55 +08:00
DarkSky
ac7a95e708 feat: misc optimizations (#14257)
fix #13798
2026-01-15 03:47:22 +08:00
DarkSky
76e1721d70 fix: journal conflict handle 2026-01-15 00:55:35 +08:00
DarkSky
fc59dff9e2 chore: enable blur background for mac 2026-01-15 00:35:11 +08:00
DarkSky
27a58e764c chore: bump version & deps 2026-01-15 00:33:51 +08:00
DarkSky
13907f7234 fix(core): event flow handle (#14256) 2026-01-15 00:04:32 +08:00
DarkSky
7c24b2521a feat: reduce backend (#14251)
#### PR Dependency Tree


* **PR #14251** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Current user profile now exposes access tokens, revealed tokens, and
detailed calendar accounts/subscriptions.
* Workspace now exposes permissions, calendars, calendar events, and a
workspace-scoped blob upload part URL.
  * New document-update mutation for applying doc updates.

* **API Changes**
  * validateAppConfig is now a query (mutation deprecated).
* Several legacy top-level calendar/blob endpoints deprecated in favor
of user/workspace fields.

* **Refactor**
* Calendar, blob-upload and access-token surfaces reorganized to use
user/workspace-centric fields.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-14 00:01:07 +08:00
github-actions[bot]
7c440686ad chore(i18n): sync translations (#14148)
New Crowdin translations by [Crowdin GH
Action](https://github.com/crowdin/github-action)

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: DarkSky <darksky2048@gmail.com>
2026-01-13 22:09:42 +08:00
DarkSky
b331a08744 feat: native update merge (#14250)
#### PR Dependency Tree


* **PR #14250** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Backend Optimization**
  * Faster document retrieval via a native binary fetch path.
* Native-accelerated merging of document updates for improved
performance and consistency.
* **Indexing & Reliability**
* Indexing now only proceeds on valid parse results, with clearer
warnings and richer metadata on failures.
* More consistent sync behavior and enhanced diagnostic logging for
indexing operations.
* **Tests**
  * Expanded tests to cover native binary retrieval error handling.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-13 22:03:55 +08:00
DarkSky
279b7bb64f feat(core): integrate google calendar sync (#14248)
fix #14170 
fix #13893 
fix #13673 
fix #13543 
fix #13308 
fix #7607




#### PR Dependency Tree


* **PR #14247**
  * **PR #14248** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Integrations panel in Account Settings to link/unlink calendar
providers.
  * Collapsible settings wrapper for improved layout.

* **Improvements**
* Calendar system reworked: per-account calendar groups, simplified
toggles with explicit Save, richer event display (multi-dot date
indicators), improved event time/title handling across journal views.

* **Localization**
* Added calendar keys: save-error, no-journal, no-calendar; removed
legacy duplicate-error keys.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-13 02:38:16 +08:00
DarkSky
89f0430242 fix: race conditions (y-crdt/y-octo#51) 2026-01-13 01:10:07 +08:00
DarkSky
0bd8160ed4 feat: init cloud calendar support (#14247)
#### PR Dependency Tree


* **PR #14247** 👈
  * **PR #14248**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Google Calendar integration (disabled by default): link/unlink
accounts, OAuth flow, webhooks, real-time push, background sync,
workspace calendars with customizable items and date-range event
viewing.
* **GraphQL / Client**
* New queries & mutations for accounts, subscriptions, events,
providers, and workspace calendar management.
* **Localization**
* Added localized error message for calendar provider request failures.
* **Tests**
* Backend tests covering sync, webhook renewal, and error/error-recovery
scenarios.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-12 23:17:43 +08:00
DarkSky
a5b60cf679 fix: index calc & detached node handle (y-crdt/y-octo#50) 2026-01-11 18:44:55 +08:00
DarkSky
ca2462f987 feat(native): sync yocto codes (#14243)
#### PR Dependency Tree


* **PR #14243** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Batch management API for coordinated document mutations and change
tracking.
* New document accessors (IDs, state snapshots, change/delete set
queries) and subscriber count.

* **Chores**
  * Upgraded Rust edition across packages to 2024.
  * Repository-wide formatting, stylistic cleanups and test adjustments.

* **Breaking Changes**
* Removed the Node native bindings package and its JS/TS declarations
and tests (no longer published/available).

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-11 06:08:33 +08:00
Adit Syed Afnan
d515d295ce feat(editor): enhance string comparison handling in eval.ts (#14233)
Refactors the compareString function to safely handle null and undefined
inputs and improves overall string comparison logic. This prevents
incorrect sort behavior and ensures consistent ordering when comparing
mixed or missing values, particularly in table view sorting scenarios.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved string comparison used for sorting: empty values are
consistently placed last, numeric parts sort numerically before
non-numeric parts, and mixed-type and case variations are handled more
predictably for stable, consistent ordering across data views.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-09 02:58:00 +00:00
DarkSky
e4dc82ee35 chore: bump deps (#14227)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated backend service dependencies to the latest stable versions for
improved performance and security.
* Upgraded UI component library dependencies to the latest minor
releases.

* **Improvements**
* Enhanced web search functionality for better search results on
standard AI models.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-07 13:15:17 +08:00
renovate[bot]
aa6f26b1a5 chore: bump up opentelemetry (#14208)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
|
[@opentelemetry/instrumentation-ioredis](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-ioredis#readme)
([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-ioredis))
| [`^0.56.0` →
`^0.57.0`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-ioredis/0.56.0/0.57.0)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-ioredis/0.57.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-ioredis/0.56.0/0.57.0?slim=true)
|
|
[@opentelemetry/instrumentation-socket.io](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-socket.io#readme)
([source](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/tree/HEAD/packages/instrumentation-socket.io))
| [`0.55.0` →
`0.55.1`](https://renovatebot.com/diffs/npm/@opentelemetry%2finstrumentation-socket.io/0.55.0/0.55.1)
|
![age](https://developer.mend.io/api/mc/badges/age/npm/@opentelemetry%2finstrumentation-socket.io/0.55.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@opentelemetry%2finstrumentation-socket.io/0.55.0/0.55.1?slim=true)
|

---

### Release Notes

<details>
<summary>open-telemetry/opentelemetry-js-contrib
(@&#8203;opentelemetry/instrumentation-ioredis)</summary>

###
[`v0.57.0`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-ioredis/CHANGELOG.md#0570-2025-12-17)

[Compare
Source](94e5b7da45...66935ac724)

##### Features

- **instrumentations-ioredis:** support `net.*` and database semconv
migration
([#&#8203;3266](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/issues/3266))
([9f92c8b](9f92c8b5b1))

##### Dependencies

- The following workspace dependencies were updated
  - devDependencies
-
[@&#8203;opentelemetry/contrib-test-utils](https://redirect.github.com/opentelemetry/contrib-test-utils)
bumped from ^0.55.0 to ^0.56.0

</details>

<details>
<summary>open-telemetry/opentelemetry-js-contrib
(@&#8203;opentelemetry/instrumentation-socket.io)</summary>

###
[`v0.55.1`](https://redirect.github.com/open-telemetry/opentelemetry-js-contrib/blob/HEAD/packages/instrumentation-socket.io/CHANGELOG.md#0551-2025-12-17)

[Compare
Source](94e5b7da45...66935ac724)

##### Dependencies

- The following workspace dependencies were updated
  - devDependencies
-
[@&#8203;opentelemetry/contrib-test-utils](https://redirect.github.com/opentelemetry/contrib-test-utils)
bumped from ^0.55.0 to ^0.56.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.

👻 **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:eyJjcmVhdGVkSW5WZXIiOiI0Mi42OS4xIiwidXBkYXRlZEluVmVyIjoiNDIuNjkuMSIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-07 11:45:15 +08:00
likljn
c1d43b9b18 fix(editor): keep slash menu alive on text input when no_result (#14141)
**Problem**
Slash menu can be prematurely aborted when the query is still in
`no_result`
due to async query updates after deletion.

**Solution**
Keep the slash menu alive on text input while in `no_result`,
preventing aborts based on a stale query state.

**Repro**
1. Type `/eeee`
2. Delete to `/`
3. Type `h`
4. Slash menu should recover and show results


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Enhanced slash-menu keyboard interaction: users can now continue
typing to refine queries when no results are displayed, instead of the
menu closing unexpectedly. Keyboard navigation and other controls remain
responsive.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: DarkSky <25152247+darkskygit@users.noreply.github.com>
2026-01-07 02:13:13 +00:00
DarkSky
b8e597fa1d fix: hide search local label if need 2026-01-07 10:42:51 +08:00
Cats Juice
cf98afb32e chore: bump theme@1.1.23 (#14222)
close #13952

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Chores**
* Upgraded the shared theme library from v1.1.16 to v1.1.23 across the
project (core components, UI widgets, content blocks, and frontend
apps), delivering the latest styling and design refinements
platform-wide.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: L-Sun <zover.v@gmail.com>
2026-01-06 20:48:44 +08:00
Yiding Jia
a11e9fe8ca feat(server): add LISTEN_ADDR env var for allowing server to listen on ipv6 (#14211)
The old code hardcoded 0.0.0.0 which means the server only listened for
ipv4 connections, making it not work on ipv6-only networks.

This change adds a LISTEN_ADDR env var which allows the server to bind
to ipv6 as well.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Server listen address is now configurable via the LISTEN_ADDR
environment variable (default: 0.0.0.0), enabling IPv4/IPv6 or
interface-specific binding.
* Configuration schemas and admin UI now expose the listen address
option so deployments can view and override it.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-05 09:31:47 +00:00
DarkSky
f42246aba1 fix: allow method for cors 2026-01-05 13:14:56 +08:00
Whitewater
f5394b7450 fix: refine handling for non-standard keyboards to avoid incorrect keyCode fallback (#14206)
Fix https://github.com/toeverything/AFFiNE/issues/14059

With the help of Claude Opus 4.5

Improve handling of keyCode fallback for non-standard keyboards by only
applying it when modifier keys are pressed. This change prevents
incorrect fallback behavior for non-ASCII characters, ensuring users can
type intended characters without triggering shortcuts.

After


https://github.com/user-attachments/assets/00ab4fb2-4bc2-4ca7-a284-9782686d298c

Event dump for Cyrillic x

```json

{
 "key": "х",
 "keyCode": 219,
 "which": 219,
 "code": "BracketLeft",
 "location": 0,
 "altKey": false,
 "ctrlKey": false,
 "metaKey": false,
 "shiftKey": false,
 "repeat": false
}
```

blocksuite commit
4c0d39890f (diff-68c46455e0eece88312235df85f8ce27ae254efccde6fb987f2505180730bd8c)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Refined keyboard input handling to properly support non-ASCII
characters (e.g., Cyrillic, Greek) by ensuring user-typed characters are
preserved instead of inadvertently triggering keyboard shortcuts. The
fix maintains keyboard shortcut functionality while improving
compatibility with international keyboards and input methods.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-01-04 09:18:03 +00:00
530 changed files with 21392 additions and 11422 deletions

View File

@@ -595,6 +595,11 @@
"description": "Multiple hosts the server will accept requests from.\n@default []",
"default": []
},
"listenAddr": {
"type": "string",
"description": "The address to listen on (e.g., 0.0.0.0 for IPv4, :: for IPv6).\n@default \"0.0.0.0\"\n@environment `LISTEN_ADDR`",
"default": "0.0.0.0"
},
"port": {
"type": "number",
"description": "Which port the server will listen on.\n@default 3010\n@environment `AFFINE_SERVER_PORT`",
@@ -629,6 +634,45 @@
}
}
},
"telemetry": {
"type": "object",
"description": "Configuration for telemetry module",
"properties": {
"allowedOrigin": {
"type": "array",
"description": "Allowed origins for telemetry collection.\n@default [\"localhost\",\"127.0.0.1\"]",
"default": [
"localhost",
"127.0.0.1"
]
},
"ga4.measurementId": {
"type": "string",
"description": "GA4 Measurement ID for Measurement Protocol.\n@default \"\"\n@environment `GA4_MEASUREMENT_ID`",
"default": ""
},
"ga4.apiSecret": {
"type": "string",
"description": "GA4 API secret for Measurement Protocol.\n@default \"\"\n@environment `GA4_API_SECRET`",
"default": ""
},
"dedupe.ttlHours": {
"type": "number",
"description": "Telemetry dedupe TTL in hours.\n@default 24",
"default": 24
},
"dedupe.maxEntries": {
"type": "number",
"description": "Telemetry dedupe max entries.\n@default 100000",
"default": 100000
},
"batch.maxEvents": {
"type": "number",
"description": "Max events per telemetry batch.\n@default 25",
"default": 25
}
}
},
"client": {
"type": "object",
"description": "Configuration for client module",
@@ -645,6 +689,40 @@
}
}
},
"calendar": {
"type": "object",
"description": "Configuration for calendar module",
"properties": {
"google": {
"type": "object",
"description": "Google Calendar integration config\n@default {\"enabled\":false,\"clientId\":\"\",\"clientSecret\":\"\",\"externalWebhookUrl\":\"\",\"webhookVerificationToken\":\"\"}\n@link https://developers.google.com/calendar/api/guides/push",
"properties": {
"enabled": {
"type": "boolean"
},
"clientId": {
"type": "string"
},
"clientSecret": {
"type": "string"
},
"externalWebhookUrl": {
"type": "string"
},
"webhookVerificationToken": {
"type": "string"
}
},
"default": {
"enabled": false,
"clientId": "",
"clientSecret": "",
"externalWebhookUrl": "",
"webhookVerificationToken": ""
}
}
}
},
"captcha": {
"type": "object",
"description": "Configuration for captcha module",

View File

@@ -1,6 +1,8 @@
# Editor configuration, see http://editorconfig.org
root = true
[*.rs]
max_line_length = 120
[*]
charset = utf-8
indent_style = space

View File

@@ -3,4 +3,4 @@ name: affine
description: AFFiNE cloud chart
type: application
version: 0.0.0
appVersion: "0.25.7"
appVersion: "0.26.0"

View File

@@ -3,7 +3,7 @@ name: doc
description: AFFiNE doc server
type: application
version: 0.0.0
appVersion: "0.25.7"
appVersion: "0.26.0"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: graphql
description: AFFiNE GraphQL server
type: application
version: 0.0.0
appVersion: "0.25.7"
appVersion: "0.26.0"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: renderer
description: AFFiNE renderer server
type: application
version: 0.0.0
appVersion: "0.25.7"
appVersion: "0.26.0"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -3,7 +3,7 @@ name: sync
description: AFFiNE Sync Server
type: application
version: 0.0.0
appVersion: "0.25.7"
appVersion: "0.26.0"
dependencies:
- name: gcloud-sql-proxy
version: 0.0.0

View File

@@ -46,6 +46,7 @@ jobs:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
- name: Upload web artifact
uses: actions/upload-artifact@v4
with:
@@ -79,6 +80,7 @@ jobs:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
- name: Upload admin artifact
uses: actions/upload-artifact@v4
with:
@@ -112,6 +114,7 @@ jobs:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
PERFSEE_TOKEN: ${{ secrets.PERFSEE_TOKEN }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
- name: Upload mobile artifact
uses: actions/upload-artifact@v4
with:

View File

@@ -798,49 +798,6 @@ jobs:
name: fuzz-artifact
path: packages/common/y-octo/utils/fuzz/artifacts/**/*
y-octo-binding-test:
name: y-octo binding test on ${{ matrix.settings.target }}
runs-on: ${{ matrix.settings.os }}
strategy:
fail-fast: false
matrix:
settings:
- { target: 'x86_64-unknown-linux-gnu', os: 'ubuntu-latest' }
- { target: 'aarch64-unknown-linux-gnu', os: 'ubuntu-24.04-arm' }
- { target: 'x86_64-apple-darwin', os: 'macos-15-intel' }
- { target: 'aarch64-apple-darwin', os: 'macos-latest' }
- { target: 'x86_64-pc-windows-msvc', os: 'windows-latest' }
- { target: 'aarch64-pc-windows-msvc', os: 'windows-11-arm' }
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: ./.github/actions/setup-node
with:
extra-flags: workspaces focus @affine-tools/cli @affine/monorepo @y-octo/node
electron-install: false
- name: Install rustup (Windows 11 ARM)
if: matrix.settings.os == 'windows-11-arm'
shell: pwsh
run: |
Invoke-WebRequest -Uri "https://static.rust-lang.org/rustup/dist/aarch64-pc-windows-msvc/rustup-init.exe" -OutFile rustup-init.exe
.\rustup-init.exe --default-toolchain none -y
"$env:USERPROFILE\.cargo\bin" | Out-File -Append -Encoding ascii $env:GITHUB_PATH
"CARGO_HOME=$env:USERPROFILE\.cargo" | Out-File -Append -Encoding ascii $env:GITHUB_ENV
- name: Install Rust (Windows 11 ARM)
if: matrix.settings.os == 'windows-11-arm'
shell: pwsh
run: |
rustup install stable
rustup target add ${{ matrix.settings.target }}
cargo --version
- name: Build Rust
uses: ./.github/actions/build-rust
with:
target: ${{ matrix.settings.target }}
package: '@y-octo/node'
- name: Run tests
run: yarn affine @y-octo/node test
rust-test:
name: Run native tests
runs-on: ubuntu-latest
@@ -1387,7 +1344,6 @@ jobs:
- miri
- loom
- fuzzing
- y-octo-binding-test
- server-test
- server-e2e-test
- rust-test

View File

@@ -69,6 +69,7 @@ jobs:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_RELEASE: ${{ inputs.app_version }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
steps:
- uses: actions/checkout@v4

View File

@@ -67,6 +67,7 @@ jobs:
SENTRY_RELEASE: ${{ inputs.app-version }}
RELEASE_VERSION: ${{ inputs.app-version }}
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
- name: Upload web artifact
uses: actions/upload-artifact@v4

View File

@@ -40,6 +40,7 @@ jobs:
env:
PUBLIC_PATH: '/'
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
@@ -69,6 +70,7 @@ jobs:
env:
PUBLIC_PATH: '/'
MIXPANEL_TOKEN: ${{ secrets.MIXPANEL_TOKEN }}
GA4_MEASUREMENT_ID: ${{ secrets.GA4_MEASUREMENT_ID }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: 'affine'
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}

View File

@@ -1,4 +1,8 @@
exclude = ["node_modules/**/*.toml", "target/**/*.toml"]
exclude = [
"node_modules/**/*.toml",
"target/**/*.toml",
"packages/frontend/apps/ios/App/Packages/AffineGraphQL/**/*.toml",
]
# https://taplo.tamasfe.dev/configuration/formatter-options.html
[formatting]

1595
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,6 @@ members = [
"./packages/backend/native",
"./packages/common/native",
"./packages/common/y-octo/core",
"./packages/common/y-octo/node",
"./packages/common/y-octo/utils",
"./packages/frontend/mobile-native",
"./packages/frontend/native",
@@ -47,7 +46,7 @@ resolver = "3"
libc = "0.2"
log = "0.4"
loom = { version = "0.7", features = ["checkpoint"] }
memory-indexer = "0.2.1"
memory-indexer = "0.3.0"
mimalloc = "0.1"
mp4parse = "0.17"
nanoid = "0.4"
@@ -64,7 +63,6 @@ resolver = "3"
notify = { version = "8", features = ["serde"] }
objc2 = "0.6"
objc2-foundation = "0.3"
ogg = "0.9"
once_cell = "1"
ordered-float = "5"
parking_lot = "0.12"
@@ -73,6 +71,7 @@ resolver = "3"
phf = { version = "0.11", features = ["macros"] }
proptest = "1.3"
proptest-derive = "0.5"
pulldown-cmark = "0.13"
rand = "0.9"
rand_chacha = "0.9"
rand_distr = "0.5"

View File

@@ -296,7 +296,7 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7",
"version": "0.26.0",
"devDependencies": {
"@vanilla-extract/vite-plugin": "^5.0.0",
"msw": "^2.12.4",

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"file-type": "^21.0.0",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
"rxjs": "^7.8.2",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"emoji-mart": "^5.6.0",
"lit": "^3.2.0",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -28,7 +28,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -28,7 +28,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"date-fns": "^4.0.0",
"lit": "^3.2.0",
@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -39,5 +39,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
"rxjs": "^7.8.2",
@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"file-type": "^21.0.0",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/katex": "^0.16.7",
"@types/mdast": "^4.0.4",
"katex": "^0.16.27",
@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -27,7 +27,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"@types/mdast": "^4.0.4",
"@vanilla-extract/css": "^1.17.0",
@@ -49,5 +49,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -44,7 +44,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"dompurify": "^3.3.0",
"html2canvas": "^1.4.1",
@@ -67,5 +67,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fractional-indexing": "^3.2.0",
"lit": "^3.2.0",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fractional-indexing": "^3.2.0",
"html2canvas": "^1.4.1",
@@ -46,5 +46,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@lit/context": "^1.1.2",
"@lottiefiles/dotlottie-wc": "^0.5.0",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/hast": "^3.0.4",
"@types/katex": "^0.16.7",
"@types/lodash-es": "^4.17.12",
@@ -82,5 +82,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"clsx": "^2.1.1",
"date-fns": "^4.0.0",
@@ -48,5 +48,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -48,32 +48,41 @@ const compareList = <T>(
return 0;
};
const compareString = (a: unknown, b: unknown): CompareType => {
if (typeof a != 'string' || a === '') {
return Compare.GT;
const strA = String(a ?? '');
const strB = String(b ?? '');
if (strA === '' && strB !== '') {
return Compare.GT; // Empty strings come last
}
if (typeof b != 'string' || b === '') {
return Compare.LT;
if (strA !== '' && strB === '') {
return Compare.LT; // Empty strings come last
}
const listA = a.split('.');
const listB = b.split('.');
if (strA === '' && strB === '') {
return 0; // Both empty, equal
}
const listA = strA.split('.');
const listB = strB.split('.');
return compareList(listA, listB, (a, b) => {
const lowA = a.toLowerCase();
const lowB = b.toLowerCase();
const lowA = String(a).toLowerCase(); // Ensure 'a' and 'b' from split are strings too
const lowB = String(b).toLowerCase();
const numberA = Number.parseInt(lowA);
const numberB = Number.parseInt(lowB);
const aIsNaN = Number.isNaN(numberA);
const bIsNaN = Number.isNaN(numberB);
if (aIsNaN && !bIsNaN) {
return 1;
return 1; // Non-numeric part comes after numeric part
}
if (!aIsNaN && bIsNaN) {
return -1;
return -1; // Numeric part comes before non-numeric part
}
if (!aIsNaN && !bIsNaN && numberA !== numberB) {
return numberA - numberB;
return numberA - numberB; // Numeric comparison for numeric parts
}
return lowA.localeCompare(lowB);
return lowA.localeCompare(lowB); // Lexicographical comparison for string parts
});
};
const compareNumber = (a: unknown, b: unknown) => {

View File

@@ -26,5 +26,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -22,7 +22,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2"
},
@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
"rxjs": "^7.8.2",
@@ -40,5 +40,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@vanilla-extract/css": "^1.17.0",
"lit": "^3.2.0",
"minimatch": "^10.1.1",
@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -30,7 +30,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -51,5 +51,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -26,7 +26,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -24,7 +24,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,5 +25,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -19,7 +19,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.15",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lit-html": "^3.2.1",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -22,7 +22,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"collapse-white-space": "^2.1.0",
"date-fns": "^4.0.0",
@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/hast": "^3.0.4",
"@types/katex": "^0.16.7",
"@types/lodash-es": "^4.17.12",
@@ -50,5 +50,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -22,7 +22,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"collapse-white-space": "^2.1.0",
"date-fns": "^4.0.0",
@@ -44,5 +44,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"collapse-white-space": "^2.1.0",
"date-fns": "^4.0.0",
@@ -42,5 +42,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -28,7 +28,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/hast": "^3.0.4",
"@types/katex": "^0.16.7",
"@types/lodash-es": "^4.17.12",
@@ -56,5 +56,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"collapse-white-space": "^2.1.0",
"date-fns": "^4.0.0",
@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -13,7 +13,7 @@
"@blocksuite/global": "workspace:*",
"@blocksuite/std": "workspace:*",
"@blocksuite/store": "workspace:*",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fractional-indexing": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -30,5 +30,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"collapse-white-space": "^2.1.0",
"date-fns": "^4.0.0",
@@ -41,5 +41,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -18,7 +18,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/bytes": "^3.1.5",
"@types/hast": "^3.0.4",
"@types/lodash-es": "^4.17.12",
@@ -77,5 +77,5 @@
"@types/pdfmake": "^0.2.12",
"vitest": "^3.2.4"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -27,7 +27,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -45,5 +45,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/icons": "^2.2.17",
"@blocksuite/std": "workspace:*",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2"
},
@@ -34,5 +34,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -21,7 +21,7 @@
"@blocksuite/std": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2",
"yjs": "^13.6.27"
@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -25,7 +25,7 @@
"@blocksuite/std": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2",
"yjs": "^13.6.27"
@@ -40,5 +40,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -22,7 +22,7 @@
"@floating-ui/dom": "^1.6.13",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -38,5 +38,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/std": "workspace:*",
"@floating-ui/dom": "^1.6.13",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/std": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2"
},
@@ -34,5 +34,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -38,7 +38,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fflate": "^0.8.2",
"lit": "^3.2.0",
@@ -55,5 +55,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -23,7 +23,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fflate": "^0.8.2",
"js-yaml": "^4.1.1",
@@ -43,5 +43,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -22,7 +22,7 @@
"@blocksuite/std": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2",
"yjs": "^13.6.27"
@@ -37,5 +37,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/store": "workspace:*",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"fflate": "^0.8.2",
"lit": "^3.2.0",
@@ -37,5 +37,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -19,7 +19,7 @@
"@blocksuite/icons": "^2.2.17",
"@blocksuite/std": "workspace:*",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -16,7 +16,7 @@
"@blocksuite/global": "workspace:*",
"@blocksuite/std": "workspace:*",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"lit": "^3.2.0",
"rxjs": "^7.8.2"
},
@@ -30,5 +30,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -20,7 +20,7 @@
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.13",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -36,5 +36,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -46,6 +46,22 @@ import {
parseGroup,
slashItemClassName,
} from './utils.js';
const isTextInputKey = (e: KeyboardEvent) => {
// Keys combined with modifiers are not considered text input
if (e.ctrlKey || e.metaKey || e.altKey) return false;
// During IME composition, do not treat keydown as text input.
// Query updates are handled by input/composition hooks.
if (e.isComposing) return false;
// Only allow single-character keys as text input
if (e.key.length !== 1) return false;
// Keep existing behavior: space closes the slash menu
if (e.key === ' ') return false;
return true;
};
type InnerSlashMenuContext = SlashMenuContext & {
onClickItem: (item: SlashMenuActionItem) => void;
searching: boolean;
@@ -228,10 +244,12 @@ export class SlashMenu extends WithDisposable(LitElement) {
}
if (key !== 'Backspace' && this._queryState === 'no_result') {
// if the following key is not the backspace key,
// the slash menu will be closed
this.abortController.abort();
return;
if (isTextInputKey(event)) {
// allow typing to change query; don't abort here
} else {
this.abortController.abort();
return;
}
}
if (key === 'Escape') {

View File

@@ -22,7 +22,7 @@
"@blocksuite/std": "workspace:*",
"@floating-ui/dom": "^1.6.13",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -38,5 +38,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -19,7 +19,7 @@
"@blocksuite/std": "workspace:*",
"@floating-ui/dom": "^1.6.13",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@types/lodash-es": "^4.17.12",
"lit": "^3.2.0",
"lodash-es": "^4.17.21",
@@ -35,5 +35,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -17,5 +17,5 @@
"dependencies": {
"@blocksuite/affine": "workspace:*"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -64,5 +64,5 @@
"devDependencies": {
"vitest": "^3.2.4"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -47,5 +47,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -86,14 +86,13 @@ export function bindKeymap(
}
}
// none standard keyboard, fallback to keyCode
const special =
event.shiftKey ||
event.altKey ||
event.metaKey ||
name.charCodeAt(0) > 127;
// For non-standard keyboards, fallback to keyCode only when modifier keys are pressed.
// Do NOT fallback when the key produces a non-ASCII character (e.g., Cyrillic 'х' on Russian keyboard),
// because the user intends to type that character, not trigger a shortcut bound to the physical key.
// See: https://github.com/toeverything/AFFiNE/issues/14059
const hasModifier = event.shiftKey || event.altKey || event.metaKey;
const baseName = base[event.keyCode];
if (special && baseName && baseName !== name) {
if (hasModifier && baseName && baseName !== name) {
const fromCode = map[modifiers(baseName, event)];
if (fromCode && fromCode(ctx)) {
return true;

View File

@@ -42,5 +42,5 @@
"!dist/__tests__",
"shim.d.ts"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -33,5 +33,5 @@
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -19,7 +19,7 @@
"@lit/context": "^1.1.3",
"@lottiefiles/dotlottie-wc": "^0.5.0",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.16",
"@toeverything/theme": "^1.1.23",
"@vanilla-extract/css": "^1.17.0",
"lit": "^3.2.0",
"rxjs": "^7.8.2",
@@ -46,5 +46,5 @@
"vite-plugin-wasm": "^3.5.0",
"vitest": "^3.2.4"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -46,5 +46,5 @@
"vite-plugin-wasm": "^3.5.0",
"vite-plugin-web-components-hmr": "^0.1.3"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -19,5 +19,5 @@
],
"ext": "ts,md,json"
},
"version": "0.25.7"
"version": "0.26.0"
}

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/monorepo",
"version": "0.25.7",
"version": "0.26.0",
"private": true,
"author": "toeverything",
"license": "MIT",
@@ -8,7 +8,6 @@
".",
"blocksuite/**/*",
"packages/*/*",
"packages/common/y-octo/node",
"packages/frontend/apps/*",
"tools/*",
"docs/reference",

View File

@@ -1,5 +1,5 @@
[package]
edition = "2021"
edition = "2024"
license-file = "LICENSE"
name = "affine_server_native"
version = "1.0.0"

View File

@@ -4,6 +4,20 @@ export declare class Tokenizer {
count(content: string, allowedSpecial?: Array<string> | undefined | null): number
}
/**
* Adds a document ID to the workspace root doc's meta.pages array.
* This registers the document in the workspace so it appears in the UI.
*
* # Arguments
* * `root_doc_bin` - The current root doc binary (workspaceId doc)
* * `doc_id` - The document ID to add
* * `title` - Optional title for the document
*
* # Returns
* A Buffer containing the y-octo update binary to apply to the root doc
*/
export declare function addDocToRootDoc(rootDocBin: Buffer, docId: string, title?: string | undefined | null): Buffer
export const AFFINE_PRO_LICENSE_AES_KEY: string | undefined | null
export const AFFINE_PRO_PUBLIC_KEY: string | undefined | null
@@ -13,6 +27,19 @@ export interface Chunk {
content: string
}
/**
* Converts markdown content to AFFiNE-compatible y-octo document binary.
*
* # Arguments
* * `title` - The document title
* * `markdown` - The markdown content to convert
* * `doc_id` - The document ID to use for the y-octo doc
*
* # Returns
* A Buffer containing the y-octo document update binary
*/
export declare function createDocWithMarkdown(title: string, markdown: string, docId: string): Buffer
export declare function fromModelName(modelName: string): Tokenizer | null
export declare function getMime(input: Uint8Array): string
@@ -77,4 +104,60 @@ export declare function parseWorkspaceDoc(docBin: Buffer): NativeWorkspaceDocCon
export declare function readAllDocIdsFromRootDoc(docBin: Buffer, includeTrash?: boolean | undefined | null): Array<string>
/**
* Updates or creates the docProperties record for a document.
*
* # Arguments
* * `existing_binary` - The current docProperties document binary
* * `properties_doc_id` - The docProperties document ID
* (db$${workspaceId}$docProperties)
* * `target_doc_id` - The document ID to update in docProperties
* * `created_by` - Optional creator user ID
* * `updated_by` - Optional updater user ID
*
* # Returns
* A Buffer containing only the delta (changes) as a y-octo update binary
*/
export declare function updateDocProperties(existingBinary: Buffer, propertiesDocId: string, targetDocId: string, createdBy?: string | undefined | null, updatedBy?: string | undefined | null): Buffer
/**
* Updates a document's title without touching content blocks.
*
* # Arguments
* * `existing_binary` - The current document binary
* * `title` - The new title
* * `doc_id` - The document ID
*
* # Returns
* A Buffer containing only the delta (changes) as a y-octo update binary
*/
export declare function updateDocTitle(existingBinary: Buffer, title: string, docId: string): Buffer
/**
* Updates an existing document with new markdown content.
* Uses structural diffing to apply block-level replacements for changes.
*
* # Arguments
* * `existing_binary` - The current document binary
* * `new_markdown` - The new markdown content to apply
* * `doc_id` - The document ID
*
* # Returns
* A Buffer containing only the delta (changes) as a y-octo update binary
*/
export declare function updateDocWithMarkdown(existingBinary: Buffer, newMarkdown: string, docId: string): Buffer
/**
* Updates a document title in the workspace root doc's meta.pages array.
*
* # Arguments
* * `root_doc_bin` - The current root doc binary (workspaceId doc)
* * `doc_id` - The document ID to update
* * `title` - The new title for the document
*
* # Returns
* A Buffer containing the y-octo update binary to apply to the root doc
*/
export declare function updateRootDocMetaTitle(rootDocBin: Buffer, docId: string, title: string): Buffer
export declare function verifyChallengeResponse(response: string, bits: number, resource: string): Promise<boolean>

View File

@@ -1,6 +1,6 @@
{
"name": "@affine/server-native",
"version": "0.25.7",
"version": "0.26.0",
"engines": {
"node": ">= 10.16.0 < 11 || >= 11.8.0"
},

View File

@@ -1,6 +1,4 @@
use affine_common::doc_parser::{
self, BlockInfo, CrawlResult, MarkdownResult, PageDocContent, WorkspaceDocContent,
};
use affine_common::doc_parser::{self, BlockInfo, CrawlResult, MarkdownResult, PageDocContent, WorkspaceDocContent};
use napi::bindgen_prelude::*;
use napi_derive::napi;
@@ -103,10 +101,7 @@ pub fn parse_doc_from_binary(doc_bin: Buffer, doc_id: String) -> Result<NativeCr
}
#[napi]
pub fn parse_page_doc(
doc_bin: Buffer,
max_summary_length: Option<i32>,
) -> Result<Option<NativePageDocContent>> {
pub fn parse_page_doc(doc_bin: Buffer, max_summary_length: Option<i32>) -> Result<Option<NativePageDocContent>> {
let result = doc_parser::parse_page_doc(doc_bin.into(), max_summary_length.map(|v| v as isize))
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(result.map(Into::into))
@@ -114,8 +109,8 @@ pub fn parse_page_doc(
#[napi]
pub fn parse_workspace_doc(doc_bin: Buffer) -> Result<Option<NativeWorkspaceDocContent>> {
let result = doc_parser::parse_workspace_doc(doc_bin.into())
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
let result =
doc_parser::parse_workspace_doc(doc_bin.into()).map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(result.map(Into::into))
}
@@ -126,22 +121,127 @@ pub fn parse_doc_to_markdown(
ai_editable: Option<bool>,
doc_url_prefix: Option<String>,
) -> Result<NativeMarkdownResult> {
let result = doc_parser::parse_doc_to_markdown(
doc_bin.into(),
doc_id,
ai_editable.unwrap_or(false),
doc_url_prefix,
)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
let result = doc_parser::parse_doc_to_markdown(doc_bin.into(), doc_id, ai_editable.unwrap_or(false), doc_url_prefix)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(result.into())
}
#[napi]
pub fn read_all_doc_ids_from_root_doc(
doc_bin: Buffer,
include_trash: Option<bool>,
) -> Result<Vec<String>> {
pub fn read_all_doc_ids_from_root_doc(doc_bin: Buffer, include_trash: Option<bool>) -> Result<Vec<String>> {
let result = doc_parser::get_doc_ids_from_binary(doc_bin.into(), include_trash.unwrap_or(false))
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(result)
}
/// Converts markdown content to AFFiNE-compatible y-octo document binary.
///
/// # Arguments
/// * `title` - The document title
/// * `markdown` - The markdown content to convert
/// * `doc_id` - The document ID to use for the y-octo doc
///
/// # Returns
/// A Buffer containing the y-octo document update binary
#[napi]
pub fn create_doc_with_markdown(title: String, markdown: String, doc_id: String) -> Result<Buffer> {
let result = doc_parser::build_full_doc(&title, &markdown, &doc_id)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}
/// Updates an existing document with new markdown content.
/// Uses structural diffing to apply block-level replacements for changes.
///
/// # Arguments
/// * `existing_binary` - The current document binary
/// * `new_markdown` - The new markdown content to apply
/// * `doc_id` - The document ID
///
/// # Returns
/// A Buffer containing only the delta (changes) as a y-octo update binary
#[napi]
pub fn update_doc_with_markdown(existing_binary: Buffer, new_markdown: String, doc_id: String) -> Result<Buffer> {
let result = doc_parser::update_doc(&existing_binary, &new_markdown, &doc_id)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}
/// Updates a document's title without touching content blocks.
///
/// # Arguments
/// * `existing_binary` - The current document binary
/// * `title` - The new title
/// * `doc_id` - The document ID
///
/// # Returns
/// A Buffer containing only the delta (changes) as a y-octo update binary
#[napi]
pub fn update_doc_title(existing_binary: Buffer, title: String, doc_id: String) -> Result<Buffer> {
let result = doc_parser::update_doc_title(&existing_binary, &doc_id, &title)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}
/// Updates or creates the docProperties record for a document.
///
/// # Arguments
/// * `existing_binary` - The current docProperties document binary
/// * `properties_doc_id` - The docProperties document ID
/// (db$${workspaceId}$docProperties)
/// * `target_doc_id` - The document ID to update in docProperties
/// * `created_by` - Optional creator user ID
/// * `updated_by` - Optional updater user ID
///
/// # Returns
/// A Buffer containing only the delta (changes) as a y-octo update binary
#[napi]
pub fn update_doc_properties(
existing_binary: Buffer,
properties_doc_id: String,
target_doc_id: String,
created_by: Option<String>,
updated_by: Option<String>,
) -> Result<Buffer> {
let result = doc_parser::update_doc_properties(
&existing_binary,
&properties_doc_id,
&target_doc_id,
created_by.as_deref(),
updated_by.as_deref(),
)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}
/// Adds a document ID to the workspace root doc's meta.pages array.
/// This registers the document in the workspace so it appears in the UI.
///
/// # Arguments
/// * `root_doc_bin` - The current root doc binary (workspaceId doc)
/// * `doc_id` - The document ID to add
/// * `title` - Optional title for the document
///
/// # Returns
/// A Buffer containing the y-octo update binary to apply to the root doc
#[napi]
pub fn add_doc_to_root_doc(root_doc_bin: Buffer, doc_id: String, title: Option<String>) -> Result<Buffer> {
let result = doc_parser::add_doc_to_root_doc(root_doc_bin.into(), &doc_id, title.as_deref())
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}
/// Updates a document title in the workspace root doc's meta.pages array.
///
/// # Arguments
/// * `root_doc_bin` - The current root doc binary (workspaceId doc)
/// * `doc_id` - The document ID to update
/// * `title` - The new title for the document
///
/// # Returns
/// A Buffer containing the y-octo update binary to apply to the root doc
#[napi]
pub fn update_root_doc_meta_title(root_doc_bin: Buffer, doc_id: String, title: String) -> Result<Buffer> {
let result = doc_parser::update_root_doc_meta_title(&root_doc_bin, &doc_id, &title)
.map_err(|e| Error::new(Status::GenericFailure, e.to_string()))?;
Ok(Buffer::from(result))
}

View File

@@ -1,8 +1,8 @@
use affine_common::doc_loader::Doc;
use napi::{
Env, Result, Task,
anyhow::anyhow,
bindgen_prelude::{AsyncTask, Buffer},
Env, Result, Task,
};
#[napi(object)]

View File

@@ -1,4 +1,4 @@
use mp4parse::{read_mp4, TrackType};
use mp4parse::{TrackType, read_mp4};
use napi_derive::napi;
#[napi]
@@ -6,9 +6,7 @@ pub fn get_mime(input: &[u8]) -> String {
let mimetype = if let Some(kind) = infer::get(&input[..4096.min(input.len())]) {
kind.mime_type().to_string()
} else {
file_format::FileFormat::from_bytes(input)
.media_type()
.to_string()
file_format::FileFormat::from_bytes(input).media_type().to_string()
};
if mimetype == "video/mp4" {
detect_mp4_flavor(input)

View File

@@ -1,7 +1,7 @@
use std::convert::TryFrom;
use affine_common::hashcash::Stamp;
use napi::{bindgen_prelude::AsyncTask, Env, Result as NapiResult, Task};
use napi::{Env, Result as NapiResult, Task, bindgen_prelude::AsyncTask};
use napi_derive::napi;
pub struct AsyncVerifyChallengeResponse {
@@ -61,9 +61,6 @@ impl Task for AsyncMintChallengeResponse {
}
#[napi]
pub fn mint_challenge_response(
resource: String,
bits: Option<u32>,
) -> AsyncTask<AsyncMintChallengeResponse> {
pub fn mint_challenge_response(resource: String, bits: Option<u32>) -> AsyncTask<AsyncMintChallengeResponse> {
AsyncTask::new(AsyncMintChallengeResponse { bits, resource })
}

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