From c69d1fe00e76c5793b33f18d400bab309f6c3395 Mon Sep 17 00:00:00 2001 From: Delirium Date: Tue, 2 Apr 2024 15:56:29 +0200 Subject: [PATCH] feat tracker update zustand plugin for better ts support (#2020) --- tracker/tracker-zustand/README.md | 20 ++- tracker/tracker-zustand/bun.lockb | Bin 0 -> 40218 bytes tracker/tracker-zustand/package.json | 8 +- tracker/tracker-zustand/src/index.ts | 134 ++++++++------- .../src/{syncod => syncod-v2/src}/chars.ts | 2 +- .../src/syncod-v2/src/decoder.ts | 79 +++++++++ .../src/{syncod => syncod-v2/src}/encoder.ts | 126 ++------------ .../src/syncod-v2/src/index.ts | 6 + .../tracker-zustand/src/syncod-v2/src/mur.ts | 162 ++++++++++++++++++ .../src/{syncod => syncod-v2/src}/sha1.ts | 0 .../tracker-zustand/src/syncod-v2/types.d.ts | 20 +++ tracker/tracker-zustand/src/syncod/index.ts | 5 - tracker/tracker-zustand/tsconfig.json | 7 +- 13 files changed, 376 insertions(+), 193 deletions(-) create mode 100755 tracker/tracker-zustand/bun.lockb rename tracker/tracker-zustand/src/{syncod => syncod-v2/src}/chars.ts (84%) create mode 100644 tracker/tracker-zustand/src/syncod-v2/src/decoder.ts rename tracker/tracker-zustand/src/{syncod => syncod-v2/src}/encoder.ts (59%) create mode 100644 tracker/tracker-zustand/src/syncod-v2/src/index.ts create mode 100644 tracker/tracker-zustand/src/syncod-v2/src/mur.ts rename tracker/tracker-zustand/src/{syncod => syncod-v2/src}/sha1.ts (100%) create mode 100644 tracker/tracker-zustand/src/syncod-v2/types.d.ts delete mode 100644 tracker/tracker-zustand/src/syncod/index.ts diff --git a/tracker/tracker-zustand/README.md b/tracker/tracker-zustand/README.md index ccbde5779..456dfbc83 100644 --- a/tracker/tracker-zustand/README.md +++ b/tracker/tracker-zustand/README.md @@ -10,28 +10,32 @@ npm i @openreplay/tracker-zustand Initialize the `@openreplay/tracker` package as usual and load the plugin into it. Then put the generated plugin into your `plugins` field of your store. -```js +```ts import create from "zustand"; import Tracker from '@openreplay/tracker'; -import trackerZustand from '@openreplay/tracker-zustand'; +import trackerZustand, { StateLogger } from '@openreplay/tracker-zustand'; const tracker = new Tracker({ projectKey: YOUR_PROJECT_KEY, }); -const zustandPlugin = tracker.use(trackerZustand()) -// store name, optional -// randomly generated if undefined -const bearStoreLogger = zustandPlugin('bear_store') +// as per https://docs.pmnd.rs/zustand/guides/typescript#middleware-that-doesn't-change-the-store-type +// cast type to new one +// but this seems to not be required and everything is working as is +const zustandPlugin = tracker.use(trackerZustand()) as unknown as StateLogger const useBearStore = create( - bearStoreLogger((set: any) => ({ + zustandPlugin((set: any) => ({ bears: 0, increasePopulation: () => set((state: any) => ({ bears: state.bears + 1 })), removeAllBears: () => set({ bears: 0 }), - })) + }), + // store name is optional + // and is randomly generated if undefined + 'bear_store' + ) ) ``` diff --git a/tracker/tracker-zustand/bun.lockb b/tracker/tracker-zustand/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..1b6ba4692ec14353c15628d6165f4df61c1be30a GIT binary patch literal 40218 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 literal 0 HcmV?d00001 diff --git a/tracker/tracker-zustand/package.json b/tracker/tracker-zustand/package.json index 67a4a812a..9922e0884 100644 --- a/tracker/tracker-zustand/package.json +++ b/tracker/tracker-zustand/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker-zustand", "description": "Tracker plugin for Zustand state recording", - "version": "1.0.3", + "version": "1.1.0", "keywords": [ "zustand", "state", @@ -22,12 +22,12 @@ "build-cjs": "rm -Rf cjs && tsc --project tsconfig-cjs.json && echo '{ \"type\": \"commonjs\" }' > cjs/package.json && replace-in-files cjs/* --string='@openreplay/tracker' --replacement='@openreplay/tracker/cjs'", "prepublishOnly": "npm run build" }, - "dependencies": {}, + "dependencies": { "zustand": "^4.5.2" }, "peerDependencies": { - "@openreplay/tracker": ">=4.0.1" + "@openreplay/tracker": ">=12.0.0" }, "devDependencies": { - "@openreplay/tracker": "^4.0.1", + "@openreplay/tracker": "^12.0.0", "prettier": "^1.18.2", "replace-in-files-cli": "^1.0.0", "typescript": "^4.6.0-dev.20211126" diff --git a/tracker/tracker-zustand/src/index.ts b/tracker/tracker-zustand/src/index.ts index 79c6a984e..085273fb2 100644 --- a/tracker/tracker-zustand/src/index.ts +++ b/tracker/tracker-zustand/src/index.ts @@ -1,68 +1,84 @@ -import { App, Messages } from '@openreplay/tracker' -import { Encoder, sha1 } from './syncod/index.js' +import { App, Messages } from "@openreplay/tracker"; +import { Encoder, murmur } from "./syncod-v2/src/index.js"; +import { StateCreator, StoreMutatorIdentifier } from "zustand"; + +export type StateLogger = < + T extends unknown, + Mps extends [StoreMutatorIdentifier, unknown][] = [], + Mcs extends [StoreMutatorIdentifier, unknown][] = [] +>( + f: StateCreator, + name?: string +) => StateCreator; + +type LoggerImpl = ( + f: StateCreator, + name?: string +) => StateCreator; export interface Options { - filter: (mutation: any, state: any) => boolean - transformer: (state: any) => any - mutationTransformer: (mutation: any) => any + filter: (mutation: any, state: any) => boolean; + transformer: (state: any) => any; + mutationTransformer: (mutation: any) => any; } function processMutationAndState( - app: App, - options: Options, - encoder: Encoder, - mutation: string[], - state: Record, + app: App, + options: Options, + encoder: Encoder, + mutation: string[], + state: Record ) { - if (options.filter(mutation, state)) { - try { - const _mutation = encoder.encode(options.mutationTransformer(mutation)) - const _state = encoder.encode(options.transformer(state)) - const _table = encoder.commit() - for (let key in _table) app.send(Messages.OTable(key, _table[key])) - app.send(Messages.Zustand(_mutation, _state)) - } catch (e) { - encoder.clear() - app.debug.error(e) - } - } + if (options.filter(mutation, state)) { + try { + const _mutation = encoder.encode(options.mutationTransformer(mutation)); + const _state = encoder.encode(options.transformer(state)); + const _table = encoder.commit(); + for (let key in _table) app.send(Messages.OTable(key, _table[key])); + app.send(Messages.Zustand(_mutation, _state)); + } catch (e) { + encoder.clear(); + app.debug.error(e); + } + } } -export default function(opts: Partial = {}) { - const options: Options = Object.assign( - { - filter: () => true, - transformer: (state) => state, - mutationTransformer: (mutation) => mutation, - }, - opts, - ) - return (app: App | null) => { - if (app === null) { - return Function.prototype - } - const encoder = new Encoder(sha1, 50) - const state = {} - return ( - storeName: string = Math.random() - .toString(36) - .substring(2, 9), - ) => (config: Function) => ( - set: (...args: any) => void, - get: () => Record, - api: any, - ) => - config( - (...args) => { - set(...args) - const newState = get() - state[storeName] = newState - const triggeredActions = args.map((action) => action.toString?.()) +const createZustandTracker = (opts: Partial = {}) => { + const options: Options = Object.assign( + { + filter: () => true, + transformer: state => state, + mutationTransformer: mutation => mutation + }, + opts + ); + return (app: App | null): LoggerImpl => { + if (app === null) { + return f => (set, get, api) => f(set, get, api); + } + const encoder = new Encoder(murmur, 50); + const state = {}; - processMutationAndState(app, options, encoder, triggeredActions, state) - }, - get, - api, - ) - } -} + return ( + f, + name = Math.random() + .toString(36) + .substring(2, 9) + ) => (set, get, api) => { + const loggedSet: typeof set = (...args) => { + set(...args); + state[name] = get(); + processMutationAndState( + app, + options, + encoder, + args.map(a => (a ? a.toString?.() ?? "" : "")), + state + ); + }; + return f(loggedSet, get, api); + }; + }; +}; + +export default createZustandTracker; diff --git a/tracker/tracker-zustand/src/syncod/chars.ts b/tracker/tracker-zustand/src/syncod-v2/src/chars.ts similarity index 84% rename from tracker/tracker-zustand/src/syncod/chars.ts rename to tracker/tracker-zustand/src/syncod-v2/src/chars.ts index ed0d4d0c5..446daec5f 100644 --- a/tracker/tracker-zustand/src/syncod/chars.ts +++ b/tracker/tracker-zustand/src/syncod-v2/src/chars.ts @@ -1,4 +1,4 @@ -const chars = {}; +const chars: Record = {}; [ "DEL", diff --git a/tracker/tracker-zustand/src/syncod-v2/src/decoder.ts b/tracker/tracker-zustand/src/syncod-v2/src/decoder.ts new file mode 100644 index 000000000..e4575c72a --- /dev/null +++ b/tracker/tracker-zustand/src/syncod-v2/src/decoder.ts @@ -0,0 +1,79 @@ +import _ from "./chars.js"; + +export default class Decoder { + _dict: Map; + constructor() { + this._dict = new Map(); + } + + set(ref, enc) { + this._dict.set(ref, enc); + } + + assign(dict) { + for (let ref in dict) { + this._dict.set(ref, dict[ref]); + } + } + + clear() { + this._dict.clear(); + } + + _unref_str(str) { + let s = this._dict.get(str); + if (s !== undefined) { + return s; + } + return str; + } + + decode(enc) { + const p = enc[0], + b = enc.slice(1); + switch (p) { + case _.UNDEF: + return undefined; + case _.TRUE: + return true; + case _.FALSE: + return false; + case _.FUNCTION: + return Function.prototype; + case _.NUMBER: + return parseFloat(b); + case _.BIGINT: + return BigInt(b); + case _.STRING: + return this._unref_str(b); + case _.SYMBOL: + return Symbol(this._unref_str(b)); + case _.NULL: + return null; + } + const unref = this._dict.get(b); + if (unref === undefined) { + throw "index missing code"; + } + if (typeof unref === "object") { + return unref; + } + const args = unref.length === 0 ? [] : unref.split(_.DEL); + switch (p) { + case _.ARRAY: + this._dict.set(b, args); + for (let i = 0; i < args.length; i++) { + args[i] = this.decode(args[i]); + } + return args; + case _.OBJECT: + const obj = {}; + this._dict.set(b, obj); + for (let i = 0; i < args.length; i += 2) { + obj[this._unref_str(args[i])] = this.decode(args[i + 1]); + } + return obj; + } + throw "unrecognized prefix"; + } +} diff --git a/tracker/tracker-zustand/src/syncod/encoder.ts b/tracker/tracker-zustand/src/syncod-v2/src/encoder.ts similarity index 59% rename from tracker/tracker-zustand/src/syncod/encoder.ts rename to tracker/tracker-zustand/src/syncod-v2/src/encoder.ts index db531a0b2..cdfae2158 100644 --- a/tracker/tracker-zustand/src/syncod/encoder.ts +++ b/tracker/tracker-zustand/src/syncod-v2/src/encoder.ts @@ -1,220 +1,120 @@ import _ from "./chars.js"; -// @ts-ignore -// @ts-ignore +type HashFunction = (str: string) => string; + export default class Encoder { -// @ts-ignore - constructor(hash, slen = Infinity) { -// @ts-ignore + _hash: HashFunction; + _slen: number; + _refmap: Map; + _refset: Set; + + constructor(hash: HashFunction, slen = Infinity) { this._hash = hash; -// @ts-ignore this._slen = slen; -// @ts-ignore this._refmap = new Map(); -// @ts-ignore this._refset = new Set(); -// @ts-ignore } -// @ts-ignore -// @ts-ignore _ref_str(str) { -// @ts-ignore - if (str.length < this._slen && str.indexOf(_.DEL) === -1) { -// @ts-ignore + if (str.length < this._slen && !str.includes(_.DEL)) { return str; -// @ts-ignore } -// @ts-ignore let ref = this._refmap.get(str); -// @ts-ignore if (ref === undefined) { -// @ts-ignore ref = this._hash(str); -// @ts-ignore this._refmap.set(str, ref); -// @ts-ignore } -// @ts-ignore return ref; -// @ts-ignore } -// @ts-ignore -// @ts-ignore _encode_prim(obj) { -// @ts-ignore - switch (typeof obj) { -// @ts-ignore + const type = typeof obj; + switch (type) { case "undefined": -// @ts-ignore return _.UNDEF; -// @ts-ignore case "boolean": -// @ts-ignore return obj ? _.TRUE : _.FALSE; -// @ts-ignore case "number": -// @ts-ignore return _.NUMBER + obj.toString(); -// @ts-ignore case "bigint": -// @ts-ignore return _.BIGINT + obj.toString(); -// @ts-ignore case "function": -// @ts-ignore return _.FUNCTION; -// @ts-ignore case "string": -// @ts-ignore return _.STRING + this._ref_str(obj); -// @ts-ignore case "symbol": -// @ts-ignore return _.SYMBOL + this._ref_str(obj.toString().slice(7, -1)); -// @ts-ignore } -// @ts-ignore if (obj === null) { -// @ts-ignore return _.NULL; -// @ts-ignore } -// @ts-ignore } -// @ts-ignore -// @ts-ignore _encode_obj(obj, ref = this._refmap.get(obj)) { -// @ts-ignore return (Array.isArray(obj) ? _.ARRAY : _.OBJECT) + ref; -// @ts-ignore } -// @ts-ignore -// @ts-ignore _encode_term(obj) { -// @ts-ignore return this._encode_prim(obj) || this._encode_obj(obj); -// @ts-ignore } -// @ts-ignore -// @ts-ignore _encode_deep(obj, depth) { -// @ts-ignore const enc = this._encode_prim(obj); -// @ts-ignore if (enc !== undefined) { -// @ts-ignore return enc; -// @ts-ignore } -// @ts-ignore const ref = this._refmap.get(obj); -// @ts-ignore switch (typeof ref) { -// @ts-ignore case "number": -// @ts-ignore return (depth - ref).toString(); -// @ts-ignore case "string": -// @ts-ignore return this._encode_obj(obj, ref); -// @ts-ignore } -// @ts-ignore this._refmap.set(obj, depth); -// @ts-ignore + const hash = this._hash( -// @ts-ignore (Array.isArray(obj) -// @ts-ignore ? obj.map(v => this._encode_deep(v, depth + 1)) -// @ts-ignore : Object.keys(obj) -// @ts-ignore .sort() -// @ts-ignore .map( -// @ts-ignore k => -// @ts-ignore this._ref_str(k) + _.DEL + this._encode_deep(obj[k], depth + 1) -// @ts-ignore ) -// @ts-ignore ).join(_.DEL) -// @ts-ignore ); -// @ts-ignore + this._refmap.set(obj, hash); -// @ts-ignore return this._encode_obj(obj, hash); -// @ts-ignore } -// @ts-ignore -// @ts-ignore encode(obj) { -// @ts-ignore return this._encode_deep(obj, 0); -// @ts-ignore } -// @ts-ignore -// @ts-ignore commit() { -// @ts-ignore const dict = {}; -// @ts-ignore this._refmap.forEach((ref, obj) => { -// @ts-ignore if (this._refset.has(ref)) { -// @ts-ignore return; -// @ts-ignore } -// @ts-ignore this._refset.add(ref); -// @ts-ignore if (typeof obj !== "string") { -// @ts-ignore obj = (Array.isArray(obj) -// @ts-ignore ? obj.map(v => this._encode_term(v)) -// @ts-ignore : Object.keys(obj).map( -// @ts-ignore k => this._ref_str(k) + _.DEL + this._encode_term(obj[k]) -// @ts-ignore ) -// @ts-ignore ).join(_.DEL); -// @ts-ignore } -// @ts-ignore dict[ref] = obj; -// @ts-ignore }); -// @ts-ignore this._refmap.clear(); -// @ts-ignore return dict; -// @ts-ignore } -// @ts-ignore -// @ts-ignore clear() { -// @ts-ignore this._refmap.clear(); -// @ts-ignore this._refset.clear(); -// @ts-ignore } -// @ts-ignore } -// @ts-ignore diff --git a/tracker/tracker-zustand/src/syncod-v2/src/index.ts b/tracker/tracker-zustand/src/syncod-v2/src/index.ts new file mode 100644 index 000000000..05beb0cb7 --- /dev/null +++ b/tracker/tracker-zustand/src/syncod-v2/src/index.ts @@ -0,0 +1,6 @@ +import Encoder from "./encoder.js"; +import Decoder from "./decoder.js"; +import sha1 from "./sha1.js"; +import murmur from "./mur.js"; + +export { Encoder, Decoder, sha1, murmur }; diff --git a/tracker/tracker-zustand/src/syncod-v2/src/mur.ts b/tracker/tracker-zustand/src/syncod-v2/src/mur.ts new file mode 100644 index 000000000..62b956c38 --- /dev/null +++ b/tracker/tracker-zustand/src/syncod-v2/src/mur.ts @@ -0,0 +1,162 @@ +function murmurhash3_32_rp(key, seed) { + var keyLength, tailLength, tailLength4, bodyLength, bodyLength8, h1, k1, i, c1_low, c1_high, c2_low, c2_high, k1B, c3; + keyLength = key.length; + tailLength = keyLength & 3; + bodyLength = keyLength - tailLength; + tailLength4 = bodyLength & 7; + bodyLength8 = bodyLength - tailLength4; + h1 = seed; + + //c1 = 0xcc9e2d51; + c1_low = 0x2d51; + c1_high = 0xcc9e0000; + + //c2 = 0x1b873593; + c2_low = 0x3593; + c2_high = 0x1b870000; + + c3 = 0xe6546b64; + + + //---------- + // body + + i = 0; + + while (i < bodyLength8) { + + k1 = + ((key.charCodeAt(i) & 0xff)) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + + k1B = + ((key.charCodeAt(++i) & 0xff)) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + + ++i; + + + //k1 *= c1; + k1 = (c1_high * k1 | 0) + (c1_low * k1); + //k1 = ROTL32(k1,15); + k1 = (k1 << 15) | (k1 >>> 17); + //k1 *= c2; + k1 = (c2_high * k1 | 0) + (c2_low * k1); + + //h1 ^= k1; + h1 ^= k1; + //h1 = ROTL32(h1,13); + h1 = (h1 << 13) | (h1 >>> 19); + //h1 = h1*5+0xe6546b64; + h1 = h1 * 5 + c3; + + + //k1 *= c1; + k1B = (c1_high * k1B | 0) + (c1_low * k1B); + //k1 = ROTL32(k1,15); + k1B = (k1B << 15) | (k1B >>> 17); + //k1 *= c2; + k1B = (c2_high * k1B | 0) + (c2_low * k1B); + + //h1 ^= k1; + h1 ^= k1B; + //h1 = ROTL32(h1,13); + h1 = (h1 << 13) | (h1 >>> 19); + //h1 = h1*5+0xe6546b64; + h1 = h1 * 5 + c3; + + } //while (i < bodyLength8) { + + + if (tailLength4) { + + k1 = + ((key.charCodeAt(i) & 0xff)) | + ((key.charCodeAt(++i) & 0xff) << 8) | + ((key.charCodeAt(++i) & 0xff) << 16) | + ((key.charCodeAt(++i) & 0xff) << 24); + + ++i; + + //k1 *= c1; + k1 = (c1_high * k1 | 0) + (c1_low * k1); + //k1 = ROTL32(k1,15); + k1 = (k1 << 15) | (k1 >>> 17); + //k1 *= c2; + k1 = (c2_high * k1 | 0) + (c2_low * k1); + + //h1 ^= k1; + h1 ^= k1; + //h1 = ROTL32(h1,13); + h1 = (h1 << 13) | (h1 >>> 19); + //h1 = h1*5+0xe6546b64; + h1 = h1 * 5 + c3; + + } //if (tailLength4) { + + + //---------- + // tail + + k1 = 0; + + switch (tailLength) { + + case 3: k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16; + case 2: k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8; + case 1: k1 ^= (key.charCodeAt(i) & 0xff); + + //k1 *= c1; + k1 = (c1_high * k1 | 0) + (c1_low * k1); + //k1 = ROTL32(k1,15); + k1 = (k1 << 15) | (k1 >>> 17); + //k1 *= c2; + k1 = (c2_high * k1 | 0) + (c2_low * k1); + //h1 ^= k1; + h1 ^= k1; + + } //switch (tailLength) { + + + //---------- + // finalization + + h1 ^= keyLength; + + //h1 = fmix32(h1); + { + //h ^= h >> 16; + h1 ^= h1 >>> 16; + //h1 *= 0x85ebca6b; + h1 = (0x85eb0000 * h1 | 0) + (0xca6b * h1); + //h ^= h >> 13; + h1 ^= h1 >>> 13; + //h1 *= 0xc2b2ae35; + h1 = (0xc2b20000 * h1 | 0) + (0xae35 * h1); + //h ^= h >> 16; + h1 ^= h1 >>> 16; + } + + + return h1 >>> 0; //convert to unsigned int + +} + + +function murmurHash3ToBase64(key, seed = 0) { + let hashValue = murmurhash3_32_rp(key, seed); + return hashToBase64(hashValue); +} + +function hashToBase64(hash) { + let buffer = new ArrayBuffer(4); // 32 bits for hash + let view = new DataView(buffer); + view.setUint32(0, hash, false); // Use big-endian + return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer))); +} + +export default murmurHash3ToBase64; diff --git a/tracker/tracker-zustand/src/syncod/sha1.ts b/tracker/tracker-zustand/src/syncod-v2/src/sha1.ts similarity index 100% rename from tracker/tracker-zustand/src/syncod/sha1.ts rename to tracker/tracker-zustand/src/syncod-v2/src/sha1.ts diff --git a/tracker/tracker-zustand/src/syncod-v2/types.d.ts b/tracker/tracker-zustand/src/syncod-v2/types.d.ts new file mode 100644 index 000000000..5c028d7c9 --- /dev/null +++ b/tracker/tracker-zustand/src/syncod-v2/types.d.ts @@ -0,0 +1,20 @@ +declare type HashFunction = (str: string) => string; +declare type Dict = { [key: string]: string }; + +export class Encoder { + constructor(hash: HashFunction, slen?: number); + commit(): Dict; + encode(obj: any): string; + clear(): void; +} + +export class Decoder { + constructor(); + set(ref: string, enc: string): void; + assign(dict: Dict): void; + decode(enc: string): any; + clear(): void; +} + +export const sha1: HashFunction; +export const murmur: HashFunction; diff --git a/tracker/tracker-zustand/src/syncod/index.ts b/tracker/tracker-zustand/src/syncod/index.ts deleted file mode 100644 index de6f7c64c..000000000 --- a/tracker/tracker-zustand/src/syncod/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -// TODO: SSR solution for all asayer libraries -import Encoder from "./encoder.js"; -import sha1 from "./sha1.js"; - -export { Encoder, sha1 }; diff --git a/tracker/tracker-zustand/tsconfig.json b/tracker/tracker-zustand/tsconfig.json index 0c5b8d1b3..b6c85ab29 100644 --- a/tracker/tracker-zustand/tsconfig.json +++ b/tracker/tracker-zustand/tsconfig.json @@ -2,11 +2,12 @@ "compilerOptions": { "noImplicitThis": true, "strictNullChecks": true, - "alwaysStrict": true, - "target": "es6", + "alwaysStrict": false, + "target": "es2017", "module": "es6", "moduleResolution": "nodenext", "declaration": true, - "outDir": "./lib" + "outDir": "./lib", + "lib": ["es2020", "dom"] } }