@sprucelabs/heartwood-view-controllers 118.0.27 → 118.0.28

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 (33) hide show
  1. package/build/.spruce/schemas/heartwoodViewControllers/v2021_02_11/webRtcPlayer.schema.js +5 -0
  2. package/build/.spruce/schemas/schemas.types.d.ts +8 -0
  3. package/build/esm/.spruce/schemas/heartwoodViewControllers/v2021_02_11/webRtcPlayer.schema.js +5 -0
  4. package/build/esm/.spruce/schemas/schemas.types.d.ts +8 -0
  5. package/build/esm/index.d.ts +3 -2
  6. package/build/esm/index.js +3 -2
  7. package/build/esm/schemas/v2021_02_11/webRtcPlayer.builder.d.ts +6 -0
  8. package/build/esm/schemas/v2021_02_11/webRtcPlayer.builder.js +6 -0
  9. package/build/esm/tests/MockRtcPeerConnection.d.ts +7 -4
  10. package/build/esm/tests/MockRtcPeerConnection.js +18 -4
  11. package/build/esm/types/heartwood.types.d.ts +1 -0
  12. package/build/esm/types/heartwood.types.js +1 -0
  13. package/build/esm/viewControllers/webRtcStreaming/WebRtcPlayer.vc.d.ts +2 -1
  14. package/build/esm/viewControllers/webRtcStreaming/WebRtcPlayer.vc.js +6 -3
  15. package/build/esm/webRtcStreaming/WebRtcConnection.d.ts +17 -5
  16. package/build/esm/webRtcStreaming/WebRtcConnection.js +24 -4
  17. package/build/esm/webRtcStreaming/WebRtcStreamer.d.ts +5 -3
  18. package/build/esm/webRtcStreaming/WebRtcStreamer.js +8 -3
  19. package/build/index.d.ts +3 -2
  20. package/build/index.js +5 -4
  21. package/build/schemas/v2021_02_11/webRtcPlayer.builder.d.ts +6 -0
  22. package/build/schemas/v2021_02_11/webRtcPlayer.builder.js +6 -0
  23. package/build/tests/MockRtcPeerConnection.d.ts +7 -4
  24. package/build/tests/MockRtcPeerConnection.js +18 -5
  25. package/build/types/heartwood.types.d.ts +1 -0
  26. package/build/types/heartwood.types.js +1 -0
  27. package/build/viewControllers/webRtcStreaming/WebRtcPlayer.vc.d.ts +2 -1
  28. package/build/viewControllers/webRtcStreaming/WebRtcPlayer.vc.js +8 -4
  29. package/build/webRtcStreaming/WebRtcConnection.d.ts +17 -5
  30. package/build/webRtcStreaming/WebRtcConnection.js +22 -5
  31. package/build/webRtcStreaming/WebRtcStreamer.d.ts +5 -3
  32. package/build/webRtcStreaming/WebRtcStreamer.js +6 -3
  33. package/package.json +1 -1
@@ -19,6 +19,11 @@ const webRtcPlayerSchema = {
19
19
  options: { valueType: `HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>`, }
20
20
  },
21
21
  /** . */
22
+ 'connection': {
23
+ type: 'raw',
24
+ options: { valueType: `HeartwoodTypes.WebRtcConnection`, }
25
+ },
26
+ /** . */
22
27
  'streamer': {
23
28
  type: 'raw',
24
29
  options: { valueType: `HeartwoodTypes.WebRtcStreamer`, }
@@ -708,6 +708,7 @@ declare module '@sprucelabs/spruce-core-schemas/build/.spruce/schemas/core.schem
708
708
  interface WebRtcPlayer {
709
709
  'id'?: string | undefined | null;
710
710
  'controller'?: (HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>) | undefined | null;
711
+ 'connection'?: (HeartwoodTypes.WebRtcConnection) | undefined | null;
711
712
  'streamer'?: (HeartwoodTypes.WebRtcStreamer) | undefined | null;
712
713
  }
713
714
  interface WebRtcPlayerSchema extends SpruceSchema.Schema {
@@ -730,6 +731,13 @@ declare module '@sprucelabs/spruce-core-schemas/build/.spruce/schemas/core.schem
730
731
  };
731
732
  };
732
733
  /** . */
