diff --git a/package-lock.json b/package-lock.json index 9bd5fa11fe3..f45eb09aa2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -117,7 +117,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -290,6 +289,10 @@ "node": ">=18" } }, + "node_modules/@breadboard-ai/opal-frontend": { + "resolved": "packages/opal-frontend", + "link": true + }, "node_modules/@breadboard-ai/types": { "resolved": "packages/types", "link": true @@ -401,7 +404,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -445,7 +447,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -2299,7 +2300,6 @@ "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", @@ -2567,7 +2567,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -2849,7 +2848,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4432,7 +4430,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -5910,7 +5907,6 @@ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.5.tgz", "integrity": "sha512-3qq+FUBtlTHhtYxbxheZgY8NIFnkkC/MR8u5TTsr7YZ3wixryQ3cCwn3iZbg8p8B88iDBBAYSfZDS75t8MN7Vg==", "license": "MIT", - "peer": true, "engines": { "node": ">=16.9.0" } @@ -8738,8 +8734,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/signal-polyfill/-/signal-polyfill-0.2.2.tgz", "integrity": "sha512-p63Y4Er5/eMQ9RHg0M0Y64NlsQKpiu6MDdhBXpyywRuWiPywhJTpKJ1iB5K2hJEbFZ0BnDS7ZkJ+0AfTuL37Rg==", - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/signal-utils": { "version": "0.21.1", @@ -9518,7 +9513,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10113,7 +10107,6 @@ "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "devOptional": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -10238,7 +10231,6 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -10255,6 +10247,24 @@ "packages/opal-backend": { "version": "0.1.0" }, + "packages/opal-frontend": { + "name": "@breadboard-ai/opal-frontend", + "version": "0.1.0", + "license": "Apache-2.0", + "dependencies": { + "@lit-labs/signals": "^0.1.3", + "lit": "^3.3.2", + "signal-polyfill": "^0.2.2", + "signal-utils": "^0.21.1" + }, + "devDependencies": { + "@google-labs/tsconfig": "^0.0.2", + "@types/node": "^22.0.0", + "typescript": "^5.8.3", + "vite": "^7.2.6", + "wireit": "^0.15.0-pre.2" + } + }, "packages/types": { "name": "@breadboard-ai/types", "version": "0.9.0", @@ -10271,6 +10281,7 @@ "version": "0.4.0", "license": "Apache-2.0", "dependencies": { + "@breadboard-ai/opal-frontend": "0.1.0", "@breadboard-ai/types": "0.9.0", "@breadboard-ai/utils": "^0.1.0", "@breadboard-ai/visual-editor": "1.30.0", diff --git a/packages/opal-frontend/.eslintrc b/packages/opal-frontend/.eslintrc new file mode 100644 index 00000000000..bb987452b0c --- /dev/null +++ b/packages/opal-frontend/.eslintrc @@ -0,0 +1,6 @@ +{ + "parser": "@typescript-eslint/parser", + "parserOptions": { + "projectService": true + } +} diff --git a/packages/opal-frontend/.gitignore b/packages/opal-frontend/.gitignore new file mode 100644 index 00000000000..849ddff3b7e --- /dev/null +++ b/packages/opal-frontend/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/packages/opal-frontend/.npmignore b/packages/opal-frontend/.npmignore new file mode 100644 index 00000000000..7ddb2133685 --- /dev/null +++ b/packages/opal-frontend/.npmignore @@ -0,0 +1,2 @@ +.env +tsconfig.tsbuildinfo diff --git a/packages/opal-frontend/index.html b/packages/opal-frontend/index.html new file mode 100644 index 00000000000..fa8c62f71e3 --- /dev/null +++ b/packages/opal-frontend/index.html @@ -0,0 +1,10 @@ + + + + + Opal Frontend + + + + + diff --git a/packages/opal-frontend/package.json b/packages/opal-frontend/package.json new file mode 100644 index 00000000000..04204e12ce0 --- /dev/null +++ b/packages/opal-frontend/package.json @@ -0,0 +1,115 @@ +{ + "name": "@breadboard-ai/opal-frontend", + "private": true, + "version": "0.1.0", + "description": "The Opal Frontend", + "main": "./dist/src/index.js", + "exports": { + ".": { + "types": "./dist/src/index.d.ts", + "default": "./dist/src/index.js" + }, + "./package.json": "./package.json" + }, + "types": "dist/src/index.d.ts", + "type": "module", + "scripts": { + "build": "wireit", + "build:vite": "wireit", + "build:tsc": "wireit", + "dev": "vite", + "lint": "wireit" + }, + "wireit": { + "build": { + "dependencies": [ + "build:vite" + ] + }, + "typescript-files-and-deps": { + "files": [ + "src/**/*.ts", + "tsconfig.json", + "vite.config.ts", + "../../core/tsconfig/base.json", + "package.json" + ] + }, + "check:tsc": { + "command": "tsc -b --pretty --noEmit", + "env": { + "FORCE_COLOR": "1" + }, + "dependencies": [ + "typescript-files-and-deps" + ], + "files": [], + "output": [] + }, + "build:tsc": { + "command": "tsc -b --pretty", + "env": { + "FORCE_COLOR": "1" + }, + "dependencies": [ + "typescript-files-and-deps" + ], + "files": [ + "dist/tsc/" + ] + }, + "build:vite": { + "command": "vite build", + "env": { + "FORCE_COLOR": "1" + }, + "dependencies": [ + "check:tsc" + ], + "files": [ + "vite.config.ts", + "*.html" + ], + "output": [ + "dist/" + ] + }, + "lint": { + "command": "eslint --max-warnings=0 'src/**/*.ts'", + "files": [ + "src/**/*.ts", + "../../eslint.config.js" + ], + "output": [] + } + }, + "repository": { + "directory": "packages/opal-frontend", + "type": "git", + "url": "git+https://github.com/breadboard-ai/breadboard.git" + }, + "files": [ + "dist/", + "index.html" + ], + "keywords": [], + "author": "Google Labs Team", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/breadboard-ai/breadboard/issues" + }, + "homepage": "https://github.com/breadboard-ai/breadboard/tree/main/packages/opal-frontend#readme", + "devDependencies": { + "@google-labs/tsconfig": "^0.0.2", + "@types/node": "^22.0.0", + "typescript": "^5.8.3", + "vite": "^7.2.6", + "wireit": "^0.15.0-pre.2" + }, + "dependencies": { + "@lit-labs/signals": "^0.1.3", + "lit": "^3.3.2", + "signal-polyfill": "^0.2.2", + "signal-utils": "^0.21.1" + } +} \ No newline at end of file diff --git a/packages/opal-frontend/src/index.ts b/packages/opal-frontend/src/index.ts new file mode 100644 index 00000000000..74f1bbe4176 --- /dev/null +++ b/packages/opal-frontend/src/index.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { signal } from "signal-utils"; +import { SignalWatcher } from "@lit-labs/signals"; +import { LitElement, html, css } from "lit"; +import { customElement } from "lit/decorators.js"; + +/** + * @constructor + * @extends {LitElement} + */ +const SignalWatcherBase = SignalWatcher(LitElement); + +@customElement("opal-main") +/** @extends {LitElement} */ +class OpalMain extends SignalWatcherBase { + static override styles = css` + :host { + display: block; + font-family: system-ui, sans-serif; + padding: 2rem; + } + `; + + @signal accessor time = new Date().toLocaleTimeString(); + + override connectedCallback() { + super.connectedCallback(); + setInterval(() => { + this.time = new Date().toLocaleTimeString(); + }, 1000); + } + + override render() { + return html`

Hello, Signals! The time is ${this.time}

`; + } +} + +declare global { + interface HTMLElementTagNameMap { + "opal-main": OpalMain; + } +} diff --git a/packages/opal-frontend/tsconfig.json b/packages/opal-frontend/tsconfig.json new file mode 100644 index 00000000000..74e1875bdd2 --- /dev/null +++ b/packages/opal-frontend/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "nodenext", + "lib": ["ES2023", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + "useDefineForClassFields": false, + "outDir": "dist/tsc", + "moduleResolution": "nodenext", + "resolveJsonModule": true, + "isolatedModules": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "types": ["vite/client", "node"] + }, + "include": ["src/**/*.ts"], + "extends": "@google-labs/tsconfig/base.json" +} diff --git a/packages/opal-frontend/vite.config.ts b/packages/opal-frontend/vite.config.ts new file mode 100644 index 00000000000..c97782d8127 --- /dev/null +++ b/packages/opal-frontend/vite.config.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { defineConfig, type UserConfig } from "vite"; + +export default defineConfig((): UserConfig => { + return { + optimizeDeps: { esbuildOptions: { target: "esnext" } }, + build: { + target: "esnext", + outDir: "dist/client", + }, + resolve: { + dedupe: ["lit"], + }, + server: { + port: 3333, + watch: { + ignored: ["**/.wireit/**"], + }, + }, + }; +}); diff --git a/packages/unified-server/package.json b/packages/unified-server/package.json index de1a89e227b..e3cb3d095dd 100644 --- a/packages/unified-server/package.json +++ b/packages/unified-server/package.json @@ -37,7 +37,8 @@ }, "build:vite": { "dependencies": [ - "../visual-editor#build" + "../visual-editor#build", + "../opal-frontend#build" ] }, "build:tsc": { @@ -167,6 +168,7 @@ "dependencies": { "@breadboard-ai/types": "0.9.0", "@breadboard-ai/utils": "^0.1.0", + "@breadboard-ai/opal-frontend": "0.1.0", "@breadboard-ai/visual-editor": "1.30.0", "@google-cloud/storage": "^7.15.2", "compression": "^1.8.1",