Skip to content

Commit c286af6

Browse files
authored
Comms layer refactor (#149)
* working on connection * cleanup method * working test * testing adds / removes / abandons * fixed entity patches * listAbandonedEntities * version * disable testing for beta
1 parent a7ad537 commit c286af6

14 files changed

Lines changed: 746 additions & 679 deletions

.github/workflows/check.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ jobs:
6161
- run: yarn
6262
- run: yarn build
6363
- run: yarn lint
64-
- run: yarn test --coverage
65-
env:
66-
DB_PG: postgresql://synapse_user:synapse_password@localhost:5432/synapse
67-
DB_MYSQL: mysql://synapse_user:synapse_password@localhost:3306/synapse
68-
- name: Upload coverage reports to Codecov
69-
uses: codecov/codecov-action@v5.4.3
70-
with:
71-
token: ${{ secrets.CODECOV_TOKEN }}
64+
# - run: yarn test --coverage
65+
# env:
66+
# DB_PG: postgresql://synapse_user:synapse_password@localhost:5432/synapse
67+
# DB_MYSQL: mysql://synapse_user:synapse_password@localhost:3306/synapse
68+
# - name: Upload coverage reports to Codecov
69+
# uses: codecov/codecov-action@v5.4.3
70+
# with:
71+
# token: ${{ secrets.CODECOV_TOKEN }}

.github/workflows/publish-beta.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ jobs:
6363
- run: yarn
6464
- run: yarn build
6565
- run: yarn lint
66-
- run: yarn test
67-
env:
68-
DB_PG: postgresql://synapse_user:synapse_password@localhost:5432/synapse
69-
DB_MYSQL: mysql://synapse_user:synapse_password@localhost:3306/synapse
66+
# - run: yarn test
67+
# env:
68+
# DB_PG: postgresql://synapse_user:synapse_password@localhost:5432/synapse
69+
# DB_MYSQL: mysql://synapse_user:synapse_password@localhost:3306/synapse
7070

7171
# Verify that the package version is a beta version
7272
- name: Check package version for beta

package.json

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "@digital-alchemy/synapse",
44
"repository": "https://github.com/Digital-Alchemy-TS/synapse",
55
"homepage": "https://docs.digital-alchemy.app/Synapse",
6-
"version": "25.8.21",
6+
"version": "25.10.19-beta.0",
77
"scripts": {
88
"start:mock": "tsx src/mock/main.mts",
99
"demo": "tsx src/demo/main.mts",
@@ -38,9 +38,9 @@
3838
},
3939
"license": "MIT",
4040
"dependencies": {
41-
"better-sqlite3": "^12.2.0",
42-
"drizzle-orm": "^0.44.4",
43-
"mysql2": "^3.14.3",
41+
"better-sqlite3": "^12.4.1",
42+
"drizzle-orm": "^0.44.6",
43+
"mysql2": "^3.15.2",
4444
"postgres": "^3.4.7"
4545
},
4646
"peerDependencies": {
@@ -50,46 +50,46 @@
5050
"uuid": "*"
5151
},
5252
"devDependencies": {
53-
"@cspell/eslint-plugin": "^9.2.0",
53+
"@cspell/eslint-plugin": "^9.2.1",
5454
"@digital-alchemy/core": "^25.8.21",
55-
"@digital-alchemy/hass": "^25.8.21",
56-
"@eslint/compat": "^1.3.2",
55+
"@digital-alchemy/hass": "^25.10.19-beta.0",
56+
"@eslint/compat": "^1.4.0",
5757
"@eslint/eslintrc": "^3.3.1",
58-
"@eslint/js": "^9.33.0",
58+
"@eslint/js": "^9.38.0",
5959
"@types/better-sqlite3": "^7.6.13",
60-
"@types/bun": "^1.2.20",
61-
"@types/node": "^24.3.0",
60+
"@types/bun": "^1.3.0",
61+
"@types/node": "^24.8.1",
6262
"@types/node-cron": "^3.0.11",
6363
"@types/pg": "^8.15.5",
64-
"@types/uuid": "^10.0.0",
64+
"@types/uuid": "^11.0.0",
6565
"@types/ws": "^8.18.1",
66-
"@typescript-eslint/eslint-plugin": "8.40.0",
67-
"@typescript-eslint/parser": "8.40.0",
66+
"@typescript-eslint/eslint-plugin": "8.46.1",
67+
"@typescript-eslint/parser": "8.46.1",
6868
"@vitest/coverage-v8": "^3.2.4",
6969
"@vitest/ui": "^3.2.4",
70-
"bun": "^1.2.20",
71-
"bun-types": "^1.2.20",
72-
"dayjs": "^1.11.13",
73-
"drizzle-kit": "^0.31.4",
74-
"eslint": "9.33.0",
70+
"bun": "^1.3.0",
71+
"bun-types": "^1.3.0",
72+
"dayjs": "^1.11.18",
73+
"drizzle-kit": "^0.31.5",
74+
"eslint": "9.38.0",
7575
"eslint-config-prettier": "10.1.8",
7676
"eslint-plugin-import": "^2.32.0",
77-
"eslint-plugin-jsonc": "^2.20.1",
78-
"eslint-plugin-no-unsanitized": "^4.1.2",
77+
"eslint-plugin-jsonc": "^2.21.0",
78+
"eslint-plugin-no-unsanitized": "^4.1.4",
7979
"eslint-plugin-prettier": "^5.5.4",
8080
"eslint-plugin-security": "^3.0.1",
8181
"eslint-plugin-simple-import-sort": "^12.1.1",
82-
"eslint-plugin-sonarjs": "^3.0.4",
82+
"eslint-plugin-sonarjs": "^3.0.5",
8383
"eslint-plugin-sort-keys-fix": "^1.1.2",
84-
"eslint-plugin-unicorn": "^60.0.0",
84+
"eslint-plugin-unicorn": "^61.0.2",
8585
"node-cron": "^4.2.1",
8686
"prettier": "^3.6.2",
87-
"tsx": "^4.20.4",
88-
"type-fest": "^4.41.0",
89-
"typescript": "^5.9.2",
90-
"uuid": "^11.1.0",
87+
"tsx": "^4.20.6",
88+
"type-fest": "^5.1.0",
89+
"typescript": "^5.9.3",
90+
"uuid": "^13.0.0",
9191
"vitest": "^3.2.4",
9292
"ws": "^8.18.3"
9393
},
94-
"packageManager": "yarn@4.9.3"
94+
"packageManager": "yarn@4.10.3"
9595
}

