Skip to content

Commit cf97753

Browse files
committed
initial commit
0 parents  commit cf97753

16 files changed

+5590
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules/

package-lock.json

+5,293
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "home-lit",
3+
"version": "1.0.0",
4+
"description": "A TypeScript library integrating Homie devices with DOM element attributes for visualization",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"start": "webpack serve --mode development",
9+
"build": "webpack --mode production",
10+
"test": "echo \"Error: no test specified\" && exit 1"
11+
},
12+
"keywords": ["homie", "lit-html", "typescript", "iot"],
13+
"author": "",
14+
"license": "ISC",
15+
"devDependencies": {
16+
"typescript": "^4.5.4",
17+
"webpack": "^5.65.0",
18+
"webpack-cli": "^4.9.1",
19+
"webpack-dev-server": "^4.7.2",
20+
"ts-loader": "^9.2.6",
21+
"html-webpack-plugin": "^5.5.0",
22+
"@types/node": "^16.11.12",
23+
"@types/aframe": "^1.2.2"
24+
},
25+
"dependencies": {
26+
"aframe": "^1.3.0",
27+
"lit": "^2.6.1"
28+
}
29+
}

src/CoralBranch.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { HomieNode } from './HomieNode';
2+
import { HomieProperty } from './HomieProperty';
3+
4+
export class CoralBranch extends HomieNode {
5+
constructor(name: string) {
6+
super(name);
7+
this.addProperty(new HomieProperty('color', 'pink'));
8+
this.addProperty(new HomieProperty('length', 10));
9+
}
10+
11+
// Add coral branch specific methods here
12+
}

src/CoralReef.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { HomieDevice } from './HomieDevice';
2+
import { CoralBranch } from './CoralBranch';
3+
4+
export class CoralReef extends HomieDevice {
5+
constructor(name: string) {
6+
super(name);
7+
this.addNode(new CoralBranch('branch1'));
8+
this.addNode(new CoralBranch('branch2'));
9+
}
10+
11+
// Add coral reef specific methods here
12+
}

src/HomieDevice.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { HomieNode } from './HomieNode';
2+
3+
export class HomieDevice {
4+
private nodes: Map<string, HomieNode> = new Map();
5+
6+
constructor(public name: string) {}
7+
8+
addNode(node: HomieNode) {
9+
this.nodes.set(node.name, node);
10+
}
11+
12+
getNode(name: string): HomieNode | undefined {
13+
return this.nodes.get(name);
14+
}
15+
16+
getAllNodes(): HomieNode[] {
17+
return Array.from(this.nodes.values());
18+
}
19+
}

src/HomieDeviceElement.ts

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { LitElement, html, css } from 'lit';
2+
import { customElement, property } from 'lit/decorators.js';
3+
import { HomieDevice } from './HomieDevice';
4+
import './HomieNodeComponent';
5+
6+
@customElement('homie-device')
7+
export class HomieDeviceElement extends LitElement {
8+
static styles = css`
9+
:host {
10+
display: block;
11+
padding: 16px;
12+
max-width: 800px;
13+
margin: 0 auto;
14+
}
15+
`;
16+
17+
@property({ type: Object })
18+
device!: HomieDevice;
19+
20+
render() {
21+
return html`
22+
<div class="homie-device">
23+
<h1>${this.device.name}</h1>
24+
${this.device.getAllNodes().map(node => html`
25+
<homie-node .node=${node}></homie-node>
26+
`)}
27+
</div>
28+
`;
29+
}
30+
}

src/HomieNode.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { HomieProperty } from './HomieProperty';
2+
3+
export class HomieNode {
4+
private properties: Map<string, HomieProperty> = new Map();
5+
6+
constructor(public name: string) {}
7+
8+
addProperty(property: HomieProperty) {
9+
this.properties.set(property.name, property);
10+
}
11+
12+
getProperty(name: string): HomieProperty | undefined {
13+
return this.properties.get(name);
14+
}
15+
16+
getAllProperties(): HomieProperty[] {
17+
return Array.from(this.properties.values());
18+
}
19+
}

src/HomieNodeComponent.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { html, render } from 'lit';
2+
import { HomieNode } from './HomieNode';
3+
import { PropertyBindingManager } from './PropertyBindingManager';
4+
5+
export class HomieNodeComponent extends HTMLElement {
6+
private node: HomieNode;
7+
private bindingManager: PropertyBindingManager;
8+
9+
constructor(node: HomieNode) {
10+
super();
11+
this.node = node;
12+
this.bindingManager = new PropertyBindingManager();
13+
}
14+
15+
connectedCallback() {
16+
this.render();
17+
}
18+
19+
render() {
20+
const template = html`
21+
<div class="homie-node">
22+
<h2>${this.node.name}</h2>
23+
${this.node.getAllProperties().map(prop => html`
24+
<div class="property">
25+
<span>${prop.name}: </span>
26+
<span>${prop.getValue()}</span>
27+
</div>
28+
`)}
29+
</div>
30+
`;
31+
render(template, this);
32+
33+
// Bind properties to attributes
34+
this.node.getAllProperties().forEach(prop => {
35+
const element = this.querySelector(`.property:has(span:contains('${prop.name}'))`);
36+
if (element instanceof HTMLElement) {
37+
this.bindingManager.bindProperty(prop, element, 'data-value');
38+
}
39+
});
40+
}
41+
}
42+
43+
customElements.define('homie-node', HomieNodeComponent);

