@withalleo/ewidget-utils 1.0.7 → 1.0.8

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 CHANGED
@@ -15,87 +15,416 @@ This package ships a browser bundle at `@withalleo/ewidget-utils/browser` (UMD).
15
15
  ```html
16
16
  <!doctype html>
17
17
  <html lang="en">
18
- <head>
19
- <meta charset="UTF-8" />
20
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21
- <title>@withalleo/ewidget-utils demo</title>
22
- </head>
23
- <body>
24
- <h1>ewidget-utils demo</h1>
25
-
26
- <!-- Browser (UMD) build -->
27
- <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
28
-
29
- <script>
30
- // For the UMD build, the library is exposed on the global `AlleoEwidgetUtils`.
31
- const alleo = AlleoEwidgetUtils.getInstance({ debug: true });
32
- alleo.demo();
33
- </script>
34
- </body>
18
+ <head>
19
+ <meta charset="UTF-8" />
20
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21
+ <title>@withalleo/ewidget-utils demo</title>
22
+ </head>
23
+ <body>
24
+ <button id="button">Add notepad</button>
25
+
26
+ <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
27
+ <script>
28
+ const alleo = AlleoEWidget.getEmbedWidgetMessenger({ debug: true })
29
+
30
+ document.getElementById('button').onclick = () =>
31
+ alleo.addContent({ type: 'notepad', textFormat: 'markdown', text: '# Status\n\nAll systems go.' })
32
+ </script>
33
+ </body>
35
34
  </html>
36
35
  ```
37
36
 
38
- ## EmbedWidgetMessenger (iframe communication)
37
+ ## Samples
38
+
39
+ Below are the exact sample files from `samples/`, included verbatim as quoted blocks.
40
+
41
+ ### `samples/iframe-basic.html`
42
+
43
+ > ```html
44
+ > <!doctype html>
45
+ > <html lang="en">
46
+ > <head>
47
+ > <meta charset="UTF-8" />
48
+ > <meta name="viewport" content="width=device-width, initial-scale=1.0" />
49
+ > <title>EmbedWidgetMessenger - Basic</title>
50
+ > <style>
51
+ > body {
52
+ > font-family: Arial, sans-serif;
53
+ > padding: 16px;
54
+ > }
55
+ > button {
56
+ > padding: 8px 12px;
57
+ > }
58
+ > pre {
59
+ > background: #f4f4f4;
60
+ > padding: 8px;
61
+ > }
62
+ > </style>
63
+ > </head>
64
+ > <body>
65
+ > <h1>EmbedWidgetMessenger - Basic</h1>
66
+ > <p>This page is intended to run inside the Embed widget iframe.</p>
67
+ >
68
+ > <button id="trigger">Trigger action</button>
69
+ > <button id="request">Request synced status</button>
70
+ >
71
+ > <h2>Log</h2>
72
+ > <pre id="log"></pre>
73
+ >
74
+ > <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
75
+ > <script>
76
+ > const logEl = document.getElementById('log')
77
+ > const log = (message, data) => {
78
+ > const line = data ? `${message} ${JSON.stringify(data)}` : message
79
+ > logEl.textContent = `${line}\n${logEl.textContent}`
80
+ > }
81
+ >
82
+ > const messenger = new AlleoEWidget.EmbedWidgetMessenger({
83
+ > targetOrigin: '*',
84
+ > debug: true,
85
+ > })
86
+ >
87
+ > messenger.onSyncedStatusUpdate((status) => {
88
+ > log('syncedStatusUpdate:', status)
89
+ > })
90
+ >
91
+ > messenger.onIncomingAction(({ actionId, data }) => {
92
+ > log(`incomingAction: ${actionId}`, data)
93
+ > })
94
+ >
95
+ > document.getElementById('trigger').addEventListener('click', () => {
96
+ > messenger.triggerAction('demo', {
97
+ > 'demo-param': 'Hello from iframe',
98
+ > })
99
+ > log('triggerAction sent')
100
+ > })
101
+ >
102
+ > document.getElementById('request').addEventListener('click', () => {
103
+ > messenger.requestSyncedStatus()
104
+ > log('requestSyncedStatus sent')
105
+ > })
106
+ > </script>
107
+ > </body>
108
+ > </html>
109
+ > ```
110
+
111
+ ### `samples/iframe-add-content.html`
112
+
113
+ > ```html
114
+ > <!doctype html>
115
+ > <html lang="en">
116
+ > <head>
117
+ > <meta charset="UTF-8" />
118
+ > <meta name="viewport" content="width=device-width, initial-scale=1.0" />
119
+ > <title>EmbedWidgetMessenger - Add Content</title>
120
+ > <style>
121
+ > body {
122
+ > font-family: Arial, sans-serif;
123
+ > padding: 16px;
124
+ > }
125
+ > button {
126
+ > padding: 8px 12px;
127
+ > margin-right: 8px;
128
+ > margin-bottom: 8px;
129
+ > }
130
+ > </style>
131
+ > </head>
132
+ > <body>
133
+ > <h1>EmbedWidgetMessenger - Add Content</h1>
134
+ > <p>These commands require "Enable adding new content to the board" in settings.</p>
135
+ >
136
+ > <button id="add-notepad">Add notepad</button>
137
+ > <button id="add-sticky">Add sticky note</button>
138
+ > <button id="add-html">Add HTML embed</button>
139
+ >
140
+ > <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
141
+ > <script>
142
+ > const messenger = new AlleoEWidget.EmbedWidgetMessenger({
143
+ > targetOrigin: '*',
144
+ > debug: true,
145
+ > })
146
+ >
147
+ > document.getElementById('add-notepad').addEventListener('click', () => {
148
+ > messenger.addContent({
149
+ > type: 'notepad',
150
+ > textFormat: 'markdown',
151
+ > text: '# New note\n\nAdded from iframe.',
152
+ > })
153
+ > })
154
+ >
155
+ > document.getElementById('add-sticky').addEventListener('click', () => {
156
+ > messenger.addContent({
157
+ > type: 'sticky-note',
158
+ > text: 'Remember to review the draft',
159
+ > color: '#FFE680',
160
+ > outlineColor: '#B38F00',
161
+ > shape: 'square',
162
+ > })
163
+ > })
164
+ >
165
+ > document.getElementById('add-html').addEventListener('click', () => {
166
+ > messenger.addContent({
167
+ > type: 'html',
168
+ > html: '<!doctype html><html><body><h2>Hello from iframe</h2></body></html>',
169
+ > })
170
+ > })
171
+ > </script>
172
+ > </body>
173
+ > </html>
174
+ > ```
175
+
176
+ ### `samples/iframe-synced-status.html`
177
+
178
+ > ```html
179
+ > <!doctype html>
180
+ > <html lang="en">
181
+ > <head>
182
+ > <meta charset="UTF-8" />
183
+ > <meta name="viewport" content="width=device-width, initial-scale=1.0" />
184
+ > <title>EmbedWidgetMessenger - Synced Status</title>
185
+ > <style>
186
+ > body {
187
+ > font-family: Arial, sans-serif;
188
+ > padding: 16px;
189
+ > }
190
+ > button {
191
+ > padding: 8px 12px;
192
+ > border: none;
193
+ > color: #111;
194
+ > }
195
+ > </style>
196
+ > </head>
197
+ > <body>
198
+ > <h1>EmbedWidgetMessenger - Synced Status</h1>
199
+ > <p>Click the button to set a random color in synced status.</p>
200
+ >
201
+ > <button id="color">Set random color</button>
202
+ >
203
+ > <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
204
+ > <script>
205
+ > const button = document.getElementById('color')
206
+ >
207
+ > const messenger = new AlleoEWidget.EmbedWidgetMessenger({
208
+ > targetOrigin: '*',
209
+ > debug: true,
210
+ > })
211
+ >
212
+ > const applyColor = (status) => {
213
+ > if (!status || !status.color) return
214
+ > button.style.backgroundColor = status.color
215
+ > }
216
+ >
217
+ > messenger.onSyncedStatusUpdate((status) => {
218
+ > applyColor(status)
219
+ > })
220
+ >
221
+ > button.addEventListener('click', () => {
222
+ > const color = `#${Math.floor(Math.random() * 0xffffff)
223
+ > .toString(16)
224
+ > .padStart(6, '0')}`
225
+ > messenger.setSyncedStatus({ color })
226
+ > })
227
+ >
228
+ > messenger.requestSyncedStatus()
229
+ > </script>
230
+ > </body>
231
+ > </html>
232
+ > ```
233
+
234
+ ## API Reference
235
+
236
+ ### Exported helpers
237
+
238
+ #### `getAlleoEwidgetUtils(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils`
239
+
240
+ Returns a singleton instance of `AlleoEwidgetUtils`. If a browser global singleton already exists, the existing instance is reused.
241
+
242
+ #### `getEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger`
243
+
244
+ Convenience helper that returns `getAlleoEwidgetUtils().createEmbedWidgetMessenger(options)`.
245
+
246
+ ### `EmbedWidgetMessenger`
247
+
248
+ #### Constructor
249
+
250
+ - `new EmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions)`
251
+ - Initializes message handling and, by default, calls `startListening()`.
252
+
253
+ #### Options (`EmbedWidgetMessengerOptions`)
254
+
255
+ - `targetOrigin?: string` (default: `'*'`) - Passed to `postMessage` for outbound commands.
256
+ - `parentWindow?: Window` (default: `window.parent`) - The window that receives outbound commands.
257
+ - `autoListen?: boolean` (default: `true`) - Auto-register the `message` event listener.
258
+ - `debug?: boolean` (default: `false`) - Enables debug logging via `console.debug`.
259
+
260
+ #### Properties
261
+
262
+ - `isListening: boolean` - Whether the instance is currently listening for `message` events.
263
+
264
+ #### Methods (commands)
265
+
266
+ - `triggerAction(actionId: string, data?: Record<string, unknown>): void`
267
+ - Sends a `triggerAction` command. If `actionId` is missing, logs a debug message and skips sending.
268
+ - `addContent(params: AddContentParams): void`
269
+ - Sends an `addContent` command with the provided content payload.
270
+ - `requestSyncedStatus(): void`
271
+ - Sends a `requestSyncedStatus` command.
272
+ - `setSyncedStatus(status: Record<string, unknown>): void`
273
+ - Sends a `setSyncedStatus` command with a `status` object.
274
+
275
+ #### Methods (events)
276
+
277
+ - `onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void`
278
+ - Registers a handler for `syncedStatusUpdate` and returns an unsubscribe function.
279
+ - `onIncomingAction(handler: (payload: { actionId: string; data: Record<string, unknown> }) => void): () => void`
280
+ - Registers a handler for `incomingAction` and returns an unsubscribe function.
281
+ - `onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void`
282
+ - Registers a handler for all widget messages and returns an unsubscribe function.
39
283
 
