@automerge/automerge-repo-network-messagechannel 0.0.1

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/.mocharc.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "extension": ["ts"],
3
+ "spec": "test/*.test.ts",
4
+ "loader": "ts-node/esm"
5
+ }
@@ -0,0 +1,11 @@
1
+ import EventEmitter from "eventemitter3";
2
+ export interface PortRefEvents {
3
+ message: (event: MessageEvent) => void;
4
+ close: () => void;
5
+ }
6
+ export interface MessagePortRef extends EventEmitter<PortRefEvents> {
7
+ start(): void;
8
+ postMessage(message: any, transferable?: Transferable[]): void;
9
+ isAlive(): boolean;
10
+ }
11
+ //# sourceMappingURL=MessagePortRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagePortRef.d.ts","sourceRoot":"","sources":["../src/MessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAExC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACtC,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY,CAAC,aAAa,CAAC;IACjE,KAAK,IAAI,IAAI,CAAA;IACb,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,CAAA;IAC9D,OAAO,IAAI,OAAO,CAAA;CACnB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import EventEmitter from "eventemitter3";
2
+ import { PortRefEvents, MessagePortRef } from "./MessagePortRef.js";
3
+ export declare class StrongMessagePortRef extends EventEmitter<PortRefEvents> implements MessagePortRef {
4
+ private port;
5
+ constructor(port: MessagePort);
6
+ postMessage(message: any, transfer: Transferable[]): void;
7
+ start(): void;
8
+ isAlive(): boolean;
9
+ }
10
+ //# sourceMappingURL=StrongMessagePortRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StrongMessagePortRef.d.ts","sourceRoot":"","sources":["../src/StrongMessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,oBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAEb,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,WAAW;IAQrC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAIzD,KAAK,IAAI,IAAI;IAIb,OAAO,IAAI,OAAO;CAGnB"}
@@ -0,0 +1,20 @@
1
+ import EventEmitter from "eventemitter3";
2
+ export class StrongMessagePortRef extends EventEmitter {
3
+ port;
4
+ constructor(port) {
5
+ port.addEventListener("message", event => {
6
+ this.emit("message", event);
7
+ });
8
+ super();
9
+ this.port = port;
10
+ }
11
+ postMessage(message, transfer) {
12
+ this.port.postMessage(message, transfer);
13
+ }
14
+ start() {
15
+ this.port.start();
16
+ }
17
+ isAlive() {
18
+ return true;
19
+ }
20
+ }
@@ -0,0 +1,12 @@
1
+ import EventEmitter from "eventemitter3";
2
+ import { PortRefEvents, MessagePortRef } from "./MessagePortRef.js";
3
+ export declare class WeakMessagePortRef extends EventEmitter<PortRefEvents> implements MessagePortRef {
4
+ private weakRef;
5
+ private isDisconnected;
6
+ constructor(port: MessagePort);
7
+ postMessage(message: any, transfer: Transferable[]): void;
8
+ start(): void;
9
+ private disconnnect;
10
+ isAlive(): boolean;
11
+ }
12
+ //# sourceMappingURL=WeakMessagePortRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeakMessagePortRef.d.ts","sourceRoot":"","sources":["../src/WeakMessagePortRef.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEnE,qBAAa,kBACX,SAAQ,YAAY,CAAC,aAAa,CAClC,YAAW,cAAc;IAEzB,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,cAAc,CAAQ;gBAElB,IAAI,EAAE,WAAW;IAU7B,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,IAAI;IAezD,KAAK,IAAI,IAAI;IAeb,OAAO,CAAC,WAAW;IAOnB,OAAO,IAAI,OAAO;CAYnB"}
@@ -0,0 +1,54 @@
1
+ import EventEmitter from "eventemitter3";
2
+ export class WeakMessagePortRef extends EventEmitter {
3
+ weakRef;
4
+ isDisconnected = false;
5
+ constructor(port) {
6
+ super();
7
+ this.weakRef = new WeakRef(port);
8
+ port.addEventListener("message", event => {
9
+ this.emit("message", event);
10
+ });
11
+ }
12
+ postMessage(message, transfer) {
13
+ const port = this.weakRef.deref();
14
+ if (!port) {
15
+ this.disconnnect();
16
+ return;
17
+ }
18
+ try {
19
+ port.postMessage(message, transfer);
20
+ }
21
+ catch (err) {
22
+ this.disconnnect();
23
+ }
24
+ }
25
+ start() {
26
+ const port = this.weakRef.deref();
27
+ if (!port) {
28
+ this.disconnnect();
29
+ return;
30
+ }
31
+ try {
32
+ port.start();
33
+ }
34
+ catch (err) {
35
+ this.disconnnect();
36
+ }
37
+ }
38
+ disconnnect() {
39
+ if (!this.isDisconnected) {
40
+ this.emit("close");
41
+ this.isDisconnected = true;
42
+ }
43
+ }
44
+ isAlive() {
45
+ if (this.isDisconnected) {
46
+ return false;
47
+ }
48
+ if (!this.weakRef.deref()) {
49
+ this.disconnnect();
50
+ return false;
51
+ }
52
+ return true;
53
+ }
54
+ }
@@ -0,0 +1,25 @@
1
+ import { ChannelId, NetworkAdapter, PeerId } from "@automerge/automerge-repo";
2
+ import { MessagePortRef } from "./MessagePortRef.js";
3
+ export declare class MessageChannelNetworkAdapter extends NetworkAdapter {
4
+ channels: {};
5
+ messagePortRef: MessagePortRef;
6
+ constructor(messagePort: MessagePort, config?: MessageChannelNetworkAdapterConfig);
7
+ connect(peerId: PeerId): void;
8
+ sendMessage(peerId: PeerId, channelId: ChannelId, uint8message: Uint8Array, broadcast: boolean): void;
9
+ announceConnection(channelId: ChannelId, peerId: PeerId): void;
10
+ join(channelId: string): void;
11
+ leave(docId: string): void;
12
+ }
13
+ interface MessageChannelNetworkAdapterConfig {
14
+ /**
15
+ * This is an optional parameter to use a weak ref to reference the message port that is passed to
16
+ * the adapter. This option is useful when using a message channel with a shared worker. If you
17
+ * use a network adapter with `useWeakRef = true` in the shared worker and in the main thread
18
+ * network adapters with strong refs the network adapter will be automatically garbage collected
19
+ * if you close a page. The garbage collection doesn't happen immediately; there might be some
20
+ * time in between when the page is closed and when the port is garbage collected
21
+ */
22
+ useWeakRef?: boolean;
23
+ }
24
+ export {};
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAOpD,qBAAa,4BAA6B,SAAQ,cAAc;IAC9D,QAAQ,KAAK;IACb,cAAc,EAAE,cAAc,CAAA;gBAG5B,WAAW,EAAE,WAAW,EACxB,MAAM,GAAE,kCAAuC;IAWjD,OAAO,CAAC,MAAM,EAAE,MAAM;IA4CtB,WAAW,CACT,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,UAAU,EACxB,SAAS,EAAE,OAAO;IAmBpB,kBAAkB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM;IAIvD,IAAI,CAAC,SAAS,EAAE,MAAM;IAQtB,KAAK,CAAC,KAAK,EAAE,MAAM;CAMpB;AAED,UAAU,kCAAkC;IAC1C;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB"}
package/dist/index.js ADDED
@@ -0,0 +1,80 @@
1
+ import { NetworkAdapter } from "@automerge/automerge-repo";
2
+ import { StrongMessagePortRef } from "./StrongMessagePortRef.js";
3
+ import { WeakMessagePortRef } from "./WeakMessagePortRef.js";
4
+ import debug from "debug";
5
+ const log = debug("automerge-repo:messagechannel");
6
+ export class MessageChannelNetworkAdapter extends NetworkAdapter {
7
+ channels = {};
8
+ messagePortRef;
9
+ constructor(messagePort, config = {}) {
10
+ super();
11
+ const useWeakRef = config.useWeakRef ?? false;
12
+ this.messagePortRef = useWeakRef
13
+ ? new WeakMessagePortRef(messagePort)
14
+ : new StrongMessagePortRef(messagePort);
15
+ }
16
+ connect(peerId) {
17
+ log("messageport connecting");
18
+ this.peerId = peerId;
19
+ this.messagePortRef.start();
20
+ this.messagePortRef.addListener("message", e => {
21
+ log("message port received", e.data);
22
+ const { origin, destination, type, channelId, message, broadcast } = e.data;
23
+ if (destination && !(destination === this.peerId || broadcast)) {
24
+ throw new Error("MessagePortNetwork should never receive messages for a different peer.");
25
+ }
26
+ switch (type) {
27
+ case "arrive":
28
+ this.messagePortRef.postMessage({
29
+ origin: this.peerId,
30
+ destination: origin,
31
+ type: "welcome",
32
+ });
33
+ this.announceConnection(channelId, origin);
34
+ break;
35
+ case "welcome":
36
+ this.announceConnection(channelId, origin);
37
+ break;
38
+ case "message":
39
+ this.emit("message", {
40
+ senderId: origin,
41
+ targetId: destination,
42
+ channelId,
43
+ message: new Uint8Array(message),
44
+ broadcast,
45
+ });
46
+ break;
47
+ default:
48
+ throw new Error("unhandled message from network");
49
+ }
50
+ });
51
+ this.messagePortRef.addListener("close", () => {
52
+ this.emit("close");
53
+ });
54
+ }
55
+ sendMessage(peerId, channelId, uint8message, broadcast) {
56
+ const message = uint8message.buffer.slice(uint8message.byteOffset, uint8message.byteOffset + uint8message.byteLength);
57
+ this.messagePortRef.postMessage({
58
+ origin: this.peerId,
59
+ destination: peerId,
60
+ channelId: channelId,
61
+ type: "message",
62
+ message,
63
+ broadcast,
64
+ }, [message]);
65
+ }
66
+ announceConnection(channelId, peerId) {
67
+ this.emit("peer-candidate", { peerId, channelId });
68
+ }
69
+ join(channelId) {
70
+ this.messagePortRef.postMessage({
71
+ origin: this.peerId,
72
+ channelId,
73
+ type: "arrive",
74
+ });
75
+ }
76
+ leave(docId) {
77
+ // TODO
78
+ throw new Error("Unimplemented: leave on MessagePortNetworkAdapter: " + docId);
79
+ }
80
+ }
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@automerge/automerge-repo-network-messagechannel",
3
+ "version": "0.0.1",
4
+ "description": "MessageChannel network adapter for Automerge Repo",
5
+ "repository": "https://github.com/pvh/automerge-repo",
6
+ "author": "Peter van Hardenberg <pvh@pvh.ca>",
7
+ "license": "MIT",
8
+ "private": false,
9
+ "type": "module",
10
+ "main": "dist/index.js",
11
+ "scripts": {
12
+ "build": "tsc",
13
+ "watch": "npm-watch",
14
+ "test": "mocha --no-warnings --experimental-specifier-resolution=node --exit"
15
+ },
16
+ "dependencies": {
17
+ "@automerge/automerge-repo": "^0.0.1"
18
+ },
19
+ "watch": {
20
+ "build": {
21
+ "patterns": "./src/**/*",
22
+ "extensions": [
23
+ ".ts"
24
+ ]
25
+ }
26
+ },
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "gitHead": "e572f26ae416140b025c3ba557d9f781abbdada1"
31
+ }
package/readme.md ADDED
@@ -0,0 +1,4 @@
1
+ ## @automerge/automerge-repo-network-message
2
+
3
+ This is a network adapter for automerge-repo that uses the [MessageChannel
4
+ API](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel) to communicate between tabs.
@@ -0,0 +1,12 @@
1
+ import EventEmitter from "eventemitter3"
2
+
3
+ export interface PortRefEvents {
4
+ message: (event: MessageEvent) => void
5
+ close: () => void
6
+ }
7
+
8
+ export interface MessagePortRef extends EventEmitter<PortRefEvents> {
9
+ start(): void
10
+ postMessage(message: any, transferable?: Transferable[]): void
11
+ isAlive(): boolean
12
+ }
@@ -0,0 +1,27 @@
1
+ import EventEmitter from "eventemitter3"
2
+ import { PortRefEvents, MessagePortRef } from "./MessagePortRef.js"
3
+
4
+ export class StrongMessagePortRef
5
+ extends EventEmitter<PortRefEvents>
6
+ implements MessagePortRef
7
+ {
8
+ constructor(private port: MessagePort) {
9
+ port.addEventListener("message", event => {
10
+ this.emit("message", event)
11
+ })
12
+
13
+ super()
14
+ }
15
+
16
+ postMessage(message: any, transfer: Transferable[]): void {
17
+ this.port.postMessage(message, transfer)
18
+ }
19
+
20
+ start(): void {
21
+ this.port.start()
22
+ }
23
+
24
+ isAlive(): boolean {
25
+ return true
26
+ }
27
+ }
@@ -0,0 +1,70 @@
1
+ import EventEmitter from "eventemitter3"
2
+ import { PortRefEvents, MessagePortRef } from "./MessagePortRef.js"
3
+
4
+ export class WeakMessagePortRef
5
+ extends EventEmitter<PortRefEvents>
6
+ implements MessagePortRef
7
+ {
8
+ private weakRef: WeakRef<MessagePort>
9
+ private isDisconnected = false
10
+
11
+ constructor(port: MessagePort) {
12
+ super()
13
+
14
+ this.weakRef = new WeakRef<MessagePort>(port)
15
+
16
+ port.addEventListener("message", event => {
17
+ this.emit("message", event)
18
+ })
19
+ }
20
+
21
+ postMessage(message: any, transfer: Transferable[]): void {
22
+ const port = this.weakRef.deref()
23
+
24
+ if (!port) {
25
+ this.disconnnect()
26
+ return
27
+ }
28
+
29
+ try {
30
+ port.postMessage(message, transfer)
31
+ } catch (err) {
32
+ this.disconnnect()
33
+ }
34
+ }
35
+
36
+ start(): void {
37
+ const port = this.weakRef.deref()
38
+
39
+ if (!port) {
40
+ this.disconnnect()
41
+ return
42
+ }
43
+
44
+ try {
45
+ port.start()
46
+ } catch (err) {
47
+ this.disconnnect()
48
+ }
49
+ }
50
+
51
+ private disconnnect() {
52
+ if (!this.isDisconnected) {
53
+ this.emit("close")
54
+ this.isDisconnected = true
55
+ }
56
+ }
57
+
58
+ isAlive(): boolean {
59
+ if (this.isDisconnected) {
60
+ return false
61
+ }
62
+
63
+ if (!this.weakRef.deref()) {
64
+ this.disconnnect()
65
+ return false
66
+ }
67
+
68
+ return true
69
+ }
70
+ }
package/src/index.ts ADDED
@@ -0,0 +1,123 @@
1
+ import { ChannelId, NetworkAdapter, PeerId } from "@automerge/automerge-repo"
2
+ import { MessagePortRef } from "./MessagePortRef.js"
3
+ import { StrongMessagePortRef } from "./StrongMessagePortRef.js"
4
+ import { WeakMessagePortRef } from "./WeakMessagePortRef.js"
5
+
6
+ import debug from "debug"
7
+ const log = debug("automerge-repo:messagechannel")
8
+
9
+ export class MessageChannelNetworkAdapter extends NetworkAdapter {
10
+ channels = {}
11
+ messagePortRef: MessagePortRef
12
+
13
+ constructor(
14
+ messagePort: MessagePort,
15
+ config: MessageChannelNetworkAdapterConfig = {}
16
+ ) {
17
+ super()
18
+
19
+ const useWeakRef = config.useWeakRef ?? false
20
+
21
+ this.messagePortRef = useWeakRef
22
+ ? new WeakMessagePortRef(messagePort)
23
+ : new StrongMessagePortRef(messagePort)
24
+ }
25
+
26
+ connect(peerId: PeerId) {
27
+ log("messageport connecting")
28
+ this.peerId = peerId
29
+ this.messagePortRef.start()
30
+ this.messagePortRef.addListener("message", e => {
31
+ log("message port received", e.data)
32
+ const { origin, destination, type, channelId, message, broadcast } =
33
+ e.data
34
+ if (destination && !(destination === this.peerId || broadcast)) {
35
+ throw new Error(
36
+ "MessagePortNetwork should never receive messages for a different peer."
37
+ )
38
+ }
39
+ switch (type) {
40
+ case "arrive":
41
+ this.messagePortRef.postMessage({
42
+ origin: this.peerId,
43
+ destination: origin,
44
+ type: "welcome",
45
+ })
46
+ this.announceConnection(channelId, origin)
47
+ break
48
+ case "welcome":
49
+ this.announceConnection(channelId, origin)
50
+ break
51
+ case "message":
52
+ this.emit("message", {
53
+ senderId: origin,
54
+ targetId: destination,
55
+ channelId,
56
+ message: new Uint8Array(message),
57
+ broadcast,
58
+ })
59
+ break
60
+ default:
61
+ throw new Error("unhandled message from network")
62
+ }
63
+ })
64
+
65
+ this.messagePortRef.addListener("close", () => {
66
+ this.emit("close")
67
+ })
68
+ }
69
+
70
+ sendMessage(
71
+ peerId: PeerId,
72
+ channelId: ChannelId,
73
+ uint8message: Uint8Array,
74
+ broadcast: boolean
75
+ ) {
76
+ const message = uint8message.buffer.slice(
77
+ uint8message.byteOffset,
78
+ uint8message.byteOffset + uint8message.byteLength
79
+ )
80
+ this.messagePortRef.postMessage(
81
+ {
82
+ origin: this.peerId,
83
+ destination: peerId,
84
+ channelId: channelId,
85
+ type: "message",
86
+ message,
87
+ broadcast,
88
+ },
89
+ [message]
90
+ )
91
+ }
92
+
93
+ announceConnection(channelId: ChannelId, peerId: PeerId) {
94
+ this.emit("peer-candidate", { peerId, channelId })
95
+ }
96
+
97
+ join(channelId: string) {
98
+ this.messagePortRef.postMessage({
99
+ origin: this.peerId,
100
+ channelId,
101
+ type: "arrive",
102
+ })
103
+ }
104
+
105
+ leave(docId: string) {
106
+ // TODO
107
+ throw new Error(
108
+ "Unimplemented: leave on MessagePortNetworkAdapter: " + docId
109
+ )
110
+ }
111
+ }
112
+
113
+ interface MessageChannelNetworkAdapterConfig {
114
+ /**
115
+ * This is an optional parameter to use a weak ref to reference the message port that is passed to
116
+ * the adapter. This option is useful when using a message channel with a shared worker. If you
117
+ * use a network adapter with `useWeakRef = true` in the shared worker and in the main thread
118
+ * network adapters with strong refs the network adapter will be automatically garbage collected
119
+ * if you close a page. The garbage collection doesn't happen immediately; there might be some
120
+ * time in between when the page is closed and when the port is garbage collected
121
+ */
122
+ useWeakRef?: boolean
123
+ }
@@ -0,0 +1,53 @@
1
+ import { runAdapterTests } from "@automerge/automerge-repo"
2
+ import { MessageChannelNetworkAdapter as Adapter } from "../src"
3
+
4
+ // bob is the hub, alice and charlie are spokes
5
+ describe("MessageChannelNetworkAdapter", () => {
6
+ runAdapterTests(async () => {
7
+ const aliceBobChannel = new MessageChannel()
8
+ const bobCharlieChannel = new MessageChannel()
9
+
10
+ const { port1: aliceToBob, port2: bobToAlice } = aliceBobChannel
11
+ const { port1: bobToCharlie, port2: charlieToBob } = bobCharlieChannel
12
+
13
+ const a = new Adapter(aliceToBob)
14
+ const b = [new Adapter(bobToAlice), new Adapter(bobToCharlie)]
15
+ const c = new Adapter(charlieToBob)
16
+
17
+ const teardown = () => {
18
+ const ports = [aliceToBob, bobToAlice, bobToCharlie, charlieToBob]
19
+ ports.forEach(port => port.close())
20
+ }
21
+
22
+ return { adapters: [a, b, c], teardown }
23
+ }, "hub and spoke")
24
+
25
+ // all 3 peers connected directly to each other
26
+ runAdapterTests(async () => {
27
+ const aliceBobChannel = new MessageChannel()
28
+ const bobCharlieChannel = new MessageChannel()
29
+ const aliceCharlieChannel = new MessageChannel()
30
+
31
+ const { port1: aliceToBob, port2: bobToAlice } = aliceBobChannel
32
+ const { port1: bobToCharlie, port2: charlieToBob } = bobCharlieChannel
33
+ const { port1: aliceToCharlie, port2: charlieToAlice } = aliceCharlieChannel
34
+
35
+ const a = [new Adapter(aliceToBob), new Adapter(aliceToCharlie)]
36
+ const b = [new Adapter(bobToAlice), new Adapter(bobToCharlie)]
37
+ const c = [new Adapter(charlieToBob), new Adapter(charlieToAlice)]
38
+
39
+ const teardown = () => {
40
+ const ports = [
41
+ aliceToBob,
42
+ bobToAlice,
43
+ bobToCharlie,
44
+ charlieToBob,
45
+ aliceToCharlie,
46
+ charlieToAlice,
47
+ ]
48
+ ports.forEach(port => port.close())
49
+ }
50
+
51
+ return { adapters: [a, b, c], teardown }
52
+ }, "all-to-all")
53
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "jsx": "react",
5
+ "module": "ESNext",
6
+ "moduleResolution": "node",
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "outDir": "./dist",
10
+ "esModuleInterop": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "strict": false,
13
+ "skipLibCheck": true
14
+ },
15
+ "include": ["src/**/*.ts"]
16
+ }