Reach the login view :D

This commit is contained in:
49lf
2024-07-23 15:08:33 -04:00
parent 286edd90af
commit a1aadd3fb8
12 changed files with 165 additions and 108 deletions

1
.gitignore vendored
View File

@ -62,3 +62,4 @@ Mac_App_Distribution.provisionprofile
*.tsbuildinfo *.tsbuildinfo
venv venv
.vite/

View File

@ -1,18 +1,23 @@
import type { ForgeConfig } from '@electron-forge/shared-types'; import type { ForgeConfig } from '@electron-forge/shared-types'
import { MakerSquirrel } from '@electron-forge/maker-squirrel'; import { MakerSquirrel } from '@electron-forge/maker-squirrel'
import { MakerZIP } from '@electron-forge/maker-zip'; import { MakerZIP } from '@electron-forge/maker-zip'
import { MakerDeb } from '@electron-forge/maker-deb'; import { MakerDeb } from '@electron-forge/maker-deb'
import { MakerRpm } from '@electron-forge/maker-rpm'; import { MakerRpm } from '@electron-forge/maker-rpm'
import { VitePlugin } from '@electron-forge/plugin-vite'; import { VitePlugin } from '@electron-forge/plugin-vite'
import { FusesPlugin } from '@electron-forge/plugin-fuses'; import { FusesPlugin } from '@electron-forge/plugin-fuses'
import { FuseV1Options, FuseVersion } from '@electron/fuses'; import { FuseV1Options, FuseVersion } from '@electron/fuses'
const config: ForgeConfig = { const config: ForgeConfig = {
packagerConfig: { packagerConfig: {
asar: true, asar: true,
}, },
rebuildConfig: {}, rebuildConfig: {},
makers: [new MakerSquirrel({}), new MakerZIP({}, ['darwin']), new MakerRpm({}), new MakerDeb({})], makers: [
new MakerSquirrel({}),
new MakerZIP({}, ['darwin']),
new MakerRpm({}),
new MakerDeb({}),
],
plugins: [ plugins: [
new VitePlugin({ new VitePlugin({
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc. // `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
@ -47,6 +52,6 @@ const config: ForgeConfig = {
[FuseV1Options.OnlyLoadAppFromAsar]: true, [FuseV1Options.OnlyLoadAppFromAsar]: true,
}), }),
], ],
}; }
export default config; export default config

26
forge.env.d.ts vendored
View File

@ -1,31 +1,35 @@
export {}; // Make this a module export {} // Make this a module
declare global { declare global {
// This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Vite // This allows TypeScript to pick up the magic constants that's auto-generated by Forge's Vite
// plugin that tells the Electron app where to look for the Vite-bundled app code (depending on // plugin that tells the Electron app where to look for the Vite-bundled app code (depending on
// whether you're running in development or production). // whether you're running in development or production).
const MAIN_WINDOW_VITE_DEV_SERVER_URL: string; const MAIN_WINDOW_VITE_DEV_SERVER_URL: string
const MAIN_WINDOW_VITE_NAME: string; const MAIN_WINDOW_VITE_NAME: string
namespace NodeJS { namespace NodeJS {
interface Process { interface Process {
// Used for hot reload after preload scripts. // Used for hot reload after preload scripts.
viteDevServers: Record<string, import('vite').ViteDevServer>; viteDevServers: Record<string, import('vite').ViteDevServer>
} }
} }
type VitePluginConfig = ConstructorParameters<typeof import('@electron-forge/plugin-vite').VitePlugin>[0]; type VitePluginConfig = ConstructorParameters<
typeof import('@electron-forge/plugin-vite').VitePlugin
>[0]
interface VitePluginRuntimeKeys { interface VitePluginRuntimeKeys {
VITE_DEV_SERVER_URL: `${string}_VITE_DEV_SERVER_URL`; VITE_DEV_SERVER_URL: `${string}_VITE_DEV_SERVER_URL`
VITE_NAME: `${string}_VITE_NAME`; VITE_NAME: `${string}_VITE_NAME`
} }
} }
declare module 'vite' { declare module 'vite' {
interface ConfigEnv<K extends keyof VitePluginConfig = keyof VitePluginConfig> { interface ConfigEnv<
root: string; K extends keyof VitePluginConfig = keyof VitePluginConfig
forgeConfig: VitePluginConfig; > {
forgeConfigSelf: VitePluginConfig[K][number]; root: string
forgeConfig: VitePluginConfig
forgeConfigSelf: VitePluginConfig[K][number]
} }
} }

View File

@ -2,7 +2,9 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> <!-- PERPETUAL TODO reconsider this option.
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
-->
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />

View File

@ -85,19 +85,7 @@ export type { MemoryItem } from '../wasm-lib/kcl/bindings/MemoryItem'
export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface' export type { ExtrudeSurface } from '../wasm-lib/kcl/bindings/ExtrudeSurface'
export const wasmUrl = () => { export const wasmUrl = () => {
const baseUrl = const fullUrl = '/wasm_lib_bg.wasm'
typeof window === 'undefined'
? 'http://127.0.0.1:3000'
: window.location.origin.includes('tauri://localhost')
? 'tauri://localhost' // custom protocol for macOS
: window.location.origin.includes('tauri.localhost')
? 'http://tauri.localhost' // fallback for Windows
: window.location.origin.includes('localhost')
? 'http://localhost:3000'
: window.location.origin && window.location.origin !== 'null'
? window.location.origin
: 'http://localhost:3000'
const fullUrl = baseUrl + '/wasm_lib_bg.wasm'
console.log(`Full URL for WASM: ${fullUrl}`) console.log(`Full URL for WASM: ${fullUrl}`)
return fullUrl return fullUrl

View File

@ -1,18 +1,43 @@
// Some of the following was taken from bits and pieces of the vite-typescript
// template that ElectronJS provides.
import { app, BrowserWindow } from 'electron' import { app, BrowserWindow } from 'electron'
import path from 'path'
const createWindow = () => { // Handle creating/removing shortcuts on Windows when installing/uninstalling.
const win = new BrowserWindow({ if (require('electron-squirrel-startup')) {
width: 800, app.quit()
height: 600
})
win.loadFile('index.html')
} }
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
})
// and load the index.html of the app.
if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL)
} else {
mainWindow.loadFile(
path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`)
)
}
// Open the DevTools.
mainWindow.webContents.openDevTools()
}
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit() if (process.platform !== 'darwin') {
app.quit()
}
}) })
app.whenReady().then(() => { // This method will be called when Electron has finished
createWindow() // initialization and is ready to create browser windows.
}) // Some APIs can only be used after this event occurs.
app.on('ready', createWindow)

0
src/preload.ts Normal file
View File

View File

@ -1,7 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": "src", "baseUrl": "src",
"outDir": "dist",
"paths": { "paths": {
"@kittycad/codemirror-lsp-client": [ "@kittycad/codemirror-lsp-client": [
"../packages/codemirror-lsp-client/src/index.ts" "../packages/codemirror-lsp-client/src/index.ts"

View File

@ -1,14 +1,22 @@
import { builtinModules } from 'node:module'; import { builtinModules } from 'node:module'
import type { AddressInfo } from 'node:net'; import type { AddressInfo } from 'node:net'
import type { ConfigEnv, Plugin, UserConfig } from 'vite'; import type { ConfigEnv, Plugin, UserConfig } from 'vite'
import pkg from './package.json'; import pkg from './package.json'
export const builtins = ['electron', ...builtinModules.map((m) => [m, `node:${m}`]).flat()]; export const builtins = [
'electron',
...builtinModules.map((m) => [m, `node:${m}`]).flat(),
]
export const external = [...builtins, ...Object.keys('dependencies' in pkg ? (pkg.dependencies as Record<string, unknown>) : {})]; export const external = [
...builtins,
...Object.keys(
'dependencies' in pkg ? (pkg.dependencies as Record<string, unknown>) : {}
),
]
export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig { export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig {
const { root, mode, command } = env; const { root, mode, command } = env
return { return {
root, root,
@ -22,56 +30,63 @@ export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig {
minify: command === 'build', minify: command === 'build',
}, },
clearScreen: false, clearScreen: false,
}; }
} }
export function getDefineKeys(names: string[]) { export function getDefineKeys(names: string[]) {
const define: { [name: string]: VitePluginRuntimeKeys } = {}; const define: { [name: string]: VitePluginRuntimeKeys } = {}
return names.reduce((acc, name) => { return names.reduce((acc, name) => {
const NAME = name.toUpperCase(); const NAME = name.toUpperCase()
const keys: VitePluginRuntimeKeys = { const keys: VitePluginRuntimeKeys = {
VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`, VITE_DEV_SERVER_URL: `${NAME}_VITE_DEV_SERVER_URL`,
VITE_NAME: `${NAME}_VITE_NAME`, VITE_NAME: `${NAME}_VITE_NAME`,
}; }
return { ...acc, [name]: keys }; return { ...acc, [name]: keys }
}, define); }, define)
} }
export function getBuildDefine(env: ConfigEnv<'build'>) { export function getBuildDefine(env: ConfigEnv<'build'>) {
const { command, forgeConfig } = env; const { command, forgeConfig } = env
const names = forgeConfig.renderer.filter(({ name }) => name != null).map(({ name }) => name!); const names = forgeConfig.renderer
const defineKeys = getDefineKeys(names); .filter(({ name }) => name != null)
.map(({ name }) => name!)
const defineKeys = getDefineKeys(names)
const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => { const define = Object.entries(defineKeys).reduce((acc, [name, keys]) => {
const { VITE_DEV_SERVER_URL, VITE_NAME } = keys; const { VITE_DEV_SERVER_URL, VITE_NAME } = keys
const def = { const def = {
[VITE_DEV_SERVER_URL]: command === 'serve' ? JSON.stringify(process.env[VITE_DEV_SERVER_URL]) : undefined, [VITE_DEV_SERVER_URL]:
command === 'serve'
? JSON.stringify(process.env[VITE_DEV_SERVER_URL])
: undefined,
[VITE_NAME]: JSON.stringify(name), [VITE_NAME]: JSON.stringify(name),
}; }
return { ...acc, ...def }; return { ...acc, ...def }
}, {} as Record<string, any>); }, {} as Record<string, any>)
return define; return define
} }
export function pluginExposeRenderer(name: string): Plugin { export function pluginExposeRenderer(name: string): Plugin {
const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name]; const { VITE_DEV_SERVER_URL } = getDefineKeys([name])[name]
return { return {
name: '@electron-forge/plugin-vite:expose-renderer', name: '@electron-forge/plugin-vite:expose-renderer',
configureServer(server) { configureServer(server) {
process.viteDevServers ??= {}; process.viteDevServers ??= {}
// Expose server for preload scripts hot reload. // Expose server for preload scripts hot reload.
process.viteDevServers[name] = server; process.viteDevServers[name] = server
server.httpServer?.once('listening', () => { server.httpServer?.once('listening', () => {
const addressInfo = server.httpServer!.address() as AddressInfo; const addressInfo = server.httpServer!.address() as AddressInfo
// Expose env constant for main process use. // Expose env constant for main process use.
process.env[VITE_DEV_SERVER_URL] = `http://localhost:${addressInfo?.port}`; process.env[
}); VITE_DEV_SERVER_URL
] = `http://localhost:${addressInfo?.port}`
})
}, },
}; }
} }
export function pluginHotRestart(command: 'reload' | 'restart'): Plugin { export function pluginHotRestart(command: 'reload' | 'restart'): Plugin {
@ -81,13 +96,13 @@ export function pluginHotRestart(command: 'reload' | 'restart'): Plugin {
if (command === 'reload') { if (command === 'reload') {
for (const server of Object.values(process.viteDevServers)) { for (const server of Object.values(process.viteDevServers)) {
// Preload scripts hot reload. // Preload scripts hot reload.
server.ws.send({ type: 'full-reload' }); server.ws.send({ type: 'full-reload' })
} }
} else { } else {
// Main process hot restart. // Main process hot restart.
// https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223 // https://github.com/electron/forge/blob/v7.2.0/packages/api/core/src/api/start.ts#L216-L223
process.stdin.emit('data', 'rs'); process.stdin.emit('data', 'rs')
} }
}, },
}; }
} }