40
- Use this helper inside the embedded page (the iframe) to send commands to the widget and listen for widget events.
284
+ #### Methods (lifecycle)
41
285
 
42
- ### Module usage (recommended)
286
+ - `startListening(): void`
287
+ - Adds a `message` event listener if running in a browser.
288
+ - `stopListening(): void`
289
+ - Removes the `message` event listener.
290
+ - `destroy(): void`
291
+ - Stops listening and clears all registered handlers.
43
292
 
44
- ```ts
45
- import { EmbedWidgetMessenger } from '@withalleo/ewidget-utils'
46
293
 
47
- const messenger = new EmbedWidgetMessenger({
48
- // Use a specific origin when possible instead of '*'
49
- targetOrigin: '*',
50
- debug: true,
51
- })
52
294
 
53
- messenger.onSyncedStatusUpdate((status) => {
54
- console.log('synced status', status)
55
- })
295
+ ### `AlleoEwidgetUtils`
56
296
 
57
- messenger.onIncomingAction(({ actionId, data }) => {
58
- console.log('incoming action', actionId, data)
59
- })
297
+ #### Constructor
60
298
 
61
- messenger.requestSyncedStatus()
299
+ - `new AlleoEwidgetUtils(options?: AlleoEwidgetUtilsOptions)`
300
+ - Creates an instance and calls `initialize()`.
301
+ - In the browser, a global singleton is stored so multiple bundle loads reuse a single instance.
62
302
 
63
- messenger.triggerAction('demo', {
64
- 'demo-param': 'Hello from iframe',
65
- })
303
+ #### Options (`AlleoEwidgetUtilsOptions`)
66
304
 
67
- messenger.setSyncedStatus({
68
- phase: 'ready',
69
- lastUpdatedAt: Date.now(),
70
- })
305
+ - `autoDestroy?: boolean` (default: `true`) - When `true`, attaches a `beforeunload` listener to call `destroy()`.
306
+ - `debug?: boolean` (default: `false`) - Enables debug logging via `console.debug`.
71
307
 
72
- messenger.addContent({
73
- type: 'notepad',
74
- textFormat: 'markdown',
75
- text: '# Status\n\nAll systems go.',
76
- })
308
+ #### Properties
309
+
310
+ - `isInitialized: boolean` - `true` when initialized and not destroyed.
311
+
312
+ #### Methods
313
+
314
+ - `static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils`
315
+ - Returns a singleton instance, creating one if needed.
316
+ - `createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger`
317
+ - Creates a new `EmbedWidgetMessenger` configured with the provided options.
318
+ - `initialize(): void`
319
+ - Idempotent; sets initialized state and attaches listeners when `autoDestroy` is enabled.
320
+ - `destroy(): void`
321
+ - Detaches listeners, clears the global singleton reference, and marks the instance destroyed.
322
+ - `log(message: string, data?: unknown): void`
323
+ - Debug logger gated by the `debug` option.
324
+
325
+ ### Types
326
+
327
+ #### `AddContentParams`
328
+
329
+ Union of the following shapes for `addContent`:
330
+
331
+ - `AddContentHtmlParams`
332
+ - `{ type: 'html', html: string }`
333
+ - `AddContentNotepadParams`
334
+ - `{ type: 'notepad', text?: string | string[], textFormat?: 'text' | 'markdown' | 'html' }`
335
+ - `AddContentStickyNoteParams`
336
+ - `{ type: 'sticky-note', text?: string, color?: string, outlineColor?: string, shape?: string }`
337
+ - `AddContentImageParams`
338
+ - `{ type: 'image', url: string }`
339
+ - `AddContentVideoParams`
340
+ - `{ type: 'video', fileId: string }`
341
+
342
+ #### Command envelopes
343
+
344
+ **Outgoing (iframe -> widget)**
345
+
346
+ - `EmbedWidgetCommandMap` defines the `command` names and their `params` shapes:
347
+ - `triggerAction`, `addContent`, `requestSyncedStatus`, `setSyncedStatus`.
348
+ - `EmbedWidgetCommandEnvelope` is the outbound `postMessage` payload shape:
349
+ - `{ type: 'EmbedWidgetCommand', command, params }`.
350
+
351
+ **Outgoing examples**
352
+
353
+ ```json
354
+ {
355
+ "type": "EmbedWidgetCommand",
356
+ "command": "triggerAction",
357
+ "params": {
358
+ "actionId": "demo",
359
+ "data": { "demo-param": "Hello from iframe" }
360
+ }
361
+ }
77
362
  ```
78
363
 
79
- ### Browser (UMD) usage
364
+ ```json
365
+ {
366
+ "type": "EmbedWidgetCommand",
367
+ "command": "addContent",
368
+ "params": {
369
+ "type": "notepad",
370
+ "textFormat": "markdown",
371
+ "text": "# Status\n\nAll systems go."
372
+ }
373
+ }
374
+ ```
80
375
 
81
- ```html
82
- <script src="https://unpkg.com/@withalleo/ewidget-utils/dist/ewidget-utils.umd.cjs"></script>
83
- <script>
84
- const messenger = new AlleoEwidgetUtils.EmbedWidgetMessenger({
85
- targetOrigin: '*',
86
- debug: true,
87
- })
88
-
89
- messenger.onSyncedStatusUpdate((status) => {
90
- console.log('synced status', status)
91
- })
92
-
93
- messenger.requestSyncedStatus()
94
- </script>
376
+ ```json
377
+ {
378
+ "type": "EmbedWidgetCommand",
379
+ "command": "requestSyncedStatus",
380
+ "params": {}
381
+ }
382
+ ```
383
+
384
+ ```json
385
+ {
386
+ "type": "EmbedWidgetCommand",
387
+ "command": "setSyncedStatus",
388
+ "params": {
389
+ "status": { "color": "#FFAA33" }
390
+ }
391
+ }
392
+ ```
393
+
394
+ #### Message envelopes
395
+
396
+ **Incoming (widget -> iframe)**
397
+
398
+ - `EmbedWidgetMessageMap` defines inbound `command` names and `params` shapes:
399
+ - `syncedStatusUpdate`, `incomingAction`.
400
+ - `EmbedWidgetMessageEnvelope` is the inbound message shape:
401
+ - `{ type: 'EmbedWidgetMessage', command, params }`.
402
+ - `EmbedWidgetMessageEvent` is the normalized event passed to `onMessage` handlers:
403
+ - `{ command, params, raw }`.
404
+
405
+ **Incoming examples (one per event)**
406
+
407
+ ```json
408
+ {
409
+ "type": "EmbedWidgetMessage",
410
+ "command": "syncedStatusUpdate",
411
+ "params": {
412
+ "syncedStatus": { "color": "#FFAA33" }
413
+ }
414
+ }
415
+ ```
416
+
417
+ ```json
418
+ {
419
+ "type": "EmbedWidgetMessage",
420
+ "command": "incomingAction",
421
+ "params": {
422
+ "actionId": "demo",
423
+ "data": { "demo-param": "Hello from widget" }
424
+ }
425
+ }
95
426
  ```
