@schoolpalm/message-bridge 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/AUTHORS +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +198 -0
  4. package/TODO.md +13 -0
  5. package/dist/__tests__/bridge.test.d.ts +6 -0
  6. package/dist/__tests__/bridge.test.d.ts.map +1 -0
  7. package/dist/__tests__/bridge.test.js +84 -0
  8. package/dist/__tests__/bridge.test.js.map +1 -0
  9. package/dist/bridgeBase.d.ts +70 -0
  10. package/dist/bridgeBase.d.ts.map +1 -0
  11. package/dist/bridgeBase.js +76 -0
  12. package/dist/bridgeBase.js.map +1 -0
  13. package/dist/hostBridge.d.ts +52 -0
  14. package/dist/hostBridge.d.ts.map +1 -0
  15. package/dist/hostBridge.js +59 -0
  16. package/dist/hostBridge.js.map +1 -0
  17. package/dist/index.d.ts +20 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +20 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/messageTypes.d.ts +38 -0
  22. package/dist/messageTypes.d.ts.map +1 -0
  23. package/dist/messageTypes.js +40 -0
  24. package/dist/messageTypes.js.map +1 -0
  25. package/dist/moduleBridge.d.ts +61 -0
  26. package/dist/moduleBridge.d.ts.map +1 -0
  27. package/dist/moduleBridge.js +70 -0
  28. package/dist/moduleBridge.js.map +1 -0
  29. package/dist/payloadSchemas.d.ts +97 -0
  30. package/dist/payloadSchemas.d.ts.map +1 -0
  31. package/dist/payloadSchemas.js +6 -0
  32. package/dist/payloadSchemas.js.map +1 -0
  33. package/package.json +36 -0
  34. package/src/__tests__/bridge.test.ts +100 -0
  35. package/src/bridgeBase.ts +93 -0
  36. package/src/hostBridge.ts +63 -0
  37. package/src/index.ts +20 -0
  38. package/src/messageTypes.ts +40 -0
  39. package/src/moduleBridge.ts +79 -0
  40. package/src/payloadSchemas.ts +115 -0
  41. package/tsconfig.json +18 -0
  42. package/vitest.config.ts +8 -0
