Skip to content

Sandcastle Reborn #12574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from 8 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Thumbs.db
/Apps/Sandcastle/jsHintOptions.js
/Apps/Sandcastle/gallery/gallery-index.js
/Apps/Sandcastle/templates/bucket.css
/Apps/Sandcastle2

/Source/Assets/
/Source/**/*.d.ts
Expand Down Expand Up @@ -43,4 +44,4 @@ yarn.lock
.idea/shelf

# Used in the CLA checking GitHub workflow
GoogleConfig.json
GoogleConfig.json
1 change: 1 addition & 0 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/node_modules
packages/sandcastle/node_modules
/ThirdParty
/Tools/**

Expand Down
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
!**/*.html
!**/*.md
!**/*.ts
!**/*.tsx

# Re-ignore a few things caught above

Expand All @@ -33,6 +34,9 @@ packages/widgets/Build/**
packages/widgets/index.js
packages/widgets/Source/ThirdParty/**

packages/sandcastle/node_modules/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Would a blanket **/node_modules/** rule work?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

technically yes but I think we specifically want it to be obvious when dependencies are messed up and it creates a node_modules inside the other two packages since that's undesired.

Apps/Sandcastle2/**
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we signal that this is built output by putting it in a Build folder?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly but potentially not very easily given how files are accessed, specifically the sample data. I'd like to leave it here for now to mimic the existing sandcastle as much as possible.


Specs/jasmine/**

Apps/Sandcastle/ThirdParty
Expand Down
30 changes: 30 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import globals from "globals";
import html from "eslint-plugin-html";
import configCesium from "@cesium/eslint-config";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";

export default [
{
Expand All @@ -15,6 +18,8 @@ export default [
"Apps/HelloWorld.html",
"Apps/Sandcastle/jsHintOptions.js",
"Apps/Sandcastle/gallery/gallery-index.js",
"Apps/Sandcastle2/",
"packages/sandcastle/public/",
"packages/engine/Source/Scene/GltfPipeline/**/*",
"packages/engine/Source/Shaders/**/*",
"Specs/jasmine/*",
Expand Down Expand Up @@ -74,6 +79,31 @@ export default [
sourceType: "module",
},
},
...[...tseslint.configs.recommended].map((config) => ({
// This is needed to restrict to a specific path unless using the tseslint.config function
// https://typescript-eslint.io/packages/typescript-eslint#config
...config,
files: ["packages/sandcastle/**/*.{ts,tsx}"],
})),
{
// This config came from the vite project generation
files: ["packages/sandcastle/**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"react-refresh/only-export-components": [
"warn",
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this be "warn" or "error"? Right now, warnings will not be indicating when running our eslint command.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Possibly. This was a direct copy out of the generated file from the vite setup just to make it work with the flat eslint config. I honestly didn't really look at what was set or not set yet, completely open to review if you want to take a stab at changing this and extracting like you mention in the other comment.

{ allowConstantExport: true },
],
},
Comment on lines +82 to +105
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder... To help isolate things a bit more, can we defined the following config in a standalone file and just import it here? I may look into this a bit. No need to hold up the PR.

},
{
files: ["Specs/**/*", "packages/**/Specs/**/*"],
languageOptions: {
Expand Down
5 changes: 5 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ export async function buildTs() {
workspaces = packageJson.workspaces;
}

// TODO: we probably need to manage workspaces better now
workspaces = workspaces.filter(
(workspace) => !workspace.includes("sandcastle"),
);

// Generate types for passed packages in order.
const importModules = {};
for (const workspace of workspaces) {
Expand Down
15 changes: 10 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"esbuild": "^0.25.0",
"eslint": "^9.1.1",
"eslint-plugin-html": "^8.1.1",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"express": "^4.17.1",
"globals": "^16.0.0",
"globby": "^14.0.0",
Expand Down Expand Up @@ -101,6 +103,7 @@
"rimraf": "^5.0.0",
"tsd-jsdoc": "^2.5.0",
"typescript": "^5.3.2",
"typescript-eslint": "^8.30.1",
"yargs": "^17.0.1"
},
"scripts": {
Expand All @@ -112,13 +115,14 @@
"build-watch": "gulp buildWatch",
"build-ts": "gulp buildTs",
"build-third-party": "gulp buildThirdParty",
"build-apps": "gulp buildApps",
"build-apps": "gulp buildApps && npm run build -w packages/sandcastle -- -l warn",
"build-sandcastle": "npm run build --workspace packages/sandcastle",
"clean": "gulp clean",
"cloc": "gulp cloc",
"coverage": "gulp coverage",
"build-docs": "gulp buildDocs",
"build-docs-watch": "gulp buildDocsWatch",
"eslint": "eslint \"./**/*.*js\" \"./**/*.html\" --cache --quiet",
"eslint": "eslint \"./**/*.*js\" \"./**/*.*ts*\" \"./**/*.html\" --cache --quiet",
"make-zip": "gulp makeZip",
"markdownlint": "markdownlint \"**/*.md\"",
"release": "gulp release",
Expand Down Expand Up @@ -146,7 +150,7 @@
"node": ">=18.18.0"
},
"lint-staged": {
"*.{js,cjs,mjs,css,html}": [
"*.{js,cjs,mjs,ts,tsx,css,html}": [
"eslint --cache --quiet",
"prettier --write"
],
Expand All @@ -157,6 +161,7 @@
},
"workspaces": [
"packages/engine",
"packages/widgets"
"packages/widgets",
"packages/sandcastle"
]
}
}
14 changes: 14 additions & 0 deletions packages/sandcastle/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

59 changes: 59 additions & 0 deletions packages/sandcastle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# CesiumJS Sandcastle

This package is the application for Sandcastle.

## Running/Building

- `npm run dev` from inside this directory to run the development server
- `npm run build` will build this to static files in `/Apps/Sandcastle2` for hosting/access from the normal dev server
- `npm run preview` will run the production build locally. <!--TODO: I'm not sure if we actually need this for our purposes -->

Linting and style is managed under the project root's scripts.

## Expanding the ESLint configuration

<!-- TODO: this section was auto-generated, should figure out if we want these suggestions then remove this -->

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default tseslint.config({
extends: [
// Remove ...tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
],
languageOptions: {
// other options...
parserOptions: {
project: ["./tsconfig.node.json", "./tsconfig.app.json"],
tsconfigRootDir: import.meta.dirname,
},
},
});
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from "eslint-plugin-react-x";
import reactDom from "eslint-plugin-react-dom";

export default tseslint.config({
plugins: {
// Add the react-x and react-dom plugins
"react-x": reactX,
"react-dom": reactDom,
},
rules: {
// other rules...
// Enable its recommended typescript rules
...reactX.configs["recommended-typescript"].rules,
...reactDom.configs.recommended.rules,
},
});
```
31 changes: 31 additions & 0 deletions packages/sandcastle/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sandcastle Reborn</title>
<style>
/* Load fonts for itwin-ui */
@font-face {
font-family: InterVariable;
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url("/fonts/InterVariable.woff2") format("woff2");
}

@font-face {
font-family: InterVariable;
font-style: italic;
font-weight: 100 900;
font-display: swap;
src: url("/fonts/InterVariable-Italic.woff2") format("woff2");
}
</style>
</head>
<body>
<div id="app-container"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
29 changes: 29 additions & 0 deletions packages/sandcastle/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@cesium/sandcastle",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@itwin/itwinui-react": "^5.0.0-alpha.14",
"@monaco-editor/react": "^4.7.0",
"monaco-editor": "^0.52.2",
"pako": "^2.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/pako": "^2.0.3",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react": "^4.3.4",
"globals": "^15.15.0",
"typescript": "~5.7.2",
"vite": "^6.2.0",
"vite-plugin-static-copy": "^2.3.1"
}
}
Loading