96
427
 
97
428
  ### Notes
98
429
 
99
- - Commands available: `triggerAction`, `addContent`, `requestSyncedStatus`, `setSyncedStatus`.
100
- - Events available: `syncedStatusUpdate`, `incomingAction`.
101
- - Use `destroy()` to remove listeners when the iframe is torn down.
430
+ - The `targetOrigin` option in `EmbedWidgetMessenger` should generally remain as `'*'` to allow communication with the widget.
@@ -13,7 +13,6 @@ export declare class AlleoEwidgetUtils {
13
13
  get isInitialized(): boolean;
14
14
  private get isBrowser();
15
15
  static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils;
16
- demo(): void;
17
16
  createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger;
18
17
  initialize(): void;
19
18
  destroy(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"AlleoEwidgetUtils.d.ts","sourceRoot":"","sources":["../src/AlleoEwidgetUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAElG,MAAM,MAAM,wBAAwB,GAAG;IACnC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAQD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAuC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAC,CAAoC;gBAExC,OAAO,CAAC,EAAE,wBAAwB;IASrD,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,OAAO,KAAK,SAAS,GAEpB;WAEa,WAAW,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,iBAAiB;IAiBzE,IAAI;IAIJ,0BAA0B,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,oBAAoB;IAIvF,UAAU,IAAI,IAAI;IAWlB,OAAO,IAAI,IAAI;IAgBf,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAQjD,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,eAAe;CAK1B;AAED,eAAO,MAAM,oBAAoB,GAAI,UAAU,wBAAwB,KAAG,iBAA2D,CAAA;AACrI,eAAO,MAAM,uBAAuB,GAAI,UAAU,2BAA2B,yBACN,CAAA"}
1
+ {"version":3,"file":"AlleoEwidgetUtils.d.ts","sourceRoot":"","sources":["../src/AlleoEwidgetUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,2BAA2B,EAAE,MAAM,2BAA2B,CAAA;AAElG,MAAM,MAAM,wBAAwB,GAAG;IACnC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAQD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAuC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAC,CAAoC;gBAExC,OAAO,CAAC,EAAE,wBAAwB;IASrD,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,OAAO,KAAK,SAAS,GAEpB;WAEa,WAAW,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,iBAAiB;IAiBzE,0BAA0B,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,oBAAoB;IAIvF,UAAU,IAAI,IAAI;IAWlB,OAAO,IAAI,IAAI;IAgBf,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAQjD,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,eAAe;CAK1B;AAED,eAAO,MAAM,oBAAoB,GAAI,UAAU,wBAAwB,KAAG,iBAA2D,CAAA;AACrI,eAAO,MAAM,uBAAuB,GAAI,UAAU,2BAA2B,yBACN,CAAA"}
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AlleoEWidget={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class{targetOrigin;parentWindow;debugEnabled;listening=!1;syncedStatusHandlers=new Set;incomingActionHandlers=new Set;messageHandlers=new Set;constructor(e){this.targetOrigin=e?.targetOrigin??`*`,this.debugEnabled=e?.debug??!1,this.parentWindow=e?.parentWindow??(this.isBrowser?window.parent:null),(e?.autoListen??!0)&&this.startListening()}get isListening(){return this.listening}triggerAction(e,t){if(!e){this.log(`triggerAction missing actionId`);return}this.sendCommand(`triggerAction`,{actionId:e,data:t})}addContent(e){this.sendCommand(`addContent`,e)}requestSyncedStatus(){this.sendCommand(`requestSyncedStatus`,{})}setSyncedStatus(e){this.sendCommand(`setSyncedStatus`,{status:e})}onSyncedStatusUpdate(e){return this.syncedStatusHandlers.add(e),()=>this.syncedStatusHandlers.delete(e)}onIncomingAction(e){return this.incomingActionHandlers.add(e),()=>this.incomingActionHandlers.delete(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}startListening(){!this.isBrowser||this.listening||(window.addEventListener(`message`,this.handleMessageEvent),this.listening=!0)}stopListening(){!this.isBrowser||!this.listening||(window.removeEventListener(`message`,this.handleMessageEvent),this.listening=!1)}destroy(){this.stopListening(),this.syncedStatusHandlers.clear(),this.incomingActionHandlers.clear(),this.messageHandlers.clear()}get isBrowser(){return typeof window<`u`&&typeof window.addEventListener==`function`}sendCommand(e,t){if(!this.parentWindow){this.log(`postMessage unavailable`);return}let n={type:`EmbedWidgetCommand`,command:e,params:t};this.parentWindow.postMessage(n,this.targetOrigin)}handleMessageEvent=e=>{if(this.parentWindow&&e.source!==this.parentWindow)return;let t=e.data;if(!t||typeof t!=`object`||t.type!==`EmbedWidgetMessage`)return;let n=t;if(this.isSyncedStatusUpdate(n)){let e=n.params.syncedStatus;e&&typeof e==`object`?this.emitSyncedStatusUpdate(e):this.emitSyncedStatusUpdate({}),this.emitMessage({command:n.command,params:n.params,raw:n});return}if(this.isIncomingAction(n)){if(typeof n.params.actionId!=`string`)return;let e=n.params.data&&typeof n.params.data==`object`?n.params.data:{};this.emitIncomingAction({actionId:n.params.actionId,data:e}),this.emitMessage({command:n.command,params:n.params,raw:n});return}this.log(`Unknown message command`,n.command)};isSyncedStatusUpdate(e){return e.command===`syncedStatusUpdate`}isIncomingAction(e){return e.command===`incomingAction`}emitSyncedStatusUpdate(e){for(let t of this.syncedStatusHandlers)t(e)}emitIncomingAction(e){for(let t of this.incomingActionHandlers)t(e)}emitMessage(e){for(let t of this.messageHandlers)t(e)}log(e,t){this.debugEnabled&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}},n=class e{static GLOBAL_KEY=`__withAlleoEwidgetUtils__`;options;initialized=!1;destroyed=!1;onBeforeUnload;constructor(e){this.options={autoDestroy:e?.autoDestroy??!0,debug:e?.debug??!1},this.initialize()}get isInitialized(){return this.initialized&&!this.destroyed}get isBrowser(){return typeof window<`u`&&typeof document<`u`}static getInstance(t){let n=globalThis;if(n&&typeof n==`object`&&(n[e.GLOBAL_KEY]??={},n[e.GLOBAL_KEY].instance))return n[e.GLOBAL_KEY].instance;let r=new e(t);return n&&typeof n==`object`&&(n[e.GLOBAL_KEY].instance=r),r}demo(){this.log(`DEMO`)}createEmbedWidgetMessenger(e){return new t(e)}initialize(){this.isInitialized||(this.initialized=!0,this.isBrowser&&(this.options.autoDestroy&&this.attachListeners(),this.log(`initialized`)))}destroy(){if(this.destroyed)return;this.destroyed=!0,this.isBrowser&&this.detachListeners();let t=globalThis;if(t&&typeof t==`object`){let n=t[e.GLOBAL_KEY];n?.instance===this&&(n.instance=void 0)}this.log(`destroyed`)}log(e,t){this.options.debug&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}attachListeners(){this.isBrowser&&(this.onBeforeUnload??=()=>this.destroy(),window.addEventListener(`beforeunload`,this.onBeforeUnload))}detachListeners(){this.isBrowser&&this.onBeforeUnload&&window.removeEventListener(`beforeunload`,this.onBeforeUnload)}};e.AlleoEwidgetUtils=n,e.EmbedWidgetMessenger=t,e.getAlleoEwidgetUtils=e=>n.getInstance(e),e.getEmbedWidgetMessenger=e=>n.getInstance().createEmbedWidgetMessenger(e)});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.AlleoEWidget={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class{targetOrigin;parentWindow;debugEnabled;listening=!1;syncedStatusHandlers=new Set;incomingActionHandlers=new Set;messageHandlers=new Set;constructor(e){this.targetOrigin=e?.targetOrigin??`*`,this.debugEnabled=e?.debug??!1,this.parentWindow=e?.parentWindow??(this.isBrowser?window.parent:null),(e?.autoListen??!0)&&this.startListening()}get isListening(){return this.listening}triggerAction(e,t){if(!e){this.log(`triggerAction missing actionId`);return}this.sendCommand(`triggerAction`,{actionId:e,data:t})}addContent(e){this.sendCommand(`addContent`,e)}requestSyncedStatus(){this.sendCommand(`requestSyncedStatus`,{})}setSyncedStatus(e){this.sendCommand(`setSyncedStatus`,{status:e})}onSyncedStatusUpdate(e){return this.syncedStatusHandlers.add(e),()=>this.syncedStatusHandlers.delete(e)}onIncomingAction(e){return this.incomingActionHandlers.add(e),()=>this.incomingActionHandlers.delete(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}startListening(){!this.isBrowser||this.listening||(window.addEventListener(`message`,this.handleMessageEvent),this.listening=!0)}stopListening(){!this.isBrowser||!this.listening||(window.removeEventListener(`message`,this.handleMessageEvent),this.listening=!1)}destroy(){this.stopListening(),this.syncedStatusHandlers.clear(),this.incomingActionHandlers.clear(),this.messageHandlers.clear()}get isBrowser(){return typeof window<`u`&&typeof window.addEventListener==`function`}sendCommand(e,t){if(!this.parentWindow){this.log(`postMessage unavailable`);return}let n={type:`EmbedWidgetCommand`,command:e,params:t};this.parentWindow.postMessage(n,this.targetOrigin)}handleMessageEvent=e=>{if(this.parentWindow&&e.source!==this.parentWindow)return;let t=e.data;if(!t||typeof t!=`object`||t.type!==`EmbedWidgetMessage`)return;let n=t;if(this.isSyncedStatusUpdate(n)){let e=n.params.syncedStatus;e&&typeof e==`object`?this.emitSyncedStatusUpdate(e):this.emitSyncedStatusUpdate({}),this.emitMessage({command:n.command,params:n.params,raw:n});return}if(this.isIncomingAction(n)){if(typeof n.params.actionId!=`string`)return;let e=n.params.data&&typeof n.params.data==`object`?n.params.data:{};this.emitIncomingAction({actionId:n.params.actionId,data:e}),this.emitMessage({command:n.command,params:n.params,raw:n});return}this.log(`Unknown message command`,n.command)};isSyncedStatusUpdate(e){return e.command===`syncedStatusUpdate`}isIncomingAction(e){return e.command===`incomingAction`}emitSyncedStatusUpdate(e){for(let t of this.syncedStatusHandlers)t(e)}emitIncomingAction(e){for(let t of this.incomingActionHandlers)t(e)}emitMessage(e){for(let t of this.messageHandlers)t(e)}log(e,t){this.debugEnabled&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}},n=class e{static GLOBAL_KEY=`__withAlleoEwidgetUtils__`;options;initialized=!1;destroyed=!1;onBeforeUnload;constructor(e){this.options={autoDestroy:e?.autoDestroy??!0,debug:e?.debug??!1},this.initialize()}get isInitialized(){return this.initialized&&!this.destroyed}get isBrowser(){return typeof window<`u`&&typeof document<`u`}static getInstance(t){let n=globalThis;if(n&&typeof n==`object`&&(n[e.GLOBAL_KEY]??={},n[e.GLOBAL_KEY].instance))return n[e.GLOBAL_KEY].instance;let r=new e(t);return n&&typeof n==`object`&&(n[e.GLOBAL_KEY].instance=r),r}createEmbedWidgetMessenger(e){return new t(e)}initialize(){this.isInitialized||(this.initialized=!0,this.isBrowser&&(this.options.autoDestroy&&this.attachListeners(),this.log(`initialized`)))}destroy(){if(this.destroyed)return;this.destroyed=!0,this.isBrowser&&this.detachListeners();let t=globalThis;if(t&&typeof t==`object`){let n=t[e.GLOBAL_KEY];n?.instance===this&&(n.instance=void 0)}this.log(`destroyed`)}log(e,t){this.options.debug&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}attachListeners(){this.isBrowser&&(this.onBeforeUnload??=()=>this.destroy(),window.addEventListener(`beforeunload`,this.onBeforeUnload))}detachListeners(){this.isBrowser&&this.onBeforeUnload&&window.removeEventListener(`beforeunload`,this.onBeforeUnload)}};e.AlleoEwidgetUtils=n,e.EmbedWidgetMessenger=t,e.getAlleoEwidgetUtils=e=>n.getInstance(e),e.getEmbedWidgetMessenger=e=>n.getInstance().createEmbedWidgetMessenger(e)});
2
2
  //# sourceMappingURL=ewidget-utils.umd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ewidget-utils.umd.cjs","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public demo() {\r\n this.log('DEMO')\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"ewidget-utils.umd.cjs","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{targetOrigin;parentWindow;debugEnabled;listening=!1;syncedStatusHandlers=new Set;incomingActionHandlers=new Set;messageHandlers=new Set;constructor(e){this.targetOrigin=e?.targetOrigin??`*`,this.debugEnabled=e?.debug??!1,this.parentWindow=e?.parentWindow??(this.isBrowser?window.parent:null),(e?.autoListen??!0)&&this.startListening()}get isListening(){return this.listening}triggerAction(e,t){if(!e){this.log(`triggerAction missing actionId`);return}this.sendCommand(`triggerAction`,{actionId:e,data:t})}addContent(e){this.sendCommand(`addContent`,e)}requestSyncedStatus(){this.sendCommand(`requestSyncedStatus`,{})}setSyncedStatus(e){this.sendCommand(`setSyncedStatus`,{status:e})}onSyncedStatusUpdate(e){return this.syncedStatusHandlers.add(e),()=>this.syncedStatusHandlers.delete(e)}onIncomingAction(e){return this.incomingActionHandlers.add(e),()=>this.incomingActionHandlers.delete(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}startListening(){!this.isBrowser||this.listening||(window.addEventListener(`message`,this.handleMessageEvent),this.listening=!0)}stopListening(){!this.isBrowser||!this.listening||(window.removeEventListener(`message`,this.handleMessageEvent),this.listening=!1)}destroy(){this.stopListening(),this.syncedStatusHandlers.clear(),this.incomingActionHandlers.clear(),this.messageHandlers.clear()}get isBrowser(){return typeof window<`u`&&typeof window.addEventListener==`function`}sendCommand(e,t){if(!this.parentWindow){this.log(`postMessage unavailable`);return}let n={type:`EmbedWidgetCommand`,command:e,params:t};this.parentWindow.postMessage(n,this.targetOrigin)}handleMessageEvent=e=>{if(this.parentWindow&&e.source!==this.parentWindow)return;let t=e.data;if(!t||typeof t!=`object`||t.type!==`EmbedWidgetMessage`)return;let n=t;if(this.isSyncedStatusUpdate(n)){let e=n.params.syncedStatus;e&&typeof e==`object`?this.emitSyncedStatusUpdate(e):this.emitSyncedStatusUpdate({}),this.emitMessage({command:n.command,params:n.params,raw:n});return}if(this.isIncomingAction(n)){if(typeof n.params.actionId!=`string`)return;let e=n.params.data&&typeof n.params.data==`object`?n.params.data:{};this.emitIncomingAction({actionId:n.params.actionId,data:e}),this.emitMessage({command:n.command,params:n.params,raw:n});return}this.log(`Unknown message command`,n.command)};isSyncedStatusUpdate(e){return e.command===`syncedStatusUpdate`}isIncomingAction(e){return e.command===`incomingAction`}emitSyncedStatusUpdate(e){for(let t of this.syncedStatusHandlers)t(e)}emitIncomingAction(e){for(let t of this.incomingActionHandlers)t(e)}emitMessage(e){for(let t of this.messageHandlers)t(e)}log(e,t){this.debugEnabled&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}},t=class t{static GLOBAL_KEY=`__withAlleoEwidgetUtils__`;options;initialized=!1;destroyed=!1;onBeforeUnload;constructor(e){this.options={autoDestroy:e?.autoDestroy??!0,debug:e?.debug??!1},this.initialize()}get isInitialized(){return this.initialized&&!this.destroyed}get isBrowser(){return typeof window<`u`&&typeof document<`u`}static getInstance(e){let n=globalThis;if(n&&typeof n==`object`&&(n[t.GLOBAL_KEY]??={},n[t.GLOBAL_KEY].instance))return n[t.GLOBAL_KEY].instance;let r=new t(e);return n&&typeof n==`object`&&(n[t.GLOBAL_KEY].instance=r),r}demo(){this.log(`DEMO`)}createEmbedWidgetMessenger(t){return new e(t)}initialize(){this.isInitialized||(this.initialized=!0,this.isBrowser&&(this.options.autoDestroy&&this.attachListeners(),this.log(`initialized`)))}destroy(){if(this.destroyed)return;this.destroyed=!0,this.isBrowser&&this.detachListeners();let e=globalThis;if(e&&typeof e==`object`){let n=e[t.GLOBAL_KEY];n?.instance===this&&(n.instance=void 0)}this.log(`destroyed`)}log(e,t){this.options.debug&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}attachListeners(){this.isBrowser&&(this.onBeforeUnload??=()=>this.destroy(),window.addEventListener(`beforeunload`,this.onBeforeUnload))}detachListeners(){this.isBrowser&&this.onBeforeUnload&&window.removeEventListener(`beforeunload`,this.onBeforeUnload)}},n=e=>t.getInstance(e),r=e=>t.getInstance().createEmbedWidgetMessenger(e);exports.AlleoEwidgetUtils=t,exports.EmbedWidgetMessenger=e,exports.getAlleoEwidgetUtils=n,exports.getEmbedWidgetMessenger=r;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{targetOrigin;parentWindow;debugEnabled;listening=!1;syncedStatusHandlers=new Set;incomingActionHandlers=new Set;messageHandlers=new Set;constructor(e){this.targetOrigin=e?.targetOrigin??`*`,this.debugEnabled=e?.debug??!1,this.parentWindow=e?.parentWindow??(this.isBrowser?window.parent:null),(e?.autoListen??!0)&&this.startListening()}get isListening(){return this.listening}triggerAction(e,t){if(!e){this.log(`triggerAction missing actionId`);return}this.sendCommand(`triggerAction`,{actionId:e,data:t})}addContent(e){this.sendCommand(`addContent`,e)}requestSyncedStatus(){this.sendCommand(`requestSyncedStatus`,{})}setSyncedStatus(e){this.sendCommand(`setSyncedStatus`,{status:e})}onSyncedStatusUpdate(e){return this.syncedStatusHandlers.add(e),()=>this.syncedStatusHandlers.delete(e)}onIncomingAction(e){return this.incomingActionHandlers.add(e),()=>this.incomingActionHandlers.delete(e)}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}startListening(){!this.isBrowser||this.listening||(window.addEventListener(`message`,this.handleMessageEvent),this.listening=!0)}stopListening(){!this.isBrowser||!this.listening||(window.removeEventListener(`message`,this.handleMessageEvent),this.listening=!1)}destroy(){this.stopListening(),this.syncedStatusHandlers.clear(),this.incomingActionHandlers.clear(),this.messageHandlers.clear()}get isBrowser(){return typeof window<`u`&&typeof window.addEventListener==`function`}sendCommand(e,t){if(!this.parentWindow){this.log(`postMessage unavailable`);return}let n={type:`EmbedWidgetCommand`,command:e,params:t};this.parentWindow.postMessage(n,this.targetOrigin)}handleMessageEvent=e=>{if(this.parentWindow&&e.source!==this.parentWindow)return;let t=e.data;if(!t||typeof t!=`object`||t.type!==`EmbedWidgetMessage`)return;let n=t;if(this.isSyncedStatusUpdate(n)){let e=n.params.syncedStatus;e&&typeof e==`object`?this.emitSyncedStatusUpdate(e):this.emitSyncedStatusUpdate({}),this.emitMessage({command:n.command,params:n.params,raw:n});return}if(this.isIncomingAction(n)){if(typeof n.params.actionId!=`string`)return;let e=n.params.data&&typeof n.params.data==`object`?n.params.data:{};this.emitIncomingAction({actionId:n.params.actionId,data:e}),this.emitMessage({command:n.command,params:n.params,raw:n});return}this.log(`Unknown message command`,n.command)};isSyncedStatusUpdate(e){return e.command===`syncedStatusUpdate`}isIncomingAction(e){return e.command===`incomingAction`}emitSyncedStatusUpdate(e){for(let t of this.syncedStatusHandlers)t(e)}emitIncomingAction(e){for(let t of this.incomingActionHandlers)t(e)}emitMessage(e){for(let t of this.messageHandlers)t(e)}log(e,t){this.debugEnabled&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}},t=class t{static GLOBAL_KEY=`__withAlleoEwidgetUtils__`;options;initialized=!1;destroyed=!1;onBeforeUnload;constructor(e){this.options={autoDestroy:e?.autoDestroy??!0,debug:e?.debug??!1},this.initialize()}get isInitialized(){return this.initialized&&!this.destroyed}get isBrowser(){return typeof window<`u`&&typeof document<`u`}static getInstance(e){let n=globalThis;if(n&&typeof n==`object`&&(n[t.GLOBAL_KEY]??={},n[t.GLOBAL_KEY].instance))return n[t.GLOBAL_KEY].instance;let r=new t(e);return n&&typeof n==`object`&&(n[t.GLOBAL_KEY].instance=r),r}createEmbedWidgetMessenger(t){return new e(t)}initialize(){this.isInitialized||(this.initialized=!0,this.isBrowser&&(this.options.autoDestroy&&this.attachListeners(),this.log(`initialized`)))}destroy(){if(this.destroyed)return;this.destroyed=!0,this.isBrowser&&this.detachListeners();let e=globalThis;if(e&&typeof e==`object`){let n=e[t.GLOBAL_KEY];n?.instance===this&&(n.instance=void 0)}this.log(`destroyed`)}log(e,t){this.options.debug&&(t===void 0?console.debug(`[ewidget-utils] ${e}`):console.debug(`[ewidget-utils] ${e}`,t))}attachListeners(){this.isBrowser&&(this.onBeforeUnload??=()=>this.destroy(),window.addEventListener(`beforeunload`,this.onBeforeUnload))}detachListeners(){this.isBrowser&&this.onBeforeUnload&&window.removeEventListener(`beforeunload`,this.onBeforeUnload)}},n=e=>t.getInstance(e),r=e=>t.getInstance().createEmbedWidgetMessenger(e);exports.AlleoEwidgetUtils=t,exports.EmbedWidgetMessenger=e,exports.getAlleoEwidgetUtils=n,exports.getEmbedWidgetMessenger=r;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public demo() {\r\n this.log('DEMO')\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -136,9 +136,6 @@ var e = class {
136
136
  let r = new t(e);
137
137
  return n && typeof n == "object" && (n[t.GLOBAL_KEY].instance = r), r;
138
138
  }
139
- demo() {
140
- this.log("DEMO");
141
- }
142
139
  createEmbedWidgetMessenger(t) {
143
140
  return new e(t);
144
141
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public demo() {\r\n this.log('DEMO')\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/EmbedWidgetMessenger.ts","../src/AlleoEwidgetUtils.ts"],"sourcesContent":["export type AddContentHtmlParams = {\r\n type: 'html'\r\n html: string\r\n}\r\n\r\nexport type AddContentNotepadParams = {\r\n type: 'notepad'\r\n text?: string | string[]\r\n textFormat?: 'text' | 'markdown' | 'html'\r\n}\r\n\r\nexport type AddContentStickyNoteParams = {\r\n type: 'sticky-note'\r\n text?: string\r\n color?: string\r\n outlineColor?: string\r\n shape?: string\r\n}\r\n\r\nexport type AddContentImageParams = {\r\n type: 'image'\r\n url: string\r\n}\r\n\r\nexport type AddContentVideoParams = {\r\n type: 'video'\r\n fileId: string\r\n}\r\n\r\nexport type AddContentParams =\r\n | AddContentHtmlParams\r\n | AddContentNotepadParams\r\n | AddContentStickyNoteParams\r\n | AddContentImageParams\r\n | AddContentVideoParams\r\n\r\nexport type EmbedWidgetCommandMap = {\r\n triggerAction: {\r\n actionId: string\r\n data?: Record<string, unknown>\r\n }\r\n addContent: AddContentParams\r\n requestSyncedStatus: Record<string, never>\r\n setSyncedStatus: {\r\n status: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetCommand = keyof EmbedWidgetCommandMap\r\n\r\nexport type EmbedWidgetCommandEnvelope<K extends EmbedWidgetCommand = EmbedWidgetCommand> = {\r\n type: 'EmbedWidgetCommand'\r\n command: K\r\n params: EmbedWidgetCommandMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageMap = {\r\n syncedStatusUpdate: {\r\n syncedStatus: Record<string, unknown>\r\n }\r\n incomingAction: {\r\n actionId: string\r\n data: Record<string, unknown>\r\n }\r\n}\r\n\r\nexport type EmbedWidgetMessageCommand = keyof EmbedWidgetMessageMap\r\n\r\nexport type EmbedWidgetMessageEnvelope<K extends EmbedWidgetMessageCommand = EmbedWidgetMessageCommand> = {\r\n type: 'EmbedWidgetMessage'\r\n command: K\r\n params: EmbedWidgetMessageMap[K]\r\n}\r\n\r\nexport type EmbedWidgetMessageEvent = {\r\n command: EmbedWidgetMessageCommand\r\n params: EmbedWidgetMessageMap[EmbedWidgetMessageCommand]\r\n raw: EmbedWidgetMessageEnvelope\r\n}\r\n\r\nexport type EmbedWidgetMessengerOptions = {\r\n targetOrigin?: string\r\n parentWindow?: Window\r\n autoListen?: boolean\r\n debug?: boolean\r\n}\r\n\r\nexport class EmbedWidgetMessenger {\r\n private readonly targetOrigin: string\r\n private readonly parentWindow: Window | null\r\n private readonly debugEnabled: boolean\r\n private listening = false\r\n private readonly syncedStatusHandlers = new Set<(status: Record<string, unknown>) => void>()\r\n private readonly incomingActionHandlers = new Set<(payload: EmbedWidgetMessageMap['incomingAction']) => void>()\r\n private readonly messageHandlers = new Set<(event: EmbedWidgetMessageEvent) => void>()\r\n\r\n public constructor(options?: EmbedWidgetMessengerOptions) {\r\n this.targetOrigin = options?.targetOrigin ?? '*'\r\n this.debugEnabled = options?.debug ?? false\r\n this.parentWindow = options?.parentWindow ?? (this.isBrowser ? window.parent : null)\r\n\r\n const autoListen = options?.autoListen ?? true\r\n if (autoListen) this.startListening()\r\n }\r\n\r\n public get isListening(): boolean {\r\n return this.listening\r\n }\r\n\r\n public triggerAction(actionId: string, data?: Record<string, unknown>): void {\r\n if (!actionId) {\r\n this.log('triggerAction missing actionId')\r\n return\r\n }\r\n this.sendCommand('triggerAction', { actionId, data })\r\n }\r\n\r\n public addContent(params: AddContentParams): void {\r\n this.sendCommand('addContent', params)\r\n }\r\n\r\n public requestSyncedStatus(): void {\r\n this.sendCommand('requestSyncedStatus', {})\r\n }\r\n\r\n public setSyncedStatus(status: Record<string, unknown>): void {\r\n this.sendCommand('setSyncedStatus', { status })\r\n }\r\n\r\n public onSyncedStatusUpdate(handler: (status: Record<string, unknown>) => void): () => void {\r\n this.syncedStatusHandlers.add(handler)\r\n return () => this.syncedStatusHandlers.delete(handler)\r\n }\r\n\r\n public onIncomingAction(handler: (payload: EmbedWidgetMessageMap['incomingAction']) => void): () => void {\r\n this.incomingActionHandlers.add(handler)\r\n return () => this.incomingActionHandlers.delete(handler)\r\n }\r\n\r\n public onMessage(handler: (event: EmbedWidgetMessageEvent) => void): () => void {\r\n this.messageHandlers.add(handler)\r\n return () => this.messageHandlers.delete(handler)\r\n }\r\n\r\n public startListening(): void {\r\n if (!this.isBrowser || this.listening) return\r\n window.addEventListener('message', this.handleMessageEvent)\r\n this.listening = true\r\n }\r\n\r\n public stopListening(): void {\r\n if (!this.isBrowser || !this.listening) return\r\n window.removeEventListener('message', this.handleMessageEvent)\r\n this.listening = false\r\n }\r\n\r\n public destroy(): void {\r\n this.stopListening()\r\n this.syncedStatusHandlers.clear()\r\n this.incomingActionHandlers.clear()\r\n this.messageHandlers.clear()\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof window.addEventListener === 'function'\r\n }\r\n\r\n private sendCommand<K extends EmbedWidgetCommand>(command: K, params: EmbedWidgetCommandMap[K]): void {\r\n if (!this.parentWindow) {\r\n this.log('postMessage unavailable')\r\n return\r\n }\r\n\r\n const message: EmbedWidgetCommandEnvelope<K> = {\r\n type: 'EmbedWidgetCommand',\r\n command,\r\n params,\r\n }\r\n\r\n this.parentWindow.postMessage(message, this.targetOrigin)\r\n }\r\n\r\n private readonly handleMessageEvent = (event: MessageEvent): void => {\r\n if (this.parentWindow && event.source !== this.parentWindow) return\r\n\r\n const data = event.data\r\n if (!data || typeof data !== 'object') return\r\n if ((data as { type?: string }).type !== 'EmbedWidgetMessage') return\r\n\r\n const envelope = data as EmbedWidgetMessageEnvelope\r\n\r\n if (this.isSyncedStatusUpdate(envelope)) {\r\n const status = envelope.params.syncedStatus\r\n if (status && typeof status === 'object') {\r\n this.emitSyncedStatusUpdate(status)\r\n } else {\r\n this.emitSyncedStatusUpdate({})\r\n }\r\n\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n if (this.isIncomingAction(envelope)) {\r\n if (typeof envelope.params.actionId !== 'string') return\r\n const actionData =\r\n envelope.params.data && typeof envelope.params.data === 'object' ? envelope.params.data : {}\r\n this.emitIncomingAction({ actionId: envelope.params.actionId, data: actionData })\r\n this.emitMessage({ command: envelope.command, params: envelope.params, raw: envelope })\r\n return\r\n }\r\n\r\n this.log('Unknown message command', envelope.command)\r\n }\r\n\r\n private isSyncedStatusUpdate(\r\n envelope: EmbedWidgetMessageEnvelope,\r\n ): envelope is EmbedWidgetMessageEnvelope<'syncedStatusUpdate'> {\r\n return envelope.command === 'syncedStatusUpdate'\r\n }\r\n\r\n private isIncomingAction(envelope: EmbedWidgetMessageEnvelope): envelope is EmbedWidgetMessageEnvelope<'incomingAction'> {\r\n return envelope.command === 'incomingAction'\r\n }\r\n\r\n private emitSyncedStatusUpdate(status: Record<string, unknown>): void {\r\n for (const handler of this.syncedStatusHandlers) handler(status)\r\n }\r\n\r\n private emitIncomingAction(payload: EmbedWidgetMessageMap['incomingAction']): void {\r\n for (const handler of this.incomingActionHandlers) handler(payload)\r\n }\r\n\r\n private emitMessage(event: EmbedWidgetMessageEvent): void {\r\n for (const handler of this.messageHandlers) handler(event)\r\n }\r\n\r\n private log(message: string, data?: unknown): void {\r\n if (!this.debugEnabled) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n}\r\n","import { EmbedWidgetMessenger, type EmbedWidgetMessengerOptions } from './EmbedWidgetMessenger.js'\r\n\r\nexport type AlleoEwidgetUtilsOptions = {\r\n autoDestroy?: boolean\r\n debug?: boolean\r\n}\r\n\r\ntype GlobalWithAlleo = typeof globalThis & {\r\n __withAlleoEwidgetUtils__?: {\r\n instance?: AlleoEwidgetUtils\r\n }\r\n}\r\n\r\nexport class AlleoEwidgetUtils {\r\n private static readonly GLOBAL_KEY = '__withAlleoEwidgetUtils__' as const\r\n private readonly options: Required<AlleoEwidgetUtilsOptions>\r\n private initialized = false\r\n private destroyed = false\r\n private onBeforeUnload?: (event: BeforeUnloadEvent) => void\r\n\r\n public constructor(options?: AlleoEwidgetUtilsOptions) {\r\n this.options = {\r\n autoDestroy: options?.autoDestroy ?? true,\r\n debug: options?.debug ?? false,\r\n }\r\n\r\n this.initialize()\r\n }\r\n\r\n public get isInitialized(): boolean {\r\n return this.initialized && !this.destroyed\r\n }\r\n\r\n private get isBrowser(): boolean {\r\n return typeof window !== 'undefined' && typeof document !== 'undefined'\r\n }\r\n\r\n public static getInstance(options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils {\r\n // Prefer a global singleton if running in a browser and the bundle was included multiple times.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY] ??= {}\r\n if (g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance) {\r\n return g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance!\r\n }\r\n }\r\n\r\n const instance = new AlleoEwidgetUtils(options)\r\n if (g && typeof g === 'object') {\r\n g[AlleoEwidgetUtils.GLOBAL_KEY]!.instance = instance\r\n }\r\n return instance\r\n }\r\n\r\n public createEmbedWidgetMessenger(options?: EmbedWidgetMessengerOptions): EmbedWidgetMessenger {\r\n return new EmbedWidgetMessenger(options)\r\n }\r\n\r\n public initialize(): void {\r\n if (this.isInitialized) return\r\n this.initialized = true\r\n\r\n if (!this.isBrowser) return\r\n\r\n if (this.options.autoDestroy) this.attachListeners()\r\n\r\n this.log('initialized')\r\n }\r\n\r\n public destroy(): void {\r\n if (this.destroyed) return\r\n this.destroyed = true\r\n\r\n if (this.isBrowser) this.detachListeners()\r\n\r\n // If this instance is the stored global singleton, clear it so callers can recreate.\r\n const g = globalThis as GlobalWithAlleo\r\n if (g && typeof g === 'object') {\r\n const holder = g[AlleoEwidgetUtils.GLOBAL_KEY]\r\n if (holder?.instance === this) holder.instance = undefined\r\n }\r\n\r\n this.log('destroyed')\r\n }\r\n\r\n public log(message: string, data?: unknown): void {\r\n if (!this.options.debug) return\r\n // eslint-disable-next-line no-console\r\n if (data === undefined) console.debug(`[ewidget-utils] ${message}`)\r\n // eslint-disable-next-line no-console\r\n else console.debug(`[ewidget-utils] ${message}`, data)\r\n }\r\n\r\n private attachListeners(): void {\r\n if (!this.isBrowser) return\r\n\r\n this.onBeforeUnload ??= () => this.destroy()\r\n window.addEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n\r\n private detachListeners(): void {\r\n if (!this.isBrowser) return\r\n if (!this.onBeforeUnload) return\r\n window.removeEventListener('beforeunload', this.onBeforeUnload)\r\n }\r\n}\r\n\r\nexport const getAlleoEwidgetUtils = (options?: AlleoEwidgetUtilsOptions): AlleoEwidgetUtils => AlleoEwidgetUtils.getInstance(options)\r\nexport const getEmbedWidgetMessenger = (options?: EmbedWidgetMessengerOptions) =>\r\n AlleoEwidgetUtils.getInstance().createEmbedWidgetMessenger(options)\r\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withalleo/ewidget-utils",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Alleo e-widget utility library.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,7 +40,8 @@
40
40
  },
41
41
  "scripts": {
42
42
  "clean": "rimraf dist",
43
- "build": "vite build && tsc -p tsconfig.build.json"
43
+ "build": "vite build && tsc -p tsconfig.build.json",
44
+ "publish": "npm run clean && npm run build && npm version patch && npm publish"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@eslint/js": "^9.22.0",