@yam8d/m8-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/index.js +162 -0
- package/dist/index.js.map +1 -0
- package/package.json +42 -0
- package/types/index.d.ts +115 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @yam8d/m8-sdk
|
|
2
|
+
|
|
3
|
+
Client SDK for iframe applications that communicate with an M8 host.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @yam8d/m8-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For local development before the package is published:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install ../yam8d/packages/m8-sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createM8Client } from '@yam8d/m8-sdk'
|
|
21
|
+
|
|
22
|
+
const m8 = await createM8Client()
|
|
23
|
+
|
|
24
|
+
console.log(m8.state.viewName)
|
|
25
|
+
await m8.sendKeyPress(['play'])
|
|
26
|
+
|
|
27
|
+
const unsubscribe = m8.onStateChange((state) => {
|
|
28
|
+
console.log(state.cursorPos)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
unsubscribe()
|
|
32
|
+
m8.disconnect()
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
For React or other environments where top-level `await` is not convenient:
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { createM8ClientSync } from '@yam8d/m8-sdk'
|
|
39
|
+
|
|
40
|
+
const { client, connect } = createM8ClientSync()
|
|
41
|
+
await connect()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The app must run inside the host iframe. Opening it directly in a standalone browser tab cannot establish the SDK handshake.
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { ChildHandshake as e, DebugMessenger as t, WindowMessenger as n } from "post-me";
|
|
2
|
+
//#region src/client.ts
|
|
3
|
+
var r = () => ({
|
|
4
|
+
viewName: null,
|
|
5
|
+
viewTitle: null,
|
|
6
|
+
minimapKey: null,
|
|
7
|
+
cursorPos: null,
|
|
8
|
+
cursorRect: null,
|
|
9
|
+
selectionMode: !1,
|
|
10
|
+
highlightColor: null,
|
|
11
|
+
titleColor: null,
|
|
12
|
+
backgroundColor: null,
|
|
13
|
+
textUnderCursor: null,
|
|
14
|
+
currentLine: null,
|
|
15
|
+
deviceModel: null,
|
|
16
|
+
fontMode: null,
|
|
17
|
+
systemInfo: null,
|
|
18
|
+
macroRunning: !1
|
|
19
|
+
}), i = class {
|
|
20
|
+
constructor(e = {}) {
|
|
21
|
+
this.connection = null, this.remoteHandle = null, this.localHandle = null, this.stateCallbacks = /* @__PURE__ */ new Set(), this.viewCallbacks = /* @__PURE__ */ new Set(), this.cursorCallbacks = /* @__PURE__ */ new Set(), this.textCallbacks = /* @__PURE__ */ new Set(), this.keyCallbacks = /* @__PURE__ */ new Set(), this._state = r(), this._isConnected = !1, this.config = e;
|
|
22
|
+
}
|
|
23
|
+
get state() {
|
|
24
|
+
return this._state;
|
|
25
|
+
}
|
|
26
|
+
get isConnected() {
|
|
27
|
+
return this._isConnected;
|
|
28
|
+
}
|
|
29
|
+
async connect() {
|
|
30
|
+
if (this.connection) return;
|
|
31
|
+
let r = new n({
|
|
32
|
+
localWindow: window,
|
|
33
|
+
remoteWindow: window.parent,
|
|
34
|
+
remoteOrigin: "*"
|
|
35
|
+
});
|
|
36
|
+
this.config.debug && (r = t(r, (e, ...t) => {
|
|
37
|
+
console.log("[M8 SDK]", e, ...t);
|
|
38
|
+
}));
|
|
39
|
+
let i = await e(r, { ping: async () => "pong" });
|
|
40
|
+
this.connection = i, this.remoteHandle = i.remoteHandle(), this.localHandle = i.localHandle(), this._isConnected = !0, this.remoteHandle.addEventListener("stateChanged", (e) => {
|
|
41
|
+
this._state = e, this.stateCallbacks.forEach((t) => {
|
|
42
|
+
t(e);
|
|
43
|
+
});
|
|
44
|
+
}), this.remoteHandle.addEventListener("viewChanged", ({ viewName: e, viewTitle: t }) => {
|
|
45
|
+
this._state = {
|
|
46
|
+
...this._state,
|
|
47
|
+
viewName: e,
|
|
48
|
+
viewTitle: t
|
|
49
|
+
}, this.viewCallbacks.forEach((n) => {
|
|
50
|
+
n(e, t);
|
|
51
|
+
});
|
|
52
|
+
}), this.remoteHandle.addEventListener("cursorMoved", ({ pos: e, rect: t, selectionMode: n }) => {
|
|
53
|
+
this._state = {
|
|
54
|
+
...this._state,
|
|
55
|
+
cursorPos: e,
|
|
56
|
+
cursorRect: t,
|
|
57
|
+
selectionMode: n
|
|
58
|
+
}, this.cursorCallbacks.forEach((r) => {
|
|
59
|
+
r(e, t, n);
|
|
60
|
+
});
|
|
61
|
+
}), this.remoteHandle.addEventListener("textUpdated", ({ textUnderCursor: e, currentLine: t }) => {
|
|
62
|
+
this._state = {
|
|
63
|
+
...this._state,
|
|
64
|
+
textUnderCursor: e,
|
|
65
|
+
currentLine: t
|
|
66
|
+
}, this.textCallbacks.forEach((n) => {
|
|
67
|
+
n(e, t);
|
|
68
|
+
});
|
|
69
|
+
}), this.remoteHandle.addEventListener("keyPressed", ({ keys: e }) => {
|
|
70
|
+
this.keyCallbacks.forEach((t) => {
|
|
71
|
+
t(e);
|
|
72
|
+
});
|
|
73
|
+
}), await this.fetchState(), this.localHandle.emit("ready", void 0);
|
|
74
|
+
}
|
|
75
|
+
async navigateToView(e) {
|
|
76
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
77
|
+
return this.remoteHandle.call("navigateToView", e);
|
|
78
|
+
}
|
|
79
|
+
async navigateTo(e, t) {
|
|
80
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
81
|
+
return this.remoteHandle.call("navigateTo", e, t);
|
|
82
|
+
}
|
|
83
|
+
async setValueToHex(e) {
|
|
84
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
85
|
+
return this.remoteHandle.call("setValueToHex", e);
|
|
86
|
+
}
|
|
87
|
+
async setValueToInt(e) {
|
|
88
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
89
|
+
return this.remoteHandle.call("setValueToInt", e);
|
|
90
|
+
}
|
|
91
|
+
async setNote(e) {
|
|
92
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
93
|
+
return this.remoteHandle.call("setNote", e);
|
|
94
|
+
}
|
|
95
|
+
async setValueToString(e, t = !0, n = !1) {
|
|
96
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
97
|
+
return this.remoteHandle.call("setValueToString", e, t, n);
|
|
98
|
+
}
|
|
99
|
+
async browseFile(e, t = !0) {
|
|
100
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
101
|
+
return this.remoteHandle.call("browseFile", e, t);
|
|
102
|
+
}
|
|
103
|
+
async sendKeyPress(e) {
|
|
104
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
105
|
+
return this.remoteHandle.call("sendKeyPress", e);
|
|
106
|
+
}
|
|
107
|
+
async sendKeyDown(e) {
|
|
108
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
109
|
+
return this.remoteHandle.call("sendKeyDown", e);
|
|
110
|
+
}
|
|
111
|
+
async sendKeyUp() {
|
|
112
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
113
|
+
return this.remoteHandle.call("sendKeyUp");
|
|
114
|
+
}
|
|
115
|
+
getState() {
|
|
116
|
+
return this._state;
|
|
117
|
+
}
|
|
118
|
+
async fetchState() {
|
|
119
|
+
if (!this.remoteHandle) throw Error("M8 SDK client is not connected");
|
|
120
|
+
let e = await this.remoteHandle.call("getState");
|
|
121
|
+
return this._state = e, e;
|
|
122
|
+
}
|
|
123
|
+
onStateChange(e) {
|
|
124
|
+
return this.stateCallbacks.add(e), () => this.stateCallbacks.delete(e);
|
|
125
|
+
}
|
|
126
|
+
onViewChange(e) {
|
|
127
|
+
return this.viewCallbacks.add(e), () => this.viewCallbacks.delete(e);
|
|
128
|
+
}
|
|
129
|
+
onCursorMove(e) {
|
|
130
|
+
return this.cursorCallbacks.add(e), () => this.cursorCallbacks.delete(e);
|
|
131
|
+
}
|
|
132
|
+
onTextUpdate(e) {
|
|
133
|
+
return this.textCallbacks.add(e), () => this.textCallbacks.delete(e);
|
|
134
|
+
}
|
|
135
|
+
onKeyPress(e) {
|
|
136
|
+
return this.keyCallbacks.add(e), () => this.keyCallbacks.delete(e);
|
|
137
|
+
}
|
|
138
|
+
disconnect() {
|
|
139
|
+
this.connection?.close(), this.connection = null, this.remoteHandle = null, this.localHandle = null, this._isConnected = !1, this.stateCallbacks.clear(), this.viewCallbacks.clear(), this.cursorCallbacks.clear(), this.textCallbacks.clear(), this.keyCallbacks.clear();
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
async function a(e = {}) {
|
|
143
|
+
let t = new i(e);
|
|
144
|
+
return await t.connect(), t;
|
|
145
|
+
}
|
|
146
|
+
function o(e = {}) {
|
|
147
|
+
let t = new i(e);
|
|
148
|
+
return {
|
|
149
|
+
client: t,
|
|
150
|
+
connect: async () => {
|
|
151
|
+
await t.connect();
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
var s = {
|
|
156
|
+
createM8Client: a,
|
|
157
|
+
createM8ClientSync: o
|
|
158
|
+
};
|
|
159
|
+
//#endregion
|
|
160
|
+
export { a as createM8Client, o as createM8ClientSync, s as default };
|
|
161
|
+
|
|
162
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/client.ts"],"sourcesContent":["// @ts-expect-error - post-me types are incomplete for the generic handshake signatures used here.\nimport { ChildHandshake, DebugMessenger, WindowMessenger } from 'post-me'\n// @ts-expect-error - post-me types are incomplete for the generic handshake signatures used here.\nimport type { Connection, LocalHandle, RemoteHandle } from 'post-me'\nimport type { M8ClientEvents, M8ClientMethods, M8HostEvents, M8HostMethods, M8KeyName, M8SdkConfig, M8State } from './types'\n\nexport type { CursorPos, CursorRect, M8KeyName, M8State, RGB, SystemInfos } from './types'\n\nexport interface M8Client {\n readonly state: M8State\n readonly isConnected: boolean\n navigateToView(viewName: string): Promise<boolean>\n navigateTo(x: number, y: number): Promise<void>\n setValueToHex(targetHex: number): Promise<boolean>\n setValueToInt(targetInt: number): Promise<boolean>\n setNote(noteString: string): Promise<boolean>\n setValueToString(targetString: string, exact?: boolean, searchInCurrentLine?: boolean): Promise<boolean>\n browseFile(targetText: string, exact?: boolean): Promise<boolean>\n sendKeyPress(keys: M8KeyName[]): Promise<void>\n sendKeyDown(keys: M8KeyName[]): Promise<void>\n sendKeyUp(): Promise<void>\n getState(): M8State\n fetchState(): Promise<M8State>\n onStateChange(callback: (state: M8State) => void): () => void\n onViewChange(callback: (viewName: string | null, viewTitle: string | null) => void): () => void\n onCursorMove(callback: (pos: M8State['cursorPos'], rect: M8State['cursorRect'], selectionMode: boolean) => void): () => void\n onTextUpdate(callback: (textUnderCursor: string | null, currentLine: string | null) => void): () => void\n onKeyPress(callback: (keys: number) => void): () => void\n disconnect(): void\n}\n\nconst getDefaultState = (): M8State => ({\n viewName: null,\n viewTitle: null,\n minimapKey: null,\n cursorPos: null,\n cursorRect: null,\n selectionMode: false,\n highlightColor: null,\n titleColor: null,\n backgroundColor: null,\n textUnderCursor: null,\n currentLine: null,\n deviceModel: null,\n fontMode: null,\n systemInfo: null,\n macroRunning: false,\n})\n\nclass M8ClientImpl implements M8Client {\n private connection: Connection<M8ClientMethods, M8HostEvents, M8HostMethods, M8ClientEvents> | null = null\n private remoteHandle: RemoteHandle<M8HostMethods, M8HostEvents> | null = null\n private localHandle: LocalHandle<M8ClientMethods, M8ClientEvents> | null = null\n private readonly stateCallbacks = new Set<(state: M8State) => void>()\n private readonly viewCallbacks = new Set<(viewName: string | null, viewTitle: string | null) => void>()\n private readonly cursorCallbacks = new Set<(pos: M8State['cursorPos'], rect: M8State['cursorRect'], selectionMode: boolean) => void>()\n private readonly textCallbacks = new Set<(textUnderCursor: string | null, currentLine: string | null) => void>()\n private readonly keyCallbacks = new Set<(keys: number) => void>()\n private _state: M8State = getDefaultState()\n private _isConnected = false\n private readonly config: M8SdkConfig\n\n constructor(config: M8SdkConfig = {}) {\n this.config = config\n }\n\n get state(): M8State {\n return this._state\n }\n\n get isConnected(): boolean {\n return this._isConnected\n }\n\n async connect(): Promise<void> {\n if (this.connection) {\n return\n }\n\n let messenger = new WindowMessenger({\n localWindow: window,\n remoteWindow: window.parent,\n remoteOrigin: '*',\n })\n\n if (this.config.debug) {\n messenger = DebugMessenger(messenger, (msg: string, ...args: unknown[]) => {\n console.log('[M8 SDK]', msg, ...args)\n })\n }\n\n const connection = await ChildHandshake<M8ClientMethods, M8HostEvents, M8HostMethods, M8ClientEvents>(messenger, {\n ping: async () => 'pong',\n })\n\n this.connection = connection\n this.remoteHandle = connection.remoteHandle()\n this.localHandle = connection.localHandle()\n this._isConnected = true\n\n this.remoteHandle.addEventListener('stateChanged', (state: M8State) => {\n this._state = state\n this.stateCallbacks.forEach((cb) => {\n cb(state)\n })\n })\n\n this.remoteHandle.addEventListener('viewChanged', ({ viewName, viewTitle }: { viewName: string | null; viewTitle: string | null }) => {\n this._state = { ...this._state, viewName, viewTitle }\n this.viewCallbacks.forEach((cb) => {\n cb(viewName, viewTitle)\n })\n })\n\n this.remoteHandle.addEventListener('cursorMoved', ({ pos, rect, selectionMode }: { pos: M8State['cursorPos']; rect: M8State['cursorRect']; selectionMode: boolean }) => {\n this._state = { ...this._state, cursorPos: pos, cursorRect: rect, selectionMode }\n this.cursorCallbacks.forEach((cb) => {\n cb(pos, rect, selectionMode)\n })\n })\n\n this.remoteHandle.addEventListener('textUpdated', ({ textUnderCursor, currentLine }: { textUnderCursor: string | null; currentLine: string | null }) => {\n this._state = { ...this._state, textUnderCursor, currentLine }\n this.textCallbacks.forEach((cb) => {\n cb(textUnderCursor, currentLine)\n })\n })\n\n this.remoteHandle.addEventListener('keyPressed', ({ keys }: { keys: number }) => {\n this.keyCallbacks.forEach((cb) => {\n cb(keys)\n })\n })\n\n await this.fetchState()\n this.localHandle.emit('ready', undefined)\n }\n\n async navigateToView(viewName: string): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('navigateToView', viewName)\n }\n\n async navigateTo(x: number, y: number): Promise<void> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('navigateTo', x, y)\n }\n\n async setValueToHex(targetHex: number): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('setValueToHex', targetHex)\n }\n\n async setValueToInt(targetInt: number): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('setValueToInt', targetInt)\n }\n\n async setNote(noteString: string): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('setNote', noteString)\n }\n\n async setValueToString(targetString: string, exact = true, searchInCurrentLine = false): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('setValueToString', targetString, exact, searchInCurrentLine)\n }\n\n async browseFile(targetText: string, exact = true): Promise<boolean> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('browseFile', targetText, exact)\n }\n\n async sendKeyPress(keys: M8KeyName[]): Promise<void> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('sendKeyPress', keys)\n }\n\n async sendKeyDown(keys: M8KeyName[]): Promise<void> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('sendKeyDown', keys)\n }\n\n async sendKeyUp(): Promise<void> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n return this.remoteHandle.call('sendKeyUp')\n }\n\n getState(): M8State {\n return this._state\n }\n\n async fetchState(): Promise<M8State> {\n if (!this.remoteHandle) throw new Error('M8 SDK client is not connected')\n const state = await this.remoteHandle.call('getState')\n this._state = state\n return state\n }\n\n onStateChange(callback: (state: M8State) => void): () => void {\n this.stateCallbacks.add(callback)\n return () => this.stateCallbacks.delete(callback)\n }\n\n onViewChange(callback: (viewName: string | null, viewTitle: string | null) => void): () => void {\n this.viewCallbacks.add(callback)\n return () => this.viewCallbacks.delete(callback)\n }\n\n onCursorMove(callback: (pos: M8State['cursorPos'], rect: M8State['cursorRect'], selectionMode: boolean) => void): () => void {\n this.cursorCallbacks.add(callback)\n return () => this.cursorCallbacks.delete(callback)\n }\n\n onTextUpdate(callback: (textUnderCursor: string | null, currentLine: string | null) => void): () => void {\n this.textCallbacks.add(callback)\n return () => this.textCallbacks.delete(callback)\n }\n\n onKeyPress(callback: (keys: number) => void): () => void {\n this.keyCallbacks.add(callback)\n return () => this.keyCallbacks.delete(callback)\n }\n\n disconnect(): void {\n this.connection?.close()\n this.connection = null\n this.remoteHandle = null\n this.localHandle = null\n this._isConnected = false\n this.stateCallbacks.clear()\n this.viewCallbacks.clear()\n this.cursorCallbacks.clear()\n this.textCallbacks.clear()\n this.keyCallbacks.clear()\n }\n}\n\nexport async function createM8Client(config: M8SdkConfig = {}): Promise<M8Client> {\n const client = new M8ClientImpl(config)\n await client.connect()\n return client\n}\n\nexport function createM8ClientSync(config: M8SdkConfig = {}): { client: M8Client; connect: () => Promise<void> } {\n const client = new M8ClientImpl(config)\n return {\n client,\n connect: async () => {\n await client.connect()\n },\n }\n}\n\nexport default {\n createM8Client,\n createM8ClientSync,\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yam8d/m8-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Client SDK for iframe applications that communicate with an M8 host.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./types/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./types/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"types",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "vite build",
|
|
22
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
23
|
+
"prepack": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"m8",
|
|
27
|
+
"sdk",
|
|
28
|
+
"iframe",
|
|
29
|
+
"postmessage"
|
|
30
|
+
],
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"post-me": "^0.4.5"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "~5.9.3",
|
|
40
|
+
"vite": "^8.0.1"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export interface CursorPos {
|
|
2
|
+
x: number
|
|
3
|
+
y: number
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface CursorRect {
|
|
7
|
+
x: number
|
|
8
|
+
y: number
|
|
9
|
+
w: number
|
|
10
|
+
h: number
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface RGB {
|
|
14
|
+
r: number
|
|
15
|
+
g: number
|
|
16
|
+
b: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface SystemInfos {
|
|
20
|
+
[key: string]: string | number | boolean | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface M8State {
|
|
24
|
+
viewName: string | null
|
|
25
|
+
viewTitle: string | null
|
|
26
|
+
minimapKey: string | null
|
|
27
|
+
cursorPos: CursorPos | null
|
|
28
|
+
cursorRect: CursorRect | null
|
|
29
|
+
selectionMode: boolean
|
|
30
|
+
highlightColor: RGB | null
|
|
31
|
+
titleColor: RGB | null
|
|
32
|
+
backgroundColor: RGB | null
|
|
33
|
+
textUnderCursor: string | null
|
|
34
|
+
currentLine: string | null
|
|
35
|
+
deviceModel: string | null
|
|
36
|
+
fontMode: number | null
|
|
37
|
+
systemInfo: SystemInfos | null
|
|
38
|
+
macroRunning: boolean
|
|
39
|
+
macroCurrentStep?: number
|
|
40
|
+
macroSequenceLength?: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type M8KeyName = 'left' | 'right' | 'up' | 'down' | 'shift' | 'play' | 'opt' | 'edit'
|
|
44
|
+
|
|
45
|
+
export interface M8HostMethods {
|
|
46
|
+
navigateToView(viewName: string): Promise<boolean>
|
|
47
|
+
navigateTo(x: number, y: number): Promise<void>
|
|
48
|
+
setValueToHex(targetHex: number): Promise<boolean>
|
|
49
|
+
setValueToInt(targetInt: number): Promise<boolean>
|
|
50
|
+
setNote(noteString: string): Promise<boolean>
|
|
51
|
+
setValueToString(targetString: string, exact?: boolean, searchInCurrentLine?: boolean): Promise<boolean>
|
|
52
|
+
browseFile(targetText: string, exact?: boolean): Promise<boolean>
|
|
53
|
+
sendKeyPress(keys: M8KeyName[]): Promise<void>
|
|
54
|
+
sendKeyDown(keys: M8KeyName[]): Promise<void>
|
|
55
|
+
sendKeyUp(): Promise<void>
|
|
56
|
+
getState(): Promise<M8State>
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface M8ClientMethods {
|
|
60
|
+
ping(): Promise<string>
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface M8HostEvents {
|
|
64
|
+
stateChanged: M8State
|
|
65
|
+
viewChanged: { viewName: string | null; viewTitle: string | null }
|
|
66
|
+
cursorMoved: { pos: CursorPos | null; rect: CursorRect | null; selectionMode: boolean }
|
|
67
|
+
textUpdated: { textUnderCursor: string | null; currentLine: string | null }
|
|
68
|
+
keyPressed: { keys: number }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface M8ClientEvents {
|
|
72
|
+
ready: undefined
|
|
73
|
+
error: { message: string }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface M8SdkConfig {
|
|
77
|
+
debug?: boolean
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface M8Client {
|
|
81
|
+
readonly state: M8State
|
|
82
|
+
readonly isConnected: boolean
|
|
83
|
+
navigateToView(viewName: string): Promise<boolean>
|
|
84
|
+
navigateTo(x: number, y: number): Promise<void>
|
|
85
|
+
setValueToHex(targetHex: number): Promise<boolean>
|
|
86
|
+
setValueToInt(targetInt: number): Promise<boolean>
|
|
87
|
+
setNote(noteString: string): Promise<boolean>
|
|
88
|
+
setValueToString(targetString: string, exact?: boolean, searchInCurrentLine?: boolean): Promise<boolean>
|
|
89
|
+
browseFile(targetText: string, exact?: boolean): Promise<boolean>
|
|
90
|
+
sendKeyPress(keys: M8KeyName[]): Promise<void>
|
|
91
|
+
sendKeyDown(keys: M8KeyName[]): Promise<void>
|
|
92
|
+
sendKeyUp(): Promise<void>
|
|
93
|
+
getState(): M8State
|
|
94
|
+
fetchState(): Promise<M8State>
|
|
95
|
+
onStateChange(callback: (state: M8State) => void): () => void
|
|
96
|
+
onViewChange(callback: (viewName: string | null, viewTitle: string | null) => void): () => void
|
|
97
|
+
onCursorMove(callback: (pos: M8State['cursorPos'], rect: M8State['cursorRect'], selectionMode: boolean) => void): () => void
|
|
98
|
+
onTextUpdate(callback: (textUnderCursor: string | null, currentLine: string | null) => void): () => void
|
|
99
|
+
onKeyPress(callback: (keys: number) => void): () => void
|
|
100
|
+
disconnect(): void
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createM8Client(config?: M8SdkConfig): Promise<M8Client>
|
|
104
|
+
|
|
105
|
+
export function createM8ClientSync(config?: M8SdkConfig): {
|
|
106
|
+
client: M8Client
|
|
107
|
+
connect: () => Promise<void>
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare const m8Sdk: {
|
|
111
|
+
createM8Client: typeof createM8Client
|
|
112
|
+
createM8ClientSync: typeof createM8ClientSync
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export default m8Sdk
|