View File

@ -1,19 +1,24 @@
import type { ConfigEnv, UserConfig } from 'vite'; import type { ConfigEnv, UserConfig } from 'vite'
import { defineConfig, mergeConfig } from 'vite'; import { defineConfig, mergeConfig } from 'vite'
import { configDefaults } from 'vitest/config' import { configDefaults } from 'vitest/config'
import viteTsconfigPaths from 'vite-tsconfig-paths' import viteTsconfigPaths from 'vite-tsconfig-paths'
import vitePluginEslint from 'vite-plugin-eslint' import vitePluginEslint from 'vite-plugin-eslint'
import vitePluginPackageVersion from 'vite-plugin-package-version' import vitePluginPackageVersion from 'vite-plugin-package-version'
import { getBuildConfig, getBuildDefine, external, pluginHotRestart } from './vite.base.config'; import {
getBuildConfig,
getBuildDefine,
external,
pluginHotRestart,
} from './vite.base.config'
import viteJsPluginReact from '@vitejs/plugin-react' import viteJsPluginReact from '@vitejs/plugin-react'
// @ts-ignore: No types available // @ts-ignore: No types available
import { lezer } from '@lezer/generator/rollup' import { lezer } from '@lezer/generator/rollup'
// https://vitejs.dev/config // https://vitejs.dev/config
export default defineConfig((env) => { export default defineConfig((env) => {
const forgeEnv = env as ConfigEnv<'build'>; const forgeEnv = env as ConfigEnv<'build'>
const { forgeConfigSelf } = forgeEnv; const { forgeConfigSelf } = forgeEnv
const define = getBuildDefine(forgeEnv); const define = getBuildDefine(forgeEnv)
const config: UserConfig = { const config: UserConfig = {
server: { server: {
open: true, open: true,
@ -74,17 +79,23 @@ export default defineConfig((env) => {
// Load the Node.js entry. // Load the Node.js entry.
mainFields: ['module', 'jsnext:main', 'jsnext'], mainFields: ['module', 'jsnext:main', 'jsnext'],
alias: { alias: {
'@kittycad/codemirror-lsp-client': '/packages/codemirror-lsp-client/src', '@kittycad/codemirror-lsp-client':
'/packages/codemirror-lsp-client/src',
}, },
}, },
plugins: [ plugins: [
pluginHotRestart('restart'), viteJsPluginReact(), viteTsconfigPaths(), vitePluginEslint(), vitePluginPackageVersion(), lezer() pluginHotRestart('restart'),
viteJsPluginReact(),
viteTsconfigPaths(),
vitePluginEslint(),
vitePluginPackageVersion(),
lezer(),
], ],
worker: { worker: {
plugins: () => [viteTsconfigPaths()], plugins: () => [viteTsconfigPaths()],
}, },
define, define,
}; }
return mergeConfig(getBuildConfig(forgeEnv), config); return mergeConfig(getBuildConfig(forgeEnv), config)
}); })

View File

@ -1,11 +1,11 @@
import type { ConfigEnv, UserConfig } from 'vite'; import type { ConfigEnv, UserConfig } from 'vite'
import { defineConfig, mergeConfig } from 'vite'; import { defineConfig, mergeConfig } from 'vite'
import { getBuildConfig, external, pluginHotRestart } from './vite.base.config'; import { getBuildConfig, external, pluginHotRestart } from './vite.base.config'
// https://vitejs.dev/config // https://vitejs.dev/config
export default defineConfig((env) => { export default defineConfig((env) => {
const forgeEnv = env as ConfigEnv<'build'>; const forgeEnv = env as ConfigEnv<'build'>
const { forgeConfigSelf } = forgeEnv; const { forgeConfigSelf } = forgeEnv
const config: UserConfig = { const config: UserConfig = {
build: { build: {
rollupOptions: { rollupOptions: {
@ -23,7 +23,7 @@ export default defineConfig((env) => {
}, },
}, },
plugins: [pluginHotRestart('reload')], plugins: [pluginHotRestart('reload')],
}; }
return mergeConfig(getBuildConfig(forgeEnv), config); return mergeConfig(getBuildConfig(forgeEnv), config)
}); })

View File

@ -1,12 +1,15 @@
import type { ConfigEnv, UserConfig } from 'vite'; import type { ConfigEnv, UserConfig } from 'vite'
import { defineConfig } from 'vite'; import { defineConfig } from 'vite'
import { pluginExposeRenderer } from './vite.base.config'; import { pluginExposeRenderer } from './vite.base.config'
import viteTsconfigPaths from 'vite-tsconfig-paths'
// @ts-ignore: No types available
import { lezer } from '@lezer/generator/rollup'
// https://vitejs.dev/config // https://vitejs.dev/config
export default defineConfig((env) => { export default defineConfig((env) => {
const forgeEnv = env as ConfigEnv<'renderer'>; const forgeEnv = env as ConfigEnv<'renderer'>
const { root, mode, forgeConfigSelf } = forgeEnv; const { root, mode, forgeConfigSelf } = forgeEnv
const name = forgeConfigSelf.name ?? ''; const name = forgeConfigSelf.name ?? ''
return { return {
root, root,
@ -15,10 +18,14 @@ export default defineConfig((env) => {
build: { build: {
outDir: `.vite/renderer/${name}`, outDir: `.vite/renderer/${name}`,
}, },
plugins: [pluginExposeRenderer(name)], plugins: [pluginExposeRenderer(name), viteTsconfigPaths(), lezer()],
resolve: { resolve: {
preserveSymlinks: true, preserveSymlinks: true,
alias: {
'@kittycad/codemirror-lsp-client':
'/packages/codemirror-lsp-client/src',
},
}, },
clearScreen: false, clearScreen: false,
} as UserConfig; } as UserConfig
}); })