Skip to content

Commit 22f3ea2

Browse files
committed
Initial files
1 parent b75651d commit 22f3ea2

File tree

116 files changed

+10388
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+10388
-0
lines changed

.eslintrc.cjs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:react-hooks/recommended',
8+
],
9+
ignorePatterns: ['dist', '.eslintrc.cjs'],
10+
parser: '@typescript-eslint/parser',
11+
plugins: ['react-refresh'],
12+
rules: {
13+
'react-refresh/only-export-components': [
14+
'warn',
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
}

.gitignore

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
docs/api
2+
3+
# Logs
4+
logs
5+
*.log
6+
npm-debug.log*
7+
yarn-debug.log*
8+
yarn-error.log*
9+
pnpm-debug.log*
10+
lerna-debug.log*
11+
12+
node_modules
13+
dist
14+
dist-ssr
15+
*.local
16+
coverage
17+
18+
# Editor directories and files
19+
.vscode/*
20+
!.vscode/extensions.json
21+
.idea
22+
.DS_Store
23+
*.suo
24+
*.ntvs*
25+
*.njsproj
26+
*.sln
27+
*.sw?

README.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
2+
![image](docs/images/extend-me.png)
3+
4+
5+
... is a framework and library that is used to create extensible and scalable
6+
TypeScript/JavaScript applications.
7+
8+
At its core ExtendMe! provides the means for a host application to dynamically
9+
import JavaScript modules - extensions - that add new features and capabilities
10+
to the application.
11+
12+
An extension comprises a `package.json` and optionally some JavaScript code. The
13+
JavaScript code may export an extension-specific API that other, dependent
14+
extensions may consume.
15+
16+
Both the host application and an extension can also define contribution points.
17+
Extensions provide contributions to one or more contribution points and the host
18+
application or host extension can consume them. Contributions are encoded in
19+
the `contributes` object of an extension's `package.json`. A contribution may be
20+
either fully specified by the JSON data in the `contributes` object, or it may
21+
require also JavaScript to be loaded and executed. Examples are commands and UI
22+
components. Such code contributions are loaded lazily: Only the first time a
23+
code contribution is needed by a consumer, the contributing extension will be
24+
loaded and activated.
25+
26+
`ExtendMe!` provides some
27+
useful [React hooks](https://react.dev/reference/react) for developing user
28+
interfaces. However, the library can be used independently of React. React is a
29+
peer dependency.
30+
31+
The core API of `ExtendMe!` has been largely inspired by the
32+
[Extension API](https://code.visualstudio.com/api)
33+
of [Visual Studio Code](https://code.visualstudio.com/).
34+
35+
`ExtendMe!` currently depends on the two awesome libraries
36+
37+
* [zustand](https://github.com/pmndrs/zustand) for state management, and
38+
* [Ajv](https://ajv.js.org/) for JSON validation.
39+
40+
`ExtendMe!` is small: `extend-me.js` 34 kB │ gzip: 10 kB.
41+
42+
## React + TypeScript + Vite
43+
44+
This template provides a minimal setup to get React working in Vite with HMR and
45+
some ESLint rules.
46+
47+
Currently, two official plugins are available:
48+
49+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md)
50+
uses [Babel](https://babeljs.io/) for Fast Refresh
51+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc)
52+
uses [SWC](https://swc.rs/) for Fast Refresh
53+
54+
### Expanding the ESLint configuration
55+
56+
If you are developing a production application, we recommend updating the
57+
configuration to enable type aware lint rules:
58+
59+
- Configure the top-level `parserOptions` property like this:
60+
61+
```js
62+
parserOptions: {
63+
ecmaVersion: 'latest',
64+
sourceType
65+
:
66+
'module',
67+
project
68+
:
69+
['./tsconfig.json', './tsconfig.node.json'],
70+
tsconfigRootDir
71+
:
72+
__dirname,
73+
}
74+
,
75+
```
76+
77+
- Replace `plugin:@typescript-eslint/recommended`
78+
to `plugin:@typescript-eslint/recommended-type-checked`
79+
or `plugin:@typescript-eslint/strict-type-checked`
80+
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
81+
-
82+
83+
Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react)
84+
and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends`
85+
list

TODO.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
## TODO
2+
3+
### Design
4+
5+
* Demo: switching a few seems very slow. Fix!
6+
* Get rid of `registerAppExtension`, just use `registerExtension` with
7+
options:
8+
- `extensionPath`: url/path to dir/source containing `package.json`
9+
- `manifest` + `moduleResolver`
10+
- `module`
11+
* Get rid of globals, instead instantiate `Framework` class that
12+
contains the configuration, the store, the API, and provides hook factories.
13+
* Allow using the package without React.
14+
Move react-dependent modules into `framework/react/core`
15+
and `framework/react/contrib`
16+
* Split modules into packages:
17+
* `@extend-me/core` (incl. `util`)
18+
* `@extend-me/contrib`
19+
* Schema validation should be optional.
20+
Add framework option `validateSchema: (jsonValue) => [boolean, errors]`
21+
22+
### Before Deployment
23+
24+
* Setup CI
25+
* Add TSDoc at to all types, classes, members, methods,
26+
functions, and constants.
27+
* Add badges in README.md for test result, docs, API docs, coverage,
28+
and package.
29+
* Implement remaining unit-tests
30+
* Find out how to test React hooks using `vitest`
31+
* Enhance the demo:
32+
- Add submenus demo
33+
* Expand the ESLint configuration `.eslintrc.cjs`, see section below
34+
* Deploy package `extend-me`
35+
* Write README.md incl. a `getting started` section
36+
37+
## DONE
38+
39+
### Design
40+
41+
* Move log levels from `levels` into `LogLevel`.
42+
* Check why in the demo the app commands are not shown
43+
* Turn `react` into a peer dependency
44+
* Use global module imports with "@"
45+
* Understand how to dynamically import from any
46+
depths in the source tree. See
47+
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
48+
--> Use trailing slash.
49+
* Use Zustand's vanilla store for `framework/core`. See
50+
https://github.com/pmndrs/zustand#using-zustand-without-react
51+
--> Implemented
52+
* Logger improvements
53+
- `warnOnce()`
54+
- `log()` without level --> use logger level
55+
56+
57+
### Before Deployment
58+
59+
* Enhance the demo:
60+
- Demo command enablement
61+
- Demo menu when clauses
62+
- Add a little more CSS
63+
* Configure TypeDoc to generate an API reference.
64+
* Add TSDoc to user-facing types, classes, members, methods,
65+
functions, and constants.

docs/images/extend-me.png

14.5 KB
Loading

index.html

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" type="image/svg+xml" href="/logo64.png" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>ExtendMe! Demo</title>
8+
</head>
9+
<style>
10+
body {
11+
font-family: Segoe UI, Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
12+
line-height: 1.5;
13+
font-weight: 400;
14+
15+
color-scheme: light dark;
16+
color: rgba(255, 255, 255, 0.87);
17+
background-color: #242424;
18+
19+
font-synthesis: none;
20+
text-rendering: optimizeLegibility;
21+
-webkit-font-smoothing: antialiased;
22+
-moz-osx-font-smoothing: grayscale;
23+
}
24+
p {
25+
font-weight: normal;
26+
font-size: small;
27+
color: rgba(255, 255, 255, 0.6);
28+
}
29+
code {
30+
color: rgba(255, 255, 255, 0.9);
31+
}
32+
h1 {
33+
font-size: 1.1em;
34+
line-height: 1.1;
35+
color: rgba(200, 200, 255, 0.8);
36+
}
37+
button {
38+
border-radius: 8px;
39+
border: 1px solid rgba(255, 255, 255, 0.3);
40+
padding: 0.6em 1em;
41+
font-size: 0.8em;
42+
font-weight: 400;
43+
font-family: inherit;
44+
background-color: #1a1a1a;
45+
cursor: pointer;
46+
transition: border-color 0.25s;
47+
}
48+
button:hover {
49+
border-color: #646cff;
50+
}
51+
button:focus,
52+
button:focus-visible {
53+
outline: 4px auto -webkit-focus-ring-color;
54+
}
55+
.row2 {
56+
display: flex;
57+
gap: 10px;
58+
padding: 10px;
59+
}
60+
.row2-item {
61+
width: 40%;
62+
}
63+
.row1 {
64+
width: 80%;
65+
padding: 10px;
66+
}
67+
.button-bar {
68+
display: flex;
69+
gap: 3px;
70+
flex-wrap: wrap;
71+
}
72+
.menu {
73+
display: flex;
74+
flex-direction: column;
75+
}
76+
.menu-item {
77+
width: 100%;
78+
}
79+
.menu-separator {
80+
width: 100%;
81+
}
82+
#root {
83+
}
84+
</style>
85+
<body>
86+
<div id="root"></div>
87+
<script type="module" src="/src/demo/main.tsx"></script>
88+
</body>
89+
</html>

0 commit comments

Comments
 (0)