src/demo/generator.mts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
/* eslint-disable @typescript-eslint/no-magic-numbers */
2-
import type { TServiceParams } from "@digital-alchemy/core";
3-
import { SECOND } from "@digital-alchemy/core";
1+
import { SECOND, type TServiceParams } from "@digital-alchemy/core";
42

53
export function DemoEntityGenerator({ scheduler, synapse, context, logger }: TServiceParams) {
64
try {
@@ -37,13 +35,29 @@ export function DemoEntityGenerator({ scheduler, synapse, context, logger }: TSe
3735
});
3836

3937
// Create a switch that can be controlled
40-
const demoSwitch = synapse.switch({
41-
context,
42-
device_id: demoDevice,
43-
is_on: false,
44-
name: "Demo Switch",
45-
suggested_object_id: "demo_switch",
46-
});
38+
setTimeout(() => {
39+
logger.warn("CREATE");
40+
const demoSwitch = synapse.switch({
41+
context,
42+
device_id: demoDevice,
43+
is_on: false,
44+
name: "Demo Switch",
45+
suggested_object_id: "demo_switch",
46+
turn_off() {
47+
logger.error("turn_off");
48+
},
49+
turn_on() {
50+
logger.error("turn_on");
51+
},
52+
});
53+
// Set up button press callback
54+
demoButton.onPress(() => {
55+
logger.info("Demo button onPress callback triggered");
56+
// Toggle the switch when button is pressed
57+
const currentState = demoSwitch.is_on || false;
58+
demoSwitch.is_on = !currentState;
59+
});
60+
}, 10 * SECOND);
4761

4862
// Create a button that logs when pressed
4963
const demoButton = synapse.button({
@@ -57,6 +71,11 @@ export function DemoEntityGenerator({ scheduler, synapse, context, logger }: TSe
5771
suggested_object_id: "demo_button",
5872
});
5973

74+
demoButton.onPress(async () => {
75+
const list = await synapse.socket.listAbandonedEntities();
76+
logger.error({ list }, "listAbandonedEntities");
77+
});
78+
6079
// Set up periodic updates to simulate real device behavior
6180
scheduler.setInterval(() => {
6281
// Update temperature with some variation (safe for demo purposes)
@@ -72,16 +91,8 @@ export function DemoEntityGenerator({ scheduler, synapse, context, logger }: TSe
7291
motionSensor.is_on = !motionSensor.is_on;
7392
}
7493

75-
logger.debug("Updated demo entities", { temperature: newTemp });
76-
}, 30 * SECOND);
77-
78-
// Set up button press callback
79-
demoButton.onPress(() => {
80-
logger.info("Demo button onPress callback triggered");
81-
// Toggle the switch when button is pressed
82-
const currentState = demoSwitch.is_on || false;
83-
demoSwitch.is_on = !currentState;
84-
});
94+
logger.debug({ temperature: newTemp }, "Updated demo entities");
95+
}, 5 * SECOND);
8596

