Skip to content

Conversation

@saltenasl
Copy link

@saltenasl saltenasl commented Nov 24, 2025

Summary by CodeRabbit

  • Chores
    • Rebranded editor packages under the @deepnote scope, updated package metadata for public publishing, redirected examples and tooling to the new scoped packages, adjusted build configuration and aliases, updated build script to include legacy OpenSSL option, and updated CI/release workflows to target a different branch and Node 18.x (removed Node 16 cache settings).
  • Chores (types)
    • Added an optional multiBlock property to React range typings.

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

@coderabbitai
Copy link

coderabbitai bot commented Nov 24, 2025

📝 Walkthrough

Walkthrough

Repository-wide refactor: core packages and examples were re-scoped from unscoped names to the @deepnote scope (slate, slate-history, slate-hyperscript, slate-react → @deepnote/). Package metadata updated (name, repository, publishConfig, peer/dev deps remapped). Rollup config now derives pkgDir by stripping scope and uses it for path resolution. Babel and Jest configs add module aliases to local ./packages//src. GitHub Actions workflows now target the deepnote branch, use Node 18.x, remove the node-specific cache key, write version to GITHUB_OUTPUT, and some release steps reference @deepnote packages; one comment trigger allows multiple senders. The site build script sets NODE_OPTIONS with --openssl-legacy-provider for both next build and next export. A type augmentation adds Range.multiBlock?: boolean. Several internal regexes were expanded to explicit character classes in string utilities.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer
  participant Repo as Repository
  participant CI_old as GitHub Actions (old)
  participant Registry as NPM Registry

  rect rgb(245,245,245)
    Dev->>Repo: push to branch (main)
    note right of Repo: Old workflows triggered "main"
    Repo->>CI_old: run workflows (Node 16.x, node-specific cache key)
    CI_old->>Registry: publish unscoped packages (slate, slate-*)
    CI_old-->>Repo: post release comment ("yarn add slate@VERSION")
  end
Loading
sequenceDiagram
  participant Dev as Developer
  participant Repo as Repository
  participant CI_new as GitHub Actions (new)
  participant Registry as NPM Registry

  rect rgb(240,255,240)
    Dev->>Repo: push to branch (deepnote)
    note right of Repo: Updated workflows trigger "deepnote"
    Repo->>CI_new: run workflows (Node 18.x, no node-specific cache key)
    CI_new->>CI_new: compute version -> append to GITHUB_OUTPUT
    CI_new->>Registry: publish scoped packages (`@deepnote/slate`, `@deepnote/slate-`*)
    CI_new-->>Repo: post release comment ("yarn add `@deepnote/slate`@VERSION")
  end
Loading
sequenceDiagram
  participant Rollup as Rollup
  participant FS as Filesystem
  rect rgb(245,250,255)
    Rollup->>FS: read package.json name (e.g., "@scope/name")
    Rollup->>Rollup: strip scope -> pkgDir = "name"
    note right of Rollup: use packages/${pkgDir}/... for input/tsconfig/babel/outputs
    Rollup->>FS: resolve and bundle files under packages/name
  end
Loading

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately summarizes the main change: renaming packages to @deepnote scope and preparing for npm release, which aligns with the comprehensive scope of package renames, dependency updates, and configuration changes throughout the PR.

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/slate-react/package.json (1)

39-40: Update devDependencies to use @deepnote scoped packages.

These still reference unscoped packages (slate, slate-hyperscript), which will now resolve from npm instead of local workspace. This breaks the monorepo setup.