package/AUTHORS ADDED
@@ -0,0 +1,7 @@
1
+ # Authors
2
+
3
+ This project is maintained by the SchoolPalm development team.
4
+
5
+ ## Contributors
6
+
7
+ - Hassan Mugabo <cybarox@gmail.com> - Lead Developer
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mugabo Hassan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+
2
+ # @schoolpalm/message-bridge
3
+
4
+ [![npm version](https://badge.fury.io/js/%40schoolpalm%2Fmessage-bridge.svg)](https://badge.fury.io/js/%40schoolpalm%2Fmessage-bridge)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ TypeScript SDK for message-based communication between SchoolPalm host and vendor modules.
8
+
9
+ ## Overview
10
+
11
+ The `@schoolpalm/message-bridge` SDK provides a robust, type-safe way to establish bidirectional communication between a host web application and embedded modules (typically iframes) using the browser's `postMessage` API. This enables seamless integration of third-party modules into the SchoolPalm platform while maintaining security through origin restrictions.
12
+
13
+ ## Features
14
+
15
+ - **Type-safe messaging**: Full TypeScript support with strongly typed message payloads
16
+ - **Bidirectional communication**: Send messages from host to module and vice versa
17
+ - **Security-focused**: Origin restrictions and structured message protocols
18
+ - **Event-driven architecture**: Register listeners for specific message types
19
+ - **Lightweight**: Minimal dependencies, focused on core functionality
20
+ - **Well-tested**: Comprehensive test suite with Vitest
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @schoolpalm/message-bridge
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ ### Host Application
31
+
32
+ ```typescript
33
+ import { HostBridge, MessageType } from '@schoolpalm/message-bridge';
34
+
35
+ // Create a bridge for an embedded iframe
36
+ const iframe = document.getElementById('module-iframe') as HTMLIFrameElement;
37
+ const hostBridge = new HostBridge(iframe, 'https://module.example.com');
38
+
39
+ // Start a module with context
40
+ hostBridge.sendModuleStart({
41
+ route: '/dashboard',
42
+ context: { userId: 123, permissions: ['read', 'write'] },
43
+ timestamp: Date.now()
44
+ });
45
+
46
+ // Listen for UI updates from the module
47
+ hostBridge.on(MessageType.UI_UPDATE, (payload) => {
48
+ document.title = payload.title;
49
+ updateBreadcrumb(payload.breadcrumb);
50
+ });
51
+
52
+ // Listen for data requests
53
+ hostBridge.on(MessageType.DATA_REQUEST, (payload) => {
54
+ // Handle data request and send response
55
+ const response = fetchData(payload.action, payload.payload);
56
+ hostBridge.send(MessageType.DATA_RESPONSE, {
57
+ requestId: payload.requestId,
58
+ status: 'success',
59
+ payload: response
60
+ });
61
+ });
62
+ ```
63
+
64
+ ### Embedded Module
65
+
66
+ ```typescript
67
+ import { ModuleBridge, MessageType } from '@schoolpalm/message-bridge';
68
+
69
+ // Create a bridge for the module
70
+ const moduleBridge = new ModuleBridge('https://host.example.com');
71
+
72
+ // Send handshake when ready
73
+ moduleBridge.sendHandshake({
74
+ version: '1.0.0',
75
+ timestamp: Date.now()
76
+ });
77
+
78
+ // Listen for module start
79
+ moduleBridge.on(MessageType.MODULE_START, (payload) => {
80
+ navigateToRoute(payload.route);
81
+ initializeWithContext(payload.context);
82
+ });
83
+
84
+ // Update host UI
85
+ moduleBridge.sendUIUpdate({
86
+ title: 'User Management',
87
+ breadcrumb: ['Home', 'Users', 'Management'],
88
+ theme: 'dark'
89
+ });
90
+
91
+ // Request data from host
92
+ moduleBridge.send(MessageType.DATA_REQUEST, {
93
+ requestId: 'user-list-123',
94
+ action: 'getUsers',
95
+ payload: { page: 1, limit: 20 }
96
+ });
97
+ ```
98
+
99
+ ## API Reference
100
+
101
+ ### Classes
102
+
103
+ - **`BridgeBase`**: Abstract base class providing core messaging functionality
104
+ - **`HostBridge`**: Host-side bridge for communicating with embedded modules
105
+ - **`ModuleBridge`**: Module-side bridge for communicating with the host application
106
+
107
+ ### Message Types
108
+
109
+ The SDK defines a comprehensive set of message types for different communication scenarios:
110
+
111
+ - `HANDSHAKE_READY`: Module signals readiness to the host
112
+ - `MODULE_START`: Host initializes a module with context
113
+ - `UI_UPDATE`: Module updates host UI (title, breadcrumb, theme)
114
+ - `DATA_REQUEST`: Module requests data from host
115
+ - `DATA_RESPONSE`: Host responds to data requests
116
+ - `ERROR`: Module reports errors to host
117
+ - `MODULE_EXIT`: Host signals module to clean up and exit
118
+
119
+ ### Payload Schemas
120
+
121
+ All message payloads are strongly typed TypeScript interfaces:
122
+
123
+ - `HandshakeReadyPayload`
124
+ - `ModuleStartPayload`
125
+ - `UIUpdatePayload`
126
+ - `DataRequestPayload`
127
+ - `DataResponsePayload`
128
+ - `ErrorPayload`
129
+ - `ModuleExitPayload`
130
+
131
+ ## Project Structure
132
+
133
+ ```
134
+ src/
135
+ ├── index.ts # Main entry point and exports
136
+ ├── bridgeBase.ts # Base bridge class with core functionality
137
+ ├── hostBridge.ts # Host-side bridge implementation
138
+ ├── moduleBridge.ts # Module-side bridge implementation
139
+ ├── messageTypes.ts # Message type enumerations
140
+ ├── payloadSchemas.ts # TypeScript interfaces for payloads
141
+ └── __tests__/
142
+ └── bridge.test.ts # Test suite
143
+ ```
144
+
145
+ ## Development
146
+
147
+ ### Prerequisites
148
+
149
+ - Node.js 16+
150
+ - npm or yarn
151
+
152
+ ### Setup
153
+
154
+ ```bash
155
+ # Clone the repository
156
+ git clone <repository-url>
157
+ cd message-bridge
158
+
159
+ # Install dependencies
160
+ npm install
161
+
162
+ # Run tests
163
+ npm test
164
+
165
+ # Build the project
166
+ npm run build
167
+
168
+ # Lint code
169
+ npm run lint
170
+ ```
171
+
172
+ ### Scripts
173
+
174
+ - `npm run build`: Compile TypeScript to JavaScript
175
+ - `npm run watch`: Watch mode for development
176
+ - `npm run test`: Run test suite
177
+ - `npm run test:watch`: Run tests in watch mode
178
+ - `npm run lint`: Lint and fix code style issues
179
+
180
+ ## Contributing
181
+
182
+ 1. Fork the repository
183
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
184
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
185
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
186
+ 5. Open a Pull Request
187
+
188
+ ## License
189
+
190
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
191
+
192
+ ## Authors
193
+
194
+ See the [AUTHORS](AUTHORS) file for a list of contributors.
195
+
196
+ ## Support
197
+
198
+ For questions or support, please contact the SchoolPalm development team.
package/TODO.md ADDED
@@ -0,0 +1,13 @@
1
+ # TODO: Project Documentation and Enhancement
2
+
3
+ ## Tasks
4
+ - [x] Enhance README.md with detailed documentation
5
+ - [x] Add doc comments to src/index.ts
6
+ - [x] Add doc comments to src/bridgeBase.ts
7
+ - [x] Add doc comments to src/hostBridge.ts
8
+ - [x] Add doc comments to src/moduleBridge.ts
9
+ - [x] Add doc comments to src/messageTypes.ts
10
+ - [x] Add doc comments to src/payloadSchemas.ts
11
+ - [x] Add doc comments to src/__tests__/bridge.test.ts
12
+ - [x] Create AUTHORS file for npm package
13
+ - [x] Verify LICENSE and package.json setup
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Test suite for the MessageBridge SDK.
3
+ * @module @schoolpalm/message-bridge/__tests__/bridge.test
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=bridge.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bridge.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @fileoverview Test suite for the MessageBridge SDK.
3
+ * @module @schoolpalm/message-bridge/__tests__/bridge.test
4
+ */
5
+ import { describe, it, expect, beforeEach, vi } from 'vitest';
6
+ import { HostBridge, ModuleBridge, MessageType } from '../index';
7
+ /**
8
+ * Test suite for the MessageBridge SDK.
9
+ *
10
+ * This suite tests the core functionality of both HostBridge and ModuleBridge
11
+ * classes, including message sending, receiving, and event handling.
12
+ */
13
+ describe('MessageBridge SDK', () => {
14
+ let iframeMock;
15
+ beforeEach(() => {
16
+ // Simulate an iframe with contentWindow
17
+ iframeMock = {
18
+ contentWindow: {
19
+ postMessage: vi.fn()
20
+ }
21
+ };
22
+ // Mock parent window for ModuleBridge
23
+ vi.stubGlobal('parent', {
24
+ postMessage: vi.fn()
25
+ });
26
+ });
27
+ // -----------------------
28
+ // HostBridge Tests
29
+ // -----------------------
30
+ /**
31
+ * Test that HostBridge sends module-start messages correctly.
32
+ */
33
+ it('HostBridge sends module-start correctly', () => {
34
+ const hostBridge = new HostBridge(iframeMock);
35
+ hostBridge.sendModuleStart({ route: '/users', context: {}, timestamp: Date.now() });
36
+ expect(iframeMock.contentWindow.postMessage).toHaveBeenCalledTimes(1);
37
+ const callArg = iframeMock.contentWindow.postMessage.mock.calls[0][0];
38
+ expect(callArg.type).toBe(MessageType.MODULE_START);
39
+ expect(callArg.payload.route).toBe('/users');
40
+ });
41
+ /**
42
+ * Test that HostBridge can register listeners and receive messages.
43
+ */
44
+ it('HostBridge can register and receive messages', () => {
45
+ const hostBridge = new HostBridge(iframeMock);
46
+ const callback = vi.fn();
47
+ hostBridge.on(MessageType.UI_UPDATE, callback);
48
+ // Simulate incoming postMessage from iframe
49
+ const event = new MessageEvent('message', {
50
+ data: {
51
+ type: MessageType.UI_UPDATE,
52
+ payload: { title: 'Test', breadcrumb: ['Home'] }
53
+ }
54
+ });
55
+ window.dispatchEvent(event);
56
+ expect(callback).toHaveBeenCalledTimes(1);
57
+ expect(callback.mock.calls[0][0].title).toBe('Test');
58
+ });
59
+ // -----------------------
60
+ // ModuleBridge Tests
61
+ // -----------------------
62
+ /**
63
+ * Test that ModuleBridge sends handshake messages correctly.
64
+ */
65
+ it('ModuleBridge sends handshake correctly', () => {
66
+ const moduleBridge = new ModuleBridge();
67
+ moduleBridge.sendHandshake({ version: '0.1.0', timestamp: Date.now() });
68
+ expect(window.parent.postMessage).toHaveBeenCalledTimes(1);
69
+ const callArg = window.parent.postMessage.mock.calls[0][0];
70
+ expect(callArg.type).toBe(MessageType.HANDSHAKE_READY);
71
+ expect(callArg.payload.version).toBe('0.1.0');
72
+ });
73
+ /**
74
+ * Test that ModuleBridge sends UI update messages.
75
+ */
76
+ it('ModuleBridge sends UI update', () => {
77
+ const moduleBridge = new ModuleBridge();
78
+ moduleBridge.sendUIUpdate({ title: 'Users', breadcrumb: ['Home', 'Users'] });
79
+ const callArg = window.parent.postMessage.mock.calls[0][0];
80
+ expect(callArg.type).toBe(MessageType.UI_UPDATE);
81
+ expect(callArg.payload.breadcrumb.length).toBe(2);
82
+ });
83
+ });
84
+ //# sourceMappingURL=bridge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.js","sourceRoot":"","sources":["../../src/__tests__/bridge.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @fileoverview Base bridge class for message-based communication.
3
+ * @module @schoolpalm/message-bridge/bridgeBase
4
+ */
5
+ import { MessageType } from './messageTypes';
6
+ import { MessagePayload } from './payloadSchemas';
7
+ /**
8
+ * Type definition for message handler functions.
9
+ * @template T - The type of message payload this handler accepts.
10
+ */
11
+ type MessageHandler<T extends MessagePayload> = (payload: T) => void;
12
+ /**
13
+ * Base class for Host and Module bridges.
14
+ *
15
+ * This abstract base class provides the core functionality for message-based
16
+ * communication between windows using the postMessage API. It handles sending
17
+ * messages, registering listeners, and managing event listeners.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * class CustomBridge extends BridgeBase {
22
+ * constructor(targetWindow: Window) {
23
+ * super(targetWindow, 'https://example.com');
24
+ * }
25
+ *
26
+ * // Add custom methods here
27
+ * }
28
+ * ```
29
+ */
30
+ export declare class BridgeBase {
31
+ /** The target window to send messages to. */
32
+ protected targetWindow: Window;
33
+ /** The origin to restrict messages to. */
34
+ protected targetOrigin: string;
35
+ /** Map of message type to array of handler functions. */
36
+ private listeners;
37
+ /**
38
+ * Creates a new BridgeBase instance.
39
+ * @param targetWindow - The window to send messages to.
40
+ * @param targetOrigin - The origin to restrict messages to (default: '*').
41
+ */
42
+ constructor(targetWindow: Window, targetOrigin?: string);
43
+ /**
44
+ * Sends a message to the target window.
45
+ * @template T - The type of the message payload.
46
+ * @param type - The message type to send.
47
+ * @param payload - The payload data to send.
48
+ */
49
+ send<T extends MessagePayload>(type: MessageType, payload: T): void;
50
+ /**
51
+ * Registers a listener for a specific message type.
52
+ * @template T - The type of the message payload.
53
+ * @param type - The message type to listen for.
54
+ * @param callback - The function to call when a message of this type is received.
55
+ */
56
+ on<T extends MessagePayload>(type: MessageType, callback: MessageHandler<T>): void;
57
+ /**
58
+ * Internal message handler for incoming postMessage events.
59
+ * @private
60
+ * @param event - The message event received.
61
+ */
62
+ private _handleMessage;
63
+ /**
64
+ * Cleans up event listeners and resources.
65
+ * Call this method when the bridge is no longer needed.
66
+ */
67
+ destroy(): void;
68
+ }
69
+ export {};
70
+ //# sourceMappingURL=bridgeBase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeBase.d.ts","sourceRoot":"","sources":["../src/bridgeBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD;;;GAGG;AACH,KAAK,cAAc,CAAC,CAAC,SAAS,cAAc,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAErE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,UAAU;IACrB,6CAA6C;IAC7C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC/B,0CAA0C;IAC1C,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC;IAC/B,yDAAyD;IACzD,OAAO,CAAC,SAAS,CAAsD;IAEvE;;;;OAIG;gBACS,YAAY,EAAE,MAAM,EAAE,YAAY,GAAE,MAAY;IAM5D;;;;;OAKG;IACH,IAAI,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;IAI5D;;;;;OAKG;IACH,EAAE,CAAC,CAAC,SAAS,cAAc,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IAK3E;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACH,OAAO;CAIR"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @fileoverview Base bridge class for message-based communication.
3
+ * @module @schoolpalm/message-bridge/bridgeBase
4
+ */
5
+ /**
6
+ * Base class for Host and Module bridges.
7
+ *
8
+ * This abstract base class provides the core functionality for message-based
9
+ * communication between windows using the postMessage API. It handles sending
10
+ * messages, registering listeners, and managing event listeners.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * class CustomBridge extends BridgeBase {
15
+ * constructor(targetWindow: Window) {
16
+ * super(targetWindow, 'https://example.com');
17
+ * }
18
+ *
19
+ * // Add custom methods here
20
+ * }
21
+ * ```
22
+ */
23
+ export class BridgeBase {
24
+ /**
25
+ * Creates a new BridgeBase instance.
26
+ * @param targetWindow - The window to send messages to.
27
+ * @param targetOrigin - The origin to restrict messages to (default: '*').
28
+ */
29
+ constructor(targetWindow, targetOrigin = '*') {
30
+ /** Map of message type to array of handler functions. */
31
+ this.listeners = new Map();
32
+ this.targetWindow = targetWindow;
33
+ this.targetOrigin = targetOrigin;
34
+ window.addEventListener('message', this._handleMessage.bind(this));
35
+ }
36
+ /**
37
+ * Sends a message to the target window.
38
+ * @template T - The type of the message payload.
39
+ * @param type - The message type to send.
40
+ * @param payload - The payload data to send.
41
+ */
42
+ send(type, payload) {
43
+ this.targetWindow.postMessage({ type, payload }, this.targetOrigin);
44
+ }
45
+ /**
46
+ * Registers a listener for a specific message type.
47
+ * @template T - The type of the message payload.
48
+ * @param type - The message type to listen for.
49
+ * @param callback - The function to call when a message of this type is received.
50
+ */
51
+ on(type, callback) {
52
+ if (!this.listeners.has(type))
53
+ this.listeners.set(type, []);
54
+ this.listeners.get(type)?.push(callback);
55
+ }
56
+ /**
57
+ * Internal message handler for incoming postMessage events.
58
+ * @private
59
+ * @param event - The message event received.
60
+ */
61
+ _handleMessage(event) {
62
+ const { type, payload } = event.data || {};
63
+ if (!type || !this.listeners.has(type))
64
+ return;
65
+ this.listeners.get(type)?.forEach(cb => cb(payload));
66
+ }
67
+ /**
68
+ * Cleans up event listeners and resources.
69
+ * Call this method when the bridge is no longer needed.
70
+ */
71
+ destroy() {
72
+ window.removeEventListener('message', this._handleMessage.bind(this));
73
+ this.listeners.clear();
74
+ }
75
+ }
76
+ //# sourceMappingURL=bridgeBase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeBase.js","sourceRoot":"","sources":["../src/bridgeBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,UAAU;IAQrB;;;;OAIG;IACH,YAAY,YAAoB,EAAE,eAAuB,GAAG;QAR5D,yDAAyD;QACjD,cAAS,GAA4C,IAAI,GAAG,EAAE,CAAC;QAQrE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAA2B,IAAiB,EAAE,OAAU;QAC1D,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IACtE,CAAC;IAED;;;;;OAKG;IACH,EAAE,CAA2B,IAAiB,EAAE,QAA2B;QACzE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACK,cAAc,CAAC,KAAmB;QACxC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO;QAC/C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @fileoverview Host-side bridge for communication with embedded modules.
3
+ * @module @schoolpalm/message-bridge/hostBridge
4
+ */
5
+ import { BridgeBase } from './bridgeBase';
6
+ import { ModuleStartPayload } from './payloadSchemas';
7
+ /**
8
+ * Host-side bridge for communication with embedded modules.
9
+ *
10
+ * This class extends BridgeBase to provide host-specific functionality for
11
+ * communicating with modules embedded in iframes. It handles initialization
12
+ * and termination of modules.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const iframe = document.getElementById('module-iframe') as HTMLIFrameElement;
17
+ * const hostBridge = new HostBridge(iframe, 'https://module.example.com');
18
+ *
19
+ * // Start a module
20
+ * hostBridge.sendModuleStart({
21
+ * route: '/dashboard',
22
+ * context: { userId: 123 },
23
+ * timestamp: Date.now()
24
+ * });
25
+ *
26
+ * // Listen for UI updates from the module
27
+ * hostBridge.on(MessageType.UI_UPDATE, (payload) => {
28
+ * console.log('UI Update:', payload);
29
+ * });
30
+ * ```
31
+ */
32
+ export declare class HostBridge extends BridgeBase {
33
+ /**
34
+ * Creates a new HostBridge instance.
35
+ * @param iframe - The iframe element containing the module.
36
+ * @param targetOrigin - The origin to restrict messages to (default: '*').
37
+ */
38
+ constructor(iframe: HTMLIFrameElement, targetOrigin?: string);
39
+ /**
40
+ * Sends a module-start message to the embedded module.
41
+ * This initializes the module with the provided route and context.
42
+ * @param payload - The module start payload containing route, context, and timestamp.
43
+ */
44
+ sendModuleStart(payload: ModuleStartPayload): void;
45
+ /**
46
+ * Sends a module-exit message to the embedded module.
47
+ * This signals the module to clean up and terminate.
48
+ * @param reason - Optional reason for the module exit.
49
+ */
50
+ sendModuleExit(reason?: string): void;
51
+ }
52
+ //# sourceMappingURL=hostBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostBridge.d.ts","sourceRoot":"","sources":["../src/hostBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC;;;;OAIG;gBACS,MAAM,EAAE,iBAAiB,EAAE,YAAY,GAAE,MAAY;IAIjE;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,kBAAkB;IAI3C;;;;OAIG;IACH,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM;CAG/B"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Host-side bridge for communication with embedded modules.
3
+ * @module @schoolpalm/message-bridge/hostBridge
4
+ */
5
+ // src/hostBridge.ts
6
+ import { BridgeBase } from './bridgeBase';
7
+ import { MessageType } from './messageTypes';
8
+ /**
9
+ * Host-side bridge for communication with embedded modules.
10
+ *
11
+ * This class extends BridgeBase to provide host-specific functionality for
12
+ * communicating with modules embedded in iframes. It handles initialization
13
+ * and termination of modules.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const iframe = document.getElementById('module-iframe') as HTMLIFrameElement;
18
+ * const hostBridge = new HostBridge(iframe, 'https://module.example.com');
19
+ *
20
+ * // Start a module
21
+ * hostBridge.sendModuleStart({
22
+ * route: '/dashboard',
23
+ * context: { userId: 123 },
24
+ * timestamp: Date.now()
25
+ * });
26
+ *
27
+ * // Listen for UI updates from the module
28
+ * hostBridge.on(MessageType.UI_UPDATE, (payload) => {
29
+ * console.log('UI Update:', payload);
30
+ * });
31
+ * ```
32
+ */
33
+ export class HostBridge extends BridgeBase {
34
+ /**
35
+ * Creates a new HostBridge instance.
36
+ * @param iframe - The iframe element containing the module.
37
+ * @param targetOrigin - The origin to restrict messages to (default: '*').
38
+ */
39
+ constructor(iframe, targetOrigin = '*') {
40
+ super(iframe.contentWindow, targetOrigin);
41
+ }
42
+ /**
43
+ * Sends a module-start message to the embedded module.
44
+ * This initializes the module with the provided route and context.
45
+ * @param payload - The module start payload containing route, context, and timestamp.
46
+ */
47
+ sendModuleStart(payload) {
48
+ this.send(MessageType.MODULE_START, payload);
49
+ }
50
+ /**
51
+ * Sends a module-exit message to the embedded module.
52
+ * This signals the module to clean up and terminate.
53
+ * @param reason - Optional reason for the module exit.
54
+ */
55
+ sendModuleExit(reason) {
56
+ this.send(MessageType.MODULE_EXIT, { reason });
57
+ }
58
+ }
59
+ //# sourceMappingURL=hostBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostBridge.js","sourceRoot":"","sources":["../src/hostBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAoB;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,UAAW,SAAQ,UAAU;IACxC;;;;OAIG;IACH,YAAY,MAAyB,EAAE,eAAuB,GAAG;QAC/D,KAAK,CAAC,MAAM,CAAC,aAAc,EAAE,YAAY,CAAC,CAAC;IAC7C,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,OAA2B;QACzC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,MAAe;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @module @schoolpalm/message-bridge
4
+ *
5
+ * TypeScript SDK for message-based communication between SchoolPalm host and vendor modules.
6
+ *
7
+ * This module exports the main classes and types for establishing communication
8
+ * between a host application and embedded modules using the postMessage API.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { HostBridge, ModuleBridge, MessageType } from '@schoolpalm/message-bridge';
13
+ * ```
14
+ */
15
+ export { BridgeBase } from './bridgeBase';
16
+ export { HostBridge } from './hostBridge';
17
+ export { ModuleBridge } from './moduleBridge';
18
+ export { MessageType } from './messageTypes';
19
+ export * from './payloadSchemas';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,cAAc,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @module @schoolpalm/message-bridge
4
+ *
5
+ * TypeScript SDK for message-based communication between SchoolPalm host and vendor modules.
6
+ *
7
+ * This module exports the main classes and types for establishing communication
8
+ * between a host application and embedded modules using the postMessage API.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { HostBridge, ModuleBridge, MessageType } from '@schoolpalm/message-bridge';
13
+ * ```
14
+ */
15
+ export { BridgeBase } from './bridgeBase';
16
+ export { HostBridge } from './hostBridge';
17
+ export { ModuleBridge } from './moduleBridge';
18
+ export { MessageType } from './messageTypes';
19
+ export * from './payloadSchemas';
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,cAAc,kBAAkB,CAAC"}