src/HomieProperty.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export class HomieProperty {
2+
constructor(public name: string, public value: any) {}
3+
4+
setValue(newValue: any) {
5+
this.value = newValue;
6+
// TODO: Implement update logic and event emission
7+
}
8+
9+
getValue(): any {
10+
return this.value;
11+
}
12+
}

src/PlayerAvatar.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { HomieNode } from './HomieNode';
2+
import { HomieProperty } from './HomieProperty';
3+
4+
export class PlayerAvatar extends HomieNode {
5+
constructor(name: string) {
6+
super(name);
7+
this.addProperty(new HomieProperty('position', { x: 0, y: 0, z: 0 }));
8+
this.addProperty(new HomieProperty('rotation', { x: 0, y: 0, z: 0 }));
9+
}
10+
11+
// Add player avatar specific methods here
12+
}

src/PropertyBindingManager.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { HomieProperty } from './HomieProperty';
2+
3+
export class PropertyBindingManager {
4+
private bindings: Map<string, HTMLElement> = new Map();
5+
6+
bindProperty(property: HomieProperty, element: HTMLElement, attribute: string) {
7+
const key = `${property.name}-${attribute}`;
8+
this.bindings.set(key, element);
9+
this.updateElement(property, element, attribute);
10+
11+
// TODO: Implement property change listener
12+
}
13+
14+
private updateElement(property: HomieProperty, element: HTMLElement, attribute: string) {
15+
element.setAttribute(attribute, property.getValue().toString());
16+
}
17+
}

src/index.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Home-Lit Demo</title>
7+
</head>
8+
<body>
9+
<div id="app"></div>
10+
<script type="module">
11+
import { CoralReef, HomieDeviceElement } from './index.ts';
12+
13+
const coralReef = new CoralReef('My Coral Reef');
14+
const deviceElement = new HomieDeviceElement(coralReef);
15+
16+
document.getElementById('app').appendChild(deviceElement);
17+
</script>
18+
</body>
19+
</html>

src/index.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Core Homie classes
2+
export { HomieProperty } from './HomieProperty';
3+
export { HomieNode } from './HomieNode';
4+
export { HomieDevice } from './HomieDevice';
5+
6+
// DOM integration
7+
export { PropertyBindingManager } from './PropertyBindingManager';
8+
export { HomieNodeComponent } from './HomieNodeComponent';
9+
export { HomieDeviceElement } from './HomieDeviceElement';
10+
11+
// Example classes
12+
export { CoralBranch } from './CoralBranch';
13+
export { PlayerAvatar } from './PlayerAvatar';
14+
export { CoralReef } from './CoralReef';

tsconfig.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2017",
4+
"module": "ESNext",
5+
"lib": ["es2017", "dom"],
6+
"declaration": true,
7+
"outDir": "./dist",
8+
"strict": true,
9+
"moduleResolution": "node",
10+
"esModuleInterop": true,
11+
"experimentalDecorators": true,
12+
"emitDecoratorMetadata": true,
13+
"sourceMap": true,
14+
"baseUrl": ".",
15+
"paths": {
16+
"*": ["node_modules/*", "src/types/*"]
17+
},
18+
"useDefineForClassFields": false,
19+
"allowSyntheticDefaultImports": true,
20+
"resolveJsonModule": true,
21+
"skipLibCheck": true,
22+
"types": ["aframe"]
23+
},
24+
"include": ["src/**/*"],
25+
"exclude": ["node_modules", "dist"]
26+
}

webpack.config.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const path = require('path');
2+
const HtmlWebpackPlugin = require('html-webpack-plugin');
3+
4+
module.exports = {
5+
entry: './src/index.ts',
6+
module: {
7+
rules: [
8+
{
9+
test: /\.tsx?$/,
10+
use: 'ts-loader',
11+
exclude: /node_modules/,
12+
},
13+
],
14+
},
15+
resolve: {
16+
extensions: ['.tsx', '.ts', '.js'],
17+
},
18+
output: {
19+
filename: 'bundle.js',
20+
path: path.resolve(__dirname, 'dist'),
21+
},
22+
plugins: [
23+
new HtmlWebpackPlugin({
24+
template: 'src/index.html',
25+
}),
26+
],
27+
devServer: {
28+
static: path.join(__dirname, 'dist'),
29+
compress: true,
30+
port: 9000,
31+
},
32+
};

0 commit comments

Comments
 (0)