Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/react-19-alignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@open-slide/core": major
"@open-slide/cli": major
---

Require React 19 for the runtime and generated workspaces.
6 changes: 6 additions & 0 deletions .changeset/vite-8-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@open-slide/core": major
"@open-slide/cli": major
---

Migrate the runtime and generated workspaces to Vite 8 with native Rolldown optimizer options.
8 changes: 4 additions & 4 deletions apps/demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
},
"dependencies": {
"@open-slide/core": "workspace:*",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1"
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3"
}
}
5 changes: 4 additions & 1 deletion apps/web/components/mdx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import type { MDXComponents } from 'mdx/types';
export function getMDXComponents(components?: MDXComponents) {
return {
...defaultMdxComponents,
img: (props) => <ImageZoom {...props} />,
img: (props) => {
const { src, ...rest } = props;
return <ImageZoom {...rest} src={typeof src === 'string' ? src : undefined} />;
},
TypeTable,
...components,
} satisfies MDXComponents;
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
},
"dependencies": {
"@open-slide/core": "^0.0.6",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react": "^19.2.7",
"react-dom": "^19.2.7"
},
"devDependencies": {
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"vite": "^5.4.10"
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"vite": "^8.1.4"
Comment on lines +14 to +20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '^(packages/cli/template/package\.json|packages/cli/template/open-slide\.config\.ts|packages/(cli|core)/package\.json|.*\.changeset|.)$' | sed -n '1,120p'

echo
echo "== package manifests relevant deps =="
for f in packages/cli/package.json packages/core/package.json packages/cli/template/package.json; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    wc -l "$f"
    sed -n '1,80p' "$f"
  fi
done

echo
echo "== changesets =="
if [ -d .changeset ]; then
  find .changeset -maxdepth 1 -type f -print -exec sh -c 'echo "--- {} ---"; sed -n "1,120p" "{}"' \;
else
  echo "no .changeset directory"
fi

echo
echo "== git diff summary/name-status =="
git diff --stat
git diff --name-status

Repository: 1weiho/open-slide

Length of output: 5810


Move template package versioning out of direct edits.

packages/cli/template/package.json is covered by the rule prohibiting direct changes to packages/cli/template/**/{package.json,open-slide.config.ts}. Drop these direct edits and update the template via the approved source-of-truth/generation flow, or update that prohibition if it is obsolete.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/template/package.json` around lines 14 - 20, Remove the direct
dependency-version edits from the template package.json and apply them through
the approved template source-of-truth or generation flow. If direct template
edits are now intentionally supported, update the prohibition rule instead; keep
the generated template output consistent with the chosen approach.

Source: Path instructions


🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

node -p "require('./packages/core/package.json').version"
node -p "require('./packages/cli/template/package.json').dependencies['`@open-slide/core`']"
rg -n '"`@open-slide/core`":' .changeset

Repository: 1weiho/open-slide

Length of output: 289


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- package.json excerpt ---\n'
sed -n '1,80p' packages/cli/template/package.json

printf '\n--- changesets ---\n'
for f in .changeset/*.md; do
  echo "### $f"
  cat -n "$f"
done

printf '\n--- package manager config relevant files ---\n'
git ls-files | rg '(^|/)(package.json|pnpm-workspace.yaml|biome.json|tsconfig.*\.json)$' | head -80

Repository: 1weiho/open-slide

Length of output: 246


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- packages/cli/template/package.json excerpt ---'
sed -n '1,80p' packages/cli/template/package.json

printf '%s\n' ''
printf '%s\n' '--- changesets ---'
for f in .changeset/*.md; do
  echo "### $f"
  cat -n "$f"
done

printf '%s\n' ''
printf '%s\n' '--- repo files relevant to package manifests/config ---'
git ls-files | rg '(^|/)(package.json|pnpm-workspace.yaml|biome.json|tsconfig.*\.json)$' || true

Repository: 1weiho/open-slide

Length of output: 2409


Publish and update the core major version in the template.

.changeset/react-19-alignment.md and .changeset/vite-8-migration.md both schedule a major @open-slide/core release, but packages/cli/template/package.json still depends on ^0.0.6 while packages/core/package.json is at 1.17.1. Generated workspaces will resolve the old compatibility core against the React 19/Vite 8 template; update this range to the released major built by the changesets.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/template/package.json` around lines 14 - 20, Update the
`@open-slide/core` dependency in packages/cli/template/package.json from the old
^0.0.6 range to the released 1.x major compatible with the React 19 and Vite 8
template, matching the major version scheduled by the changesets and the current
packages/core version.

}
}
12 changes: 6 additions & 6 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@dnd-kit/utilities": "^3.2.2",
"@fontsource-variable/geist": "^5.2.8",
"@tailwindcss/vite": "^4.3.3",
"@vitejs/plugin-react": "^4.3.3",
"@vitejs/plugin-react": "^6.0.3",
"chalk": "^5.3.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
Expand All @@ -84,8 +84,8 @@
"html-to-image": "^1.11.13",
"lucide-react": "^1.25.0",
"next-themes": "^0.4.6",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-image-crop": "^11.0.10",
"react-router-dom": "^7.18.1",
"shadcn": "^4.12.0",
Expand All @@ -94,13 +94,13 @@
"tailwindcss": "^4.2.2",
"tw-animate-css": "^1.4.0",
"use-sync-external-store": "^1.6.0",
"vite": "^5.4.10"
"vite": "^8.1.4"
},
"devDependencies": {
"@playwright/test": "~1.56.1",
"@types/node": "^22.19.17",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"tsdown": "^0.9.9",
"typescript": "^5.9.3"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function Frame({
showImageActions = false,
}: {
anchor: HTMLElement | null;
overlayRef: React.RefObject<HTMLDivElement>;
overlayRef: React.RefObject<HTMLDivElement | null>;
variant: FrameVariant;
showImageActions?: boolean;
}) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/app/lib/use-click-page-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const NAV_PASSTHROUGH =
'a, button, input, textarea, select, label, summary, iframe, video, audio, embed, object, [role="button"], [role="link"], [contenteditable="true"], [data-osd-interactive], [data-osd-chrome]';

type UseClickPageNavigationOptions<T extends HTMLElement> = {
ref: RefObject<T>;
ref: RefObject<T | null>;
enabled?: boolean;
/** Fraction of the width on each side that navigates; the center is inert. */
edgeRatio?: number;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/app/lib/use-wheel-page-navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const WHEEL_NAV_COOLDOWN_MS = 100;
const WHEEL_GESTURE_IDLE_MS = 80;

type UseWheelPageNavigationOptions<T extends HTMLElement> = {
ref: RefObject<T>;
ref: RefObject<T | null>;
enabled?: boolean;
canPrev: boolean;
canNext: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/app/routes/slide.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ function SlideViewportNavigation({
canPrev,
canNext,
}: {
targetRef: RefObject<HTMLElement>;
targetRef: RefObject<HTMLElement | null>;
onPrev: () => void;
onNext: () => void;
canPrev: boolean;
Expand Down
43 changes: 43 additions & 0 deletions packages/core/src/vite/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { describe, expect, it } from 'vitest';
import { createViteConfig } from './config.ts';

type VirtualExternalsPlugin = {
name: string;
resolveId?: (id: string) => { id: string; external: true } | undefined;
};

describe('createViteConfig', () => {
it('uses native optimizeDeps.rolldownOptions and excludes virtual modules', async () => {
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'open-slide-vite-config-'));
try {
await fs.mkdir(path.join(root, 'slides'), { recursive: true });
const config = await createViteConfig({ userCwd: root });
const optimizeDeps = config.optimizeDeps;

expect(optimizeDeps).toBeDefined();
expect(optimizeDeps).not.toHaveProperty('esbuildOptions');

const plugins = optimizeDeps?.rolldownOptions?.plugins;
expect(Array.isArray(plugins)).toBe(true);

const plugin = (plugins as VirtualExternalsPlugin[]).find(
(entry) => entry?.name === 'open-slide:virtual-externals',
);
expect(plugin).toBeDefined();
expect(plugin?.resolveId?.('virtual:open-slide/slides')).toEqual({
id: 'virtual:open-slide/slides',
external: true,
});
expect(plugin?.resolveId?.('virtual:open-slide/config')).toEqual({
id: 'virtual:open-slide/config',
external: true,
});
expect(plugin?.resolveId?.('react')).toBeUndefined();
} finally {
await fs.rm(root, { recursive: true, force: true });
}
});
});
13 changes: 6 additions & 7 deletions packages/core/src/vite/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,15 @@ export async function createViteConfig(opts: CreateViteConfigOptions): Promise<I
],
// The app source ships inside node_modules/@open-slide/core/src/app, so
// Vite's dep scanner traverses it as if it were a third-party dep and
// tries to bundle our virtual imports with esbuild. Mark them external.
esbuildOptions: {
// tries to bundle our virtual imports. Mark them external for Rolldown.
rolldownOptions: {
plugins: [
{
name: 'open-slide:virtual-externals',
setup(build) {
build.onResolve({ filter: /^virtual:open-slide\// }, (args) => ({
path: args.path,
external: true,
}));
resolveId(id: string) {
if (id.startsWith('virtual:open-slide/')) {
return { id, external: true };
}
},
},
],
Expand Down
Loading