Skip to content

Commit

Permalink
Merge pull request #72 from AllenShintani/master
Browse files Browse the repository at this point in the history
Correspond with decralative UI
  • Loading branch information
yoshihikko-kodaira authored Feb 27, 2024
2 parents 486ab0b + 6fbe5eb commit 3ec760d
Show file tree
Hide file tree
Showing 95 changed files with 1,783 additions and 467 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
'plugin:react-hooks/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:react-hooks/recommended',
],
plugins: ['@typescript-eslint'],
parser: '@typescript-eslint/parser',
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<p align="center">

<img width="300px" src="/public/images/icon.png" alt="なんかいい感じの画像">
<img width="300px" src="/public/images/icon.png" alt="Something nice img">

</p>

Expand Down
39 changes: 28 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
{
"dependencies": {
"@types/microtime": "^2.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"@types/stack-utils": "^2.0.3",
"ansi-escapes": "^6.2.0",
"auto-bind": "^5.0.1",
"cli-cursor": "^4.0.0",
"code-excerpt": "^4.0.0",
"is-in-ci": "^0.1.0",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"serialport": "^12.0.0",
"stack-utils": "^2.0.6",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
"typescript": "^5.2.2",
"yoga": "^0.0.20",
"yoga-wasm-web": "^0.3.3"
},
"devDependencies": {
"@types/ansi-escapes": "^4.0.0",
"@types/auto-bind": "^2.1.0",
"@types/lodash": "^4.14.202",
"@types/node": "^20.8.8",
"@types/react": "^18.2.52",
"@types/react-dom": "^18.2.18",
"@types/serialport": "^8.0.3",
"@typescript-eslint/eslint-plugin": "^6.18.1",
"@vitejs/plugin-react": "^4.2.1",
Expand All @@ -21,18 +29,27 @@
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"is-in-ci": "^0.1.0",
"patch-console": "^2.0.0",
"prettier": "^3.0.3",
"signal-exit": "^4.1.0",
"vite": "^5.1.1",
"vite-node": "^1.2.2",
"vite-plugin-checker": "^0.6.2",
"vitest": "^0.34.6"
},
"peerDependencies": {
"@types/react": "^18.2.55",
"@types/react-reconciler": "^0.28.8",
"react": "^18.2.0",
"react-reconciler": "^0.29.0"
},
"name": "edison",
"type": "module",
"version": "0.1.33",
"version": "0.1.34",
"exports": {
".": {
"import": "./dist/esm/index.mjs",
"import": "./dist/esm/index.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json",
Expand All @@ -53,7 +70,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/AllenShintani/Edison.git"
"url": "git+https://github.com/edison-js/Edison.git"
},
"keywords": [
"IoT",
Expand All @@ -68,7 +85,7 @@
"author": "aluta",
"license": "MIT",
"bugs": {
"url": "https://github.com/AllenShintani/Edison/issues"
"url": "https://github.com/edison-js/Edison/issues"
},
"homepage": "https://github.com/AllenShintani/Edison#readme"
"homepage": "https://github.com/edison-js/Edison#readme"
}
40 changes: 28 additions & 12 deletions rename-to-esm.mjs
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
// rename-to-esm.mjs
// rename-and-fix-imports.mjs
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { readdirSync, renameSync } from 'fs';
import { readFileSync, writeFileSync } from 'fs';
import { promisify } from 'util';
import glob from 'glob';

const globPromise = promisify(glob);

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

//
const renameJsToMjs = (dir) => {
const items = readdirSync(dir);
for (const item of items) {
const currentPath = join(dir, item);
if (item.endsWith('.js')) {
renameSync(currentPath, currentPath.replace('.js', '.mjs'));
// Import文のパスを修正する関数
const fixImportPaths = async (file) => {
let content = readFileSync(file, 'utf8');
// 正規表現で、'./' または '../'で始まるパスのimport文を対象にし、'.js'がない場合は追加
content = content.replace(/(from\s+['"])(\.\/|\.\.\/)([^'"]+?)['"]/g, (match, p1, p2, p3) => {
// '.js'で終わっていないパスに'.js'を追加
if (!p3.endsWith('.js')) {
return `${p1}${p2}${p3}.js'`;
}
}
return match;
});
writeFileSync(file, content, 'utf8');
};

// 特定のディレクトリ内のすべての.jsファイルを走査し、import文のパスを修正
const fixImportsInDirectory = async (directory) => {
const files = await globPromise(`${directory}/**/*.js`); // ディレクトリ内の全ての.jsファイルを取得
// biome-ignore lint/complexity/noForEach: <explanation>
files.forEach(file => {
fixImportPaths(file);
});
};

//
renameJsToMjs(join(__dirname, 'dist', 'esm'));
// 実行するディレクトリを指定
fixImportsInDirectory(join(__dirname, 'dist'));
6 changes: 3 additions & 3 deletions src/__tests__/utils/board.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
// import { board } from '../../utils/board'
// import { findArduinoPath } from '../../utils/findArduinoPath'

// // SerialPort と findArduinoPath のモック
// // SerialPort と findArduinoPath
// vi.mock('serialport', () => ({
// SerialPort: vi.fn().mockImplementation(() => ({
// on: vi.fn((event, callback) => {
// if (event === 'data') {
// // 'data' イベントのモック処理
// // 'data'
// setTimeout(() => callback('some data'), 0)
// }
// }),
// // 他の必要なメソッドもモック化
//
// })),
// }))

Expand Down
18 changes: 0 additions & 18 deletions src/declarative/App.tsx

This file was deleted.

23 changes: 23 additions & 0 deletions src/declarative/components/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react'
import AppContext from './AppContext'

type Props = {
readonly children: React.ReactNode
readonly stdin: NodeJS.ReadStream
readonly stdout: NodeJS.WriteStream
readonly stderr: NodeJS.WriteStream
readonly exitOnCtrlC: boolean
readonly onExit: (error?: Error) => void
}

const App = ({ children, onExit }: Props) => {
const contextValue = {
exit: onExit,
}

return (
<AppContext.Provider value={contextValue}>{children}</AppContext.Provider>
)
}

export default App
19 changes: 19 additions & 0 deletions src/declarative/components/AppContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { createContext } from 'react'

export type Props = {
/**
* Exit (unmount) the whole Edison app.
*/
readonly exit: (error?: Error) => void
}

/**
* `AppContext` is a React context, which exposes a method to manually exit the app (unmount).
*/
const AppContext = createContext<Props>({
exit() {},
})

AppContext.displayName = 'InternalAppContext'

export default AppContext
13 changes: 13 additions & 0 deletions src/declarative/components/Box.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React, { forwardRef, type PropsWithChildren } from 'react'
import { type DOMElement } from '../rendere/dom'

/**
* `<Box>` is an essential Edison component to build. It's like `<div style="display: flex">` in the browser.
*/
const Box = forwardRef<DOMElement, PropsWithChildren>(({ children }, ref) => {
return <edison-box ref={ref}>{children}</edison-box>
})

Box.displayName = 'Box'

export default Box
107 changes: 107 additions & 0 deletions src/declarative/components/ErrorOverview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import * as fs from 'node:fs'
import { cwd } from 'node:process'
import React from 'react'
import StackUtils from 'stack-utils'
import codeExcerpt, { type CodeExcerpt } from 'code-excerpt'
import Box from './Box'
import Text from './Text'

// Error's source file is reported as file:///home/user/file.js
// This function removes the file://[cwd] part
const cleanupPath = (path: string | undefined): string | undefined => {
return path?.replace(`file://${cwd()}/`, '')
}

const stackUtils = new StackUtils({
cwd: cwd(),
internals: StackUtils.nodeInternals(),
})

type Props = {
readonly error: Error
}

export default function ErrorOverview({ error }: Props) {
const stack = error.stack ? error.stack.split('\n').slice(1) : undefined
// biome-ignore lint/style/noNonNullAssertion: <explanation>
const origin = stack ? stackUtils.parseLine(stack[0]!) : undefined
const filePath = cleanupPath(origin?.file)
let excerpt: CodeExcerpt[] | undefined
let lineWidth = 0

if (filePath && origin?.line && fs.existsSync(filePath)) {
const sourceCode = fs.readFileSync(filePath, 'utf8')
excerpt = codeExcerpt(sourceCode, origin.line)

if (excerpt) {
for (const { line } of excerpt) {
lineWidth = Math.max(lineWidth, String(line).length)
}
}
}

return (
<Box>
<Box>
<Text> ERROR </Text>

<Text> {error.message}</Text>
</Box>

{origin && filePath && (
<Box>
<Text>
{filePath}:{origin.line}:{origin.column}
</Text>
</Box>
)}

{origin && excerpt && (
<Box>
{excerpt.map(({ line, value }) => (
<Box key={line}>
<Box>
<Text>{String(line).padStart(lineWidth, ' ')}:</Text>
</Box>

<Text>{` ${value}`}</Text>
</Box>
))}
</Box>
)}

{error.stack && (
<Box>
{error.stack
.split('\n')
.slice(1)
.map((line) => {
const parsedLine = stackUtils.parseLine(line)

// If the line from the stack cannot be parsed, we print out the unparsed line.
if (!parsedLine) {
return (
<Box key={line}>
<Text>- </Text>
<Text>{line}</Text>
</Box>
)
}

return (
<Box key={line}>
<Text>- </Text>
<Text>{parsedLine.function}</Text>
<Text>
{' '}
({cleanupPath(parsedLine.file) ?? ''}:{parsedLine.line}:
{parsedLine.column})
</Text>
</Box>
)
})}
</Box>
)}
</Box>
)
}
Loading

0 comments on commit 3ec760d

Please sign in to comment.