Apply this diff:

  "devDependencies": {
    "@babel/runtime": "^7.7.4",
    "@types/jest": "^27.4.1",
    "@types/jsdom": "^16.2.14",
    "@types/react": "^16.9.13",
    "@types/react-dom": "^16.9.4",
    "@types/react-test-renderer": "^16.8.0",
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "react-test-renderer": ">=16.8.0",
-   "slate": "^0.81.0",
-   "slate-hyperscript": "^0.77.0",
+   "@deepnote/slate": "workspace:*",
+   "@deepnote/slate-hyperscript": "workspace:*",
    "source-map-loader": "^0.2.4"
  },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 724d352 and 59b26e4.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (6)
  • .github/workflows/ci.yml (1 hunks)
  • .github/workflows/codeql.yml (1 hunks)
  • .github/workflows/comment.yml (3 hunks)
  • .github/workflows/release.yml (2 hunks)
  • package.json (1 hunks)
  • packages/slate-react/package.json (2 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/codeql.yml

[error] 16-16: too many spaces inside brackets

(brackets)


[error] 16-16: too many spaces inside brackets

(brackets)


[error] 19-19: too many spaces inside brackets

(brackets)


[error] 19-19: too many spaces inside brackets

(brackets)

🔇 Additional comments (7)
package.json (1)

57-60: Workspace dependencies correctly scoped to @deepnote.

The migration to local workspace references using workspace:* looks correct and aligns with the monorepo pattern.

packages/slate-react/package.json (1)

2-2: Verify umdGlobals alignment with package rename.

Line 50 still maps "slate" in umdGlobals. Confirm this is intentional for backward UMD compatibility or should be updated to reflect the new @deepnote scoping.

Also applies to: 6-9, 43-46

.github/workflows/release.yml (1)

6-6: Branch and Node version updates look good.

Transition to deepnote branch and Node 18.x LTS is appropriate and consistent across workflows.

Also applies to: 28-28

.github/workflows/ci.yml (1)

26-26: Node 18.x upgrade consistent across CI workflows.

Aligns with other workflow updates and maintains test/lint job parity.

.github/workflows/comment.yml (3)

32-32: Permitting saltenas for release commands is appropriate.

PR author now has permission to trigger /release:next for snapshot releases.


68-68: GitHub Output API change is correct.

The set-output command is deprecated in GitHub Actions. Using $GITHUB_OUTPUT file append is the modern, supported approach.


48-48: Node 18.x and scoped package name updates look correct.

Changes maintain consistency with release and CI workflows, and package name reflects the @deepnote org scope migration.

Also applies to: 75-75

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
site/examples/custom-types.d.ts (1)

114-120: Update declare module target to match scoped package import.

The module augmentation targets 'slate' but imports use '@deepnote/slate'. TypeScript won't merge the CustomTypes interface without matching names. Change line 114 from declare module 'slate' to declare module '@deepnote/slate'.

site/examples/check-lists.tsx (1)

22-66: Import custom type definitions to fix the type error.

check-lists.tsx needs to import custom-types.d.ts to activate Slate's CustomTypes augmentation. Without it, TypeScript sees initialValue objects with checked properties but Descendant[] only allows the base Element | Text types.

Add this import at the top of site/examples/check-lists.tsx:

import './custom-types'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e79fe2a and 790b558.

📒 Files selected for processing (23)
  • site/examples/check-lists.tsx (2 hunks)
  • site/examples/code-highlighting.tsx (1 hunks)
  • site/examples/custom-placeholder.tsx (1 hunks)
  • site/examples/custom-types.d.ts (1 hunks)
  • site/examples/editable-voids.tsx (1 hunks)
  • site/examples/embeds.tsx (1 hunks)
  • site/examples/forced-layout.tsx (1 hunks)
  • site/examples/hovering-toolbar.tsx (1 hunks)
  • site/examples/huge-document.tsx (1 hunks)
  • site/examples/iframe.tsx (1 hunks)
  • site/examples/images.tsx (2 hunks)
  • site/examples/inlines.tsx (1 hunks)
  • site/examples/markdown-preview.tsx (1 hunks)
  • site/examples/markdown-shortcuts.tsx (2 hunks)
  • site/examples/mentions.tsx (1 hunks)
  • site/examples/paste-html.tsx (1 hunks)
  • site/examples/plaintext.tsx (1 hunks)
  • site/examples/read-only.tsx (1 hunks)
  • site/examples/richtext.tsx (1 hunks)
  • site/examples/scroll-into-view.tsx (1 hunks)
  • site/examples/search-highlighting.tsx (1 hunks)
  • site/examples/shadow-dom.tsx (1 hunks)
  • site/examples/tables.tsx (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI
site/examples/check-lists.tsx

[error] 24-24: Type error: Type '{ type: string; children: { text: string; }[]; }' is not assignable to type 'Descendant'. Object literal may only specify known properties, and 'type' does not exist in type 'Descendant'.

🔇 Additional comments (25)
site/examples/shadow-dom.tsx (1)

3-5: Import migration looks consistent.

All Slate imports correctly updated to @deepnote scope.

site/examples/markdown-shortcuts.tsx (2)

2-2: LGTM.


11-12: LGTM.

site/examples/hovering-toolbar.tsx (2)

2-2: LGTM.


10-12: LGTM.

site/examples/code-highlighting.tsx (1)

7-9: LGTM.

site/examples/huge-document.tsx (1)

3-4: LGTM.

site/examples/plaintext.tsx (1)

2-4: LGTM.

site/examples/custom-types.d.ts (1)

9-11: LGTM.

site/examples/embeds.tsx (1)

7-7: LGTM.

site/examples/paste-html.tsx (1)

3-4: LGTM! Import migration to @deepnote scope.

Imports correctly updated to use scoped packages. Note that slate-hyperscript (line 2) remains unscoped.

Also applies to: 12-12

site/examples/read-only.tsx (1)

2-3: LGTM! Imports updated correctly.

site/examples/iframe.tsx (1)

4-6: LGTM! Import paths migrated to @deepnote scope.

site/examples/images.tsx (1)

4-4: LGTM! Scoped imports applied correctly.

Also applies to: 13-14

site/examples/mentions.tsx (1)

2-3: LGTM! Import migration complete.

Also applies to: 11-11

site/examples/search-highlighting.tsx (1)

2-3: LGTM! Imports correctly scoped.

Also applies to: 5-5

site/examples/custom-placeholder.tsx (1)

2-4: LGTM! Import paths updated.

site/examples/scroll-into-view.tsx (1)

2-4: Verified: @deepnote packages are correctly configured and resolvable.

All three scoped packages exist in the workspace with matching names in their package.json files. The imports in scroll-into-view.tsx are correct.

site/examples/editable-voids.tsx (1)

2-4: Import paths updated correctly.

The scoped package imports are consistent with the migration to @deepnote/* namespace.

site/examples/check-lists.tsx (1)

9-9: Import paths updated correctly.

Also applies to: 18-18, 20-20

site/examples/forced-layout.tsx (1)

2-2: Import paths updated correctly.

Also applies to: 9-10

site/examples/richtext.tsx (1)

3-3: Import paths updated correctly.

Also applies to: 10-11

site/examples/markdown-preview.tsx (1)

3-5: Import paths updated correctly.

site/examples/tables.tsx (1)

2-2: Import paths updated correctly.

Also applies to: 10-11

site/examples/inlines.tsx (1)

5-6: Import paths updated correctly.

Also applies to: 14-15

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 790b558 and 5edc247.

📒 Files selected for processing (5)
  • packages/slate-history/package.json (2 hunks)
  • packages/slate-hyperscript/package.json (2 hunks)
  • packages/slate-react/package.json (3 hunks)
  • packages/slate-react/src/custom-types.ts (1 hunks)
  • packages/slate/package.json (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
packages/slate-react/src/custom-types.ts (3)
packages/slate/src/interfaces/custom-types.ts (1)
  • CustomTypes (23-25)
packages/slate/src/interfaces/text.ts (1)
  • BaseText (12-14)
packages/slate/src/interfaces/range.ts (1)
  • BaseRange (12-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/slate/package.json (1)

2-2: Package renaming and metadata update look good.

Consistent scoping under @deepnote, repository URL updated, and publishConfig set correctly for public npm publishing. Workspace dependency resolution is appropriate for monorepo setup.

Verify that workspace:* syntax is supported by the package manager used in this project (appears to be pnpm, but confirm in package-lock/pnpm-lock file).

Also applies to: 6-9, 26-26

packages/slate-hyperscript/package.json (1)

2-2: Consistent with slate package changes.

Scoping and metadata updates align across the monorepo. Version constraint >=0.65.3 on peerDependency accommodates slate@0.81.1.

Confirm the umdGlobals mapping at line 31 ("slate": "Slate") is intentional for scoped packages—may need to reference the actual export name or remain as external global convention.

Also applies to: 6-9, 24-24, 28-28

packages/slate-history/package.json (1)

2-2: Aligned with monorepo migration.

All internal dependencies properly scoped and use workspace resolution. peerDependency version constraints are compatible.

Also applies to: 6-9, 24-25, 30-30

packages/slate-react/package.json (1)

2-2: Scoping and peer dependencies properly maintained.

React peer constraints preserved (lines 45–46), which is correct for external consumers. Workspace resolution for internal deps is consistent with other packages.

Verify umdGlobals at line 50 ("slate": "Slate") is correct for scoped package context—confirm this doesn't conflict with how the UMD builds will be consumed.

Also applies to: 6-9, 31-32, 44-46

packages/slate-react/src/custom-types.ts (1)

12-12: The multiBlock property is actively used in editable.tsx (line 225) and android-editable.tsx (line 160) for multi-select handling logic. This is an intentional addition, not a stray change.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5edc247 and 0cc057e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (37)
  • .changeset/config.json (1 hunks)
  • packages/slate-history/src/history-editor.ts (1 hunks)
  • packages/slate-history/src/history.ts (1 hunks)
  • packages/slate-history/src/with-history.ts (1 hunks)
  • packages/slate-hyperscript/src/creators.ts (1 hunks)
  • packages/slate-hyperscript/src/hyperscript.ts (1 hunks)
  • packages/slate-hyperscript/src/tokens.ts (1 hunks)
  • packages/slate-react/src/components/android/android-editable.tsx (1 hunks)
  • packages/slate-react/src/components/android/android-input-manager.ts (1 hunks)
  • packages/slate-react/src/components/android/diff-text.ts (1 hunks)
  • packages/slate-react/src/components/android/mutation-detection.ts (1 hunks)
  • packages/slate-react/src/components/android/use-restore-dom.tsx (1 hunks)
  • packages/slate-react/src/components/editable.tsx (1 hunks)
  • packages/slate-react/src/components/element.tsx (1 hunks)
  • packages/slate-react/src/components/leaf.tsx (1 hunks)
  • packages/slate-react/src/components/slate.tsx (1 hunks)
  • packages/slate-react/src/components/string.tsx (1 hunks)
  • packages/slate-react/src/components/text.tsx (1 hunks)
  • packages/slate-react/src/hooks/use-children.tsx (1 hunks)
  • packages/slate-react/src/hooks/use-content-key.ts (1 hunks)
  • packages/slate-react/src/hooks/use-decorate.ts (1 hunks)
  • packages/slate-react/src/hooks/use-slate-selector.tsx (1 hunks)
  • packages/slate-react/src/hooks/use-slate-static.tsx (1 hunks)
  • packages/slate-react/src/hooks/use-slate.tsx (1 hunks)
  • packages/slate-react/src/plugin/react-editor.ts (1 hunks)
  • packages/slate-react/src/plugin/with-react.ts (1 hunks)
  • packages/slate-react/src/utils/lines.ts (1 hunks)
  • packages/slate-react/src/utils/range-list.ts (1 hunks)
  • packages/slate-react/src/utils/weak-maps.ts (1 hunks)
  • site/examples/code-highlighting.tsx (1 hunks)
  • site/examples/custom-types.d.ts (2 hunks)
  • site/examples/editable-voids.tsx (1 hunks)
  • site/examples/hovering-toolbar.tsx (1 hunks)
  • site/examples/iframe.tsx (1 hunks)
  • site/examples/inlines.tsx (1 hunks)
  • site/examples/mentions.tsx (1 hunks)
  • site/examples/paste-html.tsx (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (36)
packages/slate-react/src/hooks/use-children.tsx (1)

2-2: Import scoping aligned with migration.

The @deepnote/slate import path is correctly updated to reflect the org-scoped package naming, and all downstream symbol usage (Editor, Range, Element, Ancestor, Descendant) remains unchanged and functional.

packages/slate-react/src/hooks/use-content-key.ts (1)

2-2: Import scoped to @deepnote org—aligns with PR objectives.

The import source correctly updates from slate to @deepnote/slate, consistent with the broader migration to the @deepnote namespace across Slate packages.

Verify that @deepnote/slate exports Node correctly and that all peer/dev dependencies in packages/slate-react/package.json have been updated to reference @deepnote/slate.

packages/slate-react/src/utils/range-list.ts (1)

1-1: Import correctly scoped to @deepnote/slate.

Clean and consistent with the broader migration. All downstream usages of Range (type annotations and Range.equals() calls) remain valid.

packages/slate-hyperscript/src/tokens.ts (1)

1-1: Import scope updated correctly for @deepnote release.

The change aligns with the monorepo-wide scope migration. All downstream type usage (Node, Path, Text) remains unchanged and consistent.

To ensure build consistency: verify that @deepnote/slate is properly exported from the core package and that consuming packages (slate-history, slate-react) have similarly updated their imports.

packages/slate-react/src/hooks/use-decorate.ts (1)

2-2: Import re-scope aligns with type augmentation and package renaming

Switching Range and NodeEntry to @deepnote/slate matches the scoped package migration and ensures this hook uses the augmented Range type from the same module as custom-types.ts. No further changes needed here.

packages/slate-react/src/utils/weak-maps.ts (1)

1-1: LGTM!

Import path correctly updated to scoped package.

packages/slate-react/src/components/leaf.tsx (1)

2-2: The import change is properly supported and safe to merge.

@deepnote/slate is correctly declared as a peer dependency (>=0.65.3) for runtime use, and no unscoped slate imports remain in the package. The change aligns with the org migration.

site/examples/custom-types.d.ts (1)

9-11: LGTM! Package scope migration is consistent.

All imports and module augmentation updated from unscoped packages to @deepnote/*. Changes are mechanically correct and align with the PR objective.

Also applies to: 114-114

packages/slate-react/src/components/android/mutation-detection.ts (1)

1-1: Scope migration confirmed across the codebase.

All @deepnote/slate imports are consistent. The change in packages/slate-react/src/components/android/mutation-detection.ts is correct.

packages/slate-react/src/hooks/use-slate-selector.tsx (2)

9-9: Import path scoped correctly.

The change aligns with the package migration to @deepnote org. Ensure @deepnote/slate is listed as a dependency in this package's package.json.


1-111: No unscoped imports found—all Slate references properly scoped.

Verification confirms no remaining from 'slate' or from "slate" imports exist in the slate-react package. The file under review correctly imports from @deepnote/slate. All other 'slate' word matches are data attributes and MIME types, not package imports.

packages/slate-react/src/components/android/android-input-manager.ts (1)

2-2: Incomplete import migration detected.

Verification found 1000+ unscoped 'slate' imports remaining across test, dist, and source files. The import change in this file is correct, but confirm:

  • Should test files be updated (requires @deepnote packages available in test environment)?
  • Should dist files be regenerated, or updated manually?
  • Do other source files beyond this one also need scoping to '@deepnote/slate'?

Review and update all source imports, then regenerate dist if needed.

packages/slate-react/src/components/string.tsx (1)

2-2: Scoped import verified—migration complete.

The import change from 'slate' to '@deepnote/slate' is correct and consistent. Verification confirms no unscoped slate imports remain in the codebase, and all @deepnote packages are properly configured in dependencies.

packages/slate-history/src/history.ts (1)

2-2: Import path updated correctly.

The scoped import aligns with the npm publishing preparation.

packages/slate-history/src/history-editor.ts (1)

1-1: Import path updated correctly.

The scoped import is consistent with the repository-wide migration.

packages/slate-history/src/with-history.ts (1)

1-1: Import path update verified correctly.

No unscoped slate imports exist in production source files (src/ directories). Remaining unscoped imports are in test files and generated dist files, which is expected and acceptable.

site/examples/iframe.tsx (1)

4-12: LGTM—import paths correctly updated to @deepnote scope.

The mechanical migration from unscoped to scoped packages is correct and consistent.

site/examples/paste-html.tsx (1)

2-12: LGTM—import paths correctly updated to @deepnote scope.

All slate-related imports properly migrated.

site/examples/mentions.tsx (1)

2-17: LGTM—import paths correctly updated to @deepnote scope.

Migration is correct and consistent with the broader repository changes.

site/examples/hovering-toolbar.tsx (1)

2-18: LGTM—import paths correctly updated to @deepnote scope.

Clean migration to scoped packages.

site/examples/code-highlighting.tsx (1)

7-14: LGTM—import paths correctly updated to @deepnote scope.

Scoped package migration is correct.

packages/slate-hyperscript/src/creators.ts (1)

1-1: Import scope change verified—all dependencies correct.

All source files in packages/slate-hyperscript/src/ already import from @deepnote/slate (scoped). The types (Element, Descendant, Node, Range, Text, Editor) are properly exported by @deepnote/slate. No issues found.

packages/slate-react/src/hooks/use-slate-static.tsx (1)

3-3: LGTM.

Import path correctly updated to scoped package.

packages/slate-hyperscript/src/hyperscript.ts (1)

2-2: LGTM.

Import path correctly updated.

packages/slate-react/src/components/element.tsx (1)

3-3: LGTM.

Import path correctly updated.

site/examples/editable-voids.tsx (1)

2-9: LGTM.

All slate package imports correctly updated to @deepnote scope.

.changeset/config.json (2)

3-3: Changelog repository updated correctly.

Points to deepnote/slate for release notes.


5-12: Linked packages updated correctly.

All four packages now use @deepnote scope for coordinated versioning.

packages/slate-react/src/components/text.tsx (1)

2-2: LGTM.

Import path correctly updated.

packages/slate-react/src/components/editable.tsx (2)

12-12: LGTM.

Import path correctly updated.


222-233: No issues found. The multiBlock property is properly typed in the augmentation.

The property is declared in packages/slate-react/src/custom-types.ts (lines 10-13) as an optional boolean on the Range interface extension. Type safety is ensured.

packages/slate-react/src/plugin/react-editor.ts (1)

10-10: All slate imports correctly scoped to @deepnote.

Verification confirms no unscoped slate imports in active source files. The only remaining reference is a docstring example in scrubber.ts, which doesn't require updating. Test and generated files appropriately retain original scoping.

packages/slate-react/src/components/android/android-editable.tsx (2)

2-10: Import updated correctly.


165-176: Resolved — Range.multiBlock is declared.
Declaration found in packages/slate-react/src/custom-types.ts: Range: BaseRange & { placeholder?: string; multiBlock?: boolean }.

packages/slate-react/src/components/slate.tsx (1)

2-2: Import correctly updated; consistency verified.

The scoped package import @deepnote/slate is in place at line 2, and no unscoped slate imports remain in packages/slate-react/src/. Change is good.

packages/slate-react/src/components/android/diff-text.ts (1)

1-1: Scoped import is OK — verify re-exports and fix remaining bare 'slate' imports

Change in packages/slate-react/src/components/android/diff-text.ts is acceptable if @deepnote/slate re‑exports Editor/Path/Range/Text with identical types/runtime behavior. The repository still contains many bare "from 'slate'" imports (examples: packages/slate/src/interfaces/scrubber.ts, packages/slate-react/dist/index.es.js, and many packages/slate/test/* files). Action items: verify @deepnote/slate re‑exports the needed symbols; either update all source imports to '@deepnote/slate' or add a path/alias so 'slate' resolves to '@deepnote/slate'; regenerate built/dist artifacts.

@@ -1,5 +1,5 @@
import { createContext, useContext } from 'react'
import { Editor } from 'slate'
import { Editor } from '@deepnote/slate'
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

LGTM—import path correctly updated.

Aligns with the package rescoping objective. Verify all other slate imports in this package were updated.


🏁 Script executed:

#!/bin/bash
# Verify all imports from slate packages updated to @deepnote scope

rg -n --type=ts --type=tsx -C2 "from ['\"]slate['\"]|from ['\"]slate-"

Length of output: 27



---

🏁 Script executed:

```shell
#!/bin/bash
# Search for any remaining imports from 'slate' or 'slate-*' packages
rg -n --type=ts --type=jsx -C2 'from ["\']slate["\']|from ["\']slate-' packages/slate-react/

Length of output: 68



---

🏁 Script executed:

```shell
#!/bin/bash
# Find all .ts/.tsx/.jsx files and search for slate imports
fd '\.(ts|tsx|jsx)$' packages/slate-react/ -x grep -n 'from.*slate' {}

Length of output: 3360


Update imports in slate-react package—migration incomplete.

The import at use-slate.tsx line 2 is correct, but grep found many files still importing from 'slate' instead of '@deepnote/slate'. Update all remaining imports across the package to complete the rescoping objective.

🤖 Prompt for AI Agents
In packages/slate-react/src/hooks/use-slate.tsx around line 2, the hook already
imports from '@deepnote/slate' but many other files in the package still import
from 'slate'; update all of those imports to '@deepnote/slate'. Search the
entire packages/slate-react folder for import/require statements that reference
'slate' and replace them with '@deepnote/slate', ensure named/default imports
remain identical, update any path aliases or types if needed, and then run
TypeScript build and tests to confirm no breakages.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0cc057e and b399b86.

📒 Files selected for processing (1)
  • package.json (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint:eslint
  • GitHub Check: lint:prettier
🔇 Additional comments (1)
package.json (1)

57-60: Workspace dependency migration verified and complete.

All @deepnote scoped packages correctly import their dependencies using the @deepnote scope. Source files in slate-history, slate-hyperscript, and slate-react properly import from @deepnote/slate. Package declarations consistently use @deepnote/* naming, and no legacy unscoped references remain. The workspace:* protocol in the consumer package resolves correctly to these internal packages.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 74ef8ba and 282ed50.

📒 Files selected for processing (5)
  • jest.config.js (1 hunks)
  • packages/slate-history/test/index.js (1 hunks)
  • packages/slate-react/tsconfig.json (1 hunks)
  • packages/slate/src/create-editor.ts (1 hunks)
  • packages/slate/src/utils/string.ts (2 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
packages/slate/src/utils/string.ts

[error] 222-222: A character class cannot match a character and a combining character.

A character and a combining character forms a new character. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: lint:typescript
  • GitHub Check: test
  • GitHub Check: lint:prettier
  • GitHub Check: lint:eslint
  • GitHub Check: test:integration
🔇 Additional comments (6)
packages/slate-react/tsconfig.json (2)

7-20: Verify composite: true with empty references array.

TypeScript composite projects typically declare dependencies via the references array for proper incremental builds. With composite: true but an empty references, you may lose benefits like proper type-checking order and incremental compilation across the monorepo. Confirm this is intentional and that type-checking works as expected across slate and dependent packages.


9-18: Path mappings support migration to @deepnote scope.

The dual mappings for both scoped (@deepnote/*) and unscoped (slate*) package names are well-structured for gradual migration and backward compatibility.

packages/slate-history/test/index.js (1)

3-3: Import change verified and correct.

Module aliasing is properly configured in jest.config.js and babel.config.js to resolve @deepnote/slate-hyperscript to the local source. The scoped import aligns with the package re-scoping to the @deepnote org.

packages/slate/src/utils/string.ts (2)

230-230: LGTM: Explicit emoji pictographic ranges.

The alternation structure correctly handles surrogate pairs for extended pictographic characters.


310-320: LGTM: Regional Indicator surrogate pair matching.

The surrogate pair pattern \uD83C[\uDDE6-\uDDFF] correctly matches Regional Indicator symbols, and the odd-count logic properly handles paired RIs for flag emoji detection.

packages/slate/src/create-editor.ts (1)

24-301: Remove the review comment; the cast is justified and necessary.

The as unknown as Editor cast isn't disabling type safety recklessly. The literal object fully satisfies BaseEditor (all 21+ required properties are present). The cast exists because Editor is a conditional type (ExtendedType<'Editor', BaseEditor>) that TS cannot statically validate against its base branch—a known TS limitation, not evidence of a mismatch. The alternatives suggested (narrowing Editor, introducing BaseEditor) don't solve this; BaseEditor already exists and is the type being instantiated.

The cast is a pragmatic workaround for TS's inability to reason about conditional types at this level. Add an inline comment if clarity is needed, but the cast itself is sound.

Likely an incorrect or invalid review comment.

Comment on lines +10 to +19
moduleNameMapper: {
'^slate$': '<rootDir>/packages/slate/src',
'^slate-history$': '<rootDir>/packages/slate-history/src',
'^slate-hyperscript$': '<rootDir>/packages/slate-hyperscript/src',
'^slate-react$': '<rootDir>/packages/slate-react/src',
'^@deepnote/slate$': '<rootDir>/packages/slate/src',
'^@deepnote/slate-history$': '<rootDir>/packages/slate-history/src',
'^@deepnote/slate-hyperscript$': '<rootDir>/packages/slate-hyperscript/src',
'^@deepnote/slate-react$': '<rootDir>/packages/slate-react/src',
},
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Module mappings support dual package names during migration—consider future cleanup.

The moduleNameMapper correctly aliases both unscoped (e.g., slate) and scoped (e.g., @deepnote/slate) package names to their local source directories in the monorepo. Paths follow the expected structure and Jest syntax is correct.

However, the configuration duplicates mappings for the same packages. If this is meant to be temporary during the migration, add a comment noting that unscoped imports should be phased out and the corresponding mappings removed once the migration is complete.

// Temporary dual mappings for migration from unscoped to @deepnote/* scoped packages.
// Once all imports are updated to use @deepnote/* names, remove the unscoped mappings below.
moduleNameMapper: {
  // TODO: Remove unscoped mappings post-migration
  '^slate$': '<rootDir>/packages/slate/src',
  '^slate-history$': '<rootDir>/packages/slate-history/src',
  '^slate-hyperscript$': '<rootDir>/packages/slate-hyperscript/src',
  '^slate-react$': '<rootDir>/packages/slate-react/src',
  // Scoped mappings (canonical)
  '^@deepnote/slate$': '<rootDir>/packages/slate/src',
  '^@deepnote/slate-history$': '<rootDir>/packages/slate-history/src',
  '^@deepnote/slate-hyperscript$': '<rootDir>/packages/slate-hyperscript/src',
  '^@deepnote/slate-react$': '<rootDir>/packages/slate-react/src',
},
🤖 Prompt for AI Agents
In jest.config.js around lines 10 to 19, the moduleNameMapper contains duplicate
mappings for unscoped and @deepnote-scoped package names; add a short comment
above the mappings stating these dual mappings are temporary for migration, mark
unscoped entries as TODO to remove once all imports use @deepnote/*, and keep
the scoped mappings as canonical; ensure the comment clearly instructs future
maintainers to remove the unscoped mappings when migration is complete.

}

const reExtend = /^[\p{Gr_Ext}\p{EMod}]$/u
const reExtend = /^(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65\uDD67-\uDD69\uDD6E-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uD83C[\uDFFB-\uDFFF]|\uDB40[\uDC20-\uDC7F\uDD00-\uDDEF])$/u
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Character class mixes combining marks with base characters.

The character class [\u0300-\u036F...] includes combining diacritical marks alongside regular characters. In character classes, these are treated as independent alternatives rather than as character + combining mark sequences, breaking grapheme cluster detection.

As flagged by Biome: use alternation or restructure the pattern to correctly match base character + combining mark sequences.

🧰 Tools
🪛 Biome (2.1.2)

[error] 222-222: A character class cannot match a character and a combining character.

A character and a combining character forms a new character. Replace the character class with an alternation.

(lint/suspicious/noMisleadingCharacterClass)

🤖 Prompt for AI Agents
In packages/slate/src/utils/string.ts around line 222, the large character class
mixes combining marks and base codepoints causing them to be treated as
independent alternatives; replace the single huge class with an alternation that
explicitly models combining sequences, e.g. use Unicode property escapes and
rewrite the pattern to match either one-or-more combining marks or a base
character followed by zero-or-more combining marks (for example using \p{M} for
marks and \P{M} for non-marks with the u flag), ensuring the regex matches
base+combining sequences rather than treating marks and bases as separate
alternatives.

Comment on lines +305 to 308
const endingEmojiZWJ = new RegExp(`(?:[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u2388\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2605\u2607-\u2612\u2614-\u2685\u2690-\u2705\u2708-\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763-\u2767\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC00-\uDCFF\uDD0D-\uDD0F\uDD2F\uDD6C-\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDAD-\uDDE5\uDE01-\uDE0F\uDE1A\uDE2F\uDE32-\uDE3A\uDE3C-\uDE3F\uDE49-\uDFFA]|\uD83D[\uDC00-\uDD3D\uDD46-\uDE4F\uDE80-\uDEFF\uDF74-\uDF7F\uDFD5-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE-\uDCFF\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDEFF]|\uD83F[\uDC00-\uDFFD])(?:[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09BE\u09C1-\u09C4\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3E\u0B3F\u0B41-\u0B44\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE\u0BC0\u0BCD\u0BD7\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC2\u0CC6\u0CCC\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D3E\u0D41-\u0D44\u0D4D\u0D57\u0D62\u0D63\u0D81\u0DCA\u0DCF\u0DD2-\u0DD4\u0DD6\u0DDF\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1AC0\u1B00-\u1B03\u1B34-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u200C\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F\uFF9E\uFF9F]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50]|\uD804[\uDC01\uDC38-\uDC46\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF3E\uDF40\uDF57\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB0\uDCB3-\uDCB8\uDCBA\uDCBD\uDCBF\uDCC0\uDCC2\uDCC3\uDDAF\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD30\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65\uDD67-\uDD69\uDD6E-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uD83C[\uDFFB-\uDFFF]|\uDB40[\uDC20-\uDC7F\uDD00-\uDDEF])*\u200D$`, 'u')
const endsWithEmojiZWJ = (str: string): boolean => {
return str.search(endingEmojiZWJ) !== -1
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Same combining character issue in emoji ZWJ pattern.

The pattern in endingEmojiZWJ suffers from the same character class + combining mark problem as reExtend. The character class [\u0300-\u036F...] won't correctly match combining sequences.

Use alternation or restructure to properly match emoji + combining mark + ZWJ sequences.

@saltenasl saltenasl closed this Nov 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants