{"_id":"@pvermeer/dexie-addon-suite","_rev":"63-e36588b033c0184cea148b2d08241599","name":"@pvermeer/dexie-addon-suite","dist-tags":{"latest":"2.0.0","beta":"3.0.0-beta.0"},"versions":{"1.0.0-beta.1":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"0e01e26c3d9530b640664d6765ac4e9f0b25ad60","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.1.tgz","fileCount":48,"integrity":"sha512-DAuX4dGPgDHRBAUiyzw7DSq8t+//cky5fyTaMEjaKVXW5Q9jFyiSb0RcL33b9Z5DqqlcMsYUr3ilShttQxB84A==","signatures":[{"sig":"MEUCIE80meWcfzNl3AQB0IqTlq4x73AJGmsesskjfD9imxJ/AiEAp+EsWd6M2Niq8Lx8F7pwCfB2tiYG6kqGZZLVOhNffLQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":200375,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJedmPaCRA9TVsSAnZWagAATGwP+wSKPgiQ4G/DxDuVmQsK\n3XaYqipdpBLwACVMJcq+hDRe7IoV87ESCrZzBydKgRnAicpvRCPa/XrT9B6B\nzh2efNwBwcl8JKlkwcrQgbid2G4ck9nUi+EsSlbNNguIFMjy+VD6RXmfuJpa\nO1mt226W/uv9vusf+1syHSCqeAGVcglW9q66g7C53rdUNlDjRIP8avZa4FWf\n8Rada600DKPQWqESyghIfEfgiGCq3kXbOloy83l7FjRycRoB6tfczTY4ZuV/\nePBbVtk8VzCyaz0FTSht40hodpN76mZ3wp8BkNbaOYEufnpndTfkg1/16cwU\nvxzuKbYLfVP6078v4JqWESbJyeNI57pK9q5Djxf79KgEV0kf8XhJs28WRDL/\n+vVhEWSsdJjjG9WgpTHPlPXlxQw7fkX1ubDvUsWdfIt1oRDuzyyOtmJsuveG\nrZFU668cQHcVsKKxSplUWWhaKkeS0XP5IwAOmjOXc+gOFC0X+SHtIVpWnW5w\naWi/GiGBtIyBlVLQRvPImUOWCdNqCYd7x81L47YeMo0fJUWydTqEgZ5waFlc\nu/4Z+Ec43+mRaZCgYvTY4fNA+o/2LcsiidBReSShEbw44A/Ah0OZidqpNqc9\nRjvIdBEPlEQwkA4LgQqJg2jkWmjchhywE7Zh9EBeE0VKgHS2ASVFGaol9ij0\nIVJg\r\n=y5Gh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"pre-push":"if git-branch-is -i -q -r \"master|next|next-major|beta|alpha|^v\\d+\\.\\d+(\\.\\d+)?(-\\S*)?$\"; then npm run test; fi","commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"module":"dist/esm-es5/index.js","gitHead":"50aea4416fe00e91ffe6bdef4edfa4de5763b196","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run build && npm run lint && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration","clean":"rimraf -rf dist/ && rimraf -rf reports/","build:es6":"tsc -p tsconfig.es6.json","test:karma":"karma start test/karma.conf.js","test:jasmine":"cd test && jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","semantic-release":"semantic-release","test:karma:debug":"npm run build && karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","test:jasmine:debug":"cd test && nodemon --ext ts --exec jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.13.7","description":"Collection of dexie addons","directories":{},"_nodeVersion":"12.16.1","dependencies":{"tslib":"^1.11.1","lodash":"^4.17.15","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.13","@pvermeer/dexie-populate-addon":"^1.0.0-beta.4","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.3","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.5","faker":"^4.1.0","husky":"^4.2.3","is-ci":"^2.0.0","karma":"~4.4.1","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.5.0","nodemon":"^2.0.2","ts-node":"^8.7.0","webpack":"^4.42.0","lodash-es":"^4.17.15","ts-loader":"^6.2.1","typescript":"^3.8.3","@babel/core":"^7.9.0","simplytyped":"^3.2.3","webpack-cli":"^3.3.11","@types/faker":"^4.1.10","@types/is-ci":"^2.0.0","@types/karma":"^3.0.8","babel-loader":"^8.1.0","jasmine-core":"^3.5.0","@types/lodash":"^4.14.149","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","@babel/runtime":"^7.9.0","@types/jasmine":"^3.5.9","@commitlint/cli":"^8.3.5","@types/lodash-es":"^4.17.3","semantic-release":"^17.0.4","@babel/preset-env":"^7.9.0","dts-bundle-generator":"^4.0.0","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.2.3","@semantic-release/git":"^8.0.0","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"github:PVermeer/karma-edgium-launcher#master","@commitlint/travis-cli":"^8.3.5","karma-firefox-launcher":"^1.3.0","license-webpack-plugin":"^2.1.4","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.6.1","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.2","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.0","@babel/plugin-transform-runtime":"^7.9.0","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.4"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.1_1584817113640_0.5037945312158596","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.2":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"9659590aaff8e056176f8d232331dbab988d2738","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.2.tgz","fileCount":48,"integrity":"sha512-cWPB5bTl3xhf7C0cQ+95Va9pxM0mGhYIFLntEEPmajYXZL5JboEJjDi4+PFQOmxBV7P9VeXMuY/x4cGI36h2fw==","signatures":[{"sig":"MEUCIQD/XwAkdDu8n2Ea5qrtOWJb1RlcyvpDlc3vydfDCqJ/dQIgDwfD6GDZ1WqRCwS2+0n6WKUhyvlNb35PE5zkStPQA8g=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":200677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJed5GGCRA9TVsSAnZWagAAvokQAIdNznPvbqisxcjJ5iEW\n70cXZrL3TZLa+gdLpjOaTA+79ZbO+Jesa7ASRqfnes5qtXwgqK95G0jqa9V1\nrlTxQP8CNh0cQo4RbTgGurwviebNJnbtp9ry779YNsTonJRxthxw7W1e2AwF\n1a1XqJ6qUltFnI02vMkzoWNesWIV92ywx7kP6JbMr2TieJpkhgrmINM476Mh\nFE+FKhESahH76i4vhH5KXKfkxaUs8oADb+/Ntq17ldFfZISL9xKgQAygriUV\n9MZqQWjmdAr/u2O8TtfvSGYfeqd91JrKLUWShOV8geGXWy6NRhMBFRPchsED\n51RhR8jSL9SkFjzo31feMmUj1TXE/WAdKMbo5Wjn/1EtKtww+WHUI9lIpqqU\nPDv4frcBL7SFTqkPVkX2WbzmceLVUqNW0iMrTf5BGbQolgq3gyjhaza8lWcp\ntGF3moq1Eor4+lqVRxkjdCK2MBRJ1r8NIhg/wszm+2/PQ9eSpiqMorcgt7FN\nLImkXlDtH967aTqHwLVNe5sfjBkBmMZAFjWyDlP9LQpZym74eMKKxmXXKz+C\nQDwtC3LfiJT+/1omHjIYsSzXnqfnhuVJufCRA6mLU8AAlGpyn/ABVrt6RVdH\nZYbwqGtCtkyDAO0tvA7uFk8ShS2CEBLWo6t27+bBxPW7sYO8Vo0uYgUdLcXH\n24uU\r\n=K/c+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"pre-push":"if git-branch-is -i -q -r \"master|next|next-major|beta|alpha|^v\\d+\\.\\d+(\\.\\d+)?(-\\S*)?$\"; then npm run test; fi","commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"module":"dist/esm-es5/index.js","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![Build Status](https://travis-ci.org/PVermeer/dexie-addon-suite.svg?branch=master)](https://travis-ci.org/PVermeer/dexie-addon-suite)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. \n```\nnpm install dexie\n```\nAt the time of writing Dexie v3 is in the RC stage. To install this version you have to use the @next npm version. Current version of Dexie.js: [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie@next\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default this addon will load:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    constructor() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]` and a property `group` that can be assigned with the index key of `number`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf` and `Group` in `group`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]` and for `group` it will be `Group | null`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"08de7bcd511d00bb0245986f84662155e0884307","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run build && npm run lint && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration","clean":"rimraf -rf dist/ && rimraf -rf reports/","build:es6":"tsc -p tsconfig.es6.json","test:karma":"karma start test/karma.conf.js","test:jasmine":"cd test && jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","semantic-release":"semantic-release","test:karma:debug":"npm run build && karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","test:jasmine:debug":"cd test && nodemon --ext ts --exec jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.13.7","description":"Collection of dexie addons","directories":{},"_nodeVersion":"12.16.1","dependencies":{"tslib":"^1.11.1","lodash":"^4.17.15","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.14","@pvermeer/dexie-populate-addon":"^1.0.0-beta.4","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.3","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.5","faker":"^4.1.0","husky":"^4.2.3","is-ci":"^2.0.0","karma":"~4.4.1","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.5.0","nodemon":"^2.0.2","ts-node":"^8.8.1","webpack":"^4.42.0","lodash-es":"^4.17.15","ts-loader":"^6.2.2","typescript":"^3.8.3","@babel/core":"^7.9.0","simplytyped":"^3.2.3","webpack-cli":"^3.3.11","@types/faker":"^4.1.10","@types/is-ci":"^2.0.0","@types/karma":"^3.0.8","babel-loader":"^8.1.0","jasmine-core":"^3.5.0","@types/lodash":"^4.14.149","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","@babel/runtime":"^7.9.2","@types/jasmine":"^3.5.9","@commitlint/cli":"^8.3.5","@types/lodash-es":"^4.17.3","semantic-release":"^17.0.4","@babel/preset-env":"^7.9.0","dts-bundle-generator":"^4.0.0","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.2.3","@semantic-release/git":"^8.0.0","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"github:PVermeer/karma-edgium-launcher#master","@commitlint/travis-cli":"^8.3.5","karma-firefox-launcher":"^1.3.0","license-webpack-plugin":"^2.1.4","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.6.1","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.2","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.0","@babel/plugin-transform-runtime":"^7.9.0","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.4"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.2_1584894342158_0.30615391698159833","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.3":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.3","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.3","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"46de5e1d12d02f94f911a143f9485b43691b574e","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.3.tgz","fileCount":69,"integrity":"sha512-4i0AfXl5DImm/8ZbSmZj55Qr2IpJJUcW9Q+bMR2Bg+v6qKyIp48zhM6lhBjWqVW+YgcTBKAeboes4i9XfzIwKQ==","signatures":[{"sig":"MEYCIQDdRCXhYEpcFM8NYymhNUGYYLSbTdqUx6cXDVxWwo7rJQIhAJr4sX5QqUKHOtlS3UZCDMK/vFFbiIUlywME2GfLtMIj","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":227200,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeKkWCRA9TVsSAnZWagAA9XUP/25qXADGxtbgutv6HZLG\n+FtzYBPsNynObD2rnaosoScHB8Rxc384fd3t3UIQDtEcnTwoR5pgHToUmZps\nBsn+EFynyL0/2FHZt5JNCsKYtUmI4ucm6MXf8FO9xnPVrVipb70zlbdqJZcY\nCd7SApY7iXKRPMR3EmCdefctnfEXxnpucw8NWmAIZ2jRGDQDb+hfEKsQCZnX\n/tCpU1fMZMCEPBoiIZ3wnAByweERoulfFdAFe3FCBRjPmGDs0w8u0xLgp4I6\n8Od55OEY41xSa1l3CuxLVIqrQL2e+YyxD+lBNUX+6GaQcF46Zd9c07MTprhd\n54sTdY7JnQMgkGqqqYrfJYs7TUo9G9EPvju2HjPDoJMlvR7RGkx89gX75ZhO\n0kDmOCPwCkIYwCEz/oeIbzkMnnNc4ZQpjDS5BCSDflWoYUO5f7rXZcowAu/q\n20cGdKBDX4rKsaRBEM5f9kvn1TKRe3mJFwtOD7PY2lgS665ZzojLBc0RBC2R\nbOTahgN/g3OvnkbORrRCk1KnexI/XM8nwRrPwquyqmU578I1n2fOI7S2dmh/\nLzKrGOhNwcZ9vLOUP4xlBYjuqLguHBLOZW8AV8HinL2sTPQ+woc/1EaSBwoI\nQ1W7r2zko8aro3R0w3DYTSeYuoKkL4ez6hwR0BJPafUbX/6/1ZiAqVPCVPmN\nqix4\r\n=9D4v\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"pre-push":"if git-branch-is -i -q -r \"master|next|next-major|beta|alpha|^v\\d+\\.\\d+(\\.\\d+)?(-\\S*)?$\"; then npm run test; fi","commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"types":"./dist/index.d.ts","module":"dist/esm-es5/index.js","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![Build Status](https://travis-ci.com/PVermeer/dexie-addon-suite.svg?branch=master)](https://travis-ci.com/PVermeer/dexie-addon-suite)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. \n```\nnpm install dexie\n```\nAt the time of writing Dexie v3 is in the RC stage. To install this version you have to use the @next npm version. Current version of Dexie.js: [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie@next\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default this addon will load:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    constructor() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]` and a property `group` that can be assigned with the index key of `number`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf` and `Group` in `group`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]` and for `group` it will be `Group | null`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"8e81978d3a65a748f33156aad96972b6b21fc89b","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run build && npm run lint && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration && npm run build:dl-dts","clean":"rimraf -rf dist/ && rimraf -rf reports/","build:es6":"tsc -p tsconfig.es6.json","test:karma":"karma start test/karma.conf.js","build:dl-dts":"rimraf -rf dist/ts3.4 && downlevel-dts ./dist ./dist/ts3.4","test:jasmine":"cd test && jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","semantic-release":"semantic-release","test:karma:debug":"npm run build && karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","test:jasmine:debug":"cd test && nodemon --ext ts --exec jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.13.7","description":"Collection of dexie addons","directories":{},"_nodeVersion":"12.16.1","dependencies":{"tslib":"^1.11.1","lodash":"^4.17.15","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.15","@pvermeer/dexie-populate-addon":"^1.0.0-beta.4","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.3","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.4"},"publishConfig":{"access":"public"},"typesVersions":{"<3.8":{"*":["./dist/ts3.4/index.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.5","faker":"^4.1.0","husky":"^4.2.3","is-ci":"^2.0.0","karma":"~4.4.1","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.5.0","nodemon":"^2.0.2","ts-node":"^8.8.1","webpack":"^4.42.0","lodash-es":"^4.17.15","ts-loader":"^6.2.2","typescript":"^3.8.3","@babel/core":"^7.9.0","simplytyped":"^3.2.3","webpack-cli":"^3.3.11","@types/faker":"^4.1.10","@types/is-ci":"^2.0.0","@types/karma":"^3.0.8","babel-loader":"^8.1.0","jasmine-core":"^3.5.0","@types/lodash":"^4.14.149","downlevel-dts":"^0.4.0","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","@babel/runtime":"^7.9.2","@types/jasmine":"^3.5.9","@commitlint/cli":"^8.3.5","@types/lodash-es":"^4.17.3","semantic-release":"^17.0.4","@babel/preset-env":"^7.9.0","dts-bundle-generator":"^4.0.0","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.2.3","@semantic-release/git":"^8.0.0","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"github:PVermeer/karma-edgium-launcher#master","@commitlint/travis-cli":"^8.3.5","karma-firefox-launcher":"^1.3.0","license-webpack-plugin":"^2.1.4","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.6.1","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.2","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.1","@babel/plugin-transform-runtime":"^7.9.0","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.4"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.3_1584965909985_0.30234549777788544","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.4":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.4","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.4","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"7899bdde67c6a65a61d75b7718bed39696800d20","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.4.tgz","fileCount":69,"integrity":"sha512-ymFMbJxfoGYC7LHvoYYXuQx91V3cwHxMAzXgSm+O2FUwS52ajLCgTOV9Mzs05+e8WA+sZ5XVOSppMB3rQZXLxw==","signatures":[{"sig":"MEYCIQDEMHG9yD5cZc5epK/dH+zcZuyw7MRA7EbVLRcncouC9AIhAPcpVHtJkX7Yidy4HlqqLL0B2PdXbV/jTAwTuGQWVRvL","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":227493,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeeLigCRA9TVsSAnZWagAA680QAKAJvtTCVoeyHPFk5MxL\n5HqWgeI90X2jFgeRFZUQ0dx/Yy2y3I6Io9NeWVboS1H8fZtdqaQgVUh9Cf/x\nRW6zMiBxdMeDRtJeFQRRQFELHucL8C1M2VAcwaptKSF2scBSZI9U3/p8Crza\nhZ5E+5fhYa0j9HlxqCAOFyWoINFcbCDT45cZH/m6M+g3rm6VkAwPXcX7UBTE\nThf2B+M8tdQ6/nwNCjWQQj1mX0q0OkpzmVC79JehuZQUoo9/7LJgsSvNVFy4\nuHV6IfjJpaVgWrAFCSwxr7ogpveHhYMGXyBAq0Dw8rVugH7g7kU5VImGf+B3\nrIw4kSRSLOWZcBbZ56mYZHPbEpkcCjFx9J5C3jJlP04EBfYW2NXVpRAxpQML\nhWZyxYUZELfxDSArcYOSYKFAg7Hasej1NFsQz0StzYMx61rQoy2wEf/zSZhk\nsVv78JEKTmy9fHjsjt1GIE3imGwFHgv3s1Qsi4pRNf9R04CqQn1jOtwotqqJ\nTffW6ErJpCykfcl4iuC3KZ2po+SlYsVfZ3jzdUm2pzLMkgOkfeqCWKX8pbi4\nvQ5xTERYcCOuSUN+bCX4xm9wNnvAb72baSPgSk1K/3GVILurMzcoVkgJbB8/\nvyMUmFpJ8Y5b5x6rIKryhCk1wIPj/y45IPkivukLqHV3eZu/XiRaGTw5dHoB\na97F\r\n=AZmu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"pre-push":"if git-branch-is -i -q -r \"master|next|next-major|beta|alpha|^v\\d+\\.\\d+(\\.\\d+)?(-\\S*)?$\"; then npm run test; fi","commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"types":"./dist/index.d.ts","module":"dist/esm-es5/index.js","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![Build Status](https://travis-ci.com/PVermeer/dexie-addon-suite.svg?branch=master)](https://travis-ci.com/PVermeer/dexie-addon-suite)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. \n```\nnpm install dexie\n```\nAt the time of writing Dexie v3 is in the RC stage. To install this version you have to use the @next npm version. Current version of Dexie.js: [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie@next\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default this addon will load:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    constructor() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]` and a property `group` that can be assigned with the index key of `number`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf` and `Group` in `group`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]` and for `group` it will be `Group | null`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"b83e1b6e878cb288473286edeed3aa296d7ce9af","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run build && npm run lint && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration && npm run build:dl-dts","clean":"rimraf -rf dist/ && rimraf -rf reports/","build:es6":"tsc -p tsconfig.es6.json","test:karma":"karma start test/karma.conf.js","build:dl-dts":"rimraf -rf dist/ts3.4 && downlevel-dts ./dist ./dist/ts3.4","test:jasmine":"cd test && jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","semantic-release":"semantic-release","test:karma:debug":"npm run build && karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","test:jasmine:debug":"cd test && nodemon --ext ts --exec jasmine --require=ts-node/register --config=jasmine.conf.json --reporter=jasmine-console-reporter"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.13.7","description":"Collection of dexie addons","directories":{},"_nodeVersion":"12.16.1","dependencies":{"tslib":"^1.11.1","lodash":"^4.17.15","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.15","@pvermeer/dexie-populate-addon":"^1.0.0-beta.5","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.4","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.5"},"publishConfig":{"access":"public"},"typesVersions":{"<3.8":{"*":["./dist/ts3.4/index.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.5","faker":"^4.1.0","husky":"^4.2.3","is-ci":"^2.0.0","karma":"~4.4.1","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.5.0","nodemon":"^2.0.2","ts-node":"^8.8.1","webpack":"^4.42.0","lodash-es":"^4.17.15","ts-loader":"^6.2.2","typescript":"^3.8.3","@babel/core":"^7.9.0","simplytyped":"^3.2.3","webpack-cli":"^3.3.11","@types/faker":"^4.1.10","@types/is-ci":"^2.0.0","@types/karma":"^3.0.8","babel-loader":"^8.1.0","jasmine-core":"^3.5.0","@types/lodash":"^4.14.149","downlevel-dts":"^0.4.0","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","@babel/runtime":"^7.9.2","@types/jasmine":"^3.5.9","@commitlint/cli":"^8.3.5","@types/lodash-es":"^4.17.3","semantic-release":"^17.0.4","@babel/preset-env":"^7.9.0","dts-bundle-generator":"^4.0.0","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.2.3","@semantic-release/git":"^8.0.0","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"github:PVermeer/karma-edgium-launcher#master","@commitlint/travis-cli":"^8.3.5","karma-firefox-launcher":"^1.3.0","license-webpack-plugin":"^2.1.4","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.6.1","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.2","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.1","@babel/plugin-transform-runtime":"^7.9.0","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0-rc.4"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.4_1584969888207_0.614229347712409","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.5":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.5","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.5","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"b05c6a796d8f38fa15f837d26f05b7deb291994d","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.5.tgz","fileCount":69,"integrity":"sha512-uZS65eKoTq1Pb/tyjBhrZsuYWGDn4TigCY+DudR0hmPRH87Bj7fjqVbxCf4AFL0DXiuUC7O7Pt2Ui3GGLSXmzQ==","signatures":[{"sig":"MEUCIG484yrJ8PF9YQvj5Dbt/vXUMJTvwJZIPghpJKx/rzw8AiEAieXsuAdTBQtftV9EvhLkhHmtY+34QLnvDKDH5u8TPEo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":221592,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfsT6nCRA9TVsSAnZWagAAOzQP/RYvXixL6epDPNqc9JEX\n+5vTMGCZKpMDGTnbkki8eKiiy8vOLmrvmylF0JJ5npu15zuuv4GiKcHy2qml\nRKbz8/3L/nFYlN9IK7fsOFUm7mkwrfQ67qiKQYylOMty2B4zZmGO9YBCHbau\nT4c6K77xG+m6NYJVzZp+EFsVNTz7ZLgRCFHgU/kjx/geMtYq71v5CC5BGX2B\nJH8C0hzH7WXyVZ+Vud2kzWCCep4aeH7cKXwy29HXdihrDtlhqd3wAuqYkk1c\nRXxasr+U0K6HDMzn3j7SrPT5I6qyKH39/S21jq0M95mT0mfICjvtpWdyIKXu\nLZpXXEvrYM/MUdpOuQA/CjYbkM92TnIaIQOGCg29KVrQ4IeQ3OWHYTOKhgEP\n7inMF5SFVa1KdffI3WtaGH8vh7mmmXwV6S6xUTD7hU5chUIPVwwnqRqxvKus\noI+sC082lzqXxFfTktG4fNV3iJp2SfNwR8gqHxwQrldJ6x/0TJkO45qfksWn\nTKSWOlgBBvuSxft5q14NwvfhMH/VSVbzaLvrPoTwZByyOxwdfOfoewT6cNrL\nQJ8KDl/PvJ7djIsc9SnsQfRTVcBpT72gHMlnawi2PcnmmbX7wH5HPCnHH2rr\n6l6mREtXdw/HOB3cMoWXFqw4/MTEIcnzgQo+cJsyScg7gIHPN/ZABPNmfqMS\n7Zr3\r\n=clNG\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"types":"./dist/index.d.ts","module":"dist/esm-es5/index.js","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![Build Status](https://travis-ci.com/PVermeer/dexie-addon-suite.svg?branch=master)](https://travis-ci.com/PVermeer/dexie-addon-suite)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. \n```\nnpm install dexie\n```\nAt the time of writing Dexie v3 is in the RC stage. To install this version you have to use the @next npm version. Current version of Dexie.js: [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie@next\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default this addon will load:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    constructor() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]` and a property `group` that can be assigned with the index key of `number`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf` and `Group` in `group`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]` and for `group` it will be `Group | null`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"e088764c52fc82049ceae6a238b671f6acb1a5b2","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run clean:test && npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration && npm run build:dl-dts","clean":"rimraf -rf dist/*","prepare":"patch-package","build:es6":"tsc -p tsconfig.es6.json","clean:test":"rimraf -rf reports/*","docker:dev":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev up --build --abort-on-container-exit","test:karma":"karma start test/karma.conf.js","docker:test":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.test.yml -p test build && docker-compose -f deployments/docker/docker-compose.test.yml -p test run test; docker-compose -f deployments/docker/docker-compose.test.yml -p test down","build:dl-dts":"rimraf -rf dist/ts3.4 && downlevel-dts ./dist ./dist/ts3.4","docker:build":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.yml -p build build && docker-compose -f deployments/docker/docker-compose.yml -p build run build; docker-compose -f deployments/docker/docker-compose.test.yml -p build down","test:jasmine":"cross-env TS_NODE_PROJECT='./test/tsconfig.test.json' ts-node --require=tsconfig-paths/register node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","docker:test:ci":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.test.yml -p test build && docker-compose -f deployments/docker/docker-compose.test.yml -p test run test","build:es6:watch":"tsc -p tsconfig.es6.json --watch","docker:build:ci":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.yml -p build build && docker-compose -f deployments/docker/docker-compose.yml -p build run build","docker:dev:down":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev down","docker:dev:karma":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma build && docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma run -p 9339:9229 test-karma; docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma down","semantic-release":"semantic-release","test:karma:debug":"karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","docker:dev:jasmine":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine build && docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine run -p 9229:9229 test-jasmine; docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine down","test:jasmine:debug":"cross-env TS_NODE_PROJECT='./test/tsconfig.test.json' ts-node-dev --inspect=0.0.0.0:9229 --transpile-only --clear --respawn --rs --require=tsconfig-paths/register node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","build:bundles:watch":"webpack --config webpack.config.js --watch","build:esm-es5:watch":"tsc -p tsconfig.esm-es5.json --watch"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.14.8","description":"Collection of dexie addons","directories":{},"_nodeVersion":"14.15.0","dependencies":{"tslib":"^1.14.1","lodash":"^4.17.15","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.16","@pvermeer/dexie-populate-addon":"^1.0.0-beta.6","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.5","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.7"},"publishConfig":{"access":"public"},"typesVersions":{"<3.8":{"*":["./dist/ts3.4/index.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0","faker":"^4.1.0","husky":"^4.3.0","is-ci":"^2.0.0","karma":"~4.4.1","is-wsl":"^2.2.0","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.6.1","nodemon":"^2.0.4","ts-node":"^8.10.2","webpack":"^4.44.2","cross-env":"^7.0.2","is-docker":"^2.1.1","lodash-es":"^4.17.15","ts-loader":"^6.2.2","is-windows":"^1.0.2","typescript":"^3.9.7","@babel/core":"^7.11.6","simplytyped":"^3.2.3","ts-node-dev":"^1.0.0-pre.63","webpack-cli":"^3.3.12","@types/faker":"^4.1.12","@types/is-ci":"^2.0.0","@types/karma":"^3.0.9","babel-loader":"^8.1.0","jasmine-core":"^3.6.0","@types/lodash":"^4.14.162","downlevel-dts":"^0.4.0","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","patch-package":"^6.2.2","@babel/runtime":"^7.11.2","@types/jasmine":"^3.5.14","tsconfig-paths":"^3.9.0","@commitlint/cli":"^8.3.4","@types/lodash-es":"^4.17.3","semantic-release":"^17.1.2","@babel/preset-env":"^7.11.5","dts-bundle-generator":"^3.3.1","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.4.0","@semantic-release/git":"^8.0.0","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"^4.0.0-0","@commitlint/travis-cli":"^8.3.4","karma-firefox-launcher":"^2.0.0","license-webpack-plugin":"^2.3.0","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.9.0","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.4","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.6","@babel/plugin-transform-runtime":"^7.11.5","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.5_1605451431373_0.7873387273206942","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.6":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.6","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.6","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite/issues"},"dist":{"shasum":"a21d1e9c777eb8f0ed89fcd4e41573386c8fa221","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.6.tgz","fileCount":69,"integrity":"sha512-wwuph5t8A/ScbsUY9J0twVu5ClmrpMyAVNeSQvo1ew2lNh7Jkk20Qdo5vTAwk89PY+NjLGff2MY0E3eiZ3SS3Q==","signatures":[{"sig":"MEUCIBAQGqpkUBtWR8DAY4D6Fk6H6CVm06GhSbBMOjMKa9MrAiEAwCbUua89d1AXruRbq8WTZdPh20FGwTlQQR/FDMnLKlg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":239417,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfusk2CRA9TVsSAnZWagAAzNAQAJo0CRHBqZw7pkrUgCX8\nsu12UtePVIUR6diwHSmpSwy33pxnhRxw1e0eeoGHGkUS5wJHIe7BhCAz6XXr\nstrAlR6T0GAiw0NuEPlNHiSvzqjycktgCdIefiXy2BwwSrJGlF/xOSr6rCT6\nG3H+VckH9rnaESngI5RAvof4didQNx7fGcApe6TOc031qGXuUv4HffA+88F+\nPeOBVThbTjoFaTHxEwmHhVEraESQFuzjjsdQV9aOFYkdRCsxewkIRMNRiZ1W\nbvHgnt0YsgVGHZCGdNiyMNSOrLLxeT7D2UEhe42FpRTQA9TU+NW4kKD00vKG\n0C0rzkdPjmho3J/aZ1Ve35TqIIF11w/HR9s5UGmAPyvbQbxdnRjiV+cRujvy\nOPGGAiBqlekEQZ2QApMYuasKNNBHGnNnk8jk98c2mUULA+ztJ6ytYf0aqKOA\nH6B1i6Qvrb85inMQ1QAnIYfaRBvLpFfOEDlPuECm4rbr7xy7FqgUdC3IdSbH\nD8H45UoNnYaCG4JBi7fvRcTivHJD1cknqREq55c5xeM3tUxFgbazISeB/6L7\nOMGnG6O/Jif2t0rYJVDFNn8GfsG6ChktTmP9KvBq3dwiZ86ujyYcxJS2yH4E\n7EGgj/h+NEmMy1DCnApcUlXqL+nj1FxraP9d7fW9OaUmMuYgrj4tJIk45qdC\nGMnD\r\n=0LxC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","husky":{"hooks":{"commit-msg":"commitlint -E HUSKY_GIT_PARAMS"}},"types":"./dist/index.d.ts","module":"dist/esm-es5/index.js","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![Build Status](https://travis-ci.com/PVermeer/dexie-addon-suite.svg?branch=master)](https://travis-ci.com/PVermeer/dexie-addon-suite)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. \n```\nnpm install dexie\n```\nAt the time of writing Dexie v3 is in the RC stage. To install this version you have to use the @next npm version. Current version of Dexie.js: [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie@next\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default this addon will load:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    constructor() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]` and a property `group` that can be assigned with the index key of `number`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf` and `Group` in `group`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]` and for `group` it will be `Group | null`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"41ccf0653c618afb2d2b8a89ed738a19de0814fe","scripts":{"init":"semantic-release-cli setup","lint":"tslint --project tsconfig.json","test":"npm run clean:test && npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"npm run clean && npm run build:bundles && npm run build:es6 && npm run build:esm-es5 && npm run build:declaration && npm run build:dl-dts","clean":"rimraf -rf dist/*","prepare":"patch-package","build:es6":"tsc -p tsconfig.es6.json","clean:test":"rimraf -rf reports/*","docker:dev":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev up --build --abort-on-container-exit","test:karma":"karma start test/karma.conf.js","docker:test":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.test.yml -p test build && docker-compose -f deployments/docker/docker-compose.test.yml -p test run test; docker-compose -f deployments/docker/docker-compose.test.yml -p test down","build:dl-dts":"rimraf -rf dist/ts3.4 && downlevel-dts ./dist ./dist/ts3.4","docker:build":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.yml -p build build && docker-compose -f deployments/docker/docker-compose.yml -p build run build; docker-compose -f deployments/docker/docker-compose.test.yml -p build down","test:jasmine":"cross-env TS_NODE_PROJECT='./test/tsconfig.test.json' ts-node --require=tsconfig-paths/register node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","build:bundles":"webpack --config webpack.config.js","build:esm-es5":"tsc -p tsconfig.esm-es5.json","test:coverage":"rimraf -rf reports/coverage/ && karma start test/karma.conf.js --browsers ChromeHeadless --reporters dots,coverage-istanbul","docker:test:ci":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.test.yml -p test build && docker-compose -f deployments/docker/docker-compose.test.yml -p test run test","build:es6:watch":"tsc -p tsconfig.es6.json --watch","docker:build:ci":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.yml -p build build && docker-compose -f deployments/docker/docker-compose.yml -p build run build","docker:dev:down":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev down","docker:dev:karma":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma build && docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma run -p 9339:9229 test-karma; docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-karma down","semantic-release":"semantic-release","test:karma:debug":"karma start test/karma.debug.conf.js","build:declaration":"dts-bundle-generator --config dts-bundler.config.js","docker:dev:jasmine":"COMPOSE_DOCKER_CLI_BUILD=1 docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine build && docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine run -p 9229:9229 test-jasmine; docker-compose -f deployments/docker/docker-compose.dev.yml -p dev-jasmine down","test:jasmine:debug":"cross-env TS_NODE_PROJECT='./test/tsconfig.test.json' ts-node-dev --inspect=0.0.0.0:9229 --transpile-only --clear --respawn --rs --require=tsconfig-paths/register node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","build:bundles:watch":"webpack --config webpack.config.js --watch","build:esm-es5:watch":"tsc -p tsconfig.esm-es5.json --watch"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite.git","type":"git"},"_npmVersion":"6.14.8","description":"Collection of dexie addons","directories":{},"_nodeVersion":"14.15.1","dependencies":{"tslib":"^1.14.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.18","@pvermeer/dexie-populate-addon":"^1.0.0-beta.7","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.6","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.8"},"publishConfig":{"access":"public"},"typesVersions":{"<3.8":{"*":["./dist/ts3.4/index.d.ts"]}},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0","faker":"^4.1.0","husky":"^4.3.0","is-ci":"^2.0.0","karma":"~4.4.1","is-wsl":"^2.2.0","rimraf":"^3.0.2","tslint":"^5.20.1","jasmine":"^3.6.1","nodemon":"^2.0.4","ts-node":"^8.10.2","webpack":"^4.44.2","cross-env":"^7.0.2","is-docker":"^2.1.1","ts-loader":"^6.2.2","is-windows":"^1.0.2","typescript":"^3.9.7","@babel/core":"^7.11.6","simplytyped":"^3.2.3","ts-node-dev":"^1.0.0-pre.63","webpack-cli":"^3.3.12","@types/faker":"^4.1.12","@types/is-ci":"^2.0.0","@types/karma":"^3.0.9","babel-loader":"^8.1.0","jasmine-core":"^3.6.0","downlevel-dts":"^0.4.0","git-branch-is":"^3.1.0","karma-jasmine":"^2.0.1","karma-webpack":"^4.0.2","patch-package":"^6.2.2","@babel/runtime":"^7.11.2","@types/jasmine":"^3.5.14","tsconfig-paths":"^3.9.0","@commitlint/cli":"^8.3.4","semantic-release":"^17.1.2","@babel/preset-env":"^7.11.5","dts-bundle-generator":"^3.3.1","karma-mocha-reporter":"^2.2.5","semantic-release-cli":"^5.4.0","@semantic-release/git":"^8.0.0","@types/lodash.isequal":"^4.5.5","karma-chrome-launcher":"^3.1.0","karma-edgium-launcher":"^4.0.0-0","@commitlint/travis-cli":"^8.3.4","karma-firefox-launcher":"^2.0.0","license-webpack-plugin":"^2.3.0","webpack-node-externals":"^1.7.2","webpack-bundle-analyzer":"^3.9.0","jasmine-console-reporter":"^3.1.0","@semantic-release/changelog":"^3.0.6","karma-jasmine-html-reporter":"^1.5.4","istanbul-instrumenter-loader":"^3.0.1","fork-ts-checker-webpack-plugin":"^4.1.6","@babel/plugin-transform-runtime":"^7.11.5","@commitlint/config-conventional":"^8.3.4","karma-coverage-istanbul-reporter":"^2.1.1"},"peerDependencies":{"rxjs":"^6.5.4","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.6_1606076725553_0.11172089592363288","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.7":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.7","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.7","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"83b4dae22845e2cca30aeab106109ec3169327f7","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.7.tgz","fileCount":22,"integrity":"sha512-IZhNx76K7hQf7uxrTii/sVM9Nyv3St42wIEtVXZ5SXlBlIBz7cot6IYkbnQFjsp+v8d12cSgGBHkP8g2y2O5gw==","signatures":[{"sig":"MEYCIQCWm7jGSP8hZ+r+83a0cSirnllAStL4Fj7PTFQBG0HmXwIhAMUQBP8Pa4oukXHe8W3KNSq+n9qaHSWUhNp3d93Ih1LN","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1316386,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhmotqCRA9TVsSAnZWagAAZywQAKSu8lfQujHaBIMtzjDD\nA3SvS6NvGKmwk2kPjdu9oErTC0lMLwY83N0ZNQelfJIeLYTYJAqkLqfFFBl8\ngl9YuceA88JRpp0pFRTHnoATYPgAC7v6L6HwgmKNJNu93G8XLCqNW8RIvxKz\nA2qv2Z0I+lk1aekHy9cw5wGU+byYdY04dRAqiq2/L/m39MAl2MB2aj3J1NDd\nrFv3AsGy3WbWDBqYmph5C0SqPttARp45rh8pRrH/v/cJSePQCCe82+kWl54T\n5VYNiNv004UT3+NzpEuxd6L6oEKiMDsbTgcF18jZr88ppRI9ARn+SCnGDO7c\nOT5oflqwW+fA2Y/uCLjFVvqN1pA+/dR76CzMSMIIMUKSIcLhCFMNZKxU5vrK\nkfR7i0tDadcE5NvK6HCY0JAOANuSBh+qtXDAjtXk5qAYOPsonPrCaF2IQzJd\nhDcrl4Ink4USNph+EgHPUQX4OpPmErm323K7VFnWTycnEGyDOAbHtgFTGmEt\nsQws/LXy8aJycwDA+ISfYBHw7T0hhFPj5StfOdTQAQmdr2QO+GI+xQsK65xf\n05uGEZiwKFhFKAYVGSlDzwhvoGbTTGJpungkCu1NK+f+7/We1alnJd+O/UOd\nYcpRRqFeEPxQZa9EH7wVzO+vCAauF5AAYuxREAuUPLoORAMYT3H+E2LT+WVc\n1/wP\r\n=QraW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"3025a056e027ca1d53c30f8c5ba2d2df8337c17c","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.19","@pvermeer/dexie-populate-addon":"^1.0.0-beta.8","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.7","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.7_1637518185814_0.5650697536056797","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.8":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.8","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.8","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"670ddf7941c0ec248d5be758a9be63faaa9d2baa","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.8.tgz","fileCount":22,"integrity":"sha512-jsMEZKpr/M9GO97SYMSWFQn0HczBjkfefV3jDfixzrfGEZvyFxDpRgP0QImjgPkf5UNwEPKdtSfBClO6tm6tZA==","signatures":[{"sig":"MEQCIB0b+Fi4KoX2iVIhx/R9jvy2QiwWQQxJJSV44c2dP8nbAiBVTHhGhCjSq2a1RVGvHcfZuTIP9ur2wvOO1wge2LWlLw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1316638,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhxfEECRA9TVsSAnZWagAAVosQAJltn+1a6aJAfiDNa3oD\nB5YJMV0qkkk/H0HFh8STEo0QkxRXLIL28vkcu+giJTjEIiy1Hb1jakxXOZgg\nLdceiyypq+aUYz4Mphht0S6on1Tbb9Gq4N/b8HUCvaWj7fh9tZrWmO97EKb5\nWJFDHWeycnG4/ZMMv81wi5yvTO8mwD+L7pu34GVFHZT4WzI8s45QePPuRoJE\nVdztnXSGF/CwZv910ac3hM+MdDCOM7cdFhki0kEPioEp80LXHpENGj9mEYSJ\nxXnUtPKQjPq4vB7V2TLR3zVQJjjffNXMJ0lqmWHeH5rBkc0DtjspgjYG6+P6\n/c+ugPXVX78v5iX1fcanSLsVMtGtbggJKLxq1JPll2CirlHU6nirntU5Ckjs\ngoOq8veQ33CLFHYnQzewfnoJk0T8a5w/C/IuwT4PWyYaXdvj/50dnorFBqa4\nElwOrZFCKK0UmgRM43YZoUxC61H3Ut2nEQgQNQLwmx0sTJS6+rOrWz3z4f+X\nOOCRmST04wo5AkVbE4KVpk2HRr0KT0tVAP8EKw4a8URkguG9pPhVYwLqmW9E\ntsw274sTzqkdJPOEdE65uLjY1+BK1EVCn0twA8xWlIqh6DIJ5atMHIK+jzvD\n2bNoR44ylqNERX6Iz39MHK9geNc47acpbZ8XOqaOsmsQ11XUwQezI8ePLmbK\nv3wo\r\n=vkbS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"2d4bde1ac79029954e85f0f8665ee169b272b157","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.19","@pvermeer/dexie-populate-addon":"^1.0.0-beta.9","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.7","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.8_1640362244030_0.5635591768806831","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.9":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.9","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.9","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"4de8919c475b7d0ae1f2b5c630b92158738c4351","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.9.tgz","fileCount":22,"integrity":"sha512-8Lf8jT9DnzigMTzmZ1QxNa0PL86AxYbJ4trhOs/ZrBp+9O0wzZCUn72qCGgOUE034b6Q/TYFXJKzEQ5so2feuw==","signatures":[{"sig":"MEYCIQCkFlNTUbuW5k6nZLzJar+pWdV6tIts65/WbX9n2aiFfwIhAKdE3q3wwxc/SI2nRXoI36XHa9/LjvcgnkTCyL7Kx8b4","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1317488,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhytczCRA9TVsSAnZWagAARWIQAIvka92pBZzqW6ij/7oZ\ng7R+Rquuz76t6sLZKhYln880CNBmTwwmntJDeMwhQ4rdbGxgFu3odcgXj+el\nf5i6ghny2G9ZWDHxqg05XlFtw0Hc5pqlJ2MPeYYrAfPEUkRt2FBuBWyV6vyT\nsayA/f0A+AkAWpd5jptJmJPtvxUWW4IfTKGFUFyMIIaq1tVQlXMJp2VnZS4F\nirfAqibSaw6oHhEifnQPCNVRIjS7+umqpwu7C9NaYBUBY2XzDOWUnsKKze46\n85R+Q/HsUfHoari9kOvDsBPPmq7d47YbdKFQYTN+t3l2JqtXvn1K1eOMpYx5\nB0Jn+K7cECYOhfymjVxd/PJODZ6SNere6Atpo8S0Zoxveval8GEdTElwr3tz\nBpohad/YPTFulh64IpyFDw564HBk3kE631TV63wZwi252RYoSQ52g5mXZeyT\nIG8BD6NATQuUOB2J01r/FFwxk/SPggzTJ7ceOFrsylOdXWHM6pppz6U3IfLM\nmG9V+eSj+mHmeE26g9E3qkG10j1JCkZqvlHpix2qMtYdxW88xl6B/jppUoK5\nl9RkMBEz1eAieg6Ob/Ac/CE4V7LSB1ImSxYkkSGJKDM4mC7xXnOtTrGs31W8\nLh1WnLfGEf7O3EXGUzmt019IpLoeLz3VHRw9iH9qS2fg6RfYtCimNj4gX6FL\nEEr4\r\n=x/fx\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"128b2ca7c39b9f20c5cf116edf222727c138328a","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.19","@pvermeer/dexie-populate-addon":"^1.0.0-beta.10","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.7","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.9_1640683315105_0.3979796029160332","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.10":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.10","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.10","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"e14762eb806b6ab19be6013cc6275a80959bd994","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.10.tgz","fileCount":22,"integrity":"sha512-aHwoyQf1cg/hCV3W9DTiBa94EZGhgzSP2Zp9w6JZAGUE4/ebxjyz5+Vbql/TFykure/7LGt1gTs/QyeJo18h8w==","signatures":[{"sig":"MEQCIHrdtQKBjjj6neSjpx7VEaDeRJGjk0ga0qzGQwB1hIoqAiBZh7lzTX7W08ewF4ABbzmjIEdJcIrBrSGmWjycjGDNLA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1336901,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzdpkCRA9TVsSAnZWagAArKEP/RmSCnapHjEuffm4Pyd3\nPdSGK4mo1nfirdkZb4J4bwR1l7rTz/U2KScOFg26EWV0115rStnmiRxXFiY7\ngW7iEcH0fNu1l/iTGWFbx/Fa0jCcxW+wODYTHNoCoqrMUuNKtjKJZJjbSRQM\nYaDDhznawobMR6frqppKKS7KBYApL1SfEgjwcutakMxS0SgEuDBTmU9M5cno\nH5j1PDHZwJEzZND8wfVCKafA4aaptSuxz36AuQH5r7iEpOsn8NxkGgnBGu2O\nvOppCdXNOYt3tkcW9Vg6smV4pBRyUKqTx1vNC6nO3e/TLNCjZo1QRDtowNK+\nveTCJFyj7DR0Hrn4z4nDb9Jee3e2aLS4BKR6g3bQxuBuiFbf4SAHSOS0cXoM\nKAn2kD0QGbwP+X4mIf55NY+ePrE937Cp2GOetoj9BdkzOaTjMbbgYCYQRlsh\nuQ6a42zdkxydfMJrnPLy5s60g+6pKOXJ1wAEv7VPrgRVdHH9d80dLP/eJj1n\n9vB0V+f/ru4XKAPbl9Hh/3Ypgfb84OkiI+84i9iLK60tAZ6449rgut5UHIdS\nWSj5DPp3aDTpxHpp+50o+pxXDD4xuvnYN9Iv1zKHNwoy7dUZrk7zpTJFE9GZ\no3gMupOOluoY14zxGPgQnmBIT0vQrZlPDb6k8A1QGQ/Mhlc5ewBKU6UyQd7N\n16fI\r\n=mUFi\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon.\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"4e419ecbc44432c458b84fa49e31bb1cefb1dee3","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.20","@pvermeer/dexie-class-addon":"^1.0.0-beta.2","@pvermeer/dexie-populate-addon":"^1.0.0-beta.11","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.7","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.10_1640880740655_0.5657079628972796","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.11":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.11","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.11","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"73ee0f6f5ebcdf91d197fb1f9b250b6ff9087eae","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.11.tgz","fileCount":22,"integrity":"sha512-0o69F0IU4HOX2quetr8lpJ+PGsCVEzS2/zek31UjtM9ZHIMreKmHIk8ufpE5p1nUqhR6rYRyJ8Slt3ohAz91Qg==","signatures":[{"sig":"MEUCIQDeC1DsvhIP+fJD36/H0dZGlWN1GnN4FBENEsMZFae5wQIgEifPXtdH23aFR2Li+roAvJ0Ac09G+v71+WAM+O6vnoM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1337547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzeqSCRA9TVsSAnZWagAA6s0P/icbyncJOgXWs1I6txzs\nh+G1FmpRBnbc3T3MZnyi2fCzwe/aIZDLrloreGMcz3IuT3xp+DvTk74C4dQv\noD7M8lIwZaDo7PIV8wvKn9SxsLusS5++RtJ+npCZRHKR9Y3O4t9NhR0cH8kF\nP24DLSc0NpKqYtRNF33eNAQyi/bfDAsI/KUTK9DrU3HcuzbeULcJslFDSwMl\nhppZlWkz2Cl78WgY4It8RuUUkITNW0p5hWd3Ae/H+dXOePryfYRAE2pvABA4\nftO52sjygzH3BNDGaciEVZSVMNGxHOibBwLXOS3exvsJMUz4A5aTP8T2PJKL\nxjgNlRLheutJiJLOo3Bbaj7OEYEsFfPN4RfHSPu6iryQ4FFvYfxbyJx9rN6C\npaPpkm5LQXJPP+OOSSdjTCxJt8cbYk1r5kDq67kGBUlNT1KT69DM62XRK9v0\nXif0iw2RID4wzJJM5O47nB+1MXjK3xH+LC7Ix9iJdk+r5QY9JLHdqHOnz/70\nSze54OZLogC5+huR5g725I04I2RXMnmr90qeKUHCr4rGIt/67G90VxYEVASE\nz+cbWeZLOkdT6avk+0P3VUbFxVR2cwvn6wFKEzG5s4/5EFQl2a74xrZRM22C\nAW8CAckFv28h0d3kPxVS3/NrpDD993issu+wL/KkiJmBIMwc36J66Ri7KaUg\n2pCv\r\n=1RP7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"9ad05a2206c91dd0177a08ab3f4323ae515044b9","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.21","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.12","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.7","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.11_1640884882418_0.8612361595924929","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.12":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.12","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.12","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"ddd7f06d42045bd2d74c81a8d03c5cc77d6227de","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.12.tgz","fileCount":22,"integrity":"sha512-skc7QQ81Oj12Bgb0niDmV1FlCvDhkkK5kxZaRJvLJ/PgmHyxr2hn4wOX+0Jrjh3D+kr+c00iT+bM0lng89Jzbg==","signatures":[{"sig":"MEQCIHUBp1by/Rm5fxBsPSKqkxKZbS2Be8c2AlvmkWpVe4PIAiA2Spc2xTavZdBMBKAwC9MuN6l1lJrbXfzZCrb8/gwCLQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1339665,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzxvACRA9TVsSAnZWagAA3H0QAJojSVhaPUoqK/taJmmE\n2GF/zsh1TJiEYj5gpi+BVti731fqrF2zKpvYI1EXcZe0JOsGViCZ2/QSXAE3\n5536VbpKl+ZBXSRnuei/pvekepE8h05qcFsaD04oNutUD/jj6NlJohD2WoqU\nJNf/FqPZ/bmQl4Tz1cxp8Lj+Ta0L3d3PSKwzqRvMlOYs1Dm4P37Moal4Vvk3\nedaUgICU/Mckf67xNK9rP0hGqo6LZ9ChI9afgLDzdP9Kgt7R79uUh+RibByb\nvCpojqqE9Ax6gZM4fVx2Y4JeC2xy/rnM/Rou//jQQ+SwO8vqN+x7yxVF31tn\nNE9w2lq2A31CB9Pf8DR67+z3Q111AwXpoLE4dw3U5/xbnelNLzX6AoaAutX8\nnloP+IO8nLeQs9mqiz0wn36nnW+agL2DnxA309yIdPzHl/MyTP1bUbembZlz\nAKzwlfnNf+OG2VZlJ2uWipKw9NqM4dHH1Uy1cOyR7R4BBk3sVLMmsb3YbNFa\nb5Hrd5+9Fgrnr6bHTcLIOpWUmMZQVHM/c/7Z2VNWQlVXsYWjFusMb2lCgT2j\n9DWvzZlP0NrU1Z0uSRc8YB9EIfX+FRhqbFPvCwhwAaTIObu0LN6tD1GPPnN8\narcxzAjimqnFLZYioHIvLiRS2I2z3fZygqEaZPmce5+h6pCzZpAj0FDO8gi9\nvRlQ\r\n=T//I\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"d1c9351b384e4b1dea2764be5ec8814866487e99","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.21","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.12","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.8","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.12_1640963007916_0.6602905004338917","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.13":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.13","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.13","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"3293f8faba8908a4a7efb08af04aba4a648abdda","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.13.tgz","fileCount":22,"integrity":"sha512-JR6y5xmkKpQFuF5IjekpPbgX77P3SdzNLo8dEq8qnwKvhSly+Y8CwR8KLuBR7J3lAIvJGLbrCZyIC9JipmzPAw==","signatures":[{"sig":"MEQCIGqCKoawGnp4cZNZB7rxQ0s6AFb9NULETl8kb9JbWWaEAiBDQru5FDnc2TldjZzA6/cs8LnSqaNOJgwepycyn49eVg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1339973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh0IehCRA9TVsSAnZWagAAnYkP/0TGlcmEyekPv5QE4WeM\n+EWBepME81xQ2RRt2qgmDVj2siZCRZn8Df8XNiOI4wleE67z4kF22D90asL7\nVYDwC8qJsJet74TpiCqH6MLmfaum4ZEXrAgo+8uZUYLDC1dV8QNZcUFfgZH+\n7Uh8ts/zd3J4iIdUfzTvl1MJ7d45AWdM/D1woKibA0t/YMOAyltPf0Ki102w\nYA/F7FUdstsYRd9xfeCf4613Ue3np2b0TbU9QN9KmgztY30TxfEMpnnf+KrI\nZYUAvgsWDpLZzKVSyqu5Ahy3BBEKXnSJZ+O/Z98C6k0nU9SHMCKleXR3yk1Y\nXg1KqRSJoHlm11AvwepSKDLT+5KTVeq9Z+49TMGKn4719uY+u5bI4/V329BW\nWVsvRPiZDkopdRAq1kQ7XJZwlg4CG2w8uojf87laT5mWUUa5EXTnyelRv01g\nCpVnqlhwZFlkKk9axhgNZR7/MCm52JhCh1pwLjUFzXjGZTk09d5l8lKOzmg5\n86HqjjYgoR0LOxBZZucQlgRkl5+umTK1ZreRRuHVlV/O97KnLN8yVPhGiHbA\nC6+M+nfSy81mrFPU7jVIbl62rjJlQ844hhATMRDa8BZIbbYOSOjHy/+deqeH\n7tFI2DC3OfV0fszf4Y2YgZwx11Bg8VEgelQ1d5MuIKFesneEzdBOW0eNB/o6\nkr1e\r\n=gkYt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"61d65f071c0c8924825419f164d6b300b3bc7f45","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.21","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.12","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.9","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.13_1641056160878_0.8225964510420198","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.14":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.14","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.14","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"aa3cfddc755b3fddfbf9ae48806f0a4286c9f404","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.14.tgz","fileCount":22,"integrity":"sha512-aevqxmC2paIqkmfVJiYWVVw6wAJ9bh5cQenBBSffiEpvlCWZVqtelMIcBDfHF/N+eFJLLfkcOpisn6Hz/oo+Ng==","signatures":[{"sig":"MEUCIQDVULvnK+Jdy4sOq2/L8OvKXjuw5LOzPXR5/NRlztS4jwIgAyyXDLAWuhgaraTVnAAy7VZbwnltnblGV5LkzCcHXaA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1340341,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh0dc6CRA9TVsSAnZWagAATHYP/jixjwgCt3Vesn1BrMuY\naW+ayJCowOgANrdrUHlVsABBPW41HTaEVG6r+pN3Z9trLUTLpy8ugGfDPm+m\nu8QKeowrY6800TrgibppfgkkkzFNHpdQ0tewnheks2BuCPZaacC6t6dl1vmO\nRAoAL1nO5iGXZ5QkpI10ArLAWyZEFgeR4k2vPfrb9s4YpMIjRiqRd5gk75vg\n11C6ZJGiWKPH2SqoRgyIs++5S7z5EHVnQdFih8JMGNWqWABBjcZfd3RgtYCr\nRcay+TWRpXykhgmZ1CZ8fWfOwKopUH+aDrb6+GUIHCoNEhA1fu1+4znWevYd\nUQh2IBw4brasPXJWnJvRSUwPSE1eqVnralTitSPjxO2D8OUYr4N6V21goDYn\n2LuNgg1ARhrfd9AufaoC1I3tajKgHHtEV1o7Bv3222wo1xeLjzQgCDTZbweb\nco5EnzL3tOV78/m7CYhPIF/ph3ue0HNKIeS2dOjeTgK1SsCcLHMLkAbLr4oE\nFfvF7wsPuwNsHdcK28VMivAsZdKTmhhTmayXlR6KtC6xhto3hYpQ8sQLqzAn\nXfgqwmo46k9pYRCZLfhlPuLeFbSa20MURCzvp7xQFFN9doprXTIdDeb8pl9b\nKaKQurL8PG1lZTIOR2ACTkfgGJFT+AxJ1iOZQ7nu9TRzE2zPKoqvf7eVxQuR\nw1HX\r\n=4e92\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"25eeb5af2bfb419a4527e64b0bb9a788fe880813","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.21","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.12","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.14_1641142074664_0.8113170085017147","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.15":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.15","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.15","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"bf749380b35fc00ba0fb1b686fa302bceb0d3a84","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.15.tgz","fileCount":22,"integrity":"sha512-DKpAwQzeSPZuQo7cWzlkup5hXduk/7+5HRvw8w5jn/4kETV82youjpoOoBMhYKLrkFz/efz2bZ7Bj9tGOeNrAg==","signatures":[{"sig":"MEYCIQCSElk6n3/tBaAAo9tpu97KdqaCh2/qP1G+xKwVdlXWZwIhAN7WMN9WmRv0uTErYhOBXhis+ItgCOlaBy0pcyyDO7a7","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1340929,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1DgbCRA9TVsSAnZWagAAHmkP/0YEWBLd+TKij7GDLWGN\n35mC0TDW+e2iXAxCMflkE1imkC7XkLs2J0jJu36xU65j95jKFscN2m4s+TFh\nqZKGtbwh+vpVWU1hD3wV2Qa89esDUWYNGfCaPx0ar/nfHeDyyfJ4ONggUTRL\nhPCrZF9HA/PLtVhtTx2GInM6IYgjq5h/LkAdPPW4ntTBVxgzXDjeX5E6trNJ\naFxAY4l56FbIyhRbNRdFC3S8keam9hmdi/L1j8k83VsrSWYTWV46pcTHUH9L\nhhQDBFiIggMlf1cZSu5vBlf/NQuQROcuC3uXxivI63v709GnqkxE3//Ul702\n/44I8M/Wa6HDziVFJ7dRn6Or2iNHijRSiJh1B8wAH1fpL4ZpwiOmd80TooKk\nhn9bPk3f7PlHsWsxuFyJmYV1I+kHlk70uwAV6R0ZAR92AJYIXxNpCTgoFFhr\n4j/aSqr0CQqGER9ZTDKQMUodMyXNNrPH30jsUAixhYg6PqXupC4ejE6Cw9Wz\nr/mh+439mj2kuHNZXiqT6hEiWuBqCcV25jwc/QiOcPEaU8/Wg9KjF15JM62f\nilsrSbiXiUSjAeKaw2S9Kse5p0fJHGxBlN6CCn8mpF16EfrX1ZPHYi06t0Ne\ntI9ofDTpQ8PPFZAyZOcKf8vLDks5jGeL8uuNsAj9boibAIEsWH3jwk+O6MES\nBQyH\r\n=VaqZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"ce753649a437913f1427556a0df532119ec51ad7","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.22","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.13","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.15_1641297947263_0.04018715191038402","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.16":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.16","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.16","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"69e8946207c68d6ee872e91308e3b8a91c8b2ded","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.16.tgz","fileCount":22,"integrity":"sha512-ScGFC5lGFMWiQJf+EPY6RtgvMCOuDajy8O+5BdzDFtnW9DLyDvo6aqjHyfDiAFmGbPaSWFjKLVW6i57fKdKjDg==","signatures":[{"sig":"MEUCIACyw6ZZg5DkGrIQEUfwxPciYGT5kc0WsP7sGrQg92EyAiEAxWqXn/VYnWLrE8w6+QhqvaFl4IuuBS/jFEEhFsGjKX0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1341421,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh1GEDCRA9TVsSAnZWagAAWlUP/0yaCH2WIM50TL814Q5I\nLaVlogUoBWcZLCfWEOVUG6nspHj9Wz07orGiZQ8K3yh9RDUWR7W19moxwlP1\nlzWv3VkAzXgY0m1zNd9/UrT5CSk5LIQCMq3SwiUAqCnbGSrTzFkRgN6fgR9t\n2N+jWZdOr6gclZURE4rkJ2AbAqgyhOmMd40lfmOcjlZmd79SiEPKhSN9o3Sa\n9e/QPLMEtStoXHgpg5jXPgLjrBfC0VTHJy4dB1IksSRoM/dAAN7HyE/ccRTz\nl0JSA2oPhdUXskQtj+6fSHLMbIy1yLfy1ex6USvvv/yIGmoCoyeOaja3SE38\nyscMyECb6fGLZJstsz90dBVEmonxLB1bIetWRfdBJ7IIRCmYjXGJst/qMP5q\nZMXMoKDGx1VsN77HcCmd8RgpY3CtOViNqnjub4bn7j5fqDBjo/WP9AxjKJXW\n58ZpPtZsTbokVc7XMSRnDRqeO0Z0T2Yq6xKAqgUjZ1g3m4pA7IaLioS0TqQq\n4M4RZCKpfOKk0wquBX1gh2tXn7fAtoJlhn3cEGQCLU6HBGMJUYGa4ND69kla\nYu/cpWjPzN8XuNARZYkWJPTML2W0gy8qmYyGhnmx9BwDU240ztTk0tUyThGZ\nUr5vkQ1ceOAsZRmoJU85rK9f5kfZW6diixUkdu+0oJl8TJw5Hf0N8/qpg/nl\nEMDO\r\n=ezRR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"ce3d4279426028b8c0a3e0b755860b92d2ddd9f5","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.23","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.14","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.16_1641308418756_0.29928921737312075","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.17":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.17","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.17","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"4e1b8af3109d7ac3a5de3ea1ea1b7f83b346cae9","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.17.tgz","fileCount":22,"integrity":"sha512-feH7T39kZgEJmvSRYiAuCDFFtnub8XgtbM9aWKX7yaUfHCKr1sqrkMWJoHmz93KwNRvXeZoez31YqhRy9nQANw==","signatures":[{"sig":"MEUCIQCY4E5ZMZBcUcG4mZeBGH4sZa7ZwdgMNSjAsXzI3qNYFQIgXtPxz+CSdamtjlAAnjaZwjHMWdUw73zns7w8huVHGXY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1349056,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh100hCRA9TVsSAnZWagAA+p0P/3/81dZcn8Li9mVBBNPs\nkaP2vc11gvwalpN7pweEW6dNnORlBry56y1FRsoMaHvU5/cyZItOiYKH5VLU\n47FW5wRm7TAv1N98cAlHGI58B9Nk6w9h+D3o+7mcJ6rufrVvrkRupQYBQnkw\nn+f9FZL61ECF7POBamwU6mC10cNHBSEoixz3eaLci2cYYKkZpva628FniWH+\niMPzXAem/4TO07I0nw1abnkQXpbLRbIdzRDSS8E6EDCP80YdFcJtlXLyTCIS\nCR5x+2zigcEBMHd2yCywbvHQLQ5J9oxsCUIyRHL4UqKLY2aKYuUSTP1s/QIU\nuldIiarasccZ12BzWAl/f/gNHTKcAu0KxcBwzaL8Uv4lvwc18C6woR27zohs\ndRLiqwZUW8zGQsIiKQD2zbauYz8W2a+DCNDXF+nS2hTNKqLeHS+GXRPNjkOD\n1FuToCae727NeS8XvzPkeuKJL+8q0OvXXH+71NW204y9qyVd+c7LoQQ5sG5t\noagKi4OygxhascGX6ZTXlbDoqCPvY/mFOsNQfykpt2k703I6GnwLdw0IOqn2\nn9TCkFo+4QS7FCRi6oPKMf+eOBagcGLVlzvcwf/rRFIJoQRKypMOVVeu/W/y\nCjb3IZY3cTgL/xF5zSKYeVfmvnGglNE4E+2tals9dLHv3AgpTDm2THZuFcyN\nOXkw\r\n=7CKE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"c8d96e5ad470cafc81abf0569066a1973eb5b3d4","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.24","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.15","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.17_1641499936992_0.9525663822869672","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.18":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.18","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.18","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"c145d1ea1cb54766599d6a866f6a0ed7171744ae","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.18.tgz","fileCount":22,"integrity":"sha512-nuQ7KofTydtaaNIMC0dD29pnnWI4EFNAJacRaT/MuNMYiGWrnmL4r7pNm6gq9Qv/XRhOeQ8XCuF/bvZCqJ9tRQ==","signatures":[{"sig":"MEUCIFtML4sGBupdnRHxg3T22uMjSerBsu0nbro7qHCxFQBXAiEAtWQRFLLZjechpmqkeZZF28iuns5O002vDdZxsGAhfJg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1372469,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2H8ECRA9TVsSAnZWagAA7gAP/0VQBRDPCRoI+PiOmgK2\n7/SN/0WDN9RtWC5xadvT6i2ZigPLC/bY2mFQe2sNxuzD0+UqhYnfaD4GcmqI\nmDumUxP/dEix4RTioKqe0+o115Wnp/JRUP12qGINko9kbkWHl8B/WgEgbejd\nhUrgmCBQgKcL8olcORUJ14S4i6vSJjHQpkRDzHw61/2TJ7J0rU44Uesb/gGh\n5R+06qtn27CtegBEBPuF9ehpYQduFgaGsQYNjeHKAhqrkGEPLqVERYPVVM3z\nc5ejQGXSXkiMSzk0ESQsp2NaVJ1uULl5kvCj040bUdMM9MUZjku8ObPVqIpv\nDgUd0LHdvLIfL/NaiGcNteUR5o7crVloxnVZ1HPWfHdCP8NijZSGnUaBX1Nu\nrAQiQbHbaoUR44c06DaAJ8CR4LFgKShx1OEjhB5lv49jaj9MuOjXVEpbVvNd\nKkPek4IY+YssL7CCv58Klg7heq5LO95NbzHnZCREvqgosz83pSQtnxa18CoT\nRsCCGZRleKqQbalna7HlyR4qAXzkyUoW4VmILN85XGBKu6Xyej3tJtkQRmrr\nB5/JJAnOGe5LQppTmNaVvmlYsnmx3WEpk7aY+nB4PEm+WhSdKg/zfMAhSLbH\nn0odId+6dh5EQOX2XKOXG4BlalSEqB+7o33/Al1Yqd2Z+OeJlzCzyP89pp2q\nKrXl\r\n=B6o+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"35c2007587193f83e17538d1ef30a4ef8f693212","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.25","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.15","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.18_1641578244053_0.9124885155212872","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.19":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.19","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.19","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"5e0ccdc98f85319b87420a584818e80f7d0fda30","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.19.tgz","fileCount":22,"integrity":"sha512-6SIlskyceeGYOXQjaWgyvGdwcKg80li8eE6Uel9CiQL0pNaDZv9IJ9PL642y+mVtd9YYZDnO+gWQSlM29U8GNQ==","signatures":[{"sig":"MEUCIFI9xl7c/XdDCQxVpps7aex2dTDmV0/MqsrHHmdAAaTBAiEAl253wU5sv9tUIIXhjqWpTSVzOeY4ANd+IzX9Wm7dHIU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1371581,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2aCYCRA9TVsSAnZWagAAqeIP/0b3FY6HUieMms0CPfTg\nccWAU2uTJzRgn4myy1UZubeFJaYcuB+N8OBGzClvyhRRGjCdR8OuzwRB+z4O\nenllwA9w8/OGjh7ssJiCMO8saFjlYrm3HcOKwVKHaHYsrjE15oCgoktKK0JE\nV1lzoDUK4uI6JUces08Fg8FP1Y7m6oNYKOKt/RXdsBrZkiFMpLzOMq7Ya/Fy\nKhBNvRReN+p0164kyeCO2YuKHE0ZXqusb+234y4QBbvAv1yL59WzSPdTvgVo\nHpdxlrNhavXHUQIcrVlAHUtTk2Qb0rHLzm5vuwt/6NLbWd2dDhomjn+c9bdt\ndmXSDprubOQ9lJ9O+W23/UeT79FakcSHqT3Gi9JvFdnoZuvC5gCiH2dRqDHT\nhJnMZyQjby3ncwyPoMIFu+99PhdZTgcOajIPyH7M2D0uC4zIdqncvjGc1Sg9\n49FHkPCfy4pmpDmlI7fvlj+eQGyMzicqZWwqlnwv0R2ArFy1hRnbIZG3VELr\n9HmPKzsN+XHnHWuDpqYYMciYcPFsvKkd3RNqBQgi/GJRV6HUij3aPE68CZQt\nOVLrhI5z+vYcqwuzh6n7wL3O0n5znDxexpz/04tYIBgFkv1BfH4G7eR/7UkV\nQD03JKv8FizTuzebrRb3Mlyl6qL4p+XafC/pSlc55Y/vdlk6d4ihWzvJSUWq\nWbwj\r\n=AanV\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"3e9611d83ffc6d1b5653a010695d3193d203e302","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.26","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.15","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.19_1641652376776_0.5886019866030452","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.20":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.20","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.20","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"31758c9ccdf01d20fe256a7897aeff6675140d78","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.20.tgz","fileCount":22,"integrity":"sha512-MRQMf5DOGyIuf628tiKob5b8aXoER5CE6jmZC2KafjlvrYUmbhJOaOX+27IccryAmmFAurvLGaofl9nBFYNErQ==","signatures":[{"sig":"MEQCIDbWWJfSPiR2SjUp7vASPSt/90mo5Ji/a+CRNPVD6LunAiBnirM/0K9Lp5lN04N4FDef7+Eb38033vfKS5VEHerEqw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1375219,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh208eCRA9TVsSAnZWagAACpIP/j/xwNrbBww5ZWT2RdIA\n6mJcZfbMPim5J+ZZvEYZeeHjrZxF9VlCRLKUuzGFalpW6eNCJu+VD7U69ODt\nvG9nYOK3veYj1/WBJNXnQsVDRfuRSS6LQCDO8v1P9VXlzK3q8qzjsOVOtZhH\nXU20nBbk3mdXhAVmFCmKhe5d4N2hVuW6RbwWyCx3idIQ0EyGqIRc+Les+p2B\nklWsnBNLPQTU5WqiOmZljzSve8HzK42jCJVfOhtdXJ2/EhSEgkCD3DRoN5v8\nORhe9KGoY+c3Uv/3NC3BrCqKO9DyxtBIuWkW4v7uYh0wJbOHYnVPM0U9Irar\nf6f6ohb9uNWj5i7km9stjQXE0OeTK+B2ZMCFLb+4wn1z/3Bry3T9oMSHAy/9\nA9Cl4rv5UESeGyUpTZCjGh06DbQopboxzCUaz+yNF8eZjbhvDJhnA1pw0dUc\nfeEP6OCOm05FyxNde0I+ejuxl8bqXpt8fNpqR+m8pbN4ToUUKCDWBiiQ+/0O\nFDOsxSu/na85Y0Y9Y8OXLKCfif0npWPzfZEHHMN2gQJfPBbRk7u108Qcx5kb\nh/itj6vj19Ih06MPifrPsATg9LCSVblsbS2QZnu90I9PfjhJVouLM/e+mxAl\nmzQgYbet9nDwbQuGlybno6TVolzijrGBHvkBOnYWZOUFLWxSs2W4hv5jj/+C\nsJnK\r\n=wMaJ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"21a02961c124a5c2723bdbec90f606a6d538e32c","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.27","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.15","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.20_1641762589845_0.6795196070887621","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.21":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.21","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.21","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"8cf0913c6124a084a770f0e26b45cf94ecd95329","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.21.tgz","fileCount":22,"integrity":"sha512-ktY6Q3I+cEqRMYE8eLjJI0HRkXKqy2SB+0mxEFrYHH6cqyDB29RUXhD5zkf+50U/Xh4XbUMzOqWCZMrtpjQeTg==","signatures":[{"sig":"MEUCIQCLodJTLk39LRYukzGQyeMNdNwBPfUVwJcZJi6m6e8jvgIgXLOkh/meiEFGUq48sDRjhfNLzf7vSQpvXGEC1ADss2g=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1375898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh22HPCRA9TVsSAnZWagAAot8P/3l1MlhMbYlq6n970li0\noks22VEPXGav2hXB9Yss6MNZE01yIA/ST1rApDl9w5/2WE9FWKEmgW2Nje3r\nHuQCQY/68SIkWoaXVRWUgmsMzK4mufQoAmsxvKNnC25aEgvknK35aPInKGx9\nqikyoCq9zX3TrL/6eJzzhRtNhiGKoA9cBwuKxzOn29U5IUV2wakLobfQbly1\nF5+a8GqjYTzrC1+4F15mdoWa8tU6HctksOj6LDJJJuBBlvOOpzvheSmxlEAz\ndw4XQgfQac6A0icBQerS5jHprwqiidRrnkGZIhAJR/C5yycNqYlSqm3wBUT8\nscJ6mJvMdxozIQ4vWgZca3gc7BCcliDnOJIszq613WN5q4Df5qO8hPkNIeoB\n8XepCNosipnn0Ou7B+hQZ1uXkjgeF3Zit/ccveBGHPE63ajAZ6j837RIs6vc\nNkYGGHQieLp2rwLqfyB7gGN94GxXMev+pCfNPUdbs50QOvfGWJt23GHZcou/\nwTL0i2hbBk7RwEUy1jTzOfWqbdKiWmp/Ra4si1ZHtqNZR4VfnUYBUpHOP0I3\nAc0DQVPMb7xB1JDCVVJK7YhHn2DoBPZ1O2cmXDC+hM1fItEuHfqWHXcTSGyd\nI5F9VGMmh0cLh+DE9chI+x/llA/OC2OWaD3OrIxxsMFPbt491X1/c/2/Xn0G\nT8MN\r\n=+G6k\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **dexie-immutable-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **dexie-encrypted-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **dexie-rxjs-addon**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **dexie-populate-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **dexie-class-addon**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Highlights of addons\n\n#### Dexie RxJs Addon\nFor now only `toArray()` is usable on a returned `Collection` from a `where()` query:\n```ts\nclass ObservableCollection {\n    /**\n     * Get an array of the query results.\n     * @note For now RxJs operators can be used to achieve the same functionality of Dexie.Collection.\n     */\n    public toArray() { return this._collection$; }\n}\n```\n\n#### Dexie Populate Addon\n##### Ref type\n```ts\nimport { Ref } from '@pvermeer/dexie-addon-suite';\n\nexport class Friend {\n    id?: number;\n    firstName: string;\n    lastName: string;\n    memberOf: Ref<Club[], number[]>;\n\n    doSomething() { }\n}\n```\nWith this notation we let the typesystem know we have a property `memberOf` that can be assigned with index keys of `number[]`. When population methods are used, TypeScript now knows that this has changed to `Club[]` in `memberOf`. If a Ref is not found it is `null`, thus the result for `memberOf` will be `(Club | null)[]`.\n\nThe ref type is a (fake) nominal type so the type system can differentiate this type from other assignable types.\n\n#### Dexie Encrypted Addon\n##### Encryption class\n```ts\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n    readonly secret: string;\n    readonly secretUint8Array: Uint8Array;\n    /**\n     * Create a random key.\n     */\n    static createRandomEncryptionKey(): string;\n    /**\n     * Create a base64 hash string of the provided input.\n     * @param input Any non-circulair value.\n     */\n    static hash(input: any): string;\n    \n    constructor(secret?: string);\n}\n```\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get populated RxJs observables that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nFor now, only toArray() is available on a `Collection`. (*see above*)\n\n##### Options\n```ts\ndb.friends.populate().$.get(1); // Fully populated;\ndb.friends.populate({ shallow: true }).$.get(1); // Only the record itself is populated, no deeper;\ndb.friends.populate(['memberOf', 'group']).$.get(1); // Only 'memberOf' and 'group' are deep populated;\n```\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n##### Compound\n```ts\ndb.friends.populate().$.where('[id+group]').equals([1, 2]).toArray();\ndb.friends.populate().$.where({ id: 1, group: 2 }).toArray()\n```\nAnd more... see https://dexie.org\n\n##### Can be used with RxJs methods:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption {\n\tprivate readonly _secret;\n\tget secret(): string;\n\tprivate readonly _keyUint8Array;\n\tget secretUint8Array(): Uint8Array;\n\t/**\n\t * Create a random key.\n\t */\n\tstatic createRandomEncryptionKey(): string;\n\t/**\n\t * Create a base64 hash string of the provided input.\n\t * @param input Any non-circulair value.\n\t */\n\tstatic hash(input: any): string;\n\t/**\n\t * Encrypt any value.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to encrypt with.\n\t */\n\tencrypt(json: any): string;\n\t/**\n\t * Decrypt values.\n\t * @param json Any non-circulair value.\n\t * @param key Secret key to decrypt with.\n\t */\n\tdecrypt(messageWithNonce: string): any;\n\n\tconstructor(secret?: string);\n}\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"6c73be0b82fcbd3bc7a834e62e7a420c7bc17cb9","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.28","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.15","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.10","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.21_1641767375063_0.27416471072363824","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.22":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.22","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.22","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"451820c649145f3a4664bbaa926714c8fcf38ce6","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.22.tgz","fileCount":22,"integrity":"sha512-HkWbV29wlDzlQp5YB7ZiEv3flZqkp9AqDrjlir9mDkX9GzcbL9ha373j0LfyOlKaSI/8WJyAFc1KpUP/2CqvIw==","signatures":[{"sig":"MEYCIQCNr176wmk7tNf3Jg9uGJZdkGifRG0Rs+rfOyI2PlVgqwIhAMstpqRqUmsE+GllGMH6VUa/1v/qiLYWXSOx6VdzRfPs","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1380415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh6uopCRA9TVsSAnZWagAAZFQP/j65yuT2FWL8cE9CJu+y\nzTQdkxTamxA7fgcRVs2zOGCozIfC2pBnAzW++dx9xIYAShOlTfnfmxKBEYQx\n2JGAWeEwg8jyhYeSoGSoraVINRMsKVZoD34ygET3jqhlf4XiNWBJ+vlffTeN\nMbmepSspFdC24kXudh/vJL/WGcaI+7GXHvwifTPzTFHI8chiNRGjJk+gb/Qr\nH1cBawCiTt06rdxkt+ysV4++l/APN2g/KeCFPM3CKtOfT6SOP0l/cg+yXewf\nRkHFTaZoEJLvlzCQyqhNXmHVL1j34d2R2BNqf8w4CHt7o811WqAL+0prvdcO\nGo1ZICTaNGdQtvxU0ZlHHT2fjK6EtQXZgMUaf+Yrae0q+45595VMBEqjcTTj\n/n5CyNpPxDGNYahl9Fux7fBUwRCnK3lUIhMYRweuhxnP+uH0tnsUUu1KXCf6\nY67ftwK17H8Hv6aeE8CjOIp8pm0B9oph4ByLDkmwroPegm1T6izFtW6SbMWI\npUDxcxd8fog3wN6cD1fZqR55v+Sksn+a2Ah2jofxLtAS6sfOqYyyxlulcGJ4\n01MxTJspJpUYXVjttqWDddtJO1QnXM52DIC4U6vF1Fk+LIj/RXebTT0evw+1\ngtZ5SaSRS0rfur2eQ3NdJLphF8lk8cIsSie0EXzDpnGd20fsk+zBhQniJWbK\nyJQA\r\n=jxS5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"2bca9b30c31a703238ac9fd883f844e0bcddfca0","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.29","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.16","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.11","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.22_1642785321488_0.9203305562195823","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.23":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.23","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.23","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"aea7f76b06d7a3524f081359b0b57321614d7229","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.23.tgz","fileCount":22,"integrity":"sha512-hG+rAQTxtAHWnnSbiD4bVO3mYoRXk9PLVk4+QPNoj08uSkoNme952MZauViJNHEf27yu57IUVD5gBFFQu6hkZw==","signatures":[{"sig":"MEUCIQDSXN3o+dCHZmn56TN69k/s1yxpuzSA0nm2sAOzRvw3OwIgdTS7QLsf+TjBqRHR+RdEwjmTqIaOQyTuWPN0Ht76aCs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1382930,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh9VwGCRA9TVsSAnZWagAAYxAP/1ZikJ0Wf2jV5AGOOrqj\nYCvnW25FD5/ZsvRUiWFf5q627x44O/reVYdMHfrR8OVQFC99OvZtb0XgroXp\nW/Kl5oeF+OAZTkT4YZmunWtj4p+uAnkjB26hRIpjYgp+zxgx9Q6VXVOWQ6j0\nAeSLYdHouFohhHSRGv5xiPj7XK26WFXKRnVR/qY7vtqUCZVgQ1+5oZlUVmm9\ncKbRl4cex9QgHaDy1YRx9cbL2eIWs/ONFwMdc2+1V21GquPH1fy8nfSrpN+A\nzEgEJbC72sj/NfTmlYtRxwaoigcBQmK7Jmf14ESaJkKTbiSEvN1lSbIarzlu\njMNodS7PMafvXqCETchIlOxA6EKF9DNx0HSu5YIiOVzS7ndhSqU5rvtZefTE\nmLzw1+X3DtDXqYQJLxjqalr0nSQ2ZbW+DMAqhdSFjy4Me9IyvFjPpFWkuHCv\nqlMORUWA06CKILGpn3NvFNYgbtSBwufNPNnwpsi3sOAnwntejqmL7Gzjny0x\n/thig9gXRBNseHofR9dqiIoJJYN9YuLQjlVikirRIXLxDd6kaOQf9HvPN3Sz\nblETem9Zvhp3q4G9GIcXK8/CtAgpeu00AMbtNNwDOZx0AAwStitijSgewdCc\nBcyo+R5yZmPluoWPWmriKRjSmeifWdIQbRfYEpp9XwAU7V02PdOYJHRt9WSy\n5yu8\r\n=vJkE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club[], number[]>;\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\ntype Ref<O extends object, K extends IndexableType, _N = 'Ref'> = NominalT<O> | K;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"8b66191c8ec95af9955325fdc4029e4818735f1e","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.30","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.17","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.12","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.23_1643469830256_0.9518770154631884","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.24":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.24","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.24","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"740810ae48fe1da908d5ca4dea729b88a5ea4406","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.24.tgz","fileCount":22,"integrity":"sha512-2HUpEdpDKXKixAxahhug5BM88LNu0L2F4kGkQmgBZbWEsNA0GrWikVybT2YX5U7BxWuN7Bv+Eml2wi8YOSEJ8Q==","signatures":[{"sig":"MEUCIQCn8HmSfwe3JQK1j2jghG+qobYp6RfLQ1oRZXEhGuS/6AIgCcbxYHxUIn6FBZNsqO6XBbLKKvOc+GISwbHUO0OZNjs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1380858,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh9sm0CRA9TVsSAnZWagAAz/wP/RRoqgcdZiQSVeEKRxJa\nc1jOeuYH4rihmKb14Blbg88USpqi1+FxudUV92gMjx4MqfzoGoF8LytEdlQa\nLQLDefugWoJCLQX4NUl1OKm9FNApqx0+Ma3TbXhm2Xfi/WB6sNj+2uEgIGaW\nuHUBmkczlrxPNUPPDcV4wASCcjAusybNFqeEySlRvd3efCXXdjdgfziTurJS\nUN1AoNl2fOAhxopizE2ncFrKWTJE3+jkXmD7Xlax0ig8QuvIF08pj7N1FQUk\n5rITZNz4s9CSQqpgf2wwrK/PfLXtBTKG1SUHs4tMCkKQULNuc9Sp+KBNOdAs\neUvaxZ63nu9q+382YRzVFh4jdSDMjvXPYYJ7vSEfzn/5P0qgCfi5B/x2nxu5\nFOhdeHKg3fJz0A0oDibSJLjDV6Ght3fMz7cx3gRELQcP0XmKevZ6hjGR2Res\nvxX02b2Es3aEcFQ6HJdMd0YCNTdPRbW4b1BRhFzUI7cbpWgIemksX1MLzztz\nRQdxG8uQcpG5tS/DT3Mzd3Rjo5suKwR1I6gcj2eCeKDw3qZ9gfB0TqDlJBP+\nSzbwSfqNZ+4i8oJHU9xBAgNtoZXHKwx58g5Mk9+z7LGUp/XQwyEOEjncsxTH\nte1b2IlFMZqd9c36rZtDxuXlxUg1AIDzCOqJAdVZkWe3b76Snpdjh2lJ9IiU\n/SYQ\r\n=ckNx\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"42a83cd8200af4c3869e739617dad82c23a2623e","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run build && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.31","@pvermeer/dexie-class-addon":"^1.0.0-beta.3","@pvermeer/dexie-populate-addon":"^1.0.0-beta.18","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.12","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.9"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.24_1643563443825_0.10889997359951842","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.25":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.25","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.25","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"b4f1d0c899103c8c940c307467be98886a7ee24b","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.25.tgz","fileCount":12,"integrity":"sha512-PfYv9IuH+kAWGN3cqxheXYmJGvJiPIZCctZSz1AYzWM4EqYaBAMHSDTEHGMTNQISwR7siZ5gDyyoIulAOUisOw==","signatures":[{"sig":"MEUCIQDdT0RyQo+6m0Jqiw+sfH8vK0cQKWl7p9i0OgIZnbqVGAIgDFYViv+XWNWakr14bpb+fB9noaHHp6mj1Fl5OzyuhfE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37180,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+BKBCRA9TVsSAnZWagAAC1IP/jMHo7nsv3SJPSfHxDhn\nJ9aBGC3AMK0n/Dlt6dI5icxdGwIpei8Q2OPz8mUrIDD+ZUO7o62oEZgUNLGd\nI3nKkPPSblwgW2f/5o0U6ToC6U4xyBHJpgu9gJ/jpAp2e1tod5wplreUnAzG\nFKkcFPQlv+Wqv0yoBRllxcGOWORwvwqihxxLbpRs4kUHup5CPndyaNNraazm\nF5irI+tFrrTekHbEG2WGifGKlK7JYirTKDmUM/emEaug7boF+np5JLWaeATa\n68vP8lJj6HawIhwsP7pjMUaVhFHs0oiRQmoBu9rmys7cHQE52llq7alVX0OX\nj1C3kqTMB3ff+tMnymakgke9/csf99GlEYhe8p0MppOgbEVwdLuZ685Gs5DO\nq5PflN9GLFzSJmP656L0o8iIhfMhzTQIhZpZfPAR8ebhHzUvyi9PkqpcifhN\nqK7P0cwRegZrSuOlovHalB3+fb9n55U3RQD/Eo+3fso9mwxL7WdW63W6IIpr\n6rnpd2gcy9oO8XGt1sRQa6b/uKPWgoXpo9bB+J6L5NJYsViODWk7Hm1C9cDW\n0iG1SqNAgRbphDpJDmt+z3Guxof4Q5WH9n+ji4h/wtkYFtjS9xdLnZMBhLaI\nt/xWide8e3QCTwHVnljSz/beknRcOdBinIEgZZNndOoqX/2OPSCdndV7ZtXZ\nmvih\r\n=uIOq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"c1bc1930d1b59b86a4f059fda625e787b19f14ef","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.32","@pvermeer/dexie-class-addon":"^1.0.0-beta.4","@pvermeer/dexie-populate-addon":"^1.0.0-beta.19","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.13","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.10"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.25_1643647616897_0.5915831659857924","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.26":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.26","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.26","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"5db6e3ce24f249e3f9f8e3283ff16e824ca18f93","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.26.tgz","fileCount":22,"integrity":"sha512-SBImkyRmGgmvoQ3agtXsWYKW9g5AeIsGwS6U7sdwvbSd3nTSdSyoAexc6JiKP8VACBgrbc08RFP9eOHWL1QJpw==","signatures":[{"sig":"MEYCIQCQyFBcJJYd14sFT/T7w9ff0/ykldxM7qQZlPR1/TGprgIhAOMtlzm/8E+6Snnn5INkENxry1UxbCNgjrF69lVVVALP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1381181,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+CJUCRA9TVsSAnZWagAAvZoP/iwKqZa+eQS70vIyztnZ\n7l3WnztS7Vw8V68J5W72zeDK71sLq97HGua8OlK83Stq2NzXR0nq2+uJ01BI\nv+9ByUQmglt5reaJRHerlRDhLJijSDIYmuTlwRA41y2NzssdVmAKWzzGDhzk\nwOTiPSI4shAiA+5FxUOAwhg7k/VKog8eRa8aY2iQxn61snH/N6SW3uFQtPn+\nYtNbmQWQhnMUmBeHE0EHxeJjT43+n4NrIwmJkApONfqD0UHJJhE13jjjYiyk\nKmBnuV6I74tSiAkDd3K7ehpGOkB1KJ0YhmeHsOeH2Mdxe0zmliNnzdaUmW51\n5P9MTGcxu0kfZs0FMbrSZyEXE9EKiUfMDcRgUZr2Q+Q7ouSVO+cOJS2vPJIp\nYboaboKxB3tylqFte0600T6vplObYNzAV0sRkRe+H2TDg8X6y0Z+JR/7GgKn\nczPZqkGUmjpux8i+605Y824VIrzsPSgkNb7FhzeyBfNe1wxXhA524BiEx6vy\nb1tuPwjEqZDaiMTTCuNubfNUFwi8mhe+mBnEln7Wn0RxfKSpoIOYJZU8MhUI\nK3065Y7Oi5CcBLpubWH70GRbYKnpp0tCIUsWzPx6JqDlCvfawrXnigs1DwRE\n95uNCSnZtxmxZuyUO0L8Rorhu/sjlHAR5IY4XDLVpI7nDnX34gI+bi6ho/si\n2TPG\r\n=aaO7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"39fdadfbc48a62478b29653e6ec8aa561110bc57","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.33","@pvermeer/dexie-class-addon":"^1.0.0-beta.5","@pvermeer/dexie-populate-addon":"^1.0.0-beta.20","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.14","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.26_1643651668588_0.1611575809424146","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.27":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.27","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.27","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"393d7399c1a1c3415f95a59b7773239f0ebdc8e9","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.27.tgz","fileCount":22,"integrity":"sha512-b+slwdTMnljn3bJn7w4QaKmxLVoixaNwhfKzBoIOaN/hTvSXatdJxjMSHqL4O/CrFj+ZPeKUsnxKGwTDweYDiw==","signatures":[{"sig":"MEUCIQDQY5qzvyFPNOExgv2Nz5/FpF+VzVLKYHh0ti0MV0DOywIgXSmseKUMbOE6/ev6jW0kuJQizt+OdfNN9e8I+IAkE7c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1378958,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+qUACRA9TVsSAnZWagAAuSwQAKRpRtNSMZdxz+cAJwKp\ndm99osT4aLfJ4ZgPFzmD1MFfKJg4PUb/hGUqdRkg8a/6a8R2rV0sULdKIyyX\nCxVn3UBUDXXZB1b/lwTQhttdZWf9QgZSpRfSSjMRkzxBg1ro2LgQ7zhYPaRP\nfAdNhBZhjNCRb1nZSZmSv1Rb0LmcyWg9Jls+6wC9YnvXTgqxed4QlsjMpev8\n5ZpantIUIYZ1z2p106NlSAWoc+OazVt5A0ukZKEcHXqBLXxFbHiq3un5FOKQ\nwMDl0rBsK0eWo4RZJGZEybgdzvoByJfT/Z/6DaNhrduytfRp7axx/FD5TMig\n9CC4ZRA7LD+O5eqnfKjCIgJXWFiNDefG8W4ylPf+jANuNt+MmPIB5uuC4PBa\nTHOuwUconuIDuxccqZLWUa7aGhtc3IKQBgOplp8eJxNx5u5y/VbMyK/Vhxet\nuXwTeRYEJgX6T7Rx1sUp0jKoUFt9LztIarFYzf2lodvd5Teq77wm9onjNTnU\newWu0WOHSwSJjVjQ1sCPkatIoa4cPS6UcSSL/P4hgbpbyCxlYMUGLxUKjln6\n7Brecbj8I1EOyaE6Nv1PfrofGgQz75EckCptwKyDvh1F5NdKcgIT57xwZ6jj\nmFc01HWh4sD4i2AhzvVZyxmb6Bi/pORbFBHe55Zbo5zH0KEVpzLkCUmA3Etm\ntTor\r\n=mRmb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"e6120d385bfb46e0ba7e2768321c541d8c49c28f","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.34","@pvermeer/dexie-class-addon":"^1.0.0-beta.5","@pvermeer/dexie-populate-addon":"^1.0.0-beta.20","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.14","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.27_1643816192326_0.6050254666725239","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.28":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.28","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.28","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"d041e62cd15331e47c4eb509a703b895f43eb480","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.28.tgz","fileCount":22,"integrity":"sha512-t487N4+iX/laDCUnb9jxoedY7qjPAiRF0D9QblJQgTIufC22bd8Pho28mxRcUaH3txzl+p4uHdhtvval/5RWvg==","signatures":[{"sig":"MEUCIAfaIhpVvST2KTl7wD/4HDeSMYHHtGkn5luZBakvZw5WAiEA22pvkjgic+5KIL0c/f5Hurp9KRXCWldeIH+DwRFdllo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1387879,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+s//CRA9TVsSAnZWagAAZkcP/R4v9EmxP2aucdc91SyJ\nz6NquT4hOunt2CgaZ+LI0vTm5AqkMc9KMWvxRdTd3uqGzjaGf1GQcRkS9MFH\n63bpZBQvYVEtsT8MLz1cn/q3JH1cpKFlvTXfcZXjOkW+5LvA5avZmDgqhBNw\nmDdQejoonHP2IZYtAhVkmFN3qwAgccH+qul8mxDlxldShAMUiwsXi+34S4vh\n4t/wB39D8goI0VBuIXtWWUhJE4jz5GfFyWiXzDOWWCez7TLCMK5LDIW7DnVp\nwbmcBEC1noDf09UyZbik4gKhtV+AlQn+vVDPlbi1/UvcjefEEijYau4RqEi6\nn3XxGV1xjqGGSM1Nxj0YAl8bPJsiE0/hPPZb9F1u5oKPbZ4DYhXuj+aLAytr\nEi+ietYH6QcHLfKLPFvNIEysXgD5+KBZsTusocCFAq3a7SfPSh1vPrjgFK2H\n5aOm3pDfLw5GPmuZnnhqqzPEjMWPfAgmQ3EzRNaeWhIt7EmRYbvG/6zF+IFB\nnCIzfFS37m/rlS9t38oW2ptK6XoPjI5NJSYv5h9MGPUPPsI46e8n0bKJRy3H\n6PNtkjUQYvBZdpKugK81L3y9YCEFD/AVQMRnsdd9EhnVm/HEB6WuJCl9Pnkp\nBWEyemaB6dsM9Xe/fp4VGpjJb1skTx7mpj8wm2H4VyeD0u4WxxooM/UTKQ+L\nOWW2\r\n=CotN\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"47fafba3de557b6fc9208ef907656f90a97a5da6","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.13.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.13.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.5","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.14","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.28_1643827199780_0.8343836994551814","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.29":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.29","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.29","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"ab40b1e71b5fd98404ef0d9b7d364b4881870d6c","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.29.tgz","fileCount":22,"integrity":"sha512-Gt/XKoasArq00IQRQL5uAjk+UkAuuZsq4Q+g+5rHkH6x5SFpuzZSRfoHmimgo00lb7nGig77B7Vf3m4fMH4HVg==","signatures":[{"sig":"MEUCIQCxaA7U2pEcww54bKo8hkFdqIK3fdlH4OkXwx4Yq73VWAIgPiEaCyYzfInrcWQ09iGrcHBKzifzFUpK/fjmhkyES+E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1389547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiIL3QACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo/Pg//btXPcR64ePt873mU5GNOzEChFu6maG7nOfhtah2aTM+YpVR1\r\nR73BonWox6jKk8X1qXrIIW+6DZbVSyKGHkqiZKMXupLirbF24OTam4LUljWo\r\ns4QsA1R9pf8bd7EYgdujNXFtPegrwfWjeN06MqfqEVnTq/J8hhbq6pMpY2GG\r\n+6fx47eiHLdVJ+WyAcqYDKces20GtPDAM1zgPgyZjYjy1LWoLxu86xal5/ZX\r\n/bhGhHy3yzeMVK9cAF+ErtPIxaUqnrSzVWcEUBbkSMD2XdAhCBCwZ1HZsbi1\r\nlobMIGA8tmHjaxJhUnGWJPyjseEomm8jS3GlNh1cWM/CYt1bB8/C5PV6f7wf\r\nLjx42iL284ltMR5KLCMOQNsPAaPigVjOJvuRzRBiLQNKd5Qt1QPCbCJXCF39\r\nS6ZjEOQRP5zyz/xtHKmY/pV0dMhnvCwOGTqCqQpOFWS+PqjvM9W5etPKy4nE\r\njBHRtN/6upASHyk/sSUhP4oZuLRWObg7Agm5REP3EosO2QC6zPgFQTW+IAI5\r\ngNpbd8XG9LitCNL3Bl5v37VJyBcbmg1dUDf7n/WMDl/dufsI4kjLIpNk+p0z\r\nBafa0XAMn8g9f3/Uzayj0W8L6z0yKq84aGcROVS87wmsT1DLXUP2uz6MdkVB\r\nvuK4WrwjeUDV49Pve/zrhq2Iu+dNaEtM1oc=\r\n=y1zJ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"7250227ec60171e317fbabb5b49e2e2ddd8704c4","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.14.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.5","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.14","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.29_1646312912500_0.02214617804617558","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.30":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.30","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.30","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"b9a50f4c789ca9aa0df0201549895ded61f3f13e","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.30.tgz","fileCount":22,"integrity":"sha512-bVxSgmPHZ9MoA1YHemwxqAgggEnE9vc8j7BQvEsdUnCmFEjTfDEcCLqdsDruzYtBtXiGPqULqCrdS+JD+mzLwQ==","signatures":[{"sig":"MEQCIAnzGl9QZ4ma2IQt3t/sIStjngAegcxBnoofae++CJKlAiAeHQELmbQ6lxgNWSgR82Bj+FhHw67R/nd5RF1pPcpdyQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1391874,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiJ10vACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr26g//ZzgW0lEwTnp+I3NyeBWQZ2uP7wPyc3FX7UCFD8kXWNQ6y+Nq\r\n1zuehyDeIO6BwVQV97+rn4nptrGOE3yF5govihFKdEa7ijHfId9BpHZc4f+W\r\noglorbz2PQQ6jdgTPPxozf/AzejZDncRvD8eGoUJldjg5jJZgB9YEwA/r5OD\r\nzxOYWYrGIxdjIqtfQ9nGT8TG3IdaOukRluiloV6M+2KesxT4TnL4q/nphX+N\r\nFYIwcFguq7U41EfODlHAxLFup+6/LhQS+pZGVU6xLYuJT3gv/u7Ioxf51t29\r\nR3NGjgVOVuYNdn3Yb3lXZA1WxIGS5waF0/O7VYRgMybn6PbvnLG9ILyu+ypN\r\nM4KN9+aceLTCOxRgZ5ZwYsquFke0LESi2nbG/WIu5rGZGg+euou8tQZaoLan\r\nqgWgksH9Mqjg0izdHvj7b2kDbQQysjFr+QtuEpOB35psnl8G6R61Fkt3nf9m\r\nbNg1w1/VlwNVc+J1r02JBZvJ96hurFiPIKuPXovlX/+okhaT1PGnEdOrANOb\r\n+bwilxbtdv9MV9LnsODPshQ94JfD4EVZZjEdceWKJ9PhDRGNba7o8VSeqkjP\r\n8JzO8kxrtIehF8IBDtv1DkPrNU7kfcoPSTQ9RKDggns/ZuEsrzaTlihbleHS\r\n+w4uj4nAf917CV10H5m1xopAgA1fpVnOA9c=\r\n=gYWC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting a raw document\nTo get a raw document, unaltered by reading hooks, a transaction can be used while setting `getRaw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.getRaw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. So no Class mapping or decrecyption will be performed on the document. Typing might also be not correct anymore.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"6b35034264d53ddfb17c7badcf409de3032d0cc9","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.14.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.6","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.15","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.30_1646746927008_0.5959760841476855","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.31":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.31","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.31","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"663730eb302e814a552fb003e2f674c9eb437414","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.31.tgz","fileCount":22,"integrity":"sha512-brudOK5s488SZ2ERlyoY+bF0s8CC0mr3dZ2ZW8Q88Hd1t/0PAOBj4uwMdb+T7TTuv1iciCv6wF96MkepDNtEOA==","signatures":[{"sig":"MEYCIQDRWmfaLXzax7Wb0NBQ8sblLCA7tnmInRQNkgP6dWHUgQIhANYyH2XUVLpyX0ylMT+9GG75GEQxHDsZS6OmTygW1eo0","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1391971,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiKIsjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq64Q//VvEYuQKLVWXQLh9oIWLIWqjkI+S2LJGLqU/3GEcOo65QUcQ9\r\nVjChCRQ4vkNgkBuQOD1uOj6jGLuVXxglz++uQQSp6KGr7ndYc4if7HwVLlSy\r\nmJ1URAOdeaWhSq4TuxxuGBA0czVo8qi2y0zMpXxKVshB0BizZXesVCNarcTR\r\nBTfXpCbXryAPLlnTK1PYmySNDUJx1wy92PA/l/mtAZCjgNGC4dXjzH7IozlR\r\nuCKI05PgD7C5lwVCt/76BleFa8+mt1gEQelduxzquXJwOAkIv2i/UDFajrK0\r\nkWC+NnW/lzDEI9mMsfDTUwAT41/XcwM47b0uMw3k+N2w/1pcFyQiPhQtwEs4\r\nj5rZyK3FoLIywVtEGwYRFvIqa0/uZmYTD9fN5PGOgAO9PpQXN/6M/SS6kf/X\r\nuMExxLPE1aKsbSv5b4qfvt551BrV5J3yGEZciTj2Rt5sa9h7UFt9PES8Yw5L\r\ncAQaeGvkOa7t/XHS0RUUdcYJVmX3ykLNWyav6i9AdnvvnmIqfsj5OHs3/9OM\r\n28ScnB64ESgvuhk/2VQLQPB3Y6g7A6agLvSX0tCVGPf8YalZQWYmcoJT/dhb\r\nu3tso8tOl3dNrKXneLuQ3+m3oJyA2Ynq+ljanEwoPqCucbqznDrkC/61Sxnd\r\nxb/R8+h/NoFcAMcyrX9iz+Kc5bfYtlW3RBY=\r\n=H6Mq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting a raw document\nTo get a raw document, unaltered by reading hooks, a transaction can be used while setting `getRaw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.getRaw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. So no Class mapping or decrecyption will be performed on the document. Typing might also be not correct anymore.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"dcb4ddfe2c5ee94d32269513d7fadcc12c409465","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.14.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.6","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.16","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.31_1646824227053_0.7951121715802207","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.32":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.32","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.32","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"3cc61fda1b0a4c341e2bf0a332dd075ecef40e5d","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.32.tgz","fileCount":22,"integrity":"sha512-XxyMP8sJ80eWWBfEb+J0K0UaFmyCqwA3dpPuv8EqeTP3UrIjO6D9LxoyrHdhXgaM2dQbd3XhWnI4qGSmenkDIw==","signatures":[{"sig":"MEQCIB83lBss5fzUPzhFkeBBk1OEY0hAhCzVSTZ1jtgRDHCrAiBAHLUcBLincx4TXSLxqxdu1GmJBwKH5jv7AURq3084bw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1393470,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiVAKmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqxGw//R4zJ4AHrgkWGH4KcYRGzffh3nb4R1VlDLCM0XEX0Y/Aq8/GP\r\nfv0MHNdmWZR0Z92qbpNrH5GYYX9ltX2Uc+z1rM45mY+E4yHnbEUX/6t+EUrG\r\n611yAgsEnGhkJEoyStm8T5+K0krFirI4wgjP+2X/OhWflIgSxYryg5ws6cv4\r\nBLU/f10pVM0yHPkjoFWevyA5t5nL/1QgVn3wuS7kgX3g88k23bhN9isFxp1q\r\ncc9d9BzM8+ZfBsZgnY6ZU0XOHtienYjaWcSpZPQ8aF6aIAqb3G5GL4qD6kdV\r\nLa4YZ5F36YzZHeatIxm69mj5Wa12ECbNpFj0DzVXvv1lcFNIw69SrMdMRSzJ\r\nQO79eXJImS3216cxh1i3mpDAZEn68LfET3DU0KtSL8JdqWelH6+/BLSGf7pX\r\ndqSkzy27dCf5uno/0zIMyDmZd8HCvY76GbRAQIBBfB2RESTdlf8gS7RsYkbH\r\nwRzrjPfOEI4COBkykqWsYdhZbP7TiQYhc/FurzAp9JuBgy7Is9XWjN7pclfz\r\nmRRJbdqVfcnPpXpSlFDORAraYFJdabygxAwQW5iXJ9B+XwHQF3QHJOjfh5aU\r\ns/2rkOyFG7C3R/zCMwvDfFGehF1SZ+nWH6Cl3WI/qNFw2C+AyPrANqwg96yi\r\nLC/I5+dxaj2SPfaQFDpieayZb4rD1Qc/nFc=\r\n=2ndJ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    // For dexie-class-addon (will call constructor/serialize on read/write)\n    serialize() {\n        return {\n            id: this.id,\n            name: this.name,\n            memberOf: this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport declare type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\ntype Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nclass Encryption { } // See dexie-encrypted-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"da2ad487eec137d3e7c3ed6f404756ffad1f2fc7","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.14.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.14.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.7","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.17","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.32_1649672869764_0.9909951065631537","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.33":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.33","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.33","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"cc696a9b5f192a915f0546ee369e105a3c2a1265","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.33.tgz","fileCount":22,"integrity":"sha512-Gj2YHK02uWPJBFDLVtF13RoKAnbdMLl+2QF4J/0L99bvYsNZwcgARnEeKH44nwaSUiSN4z7oyyn37DmBuFcL5A==","signatures":[{"sig":"MEYCIQDJPYbeddR7NtS82qEoBI20dRDLrssik0X1bqfa3MldDQIhAOML2pK0xnQFZvcflDhng7OTn0VcyuLPBS7COiy88kB/","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1400328,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiXrYpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr8Gg//T1YGbWlv+r4x0NzKdTDb+XeUlfsMcO7pOGJpmxRzwePF1BPD\r\nsr7szdzNJD6zf9cPNfflBsG6uypXjCKX6yz3/tU5FRUuEaNh5ACRt5Hb7fWR\r\n9pB1fxaubhBrex2/7ZK/GoFm6PCDtOix3UhOFTumVTmr9+k6PdcEzF4JyP1P\r\nWc2BRGhNYpAwkCjKhWZp8/vrzZN3ryYeyS6+fPqaxSX4QddsUXDeP4acKiAy\r\nzB/613+o0fKnhMKyHrPiLrLN/kle9XT5SORVqjWFGyCa8r/6Fed52m+DfxQL\r\n9Vf4X739F8y4OrrK2d+pgXpe7WV1YewMJjabPOdZT/L2NsTBeG01KdDqvoeL\r\n66gPPt3bdkRxP51LOzXRAsRp7lprvV28uTTHeGeti6MZ1usdfqg1E5suYfrJ\r\nGLWjqM8Tv26w/5tHKAtOJrKozPO3WH0K7MdPiGsLxd9D0kao9JwW2Z997zSI\r\ni7MKhvr7eUwHONKDekmcaA0LUvw/HtW3KhpB6I0lTYahMYc680iNo2CI8NVo\r\n3w510cNvgqs+0fdcYxqOPlAdSzhRlAv5/TjF/ch06O8Eeq4OOOjLzfd6Njn5\r\neHgsS0IDu9mIS9e63hMspaOHmqrwMKAlL3Fw8Nyacz4ksrKokrJcYtgNRRhs\r\nxWdUMr5SlxeQRJiVp8ENRN+gxX7mjLhWIKY=\r\n=lxkv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"a8b95288734f490388f6bdf45fce72b4d5131a88","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.14.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.14.2","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.35","@pvermeer/dexie-class-addon":"^1.0.0-beta.8","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.17","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.33_1650374185175_0.8216628182141554","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.34":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.34","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.34","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"894ad144eceb396975723ed344dc2bfdb5e30d36","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.34.tgz","fileCount":22,"integrity":"sha512-1FB1z1yXSGVo+hxIPYs2dXqCBbsTf3/NqOmGtNZbO7IamzFUFmGoXfzDdrJn+1w01sBMlSxWuQJHTrJZAw84pA==","signatures":[{"sig":"MEUCIQD8J1WheCSKC8IiVQeS4AYXaWc5haU18SY5o/0koLglmQIgIC6z5w1U2j2zdg1FaAHCO1jagACGT5y1wgf9+OEf9P8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1470698,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJij3ZbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFThAAg+CWvTBZd41+CWiAKkUp+oUYxWg/t4gj7g1+tJI2bWOAxeDt\r\n3oOKYUjHFLYF1vDJuMy/E/WoPKK79ET0l6AQ9MHgwsG7MkG5K8xwNLPs4o6K\r\nY4zOSRxsYVy5//9Y60yYg5H3OIcFuEFcjkCymppaRGV3goxpjG+3YnCnrnnQ\r\nPkpxQUw3iO7rjHLPIyUZdKRzASPwkmnTMwcP2UjBz0mhTrxwVxnbIQbf9/Xa\r\nlclamsx4cTB28W6u+DO3ThJ7rBK4LGBNzIQycyNXblHgJA0eJie1X2daQBCL\r\nWPij66AHg1pYSaImYDymRIWBryYP4N/3+fp+wY7rzgAdGpTOYPT5/0WVhpKa\r\nEXoTFobO4TFjX2icPCMk2O4pUFYwJPK8hkbgDuu/r7AKmIia2pl6GvpLtl9o\r\nyHNDBpyXY03UvAWARMSz572DLF74gqQVvSjStc4RUOeHxBOv66IT5MyM6lfg\r\n7EVc3NYQjXnEPoUyr7UVSPlcYCrT1GaA7IBCzLDWKmmRN/2sP99AEU/88EdO\r\nD4gSI2cNfjbMZYX0YJ6ksw01tkwZOmLrlqsvjf5nSYbeKMqSYRP4JoNGAFRN\r\nGHMYAtldPI8uXDkRb/NbFA5x3mjRS+aqUAiPUfhqIIFByk7iSKF5TBecG3jD\r\n4oQ0vDFNEbMxP8JZPJIlQnoT1iDty/53VVQ=\r\n=Wo3b\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"efaed1b598dc0e4abb53af85d547e1bd053adfb4","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.15.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.15.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.36","@pvermeer/dexie-class-addon":"^1.0.0-beta.8","@pvermeer/dexie-populate-addon":"^1.0.0-beta.21","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.17","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.34_1653569115334_0.3592849591816414","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.35":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.35","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.35","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"8c7afcf65c69fc3da24c57277d51a94791d00bbe","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.35.tgz","fileCount":22,"integrity":"sha512-87MhCfa0hvJJeHWzHt17N4ABR+Xxwh3VSfcbzSqRYK91lFm8icJTyHXCISh3MW/xTB1gfQPiTShq2KVdKcSTvA==","signatures":[{"sig":"MEQCIGWIPq0jUnS9KlQb7KY2Q+A85lKRQchqNREhxOS7S5XnAiA1vyF7OEpZlDI50EnbpVvGJYoLbV7VafGQQmyDiQrZAg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1471271,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJir1CnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrljA//ey5nM95LBFk5k4HTmNLPWjA1hoxoZ80TW5MNbPwymtqzpkX4\r\nj/BmRhoX+pnhqi9bcqoaAcdjzfg7YL/wh3eaOn3nrCS7+TaRnoGY9uSRXOwj\r\nLsftNH3MU84EFls0ZGXkZFs1pmoxpSkNRftuuP3KOVFP4cinQl497XAX6mby\r\nnxXTj0sP88jcgwvrMY2u08gSq0ng0zlkiBmDdCnOnTzZNW2PmIg709+aplXf\r\n6WR2jZJjtwp8ex9C1Pg08PXtuaGP5UxPbYxrc5hJdPjIxHw3bPimdG3HdzWE\r\nibSiYCYCoID/jFJ5vxC/FIFWdFZEy11m901jFR9oNt5hDNUC8SacslvsTi8g\r\nvGfRALSsCiYnchPYavAxqGOoCh6ocfKYiBYb6BPI0DUcGBUVCFWD/suBKHr3\r\nZ1Pcv8gNcGhGV56jEFL/gtsAgz0NfrjTHJHxMWOp5VW3zHzv3PtK8EqTepMw\r\nMjFo+ipEoN+L1QnLDFAPDygEy/Fd3484fF8TZ0z+0dTnvzomi3IE/iAFLWzc\r\nyc6A/ce03wBzSYKp0vk7OEAG5ehsMHvZzGdyEVUbScW5I3jwpJdVTTGFVOfD\r\n138b0Q67tN0s7G5H5e+6zyWczJR6KxD2H93ZVACg1+YaF08yEQsLS6MsO7hY\r\ndYr4hCzbCOr9yG8WAMovf3/gEGz4lb4vV1U=\r\n=7fnQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"16896d42d801526e191cc38d720a5c8eb3e1dad1","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.15.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.15.1","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.36","@pvermeer/dexie-class-addon":"^1.0.0-beta.8","@pvermeer/dexie-populate-addon":"^1.0.0-beta.22","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.17","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.35_1655656614921_0.36171525383452985","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.0-beta.36":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.0-beta.36","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.0-beta.36","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"0b333ab3d5d3a0fbfc06083635492490dc2e2be3","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.0-beta.36.tgz","fileCount":22,"integrity":"sha512-G5c9pnvRBcvrMJ11oI7H9SA2IdACZZy1DBcI7C+V7f2TjlOs8YQp0OzUI0tLUBaVDfCVM5WQap50UxSjiJqpnw==","signatures":[{"sig":"MEUCIEgvuovc6LqAGD2ME7NpgQjho6s1e01p5/Z3bbzQwloIAiEAiE1plVWk0Kh3q6ODl6ssaPmBluqqI+03WQr9dYLX2zw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1471992,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi0vYBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq1jA/+JvaMKnKZkOUIHYrOSOvEcyXHjx+fpj7ihHKYyTmPCGgoH/rD\r\nZMemeuXjYAlckIzBvyVzM1xI9MB8xBc82/KR4Kb9EwdgkG0E0mCzBWumspne\r\nh90d3+m96EXWqYLxfqwVnDCUh2zAdL96sTuiKbqcWTrmViOZWS2sqeXgDpvc\r\n43RP1sP0K7+/8nWxYponFI6kRnQqF4Q3j1iF4jvReoveX7Lif7xVc1GY+k6E\r\nCl0pbV7VomA+d5rxmnp0QsiEhoohw+YhSn3Fw9MTyZbybQWyPM4CMAWW1EzD\r\n/n/q8cg8iHtoJhiAsbUjRocHsSmuJZ1IzvjjXly494xEkDEoyghRR2ZhkgQF\r\nNN4lmKX1h4G3WFikW0JXDLFrbbbMIx5UsPtpk0X/1qKyS7bBFpr/hdgELump\r\n2DDTdH6ys+RLBs6RaPegTLAoXB8V/tQ9JkRPw609q8B9cAsz8TJsUNpt/Utw\r\nrwrwHOecnbg/LQ1Nnsco2ZlxvV1SvKW75anCKrDQZiRXEJ5p7wd5KoN7tQvW\r\nWOmA/+J7gw7lrH65zJcmT91rQ3qD6j0LclPvEByEmV1xWVhqifr1H0NjG1To\r\nJGi+3/sXHdLKcrNxeUiCKERpFqpGehJHAu/fAO7x+5VXgqLa1GrbKB5JSW1y\r\nCwLQ6RoESxzSGy3fMZ31rQn/Mo/FfkusKB0=\r\n=14OG\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/test.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"a82fe247773dd19e5a0dd39cbbbf73c097ca1284","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.16.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.16.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.0-beta.36","@pvermeer/dexie-class-addon":"^1.0.0-beta.9","@pvermeer/dexie-populate-addon":"^1.0.0-beta.23","@pvermeer/dexie-encrypted-addon":"^2.0.0-beta.17","@pvermeer/dexie-immutable-addon":"^1.0.0-beta.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.0-beta.36_1657992704989_0.048258637008541605","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.1":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@outlook.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"6961fb7d2bdc664e8686d8787226b019f2d02933","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.1.tgz","fileCount":22,"integrity":"sha512-+k83rBY4+PyFZTu2kqqLZyqk98vpHfhRcMyK4XdeF2HotYZHcx4PPCzWrnV7n3gokz40lvnkrMTei4t2NW4U4Q==","signatures":[{"sig":"MEQCIFfT64CKMR2Pr6uNX5+M1k6h1gTo0B/V3WahZ3/tbAQHAiBbasN1ozd8Vz8V+JLD2OZrMTubHBXjzOL+yv09oNfCpg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1472424,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2uGmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo0Uw/9GQPB87j8sHO1GuhLMdzyhRxGCQqurPuleGdz21n/scTzQyr0\r\nzrAiyLqUiUqdipIN8dLGLL7pDMJn8mWIGSIhHq7UXCXFjMe2n6A0hIzXriyK\r\nMW8yDyZxhP/coiMG4/toHn7svq1Mi0cjiJcwEi37vllv1Z6RckFfeh8zC9hw\r\nV625u+LFYdlupIp1pMx7hpHAZ6Zzx7mkMQ9BpVN2bgFfb25+VsyMLV4ESXen\r\nRQB8zSeEilH5LtiDW7K5DyaLdXEkBhXDS0zriyGWMWYdgF/bs/fHG1e8V3zj\r\nTLBA4DLIBMY5OMIBl0ytmogau2P1du+7QS8iOsh3TU5XJYeZrdZH5F60ASMd\r\ncCBDa7H/9vEB7Q197Y0WzM40OHmy35vMygtg8luLDfDqpiHj6vKdfLjlSPX4\r\n0bl+2nRaOOugLI2Dvs0LtchhqVyaPiaf/m4jHXhF1HdgMvmo0hDk43fkmS+6\r\nvpSCQaG017iza5FkvgSs+Y+Ix6aurnXWMPaM1NY4MT4in2ejefgolPV/Y0p8\r\nb4HtwLf6Eae97GI+Ha+vn0LoWChSedarB3rQao5SxGGiWHnAhEsus2h4iWsp\r\nVzqRnA4j6WmFaN2qNsQxBITz7VaHD47hS0OX+zhKD8uwAJRzkz/L8F/8sgNQ\r\nNF/vuR98LjZPkqnfAEVGyrxPfhZneOpQPZA=\r\n=70FE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"e85919b74e555361b7ec6dba3ac7c33f65a56e1d","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@outlook.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.16.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.16.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.1","@pvermeer/dexie-class-addon":"^1.0.1","@pvermeer/dexie-populate-addon":"^1.0.1","@pvermeer/dexie-encrypted-addon":"^2.0.1","@pvermeer/dexie-immutable-addon":"^1.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.1_1658511781815_0.8789213108255967","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.0.2":{"name":"@pvermeer/dexie-addon-suite","version":"1.0.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.0.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"fd38ac8ae8935384cf58a1acf4bf75d65a9ba350","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.0.2.tgz","fileCount":22,"integrity":"sha512-XhNyHyO2qOuhI6ZF8let4q4xU+yPK7Lp1ruuzPGwd+7fkPlSr7GxTAMI292fbBzw5vN9v3JfFM8vBqG8iWQvPA==","signatures":[{"sig":"MEQCIGC+UH5WFUDAcVF7lXoGWawgoz/RQwmy1d+6jaBBYVidAiBSNHR9ilgmG1Pcf7TtX8mdonGt7FGgA8DNgVGYvMNrAQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1472654,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2ulaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq3vxAAisEGRwyfL2VbwBcF34wZdXp7isrkumh4OIMlhLepPZhgDYDo\r\n7ZvkDwPmEsR/5hbr85W3Cj31j6sWol7vaxmWYKCGwaBhzlqvwp1XytMHfFrd\r\nAqq4a/ouqG05ir0qblJxHZ+PYBAozcqTil8TDdWyIt8ElddWzp47OSJ9mm6E\r\n9vVeAkDYIE5dGbhbe6ahxf14Exqmlc5MeQAt81dktWARTK/58KDWfh/EQNpM\r\n636wohCH2LFJZLjUQxOveWV+762jCEga/i6jSQipUp81odYoQc23dE97tz7e\r\nvrNkGEaSZsDHw38b3VL6G2PMjZkfR9NzQykFdyrAOIFhFqDlirJhrPXcepdn\r\nS4Qa+c47f9HzV2Pe9Q8JlWYkqumA7zJE15DaSX/qfkPWHsv9QAMGh87l6Jrx\r\nZBxLpqeVMTE6laVr2FlA5Xu3kYG1QhjAyaSykOrDQdB1DGYbLZp8uTPnBf+c\r\ndd474nxWvFIfWCaw0JcOQfghedtuDP42T62j88MdObCBLf9vd/sBu+hIyy4m\r\na5chAND2i2M4tRgc3YtM+5DLDjxVuB8PUtsZwo20KumOT4ny2acVwVRiGg/V\r\nQJ/NRE1S2t1KKsOdIgvjF7USIjlWiMJUNPEXatH48PZ19Ni4yzmGYJoEPQsh\r\nE2zO2bDgVOhJ95TTGSK5ocf9k9NbkqG3LIA=\r\n=7fpb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"2436153946c9c4caa88b5e80d00a3b0edbf7f82d","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.16.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"16.16.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.2","@pvermeer/dexie-class-addon":"^1.0.2","@pvermeer/dexie-populate-addon":"^1.0.2","@pvermeer/dexie-encrypted-addon":"^2.0.2","@pvermeer/dexie-immutable-addon":"^1.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.0.2_1658513753904_0.39517038043669284","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"a668ce876be7c1babfd223b40e28d7d2e7195a52","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.0.tgz","fileCount":22,"integrity":"sha512-AU63/G7rbIrmQbIX7UaBSqRLJTe5Hvd0RkHzwQoK4pR4RQX9qwuoPP0gp4svakM4PIeRcA5YzpPUIIpsggBgpQ==","signatures":[{"sig":"MEUCIQCewv88+D5rbcD+alIUN48GqOt83ikxAKblMamwzPQxrQIgV1iJFa2f6m7JENXebFuT+7ENt3KHCA+EfepTUKz6X0E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1669300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaVCIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoq5w//Z1Z36gpZDbCSUoCIDnxBnzajWMqekFZwIlFED7vQ/yujANKT\r\nAB3LkO/M46lF/mAgjlPRpHmF8fbS/kKXJK2Qr5ArKhdpj1ZzlU8UJWHUPJmB\r\nkoQjkeiQbz/cw1r2mEoQFIlJkZb0pJB+iso8X8U313F5D8WOAVHbjMW7mWPi\r\n7QL6lNiiyTt4qTOX8ZCxHN8ctCI2l6dV/+ZSCFGlQisZY6dP/ysYBrydD1am\r\nbangth8LDsKn+8MRLx5BwWlKsZQ5VP8YEVxixmQZJfNP1UShKjtO3pLII/jF\r\nzukgcEE2lsagwUEABrdy/lEAWUbWb5mPpbmhoBfvyGxPgtAt1bPpBE0SWdHf\r\nP1dJEb5IRdvJCQpHYoqSpnB4brBQDpgcKT4EpO+Zkr4+23BOTWhe0bIQ4o81\r\nDegvliiH0RYE+gBZi1IOZsiSAkL7wdr9NG5oEmWklsW2Q7BR6X6r4MIwKASa\r\nLL5zAgaiA0c5lyWflnCI5nMDIgAOF/fxNCMiAnJxv8JZFQ3T4ys2dq/O2tmk\r\nuTjD8+9KEzuq0hUYL2I0psIObgvpTmpBJ3sRnkXQqZW9/HGmU9UTkhvP5PPJ\r\ntAKkmph4IDbnudMssl/CtTfPm2f3kHK+RXHOTrBC7EsGVE3XC7mVPjI74/04\r\nENa+XrwSNvvQiRqmUK1FGWD/mai+V7+w7EM=\r\n=GmSD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n- **[dexie-boolean-null-index-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-boolean-null-index-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-boolean-null-index-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-boolean-null-index-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n    booleanNullIndex?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n- Provide `booleanNullIndex: true` to disable indexing of boolean and null values. (*null and boolean values will be mapped to binary (`BufferArray`) so indexedDB can index these*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"ef7e7b21cfb0d3aea3712ad9f4b3879e73cfd99d","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.0","@pvermeer/dexie-class-addon":"^1.0.3-beta.0","@pvermeer/dexie-populate-addon":"^1.0.3-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.0","@pvermeer/dexie-boolean-null-index-addon":"file:../dexie-rxjs-addon"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.0_1667846280268_0.4907860379772828","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.1":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"0de0d84268cf1340c75b4b63abf5912debdcf629","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.1.tgz","fileCount":22,"integrity":"sha512-I4J2FsJE3c+qPrp1z3thZl6WnKDZ5JxHP+jyz1f86sWkqS5SOkMfAdjBzzFdhQ8p6E6K6gdSD9Xjcv/iFIr3WQ==","signatures":[{"sig":"MEUCIBhxn+MXohLU9mE2IhuG84HcOt2h+lJVoyvK2HLg4pDyAiEArWbfm9uJaWoG8cIlJ2He9bSZGkUa9S2keOjSInLfTHs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1669673,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaiIVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr2LhAAnFx7e8PLR4fN6Vaz74wViQOH1ehFTzwx835VWEOOuspG1xGl\r\n7/Mg2qxqHQ5QEY5eOdQBJE0MeFoXZ7B/HaeBtL0OPxs5umODVT2JHIxqQ8BY\r\n2vG3BaubHg8HpM0jUHmQxwM+KKQAU9Iyy23LJBdBSHxLwdZKfixK7wtWdNQS\r\nzJWZB/6RpV1eK5yzZPOqNnFvf22NlMsb+4mfDBrx4mnLH3IqgDXxCRpldLaU\r\nlXsFrUb0gf7Ozc1iM50ropIg9+JqJoNAZprP4ooy7Ih6rFWF9Xb5UtrJI0Y+\r\n7ejpKIUoOcdtAsKsxZVaZAEvw//oSJ9Hb/zO2aVimywScdO7G8VguMdttn25\r\n4+VNtezpJEvyRmPiKSLI4batWKBdObwSh+jKa2pLhLa3Er7/FA3ND2LDAMP9\r\noduJaSjmwk5VHjaK5ViOldYPrjWWHFFVKc65bRz97HI9TbF14Lo1mO9OAglx\r\ngX+/sVvUKc+Bs7/dHM7GO/SME1xEANDpsqe48ylydrgvQJc+II17D1GDhhIi\r\nVZF3FxPGRpFsyNNZ/Lt8hxsut5nmWNLODCIATeibgYvKFHvCp3TRbN+DV6c2\r\niDIChzEFqbXapgxUsIWaegIAYOiJCeKxHh3MnUy5/Q8pNMZ2LX1QMNRcpLqs\r\noucmkIYAvudN9HzpxBdOEiXPN5G/BfPzvBo=\r\n=xnNp\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n- **[dexie-boolean-null-index-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-boolean-null-index-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-boolean-null-index-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-boolean-null-index-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n    booleanNullIndex?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n- Provide `booleanNullIndex: true` to disable indexing of boolean and null values. (*null and boolean values will be mapped to binary (`BufferArray`) so indexedDB can index these*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"76f1cc81ebf409e98459dbd890a0d952688850a7","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.0","@pvermeer/dexie-class-addon":"^1.0.3-beta.0","@pvermeer/dexie-populate-addon":"^1.0.3-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.0","@pvermeer/dexie-boolean-null-index-addon":"^1.1.0-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.1_1667899925591_0.4035803620131717","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.2":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"b0bc0be17912eb7a1250bdf3896fad4c5c7778c5","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.2.tgz","fileCount":22,"integrity":"sha512-JiYqAtcHqFlUHHI9rfrQYM5w1lijMp23OxywB/5wCXsRSFU1WLiNaHo2iCZNIIdRmSh932QztPXIK9UnaEyfvg==","signatures":[{"sig":"MEYCIQC6KmoZYMjPtLrpBJfLOGIpjDddzp1Sa5tlVryH+CAk9AIhANISM7V8iDtycnFT6mvFtMJSHl6ECENR+bvLbBpqRaSM","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1672035,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaiyxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo7pQ/8CBE9kxoPQsf4pPccPjwBToGJAPoZ/TyJKf0y4wk1XdA+qh2y\r\njvaA7LOEnAyngkIGSABEhKCF/HHVluTZqsBTU/hm3edJmGsLfbHR/xZ6pNJB\r\nszkeDY0vxSFX+m3YzyMlrtyZcA7Il9x+4F0lc5xlTV9oUG2oy1LScjCgq5Bs\r\n6DKdLKfffvGI+aUYc9gEnYfiFS4cUGTvTHo6Q5Duxlsj3fgVRmt6HAb2PW2R\r\ny9BWWtFiDJ2Ilrmj9ahrZ6Nf0jZRbrkJQtnzwovV1lUPXvp8wNN1i4a9wFYU\r\n4/esei31uYBES9gM0ZgZ29JL3ClSIZq4IsKRJyVSuEv4Xx2FDnB5TRzsgI4k\r\n6i5WQFIxVKLuIU4/T/9vfxNurn6IbmRA1PT/8/q1VR7boBtB0zqUka69xgPq\r\nE7RRiKwd52adm5+bAABHnIi5ljw2sje6qCIwuKXG5kk/mV2yijTisDm3BcU8\r\n591AYwkHiW55n4jijNRXXFNelEBRMowqLZ71B1gXH+4V4SK5td9WYyVdCxBS\r\nisDrykOcqE5Y+7pO0t8BYpSp2VfHpeTzTXT+1AGdVAdDBHUk47uSJAMqxLIr\r\nyAkURkb1Zi3XYZUzG95mrZWj9R1KAP1Ob3OIv8ZmvHB1MudXECaybzaLmNXx\r\nTzsaITEafQyC1wZUYxaC4jKtERGbe2ACe9U=\r\n=p5t2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n- **[dexie-boolean-null-index-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-boolean-null-index-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-boolean-null-index-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-boolean-null-index-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n    booleanNullIndex?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n- Provide `booleanNullIndex: true` to disable indexing of boolean and null values. (*null and boolean values will be mapped to binary (`BufferArray`) so indexedDB can index these*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"2f524b624667f9b8be96eee9132ce5a4fa16cb50","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.0","@pvermeer/dexie-class-addon":"^1.0.3-beta.0","@pvermeer/dexie-populate-addon":"^1.0.3-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.0","@pvermeer/dexie-boolean-null-index-addon":"^1.1.0-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.2_1667902640981_0.03388124247009805","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.3":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.3","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.3","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"3e6d3e7bbb8d9aabc7bc20411c3de8357d710649","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.3.tgz","fileCount":22,"integrity":"sha512-lN282UOW0Zu8RYOjlo69uGWBRLUVzds6G5adiDooH51cMuLwUTQXhP9f/kQcKE6rmXBO7aTdAW3CiFPkEOkflA==","signatures":[{"sig":"MEYCIQDFpAjXGDAINUTyxrVKNVZj9NA98IQRKsYFpDMNLOdshQIhAJtGWWrLfstSerUpoSFo2fjfzgDbPg78yrt6KtK+Y8Lc","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1682856,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjalSQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoGcBAAh3dB8i14h8tiBPca8H8oDaVT1dOnfakookSqfwP6yCi52KSg\r\nqhSG+nzbhv/8lH1Fcl1itk7L1/RuT0rPhd8//lJEglwcNWErUuSTb/zdyJCg\r\n5BQ0BYudJG+nJxYN4egcRafviP+BgDz5MIOdfOsE/SkPh52C9GXQESuSkAyV\r\nRpLvslDkiJPM7s7oZ7vawI04bxvMItX7x7UceU6fQTYqlioniOsZd4MzA65a\r\nb8IOVxCdtEXIePLSdgNZE3fwmjUF+BRnsgHamnLB7K5WrkSntJ8GR7BxMit+\r\nsUYQzW1v1igW8qfAKRyXXopWWjhtTV6oi0Fx691ZXg01gWmCd0Z4OmartsDH\r\naZE4uHWx9pok9yLc+h3PAM5LvVGUyturSggDMG98qJhMX/Uj+rpolVMVvNeu\r\nwRe4zV8qI/Hak9kLgqosmZ8+p3Zbz+H9MnoaGPOyZouZ2iicKRaKJ/1wIQF/\r\nU04uBPH7Lp/fzuYyzxo1ko/YA6MsJ6kRkXjK0GFjlUZtd/n3v9yvftVQYsZL\r\nwqEYuA8A2KOemwzxBnPq7oNa6/Fqzl5zVVXliP9AXJ56pc8zrmNBEJkC0TMy\r\nEV/hwia+yCurPCqR0GYqR78mEWgQkgG+IP+z9DCN7c7VNsFKgSoZZalK33pC\r\nhy7eYGPBilq3F2O5fVOOvP56DnUBWkb33GA=\r\n=hq+k\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n- **[dexie-boolean-null-index-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-boolean-null-index-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-boolean-null-index-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-boolean-null-index-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n    booleanNullIndex?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n- Provide `booleanNullIndex: true` to disable indexing of boolean and null values. (*null and boolean values will be mapped to binary (`BufferArray`) so indexedDB can index these*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon.\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon.\n\nexport class IndexValueEncoder { }; // Boolean-null index encoder. See dexie-boolean-null-index-addon.\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"b89dde26c68401e7b97c291c35d97d67cddf6a12","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.0","@pvermeer/dexie-class-addon":"^1.0.3-beta.0","@pvermeer/dexie-populate-addon":"^1.0.3-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.0","@pvermeer/dexie-boolean-null-index-addon":"^1.1.0-beta.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.3_1667912847998_0.5955285464493731","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.4":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.4","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.4","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"f65fa2b628af7a77b85f005a9f5ef5b3cf95e19b","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.4.tgz","fileCount":22,"integrity":"sha512-H4iG/vrxsGc5d1ZZeYXYueHYvbKURL2bx5A6FRS3RsZrQRPxinXKG1MpLsdG55b/v7QZzO4zH2JRCk4/Uk8+vA==","signatures":[{"sig":"MEUCIQCXUOkJXF+VyWzmDufpU3tq4Q3RTEoloBLlaXLsCMPcogIgLCjiT/WM5GdHaYu+vygnGHJEjdVrVr12e0PHGCJV8E8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1473039,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJja/H7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq/OBAAj6c64nhoL2B2esEzBBGWVpVo0UgyZVAgLd9sagPhS4daCoV0\r\nDWNLbl18iErukTpo2vkx9NvkXcMWD3K73I8fGFR/dhYnt6OcExQeSUWXM0Fb\r\naYF3zPNWmus2CSN24o4IGa8dir5ywwMXesyCkLyjRCmUcpOMLdToR6Q4KogL\r\nIvEDXyKvlyj0BJrXu3+n17a8bbd7nXoXCtnr0qmb0EHony5LhyMqqrIbs9Cf\r\nnbmxWEDR2D57Cdj9fgSsMNDcAnB0Q5QGKZSM4kplJ7Kvk6wg9a/++7b1Sn4N\r\nzbv3tQHv2bUhas+A7Qk+Ic5O+p8M4A/v0uSVjte3LZj6tTPCatTLHrysFuDa\r\neVuLV6q9w9vausez4eev8MgVk9xz4EfgXt+M9emlglvjXkd8ce1MUXxiS4ek\r\nb+oFFP46CpSzzHIQ8tufXXUg7bS7S5xBS5HBqe9Y33HTTAotmzp5WgHTYny6\r\nHm+OS7/V6yb0MNcf/GwfF3OncdRYmbLdBAMyc05UUcAhoDyhI3AZDx3nFFvo\r\nNfhMoXP1D3xcX03m2evSis+mufBppg4zXpLdnoQbQJd3agdQ7OWSQkaGmrn7\r\nNCvTXNXAdtddJyUJJEeh1i623MI7q5Lw2DEpbQVdPxLhuq1iuMmDdUxVr3uy\r\n9/F1y31mZuvCaWqb8Amuy53Nf2Weiax0bJY=\r\n=pax6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"bb51cb35be3f49e34e6dca67bac8ce6d312f0cf4","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.3.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.1","@pvermeer/dexie-class-addon":"^1.0.3-beta.1","@pvermeer/dexie-populate-addon":"^1.0.3-beta.1","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.1","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.4.0","dexie":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.4_1668018683026_0.02339794965482267","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.5":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.5","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.5","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"84d22f0b78fc6e7f92819fc715b8e19e75571799","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.5.tgz","fileCount":22,"integrity":"sha512-ETxDSfLduVo3x/JkZnGNscedfZUy0aUNQ/foCdH8Rf8AoszEappEV2eHMGHH1Wg9GOyyRtVeyH2+qFHvxiJZWw==","signatures":[{"sig":"MEUCIQCsiarR39zFDP+y+jSH6u0k1sKIkGDPVoG2ipMrZSA0YAIgQpJl6dLXvHvVk3D5u15XlhyHUCYLrGdd0ICrcbK+0DI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1548931,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbtcVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpD2g//aZA6Y9Ur8xkfGCzFUBXDTdaYTEiJiaeUDINOlLKaObovuerr\r\nABTxp4Kt4gDx4OsEOdle2VcqC6bRSJAFTOgW9AIxbvdJyi3lt1DYeI3Y5HLS\r\nOXkhvwlALAYLa3+5bDmTiE34TS/waAHPJhCjmR/RRIyDMHtfGNwBKjeOUphP\r\nBL1niyIJfjNP6AxNjYV7Nd09WtFaQ9XY1BHiCePGfahSixBw00mzE3ZpyYzQ\r\nrvVXTYtCJWcTdrgypQcWaH4uecUcgHSRgFHt4iQCZZVXlz2+Alo8mEx9Kq/u\r\niUHUQDzHPSABnEA8IpN+IQPF6/7hTWHQkAnd6vSSYLogRSZyLbKFXB6hThyN\r\ncleZFl4PA1Ib3dzO7eSbQaY7PNVKonIw6vVa6gTbsJY0wShJdCkHRs71k7IQ\r\n/WV173vo5qVAzSsjgbQqlaDHZX9ky/nqV/jOKRAfnOSGA1AwwugUN9Pr3wtk\r\nJJW/xD/ILqsjwkBa+QUxVZrSW+y39FA2qxdQGLoN2bKtu74O4gzxx6A4a/pz\r\ns6hGbvFrMVTGYs4GdpzeZRDPDG7LvCHJYAGpOragQfzr/5IU1ICeiodJGojI\r\n3TzvkcG7LVoIw5xQxWan2tw2WHdffU2tOjW3lPKlO53QDYioQskm8Id80sPf\r\ntVdeUWE8rau6FclQyyNI5AZ/mx0ykvP1yxI=\r\n=+67O\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"9f07ebc92a654d468b14a5eaf32043ddf4a3f6a9","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.2","@pvermeer/dexie-class-addon":"^1.0.3-beta.2","@pvermeer/dexie-populate-addon":"^1.0.3-beta.2","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.2","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.5.7","dexie":"^3.2.2"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.5_1668208405666_0.49621716631694346","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.6":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.6","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.6","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"dc9ba3d2e74f05eda69efa3c04058a02441c0d0d","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.6.tgz","fileCount":22,"integrity":"sha512-w4Kjx+fyCiFc/+kBaPqu0zB4iPc0t16JfZdOyAIxEuotYHv04DWdeCrmlGrEvBIW6DBeTK+l9JxVDnCScvG23w==","signatures":[{"sig":"MEYCIQDWcFphyY8fRytouGuzNx+crIfVzqxSXk4gxr39cl8MpgIhALifcCW3G+CMc+/l9Dn7WfO8mjGYD91g0pa+KPECpw4J","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1549283,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjb7FHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo6oA/+PQE6qfI3ISxdT89SeDaiC/fNSrQrrtrZmhIkubt6oeDuzCwe\r\n+v7gx2ryclZlPFGNCqPhq7rU/F49jq7w9bFboCg5RXrCB5HJC8Qyss0n9WVI\r\n++7usm4DuwADmYA8PVPZ4xYH5k2fiO0rtMYsBZ5cmlrjInTF/VPcShUi+0sF\r\nCgAOCaHIxG7yql7kDVXumYi9N99GIq/E4e+YAfqpGytp52fjWTlcOu7RyGT7\r\nJOhusyJxGwnkZM3q4RM2D5GK7xJBz7MTEt4Hn4+j5XFQA8guCL3EDu35eRZ+\r\njgE312CYE7pn9KHHvmZNOSAyltxkRzQIVUSwWJaul9X3B2BRRpIaMSgsFa/6\r\n/1SlB2R/CuL70eN1HpktQBolhlzSwSmq/MTChVH2odoouroBSlhympexDjDh\r\nIyzXoLMW0Q5IB0DeL/iP4lkhdNCgcZyeBA0qKkiV5utn6iqD9I+37mwvRIBU\r\nwAvg8kyVyDORMSFAofTgXrvl2dq/YZ2PLPIxO/WV60nP67nrmQ9tzf/cGana\r\ncMWulWCoyQUip8wzQZHU9JGwlpjArXEy7RJCSt8lCS6GD/Dp991nx6IOgHmP\r\n9aVsksB9Kq5mrG4BD12Q7WM/ObwjIUNpWETFalKHviflq1Q7mvUYtAjX1AeA\r\nzGt8GxMTMTqQFPrNe4gPnLeoMhaaPy43h0Y=\r\n=BtH1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"691289cc25c05870a56675e26c63eeee7df3d0cb","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v18.12.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.3","@pvermeer/dexie-class-addon":"^1.0.3-beta.3","@pvermeer/dexie-populate-addon":"^1.0.3-beta.3","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.3","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.6_1668264262985_0.5706647226695685","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.7":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.7","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.7","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"0348bb95df222bf72d431d99312692cfcfb45a46","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.7.tgz","fileCount":22,"integrity":"sha512-NLAGY0tzT9jR/Tq0NQTJlUjYX0lA2Y+s26J62YSJ6Gz73Xx50bQJ4B2TGcOyP2P4JTAFed8bgt34uwUbCCwABw==","signatures":[{"sig":"MEQCIDUeC+T7x/Zf8Qhfceg/PYWKJ02RvAfH+ZigctKsWQC+AiB0Qtt36sgNITySoLWfYf/dy3uOeIwqvHl8fSf5IVz/lQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1549669,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjjd7+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmogRA//SgrrXwL6olGc8JMJy6aBnMm/B7p00YcQxzZ3MMw22nrdSGm6\r\nswTAkTanqVZrwNO2t75zJ20AbKeaqmS7gJJLERX+f3yxkYSNkvsSLw2m1FbH\r\nSjMi13Jn3UzgteJMnts01ZABQ5Lf3bGLzkQViWOKGpAnzMW9iUtQV1oLK/BE\r\nAIk8CMMhF2wDW7MgLB4ImAViVwEPtGId7oCmVDv7j99F4EkB+JOtXn1JAmkh\r\nH6hYZ5oh/+wNET3hxJ45OtTMZq7c3MPFN86Jttz33+w/kw7R2CAJFGQWcMxO\r\n7PHZZmI4mnB5svKFvsWljR5mTUJqcMlZFuIx/+VLzFz2241x/QDwnoGuPfq3\r\nj9K3dk1l9vbJ8WcjEGN0LaRg0fwKc05Tb6QIv8xKIE7x+Z9BUS28/ET2gdWG\r\neQg9/LXj4pSP8M7pYYFc7PlU1Lt1YPyKw0EzF7nQ7bUYCjCamR2+PhiEdgLu\r\nj7CJYV0m9xjEYxRNIZ43QbShxK+ITuSzdnjJIuRk1MpPyTwXFzlWnY0al7kG\r\n6pOQc0kS9Q/Wfh+NSuZl3DgYzSfNvGZR6wmmf9t/oZ22KYkKHVvqN6tijj8H\r\nUQGSyvo3Ms+C+3UNa/kSvXBpUdSqhUVwpV+hLDGjBhXsuz3QYD2L9NsKNcCy\r\nkzAa13S/D1BPIYIPjded+IT88g9405SeAqg=\r\n=AdSm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"Dexie Addon Suite\n======\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\n\nAdds new functionality:\n- **populated rxjs observables**.\n\nInstall over npm\n----------------\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n```\nnpm install dexie\n```\n\nDocumentation\n----------------\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n\n# How to use\n## Added Schema Syntax\nSymbol | Description\n----- | ------\n\\$   | Encrypt this value (*does not create an index*)\n\\#  | Only as first key: hash the original document and create an index\n=>  | Relational notation: `group => groups.id`  (*group is indexed*)\n\n## Addon\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (*links are above*).\n\nBy default these addons will be loaded:\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n*see individual package readme for more info*\n\n### Config\n```ts\ninterface EncryptedOptions {\n\tsecretKey?: string;\n\timmutable?: boolean;\n}\n\ninterface Config {\n\tencrypted?: EncryptedOptions;\n\timmutable?: boolean;\n    class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ immutable: false, class: false })]\n});\n\n```\n- Provide `secretKey` to enable encryption. (*see below and dexie-encrypted-addon on how to use*)\n- Provide `immutable: false` to disable immutability. (*not recommended in combination with encryption*)\n- Provide `class: false` to disable class mapping. (*class constructor and serializer will not be called anymore*)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n```ts\ndb.friends.populate().$.get(id);\n```\nor\n```ts\ndb.friends.$.populate().get(id);\n```\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n```ts\ndb.friends.$.populate().where(':id').anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends.populate().$.where(':id').anyOf([1, 2]).toArray().pipe(map(x => x));\n\nconst sub = friends$.subscribe(friends => { friends.forEach(friend => console.log(friend)); });\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n```ts\nawait db.transaction('readonly', db.friends, async (transaction) => {\n    transaction.raw = true;\n    const friendRaw = await db.friends.get(id) as RawFriend;\n});\n```\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n##### TypeScript\n```ts\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption, Ref, OnSerialize } from '@pvermeer/dexie-addon-suite';\n\n// Declare classes\nclass Style {\n    styleId?: number;\n    name: string;\n    color: string;\n    description: string;\n}\nclass Theme {\n    id?: number;\n    name: string;\n    style: Ref<Style, number>;\n    description: string;\n}\nclass Club {\n    id?: number;\n    name: string;\n    size: number;\n    theme: Ref<Theme, number>;\n    description: string;\n}\nclass Group {\n    id?: number;\n    name: string;\n    true: boolean;\n    description: string;\n}\nclass Friend implements OnSerialize {\n    id?: number;\n    name: string;\n    memberOf: Ref<Club, number>[];\n    group: Ref<Group, number>;\n\n    doSomething() { return 'done'; }\n\n    /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n    serialize() { \n        return {\n            id: () => this.id,\n            name: () => this.name,\n            memberOf: () => this.memberOf.map(club => club instanceof Club ? club.id : club),\n            group: () => this.group instanceof Group ? this.group.id : group,\n        };\n    }\n\n    deserialize(input: OmitMethods<Friend>) {\n        Object.entries(input).forEach(([prop, value]) => this[prop] = value);\n        this.date = new Date(input.date);\n    }\n\n    constructor(input: OmitMethods<Friend>) {\n        this.deserialize(input);\n    }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n\n    public friends: Dexie.Table<Friend, number>;\n    public clubs: Dexie.Table<Club, number>;\n    public themes: Dexie.Table<Theme, number>;\n    public groups: Dexie.Table<Group, number>;\n    public styles: Dexie.Table<Style, number>;\n\n    constructor(name: string) {\n        super(name);\n\n        const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n        addonSuite(this, { secretKey });\n\n        this.version(1).stores({\n            friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n            clubs: '++id, $name, theme => themes.id',\n            themes: '++id, $name, style => styles.styleId',\n            styles: '++styleId, $name, color',\n            groups: '++id, $name'\n        });\n\n        this.friends.mapToClass(Friend);\n        this.clubs.mapToClass(Club);\n        this.themes.mapToClass(Theme);\n        this.groups.mapToClass(Group);\n        this.styles.mapToClass(Style);\n    }\n}\n\nconst db = new FriendDatabase('FriendsDatabase');\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### ES6\n```js\nimport Dexie from 'dexie';\nimport { addonSuite, Encryption } from '@pvermeer/dexie-addon-suite';\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n    addons: [addonSuite.setConfig({ secretKey })]\n});\ndb.version(1).stores({\n    friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n    clubs: '++id, $name, theme => themes.id',\n    themes: '++id, $name, style => styles.styleId',\n    styles: '++styleId, $name, color',\n    groups: '++id, $name'\n});\n\n// Open the database\ndb.open()\n    .then(() => {\n        console.log('DB loaded! :D')\n        // Use Dexie\n    });\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!doctype html>\n<html>\n    <head>\n        <!-- Include Dexie (@next if v3 is still in RC) -->\n        <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script> \n\n        <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n        <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n        <script>\n\n            const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n            // Define your database\n            const db = new Dexie(\"FriendDatabase\", {\n                addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })]\n            });\n            db.version(1).stores({\n                friends: '#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]',\n                clubs: '++id, $name, theme => themes.id',\n                themes: '++id, $name, style => styles.styleId',\n                styles: '++styleId, $name, color',\n                groups: '++id, $name'\n            });\n\n            // Open the database\n            db.open()\n                .then(() => {\n                    console.log('DB loaded! :D')\n                    // Do Dexie stuff\n                });\n        </script>\n    </head>\n</html>\n```\n\n\nAPI\n---\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---------------------------------------------------\n\nDexie.js\n========\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"06de7b3cb8a07e954d396511430db9524f63c218","scripts":{"lint":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './tsconfig.json'\"} ./src && npm run lint:test","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","lint:test":"eslint -c ../../.eslintrc.json --parser-options \"{'project': './test/tsconfig.json'\"} ./test","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.0.3/node@v18.12.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.1","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.4","@pvermeer/dexie-class-addon":"^1.0.3-beta.4","@pvermeer/dexie-populate-addon":"^1.0.3-beta.3","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.3","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.5.7"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.7_1670242046597_0.5392850003850551","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0-beta.8":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0-beta.8","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0-beta.8","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"45bf6835a9de27a9bac039dca7f6c79eb24566c9","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0-beta.8.tgz","fileCount":23,"integrity":"sha512-/JnMkOTqrz0oOH42b+Nl1kpn3Hb3vnQO+4QVp+AO++7aSXpjqL3VA9EqY6ppviayg+g13+4Bqts+XPK2Bn3W3g==","signatures":[{"sig":"MEYCIQCOxb2zUy2CqUSVXhFO88JpN4uriTVuu2fQhI/XjqVuGQIhAK/pYZPN8+4+rPBMDK/lnmTcHVSHSNHfUSkE42yJYW6l","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1635872,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjoNPvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmobPA//d3C5a243Gub52RIHjkbU6sUVFUYJyjGT+zgnqRdQuqHznZ4C\r\nH2U/h02fi8nVxfgy6ikMl+EkVZvvGiNePQEjaZZ5DwKhBBTmUuq8znq1seda\r\n2OmkpdaLE0yKRKwtYY+du+t8SH/NEFDnhTvLCs5a9XfJaFkmjcpoic3jtQxL\r\nfEN0moWijtLkgne799ZU8lAaskxu86IopgqN/ckiQW4eSLpQ894wCEtbCXSx\r\naJUoOpb9E8+u09C6EOAFEa9bnrC8A8cZxlKavJMwcgWRg60XTy2/P4HJHlg9\r\nORC82bsr57WFWeqoYPicSsmO1DN3GVLF8rJoNGAifve6dwJqmVJedFV7E/4K\r\ntl+D6h7fBgIL7FoN9quQRPWeDG4VqTIRwPpCJ31dg+RrM2gX5tc4ZN/9lJYp\r\nevY+IoVB+n+9B2SKwDRux9ij6kv0I5YBkAA6CzT0JojantKuVDx2/pqoe9WC\r\nKErE6KhHzox+WVzfwxhxI4lMQbhJOonkjJNpMWhmh3AawHgEdsaIeUKgUdvA\r\nZdpZ4PaSOULzsl90MPSqTdQzCGBebHkmv7xvtKv7TvL8PKiCJToyRN1v9TYw\r\nVhRW+5Esnl85vD/g1pqAjefq73+MjRkHNd+E7hJ2YTfK+zLSFKCHmWgp+fuS\r\nbwbFP6GFfEtVv9lGbsakf3zpEfpJicJvIQA=\r\n=o700\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey?: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"e553f7f8912323c4c020cfdd6e34110be2b26469","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.12.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.1","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3-beta.5","@pvermeer/dexie-class-addon":"^1.0.3-beta.5","@pvermeer/dexie-populate-addon":"^1.0.3-beta.4","@pvermeer/dexie-encrypted-addon":"^2.0.3-beta.4","@pvermeer/dexie-immutable-addon":"^1.1.2-beta.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0-beta.8_1671484399425_0.7673181037222394","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.0":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"5bf14c0d4929f5a33eef306e2617c16b83d1b572","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.0.tgz","fileCount":23,"integrity":"sha512-c2+sajD3BwWNcdfjHribNrdImvc9PsVa9RhaWgfZIt/7JkFuhzYfH57vMJcYZZ36ShUgfrvU0uXPIbTjRpdn2A==","signatures":[{"sig":"MEQCIBKEDC1EQGdEh6UDwj9KRDuk3VZ+I3YZf5QxJW+RZqemAiA5fHl7VNiQnShcJwy9g6FWGC4TtgIzvLdJJJcKCv3dKw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1636064,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjrHU8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmotiA/+KxpFiPE3jEW3swD88Sd3iBfUfb3vSiNLXKZmbRp4k7eLDS8y\r\nIpXN7WRGCH0hdPtMvso8yzFVb3MlIZmZUT5XGm7HN87vua4iw9jXqVtBcSmP\r\najERraJ9+hq0WN/b3qtTXc8aWvyoQYoELQYi5YwcMwoPDVs+w2Q3kvqv6LnU\r\nehFDVikfbfEE3M0Zu6bjqXjL/hJWEMjpZ+LY5FuG2w24V8E+ZVWOe2OOYiNF\r\nNVCXk0qE9q7tp02oWluTplvAgfpyl5wkFKbFejse00uQyBFklyLIZrnJmfHx\r\nqcBYTjHE76sdUYLDmF6bTdxUULzhb8FIaaARkA5fivHREM3Uld6PyL+K2kBN\r\nbuRzCa/3nhIuikce74TwqW69yHTnp4EwlDrbspw4cB4sa/e/iVYP7MiuSsZh\r\nwa+24vz8ssY/Lxh2jacXdDycwUTVoJLrVvjSqAYe4iL7PaLtKtSJs/FOodF2\r\nAC8cVPs9AnNpwLg2zQLkfPDG6MSVKP9K6t252H9gavWiYCIifG03OBjsatxv\r\n/s8MctEWRP8LZvxS41n6QWu7P8nY50MU1zauLV4wZe/pKfcw/GRbxLih5MdO\r\nMLw4umWP4oakR5Afm/1Wy8p31okOdXlyytfQOw1vORbp+FSj+QLwJM2zxVWy\r\nfh182tbO85ace09AIPg1IM+g3N8TqbuxbD4=\r\n=JGVE\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"1a396be5b7eba70c9ad2020f74d8de8953859954","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.12.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.1","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3","@pvermeer/dexie-class-addon":"^1.0.3","@pvermeer/dexie-populate-addon":"^1.0.3","@pvermeer/dexie-encrypted-addon":"^2.0.3","@pvermeer/dexie-immutable-addon":"^1.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.0_1672246588418_0.5171406091745432","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.1":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"90f891c1561bb8452ae094de18d86b6e7b2c8e19","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.1.tgz","fileCount":23,"integrity":"sha512-JM2E0gyehsn4dI+S+FGp3x+4V+6Y0dEFIKr2aN+aaCxkFQi2QepOVlnMsw177ZUSIOHeY5dKXuKq9rutYpglgA==","signatures":[{"sig":"MEQCIEpPSqPoazY0VxvuQ+Oe239VuyXic7Qf+U8KQ8RCHnGMAiB2BC3LLvbST+1XjZ/CihHoxiIyy8Byd8SkvvsFWh0l2w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1636292,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvCJSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp9rxAAhJqWeiO80lEscZBjRliRyWxVSfteYXelRKgHABv/oGyoIRlu\r\n179mmq8ESmSOXH1BPnJl6jFe88K1Rbxb6G/tZxxLCL9SFVAopKdSeT6i6WaP\r\nwO+cJfD48/v+xBW85t/09h1CedKVD869AoTWnOZmHlClR6IbtBLDa8hCo1tR\r\n513K0iIDeivKLpKo29H922VO2DBUVKssoVQpvka0P5Ahpwu4NxRkEJTAsLCW\r\n8BUhtI2vhHKB2KWlhLsPIfRjEjkeFNmrYNT2FV3V80QnVdociqHXcTXrOLiw\r\nU7jJ2asaY4FvUfKpD1UXB3/o96GckTIf63UOTu4yvz0Xm1ASdunU/u7ckXfR\r\nPxsPgGR/qmRfm4gPHYTM+z/prO13tUmwFd1v0MyufZsg1+4lGiIj9irDsqUk\r\n6F1r6nlUAXVsc1syyVno2GCZamh8j+XOvnH7wCA5vGcxpH3DiYWqxLU887Ky\r\nR1/zeUO3h6z8j9KTvl8rurUinAi/JXC/Lj/0p1SUY4qbTKRjA/WGlGanuwmW\r\nep8KvGKCx8EI5tZJCMBw+gimS0GPmPDPdqPalOQrE+hbuolxixwLTqbf1mAE\r\nxhrkclaFU5HBQMJkTROgz9Ap62LkfMg//XhIoWKmo++6yKOsmC+58rj1LZ2Z\r\nNEgNfx/KRMcMlzGThNCyKePWZ/fG3nDpJDc=\r\n=xmTk\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"6df0dc538f8e1116dc606fb3fb58a7c25b39a27b","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.12.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.12.1","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.3","@pvermeer/dexie-class-addon":"^1.0.3","@pvermeer/dexie-populate-addon":"^1.0.3","@pvermeer/dexie-encrypted-addon":"^2.0.4","@pvermeer/dexie-immutable-addon":"^1.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.1_1673273938435_0.6333316071150052","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.0-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"1.2.0-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.2.0-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"76c431c3ce1bff86cdd49d0ddd9a101ba2d48fdb","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.2.0-beta.0.tgz","fileCount":23,"integrity":"sha512-8jvjT84fuaQnEWdDj4PWBlKJeIf8OUUsYGYPsXv7YCSnAZXeJb4NT9m85dR341fB/ZJbF7svRbiDnT2+Sga9vA==","signatures":[{"sig":"MEUCIQDZbDz10zKu8OkWpiAzZ3NdKZ72vOXmZPqGHovvn67lcwIgFt3ZBwqsc9bRXtojAzOoFJPWn3FDXAxd4pXg+6hd9g0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1637911,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyurUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqpkg//UwTTx1R6s70hd0G1w4NBAwePbR7sRwNH1qe3PWQT2Sj1Hv5t\r\nw1PBPSGxFszEP13Y16noDYJnQPH6XEqqiScMhaSGT22Md65stpo1fP57u/F7\r\nt6AVE6E7GMhaCBYJr8pmJRMRw4kgkcz2/dQfshZx8xlTRHq0eXIQT+2E7UXn\r\nolQZUZAzXNEYdgDGj/nycD+QYyxrSnOVdhoQqmx2ON0pNvSf7EUsP9sjyxhH\r\nNSsy9OGMUYDLD7bCsSKKTjueMoTFgvstaoURqnJAzqTfaaouGP7oZ0d/tsuq\r\nxFNwEpt8Or5VZUhvw67E0OT/3oRAu6+q/z3zu7/Qi1jrZZzkYYGtzcH94dtd\r\nPPZXqi58t24rPlQvGNcXz4iFglheOhldyEUrKnknfijG2Edhe9VjodaEhzMf\r\nNcRm+gIMCRadjB/sZ4dxMGngSgIIQrbvaiOSXKJmTHcprSWhB2poPPLdqY4d\r\nVi2DadB9dUWFKDCoWzYw9F2/F3VWdqFBIyqVAyXEwR/CpsADeQyF0C+sfOfb\r\n24x4riK2otMXF3VFFcmKL3GimcxO5LKXeivX/hATtYJEDOIj0WEV2bm/rrY4\r\nfcTBX0r68bHaJpY4qy0fp3Bt9toUqHuPQy4RxDu9dh92qtrG2jkwsC8EhoJr\r\nYZeYgMgAcU4fAEQIQWsAsGVoo0uYMSOlm98=\r\n=ovId\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey?: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"90a49c461df32f0bc5360f5e77c8a218689c7a74","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.13.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.0-beta.0","@pvermeer/dexie-class-addon":"^1.0.4-beta.0","@pvermeer/dexie-populate-addon":"^1.0.4-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.5-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.3-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.2.0-beta.0_1674242772524_0.5036028574332856","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.0-beta.1":{"name":"@pvermeer/dexie-addon-suite","version":"1.2.0-beta.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.2.0-beta.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"6abf73cd5742839f40adebd9d3e4863f488e8314","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.2.0-beta.1.tgz","fileCount":23,"integrity":"sha512-BNEHbfJM/MHFRFeJHTWoNCRdi5sDyzBsp0YS5cgj2r1B8NzAMi4MFKDYvEfripBNUhxxZDw8fgVa9zJ3eoCScA==","signatures":[{"sig":"MEUCIQCjG0GmigUip00fUjxGkpPxoLSKKo0Qeb0ZDQP5gg41pwIgWcSJNvprSaa4eTBfJhI+/ntUfhL/hYGOoHc8ZbR4T+M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1639869,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjzUeiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpBpw/+JIL4O+zRO0G7+bmbtjWXU3U8HOYMmKLMJdJcJg+s735+RcRU\r\n8JT48yFZLc6qFn1kl0G0QE3ih97T2lOIr6X+Dc78Ss5/N0Nr0qy0bcNGEhIr\r\nBiDbIXmhTgyte43zX0/dIsi6NBUg+kRA/m69KD1optm4Yoov8yXNGuL4B17z\r\n9ULz/dqXDm9X+SEj/J7aADWNnbfFKALAp+ECWa0X2JtMbO/FyEzeP9eCPIzM\r\nyVOXP65hXx8VFyuj+KY/TbiFpgxptbp5hpEcVzokZx29cTSpw6GBYiU8MjrN\r\nkJtfgZpyC4IpIVgUH95J7L+dcEBUjs0wg/LwvKs259vaLrcL+NZEkAxmegyb\r\nX6QtZrey6avjIKrEjtApon1B7NUVe/bnO76rBA9pNRuHGIAph6HnhbyRLSw2\r\nQVf4RnLyaybjeh21a6y7zVKwxHY5hiVy4fFkfOx7BrUdaO+lggkLXN/XCXvL\r\nTlRJmH+/wqYeIvckuSvB9ss6q5tXrDaBXmGaPa4Xb3khCz9URcpl70AT3E3C\r\nUdyhniYQxOWUv9PnRCPQQFu9Jy12t2JAi6qnOkQBmydOdWxz8YHXBqNM1YST\r\nLlJHUuB+ewyFexRP0WU+v6GvZhBSvHojAtprswepOd/7zsw+at7Ve/UdlCRc\r\njaiXoOuKBCKEirHQFQkG5uizjKYaPHI2PJQ=\r\n=J9dr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey?: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"b6210c823c39825d9eff103bac4e88581be934e0","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.13.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.0-beta.1","@pvermeer/dexie-class-addon":"^1.0.4-beta.0","@pvermeer/dexie-populate-addon":"^1.0.4-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.5-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.3-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.2.0-beta.1_1674397602606_0.3383825221492185","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.1.2":{"name":"@pvermeer/dexie-addon-suite","version":"1.1.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.1.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"189850e6bc34993c71e7390e9664378cb8ea6ca1","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.1.2.tgz","fileCount":23,"integrity":"sha512-tvAWpE8/4Q0T7WIt92citJHBhlLSc1GvO3Uln0TuFRS7fjMw8Kwz+rDoNko6uKvKHFfrFUogOVPxFqAGTIWeuA==","signatures":[{"sig":"MEQCIClaurgZGGp4EqPpH05Z5vnKRhOg3Ehq9HU7hbsrbjhsAiBEfpjMC32VhNyAi+V10w21YpdDPydlOchtbpiFUNi/jg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1636625,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0CrBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqHqQ/8C5kFngUQQiH/77a+Ra9oag1NEioGaNrEgFrpPJ5/brwc9Lpj\r\n1X+kIMOixZyAN5rQejx0VuXhsXlG97UOTvoftfavaCZGZOjPoXKGIMsMbMjr\r\nwV1GlZdtqCMrcN0wfaGNvS5pQ9JbjiAa4PLQ9MzFMfRHpBKc015rvzJIF+WT\r\nB4HPJHjvJPYaAJU/mDqz+kbSngWLMr1/pqz8dOc4/OY/RdIEgXeXfBWlT6EV\r\nzRz7MU2VZeheOInSiLO8Vg4q+ukcgpTn8WAGAAJamh0ppeeCZxNSjA3BQPb/\r\nmqYovH0clL+dxcrhUv0scGOglj71wtP9K3xTwOFSNxTsSvjz4agKC7cAJX2j\r\nLX9P3cZ/exdOjBmWo0LHVrNCVfcCdF7UsthxxBQ5pztz/O4YB4zaYQD2yMI7\r\nxfDGQBSGZca5QJSwLpNK+tPAveRTXlu9JWfF20m96oPxUaMrPjasQMNC+DGM\r\n6mVhoAICRJElGgeAM4Mlqkolmwi6Xv9CjrUXePPYNDWJB2HXXbTHvFOaCqLm\r\nkkj6ag7zAsNFgraieQssGrfWDF8zfohuHOST5O4RBx5OfZ4wV8hWi4VGpmGU\r\nj/P2hqS+E+r5JFgHyDPRdlG5pbk76wdRrYClB3UZA0CEpZcoBrdomQmcibRZ\r\nTZL7CQOV2NfRiOEpsMCSkfGw0fUyBZOD9EI=\r\n=Ut1i\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"1fbb739d7f5ea750599feeae7526729e63a9f268","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.13.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.0.4","@pvermeer/dexie-class-addon":"^1.0.3","@pvermeer/dexie-populate-addon":"^1.0.3","@pvermeer/dexie-encrypted-addon":"^2.0.4","@pvermeer/dexie-immutable-addon":"^1.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.1.2_1674586817396_0.773057943793461","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.0-beta.2":{"name":"@pvermeer/dexie-addon-suite","version":"1.2.0-beta.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.2.0-beta.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"b2e3b76e57c637574eb86598578c583754c7a16b","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.2.0-beta.2.tgz","fileCount":23,"integrity":"sha512-AE5ZT3j8CKI7kR16F7HQmq1HtYMIMbTj62Jl+L5Q0RCfO7qluzSD+MyJoFFpiL6B2eieL1jPHeKKf7KlxPmHGg==","signatures":[{"sig":"MEUCIEj9vN8tJ8kPI99froKUHxdT1pRbFcVDqZ1qh7lAK9EsAiEA4HbAraJ0KVcYIGZwNswZqz2N2KOQeHIFz01Fhx7aYPg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1640775,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0Sd9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp63w/9HKprPH2AksKXuV5niDvLWkQSwlDQ6MPBwAOPPwIvrkEeRkcH\r\nYGVuujaKsE6OLO2AIDkSOlTM4cEMdp7rOCJM18+U0r1ZHRFH1aHNAPTzksbm\r\nFr7XeeE9gNJiwZVK0ek1Tv9m9HCsivI5SaYx0qgkwGjs7WsvwdatSko5YfEs\r\n25A6v6S39qWGcrz4veoaD1Ygk5QXU4hS6ESQycShLxHZ7PDMdtCJEdhXj5QO\r\nYhK+7LSrXNUijLC/P8T4erAsCQmN//d2G6/eKdU0nuMDOh7SCXpiNB9VPovq\r\nMSbRtksEj4m2lrGlmJC8G7c2H8OosmdZOovN8AOWYNlRbGE3vfCLMdJ5MWzS\r\n86pf9REBzCFjNMy7FVy2jCXGw06V3Zf+RoMjxvv3mq9OTrdMms77m90Bfiox\r\nCOH1pMeF0o3B1An5Nr3iLqNDKoOr1rTCl4i0ylWi7KNFtIAYHoHSJEfnNTkX\r\nXt0CpPHnYwMcxV78xiprMNUIQ4Pun+LSCRm/3+HVLSuWMbIO1i5tx0qRrcnD\r\n4kwPq1ubQ8RFTWbLX2gCXRCH/vzsHXoqurp6p/BC5hROg6a9XVKASoQDP/7c\r\ndln2mHGk9jcrwCrPVlhyippE8AO+b6qAaxTcRkFJkWN6EVG02mBQ+fpg+wYp\r\nGdDSNozuxwzo705kclj6JUO+XRv4KZJ8d5E=\r\n=odqn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey?: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"49456eed415ac67ee5c877df981970b17d8bf944","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.13.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.0-beta.2","@pvermeer/dexie-class-addon":"^1.0.4-beta.0","@pvermeer/dexie-populate-addon":"^1.0.4-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.5-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.3-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.2.0-beta.2_1674651517008_0.08399042221681774","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.0":{"name":"@pvermeer/dexie-addon-suite","version":"1.2.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.2.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"e82d9ea1fb90ccaaa72516665a2c39f58c7dda72","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.2.0.tgz","fileCount":23,"integrity":"sha512-l1l3sRPHsj0wSvtkcY93uLJXie9guCfUiEyMcv3lDH7q2hATxDjbF9EP2hv6nKodHlyH7kyYpgSk2D2EyED+3Q==","signatures":[{"sig":"MEQCIH9wyp7nCc2EGV6xrapE+MOXLUjs3O5X1lJa0Jys99vZAiAywtY63CpyZ6aH+m+2B7S6P/x1jpk8yZfhxSYwTo75Pw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1640967,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj3n4jACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoq3hAAnMwXODK1/x45AFkUY1qz0xMH6TrkksFPwH/5nsIXd+Um3Fja\r\n+cFMyTvw5ZZO2Ru7l324wVEeto/8qvDtLo651d0OEBZNLFaynY4ntJ9SHhC3\r\nVSWnVy8PveFxgaohYK40P1dZuiZMgYbKlEn8o7iNon2GQ+VGtoKK5MSYdOAi\r\nl6p05+tVG+vfbNaSIBEXV7evkkEopKlSeXoShzNGbBaGbk3PNZpQOE9l7JSV\r\nWvLstiOtaKUx2SadgRaBpJlXEZ+XgM0tWW4oXSplayZYd8n4JWQJbaY8+bCI\r\n893qdUgayZbmekjnHC4Izon7jvEUBSzVj0ZlQ0/ZNlNQqAp3WD2+2R4Qfj6I\r\nhMwzZywxmya88rkXs7Gh0STFzaeJtDXM76hlfOR4Qhyv5DlITWQ+XGBxxH5m\r\nPoQTQAIpqU56LJ/TnitDPHIgpmHJNXp+OY/F48XBHXT/SA/cADGJaCrpfQ3y\r\nADApjiqqUTJkEYhgdk4UNMt460kP2zZoFY4inl4QeaKUjUuVxVx4Zm3msEFP\r\nHzb2DlDTchOUuMp0s36f4hhsRyyGShsF6JgrfRjI99PmG2s3RSwvC8oSEeM3\r\ng3ym7LRBnfdIl9AWwATx0QwcM7SVeMw1iRIuRBP9hEumZqKfElZpXn4SSFoo\r\noSgpqYXu68Yn8CMzwfxmOTBHq9lSa6SIFZc=\r\n=trMw\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"802ec1261061e4f9517d8460512989e98506585e","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.13.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.13.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.0","@pvermeer/dexie-class-addon":"^1.0.4","@pvermeer/dexie-populate-addon":"^1.0.4","@pvermeer/dexie-encrypted-addon":"^2.0.5","@pvermeer/dexie-immutable-addon":"^1.1.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.2.0_1675525667699_0.445252553823166","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"1.2.1-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"1.2.1-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@1.2.1-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"0b2be415e4c315f828a90398cf3050480cab82d9","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-1.2.1-beta.0.tgz","fileCount":23,"integrity":"sha512-Et6jTEIsKUw/CTxULFjIWowyefm5/dZ6bng90LRSXqC8f+XgxkswSTdMUuikvy8+8v55/ivyA3sg/d8Gw46Zeg==","signatures":[{"sig":"MEQCIGCnABedAlVkiXg+trxrchbfr3LEE7UdIolFtAsnLxsTAiA0+ig/m2/UJLy6J+JYPaqpCR6BKWUQ9ibZAYP3kP8eGA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1641251,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj5+IrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqAQw//btXPANlgOE4EkjHGRaN6UuDTnLZN1mj4tz5AdzQ0DUm4kfBn\r\nkk78+BcLYe/upGxGbtNGGFc3zMtCdPQ/EaMS2PP02NUiZJ4vggtTIpjVimN9\r\nUlEDiLk+D8MUuRJOp/wJXf8zN9kfibE+VH3qokLwz2ZTZhTjadZSFG/Haynm\r\nQgYk2AWRV9TStMtUl0l0KzLqIon+7seOAxtFuDMBr9s1vU8SmNUA07QVPFah\r\nUc14UJjddDDhJvcXopceS6iARwddKhxtNYPw4fVdaWheZSjgxR4UQy9nIyYV\r\nUHgOuoA75oe3aXYFxlyr4/iSNYg6SSHQfj/tBA0MEO4/HlvySG0938wlvV/G\r\nXmA0bMVY5mgAwzfEF6OkmVi0wSD1LCyubsRAZomUdPdGy71SWqMYi69THlJK\r\nIRNabLf9y1FP3bhcQLY2v3iwYsU+xbcP70NTlvut061OA90rubW0BZ4oBzFG\r\nW4pkqvJx5bSy3ya/TvSksNTg7HcnWJgltiZD9/yijJAZNVFugw7d7v9/PNRV\r\nr4Yy3m3ACyS2cY05HW4LUjp7QZlLnAuHoPZGsz3xwqCbWvMBEeaEDjcEUhrk\r\n0dGEgFbPT82BVUZ5SIlnGNeWbxlBZ9X0LbSh8TSz2kd5prHl3xfVNbOLX93C\r\nQDXOKJOBp2tFdrH2FxRMzPHedmXj0E4oqzQ=\r\n=LFLz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey?: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"6513bccedaba5af491f52aa2e9ad3de895bd3a01","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.14.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.14.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1-beta.0","@pvermeer/dexie-class-addon":"^1.0.5-beta.0","@pvermeer/dexie-populate-addon":"^1.0.5-beta.0","@pvermeer/dexie-encrypted-addon":"^2.0.6-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.4-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_1.2.1-beta.0_1676141099406_0.8076231724860945","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.0-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.0-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"b428f5d2394f6cf69084a0affcc930c4b8f81a71","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.0-beta.0.tgz","fileCount":23,"integrity":"sha512-QGUrNEl/0A+XcBmepcEhimPKUGbQ0cy/owrg96vbczSZf8ToZC/8PKqnFiutfNl5pH8+TH4sIz833YXE4FuNRQ==","signatures":[{"sig":"MEUCIQC0zMAfrVlJJUro85P0/r/J+D2Mg/2150of+rBZ0A8OjQIgZQ6bfeCnXwlIAlAyLs8EDOBW/4gVBUs+lpw5XGMGM/8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1642340,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj93ABACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9bQ/+JQO4/lSypcXJJ4yL5u05AeiFJJfomQIIl72z2StALZiQ9yVr\r\nGJjT8X+SLD7Yzm6uzpcasiuw2jpJB3E5uMIJCfn//AnBkt9gvfS4pYYLfCnP\r\nTlm35er0L2/ZhWSyAg4m22ZPlsxd8zjzWkZqSLQxnfGmJ+RSanUMj4HtS2HY\r\nN7pviCBSjJoTB9mOT40KJjt7vut0VwkKfLwag5NucGziSkgOLFZB8TtId06r\r\nb0K7TGDrGkZ7Yop79r0WYP3Ho/LyFrD1gD9JGQxSpbD7Qei9eZhFeSOMq6mD\r\nWKmgtRoSRL0kNYKlS+Bf0SigGqCsfPHCF/MO1cnFZ8obNZEMUPZvsywX7OdJ\r\n5gLuMzEx40IJ+6rMtbDM0R62zVRpcC6LamV0+WpgzEgLfATVnj3ImkhZ/+Lv\r\nFxI6XJEQOXJuMeawarJTDvecQJuvFPNRweeShlWdmSWveHBBJuylfxaX0Kod\r\nvm+nX6tTOMZb32kKLuJP4WW0cWqwSl6AwVaoKtJ0YtCdwTCriQfwtzjz2UCS\r\nK78NCcklThCQKheN9RT52eE3/aXvjtoMqFKcVYTkq6Me7Rm6VIrROG6iU6l7\r\ncElfzbSWSqnXxvbvrUWlMm/8PicGj4jbdLT7fxZZKh9QUYMCLOYx90pmPMcl\r\njxkoXXl4BG+LdS5Sn3lVchJq4UWSRcbyL4A=\r\n=EA62\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string) {\n    super(name);\n\n    const secretKey = Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\nconst db = new FriendDatabase(\"FriendsDatabase\");\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\nconst secretKey = Encryption.createRandomEncryptionKey(); // Might wanna store this somewhere\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      const secretKey = DexieAddonSuite.Encryption.createRandomEncryptionKey(); // Might wanna save this somewhere\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"10497b597596b9f3fd897edcf4d7e5b15aca2ec0","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.14.1+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.14.1","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1-beta.0","@pvermeer/dexie-class-addon":"^1.0.5-beta.0","@pvermeer/dexie-populate-addon":"^1.0.5-beta.0","@pvermeer/dexie-encrypted-addon":"^3.0.0-beta.0","@pvermeer/dexie-immutable-addon":"^1.1.4-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.0-beta.0_1677160448944_0.03185453118692938","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-beta.1":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.0-beta.1","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.0-beta.1","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"98657a92fd932e03a9fd50a7957101c698a7e260","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.0-beta.1.tgz","fileCount":23,"integrity":"sha512-szNhEa6FH59ms6KoGesUpEsyDYP5YiOrpn3dn+ir16CSXouG3zEocyQoe/73t/r2ooh1exN9Pjmz24uCokK/gQ==","signatures":[{"sig":"MEQCIFcZwvN/LMKTnA5vJNn6QT305YBZH7nfeBx7Nv3Mgqc1AiAogKfIGXeOA6BheiZKASaUkNRy/FCZN5AaXXRwpz+9pw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1652427,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkA1EvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqOPQ/9EuB5UFcrF/VNGyAHG/mCEIOEG67cxOC3AnOunlrcGSZak22C\r\n+6TsZwIVWQkDVI2d82K3jvLKJ5ZQJ4nfS3u17Ni3cIjznCH86udvDQ3+VjHH\r\nX0xpVZEZ55aKo76zDBlg4ZfCGZdrr+z056a+Wbw0/6Vp2it0fbL4C+gohmld\r\nQ4fs94w40xFkKylJ6YKBBIhJ2MibWbFG1tb1wgha7DJ8eY79JaIoO4E3sn6F\r\nI5X+ElFYAkO1ze1XfMQZtM5WhAChIYwqgvG4HSYB501cvFxhweuIGpPeV8D4\r\ng/+iJYQhrmHUtcaNZBMrfeXu8IS/BLoRVAe21//D3kmg//L9eEs3q/Cg8t6c\r\nFJdTKSaH8oRpLvsf+xufghOUmN9m5KPLbfuzyIXh+6P/bCmTqk/0fArIoMwG\r\ndFQUywiixFbKxiyKbIzSYYE+zSSqyku4Rbc3C1B5/LLc+FgMri0Qe+Da7YOV\r\nGxpKl28uQt47igooajrbfsO51z1ckXJpXZSUwfU1EHQBh5qJ3TwOozuFm8Dj\r\nVVWhLgfnRuoO2hqxYZgGtfYpljH793QoSx8VMOSjAPJ9Lxecqd9cteC6Qm1A\r\n74nF0rSLqMkXT9ir+8XHyV2vJjeDNxxR1P/GO9ESU2ero+SrdfGlb76mZc2o\r\nl99kksdXJr7G9q9QUwSRYl/WF9W/1gnCWXo=\r\n=qht6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string, secretKey: string) {\n    super(name);\n\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\nconst db = new FriendDatabase(\"FriendsDatabase\", secretKey);\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      // Generate a random key (only on first use the database)\n      const newSecret = DexieAddonSuite.Encryption.createRandomEncryptionKey();\n      // Save this key somewhere secure and trusted to be used on reopening the database\n\n      const secretKey = \"[key fetched from a secure location]\";\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"577c2166919c581701d15c7208f1925670b7aca4","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.14.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.14.2","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1-beta.0","@pvermeer/dexie-class-addon":"^1.0.5-beta.0","@pvermeer/dexie-populate-addon":"^1.0.5-beta.0","@pvermeer/dexie-encrypted-addon":"^3.0.0-beta.1","@pvermeer/dexie-immutable-addon":"^1.1.4-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.0-beta.1_1677938991239_0.6142192302708798","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-beta.2":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.0-beta.2","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.0-beta.2","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"ce98d763d5358811b1ac2267832f384962d8ee63","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.0-beta.2.tgz","fileCount":23,"integrity":"sha512-yumTFoCqqNAVRz3wyA9V/lUNvK6qPZsk1t4JaVRhK+6TyzjIUBHvjzv9yjB4RLqIJ25AfAd7IEWg/OVKwyZCCA==","signatures":[{"sig":"MEQCIEJE3u0TlPz1a3FRsJ/1w0HLHguv/6wAwyBL5vdgrGomAiBIl9P3Xo742bX2gt9Tdr/XcQY4bubJZNwML2dLOKdGpQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1654256,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkA3vbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqAg/+PYmWGl1rMmUgSGRkAhAYXBeXe7LX/gY9XBQ7OjnNGxsg7nKH\r\n2NQGrUAQNwm3zAzh5df6YQlHKKtamqn5IFIl3iNS0dgJnMqOlPMWkRpjZ/XP\r\ngGG85rZsqVZqcyMED/muYUYbpg7RHnSs8ibkc1leX6cfcHe9kBWSR55vKaxW\r\nNHiswTzRLfV6r0/j8zqMzPDZt+UAfWnIPolh0JcT3qdncE222vEwsjtM+raZ\r\nw/9NT4dQh6hl9BAfnhBibJZuFxI1Tkva20GnJLcjh0sz25Z218m6YiXGf9So\r\nAm6JyDFrIrVmYtu2Fq8xjwlL01kog2ZlA7b8KpjDdaCqPmvOoiRtvD4smvlo\r\nxAVgbzcvkxqv3iMkwbRrHcmvzBLIhSN18e9deJvu8zADG4Cqgx1CZWrP2aqi\r\nFQHelN5UR4F2UGrtze1MRrF/MtRMHDf7CEDC082uPkhSac4UujEOBAJNzOIB\r\nfQZkaaT+c0ZlET97uY9pmrJn5zD9/K2xAS5lfq31BRc86fVWn+0nms43qnJ3\r\nQ6Dh+0AF4sXbg8LRKZbQxFkATZ7LysMdBicJ0YXVCyEDrRmSa4WNuS+E+s/K\r\nPAQUgXdX/e6xE2mNFsrNfP695qIZvwS/9BWB/c131ow2DkCTW76fV6Bfcu6J\r\nPMwoTIW2vww1hefA4H2AzWLQ1wMZRvMQjZk=\r\n=nZoC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string, secretKey: string) {\n    super(name);\n\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\nconst db = new FriendDatabase(\"FriendsDatabase\", secretKey);\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      // Generate a random key (only on first use the database)\n      const newSecret = DexieAddonSuite.Encryption.createRandomEncryptionKey();\n      // Save this key somewhere secure and trusted to be used on reopening the database\n\n      const secretKey = \"[key fetched from a secure location]\";\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"68f20ec69d31b955308ee5214038cad6ef464e06","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.14.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.14.2","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1-beta.0","@pvermeer/dexie-class-addon":"^1.0.5-beta.0","@pvermeer/dexie-populate-addon":"^1.0.5-beta.0","@pvermeer/dexie-encrypted-addon":"^3.0.0-beta.2","@pvermeer/dexie-immutable-addon":"^1.1.4-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.0-beta.2_1677949914805_0.09448961824761115","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0-beta.3":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.0-beta.3","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.0-beta.3","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"48d43c4d28f5c21c6e6ae20c85bc81259c8bea99","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.0-beta.3.tgz","fileCount":23,"integrity":"sha512-4fvG+VUtyYXZ80gBI3DQc9ZRWuBOS4XB46sS1D51Vl2moCQ0vCwJPIEBB+t7EArA48lHoI4Lbus1lCnvvm/XbA==","signatures":[{"sig":"MEYCIQDzfM4k/BFEER30WuQZM4QvNscnWgLLumreFmdOKcrE4gIhAOgByNRzujSrWE8NrEmJN/5OVZX6+rW0sTUnQdkIyWTL","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1452289},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string, secretKey: string) {\n    super(name);\n\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\nconst db = new FriendDatabase(\"FriendsDatabase\", secretKey);\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      // Generate a random key (only on first use the database)\n      const newSecret = DexieAddonSuite.Encryption.createRandomEncryptionKey();\n      // Save this key somewhere secure and trusted to be used on reopening the database\n\n      const secretKey = \"[key fetched from a secure location]\";\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"69dd1ebb273ef8adc25561c48515ee918f88e228","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.1.0/node@v18.16.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.16.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1-beta.0","@pvermeer/dexie-class-addon":"^1.0.5-beta.0","@pvermeer/dexie-populate-addon":"^1.0.5-beta.1","@pvermeer/dexie-encrypted-addon":"^3.0.0-beta.3","@pvermeer/dexie-immutable-addon":"^1.1.4-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.0-beta.3_1684944287774_0.7132509303543586","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.0":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"3c9be201a6d56b27e7b97788043cfa8e4b3048ff","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.0.tgz","fileCount":23,"integrity":"sha512-m7B1PC48+qGU0i3HVr+vbTOD6MkqrhbVG8voDLumAPGHCGxqDKaRA3u23tj7EM5e2mLTre+H/hzztDitQcZ21A==","signatures":[{"sig":"MEYCIQC7TliPNEm1+tnoMbGxwyEwCnzlt5uVn4khoCkh3l/HmQIhAL2kymZWsJSBqEo35L7Gmpo+/KfdE1euM8HfMs3az22R","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1462374},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","gitHead":"2d91ce711d3d8f6cc2f63692fc5c88a6046c42c1","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v18.16.0+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"18.16.0","dependencies":{"tslib":"^2.4.1","lodash.isequal":"^4.5.0","lodash.clonedeep":"^4.5.0","@pvermeer/dexie-rxjs-addon":"^1.1.1","@pvermeer/dexie-class-addon":"^1.0.5","@pvermeer/dexie-populate-addon":"^1.0.5","@pvermeer/dexie-encrypted-addon":"^3.0.0","@pvermeer/dexie-immutable-addon":"^1.1.4"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.0_1685013686059_0.6497543338628036","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"2.0.1-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"2.0.1-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@2.0.1-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"c552680b74e2605a4cf54a860b7ff81bfd946f87","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-2.0.1-beta.0.tgz","fileCount":22,"integrity":"sha512-KoK1CNFcCg2VlbHNHUqOXGnHRkD5F7AiWkJ19Nj2VsLvMsoWIAOeD5E/O+eZa9QoDQmwJH0/QSVZNd3Sp/QNmA==","signatures":[{"sig":"MEUCICoEWUBjz2FFPxgwUbp6SBG+4tzU6YB1u6Wk+4LVXcx3AiEA8trjXs4FpvOVMe1+JF6ErgUx/SNMJe7jI5DXmz3yUE0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1138287},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string, secretKey: string) {\n    super(name);\n\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\nconst db = new FriendDatabase(\"FriendsDatabase\", secretKey);\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      // Generate a random key (only on first use the database)\n      const newSecret = DexieAddonSuite.Encryption.createRandomEncryptionKey();\n      // Save this key somewhere secure and trusted to be used on reopening the database\n\n      const secretKey = \"[key fetched from a secure location]\";\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"bd8be8ffe3c0f38734770351dff7deafe944145b","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v20.12.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"20.12.2","dependencies":{"tslib":"^2.4.1","@pvermeer/dexie-rxjs-addon":"^1.1.2-beta.0","@pvermeer/dexie-class-addon":"^1.0.6-beta.0","@pvermeer/dexie-populate-addon":"^1.0.6-beta.0","@pvermeer/dexie-encrypted-addon":"^3.0.1-beta.0","@pvermeer/dexie-immutable-addon":"^1.2.0-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_2.0.1-beta.0_1714381975796_0.7898987762005767","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."},"3.0.0-beta.0":{"name":"@pvermeer/dexie-addon-suite","version":"3.0.0-beta.0","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"author":{"name":"PVermeer"},"license":"MIT","_id":"@pvermeer/dexie-addon-suite@3.0.0-beta.0","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"dist":{"shasum":"d02bc0d132b9a61f7a4e677d538419a53e2bddd6","tarball":"https://registry.npmjs.org/@pvermeer/dexie-addon-suite/-/dexie-addon-suite-3.0.0-beta.0.tgz","fileCount":22,"integrity":"sha512-LBwGQvr3CTR6IXUGXElOVYYOVuXIIiC7Gx5njvvYlsbGSX2UK4zqtHJSdf4G/Fo7McDcEnmzRXymrWGE/nTYfA==","signatures":[{"sig":"MEQCID7qwboWCCya4erCX1gpKnDxA4ZmIxyokqTl0ylSGj6cAiBrbn39eOVhm/2kUlAfpXnqp/fE/HobmA/6LSUYyG20Yg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1138704},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","readme":"# Dexie Addon Suite\n\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n[![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-addon-suite/beta.svg)](https://www.npmjs.com/package/@pvermeer/dexie-addon-suite)\n![master](https://github.com/pvermeer/dexie-addon-suite-monorepo/actions/workflows/ci.yml/badge.svg?branch=master)\n[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lerna.js.org/)\n[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)\n\nDexie Addon Suite combines the Dexie-addons from:\n\n- **[dexie-immutable-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-immutable-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-immutable-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-immutable-addon)\n- **[dexie-encrypted-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-encrypted-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-encrypted-addon)\n- **[dexie-rxjs-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-rxjs-addon)**; [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-rxjs-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-rxjs-addon)\n- **[dexie-populate-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-populate-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-populate-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-populate-addon)\n- **[dexie-class-addon](https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-class-addon)**. [![NPM Version](https://img.shields.io/npm/v/@pvermeer/dexie-class-addon/latest.svg)](https://www.npmjs.com/package/@pvermeer/dexie-class-addon)\n\nAdds new functionality:\n\n- **populated rxjs observables**.\n\n## Install over npm\n\n```\nnpm install @pvermeer/dexie-addon-suite rxjs\n```\n\n#### Peer dependencies\n\n**rxjs**: https://rxjs-dev.firebaseapp.com/\n\nRxJs is not bundled so you can use your own implementation.\n\n**Dexie.js**:\n\nDexie Addon Suite depends on Dexie.js v3. [![NPM Version](https://img.shields.io/npm/v/dexie/latest.svg)](https://www.npmjs.com/package/dexie)\n\n```\nnpm install dexie\n```\n\n## Documentation\n\n#### Extend your database the Dexie way!\n\nAddon is written to be as easy to use as Dexie.js itself.\n\n# How to use\n\n## Added Schema Syntax\n\n| Symbol | Description                                                       |\n| ------ | ----------------------------------------------------------------- |\n| \\$     | Encrypt this value (_does not create an index_)                   |\n| \\#     | Only as first key: hash the original document and create an index |\n| =>     | Relational notation: `group => groups.id` (_group is indexed_)    |\n\n## Addon\n\nAdd `addonSuite(db: Dexie)` to your Dexie database. See below examples and https://dexie.org for more info.\n\nFor individual documentation check the individual repositories / packages (_links are above_).\n\nBy default these addons will be loaded:\n\n- dexie-immutable-addon;\n- dexie-populate-addon;\n- dexie-rxjs-addon;\n- dexie-class-addon.\n\n_see individual package readme for more info_\n\n### Config\n\n```ts\ninterface EncryptedOptions {\n  secretKey: string;\n  immutable?: boolean;\n}\n\ninterface Config {\n  encrypted?: EncryptedOptions;\n  immutable?: boolean;\n  class?: boolean;\n}\n\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions);\n\n// It is also possibe to provide the config using:\nnew Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ immutable: false, class: false })],\n});\n```\n\n- Provide `secretKey` to enable encryption. (_see below and dexie-encrypted-addon on how to use_)\n- Provide `immutable: false` to disable immutability. (_not recommended in combination with encryption_)\n- Provide `class: false` to disable class mapping. (_class constructor and serializer will not be called anymore_)\n\nRxjs and Populate are mandatory, could not (yet) figure out conditional typings for these.\n\n### Examples\n\n#### Populated RxJs observables:\n\nTo get a populated RxJs observable that emit on changes use:\n\n```ts\ndb.friends.populate().$.get(id);\n```\n\nor\n\n```ts\ndb.friends.$.populate().get(id);\n```\n\nThese methods are interchangeable and also detect changes in the populated records and emit accordingly.\nSee dexie-populate-addon and dexie-rxjs-addon for all query options.\n\n##### Array methods\n\n```ts\ndb.friends.$.populate().where(\":id\").anyOf([1]).toArray();\ndb.friends.$.populate().toArray();\n```\n\nAnd more... see rxjs / populate addon and https://dexie.org\n\n##### RxJs usage:\n\n```ts\nconst friends$ = db.friends\n  .populate()\n  .$.where(\":id\")\n  .anyOf([1, 2])\n  .toArray()\n  .pipe(map((x) => x));\n\nconst sub = friends$.subscribe((friends) => {\n  friends.forEach((friend) => console.log(friend));\n});\n\n// Don't forget to unsubscribe when done! (many ways to handle this, see RxJs documentation and guides / blogs)\nsub.unsubscribe();\n```\n\n#### Getting and setting a raw document\n\nTo get or set raw document, unaltered by hooks, a transaction can be used while setting `raw` to `true` on the `transaction` object:\n\n```ts\nawait db.transaction(\"readonly\", db.friends, async (transaction) => {\n  transaction.raw = true;\n  const friendRaw = (await db.friends.get(id)) as RawFriend;\n});\n```\n\nAll read actions in the transaction will return a raw document as saved in the db. All set actions will save the document as is. So no Class mapping or decryption / encryption will be performed on the document.\n\n### Create Dexie database\n\n##### TypeScript\n\n```ts\nimport Dexie from \"dexie\";\nimport {\n  addonSuite,\n  Encryption,\n  Ref,\n  OnSerialize,\n} from \"@pvermeer/dexie-addon-suite\";\n\n// Declare classes\nclass Style {\n  styleId?: number;\n  name: string;\n  color: string;\n  description: string;\n}\nclass Theme {\n  id?: number;\n  name: string;\n  style: Ref<Style, number>;\n  description: string;\n}\nclass Club {\n  id?: number;\n  name: string;\n  size: number;\n  theme: Ref<Theme, number>;\n  description: string;\n}\nclass Group {\n  id?: number;\n  name: string;\n  true: boolean;\n  description: string;\n}\nclass Friend implements OnSerialize {\n  id?: number;\n  name: string;\n  memberOf: Ref<Club, number>[];\n  group: Ref<Group, number>;\n\n  doSomething() {\n    return \"done\";\n  }\n\n  /*\n        For dexie-class-addon (will call constructor/serialize on read/write).\n        Implement OnSerialize to enable type checking for this method.\n        See dexie-class-addon documentation for more info\n    */\n  serialize() {\n    return {\n      id: () => this.id,\n      name: () => this.name,\n      memberOf: () =>\n        this.memberOf.map((club) => (club instanceof Club ? club.id : club)),\n      group: () => (this.group instanceof Group ? this.group.id : group),\n    };\n  }\n\n  deserialize(input: OmitMethods<Friend>) {\n    Object.entries(input).forEach(([prop, value]) => (this[prop] = value));\n    this.date = new Date(input.date);\n  }\n\n  constructor(input: OmitMethods<Friend>) {\n    this.deserialize(input);\n  }\n}\n\n// Declare Database\nclass FriendsDatabase extends Dexie {\n  public friends: Dexie.Table<Friend, number>;\n  public clubs: Dexie.Table<Club, number>;\n  public themes: Dexie.Table<Theme, number>;\n  public groups: Dexie.Table<Group, number>;\n  public styles: Dexie.Table<Style, number>;\n\n  constructor(name: string, secretKey: string) {\n    super(name);\n\n    addonSuite(this, { secretKey });\n\n    this.version(1).stores({\n      friends:\n        \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n      clubs: \"++id, $name, theme => themes.id\",\n      themes: \"++id, $name, style => styles.styleId\",\n      styles: \"++styleId, $name, color\",\n      groups: \"++id, $name\",\n    });\n\n    this.friends.mapToClass(Friend);\n    this.clubs.mapToClass(Club);\n    this.themes.mapToClass(Theme);\n    this.groups.mapToClass(Group);\n    this.styles.mapToClass(Style);\n  }\n}\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\nconst db = new FriendDatabase(\"FriendsDatabase\", secretKey);\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### ES6\n\n```js\nimport Dexie from \"dexie\";\nimport { addonSuite, Encryption } from \"@pvermeer/dexie-addon-suite\";\n\n// Generate a random key (only on first use the database)\nconst newSecret = Encryption.createRandomEncryptionKey();\n// Save this key somewhere secure and trusted to be used on reopening the database\n\nconst secretKey = \"[key fetched from a secure location]\";\n\n// Declare Database\nconst db = new Dexie(\"FriendDatabase\", {\n  addons: [addonSuite.setConfig({ secretKey })],\n});\ndb.version(1).stores({\n  friends: \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n  clubs: \"++id, $name, theme => themes.id\",\n  themes: \"++id, $name, style => styles.styleId\",\n  styles: \"++styleId, $name, color\",\n  groups: \"++id, $name\",\n});\n\n// Open the database\ndb.open().then(() => {\n  console.log(\"DB loaded! :D\");\n  // Use Dexie\n});\n```\n\n##### HTML import\n\nBundled & minified package: <https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js>.\n\nAddon is exported as namespace DexieAddonSuite\n\n```html\n<!DOCTYPE html>\n<html>\n  <head>\n    <!-- Include Dexie (@next if v3 is still in RC) -->\n    <script src=\"https://unpkg.com/dexie@latest/dist/dexie.js\"></script>\n\n    <!-- Include DexieAddonSuite (always after Dexie, it's a dependency) -->\n    <script src=\"https://unpkg.com/@pvermeer/dexie-addon-suite@latest/dist/dexie-addon-suite.min.js\"></script>\n\n    <script>\n      // Generate a random key (only on first use the database)\n      const newSecret = DexieAddonSuite.Encryption.createRandomEncryptionKey();\n      // Save this key somewhere secure and trusted to be used on reopening the database\n\n      const secretKey = \"[key fetched from a secure location]\";\n\n      // Define your database\n      const db = new Dexie(\"FriendDatabase\", {\n        addons: [DexieAddonSuite.addonSuite.setConfig({ secretKey })],\n      });\n      db.version(1).stores({\n        friends:\n          \"#id, $name, *memberOf => clubs.id, group => groups.id, [id+group]\",\n        clubs: \"++id, $name, theme => themes.id\",\n        themes: \"++id, $name, style => styles.styleId\",\n        styles: \"++styleId, $name, color\",\n        groups: \"++id, $name\",\n      });\n\n      // Open the database\n      db.open().then(() => {\n        console.log(\"DB loaded! :D\");\n        // Do Dexie stuff\n      });\n    </script>\n  </head>\n</html>\n```\n\n## API\n\nThe package main exports:\n\n```ts\nfunction addonSuite(db: Dexie, config?: Config | EncryptedOptions): void;\nnamespace addonSuite {\n\tconst setConfig: (config?: EncryptedOptions | Config) => (db: Dexie) => string;\n}\n\n/**\n * Ref nominal type.\n * TS does not support nominal types. Fake implementation so the type system can match.\n */\nexport type Ref<O extends object, K extends IndexTypes, _N = \"Ref\"> = NominalRef<O> | K | null;\n\n/**\n * Overwrite the return type to the type as given in the Ref type after refs are populated.\n * T = object type;\n * B = boolean if shallow populate;\n * O = union type of object keys to populate or the string type to populate all.\n */\nexport type Populated<T, B extends boolean = false, O extends string = string>;\n\n/**\n * Class with cryptic methods\n */\nexport class Encryption { } // See dexie-encrypted-addon\n\nexport interface OnSerialize { } // Add to database classes that use serialization. See dexie-class-addon\n\nexport as namespace DexieAddonSuite;\n```\n\nAlso exports some other classes and types to support further extension. See declaration or source.\n\n---\n\n# Dexie.js\n\nDexie.js is a wrapper library for indexedDB - the standard database in the browser. https://dexie.org\n","gitHead":"c319825809c3ece9f5e1083564b84b0cf9a1bcf4","scripts":{"lint":"npm run eslint .","test":"npm run lint && npm run test:jasmine && npm run test:karma","build":"bash ../../scripts/build-package.sh","eslint":"eslint --max-warnings=0 --config ../../.eslintrc.json --ignore-path ../../.gitignore --parser-options project:../../tsconfig.base.json","lint:fix":"npm run eslint:fix .","eslint:fix":"npm run eslint -- --fix","test:karma":"karma start ../../karma.conf.js  --context=$PWD","test:jasmine":"ts-node ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'","test:karma:debug":"karma start ../../karma.conf.js --context=$PWD --debug","test:jasmine:debug":"nodemon --inspect-brk=127.0.0.1:9334 -r ts-node/register ../../node_modules/jasmine/bin/jasmine --reporter=jasmine-console-reporter 'test/unit-tests/jasmine/**/*.spec.ts'"},"_npmUser":{"name":"pvermeer","email":"pim.vermeer@gmail.com"},"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"_npmVersion":"lerna/6.6.2/node@v20.12.2+x64 (linux)","description":"Suite of the dexie addons","directories":{},"_nodeVersion":"20.12.2","dependencies":{"tslib":"^2.4.1","@pvermeer/dexie-rxjs-addon":"^2.0.0-beta.0","@pvermeer/dexie-class-addon":"^2.0.0-beta.0","@pvermeer/dexie-populate-addon":"^2.0.0-beta.0","@pvermeer/dexie-encrypted-addon":"^4.0.0-beta.0","@pvermeer/dexie-immutable-addon":"^2.0.0-beta.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"rxjs":"^7.8.0"},"peerDependencies":{"rxjs":"^7.0.0","dexie":"^4.0.0"},"_npmOperationalInternal":{"tmp":"tmp/dexie-addon-suite_3.0.0-beta.0_1714411342095_0.38587108523518854","host":"s3://npm-registry-packages"},"deprecated":"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info."}},"time":{"created":"2020-03-21T18:58:33.394Z","modified":"2024-12-14T10:47:21.654Z","1.0.0-beta.1":"2020-03-21T18:58:33.733Z","1.0.0-beta.2":"2020-03-22T16:25:42.346Z","1.0.0-beta.3":"2020-03-23T12:18:30.117Z","1.0.0-beta.4":"2020-03-23T13:24:48.354Z","1.0.0-beta.5":"2020-11-15T14:43:51.494Z","1.0.0-beta.6":"2020-11-22T20:25:25.719Z","1.0.0-beta.7":"2021-11-21T18:09:46.005Z","1.0.0-beta.8":"2021-12-24T16:10:44.208Z","1.0.0-beta.9":"2021-12-28T09:21:55.278Z","1.0.0-beta.10":"2021-12-30T16:12:20.903Z","1.0.0-beta.11":"2021-12-30T17:21:22.629Z","1.0.0-beta.12":"2021-12-31T15:03:28.112Z","1.0.0-beta.13":"2022-01-01T16:56:01.107Z","1.0.0-beta.14":"2022-01-02T16:47:54.872Z","1.0.0-beta.15":"2022-01-04T12:05:47.468Z","1.0.0-beta.16":"2022-01-04T15:00:19.017Z","1.0.0-beta.17":"2022-01-06T20:12:17.285Z","1.0.0-beta.18":"2022-01-07T17:57:24.230Z","1.0.0-beta.19":"2022-01-08T14:32:56.914Z","1.0.0-beta.20":"2022-01-09T21:09:50.165Z","1.0.0-beta.21":"2022-01-09T22:29:35.296Z","1.0.0-beta.22":"2022-01-21T17:15:21.664Z","1.0.0-beta.23":"2022-01-29T15:23:50.437Z","1.0.0-beta.24":"2022-01-30T17:24:04.008Z","1.0.0-beta.25":"2022-01-31T16:46:57.048Z","1.0.0-beta.26":"2022-01-31T17:54:28.817Z","1.0.0-beta.27":"2022-02-02T15:36:32.536Z","1.0.0-beta.28":"2022-02-02T18:39:59.942Z","1.0.0-beta.29":"2022-03-03T13:08:32.681Z","1.0.0-beta.30":"2022-03-08T13:42:07.234Z","1.0.0-beta.31":"2022-03-09T11:10:27.293Z","1.0.0-beta.32":"2022-04-11T10:27:50.045Z","1.0.0-beta.33":"2022-04-19T13:16:25.422Z","1.0.0-beta.34":"2022-05-26T12:45:15.548Z","1.0.0-beta.35":"2022-06-19T16:36:55.143Z","1.0.0-beta.36":"2022-07-16T17:31:45.169Z","1.0.1":"2022-07-22T17:43:02.131Z","1.0.2":"2022-07-22T18:15:54.183Z","1.1.0-beta.0":"2022-11-07T18:38:00.472Z","1.1.0-beta.1":"2022-11-08T09:32:05.792Z","1.1.0-beta.2":"2022-11-08T10:17:21.246Z","1.1.0-beta.3":"2022-11-08T13:07:28.222Z","1.1.0-beta.4":"2022-11-09T18:31:23.316Z","1.1.0-beta.5":"2022-11-11T23:13:25.826Z","1.1.0-beta.6":"2022-11-12T14:44:23.220Z","1.1.0-beta.7":"2022-12-05T12:07:26.837Z","1.1.0-beta.8":"2022-12-19T21:13:19.652Z","1.1.0":"2022-12-28T16:56:28.620Z","1.1.1":"2023-01-09T14:18:58.656Z","1.2.0-beta.0":"2023-01-20T19:26:12.757Z","1.2.0-beta.1":"2023-01-22T14:26:42.865Z","1.1.2":"2023-01-24T19:00:17.695Z","1.2.0-beta.2":"2023-01-25T12:58:37.208Z","1.2.0":"2023-02-04T15:47:47.953Z","1.2.1-beta.0":"2023-02-11T18:44:59.677Z","2.0.0-beta.0":"2023-02-23T13:54:09.172Z","2.0.0-beta.1":"2023-03-04T14:09:51.414Z","2.0.0-beta.2":"2023-03-04T17:11:55.075Z","2.0.0-beta.3":"2023-05-24T16:04:48.109Z","2.0.0":"2023-05-25T11:21:26.254Z","2.0.1-beta.0":"2024-04-29T09:12:56.035Z","3.0.0-beta.0":"2024-04-29T17:22:22.406Z"},"bugs":{"url":"https://github.com/PVermeer/dexie-addon-suite-monorepo/issues"},"author":{"name":"PVermeer"},"license":"MIT","homepage":"https://github.com/PVermeer/dexie-addon-suite-monorepo#readme","keywords":["dexie","dexie.js","indexeddb","database","addon","suite","rxjs","populate","immutable","encrypted","observable","relational"],"repository":{"url":"git+https://github.com/PVermeer/dexie-addon-suite-monorepo.git","type":"git"},"description":"Suite of the dexie addons","maintainers":[{"name":"pvermeer","email":"pim.vermeer@gmail.com"}],"readme":"","readmeFilename":""}