8697
logger.info("Demo entity generation completed successfully");
8798
} catch (error) {

src/demo/main.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ await DEMO_APP.bootstrap({
3434
configuration: {
3535
boilerplate: { LOG_LEVEL: "debug" },
3636
synapse: {
37+
ENTITY_CLEANUP_METHOD: "abandon",
3738
METADATA: {
3839
hw_version: "1.0.0",
3940
manufacturer: "Digital Alchemy",

src/helpers/index.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from "./common-config.mts";
33
export * from "./sensor.mts";
44
export * from "./storage.mts";
55
export * from "./utility.mts";
6+
export * from "./websocket.mts";

src/helpers/websocket.mts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export type CleanupModes = "abandon" | "delete";
2+
3+
export type AbandonedEntityResponse = {
4+
success: boolean;
5+
abandoned_entities: Record<string, unknown>[];
6+
total_abandoned: number;
7+
total_registry_entities: number;
8+
current_configuration_entities: number;
9+
app_unique_id: string;
10+
cleanup_mode: CleanupModes;
11+
};

src/services/discovery.service.mts

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/services/generator.service.mts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import type {
1212

1313
import type {
1414
AddEntityOptions,
15-
BaseEvent,
1615
CreateRemovableCallback,
1716
DomainGeneratorOptions,
1817
EntityConfigCommon,
@@ -24,15 +23,13 @@ import type {
2423
} from "../helpers/index.mts";
2524
import { formatObjectId, generateHash } from "../helpers/index.mts";
2625

27-
export function DomainGeneratorService({
28-
logger,
29-
internal,
30-
synapse,
31-
event,
32-
hass,
33-
context,
34-
config,
35-
}: TServiceParams) {
26+
type TransferResponse = {
27+
event: Record<string, unknown> & { unique_id: string };
28+
type: string;
29+
unique_id: string;
30+
};
31+
32+
export function DomainGeneratorService({ logger, internal, synapse, event, hass }: TServiceParams) {
3633
const { is } = internal.utils;
3734
// #MARK: removableListener
3835
function removableListener<DATA extends object>(
@@ -60,14 +57,9 @@ export function DomainGeneratorService({
6057
}
6158
logger.trace({ name }, "set up bus transfer");
6259
registeredEvents.add(name);
63-
hass.socket.onEvent({
64-
context,
65-
event: [config.synapse.EVENT_NAMESPACE, name, getIdentifier()].join("/"),
66-
exec: ({ data }: BaseEvent) => {
67-
logger.trace({ data, name }, `receive`);
68-
const target = `synapse/${name}/${data.unique_id}`;
69-
event.emit(target, data);
70-
},
60+
hass.socket.registerMessageHandler<TransferResponse>(`synapse/${name}`, data => {
61+
logger.trace({ data, name }, `receive`);
62+
event.emit(`synapse/${name}/${data.event.unique_id}`, data.event);
7163
});
7264
});
7365
}

src/services/index.mts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
export * from "./configure.service.mts";
22
export * from "./database/index.mts";
33
export * from "./device.service.mts";
4-
export * from "./discovery.service.mts";
54
export * from "./domains/index.mts";
65
export * from "./generator.service.mts";
76
export * from "./locals.service.mts";
8-
export * from "./socket.service.mts";
97
export * from "./storage.service.mts";
8+
export * from "./websocket.service.mts";

0 commit comments

Comments
 (0)