Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@
"@aws-sdk/client-s3": "^3.44.0",
"@aws-sdk/s3-request-presigner": "^3.44.0",
"@concord-consortium/dynamic-text": "^1.0.6",
"@concord-consortium/interactive-api-host": "^0.8.0",
"@concord-consortium/lara-interactive-api": "^1.10.0",
"@concord-consortium/interactive-api-host": "0.10.0",
"@concord-consortium/lara-interactive-api": "1.11.0",
"@concord-consortium/object-storage": "1.0.0-pre.6",
"@concord-consortium/text-decorator": "^1.0.2",
"@concord-consortium/token-service": "^2.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import {
IGetInteractiveSnapshotResponse, IInitInteractive, ILinkedInteractive, IReportInitInteractive,
ISupportedFeatures, ServerMessage, IShowModal, ICloseModal, INavigationOptions, ILinkedInteractiveStateResponse,
IAddLinkedInteractiveStateListenerRequest, IRemoveLinkedInteractiveStateListenerRequest, IDecoratedContentEvent,
ITextDecorationInfo, ITextDecorationHandlerInfo, IAttachmentUrlRequest, IAttachmentUrlResponse, IGetInteractiveState, AttachmentInfoMap
ITextDecorationInfo, ITextDecorationHandlerInfo, IAttachmentUrlRequest, IAttachmentUrlResponse, IGetInteractiveState, AttachmentInfoMap,
IPubSubCreateChannel, IPubSubSubscribe, IPubSubUnsubscribe, IPubSubPublish
} from "@concord-consortium/lara-interactive-api";
import { PubSubManager } from "@concord-consortium/interactive-api-host";
import { DynamicTextCustomMessageType, DynamicTextMessage, useDynamicTextContext } from "@concord-consortium/dynamic-text";
import { FirebaseObjectStorageConfig, FirebaseObjectStorageUser } from "@concord-consortium/object-storage";
import Shutterbug from "shutterbug";
Expand Down Expand Up @@ -88,6 +90,9 @@ interface IProps {
log: (logData: any) => void;
}

// this is managed outside of the component to persist across component unmount/mount cycles
const pubSubManager = new PubSubManager();

export const IframeRuntime: React.ForwardRefExoticComponent<IProps> = forwardRef((props, ref) => {
const { url, id, authoredState, initialInteractiveState, legacyLinkedInteractiveState, setInteractiveState, linkedInteractives, report,
proposedHeight, containerWidth, setNewHint, getFirebaseJWT, getAttachmentUrl, showModal, closeModal, setSupportedFeatures,
Expand Down Expand Up @@ -122,6 +127,8 @@ export const IframeRuntime: React.ForwardRefExoticComponent<IProps> = forwardRef
return;
}

pubSubManager.addInteractive(id, phone);

// Just to add some type checking to phone post (ServerMessage).
const post = (type: ServerMessage, data: any) => phone.post(type, data);
const addListener = (type: ClientMessage, handler: any) => phone.addListener(type, handler);
Expand Down Expand Up @@ -276,6 +283,18 @@ export const IframeRuntime: React.ForwardRefExoticComponent<IProps> = forwardRef
}
}
});
addListener("createChannel", (message: IPubSubCreateChannel) => {
pubSubManager.createChannel(message.channelId, message.channelInfo);
});
addListener("publish", (message: IPubSubPublish) => {
pubSubManager.publish(id, message.channelId, message.message);
});
addListener("subscribe", (message: IPubSubSubscribe) => {
pubSubManager.subscribe(id, message.channelId, message.subscriptionId);
});
addListener("unsubscribe", (message: IPubSubUnsubscribe) => {
pubSubManager.unsubscribe(id, message.channelId, message.subscriptionId);
});

// Legacy bug fix: In the 1.0.0 release of the AP the special 'nochange'
// message wasn't handled correctly and it was saved as the interactive state
Expand Down Expand Up @@ -419,6 +438,8 @@ export const IframeRuntime: React.ForwardRefExoticComponent<IProps> = forwardRef
dynamicText.unregisterComponent(componentId);
});

pubSubManager.removeInteractive(id);

if (phoneRef.current) {
phoneRef.current.disconnect();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,37 @@ jest.mock("@concord-consortium/token-service", () => ({
}));

const mockHandleGetAttachmentUrl = jest.fn();
jest.mock("@concord-consortium/interactive-api-host", () => ({
handleGetAttachmentUrl: (...args: any) => mockHandleGetAttachmentUrl(...args)
}));
let mockAddInteractive: jest.Mock;
let mockRemoveInteractive: jest.Mock;
let mockCreateChannel: jest.Mock;
let mockSubscribe: jest.Mock;
let mockUnsubscribe: jest.Mock;
let mockPublish: jest.Mock;

jest.mock("@concord-consortium/interactive-api-host", () => {
// Initialize the mock functions
mockAddInteractive = jest.fn();
mockRemoveInteractive = jest.fn();
mockCreateChannel = jest.fn();
mockSubscribe = jest.fn();
mockUnsubscribe = jest.fn();
mockPublish = jest.fn();

// Create a mock class that returns an instance with all the methods
class MockPubSubManager {
addInteractive = mockAddInteractive;
removeInteractive = mockRemoveInteractive;
createChannel = mockCreateChannel;
subscribe = mockSubscribe;
unsubscribe = mockUnsubscribe;
publish = mockPublish;
}

return {
handleGetAttachmentUrl: (...args: any) => mockHandleGetAttachmentUrl(...args),
PubSubManager: MockPubSubManager
};
});

const mockWatchAnswer = jest.fn((id: string, callback: (answer: any) => void) => callback({ meta: {} }));
jest.mock("../../../firebase-db", () => ({
Expand Down
Loading