@fluxdeck/sdk 0.0.4 → 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/dist/index.d.mts +138 -162
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,65 @@
|
|
|
1
|
-
//#region ../bindings/
|
|
1
|
+
//#region ../bindings/dist/ClientRequestEvent.d.ts
|
|
2
|
+
type ClientRequestEvent = {
|
|
3
|
+
"event": "getPluginSettings";
|
|
4
|
+
name: string;
|
|
5
|
+
};
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region ../bindings/dist/ClientRegisterPayload.d.ts
|
|
8
|
+
type ClientRegisterPayload = {
|
|
9
|
+
clientUuid: string | null;
|
|
10
|
+
name: string;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region ../bindings/dist/JsonValue.d.ts
|
|
2
14
|
type JsonValue = null | string | number | boolean | Array<JsonValue> | JsonObject;
|
|
3
15
|
type JsonObject = {
|
|
4
16
|
[key: string]: JsonValue;
|
|
5
17
|
};
|
|
6
18
|
//#endregion
|
|
7
|
-
//#region ../bindings/
|
|
8
|
-
type
|
|
9
|
-
|
|
19
|
+
//#region ../bindings/dist/SetBoardIdPayload.d.ts
|
|
20
|
+
type SetBoardIdPayload = {
|
|
21
|
+
clientUuid: string;
|
|
22
|
+
profileId: number;
|
|
23
|
+
boardId: number;
|
|
24
|
+
};
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region ../bindings/dist/ClientEvent.d.ts
|
|
27
|
+
type ClientEvent = {
|
|
28
|
+
"event": "editorRegister";
|
|
29
|
+
payload: string;
|
|
30
|
+
} | {
|
|
31
|
+
"event": "pluginRegister";
|
|
32
|
+
payload: string;
|
|
33
|
+
} | {
|
|
34
|
+
"event": "sendToPlugin";
|
|
35
|
+
name: string;
|
|
10
36
|
payload: JsonValue;
|
|
37
|
+
} | {
|
|
38
|
+
"event": "sendToEditor";
|
|
39
|
+
name: string;
|
|
40
|
+
payload: JsonValue;
|
|
41
|
+
} | {
|
|
42
|
+
"event": "setPluginSettings";
|
|
43
|
+
name: string;
|
|
44
|
+
payload: JsonValue;
|
|
45
|
+
} | {
|
|
46
|
+
"event": "press";
|
|
47
|
+
payload: number;
|
|
48
|
+
} | {
|
|
49
|
+
"event": "release";
|
|
50
|
+
payload: number;
|
|
51
|
+
} | {
|
|
52
|
+
"event": "setBoardId";
|
|
53
|
+
payload: SetBoardIdPayload;
|
|
54
|
+
} | {
|
|
55
|
+
"event": "clientRegister";
|
|
56
|
+
payload: ClientRegisterPayload;
|
|
11
57
|
};
|
|
12
58
|
//#endregion
|
|
13
|
-
//#region ../bindings/
|
|
59
|
+
//#region ../bindings/dist/ConnectionRejectedReason.d.ts
|
|
60
|
+
type ConnectionRejectedReason = "Blocked" | "Denied";
|
|
61
|
+
//#endregion
|
|
62
|
+
//#region ../bindings/dist/GetActionDto.d.ts
|
|
14
63
|
type GetActionDto = {
|
|
15
64
|
id: number;
|
|
16
65
|
uuid: string;
|
|
@@ -21,12 +70,12 @@ type GetActionDto = {
|
|
|
21
70
|
children: { [key in string]?: Array<GetActionDto> };
|
|
22
71
|
};
|
|
23
72
|
//#endregion
|
|
24
|
-
//#region ../bindings/
|
|
73
|
+
//#region ../bindings/dist/GetColorDto.d.ts
|
|
25
74
|
type GetColorDto = {
|
|
26
75
|
value: string | null;
|
|
27
76
|
};
|
|
28
77
|
//#endregion
|
|
29
|
-
//#region ../bindings/
|
|
78
|
+
//#region ../bindings/dist/GetIconDto.d.ts
|
|
30
79
|
type GetIconDto = {
|
|
31
80
|
id: number | null;
|
|
32
81
|
path: string;
|
|
@@ -36,10 +85,10 @@ type GetIconDto = {
|
|
|
36
85
|
mode: string | null;
|
|
37
86
|
};
|
|
38
87
|
//#endregion
|
|
39
|
-
//#region ../bindings/
|
|
88
|
+
//#region ../bindings/dist/TextAlign.d.ts
|
|
40
89
|
type TextAlign = "top" | "middle" | "bottom";
|
|
41
90
|
//#endregion
|
|
42
|
-
//#region ../bindings/
|
|
91
|
+
//#region ../bindings/dist/GetTitleDto.d.ts
|
|
43
92
|
type GetTitleDto = {
|
|
44
93
|
value: string | null;
|
|
45
94
|
align: TextAlign | null;
|
|
@@ -48,7 +97,7 @@ type GetTitleDto = {
|
|
|
48
97
|
size: number | null;
|
|
49
98
|
};
|
|
50
99
|
//#endregion
|
|
51
|
-
//#region ../bindings/
|
|
100
|
+
//#region ../bindings/dist/GetStateSnapshotDto.d.ts
|
|
52
101
|
type GetStateSnapshotDto = {
|
|
53
102
|
id: number | null;
|
|
54
103
|
title: GetTitleDto | null;
|
|
@@ -56,7 +105,7 @@ type GetStateSnapshotDto = {
|
|
|
56
105
|
color: GetColorDto | null;
|
|
57
106
|
};
|
|
58
107
|
//#endregion
|
|
59
|
-
//#region ../bindings/
|
|
108
|
+
//#region ../bindings/dist/GetItemStateDto.d.ts
|
|
60
109
|
type GetItemStateDto = {
|
|
61
110
|
id: number;
|
|
62
111
|
boardId: number;
|
|
@@ -65,7 +114,7 @@ type GetItemStateDto = {
|
|
|
65
114
|
state: GetStateSnapshotDto;
|
|
66
115
|
};
|
|
67
116
|
//#endregion
|
|
68
|
-
//#region ../bindings/
|
|
117
|
+
//#region ../bindings/dist/GetPageDto.d.ts
|
|
69
118
|
type GetPageDto = {
|
|
70
119
|
boardId: number;
|
|
71
120
|
position: number;
|
|
@@ -73,30 +122,36 @@ type GetPageDto = {
|
|
|
73
122
|
icon: string | null;
|
|
74
123
|
};
|
|
75
124
|
//#endregion
|
|
76
|
-
//#region ../bindings/
|
|
125
|
+
//#region ../bindings/dist/GetBoardStateDto.d.ts
|
|
77
126
|
type GetBoardStateDto = {
|
|
78
127
|
boardId: number;
|
|
79
128
|
page: GetPageDto | null;
|
|
80
129
|
items: Array<GetItemStateDto>;
|
|
81
130
|
};
|
|
82
131
|
//#endregion
|
|
83
|
-
//#region ../bindings/
|
|
132
|
+
//#region ../bindings/dist/GetClientDto.d.ts
|
|
84
133
|
type GetClientDto = {
|
|
85
134
|
id: number;
|
|
86
135
|
uuid: string;
|
|
87
136
|
name: string;
|
|
88
137
|
profileId: number;
|
|
89
138
|
boardId: number;
|
|
139
|
+
/**
|
|
140
|
+
* Whether the Client currently has a live Connection. Derived from the
|
|
141
|
+
* Session Registry, never persisted (see ADR-0007). Defaults to `false`
|
|
142
|
+
* for single-client reads that do not compute Presence.
|
|
143
|
+
*/
|
|
144
|
+
online: boolean;
|
|
90
145
|
};
|
|
91
146
|
//#endregion
|
|
92
|
-
//#region ../bindings/
|
|
147
|
+
//#region ../bindings/dist/GetLayoutDto.d.ts
|
|
93
148
|
type GetLayoutDto = {
|
|
94
149
|
profileId: number;
|
|
95
150
|
rows: number | null;
|
|
96
151
|
cols: number | null;
|
|
97
152
|
};
|
|
98
153
|
//#endregion
|
|
99
|
-
//#region ../bindings/
|
|
154
|
+
//#region ../bindings/dist/GetStyleDto.d.ts
|
|
100
155
|
type GetStyleDto = {
|
|
101
156
|
profileId: number;
|
|
102
157
|
spacing: number | null;
|
|
@@ -109,7 +164,7 @@ type GetStyleDto = {
|
|
|
109
164
|
backgroundColor: string | null;
|
|
110
165
|
};
|
|
111
166
|
//#endregion
|
|
112
|
-
//#region ../bindings/
|
|
167
|
+
//#region ../bindings/dist/GetClientStateDto.d.ts
|
|
113
168
|
type GetClientStateDto = {
|
|
114
169
|
clientUuid: string;
|
|
115
170
|
profileId: number;
|
|
@@ -119,8 +174,15 @@ type GetClientStateDto = {
|
|
|
119
174
|
style: GetStyleDto;
|
|
120
175
|
};
|
|
121
176
|
//#endregion
|
|
122
|
-
//#region ../bindings/
|
|
177
|
+
//#region ../bindings/dist/ServerEvent.d.ts
|
|
123
178
|
type ServerEvent = {
|
|
179
|
+
"event": "connectionPending";
|
|
180
|
+
} | {
|
|
181
|
+
"event": "connectionRejected";
|
|
182
|
+
reason: ConnectionRejectedReason;
|
|
183
|
+
} | {
|
|
184
|
+
"event": "clientDeleted";
|
|
185
|
+
} | {
|
|
124
186
|
"event": "trigger";
|
|
125
187
|
itemId: number;
|
|
126
188
|
action: GetActionDto;
|
|
@@ -162,94 +224,26 @@ type ServerEvent = {
|
|
|
162
224
|
"event": "currentStateChanged";
|
|
163
225
|
};
|
|
164
226
|
//#endregion
|
|
165
|
-
//#region
|
|
166
|
-
type
|
|
167
|
-
//#endregion
|
|
168
|
-
//#region src/editor.d.ts
|
|
169
|
-
type SaveHandler = () => unknown;
|
|
170
|
-
declare class Editor {
|
|
171
|
-
private connection;
|
|
172
|
-
private bridge;
|
|
173
|
-
private params;
|
|
174
|
-
private saveHandler?;
|
|
175
|
-
private eventEmitter;
|
|
176
|
-
constructor();
|
|
177
|
-
onRecieveFromPlugin<T>(listener: Listener<T>): Promise<() => void>;
|
|
178
|
-
sendToPlugin<T extends JsonValue>(data: T): void;
|
|
179
|
-
getActionSettings(): Promise<JsonValue>;
|
|
180
|
-
onActionSave(handler: SaveHandler): () => void;
|
|
181
|
-
getPluginSettings(): Promise<ServerResponseEvent>;
|
|
182
|
-
setPluginSettings(data: JsonValue): Promise<void>;
|
|
183
|
-
}
|
|
184
|
-
//#endregion
|
|
185
|
-
//#region ../bindings/src/ClientRequestEvent.d.ts
|
|
186
|
-
type ClientRequestEvent = {
|
|
227
|
+
//#region ../bindings/dist/ServerResponseEvent.d.ts
|
|
228
|
+
type ServerResponseEvent = {
|
|
187
229
|
"event": "getPluginSettings";
|
|
188
|
-
|
|
230
|
+
payload: JsonValue;
|
|
189
231
|
};
|
|
190
232
|
//#endregion
|
|
191
|
-
//#region src/
|
|
233
|
+
//#region src/connection.d.ts
|
|
192
234
|
type Handler<T extends ServerEvent["event"]> = (data: Extract<ServerEvent, {
|
|
193
235
|
event: T;
|
|
194
236
|
}>) => void;
|
|
195
|
-
type ResponseFor
|
|
237
|
+
type ResponseFor<T extends ClientRequestEvent["event"]> = Extract<ServerResponseEvent, {
|
|
196
238
|
event: T;
|
|
197
239
|
}>;
|
|
198
|
-
//#endregion
|
|
199
|
-
//#region ../bindings/src/ClientRegisterPayload.d.ts
|
|
200
|
-
type ClientRegisterPayload = {
|
|
201
|
-
clientUuid: string | null;
|
|
202
|
-
name: string;
|
|
203
|
-
};
|
|
204
|
-
//#endregion
|
|
205
|
-
//#region ../bindings/src/SetBoardIdPayload.d.ts
|
|
206
|
-
type SetBoardIdPayload = {
|
|
207
|
-
clientUuid: string;
|
|
208
|
-
profileId: number;
|
|
209
|
-
boardId: number;
|
|
210
|
-
};
|
|
211
|
-
//#endregion
|
|
212
|
-
//#region ../bindings/src/ClientEvent.d.ts
|
|
213
|
-
type ClientEvent = {
|
|
214
|
-
"event": "editorRegister";
|
|
215
|
-
payload: string;
|
|
216
|
-
} | {
|
|
217
|
-
"event": "pluginRegister";
|
|
218
|
-
payload: string;
|
|
219
|
-
} | {
|
|
220
|
-
"event": "sendToPlugin";
|
|
221
|
-
name: string;
|
|
222
|
-
payload: JsonValue;
|
|
223
|
-
} | {
|
|
224
|
-
"event": "sendToEditor";
|
|
225
|
-
name: string;
|
|
226
|
-
payload: JsonValue;
|
|
227
|
-
} | {
|
|
228
|
-
"event": "setPluginSettings";
|
|
229
|
-
name: string;
|
|
230
|
-
payload: JsonValue;
|
|
231
|
-
} | {
|
|
232
|
-
"event": "press";
|
|
233
|
-
payload: number;
|
|
234
|
-
} | {
|
|
235
|
-
"event": "release";
|
|
236
|
-
payload: number;
|
|
237
|
-
} | {
|
|
238
|
-
"event": "setBoardId";
|
|
239
|
-
payload: SetBoardIdPayload;
|
|
240
|
-
} | {
|
|
241
|
-
"event": "clientRegister";
|
|
242
|
-
payload: ClientRegisterPayload;
|
|
243
|
-
};
|
|
244
|
-
//#endregion
|
|
245
|
-
//#region src/connection.d.ts
|
|
246
|
-
type ConnectionStatus = "connecting" | "connected" | "disconnected";
|
|
247
|
-
type StatusListener = (status: ConnectionStatus) => void;
|
|
248
240
|
type ConnectionOptions = {
|
|
249
241
|
autoreconnect?: boolean;
|
|
250
242
|
requestTimeout?: number;
|
|
251
243
|
port?: number;
|
|
252
244
|
};
|
|
245
|
+
type ConnectionStatus = "connecting" | "connected" | "disconnected";
|
|
246
|
+
type StatusListener = (status: ConnectionStatus) => void;
|
|
253
247
|
declare class Connection {
|
|
254
248
|
private url;
|
|
255
249
|
private ws?;
|
|
@@ -269,109 +263,92 @@ declare class Connection {
|
|
|
269
263
|
private setStatus;
|
|
270
264
|
reconnect(): void;
|
|
271
265
|
connect(): void;
|
|
272
|
-
|
|
266
|
+
disableAutoreconnect(): void;
|
|
273
267
|
close(): void;
|
|
274
268
|
private send;
|
|
275
269
|
sendEvent(event: ClientEvent): Promise<void>;
|
|
276
270
|
on<T extends ServerEvent["event"]>(event: T, handler: Handler<T>): () => void;
|
|
277
271
|
private onMessage;
|
|
278
|
-
request<E extends ClientRequestEvent>(event: E): Promise<ResponseFor
|
|
272
|
+
request<E extends ClientRequestEvent>(event: E): Promise<ResponseFor<E["event"]>>;
|
|
279
273
|
}
|
|
280
274
|
//#endregion
|
|
281
|
-
//#region src/
|
|
282
|
-
type MessageHandler<T extends keyof EventRequests> = (payload: EventRequests[T], event: MessageEvent, respond?: (responsePayload: ResponseFor<T>) => void) => void;
|
|
275
|
+
//#region src/iframe-bridge.d.ts
|
|
283
276
|
type BridgeOptions = {
|
|
284
277
|
targetOrigin?: string;
|
|
285
278
|
timeout?: number;
|
|
286
279
|
debug?: boolean;
|
|
287
280
|
};
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
requestId?: number;
|
|
291
|
-
isRequest?: boolean;
|
|
292
|
-
isResponse?: boolean;
|
|
293
|
-
};
|
|
294
|
-
type BridgeMessage<T> = {
|
|
295
|
-
type: string;
|
|
296
|
-
payload: T;
|
|
297
|
-
meta: MessageMeta;
|
|
298
|
-
};
|
|
299
|
-
interface EventRequests {
|
|
300
|
-
SET_ACTION_SETTINGS: {
|
|
281
|
+
interface BridgeRequests {
|
|
282
|
+
SAVE_ACTION_SETTINGS: {
|
|
301
283
|
id: string;
|
|
302
284
|
};
|
|
303
285
|
GET_ACTION_SETTINGS: {
|
|
304
286
|
id: string;
|
|
305
287
|
};
|
|
306
288
|
}
|
|
307
|
-
interface
|
|
308
|
-
|
|
289
|
+
interface BridgeResponses {
|
|
290
|
+
SAVE_ACTION_SETTINGS: {
|
|
309
291
|
settings: string | null;
|
|
310
292
|
};
|
|
311
293
|
GET_ACTION_SETTINGS: {
|
|
312
294
|
settings: string | null;
|
|
313
295
|
};
|
|
314
296
|
}
|
|
315
|
-
type
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
declare class
|
|
297
|
+
type BridgeMessageType = keyof BridgeRequests;
|
|
298
|
+
type ResponseFor$1<K extends BridgeMessageType> = K extends keyof BridgeResponses ? BridgeResponses[K] : never;
|
|
299
|
+
type MessageHandler<K extends BridgeMessageType> = (payload: BridgeRequests[K], event: MessageEvent, respond?: (responsePayload: ResponseFor$1<K>) => void) => void;
|
|
300
|
+
declare class IframeBridge {
|
|
319
301
|
private options;
|
|
320
302
|
private handlers;
|
|
321
303
|
private pendingRequests;
|
|
322
|
-
private requestId;
|
|
323
304
|
private isParent;
|
|
324
305
|
private target;
|
|
325
306
|
private boundHandleMessage;
|
|
326
307
|
constructor(options?: BridgeOptions);
|
|
327
308
|
private init;
|
|
328
|
-
/**
|
|
329
|
-
* Установить цель для отправки сообщений (для родительского окна)
|
|
330
|
-
*/
|
|
309
|
+
/** Set the target window to post messages to (used by the parent window). */
|
|
331
310
|
setTarget(iframeElement: HTMLIFrameElement): void;
|
|
332
|
-
/**
|
|
333
|
-
* Получить целевое окно для отправки сообщений
|
|
334
|
-
*/
|
|
311
|
+
/** Resolve the window to post messages to. */
|
|
335
312
|
private getTargetWindow;
|
|
336
|
-
/**
|
|
337
|
-
* Обработка входящих сообщений
|
|
338
|
-
*/
|
|
313
|
+
/** Handle an incoming message. */
|
|
339
314
|
private handleMessage;
|
|
340
|
-
/**
|
|
341
|
-
* Отправить сообщение
|
|
342
|
-
*/
|
|
315
|
+
/** Post a fire-and-forget message. */
|
|
343
316
|
send(type: string, payload?: unknown): void;
|
|
344
|
-
/**
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
request(type: T, payload: EventRequests[T], timeout?: number): Promise<ResponseFor<T>>;
|
|
348
|
-
/**
|
|
349
|
-
* Отправить ответ на запрос
|
|
350
|
-
*/
|
|
317
|
+
/** Post a request and wait for its response. */
|
|
318
|
+
request<K extends BridgeMessageType>(type: K, payload: BridgeRequests[K], timeout?: number): Promise<ResponseFor$1<K>>;
|
|
319
|
+
/** Post a response back to the window that issued the request. */
|
|
351
320
|
private sendResponse;
|
|
352
|
-
/**
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
on(type: T, handler: MessageHandler<T>): () => void;
|
|
360
|
-
/**
|
|
361
|
-
* Отписаться от события
|
|
362
|
-
*/
|
|
363
|
-
off(type: string): void;
|
|
364
|
-
/**
|
|
365
|
-
* Подписаться на событие один раз
|
|
366
|
-
*/
|
|
367
|
-
once(type: T, handler: MessageHandler<T>): () => void;
|
|
368
|
-
/**
|
|
369
|
-
* Очистить все обработчики
|
|
370
|
-
*/
|
|
321
|
+
/** Subscribe to a message type (single handler per type). */
|
|
322
|
+
on<K extends BridgeMessageType>(type: K, handler: MessageHandler<K>): () => void;
|
|
323
|
+
/** Unsubscribe from a message type. */
|
|
324
|
+
off(type: BridgeMessageType): void;
|
|
325
|
+
/** Subscribe to a message type for a single delivery. */
|
|
326
|
+
once<K extends BridgeMessageType>(type: K, handler: MessageHandler<K>): () => void;
|
|
327
|
+
/** Tear down the bridge and reject every outstanding request. */
|
|
371
328
|
destroy(): void;
|
|
372
329
|
}
|
|
373
330
|
//#endregion
|
|
331
|
+
//#region src/editor.d.ts
|
|
332
|
+
type Listener$1<T> = (payload: T) => void;
|
|
333
|
+
type SaveHandler = () => unknown;
|
|
334
|
+
declare class Editor {
|
|
335
|
+
private connection;
|
|
336
|
+
private bridge;
|
|
337
|
+
private params;
|
|
338
|
+
private saveHandler?;
|
|
339
|
+
constructor();
|
|
340
|
+
connect(): void;
|
|
341
|
+
private onReceiveFromPluginListeners;
|
|
342
|
+
onReceiveFromPlugin<T>(listener: Listener$1<T>): () => void;
|
|
343
|
+
sendToPlugin<T extends JsonValue>(data: T): void;
|
|
344
|
+
getActionSettings(): Promise<JsonValue>;
|
|
345
|
+
onActionSave(handler: SaveHandler): () => void;
|
|
346
|
+
getPluginSettings(): Promise<ServerResponseEvent>;
|
|
347
|
+
setPluginSettings(data: JsonValue): Promise<void>;
|
|
348
|
+
}
|
|
349
|
+
//#endregion
|
|
374
350
|
//#region src/plugin.d.ts
|
|
351
|
+
type Listener<T> = (payload: T) => void;
|
|
375
352
|
type ActionData<T> = {
|
|
376
353
|
trigger: string;
|
|
377
354
|
settings: T;
|
|
@@ -380,23 +357,22 @@ interface Action<T> {
|
|
|
380
357
|
name: string;
|
|
381
358
|
onTrigger?: (data: ActionData<T>) => void;
|
|
382
359
|
}
|
|
383
|
-
declare class
|
|
360
|
+
declare class Plugin {
|
|
384
361
|
private connection;
|
|
385
362
|
private actions;
|
|
386
363
|
private pluginName?;
|
|
387
|
-
private eventEmitter;
|
|
388
364
|
constructor();
|
|
389
365
|
connect(): void;
|
|
390
|
-
private
|
|
366
|
+
private ensurePluginName;
|
|
391
367
|
private registerPlugin;
|
|
392
368
|
registerAction<T>(action: Action<T>): void;
|
|
393
|
-
|
|
394
|
-
|
|
369
|
+
onPluginSettings<T>(listener: Listener<T>): Promise<() => void>;
|
|
370
|
+
onReceiveFromEditor<T>(listener: Listener<T>): Promise<() => void>;
|
|
395
371
|
sendToEditor<T extends JsonValue>(data: T): void;
|
|
396
372
|
getPluginSettings(): Promise<ServerResponseEvent>;
|
|
397
373
|
setPluginSettings<T extends JsonValue>(data: T): Promise<void>;
|
|
398
374
|
}
|
|
399
|
-
declare const fluxDeck:
|
|
375
|
+
declare const fluxDeck: Plugin;
|
|
400
376
|
//#endregion
|
|
401
|
-
export { Action, ActionData,
|
|
377
|
+
export { Action, ActionData, Connection, ConnectionStatus, Editor, Handler, IframeBridge, Plugin, ResponseFor, fluxDeck };
|
|
402
378
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../bindings/src/JsonValue.ts","../../bindings/src/ServerResponseEvent.ts","../../bindings/src/GetActionDto.ts","../../bindings/src/GetColorDto.ts","../../bindings/src/GetIconDto.ts","../../bindings/src/TextAlign.ts","../../bindings/src/GetTitleDto.ts","../../bindings/src/GetStateSnapshotDto.ts","../../bindings/src/GetItemStateDto.ts","../../bindings/src/GetPageDto.ts","../../bindings/src/GetBoardStateDto.ts","../../bindings/src/GetClientDto.ts","../../bindings/src/GetLayoutDto.ts","../../bindings/src/GetStyleDto.ts","../../bindings/src/GetClientStateDto.ts","../../bindings/src/ServerEvent.ts","../src/event-emitter.ts","../src/editor.ts","../../bindings/src/ClientRequestEvent.ts","../src/types/connection.ts","../../bindings/src/ClientRegisterPayload.ts","../../bindings/src/SetBoardIdPayload.ts","../../bindings/src/ClientEvent.ts","../src/connection.ts","../src/types/bridge.ts","../src/bridge.ts","../src/plugin.ts"],"sourcesContent":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":["ClientRequestEvent","ClientRegisterPayload","JsonValue","Array","JsonObject","SetBoardIdPayload","ClientRegisterPayload","JsonValue","SetBoardIdPayload","ClientEvent","ConnectionRejectedReason","GetActionDto","Array","GetColorDto","GetIconDto","TextAlign","TextAlign","GetTitleDto","GetColorDto","GetIconDto","GetTitleDto","GetStateSnapshotDto","GetStateSnapshotDto","GetItemStateDto","GetPageDto","GetItemStateDto","GetPageDto","GetBoardStateDto","Array","GetClientDto","GetLayoutDto","GetStyleDto","GetBoardStateDto","GetLayoutDto","GetStyleDto","GetClientStateDto","Array","ConnectionRejectedReason","GetActionDto","GetBoardStateDto","GetClientDto","GetClientStateDto","GetItemStateDto","GetLayoutDto","GetStyleDto","JsonValue","ServerEvent","Array","JsonValue","ServerResponseEvent"],"sources":["../../bindings/dist/ClientRequestEvent.d.ts","../../bindings/dist/ClientRegisterPayload.d.ts","../../bindings/dist/JsonValue.d.ts","../../bindings/dist/SetBoardIdPayload.d.ts","../../bindings/dist/ClientEvent.d.ts","../../bindings/dist/ConnectionRejectedReason.d.ts","../../bindings/dist/GetActionDto.d.ts","../../bindings/dist/GetColorDto.d.ts","../../bindings/dist/GetIconDto.d.ts","../../bindings/dist/TextAlign.d.ts","../../bindings/dist/GetTitleDto.d.ts","../../bindings/dist/GetStateSnapshotDto.d.ts","../../bindings/dist/GetItemStateDto.d.ts","../../bindings/dist/GetPageDto.d.ts","../../bindings/dist/GetBoardStateDto.d.ts","../../bindings/dist/GetClientDto.d.ts","../../bindings/dist/GetLayoutDto.d.ts","../../bindings/dist/GetStyleDto.d.ts","../../bindings/dist/GetClientStateDto.d.ts","../../bindings/dist/ServerEvent.d.ts","../../bindings/dist/ServerResponseEvent.d.ts","../src/connection.ts","../src/iframe-bridge.ts","../src/editor.ts","../src/plugin.ts"],"sourcesContent":["export type ClientRequestEvent = {\n \"event\": \"getPluginSettings\";\n name: string;\n};\n//# sourceMappingURL=ClientRequestEvent.d.ts.map","export type ClientRegisterPayload = {\n clientUuid: string | null;\n name: string;\n};\n//# sourceMappingURL=ClientRegisterPayload.d.ts.map","export type JsonValue = null | string | number | boolean | Array<JsonValue> | JsonObject;\nexport type JsonObject = {\n [key: string]: JsonValue;\n};\n//# sourceMappingURL=JsonValue.d.ts.map","export type SetBoardIdPayload = {\n clientUuid: string;\n profileId: number;\n boardId: number;\n};\n//# sourceMappingURL=SetBoardIdPayload.d.ts.map","import type { ClientRegisterPayload } from \"./ClientRegisterPayload\";\nimport type { JsonValue } from \"./JsonValue\";\nimport type { SetBoardIdPayload } from \"./SetBoardIdPayload\";\nexport type ClientEvent = {\n \"event\": \"editorRegister\";\n payload: string;\n} | {\n \"event\": \"pluginRegister\";\n payload: string;\n} | {\n \"event\": \"sendToPlugin\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"sendToEditor\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"setPluginSettings\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"press\";\n payload: number;\n} | {\n \"event\": \"release\";\n payload: number;\n} | {\n \"event\": \"setBoardId\";\n payload: SetBoardIdPayload;\n} | {\n \"event\": \"clientRegister\";\n payload: ClientRegisterPayload;\n};\n//# sourceMappingURL=ClientEvent.d.ts.map","export type ConnectionRejectedReason = \"Blocked\" | \"Denied\";\n//# sourceMappingURL=ConnectionRejectedReason.d.ts.map","export type GetActionDto = {\n id: number;\n uuid: string;\n type: string;\n group: string;\n position: number;\n settings: string | null;\n children: {\n [key in string]?: Array<GetActionDto>;\n };\n};\n//# sourceMappingURL=GetActionDto.d.ts.map","export type GetColorDto = {\n value: string | null;\n};\n//# sourceMappingURL=GetColorDto.d.ts.map","export type GetIconDto = {\n id: number | null;\n path: string;\n version: number;\n color: string | null;\n scale: number | null;\n mode: string | null;\n};\n//# sourceMappingURL=GetIconDto.d.ts.map","export type TextAlign = \"top\" | \"middle\" | \"bottom\";\n//# sourceMappingURL=TextAlign.d.ts.map","import type { TextAlign } from \"./TextAlign\";\nexport type GetTitleDto = {\n value: string | null;\n align: TextAlign | null;\n font: string | null;\n color: string | null;\n size: number | null;\n};\n//# sourceMappingURL=GetTitleDto.d.ts.map","import type { GetColorDto } from \"./GetColorDto\";\nimport type { GetIconDto } from \"./GetIconDto\";\nimport type { GetTitleDto } from \"./GetTitleDto\";\nexport type GetStateSnapshotDto = {\n id: number | null;\n title: GetTitleDto | null;\n icon: GetIconDto | null;\n color: GetColorDto | null;\n};\n//# sourceMappingURL=GetStateSnapshotDto.d.ts.map","import type { GetStateSnapshotDto } from \"./GetStateSnapshotDto\";\nexport type GetItemStateDto = {\n id: number;\n boardId: number;\n row: number;\n col: number;\n state: GetStateSnapshotDto;\n};\n//# sourceMappingURL=GetItemStateDto.d.ts.map","export type GetPageDto = {\n boardId: number;\n position: number;\n name: string | null;\n icon: string | null;\n};\n//# sourceMappingURL=GetPageDto.d.ts.map","import type { GetItemStateDto } from \"./GetItemStateDto\";\nimport type { GetPageDto } from \"./GetPageDto\";\nexport type GetBoardStateDto = {\n boardId: number;\n page: GetPageDto | null;\n items: Array<GetItemStateDto>;\n};\n//# sourceMappingURL=GetBoardStateDto.d.ts.map","export type GetClientDto = {\n id: number;\n uuid: string;\n name: string;\n profileId: number;\n boardId: number;\n /**\n * Whether the Client currently has a live Connection. Derived from the\n * Session Registry, never persisted (see ADR-0007). Defaults to `false`\n * for single-client reads that do not compute Presence.\n */\n online: boolean;\n};\n//# sourceMappingURL=GetClientDto.d.ts.map","export type GetLayoutDto = {\n profileId: number;\n rows: number | null;\n cols: number | null;\n};\n//# sourceMappingURL=GetLayoutDto.d.ts.map","export type GetStyleDto = {\n profileId: number;\n spacing: number | null;\n itemBorder: number | null;\n itemBorderColor: string | null;\n itemBorderRadius: number | null;\n itemBackgroundColor: string | null;\n itemBackgroundImage: string | null;\n backgroundImage: string | null;\n backgroundColor: string | null;\n};\n//# sourceMappingURL=GetStyleDto.d.ts.map","import type { GetBoardStateDto } from \"./GetBoardStateDto\";\nimport type { GetLayoutDto } from \"./GetLayoutDto\";\nimport type { GetStyleDto } from \"./GetStyleDto\";\nexport type GetClientStateDto = {\n clientUuid: string;\n profileId: number;\n boardId: number;\n boards: Array<GetBoardStateDto>;\n layout: GetLayoutDto;\n style: GetStyleDto;\n};\n//# sourceMappingURL=GetClientStateDto.d.ts.map","import type { ConnectionRejectedReason } from \"./ConnectionRejectedReason\";\nimport type { GetActionDto } from \"./GetActionDto\";\nimport type { GetBoardStateDto } from \"./GetBoardStateDto\";\nimport type { GetClientDto } from \"./GetClientDto\";\nimport type { GetClientStateDto } from \"./GetClientStateDto\";\nimport type { GetItemStateDto } from \"./GetItemStateDto\";\nimport type { GetLayoutDto } from \"./GetLayoutDto\";\nimport type { GetStyleDto } from \"./GetStyleDto\";\nimport type { JsonValue } from \"./JsonValue\";\nexport type ServerEvent = {\n \"event\": \"connectionPending\";\n} | {\n \"event\": \"connectionRejected\";\n reason: ConnectionRejectedReason;\n} | {\n \"event\": \"clientDeleted\";\n} | {\n \"event\": \"trigger\";\n itemId: number;\n action: GetActionDto;\n kind: string;\n} | {\n \"event\": \"sendToPlugin\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"sendToEditor\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"setPluginSettings\";\n name: string;\n payload: JsonValue;\n} | {\n \"event\": \"clientRegister\";\n payload: GetClientDto;\n} | {\n \"event\": \"clientState\";\n payload: GetClientStateDto;\n} | {\n \"event\": \"profileChanged\";\n payload: number;\n} | {\n \"event\": \"boardState\";\n payload: GetBoardStateDto;\n} | {\n \"event\": \"itemsState\";\n payload: Array<GetItemStateDto>;\n} | {\n \"event\": \"styleState\";\n payload: GetStyleDto;\n} | {\n \"event\": \"layoutState\";\n payload: GetLayoutDto;\n} | {\n \"event\": \"currentStateChanged\";\n};\n//# sourceMappingURL=ServerEvent.d.ts.map","import type { JsonValue } from \"./JsonValue\";\nexport type ServerResponseEvent = {\n \"event\": \"getPluginSettings\";\n payload: JsonValue;\n};\n//# sourceMappingURL=ServerResponseEvent.d.ts.map"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{nanoid as e}from"nanoid";var t=class{
|
|
1
|
+
import{nanoid as e}from"nanoid";var t=class{pending=new Map;create(t){let n=e();return{id:n,promise:new Promise((e,r)=>{let i=setTimeout(()=>{this.pending.delete(n),r(Error(`Request timed out`))},t);this.pending.set(n,{resolve:t=>e(t),reject:r,timeoutId:i})})}}resolve(e,t){let n=this.pending.get(e);n&&(clearTimeout(n.timeoutId),this.pending.delete(e),n.resolve(t))}reject(e,t){let n=this.pending.get(e);n&&(clearTimeout(n.timeoutId),this.pending.delete(e),n.reject(t))}rejectAll(e){for(let t of this.pending.values())clearTimeout(t.timeoutId),t.reject(e);this.pending.clear()}};function n(e){if(e.port!=null)return`ws://localhost:${e.port}/ws`;if(typeof location<`u`&&location.host)return`ws://${location.host}/ws`;throw Error(`Port must be set for Node connection`)}var r=class{url;ws;handlers=new Map;pendingRequests=new t;options;status=`disconnected`;statusListeners=new Set;resolve;reject;connectionPromise=new Promise((e,t)=>{this.resolve=e,this.reject=t});backoff=this.createBackoff();constructor(e={}){this.options={autoreconnect:e.autoreconnect??!0,requestTimeout:e.requestTimeout??3e4,port:e.port},this.url=n(e)}createBackoff({min:e=1e3,max:t=32e3,factor:n=2}={}){let r=e;return{next(){let e=r;return r=Math.min(r*n,t),e},reset(){r=e}}}getStatus(){return this.status}onStatusChange(e){return this.statusListeners.add(e),()=>{this.statusListeners.delete(e)}}setStatus(e){if(this.status!==e){this.status=e;for(let t of this.statusListeners)t(e)}}reconnect(){this.status===`disconnected`&&this.connect()}connect(){this.setStatus(`connecting`),this.connectionPromise=new Promise((e,t)=>{this.resolve=e,this.reject=t}),this.ws?.close(),this.ws=new WebSocket(this.url),this.ws.onopen=()=>{this.setStatus(`connected`),this.resolve?.(),this.backoff.reset()},this.ws.onmessage=e=>{this.onMessage(e.data)},this.ws.onclose=()=>{this.setStatus(`disconnected`),this.pendingRequests.rejectAll(Error(`WebSocket connection closed`)),this.options.autoreconnect&&setTimeout(()=>this.reconnect(),this.backoff.next())},this.ws.onerror=e=>{console.error(`WebSocket error:`,e),this.reject?.(Error(`WebSocket error`))}}disableAutoreconnect(){this.options.autoreconnect=!1}close(){this.ws?.close()}async send(e){await this.connectionPromise,this.ws?.send(JSON.stringify(e))}async sendEvent(e){return this.send({type:`event`,event:e})}on(e,t){let n=this.handlers.get(e);n||(n=new Set,this.handlers.set(e,n));let r=t;return n.add(r),()=>{n.delete(r)}}onMessage(e){let t=JSON.parse(e);if(t.type===`response`&&t.requestId){this.pendingRequests.resolve(t.requestId,t.event);return}if(t.type===`event`){let e=this.handlers.get(t.event.event);if(e)for(let n of e)n(t.event)}}async request(e){let{id:t,promise:n}=this.pendingRequests.create(this.options.requestTimeout);try{await this.send({type:`request`,requestId:t,event:e})}catch(e){this.pendingRequests.reject(t,e instanceof Error?e:Error(String(e)))}return n}},i=class{options;handlers=new Map;pendingRequests=new t;isParent;target;boundHandleMessage;constructor(e={}){this.options={targetOrigin:`*`,timeout:5e3,debug:!1,...e},this.isParent=window.parent!==window,this.target=null,this.boundHandleMessage=this.handleMessage.bind(this),this.init()}init(){window.addEventListener(`message`,this.boundHandleMessage),this.options.debug&&console.log(`[IframeBridge] Initialized`,{isParent:this.isParent,targetOrigin:this.options.targetOrigin})}setTarget(e){e instanceof HTMLIFrameElement?this.target=e.contentWindow:console.error(`[IframeBridge] Invalid iframe element`)}getTargetWindow(){return this.isParent?window.parent:this.target?this.target:(console.error(`[IframeBridge] Target is not set. Call setTarget() on the parent window`),null)}handleMessage(e){if(this.options.targetOrigin!==`*`&&e.origin!==this.options.targetOrigin){this.options.debug&&console.warn(`[IframeBridge] Message from unknown origin:`,e.origin);return}let{type:t,payload:n,meta:r}=e.data;if(!t)return;if(this.options.debug&&console.log(`[IframeBridge] Received message:`,{type:t,payload:n,meta:r}),r?.isResponse&&r.requestId!==void 0){this.pendingRequests.resolve(r.requestId,n);return}let i=this.handlers.get(t);if(i)if(r?.isRequest&&r.requestId!==void 0){let{requestId:a}=r,o=e.source;i(n,e,e=>{this.sendResponse(t,a,e,o)})}else i(n,e)}send(e,t={}){let n=this.getTargetWindow();if(!n)return;let r={type:e,payload:t,meta:{timestamp:Date.now()}};n.postMessage(r,this.options.targetOrigin),this.options.debug&&console.log(`[IframeBridge] Sent message:`,r)}request(e,t,n=this.options.timeout){let r=this.getTargetWindow();if(!r)return Promise.reject(Error(`Target window not found`));let{id:i,promise:a}=this.pendingRequests.create(n),o={type:e,payload:t,meta:{requestId:i,isRequest:!0,timestamp:Date.now()}};return r.postMessage(o,this.options.targetOrigin),this.options.debug&&console.log(`[IframeBridge] Sent request:`,o),a}sendResponse(e,t,n,r){let i={type:e,payload:n,meta:{requestId:t,isResponse:!0,timestamp:Date.now()}};r.postMessage(i,this.options.targetOrigin),this.options.debug&&console.log(`[IframeBridge] Sent response:`,i)}on(e,t){return this.handlers.set(e,t),()=>this.off(e)}off(e){this.handlers.delete(e)}once(e,t){return this.on(e,(...n)=>{t(...n),this.off(e)})}destroy(){this.handlers.clear(),this.pendingRequests.rejectAll(Error(`Bridge destroyed`)),window.removeEventListener(`message`,this.boundHandleMessage),this.options.debug&&console.log(`[IframeBridge] Destroyed`)}};function a(e){try{return JSON.parse(e??`{}`)}catch(e){return console.error(e),{}}}function o(e){return JSON.stringify(e)}function s(e,t){return{get(){return e.request({name:t,event:`getPluginSettings`})},set(n){return e.sendEvent({name:t,event:`setPluginSettings`,payload:n})}}}var c=class{connection;bridge;params;saveHandler;constructor(){if(typeof window>`u`)throw Error(`Flux Deck Editor must be used only in plugin editor`);let e=new URLSearchParams(location.search),t=t=>{let n=e.get(t);if(n===null)throw Error(`${t} must be provided`);return n};this.params={id:t(`id`),group:t(`group`)},this.connection=new r,this.bridge=new i,this.bridge.on(`SAVE_ACTION_SETTINGS`,(e,t,n)=>{if(e.id==this.params.id&&this.saveHandler){let e=this.saveHandler();try{n?.({settings:o(e)})}catch(e){console.error(e),n?.({settings:null})}}})}connect(){this.connection.on(`sendToEditor`,e=>{this.onReceiveFromPluginListeners.forEach(t=>{t(e.payload)})}),this.connection.connect(),this.connection.sendEvent({event:`editorRegister`,payload:this.params.group})}onReceiveFromPluginListeners=new Set;onReceiveFromPlugin(e){return this.onReceiveFromPluginListeners.add(e),()=>{this.onReceiveFromPluginListeners.delete(e)}}sendToPlugin(e){this.connection.sendEvent({event:`sendToPlugin`,name:this.params.group,payload:e})}async getActionSettings(){return a((await this.bridge.request(`GET_ACTION_SETTINGS`,{id:this.params.id})).settings)}onActionSave(e){return this.saveHandler=e,()=>{this.saveHandler=void 0}}async getPluginSettings(){return await this.connection.request({name:this.params.group,event:`getPluginSettings`})}async setPluginSettings(e){return this.connection.sendEvent({name:this.params.group,event:`setPluginSettings`,payload:e})}},l=class{connection;actions=[];pluginName;constructor(){if(typeof process<`u`){this.pluginName=process?.argv[2];let e=Number(process?.argv[3]);this.connection=new r(Number.isNaN(e)?{}:{port:e})}else this.connection=new r}connect(){this.ensurePluginName(),this.connection.on(`trigger`,e=>{for(let t of this.actions)t.name==e.action.type&&t.onTrigger?.({trigger:e.kind,settings:a(e.action.settings)})}),this.connection.connect(),this.pluginName&&this.registerPlugin(this.pluginName)}ensurePluginName(){if(!this.pluginName)throw Error(`No plugin name`);return this.pluginName}registerPlugin(e){this.connection.sendEvent({event:`pluginRegister`,payload:e})}registerAction(e){this.actions.push(e)}async onPluginSettings(e){let t=this.ensurePluginName(),n=s(this.connection,t),r=this.connection.on(`setPluginSettings`,t=>{e(t.payload)});return e((await n.get()).payload),r}async onReceiveFromEditor(e){return this.connection.on(`sendToPlugin`,t=>{e(t.payload)})}sendToEditor(e){let t=this.ensurePluginName();this.connection.sendEvent({event:`sendToEditor`,name:t,payload:e})}async getPluginSettings(){let e=this.ensurePluginName();return s(this.connection,e).get()}async setPluginSettings(e){let t=this.ensurePluginName();return s(this.connection,t).set(e)}};const u=new l;export{r as Connection,c as Editor,i as IframeBridge,l as Plugin,u as fluxDeck};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["message: BridgeMessage<unknown>","message: BridgeMessage<EventRequests[T]>","message: BridgeMessage<EventResponses[T]>","wrappedHandler: MessageHandler<T>","Bridge"],"sources":["../src/bridge.ts","../src/connection.ts","../src/event-emitter.ts","../src/editor.ts","../src/plugin.ts"],"sourcesContent":["// Vibecoded by Claude\n\nimport type {\n BridgeOptions,\n MessageHandler,\n PendingRequest,\n BridgeMessage,\n EventRequests,\n ResponseFor,\n EventResponses,\n} from \"./types/bridge\";\n\nexport class Bridge<T extends keyof EventRequests = keyof EventRequests> {\n private options: Required<BridgeOptions>;\n private handlers: Map<string, MessageHandler<T>>;\n private pendingRequests: Map<number, PendingRequest<T>>;\n private requestId: number;\n private isParent: boolean;\n private target: Window | null;\n private boundHandleMessage: (event: MessageEvent) => void;\n\n constructor(options: BridgeOptions = {}) {\n this.options = {\n targetOrigin: \"*\",\n timeout: 5000,\n debug: false,\n ...options,\n };\n\n this.handlers = new Map();\n this.pendingRequests = new Map();\n this.requestId = 0;\n this.isParent = window.parent !== window;\n this.target = null;\n this.boundHandleMessage = this.handleMessage.bind(this);\n\n this.init();\n }\n\n private init(): void {\n window.addEventListener(\"message\", this.boundHandleMessage);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Инициализирован\", {\n isParent: this.isParent,\n targetOrigin: this.options.targetOrigin,\n });\n }\n }\n\n /**\n * Установить цель для отправки сообщений (для родительского окна)\n */\n setTarget(iframeElement: HTMLIFrameElement): void {\n if (iframeElement instanceof HTMLIFrameElement) {\n this.target = iframeElement.contentWindow;\n } else {\n console.error(\"[IframeBridge] Неверный элемент iframe\");\n }\n }\n\n /**\n * Получить целевое окно для отправки сообщений\n */\n private getTargetWindow(): Window | null {\n // Если мы внутри iframe - отправляем родителю\n if (this.isParent) {\n return window.parent;\n }\n\n // Если мы родитель - отправляем в iframe\n if (this.target) {\n return this.target;\n }\n\n console.error(\n \"[IframeBridge] Target не установлен. Используйте setTarget() для родительского окна\",\n );\n\n return null;\n }\n\n /**\n * Обработка входящих сообщений\n */\n private handleMessage(event: MessageEvent): void {\n // Проверка origin\n // TODO: not necessary to check origin\n if (\n this.options.targetOrigin !== \"*\" &&\n event.origin !== this.options.targetOrigin\n ) {\n if (this.options.debug) {\n console.warn(\n \"[IframeBridge] Сообщение от неизвестного origin:\",\n event.origin,\n );\n }\n return;\n }\n\n const data = event.data as BridgeMessage<unknown>;\n const { type, payload, meta } = data;\n\n if (!type) return;\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Получено сообщение:\", {\n type,\n payload,\n _meta: meta,\n });\n }\n\n // Если это ответ на запрос\n if (meta?.isResponse && meta?.requestId !== undefined) {\n this.handleResponse(meta.requestId, payload as ResponseFor<T>);\n return;\n }\n\n // Обработка обычного события\n const handler = this.handlers.get(type);\n if (handler) {\n // Если нужен ответ\n if (meta?.isRequest && meta?.requestId !== undefined) {\n const respond = (responsePayload: EventResponses[T]): void => {\n this.sendResponse(\n meta.requestId!,\n responsePayload,\n event.source as Window,\n );\n };\n handler(payload as EventRequests[T], event, respond);\n } else {\n handler(payload as EventRequests[T], event);\n }\n }\n }\n\n /**\n * Отправить сообщение\n */\n send(type: string, payload: unknown = {}): void {\n const targetWindow = this.getTargetWindow();\n if (!targetWindow) return;\n\n const message: BridgeMessage<unknown> = {\n type,\n payload,\n meta: {\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Отправлено сообщение:\", message);\n }\n }\n\n /**\n * Отправить запрос и ждать ответа\n */\n request(\n type: T,\n payload: EventRequests[T],\n timeout: number = this.options.timeout,\n ): Promise<ResponseFor<T>> {\n return new Promise((resolve, reject) => {\n const targetWindow = this.getTargetWindow();\n if (!targetWindow) {\n reject(new Error(\"Target window не найден\"));\n return;\n }\n\n const requestId = ++this.requestId;\n\n // Таймаут для запроса\n const timeoutId = window.setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(`Request timeout: ${type}`));\n }, timeout);\n\n // Сохраняем промис\n this.pendingRequests.set(requestId, {\n resolve,\n reject,\n timeoutId,\n });\n\n const message: BridgeMessage<EventRequests[T]> = {\n type,\n payload,\n meta: {\n requestId,\n isRequest: true,\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Отправлен запрос:\", message);\n }\n });\n }\n\n /**\n * Отправить ответ на запрос\n */\n private sendResponse(\n requestId: number,\n payload: EventResponses[T],\n targetWindow: Window,\n ): void {\n const message: BridgeMessage<EventResponses[T]> = {\n type: \"__response__\",\n payload,\n meta: {\n requestId,\n isResponse: true,\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Отправлен ответ:\", message);\n }\n }\n\n /**\n * Обработать ответ на запрос\n */\n private handleResponse(\n requestId: number,\n payload: ResponseFor<T>,\n error?: string | null,\n ): void {\n const pending = this.pendingRequests.get(requestId);\n if (!pending) return;\n\n clearTimeout(pending.timeoutId);\n this.pendingRequests.delete(requestId);\n\n if (error) {\n pending.reject(new Error(error));\n } else {\n pending.resolve(payload);\n }\n }\n\n /**\n * Подписаться на событие\n */\n on(type: T, handler: MessageHandler<T>): () => void {\n this.handlers.set(type, handler);\n return () => this.off(type);\n }\n\n /**\n * Отписаться от события\n */\n off(type: string): void {\n this.handlers.delete(type);\n }\n\n /**\n * Подписаться на событие один раз\n */\n once(type: T, handler: MessageHandler<T>): () => void {\n const wrappedHandler: MessageHandler<T> = (...args) => {\n handler(...args);\n this.off(type);\n };\n return this.on(type, wrappedHandler);\n }\n\n /**\n * Очистить все обработчики\n */\n destroy(): void {\n this.handlers.clear();\n this.pendingRequests.forEach(({ reject, timeoutId }) => {\n clearTimeout(timeoutId);\n reject(new Error(\"Bridge destroyed\"));\n });\n this.pendingRequests.clear();\n window.removeEventListener(\"message\", this.boundHandleMessage);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Уничтожен\");\n }\n }\n}\n\nexport default Bridge;\nexport type { BridgeOptions, MessageHandler, BridgeMessage };\n","import { nanoid } from \"nanoid\";\nimport type { WsClientMessage } from \"@fluxdeck/bindings/WsClientMessage\";\nimport type {\n EventHandlers,\n PendingRequests,\n Handler,\n ResponseFor,\n EventHandler,\n} from \"./types/connection\";\nimport type { ClientRequestEvent } from \"@fluxdeck/bindings/ClientRequestEvent\";\nimport type { WsServerMessage } from \"@fluxdeck/bindings/WsServerMessage\";\nimport type { ClientEvent } from \"@fluxdeck/bindings/ClientEvent\";\nimport type { ServerEvent } from \"@fluxdeck/bindings/ServerEvent\";\n\nfunction resolveUrl(options: ConnectionOptions): string {\n if (options.port != undefined) {\n return `ws://localhost:${options.port}/ws`;\n }\n\n if (typeof location !== \"undefined\" && location.host) {\n return `ws://${location.host}/ws`;\n }\n\n throw Error(\"Port must be set for Node connection\");\n}\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\ntype StatusListener = (status: ConnectionStatus) => void;\n\ntype ConnectionOptions = {\n autoreconnect?: boolean;\n requestTimeout?: number;\n port?: number;\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30000;\n\nexport class Connection {\n private url: string;\n\n private ws?: WebSocket;\n\n private handlers: EventHandlers = [];\n private pendingRequests: PendingRequests = new Map();\n\n private options: ConnectionOptions = {\n autoreconnect: true,\n requestTimeout: DEFAULT_REQUEST_TIMEOUT_MS,\n };\n\n private status: ConnectionStatus = \"disconnected\";\n private statusListeners = new Set<StatusListener>();\n\n private resolve?: () => void;\n private reject?: () => void;\n\n private connectionPromise: Promise<void> = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n\n private backoff = this.createBackoff();\n\n constructor(options: ConnectionOptions = {}) {\n for (const key in options) {\n const property = key as keyof ConnectionOptions;\n\n if (options[property] != undefined) {\n this.options[property] = options[property] as never;\n }\n }\n\n this.url = resolveUrl(options);\n }\n\n private createBackoff({ min = 1000, max = 32000, factor = 2 } = {}) {\n let delay = min;\n\n return {\n next() {\n const current = delay;\n delay = Math.min(delay * factor, max);\n return current;\n },\n reset() {\n delay = min;\n },\n };\n }\n\n getStatus(): ConnectionStatus {\n return this.status;\n }\n\n onStatusChange(listener: StatusListener): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n private setStatus(next: ConnectionStatus) {\n if (this.status === next) return;\n this.status = next;\n for (const listener of this.statusListeners) {\n listener(next);\n }\n }\n\n reconnect() {\n if (this.status === \"disconnected\") {\n this.connect();\n }\n }\n\n connect() {\n this.setStatus(\"connecting\");\n\n this.connectionPromise = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n\n this.ws?.close();\n this.ws = new WebSocket(this.url);\n\n this.ws.onopen = () => {\n this.setStatus(\"connected\");\n\n this.resolve?.();\n this.backoff.reset();\n };\n\n this.ws.onmessage = (event) => {\n this.onMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this.setStatus(\"disconnected\");\n this.failPendingRequests(new Error(\"WebSocket connection closed\"));\n\n if (this.options.autoreconnect) {\n setTimeout(() => this.reconnect(), this.backoff.next());\n }\n };\n\n this.ws.onerror = (err) => {\n console.error(\"WebSocket error:\", err);\n this.reject?.();\n };\n }\n\n private failPendingRequests(error: Error) {\n for (const pending of this.pendingRequests.values()) {\n clearTimeout(pending.timeoutId);\n pending.reject(error);\n }\n\n this.pendingRequests.clear();\n }\n\n close() {\n this.ws?.close();\n }\n\n private async send(msg: WsClientMessage): Promise<void> {\n await this.connectionPromise;\n this.ws?.send(JSON.stringify(msg));\n }\n\n async sendEvent(event: ClientEvent): Promise<void> {\n return this.send({ type: \"event\", event });\n }\n\n on<T extends ServerEvent[\"event\"]>(\n event: T,\n handler: Handler<T>,\n ): () => void {\n const eventHandler = { event, handler } as unknown as EventHandler<\n ServerEvent[\"event\"]\n >;\n\n this.handlers.push(eventHandler);\n\n return () => {\n this.handlers = this.handlers.filter((value) => value !== eventHandler);\n };\n }\n\n private onMessage(raw: string) {\n const msg = JSON.parse(raw) as WsServerMessage;\n\n if (msg.type === \"response\" && msg.requestId) {\n const pending = this.pendingRequests.get(msg.requestId);\n\n if (pending) {\n clearTimeout(pending.timeoutId);\n this.pendingRequests.delete(msg.requestId);\n pending.resolve(msg.event);\n }\n\n return;\n }\n\n if (msg.type === \"event\") {\n const handlers = this.handlers.filter(\n (value) => value.event == msg.event.event,\n );\n\n for (const eventHandler of handlers) {\n eventHandler.handler(msg.event);\n }\n }\n }\n\n async request<E extends ClientRequestEvent>(\n event: E,\n ): Promise<ResponseFor<E[\"event\"]>> {\n const requestId = nanoid();\n\n const promise = new Promise<ResponseFor<E[\"event\"]>>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(`Request timeout: ${event.event}`));\n }, this.options.requestTimeout);\n\n this.pendingRequests.set(requestId, {\n resolve: (value) => resolve(value as ResponseFor<E[\"event\"]>),\n reject,\n timeoutId,\n });\n });\n\n try {\n await this.send({\n type: \"request\",\n requestId,\n event,\n });\n } catch (err) {\n const pending = this.pendingRequests.get(requestId);\n if (pending) {\n clearTimeout(pending.timeoutId);\n this.pendingRequests.delete(requestId);\n pending.reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n return promise;\n }\n}\n","import type { ServerEvent } from \"@fluxdeck/bindings/ServerEvent\";\n\nexport type Listener<T> = (payload: T) => void;\n\nexport class EventEmitter {\n private listeners: Record<string, Listener<unknown>[]> = {};\n\n emit(event: string, data: unknown) {\n for (const listener of this.listeners[event] ?? []) {\n listener(data);\n }\n }\n\n on(event: ServerEvent[\"event\"], listener: Listener<unknown>) {\n const listeners = this.listeners[event] ?? [];\n listeners.push(listener);\n this.listeners[event] = listeners;\n return () => {\n this.listeners[event] =\n this.listeners[event]?.filter((cb) => cb !== listener) ?? [];\n };\n }\n}\n","import type { JsonValue } from \"@fluxdeck/bindings/JsonValue\";\nimport Bridge from \"./bridge\";\nimport { Connection } from \"./connection\";\nimport { EventEmitter, Listener } from \"./event-emitter\";\n\ntype SaveHandler = () => unknown;\n\ntype EditorParams = {\n id: string;\n group: string;\n};\n\nexport class Editor {\n private connection: Connection;\n private bridge: Bridge;\n private params: EditorParams;\n private saveHandler?: SaveHandler;\n private eventEmitter = new EventEmitter();\n\n constructor() {\n if (typeof window === \"undefined\") {\n throw Error(\"Flux Deck Editor must be used only in plugin editor\");\n }\n\n const urlParams = new URLSearchParams(location.search);\n\n const getStringParam = (key: string): string => {\n const value = urlParams.get(key);\n\n if (value === null) {\n throw Error(`${key} must be provided`);\n }\n\n return value;\n };\n\n this.params = {\n id: getStringParam(\"id\"),\n group: getStringParam(\"group\"),\n };\n\n this.connection = new Connection();\n this.connection.connect();\n\n this.connection.sendEvent({\n event: \"editorRegister\",\n payload: this.params.group,\n });\n\n this.connection.on(\"sendToEditor\", (data) => {\n this.eventEmitter.emit(\"sendToEditor\", data.payload);\n });\n\n this.bridge = new Bridge();\n this.bridge.on(\"SET_ACTION_SETTINGS\", (payload, _event, respond) => {\n if (payload.id == this.params.id && this.saveHandler) {\n const settings = this.saveHandler();\n\n try {\n const string = JSON.stringify(settings);\n respond?.({ settings: string });\n } catch (err) {\n console.error(err);\n respond?.({ settings: null });\n }\n }\n });\n }\n\n async onRecieveFromPlugin<T>(listener: Listener<T>) {\n return this.eventEmitter.on(\"sendToEditor\", listener as Listener<unknown>);\n }\n\n sendToPlugin<T extends JsonValue>(data: T) {\n this.connection.sendEvent({\n event: \"sendToPlugin\",\n name: this.params.group,\n payload: data,\n });\n }\n\n async getActionSettings(): Promise<JsonValue> {\n const parse = (data: string | null) => {\n try {\n if (typeof data == \"string\") {\n return JSON.parse(data);\n } else {\n return {};\n }\n } catch (err) {\n console.error(err);\n return {};\n }\n };\n\n const response = await this.bridge.request(\"GET_ACTION_SETTINGS\", {\n id: this.params.id,\n });\n\n return parse(response.settings);\n }\n\n onActionSave(handler: SaveHandler) {\n this.saveHandler = handler;\n\n return () => {\n this.saveHandler = undefined;\n };\n }\n\n async getPluginSettings() {\n return await this.connection.request({\n name: this.params.group,\n event: \"getPluginSettings\",\n });\n }\n\n async setPluginSettings(data: JsonValue) {\n return this.connection.sendEvent({\n name: this.params.group,\n event: \"setPluginSettings\",\n payload: data,\n });\n }\n}\n","import type { JsonValue } from \"@fluxdeck/bindings/JsonValue\";\nimport { Connection } from \"./connection\";\nimport { EventEmitter, Listener } from \"./event-emitter\";\n\nexport type ActionData<T> = {\n trigger: string;\n settings: T;\n};\n\nexport interface Action<T> {\n name: string;\n onTrigger?: (data: ActionData<T>) => void;\n}\n\nexport class FluxDeck {\n private connection: Connection;\n private actions: Action<unknown>[] = [];\n\n private pluginName?: string;\n\n private eventEmitter = new EventEmitter();\n\n constructor() {\n if (typeof process != \"undefined\") {\n this.pluginName = process?.argv[2];\n\n const port = Number(process?.argv[3]);\n this.connection = new Connection(\n Number.isNaN(port) ? {} : { port },\n );\n } else {\n this.connection = new Connection();\n }\n }\n\n connect() {\n if (typeof process != \"undefined\" && !this.pluginName) {\n throw Error(\"No plugin name\");\n }\n\n this.connection.on(\"trigger\", (data) => {\n for (const action of this.actions) {\n if (action.name == data.action.type) {\n action.onTrigger?.({\n trigger: data.kind,\n settings: this.parseSettings(data.action.settings),\n });\n }\n }\n });\n\n this.connection.on(\"setPluginSettings\", (data) => {\n this.eventEmitter.emit(\"setPluginSettings\", data.payload);\n });\n\n this.connection.on(\"sendToPlugin\", (data) => {\n this.eventEmitter.emit(\"sendToPlugin\", data.payload);\n });\n\n this.connection.connect();\n\n if (this.pluginName) {\n this.registerPlugin(this.pluginName);\n }\n }\n\n private parseSettings(str: string | null) {\n try {\n return JSON.parse(str ?? \"{}\");\n } catch (err) {\n console.error(err);\n return {};\n }\n }\n\n private registerPlugin(name: string) {\n this.connection.sendEvent({ event: \"pluginRegister\", payload: name });\n }\n\n registerAction<T>(action: Action<T>) {\n this.actions.push(action as Action<unknown>);\n }\n\n async onSetSettings<T>(listener: Listener<T>) {\n const on = this.eventEmitter.on(\n \"setPluginSettings\",\n listener as Listener<unknown>,\n );\n const settings = await this.getPluginSettings();\n listener(settings.payload as T);\n return on;\n }\n\n async onRecieveFromEditor<T>(listener: Listener<T>) {\n return this.eventEmitter.on(\"sendToPlugin\", listener as Listener<unknown>);\n }\n\n sendToEditor<T extends JsonValue>(data: T) {\n if (!this.pluginName) {\n throw Error(\"No plugin name\");\n }\n\n this.connection.sendEvent({\n event: \"sendToEditor\",\n name: this.pluginName,\n payload: data,\n });\n }\n\n async getPluginSettings() {\n if (!this.pluginName) {\n throw Error(\"No plugin name\");\n }\n\n return this.connection.request({\n name: this.pluginName,\n event: \"getPluginSettings\",\n });\n }\n\n async setPluginSettings<T extends JsonValue>(data: T) {\n if (!this.pluginName) {\n throw Error(\"No plugin name\");\n }\n\n return this.connection.sendEvent({\n name: this.pluginName,\n event: \"setPluginSettings\",\n payload: data,\n });\n }\n}\n\nexport const fluxDeck = new FluxDeck();\n"],"mappings":"gCAYA,IAAa,EAAb,KAAyE,CACvE,QACA,SACA,gBACA,UACA,SACA,OACA,mBAEA,YAAY,EAAyB,EAAE,CAAE,CACvC,KAAK,QAAU,CACb,aAAc,IACd,QAAS,IACT,MAAO,GACP,GAAG,EACJ,CAED,KAAK,SAAW,IAAI,IACpB,KAAK,gBAAkB,IAAI,IAC3B,KAAK,UAAY,EACjB,KAAK,SAAW,OAAO,SAAW,OAClC,KAAK,OAAS,KACd,KAAK,mBAAqB,KAAK,cAAc,KAAK,KAAK,CAEvD,KAAK,MAAM,CAGb,MAAqB,CACnB,OAAO,iBAAiB,UAAW,KAAK,mBAAmB,CAEvD,KAAK,QAAQ,OACf,QAAQ,IAAI,iCAAkC,CAC5C,SAAU,KAAK,SACf,aAAc,KAAK,QAAQ,aAC5B,CAAC,CAON,UAAU,EAAwC,CAC5C,aAAyB,kBAC3B,KAAK,OAAS,EAAc,cAE5B,QAAQ,MAAM,yCAAyC,CAO3D,iBAAyC,CAevC,OAbI,KAAK,SACA,OAAO,OAIZ,KAAK,OACA,KAAK,QAGd,QAAQ,MACN,sFACD,CAEM,MAMT,cAAsB,EAA2B,CAG/C,GACE,KAAK,QAAQ,eAAiB,KAC9B,EAAM,SAAW,KAAK,QAAQ,aAC9B,CACI,KAAK,QAAQ,OACf,QAAQ,KACN,mDACA,EAAM,OACP,CAEH,OAIF,GAAM,CAAE,OAAM,UAAS,QADV,EAAM,KAGnB,GAAI,CAAC,EAAM,OAWX,GATI,KAAK,QAAQ,OACf,QAAQ,IAAI,qCAAsC,CAChD,OACA,UACA,MAAO,EACR,CAAC,CAIA,GAAM,YAAc,GAAM,YAAc,IAAA,GAAW,CACrD,KAAK,eAAe,EAAK,UAAW,EAA0B,CAC9D,OAIF,IAAM,EAAU,KAAK,SAAS,IAAI,EAAK,CACnC,IAEE,GAAM,WAAa,GAAM,YAAc,IAAA,GAQzC,EAAQ,EAA6B,EAPpB,GAA6C,CAC5D,KAAK,aACH,EAAK,UACL,EACA,EAAM,OACP,EAEiD,CAEpD,EAAQ,EAA6B,EAAM,EAQjD,KAAK,EAAc,EAAmB,EAAE,CAAQ,CAC9C,IAAM,EAAe,KAAK,iBAAiB,CAC3C,GAAI,CAAC,EAAc,OAEnB,IAAMA,EAAkC,CACtC,OACA,UACA,KAAM,CACJ,UAAW,KAAK,KAAK,CACtB,CACF,CAED,EAAa,YAAY,EAAS,KAAK,QAAQ,aAAa,CAExD,KAAK,QAAQ,OACf,QAAQ,IAAI,uCAAwC,EAAQ,CAOhE,QACE,EACA,EACA,EAAkB,KAAK,QAAQ,QACN,CACzB,OAAO,IAAI,SAAS,EAAS,IAAW,CACtC,IAAM,EAAe,KAAK,iBAAiB,CAC3C,GAAI,CAAC,EAAc,CACjB,EAAW,MAAM,0BAA0B,CAAC,CAC5C,OAGF,IAAM,EAAY,EAAE,KAAK,UAGnB,EAAY,OAAO,eAAiB,CACxC,KAAK,gBAAgB,OAAO,EAAU,CACtC,EAAW,MAAM,oBAAoB,IAAO,CAAC,EAC5C,EAAQ,CAGX,KAAK,gBAAgB,IAAI,EAAW,CAClC,UACA,SACA,YACD,CAAC,CAEF,IAAMC,EAA2C,CAC/C,OACA,UACA,KAAM,CACJ,YACA,UAAW,GACX,UAAW,KAAK,KAAK,CACtB,CACF,CAED,EAAa,YAAY,EAAS,KAAK,QAAQ,aAAa,CAExD,KAAK,QAAQ,OACf,QAAQ,IAAI,mCAAoC,EAAQ,EAE1D,CAMJ,aACE,EACA,EACA,EACM,CACN,IAAMC,EAA4C,CAChD,KAAM,eACN,UACA,KAAM,CACJ,YACA,WAAY,GACZ,UAAW,KAAK,KAAK,CACtB,CACF,CAED,EAAa,YAAY,EAAS,KAAK,QAAQ,aAAa,CAExD,KAAK,QAAQ,OACf,QAAQ,IAAI,kCAAmC,EAAQ,CAO3D,eACE,EACA,EACA,EACM,CACN,IAAM,EAAU,KAAK,gBAAgB,IAAI,EAAU,CAC9C,IAEL,aAAa,EAAQ,UAAU,CAC/B,KAAK,gBAAgB,OAAO,EAAU,CAElC,EACF,EAAQ,OAAW,MAAM,EAAM,CAAC,CAEhC,EAAQ,QAAQ,EAAQ,EAO5B,GAAG,EAAS,EAAwC,CAElD,OADA,KAAK,SAAS,IAAI,EAAM,EAAQ,KACnB,KAAK,IAAI,EAAK,CAM7B,IAAI,EAAoB,CACtB,KAAK,SAAS,OAAO,EAAK,CAM5B,KAAK,EAAS,EAAwC,CAKpD,OAAO,KAAK,GAAG,GAJ4B,GAAG,IAAS,CACrD,EAAQ,GAAG,EAAK,CAChB,KAAK,IAAI,EAAK,EAEoB,CAMtC,SAAgB,CACd,KAAK,SAAS,OAAO,CACrB,KAAK,gBAAgB,SAAS,CAAE,SAAQ,eAAgB,CACtD,aAAa,EAAU,CACvB,EAAW,MAAM,mBAAmB,CAAC,EACrC,CACF,KAAK,gBAAgB,OAAO,CAC5B,OAAO,oBAAoB,UAAW,KAAK,mBAAmB,CAE1D,KAAK,QAAQ,OACf,QAAQ,IAAI,2BAA2B,GAK7C,EAAe,EC7Rf,SAAS,EAAW,EAAoC,CACtD,GAAI,EAAQ,MAAQ,KAClB,MAAO,kBAAkB,EAAQ,KAAK,KAGxC,GAAI,OAAO,SAAa,KAAe,SAAS,KAC9C,MAAO,QAAQ,SAAS,KAAK,KAG/B,MAAM,MAAM,uCAAuC,CAerD,IAAa,EAAb,KAAwB,CACtB,IAEA,GAEA,SAAkC,EAAE,CACpC,gBAA2C,IAAI,IAE/C,QAAqC,CACnC,cAAe,GACf,eAAgB,IACjB,CAED,OAAmC,eACnC,gBAA0B,IAAI,IAE9B,QACA,OAEA,kBAA2C,IAAI,SAAS,EAAS,IAAW,CAC1E,KAAK,QAAU,EACf,KAAK,OAAS,GACd,CAEF,QAAkB,KAAK,eAAe,CAEtC,YAAY,EAA6B,EAAE,CAAE,CAC3C,IAAK,IAAM,KAAO,EAAS,CACzB,IAAM,EAAW,EAEb,EAAQ,IAAa,OACvB,KAAK,QAAQ,GAAY,EAAQ,IAIrC,KAAK,IAAM,EAAW,EAAQ,CAGhC,cAAsB,CAAE,MAAM,IAAM,MAAM,KAAO,SAAS,GAAM,EAAE,CAAE,CAClE,IAAI,EAAQ,EAEZ,MAAO,CACL,MAAO,CACL,IAAM,EAAU,EAEhB,MADA,GAAQ,KAAK,IAAI,EAAQ,EAAQ,EAAI,CAC9B,GAET,OAAQ,CACN,EAAQ,GAEX,CAGH,WAA8B,CAC5B,OAAO,KAAK,OAGd,eAAe,EAAsC,CAEnD,OADA,KAAK,gBAAgB,IAAI,EAAS,KACrB,CACX,KAAK,gBAAgB,OAAO,EAAS,EAIzC,UAAkB,EAAwB,CACpC,QAAK,SAAW,EACpB,MAAK,OAAS,EACd,IAAK,IAAM,KAAY,KAAK,gBAC1B,EAAS,EAAK,EAIlB,WAAY,CACN,KAAK,SAAW,gBAClB,KAAK,SAAS,CAIlB,SAAU,CACR,KAAK,UAAU,aAAa,CAE5B,KAAK,kBAAoB,IAAI,SAAS,EAAS,IAAW,CACxD,KAAK,QAAU,EACf,KAAK,OAAS,GACd,CAEF,KAAK,IAAI,OAAO,CAChB,KAAK,GAAK,IAAI,UAAU,KAAK,IAAI,CAEjC,KAAK,GAAG,WAAe,CACrB,KAAK,UAAU,YAAY,CAE3B,KAAK,WAAW,CAChB,KAAK,QAAQ,OAAO,EAGtB,KAAK,GAAG,UAAa,GAAU,CAC7B,KAAK,UAAU,EAAM,KAAK,EAG5B,KAAK,GAAG,YAAgB,CACtB,KAAK,UAAU,eAAe,CAC9B,KAAK,oBAAwB,MAAM,8BAA8B,CAAC,CAE9D,KAAK,QAAQ,eACf,eAAiB,KAAK,WAAW,CAAE,KAAK,QAAQ,MAAM,CAAC,EAI3D,KAAK,GAAG,QAAW,GAAQ,CACzB,QAAQ,MAAM,mBAAoB,EAAI,CACtC,KAAK,UAAU,EAInB,oBAA4B,EAAc,CACxC,IAAK,IAAM,KAAW,KAAK,gBAAgB,QAAQ,CACjD,aAAa,EAAQ,UAAU,CAC/B,EAAQ,OAAO,EAAM,CAGvB,KAAK,gBAAgB,OAAO,CAG9B,OAAQ,CACN,KAAK,IAAI,OAAO,CAGlB,MAAc,KAAK,EAAqC,CACtD,MAAM,KAAK,kBACX,KAAK,IAAI,KAAK,KAAK,UAAU,EAAI,CAAC,CAGpC,MAAM,UAAU,EAAmC,CACjD,OAAO,KAAK,KAAK,CAAE,KAAM,QAAS,QAAO,CAAC,CAG5C,GACE,EACA,EACY,CACZ,IAAM,EAAe,CAAE,QAAO,UAAS,CAMvC,OAFA,KAAK,SAAS,KAAK,EAAa,KAEnB,CACX,KAAK,SAAW,KAAK,SAAS,OAAQ,GAAU,IAAU,EAAa,EAI3E,UAAkB,EAAa,CAC7B,IAAM,EAAM,KAAK,MAAM,EAAI,CAE3B,GAAI,EAAI,OAAS,YAAc,EAAI,UAAW,CAC5C,IAAM,EAAU,KAAK,gBAAgB,IAAI,EAAI,UAAU,CAEnD,IACF,aAAa,EAAQ,UAAU,CAC/B,KAAK,gBAAgB,OAAO,EAAI,UAAU,CAC1C,EAAQ,QAAQ,EAAI,MAAM,EAG5B,OAGF,GAAI,EAAI,OAAS,QAAS,CACxB,IAAM,EAAW,KAAK,SAAS,OAC5B,GAAU,EAAM,OAAS,EAAI,MAAM,MACrC,CAED,IAAK,IAAM,KAAgB,EACzB,EAAa,QAAQ,EAAI,MAAM,EAKrC,MAAM,QACJ,EACkC,CAClC,IAAM,EAAY,GAAQ,CAEpB,EAAU,IAAI,SAAkC,EAAS,IAAW,CACxE,IAAM,EAAY,eAAiB,CACjC,KAAK,gBAAgB,OAAO,EAAU,CACtC,EAAW,MAAM,oBAAoB,EAAM,QAAQ,CAAC,EACnD,KAAK,QAAQ,eAAe,CAE/B,KAAK,gBAAgB,IAAI,EAAW,CAClC,QAAU,GAAU,EAAQ,EAAiC,CAC7D,SACA,YACD,CAAC,EACF,CAEF,GAAI,CACF,MAAM,KAAK,KAAK,CACd,KAAM,UACN,YACA,QACD,CAAC,OACK,EAAK,CACZ,IAAM,EAAU,KAAK,gBAAgB,IAAI,EAAU,CAC/C,IACF,aAAa,EAAQ,UAAU,CAC/B,KAAK,gBAAgB,OAAO,EAAU,CACtC,EAAQ,OAAO,aAAe,MAAQ,EAAU,MAAM,OAAO,EAAI,CAAC,CAAC,EAIvE,OAAO,ICrPE,EAAb,KAA0B,CACxB,UAAyD,EAAE,CAE3D,KAAK,EAAe,EAAe,CACjC,IAAK,IAAM,KAAY,KAAK,UAAU,IAAU,EAAE,CAChD,EAAS,EAAK,CAIlB,GAAG,EAA6B,EAA6B,CAC3D,IAAM,EAAY,KAAK,UAAU,IAAU,EAAE,CAG7C,OAFA,EAAU,KAAK,EAAS,CACxB,KAAK,UAAU,GAAS,MACX,CACX,KAAK,UAAU,GACb,KAAK,UAAU,IAAQ,OAAQ,GAAO,IAAO,EAAS,EAAI,EAAE,ICPvD,EAAb,KAAoB,CAClB,WACA,OACA,OACA,YACA,aAAuB,IAAI,EAE3B,aAAc,CACZ,GAAI,OAAO,OAAW,IACpB,MAAM,MAAM,sDAAsD,CAGpE,IAAM,EAAY,IAAI,gBAAgB,SAAS,OAAO,CAEhD,EAAkB,GAAwB,CAC9C,IAAM,EAAQ,EAAU,IAAI,EAAI,CAEhC,GAAI,IAAU,KACZ,MAAM,MAAM,GAAG,EAAI,mBAAmB,CAGxC,OAAO,GAGT,KAAK,OAAS,CACZ,GAAI,EAAe,KAAK,CACxB,MAAO,EAAe,QAAQ,CAC/B,CAED,KAAK,WAAa,IAAI,EACtB,KAAK,WAAW,SAAS,CAEzB,KAAK,WAAW,UAAU,CACxB,MAAO,iBACP,QAAS,KAAK,OAAO,MACtB,CAAC,CAEF,KAAK,WAAW,GAAG,eAAiB,GAAS,CAC3C,KAAK,aAAa,KAAK,eAAgB,EAAK,QAAQ,EACpD,CAEF,KAAK,OAAS,IAAIE,EAClB,KAAK,OAAO,GAAG,uBAAwB,EAAS,EAAQ,IAAY,CAClE,GAAI,EAAQ,IAAM,KAAK,OAAO,IAAM,KAAK,YAAa,CACpD,IAAM,EAAW,KAAK,aAAa,CAEnC,GAAI,CACF,IAAM,EAAS,KAAK,UAAU,EAAS,CACvC,IAAU,CAAE,SAAU,EAAQ,CAAC,OACxB,EAAK,CACZ,QAAQ,MAAM,EAAI,CAClB,IAAU,CAAE,SAAU,KAAM,CAAC,IAGjC,CAGJ,MAAM,oBAAuB,EAAuB,CAClD,OAAO,KAAK,aAAa,GAAG,eAAgB,EAA8B,CAG5E,aAAkC,EAAS,CACzC,KAAK,WAAW,UAAU,CACxB,MAAO,eACP,KAAM,KAAK,OAAO,MAClB,QAAS,EACV,CAAC,CAGJ,MAAM,mBAAwC,CAkB5C,OAjBe,GAAwB,CACrC,GAAI,CAIA,OAHE,OAAO,GAAQ,SACV,KAAK,MAAM,EAAK,CAEhB,EAAE,OAEJ,EAAK,CAEZ,OADA,QAAQ,MAAM,EAAI,CACX,EAAE,KAII,MAAM,KAAK,OAAO,QAAQ,sBAAuB,CAChE,GAAI,KAAK,OAAO,GACjB,CAAC,EAEoB,SAAS,CAGjC,aAAa,EAAsB,CAGjC,MAFA,MAAK,YAAc,MAEN,CACX,KAAK,YAAc,IAAA,IAIvB,MAAM,mBAAoB,CACxB,OAAO,MAAM,KAAK,WAAW,QAAQ,CACnC,KAAM,KAAK,OAAO,MAClB,MAAO,oBACR,CAAC,CAGJ,MAAM,kBAAkB,EAAiB,CACvC,OAAO,KAAK,WAAW,UAAU,CAC/B,KAAM,KAAK,OAAO,MAClB,MAAO,oBACP,QAAS,EACV,CAAC,GC5GO,EAAb,KAAsB,CACpB,WACA,QAAqC,EAAE,CAEvC,WAEA,aAAuB,IAAI,EAE3B,aAAc,CACZ,GAAI,OAAO,QAAW,IAAa,CACjC,KAAK,WAAa,SAAS,KAAK,GAEhC,IAAM,EAAO,OAAO,SAAS,KAAK,GAAG,CACrC,KAAK,WAAa,IAAI,EACpB,OAAO,MAAM,EAAK,CAAG,EAAE,CAAG,CAAE,OAAM,CACnC,MAED,KAAK,WAAa,IAAI,EAI1B,SAAU,CACR,GAAI,OAAO,QAAW,KAAe,CAAC,KAAK,WACzC,MAAM,MAAM,iBAAiB,CAG/B,KAAK,WAAW,GAAG,UAAY,GAAS,CACtC,IAAK,IAAM,KAAU,KAAK,QACpB,EAAO,MAAQ,EAAK,OAAO,MAC7B,EAAO,YAAY,CACjB,QAAS,EAAK,KACd,SAAU,KAAK,cAAc,EAAK,OAAO,SAAS,CACnD,CAAC,EAGN,CAEF,KAAK,WAAW,GAAG,oBAAsB,GAAS,CAChD,KAAK,aAAa,KAAK,oBAAqB,EAAK,QAAQ,EACzD,CAEF,KAAK,WAAW,GAAG,eAAiB,GAAS,CAC3C,KAAK,aAAa,KAAK,eAAgB,EAAK,QAAQ,EACpD,CAEF,KAAK,WAAW,SAAS,CAErB,KAAK,YACP,KAAK,eAAe,KAAK,WAAW,CAIxC,cAAsB,EAAoB,CACxC,GAAI,CACF,OAAO,KAAK,MAAM,GAAO,KAAK,OACvB,EAAK,CAEZ,OADA,QAAQ,MAAM,EAAI,CACX,EAAE,EAIb,eAAuB,EAAc,CACnC,KAAK,WAAW,UAAU,CAAE,MAAO,iBAAkB,QAAS,EAAM,CAAC,CAGvE,eAAkB,EAAmB,CACnC,KAAK,QAAQ,KAAK,EAA0B,CAG9C,MAAM,cAAiB,EAAuB,CAC5C,IAAM,EAAK,KAAK,aAAa,GAC3B,oBACA,EACD,CAGD,OADA,GADiB,MAAM,KAAK,mBAAmB,EAC7B,QAAa,CACxB,EAGT,MAAM,oBAAuB,EAAuB,CAClD,OAAO,KAAK,aAAa,GAAG,eAAgB,EAA8B,CAG5E,aAAkC,EAAS,CACzC,GAAI,CAAC,KAAK,WACR,MAAM,MAAM,iBAAiB,CAG/B,KAAK,WAAW,UAAU,CACxB,MAAO,eACP,KAAM,KAAK,WACX,QAAS,EACV,CAAC,CAGJ,MAAM,mBAAoB,CACxB,GAAI,CAAC,KAAK,WACR,MAAM,MAAM,iBAAiB,CAG/B,OAAO,KAAK,WAAW,QAAQ,CAC7B,KAAM,KAAK,WACX,MAAO,oBACR,CAAC,CAGJ,MAAM,kBAAuC,EAAS,CACpD,GAAI,CAAC,KAAK,WACR,MAAM,MAAM,iBAAiB,CAG/B,OAAO,KAAK,WAAW,UAAU,CAC/B,KAAM,KAAK,WACX,MAAO,oBACP,QAAS,EACV,CAAC,GAIN,MAAa,EAAW,IAAI"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["message: BridgeMessage<unknown>","message: BridgeMessage<BridgeRequests[K]>","wrappedHandler: MessageHandler<K>"],"sources":["../src/pending-requests.ts","../src/connection.ts","../src/iframe-bridge.ts","../src/settings.ts","../src/editor.ts","../src/plugin.ts"],"sourcesContent":["import { nanoid } from \"nanoid\";\n\ntype PendingEntry = {\n resolve: (value: unknown) => void;\n reject: (reason: Error) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n};\n\nexport class PendingRequests {\n private pending = new Map<string, PendingEntry>();\n\n create<R>(timeoutMs: number): { id: string; promise: Promise<R> } {\n const id = nanoid();\n\n const promise = new Promise<R>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(\"Request timed out\"));\n }, timeoutMs);\n\n this.pending.set(id, {\n resolve: (value) => resolve(value as R),\n reject,\n timeoutId,\n });\n });\n\n return { id, promise };\n }\n\n resolve(id: string, value: unknown): void {\n const entry = this.pending.get(id);\n if (!entry) return;\n\n clearTimeout(entry.timeoutId);\n this.pending.delete(id);\n entry.resolve(value);\n }\n\n reject(id: string, error: Error): void {\n const entry = this.pending.get(id);\n if (!entry) return;\n\n clearTimeout(entry.timeoutId);\n this.pending.delete(id);\n entry.reject(error);\n }\n\n rejectAll(error: Error): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timeoutId);\n entry.reject(error);\n }\n\n this.pending.clear();\n }\n}\n","import type { WsClientMessage } from \"@fluxdeck/bindings/WsClientMessage\";\nimport type { ClientRequestEvent } from \"@fluxdeck/bindings/ClientRequestEvent\";\nimport type { WsServerMessage } from \"@fluxdeck/bindings/WsServerMessage\";\nimport type { ClientEvent } from \"@fluxdeck/bindings/ClientEvent\";\nimport type { ServerEvent } from \"@fluxdeck/bindings/ServerEvent\";\nimport type { ServerResponseEvent } from \"@fluxdeck/bindings/ServerResponseEvent\";\nimport { PendingRequests } from \"./pending-requests\";\n\nexport type Handler<T extends ServerEvent[\"event\"]> = (\n data: Extract<ServerEvent, { event: T }>,\n) => void;\n\nexport type ResponseFor<T extends ClientRequestEvent[\"event\"]> = Extract<\n ServerResponseEvent,\n { event: T }\n>;\n\ntype ConnectionOptions = {\n autoreconnect?: boolean;\n requestTimeout?: number;\n port?: number;\n};\n\nexport type ConnectionStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\ntype StatusListener = (status: ConnectionStatus) => void;\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 30000;\n\nfunction resolveUrl(options: ConnectionOptions): string {\n if (options.port != undefined) {\n return `ws://localhost:${options.port}/ws`;\n }\n\n if (typeof location !== \"undefined\" && location.host) {\n return `ws://${location.host}/ws`;\n }\n\n throw Error(\"Port must be set for Node connection\");\n}\n\nexport class Connection {\n private url: string;\n\n private ws?: WebSocket;\n\n private handlers = new Map<string, Set<Handler<ServerEvent[\"event\"]>>>();\n private pendingRequests = new PendingRequests();\n\n private options: {\n autoreconnect: boolean;\n requestTimeout: number;\n port?: number;\n };\n\n private status: ConnectionStatus = \"disconnected\";\n private statusListeners = new Set<StatusListener>();\n\n private resolve?: () => void;\n private reject?: (error: Error) => void;\n\n private connectionPromise: Promise<void> = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n\n private backoff = this.createBackoff();\n\n constructor(options: ConnectionOptions = {}) {\n this.options = {\n autoreconnect: options.autoreconnect ?? true,\n requestTimeout: options.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT_MS,\n port: options.port,\n };\n\n this.url = resolveUrl(options);\n }\n\n private createBackoff({ min = 1000, max = 32000, factor = 2 } = {}) {\n let delay = min;\n\n return {\n next() {\n const current = delay;\n delay = Math.min(delay * factor, max);\n return current;\n },\n reset() {\n delay = min;\n },\n };\n }\n\n getStatus(): ConnectionStatus {\n return this.status;\n }\n\n onStatusChange(listener: StatusListener): () => void {\n this.statusListeners.add(listener);\n return () => {\n this.statusListeners.delete(listener);\n };\n }\n\n private setStatus(next: ConnectionStatus) {\n if (this.status === next) return;\n this.status = next;\n for (const listener of this.statusListeners) {\n listener(next);\n }\n }\n\n reconnect() {\n if (this.status === \"disconnected\") {\n this.connect();\n }\n }\n\n connect() {\n this.setStatus(\"connecting\");\n\n this.connectionPromise = new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n\n this.ws?.close();\n this.ws = new WebSocket(this.url);\n\n this.ws.onopen = () => {\n this.setStatus(\"connected\");\n\n this.resolve?.();\n this.backoff.reset();\n };\n\n this.ws.onmessage = (event) => {\n this.onMessage(event.data);\n };\n\n this.ws.onclose = () => {\n this.setStatus(\"disconnected\");\n this.pendingRequests.rejectAll(\n new Error(\"WebSocket connection closed\"),\n );\n\n if (this.options.autoreconnect) {\n setTimeout(() => this.reconnect(), this.backoff.next());\n }\n };\n\n this.ws.onerror = (err) => {\n console.error(\"WebSocket error:\", err);\n this.reject?.(new Error(\"WebSocket error\"));\n };\n }\n\n disableAutoreconnect() {\n this.options.autoreconnect = false;\n }\n\n close() {\n this.ws?.close();\n }\n\n private async send(msg: WsClientMessage): Promise<void> {\n await this.connectionPromise;\n this.ws?.send(JSON.stringify(msg));\n }\n\n async sendEvent(event: ClientEvent): Promise<void> {\n return this.send({ type: \"event\", event });\n }\n\n on<T extends ServerEvent[\"event\"]>(\n event: T,\n handler: Handler<T>,\n ): () => void {\n let handlers = this.handlers.get(event);\n if (!handlers) {\n handlers = new Set();\n this.handlers.set(event, handlers);\n }\n\n const typedHandler = handler as unknown as Handler<\n ServerEvent[\"event\"]\n >;\n handlers.add(typedHandler);\n\n return () => {\n handlers!.delete(typedHandler);\n };\n }\n\n private onMessage(raw: string) {\n const msg = JSON.parse(raw) as WsServerMessage;\n\n if (msg.type === \"response\" && msg.requestId) {\n this.pendingRequests.resolve(msg.requestId, msg.event);\n return;\n }\n\n if (msg.type === \"event\") {\n const handlers = this.handlers.get(msg.event.event);\n if (handlers) {\n for (const handler of handlers) {\n handler(msg.event);\n }\n }\n }\n }\n\n async request<E extends ClientRequestEvent>(\n event: E,\n ): Promise<ResponseFor<E[\"event\"]>> {\n const { id: requestId, promise } = this.pendingRequests.create<\n ResponseFor<E[\"event\"]>\n >(this.options.requestTimeout);\n\n try {\n await this.send({\n type: \"request\",\n requestId,\n event,\n });\n } catch (err) {\n this.pendingRequests.reject(\n requestId,\n err instanceof Error ? err : new Error(String(err)),\n );\n }\n\n return promise;\n }\n}\n","import { PendingRequests } from \"./pending-requests\";\n\ntype BridgeOptions = {\n targetOrigin?: string;\n timeout?: number;\n debug?: boolean;\n};\n\ntype MessageMeta = {\n timestamp: number;\n requestId?: string;\n isRequest?: boolean;\n isResponse?: boolean;\n};\n\ntype BridgeMessage<T> = {\n type: string;\n payload: T;\n meta: MessageMeta;\n};\n\ninterface BridgeRequests {\n SAVE_ACTION_SETTINGS: { id: string };\n GET_ACTION_SETTINGS: { id: string };\n}\n\ninterface BridgeResponses {\n SAVE_ACTION_SETTINGS: { settings: string | null };\n GET_ACTION_SETTINGS: { settings: string | null };\n}\n\ntype BridgeMessageType = keyof BridgeRequests;\n\ntype ResponseFor<K extends BridgeMessageType> =\n K extends keyof BridgeResponses ? BridgeResponses[K] : never;\n\ntype MessageHandler<K extends BridgeMessageType> = (\n payload: BridgeRequests[K],\n event: MessageEvent,\n respond?: (responsePayload: ResponseFor<K>) => void,\n) => void;\n\nconst DEFAULT_TIMEOUT_MS = 5000;\n\nexport class IframeBridge {\n private options: Required<BridgeOptions>;\n private handlers = new Map<string, MessageHandler<BridgeMessageType>>();\n private pendingRequests = new PendingRequests();\n private isParent: boolean;\n private target: Window | null;\n private boundHandleMessage: (event: MessageEvent) => void;\n\n constructor(options: BridgeOptions = {}) {\n this.options = {\n targetOrigin: \"*\",\n timeout: DEFAULT_TIMEOUT_MS,\n debug: false,\n ...options,\n };\n\n this.isParent = window.parent !== window;\n this.target = null;\n this.boundHandleMessage = this.handleMessage.bind(this);\n\n this.init();\n }\n\n private init(): void {\n window.addEventListener(\"message\", this.boundHandleMessage);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Initialized\", {\n isParent: this.isParent,\n targetOrigin: this.options.targetOrigin,\n });\n }\n }\n\n /** Set the target window to post messages to (used by the parent window). */\n setTarget(iframeElement: HTMLIFrameElement): void {\n if (iframeElement instanceof HTMLIFrameElement) {\n this.target = iframeElement.contentWindow;\n } else {\n console.error(\"[IframeBridge] Invalid iframe element\");\n }\n }\n\n /** Resolve the window to post messages to. */\n private getTargetWindow(): Window | null {\n // Inside an iframe: post to the parent.\n if (this.isParent) {\n return window.parent;\n }\n\n // Parent window: post to the iframe.\n if (this.target) {\n return this.target;\n }\n\n console.error(\n \"[IframeBridge] Target is not set. Call setTarget() on the parent window\",\n );\n\n return null;\n }\n\n /** Handle an incoming message. */\n private handleMessage(event: MessageEvent): void {\n // TODO: not necessary to check origin\n if (\n this.options.targetOrigin !== \"*\" &&\n event.origin !== this.options.targetOrigin\n ) {\n if (this.options.debug) {\n console.warn(\n \"[IframeBridge] Message from unknown origin:\",\n event.origin,\n );\n }\n return;\n }\n\n const data = event.data as BridgeMessage<unknown>;\n const { type, payload, meta } = data;\n\n if (!type) return;\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Received message:\", { type, payload, meta });\n }\n\n // A response is identified by its response meta and request id.\n if (meta?.isResponse && meta.requestId !== undefined) {\n this.pendingRequests.resolve(meta.requestId, payload);\n return;\n }\n\n const handler = this.handlers.get(type);\n if (!handler) return;\n\n if (meta?.isRequest && meta.requestId !== undefined) {\n const { requestId } = meta;\n const source = event.source as Window;\n\n handler(\n payload as BridgeRequests[BridgeMessageType],\n event,\n (responsePayload) => {\n this.sendResponse(type, requestId, responsePayload, source);\n },\n );\n } else {\n handler(payload as BridgeRequests[BridgeMessageType], event);\n }\n }\n\n /** Post a fire-and-forget message. */\n send(type: string, payload: unknown = {}): void {\n const targetWindow = this.getTargetWindow();\n if (!targetWindow) return;\n\n const message: BridgeMessage<unknown> = {\n type,\n payload,\n meta: {\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Sent message:\", message);\n }\n }\n\n /** Post a request and wait for its response. */\n request<K extends BridgeMessageType>(\n type: K,\n payload: BridgeRequests[K],\n timeout: number = this.options.timeout,\n ): Promise<ResponseFor<K>> {\n const targetWindow = this.getTargetWindow();\n if (!targetWindow) {\n return Promise.reject(new Error(\"Target window not found\"));\n }\n\n const { id: requestId, promise } =\n this.pendingRequests.create<ResponseFor<K>>(timeout);\n\n const message: BridgeMessage<BridgeRequests[K]> = {\n type,\n payload,\n meta: {\n requestId,\n isRequest: true,\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Sent request:\", message);\n }\n\n return promise;\n }\n\n /** Post a response back to the window that issued the request. */\n private sendResponse(\n type: string,\n requestId: string,\n payload: unknown,\n targetWindow: Window,\n ): void {\n const message: BridgeMessage<unknown> = {\n type,\n payload,\n meta: {\n requestId,\n isResponse: true,\n timestamp: Date.now(),\n },\n };\n\n targetWindow.postMessage(message, this.options.targetOrigin);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Sent response:\", message);\n }\n }\n\n /** Subscribe to a message type (single handler per type). */\n on<K extends BridgeMessageType>(\n type: K,\n handler: MessageHandler<K>,\n ): () => void {\n this.handlers.set(\n type,\n handler as unknown as MessageHandler<BridgeMessageType>,\n );\n\n return () => this.off(type);\n }\n\n /** Unsubscribe from a message type. */\n off(type: BridgeMessageType): void {\n this.handlers.delete(type);\n }\n\n /** Subscribe to a message type for a single delivery. */\n once<K extends BridgeMessageType>(\n type: K,\n handler: MessageHandler<K>,\n ): () => void {\n const wrappedHandler: MessageHandler<K> = (...args) => {\n handler(...args);\n this.off(type);\n };\n\n return this.on(type, wrappedHandler);\n }\n\n /** Tear down the bridge and reject every outstanding request. */\n destroy(): void {\n this.handlers.clear();\n this.pendingRequests.rejectAll(new Error(\"Bridge destroyed\"));\n window.removeEventListener(\"message\", this.boundHandleMessage);\n\n if (this.options.debug) {\n console.log(\"[IframeBridge] Destroyed\");\n }\n }\n}\n","import type { JsonValue } from \"@fluxdeck/bindings/JsonValue\";\nimport type { Connection } from \"./connection\";\n\nexport function parseJsonSettings(str: string | null): JsonValue {\n try {\n return JSON.parse(str ?? \"{}\");\n } catch (err) {\n console.error(err);\n return {};\n }\n}\n\nexport function serializeSettings(value: JsonValue): string {\n return JSON.stringify(value);\n}\n\nexport function pluginSettings(connection: Connection, name: string) {\n return {\n get() {\n return connection.request({\n name,\n event: \"getPluginSettings\",\n });\n },\n set(data: JsonValue) {\n return connection.sendEvent({\n name,\n event: \"setPluginSettings\",\n payload: data,\n });\n },\n };\n}\n","import type { JsonValue } from \"@fluxdeck/bindings/JsonValue\";\nimport { IframeBridge } from \"./iframe-bridge\";\nimport { Connection } from \"./connection\";\nimport { parseJsonSettings, serializeSettings } from \"./settings\";\n\ntype Listener<T> = (payload: T) => void;\n\ntype SaveHandler = () => unknown;\n\ntype EditorParams = {\n id: string;\n group: string;\n};\n\nexport class Editor {\n private connection: Connection;\n private bridge: IframeBridge;\n private params: EditorParams;\n private saveHandler?: SaveHandler;\n\n constructor() {\n if (typeof window === \"undefined\") {\n throw Error(\"Flux Deck Editor must be used only in plugin editor\");\n }\n\n const urlParams = new URLSearchParams(location.search);\n\n const getStringParam = (key: string): string => {\n const value = urlParams.get(key);\n\n if (value === null) {\n throw Error(`${key} must be provided`);\n }\n\n return value;\n };\n\n this.params = {\n id: getStringParam(\"id\"),\n group: getStringParam(\"group\"),\n };\n\n this.connection = new Connection();\n this.bridge = new IframeBridge();\n\n this.bridge.on(\"SAVE_ACTION_SETTINGS\", (payload, _event, respond) => {\n if (payload.id == this.params.id && this.saveHandler) {\n const settings = this.saveHandler();\n\n try {\n respond?.({ settings: serializeSettings(settings as JsonValue) });\n } catch (err) {\n console.error(err);\n respond?.({ settings: null });\n }\n }\n });\n }\n\n connect() {\n this.connection.on(\"sendToEditor\", (data) => {\n this.onReceiveFromPluginListeners.forEach((listener) => {\n listener(data.payload);\n });\n });\n\n this.connection.connect();\n\n this.connection.sendEvent({\n event: \"editorRegister\",\n payload: this.params.group,\n });\n }\n\n private onReceiveFromPluginListeners = new Set<Listener<unknown>>();\n\n onReceiveFromPlugin<T>(listener: Listener<T>) {\n this.onReceiveFromPluginListeners.add(\n listener as Listener<unknown>,\n );\n return () => {\n this.onReceiveFromPluginListeners.delete(listener as Listener<unknown>);\n };\n }\n\n sendToPlugin<T extends JsonValue>(data: T) {\n this.connection.sendEvent({\n event: \"sendToPlugin\",\n name: this.params.group,\n payload: data,\n });\n }\n\n async getActionSettings(): Promise<JsonValue> {\n const response = await this.bridge.request(\"GET_ACTION_SETTINGS\", {\n id: this.params.id,\n });\n\n return parseJsonSettings(response.settings);\n }\n\n onActionSave(handler: SaveHandler) {\n this.saveHandler = handler;\n\n return () => {\n this.saveHandler = undefined;\n };\n }\n\n async getPluginSettings() {\n return await this.connection.request({\n name: this.params.group,\n event: \"getPluginSettings\",\n });\n }\n\n async setPluginSettings(data: JsonValue) {\n return this.connection.sendEvent({\n name: this.params.group,\n event: \"setPluginSettings\",\n payload: data,\n });\n }\n}\n","import type { JsonValue } from \"@fluxdeck/bindings/JsonValue\";\nimport { Connection } from \"./connection\";\nimport { parseJsonSettings, pluginSettings } from \"./settings\";\n\ntype Listener<T> = (payload: T) => void;\n\nexport type ActionData<T> = {\n trigger: string;\n settings: T;\n};\n\nexport interface Action<T> {\n name: string;\n onTrigger?: (data: ActionData<T>) => void;\n}\n\nexport class Plugin {\n private connection: Connection;\n private actions: Action<unknown>[] = [];\n private pluginName?: string;\n\n constructor() {\n if (typeof process != \"undefined\") {\n this.pluginName = process?.argv[2];\n\n const port = Number(process?.argv[3]);\n this.connection = new Connection(\n Number.isNaN(port) ? {} : { port },\n );\n } else {\n this.connection = new Connection();\n }\n }\n\n connect() {\n this.ensurePluginName();\n\n this.connection.on(\"trigger\", (data) => {\n for (const action of this.actions) {\n if (action.name == data.action.type) {\n action.onTrigger?.({\n trigger: data.kind,\n settings: parseJsonSettings(data.action.settings),\n });\n }\n }\n });\n\n this.connection.connect();\n\n if (this.pluginName) {\n this.registerPlugin(this.pluginName);\n }\n }\n\n private ensurePluginName(): string {\n if (!this.pluginName) {\n throw Error(\"No plugin name\");\n }\n return this.pluginName;\n }\n\n private registerPlugin(name: string) {\n this.connection.sendEvent({ event: \"pluginRegister\", payload: name });\n }\n\n registerAction<T>(action: Action<T>) {\n this.actions.push(action as Action<unknown>);\n }\n\n async onPluginSettings<T>(listener: Listener<T>) {\n const name = this.ensurePluginName();\n const accessor = pluginSettings(this.connection, name);\n const on = this.connection.on(\"setPluginSettings\", (data) => {\n listener(data.payload as T);\n });\n const settings = await accessor.get();\n listener(settings.payload as T);\n return on;\n }\n\n async onReceiveFromEditor<T>(listener: Listener<T>) {\n return this.connection.on(\"sendToPlugin\", (data) => {\n listener(data.payload as T);\n });\n }\n\n sendToEditor<T extends JsonValue>(data: T) {\n const name = this.ensurePluginName();\n\n this.connection.sendEvent({\n event: \"sendToEditor\",\n name,\n payload: data,\n });\n }\n\n async getPluginSettings() {\n const name = this.ensurePluginName();\n const accessor = pluginSettings(this.connection, name);\n return accessor.get();\n }\n\n async setPluginSettings<T extends JsonValue>(data: T) {\n const name = this.ensurePluginName();\n const accessor = pluginSettings(this.connection, name);\n return accessor.set(data);\n }\n}\n\nexport const fluxDeck = new Plugin();\n"],"mappings":"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"}
|