734
+ 'connection': {
735
+ type: 'raw';
736
+ options: {
737
+ valueType: `HeartwoodTypes.WebRtcConnection`;
738
+ };
739
+ };
740
+ /** . */
733
741
  'streamer': {
734
742
  type: 'raw';
735
743
  options: {
@@ -17,6 +17,11 @@ const webRtcPlayerSchema = {
17
17
  options: { valueType: `HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>`, }
18
18
  },
19
19
  /** . */
20
+ 'connection': {
21
+ type: 'raw',
22
+ options: { valueType: `HeartwoodTypes.WebRtcConnection`, }
23
+ },
24
+ /** . */
20
25
  'streamer': {
21
26
  type: 'raw',
22
27
  options: { valueType: `HeartwoodTypes.WebRtcStreamer`, }
@@ -708,6 +708,7 @@ declare module '@sprucelabs/spruce-core-schemas/build/.spruce/schemas/core.schem
708
708
  interface WebRtcPlayer {
709
709
  'id'?: string | undefined | null;
710
710
  'controller'?: (HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>) | undefined | null;
711
+ 'connection'?: (HeartwoodTypes.WebRtcConnection) | undefined | null;
711
712
  'streamer'?: (HeartwoodTypes.WebRtcStreamer) | undefined | null;
712
713
  }
713
714
  interface WebRtcPlayerSchema extends SpruceSchema.Schema {
@@ -730,6 +731,13 @@ declare module '@sprucelabs/spruce-core-schemas/build/.spruce/schemas/core.schem
730
731
  };
731
732
  };
732
733
  /** . */
734
+ 'connection': {
735
+ type: 'raw';
736
+ options: {
737
+ valueType: `HeartwoodTypes.WebRtcConnection`;
738
+ };
739
+ };
740
+ /** . */
733
741
  'streamer': {
734
742
  type: 'raw';
735
743
  options: {
@@ -69,8 +69,9 @@ export { default as buildBigForm } from './builders/buildBigForm';
69
69
  export { default as buildForm } from './builders/buildForm';
70
70
  export { default as buildSkillView } from './builders/buildSkillView';
71
71
  export { WebRtcStreamer, default as WebRtcStreamerImpl, } from './webRtcStreaming/WebRtcStreamer';
72
- export { default as WebRtcConnection } from './webRtcStreaming/WebRtcConnection';
73
- export { default as MocRtcPeerConnection } from './tests/MockRtcPeerConnection';
72
+ export { default as MockRtcPeerConnection } from './tests/MockRtcPeerConnection';
73
+ export { default as WebRtcConnectionImpl } from './webRtcStreaming/WebRtcConnection';
74
+ export * from './webRtcStreaming/WebRtcConnection';
74
75
  export { default as calendarEventColorsSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/calendarEventColors.schema';
75
76
  export { default as bigFormSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/bigForm.schema';
76
77
  export { default as skillViewSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/skillView.schema';
@@ -68,8 +68,9 @@ export { default as buildBigForm } from './builders/buildBigForm.js';
68
68
  export { default as buildForm } from './builders/buildForm.js';
69
69
  export { default as buildSkillView } from './builders/buildSkillView.js';
70
70
  export { default as WebRtcStreamerImpl, } from './webRtcStreaming/WebRtcStreamer.js';
71
- export { default as WebRtcConnection } from './webRtcStreaming/WebRtcConnection.js';
72
- export { default as MocRtcPeerConnection } from './tests/MockRtcPeerConnection.js';
71
+ export { default as MockRtcPeerConnection } from './tests/MockRtcPeerConnection.js';
72
+ export { default as WebRtcConnectionImpl } from './webRtcStreaming/WebRtcConnection.js';
73
+ export * from './webRtcStreaming/WebRtcConnection.js';
73
74
  export { default as calendarEventColorsSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/calendarEventColors.schema.js';
74
75
  export { default as bigFormSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/bigForm.schema.js';
75
76
  export { default as skillViewSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/skillView.schema.js';
@@ -10,6 +10,12 @@ declare const _default: {
10
10
  valueType: string;
11
11
  };
12
12
  };
13
+ connection: {
14
+ type: "raw";
15
+ options: {
16
+ valueType: string;
17
+ };
18
+ };
13
19
  streamer: {
14
20
  type: "raw";
15
21
  options: {
@@ -11,6 +11,12 @@ export default buildSchema({
11
11
  valueType: 'HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>',
12
12
  },
13
13
  },
14
+ connection: {
15
+ type: 'raw',
16
+ options: {
17
+ valueType: 'HeartwoodTypes.WebRtcConnection',
18
+ },
19
+ },
14
20
  streamer: {
15
21
  type: 'raw',
16
22
  options: {
@@ -1,12 +1,13 @@
1
- export default class MocRtcPeerConnection implements RTCPeerConnection {
2
- static instance: MocRtcPeerConnection;
1
+ export default class MockRtcPeerConnection implements RTCPeerConnection {
2
+ static instance: MockRtcPeerConnection;
3
+ private static onCreateOfferHandler?;
3
4
  private constructorOptions?;
4
5
  private offerOptions?;
5
6
  offer: RTCSessionDescription;
6
7
  private lastAddedEventListener?;
7
8
  constructor(options?: RTCConfiguration);
8
- assertGeneratedOfferEquals(offer: RTCSessionDescriptionInit): void;
9
- assertGeneratedOfferSdpEquals(sdp: string): void;
9
+ assertCreatedOfferEquals(offer: RTCSessionDescriptionInit): void;
10
+ assertCreatedOfferSdpEquals(sdp: string): void;
10
11
  assertCreatedWithOptions(expected: {
11
12
  sdpSemantics: string;
12
13
  iceServers: never[];
@@ -18,6 +19,8 @@ export default class MocRtcPeerConnection implements RTCPeerConnection {
18
19
  sdp: string;
19
20
  }): void;
20
21
  assertTrackListenerSet(expected: () => void): void;
22
+ static onCreateOffer(cb?: () => void): void;
23
+ emitTrackAdded(): void;
21
24
  canTrickleIceCandidates: boolean | null;
22
25
  connectionState: RTCPeerConnectionState;
23
26
  currentLocalDescription: RTCSessionDescription | null;
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { assert, generateId } from '@sprucelabs/test-utils';
11
- export default class MocRtcPeerConnection {
11
+ export default class MockRtcPeerConnection {
12
12
  constructor(options) {
13
13
  this.offer = {
14
14
  [generateId()]: generateId(),
@@ -34,13 +34,13 @@ export default class MocRtcPeerConnection {
34
34
  this.remoteDescription = null;
35
35
  this.sctp = null;
36
36
  this.signalingState = {};
37
- MocRtcPeerConnection.instance = this;
37
+ MockRtcPeerConnection.instance = this;
38
38
  this.constructorOptions = options;
39
39
  }
40
- assertGeneratedOfferEquals(offer) {
40
+ assertCreatedOfferEquals(offer) {
41
41
  assert.isEqualDeep(offer, this.offer, 'Did not return the generated offer');
42
42
  }
43
- assertGeneratedOfferSdpEquals(sdp) {
43
+ assertCreatedOfferSdpEquals(sdp) {
44
44
  assert.isEqualDeep(this.offer.sdp, sdp, 'Did not return the generated offer sdp');
45
45
  }
46
46
  assertCreatedWithOptions(expected) {
@@ -61,6 +61,18 @@ export default class MocRtcPeerConnection {
61
61
  listener: expected,
62
62
  }, 'did not call connection.addEventListener with track listener');
63
63
  }
64
+ static onCreateOffer(cb) {
65
+ this.onCreateOfferHandler = cb;
66
+ }
67
+ emitTrackAdded() {
68
+ const lastListener = this.lastAddedEventListener;
69
+ if ((lastListener === null || lastListener === void 0 ? void 0 : lastListener.eventName) === 'track') {
70
+ lastListener.listener({});
71
+ }
72
+ else {
73
+ assert.fail('Did not call connection.addEventListener with track listener');
74
+ }
75
+ }
64
76
  addIceCandidate(_candidate, _successCallback, _failureCallback) {
65
77
  return __awaiter(this, void 0, void 0, function* () {
66
78
  throw new Error('Method not implemented.');
@@ -86,7 +98,9 @@ export default class MocRtcPeerConnection {
86
98
  //@ts-ignore
87
99
  createOffer(options) {
88
100
  return __awaiter(this, void 0, void 0, function* () {
101
+ var _a;
89
102
  this.offerOptions = options;
103
+ (_a = MockRtcPeerConnection.onCreateOfferHandler) === null || _a === void 0 ? void 0 : _a.call(MockRtcPeerConnection);
90
104
  return this.offer;
91
105
  });
92
106
  }
@@ -257,6 +257,7 @@ export type ListColumnWidth = NonNullable<List['columnWidths']>[number];
257
257
  export type TriggerRender = () => void;
258
258
  export type TriggerRenderHandler = () => void;
259
259
  export { WebRtcStreamer } from '../webRtcStreaming/WebRtcStreamer';
260
+ export * from '../webRtcStreaming/WebRtcConnection';
260
261
  export interface ViewController<ViewModel extends Record<string, any>> {
261
262
  render(): ViewModel;
262
263
  setTriggerRenderHandler: (handler: TriggerRenderHandler) => void;
@@ -45,3 +45,4 @@ export const authContract = buildEventContract({
45
45
  },
46
46
  },
47
47
  });
48
+ export * from '../webRtcStreaming/WebRtcConnection.js';
@@ -1,9 +1,10 @@
1
- import { AbstractViewController } from '../..';
2
1
  import { ViewControllerOptions, WebRtcPlayer } from '../../types/heartwood.types';
3
2
  import { WebRtcStreamer } from '../../webRtcStreaming/WebRtcStreamer';
3
+ import AbstractViewController from '../Abstract.vc';
4
4
  export default class WebRtcPlayerViewController extends AbstractViewController<WebRtcPlayer> {
5
5
  static id: string;
6
6
  private model;
7
+ private connection;
7
8
  constructor(options: ViewControllerOptions & WebRtcPlayerOptions);
8
9
  setStreamer(streamer: WebRtcStreamer): void;
9
10
  createOffer(offerOptions: RTCOfferOptions): Promise<string>;
@@ -8,12 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { assertOptions } from '@sprucelabs/schema';
11
- import { AbstractViewController, removeUniversalViewOptions, WebRtcConnection, } from '../../index.js';
12
11
  import SpruceError from '../../errors/SpruceError.js';
12
+ import removeUniversalViewOptions from '../../utilities/removeUniversalViewOptions.js';
13
+ import WebRtcConnectionImpl from '../../webRtcStreaming/WebRtcConnection.js';
14
+ import AbstractViewController from '../Abstract.vc.js';
13
15
  class WebRtcPlayerViewController extends AbstractViewController {
14
16
  constructor(options) {
15
17
  super(options);
16
- this.model = Object.assign(Object.assign({}, removeUniversalViewOptions(options)), { controller: this });
18
+ this.connection = WebRtcConnectionImpl.Connection();
19
+ this.model = Object.assign(Object.assign({ connection: this.connection }, removeUniversalViewOptions(options)), { controller: this });
17
20
  }
18
21
  setStreamer(streamer) {
19
22
  assertOptions({ streamer }, ['streamer']);
@@ -22,7 +25,7 @@ class WebRtcPlayerViewController extends AbstractViewController {
22
25
  }
23
26
  createOffer(offerOptions) {
24
27
  return __awaiter(this, void 0, void 0, function* () {
25
- const { offerSdp, streamer } = yield WebRtcConnection.createOffer({
28
+ const { offerSdp, streamer } = yield this.connection.createOffer({
26
29
  offerOptions,
27
30
  });
28
31
  this.setStreamer(streamer);
@@ -1,12 +1,14 @@
1
1
  import MockRtcPeerConnection from '../tests/MockRtcPeerConnection';
2
2
  import { WebRtcStreamer } from './WebRtcStreamer';
3
- export default class WebRtcConnection {
3
+ export default class WebRtcConnectionImpl implements WebRtcConnection {
4
+ static Class: new () => WebRtcConnection;
4
5
  static get RTCPeerConnection(): new (config: RTCConfiguration) => RTCPeerConnection | MockRtcPeerConnection;
5
6
  static set RTCPeerConnection(value: new (config: RTCConfiguration) => RTCPeerConnection | MockRtcPeerConnection);
6
- static createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<{
7
- offerSdp: RTCSessionDescriptionInit;
8
- streamer: WebRtcStreamer;
9
- }>;
7
+ private stateChangeHandlers;
8
+ static Connection(): WebRtcConnection;
9
+ createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
10
+ private emitStateChange;
11
+ onStateChange(cb: WebRtcStateChangeHandler): void;
10
12
  }
11
13
  export interface WebRtcVcPluginCreateOfferOptions {
12
14
  offerOptions: {
@@ -14,3 +16,13 @@ export interface WebRtcVcPluginCreateOfferOptions {
14
16
  offerToReceiveVideo?: boolean;
15
17
  };
16
18
  }
19
+ export type WebRtcConnectionState = 'createdOffer' | 'suppliedAnswer' | 'trackAdded';
20
+ export type WebRtcStateChangeHandler = (state: WebRtcConnectionState) => void | Promise<void>;
21
+ export interface WebRtcConnection {
22
+ createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
23
+ onStateChange(cb: WebRtcStateChangeHandler): void;
24
+ }
25
+ export interface WebRtcCreateOfferResponse {
26
+ offerSdp: RTCSessionDescriptionInit;
27
+ streamer: WebRtcStreamer;
28
+ }
@@ -9,27 +9,47 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { assertOptions } from '@sprucelabs/schema';
11
11
  import WebRtcStreamerImpl from './WebRtcStreamer.js';
12
- export default class WebRtcConnection {
12
+ export default class WebRtcConnectionImpl {
13
+ constructor() {
14
+ this.stateChangeHandlers = [];
15
+ }
13
16
  static get RTCPeerConnection() {
14
17
  return window.RTCPeerConnection;
15
18
  }
16
19
  static set RTCPeerConnection(value) {
17
20
  global.window.RTCPeerConnection = value;
18
21
  }
19
- static createOffer(options) {
22
+ static Connection() {
23
+ var _a;
24
+ return new ((_a = this.Class) !== null && _a !== void 0 ? _a : this)();
25
+ }
26
+ createOffer(options) {
20
27
  return __awaiter(this, void 0, void 0, function* () {
21
28
  const { offerOptions } = assertOptions(options, ['offerOptions']);
22
- const connection = new WebRtcConnection.RTCPeerConnection({
29
+ const connection = new WebRtcConnectionImpl.RTCPeerConnection({
23
30
  //@ts-ignore
24
31
  sdpSemantics: 'unified-plan',
25
32
  iceServers: [],
26
33
  });
27
34
  const offer = yield connection.createOffer(offerOptions);
28
35
  yield connection.setLocalDescription(offer);
36
+ void this.emitStateChange('createdOffer');
29
37
  return {
30
38
  offerSdp: offer,
31
- streamer: WebRtcStreamerImpl.Streamer(connection),
39
+ streamer: WebRtcStreamerImpl.Streamer(connection, (status) => __awaiter(this, void 0, void 0, function* () {
40
+ yield this.emitStateChange(status);
41
+ })),
32
42
  };
33
43
  });
34
44
  }
45
+ emitStateChange(state) {
46
+ return __awaiter(this, void 0, void 0, function* () {
47
+ for (const handler of this.stateChangeHandlers) {
48
+ yield handler(state);
49
+ }
50
+ });
51
+ }
52
+ onStateChange(cb) {
53
+ this.stateChangeHandlers.push(cb);
54
+ }
35
55
  }
@@ -1,8 +1,10 @@
1
+ import { WebRtcStateChangeHandler } from './WebRtcConnection';
1
2
  export default class WebRtcStreamerImpl implements WebRtcStreamer {
2
3
  private connection;
3
- static Class?: new (connection: RTCPeerConnection) => WebRtcStreamer;
4
- protected constructor(connection: RTCPeerConnection);
5
- static Streamer(connection: RTCPeerConnection): WebRtcStreamer;
4
+ static Class?: new (connection: RTCPeerConnection, stateChangeHandlers?: WebRtcStateChangeHandler) => WebRtcStreamer;
5
+ private stateChangeHandler?;
6
+ protected constructor(connection: RTCPeerConnection, stateChangeHandler?: WebRtcStateChangeHandler);
7
+ static Streamer(connection: RTCPeerConnection, stateChangeHandler?: WebRtcStateChangeHandler): WebRtcStreamer;
6
8
  setAnswer(answerSdp: string): Promise<void>;
7
9
  onTrack(cb: (event: RTCTrackEvent) => void): void;
8
10
  }
@@ -9,23 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { assertOptions } from '@sprucelabs/schema';
11
11
  export default class WebRtcStreamerImpl {
12
- constructor(connection) {
12
+ constructor(connection, stateChangeHandler) {
13
13
  this.connection = connection;
14
+ this.stateChangeHandler = stateChangeHandler;
14
15
  }
15
- static Streamer(connection) {
16
+ static Streamer(connection, stateChangeHandler) {
16
17
  var _a;
17
- return new ((_a = this.Class) !== null && _a !== void 0 ? _a : this)(connection);
18
+ return new ((_a = this.Class) !== null && _a !== void 0 ? _a : this)(connection, stateChangeHandler);
18
19
  }
19
20
  setAnswer(answerSdp) {
20
21
  return __awaiter(this, void 0, void 0, function* () {
22
+ var _a;
21
23
  assertOptions({ answerSdp }, ['answerSdp']);
22
24
  yield this.connection.setRemoteDescription({
23
25
  type: 'answer',
24
26
  sdp: answerSdp,
25
27
  });
28
+ yield ((_a = this.stateChangeHandler) === null || _a === void 0 ? void 0 : _a.call(this, 'suppliedAnswer'));
26
29
  });
27
30
  }
28
31
  onTrack(cb) {
32
+ var _a;
29
33
  this.connection.addEventListener('track', cb);
34
+ void ((_a = this.stateChangeHandler) === null || _a === void 0 ? void 0 : _a.call(this, 'trackAdded'));
30
35
  }
31
36
  }
package/build/index.d.ts CHANGED
@@ -69,8 +69,9 @@ export { default as buildBigForm } from './builders/buildBigForm';
69
69
  export { default as buildForm } from './builders/buildForm';
70
70
  export { default as buildSkillView } from './builders/buildSkillView';
71
71
  export { WebRtcStreamer, default as WebRtcStreamerImpl, } from './webRtcStreaming/WebRtcStreamer';
72
- export { default as WebRtcConnection } from './webRtcStreaming/WebRtcConnection';
73
- export { default as MocRtcPeerConnection } from './tests/MockRtcPeerConnection';
72
+ export { default as MockRtcPeerConnection } from './tests/MockRtcPeerConnection';
73
+ export { default as WebRtcConnectionImpl } from './webRtcStreaming/WebRtcConnection';
74
+ export * from './webRtcStreaming/WebRtcConnection';
74
75
  export { default as calendarEventColorsSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/calendarEventColors.schema';
75
76
  export { default as bigFormSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/bigForm.schema';
76
77
  export { default as skillViewSchema } from './.spruce/schemas/heartwoodViewControllers/v2021_02_11/skillView.schema';
package/build/index.js CHANGED
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.MocRtcPeerConnection = exports.WebRtcConnection = exports.WebRtcStreamerImpl = exports.buildSkillView = exports.buildForm = exports.buildBigForm = exports.AuthenticatorImpl = exports.PolarAreaViewController = exports.SpyViewControllerExporter = exports.lockScreenAssert = exports.MockActiveRecordCard = exports.activeRecordCardAssert = exports.buildActiveRecordList = exports.buildActiveRecordCard = exports.AbstractInputViewController = exports.AutocompleteInputViewController = exports.AbstractCalendarEventViewController = exports.RatingsViewController = exports.ProgressViewController = exports.StatsViewController = exports.FeedViewController = exports.ActiveRecordListViewController = exports.ActiveRecordCardViewController = exports.TalkingSprucebotViewController = exports.ButtonBarViewController = exports.CalendarViewController = exports.SwipeCardViewControllerImpl = exports.SwipeViewControllerImpl = exports.WebRtcPlayerViewController = exports.PagerViewController = exports.ProgressNavigatorViewController = exports.CountdownTimerViewController = exports.FormBuilderCardViewControllerImpl = exports.LoginViewController = exports.LineGraphViewController = exports.BarChartViewController = exports.ToolBeltViewController = exports.FormViewControllerImpl = exports.ListCellViewController = exports.ListRowViewController = exports.ListViewController = exports.NavigationViewController = exports.LockScreenSkillViewController = exports.DialogViewController = exports.ConfirmViewController = exports.CardViewControllerImpl = exports.ButtonGroupViewController = exports.AbstractAppController = exports.AbstractViewController = exports.AbstractSkillViewController = void 0;
20
+ exports.WebRtcConnectionImpl = exports.MockRtcPeerConnection = exports.WebRtcStreamerImpl = exports.buildSkillView = exports.buildForm = exports.buildBigForm = exports.AuthenticatorImpl = exports.PolarAreaViewController = exports.SpyViewControllerExporter = exports.lockScreenAssert = exports.MockActiveRecordCard = exports.activeRecordCardAssert = exports.buildActiveRecordList = exports.buildActiveRecordCard = exports.AbstractInputViewController = exports.AutocompleteInputViewController = exports.AbstractCalendarEventViewController = exports.RatingsViewController = exports.ProgressViewController = exports.StatsViewController = exports.FeedViewController = exports.ActiveRecordListViewController = exports.ActiveRecordCardViewController = exports.TalkingSprucebotViewController = exports.ButtonBarViewController = exports.CalendarViewController = exports.SwipeCardViewControllerImpl = exports.SwipeViewControllerImpl = exports.WebRtcPlayerViewController = exports.PagerViewController = exports.ProgressNavigatorViewController = exports.CountdownTimerViewController = exports.FormBuilderCardViewControllerImpl = exports.LoginViewController = exports.LineGraphViewController = exports.BarChartViewController = exports.ToolBeltViewController = exports.FormViewControllerImpl = exports.ListCellViewController = exports.ListRowViewController = exports.ListViewController = exports.NavigationViewController = exports.LockScreenSkillViewController = exports.DialogViewController = exports.ConfirmViewController = exports.CardViewControllerImpl = exports.ButtonGroupViewController = exports.AbstractAppController = exports.AbstractViewController = exports.AbstractSkillViewController = void 0;
21
21
  exports.buttonBarButtonSchema = exports.buttonBarSchema = exports.toolBeltToolSchema = exports.toolBeltSchema = exports.calendarTimeSchema = exports.calendarPersonSchema = exports.calendarSchema = exports.themePropsSchema = exports.themeSchema = exports.cardFooterButtonSchema = exports.criticalErrorSchema = exports.sprucebotTypedMessageSentenceSchema = exports.sprucebotTypedMessageAvatarSchema = exports.selectInputChoiceSchema = exports.calendarEventColorOverrideSchema = exports.portalSchema = exports.listTextInputSchema = exports.listSelectInputSchema = exports.listCellButtonSchema = exports.dropdownButtonSchema = exports.bigFormSectionSchema = exports.textInputSchema = exports.phoneInputSchema = exports.inputSchema = exports.dropdownSchema = exports.sprucebotTypedMessageSchema = exports.talkingSprucebotSchema = exports.sprucebotAvatarSchema = exports.formBuilderImportExportObjectSchema = exports.listCellSchema = exports.listRowSchema = exports.listSchema = exports.layoutSchema = exports.cardSectionSchema = exports.cardHeaderSchema = exports.cardFooterSchema = exports.cardBodySchema = exports.cardSchema = exports.formSectionSchema = exports.formSchema = exports.textSchema = exports.lockScreenSchema = exports.dialogSchema = exports.buttonSchema = exports.lineIconSchema = exports.fancyIconSchema = exports.selectInputSchema = exports.skillViewSchema = exports.bigFormSchema = exports.calendarEventColorsSchema = void 0;
22
22
  exports.listAssert = exports.buttonAssert = exports.deviceAssert = exports.navigationAssert = exports.toolBeltAssert = exports.toastAssert = exports.vcPluginAssert = exports.vcDurationAssert = exports.pagerAssert = exports.vcAssert = exports.vcAssertUtil = exports.feedAssert = exports.feedInteractor = exports.normalizeFormSectionFieldNamesUtil = exports.ViewControllerError = exports.SpyDevice = exports.StubStorage = exports.ViewControllerFactory = exports.ViewControllerImporter = exports.ViewControllerExporter = exports.webRtcPlayerSchema = exports.pagerSchema = exports.polarAreaDataItemSchema = exports.polarAreaSchema = exports.inputButtonSchema = exports.mapPinSchema = exports.mapSchema = exports.latLngSchema = exports.formBuilderImportExportPageSchema = exports.autocompleteSuggestionSchema = exports.autocompleteInputSchema = exports.feedSchema = exports.calendarShiftSchema = exports.receiptTotalSchema = exports.receiptSectionSchema = exports.receiptLineItemSchema = exports.receiptHeaderSchema = exports.receiptSchema = exports.listDateInputSchema = exports.calendarSelectedDateSchema = exports.calendarEventSchema = exports.ratingsInputSchema = exports.listRatingsInputSchema = exports.ratingsSchema = exports.progressSchema = exports.statsStatSchema = exports.statsSchema = exports.toggleInputSchema = exports.listToggleInputSchema = exports.addressInputSchema = void 0;
23
23
  exports.navigationRouteSchema = exports.routerDestinationSchema = exports.navigationDropdownButtonSchema = exports.navigationButtonDropdownSchema = exports.chartDataSetSchema = exports.chartDataPointSchema = exports.lineGraphSchema = exports.barChartSchema = exports.progressDetailsSchema = exports.progressNavigatorStepSchema = exports.progressNavigatorSchema = exports.countdownTimerSchema = exports.permissionContractReferenceSchema = exports.navigationButtonSchema = exports.navigationSchema = exports.ToolBeltStateMachine = exports.removeUniversalViewOptions = exports.buildSkillViewLayout = exports.splitCardsIntoLayouts = exports.listUtil = exports.mapInteractor = exports.mapAssert = exports.renderUtil = exports.routerTestPatcher = exports.dialogTestPatcher = exports.confirmTestPatcher = exports.calendarSeeder = exports.interactionUtil = exports.chartAssert = exports.progressNavigatorAssert = exports.countdownTimerInteractor = exports.countdownTimerAssert = exports.calendarInteractor = exports.interactor = exports.normalizeScopeFromVc = exports.autocompleteInteractor = exports.webRtcAssert = exports.formAssert = exports.autocompleteAssert = void 0;
@@ -139,10 +139,11 @@ var buildSkillView_1 = require("./builders/buildSkillView");
139
139
  Object.defineProperty(exports, "buildSkillView", { enumerable: true, get: function () { return __importDefault(buildSkillView_1).default; } });
140
140
  var WebRtcStreamer_1 = require("./webRtcStreaming/WebRtcStreamer");
141
141
  Object.defineProperty(exports, "WebRtcStreamerImpl", { enumerable: true, get: function () { return __importDefault(WebRtcStreamer_1).default; } });
142
- var WebRtcConnection_1 = require("./webRtcStreaming/WebRtcConnection");
143
- Object.defineProperty(exports, "WebRtcConnection", { enumerable: true, get: function () { return __importDefault(WebRtcConnection_1).default; } });
144
142
  var MockRtcPeerConnection_1 = require("./tests/MockRtcPeerConnection");
145
- Object.defineProperty(exports, "MocRtcPeerConnection", { enumerable: true, get: function () { return __importDefault(MockRtcPeerConnection_1).default; } });
143
+ Object.defineProperty(exports, "MockRtcPeerConnection", { enumerable: true, get: function () { return __importDefault(MockRtcPeerConnection_1).default; } });
144
+ var WebRtcConnection_1 = require("./webRtcStreaming/WebRtcConnection");
145
+ Object.defineProperty(exports, "WebRtcConnectionImpl", { enumerable: true, get: function () { return __importDefault(WebRtcConnection_1).default; } });
146
+ __exportStar(require("./webRtcStreaming/WebRtcConnection"), exports);
146
147
  var calendarEventColors_schema_1 = require("./.spruce/schemas/heartwoodViewControllers/v2021_02_11/calendarEventColors.schema");
147
148
  Object.defineProperty(exports, "calendarEventColorsSchema", { enumerable: true, get: function () { return __importDefault(calendarEventColors_schema_1).default; } });
148
149
  var bigForm_schema_1 = require("./.spruce/schemas/heartwoodViewControllers/v2021_02_11/bigForm.schema");
@@ -10,6 +10,12 @@ declare const _default: {
10
10
  valueType: string;
11
11
  };
12
12
  };
13
+ connection: {
14
+ type: "raw";
15
+ options: {
16
+ valueType: string;
17
+ };
18
+ };
13
19
  streamer: {
14
20
  type: "raw";
15
21
  options: {
@@ -13,6 +13,12 @@ exports.default = (0, schema_1.buildSchema)({
13
13
  valueType: 'HeartwoodTypes.ViewController<HeartwoodTypes.WebRtcPlayer>',
14
14
  },
15
15
  },
16
+ connection: {
17
+ type: 'raw',
18
+ options: {
19
+ valueType: 'HeartwoodTypes.WebRtcConnection',
20
+ },
21
+ },
16
22
  streamer: {
17
23
  type: 'raw',
18
24
  options: {
@@ -1,12 +1,13 @@
1
- export default class MocRtcPeerConnection implements RTCPeerConnection {
2
- static instance: MocRtcPeerConnection;
1
+ export default class MockRtcPeerConnection implements RTCPeerConnection {
2
+ static instance: MockRtcPeerConnection;
3
+ private static onCreateOfferHandler?;
3
4
  private constructorOptions?;
4
5
  private offerOptions?;
5
6
  offer: RTCSessionDescription;
6
7
  private lastAddedEventListener?;
7
8
  constructor(options?: RTCConfiguration);
8
- assertGeneratedOfferEquals(offer: RTCSessionDescriptionInit): void;
9
- assertGeneratedOfferSdpEquals(sdp: string): void;
9
+ assertCreatedOfferEquals(offer: RTCSessionDescriptionInit): void;
10
+ assertCreatedOfferSdpEquals(sdp: string): void;
10
11
  assertCreatedWithOptions(expected: {
11
12
  sdpSemantics: string;
12
13
  iceServers: never[];
@@ -18,6 +19,8 @@ export default class MocRtcPeerConnection implements RTCPeerConnection {
18
19
  sdp: string;
19
20
  }): void;
20
21
  assertTrackListenerSet(expected: () => void): void;
22
+ static onCreateOffer(cb?: () => void): void;
23
+ emitTrackAdded(): void;
21
24
  canTrickleIceCandidates: boolean | null;
22
25
  connectionState: RTCPeerConnectionState;
23
26
  currentLocalDescription: RTCSessionDescription | null;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const test_utils_1 = require("@sprucelabs/test-utils");
4
- class MocRtcPeerConnection {
4
+ class MockRtcPeerConnection {
5
5
  constructor(options) {
6
6
  this.offer = {
7
7
  [(0, test_utils_1.generateId)()]: (0, test_utils_1.generateId)(),
@@ -27,13 +27,13 @@ class MocRtcPeerConnection {
27
27
  this.remoteDescription = null;
28
28
  this.sctp = null;
29
29
  this.signalingState = {};
30
- MocRtcPeerConnection.instance = this;
30
+ MockRtcPeerConnection.instance = this;
31
31
  this.constructorOptions = options;
32
32
  }
33
- assertGeneratedOfferEquals(offer) {
33
+ assertCreatedOfferEquals(offer) {
34
34
  test_utils_1.assert.isEqualDeep(offer, this.offer, 'Did not return the generated offer');
35
35
  }
36
- assertGeneratedOfferSdpEquals(sdp) {
36
+ assertCreatedOfferSdpEquals(sdp) {
37
37
  test_utils_1.assert.isEqualDeep(this.offer.sdp, sdp, 'Did not return the generated offer sdp');
38
38
  }
39
39
  assertCreatedWithOptions(expected) {
@@ -54,6 +54,18 @@ class MocRtcPeerConnection {
54
54
  listener: expected,
55
55
  }, 'did not call connection.addEventListener with track listener');
56
56
  }
57
+ static onCreateOffer(cb) {
58
+ this.onCreateOfferHandler = cb;
59
+ }
60
+ emitTrackAdded() {
61
+ const lastListener = this.lastAddedEventListener;
62
+ if (lastListener?.eventName === 'track') {
63
+ lastListener.listener({});
64
+ }
65
+ else {
66
+ test_utils_1.assert.fail('Did not call connection.addEventListener with track listener');
67
+ }
68
+ }
57
69
  async addIceCandidate(_candidate, _successCallback, _failureCallback) {
58
70
  throw new Error('Method not implemented.');
59
71
  }
@@ -75,6 +87,7 @@ class MocRtcPeerConnection {
75
87
  //@ts-ignore
76
88
  async createOffer(options) {
77
89
  this.offerOptions = options;
90
+ MockRtcPeerConnection.onCreateOfferHandler?.();
78
91
  return this.offer;
79
92
  }
80
93
  getConfiguration() {
@@ -115,4 +128,4 @@ class MocRtcPeerConnection {
115
128
  return true;
116
129
  }
117
130
  }
118
- exports.default = MocRtcPeerConnection;
131
+ exports.default = MockRtcPeerConnection;
@@ -257,6 +257,7 @@ export type ListColumnWidth = NonNullable<List['columnWidths']>[number];
257
257
  export type TriggerRender = () => void;
258
258
  export type TriggerRenderHandler = () => void;
259
259
  export { WebRtcStreamer } from '../webRtcStreaming/WebRtcStreamer';
260
+ export * from '../webRtcStreaming/WebRtcConnection';
260
261
  export interface ViewController<ViewModel extends Record<string, any>> {
261
262
  render(): ViewModel;
262
263
  setTriggerRenderHandler: (handler: TriggerRenderHandler) => void;
@@ -66,3 +66,4 @@ exports.authContract = (0, mercury_types_1.buildEventContract)({
66
66
  },
67
67
  },
68
68
  });
69
+ __exportStar(require("../webRtcStreaming/WebRtcConnection"), exports);
@@ -1,9 +1,10 @@
1
- import { AbstractViewController } from '../..';
2
1
  import { ViewControllerOptions, WebRtcPlayer } from '../../types/heartwood.types';
3
2
  import { WebRtcStreamer } from '../../webRtcStreaming/WebRtcStreamer';
3
+ import AbstractViewController from '../Abstract.vc';
4
4
  export default class WebRtcPlayerViewController extends AbstractViewController<WebRtcPlayer> {
5
5
  static id: string;
6
6
  private model;
7
+ private connection;
7
8
  constructor(options: ViewControllerOptions & WebRtcPlayerOptions);
8
9
  setStreamer(streamer: WebRtcStreamer): void;
9
10
  createOffer(offerOptions: RTCOfferOptions): Promise<string>;
@@ -4,13 +4,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const schema_1 = require("@sprucelabs/schema");
7
- const __1 = require("../..");
8
7
  const SpruceError_1 = __importDefault(require("../../errors/SpruceError"));
9
- class WebRtcPlayerViewController extends __1.AbstractViewController {
8
+ const removeUniversalViewOptions_1 = __importDefault(require("../../utilities/removeUniversalViewOptions"));
9
+ const WebRtcConnection_1 = __importDefault(require("../../webRtcStreaming/WebRtcConnection"));
10
+ const Abstract_vc_1 = __importDefault(require("../Abstract.vc"));
11
+ class WebRtcPlayerViewController extends Abstract_vc_1.default {
10
12
  constructor(options) {
11
13
  super(options);
14
+ this.connection = WebRtcConnection_1.default.Connection();
12
15
  this.model = {
13
- ...(0, __1.removeUniversalViewOptions)(options),
16
+ connection: this.connection,
17
+ ...(0, removeUniversalViewOptions_1.default)(options),
14
18
  controller: this,
15
19
  };
16
20
  }
@@ -20,7 +24,7 @@ class WebRtcPlayerViewController extends __1.AbstractViewController {
20
24
  this.triggerRender();
21
25
  }
22
26
  async createOffer(offerOptions) {
23
- const { offerSdp, streamer } = await __1.WebRtcConnection.createOffer({
27
+ const { offerSdp, streamer } = await this.connection.createOffer({
24
28
  offerOptions,
25
29
  });
26
30
  this.setStreamer(streamer);
@@ -1,12 +1,14 @@
1
1
  import MockRtcPeerConnection from '../tests/MockRtcPeerConnection';
2
2
  import { WebRtcStreamer } from './WebRtcStreamer';
3
- export default class WebRtcConnection {
3
+ export default class WebRtcConnectionImpl implements WebRtcConnection {
4
+ static Class: new () => WebRtcConnection;
4
5
  static get RTCPeerConnection(): new (config: RTCConfiguration) => RTCPeerConnection | MockRtcPeerConnection;
5
6
  static set RTCPeerConnection(value: new (config: RTCConfiguration) => RTCPeerConnection | MockRtcPeerConnection);
6
- static createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<{
7
- offerSdp: RTCSessionDescriptionInit;
8
- streamer: WebRtcStreamer;
9
- }>;
7
+ private stateChangeHandlers;
8
+ static Connection(): WebRtcConnection;
9
+ createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
10
+ private emitStateChange;
11
+ onStateChange(cb: WebRtcStateChangeHandler): void;
10
12
  }
11
13
  export interface WebRtcVcPluginCreateOfferOptions {
12
14
  offerOptions: {
@@ -14,3 +16,13 @@ export interface WebRtcVcPluginCreateOfferOptions {
14
16
  offerToReceiveVideo?: boolean;
15
17
  };
16
18
  }
19
+ export type WebRtcConnectionState = 'createdOffer' | 'suppliedAnswer' | 'trackAdded';
20
+ export type WebRtcStateChangeHandler = (state: WebRtcConnectionState) => void | Promise<void>;
21
+ export interface WebRtcConnection {
22
+ createOffer(options: WebRtcVcPluginCreateOfferOptions): Promise<WebRtcCreateOfferResponse>;
23
+ onStateChange(cb: WebRtcStateChangeHandler): void;
24
+ }
25
+ export interface WebRtcCreateOfferResponse {
26
+ offerSdp: RTCSessionDescriptionInit;
27
+ streamer: WebRtcStreamer;
28
+ }
@@ -5,26 +5,43 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const schema_1 = require("@sprucelabs/schema");
7
7
  const WebRtcStreamer_1 = __importDefault(require("./WebRtcStreamer"));
8
- class WebRtcConnection {
8
+ class WebRtcConnectionImpl {
9
+ constructor() {
10
+ this.stateChangeHandlers = [];
11
+ }
9
12
  static get RTCPeerConnection() {
10
13
  return window.RTCPeerConnection;
11
14
  }
12
15
  static set RTCPeerConnection(value) {
13
16
  global.window.RTCPeerConnection = value;
14
17
  }
15
- static async createOffer(options) {
18
+ static Connection() {
19
+ return new (this.Class ?? this)();
20
+ }
21
+ async createOffer(options) {
16
22
  const { offerOptions } = (0, schema_1.assertOptions)(options, ['offerOptions']);
17
- const connection = new WebRtcConnection.RTCPeerConnection({
23
+ const connection = new WebRtcConnectionImpl.RTCPeerConnection({
18
24
  //@ts-ignore
19
25
  sdpSemantics: 'unified-plan',
20
26
  iceServers: [],
21
27
  });
22
28
  const offer = await connection.createOffer(offerOptions);
23
29
  await connection.setLocalDescription(offer);
30
+ void this.emitStateChange('createdOffer');
24
31
  return {
25
32
  offerSdp: offer,
26
- streamer: WebRtcStreamer_1.default.Streamer(connection),
33
+ streamer: WebRtcStreamer_1.default.Streamer(connection, async (status) => {
34
+ await this.emitStateChange(status);
35
+ }),
27
36
  };
28
37
  }
38
+ async emitStateChange(state) {
39
+ for (const handler of this.stateChangeHandlers) {
40
+ await handler(state);
41
+ }
42
+ }
43
+ onStateChange(cb) {
44
+ this.stateChangeHandlers.push(cb);
45
+ }
29
46
  }
30
- exports.default = WebRtcConnection;
47
+ exports.default = WebRtcConnectionImpl;
@@ -1,8 +1,10 @@
1
+ import { WebRtcStateChangeHandler } from './WebRtcConnection';
1
2
  export default class WebRtcStreamerImpl implements WebRtcStreamer {
2
3
  private connection;
3
- static Class?: new (connection: RTCPeerConnection) => WebRtcStreamer;
4
- protected constructor(connection: RTCPeerConnection);
5
- static Streamer(connection: RTCPeerConnection): WebRtcStreamer;
4
+ static Class?: new (connection: RTCPeerConnection, stateChangeHandlers?: WebRtcStateChangeHandler) => WebRtcStreamer;
5
+ private stateChangeHandler?;
6
+ protected constructor(connection: RTCPeerConnection, stateChangeHandler?: WebRtcStateChangeHandler);
7
+ static Streamer(connection: RTCPeerConnection, stateChangeHandler?: WebRtcStateChangeHandler): WebRtcStreamer;
6
8
  setAnswer(answerSdp: string): Promise<void>;
7
9
  onTrack(cb: (event: RTCTrackEvent) => void): void;
8
10
  }
@@ -2,11 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const schema_1 = require("@sprucelabs/schema");
4
4
  class WebRtcStreamerImpl {
5
- constructor(connection) {
5
+ constructor(connection, stateChangeHandler) {
6
6
  this.connection = connection;
7
+ this.stateChangeHandler = stateChangeHandler;
7
8
  }
8
- static Streamer(connection) {
9
- return new (this.Class ?? this)(connection);
9
+ static Streamer(connection, stateChangeHandler) {
10
+ return new (this.Class ?? this)(connection, stateChangeHandler);
10
11
  }
11
12
  async setAnswer(answerSdp) {
12
13
  (0, schema_1.assertOptions)({ answerSdp }, ['answerSdp']);
@@ -14,9 +15,11 @@ class WebRtcStreamerImpl {
14
15
  type: 'answer',
15
16
  sdp: answerSdp,
16
17
  });
18
+ await this.stateChangeHandler?.('suppliedAnswer');
17
19
  }
18
20
  onTrack(cb) {
19
21
  this.connection.addEventListener('track', cb);
22
+ void this.stateChangeHandler?.('trackAdded');
20
23
  }
21
24
  }
22
25
  exports.default = WebRtcStreamerImpl;
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "sideEffects": false,
14
14
  "license": "MIT",
15
15
  "description": "All the power of Heartwood in one, convenient package.",
16
- "version": "118.0.27",
16
+ "version": "118.0.28",
17
17
  "skill": {
18
18
  "namespace": "HeartwoodViewControllers",
19
19
  "commandOverrides": {